本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
故障診斷因缺少記錄而導致的複寫失敗
搭配使用 Amazon RDS for MySQL 或 MariaDB 與二進位日誌複寫時,您可能會遇到複寫失敗,其中程序因僅供讀取複本上的記錄遺失而停止。本節說明如何診斷和解決這些問題。
常見原因
來源和複本之間的資料不一致可能是下列其中一個案例所造成:
-
複本上的手動資料修改
-
使用 略過的交易
sql_replica_skip_counter(sql_slave_skip_counter在 MySQL 8.0.26 之前) -
使用遷移工具在初始資料同步期間缺少複本上的資料列
識別問題
此問題的常見指標是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(SHOW SLAVE STATUS\GMySQL 8.0.22 之前) 並檢閱資料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. -
檢查複寫程序在複本執行個體上停止的二進位日誌檔案名稱和位置。您可以在複本執行個體的錯誤日誌中找到此資訊。
分析二進位日誌
若要調查特定交易的複寫失敗,您可以使用 mysqlbinlog899中end_log_pos的位置失敗mysql-bin-changelog.031523,您可以分析此特定位置,以識別失敗的原因。
注意
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 式複寫。
-
在主要執行個體
ROW上使用binlog_format做為 。使用binlog_format作為MIXED,複寫有機會以無提示的方式隱藏不一致。 -
在複本執行個體
1上將read_only設定為 ,以防止意外的資料列修改。 -
在複本執行個體
1上innodb_flush_log_at_trx_commit將 設定為 。 -
在主要執行個體
1上sync_binlog將 設定為 。 -
驗證主要和複本之間的資料表結構描述同位。
-
確保複寫的資料表具有主索引鍵。