

# 对因缺少记录而导致的复制失败进行故障排除
<a name="USER_ReadRepl.Troubleshooting.MissingRecords"></a>

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

## 常见原因
<a name="USER_ReadRepl.Troubleshooting.MissingRecords.Causes"></a>

源和副本之间的数据不一致可能是由于下列情况之一所导致：
+ 在副本上手动修改数据
+ 使用 `sql_replica_skip_counter`（在 MySQL 8.0.26 之前为 `sql_slave_skip_counter`）跳过了事务
+ 使用迁移工具进行初始数据同步期间，副本上缺少行

## 识别问题
<a name="USER_ReadRepl.Troubleshooting.MissingRecords.Identifying"></a>

此问题的一个常见指标是 `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 引擎的错误日志格式各不相同。有关如何检索日志的信息，请参阅[查看和列出数据库日志文件](USER_LogAccess.Procedural.Viewing.md)。

## 诊断问题
<a name="USER_ReadRepl.Troubleshooting.MissingRecords.Diagnosing"></a>

要诊断复制失败，请执行以下操作：
+ 查看副本错误日志，确定复制停止的位置。您可以使用 `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.
  ```
+ 检查二进制日志文件名以及复制进程在副本实例上停止的位置。您可以在副本实例的错误日志中找到此信息。

## 分析二进制日志
<a name="USER_ReadRepl.Troubleshooting.MissingRecords.BinlogAnalysis"></a>

要调查特定事务的复制失败，您可以使用 [https://dev.mysql.com/doc/refman/en/mysqlbinlog.html](https://dev.mysql.com/doc/refman/en/mysqlbinlog.html) 实用程序检查二进制日志文件。例如，如果在二进制日志文件 `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 二进制日志](USER_LogAccess.MySQL.Binarylog.md)。

在写入器实例的二进制日志中，显示出写入器实例尝试更新 `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` 操作复制失败，因为副本上不存在目标行。

## 避免复制失败
<a name="USER_ReadRepl.Troubleshooting.MissingRecords.Prevention"></a>

我们建议采用以下最佳实践来避免复制不一致的情况：
+ 使用基于 GTID 的复制。有关更多信息，请参阅 [使用基于 GTID 的复制](mysql-replication-gtid.md)。
+ 在主实例上使用 `binlog_format` 作为 `ROW`。使用 `binlog_format` 作为 `MIXED`，复制就有可能隐藏不一致之处而不提示。
+ 在副本实例上将 `read_only` 配置为 `1` 可防止意外修改行。
+ 在副本实例上将 `innodb_flush_log_at_trx_commit` 设置为 `1`。
+ 在主实例上将 `sync_binlog` 设置为 `1`。
+ 验证主实例与副本之间的表架构奇偶校验。
+ 确保复制的表具有主键。