
ЖУРНАЛ УПРЕЖДАЮЩЕЙ ЗАПИСИ
~~~~~~~~~~~~~~~~~~~~~~~~~

Посмотрим на содержимое журнала для одних и тех же действий
при разных уровнях, установленных в параметре wal_level.

Сначала создадим отдельную базу данных:

        => create database db8;
        CREATE DATABASE

        => \c db8
        You are now connected to database "db8" as user "postgres".

.......................................................................

Создадим таблицу:

        => create table t(n numeric);
        CREATE TABLE

.......................................................................

MINIMAL
~~~~~~~

Установим уровень minimal.

        => alter system set wal_level = minimal;
        ALTER SYSTEM

А также выключим параметры full_page_writes и wal_log_hints,
чтобы не загромождать журнал.

        => alter system set full_page_writes = off;
        ALTER SYSTEM

        => alter system set wal_log_hints = off;
        ALTER SYSTEM

.......................................................................

Перезапустим сервер.

        => \q

pg_ctl restart -w -m fast -l /home/postgres/logfile 
waiting for server to shut down.... done
server stopped
waiting for server to start.... done
server started
        psql 

        => \c db8
        You are now connected to database "db8" as user "postgres".

.......................................................................

Начинаем транзакцию.

        => begin;
        BEGIN

        => select txid_current();
         txid_current 
        --------------
               557768
        (1 row)
        

        => select txid_current() as txid \gset

        => \setenv TXID :txid

.......................................................................

Текущая позиция в журнале:

        => select pg_current_xlog_location();
         pg_current_xlog_location 
        --------------------------
         3/B35D1DF0
        (1 row)
        

LSN выводится как два 32-битных числа в шестнадцатеричной системе через косую черту.

        => select pg_current_xlog_location() as start_lsn \gset

        => \setenv START_LSN :start_lsn

Эта позиция соответствует файлу:

        => select pg_xlogfile_name(:'start_lsn');
             pg_xlogfile_name     
        --------------------------
         0000001100000003000000B3
        (1 row)
        

        => select pg_xlogfile_name(:'start_lsn') as start_seg \gset

        => \setenv START_SEG :start_seg

.......................................................................

        => truncate table t;
        TRUNCATE TABLE

        => copy t from stdin;
        => 1
        => 2
        => \.
        COPY 2

        => insert into t values (3);
        INSERT 0 1

        => commit;
        COMMIT

.......................................................................

Теперь позиция в журнале:

        => select pg_current_xlog_location();
         pg_current_xlog_location 
        --------------------------
         3/B35D2390
        (1 row)
        

        => select pg_current_xlog_location() as end_lsn \gset

        => \setenv END_LSN :end_lsn

.......................................................................

Размер журнальных записей, соответствующих нашей транзакции:

        => select :'end_lsn'::pg_lsn - :'start_lsn'::pg_lsn;
         ?column? 
        ----------
             1440
        (1 row)
        

Безусловно, в журнал попадает информация обо всех действиях во всем кластере,
но в данном случае мы рассчитываем на то, что в системе ничего не происходит.

.......................................................................

