PostgreSQL 16 の新機能: 本日から Cloud SQL で利用可能になった新機能のご紹介
Indu Akkineni
Database Engineer, Cloud SQL
※この投稿は米国時間 2024 年 6 月 8 日に、Google Cloud blog に投稿されたものの抄訳です。
Cloud SQL のお客様は、PostgreSQL 16 を利用してユーザビリティを改善し、情報に基づいた意思決定を促進できるようになりました。このバージョンでは、データベースの運用をきめ細かく分析し、ユーザビリティを向上させるための新機能が導入されています。
今回のブログ投稿では、PostgreSQL 16 バージョンの目玉である以下の項目について取り上げます。
-
オブザーバビリティの改善
-
パフォーマンスの向上
-
バキュームの効率
-
レプリケーションの改善
各項目について詳しく見ていきましょう。
オブザーバビリティの改善
オブザーバビリティはデータベースの重要な側面です。これにより、オペレーターはリソースの利用状況に関する分析情報を手に入れ、リソースの使用量を最適化できます。PostgreSQL 16 で導入されたオブザーバビリティに関する重要な機能強化について、以下で説明します。
PG_STAT_IO
PostgreSQL 16 に新しいビュー pg_stat_io が追加されました。このビューには、PostgreSQL データベースの入力 / 出力(IO)動作に関する分析情報が表示されます。データベースのパフォーマンスの最適化、リソース使用率の改善、データベース システムの全体的な健全性とスケーラビリティの確保のために、このビューを使用して情報に基づく決定を下すことができます。このビューにはインスタンス全体の統計データが表示されます。
このビューからどのようなことを推測できるでしょうか。
他の pg_stat_*
ビューと同様、このビューの統計情報も累積的です。一定期間にわたって pg_stat_io ビューの変化を追跡するには、ワークロードの最初と最後の値を記録します。
このビューは、主に backend_type、io_context、io_object の列を基準に統計データを追跡します。
backend_type は接続プロセスであり、クライアント バックエンド(client backend)、バックグラウンド ワーカー(background worker)、チェックポインタ(checkpointer)、スタンドアロン バックエンド(standalone backend)、自動バキューム ランチャー(autovacuum launcher)、自動バキューム ワーカー(autovacuum worker)のいずれかです。io_context は、負荷に基づいて、通常(normal)、一括読み取り(bulk read)、一括書き込み(bulk write)、またはバキューム(vacuum)として分類されます。
インスタンスの I/O のステータスを把握するために実際に考慮される統計データは、読み取り(reads)、書き込み(writes)、拡張(extends)、ヒット(hits)、エビクション(evictions)、再利用(reuses)です。
ヒットに対するエビクションの比率を比較することで、共有バッファの効率をモニタリングできます。各コンテキストのヒットがエビクションよりもかなり大きい場合に、バッファヒット率が有効であるとみなされます。
一括読み取りと一括書き込みは、シーケンシャル スキャンと考えられます。この場合、これらのエビクション、ヒット、再利用は、リングバッファの効率性を示します。
また、自動バキュームまたはバキューム プロセスの一環として読み取られたデータまたは書き込まれたデータの量も確認できます。自動バキュームに関連する指標データについては、io_context が「vacuum」で、backend_type が「autovacuum worker」のものを確認します。バキューム プロセスについては、backend_type が「standalone backend」で、io_context が「vacuum」のものを確認します。
ビューの例を以下に示します。
テーブルとインデックスでの最後のシーケンシャル スキャンとインデックス スキャン
ビュー pg_stat_*_tables
に 2 つの新しい列が追加されました。
last_seq_scan
last_idx_scan
テーブルでシーケンシャル スキャンまたはインデックス スキャンが最後に実行されたタイミングを知りたいとしましょう。その場合、pg_stat_*_tables
に新しく追加された列 last_seq_scan
と last_idx_scan
を確認します。
これらの列に、テーブルで最後に実行されたシーケンシャル スキャンまたはインデックス スキャンのタイムスタンプが表示されます。これは「クエリ読み取り」問題の特定に役立ちます。
同様に、列 last_idx_scan
が pg_stat_*_indexes
に追加されました。この列には、インデックスが最後に使用されたときのタイムスタンプが表示されます。インデックスを削除する場合に、この列にあるインデックスの値を参照し、情報に基づく決定を下すことができます。
更新時に新しいページに表示されるタプルのオカレンスに関する統計情報
ビュー pg_stat_*_tables
に新しい列 n_tup_newpage_upd
が追加されました。
テーブルで更新を実行し、最終的に新しいヒープページに表示される行の数をモニタリングする場合、列 n_tup_newpage_upd
で情報を確認できるようになりました。
この列から、時間の経過に応じたテーブルの拡大に関与する要因が明らかになります。この列の値を使用して、テーブルの「fillfactor」セットを検証することもできます。特に「HOT」となることが予測される更新については、この列の統計データを確認することで、「fillfactor」が最適かどうかを判断できます。
パフォーマンスの向上
パフォーマンスは常にデータベースの最優先事項です。メジャー バージョンのリリースでは、他の機能強化に先駆けてパフォーマンスの向上が取り入れられています。ここでは、PostgreSQL 16 におけるパフォーマンスの向上をいくつかご紹介します。
列に BRIN インデックスのみがあるテーブルは「HOT」とみなされる
PostgreSQL 16 では、BRIN インデックスがあるテーブルに対する更新が、そのテーブルの fillfactor が最適となっている場合、「HOT」であるとみなされるようになりました。「fillfactor」は、この更新が「HOT」とマークされるようにするための重要な設定です。この改良により、テーブルなどのバキュームが迅速になり、リソースを効率的に使用できます。
完全結合または外部結合の並列処理
このパフォーマンスの向上は、完全結合または外部結合によって結合される非常に大きなテーブルが関与する select を使用する場合に非常に有益です。PostgreSQL 16 では、ヒープフェッチを完全に実行した後のマージまたはハッシュではなく、各テーブルの並列シーケンシャル スキャンを実行した後の並列ハッシュとなります。Google のテストで、PG15 と比べて非常に大きな機能改良が実現していることが判明しました。
完全外部結合の例
Explain (generic_plan)
PostgreSQL 16 が登場する前は、パラメータ化された SQL の場合、実行プランを取得するためにパラメータの値を渡さなければなりませんでした。PostgreSQL 16 にはオプション (generic_plan) が用意されているため、実行プランを取得するために追加の値を SQL に指定する必要はありません。
例
バキュームの改善
バキュームは PostgreSQLMVCC で重要な役割を果たします。バキュームはデッドタプルを削除した後に領域を解放し、テーブルの肥大化を最小限に抑えます。これにより、データベースのトランザクション ラップアラウンドの問題を回避できます。ここでは、PostgreSQL 16 でのバキューム プロセスの改良点をいくつかご紹介します。
大きいテーブルを対象とした VACUUM オペレーションのパフォーマンスの向上
BUFFER_USAGE_LIMIT
PostgreSQL 16 に新しいサーバー変数「vacuum_buffer_usage_limit」が追加されました。この変数は、VACUUM オペレーションと ANALYZE オペレーションに割り当てられたリングバッファにデフォルト値 256 KB を設定します。VACUUM オペレーションの実行中に「BUFFER_USAGE_LIMIT」オプションを設定すると、「vacuum_buffer_usage_limit」のデフォルト値がオーバーライドされ、指定したリングバッファのサイズが割り当てられます。「buffer_usage_limit」に大きな値を指定すると vacuum オペレーションが高速で実行されますが、メインのワークロードで使用されるバッファが「shared_buffers」から除外され、結果的にパフォーマンスが低下する可能性があります。非常に大きなテーブルに対してバキューム処理を実行するときは、常に「buffer_usage_limit」を使用して VACUUM オペレーションのリングバッファの使用量を制限することをおすすめします。このオプションは、VACUUM を完了することが不可欠な、TXID のラップアラウンドに近づいた時点で慎重に使用します。VACUUM オペレーションに ANALYZE も含まれている場合は、両方のオペレーションが「buffer_usage_limit」で指定された同じリングバッファのサイズを使用します。「buffer_usage_limit」に「0」を設定すると、バッファ アクセス ストラテジが無効になります。その結果、共有バッファが大量に削除され、パフォーマンスの低下につながります。「buffer_usage_limit」に指定できる範囲は 128 KB~16 GB です。
VACUUM による TOAST テーブルのみの処理
PostgreSQL 16 では、リレーションに関連する TOAST テーブルのみをバキューム処理できるようになりました。以前、FALSE に設定した場合に TOAST テーブルのバキューム処理がオフになるオプション「process_toast」が追加されました。これ以外の場合は、リレーションのメインのテーブルと TOAST テーブルの両方でバキュームが実行されていました。PostgreSQL 16 では、要件に基づいて、メインのテーブルと TOAST テーブルの両方をバキューム処理することも、リレーションに属する片方のみをバキューム処理することもできます。これにより、必要に応じて、メイン、TOAST、または両方のバキューム処理を適切に実行できるようになります。
その適用方法の例を以下に示します。
vacuumdb オプションによるスキーマの処理
vacuumdb に、データベースのスキーマに属すテーブルすべてのバキューム処理または分析を行うためのオプションが追加されました。この機能は、スキーマが 1 つのみのテーブルを対象とする場合に非常に便利です。
レプリケーションの改善
レプリケーションは、データベースの高可用性機能を構成する重要な要素です。PostgreSQL 16 では、コミュニティによって複数のユーザビリティ機能がレプリケーションに追加されました。
論理レプリケーションでの初期テーブル同期によるバイナリ形式の行のコピー
PostgreSQL 16 の論理レプリケーションでは、バイナリ形式の行のコピーを初期設定できます。特にバイナリデータを含む列では、非常に迅速に処理できます。以下に、初期データのコピーがバイナリ形式のサブスクリプションを作成する方法の例を示します。
改良された logical replication apply(主キーなしの場合)
従来、PostgreSQL の論理レプリケーションでは、テーブルに主キーがない場合はテーブルのフルスキャンを実行していたため、パフォーマンスに影響が及んでいました。これに対して、PostgreSQL 16 ではテーブルにある B ツリー インデックスを利用できるようになり、logical apply の効率が大幅に向上しました。インデックスの使用統計情報は pg_stat_*_indexes ビューで確認できます。
論理デコーディングのスタンバイ
PostgreSQL 16 では、リードレプリカで論理デコーディングが有効になっているため、サブスクライバーはプライマリ db インスタンスではなくリードレプリカに接続できます。こうすることで、ワークロードがプライマリ インスタンスとレプリカの間で共有され、プライマリ インスタンスへの負担が軽減されます。これにより、論理レプリケーション ワークロードがプライマリ インスタンスからレプリカにオフロードされます。その結果、特に多くの論理レプリケーション スロットがあるプライマリ ノードの場合、ノードのパフォーマンスが大幅に向上します。もう 1 つのメリットは、レプリカが昇格される場合もサブスクライバーは変更の影響を受けず、一切の障害なく機能し続けることです。これまでとは異なり、リードレプリカの遅延が結果的に論理サブスクライバーに影響を及ぼす点に注意してください。
PostgreSQL 16 の利用を今すぐ開始
オブザーバビリティ、論理レプリケーション、バキューム処理などが強化された PostgreSQL 16 を Cloud SQL で早速使ってみましょう。Cloud SQL で PostgreSQL 16 の利用を開始するには、こちらにアクセスしてください。
ー データベース エンジニア Indu Akkineni