项目 | 要求 |
云数据库 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_extensionWHERE 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 文件数量,数值越大分析范围越广 |
字段 | 类型 | 说明 |
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 产生量(分析最近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 维度汇总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 最多的表 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 |
-- 按 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 |
-- FPI 占比分析SELECTpg_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 |
步骤1: 查看整体 WAL 产生概况└── tencentdb_wal_stat(50) 按 database 汇总│步骤2: 定位目标数据库└── 按 schema 汇总,找到异常 schema│步骤3: 精确到表└── 按 relation 查看 TOP10表│步骤4: 分析原因├── Heap 类型多 → 大量 INSERT/UPDATE/DELETE├── Btree 类型多 → 索引维护开销大└── FPI 占比高 → checkpoint 过于频繁│步骤5: 采取措施├── 限制异常租户写入速率├── 暂停非核心批量任务└── 优化索引策略
-- 每小时记录各数据库 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 | 说明 |
紧急排查 | 5 ~ 10 | 快速返回,查看最近的 WAL 来源 |
日常巡检 | 20 ~ 50 | 覆盖较长时间范围,数据更具代表性 |
深度分析 | 100 ~ 200 | 需要全面了解 WAL 分布时使用 |
名词 | 解释 |
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 无法被清理 |
<oid:N> 或 <filenode:N>,这是正常现象(跨库无法解析 catalog)。文档反馈