Теперь воспользуемся утилитой pg_xlogdump, чтобы посмотреть содержимое журнала.
Утилита может работать как с диапазоном lsn, так и выбрать записи для транзакции.

        => \! pg_xlogdump -p $PGDATA/pg_xlog -s $START_LSN -e $END_LSN -x $TXID $START_SEG
        rmgr: XLOG        len (rec/tot):      4/    30, tx:     557768, lsn: 3/B35D1DF0, prev 3/B35D1D88, desc: NEXTOID 135110
        rmgr: Storage     len (rec/tot):     16/    42, tx:     557768, lsn: 3/B35D1E10, prev 3/B35D1DF0, desc: CREATE base/126911/126918
        rmgr: Heap        len (rec/tot):     14/   123, tx:     557768, lsn: 3/B35D1E3C, prev 3/B35D1E10, desc: UPDATE off 9 xmax 557768 ; new off 10 xmax 0, blkref #0: rel 1663/126911/1259 blk 0
        rmgr: Btree       len (rec/tot):      2/    60, tx:     557768, lsn: 3/B35D1EB8, prev 3/B35D1E3C, desc: INSERT_LEAF off 315, blkref #0: rel 1663/126911/2662 blk 1
        rmgr: Btree       len (rec/tot):      2/    64, tx:     557768, lsn: 3/B35D1EF4, prev 3/B35D1EB8, desc: INSERT_LEAF off 42, blkref #0: rel 1663/126911/2663 blk 2
        rmgr: Btree       len (rec/tot):      2/    64, tx:     557768, lsn: 3/B35D1F34, prev 3/B35D1EF4, desc: INSERT_LEAF off 283, blkref #0: rel 1663/126911/3455 blk 1
        rmgr: Storage     len (rec/tot):     16/    42, tx:     557768, lsn: 3/B35D1F74, prev 3/B35D1F34, desc: CREATE base/126911/126919
        rmgr: Heap        len (rec/tot):     14/   123, tx:     557768, lsn: 3/B35D1FA0, prev 3/B35D1F74, desc: UPDATE off 7 xmax 557768 ; new off 11 xmax 0, blkref #0: rel 1663/126911/1259 blk 0
        rmgr: Btree       len (rec/tot):      2/    60, tx:     557768, lsn: 3/B35D2030, prev 3/B35D1FA0, desc: INSERT_LEAF off 317, blkref #0: rel 1663/126911/2662 blk 1
        rmgr: Btree       len (rec/tot):      2/    76, tx:     557768, lsn: 3/B35D206C, prev 3/B35D2030, desc: INSERT_LEAF off 101, blkref #0: rel 1663/126911/2663 blk 4
        rmgr: Btree       len (rec/tot):      2/    64, tx:     557768, lsn: 3/B35D20B8, prev 3/B35D206C, desc: INSERT_LEAF off 284, blkref #0: rel 1663/126911/3455 blk 1
        rmgr: Storage     len (rec/tot):     16/    42, tx:     557768, lsn: 3/B35D20F8, prev 3/B35D20B8, desc: CREATE base/126911/126920
        rmgr: Heap        len (rec/tot):     14/    87, tx:     557768, lsn: 3/B35D2124, prev 3/B35D20F8, desc: UPDATE off 8 xmax 557768 ; new off 12 xmax 0, blkref #0: rel 1663/126911/1259 blk 0
        rmgr: Btree       len (rec/tot):      2/    60, tx:     557768, lsn: 3/B35D217C, prev 3/B35D2124, desc: INSERT_LEAF off 319, blkref #0: rel 1663/126911/2662 blk 1
        rmgr: Btree       len (rec/tot):      2/    84, tx:     557768, lsn: 3/B35D21B8, prev 3/B35D217C, desc: INSERT_LEAF off 103, blkref #0: rel 1663/126911/2663 blk 4
        rmgr: Btree       len (rec/tot):      2/    64, tx:     557768, lsn: 3/B35D220C, prev 3/B35D21B8, desc: INSERT_LEAF off 285, blkref #0: rel 1663/126911/3455 blk 1
        rmgr: Heap        len (rec/tot):      2/   184, tx:     557768, lsn: 3/B35D224C, prev 3/B35D220C, desc: INPLACE off 12, blkref #0: rel 1663/126911/1259 blk 0
        rmgr: Heap        len (rec/tot):      3/    60, tx:     557768, lsn: 3/B35D2304, prev 3/B35D224C, desc: INSERT off 3, blkref #0: rel 1663/126911/126918 blk 0
        rmgr: Transaction len (rec/tot):     52/    78, tx:     557768, lsn: 3/B35D2340, prev 3/B35D2304, desc: COMMIT 2017-12-14 18:58:54.231567 MSK; rels: base/126911/126917 base/126911/126915 base/126911/126912

