F.37. pg_walinspect — WAL 的底层检查 #
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 向其他用户授予访问权限。
F.37.1. 通用函数 #
-
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 记录中的信息拆解为展开形式:对每个块引用输出一行,因此某些细节是在块引用级别而不是整条记录级别进行跟踪。这种结构适合配合跟踪单个块随时间变化的查询使用。需要注意,不含块引用的记录(如COMMITWAL 记录)不会返回任何行,因此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函数(见表 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不可用,函数会报错。
F.37.2. 作者 #
Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>
报告文档问题
阅读 上游文档. 通过 PostgreSQL 文档反馈表单.