操作系统:centos7
mycat:192.168.10.10,版本:1.6
mysql:192.168.10.11,版本:5.7
10.11服务器安装docker来启动两个mysql实例,端口分别为3307,3308,两个数据库互为主从。
查看mysql镜像
docker search mysql
docker pull mysql:5.7
拉取完成后,查看镜像
docker images
创建目录
mkdir /test/docker/mysql -r
用于存放mysql配置文件和数据,该目录下创建两个文件夹mysql3307,mysql3308,每个文件夹下创建data目录和mysqld.cnf文件
修改mysql3307下的mysqld.cnf
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
symbolic-links=0
binlog-ignore-db = mysql,information_schema,performance_schema,sys
log-bin=mysql.bin //开启二进制文件
server-id=1 //标识唯一性
mysql3308下的mysqld.cnf将server-id改为2即可。
log-bin=mysql.bin:开启binlog日志用于主从复制
server-id=1:标识
docker启动容器
docker run -d --name m3307 -p 3307:3306 -v /test/docker/mysql/mysql3307/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf -v /test/docker/mysql/mysql3307/data/:/var/lib/mysql/ -e MYSQL_ROOT_PASSWORD=123456789 mysql:5.7
docker run -d --name m3308 -p 3308:3306 -v /test/docker/mysql/mysql3308/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf -v /test/docker/mysql/mysql3308/data/:/var/lib/mysql/ -e MYSQL_ROOT_PASSWORD=123456789 mysql:5.7
-d:后台运行
–name:容器名称
-p:端口映射(此处映射了3308和3307端口)
-v:路径映射(此处映射了mysql的数据data和mysqld.cnf配置文件)
-e:设置环境变量(此处设置mysql密码123456789)
查看容器
docker ps -a
可以看到3307和3308都启动成功了,接下来配置主从。
shell进入m3307容器配置,也就是端口为3307的容器,73ad2f2eba00 为容器ID,上图
docker exec -it 73ad2f2eba00 /bin/bash
进入数据库,创建授权用于主从复制的账号slave,仅允许11服务器访问。
root@73ad2f2eba00:/# mysql -uroot -p123456789
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 17
Server version: 5.7.30-log MySQL Community Server (GPL)
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> grant replication slave,replication client on *.* to 'slave'@'192.168.10.11' identified by "123456789";
Query OK, 0 rows affected, 1 warning (0.01 sec)
查看用户是否创建成功
mysql> select host,user from mysql.user;
+---------------+---------------+
| host | user |
+---------------+---------------+
| % | root |
| 192.168.10.11 | slave |
| localhost | mysql.session |
| localhost | mysql.sys |
| localhost | root |
+---------------+---------------+
5 rows in set (0.00 sec)
查看主库日志文件名(File)和日志偏移位置(Position),下面配置主从有用
mysql> show master status;
+--------------+----------+--------------+-------------------------------------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+--------------+----------+--------------+-------------------------------------------------+-------------------+
| mysql.000003 | 774 | | mysql,information_schema,performance_schema,sys | |
+--------------+----------+--------------+-------------------------------------------------+-------------------+
1 row in set (0.00 sec)
进入m3308容器的mysql中连接主库
运行以下命令(连接到主库11上面)
change master to master_host="192.168.10.11",master_port=3307,master_user="slave",master_password="123456789",master_log_file="mysql.000003",master_log_pos=774;
start slave;
mysql> change master to master_host="192.168.10.11",master_port=3307,master_user="slave",master_password="123456789",master_log_file="mysql.000003",master_log_pos=774;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status \G
*************************** 1. row ***************************
.....
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
.....
1 row in set (0.00 sec)
上面设置是以m3307为主库,m3308为从库,为一主一从。
要设置为互为主从,则在m3308设置一个用于从库登录的账号,m3307连接m3308,与上诉过程一致,就不描述了。
为什么设置为互为主从?
如果主库m3307挂了,m3308升为主库,此时读写全部在m3308上面,当m3307恢复了,因为设置了互为主从的关系,m3307会去m3308拉取数据,从而保持数据的一致性,如果不是互为主从,m3307恢复后将会缺失宕机的这部分数据
主从测试1
3307上创建数据库test
CREATE DATABASE IF NOT EXISTS `test` DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci
3308上面创建表格user
CREATE TABLE IF NO EXISTS `user` (
`id` CHAR(20) NOT NULL,
`type` CHAR(10)
)ENGINE=INNODB DEFAULT charset=utf8
在3307上同步成功
在m3307上创建用于mycat连接的用户名和密码,3308会同步过去
grant all privileges on *.* to "proxy"@"192.168.10.10" identified by "123465789";
安装
下载tar包
wget http://dl.mycat.org.cn/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
解压:tar -xzvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
移动:mv mycat /usr/local/
修改/usr/local/mycat/conf/server.xml 和 schema.xml
server.xml配置登录用户帐号和密码
.......
<user name="cqzs">
<property name="password">123456789property>
<property name="schemas">testproperty>
user>
mycat:server>
注释其它多余的user,留一个
参数说明:
user 用户配置节点
name 登录的用户名,也就是连接Mycat的用户名。
password 登录的密码,也就是连接Mycat的密码
schemas 数据库名,这里会和schema.xml中的配置关联,多个用逗号分开,例如需要这个用户需要管理两个数据库db1,db2,则配置db1,dbs(该地方为逻辑数据库名可以随意设置)
privileges 配置用户针对表的增删改查的权限
readOnly mycat逻辑库所具有的权限(只读或读写)。
schema.xml配置主从切换和读写分离
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="test" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
schema>
<dataNode name="dn1" dataHost="Mycat-node" database="test" />
<dataHost name="Mycat-node" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>show slave statusheartbeat>
<writeHost host="hostM1" url="192.168.10.11:3307" user="proxy"
password="123456789">
<readHost host="hostS2" url="192.168.10.11:3308" user="proxy" password="123456789" />
writeHost>
<writeHost host="hostS2" url="192.168.10.11:3308" user="proxy" password="123456789" >
<readHost host="hostM1" url="192.168.10.11:3307" user="proxy" password="123456789" />
writeHost>
dataHost>
mycat:schema>
上面配置中wirteHost与readHost写了两个,第二个是当3308作为写,3307作为读,当第一个wirteHost挂了(也就是3307挂了)之后,mycat会启用第二个writeHost。
参数说明
schema节点
dataNode节点
dataHost节点
(1)balance=“0”, 不开启读写分离机制,所有读操作都发送到当前可用的writeHost 上。
(2)balance=“1”,全部的 readHost 与 stand by writeHost 参与 select 语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且 M1 与 M2 互为主备),正常情况下,M2,S1,S2 都参与 select 语句的负载均衡。
(3)balance=“2”,所有读操作都随机的在 writeHost、 readhost 上分发。
(4)balance=“3”,所有读请求随机的分发到 wiriterHost 对应的 readhost 执行,writerHost 不负担读压力,注意 balance=3 只在 1.4 及其以后版本有,1.3 没有。
(1)writeType=“0”, 所有写操作发送到配置的第一个 writeHost,第一个挂了切到还生存的第二个riteHost,重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties.
(2)writeType=“1”,所有写操作都随机的发送到配置的 writeHost,1.5 以后废弃不推荐。
-1 表示不自动切换
1 默认值,自动切换
2 基于 MySQL 主从同步的状态决定是否切换
心跳语句为 show slave status
3 基于 MySQL galary cluster 的切换机制(适合集群)(1.4.1)
心跳语句为 show status like ‘wsrep%’.
writeHost节点
readHost节点与writeHost节点一致
启动连接mycat
/usr/local/mycat/bin/mycat start
navicat连接mycat测试,账号是server.xml的user和password,端口号默认是8066端口。
将mycat日志设置为debug用于测试查看日志
vim /usr/local/mycat/conf/log4j2.xml
/usr/local/bin/mycat restart
读写分离测试:
插入数据
insert into user (id,type) values ("7","7777")
查看mycat.log日志
DEBUG [$_NIOREACTOR-1-RW] (io.mycat.backend.mysql.nio.MySQLConnection.synAndDoExecute
(MySQLConnection.java:448)) - con need syn ,total syn cmd 1 commands SET names utf8mb4;schema change:false
con:MySQLConnection [id=9, lastTime=1589005877906, user=proxy, schema=test, old shema=test, borrowed=true,
fromSlaveDB=false, threadId=125, charset=utf8, txIsolation=3, autocommit=true, attachment=dn1{insert into user
(id,type) values ("7","7777")}, respHandler=SingleNodeHandler [node=dn1{insert into user (id,type) values
("7","7777")}, packetId=0], host=192.168.10.11, port=3307, statusSync=null, writeQueue=0, modifiedSQLExecuted=true]
可以看到插入的数据是写在3307上。
查询数据
select * from user
DEBUG [$_NIOREACTOR-0-RW] (io.mycat.server.NonBlockingSession.releaseConnection
(NonBlockingSession.java:341)) - release connection MySQLConnection [id=12, lastTime=1589006236648, user=proxy,
schema=test, old shema=test, borrowed=true, fromSlaveDB=true, threadId=101, charset=utf8, txIsolation=3,
autocommit=true, attachment=dn1{select * from user}, respHandler=SingleNodeHandler [node=dn1{select * from user},
packetId=11], host=192.168.10.11, port=3308, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]
看到读取的是3308库。以上测试说明读写分离配置成功
主从切换测试:
停掉3307库
插入数据
insert into user (id,type) values ("11","1111")
DEBUG [$_NIOREACTOR-0-RW] (io.mycat.server.NonBlockingSession.releaseConnection(NonBlockingSession.java:3
41)) - release connection MySQLConnection [id=53, lastTime=1589019236932,
user=proxy, schema=test, old shema=test, borrowed=true, fromSlaveDB=false,
threadId=26, charset=utf8, txIsolation=3, autocommit=true, attachment=dn1{insert
into user (id,type) values ("11","1111")}, respHandler=SingleNodeHandler
[node=dn1{insert into user (id,type) values ("11","1111")}, packetId=1],
host=192.168.10.11, port=3308, statusSync=null, writeQueue=0,
modifiedSQLExecuted=true]
可以看到插入的数据是插入到3308上面。
查询数据
select * from user
DEBUG [$_NIOREACTOR-1-RW] (io.mycat.server.NonBlockingSession.releaseConnection(NonBlockingSession.java:3
41)) - release connection MySQLConnection [id=64, lastTime=1589019394352,
user=proxy, schema=test, old shema=test, borrowed=true, fromSlaveDB=false,
threadId=27, charset=utf8, txIsolation=3, autocommit=true, attachment=dn1{select
* from user}, respHandler=SingleNodeHandler [node=dn1{select * from user},
packetId=15], host=192.168.10.11, port=3308,
statusSync=io.mycat.backend.mysql.nio.MySQLConnection$StatusSync@3fac3cf6,
writeQueue=0, modifiedSQLExecuted=false]
由于停掉了3307,3308即作为读也作为写,所以读也落在了3308上。
此时我们开启3307,查看3307数据库的数据
可以看到刚插入的1111数据同步到了3307上,这就是刚才为什么要设置为互为主从的关系。
到此,已实现主从复制,读写分离,主从切换。
如有错误,欢迎指出~~