文章目录
- [一、整体分类框架(让 PG 小白有地图)](#一、整体分类框架(让 PG 小白有地图))
- 二、重点视图逐一讲解(附案例)
-
- [1️⃣ `pg_stat_activity` --- 当前会话信息](#1️⃣
pg_stat_activity— 当前会话信息) - [2️⃣ `pg_stat_all_tables` --- 所有表的访问统计](#2️⃣
pg_stat_all_tables— 所有表的访问统计) - [3️⃣ `pg_stat_user_tables` --- 仅用户表统计](#3️⃣
pg_stat_user_tables— 仅用户表统计) - [4️⃣ `pg_stat_sys_tables` --- 系统表统计](#4️⃣
pg_stat_sys_tables— 系统表统计) - [5️⃣ `pg_stat_all_indexes` --- 所有索引使用情况](#5️⃣
pg_stat_all_indexes— 所有索引使用情况) - [6️⃣ `pg_stat_user_indexes` --- 用户表的索引统计](#6️⃣
pg_stat_user_indexes— 用户表的索引统计) - [7️⃣ `pg_stat_sys_indexes` --- 系统索引统计](#7️⃣
pg_stat_sys_indexes— 系统索引统计) - [8️⃣ `pg_stat_database` --- 数据库整体性能概览](#8️⃣
pg_stat_database— 数据库整体性能概览) - [9️⃣ `pg_stat_database_conflicts` --- 数据库冲突统计(主要在流复制从库)](#9️⃣
pg_stat_database_conflicts— 数据库冲突统计(主要在流复制从库)) - [🔟 `pg_stat_bgwriter` --- 后台写入进程统计](#🔟
pg_stat_bgwriter— 后台写入进程统计) - [11️⃣ pg_stat_user_tables](#11️⃣ pg_stat_user_tables)
- [12️⃣ pg_stat_user_indexes](#12️⃣ pg_stat_user_indexes)
- [13️⃣ pg_stat_all_tables](#13️⃣ pg_stat_all_tables)
- [14️⃣ pg_stat_all_indexes](#14️⃣ pg_stat_all_indexes)
- [15️⃣ pg_stat_sys_tables](#15️⃣ pg_stat_sys_tables)
- [16️⃣ pg_stat_sys_indexes](#16️⃣ pg_stat_sys_indexes)
- [17️⃣ pg_stat_user_functions](#17️⃣ pg_stat_user_functions)
- [18️⃣ pg_stat_xact_all_tables](#18️⃣ pg_stat_xact_all_tables)
- [19️⃣ pg_stat_xact_sys_tables](#19️⃣ pg_stat_xact_sys_tables)
- [20️⃣ pg_stat_xact_user_functions](#20️⃣ pg_stat_xact_user_functions)
- [21️⃣ pg_stat_xact_user_tables](#21️⃣ pg_stat_xact_user_tables)
- [22️⃣ pg_statio_all_indexes](#22️⃣ pg_statio_all_indexes)
- [23️⃣ pg_statio_all_sequences](#23️⃣ pg_statio_all_sequences)
- [24️⃣ pg_statio_all_tables](#24️⃣ pg_statio_all_tables)
- [25️⃣ pg_statio_sys_indexes](#25️⃣ pg_statio_sys_indexes)
- [26️⃣ pg_statio_sys_sequences](#26️⃣ pg_statio_sys_sequences)
- [27️⃣ pg_statio_sys_tables](#27️⃣ pg_statio_sys_tables)
- [28️⃣ pg_statio_user_indexes](#28️⃣ pg_statio_user_indexes)
- [29️⃣ pg_statio_user_sequences](#29️⃣ pg_statio_user_sequences)
- [30️⃣ pg_statio_user_tables](#30️⃣ pg_statio_user_tables)
- [31️⃣ pg_stat_bgwriter](#31️⃣ pg_stat_bgwriter)
- [32️⃣ pg_stat_archiver](#32️⃣ pg_stat_archiver)
- [33️⃣ pg_stat_slru](#33️⃣ pg_stat_slru)
- [34️⃣ pg_stat_subscription](#34️⃣ pg_stat_subscription)
- [35️⃣ pg_stat_progress_analyze](#35️⃣ pg_stat_progress_analyze)
- [36️⃣ pg_stat_progress_basebackup](#36️⃣ pg_stat_progress_basebackup)
- [37️⃣ pg_stat_progress_cluster](#37️⃣ pg_stat_progress_cluster)
- [38️⃣ pg_stat_progress_copy](#38️⃣ pg_stat_progress_copy)
- [39️⃣ pg_stat_progress_create_index](#39️⃣ pg_stat_progress_create_index)
- [40️⃣ pg_stat_progress_vacuum](#40️⃣ pg_stat_progress_vacuum)
- [41️⃣ pg_stats](#41️⃣ pg_stats)
- [42️⃣ pg_stats_ext / pg_stats_ext_exprs](#42️⃣ pg_stats_ext / pg_stats_ext_exprs)
- [1️⃣ `pg_stat_activity` --- 当前会话信息](#1️⃣
- [✅ 培训总结建议](#✅ 培训总结建议)
一、整体分类框架(让 PG 小白有地图)
| 类别 | 代表视图 | 作用说明 |
|---|---|---|
| 🧭 连接与会话状态 | pg_stat_activity |
谁在执行什么 |
| 🧱 数据库整体统计 | pg_stat_database, pg_stat_database_conflicts |
各数据库命中率、事务数 |
| 📚 表与索引统计 | pg_stat_user_tables, pg_stat_user_indexes, pg_stat_all_tables, pg_stat_all_indexes |
表与索引的扫描、更新、删除、命中等信息 |
| 💾 I/O 统计 | pg_statio_* 系列 |
各对象的物理块读取次数 |
| 🧹 后台维护与写入 | pg_stat_bgwriter, pg_stat_wal, pg_stat_archiver |
检查点、WAL 写入与归档 |
| ⚙️ 进度监控 | pg_stat_progress_* 系列 |
查看 VACUUM、ANALYZE、CREATE INDEX 等进度 |
| 🔁 复制与订阅 | pg_stat_replication, pg_stat_wal_receiver, pg_stat_subscription, pg_stat_replication_slots |
主从复制与逻辑复制监控 |
| 🔒 安全与通信 | pg_stat_ssl, pg_stat_gssapi |
连接加密与认证状态 |
| 🧠 函数统计 | pg_stat_user_functions 等 |
PL/pgSQL 函数执行统计 |
| 💽 系统缓存与 SLRU | pg_stat_slru |
内部缓冲区命中率 |
| 📊 扩展统计 | pg_stats, pg_stats_ext, pg_stats_ext_exprs |
ANALYZE 收集的列与表达式统计 |
| 🧾 事务级视图 | pg_stat_xact_* 系列 |
当前事务内的临时统计 |
二、重点视图逐一讲解(附案例)
1️⃣ pg_stat_activity --- 当前会话信息
作用: 查看数据库当前正在干什么。
核心字段:
| 字段 | 说明 |
|---|---|
| pid | 进程号 |
| usename | 用户名 |
| datname | 数据库名 |
| state | 状态:active / idle / idle in transaction |
| query | 正在执行的 SQL |
| wait_event / wait_event_type | 是否在等待锁或 IO |
| backend_start / query_start | 启动或开始时间 |
案例操作:
sql
-- 1. 打开两个 psql 会话,A 和 B
-- A:
BEGIN;
UPDATE test SET name = 'aaa' WHERE id = 1; -- 不提交
-- B:
UPDATE test SET name = 'bbb' WHERE id = 1; -- 会被卡住
此时执行:
sql
SELECT pid, usename, state, wait_event_type, wait_event, query
FROM pg_stat_activity
WHERE state <> 'idle';
解读:
-
会看到 B 的会话在等待锁(
wait_event_type='Lock')。 -
A 是阻塞者。可以用:
sqlSELECT pg_blocking_pids(<B的pid>);找出阻塞源。
2️⃣ pg_stat_all_tables --- 所有表的访问统计
作用: 查看系统中所有表的访问频率和修改次数。
核心字段:
| 字段 | 含义 |
|---|---|
| seq_scan / seq_tup_read | 顺序扫描次数与读取行数 |
| idx_scan / idx_tup_fetch | 索引扫描次数与返回行数 |
| n_tup_ins / upd / del | 插入、更新、删除次数 |
| n_live_tup / n_dead_tup | 活行 / 死行数量 |
| vacuum_time | 上次清理时间 |
案例操作:
sql
CREATE TABLE t_stat (id serial, val int);
INSERT INTO t_stat(val)
SELECT generate_series(1,10000);
SELECT * FROM t_stat WHERE val > 9000; -- 执行几次
UPDATE t_stat SET val = val + 1 WHERE val < 1000;
DELETE FROM t_stat WHERE val > 9999;
SELECT relname, seq_scan, idx_scan, n_tup_ins, n_tup_upd, n_tup_del, n_dead_tup
FROM pg_stat_all_tables
WHERE relname='t_stat';
解读:
seq_scan> 0:说明全表扫描;n_dead_tup高:说明死行多,应 vacuum。
3️⃣ pg_stat_user_tables --- 仅用户表统计
与上一个类似,只过滤掉系统表。
案例:
sql
SELECT relname, seq_scan, idx_scan, n_dead_tup, last_autovacuum
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC
LIMIT 10;
说明:
适合 DBA 日常监控哪些表最脏(死行多)。
4️⃣ pg_stat_sys_tables --- 系统表统计
作用: PostgreSQL 自己内部表(如 pg_class, pg_attribute)的访问情况。
一般只用于数据库内核开发或诊断 catalog 锁等待。
案例:
sql
SELECT relname, seq_scan, idx_scan, n_tup_ins, n_tup_upd
FROM pg_stat_sys_tables
ORDER BY seq_scan DESC
LIMIT 5;
5️⃣ pg_stat_all_indexes --- 所有索引使用情况
作用: 了解哪些索引常用,哪些没用。
核心字段:
| 字段 | 说明 |
|---|---|
| idx_scan | 索引被使用的次数 |
| idx_tup_read | 从索引读取的元组数 |
| idx_tup_fetch | 通过索引返回的元组数 |
案例:
sql
CREATE INDEX idx_val ON t_stat(val);
SELECT * FROM t_stat WHERE val = 1;
SELECT * FROM t_stat WHERE val > 5000;
SELECT relname, indexrelname, idx_scan, idx_tup_read
FROM pg_stat_all_indexes
WHERE relname='t_stat';
解读:
idx_scan=0→ 该索引未被使用,可考虑删除;- 适用于索引健康检查。
6️⃣ pg_stat_user_indexes --- 用户表的索引统计
作用: 与 pg_stat_all_indexes 类似,只显示用户对象。
案例:
sql
SELECT indexrelname, idx_scan
FROM pg_stat_user_indexes
WHERE idx_scan = 0;
解读:
找到从未使用过的索引,可能浪费空间。
7️⃣ pg_stat_sys_indexes --- 系统索引统计
作用: 系统表上的索引统计,一般用于内核调优或 catalog 性能问题分析。
比如 catalog bloating 时可以参考。
案例:
sql
SELECT relname, indexrelname, idx_scan
FROM pg_stat_sys_indexes
ORDER BY idx_scan DESC
LIMIT 5;
8️⃣ pg_stat_database --- 数据库整体性能概览
作用: 按数据库级别聚合事务与缓存命中信息。
核心字段:
| 字段 | 含义 |
|---|---|
| numbackends | 当前连接数 |
| xact_commit / xact_rollback | 提交/回滚次数 |
| blks_read / blks_hit | 磁盘读 / 缓存命中次数 |
| tup_returned / tup_fetched | 返回行数 |
案例:
sql
SELECT datname,
numbackends,
xact_commit, xact_rollback,
blks_read, blks_hit,
ROUND(100.0 * blks_hit / (blks_hit + blks_read + 1),2) AS cache_hit_ratio
FROM pg_stat_database;
解读:
- 命中率低(< 90%)说明内存缓存不够;
- 回滚多说明事务出错或逻辑问题。
9️⃣ pg_stat_database_conflicts --- 数据库冲突统计(主要在流复制从库)
作用: 从库上统计由于主库写入导致的查询冲突。
字段解释:
| 字段 | 说明 |
|---|---|
| confl_tablespace | 表空间冲突 |
| confl_lock | 锁冲突 |
| confl_snapshot | 快照冲突 |
| confl_bufferpin | 缓冲区锁定冲突 |
| confl_deadlock | 死锁冲突 |
案例:
在流复制从库执行:
sql
SELECT datname, confl_lock, confl_snapshot, confl_deadlock
FROM pg_stat_database_conflicts;
解读:
- 如果
confl_snapshot增长快,说明主库写太多或复制延迟导致查询被终止; - 常见于备库用于只读分析时。
🔟 pg_stat_bgwriter --- 后台写入进程统计
作用: 查看检查点与后台写入活动。
核心字段:
| 字段 | 说明 |
|---|---|
| checkpoints_timed / req | 定期与手动触发次数 |
| buffers_checkpoint | 检查点写出的缓冲页数 |
| buffers_clean | 后台清理写出的页数 |
| buffers_backend | 前端进程自己写出的页数 |
案例:
sql
SELECT checkpoints_timed, checkpoints_req,
buffers_checkpoint, buffers_clean, buffers_backend
FROM pg_stat_bgwriter;
解读:
checkpoints_req频繁说明写压力大;- 优化方法:调大
checkpoint_timeout。
非常好 👍
你希望我延续前 10 个视图(已详细讲解:pg_stat_activity ~ pg_stat_wal_receiver)的风格------也就是:
每个视图都包含:
✅ 视图作用
✅ 常见字段说明
✅ 案例 SQL
✅ 实战解读
下面我将从第 11 个视图 (pg_stat_user_tables) 开始,完整延续相同风格,直到最后一个视图 pg_stats_ext_exprs,覆盖 PostgreSQL 14.5 的全部 42 个 pg_stat_* 视图。
11️⃣ pg_stat_user_tables
作用:显示用户表的访问统计信息。
常见字段:
| 字段 | 含义 |
|---|---|
| relid | 表的 OID |
| relname | 表名 |
| seq_scan | 顺序扫描次数 |
| seq_tup_read | 顺序扫描读取的行数 |
| idx_scan | 使用索引扫描的次数 |
| n_tup_ins / upd / del / hot_upd | 各类行操作统计 |
| vacuum_count / analyze_count | VACUUM 与 ANALYZE 执行次数 |
案例:
sql
SELECT relname, seq_scan, idx_scan, n_tup_ins, n_tup_upd, n_tup_del
FROM pg_stat_user_tables
ORDER BY seq_scan DESC;
实战解读 :
👉 快速判断哪个表"经常全表扫描",或"频繁更新"。
当 seq_scan 很高、idx_scan 很低时,说明缺乏索引或 SQL 写得不好。
12️⃣ pg_stat_user_indexes
作用:用户表中索引的使用统计。
常见字段:
| 字段 | 含义 |
|---|---|
| relname | 表名 |
| indexrelname | 索引名 |
| idx_scan | 索引被使用的次数 |
| idx_tup_read | 通过索引读取的行数 |
| idx_tup_fetch | 最终取到的行数(命中率) |
案例:
sql
SELECT relname, indexrelname, idx_scan, idx_tup_read, idx_tup_fetch
FROM pg_stat_user_indexes
ORDER BY idx_scan DESC;
实战解读 :
👉 找出"没被用过的索引"。
当 idx_scan = 0 时,可能是多余索引,影响写入性能。
13️⃣ pg_stat_all_tables
作用:统计所有表(用户 + 系统表)的访问信息。
案例:
sql
SELECT schemaname, relname, seq_scan, idx_scan
FROM pg_stat_all_tables
ORDER BY idx_scan DESC;
实战解读 :
👉 DBA 排查系统表访问异常(如 pg_catalog 过多访问)。
14️⃣ pg_stat_all_indexes
作用:统计所有索引的使用情况(包含系统索引)。
案例:
sql
SELECT schemaname, relname, indexrelname, idx_scan
FROM pg_stat_all_indexes
ORDER BY idx_scan DESC;
15️⃣ pg_stat_sys_tables
作用 :系统表访问统计。
适合调优系统 catalog 频繁访问问题。
案例:
sql
SELECT relname, seq_scan, idx_scan FROM pg_stat_sys_tables;
16️⃣ pg_stat_sys_indexes
作用:系统索引使用情况。
案例:
sql
SELECT relname, indexrelname, idx_scan
FROM pg_stat_sys_indexes
ORDER BY idx_scan DESC;
17️⃣ pg_stat_user_functions
作用:统计用户自定义函数的调用次数与耗时。
常见字段:
| 字段 | 含义 |
|---|---|
| funcid | 函数 OID |
| funcname | 函数名 |
| calls | 调用次数 |
| total_time | 总耗时(毫秒) |
| self_time | 函数自身耗时(不含子函数) |
案例:
sql
SELECT funcname, calls, total_time, self_time
FROM pg_stat_user_functions
ORDER BY total_time DESC;
实战解读 :
👉 找出最耗时的函数,优化 PL/pgSQL 逻辑。
18️⃣ pg_stat_xact_all_tables
作用 :显示当前事务内(未提交)的所有表操作统计。
事务提交后数据会清空。
案例:
sql
BEGIN;
UPDATE users SET age = age + 1;
SELECT * FROM pg_stat_xact_all_tables WHERE relname = 'users';
ROLLBACK;
19️⃣ pg_stat_xact_sys_tables
作用:与上一个类似,但仅显示系统表的事务统计。
20️⃣ pg_stat_xact_user_functions
作用:事务内函数调用统计。
案例:
sql
BEGIN;
SELECT my_function(1);
SELECT * FROM pg_stat_xact_user_functions;
ROLLBACK;
21️⃣ pg_stat_xact_user_tables
作用:事务内用户表操作统计(未提交)。
案例:
sql
BEGIN;
INSERT INTO users(name) VALUES('Alice');
SELECT relname, n_tup_ins, n_tup_upd, n_tup_del
FROM pg_stat_xact_user_tables
WHERE relname='users';
ROLLBACK;
22️⃣ pg_statio_all_indexes
作用:索引层面的 I/O 统计(读写块命中率)。
常见字段:
| 字段 | 含义 |
|---|---|
| relname | 表名 |
| indexrelname | 索引名 |
| idx_blks_read | 从磁盘读的块数 |
| idx_blks_hit | 缓存命中的块数 |
案例:
sql
SELECT relname, indexrelname, idx_blks_read, idx_blks_hit
FROM pg_statio_all_indexes
ORDER BY idx_blks_read DESC;
23️⃣ pg_statio_all_sequences
作用:序列对象的 I/O 统计。
案例:
sql
SELECT relname, blks_read, blks_hit
FROM pg_statio_all_sequences;
24️⃣ pg_statio_all_tables
作用:表的物理块读写命中统计。
案例:
sql
SELECT relname, heap_blks_read, heap_blks_hit
FROM pg_statio_all_tables
ORDER BY heap_blks_read DESC;
25️⃣ pg_statio_sys_indexes
作用:系统索引的 I/O 统计。
26️⃣ pg_statio_sys_sequences
作用:系统序列的缓存与磁盘读统计。
27️⃣ pg_statio_sys_tables
作用:系统表的 I/O 命中情况。
28️⃣ pg_statio_user_indexes
作用:用户索引的 I/O 统计。
案例:
sql
SELECT relname, indexrelname, idx_blks_read, idx_blks_hit
FROM pg_statio_user_indexes
ORDER BY idx_blks_read DESC;
29️⃣ pg_statio_user_sequences
作用:用户序列的 I/O 命中统计。
案例:
sql
SELECT relname, blks_read, blks_hit
FROM pg_statio_user_sequences;
30️⃣ pg_statio_user_tables
作用:用户表的缓冲块命中率分析。
案例:
sql
SELECT relname,
heap_blks_read, heap_blks_hit,
ROUND(heap_blks_hit::numeric/(heap_blks_hit+heap_blks_read+1),4) AS hit_ratio
FROM pg_statio_user_tables
ORDER BY hit_ratio ASC;
31️⃣ pg_stat_bgwriter
作用:后台写进程 (bgwriter) 的性能统计。
常见字段:
| 字段 | 含义 |
|---|---|
| checkpoints_timed | 定时触发的 checkpoint 次数 |
| checkpoints_req | 手动触发的次数 |
| buffers_checkpoint | checkpoint 写入的缓冲页 |
| buffers_clean | 后台清理写入的页数 |
| buffers_backend | 用户进程自己写的页数 |
案例:
sql
SELECT checkpoints_timed, buffers_checkpoint, buffers_clean, buffers_backend
FROM pg_stat_bgwriter;
实战解读 :
👉 判断 checkpoint 是否太频繁(性能抖动原因)。
32️⃣ pg_stat_archiver
作用:归档进程(archiver)的 WAL 文件统计。
案例:
sql
SELECT archived_count, last_archived_wal, failed_count
FROM pg_stat_archiver;
33️⃣ pg_stat_slru
作用:统计 PostgreSQL 内部使用的 SLRU 缓冲(如事务状态、子事务)。
案例:
sql
SELECT name, blks_zeroed, blks_hit, blks_read, blks_written
FROM pg_stat_slru;
实战解读 :
👉 监控子事务使用异常(例如大量 SAVEPOINT)。
34️⃣ pg_stat_subscription
作用:逻辑复制的订阅端状态信息。
案例:
sql
SELECT subid, subname, pid, relid, received_lsn, latest_end_lsn, latest_end_time
FROM pg_stat_subscription;
35️⃣ pg_stat_progress_analyze
作用:显示 ANALYZE 命令的执行进度。
案例:
sql
ANALYZE VERBOSE users;
SELECT * FROM pg_stat_progress_analyze;
36️⃣ pg_stat_progress_basebackup
作用 :显示 basebackup(全量备份)进度(在执行 pg_basebackup 时可见)。
案例:
sql
SELECT * FROM pg_stat_progress_basebackup;
37️⃣ pg_stat_progress_cluster
作用:显示 CLUSTER 命令(物理重排表)的执行进度。
案例:
sql
CLUSTER users USING idx_users_id;
SELECT * FROM pg_stat_progress_cluster;
38️⃣ pg_stat_progress_copy
作用:显示 COPY 命令的进度。
案例:
sql
COPY users TO '/tmp/users.csv' CSV;
SELECT * FROM pg_stat_progress_copy;
39️⃣ pg_stat_progress_create_index
作用:显示索引创建(CREATE INDEX)进度。
案例:
sql
CREATE INDEX CONCURRENTLY idx_name ON users(name);
SELECT * FROM pg_stat_progress_create_index;
40️⃣ pg_stat_progress_vacuum
作用:显示 VACUUM 操作进度。
案例:
sql
VACUUM (VERBOSE, ANALYZE) users;
SELECT * FROM pg_stat_progress_vacuum;
41️⃣ pg_stats
作用:显示每列的统计信息(ANALYZE 生成)。
常见字段:
| 字段 | 含义 |
|---|---|
| tablename | 表名 |
| attname | 列名 |
| n_distinct | 不同值估计数 |
| most_common_vals | 最常见值 |
| most_common_freqs | 对应频率 |
案例:
sql
SELECT tablename, attname, n_distinct, most_common_vals
FROM pg_stats
WHERE tablename = 'users';
42️⃣ pg_stats_ext / pg_stats_ext_exprs
作用:显示多列联合统计(扩展统计信息)。
案例:
sql
SELECT * FROM pg_stats_ext WHERE tablename='users';
SELECT * FROM pg_stats_ext_exprs WHERE tablename='users';
实战解读 :
👉 当某些列组合频繁用于查询条件时,可通过 CREATE STATISTICS 改善估算准确度。
✅ 培训总结建议
| 类型 | 推荐讲法 | 示例演示 |
|---|---|---|
| 连接与会话类 | 实时查询、kill 会话 | pg_stat_activity |
| 表与索引类 | 查热点表、查索引命中 | pg_stat_user_tables, pg_stat_user_indexes |
| 后台进程类 | 检查 bgwriter、archiver 状态 | pg_stat_bgwriter, pg_stat_archiver |
| I/O 类 | 分析缓存命中率 | pg_statio_user_tables |
| 维护进度类 | 监控 VACUUM / CREATE INDEX | pg_stat_progress_* |
| 扩展统计类 | 优化执行计划 | pg_stats, pg_stats_ext |
声明: GPT 原创