LoginSignup
2
1

More than 3 years have passed since last update.

pg_waldump出力結果の読み方(INSERTの場合)

Last updated at Posted at 2019-07-02

最近、pg_waldumpの出力結果の読み方を聞かれる機会があったものの、ここをみればとりあえずOK。と言えそうなサイトがすぐに出てこなかったので、ここにメモを残しておきます。

pg_waldumpとは

マニュアルによると「pg_waldump — PostgreSQLデータベースクラスタの先行書き込みログ(=WAL)を可読性が高い表現で表示する」となっています。参照元はここです。

PostgreSQL 8.Xのころは「xlogdump」、9.Xでは「pg_xlogdump」など、名前は変えつつもなんだかんだ長く使われている優良ツールだと思います。
が、出力結果はテキストに変換されて人が読める形にはなるけど、WALがどんな物かを理解してないと決して見やすくはない感じです。
自分もそんなにちゃんと理解してるわけではないんですがね。

前準備(WALの準備)

pg_waldumpはWALを読むツールなので、読取り対象となるWALが存在している必要があります。
今回は下記のやり方で用意しました。

[postgres@localhost data]$ pg_ctl --version
pg_ctl (PostgreSQL) 11.4
[postgres@localhost data]$ echo $PGDATA
/var/lib/pgsql/11/data
[postgres@localhost data]$ pg_ctl init
データベースシステム内のファイルの所有者は"postgres"となります。
このユーザがサーバプロセスも所有する必要があります。
(中略)
成功しました。以下のようにしてデータベースサーバを起動できます。

    /usr/pgsql-11/bin/pg_ctl -D /var/lib/pgsql/11/data -l <ログファイル> start

[postgres@localhost data]$ pg_ctl start
サーバの起動完了を待っています....2019-07-02 22:00:15.617 JST [9748] LOG:  IPv6アドレス"::1"、ポート5432で待ち受けています
2019-07-02 22:00:15.618 JST [9748] LOG:  IPv4アドレス"127.0.0.1"、ポート5432で待ち受けています
2019-07-02 22:00:15.620 JST [9748] LOG:  Unixソケット"/var/run/postgresql/.s.PGSQL.5432"で待ち受けています
2019-07-02 22:00:15.624 JST [9748] LOG:  Unixソケット"/tmp/.s.PGSQL.5432"で待ち受けています
2019-07-02 22:00:15.678 JST [9748] LOG:  ログ出力をログ収集プロセスにリダイレクトしています
2019-07-02 22:00:15.678 JST [9748] ヒント:  ここからのログ出力はディレクトリ"log"に現れます。
完了
サーバ起動完了
[postgres@localhost data]$ psql
psql (11.4)
"help" でヘルプを表示します。

postgres=# create table test (c1 int);
CREATE TABLE
postgres=# insert into test values(1);
INSERT 0 1
postgres=# insert into test values(2);
INSERT 0 1
postgres=# select xmin,* from test;
 xmin | c1 
------+----
  569 |  1
  570 |  2
(2 行)

postgres=# \q

ここまでで、xid(=xmin)が569と570でINSERTされた行が2つできました。

次に手っ取り早くWALをファイルに書き出す為に postgres を再起動します。

[postgres@localhost data]$ pg_ctl restart
サーバ停止処理の完了を待っています....完了
サーバは停止しました
サーバの起動完了を待っています....2019-07-02 22:01:37.624 JST [9841] LOG:  IPv6アドレス"::1"、ポート5432で待ち受けています
2019-07-02 22:01:37.624 JST [9841] LOG:  IPv4アドレス"127.0.0.1"、ポート5432で待ち受けています
2019-07-02 22:01:37.627 JST [9841] LOG:  Unixソケット"/var/run/postgresql/.s.PGSQL.5432"で待ち受けています
2019-07-02 22:01:37.631 JST [9841] LOG:  Unixソケット"/tmp/.s.PGSQL.5432"で待ち受けています
2019-07-02 22:01:37.689 JST [9841] LOG:  ログ出力をログ収集プロセスにリダイレクトしています
2019-07-02 22:01:37.689 JST [9841] ヒント:  ここからのログ出力はディレクトリ"log"に現れます。
完了
サーバ起動完了
[postgres@localhost data]$ ls -lrt $PGDATA/pg_wal 
合計 16384
drwx------ 2 postgres postgres        6  7月  2 22:00 archive_status
-rw------- 1 postgres postgres 16777216  7月  2 22:01 000000010000000000000001
[postgres@localhost data]$ 

pg_waldump実行

下記のように実行して、WALの内容を表示します。
「--rmgr: Heap」をしていしているのは、テーブルやインデックスをのを更新するのはHeapリソースマネージャの役目なので、出力結果をHeapだけに絞るためです。(今回みたいな場合は「-x xid」でもよかったかも)
下記は先程の2件のINSERTに関する行のみ表示しています。これは「xt:」の後に表示されるトランザクションIDと、先程のINSERTの結果挿入された行のxmin列の対応関係で判断します。

[postgres@localhost pg_wal]$ cd $PGDATA/pg_wal
[postgres@localhost pg_wal]$ pg_waldump 000000010000000000000001 --rmgr=Heap
(中略)
rmgr: Heap        len (rec/tot):     59/    59, tx:        569, lsn: 0/016C8798, prev 0/016C8600, desc: INSERT+INIT off 1, blkref #0: rel 1663/13878/16384 blk 0
rmgr: Heap        len (rec/tot):     59/    59, tx:        570, lsn: 0/016C8800, prev 0/016C87D8, desc: INSERT off 2, blkref #0: rel 1663/13878/16384 blk 0

処理の内容は「desc:」の所で表示されます。今回はINSERTの処理なので「INAERT」や「INSERT+INIT」になります。
「INSERT+INIT」は初回INSERT時のように領域の初期化を伴う場合に出力されます。
じゃあどのテーブルにINSERTしたのかというのは「rel」の所で確認します。
上記の例では「1663/13878/16384」と表示されていますが、これは
「テーブルスペースのOID/データベースのOID/テーブルのOID」という形式で表現されています。
各OIDは「oid2name」コマンドで確認できます。

テーブルスペースのOID
[postgres@localhost ~]$ oid2name -s
All tablespaces:
   Oid  Tablespace Name
-----------------------
  1663       pg_default
  1664        pg_global
データベースのOID
[postgres@localhost ~]$ oid2name 
All databases:
    Oid  Database Name  Tablespace
----------------------------------
  13878       postgres  pg_default
  13877      template0  pg_default
      1      template1  pg_default
テーブルのOID
[postgres@localhost ~]$ oid2name -d postgres
From database "postgres":
  Filenode  Table Name
----------------------
     16384        test

一瞬「あ、テーブル名を表示するオプションとか用意したら便利じゃね?」とは思いましたが、きっと敢えてそうしてない理由が何かあるんだろうな。。。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1