このページでは、Cloud SQL リードレプリカのレプリケーション ラグのトラブルシューティングと修正方法について説明します。
概要
Cloud SQL リードレプリカは、グローバル トランザクション識別子(GTID)を使用した MySQL 行ベースのレプリケーションを使用します。変更はプライマリ インスタンスのバイナリログに書き込まれ、レプリカに送信されます。レプリカでは変更を受信し、データベースに適用します。レプリケーション ラグは、次のようないくつかのシナリオで発生する可能性があります。
- プライマリ インスタンスが、レプリカに変更を十分な速さで送信できない。
- レプリカが変更を十分な速さで受信できない。
- レプリカが変更を十分な速さで適用できない。
network_lag 指標を使用して、プライマリ インスタンスが変更を十分な速さで送信できない、あるいはレプリカが変更を十分な速さで受信できない、という最初の 2 つのシナリオをモニタリングします。
合計ラグは、replica_lag 指標で観測されます。replica_lag と network_lag の違いから、レプリカがレプリケーションの変更をすぐに適用できない 3 番目の理由がわかります。これらの指標については、この後のレプリケーション ラグをモニタリングするセクションで説明します。
より高速なレプリカ構成
MySQL レプリカで変更をより高速に適用するには、次の 2 つの方法があります。ユーザーは、次の方法でレプリカを構成できます。
- 並列レプリケーション
- 高パフォーマンスのフラッシュ
並列レプリケーション
レプリカに変更を適用する複数のスレッドを同時に使用するようにレプリカを構成すると、並列レプリケーションがレプリケーション ラグに役立つ場合があります。並列レプリケーションの使用については、並列レプリケーションの構成をご覧ください。
replica_parallel_workers(または slave_parallel_workers)フラグを設定して並列レプリケーションを有効にする場合は、次の点を考慮してください。
replica_parallel_workersフラグの値を、レプリカ インスタンスの vCPU 数と一致する数値に設定することをおすすめします。値を大きくしすぎると、ロック待機、ロック待機タイムアウト、デッドロックが発生する可能性があります。レプリケーションの遅延と一致するロック待機が急増した場合は、並列処理の削減を検討してください。- MySQL のバージョンが
binlog_transaction_dependency_trackingフラグをサポートしている場合は、プライマリ インスタンスでWRITESETに設定することを検討してください。 これは 8.4 以降のデフォルトの動作です。
高パフォーマンスのフラッシュ
デフォルトでは、Cloud SQL for MySQL は耐久性のために各トランザクションの後に REDO ログをディスクにフラッシュします。 高パフォーマンスのフラッシュでは、REDO ログがディスクにフラッシュされる頻度が 1 秒に 1 回ずつ削減されます。これにより、ディスク I/O を削減してレプリカの書き込みパフォーマンスを向上させることができます。
リードレプリカの innodb_flush_log_at_trx_commit フラグを 2 に設定します。レプリカでバイナリ ロギングが有効になっている場合は、innodb_flush_log_at_trx_commit フラグを有効にするために、sync_binlog フラグに大きな値(10,000 など)を設定することをおすすめします。
このフラグの詳細については、フラグの使用に関するヒントをご覧ください。
リードレプリカに innodb_flush_log_at_trx_commit フラグが設定され、Cloud SQL がクラッシュの可能性を検出すると、Cloud SQL は自動的にレプリカを再作成します。
レプリカが適切にプロビジョニングされていることを確認する
プライマリ インスタンスよりも小さいレプリカ インスタンス(vCPU とメモリが少ないなど)では、レプリケーションの遅延が発生する可能性があります。小さいレプリカでは、大きいプライマリ インスタンスとは異なるデフォルトの構成フラグが設定されている場合もあります。レプリケーションの負荷を処理するのに十分なリソースを確保するため、レプリカ インスタンスはプライマリ インスタンスと同じサイズか、それ以上にすることをおすすめします。
レプリカの CPU 使用率が高いと、レプリケーションが遅延する可能性もあります。レプリカの CPU 使用率が高い場合(90% を超えるなど)、レプリカの CPU 容量を増やすことを検討してください。
SHOW VARIABLES コマンドを使用すると、レプリカ インスタンスとプライマリ インスタンスの構成を表示して、違いを比較できます。たとえば、小さいレプリカでは innodb_buffer_pool_size をプライマリと同じ値に構成できません。これはレプリカのパフォーマンスに影響する可能性があります。
クエリとスキーマを最適化する
このセクションでは、レプリケーションのパフォーマンスを改善するためによく実行するクエリとスキーマの最適化について説明します。
リードレプリカのクエリ分離レベル
REPEATABLE READ と SERIALIZABLE のトランザクション分離レベルは、レプリケーションの変更をブロックする可能性のあるロックを取得します。レプリカ内のクエリの分離レベルを下げることを検討してください。READ COMMITTED のトランザクション分離レベルのほうがパフォーマンスが向上する可能性があります。
プライマリ データベースでの長時間実行トランザクション
プライマリ インスタンスで長時間実行されているトランザクションは、レプリケーションの遅延を引き起こす可能性があります。 トランザクションが commit されるまで、バイナリログはレプリカに送信されません。
1 つのトランザクションで多数の行が更新されると、プライマリ インスタンスに適用してからレプリカに送信する必要がある変更の数が急増する可能性があります。これは、多くの行に同時に影響する単一ステートメントの更新または削除が行われると発生します。変更は commit 後にレプリカに送信されます。レプリカの変更が急増し、レプリカのクエリ負荷が高くなると、レプリカのロック競合が発生し、レプリケーション ラグが発生する可能性があります。
大規模なトランザクションを複数の小さなトランザクションに分割することを検討してください。長時間実行トランザクションをモニタリングするには、プライマリの cloudsql.googleapis.com/database/mysql/innodb/active_trx_longest_time 指標を確認します。
主キーの欠如
Cloud SQL リードレプリカは、行ベースのレプリケーションを使用します。そのため、複製される MySQL テーブルに主キーがない場合、パフォーマンスが低下します。レプリケートされたすべてのテーブルに主キーを設定することをおすすめします。
MySQL 8 以降では、データベースのテーブルに主キーが必要となるように sql_require_primary_key フラグを ON に設定することをおすすめします。
リードレプリカでの長時間実行トランザクション
レプリカで長時間実行されるトランザクション(SELECT ステートメントなど)は、レプリケーションをブロックまたは遅延させる可能性があります。一般的な問題としてテーブル スキャンがあります。実行時間の長いクエリを調査し、最適化を検討してください。これらのクエリにより、InnoDB 履歴リストのサイズが増大する可能性があります。
InnoDB の履歴が長すぎる
InnoDB 履歴リストが非常に大きいと、パフォーマンスの問題が発生し、レプリケーションが遅くなる可能性があります。cloudsql.googleapis.com/database/mysql/innodb/history_list_length 指標を使用して、履歴リストの長さをモニタリングできます。
この指標はプライマリでも高くなる可能性があり、すでにパフォーマンスの問題を引き起こしている可能性もあります。初期起動後にレプリカでレプリケーション ラグが大きい兆候が見られる場合は、これが原因である可能性があります。
履歴リストが大きくなる原因としては、次のものがあります。
- 長時間実行トランザクション。長時間実行中のトランザクションまたはアイドル状態のトランザクションは、古い undo ログエントリのパージを妨げます。
- ディスクのパフォーマンスが遅い。パージは I/O 負荷の高いオペレーションです。
REPEATABLE READ分離レベル。履歴リストの増加につながる可能性があります。- パージ構成が不十分。パージ専用のスレッド数を制御する
innodb_purge_threadsパラメータが、ワークロードに対して小さすぎる可能性があります。
この問題に対処するには、次のことをお試しください。
- 大きなトランザクションを小さなトランザクションに分割する。古いログをより迅速に削除できます。
- より大きなインスタンスを使用する。インスタンスが大きいほど、CPU とメモリが多くなります。
- パージの設定を調整する。
innodb_purge_threads、innodb_io_capacity、innodb_io_capacity_maxを増やします。 READ COMMITTED分離レベルを使用する。- テーブルに主キーがあることを確認する。主キーのないテーブルはテーブル スキャンを引き起こし、レプリケーションの速度低下や、履歴リストの増加につながる可能性があります。
ロック待機が多い
レプリカでのロック待機が多いと、レプリケーションが遅くなる可能性があります。特に、並列レプリケーションが有効になっている場合は、その可能性が高くなります。次の指標を使用して、ロックの待機とデッドロックをモニタリングできます。
cloudsql.googleapis.com/database/mysql/innodb/row_lock_waits_countcloudsql.googleapis.com/database/mysql/innodb/row_lock_timecloudsql.googleapis.com/database/mysql/innodb/lock_timeout_countcloudsql.googleapis.com/database/mysql/innodb/deadlocks_count
これらのロック指標が高すぎて、レプリケーションの遅延と関係していると思われる場合は、replica_parallel_workers フラグの値を減らすことを検討してください。
分離レベルもロックに影響する可能性があります。
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 を使用すると、ラグが発生した過去の発生期間を確認できます。
遅延レプリカを再作成する
レプリケーションが許容可能な時間内に完了しなかった場合は、遅延レプリカを再作成します。
Cloud SQL では、許容できる時間を超えてレプリケーションにラグがある(または遅延している)場合、その遅延が 5 分以上続く場合に、リードレプリカを再作成するように構成できます。
許容できるレプリケーション遅延を 360 秒未満(6 分)と定義しており、361 秒以上のレプリケーション遅延が 5 分間以上続く場合、プライマリ インスタンスの新しいスナップショットが作成され、このスナップショットを使用してリードレプリカが再作成されます。
遅延リードレプリカを再作成することで、次のメリットがあります。
- レプリケーション遅延の許容範囲を制御します。
- レプリケーション遅延のトラブルシューティングに費やす時間を数時間、場合によっては数日間短縮できます。
次の特性が追加で適用されます。
- 次のバージョンと互換性があります。
- MySQL 5.7
- MySQL 8.0
- MySQL 8.4
- レプリケーション ラグまたは遅延の許容範囲は秒単位で定義する必要があります。
- 最小許容値は 300 秒(5 分)です。
- 最大許容値は 31,536,000 秒(1 年)です。
- インスタンスで遅延レプリカの再作成を有効にするが、許容できるレプリケーション遅延の最大値を設定しない場合、Cloud SQL ではデフォルト値の 1 年が設定されます。
- サポートされているインスタンスのタイプ:
- リードレプリカ
- クロスリージョン リードレプリカ
- カスケード レプリカ
replicationLagMaxSecondsフィールドに設定する値は、各レプリカ インスタンスに固有です。プライマリ インスタンスに複数のレプリカ インスタンスがある場合は、各レプリカに異なる値を設定できます。- レプリカが再作成されると、次のオペレーションが完了するまで、ダウンタイムが発生する可能性があります。
- レプリケーションが停止している。
- レプリカが削除されます。
- プライマリ インスタンスのスナップショットが作成されます。
- レプリカは、この最新のスナップショットから再作成されます。新しいレプリカは、以前のレプリカと同じ名前と IP アドレスを使用します。そのため、MySQL を停止して再起動する必要があります。
- 新しいレプリカがデータのレプリケーションを開始します。
replicationLagMaxSecondsはインスタンス レベルのフィールドです。各インスタンスには独自の値があります。同じプライマリ インスタンスに複数のリードレプリカがある場合は、各レプリカの
replicationLagMaxSecondsフィールドに一意の値を設定できます。レプリカごとに異なる時間しきい値を定義すると、すべてのレプリカが同時に停止するシナリオを回避できます。
遅延レプリカの再作成を有効にする
遅延レプリカの再作成機能は、デフォルトでは無効になっています。インスタンスの作成時に有効にするには、次のいずれかの方法を使用します。
gcloud
gcloud sql instances create コマンドで、
--replication-lag-max-seconds-for-recreate フラグを使用して新しいリードレプリカ インスタンスを作成します。
gcloud beta sql instances create REPLICA_INSTANCE_NAME \ --master-instance-name=PRIMARY_INSTANCE_NAME \ --database-version=DATABASE_VERSION \ --tier=TIER \ --edition=EDITION \ --region=REGION \ --root-password=PASSWORD \ --replication-lag-max-seconds-for-recreate=REPLICATION_LAG_MAX_SECONDS
ここで
REPLICA_INSTANCE_NAMEはレプリカ インスタンスの名前です。PRIMARY_INSTANCE_NAMEはプライマリ インスタンスの名前です。DATABASE_VERSION: インスタンスのデータベース バージョン。たとえば、MYSQL_8_0_31です。TIERは、レプリカ インスタンスに使用するマシンタイプです。たとえば、db-perf-optimized-N-4です。詳細については、カスタム インスタンス構成をご覧ください。EDITIONは、レプリカ インスタンスに使用するエディションです。たとえば、ENTERPRISE_PLUSです。詳細については、インスタンスの作成をご覧ください。REGIONは、レプリカ インスタンスに使用するリージョンです。たとえば、us-central1です。PASSWORDは、インスタンスの root パスワードです。REPLICATION_LAG_MAX_SECONDSは、許容できる最大レプリケーション ラグまたは遅延(秒単位)です。たとえば、600です。最小許容値は 300 秒(5 分)です。最大許容値は 31,536,000 秒(1 年)です。
REST API
replicationLagMaxSeconds フィールドは DatabaseInstance リソースにあります。リクエスト本文に次のフィールドを追加します。
{ "settings": { "replicationLagMaxSeconds" :REPLICATION_LAG_MAX_SECONDS, } ... }
ここで
REPLICATION_LAG_MAX_SECONDSは、許容できる最大レプリケーション ラグまたは遅延(秒単位)です。たとえば、600です。
レプリケーション ラグの再作成時間を更新する
インスタンスの設定を表示するには、インスタンスの概要情報を表示するで説明されているいずれかの方法に従って操作してください。
この情報に基づいて、レプリカの再作成前に許容可能として指定したレプリケーション ラグ時間枠を更新するかどうかを選択できます。
gcloud
gcloud sql instances patch コマンドを使用して、レプリケーション ラグに基づいてインスタンスの再作成の期間を更新します。
gcloud beta sql instances patch INSTANCE_NAME \ --replication-lag-max-seconds-for-recreate=REPLICATION_LAG_MAX_SECONDS
ここで
INSTANCE_NAMEはインスタンスの名前です。REPLICATION_LAG_MAX_SECONDSは、許容できる最大レプリケーション ラグまたは遅延(秒単位)です。たとえば、700です。デフォルト値の 1 年にリセットする場合は、31536000を入力します。最小許容値は 300 秒(5 分)です。最大許容値は 31,536,000 秒(1 年)です。
REST API
ポリシーは、instances.patch と instance.insert を使用して更新できます。
REST API を使用して設定を更新する方法の例については、インスタンスを編集するをご覧ください。
制限事項
遅延レプリカの再作成には、次の制限が適用されます。
replicationLagMaxSecondsの値は秒単位でのみ設定できます。- 再作成オペレーションの前にリードレプリカに作成されたインデックスは保持されません。インデックスが存在する場合は、レプリカの再作成後にセカンダリ インデックスを作成します。
- リードレプリカの頻繁な停止を回避するため、再作成はインスタンスごとに 1 日 1 回に制限されています。
- この機能では、外部サーバーのレプリカはサポートされていません。
- カスケード レプリカで遅延レプリカの再作成を有効にすると、レプリケーションの整合性を維持するために、Cloud SQL はまずリーフレプリカを再作成します。
- クロスリージョン レプリカを再作成すると、追加の費用が発生します。
- Google Cloud コンソールで、遅延レプリカの再作成を有効にすることはできません。