MySQL主从想必大家都知道如何部署,单纯的主从,主库写,从库读,不涉及切换问题,我们不需要给系统配置主主同步。实际环境中,我们可能需要再进一步的升级这套集群,我们可以配置主主同步,添加浮动IP,用keepalive管理VIP,这样一旦发生切换,主主同步集群,可以不影响数据的写入。
问题来了,系统浮动IP可能会使主主同步出现问题,报IO错误。
下面我来重现这个问题,解惑答疑。
系统环境
操作系统:centos 6
数据库:MySQL 5.7
db1:172.16.20.1
db2:172.16.20.2
VIP:172.16.20.3
主从环境搭建
db1作为主库,db2作为从库
db1获取日志的File和Position
mysql> show master status\G;
*************************** 1. row ***************************
File: mysql-bin.000005
Position: 105058
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
db2配置同步
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
mysql> change master to master_host='172.16.20.1', master_user='repl', master_password='repl', master_log_file='mysql-bin.000005', master_log_pos=105058;
Query OK, 0 rows affected, 2 warnings (0.00 sec)
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status\G;
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
两个Yes表示主从配置成功。
主主环境搭建
现在做将db2作为主库,db1作为从库的部署,从而实现主主
db2获取日志的File和Position
mysql> show master status\G;
*************************** 1. row ***************************
File: mysql-bin.000002
Position: 104678
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
db1配置同步
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> change master to master_host='172.16.20.2', master_user='repl', master_password='repl', master_log_file='mysql-bin.000002', master_log_pos=104678;
Query OK, 0 rows affected, 2 warnings (0.00 sec)
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status\G;
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes
Last_IO_Errno: 1130
Last_IO_Error: error connecting to master 'repl@172.16.20.2:3306' - retry-time: 60 retries: 7
主从复制IO进程出现了报错
问题分析:
Last_IO_Errno: 1130,是说连接数据库失败,没有连接数据库的权限。
那我们查一下用户,分别在db1和db2执行如下:
mysql> select user,host from user;
两个主机结果中都包含:
| repl | 172.16.20.1 |
| repl | 172.16.20.2 |
那就奇怪了,明明已经授权了,为什么会这样。那我们用repl这个用户远程连接一下数据库试试
db2远程连接db1
mysql -urepl -p -h 172.16.20.2
输入密码连接成功。
db2远程连接db1
mysql -urepl -p -h 172.16.20.2
输入密码连接失败,报错
ERROR 1045 (28000): Access denied for user 'repl'@'172.16.20.3' (using password: YES)
找到问题所在了,是VIP 172.16.20.3导致
解决方法
在db1执行对VIP 172.16.20.3的授权(当前db1是主库,权限会同步到db2)
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'172.16.20.3' IDENTIFIED BY 'repl';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
此时重新按上述步骤搭建主主,即可成功了。
有个小窍门,在配置主从的时候我们可以使用如下%通配的方式授权,可以省事,但是这样会降低系统安全性。
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'172.16.20.%' IDENTIFIED BY 'repl';
mysql> flush privileges;
总结:系统的浮动IP会导致数据库连接受限,从而导致主主同步出现IO线程问题。