Сначала происходит работа со словарем данных: создается новый файл
при команде truncate, изменяются данные в pg_class и других таблицах,
обновляются индексы на системных таблицах.
Вставка строк 1 и 2 не попадает в журнал. Это оптимизация: сохранность
данных обеспечивается их записью на диск.
Вставка строки отражена в журнале, это предпоследняя строка (INSERT).
Далее идет запись о фиксации изменений.

.......................................................................

ARCHIVE
~~~~~~~

Теперь посмотрим на ту же транзакцию при уровне журнала archive.

        => alter system set wal_level = archive;
        ALTER SYSTEM

        => \q

pg_ctl restart -w -m fast -l /home/postgres/logfile 
waiting for server to shut down.... done
server stopped
waiting for server to start.... done
server started
        psql 

        => \c db8
        You are now connected to database "db8" as user "postgres".

.......................................................................

Начинаем транзакцию.

        => begin;
        BEGIN

        => select txid_current() as txid \gset

        => \setenv TXID :txid

        => select pg_current_xlog_location() as start_lsn \gset

        => \setenv START_LSN :start_lsn

        => select pg_xlogfile_name(:'start_lsn') as start_seg \gset

        => \setenv START_SEG :start_seg

.......................................................................

        => truncate table t;
        TRUNCATE TABLE

        => copy t from stdin;
        => 1
        => 2
        => \.
        COPY 2

        => update t set n=n+1 where n=2;
        UPDATE 1

        => commit;
        COMMIT

.......................................................................

        => select pg_current_xlog_location();
         pg_current_xlog_location 
        --------------------------
         3/B35D2A88
        (1 row)
        

        => select pg_current_xlog_location() as end_lsn \gset

        => \setenv END_LSN :end_lsn

Размер журнальных записей:

        => select :'end_lsn'::pg_lsn - :'start_lsn'::pg_lsn;
         ?column? 
        ----------
             1628
        (1 row)
        

.......................................................................

