如何获取PostgreSQL每小时WAL生成量?是否有类似Oracle的查询方法?
查询PostgreSQL WAL相关统计的方法
刚好最近也帮朋友处理过类似的需求,这就给你拆解清楚PostgreSQL里的几种方法,完全对应你提到的Oracle里的操作场景~
1. 统计每小时生成的WAL大小
PostgreSQL提供了几种不同的方式来统计,分版本推荐:
方法一:用pg_stat_wal视图(PostgreSQL 10+ 推荐)
这个系统视图自带WAL生成量的统计数据,直接写SQL就能按小时聚合:
SELECT date_trunc('hour', stats_time) AS hour, -- 转换为MB单位,方便查看 sum(wal_bytes) / 1024 / 1024 AS wal_size_mb FROM pg_stat_wal -- 按需调整时间范围,比如查最近7天 WHERE stats_time >= now() - interval '7 days' GROUP BY hour ORDER BY hour DESC;
说明:stats_time是统计的时间戳,wal_bytes是该统计周期内生成的WAL字节数,累加后转成MB就是每小时的生成量。
方法二:直接统计WAL目录文件(兼容所有版本)
如果你的PostgreSQL版本比较旧(低于10),或者想直接从文件层面验证,可以通过shell命令统计pg_wal(10+)或pg_xlog(旧版本)目录下的文件大小,按小时分组:
# 替换成你的PostgreSQL数据目录路径 PGDATA="/var/lib/postgresql/14/main" # 10+版本用pg_wal,旧版本替换成pg_xlog ls -l $PGDATA/pg_wal | awk '{print $6, $7, $5}' | grep "^[0-9]" | awk '{printf "%s %s %d\n", $1, $2, $3}' | sort | awk '{ hour = substr($2, 1, 2); key = $1 " " hour; total[key] += $3; } END { for (k in total) { printf "%s: %.2f MB\n", k, total[k]/1024/1024; } }'
说明:这个命令会按日期+小时,统计该时间段内所有WAL文件的总大小,输出更直观的MB单位。
2. 类似Oracle redo切换次数的WAL切换统计
Oracle里查v$log_history看redo切换,PostgreSQL里也有对应的方式:
方法一:用pg_stat_wal统计切换次数(10+推荐)
pg_stat_wal里的wal_switch_count是累计的WAL切换次数,按小时计算增量就是每小时的切换次数:
SELECT date_trunc('hour', stats_time) AS hour, -- 用最大累计值减最小累计值,得到该小时的切换次数 max(wal_switch_count) - min(wal_switch_count) AS hourly_switch_count FROM pg_stat_wal WHERE stats_time >= now() - interval '7 days' GROUP BY hour ORDER BY hour DESC;
方法二:从PostgreSQL日志统计(兼容所有版本)
PostgreSQL默认日志里会记录switched WAL file的条目,直接用日志统计更直观:
# 替换成你的PostgreSQL日志路径 LOG_PATH="/var/log/postgresql/postgresql-14-main.log" grep "switched WAL file" $LOG_PATH | awk '{print $1, $2}' | awk '{ hour = substr($2, 1, 2); key = $1 " " hour; count[key]++ } END { for (k in count) printf "%s: %d 次\n", k, count[k] }'
说明:这个命令会按日期+小时,统计该时间段内WAL切换的次数,和Oracle里查redo切换次数的效果完全一致。
3. 停止复制期间的WAL监控注意事项
如果要暂时停止复制(比如停掉standby的recovery),主库的WAL会持续生成,建议实时监控:
可以用LSN差值来计算一段时间内的WAL生成量:
-- 第一步:记录当前LSN SELECT pg_current_wal_lsn(); -- 第二步:过一段时间(比如1小时)后再次查询,计算差值 SELECT (pg_current_wal_lsn() - '之前记录的LSN值') / 1024 / 1024 AS wal_generated_mb;
这样能精准计算这段时间内的WAL生成量,避免磁盘被占满。
内容的提问来源于stack exchange,提问作者user144368
相关产品推荐
相关产品推荐

