レプリカ遅延を確認するときは、SHOW REPLICA STATUSのSeconds_をよく見ます。ただし、この値だけでは遅延の原因まではわかりません。大きなトランザクションを適用しているのか、workerが足りないのか、依存関係やcommit順序を待っているのかは、別に調べる必要があります。
Replication Applier MetricsはMySQL 9.
Replication Applier Metricsについて
Replication Applier MetricsはWL#15620でMySQL 9.
WL#15620によると、従来のMTA統計はエラーログへ最大120秒程度の間隔で出力されていました。エラーログの情報はSQLで取得しにくく、時系列での監視にも使いにくいものでした。Replication Applier Metricsでは、これらの情報をPerformance Schemaから取得できます。
従来の確認方法
SHOW REPLICA STATUSでは、接続状態、GTID、relay logの位置、エラーなどを確認できます。Seconds_では遅延時間も確認できます。ただし、どこで待っているかまではわかりません。また、applierを停止するとSeconds_はNULLになります。
既存のreplication_テーブルでは、workerのthread ID、GTID、retry、errorなどを確認できます。Replication Applier Metricsでは、これに加えて未処理トランザクションの件数とサイズ、coordinatorの待機理由、workerの適用状況を確認できます。
2つのPerformance Schemaテーブル
利用するには、次のSQLでコンポーネントをインストールします。インストール後は対象channelを開始し直します。
INSTALL COMPONENT 'file://component_replication_applier_metrics';
追加されるのは次のテーブルです。
replication_:channel単位の累積値applier_ metrics replication_:worker単位の現在値applier_ progress_ by_ worker
replication_applier_metrics のカラム
このテーブルはchannelごとに1行を返します。時間の単位はナノ秒です。COUNTとSUM_は累積値です。
| カラム | 意味 |
|---|---|
CHANNEL_ |
replication channel名。デフォルトchannelは空文字列 |
TOTAL_ |
applier稼働時間の累計 |
LAST_ |
applierの最終開始日時 |
TRANSACTIONS_ |
applierがcommitまで完了したトランザクション数 |
TRANSACTIONS_ |
workerが現在処理しているトランザクション数 |
TRANSACTIONS_ |
receiverが受信済みで未commitのトランザクション数。処理中のものを含む値 |
TRANSACTIONS_ |
commit済みトランザクションの合計サイズ |
TRANSACTIONS_ |
現在処理中のトランザクションの総サイズ。複数worker分の合計 |
TRANSACTIONS_ |
処理中トランザクションで適用済みのサイズ。複数worker分の合計 |
TRANSACTIONS_ |
受信済みで未commitのトランザクションの合計サイズ。算出できない場合はNULL |
EVENTS_ |
commit済みトランザクションに含まれるbinlog event数 |
WAITS_ |
relay logへの次の仕事をapplierが待った回数 |
WAITS_ |
上記待機時間の累計 |
WAITS_ |
coordinatorが空きworkerを待った回数 |
WAITS_ |
上記待機時間の累計 |
WAITS_ |
先行トランザクションとのschedule dependency解消を待った回数 |
WAITS_ |
上記待機時間の累計 |
WAITS_ |
worker queue全体がreplica_のメモリ上限内に収まるのを待った回数 |
WAITS_ |
上記待機時間の累計 |
WAITS_ |
worker queueの空きを待った回数 |
WAITS_ |
上記待機時間の累計 |
WAITS_ |
workerが先行トランザクションのcommitを待った回数 |
WAITS_ |
上記待機時間の累計 |
TIME_ |
coordinatorによるrelay log読取り時間の累計 |
replication_applier_progress_by_worker のカラム
こちらはworkerごとの現在値です。9.ONGOING_がUNASSIGNED、サイズが0になります。
| カラム | 意味 |
|---|---|
CHANNEL_ |
workerが所属するreplication channel名 |
WORKER_ |
channel内のworker番号 |
THREAD_ |
対応するPerformance Schema thread ID。threadsやlock系テーブルとの結合キー |
ONGOING_ |
処理中トランザクションの種別。DML、DDL、未割当てのUNASSIGNED |
ONGOING_ |
workerが処理中のトランザクションの総サイズ |
ONGOING_ |
workerが適用済みのサイズ |
ONGOING_が増えていないworkerがあれば、THREAD_を使ってperformance_やlock系テーブルを確認します。
2つのworkerで待ちを発生させる
検証にはMySQL 9.replica_、replica_にしました。replica側でテーブルをロックしたまま、sourceから3つのトランザクションを実行します。
LOCK TABLES lab.article_slow WRITE;
INSERT INTO lab.article_slow VALUES (2, 'blocked first transaction');
INSERT INTO lab.article_fast_a VALUES (2, 'applied but cannot commit first');
INSERT INTO lab.article_fast_b VALUES (2, 'waits for a free worker');
ロックしている間に、channel単位の情報を取得します。
SELECT *
FROM performance_schema.replication_applier_metrics\G
*************************** 1. row ***************************
CHANNEL_NAME:
TOTAL_ACTIVE_TIME_DURATION: 144676734327
LAST_APPLIER_START: 2026-07-15 00:08:54
TRANSACTIONS_COMMITTED_COUNT: 8
TRANSACTIONS_ONGOING_COUNT: 2
TRANSACTIONS_PENDING_COUNT: 3
TRANSACTIONS_COMMITTED_SIZE_BYTES_SUM: 2241
TRANSACTIONS_ONGOING_FULL_SIZE_BYTES_SUM: 634
TRANSACTIONS_ONGOING_PROGRESS_SIZE_BYTES_SUM: 505
TRANSACTIONS_PENDING_SIZE_BYTES_SUM: NULL
EVENTS_COMMITTED_COUNT: 28
WAITS_FOR_WORK_FROM_SOURCE_COUNT: 15
WAITS_FOR_WORK_FROM_SOURCE_SUM_TIME: 113511377054
WAITS_FOR_AVAILABLE_WORKER_COUNT: 2
WAITS_FOR_AVAILABLE_WORKER_SUM_TIME: 31124522291
WAITS_COMMIT_SCHEDULE_DEPENDENCY_COUNT: 2
WAITS_COMMIT_SCHEDULE_DEPENDENCY_SUM_TIME: 35017
WAITS_FOR_WORKER_QUEUE_MEMORY_COUNT: 0
WAITS_FOR_WORKER_QUEUE_MEMORY_SUM_TIME: 0
WAITS_WORKER_QUEUES_FULL_COUNT: 0
WAITS_WORKER_QUEUES_FULL_SUM_TIME: 0
WAITS_DUE_TO_COMMIT_ORDER_COUNT: 2
WAITS_DUE_TO_COMMIT_ORDER_SUM_TIME: 31125210259
TIME_TO_READ_FROM_RELAY_LOG_SUM_TIME: 148113
次にworker単位の情報を確認します。
SELECT *
FROM performance_schema.replication_applier_progress_by_worker\G
*************************** 1. row ***************************
CHANNEL_NAME:
WORKER_ID: 0
THREAD_ID: 50
ONGOING_TRANSACTION_TYPE: DML
ONGOING_TRANSACTION_FULL_SIZE_BYTES: 313
ONGOING_TRANSACTION_APPLIED_SIZE_BYTES: 215
*************************** 2. row ***************************
CHANNEL_NAME:
WORKER_ID: 1
THREAD_ID: 51
ONGOING_TRANSACTION_TYPE: DML
ONGOING_TRANSACTION_FULL_SIZE_BYTES: 321
ONGOING_TRANSACTION_APPLIED_SIZE_BYTES: 290
THREAD_を使ってperformance_も確認します。
SELECT p.WORKER_ID, p.THREAD_ID, t.PROCESSLIST_STATE
FROM performance_schema.replication_applier_progress_by_worker AS p
LEFT JOIN performance_schema.threads AS t
ON t.THREAD_ID = p.THREAD_ID
ORDER BY p.WORKER_ID\G
*************************** 1. row ***************************
WORKER_ID: 0
THREAD_ID: 50
PROCESSLIST_STATE: Waiting for table metadata lock
*************************** 2. row ***************************
WORKER_ID: 1
THREAD_ID: 51
PROCESSLIST_STATE: Waiting for preceding transaction to commit
worker 0はmetadata lockを待っています。worker 1は適用をほぼ終えていますが、先行トランザクションのcommitを待っています。2つのworkerが両方とも待っているため、coordinatorは3つ目のトランザクションをworkerへ渡せません。この例では、ロック待ち、commit順序待ち、空きworker待ちが発生していることを確認できました。
Apply待ちを直接表すカラムはありません。workerの進捗が増えていなければ、thread IDからstatement、stage、lockを確認します。
他の処理でも確認する
3,000行、約3MBのINSERTをreplicaのtable lockで止めました。workerにはDML、総サイズ3,034,363bytes、適用済み207bytesと表示されました。3,000行のUPDATEでは、総サイズ6,069,247bytes、適用済み216bytesでした。大きなトランザクションを処理していることと、ほとんど進んでいないことがわかります。
ALTER TABLEをmetadata lockで止めた場合はDDL、総サイズ218bytes、適用済み77bytesとなりました。threadの状態はWaiting for table metadata lockでした。また、applierを停止して10トランザクションを受信させると、Seconds_はNULLですが、TRANSACTIONS_は10になりました。
sourceでcommitしていないトランザクションは、replica側のcommitted、ongoing、pendingには表示されませんでした。まだbinlogへ書き込まれていないためです。この場合はsource側を確認します。
監視するときの見方
値は累積値なので、監視では前回の取得結果との差分を見ます。pendingが増えている場合は、空きworker、schedule dependency、queue、commit順序のどの待ちが増えたかを確認します。その後、workerの進捗とthreadのlockを確認します。
1回のSELECTで取得した各カラムは、完全に同じ時点の値ではありません。取得中にも適用処理が進むためです。また、収集開始前からrelay logにあったトランザクションは、pending bytesがNULLになる場合があります。SHOW REPLICA STATUSや既存のreplication表と組み合わせて確認します。
まとめ
Replication Applier MetricsがMySQL 9.Seconds_だけではわからなかった待機理由やworkerの進捗を確認できます。SHOW REPLICA STATUSやreplication_と組み合わせることでレプリカ遅延のより詳細な調査が可能となりました。