PostgreSQL 17がやってくる(2) システムカタログの差分

# はじめに
にゃーん

今回は、PostgreSQL 16とPostgreSQL 17devのシステムカタログの差分を調べてみる。
まだbetaリリース前の版なので、今後変わっていく可能性が大きいけど、現時点の版で調査をしてみた。

## 調査方法
PostgreSQL 16とPostgreSQL 17dev(commitid 93582974315174d544592185d797a2b44696d1e5)それぞれで以下の手順を実施。

* psqlでpostgresデータベースにログイン
* `\o` *ファイル名* メタコマンドで出力先ファイルを指定
* `\a` メタコマンドで整形用の空白が入らないようにする。
* 以下のSELECT文を実行してpsqlを終了する。

```sql
SELECT c.relname, attname, atttypid
FROM pg_class c JOIN pg_attribute a ON (a.attrelid = c.oid) JOIN pg_namespace ns ON (c.relnamespace = ns.oid)
WHERE ns.nspname = 'pg_catalog' AND c.relkind ='r'
ORDER BY c.relname, a.attname
;
```
ソートはリレーション名と属性名にする。（あえてリレーション内の属性の並び番号ではソートしない）

* psqlを終了する。
* PostgreQSL 13の検索結果ファイルと、PostgreSQL 14の検索結果ファイルをdiffる。

システムビューについても同様に差分を取得する（SELECT文の `c.relkind = 'r'`の箇所を`v`に変更する）。

```sql
SELECT c.relname, attname, atttypid
FROM pg_class c JOIN pg_attribute a ON (a.attrelid = c.oid) JOIN pg_namespace ns ON (c.relnamespace = ns.oid)
WHERE ns.nspname = 'pg_catalog' AND c.relkind ='v'
ORDER BY c.relname, a.attname
;
```
# テーブル/ビュー単位での変更まとめ
システムテーブルのテーブル単位での新規追加はないが、システムビューはいくつか新規追加されたものがある。

## システムテーブル
新規にテーブル単位で追加されたものはなさそう。
ということは新規にDDLが追加されるということもなさそうかな。

|テーブル名|変更種別|修正概要|
|:--|:-:|:--|
|pg_collation|変更|colliculocal列eの削除<br>colllocale列の追加|
|pg_constraint|変更|conperiod列の追加|
|pg_database|変更|daticulocale列の削除<br>datlocale列の追加<br>dathasloginevt列の追加|
|pg_statistic_ext|変更|stxstattarget列の型変更|
|pg_subscription|変更|subfailover列の追加|


## システムビュー
PostgreSQL 17では``pg_stat_checkpointer``と``pg_wait_event``ビューが追加された。
また、progress系のシステムビューにいくつか変更が入っている。

|ビュー名|変更種別|修正概要|
|:--|:-:|:--|
|pg_replication_slots|変更||
|pg_stat_bgwriter|変更|多くの列の削除|
|pg_stat_checkpointer|追加|チェックポイントに関する活動統計ビューの追加|
|pg_stat_progress_copy|変更|tuples_skipped列の追加|
|pg_stat_progress_vacuum|変更|dead tupleに関する列の変更<br>インデックスに関する列の追加|
|pg_stat_subscription|変更||
|pg_stats|変更|範囲型に関する列が追加されている。|
|pg_wait_event|追加|待機イベントに関すす説明が入っているシステムビュー。|

# 変更内容の詳細

## システムテーブル
### pg_collation
このシステムテーブルは、SQL名とオペレーティングシステムのロケールカテゴリとの基本的な対応付けを行う照合順序を管理するもの。``CREATE COLLATION``で新規に定義した照合順序もここで管理される。

PostgreSQL 17では以下の列が追加された。
|列名|データ型|説明|
|:--|:--|:--|
|colllocale|text|この照合順序オブジェクトのICUロケールID。|

また、PostgreSQL 17では以下の列が削除された。
|列名|データ型|説明|
|:--|:--|:--|
|colliculocale|text|この照合順序オブジェクトの照合順序プロバイダのロケール名。プロバイダがlibc の場合、colllocaleはNULL。|

``colliculocaleh``の設定は、``collcollate``や``collctype``の設定にも関連しているようだ。

### pg_constraint
このシステムテーブルはテーブルに対する検査制約、not-null制約、主キー制約、一意制約、外部キー制約、排他制約を格納する。

PostgreSQL 17では以下の列が追加された。
|列名|データ型|説明|
|:--|:--|:--|
|conperiod|bool|この制約はがWITHOUT OVERLAPS（主キーと一意制約の場合）またはPERIOD（外部キーの場合）で定義されたものかを示す。|

``WITHOUT OVERLAPS``も``PERIOD``も知らない制約だな・・・。
``ALTER TABLE``の構文にも変更あるのかな。後で調べてみよう。

### pg_database
このシステムテーブルはデータベースに関する様々な情報を管理するシステムテーブルである。

PostgreSQL 17では以下の列が追加された。

