システムカタログの差分

# はじめに
にゃーん
この記事は、[PostgreSQL 10全部ぬこ Advent Calendar 2017](https://qiita.com/advent-calendar/2017/pg10-nuko-only) の14日目のエントリです。

# PostgreSQLのシステムカタログ
PostgreSQL、特にDDLや監視用の稼働統計情報などは、pg_catalogスキーマに置かれているシステムカタログや、稼働統計情報ビューによって管理されている。
システムカタログとして、どういった情報が定義されているか、また稼働統計情報ビューの定義を見ると、どういった機能が実装されているか、おぼろげながら分かると思う。
また、新バージョンにどういった機能が追加されているかも、これらの情報を確認することで分かることもある。

ということで、今日はシステムカタログの差分から、どういった機能がPostgreSQL 10で実装されたのかを追ってみることにする。

# 差分の求め方
差分を求めるために、PostgreSQL文書を比較してみるのもいいが、ぬこは英語が大変苦手なので、そういう面倒なことはしたくない。にゃーん。
なので、PostgreSQL 9.6, PostgreSQL 10に対してクエリを発行し、その結果をdiffるという方法で今回は差分を見つけ出してみたい。

使うクエリは以下の2つ。

* クエリ1：リレーションの単位で差分を見つける

```postgres
SELECT c.relkind, c.relname
  FROM pg_class c
  WHERE c.relname LIKE 'pg_%' AND c.relkind IN ('r','v') 
  ORDER BY  c.relkind, c.relname
;
```

* クエリ2：属性の単位で差分を見つける。

```postgres
SELECT c.relkind, c.relname, a.attname, t.typname 
  FROM pg_class c JOIN pg_attribute a ON (c.oid = a.attrelid) 
    JOIN pg_type t ON (t.oid = a.atttypid)
  WHERE c.relname LIKE 'pg_%' AND c.relkind IN ('r','v') 
  ORDER BY  c.relkind, c.relname, a.attname
;
```
これらのクエリをPostgreSQL 9.6, PostgreSQL 10で実行し、その結果をファイルに書き出しておき、その差分をdiffを使って探す。
psqlで実行する場合、以下のようにすると楽。

* ```\a``` メタコマンドでnoalignにしておく。余計な空白が入らないので、diffしやすくなる。
* ```\o <filename>``` でメタコマンドで、指定したファイルに結果を書き込む

本当はrelnameではなく、pg_catalogスキーマ上のリレーションを探すようなクエリが正しいのだが、今回はちょっとズルして、'LIKE pg_%'で探すことにする。
(スキーマ名で探すと、もう1つJOINを追加しなきゃいけない)
また、差分を見つけるためなら、実はクエリ2だけでもいいのだけど、まずリレーション単位での差分だけを確認しておきたいというケースもあるので、今回はクエリ1も掲載した。

# PostgreSQL 9.6とPostgreSQL 10の差分
## リレーション単位
リレーション単位だと、以下のテーブル/ビューが追加されている。

|種別|名前|関連する追加機能|
|:--|:--|:--|
|テーブル|pg_partitioned_table|宣言パーティション|
|テーブル|pg_publication |ロジカルレプリケーション |
|テーブル|pg_publication_rel |ロジカルレプリケーション |
|テーブル|pg_sequence |CREATE SEQUENCE AS|
|テーブル|pg_statistic_ext |複数列間の拡張統計機能 |
|テーブル|pg_subscription |ロジカルレプリケーション |
|テーブル|pg_subscription_rel |ロジカルレプリケーション |
|ビュー|pg_hba_file_rules |ビューによるpg_hba.confの参照 |
|ビュー|pg_publication_tables |ロジカルレプリケーション |
|ビュー|pg_sequences |CREATE SEQUENCE AS |
|ビュー|pg_stat_subscription |ロジカルレプリケーション |


## 属性単位
先に上げた、リレーション単位での追加内容以外のものを列挙する。

|テーブル/ビュー名|属性名|型名|変更点|関連する機能|
|:--|:--|:--|:--|:--|
|pg_attribute|attidentity|char|列の追加|ID列|
|pg_class|relispartition|bool|列の追加|宣言パーティション|
|pg_class|relpartbound|pg_node_tree|列の追加|宣言パーティション|
|pg_collation|collprovider|char|列の追加|ICUコレーションサポート|
|pg_collation|collversion|text|列の追加|ICUコレーションサポート|
|pg_policy|polpermissive|bool|列の追加|CREATE POLICYのPERMISSIVE/RESTRICTIVE 句の追加|
|pg_trigger|tgnewtable|name|列の追加|トリガのtransition tables対応？|
|pg_trigger|tgoldtable|name|列の追加|トリガのtransition tables対応？|
|pg_policies|permissive|text|列の追加|CREATE POLICYのPERMISSIVE/RESTRICTIVE 句の追加|
|pg_replication_slots|temporary|bool|列の追加|テンポラリスロット対応|
|pg_stat_activity|backend_type|text|列の追加|wal_sender等のバックグラウンドプロセスの表示|
|pg_stat_replication|flush_location|pg_lsn|列の削除||
|pg_stat_replication|flush_lag|interval|列の追加|レプリケーション遅延時間の報告|
|pg_stat_replication|flush_lsn|pg_lsn|列の追加|flush_locationからのRENAME?|
|pg_stat_replication|replay_location|pg_lsn|列の削除||
|pg_stat_replication|replay_lag|interval|列の追加|レプリケーション遅延時間の報告|
|pg_stat_replication|replay_lsn|pg_lsn|列の追加|replay_locationからのRENAME?|
|pg_stat_replication|sent_location|pg_lsn|列の削除||
|pg_stat_replication|sent_lsn|pg_lsn|列の追加|sent_locationからのRENAME?|
|pg_stat_replication|write_location|pg_lsn|列の削除||
|pg_stat_replication|write_lag|interval|列の追加|レプリケーション遅延時間の報告|
|pg_stat_replication|write_lsn|pg_lsn|列の追加|write_locationからのRENAME?|

なお、```pg_stat_activity```の変更に関しては値域が変わったものもあり、別エントリで詳細を書く予定。


# おわりに
今日はPostgreSQL 9.6とPostgreSQL 10のシステムカタログの変更についてまとめてみた。やはりロジカルレプリケーションと宣言パーティションという大きな2つの機能が追加されたことで、システムカタログについても、大きな変更があったことがわかる。

稼働統計情報ビューに関しては、```pg_stat_activity```と```pg_stat_replication```くらいしか変更はないが、ここの2つを監視することは運用上多いと思うので、この変更についてはしっかりと確認しておく必要がある。

# 参考：該当するリリースノート
本エントリに関連するPostgreSQL 10リリースノートの記載ですが、今回はいろいろあるので割愛。
システムテーブルの追加や変更＝機能追加なんだよねぇ。