PostgreSQL 17がやってくる(1) 設定パラメータの差分

# はじめに
にゃーん。
いつものように、PostgreSQL新バージョンの差分先行調査の時期になりました。
ということで、今回はPostgreSQL 16とPostgreSQL 17devの設定パラメータの差分を調べてみる。

# 調査方法
* PostgreSQL 16/PostgreSQL 17dev(commitid 93582974315174d544592185d797a2b44696d1e5)を使って、以下の操作を実行。
  * initdb（-Dオプションと-U postgresオプションのみ指定）を実行。
  * 生成されたデータベースクラスタを起動。
  * postgresユーザでpostgresデータベースにログイン。
  * psqlの\aメタコマンドを実行。
  * psqlの\oオプションで出力ファイルを指定。
  * ``SELECT name, setting, unit, category, context, vartype, min_val, max_val, enumvals FROM pg_settings ORDER BY name;``を実行。[^1]
* 生成されたPostgreSQL 16の結果とPostgreSQL 17develの結果をdiffる。
* パラメータの説明は調査時点(2024-04-14)のPostgreSQL Document(devel)に記載された内容を元にしている。

# 調査結果
## 行数
SELECT文の行数(rows)

|version|rows|
|:--|--:|
|PostgreSQL 16|360|
|PostgreSQL 17dev|378|


## 差分概要
PostgreSQL 16.3とPostgreSQL 17devの設定パラメータ差分のサマリを以下に示す。
今回も追加されたパラメータは結構多い。

|パラメータ名|種別|差分概要|
|:--|:-:|:--|
|allow_alter_system|追加|ALTER SYSTEMを許容するかどうかを制御するパラメータの追加|
|backtrace_on_internal_error|追加|開発者向けパラメータ。エラーコード``XX000`` (内部エラー)発生時の挙動を制御するパラメータの追加|
|commit_timestamp_buffers|追加|pg_commit_tsの内容をキャッシュするために使用するメモリ量を指定するパラメータの追加|
|db_user_namespace|削除||
|enable_group_by_reordering|追加|プランナメソッド制御パラメータの追加|
|enable_self_join_removal|追加|プランナメソッド制御パラメータの追加|
|event_triggers|追加|イベントトリガの実行を一時的に無効にするパラメータの追加|
|huge_pages_status|追加|hugepageの状態を報告するパラメータの追加|
|io_combine_limit|追加|I/Oを組み合わせた操作のバッファを指定するパラメータの追加|
|max_notify_queue_pages|追加|NOTIFY/LISTENキューを制御するパラメータの追加|
|multixact_member_buffers|追加|pg_multixact/membersのキャッシュ制御のパラメータの追加|
|multixact_offset_buffers|追加|pg_multixact/offsetのキャッシュ制御のパラメータの追加|
|notify_buffers|追加|pg_notifyのキャッシュ制御のパラメータの追加|
|old_snapshot_threshold|削除||
|serializable_buffers|追加|pg_serialのキャッシュ制御のパラメータの追加|
|standby_slot_names|追加|論理WAL送信プロセスが待機するストリーミングレプリケーション待機サーバースロット名を指定するパラメータの追加|
|subtransaction_buffers|追加|pg_subtranslのキャッシュ制御のパラメータの追加|
|summarize_wal|追加|インクリメンタルバックアップに関連するパラメータの追加|
|sync_replication_slots|追加|論理サブスクライバがフェイルオーバ後に新しいプライマリサーバからレプリケーションを再開できるようにするパラメータの追加|
|trace_connection_negotiation|追加|開発者向けオプション。詳細未調査。|
|trace_recovery_messages|削除|開発者向けオプション。詳細未調査。|
|transaction_buffers|追加|pg_xactのキャッシュ制御のパラメータの追加|
|transaction_timeout|追加|トランザクションタイムアウト制御パラメータの追加|
|vacuum_buffer_usage_limit|変更|デフォルト値（256(kB)→2048(kB)）の変更|
|wal_summary_keep_time|追加|インクリメンタルバックアップに関連するパラメータの追加|


# 追加されたパラメータ
PostgreSQL 17では結構多くのパラメータの追加がある。

## allow_alter_system