Сам журнал:

        => \! pg_xlogdump -p $PGDATA/pg_xlog -s $START_LSN -e $END_LSN -x $TXID $START_SEG
        rmgr: XLOG        len (rec/tot):      4/    30, tx:     557769, lsn: 3/B35D242C, prev 3/B35D23F8, desc: NEXTOID 135113
        rmgr: Storage     len (rec/tot):     16/    42, tx:     557769, lsn: 3/B35D244C, prev 3/B35D242C, desc: CREATE base/126911/126921
        rmgr: Heap        len (rec/tot):     14/   123, tx:     557769, lsn: 3/B35D2478, prev 3/B35D244C, desc: UPDATE off 10 xmax 557769 ; new off 13 xmax 0, blkref #0: rel 1663/126911/1259 blk 0
        rmgr: Btree       len (rec/tot):      2/    60, tx:     557769, lsn: 3/B35D24F4, prev 3/B35D2478, desc: INSERT_LEAF off 315, blkref #0: rel 1663/126911/2662 blk 1
        rmgr: Btree       len (rec/tot):      2/    64, tx:     557769, lsn: 3/B35D2530, prev 3/B35D24F4, desc: INSERT_LEAF off 42, blkref #0: rel 1663/126911/2663 blk 2
        rmgr: Btree       len (rec/tot):      2/    64, tx:     557769, lsn: 3/B35D2570, prev 3/B35D2530, desc: INSERT_LEAF off 286, blkref #0: rel 1663/126911/3455 blk 1
        rmgr: Storage     len (rec/tot):     16/    42, tx:     557769, lsn: 3/B35D25B0, prev 3/B35D2570, desc: CREATE base/126911/126922
        rmgr: Heap        len (rec/tot):     14/   123, tx:     557769, lsn: 3/B35D25DC, prev 3/B35D25B0, desc: UPDATE off 11 xmax 557769 ; new off 14 xmax 0, blkref #0: rel 1663/126911/1259 blk 0
        rmgr: Btree       len (rec/tot):      2/    60, tx:     557769, lsn: 3/B35D2658, prev 3/B35D25DC, desc: INSERT_LEAF off 318, blkref #0: rel 1663/126911/2662 blk 1
        rmgr: Btree       len (rec/tot):      2/    76, tx:     557769, lsn: 3/B35D2694, prev 3/B35D2658, desc: INSERT_LEAF off 101, blkref #0: rel 1663/126911/2663 blk 4
        rmgr: Btree       len (rec/tot):      2/    64, tx:     557769, lsn: 3/B35D26E0, prev 3/B35D2694, desc: INSERT_LEAF off 287, blkref #0: rel 1663/126911/3455 blk 1
        rmgr: Storage     len (rec/tot):     16/    42, tx:     557769, lsn: 3/B35D2720, prev 3/B35D26E0, desc: CREATE base/126911/126923
        rmgr: Heap        len (rec/tot):     14/    87, tx:     557769, lsn: 3/B35D274C, prev 3/B35D2720, desc: UPDATE off 12 xmax 557769 ; new off 15 xmax 0, blkref #0: rel 1663/126911/1259 blk 0
        rmgr: Btree       len (rec/tot):      2/    60, tx:     557769, lsn: 3/B35D27A4, prev 3/B35D274C, desc: INSERT_LEAF off 321, blkref #0: rel 1663/126911/2662 blk 1
        rmgr: Btree       len (rec/tot):      2/    84, tx:     557769, lsn: 3/B35D27E0, prev 3/B35D27A4, desc: INSERT_LEAF off 104, blkref #0: rel 1663/126911/2663 blk 4
        rmgr: Btree       len (rec/tot):      2/    64, tx:     557769, lsn: 3/B35D2834, prev 3/B35D27E0, desc: INSERT_LEAF off 288, blkref #0: rel 1663/126911/3455 blk 1
        rmgr: XLOG        len (rec/tot):      0/   113, tx:     557769, lsn: 3/B35D2874, prev 3/B35D2834, desc: FPI , blkref #0: rel 1663/126911/126923 blk 0 FPW
        rmgr: Heap        len (rec/tot):      2/   184, tx:     557769, lsn: 3/B35D28E8, prev 3/B35D2874, desc: INPLACE off 15, blkref #0: rel 1663/126911/1259 blk 0
        rmgr: Heap2       len (rec/tot):      4/    77, tx:     557769, lsn: 3/B35D29A0, prev 3/B35D28E8, desc: MULTI_INSERT+INIT 2 tuples, blkref #0: rel 1663/126911/126921 blk 0
        rmgr: Heap        len (rec/tot):     14/    70, tx:     557769, lsn: 3/B35D29F0, prev 3/B35D29A0, desc: HOT_UPDATE off 2 xmax 557769 ; new off 3 xmax 0, blkref #0: rel 1663/126911/126921 blk 0
        rmgr: Transaction len (rec/tot):     52/    78, tx:     557769, lsn: 3/B35D2A38, prev 3/B35D29F0, desc: COMMIT 2017-12-14 18:58:56.354692 MSK; rels: base/126911/126920 base/126911/126919 base/126911/126918

Здесь появляется запись MULTI_INSERT+INIT, соответствующая команде
copy, вставившей две строки. Эти данные необходимы для того, чтобы
повторить команду при восстановлении из архива.

.......................................................................

HOT_STANDBY
~~~~~~~~~~~

Та же транзакция при уровне журнала hot_standby.

        => alter system set wal_level = hot_standby;
        ALTER SYSTEM

        => \q