|列名|データ型|説明|
|:--|:--|:--|
|datlocale|text|このデータベースの照合順序プロバイダのロケール名。プロバイダがlibcの場合、datlocaleは NULLとなり、代わりにdatcollateと datctypeが使用される。|
|dathasloginevt|bool|このデータベースにログインイベントトリガが定義されていることを示す。このフラグは、各バックエンドの起動時にpg_event_triggerテーブルの余分な検索を避けるために使用される。このフラグはPostgreSQLが内部的に使用するものであり、監視のために手動で変更したり読み込んだりすべきではない。|

ほう！**ログインイベントトリガ**という機能が追加されたのかな。
データベースログイン契機で何か処理をさせることができそう。きちんと調べてみないとわかんないけど、例えばログイン履歴をテーブルに挿入できたりすんのかな。面白そう。

また、PostgreSQL 17では以下の列が削除された。

|列名|データ型|説明|
|:--|:--|:--|
|daticulocale|text|このデータベースのICUロケールID|

### pg_statistic_ext
このシステムテーブルはインデックスに関する情報の一部を管理している。
PostgreSQL 17では以下の列が追加された。

|列名|データ型|説明|
|:--|:--|:--|
|stxstattarget|int2|stxstattargetは、ANALYZEによってこの統計オブジェクトに蓄積される統計の詳細レベルを制御する。ゼロ値は統計情報を収集しないことを示す。NULL値は、参照される列の統計対象の最大値（設定されている場合）、またはシステムのデフォルトの統計対象を使用することを示す。stxstattargetの正の値は、収集する「最も一般的な値」の目標数を決定する|

拡張統計情報を持つ列への``ANALYZE``の挙動を制御するパラメータなのかな。
このシステムカタログは``CREATE STATISTICS``と関連してそうな気がするけど、現時点(2024-04-17)のPostgreSQL文書の``CREATE STATISTICS``のページ見ても、それっぽい記述ないんだよな・・・。


### pg_subscription
既存のすべての論理レプリケーション・サブスクリプションが含まれる。

PostgreSQL 17では以下の列が追加された。

|列名|データ型|説明|
|:--|:--|:--|
|subfailover|bool|trueの場合、上流データベースの関連するレプリケーション・スロット（メイン・スロットとテーブル同期スロット）は、スタンバイ・データベースと同期できるようになる。|

これはPostgreSQL 17で追加される予定の``sync_replication_slots``とも関連していそう。
ストリーミングレプリケーション＋論理レプリケーション構成を組んで検証が必要そう。



## システムビュー
### pg_replication_slots

データベースクラスタ上に現在存在する全てのレプリケーションスロットとその現在の状態の一覧を表示する。

PostgreSQL 17では以下の列が追加された。

|列名|データ型|説明|
|:--|:--|:--|
|failover|boolean|フェイルオーバー後に新しいプライマリから論理レプリケーションを再開できるように、この論理スロットがスタンドバイへの同期が有効になっている場合はtrue。物理スロットの場合は常にfalse。|
|inactive_since |timestamptz|スロットが非アクティブになってからの時間。スロットが現在使用されている場合はNULL。プライマリサーバから同期されているスタンバイ上のスロット（そのsyncedフィールドがtrue）の場合、inactive_sinceは最後の同期時刻を示す。|
|invalidation_reason|text|スロットが無効になった理由。論理スロットと物理スロットの両方に設定される。スロットが無効でない場合はNULL。値域は以下。<br>``wal_removed``：必要なWALが削除された。<br>``rows_removed``：必要な行が削除された。論理スロットに対してのみ設定される。<br>``wal_level_insufficient``：プライマリが論理デコードを実行するのに十分なwal_levelを持っていないことを意味する。論理スロットに対してのみ設定される。|
|synced|bool|プライマリサーバーから同期された論理スロットである場合、true。<br>ホットスタンバイでは、syncedカラムがtrueとマークされたスロットは、論理デコードに使用することも、手動でドロップすることもできまない。<br>このカラムの値はプライマリ・サーバ上では意味を持たない。<br>プライマリでのカラム値はすべてのスロットでデフォルトのfalseだが、（昇格スタンバイから残っている場合は）trueになることもある。|

``synced``の説明が難しい・・・


### pg_stat_bgwriter

データベースクラスタのバックグラウンドライタに関する情報。
１行のみ存在する。

PostgreSQL 17では大幅に列が削除された。後述する``pg_stat_checkpointer``に移動したのかな。
このビューをSQL文で監視している場合、削除対象の列を含んでいないか要確認。

以下の列が削除された。

|列名|データ型|説明|
|:--|:--|:--|
|buffers_backend |bigint|バックエンドが直接書き込んだバッファの数。|
|buffers_backend_fsync |bigint|バックエンドが独自のfsync呼び出しを実行しなければならなかった回数。|
|buffers_checkpoint |bigint|チェックポイント中に書き込まれたバッファの数。|
|checkpoint_sync_time |double precision|チェックポイント処理のうち、ファイルがディスクに同期される部分に費やされた時間の合計（ミリ秒単位）。|
|checkpoint_write_time |double precision|チェックポイント処理のうち、ファイルがディスクに書き込まれる部分に費やされた時間の合計（ミリ秒単位|
|checkpoints_req |bigint|要求されたチェックポイントが実行された数。|
|checkpoints_timed |bigint|スケジュールされたチェックポイントが実行された数。|

