View a markdown version of this page

对因缺少记录而导致的复制失败进行故障排除 - Amazon Relational Database Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

对因缺少记录而导致的复制失败进行故障排除

使用带二进制日志复制功能的 Amazon RDS for MySQL 或 MariaDB 时,您可能会遇到由于只读副本上缺少记录导致进程停止的复制故障。此部分介绍如何诊断和解决此问题。

常见原因

源和副本之间的数据不一致可能是由于下列情况之一所导致:

  • 在副本上手动修改数据

  • 使用 sql_replica_skip_counter(在 MySQL 8.0.26 之前为 sql_slave_skip_counter)跳过了事务

  • 使用迁移工具进行初始数据同步期间,副本上缺少行

识别问题

此问题的一个常见指标是 Error 1032(附带消息 Can't find record)。副本的错误日志中显示以下错误消息:

2025-11-04T21:24:11.038899Z 566 [ERROR] [MY-010584] [Repl] Replica SQL for channel '': Worker 1 failed executing transaction 'ANONYMOUS' at source log mysql-bin-changelog.031523, end_log_pos 899; Could not execute Update_rows event on table test_replication.users; Can't find record in 'users', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's source log mysql-bin-changelog.031523, end_log_pos 899, Error_code: MY-001032
注意

MySQL 和 MariaDB 引擎的错误日志格式各不相同。有关如何检索日志的信息,请参阅查看和列出数据库日志文件

诊断问题

要诊断复制失败,请执行以下操作:

  • 查看副本错误日志,确定复制停止的位置。您可以使用 MY-010584 作为搜索关键字。

  • 在副本上运行 SHOW REPLICA STATUS\G(在 MySQL 8.0.22 之前为 SHOW SLAVE STATUS\G),然后查看 Last_Error 列:

    Last_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction 'ANONYMOUS' at source log mysql-bin-changelog.031523, end_log_pos 899. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.
  • 检查二进制日志文件名以及复制进程在副本实例上停止的位置。您可以在副本实例的错误日志中找到此信息。

分析二进制日志

要调查特定事务的复制失败,您可以使用 mysqlbinlog 实用程序检查二进制日志文件。例如,如果在二进制日志文件 mysql-bin-changelog.031523 中,复制在 end_log_pos 位置 899 失败,您可以分析这个特定位置以确定失败的原因。

注意

end_log_pos 值表示失败事件的结束位置。在解码后的二进制日志输出中,查找哪个事件的 end_log_pos 与该值匹配。

使用 mysqlbinlog 实用程序下载并检查相关的二进制日志。为主实例使用端点。

$ mysqlbinlog --read-from-remote-server \ --host=<rds-endpoint> \ --port=3306 \ --user=<username> \ --password=<password> \ --base64-output=DECODE-ROWS -vv \ mysql-bin-changelog.031523 > decoded-binlog-file-name
注意

mysqlbinlog 实用程序是一款原生 MySQL 工具,可帮助您读取和解释二进制日志内容。有关访问 Amazon RDS 上的二进制日志的更多信息,请参阅访问 MySQL 二进制日志

在写入器实例的二进制日志中,显示出写入器实例尝试更新 test_replication.users 表中 id=1 的记录:

#251104 21:13:13 server id 680788197 end_log_pos 899 CRC32 0x89b1e255 Update_rows: table id 101 flags: STMT_END_F ### UPDATE `test_replication`.`users` ### WHERE ### @1=1 /* INT meta=0 nullable=0 is_null=0 */ ### @2='Test User' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */ ### @3='updated4@example.com' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */ ### @4=1762288260 /* TIMESTAMP(0) meta=0 nullable=1 is_null=0 */ ### SET ### @1=1 /* INT meta=0 nullable=0 is_null=0 */ ### @2='Test User' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */ ### @3='updated5@example.com' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */ ### @4=1762288260 /* TIMESTAMP(0) meta=0 nullable=1 is_null=0 */ # at 899

副本的错误日志显示副本无法执行 UPDATE 语句,因为目标记录不存在:

Can't find record in 'users', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND

要验证该行是否缺失,请检查副本上是否存在该特定行:

SELECT 1 FROM test_replication.users WHERE id=1; Empty set (0.00 sec)

此输出确认源数据库实例的 UPDATE 操作复制失败,因为副本上不存在目标行。

避免复制失败

我们建议采用以下最佳实践来避免复制不一致的情况:

  • 使用基于 GTID 的复制。有关更多信息,请参阅 使用基于 GTID 的复制

  • 在主实例上使用 binlog_format 作为 ROW。使用 binlog_format 作为 MIXED,复制就有可能隐藏不一致之处而不提示。

  • 在副本实例上将 read_only 配置为 1 可防止意外修改行。

  • 在副本实例上将 innodb_flush_log_at_trx_commit 设置为 1

  • 在主实例上将 sync_binlog 设置为 1

  • 验证主实例与副本之间的表架构奇偶校验。

  • 确保复制的表具有主键。