一、统计信息
1.1 PG统计信息概述
pg的统计信息主要分为两种:
第一类统计信息是是负载指标“统计信息”(Monitoring stats),通过stat collector进程进行实时采集更新的负载指标,记录一些对磁盘块、表、索引相关的统计信息,SQL语句执行代价信息等。
第二类统计信息是数据分布状态描述“统计信息”(Data distribution stats),这些统计信息为优化器选择最优执行计划提供依据。该类统计信息采集的方式有两种:
- 后台进程autovacuum lancher触发的统计信息采集
autovacuum : 历史无效数据、冻结事务、xid信息的清理都是由该进程处理。
vacuum : 标准形式的 vacuum 可以和生产数据库操作并行运行(select、insert、update、delete等命令将继续正常工作,但在清理期间你无法使用alter table等命令来更新表的定义)。
vacuum full : vacuum full 类似于表的重建或者说碎片整理,以收回更多磁盘空间但是运行起来更慢,而且vacuum full操作执行期间无法和对此表上的其他操作并发执行。vacuum full不会有后台进程主从触发(只能手动执行)。
- 手动执行analyze table进行手动采集更新统计信息
1.2 负载指标统计信息
1.2.1 pg_stat_database 指标含义
通过pg_stat_database我们可以大致的了解一个数据库的历史运行情况,比较常见的一个问题定位有:
- 当tup_returned值远大于tup_fetched时,说明该数据库下存在较多全表扫描SQL,结合pg_stat_statments来定位具体慢SQL或者结合pg_stat_user_tables来定位全表扫描相关表
- 当tup_updated的数值比较大时,说明数据库有很频繁的更新,这个时候就需要关注一下vacuum相关的指标和长事务,如果没有及时进行垃圾回收会造成数据膨胀的比较厉害,一定程度会响应表查询效率
- 当temp_files的数值比较大时,说明存在很多的排序,hash,或者聚合这种操作,可以通过增大work_mem减少临时文件的产生,并且同时这些操作的性能也会有较大的提升
postgres=# select * from pg_stat_database where datname='db1';
-[ RECORD 1 ]---------+------------------------------
datid | 16384 //数据库oid
datname | db1 //数据库名称
numbackends | 0 //访问当前数据库连接数量
xact_commit | 35170800 //该数据库事务提交总量
xact_rollback | 65 //该数据库事务回滚总量
blks_read | 1047403 //总磁盘物理读的块数,这里read也可能是从page cache读取,如果这里很高需要结合blk_read_time看是否真的存在很多实际从磁盘读取的情况。
blks_hit | 152779457 //在shared_buffer命中的块数
tup_returned | 218640517 //对于表来说是全表扫描的行数,对于索引是通过索引方法返回的索引行数,如果这个值数量明显大于tup_fetched,说明当前数据库存在大量全表扫描的情况。
tup_fetched | 32778249 //指通过索引返回的行数
tup_inserted | 18513456 //插入的行数
tup_updated | 1755886 //更新的行数
tup_deleted | 21499 //删除的行数
conflicts | 0 //与恢复冲突取消的查询次数(只会在备库上发生)
temp_files | 20 //产生临时文件的数量,如果这个值很高说明work_mem需要调大
temp_bytes | 334708736 //临时文件的大小
deadlocks | 1 //死锁的数量,如果这个值很大说明业务逻辑有问题
checksum_failures |
checksum_last_failure | //
blk_read_time | 0 //数据库中花费在读取文件的时间,这个值较高说明内存较小,需要频繁的从磁盘中读入数据文件
blk_write_time | 0 //数据库中花费在写数据文件的时间,pg中脏页一般都写入page cache,如果这个值较高,说明page cache较小,操作系统的page cache需要更积极的写入。
stats_reset | 2020-09-24 16:15:54.395313+08 //统计信息重置的时间
1.2.2 pg_stat_user_tables 指标含义
通过 pg_stat_user_tables,我们可以知道当前数据库下哪些表发生全表扫描频繁,哪些表变更比较频繁,对于变更较频繁的表可多关注其vacuum相关的指标,避免表膨胀。
db1=# select * from pg_stat_user_tables where relname='t1';
-[ RECORD 1 ]-------+------------------------------
relid | 17087 //表的oid
schemaname | public //schema模式
relname | t1 //表名称
seq_scan | 66 //发生全表扫描次数
seq_tup_read | 602468 //全表扫描数据行数,如果这个值很大说明对这个表进行sql很有可能都是全表扫描,需要结合具体的执行计划来看
idx_scan | 149 //索引扫描测试
idx_tup_fetch | 140 //通过索引扫描返回的行数
n_tup_ins | 10000 //插入数据行数
n_tup_upd | 40 //更新数据行数
n_tup_del | 1 //删除数据行数
n_tup_hot_upd | 35 //hot update的数据行数,这个值与n_tup_upd越接近说明update的性能较好,更新数据时不会更新索引。
n_live_tup | 9999 //活着的行数量
n_dead_tup | 34 //死亡的行数量,无效数据行
n_mod_since_analyze | 22 //上次analyze的时间
last_vacuum | //上次手动vacuum的时间
last_autovacuum | //上次autovacuum的时间
last_analyze | //上次手动analyze的时间
last_autoanalyze | 2020-10-12 14:21:44.597134+08 //上次自动analyze的时间
vacuum_count | 0