-
2023-05-24 PostgreSQL
PostgreSQL 15 で追加された pg_walinspect 拡張モジュールの概要
PostgreSQL 15 から pg_walinspect という拡張モジュールが追加されました。
この pg_walinspect 拡張モジュールを利用することで、WAL レコードの情報を SQL コマンドで確認できます。
PostgreSQL 14 以前で、WAL レコードの情報を確認しようとすると、OS コマンドである pg_waldump(pg_xlogdump)を利用していたのですが、PostgreSQL 15 からは pg_walinspect 拡張モジュールを利用して SQL コマンドで確認できるようになったことになります。
公式ドキュメントの URL は下記となります。
https://www.postgresql.org/docs/current/pgwalinspect.html
pg_walinspect 拡張モジュールの導入方法
pg_walinspect 拡張モジュールを利用できるようにするには、通常の拡張モジュールと同様の方法となります。
ソースコードのインストールを行い、その後、CREATE EXTENSION で拡張モジュールを導入します。
その際、shared_preload_libraries パラメータへの記入は不要となります。
具体的な pg_walinspect 拡張モジュールの導入手順の例
1. pg_walinspect 拡張モジュールのディレクトリに移動します
$ cd ./postgresql-15.2/contrib/pg_walinspect
- ./postgresql-15.2 が PostgreSQL 15 のソースコードのディレクトリです。
2. pg_config にパスが通っているか確認します。
$ pg_config --version
PostgreSQL 15.2
- pg_config にパスが通っていない場合は、通してください。
3. pg_walinspect 拡張モジュールをコンパイルします
$ make USE_PGXS=1
$ sudo make install USE_PGXS=1
4. psql でデータベースクラスタに接続して、CREATE EXTENSION コマンドを実行します
$ psql -c "CREATE EXTENSION pg_walinspect"
CREATE EXTENSION
5. インストールされているかを確認します
postgres=# SELECT * FROM pg_extension;
oid | extname | extowner | extnamespace | extrelocatable | extversion | extconfig | extcondition
-------+---------------+----------+--------------+----------------+------------+-----------+--------------
12755 | plpgsql | 10 | 11 | f | 1.0 | |
24576 | pg_walinspect | 10 | 2200 | t | 1.0 | |
(2 rows)
- 結果内に pg_walinspect が含まれていると、問題なくインストールされています。
pg_walinspect 拡張モジュールが提供する関数
pg_walinspect 拡張モジュールには 5 つの関数が用意されています。
- pg_get_wal_record_info
- pg_get_wal_records_info
- pg_get_wal_records_info_till_end_of_wal
- pg_get_wal_stats
- pg_get_wal_stats_till_end_of_wal
の 5 つです。
pg_walinspect 拡張モジュールが提供する関数の実行例
pg_walinspect 拡張モジュールが提供する関数を実際に実行し、どのような結果が返ってくるのかを確認します。
※詳しい引数や結果などは、前述の公式ドキュメント上に記載されていますので、合わせてご参照ください。
pg_get_wal_record_info 関数
pg_get_wal_record_info 関数に pg_lsn 型の値を指定して実行すると、その WAL 情報が出力されます。
pg_get_wal_record_info 関数の実行例を下記に記載します。
postgres=# SELECT pg_current_wal_lsn();
pg_current_wal_lsn
--------------------
0/35000000
(1 row)
postgres=# SELECT * FROM pg_get_wal_record_info('0/35000000');
start_lsn | end_lsn | prev_lsn | xid | resource_manager | record_type | record_length | main_data_length | fpi_length | description | block_ref
------------+------------+------------+-----+------------------+---------------+---------------+------------------+------------+---------------------------------------------------------------------------+-----------
0/35000028 | 0/35000060 | 0/34029B18 | 0 | Standby | RUNNING_XACTS | 54 | 28 | 0 | nextXid 1583 latestCompletedXid 1581 oldestRunningXid 1582; 1 xacts: 1582 |
(1 row)
- pg_current_wal_lsn 関数で取得した、現在の WAL 書き込み先 lsn を pg_get_wal_record_info 関数の引数に指定していた結果です。
- 引数に指定した lsn の WAL 情報が出力されます。
- pg_get_wal_records_info 関数は、引数に指定した開始 lsn と終了 lsn の間の WAL 情報が出力されます。
- pg_get_wal_records_info_till_end_of_wal 関数は、引数に指定した lsn 以上の WAL 情報が出力されます。
pg_get_wal_stats 関数
pg_get_wal_stats 関数は「開始 lsn」「終了 lsn」「record_type ごとに出力するか」の 3 つの引数を指定できます。
第 3 引数の「record_type ごとに出力するか」に関しては、指定しない場合 false となります。
pg_get_wal_stats 関数の第 3 引数に false を指定した場合の実行例を、下記に記載します。
postgres=# SELECT * FROM pg_get_wal_stats('0/35000000', '0/350157B8') ORDER BY 1;
resource_manager/record_type | count | count_percentage | record_size | record_size_percentage | fpi_size | fpi_size_percentage | combined_size | combined_size_percentage
------------------------------+-------+--------------------+-------------+------------------------+----------+---------------------+---------------+--------------------------
BRIN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
Btree | 67 | 64.42307692307692 | 4373 | 41.623833999619265 | 50660 | 65.79562574679204 | 55033 | 62.89341957898105
CLOG | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
CommitTs | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
Database | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
Generic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
Gin | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
Gist | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
Hash | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
Heap | 14 | 13.461538461538462 | 1597 | 15.200837616600039 | 13588 | 17.64767000883163 | 15185 | 17.35388905396448
Heap2 | 11 | 10.576923076923077 | 2994 | 28.498001142204455 | 12660 | 16.442412592861967 | 15654 | 17.889876802815937
LogicalMessage | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
MultiXact | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
RelMap | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
ReplicationOrigin | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
SPGist | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
Sequence | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
Standby | 3 | 2.8846153846153846 | 138 | 1.313535122786979 | 0 | 0 | 138 | 0.1577106808987223
Storage | 3 | 2.8846153846153846 | 126 | 1.1993146773272416 | 0 | 0 | 126 | 0.1439967086466595
Tablespace | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
Transaction | 5 | 4.8076923076923075 | 1229 | 11.698077289168095 | 0 | 0 | 1229 | 1.4045393248154328
XLOG | 1 | 0.9615384615384616 | 49 | 0.4664001522939273 | 88 | 0.11429165151436438 | 137 | 0.15656784987771707
(22 rows)
pg_get_wal_stats 関数の第 3 引数に true を指定した場合の実行例を、下記に記載します。
postgres=# SELECT * FROM pg_get_wal_stats('0/35000000', '0/350157B8', true) ORDER BY 1;
resource_manager/record_type | count | count_percentage | record_size | record_size_percentage | fpi_size | fpi_size_percentage | combined_size | combined_size_percentage
------------------------------+-------+--------------------+-------------+------------------------+----------+---------------------+---------------+--------------------------
Btree/INSERT_LEAF | 66 | 63.46153846153846 | 4283 | 40.767180658671236 | 50660 | 65.79562574679204 | 54943 | 62.79056478709058
Btree/NEWROOT | 1 | 0.9615384615384616 | 90 | 0.8566533409480297 | 0 | 0 | 90 | 0.10285479189047107
Heap/HOT_UPDATE | 3 | 2.8846153846153846 | 218 | 2.0750047591852274 | 0 | 0 | 218 | 0.24913716257914104
Heap/INPLACE | 2 | 1.9230769230769231 | 376 | 3.5789072910717685 | 0 | 0 | 376 | 0.42970446389796807
Heap/INSERT | 7 | 6.730769230769231 | 852 | 8.109651627641348 | 13588 | 17.64767000883163 | 14440 | 16.50247994331558
Heap/INSERT+INIT | 2 | 1.9230769230769231 | 151 | 1.4372739387016942 | 0 | 0 | 151 | 0.17256748417179035
Heap2/MULTI_INSERT | 10 | 9.615384615384615 | 2902 | 27.62231106034647 | 12660 | 16.442412592861967 | 15562 | 17.784736348883452
Heap2/PRUNE | 1 | 0.9615384615384616 | 92 | 0.8756900818579859 | 0 | 0 | 92 | 0.10514045393248155
Standby/LOCK | 2 | 1.9230769230769231 | 84 | 0.799543118218161 | 0 | 0 | 84 | 0.09599780576443967
Standby/RUNNING_XACTS | 1 | 0.9615384615384616 | 54 | 0.5139920045688178 | 0 | 0 | 54 | 0.06171287513428265
Storage/CREATE | 3 | 2.8846153846153846 | 126 | 1.1993146773272416 | 0 | 0 | 126 | 0.1439967086466595
Transaction/ABORT | 1 | 0.9615384615384616 | 34 | 0.32362459546925565 | 0 | 0 | 34 | 0.03885625471417796
Transaction/COMMIT | 4 | 3.8461538461538463 | 1195 | 11.374452693698839 | 0 | 0 | 1195 | 1.3656830701012548
XLOG/FPI | 1 | 0.9615384615384616 | 49 | 0.4664001522939273 | 88 | 0.11429165151436438 | 137 | 0.15656784987771707
(14 rows)
- 第 3 引数が false と true の結果を比較すると、true の場合がより細かく結果が出力されていることを確認できました(あと、count = 0 の情報は出力されていないようです)。
- pg_get_wal_stats 関数の内容は、pg_get_wal_record_info 関数の結果を集約したような内容であることを確認できました。
- pg_get_wal_stats_till_end_of_wal 関数は、「開始 lsn」「record_type ごとに出力するか」を指定し、「開始 lsn」以降の WAL 情報が出力されます。
pg_waldump コマンドの実行結果
比較として、pg_waldump コマンドの実行結果も下記に記載します。
postgres@server:~/db_clusters$ pg_waldump 15a/pg_wal/000000010000000000000035 | head
rmgr: Standby len (rec/tot): 54/ 54, tx: 0, lsn: 0/35000028, prev 0/34029B18, desc: RUNNING_XACTS nextXid 1583 latestCompletedXid 1581 oldestRunningXid 1582; 1 xacts: 1582
rmgr: Heap len (rec/tot): 79/ 79, tx: 1582, lsn: 0/35000060, prev 0/35000028, desc: INSERT+INIT off 1 flags 0x00, blkref #0: rel 1663/5/25305 blk 0
rmgr: Btree len (rec/tot): 90/ 90, tx: 1582, lsn: 0/350000B0, prev 0/35000060, desc: NEWROOT lev 0, blkref #0: rel 1663/5/25306 blk 1, blkref #2: rel 1663/5/25306 blk 0
rmgr: Btree len (rec/tot): 64/ 64, tx: 1582, lsn: 0/35000110, prev 0/350000B0, desc: INSERT_LEAF off 1, blkref #0: rel 1663/5/25306 blk 1
rmgr: Transaction len (rec/tot): 34/ 34, tx: 1582, lsn: 0/35000150, prev 0/35000110, desc: COMMIT 2023-05-15 17:58:54.918760 JST
rmgr: Storage len (rec/tot): 42/ 42, tx: 0, lsn: 0/35000178, prev 0/35000150, desc: CREATE base/5/25308
rmgr: Heap len (rec/tot): 54/ 5370, tx: 1583, lsn: 0/350001A8, prev 0/35000178, desc: INSERT off 26 flags 0x00, blkref #0: rel 1663/5/24688 blk 14 FPW
rmgr: Btree len (rec/tot): 53/ 5373, tx: 1583, lsn: 0/350016A8, prev 0/350001A8, desc: INSERT_LEAF off 264, blkref #0: rel 1663/5/24693 blk 2 FPW
rmgr: Btree len (rec/tot): 53/ 2341, tx: 1583, lsn: 0/35002BC0, prev 0/350016A8, desc: INSERT_LEAF off 61, blkref #0: rel 1663/5/24694 blk 7 FPW
rmgr: Heap2 len (rec/tot): 57/ 7473, tx: 1583, lsn: 0/350034E8, prev 0/35002BC0, desc: MULTI_INSERT 1 tuples flags 0x02, blkref #0: rel 1663/5/24881 blk 13 FPW
- pg_get_wal_record_info 関数と同様の結果が出力されます。
- pg_walinspect 拡張モジュールが提供する関数は lsn を指定するのに対して、pg_waldump コマンドは WAL ファイル名を指定します。
- 出力結果が長いので head コマンドで抜粋しています。
-z オプションをつけて pg_waldump コマンドを実行
$ pg_waldump 15a/pg_wal/000000010000000000000035 -z
WAL statistics between 0/35000028 and 0/35018680:
Type N (%) Record size (%) FPI size (%) Combined size (%)
---- - --- ----------- --- -------- --- ------------- ---
XLOG 3 ( 1.86) 212 ( 1.42) 176 ( 0.21) 388 ( 0.39)
Transaction 8 ( 4.97) 2530 ( 16.98) 0 ( 0.00) 2530 ( 2.55)
Storage 5 ( 3.11) 210 ( 1.41) 0 ( 0.00) 210 ( 0.21)
CLOG 0 ( 0.00) 0 ( 0.00) 0 ( 0.00) 0 ( 0.00)
Database 0 ( 0.00) 0 ( 0.00) 0 ( 0.00) 0 ( 0.00)
Tablespace 0 ( 0.00) 0 ( 0.00) 0 ( 0.00) 0 ( 0.00)
MultiXact 0 ( 0.00) 0 ( 0.00) 0 ( 0.00) 0 ( 0.00)
RelMap 0 ( 0.00) 0 ( 0.00) 0 ( 0.00) 0 ( 0.00)
Standby 11 ( 6.83) 498 ( 3.34) 0 ( 0.00) 498 ( 0.50)
Heap2 13 ( 8.07) 3178 ( 21.33) 12660 ( 15.01) 15838 ( 15.95)
Heap 48 ( 29.81) 3493 ( 23.44) 20872 ( 24.74) 24365 ( 24.54)
Btree 73 ( 45.34) 4781 ( 32.08) 50660 ( 60.05) 55441 ( 55.85)
Hash 0 ( 0.00) 0 ( 0.00) 0 ( 0.00) 0 ( 0.00)
Gin 0 ( 0.00) 0 ( 0.00) 0 ( 0.00) 0 ( 0.00)
Gist 0 ( 0.00) 0 ( 0.00) 0 ( 0.00) 0 ( 0.00)
Sequence 0 ( 0.00) 0 ( 0.00) 0 ( 0.00) 0 ( 0.00)
SPGist 0 ( 0.00) 0 ( 0.00) 0 ( 0.00) 0 ( 0.00)
BRIN 0 ( 0.00) 0 ( 0.00) 0 ( 0.00) 0 ( 0.00)
CommitTs 0 ( 0.00) 0 ( 0.00) 0 ( 0.00) 0 ( 0.00)
ReplicationOrigin 0 ( 0.00) 0 ( 0.00) 0 ( 0.00) 0 ( 0.00)
Generic 0 ( 0.00) 0 ( 0.00) 0 ( 0.00) 0 ( 0.00)
LogicalMessage 0 ( 0.00) 0 ( 0.00) 0 ( 0.00) 0 ( 0.00)
-------- -------- -------- --------
Total 161 14902 [15.01%] 84368 [84.99%] 99270 [100%]
pg_waldump: error: error in WAL record at 0/35018648: invalid record length at 0/35018680: wanted 24, got 0
- -z オプションをつけて実行した場合、pg_get_wal_stats 関数と同様の結果が出力されます。
まとめ
簡単ですが、pg_walinspect 拡張モジュールの導入方法、実行例を記載いたしました。
WAL レコードの内容を確認する機会は少ないとは思いますが、WAL レコードの中身を眺めているだけでも面白いですよね。
機会があれば、pg_get_wal_record_info 関数の結果の解説などもしていければと思います。