pg_ctl restart -w -m fast -l /home/postgres/logfile 
waiting for server to shut down.... done
server stopped
waiting for server to start.... done
server started
        psql 

        => \c db8
        You are now connected to database "db8" as user "postgres".

.......................................................................

Начинаем транзакцию.

        => begin;
        BEGIN

        => select txid_current() as txid \gset

        => \setenv TXID :txid

        => select pg_current_xlog_location() as start_lsn \gset

        => \setenv START_LSN :start_lsn

        => select pg_xlogfile_name(:'start_lsn') as start_seg \gset

        => \setenv START_SEG :start_seg

.......................................................................

        => truncate table t;
        TRUNCATE TABLE

        => copy t from stdin;
        => 1
        => 2
        => \.
        COPY 2

        => update t set n=n+1 where n=2;
        UPDATE 1

        => commit;
        COMMIT

.......................................................................

        => select pg_current_xlog_location();
         pg_current_xlog_location 
        --------------------------
         3/B35D32E4
        (1 row)
        

        => select pg_current_xlog_location() as end_lsn \gset

        => \setenv END_LSN :end_lsn

Размер журнальных записей:

        => select :'end_lsn'::pg_lsn - :'start_lsn'::pg_lsn;
         ?column? 
        ----------
             1984
        (1 row)
        

.......................................................................

