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

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

## 注意
* 2020-05-14にPostgreSQL 13 beta1がリリースされたので、再調査した。beta1で再調査すると結構変更がある・・・。

# 調査方法
* PostgreSQL 12/PostgreSQL 13-develを使って、以下の操作を実行。
  * initdb（``-Dオ``プションと``-U postgres``オプションのみ指定）を実行。
  * 生成されたデータベースクラスタを起動。
  * postgresユーザでpostgresデータベースにログイン。
  * psqlの``\a``メタコマンドを実行。
  * psqlの``\o``オプションで出力ファイルを指定。
  * ``SELECT name, setting, unit, category, context, vartype, min_val, max_val FROM pg_settings ORDER BY name;``を実行。
* 生成されたPostgreSQL 12の結果とPostgreSQL 13-develの結果をdiffる。

# 調査結果
## 行数
SELECT文の行数(rows)を見ると、PostgreSQL 12は314行、PostgreSQL 13-develは312行。やっぱり何らかのパラメータ追加はあるっぽい。

## 差分
例によって生成されたデータベースクラスタパスに依存する値や、バージョン番号に依存する値、configureオプション(--enable-debug/--enable-cassert)による差、設定ファイル内の行数差、説明文のみの変更などは差分としてはカウントしない。

|パラメータ名|差分種別|差分概要|
|:--|:-:|:--|
|allow_system_table_mods   |変更   |contextがpostmasterからsuperuserに変更された。   |
| autovacuum_vacuum_insert_scale_factor |追加 |autovacuum_vacuum_scale_factorとは別に行挿入に特化したパラメータかな？<br>デフォルトは0.2(20%) |
| autovacuum_vacuum_insert_threshold |追加 |autovacuum_vacuum_thresholdとは別に行挿入に特化したパラメータかな？<br>デフォルトは1000タプル。-1を指定すると挿入契機で自動バキュームをしなくなる。 |
|backtrace_functions   |追加   |Developer Optionsとして追加。   |
|enable_groupingsets_hash_disk |追加 |大規模なグループ化セットの結果に対して、グループ化セットがディスクストレージでハッシュ集計を使用できるようにした|
|enable_hashagg_disk |追加 |ハッシュ集計で大規模な集計結果セットにディスクストレージを使用できるようにした。  |
|enable_incrementalsort |追加 |増分ソートを有効にする。 |
|ignore_invalid_pages   |追加   | リカバリ時に不正なWALを検出してもリカバリを継続するかどうか制御する。  |
|logical_decoding_work_mem   |追加   | 論理レプリケーション専用の作業メモリ確保パタメータ。  |
|log_min_duration_sample   |追加   | log_min_duration_statement によるログ出力割合を制御する。   |
|log_parameter_max_length |追加 |エラー以外のステートメントロギングメッセージで報告される各バインドパラメータ値は、この数バイトにトリミングされる。<br>0はステートメントでのバインドパラメータのログ記録を無効にする。<br>-1は全て記録する。 |
|log_parameters_on_error   |追加   | ステートメントのエラー（特にタイムアウト）時に、パラメータをログに記録するかどうか制御する。  |
|max_files_per_process   |変更   |min_valが25→64に変更。   |
|max_slot_wal_keep_size | 追加 |チェックポイント時にレプリケーションスロットがpg_walディレクトリに保持できるWALファイルの最大サイズを指定する。<br>-1（デフォルト）の場合、複製スロットは無制限の量のWALファイルを保持する。|
|primary_conninfo|変更|contextがpostmasterからsighupに変更された。|
|primary_slot_name|変更|contextがpostmasterからsighupに変更された。|
| ssl_min_protocol_version  |変更   |初期設定値が`TLSv1`から`TLSv1.2`に変更<br>古いSSLバージョンは使わせねーぞという強い意志を感じる。   |
| ssl_passphrase_command  | 変更 | superuserのみ参照可能に変更、とのこと(実機未確認) |
|track_activity_query_size   |変更   |max_valが102400から1048576に変更。<br>(1048576 = 8192 * 128)   |
|wal_receiver_create_temp_slot   |追加   | walreceiver がデフォルトで中間スロットを使用するかを制御するパラメータ？  |
|wal_skip_threshold|追加 |wal_levelがminimalの場合、永続的なリレーションの作成/変更時にこの設定よりも小さい場合は、WALログに書き込む。|

