このページでは、Cloud SQL リードレプリカのレプリケーション ラグのトラブルシューティングと修正方法について説明します。
概要
Cloud SQL リードレプリカは、グローバル トランザクション識別子(GTID)を使用した MySQL 行ベースのレプリケーションを使用します。変更はプライマリ インスタンスのバイナリログに書き込まれ、レプリカに送信されます。レプリカでは変更を受信し、データベースに適用します。レプリケーション ラグは、次のようないくつかのシナリオで発生する可能性があります。
- プライマリ インスタンスが、レプリカに変更を十分な速さで送信できない。
- レプリカが変更を十分な速さで受信できない。
- レプリカが変更を十分な速さで適用できない。
network_lag
指標を使用して、プライマリ インスタンスが変更を十分な速さで送信できない、あるいはレプリカが変更を十分な速さで受信できない、という最初の 2 つのシナリオをモニタリングします。
合計ラグは、replica_lag
指標で観測されます。replica_lag
と network_lag
の違いから、レプリカがレプリケーションの変更をすぐに適用できない 3 番目の理由がわかります。これらの指標については、この後のレプリケーション ラグをモニタリングするセクションで説明します。
より高速なレプリカ構成
MySQL レプリカで変更をより高速に適用するには、次の 2 つの方法があります。ユーザーは、次の方法でレプリカを構成できます。
- 並列レプリケーション
- 高パフォーマンスのフラッシュ
並列レプリケーション
レプリカに変更を適用する複数のスレッドを同時に使用するようにレプリカを構成すると、並列レプリケーションがレプリケーション ラグに役立つ場合があります。並列レプリケーションの使用については、並列レプリケーションの構成をご覧ください。
高パフォーマンスのフラッシュ
デフォルトでは、Cloud SQL for MySQL は各トランザクションの後に REDO ログをディスクにフラッシュします。高パフォーマンスのフラッシュでは、REDO ログがディスクにフラッシュされる頻度が 1 秒に 1 回ずつ削減されるため、書き込みのパフォーマンスが向上します。
リードレプリカの innodb_flush_log_at_trx_commit
フラグを 2 に設定します。また、innodb_flush_log_at_trx_commit
フラグを有効にするには、sync_binlog
フラグに高い値を設定する必要があります。
このフラグの詳細については、フラグの使用に関するヒントをご覧ください。
リードレプリカに innodb_flush_log_at_trx_commit フラグが設定され、Cloud SQL がクラッシュの可能性を検出すると、Cloud SQL は自動的にレプリカを再作成します。
クエリとスキーマを最適化する
このセクションでは、レプリケーションのパフォーマンスを改善するためによく実行するクエリとスキーマの最適化について説明します。
リードレプリカのクエリ分離レベル
REPEATABLE READ
と SERIALIZABLE
のトランザクション分離レベルは、レプリケーションの変更をブロックする可能性のあるロックを取得します。レプリカ内のクエリの分離レベルを下げることを検討してください。READ COMMITTED
のトランザクション分離レベルのほうがパフォーマンスが向上する可能性があります。
プライマリ データベースでの長時間実行トランザクション
1 つのトランザクションで多数の行が更新されると、プライマリ インスタンスに適用してからレプリカに送信する必要がある変更の数が急増する可能性があります。これは、多くの行に同時に影響する単一ステートメントの更新または削除が行われると発生します。変更は commit 後にレプリカに送信されます。レプリカの変更が急増し、レプリカのクエリ負荷が高くなると、レプリカのロック競合が発生し、レプリケーション ラグが発生する可能性があります。
大きなトランザクションを複数の小さなトランザクションに分割することを検討してください。
主キーの欠如
Cloud SQL リードレプリカは、行ベースのレプリケーションを使用します。そのため、複製される MySQL テーブルに主キーがない場合、パフォーマンスが低下します。レプリケートされたすべてのテーブルに主キーを設定することをおすすめします。
MySQL 8 以降では、データベースのテーブルに主キーが必要となるように sql_require_primary_key
フラグを ON
に設定することをおすすめします。
DDL による排他ロック
データ定義言語(DDL)コマンド(ALTER TABLE
や CREATE INDEX
など)では、排他的ロックによってレプリカでレプリケーション ラグが発生することがあります。ロックの競合を回避するには、レプリカでクエリの負荷が低いときに DDL の実行をスケジュールすることを検討してください。
レプリカの過負荷
リードレプリカが受信するクエリが多すぎると、レプリケーションがブロックされることがあります。読み取りを複数のレプリカに分割して、各レプリカの負荷を減らすことを検討してください。
クエリの急増を回避するには、アプリケーション ロジックまたはプロキシレイヤ(1 つ使用している場合)でレプリカの読み取りクエリを抑制することを検討してください。
プライマリ インスタンスでアクティビティが急増した場合は、更新を分散させることを検討してください。
モノリシックなプライマリ データベース
プライマリ データベースを垂直方向(または水平方向)に分割して、1 つ以上のラグテーブルが他のすべてのテーブルを抑制しないようにすることを検討してください。
レプリケーション ラグをモニタリングする
replica_lag
指標と network_lag
指標を使用してレプリケーション ラグをモニタリングし、ラグの原因がプライマリ データベース、ネットワーク、レプリカのどれにあるのかを識別できます。
指標 | 説明 |
---|---|
レプリケーション ラグ ( cloudsql.googleapis.com ) |
レプリカの状態がプライマリ インスタンスの状態よりも遅れている秒数。これは、現在の時刻と、現在レプリカに適用されているトランザクションをプライマリ データベースが commit した時点のタイムスタンプとの差です。特に、レプリカが書き込みを受信していても、レプリカがデータベースへの書き込みをまだ適用していない場合、書き込みは遅延として記録される可能性があります。 この指標は、レプリカで |
最後の I/O スレッドエラー番号 ( cloudsql.googleapis.com ) |
I/O スレッドが失敗する原因となった最後のエラーを示します。この値がゼロでない場合は、レプリケーションが中断します。このケースはまれですが、発生する可能性はあります。エラーコードが示す内容を理解するには、MySQL のドキュメントをご覧ください。たとえば、プライマリ インスタンスの binlog ファイルが、レプリカが受信する前に削除されている可能性があります。通常、Cloud SQL は、レプリケーションが壊れた場合、レプリカを自動的に再作成します。この |
最後の SQL スレッドのエラー番号 ( cloudsql.googleapis.com ) |
SQL スレッドが失敗する原因となった最後のエラーを示します。この値がゼロでない場合は、レプリケーションが中断します。このケースはまれですが、発生する可能性はあります。エラーコードが示す内容を理解するには、MySQL のドキュメントをご覧ください。レプリケーションが中断した場合、Cloud SQL は通常、自動的にレプリカを再作成します。この |
ネットワーク ラグ ( cloudsql.googleapis.com ) |
プライマリ データベースのバイナリログに書き込んでから、レプリカの I/O スレッドに到達するまでにかかる時間(秒)。
|
レプリケーションを検証する
レプリケーションが機能していることを確認するには、レプリカに対して次のステートメントを実行します。
mysql> SHOW SLAVE STATUS\G;
*************************** 1. row ***************************
Slave_IO_State: Queueing master event to the relay log
Master_Host: xx.xxx.xxx.xxx
Master_User: cloudsqlreplica
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.199927
Read_Master_Log_Pos: 83711956
Relay_Log_File: relay-log.000025
Relay_Log_Pos: 24214376
Relay_Master_Log_File: mysql-bin.199898
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 24214163
Relay_Log_Space: 3128686571
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: Yes
Master_SSL_CA_File: master_server_ca.pem
Master_SSL_CA_Path: /mysql/datadir
Master_SSL_Cert: replica_cert.pem
Master_SSL_Cipher:
Master_SSL_Key: replica_pkey.pem
Seconds_Behind_Master: 2627
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 321071839
Master_UUID: 437d04e9-8456-11e8-b13d-42010a80027b
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: System lock
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: 437d04e9-8456-11e8-b13d-42010a80027b:52111095710-52120776390
Executed_Gtid_Set: 437d04e9-8456-11e8-b13d-42010a80027b:1-52113039508
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
レプリケーションが行われている場合は、Slave_IO_State
(最初の列)に Waiting
for master to send event
または類似のメッセージが表示されます。また、Last_IO_Error
フィールドは空です。
レプリケーションが行われていない場合、Slave_IO_State
列にステータス Connecting to master
が表示され、Last_IO_Error
列にはステータス error connecting to master cloudsqlreplica@x.x.x.x:3306
が表示されます。
MySQL のドキュメントによると、レプリケーション ラグに関連するその他の興味深いフィールドは次のとおりです。
フィールド | 説明 |
---|---|
Master_Log_File |
I/O スレッドが現在読み取るソース バイナリ ログファイルの名前。 |
Read_Master_Log_Pos |
I/O スレッドが読み取った現在のソース バイナリ ログファイル内の位置。 |
Relay_Log_File |
SQL スレッドが現在読み込んで実行しているリレーログ ファイルの名前。 |
Relay_Log_Pos |
SQL スレッドが読み取って実行した現在のリレーログ ファイル内の位置。 |
Relay_Master_Log_File |
SQL スレッドによって実行された最新のイベントを含むソース バイナリログ ファイルの名前。 |
上の例では、Relay_Master_Log_File
の値は mysql-bin.199898
です。Master_Log_File
の値は mysql-bin.199927
です。数値のサフィックス 199898 は 199927 未満です。これは、レプリカが新しい mysql-bin.199927
ログファイルを受信しましたが、まだ古い mysql-bin.199898
を適用していることを意味します。
この場合、レプリカで SQL スレッドのラグが発生します。
プライマリ データベースに接続して実行することもできます。
SHOW MASTER STATUS;
このコマンドは、プライマリ データベースに書き込まれているバイナリログ ファイルを表示します。
プライマリ データベースのバイナリログ ファイルがレプリカの Master_Log_File
より新しい場合は、I/O スレッドが遅れていることを意味します。レプリカはまだプライマリ データベースから古いバイナリログ ファイルを読み取っています。
I/O スレッドが遅延している場合、network_lag
指標も高くなります。SQL スレッドは遅延しているが、I/O スレッドは遅延していない場合、network_lag
指標はそれほど大きくありませんが、replica_lag
は高くなります。
前述のコマンドでは、ラグの発生中にラグの詳細を確認できますが、指標 network_lag
と replica_lag
を使用すると、ラグが発生した過去の発生期間を確認できます。