PolarDB for PostgreSQL では、物理レプリケーションと論理レプリケーションのプロセスが WAL バッファーから先行書き込みログ (WAL) ログを読み取ることができます。これにより、読み取り I/O がメモリコピーに変換されます。この機能は、複数のレプリケーションプロセスによる I/O 増幅を大幅に削減し、WAL ログの読み取り帯域幅を節約し、読み取りレイテンシーを低減します。その結果、全体的なレプリケーションレイテンシーも短縮されます。
背景情報
ネイティブの PostgreSQL では、レプリケーションは物理レプリケーションと論理レプリケーションに分かれています。
物理レプリケーション:WAL ログの内容を転送することで、プライマリノードとスタンバイノード間でデータを同期します。
論理レプリケーション:WAL ログからデコードされた論理的な変更を転送することで、パブリッシャーノードとサブスクライバーノード間でデータを同期します。
実行中の PostgreSQL インスタンスは、複数の物理レプリケーションリンクと論理レプリケーションリンクを同時に持つことができます。各リンクには対応する WAL 送信者プロセスがあり、ストレージから WAL ログを読み取り、解析し、ネットワーク経由で下流システムに送信します。各リンクのレプリケーションの進捗は独立しています。
各リンクのレプリケーションの進捗は独立しているため、各レプリケーションプロセスは WAL ログの完全なセットを読み取り、処理し、送信する必要があります。レプリケーションリンクが多い場合、WAL ログの読み取り帯域幅は書き込み帯域幅の数倍になる可能性があります。これにより、多くの IOPS (1 秒あたりの入出力操作) が消費されます。インスタンスが高い I/O プレッシャー下にある場合、大量の WAL ログの読み取り I/O が通常のビジネスの読み書き I/O に干渉する可能性があります。この干渉は、ビジネス運用を遅くし、レプリケーションレイテンシーを増加させます。
ネイティブの PostgreSQL では、WAL ログが生成されると、まず WAL バッファーに書き込まれます。その後、バックグラウンドプロセスまたは通常のプロセスによってストレージに書き込まれます。WAL バッファー内のスペースは周期的に再利用されます。したがって、WAL バッファーには最新の WAL ログが保持されており、これらはレプリケーションプロセスによって使用される可能性が最も高いログです。
PolarDB for PostgreSQL は、ログがディスクに書き込まれた後でもバッファー内に存在する場合、WAL バッファーから直接 WAL ログを読み取ることをサポートします。これにより、レプリケーションプロセスからの読み取り I/O がメモリコピー操作に変換されます。この最適化により、複数のレプリケーションプロセスによる読み取り I/O の増幅が大幅に削減され、WAL ログの読み取り帯域幅が節約されます。また、WAL ログの読み取りレイテンシーも低減され、結果としてレプリケーションレイテンシーが短縮されます。
適用範囲
この機能は、次のバージョンの PolarDB for PostgreSQL で利用できます。
PostgreSQL 18 (マイナーエンジンバージョン 2.0.18.0.1.0 以降)
PostgreSQL 17 (マイナーエンジンバージョン 2.0.17.2.1.0 以降)
PostgreSQL 16 (マイナーエンジンバージョン 2.0.16.6.2.0 以降)
PostgreSQL 15 (マイナーエンジンバージョン 2.0.15.12.4.0 以降)
PostgreSQL 14 (マイナーエンジンバージョン 2.0.14.13.27.0 以降)
コンソールで、または SHOW polardb_version; 文を実行することで、マイナーエンジンバージョン番号を表示できます。マイナーエンジンバージョンが要件を満たしていない場合は、マイナーエンジンバージョンをアップグレードできます。
使用方法
polar_enable_read_from_wal_buffers パラメーターを on に設定することで、レプリケーションプロセスに対してこの機能を有効にできます。デフォルト値は on です。クラスターパラメーターの設定方法の詳細については、「クラスターパラメーターの設定」をご参照ください。
polar_monitor 拡張機能を使用して、WAL バッファーからの WAL ログ読み取りのヒット統計を確認できます。
polar_monitor 拡張機能を作成します。
CREATE EXTENSION IF NOT EXISTS polar_monitor;WAL バッファーから WAL ログを読み取る際のヒット統計を確認します。
SELECT * FROM polar_stat_walsnd_xlog_read();コマンドは、次のような結果を返します。
pid | hit | hit_bytes | prefetched | prefetched_bytes | read | read_bytes ---------+------+-----------+------------+------------------+------+------------ 3865685 | 2175 | 251583064 | 0 | 0 | 82 | 10628128 3865751 | 2173 | 251582792 | 0 | 0 | 82 | 10628400 (2 rows)
次の表に、返されるフィールドを示します。
列 | データ型 | 説明 |
pid | INTEGER | レプリケーションプロセスのプロセス ID (PID) です。 |
hit | BIGINT | WAL バッファーに直接ヒットした読み取り I/O 操作の数です。 |
hit_bytes | BIGINT | WAL バッファーに直接ヒットした I/O 操作によって読み取られたバイト数です。 |
prefetched | BIGINT | WAL ログがストレージからバッチでプリフェッチされた後、メモリキャッシュにヒットした読み取り I/O 操作の数です。 |
prefetched_bytes | BIGINT | WAL ログがストレージからバッチでプリフェッチされた後、メモリキャッシュにヒットした I/O 操作によって読み取られたバイト数です。 |
read | BIGINT | ストレージから WAL ログを読み取った読み取り I/O 操作の数です。 |
read_bytes | BIGINT | ストレージから読み取られた WAL ログのバイト数です。 |