云数据库 PostgreSQL WAL 日志来源分析(tencentdb_wal_stat)

云数据库 PostgreSQL 提供 WAL 日志来源分析扩展,这里说明关于 WAL 日志来源分析(tencentdb_wal_stat)扩展的说明及实践。

相关产品
云数据库 PostgreSQL 产品页,含版本规格、价格与购买入口。

一、概述

tencentdb_wal_stat 是云数据库 PostgreSQL 提供的 WAL 日志来源分析扩展,支持在线按 database、schema、table 三个维度统计 WAL 日志的产生量,帮助你快速定位产生大量 WAL 的对象,及时干预避免磁盘空间告急。

核心价值:

·精准定位:按 database → schema → table 逐层下钻,快速找到 WAL 产生大户。

·在线分析:通过 SQL 直接调用,无需离线解析 WAL 文件。

·多维聚合:同时展示 RMGR 类型(Heap/Btree/Transaction 等)、FPI 统计等详细信息。

·生产安全:只读分析,不影响业务运行。

典型场景:

·SaaS 多租户环境下,某租户突发大量写入导致 WAL 堆积。

·逻辑复制消费端积压,需要找出 WAL 产生量最大的表进行限流。

·日常运维监控 WAL 产生趋势,预防磁盘空间问题。

二、环境要求

项目 要求
云数据库 PostgreSQL 版本 15.x 及以上
扩展版本 tencentdb_wal_stat v1.0
执行权限 pg_tencentdb_superuser 角色成员
执行环境 仅支持在主库(Primary)上执行

四、安装扩展

CREATE EXTENSION IF NOT EXISTS tencentdb_wal_stat;

五、验证安装

输入:

SELECT extname, extversion FROM pg_extension WHERE extname = 'tencentdb_wal_stat';

输出:

extname extversion
tencentdb_wal_stat 1.0

七、函数

tencentdb_wal_stat(wal_num integer)RETURNS SETOF record

参数:

参数 类型 范围 说明
wal_num integer 1 ~ 500 要分析的 WAL 文件数量,数值越大分析范围越广

注意:说明:

注意:wal_num 越大,分析时间越长。建议在业务低峰期执行大范围分析。

八、输出字段

字段 类型 说明
database_oid oid 数据库 OID(共享对象和系统级 WAL 为0)
database_name text 数据库名称
schema_oid oid Schema OID
schema_name text Schema 名称(仅当前数据库和共享 catalog 可解析)
relation_oid oid 关系(表/索引)OID
relation_name text 关系名称(已删除的对象显示为 <filenode:N>)
relation_kind text 关系类型:table index toast sequence matview shared_table shared_index system unknown
rmgr_name text WAL 资源管理器名称(Heap、Btree、Transaction 等)
wal_records bigint WAL 记录条数
wal_bytes bigint WAL 字节数(不含 FPI)
wal_fpi bigint Full Page Image(FPI)记录数
wal_fpi_bytes bigint FPI 字节数

注意:说明:

注意:WAL 总大小 = wal_bytes + wal_fpi_bytes。FPI 是 checkpoint 后首次修改页面时写入的完整页面副本,通常占 WAL 总量的20%~40%。

十、场景一:磁盘告警,快速定位哪个数据库产生了最多 WAL

输入:

— 按数据库汇总 WAL 产生量(分析最近50个 WAL 文件)SELECT database_name, SUM(wal_records) AS total_records, pg_size_pretty(SUM(wal_bytes + wal_fpi_bytes)::bigint) AS total_size, ROUND(SUM(wal_bytes + wal_fpi_bytes) * 100.0 / SUM(SUM(wal_bytes + wal_fpi_bytes)) OVER (), 1) AS pctFROM tencentdb_wal_stat(50)GROUP BY database_nameORDER BY SUM(wal_bytes + wal_fpi_bytes) DESC;

输出:

