场景重现:
MySQL 双主实现同步之后,同步机器IP设置为:192.168.101.118和192.168.101.119
在同步数据库中创建一个表
create table test (tno int(5),
tname char(10),
primary key(tno));
然后在118端插入数据如下:
+——-+———+
| tno | tname |
+——-+———+
| 10001 | liming |
| 10002 | linxiao |
在119端实现了同步:
+——-+———+
| tno | tname |
+——-+———+
| 10001 | liming |
| 10002 | linxiao |
然后把119的数据库关闭(模拟119机器环境突然宕机)
在118机器上面插入数据(10003,hanmeimei);
mysql> select * from test;
+——-+———–+
| tno | tname |
+——-+———–+
| 10001 | liming |
| 10002 | linxiao |
| 10003 | hanmeimei |
+——-+———–+
然后模拟118机器也宕机了,并恢复119的环境,然后在119库里面插入数据(10003,‘gaoyao’),,(10004, ‘chenhu’),插入成功
mysql> select * from test;
+——-+———+
| tno | tname |
+——-+———+
| 10001 | liming |
| 10002 | linxiao |
| 10003 | gaoyao |
| 10004 | chenhu |
+——-+———+
然后恢复118机器的环境,此时问题出现,两边不能同步了,
查看记录如下:
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.101.118
Master_User: backup
Master_Port: 3306
Connect_Retry: 50
Master_Log_File: mysql-bin.000014
Read_Master_Log_Pos: 202
Relay_Log_File: localhost-relay-bin.000014
Relay_Log_Pos: 251
Relay_Master_Log_File: mysql-bin.000013
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB: cdn
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 1062
Last_Error: Error ‘Duplicate entry ‘10003’ for key ‘PRIMARY” on query. Default database: ‘cdn’. Query: ‘insert into test values(10003, ‘hanmeimei’)’
Last_Error: Error ‘Duplicate entry ‘10003’ for key ‘PRIMARY” on query. Default database: ‘cdn’. Query: ‘insert into test values(10003, ‘gaoyao’)’
(红色部分为118上面的日志)
Skip_Counter: 0
Exec_Master_Log_Pos: 497
Relay_Log_Space: 915
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 1062
Last_SQL_Error: Error ‘Duplicate entry ‘10003’ for key ‘PRIMARY” on query. Default database: ‘cdn’. Query: ‘insert into test values(10003, ‘hanmeimei’)’
Last_SQL_Error: Error ‘Duplicate entry ‘10003’ for key ‘PRIMARY” on query. Default database: ‘cdn’. Query: ‘insert into test values(10003, ‘gaoyao’)’
1 row in set (0.00 sec)
原因分析:
两边数据不一致,数据库开始进行同步,但是由于在复制同步的时候,发现对方库中存在相同的主键,从而同步失败
并导致 Slave_SQL_Running: No 出现
要求:
要求模拟上述场景,并解决工作中实际出现的这种问题
即双主中有一台机器A宕机后,紧接着另一台B在插入了部分数据之后也宕机了,然后A机器先恢复启动,并在不知情的情况下也插入了相同主键但是内容不一致的数据,
然后B再启动,此时就会出现上述错误
解决(1)
此种情况下只要保证机器B先启动就不会存在此种问题,所以要解决的问题是怎么控制B先启动的问题
解决(2)
网上有其他修改参数的相关建议,但是可能场景不是很合要求
如:
修改mysql的配置文件,/etc/my.cnf,在[mysqld]下面添加一行
slave_skip_errors = 1062
保存、重启mysql服务,再次查看主从复制,问题解决。
此种方法在此场景只能保证忽略报错,在后序的数据中还能保持同步,但是对于已经不同步的数据不能恢复同步:
mysql> select * from test; ————A
+——-+———–+
| tno | tname |
+——-+———–+
| 10001 | liming |
| 10002 | hanmeimei |
| 10003 | Jimmy |
+——-+———–+
mysql> select * from test; ——————B
+——-+———–+
| tno | tname |
+——-+———–+
| 10001 | liming |
| 10002 | hanmeimei |
| 10003 | gaoyao |
+——-+———–+
在A中插入一条数据(10004,’Green’), 这条数据马上能同步到B, 但是 tno = 10003的数据还是混乱的,不知道选择哪条了,所以此条记录没有同步
还有另外一种: 此种和上面方法类似,都是相当于路过了当前问题,令后面的同步
mysql> slave stop;
mysql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
mysql> slave start;