# 追加されたパラメータについて
## autovacuum_vacuum_insert_scale_factor
beta1マニュアルから。
> VACUUMをトリガーするかどうかを決定するときにautovacuum_vacuum_insert_thresholdに追加するテーブルサイズの割合を指定します。 デフォルトは0.2（テーブルサイズの20％）です。 このパラメーターは、postgresql.confファイルまたはサーバーのコマンドラインでのみ設定できます。 ただし、テーブルストレージパラメータを変更することで、個々のテーブルの設定を上書きできます。

## autovacuum_vacuum_insert_threshold
beta1マニュアルから。
> 1つのテーブルでVACUUMをトリガーするために必要な挿入されたタプルの数を指定します。 デフォルトは1000タプルです。 -1が指定されている場合、autovacuumは挿入の数に基づいてどのテーブルに対してもVACUUM操作をトリガーしません。 このパラメーターは、postgresql.confファイルまたはサーバーのコマンドラインでのみ設定できます。 ただし、テーブルストレージパラメータを変更することで、個々のテーブルの設定を上書きできます。

## backtrace_functions
このパラメータについては、昨年12月の[PostgreSQL Advent Calender 2019](https://qiita.com/advent-calendar/2019/postgresql)で @kasa_zip さんが調べているので、そっちを見ていただければと。
→[PostgreSQLのバックトレースレポート機能](https://qiita.com/kasa_zip/items/b23f8a72e7ac794cc8fa)

## enable_groupingsets_hash_disk
beta1マニュアルより。
> ハッシュテーブルの合計サイズがwork_memを超えることが予想される場合に、クエリプランナーがグループ化セットに対してハッシュされた集計プランタイプを使用することを有効または無効にします。 セクション7.2.4を参照してください。 デフォルトはオフです。

## enable_hashagg_disk
beta1マニュアルより。
> メモリ使用量がwork_memを超えることが予想される場合に、クエリプランナーがハッシュされた集計プランタイプを使用することを有効または無効にします。 デフォルトはオンです。

## enable_incrementalsort
beta1マニュアルより。
> クエリプランナーによるインクリメンタルソートステップの使用を有効または無効にします。 デフォルトはオンです。

incremental sortについては、以前、Qiita記事を書いたので、そっちを見てもらえるとありがたいです。
[PostgreSQL 13がやってくる！(5) - incremental sort](https://qiita.com/nuko_yokohama/items/89c2b9b4cac1fd6c073e)

## ignore_invalid_pages
これまで、リカバリ中に無効なページへの参照を持つWALレコードを検出すると、PostgreSQLはPANICレベルのエラーを発生させ、リカバリを中止するという挙動になっていましたが、このパラメータにonを設定すると、警告は出すけど、無理やりリカバリを継続する挙動にするパラメータっぽいです。

この機能の議論は、以下のスレッドから追えるようです。
[pgsql: Add GUC ignore_invalid_pages. ](https://www.postgresql-archive.org/pgsql-Add-GUC-ignore-invalid-pages-td6120179.html)

よくわからない、という人は、この機能のAuthorである、[Fujii Masao](https://twitter.com/fujii_masao)さんに聞いてみると良いかもしれません。:smile:

## log_min_duration_sample
このパラメータ、PostgreSQL 12 beta1の頃にも追加が提案されたけど、その後の議論でなくなってしまい、PostgreSQL 12には入らなかったパラメータだった気がする。

このパタメータ、要するに、'log_min_duration_statement = 0'に設定したときに、大量のslow queryログが出ちゃうので、それを出力する割合を指定する、というものになるはず。
非常にクエリのレイテンシが低いことを要求するようなシステムで、漏れなくスロークエリとなったSQLは検出したいけど、でもサーバログが大きくなるのはいやーんな人向けのパラメータ・・・なんだろう。たぶん。

この機能については、@mimitaro さんが、[PostgreSQL Advent Calender 2019](https://qiita.com/advent-calendar/2019/postgresql)で記事を書いているので、そちらを参照してもらうといいかも。
→[PostgreSQL13の新機能を試してみた](https://qiita.com/mimitaro/items/40bbdd89fef05374fa89)
## logical_decoding_work_mem
どうやら、PostgreSQL 12までは、論理レプリケーションによりサーバーのメモリが不足する可能性があるらしいです。で、このパラメータを提案したと。
詳しいことは、EnterpriseDB社のblog、[Postgres 13 - logical_decoding_work_mem and how it saves your server from going out of memory.](https://www.enterprisedb.com/ja/postgres-tutorials/postgres-13-logicaldecodingworkmem-and-how-it-saves-your-server-going-out-memory)に書いてあるようです。

## log_parameter_max_length
beta1マニュアルから。
> ゼロより大きい場合、エラー以外のステートメントロギングメッセージで報告される各バインドパラメータ値は、この数バイトにトリミングされます。 ゼロは、ステートメントでのバインドパラメータのログ記録を無効にします。 -1（デフォルト）では、バインドパラメータを完全にログに記録できます。 この値を単位なしで指定した場合、バイトとして扱われます。 スーパーユーザーのみがこの設定を変更できます。
>
> この設定は、log_statement、log_duration、および関連する設定の結果として出力されるログメッセージにのみ影響します。 この設定のゼロ以外の値では、特にパラメーターがバイナリ形式で送信される場合、テキストへの変換が必要になるため、オーバーヘッドが多少追加されます。

## log_parameters_on_error
これまで、ステートメントのエラー（特にタイムアウト）時に、パラメータがログに記録されず再現が困難であったことの解決方法として、提案されたパラメータっぽい。
この機能については、以下のスレッドで議論されている模様。
[log bind parameter values on error](http://micronetinternational.com/index.pl/en/00/https/www.postgresql-archive.org/log-bind-parameter-values-on-error-td6062921.html)
常時、この機能を有効にすると、メモリとCPUのオーバヘッドが発生するので、パラメータでon/off可能にするってことかな。
なお、この機能が使えるのは、現状では組み込みデータ型のみらしい。拡張したユーザ定義型には使えないようだ。

## max_slot_wal_keep_size
beta1マニュアルより。
> チェックポイント時にレプリケーションスロットがpg_walディレクトリに保持できるWALファイルの最大サイズを指定します。 max_slot_wal_keep_sizeが-1（デフォルト）の場合、複製スロットは無制限の量のWALファイルを保持します。 レプリケーションスロットのrestart_lsnが現在のLSNからそのメガバイトを超えると、必要なWALファイルが削除されるため、スロットを使用するスタンバイがレプリケーションを続行できなくなる可能性があります。 > pg_replication_slotsでレプリケーションスロットのWAL可用性を確認できます。

## wal_receiver_create_temp_slot
現状、walreceiverはデフォルトで一時複製スロットを使用するけど、それを使わないように制御するパラメータなのかな？
型はboolean。デフォルトはon。
この機能は、以下のスレッドで議論されているようです。
[pgsql: walreceiver uses a temporary replication slot by default](https://www.postgresql.org/message-id/flat/E1irMhK-00021w-9z@gemulon.postgresql.org)

## wal_skip_threshold
beta1マニュアルより。
> wal_levelが最小で、永続的なリレーションを作成または書き換えた後にトランザクションがコミットする場合、この設定は新しいデータを永続化する方法を決定します。
データがこの設定よりも小さい場合は、WALログに書き込みます。それ以外の場合は、影響を受けるファイルのfsyncを使用します。
ストレージのプロパティによっては、この値を上げたり下げたりすると、そのようなコミットによって同時トランザクションが遅くなる場合があります。
この値を単位なしで指定すると、キロバイトとして扱われます。 デフォルトは2メガバイト（2MB）です。

## その他
ssl_passphrase_command がSuperuserのみ参照可に変更、とのこと（[篠田さん](https://twitter.com/nori_shinoda)からのコメント）。
pg_settingsからだけだと、そういう情報出てこないんですよね・・・。

# おわりに
ということで、PostgreSQL 13 beta1リリースとなったので、PostgreSQL 12とPostgreSQL 13-beta1版のパラメータを再度比較していました。
思ったよりも前回調査(2020-03-14)との差分多かったなー。