このページでは、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
を使用すると、ラグが発生した過去の発生期間を確認できます。
遅延レプリカを再作成する
レプリケーションが許容可能な時間内に完了しなかった場合は、遅延レプリカを再作成します。
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 コンソールで、遅延レプリカの再作成を有効にすることはできません。