DBAtlas · データベース運用アトラス

壊れたレプリカを修復: 1062 / 1032の行の競合

MySQLレプリケーション

コマンド

-- 1) Failing worker, error and GTID
SELECT WORKER_ID, LAST_ERROR_NUMBER, LEFT(LAST_ERROR_MESSAGE, 250) AS last_error, APPLYING_TRANSACTION
FROM performance_schema.replication_applier_status_by_worker
WHERE LAST_ERROR_NUMBER <> 0;

-- 2) Shell: decode the row images of that transaction from the relay log
mysqlbinlog --base64-output=DECODE-ROWS -vv --include-gtids='af6bc361-c353-11f1-8f12-f69e63ad6c0e:11' /var/lib/mysql/db2-relay-bin.0* | grep '^###'

-- 3a) 1062 Duplicate entry: delete the extra row on the replica without binlogging
SET SESSION sql_log_bin = 0;
DELETE FROM shop.orders WHERE id = 20001;
-- 3b) 1032 Can't find record: insert the missing row from the WHERE (before image) values
INSERT INTO shop.orders (id, cust, amount, note, created) VALUES (6, 6, 9.00, 'n6', '2026-10-08 20:09:44');
SET SESSION sql_log_bin = 1;

-- 4) Start the applier and verify
START REPLICA SQL_THREAD;
SELECT SERVICE_STATE, LAST_ERROR_NUMBER FROM performance_schema.replication_applier_status_by_coordinator;

概要

行ベースレプリケーションで最もよくある2つの停止(1062 重複キー、1032 行が見つからない)を、トランザクションをスキップせず、レプリカの行をソースが期待する状態にすることで修正する。データの整合性は保たれる。

使用する場面

Replica_SQL_Running = Noでエラー1062 / 1032のときに。空のトランザクションでGTIDをスキップする代わりの適切な修復として。

注意

レプリカでの修正はsql_log_bin=0で実行する必要がある。そうしないと誤ったGTID(errant GTID)が作成され、フェイルオーバー時に問題になる。super_read_only=ONの場合は一時的に無効にし、その後再度有効にする。変更前イメージの値はbinlog_row_image=FULLを前提としている。MINIMALではPKのみが記録されるため、行の残りはソースから読み取る必要がある。表で1つの競合があれば通常は他にもある。修復後はpt-table-checksumで表をソースと比較する。リレーログのパス: SELECT @@relay_log_basename;

DBAtlas で開く →

関連項目