mysql slave同步错误:Last_Errno: 1062解决办法

场景重现:

      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;