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

# はじめに
にゃーん

今回は、PostgreSQL 14とPostgreSQL 15のシステムカタログの差分を調べてみる。
これもまだbeta1版なので、今後変わっていく可能性が大きいけど、現時点の版で調査をしてみた。

## 調査方法
PostgreSQL 14とPostgreSQL 15それぞれで以下の手順を実施。

* psqlでログイン
* `\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
;
```
# テーブル/ビュー単位での変更まとめ
システムテーブルのテーブル単位での新規追加はないが、システムビューはいくつか新規追加されたものがある。

## システムテーブル
新規にテーブル単位で追加されたものは、``pg_parameter_acl``と``pg_publication_namespace``の2つ。

|テーブル名|変更種別|その他修正|
|:--|:-:|:--|
|pg_collation|変更|collcollate列, collctype列の型変更(name→text)<br>colliculocale列の追加|
|pg_constraint|変更|confdelsetcols列の追加|
|pg_database|変更|datcollate列,datctype列の型変更(name→text)<br>datcollversion列,daticulocale列,datlocprovider列の追加<br>datlastsysoid列の削除<br>
|pg_index|変更|indnullsnotdistinct列の追加|
|pg_parameter_acl|追加|1つ以上のロールに権限が付与されている設定パラメータを記録するシステムテーブル|
|pg_publication_namespace|追加|データベース内のスキーマとパブリケーションの間のマッピングを記録するシステムテーブル|
|pg_publication_rel|変更|prattrs列,prqual列の追加|
|pg_statistic_ext_data|変更|stxdexpr列の型変更(pg_statistic[]であるのは変わりないが型のoidが異なる)<br>stxdinherit列の追加|
|pg_subscription|変更|subdisableonerr列,subskiplsn列,subtwophasestate列の追加|


## システムビュー
追加されたシステムビューは``pg_ident_file_mappings``,``pg_stat_recovery_prefetch``,``pg_stat_subscription_stats``の3つ。

|ビュー名|変更種別|その他修正|
|:--|:-:|:--|
|pg_ident_file_mappings|追加|pg_ident.confの内容の要約を提供するシステムビュー|
|pg_stat_recovery_prefetch|追加|リカバリ時のWALプリフェッチに関する情報を提供する活動統計ビュー|
|pg_stat_subscription_stats|追加|サブスクリプションへの反映時のエラー数などを提供する活動統計ビュー。|
|pg_stats_ext|変更|inherited列の追加|
|pg_stats_ext_exprs|変更|inherited列の追加|

# 変更内容の詳細

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

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

### pg_constraint
このシステムテーブルは非NULL制約以外の制約を管理するシステムテーブルである。

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

|列名|データ型|説明|
|:--|:--|:--|
|confdelsetcols|int2\[\]|外部キーが SET NULL または SET DEFAULT 削除アクションを持つ場合、更新されるカラムを指定する。<br>NULLの場合、参照しているすべてのカラムが更新される。|

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

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

|列名|データ型|説明|
|:--|:--|:--|
|datcollversion|text|照合順序のプロバイダー固有のバージョン。<br>データベース作成時に記録され、使用時にチェックされ、データ破損につながる照合順序の定義の変更を検出するために使用される。|
|daticulocale|text|このデータベースのICUロケールID|
|datlocprovider|text|(現時点ではPostgreSQL文書に記載なし)|

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

|列名|データ型|説明|
|:--|:--|:--|
|datlastsysoid|oid|データベース最終のシステムOID。<br>以前は``pg_dump``でなにか使っていたような記述があったが、これが削除されたことにより、PostgreSQL 15の``pg_dump``にも何かしら影響があるのかもしれない。|

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

|列名|データ型|説明|
|:--|:--|:--|
|indnullsnotdistinct|bool|この列は一意インデックスにのみ使用される。<br>falseの場合、この一意インデックスはNULL値を区別するものとみなす。<br>true の場合、NULL 値を等しいとみなす。<br>この列を見てプランナが何かしら判断するのだろうか？|