|項目|説明|
|:--|:--|
|カテゴリ|Other Platforms and Clients|
|context|sighup|
|データ型|bool|
|説明|ALTER SYSTEMコマンドの実行可否を示す。offの場合、``ALTER SYSTEM``コマンドを実行するとエラーが返される。|
|デフォルト値|on|

【メモ】
この設定はALTER SYSTEMコマンドを無効にするだけである。
スーパーユーザが他のSQLコマンドを使用して設定を変更することを防ぐことはできない。スーパーユーザはオペレーティングシステムレベルでシェルコマンドを実行する多くの手段を持っている。したがって、この設定の値に関係なくpostgresql.auto.confを変更することは可能。

## backtrace_on_internal_error

|項目|説明|
|:--|:--|
|カテゴリ|Developer Optionss|
|context|superuser|
|データ型|bool|
|説明|このパラメータがonの場合、エラーコード``XX000`` (内部エラー) が発生した場合、エラーメッセージとともにバックトレースがサーバログに書き込まれる。|
|デフォルト値|off|

【メモ】
デフォルト値はoffなので、正式版のRPMバイナリでもoffになりそう。そうすると通常の運用者がこの機能の恩恵を受けることはないかも。
``XX000``ってOracleでいうところの``ORA-0600``みたいなイメージなんだけど、エラーのバックトレースが運用中に出力できると嬉しいケースあったりしないのかな？

## commit_timestamp_buffers

|項目|説明|
|:--|:--|
|カテゴリ|Resource Usage / Memory|
|context|postmaster|
|データ型|integer|
|説明|pg_commit_tsの内容をキャッシュするために使用するメモリ量を指定する。この値が単位なしで指定された場合、ブロック、つまりBLCKSZバイト、通常は8kBとして扱われる。デフォルト値（0）は、shared_buffers/512のブロック数（最大1024ブロックまで）を要求する。|
|デフォルト値|32(=256kB)|
|値域|0～131072|

【メモ】
どういうときに、このパラメータを調整するのか、自分ではあまり良くわかっていない・・・。

## enable_group_by_reordering

|項目|説明|
|:--|:--|
|カテゴリ|Query Tuning / Planner Method Configuration|
|context|user|
|データ型|bool|
|説明|(not documented)|
|デフォルト値|on|

【メモ】
これはプランナの改善項目のリリースノート等読まないとわかんないかな。

## enable_self_join_removal

|項目|説明|
|:--|:--|
|カテゴリ|Query Tuning / Planner Method Configuration|
|context|user|
|データ型|bool|
|説明|問い合わせツリーを分析し、自己結合を意味的に等価な単一スキャンに置き換える問い合わせプランナの最適化を有効もしくは無効にする。プレーンテーブルのみを考慮します。|
|デフォルト値|on|

【メモ】
これもプランナの改善項目のリリースノート等読まないとわかんないかな。

## event_triggers

|項目|説明|
|:--|:--|
|カテゴリ|Client Connection Defaults / Statement Behavior|
|context|superuser|
|データ型|bool|
|説明|イベントトリガの実行を一時的に無効にする。offに設定すると全てのイベントトリガが無効にる。onに設定すると、全てのイベントトリガが発火するようになる。|
|デフォルト値|on|

【メモ】
不具合のあるイベントトリガーのトラブルシューティングや修復のためにoffにする機能が追加になったらしい。

## huge_pages_status

|項目|説明|
|:--|:--|
|カテゴリ|Preset Options|
|context|internal|
|データ型|enum|
|説明|現在のインスタンスにおけるhugepageの状態を報告する。|
|デフォルト値|on|
|値域|on, off, unknown|


【メモ】
giant_pages=tryで巨大ページの割り当てが成功したかどうかを判断するのに使えるらしい。
unknownは``postgres -C``で表示された場合はこれが表示される（と書いているが良くわからん・・・）

## io_combine_limit

|項目|説明|
|:--|:--|
|カテゴリ|Resource Usage / Asynchronous Behaviors|
|context|user|
|データ型|integer|
|説明|I/Oを組み合わせた操作における最大のI/Oサイズを制御する。|
|デフォルト値|16(=128kB)|
|値域|1～32|


【メモ】
これは何に対するI/O操作を制御するパラメータなんだろう？
データファイル/WALに対するI/O操作で共通なんだろうか？

## max_notify_queue_pages

