Создадим небольшую таблицу:
=> CREATE DATABASE wal_log;
CREATE DATABASE
=> \c wal_log
You are now connected to database "wal_log" as user "postgres".
=> CREATE TABLE t(id integer);
CREATE TABLE
=> INSERT INTO t VALUES (1);
INSERT 0 1
Мы будем заглядывать в заголовок табличной страницы. Для этого понадобится расширение:
=> CREATE EXTENSION pageinspect;
CREATE EXTENSION
Начнем транзакцию.
=> BEGIN;
BEGIN
Текущая позиция в журнале:
=> SELECT pg_current_wal_insert_lsn();
pg_current_wal_insert_lsn --------------------------- 0/1C349E8 (1 row)
LSN выводится как два 32-битных числа в шестнадцатеричной системе через косую черту.
Эта позиция соответствует файлу:
=> SELECT pg_walfile_name('0/1C349E8');
pg_walfile_name -------------------------- 000000010000000000000001 (1 row)
Имя файла состоит из трех чисел. Первое - номер ветви времени (используется при восстановлении из архива), а два следующих - старшие разряды LSN.
Все журнальные файлы находятся в каталоге /usr/local/pgsql/data/pg_wal/, а в PostgreSQL 10 их также можно увидеть специальной функцией:
=> SELECT * FROM pg_ls_waldir() LIMIT 10;
name | size | modification --------------------------+----------+------------------------ 000000010000000000000001 | 16777216 | 2019-08-12 17:15:46+03 (1 row)
Изменим строку в таблице:
=> UPDATE t SET id = id + 1;
UPDATE 1
Позиция в журнале изменилась:
=> SELECT pg_current_wal_insert_lsn();
pg_current_wal_insert_lsn --------------------------- 0/1C34A30 (1 row)
Этот же номер LSN (или меньший, если в журнал попали дополнительные записи) мы найдем и в заголовке измененной страницы:
=> SELECT lsn FROM page_header(get_raw_page('t',0));
lsn ----------- 0/1C34A30 (1 row)
Завершим транзакцию.
=> COMMIT;
COMMIT
Позиция в журнале снова изменилась:
=> SELECT pg_current_wal_insert_lsn();
pg_current_wal_insert_lsn --------------------------- 0/1C34A54 (1 row)
Размер журнальных записей (в байтах), соответствующих нашей транзакции, можно узнать вычитанием одной позиции из другой:
=> SELECT '0/1C34A54'::pg_lsn - '0/1C349E8'::pg_lsn;
?column? ---------- 108 (1 row)
Безусловно, в журнал попадает информация обо всех действиях во всем кластере, но в данном случае мы рассчитываем на то, что в системе ничего не происходит.
Теперь воспользуемся утилитой pg_waldump, чтобы посмотреть содержимое журнала.
Список менеджеров ресурсов:
student$ pg_waldump -r list
XLOG Transaction Storage CLOG Database Tablespace MultiXact RelMap Standby Heap2 Heap Btree Hash Gin Gist Sequence SPGist BRIN CommitTs ReplicationOrigin Generic LogicalMessage
Утилита может работать и с диапазоном LSN (как в этом примере), и выбрать записи для указанной транзакции. Запускать ее следует от имени пользователя ОС postgres, так как ей требуется доступ к журнальным файлам на диске.
postgres$ pg_waldump -p /usr/local/pgsql/data/pg_wal -s 0/1C349E8 -e 0/1C34A54 000000010000000000000001
rmgr: Heap len (rec/tot): 69/ 69, tx: 670, lsn: 0/01C349E8, prev 0/01C344B0, desc: HOT_UPDATE off 1 xmax 670 ; new off 2 xmax 0, blkref #0: rel 1663/16625/16626 blk 0 rmgr: Transaction len (rec/tot): 34/ 34, tx: 670, lsn: 0/01C34A30, prev 0/01C349E8, desc: COMMIT 2019-08-12 17:15:46.557989 MSK
Мы видим заголовки журнальных записей:
Конец демонстрации.