MySQL 8.0 リファレンスマニュアル


17.5.1.21 レプリケーションと MEMORY テーブル

レプリケーションソースサーバーが停止して再起動すると、その MEMORY テーブルは空になります。 この効果をレプリカにレプリケートするには、ソースが起動後に最初に特定の MEMORY テーブルを使用するときに、そのテーブルの DELETE ステートメントまたは (MySQL 8.0.22 から) TRUNCATE TABLE ステートメントをバイナリログに書き込むことによってテーブルを空にする必要があることをレプリカに通知するイベントをログに記録します。 この生成されたイベントはバイナリログ内のコメントによって識別でき、GTID がサーバー上で使用されている場合は GTID が割り当てられます。 バイナリロギング形式が ROW に設定されている場合でも、ステートメントは常にステートメント形式で記録され、read_only または super_read_only モードがサーバーで設定されていても書き込まれます。 ソースの再起動からテーブルの最初の使用までの間、レプリカの MEMORY テーブルに古いデータが残っていることに注意してください。 レプリカへの直接クエリーで失効したデータが返される可能性がある場合にこの間隔を回避するには、init_file システム変数を設定して、起動時にソースの MEMORY テーブルに移入するステートメントを含むファイルに名前を付けることができます。

レプリカサーバーを停止して再起動すると、その MEMORY テーブルは空になります。 これにより、レプリカがソースと同期しなくなり、他の障害が発生したり、レプリカが停止する可能性があります:

  • ソースから受信した行形式の更新および削除は、Can't find record in 'memory_table'で失敗する場合があります。

  • INSERT INTO ... SELECT FROM memory_table などのステートメントによって、ソースおよびレプリカに異なる行セットが挿入される場合があります。

レプリカはまた、DELETE または (MySQL 8.0.22) TRUNCATE TABLE ステートメントを独自のバイナリログに書き込み、それがダウンストリームレプリカに渡されて、独自の MEMORY テーブルが空になります。

MEMORY テーブルをレプリケートしているレプリカを再起動する安全な方法は、まずソース上の MEMORY テーブルからすべての行を削除し、それらの変更がレプリカにレプリケートされるまで待機することです。 その後、レプリカを安全に再起動できます。

場合によっては、別の再起動方法を適用できることがあります。 binlog_format=ROW の場合、レプリカを再起動する前に slave_exec_mode=IDEMPOTENT を設定すると、レプリカが停止しないようにできます。 これにより、レプリカはレプリケートを続行できますが、その MEMORY テーブルはソースのテーブルとは異なります。 これは、MEMORY テーブルの内容が安全に失われるようにアプリケーションロジックが設定されている場合 (MEMORY テーブルがキャッシュに使用されている場合など) に許容されます。slave_exec_mode=IDEMPOTENT はすべてのテーブルにグローバルに適用されるため、MEMORY 以外のテーブルの他のレプリケーションエラーが非表示になる可能性があります。

(ここで説明した方法は NDB Cluster では適用できません。ここでは、slave_exec_mode は常に IDEMPOTENT であり、変更できません。)

MEMORY テーブルのサイズは、max_heap_table_size システム変数の値によって制限され、これは複製されません (セクション17.5.1.39「レプリケーションと変数」を参照してください)。 max_heap_table_size での変更は、変更後に ALTER TABLE ... ENGINE = MEMORY または TRUNCATE TABLE を使用して作成または更新された MEMORY テーブルに、またはサーバー再起動後にすべての MEMORY テーブルに反映されます。 レプリカで実行せずにソースでこの変数の値を増やすと、ソース上のテーブルがレプリカ上の対応するテーブルより大きくなり、ソースでは正常に挿入されますが、「テーブルがいっぱいです」エラーでレプリカでは失敗します。 これは既知の問題です (Bug #48666)。 このような場合は、レプリカおよびソースで max_heap_table_size のグローバル値を設定してから、レプリケーションを再起動する必要があります。 また、ソースとレプリカの両方の MySQL サーバーを再起動して、それぞれに新しい値が完全 (グローバル) に有効になるようにすることをお薦めします。

MEMORY テーブルに関する詳細は、セクション16.3「MEMORY ストレージエンジン」を参照してください。


関連キーワード:  テーブル, ソース, MEMORY, ステートメント, バイナリ, 設定, GTID, 変数, サーバー, ベース