读书笔记:MySQL Replication复制故障排除

2024-02-29 22:38

本文主要是介绍读书笔记: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复制故障排除的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/760343

相关文章

mysql中的group by高级用法

《mysql中的groupby高级用法》MySQL中的GROUPBY是数据聚合分析的核心功能,主要用于将结果集按指定列分组,并结合聚合函数进行统计计算,下面给大家介绍mysql中的groupby用法... 目录一、基本语法与核心功能二、基础用法示例1. 单列分组统计2. 多列组合分组3. 与WHERE结合使

Mysql用户授权(GRANT)语法及示例解读

《Mysql用户授权(GRANT)语法及示例解读》:本文主要介绍Mysql用户授权(GRANT)语法及示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql用户授权(GRANT)语法授予用户权限语法GRANT语句中的<权限类型>的使用WITH GRANT

Mysql如何解决死锁问题

《Mysql如何解决死锁问题》:本文主要介绍Mysql如何解决死锁问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录【一】mysql中锁分类和加锁情况【1】按锁的粒度分类全局锁表级锁行级锁【2】按锁的模式分类【二】加锁方式的影响因素【三】Mysql的死锁情况【1

SQL BETWEEN 的常见用法小结

《SQLBETWEEN的常见用法小结》BETWEEN操作符是SQL中非常有用的工具,它允许你快速选取某个范围内的值,本文给大家介绍SQLBETWEEN的常见用法,感兴趣的朋友一起看看吧... 在SQL中,BETWEEN是一个操作符,用于选取介于两个值之间的数据。它包含这两个边界值。BETWEEN操作符常用

MySQL索引的优化之LIKE模糊查询功能实现

《MySQL索引的优化之LIKE模糊查询功能实现》:本文主要介绍MySQL索引的优化之LIKE模糊查询功能实现,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一、前缀匹配优化二、后缀匹配优化三、中间匹配优化四、覆盖索引优化五、减少查询范围六、避免通配符开头七、使用外部搜索引擎八、分

MySql match against工具详细用法

《MySqlmatchagainst工具详细用法》在MySQL中,MATCH……AGAINST是全文索引(Full-Textindex)的查询语法,它允许你对文本进行高效的全文搜素,支持自然语言搜... 目录一、全文索引的基本概念二、创建全文索引三、自然语言搜索四、布尔搜索五、相关性排序六、全文索引的限制七

数据库面试必备之MySQL中的乐观锁与悲观锁

《数据库面试必备之MySQL中的乐观锁与悲观锁》:本文主要介绍数据库面试必备之MySQL中乐观锁与悲观锁的相关资料,乐观锁适用于读多写少的场景,通过版本号检查避免冲突,而悲观锁适用于写多读少且对数... 目录一、引言二、乐观锁(一)原理(二)应用场景(三)示例代码三、悲观锁(一)原理(二)应用场景(三)示例

SQL表间关联查询实例详解

《SQL表间关联查询实例详解》本文主要讲解SQL语句中常用的表间关联查询方式,包括:左连接(leftjoin)、右连接(rightjoin)、全连接(fulljoin)、内连接(innerjoin)、... 目录简介样例准备左外连接右外连接全外连接内连接交叉连接自然连接简介本文主要讲解SQL语句中常用的表

SQL server配置管理器找不到如何打开它

《SQLserver配置管理器找不到如何打开它》最近遇到了SQLserver配置管理器打不开的问题,尝试在开始菜单栏搜SQLServerManager无果,于是将自己找到的方法总结分享给大家,对SQ... 目录方法一:桌面图标进入方法二:运行窗口进入方法三:查找文件路径方法四:检查 SQL Server 安

MySQL 中的 LIMIT 语句及基本用法

《MySQL中的LIMIT语句及基本用法》LIMIT语句用于限制查询返回的行数,常用于分页查询或取部分数据,提高查询效率,:本文主要介绍MySQL中的LIMIT语句,需要的朋友可以参考下... 目录mysql 中的 LIMIT 语句1. LIMIT 语法2. LIMIT 基本用法(1) 获取前 N 行数据(