17.5.4 复制故障排除

如果您已按照说明进行操作,但您的复制设置不起作用,那么首先要做的是检查错误日志中的消息。许多用户在遇到问题后没有尽快这样做而浪费了时间。

如果您无法从错误日志中判断问题出在哪里,请尝试以下技术:

  • SHOW MASTER STATUS通过发出语句 验证源是否启用了二进制日志记录 。默认情况下启用二进制日志记录。如果启用了二进制日志记录,Position则为非零。如果未启用二进制日志记录,请验证您没有使用禁用二进制日志记录的任何设置运行源代码,例如 --skip-log-bin 选项。

  • 验证server_id 系统变量是否在启动时在源和副本上设置,并且 ID 值在每台服务器上都是唯一的。

  • 验证副本是否正在运行。用于 SHOW REPLICA STATUS检查 Replica_IO_Running和 的Replica_SQL_Running值是否都是 Yes. 如果不是,请验证启动副本服务器时使用的选项。例如, --skip-slave-start命令行选项或 MySQL 8.0.24 中的 skip_slave_start系统变量会阻止复制线程启动,直到您发出一条 START REPLICA语句。

  • 如果副本正在运行,请检查它是否建立了与源的连接。使用SHOW PROCESSLIST,找到 I/O(接收方)和 SQL(应用程序)线程并检查它们的State 列以查看它们显示的内容。请参阅 第 17.2.3 节,“复制线程”。如果接收器线程状态Connecting to master为 ,请检查以下内容:

    • 验证复制用户在源上的权限。

    • 检查源的主机名是否正确,以及您是否使用正确的端口连接到源。用于复制的端口与用于客户端网络通信的端口相同(默认为 3306)。对于主机名,确保该名称解析为正确的 IP 地址。

    • 检查配置文件以查看 skip_networking系统变量是否已在源或副本上启用以禁用网络。如果是这样,请评论该设置或将其删除。

    • 如果源有防火墙或 IP 过滤配置,请确保用于 MySQL 的网络端口未被过滤。

    • 检查您是否可以通过使用 pingtraceroute/tracert 到达主机来到达源。

  • 如果副本之前正在运行但已停止,原因通常是某些在源上成功的语句在副本上失败。如果您已经对源进行了适当的快照,并且从未在复制线程之外修改副本上的数据,那么这种情况永远不会发生。如果副本意外停止,这是一个错误,或者您遇到了第 17.5.1 节“复制功能和问题”中描述的已知复制限制之一。如果它是错误,请参阅 第 17.5.5 节,“如何报告复制错误或问题”,以获取有关如何报告它的说明。

  • 如果在源上成功的语句拒绝在副本上运行,如果通过删除副本的数据库并从源复制新快照来执行完整的数据库重新同步不可行,请尝试以下过程:

    1. 确定副本上受影响的表是否与源表不同。试着理解这是怎么发生的。然后使副本表与源表相同并运行 START REPLICA

    2. 如果前面的步骤不起作用或不适用,请尝试了解手动进行更新(如果需要)是否安全,然后忽略来自源的下一条语句。

    3. 如果您决定副本可以跳过源中的下一条语句,请发出以下语句:

      mysql> SET GLOBAL sql_slave_skip_counter = N;
      mysql> START SLAVE;
      
      Or from MySQL 8.0.26:
      mysql> SET GLOBAL sql_replica_skip_counter = N;
      mysql> START REPLICA;

      N如果源中的下一条语句不使用 AUTO_INCREMENTor ,则 的值应为 1 LAST_INSERT_ID()。否则,该值应为 2。对于使用 AUTO_INCREMENTor 的语句使用值 2 的原因LAST_INSERT_ID()是它们在源的二进制日志中获取两个事件。

      另见 SET GLOBAL sql_slave_skip_counter 语句

    4. 如果您确定副本开始时与源完全同步,并且没有人更新复制线程之外涉及的表,那么可能是错误导致的差异。如果您运行的是最新版本的 MySQL,请报告问题。如果您运行的是旧版本,请尝试升级到最新的生产版本以确定问题是否仍然存在。