mysql主从复制报错及解决方法
查看主从同步状态:
-- 从库执行
show slave status\G
查看主从报错binlog:
-- 从库执行
select * from performance_schema.replication_applier_status_by_worker\G
1. mysql数据库slave同步报错 1366:
原因:数据库表的字符集和表中的字段的字符集不一致导致的
解决方法:依据实际情况改成一致的
2. mysql数据库slave同步报错 1061:
原因:主库上某表的索引已经在slave对应表上存在,主库继续同步到slave上,会提示slave上某表索引已经存在而导致同步报错。
解决方法:在从库操作删除表索引
3. mysql主从复制报错 1060
原因:slave上表字段重复
解决方法:删除报错指出的重复字段
4. mysql同步报错 1396
原因:主库删除从库上不存在的数据库用户导致的
解决办法:
mysql>stop slave;
mysql> set global sql_slave_skip_counter=1
mysql>start slave;
5. mysql主从复制报错 1007
slave 上报错:
Last_SQL_Errno: 1007
Last_SQL_Error: Error 'Can't create database 'wjw02'; database exists' on query. Default database: 'wjw02'.Query: 'create database wjw02'
Replicate_Ignore_Server_Ids:
原因:slave上早已经存在master上同名的的库,所以master上再次创建库,slave上会提示库已经存在,导致报错;
解决办法:
mysql>stop slave;
Query OK,0 rows affected (0.01 sec)
mysql>set global sql_slave_skip_counter=1;
Query OK,0 rows affected (0.00 sec)
mysql>start slave;
Query OK,0 rows affected (0.01 sec)
或者修改配置文件跳过1007错误
6. mysql主从复制报错 1008
slave上提示:
Last_SQL_Errno:1008
Last_SQL_Error: Error 'Can't drop database 'wjw02'; database doesn't exist' on query. Default database:'wjw02'. Query: 'drop database wjw02'
原因:从库提前删除数据库wjw02,然后在master上再次删除wjw02库,slave上提示为wjw02库不存在,导致复制报错;
解决方法:
在slave上执行:
mysql>stop slave;
Query OK,0 rows affected (0.02 sec)
mysql>set global sql_slave_skip_counter=1;
Query OK,0 rows affected (0.05 sec)
mysql>start slave;
Query OK,0 rows affected (0.02 sec)
7. 将slave_skip_errors=参数写入配置文件
将slave_skip_errors=参数写入slave上的配置文件my.cnf
[root@localhost ~]# grep slave_skip_errors /etc/my.cnf
slave_skip_errors=1007,1008
[root@localhost ~]# /etc/init.d/mysqld restart
这样可以直接忽略slave同步报错信息
注意:生产环境考虑到主从库数据的一致性,是不允许不分情况的set global sql_slave_skip_counter=1; slave_skip_errors 操作这样的参数来忽略错误的,如果遇到主从同步失败的话,就让他卡到那了,人工介入进行手动恢复故障
8. slave_exec_mode 参数可以动态自动处理同步复制错误
注意:此参数的设置只能忽略错误1032和1062的错误。
mysql>show variables like 'slave_exec_mode';
+-----------------+--------+
|Variable_name | Value |
+-----------------+--------+
|slave_exec_mode | STRICT |
+-----------------+--------+
此参数默认是STRICT严格模式;
将该参数设置为IDEMPOTENT模式,slave同步出现1032错误(记录没找到)和1062错误(主键重复),就会自动跳过次错误,并且记录到错误日志里面,其实此参数和slave_skip_errors作用是一样的。
只不过slave_skip_errors参数必须写入配置文件my.cnf,重启mysql,然而IDEMPOTENT默认不需要重新启动slave的mysql服务。
mysql>set global slave_exec_mode='IDEMPOTENT';
Query OK,0 rows affected (0.05 sec)
mysql>show variables like 'slave_exec_mode';
+-----------------+------------+
|Variable_name | Value |
+-----------------+------------+
|slave_exec_mode | IDEMPOTENT |
+-----------------+------------+
1 row inset (0.00 sec)
mysql>stop slave;
Query OK,0 rows affected (0.00 sec)
mysql>start slave;
演示:
slave上操作:
mysql>select * from dr_user_info;
+----+----------------------------------+-------------+------------+--------+
| id |dev_id |tel | updatetime | pwd |
+----+----------------------------------+-------------+------------+--------+
| 20 |CFD0CCDA603705F35C8EE74427C9CC45 | 13713340729 | 1488174916 | 111111 |
| 21 |11713EA0EDAFC1113E9AB016471BBDCF | 18341732393 | 1487632768 | 111111 |
| 22 |C9DEBE883FF6C05A19D5C0487E9C9D63 | 18600271207 | 1488521317 | 111111 |
| 23 |D73C9DADAB3611D82B7D5CA11B62DBA1 | 18974748447 | 1491177725 | 111111 |
| 24 |qwertyuiop |18234123308 | 1491177726 | 666666 |
+----+----------------------------------+-------------+------------+--------+
5 rows inset (0.00 sec)
mysql>delete from dr_user_info where id=24;
在master上操作:
mysql>select * from dr_user_info;
+----+----------------------------------+-------------+------------+----------+
| id |dev_id | tel | updatetime | pwd |
+----+----------------------------------+-------------+------------+----------+
| 20 |CFD0CCDA603705F35C8EE74427C9CC45 | 13713340729 | 1488174916 | 111111 |
| 21 |11713EA0EDAFC1113E9AB016471BBDCF | 18341732393 | 1487632768 | 111111 |
| 22 |C9DEBE883FF6C05A19D5C0487E9C9D63 | 18600271207 | 1488521317 | 111111 |
| 23 |D73C9DADAB3611D82B7D5CA11B62DBA1 | 18974748447 | 1491177725 | 111111 |
| 24 |qwertyuiop |18234123308 | 1491177726 | 33333333 |
+----+----------------------------------+-------------+------------+----------+
5 rows inset (0.00 sec)
mysql>select * from dr_user_info;
+----+----------------------------------+-------------+------------+--------+
| id | dev_id | tel | updatetime | pwd |
+----+----------------------------------+-------------+------------+--------+
| 20 |CFD0CCDA603705F35C8EE74427C9CC45 | 13713340729 | 1488174916 | 111111 |
| 21 |11713EA0EDAFC1113E9AB016471BBDCF | 18341732393 | 1487632768 | 111111 |
| 22 |C9DEBE883FF6C05A19D5C0487E9C9D63 | 18600271207 | 1488521317 | 111111 |
| 23 |D73C9DADAB3611D82B7D5CA11B62DBA1 | 18974748447 | 1491177725 | 111111 |
+----+---------
mysql> show slave status\G
查看错误日志
[root@localhost logs]# tail -1/data/mysql/logs/mysql-error.log
2017-05-1405:22:55 4707 [Warning] Slave SQL: Could not execute Delete_rows event on tabledr_brower_db.dr_user_info; Can't find record in 'dr_user_info', Error_code:1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master logmysql-bin.000010, end_log_pos 5298692, Error_code: 1032
9. mysql同步报错1062(主键重复)
原因:slave上表记录重复,导致slave复制报错1062主键重复
在slave上擦看报错:
Last_SQL_Errno:1062
Last_SQL_Error: Could notexecute Write_rows event on tabledr_brower_db.dr_user_info; Duplicate entry '24' for key 'PRIMARY', Error_code:1062;handler error HA_ERR_FOUND_DUPP_KEY; the event's master logmysql-bin.000010, end_log_pos 5295916
解决办法:删除slave上表dr_user_info重复的id为24的记录
mysql>delete from dr_user_info where id=24;
mysql>stop slave;
Query OK,0 rows affected (0.01 sec)
mysql>start slave;
mysql>show slave status\G
在master上更新一条表记录然而在slave上找不到这条记录报错 1032
在slave上擦看报错:
Last_SQL_Errno:1032
Last_SQL_Error: Could notexecute Delete_rows event on tabledr_brower_db.dr_user_info; Can't find recordin 'dr_user_info', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; theevent's master log mysql-bin.000010,end_log_pos 5296175
解决办法:
在master上查看mysql-bin.000010日志上的sql语句,分析出错处5296175,sql语句在干嘛,依据情况处理改事务
注意:如果是执行的update语句,此时slave同步报错1032的话,是不允许set global sql_slave_skip_counter=1;进行忽略这个错误的,建议查看binlog日志看下是卡在什么地方,然后在slave库上把这条不存在的记录insert,然后在start slave开启同步;
slave的中继日志relay-log损坏导致mysql同步报错
原因:当slave意外宕机时,有可能会损坏中继日志relay-log,再次开启同步复制时,报错信息如下;
解决办法:找到同步的binlog日志和pos点。然后重新同步,
提示:在mysql5.5版本及以上版本,已经考虑到slave宕机导致relay-log损坏的问题造成mysql同步失败。
即在slave的my.cnf配置文件中加入参数relay_log_recovery=1,就可以了
mysql主从复制报错:2003
在slave上擦看报错:
Last_IO_Errno:2003
Last_IO_Error: error connectingto master 'rep@10.0.0.201:3306' - retry-time: 60 retries: 2
原因有多种,可能是slave上防火墙开启限制了3306端口,也可能是在slave上执行change master to 时,指定的连接复制数据库的账户和密码不对导致的。也可能是对端的master开启防火墙做了3306端口的的限制等,也有可能是服务器之间网络的问题导致的
还有就是master上的my.cnf配置文件使用参数:binlog_ignore_db=mydb1,slave上的my.cn配置文件使用参数:replicate-ignore-db =mydb1,也可以导致mysql同步报错2003
master上:
[root@localhost~]*# grep wjw01 /etc/my.cnf* binlog_ignore_db= wjw01
[root@localhost~]*# /etc/init.d/mysqld restart*
slave上:
[root@localhost~]# tail -3 /data/mysql/logs/mysql-error.log
2017-05-1415:59:54 5335 [Warning] Storing MySQL user name or password information inthemaster info repository is not secure and is therefore not recommended. Pleaseconsider using the USER and PASSWORD connection options for START SLAVE; seethe 'START SLAVE Syntax' in the MySQL Manual for more information.
2017-05-1415:59:54 5335 [ERROR] Slave I/O: error reconnecting tomaster'rep@10.0.0.201:3306' - retry-time: 60 retries: 1, Error_code: 2003
2017-05-1416:00:54 5335 [Note] Slave: connected tomaster'rep@10.0.0.201:3306',replication resumed in log 'mysql-bin.000014' atposition628
binlog_ignore_db引起的同步复制故障
一个网友的案例:
在mysql的master上采用binlog_ignore_db命令忽略了一个库以后,使用mysql –e 执行的所有的语句就不写入binlog了,原因是在进行主从复制时,有一个库不复制,查看了一下他的配置,binlog格式为row模式,跟他要了当时的sql语句:
mysql -e ‘create table db.tb like db.tb1’;
查看mysql的手册知道忽略某个数据库的复制有两个参数,一个是binlog_ignore_db,另一个是replicate-ignore-db,他们是有区别的:
binlog_ignore_db参数是设置在master上的,例如:binlog_ignore_db=test,那么针对test库下的所有的操作(增删改)都不会记录下来,这样slave上接受主库上的binlog时文件量就会减少,这样做好处是可以减少网络io,减少slave端I/O线程的I/O量,从而最大程度的优化复制性能,。但是也存在一个隐患,在下面会提到。
replicate-ignore-db是设置在slave上的replicate-ignore-db=test1,那么针对test1库下的所有的操作(增删改)都不会被sql线程执行,
结论:如果想在slave上忽略一个库的复制,最好不要采用binlog_ignore_db这个参数,使用replicate-ignore-db= db来代替