database_name total_records total_size pct
func_veri 447033 49 MB 79.6
postgres 53164 7812 KB 12.3
business_analysis 8 49 KB 0.1
monitor 7 44 KB 0.1
instance 7 44 KB 0.1
pg_instance 14 34 KB 0.1

十一、场景二:定位到库后,进一步查看哪个 Schema 产生最多 WAL

输入:

— 按 schema 维度汇总SELECT database_name, schema_name, SUM(wal_records) AS total_records, pg_size_pretty(SUM(wal_bytes + wal_fpi_bytes)::bigint) AS total_sizeFROM tencentdb_wal_stat(50)WHERE database_name = 'func_veri' — 替换为目标数据库名 AND schema_name IS NOT NULL AND schema_name != ''GROUP BY database_name, schema_nameORDER BY SUM(wal_bytes + wal_fpi_bytes) DESC;

输出:

database_name schema_name total_records total_size
func_veri public 185846 19 MB
func_veri pg_catalog 9110 2230 KB
func_veri test_schema 20521 1443 KB
func_veri pg_toast 190 179 KB

十二、场景三:精确到表级别,找出 WAL 产生量 TOP10的表

输入:

— 查看产生 WAL 最多的表 TOP10SELECT database_name, schema_name, relation_name, relation_kind, wal_records, pg_size_pretty(wal_bytes::bigint) AS wal_size, pg_size_pretty(wal_fpi_bytes::bigint) AS fpi_size, pg_size_pretty((wal_bytes + wal_fpi_bytes)::bigint) AS total_sizeFROM tencentdb_wal_stat(50)WHERE relation_kind IN ('table', 'index')ORDER BY (wal_bytes + wal_fpi_bytes) DESCLIMIT 10;

输出:

database_name schema_name relation_name relation_kind wal_records wal_size fpi_size total_size
func_veri public idx_test_orders table 50000 4932 KB 0 bytes 4932 KB
func_veri public idx_test_products table 30000 3757 KB 0 bytes 3757 KB
func_veri public idx_test_orders_pkey index 50411 3226 KB 0 bytes 3226 KB
func_veri public idx_test_orders_customer_id_status_id_product_name_amount_o_idx index 444 21 KB 3166 kB 3187 KB
func_veri public idx_test_products_pkey index 30246 1935 KB 0 bytes 1935 KB
postgres pg_catalog pg_attribute table 2475 1023 KB 142 kB 1165 KB
func_veri public idx_test_customers table 10000 1034 KB 0 bytes 1034 KB
func_veri test_schema orders table 10000 732 KB 0 bytes 732 KB
func_veri test_schema orders_pkey index 10084 645 KB 0 bytes 645 KB
func_veri public idx_test_customers_pkey index 10084 645 KB 0 bytes 645 KB

十三、场景四:分析 WAL 类型分布(Heap 写入 vs Index 写入)

输入:

— 按 RMGR 类型查看 WAL 分布SELECT rmgr_name, SUM(wal_records) AS total_records, pg_size_pretty(SUM(wal_bytes)::bigint) AS wal_size, ROUND(SUM(wal_records) * 100.0 / SUM(SUM(wal_records)) OVER (), 1) AS pctFROM tencentdb_wal_stat(50)GROUP BY rmgr_nameORDER BY SUM(wal_records) DESC;

输出:

rmgr_name total_records wal_size pct
Btree 246781 16 MB 44.9
Heap 229351 25 MB 41.7
Heap2 46408 3726 KB 8.4
Generic 11119 4349 KB 2.0
Transaction 7120 2015 KB 1.3
Sequence 6288 608 KB 1.1
Standby 1737 73 KB 0.3
XLOG 1163 49 KB 0.2
Storage 116 4912 bytes 0.0
CLOG 1 30 bytes 0.0

注意:说明:

注意:Btree 和 Heap 类型占比高说明表写入(INSERT/UPDATE/DELETE)及其关联的索引维护是 WAL 的主要来源。如果 Btree 占比异常高,可考虑减少不必要的索引。

十四、场景五:查看 FPI(Full Page Image)占比