### pg_stat_checkpointer
PostgreSQL 17から追加された活動統計ビュー。
データベースクラスタのcheckpointerプロセスに関するデータをもつ。
このビューは常に1行のみ存在する。

|列名|データ型|説明|
|:--|:--|:--|
|num_timed  |bigint|スケジュール実行されたチェックポイントの数。　|
|num_requested  |bigint|リクエストされたチェックポイントが実行された数。　|
|restartpoints_timed  |bigint|タイムアウトのため、またはリスタートポイントの実行に失敗したためにスケジュール実行されたリスタートポイントの数。（翻訳あやしい）　|
|restartpoints_req |bigint|要求されたリスタートポイントの数。　|
|restartpoints_done  |bigint|実行されたリスタートポイントの数。　|
|write_time  |double precision|チェックポイントとリスタートポイントの処理のうち、ファイルがディスクに書き込まれる部分に費やされた時間の合計（ミリ秒単位）。　|
|sync_time  |double precision|チェックポイントとリスタートポイントの処理のうち、ファイルがディスクに同期される部分に費やされた時間の合計（ミリ秒単位）。　|
|buffers_written  |bigint|チェックポイントとリスタートポイント中に書き込まれたバッファの数　|
|stats_reset  |timestamptz|チェックポイントとリスタートポイント中に書き込まれたバッファの数の統計が最後にリセットされた時間　|

チェックポイントだけでなくリスタートポイントに関する統計情報も取得しているようだ。

### pg_stat_progress_copy
COPYが実行されている場合、pg_stat_progress_copyビューには、現在COPYコマンドを実行しているバックエンドごとに1行表示される。
PostgreSQL 17では以下の列が追加された。

|列名|データ型|説明|
|:--|:--|:--|
|tuples_skipped |bigint|不正なデータを含むためにスキップされたタプルの数。このカウンタは、ON_ERRORオプションにstop以外の値が指定された場合にのみ進む。|

PostgreSQL 17では不正なフォーマットの入力行があってもスキップする機能が入るので、それに対応する列が追加されたっぽい。

### pg_stat_progress_vacuum
現在バキューム処理中のバックエンド（autovacuumワーカープロセスを含む）毎に1行が含まれます。
PostgreSQL 17では以下の列が削除された。

|列名|データ型|説明|
|:--|:--|:--|
|max_dead_tuples |bigint | |
|num_dead_tuples |bigint | |

また、以下の列が追加された。

|列名|データ型|説明|
|:--|:--|:--|
|dead_tuple_bytes |bigint | |
|indexes_processed |bigint | |
|indexes_total |bigint | |
|max_dead_tuple_bytes |bigint | |

### pg_stat_subscription
（そういえば、このビュー自体の説明文ってPostgreSQL文書にないな）

PostgreSQL 17では以下の列が追加された。

|列名|データ型|説明|
|:--|:--|:--|
|worker_type |text |サブスクリプションワーカープロセスのタイプ。<br>値域はapply, parallel apply, table synchronization |

### pg_stats

PostgreSQL 17では以下の列が追加された。

|列名|データ型|説明|
|:--|:--|:--|
|range_bounds_histogram |anyarray |非emptyおよび非NULLの範囲値の下限値と上限値のヒストグラム。(非範囲型の場合は Null）。<br>これらの2つのヒストグラムは範囲の1つの配列として表現され、その下界は下界のヒストグラムを表し、上界は上界のヒストグラムを表す。 |
|range_empty_frac |float4 |値が空の範囲である列エントリの割合。(範囲型でない場合は NULL) |
|range_length_histogram |anyarray |範囲型カラムの非空および非NULL範囲値の長さのヒストグラム(範囲型でない場合は Null)。このヒストグラムは、範囲の境界が包括的であるかどうかに関係なく、subtype_diffrange関数を使用して計算される。|

範囲型に関連する列が追加されているということは、何か配列型に関するプランナの改善があったのかな・・・。

### pg_wait_events
PostgreSQL 17から追加されたシステムビュー。
待ちイベントに関する説明を提供する。

|列名|データ型|説明|
|:--|:--|:--|
|type   |text|待機イベントのタイプ　|
|name    |text|待機イベントの名前|
|description    |text|待機イベントの説明　|

ただ、``pg_stat_activity``の``wait_event_type``や``wait_event``はそのまま。
``pg_wait_events``のoidに置き換わるわけではなさそう（少なくとも現時点では）。

# おわりに
ざっと見た感じでは、新規のDDLコマンドが追加されそうな大きな変更はなさそう。
ただ、ログインイベントトリガなどの機能に関する変更もありそうなので、そのあたりの新規機能は調べておきたい。

今日の調査時点では差分の内容について不明確なものも多いので、今後、他の機能調査結果と合わせて随時補完していきたい。
また、PostgreSQL文書も今後、改訂・追記されていくと思うので、それに合わせてこの調査内容も随時修正しようと思う。