### pg_parameter_acl
PostgreSQL 15から追加されたシステムテーブル。
このシステムテーブルは、1つ以上のロールに権限が付与されている設定パラメータを管理する。。デフォルトの権限を持つパラメータについてはここでは管理はしない。
また、ほとんどのシステムカタログとは異なり、pg_parameter_aclはクラスタの全てのデータベースで共有される。

pg_parameter_aclは以下の列から構成される。

|列名|データ型|説明|
|:--|:--|:--|
|oid|oid|このテーブルのID。|
|parname|text|権限を付与するコンフィギュレーションパラメータ名。|
|paracl |aclitem[]|アクセス権。|

### pg_publication_namespace
PostgreSQL 15から追加されたシステムテーブル。
データベース内のスキーマとパブリケーションの間のマッピング管理する。
これは多対多のマッピングになる。

pg_publication_namespaceは以下の列から構成される。

|列名|データ型|説明|
|:--|:--|:--|
|oid|oid|このテーブルのID|
|pnpubid |oid|PUBLICATIONの参照。|
|pnnspid |oid|スキーマの参照。|

### pg_publication_rel
このシステムテーブルは、データベース内のリレーションとパブリケーションのマッピングを管理するもの。
PostgreSQL 15では以下の列が追加された。

|列名|データ型|説明|
|:--|:--|:--|
|prattrs|int2vector|どのテーブルカラムがパブリケーションの一部であるかを示す値の配列である。ヌル値は、すべてのカラムがパブリッシュされることを意味する。<br>一部の列のみを論理レプリケーションできるようになった、ということかな？|
|prqual|pg_node_tree|パブリッシャ条件のExpresson Tree (nodeToString() 表現)。パブリッシャの条件がない場合は NULL。|

``prattrs``は以下のリリースノート記述が関係していそう。

> Allow publications to be restricted to specific columns (Tomas Vondra, Álvaro Herrera, Rahila Syed)

``prqual``は以下のリリースノート記述が関係していそう。

> Allow publication content to be filtered using a WHERE clause (Hou Zhijie, Euler Taveira, Peter Smith, Ajin Cherian, Tomas Vondra, Amit Kapila)

### pg_statistic_ext_data
このシステムテーブルはこのシステムテーブルはpg_statistic_extで定義されたプランナの拡張統計情報のデータを管理する（``CREATE STATISTICS``コマンドで作成された拡張統計情報が入っていると思えば良い）。
PostgreSQL 15では以下の列が追加された。

|列名|データ型|説明|
|:--|:--|:--|
|stxdinherit|boolean|trueの場合、統計情報は指定されたリレーションの値だけでなく、継承された子カラムも含む。|

### pg_subscription
このシステムテーブルはサブスクリプションの定義に関する情報を管理している。
PostgreSQL 15では以下の列が追加された。

|列名|データ型|説明|
|:--|:--|:--|
|subdisableonerr|boolean|true の場合、ワーカーの1つがエラーを検出すると、サブスクリプションは無効になる。<br>これはCREATE SUBSCRIPTIONのコマンドの変更もセットでみないといけないかな。|
|subskiplsn|pg_lsn|変更をスキップするトランザクションの終了 LSN（有効な LSN の場合）、それ以外は ``0/0``。<br>論理レプリケーションの変更スキップについてもなんか変更があったってことかな。|
|subtwophasestate|char|二相モードの状態コード：d＝無効、p＝有効化待ち、e＝有効。<br>論理レプリケーション＆二相コミットまわりの改善項目に関係しているのかな。要確認。<br>型が`enum`はなく`char`な理由は良くわからないけど。|


