本文主要是介绍读书笔记:MySQL Replication复制故障排除,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、master上的问题MySQL复制出现问题经常是由于意外操作或者配置的改变引起的。replication出现故障时大多数原因一般都出现在slave上面。但是在诊断时,还是应该同时检查master和slave。
1.master上二进制日志损坏
服务器崩溃或者磁盘损坏等导致的master上二进制日志损坏,将导致slave无法执行,常常出现“不能解析中继日志事件”的错误。
这种情况下,必须检查二进制日志中的可恢复事件,并使用FLUSH LOGS命令轮转master上的日志。
此时,复制故障已经在所难免。最好的恢复办法是使用备份恢复工具重新同步master和slave,然后重启复制。
2.master崩溃及二进制日志事件不一致
默认情况下,二进制日志并不是同步磁盘写。如果服务器在MySQL将二进制事件缓存刷新到磁盘文件之前崩溃,就会丢失缓存事件。
另外,如果二进制日志是磁盘同步写,当一个事务在COMMIT之前如果master崩溃了,在下次重启时这个事务将会被ROLLBACK。但是,二进制日志中会记录在事务提交前执行的操作。
以上两种情况都会出现slave获取的二进制日志偏移事件不一致,导致复制出错。好在master的这种故障可以预先设置而避免。为了高可用性,建议将以下参数设置写入配置文件。前者实现二进制日志磁盘同步写,后者通过XA事务确保二进制日志与InnoDB数据文件一致。所以,该配置并不对MyISAM表起作用。
sync_binlog=1
Innodb_support_xa=1
3.崩溃之后表损坏
如果master或slave崩溃了,重启之后就会发现一个或多个表损坏。需要在重启replication之前解决表损坏问题。
可以通过检查错误日志检查哪些表被损坏,然后参考以下命令修复。在修复前一定要执行备份。
mysqlcheck -u -p --check --optimize --auto-repair db
确保master和slave上损坏的表都完成了修复。修复会导致master和slave数据不一致,尤其是修复导致数据丢失的时候。这时候需要对比受影响的表中的数据,确定是否同步。如果master丢失数据,需要将slave上的数据复制到master;如果slave丢失数据,需要手动为受影响的表重新加载数据。
4.master崩溃及memory表不一致
master从崩溃中重新启动时,memory表中的数据会被清除。但是如果memory存储引擎表正在被工作中的slave复制,slave还没有重启,slave就会含有过时数据。
master恢复后第一次访问memory表时,一个特殊的删除事件会被发送到slave上,让slave清除过时数据从而达到数据同步。但是在memory表被引用和复制事件被传送之间的时间间隔内,还是会导致slave含有过时数据。
为了避免这个问题,可以写一个memory表的数据清除填充脚本,在master启动时使用init_file选项引用。
5.master上杀死非事物型表上长时间运行的查询
如果强行终止修改非事物型表的查询,该查询可能已经被复制到slave上并执行了。这时候很可能产生master与slave不一致。这时候通常需要修正master,然后备份master上的数据并在slave上进行恢复。
6.不安全的语句
不安全的语句能够在master和slave上导致不同的结果而产生数据不一致。如在同一个事务中使用事物型表和非事物型表,使用不安全的函数等。避免不安全语句的最好办法,就是考虑使用基于行的二进制日志、全部使用事物型表、培训用户哪些语句是不安全的以及监听复制警告。
7.master上查询正常但在slave上出错
有时候查询在master上运行良好,但是在slave上不能正常运行。这种情况大多数是参照完整性问题,或者slave配置出了问题。这种情况下,可以考虑在slave上使用“sql_slave_skip_counter”变量跳过事件。
二、slave上的问题
replication中遇到的大部分问题是由于slave出现错误引起的。这些问题有些来源于master,但总是以某种方式出现在slave上。确保slave更强大的一个方法是使用“log-slave-updates”选项开启二进制日志。
1.slave上中继日志损坏
中继日志损坏时,最佳做法是:确认master上二进制日志最后执行的已知事件的位置,然后使用CHANGE MASTER命令重启复制。这将强迫slave重新创建新的中继日志。
2.崩溃后表损坏
这种情况很少发生,但还是应该例行检查一下。如果出现,需要在重启复制之前使用备份恢复或类似手段将损坏的表与master同步。
3.memory表数据丢失
使用memory存储引擎的表,在slave服务器重启后就会丢失数据。可以在重启复制之前,执行一个从master拷贝数据然后重新填充到slave的脚步。当然,也可以考虑在replication中过滤临时表,或者干脆不使用memory存储引擎。
4.slave崩溃后temporary表丢失
slave重启时temporary表就会丢失。所以在replication中,要留意使用的临时表。
5.slave崩溃后数据丢失
slave崩溃后可能没有记录最近可知的master的binlog位置,该信息存储在relay_log文件。如果发生这种情况,slave将试图在错误(旧)的位置重启,试图执行已经执行过的查询。这通常会造成查询错误,可以通过跳过重复事件来解决。
6.slave连接master出错
这很可能是用于复制的账户权限除了问题,可以去master重新赋权。
7.slave连接超时及反复重新连接
常常出现在拓扑结构上有多个slave,而两个或者两个以上的slave没有设置server_id或者设置的server_id相同,出现服务器id冲突。解决办法就是为所有服务器设置不同的server_id。
8.slave服务器崩溃及复制无法启动
当slave服务器崩溃复制无法启动时,只要知道slave上最后执行的正确事件,就很容易重新开启复制。可以通过SHOW SLAVE STATUS命令查看结果。
9.slave重启时的多个错误
难以检测和修复的难题。这种问题发生时,检测错误日志和SHOW SLAVE STATUS的输出结果,寻找相关错误信息。
10.slave和master上的错误不一样
一种不常见的情况:语句在slave上和master上呈现的错误不一样。例如“查询X导致master和slave上的错误不同…”这种错误通常是由触发器或事件等存储程序引起的。
11.slave运行慢而且与master不同步
slave过度滞后(excessive lag)指slave处理来自master的所有事件的速度不够快,导致更新延迟。可以通过监控slave上SHOW SLAVE STATUS输出结果中的Seconds_Behind_Master字段确保延迟在应用程序允许的范围内。为了减轻复制的负担,可以考虑:
①将某些数据库移动到其他slave上减少复制到slave上的数据库数量;
②留意网络延迟;
③提高slave存储性能;
④在一个单独的slave上做变更,然后在拓扑结构中的其他服务器使用备份恢复方法应用这些变更。
12.slave上事务失败的后果
如果混合使用事物型和非事物型表,事务失败更新回滚的时候就难免出现问题。所以,应该总是使用事物型存储引擎。
13.slave上的查询结果与master上的不同
这种问题往往不容易察觉,产生的原因也是多方面的:
①执行了不安全的语句;
②master上的写操作误发给slave;
③混合使用事物型和非事物型存储引擎;
④master和slave上的查询选项集(SQL_MODE)不同;
⑤master和slave上的字符集不同;
⑥master和slave上的默认存储引擎不同;
⑦master和slave上的表定义不同。
三、I/O Thread问题
有三种常见的与I/O线程有关的问题:
①到master的连接丢失;
②到master的连接断断续续;
③slave严重滞后于master。
从slave的状态输出中可以明显地定位问题,如果错误不那么容易理解,可以按照以下步骤隔离问题:
①检查CHANGE MASTER命令,确保使用正确的复制账户。
②检查master上复制账户的证书。
③在客户端使用ping hostname(master机器名)检查网络,确保master是可达的。
④使用telnet hostname port(master端口号)检查端口。
四、SQL Thread问题
SQL线程最常见的问题是语句在slave上执行失败。这时SQL线程就会停止,然后抛出一个错误。常见原因包括:
①键冲突;
②写请求误发送到slave;
③master和slave数据不一致。
大部分SQL问题的解决办法就是将slave与master同步。
五、一般步骤
①检查master状态,记录异常信息;
②检查slave状态,记录异常信息;
③阅读所有服务器上的错误日志;
④检查每个服务器上的进程列表,查找状态中的异常信息;
⑤如果没有报错,尝试重启slave,记录出现的任何错误;
⑥检查有问题的服务器的配置信息,确保没有什么被修改;
⑦检查笔记,为研究和修复问题制定计划。
内容整理自:
《高可用MySQL》( https://book.douban.com/subject/26630834/ )
这篇关于读书笔记:MySQL Replication复制故障排除的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!