pg_walinspect 模块提供 SQL 函数,允许你在低层级检查运行中的 PostgreSQL 数据库集簇的预写式日志(WAL)内容,这对调试、分析、报告或教学很有用。它与 pg_waldump 类似,但通过 SQL 而非独立实用程序访问。
该模块的所有函数都使用服务器当前的时间线 ID 提供 WAL 信息。
调用 pg_walinspect 函数时,通常传入一个 LSN 参数,用于指定感兴趣的已知 WAL 记录开始的位置。不过,某些函数(例如
pg_logical_emit_message)
返回的是刚插入记录之后的 LSN。
所有显示某个 LSN 范围内记录信息的 pg_walinspect 函数,对于接受超出服务器当前 LSN 的 end_lsn 参数都比较宽容。使用“来自未来”的 end_lsn 不会引发错误。
提供 FFFFFFFF/FFFFFFFF(最大有效 pg_lsn 值)作为 end_lsn 参数可能很方便。这等效于提供与服务器当前 LSN 匹配的 end_lsn 参数。
默认情况下,这些函数的使用仅限于超级用户和 pg_read_server_files 角色的成员。超级用户可以通过 GRANT 将访问权限授予其他用户。
pg_get_wal_record_info(in_lsn pg_lsn) returns record
#
获取位于 in_lsn 参数处或之后的 WAL 记录的信息。例如:
postgres=# 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
如果 in_lsn 不在某个 WAL 记录的起始处,则显示下一个有效 WAL 记录的信息。如果没有下一个有效 WAL 记录,该函数将抛出错误。
pg_get_wal_records_info(start_lsn pg_lsn, end_lsn pg_lsn)
returns setof record
#
获取 start_lsn 与 end_lsn 之间所有有效 WAL 记录的信息。每个 WAL 记录返回一行。例如:
postgres=# 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 |
如果 start_lsn 不可用,该函数将抛出错误。
pg_get_wal_block_info(start_lsn pg_lsn, end_lsn pg_lsn, show_data boolean DEFAULT true) returns setof record
#
获取 start_lsn 与 end_lsn 之间所有含有一个或多个块引用的有效 WAL 记录中每个块引用的信息。每个 WAL 记录的每个块引用返回一行。例如:
postgres=# 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 输出的行保证具有唯一的 start_lsn 与 block_id 值组合。
这里显示的大部分信息与 pg_get_wal_records_info 在相同参数下的输出一致。不过,pg_get_wal_block_info 通过为每个块引用输出一行,将每个 WAL 记录的信息展开为更细的形式,因此某些细节是在块引用层级而非整个记录层级上跟踪的。这种结构适合跟踪单个块随时间变化的查询。请注意,不含块引用的记录(例如 COMMIT WAL 记录)不会返回任何行,因此 pg_get_wal_block_info 实际返回的行可能比 pg_get_wal_records_info 更少。
reltablespace、reldatabase 与 relfilenode 参数分别对应
pg_tablespace.oid、
pg_database.oid 与
pg_class.relfilenode。relforknumber 字段是该块引用在关系中的分支编号;详见 common/relpath.h。
pg_filenode_relation 函数(参见 Table 9.103)可以帮助你确定最初执行时修改的是哪个关系。
客户端可以避免物化块数据的开销,这可能显著加快函数执行速度。当 show_data 设为 false 时,block_data 与 block_fpi_data 值会被省略(即所有返回行的 block_data 与 block_fpi_data OUT 参数为 NULL)。显然,这种优化只适用于块数据并非真正必需的查询。
如果 start_lsn 不可用,该函数将抛出错误。
pg_get_wal_stats(start_lsn pg_lsn, end_lsn pg_lsn, per_record boolean DEFAULT false)
returns setof record
#
获取 start_lsn 与 end_lsn 之间所有有效 WAL 记录的统计信息。默认情况下,每种 resource_manager 类型返回一行。当 per_record 设为 true 时,每种 record_type 返回一行。例如:
postgres=# 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
如果 start_lsn 不可用,该函数将抛出错误。
Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>