|項目|説明|
|:--|:--|
|カテゴリ|Resource Usage / Disk|
|context|postmaster|
|データ型|integer|
|説明|NOTIFY/LISTENキューの最大確保ページ数を指定する。8KBのページに対して、最大8GBのディスク容量を消費することができる。|
|デフォルト値|1048576|
|値域|64～2147483647|

【メモ】
NOTIFY文/LISTEN文ってあんまり使わないんだよな・・・。
最小値(64)あるいは最大値(2147483647)を指定したら、どういう弊害があるのか気になる。

## multixact_member_buffers

|項目|説明|
|:--|:--|
|カテゴリ|Resource Usage / Memory|
|context|postmaster|
|データ型|integer|
|説明|pg_multixact/membersの内容をキャッシュするために使用する共有メモリの量を指定する。|
|デフォルト値|32|
|値域|16～131072|

【メモ】
二相コミットを使うどういうケースでチューニングしないといけないのか、良くわからない・・・。

## multixact_offset_buffers

|項目|説明|
|:--|:--|
|カテゴリ|Resource Usage / Memory|
|context|postmaster|
|データ型|integer|
|説明|pg_multixact/offsetの内容をキャッシュするために使用する共有メモリの量を指定する。|
|デフォルト値|16|
|値域|16～131072|

【メモ】
二相コミットを使うどういうケースでチューニングしないといけないのか、良くわからない・・・。

## notify_buffers

|項目|説明|
|:--|:--|
|カテゴリ|Resource Usage / Memory|
|context|postmaster|
|データ型|integer|
|説明|pg_notifyの内容をキャッシュするために使用する共有メモリの量を指定する。|
|デフォルト値|16(256kB)|
|値域|16～131072|

【メモ】
LISTEN/NOTIFYのときに使われるのだろうけど、どういうチューニングをすればいいのかがわからない・・・


## serializable_buffers

|項目|説明|
|:--|:--|
|カテゴリ|Resource Usage / Memory|
|context|postmaster|
|データ型|integer|
|説明|pg_serialの内容をキャッシュするために使用する共有メモリの量を指定する。|
|デフォルト値|32(=256kB)|
|値域|16～131072|

【メモ】
pg_serialってそもそもなんだっけ・・・？

## standby_slot_names

|項目|説明|
|:--|:--|
|カテゴリ|Replication / Primary Server|
|context|sighup|
|データ型|string|
|説明|論理WAL送信プロセスが待機するストリーミングレプリケーション待機サーバースロット名のカンマ区切りリスト。|
|デフォルト値|on|

【メモ】
standby_slot_namesに指定されたスロットが存在しないか無効になっている場合、論理レプリケーションは続行されない。
このへんの機能は論理レプリケーションの改善まわりをきちんと理解しないと、このパラメータの意味や設定方法等も理解できなさそうだ。

## subtransaction_buffers

|項目|説明|
|:--|:--|
|カテゴリ|Resource Usage / Memory|
|context|postmaster|
|データ型|integer|
|説明|pg_subtransの内容をキャッシュするために使用する共有メモリの量を指定する。|
|デフォルト値|32(=256kB)|
|値域|0～131072|

【メモ】
serializable_buffers等と同様に関連するページ見ないとわからないかも。

## summarize_wal

|項目|説明|
|:--|:--|
|カテゴリ|Write-Ahead Log / Summarization|
|context|sighup|
|データ型|bool|
|説明|WAL要約処理を有効にする。|
|デフォルト値|off|

【メモ】
インクリメンタルバックアップに関連するパラメータ。

## sync_replication_slots

|項目|説明|
|:--|:--|
|カテゴリ|Replication / Standby Servers|
|context|sighup|
|データ型|bool|
|説明|物理スタンバイがプライマリサーバからの論理フェイルオーバスロットを同期することを可能にし、論理サブスクライバがフェイルオーバ後に新しいプライマリサーバからレプリケーションを再開できるようにする。|
|デフォルト値|off|

【メモ】
これはストリーミングレプリケーション＋論理レプリケーション構成のときに役にたつ機能を制御するパラメータなのかな。
あと、PostgreSQL文書上「このパラメータはpostgresql.confファイルまたはサーバコマンドラインでのみ設定できる」という記述があるけど、``ALTER SYSTEM``では設定できないということなんだろうか？

## trace_connection_negotiation

