pg_walinspect模块提供一组 SQL 函数, 允许在底层检查正在运行的 PostgreSQL 数据库集簇的预写式日志内容, 这对于调试、分析、报表或教学用途很有帮助。 它与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.102) 可帮助确定在最初执行时被修改的是哪个关系。
客户端可以避免物化块数据所带来的开销, 这可能使函数执行显著加快。 当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>
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。