pg_walinspect — просмотр WAL на низком уровне

Модуль pg_walinspect предоставляет функции SQL, позволяющие просматривать содержимое журнала упреждающей записи запущенного кластера баз данных QHB на низком уровне, что полезно для целей отладки, анализа, отчетности или обучения. Он схож с программой qhb_waldump, но доступен через SQL, а не как отдельная утилита.

Все функции этого модуля предоставляют информацию WAL, используя идентификатор текущей временной линии сервера.

Примечание
Функции pg_walinspect часто вызываются с аргументом LSN, задающим место начала интересующей известной записи WAL. Однако некоторые функции, например pg_logical_emit_message, возвращают LSN после только что добавленной записи.

Совет
Все функции pg_walinspect, отображающие информацию о записях, находящихся в определенном диапазоне LSN могут принимать конечные_lsn, расположенные после текущего LSN сервера. Использование конечного_lsn «из будущего» не вызовет ошибки.

Для удобства можно предоставить в качестве конечного_lsn значение FFFFFFFF/FFFFFFFF (максимальное допустимое значение pg_lsn). Это равнозначно указанию конечного_lsn, соответствующего текущему LSN сервера.

По умолчанию использовать эти функции разрешено только суперпользователям и членам роли pg_read_server_files. Суперпользователи могут дать доступ другим пользователям с помощью команды GRANT.


Универсальные функции

pg_get_wal_record_info

pg_get_wal_record_info(заданный_lsn pg_lsn) returns record

Получает информацию о записи WAL, которая расположена по заданному_lsn или после него. Например:

qhb=# SELECT * FROM pg_get_wal_record_info('0/E419E28');
-[ RECORD 1 ]----+-------------------------------------------------
start_lsn        | 0/E419E28
end_lsn          | 0/E419E68
prev_lsn         | 0/E419D78
xid              | 0
resource_manager | Heap2
record_type      | VACUUM
record_length    | 58
main_data_length | 2
fpi_length       | 0
description      | nunused: 5, unused: [1, 2, 3, 4, 5]
block_ref        | blkref #0: rel 1663/16385/1249 fork main blk 364

Если заданный_lsn находится не в начале записи WAL, вместо этого отображается информация о следующей доступной допустимой записи WAL. Если следующей допустимой записи WAL нет, функция выдает ошибку.

pg_get_wal_records_info

pg_get_wal_records_info(начальный_lsn pg_lsn, конечный_lsn pg_lsn) returns setof record

Получает информацию обо всех допустимых записях WAL между начальным_lsn и конечным_lsn. Возвращает по одной строке для каждой записи WAL. Например:

qhb=# SELECT * FROM pg_get_wal_records_info('0/1E913618', '0/1E913740') LIMIT 1;
-[ RECORD 1 ]----+--------------------------------------------------------------
start_lsn        | 0/1E913618
end_lsn          | 0/1E913650
prev_lsn         | 0/1E9135A0
xid              | 0
resource_manager | Standby
record_type      | RUNNING_XACTS
record_length    | 50
main_data_length | 24
fpi_length       | 0
description      | nextXid 33775 latestCompletedXid 33774 oldestRunningXid 33775
block_ref        |

Если начальный_lsn недоступен, функция выдает ошибку.

pg_get_wal_block_info

pg_get_wal_block_info(начальный_lsn pg_lsn, конечный_lsn pg_lsn, показать_данные boolean DEFAULT true) returns setof record

Получает информацию о каждой ссылке на блок из всех допустимых записей WAL между начальным_lsn и конечным_lsn с одной или несколькими ссылками на блок. Возвращает по одной строке для ссылки на блок для каждой записи WAL. Например:

qhb=# SELECT * FROM pg_get_wal_block_info('0/1230278', '0/12302B8');
-[ RECORD 1 ]-----+-----------------------------------
start_lsn         | 0/1230278
end_lsn           | 0/12302B8
prev_lsn          | 0/122FD40
block_id          | 0
reltablespace     | 1663
reldatabase       | 1
relfilenode       | 2658
relforknumber     | 0
relblocknumber    | 11
xid               | 341
resource_manager  | Btree
record_type       | INSERT_LEAF
record_length     | 64
main_data_length  | 2
block_data_length | 16
block_fpi_length  | 0
block_fpi_info    |
description       | off: 46
block_data        | \x00002a00070010402630000070696400
block_fpi_data    |

В этом примере приведена запись WAL, содержащая только одну ссылку на блок, но многие записи WAL содержат несколько таких ссылок. Выходные строки функции pg_get_wal_block_info будут гарантированно иметь уникальную комбинацию значений начального_lsn и id_блока.

Большая часть показанной здесь информации совпадает с выводом, который отобразила бы функция pg_get_wal_records_info при условии передачи одинаковых аргументов. Однако pg_get_wal_block_info разворачивает информацию о каждой записи WAL в расширенную форму путем вывода по одной строка для каждой ссылки на блок, поэтому некоторые детали отслеживаются на уровне ссылки на блок, а не на уровне целой записи. Эта структура полезна для запросов, отслеживающих изменения отдельных блоков с течением времени. Обратите внимание, что для записей без ссылок на блоки (например, записи WAL для COMMIT) строки возвращаться не будут, поэтому pg_get_wal_block_info действительно может возвращать меньше строк, чем pg_get_wal_records_info.

Параметры reltablespace, reldatabase и relfilenode ссылаются на pg_tablespace.oid, pg_database.oid и pg_class.relfilenode соответственно. Поле relforknumber содержит номер ветви в отношении для ссылок на блоки.

Совет
Функция pg_filenode_relation (см. подраздел Функции для определения местоположения объектов базы данных) может помочь определить, какое отношение было изменено во время изначального выполнения.

Клиенты могут избежать издержек материализации данных блока. Это может значительно ускорить выполнение функции. Когда в аргументе показывать_данные передается false, значения block_data и block_fpi_data опускаются (то есть выходные (OUT) аргументы block_data и block_fpi_data равны NULL для всех возвращаемых строк). Очевидно, что эта оптимизация осуществима только для запросов, в которых на самом деле не требуются данные блоков.

Если начальный_lsn недоступен, функция выдает ошибку.

pg_get_wal_stats

pg_get_wal_stats(начальный_lsn pg_lsn, конечный_lsn pg_lsn, по_типу_записи boolean DEFAULT false) returns setof record

Получает статистику по всем допустимым записям WAL между начальным_lsn and конечным_lsn. По умолчанию она возвращает по одной строке для каждого типа менеджера_ресурсов. Когда в параметре по_типу_записи установлено true, она возвращает по одной строке для каждого типа_записи. Например:

qhb=# SELECT * FROM pg_get_wal_stats('0/1E847D00', '0/1E84F500')
           WHERE count > 0 AND
                 "resource_manager/record_type" = 'Transaction'
           LIMIT 1;
-[ RECORD 1 ]----------------+-------------------
resource_manager/record_type | Transaction
count                        | 2
count_percentage             | 8
record_size                  | 875
record_size_percentage       | 41.23468426013195
fpi_size                     | 0
fpi_size_percentage          | 0
combined_size                | 875
combined_size_percentage     | 2.8634072910530795

Если начальный_lsn недоступен, функция выдает ошибку.


Автор

Бхарат Рупиредди (Bharath Rupireddy), bharath.rupireddyforpostgres@gmail.com