|項目|説明|
|:--|:--|
|カテゴリ|Developer Options|
|context|postmaster|
|データ型|bool|
|説明|(not documented)|
|デフォルト値|off|

【メモ】
開発者用オプションなので、すぐに調べなくてもいいか・・・

## trace_recovery_messages

|項目|説明|
|:--|:--|
|カテゴリ|Developer Options|
|context|sighup|
|データ型|enum|
|説明|(not documented)|
|デフォルト値|log|
|値域|debug5,debug4,debug3,debug2,debug1,log,notice,warning,error|

【メモ】
開発者用オプションなので、すぐに調べなくてもいいか・・・

## transaction_buffers

|項目|説明|
|:--|:--|
|カテゴリ|Resource Usage / Memory|
|context|postmaster|
|データ型|integer|
|説明|pg_xactの内容をキャッシュするために使用する共有メモリの量を指定する。|
|デフォルト値|0(block)|
|値域|0～131072|

【メモ】
デフォルト値(0)の場合、shared_buffers/512を1024ブロックまで要求する。

## transaction_timeout

|項目|説明|
|:--|:--|
|カテゴリ|Client Connection Defaults / Statement Behavior|
|context|user|
|データ型|integer|
|説明|トランザクション内で指定された時間以上のセッションを終了する。|
|デフォルト値|0(ms)|
|値域|0～2147483647|

【メモ】
明示的に開始されたトランザクション（BEGINで開始）と、1つの文に対応する暗黙的に開始されたトランザクションの両方に適用される。この値が単位なしで指定された場合、ミリ秒とみなされる。
値0（デフォルト）はタイムアウトを無効にする。


## wal_summary_keep_time

|項目|説明|
|:--|:--|
|カテゴリ|Write-Ahead Log / Summarization|
|context|sighup|
|データ型|integer|
|説明|WALサマライザが古いWALサマリを自動的に削除する時間を設定する。|
|デフォルト値|14400(min)|
|値域|0～35791394|

【メモ】
インクリメンタルバックアップに関連するパラメータ。

# 変更されたパラメータ

## vacuum_buffer_usage_limit

|項目|説明|
|:--|:--|
|カテゴリ|Resource Usage / Memory|user|
|context|user|
|データ型|integer|
|説明|VACUUMおよびANALYZEコマンドで使用されるBuffer Access Strategyのサイズを指定する。|
|デフォルト値|256(kB)→2048(kB)|
|値域|0～16777216|

【メモ】
デフォルト値が大きくなったのみ。

# 削除されたパラメータ

## db_user_namespace

|項目|説明|
|:--|:--|
|カテゴリ|Connections and Authentication / Authentication|
|context|sighup|
|データ型|bool|
|説明|このパラメータがonの場合、データベースごとのユーザー名を有効にする。その場合、username@dbnameとしてユーザを作成する必要がある。|
|デフォルト値|off|

【メモ】
こんなパラメータ使ったことない。PostgreSQL 17で削除された理由はなんだろう？

## old_snapshot_threshold

|項目|説明|
|:--|:--|
|カテゴリ|Resource Usage / Asynchronous Behavior|
|context|postmaster|
|データ型|integer|
|説明|スナップショット使用時に "snapshot too old "エラーが発生するリスクなしにクエリスナップショットを使用できる最小時間を設定する。このしきい値より長い間停止しているデータは、バキュームされる。-1はこの機能を無効にする。|
|デフォルト値|-1|

【メモ】
これはPostgreSQL 17のVacuum関連の改善によって、意味がなくなって削除されたパラメータなんだろうか？


# おわりに
PostgreSQL 17でも多くの設定パラメータの変更があるようだ。まだ、一部のパラメータはPostgreSQL文書への記載がないので、調査としては完全ではないけど、PostgreSQL 17でも、かなりパラメータの変更があるのはわかってきた。
システムカタログ？のキャッシュに関連するパラメータ、トランザクションタイムアウトに関するパラメータ、**インクリメンタルバックアップ**に関するパラメータなどが気になるところ。

今回の記事は机上調査でしかないので、今後、各機能を実際に動かしてみてどういう新機能が追加されたのかを確認していきたい。
また、この調査結果はあくまでも4/14時点のものなので、今後開発が進んでbeta以降で変更される可能性も大いにありうる。