## システムビュー
### pg_ident_file_mappings
PostgreSQL 15で追加されたビュー。
クライアントユーザ名マッピング設定ファイル``pg_ident.conf``の内容の要約を提供する。このビューには、ファイル内の空でない、コメントでない行ごとに行が表示され、ルールが正常に適用できたかどうかを示す注釈が付く。
以前からpg_hba.confの内容の要約を提供するシステムビュー ``pg_hba_file_rules``があったが、それの``pg_ident.conf``版っぽい。

pg_ident_file_mappingsは以下の5列から構成される。

|列名|データ型|説明|
|:--|:--|:--|
|line_number |int4|``pg_ident.conf``ファイル内の行数。|
|map_name |text|マッピングの名前。|
|sys_name |text|検出されたクライアントのユーザー名。|
|pg_username |text|要求されたPostgreSQLのユーザー名。|
|error|text|NULLでない場合、この行を処理できなかった理由を示すエラーメッセージを表示する。|

### pg_stat_recovery_prefetch
PostgreSQL 15から追加された活動統計ビュー。
1行のみ存在する。
wal_distance、block_distance、io_depth列は現在の値を示し、その他の列はpg_stat_reset_shared関数でリセット可能な累積カウンタを示す。
たぶん、リカバリ時のWALプリフェッチに関する統計情報を見せるものなんだろうな。

この活動統計ビューは以下の列から構成される。

|列名|データ型|説明|
|:--|:--|:--|
|prefetch |bigint|バッファプールにないためプリフェッチされたブロック数。|
|hit|bigint|すでにバッファプールにあったためプリフェッチされなかったブロック数。|
|skip_init|bigint|ゼロ初期化されるためプリフェッチされなかったブロック数。|
|skip_new|bigint|まだ存在しないためにプリフェッチされなかったブロック数。|
|skip_fpw|bigint|WALにフルページイメージが含まれていたため、プリフェッチされなかったブロック数。|
|skip_rep|bigint|最近プリフェッチされたため、プリフェッチされなかったブロック数。|
|wal_distance|int|プリフェッチャが何バイト先を見ているか。|
|block_distance|int|プリフェッチャが何ブロック先を見ているか。|
|io_depth|int|開始されたものの、完了したことが確認されていないプリフェッチの数。|

この活動統計ビューを使ってどういう監視をすることを考えているのかな・・・？


### pg_stat_subscription_stats
PostgreSQL 15から追加された活動統計ビュー。
pg_stat_subscription_statsビューは、サブスクリプションごとに1行存在する。

この活動統計ビューは以下の5列から構成される。

|列名|データ型|説明|
|:--|:--|:--|
|subid |oid|サブスクリプションのOID。|
|subname|name|サブスクリプション名。|
|apply_error_count|bigint|変更の適用中にエラーが発生した回数。|
|sync_error_count|bigint|初期テーブル同期時にエラーが発生した回数。|
|stats_reset|timestamp with time zone|この統計情報が最後にリセットされた時刻。|

これを使った論理レプリケーションの監視方式も考えておかないとなあ。

### pg_stats_ext
このシステムビューは、``pg_statistic_ext``と``pg_statistic_ext_data``に格納された情報を組み合わせて、データベース内の各拡張統計オブジェクトに関する情報へのアクセスを提供する。
PostgreSQLでは以下の列が追加された。

|列名|データ型|説明|
|:--|:--|:--|
|inherited|boolean|true の場合、この行は指定されたテーブルの値だけでなく、継承された子カラムも含む。（多分）<br>（多分）というのは、現時点ではPostgreSQL文書には記述されていないから。|

### pg_stats_ext_exprs
このシステムビューは``pg_statistic_ext``と``pg_statistic_ext_data``に格納された情報を組み合わせて、拡張統計オブジェクトに含まれる全ての式に関する情報へのアクセスを提供する。
PostgreSQL 15では以下の列が追加された。

|列名|データ型|説明|
|:--|:--|:--|
|inherited|boolean|true の場合、この行は指定されたテーブルの値だけでなく、継承された子カラムも含む。（多分）<br>（多分）というのは、現時点ではPostgreSQL文書には記述されていないから。|


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