输入:

— FPI 占比分析SELECT pg_size_pretty(SUM(wal_bytes)::bigint) AS wal_data_size, pg_size_pretty(SUM(wal_fpi_bytes)::bigint) AS fpi_size, pg_size_pretty(SUM(wal_bytes + wal_fpi_bytes)::bigint) AS total_size, ROUND(SUM(wal_fpi_bytes) * 100.0 / NULLIF(SUM(wal_bytes + wal_fpi_bytes), 0), 1) AS fpi_pctFROM tencentdb_wal_stat(50);

输出:

wal_data_size fpi_size total_size fpi_pct
51MB 11MB 62MB 17.5

注意:说明:

注意:如果 FPI 占比超过40%,可以考虑调大 max_wal_size 来减少 checkpoint 频率,从而降低 FPI 产生量。

十六、WAL 堆积应急处理流程

当收到磁盘空间告警或发现 WAL 堆积时,按照以下步骤排查:

步骤1: 查看整体 WAL 产生概况 └── tencentdb_wal_stat(50) 按 database 汇总 │步骤2: 定位目标数据库 └── 按 schema 汇总,找到异常 schema │步骤3: 精确到表 └── 按 relation 查看 TOP10表 │步骤4: 分析原因 ├── Heap 类型多 → 大量 INSERT/UPDATE/DELETE ├── Btree 类型多 → 索引维护开销大 └── FPI 占比高 → checkpoint 过于频繁 │步骤5: 采取措施 ├── 限制异常租户写入速率 ├── 暂停非核心批量任务 └── 优化索引策略

十七、日常监控建议

建议定期执行以下查询,记录 WAL 产生趋势:

— 每小时记录各数据库 WAL 产生量(可写入监控表)INSERT INTO wal_monitor_log (check_time, database_name, wal_records, wal_bytes)SELECT now(), database_name, SUM(wal_records), SUM(wal_bytes + wal_fpi_bytes)FROM tencentdb_wal_stat(10)GROUP BY database_name;

十八、wal_num 参数选择建议

场景 推荐 wal_num 说明
紧急排查 5 ~ 10 快速返回,查看最近的 WAL 来源
日常巡检 20 ~ 50 覆盖较长时间范围,数据更具代表性
深度分析 100 ~ 200 需要全面了解 WAL 分布时使用

注意:说明:

注意:wal_num 越大,分析时间越长。建议在业务低峰期执行大范围分析。

十九、名词解释

名词 解释
WAL Write-Ahead Logging,预写式日志。PostgreSQL 通过先写日志再写数据文件的方式来保证事务的持久性和崩溃恢复能力
LSN Log Sequence Number,日志序列号。唯一标识 WAL 日志中的位置
RMGR Resource Manager,资源管理器。WAL 按不同的操作类型分类,如 Heap(表数据)、Btree(B-tree 索引)、Transaction(事务)
FPI Full Page Image,全页镜像。checkpoint 后首次修改某个数据页时,会将该页完整内容写入 WAL,用于崩溃恢复时避免部分写入问题
Replication Slot 复制槽。用于保留 WAL 日志直到下游订阅者消费完成。如果下游消费慢,会导致 WAL 无法被清理

20、注意事项

·仅主库可用:在备库上执行会报错,这是因为备库没有独立的 WAL 写入。

·权限要求:需要 pg_tencentdb_superuser 角色成员权限。

·参数范围:wal_num 取值1 ~ 500,超出范围会报错。

·名称解析:其他数据库中的对象名称可能显示为 <oid:N> 或 <filenode:N>,这是正常现象(跨库无法解析 catalog)。

·性能影响:该函数读取 WAL 文件进行统计,wal_num 较大时执行时间会增加,建议避免在高峰期使用大 wal_num。

·WAL 可用性:仅能分析尚未被清理的 WAL 文件,已回收的历史 WAL 无法分析。

赞 (0)
上一篇 4天前
下一篇 4天前