《mycat结合MysqL双主实现读写分离》要点:
本文介绍了mycat结合MysqL双主实现读写分离,希望对您有用。如果有疑问,可以联系我们。
作者介绍
服务器拓扑
服务器架构
安装MysqL
创建MysqL用户
groupadd MysqL useradd -r -g MysqL -s /bin/false MysqL
安装MysqL
yum install -y libaio cd /usr/local/src/ wget http://mirrors.sohu.com/MysqL/MysqL-5.7/MysqL-5.7.17-linux-glibc2.5-x86_64.tar.gz tar -zxf MysqL-5.7.17-linux-glibc2.5-x86_64.tar.gz cp -rf MysqL-5.7.17-linux-glibc2.5-x86_64 /data/app/MysqL-3306 cp -rf MysqL-5.7.17-linux-glibc2.5-x86_64 /data/app/MysqL-3307 chown -R MysqL:MysqL /data/app/MysqL-3306 chown -R MysqL:MysqL /data/app/MysqL-3307 /data/app/MysqL-3306/bin/MysqLd --initialize-insecure --user=MysqL --basedir=/data/app/MysqL-3306 --datadir=/data/app/MysqL-3306/data /data/app/MysqL-3307/bin/MysqLd --initialize-insecure --user=MysqL --basedir=/data/app/MysqL-3307 --datadir=/data/app/MysqL-3307/data
修改my.cnf
需要修改的参数:
- server-id:保证每个配置文件唯一
- 两台master的自增长ID必须不同
linux-node2
master
cat > /data/app/MysqL-3306/my.cnf<<EOF [client] port = 3306 socket = /data/app/MysqL-3306/MysqL.sock [MysqLd] port = 3306 user = MysqL server-id = 1 bind-address = 0.0.0.0 basedir = /data/app/MysqL-3306 datadir = /data/app/MysqL-3306/data socket = /data/app/MysqL-3306/MysqL.sock pid-file = /data/app/MysqL-3306/MysqL.pid log-error = /data/app/MysqL-3306/MysqLd.log skip-name-resolve log_bin = MysqL-bin log-slave-updates auto-increment-increment = 2 auto-increment-offset = 1 sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES EOF chown MysqL.MysqL /data/app/MysqL-3306/my.cnf
slave
cat > /data/app/MysqL-3307/my.cnf<<EOF [client] port = 3307 socket = /data/app/MysqL-3307/MysqL.sock [MysqLd] port = 3307 user = MysqL server-id = 11 bind-address = 0.0.0.0 basedir = /data/app/MysqL-3307 datadir = /data/app/MysqL-3307/data socket = /data/app/MysqL-3307/MysqL.sock pid-file = /data/app/MysqL-3307/MysqL.pid log-error = /data/app/MysqL-3307/MysqLd.log skip-name-resolve log_bin = MysqL-bin sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES EOF chown MysqL.MysqL /data/app/MysqL-3307/my.cnf
linux-node3
master
cat > /data/app/MysqL-3306/my.cnf<<EOF [client] port = 3306 socket = /data/app/MysqL-3306/MysqL.sock [MysqLd] port = 3306 user = MysqL server-id = 2 bind-address = 0.0.0.0 basedir = /data/app/MysqL-3306 datadir = /data/app/MysqL-3306/data socket = /data/app/MysqL-3306/MysqL.sock pid-file = /data/app/MysqL-3306/MysqL.pid log-error = /data/app/MysqL-3306/MysqLd.log skip-name-resolve log_bin = MysqL-bin log-slave-updates auto-increment-increment = 2 auto-increment-offset = 2 sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES EOF chown MysqL.MysqL /data/app/MysqL-3306/my.cnf
slave
cat > /data/app/MysqL-3307/my.cnf<<EOF [client] port = 3307 socket = /data/app/MysqL-3307/MysqL.sock [MysqLd] port = 3307 user = MysqL server-id = 22 bind-address = 0.0.0.0 basedir = /data/app/MysqL-3307 datadir = /data/app/MysqL-3307/data socket = /data/app/MysqL-3307/MysqL.sock pid-file = /data/app/MysqL-3307/MysqL.pid log-error = /data/app/MysqL-3307/MysqLd.log skip-name-resolve log_bin = MysqL-bin sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES EOF chown MysqL.MysqL /data/app/MysqL-3307/my.cnf
启动MysqL
启动服务
linux-node2和linux-node3都执行如下命令
touch /data/app/MysqL-3306/MysqLd.log && chown MysqL.MysqL /data/app/MysqL-3306/MysqLd.log sed -i 's#/usr/local/MysqL#/data/app/MysqL-3306#g' /data/app/MysqL-3306/bin/MysqLd_safe /data/app/MysqL-3306/bin/MysqLd_safe --defaults-file=/data/app/MysqL-3306/my.cnf --basedir=/data/app/MysqL-3306 --datadir=/data/app/MysqL-3306/data --user=MysqL & touch /data/app/MysqL-3307/MysqLd.log && chown MysqL.MysqL /data/app/MysqL-3307/MysqLd.log sed -i 's#/usr/local/MysqL#/data/app/MysqL-3307#g' /data/app/MysqL-3307/bin/MysqLd_safe /data/app/MysqL-3307/bin/MysqLd_safe --defaults-file=/data/app/MysqL-3307/my.cnf --basedir=/data/app/MysqL-3307 --datadir=/data/app/MysqL-3307/data --user=MysqL &
检查端口
ss -lntup |egrep '3306|3307' tcp LISTEN 0 80 *:3306 *:* users:(("MysqLd",19973,22)) tcp LISTEN 0 80 *:3307 *:* users:(("MysqLd",20537,22))
配置双主
配置主从
linux-node2
master
cd /data/app/MysqL-3306/ ./bin/MysqL -uroot -p -S MysqL.sock -P 3306 MysqL> CREATE USER 'repl'@'192.%' IDENTIFIED BY 'MysqL'; Query OK,0 rows affected (0.05 sec) MysqL> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.%'; Query OK,0 rows affected (0.00 sec) MysqL> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | binlog_Do_DB | binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | MysqL-bin.000001 | 613 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
slave
cd /data/app/MysqL-3307/ ./bin/MysqL -uroot -p -S MysqL.sock -P 3307 MysqL> CHANGE MASTER TO MASTER_HOST='192.168.56.12', -> MASTER_PORT=3306, -> MASTER_USER='repl', -> MASTER_PASSWORD='MysqL', -> MASTER_LOG_FILE='MysqL-bin.000001', -> MASTER_LOG_POS=613; Query OK,0 rows affected,2 warnings (0.04 sec) MysqL> start slave; Query OK,0 rows affected (0.02 sec) MysqL> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.56.12 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: MysqL-bin.000001 Read_Master_Log_Pos: 613 Relay_Log_File: linux-node2-relay-bin.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: MysqL-bin.000001 Slave_IO_Running: Yes Slave_sql_Running: Yes
linux-node3
master
cd /data/app/MysqL-3306/ ./bin/MysqL -uroot -p -S MysqL.sock -P 3306 MysqL> CREATE USER 'repl'@'192.%' IDENTIFIED BY 'MysqL'; Query OK,0 rows affected (0.00 sec) MysqL> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | binlog_Do_DB | binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | MysqL-bin.000001 | 613 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
slave
cd /data/app/MysqL-3307/ ./bin/MysqL -uroot -p -S MysqL.sock -P 3307 MysqL> CHANGE MASTER TO MASTER_HOST='192.168.56.13', MASTER_PORT=3306, MASTER_USER='repl', MASTER_PASSWORD='MysqL', MASTER_LOG_FILE='MysqL-bin.000001', MASTER_LOG_POS=613; Query OK,0 rows affected (0.02 sec) MysqL> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.56.13 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: MysqL-bin.000001 Read_Master_Log_Pos: 613 Relay_Log_File: linux-node2-relay-bin.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: MysqL-bin.000001 Slave_IO_Running: Yes Slave_sql_Running: Yes
配置双主
master的binlog位置
linux-node2 master端
d /data/app/MysqL-3306/ ./bin/MysqL -uroot -p -S MysqL.sock -P 3306 MysqL> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | binlog_Do_DB | binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | MysqL-bin.000001 | 613 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
linux-node3 master端
cd /data/app/MysqL-3306/ ./bin/MysqL -uroot -p -S MysqL.sock -P 3306 MysqL> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | binlog_Do_DB | binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | MysqL-bin.000001 | 613 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
linux-node2 master配置跟linux-node3 master同步
MysqL> CHANGE MASTER TO MASTER_HOST='192.168.56.13', MASTER_LOG_POS=613; MysqL> start slave; Query OK,0 rows affected (0.03 sec) MysqL> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.56.13 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: MysqL-bin.000001 Read_Master_Log_Pos: 613 Relay_Log_File: linux-node2-relay-bin.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: MysqL-bin.000001 Slave_IO_Running: Yes Slave_sql_Running: Yes
linux-node3 master配置跟linux-node2 master同步
MysqL> CHANGE MASTER TO MASTER_HOST='192.168.56.12',0 rows affected (0.00 sec) MysqL> MysqL> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.56.12 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: MysqL-bin.000001 Read_Master_Log_Pos: 613 Relay_Log_File: linux-node3-relay-bin.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: MysqL-bin.000001 Slave_IO_Running: Yes Slave_sql_Running: Yes
验证
从linux-node2上验证
在linux-node2 master上创建数据
MysqL> create database test; Query OK,1 row affected (0.01 sec) MysqL> use test; Database changed MysqL> create table temp(id int,name varchar(64)); Query OK,0 rows affected (0.11 sec) MysqL> insert into temp values(1,'aaa'); Query OK,1 row affected (0.28 sec) MysqL> CREATE TABLE temp2(id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,nname VARCHAR(64)); Query OK,0 rows affected (0.01 sec) MysqL> insert into temp2(nname) values('bbb'); Query OK,1 row affected (0.01 sec) MysqL> select * from test.temp; +------+------+ | id | name | +------+------+ | 1 | aaa | +------+------+ 1 row in set (0.01 sec)
在linux-node2 slave上查看数据
MysqL> select * from test.temp; +------+------+ | id | name | +------+------+ | 1 | aaa | +------+------+ 1 row in set (0.00 sec)
在linux-node3 master上查看数据
MysqL> select * from test.temp; +------+------+ | id | name | +------+------+ | 1 | aaa | +------+------+ 1 row in set (0.00 sec)
在linux-node3 slave上查看数据
MysqL> select * from test.temp; +------+------+ | id | name | +------+------+ | 1 | aaa | +------+------+ 1 row in set (0.00 sec)
从linux-node3上验证
在linux-node3 master上创建数据
MysqL> use test; MysqL> insert into temp2(nname) values('ddd'); Query OK,1 row affected (0.02 sec) MysqL> insert into temp2(nname) values('fff'); Query OK,1 row affected (0.00 sec) MysqL> select * from test.temp2; +----+-------+ | id | nname | +----+-------+ | 1 | bbb | | 2 | ddd | | 4 | fff | +----+-------+
在linux-node3 slave上查看数据
MysqL> select * from test.temp2; +----+-------+ | id | nname | +----+-------+ | 1 | bbb | | 2 | ddd | | 4 | fff | +----+-------+ 3 rows in set (0.00 sec)
在linux-node2 master上查看数据
MysqL> select * from test.temp2; +----+-------+ | id | nname | +----+-------+ | 1 | bbb | | 2 | ddd | | 4 | fff | +----+-------+ 3 rows in set (0.00 sec)
在linux-node2 slave上查看数据
MysqL> select * from test.temp2; +----+-------+ | id | nname | +----+-------+ | 1 | bbb | | 2 | ddd | | 4 | fff | +----+-------+ 3 rows in set (0.00 sec)
结论
- 在任意一个master端更新数据,其他任意端都可以更新数据
- 两台服务器配置了间隔自增长,数据不同冲突
linux-node1上安装mycat
安装mycat
cd /usr/local/src wget http://dl.mycat.io/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz tar -zxf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz mv mycat /data/app/mycat-1.6 ln -s /data/app/mycat-1.6 /data/app/mycat
修改schema.xml
balance="1"
全部的readHost与stand by writeHost参与select语句的负载均衡writeType="0"
所有写操作发送到配置的第一个writeHost,第一个挂了切到还生存的第二个 writeHost,重新启动后以切换后的为准,切换记录在配置文件中:dnindex.propertiesswitchType="1"
默认值为1,自动切换
cd /data/app/mycat cp conf/schema.xml conf/schema.xml.bak cat > conf/schema.xml <<EOF <?xml version="1.0"?> <!DOCTYPE mycat:schema SYstem "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="TESTDB" checksqlschema="true" sqlMaxLimit="100" datanode="dn1"></schema> <datanode name="dn1" dataHost="node1" database="test" /> <dataHost name="node1" maxCon="10" minCon="5" balance="1" writeType="0" dbType="MysqL" dbDriver="native" switchType="1"> <heartbeat>select user()</heartbeat> <writeHost host="master1" url="192.168.56.12:3306" user="root" password="MysqL"> <readHost host="slave2" url="192.168.56.13:3307" user="root" password="MysqL" /> </writeHost> <writeHost host="master2" url="192.168.56.13:3306" user="root" password="MysqL"> <readHost host="slave2" url="192.168.56.13:3307" user="root" password="MysqL" /> </writeHost> </dataHost> </mycat:schema> EOF
启动mycat
./bin/mycat start ss -lntup |egrep '(8066|9066)' tcp LISTEN 0 100 :::8066 :::* users:(("java",16546,79)) tcp LISTEN 0 100 :::9066 :::* users:(("java",75))
验证mycat服务是否正常
在linux-node2-master端配置mycat连接账号
MysqL> GRANT ALL PRIVILEGES ON *.* TO root@'192.%' IDENTIFIED BY 'MysqL'; Query OK,1 warning (0.07 sec
在mycat服务器上安装MysqL服务,但是不启动
使用MysqL的客户端连接mycat
cd /data/app/MysqL/ ./bin/MysqL -uroot -p -P 8066 -h 192.168.56.11 ##连接mycat,初始密码123456 MysqL> show databases; +----------+ | DATABASE | +----------+ | TESTDB | +----------+ 1 row in set (0.00 sec) MysqL> use TESTDB; MysqL> insert into temp2(nname) values('eee'); Query OK,1 row affected (0.09 sec) MysqL> insert into temp2(nname) values('ggg'); Query OK,1 row affected (0.01 sec)
linux-node3 slave端查看数据是否同步
MysqL> select * from test.temp2; +----+-------+ | id | nname | +----+-------+ | 1 | bbb | | 2 | ddd | | 4 | fff | | 5 | eee | | 7 | ggg | +----+-------+ 5 rows in set (0.00 sec)
结果发现数据写入到了linux-node2 slave端
测试
服务自动迁移
关闭linux-node2 master的MysqL服务
MysqL> shutdown; Query OK,0 rows affected (0.01 sec) shell > ss -lntup |grep 3306
mycat端插入新的数据查看数据是否同步
MysqL> insert into temp2(nname) values('mmmm'); Query OK,1 row affected (0.07 sec) MysqL> insert into temp2(nname) values('nnnn'); Query OK,1 row affected (0.01 sec)
linux-node3 slave端查看数据是否同步
MysqL> select * from test.temp2; +----+-------+ | id | nname | +----+-------+ | 1 | bbb | | 2 | ddd | | 4 | fff | | 5 | eee | | 7 | ggg | | 8 | mmmm | | 10 | nnnn | +----+-------+ 7 rows in set (0.00 sec)
linux-node2 slave端查看数据是否同步
MysqL> select * from test.temp2; +----+-------+ | id | nname | +----+-------+ | 1 | bbb | | 2 | ddd | | 4 | fff | | 5 | eee | | 7 | ggg | +----+-------+ 5 rows in set (0.00 sec)
发现因为linux-node2的master端已经挂了,数据不能同步了
数据访问是否正常
登录到mycat服务器上执行如下命令:
MysqL> select * from temp2; +----+-------+ | id | nname | +----+-------+ | 1 | bbb | | 2 | ddd | | 4 | fff | | 5 | eee | | 7 | ggg | | 8 | mmmm | | 10 | nnnn | +----+-------+ 7 rows in set (0.00 sec)
执行多次发现结果一样,说明在一台master端挂掉的情况下,其连接的slave端也被剔除,因此数据完整性可以保证
故障汇总
第一次配置的时候maser端没有配置log-slave-updates
,导致node3-slave上没有node2-master端的数据.
解释:
从库开启log-bin参数,如果直接往从库写数据,是可以记录log-bin日志的,但是从库通过I0线程读取主库二进制日志文件,然后通过sql线程写入的数据,是不会记录binlog日志的.也就是说从库从主库上复制的数据,是不写入从库的binlog日志的.所以从库做为其他从库的主库时需要在配置文件中添加log-slave-updates参数.
解决办法:
[MysqLd] log-slave-updates
文章来自微信公众号:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。