Сам журнал:

        => \! pg_xlogdump -p $PGDATA/pg_xlog -s $START_LSN -e $END_LSN -x $TXID $START_SEG
        rmgr: Standby     len (rec/tot):     16/    42, tx:     557770, lsn: 3/B35D2B24, prev 3/B35D2AF0, desc: LOCK xid 557770 db 126911 rel 126912 
        rmgr: XLOG        len (rec/tot):      4/    30, tx:     557770, lsn: 3/B35D2B50, prev 3/B35D2B24, desc: NEXTOID 135116
        rmgr: Storage     len (rec/tot):     16/    42, tx:     557770, lsn: 3/B35D2B70, prev 3/B35D2B50, desc: CREATE base/126911/126924
        rmgr: Heap        len (rec/tot):     14/   123, tx:     557770, lsn: 3/B35D2B9C, prev 3/B35D2B70, desc: UPDATE off 13 xmax 557770 ; new off 16 xmax 0, blkref #0: rel 1663/126911/1259 blk 0
        rmgr: Btree       len (rec/tot):      2/    60, tx:     557770, lsn: 3/B35D2C18, prev 3/B35D2B9C, desc: INSERT_LEAF off 315, blkref #0: rel 1663/126911/2662 blk 1
        rmgr: Btree       len (rec/tot):      2/    64, tx:     557770, lsn: 3/B35D2C54, prev 3/B35D2C18, desc: INSERT_LEAF off 42, blkref #0: rel 1663/126911/2663 blk 2
        rmgr: Btree       len (rec/tot):      2/    64, tx:     557770, lsn: 3/B35D2C94, prev 3/B35D2C54, desc: INSERT_LEAF off 289, blkref #0: rel 1663/126911/3455 blk 1
        rmgr: Standby     len (rec/tot):     16/    42, tx:     557770, lsn: 3/B35D2CD4, prev 3/B35D2C94, desc: LOCK xid 557770 db 126911 rel 126915 
        rmgr: Storage     len (rec/tot):     16/    42, tx:     557770, lsn: 3/B35D2D00, prev 3/B35D2CD4, desc: CREATE base/126911/126925
        rmgr: Heap        len (rec/tot):     14/   123, tx:     557770, lsn: 3/B35D2D2C, prev 3/B35D2D00, desc: UPDATE off 14 xmax 557770 ; new off 17 xmax 0, blkref #0: rel 1663/126911/1259 blk 0
        rmgr: Btree       len (rec/tot):      2/    60, tx:     557770, lsn: 3/B35D2DA8, prev 3/B35D2D2C, desc: INSERT_LEAF off 319, blkref #0: rel 1663/126911/2662 blk 1
        rmgr: Btree       len (rec/tot):      2/    76, tx:     557770, lsn: 3/B35D2DE4, prev 3/B35D2DA8, desc: INSERT_LEAF off 101, blkref #0: rel 1663/126911/2663 blk 4
        rmgr: Btree       len (rec/tot):      2/    64, tx:     557770, lsn: 3/B35D2E30, prev 3/B35D2DE4, desc: INSERT_LEAF off 290, blkref #0: rel 1663/126911/3455 blk 1
        rmgr: Standby     len (rec/tot):     16/    42, tx:     557770, lsn: 3/B35D2E70, prev 3/B35D2E30, desc: LOCK xid 557770 db 126911 rel 126917 
        rmgr: Storage     len (rec/tot):     16/    42, tx:     557770, lsn: 3/B35D2E9C, prev 3/B35D2E70, desc: CREATE base/126911/126926
        rmgr: Heap        len (rec/tot):     14/    87, tx:     557770, lsn: 3/B35D2EC8, prev 3/B35D2E9C, desc: UPDATE off 15 xmax 557770 ; new off 18 xmax 0, blkref #0: rel 1663/126911/1259 blk 0
        rmgr: Btree       len (rec/tot):      2/    60, tx:     557770, lsn: 3/B35D2F20, prev 3/B35D2EC8, desc: INSERT_LEAF off 323, blkref #0: rel 1663/126911/2662 blk 1
        rmgr: Btree       len (rec/tot):      2/    84, tx:     557770, lsn: 3/B35D2F5C, prev 3/B35D2F20, desc: INSERT_LEAF off 105, blkref #0: rel 1663/126911/2663 blk 4
        rmgr: Btree       len (rec/tot):      2/    64, tx:     557770, lsn: 3/B35D2FB0, prev 3/B35D2F5C, desc: INSERT_LEAF off 291, blkref #0: rel 1663/126911/3455 blk 1
        rmgr: XLOG        len (rec/tot):      0/   113, tx:     557770, lsn: 3/B35D2FF0, prev 3/B35D2FB0, desc: FPI , blkref #0: rel 1663/126911/126926 blk 0 FPW
        rmgr: Heap        len (rec/tot):      2/   184, tx:     557770, lsn: 3/B35D3064, prev 3/B35D2FF0, desc: INPLACE off 18, blkref #0: rel 1663/126911/1259 blk 0
        rmgr: Heap2       len (rec/tot):      4/    77, tx:     557770, lsn: 3/B35D311C, prev 3/B35D3064, desc: MULTI_INSERT+INIT 2 tuples, blkref #0: rel 1663/126911/126924 blk 0
        rmgr: Heap        len (rec/tot):     14/    70, tx:     557770, lsn: 3/B35D316C, prev 3/B35D311C, desc: HOT_UPDATE off 2 xmax 557770 ; new off 3 xmax 0, blkref #0: rel 1663/126911/126924 blk 0
        rmgr: Transaction len (rec/tot):    272/   301, tx:     557770, lsn: 3/B35D31B4, prev 3/B35D316C, desc: COMMIT 2017-12-14 18:58:58.474887 MSK; rels: base/126911/126923 base/126911/126922 base/126911/126921; inval msgs: catcache 45 catcache 44 catcache 45 catcache 44 catcache 45 catcache 44 catcache 45 catcache 44 relcache 126915 relcache 126917 relcache 126917 relcache 126915 relcache 126912

Здесь появляются записи LOCK для отражения эксклюзивных блокировок.
Эта информация нужна для выполнения запросов на горячей резервной копии.

.......................................................................

Конец демонстрации.

.......................................................................

        => alter system reset all;
        ALTER SYSTEM

        => \q

pg_ctl restart -w -m fast -l /home/postgres/logfile 
waiting for server to shut down.... done
server stopped
waiting for server to start.... done
server started
