PostgreSQL 插件 pg_stat_statements
1. pg_stat_statements 说明
pg_stat_statements 是 PostgreSQL 数据库的一个开源插件,简称 pgss,用于跟踪数据库中 SQL 语句的执行计划,统计执行时间和资源消耗。
2. pg_stat_statements 参数
- pg_stat_statements.max,跟踪的最大 SQL 语句数量,最小值 100, 最大值 INT_MAX,默认值 5000
- pg_stat_statements.track,表示跟踪什么类型的 SQL 语句,可选值为 none,top,all,默认值为 top
- pg_stat_statements.track_utility,表示是否跟踪 utility 语句,可选值 true,false,默认值 true
- pg_stat_statements.track_planning,表示是否跟踪执行计划耗时,可选值 true,false,默认值 false
- pg_stat_statements.save,表示当数据库关机时,是否保存统计信息,可选值 true,false,默认值 true
3. pg_stat_statements 使用方法
在 postgresql.conf 文件中设置参数,在数据库启动时加载 pgss,如下:
shared_preload_libraries = 'pg_stat_statements'
连接到数据库创建扩展 pg_stat_statements,如下:
create extension pg_stat_statements;
创建扩展之后,数据库中会创建一个视图,名为 pg_stat_statements,该视图中保存了跟踪到的 SQL 统计信息,查询视图如下:
select * from pg_stat_statements;
通常的查询如下,包含用户ID,数据库ID,查询ID,查询SQL,执行计划,执行计划耗时(最小,最大,平均),调用次数,总的执行耗时,最小执行耗时,最大执行耗时,平均执行耗时,涉及的行数,共享页相关的情况(命中数量,读取数量,脏页数量,写回磁盘的数量),本地页相关的情况(命中数量,读取数量,脏页数量,写回磁盘的数量),临时页读写情况,WAL日志相关情况(WAL 记录数量,FPI数量,字节数量)。
userid | 10 dbid | 13580 queryid | 7402507857450412395 query | insert into t1 select * from t1 plans | 0 total_plan_time | 0 min_plan_time | 0 max_plan_time | 0 mean_plan_time | 0 stddev_plan_time | 0 calls | 11 total_exec_time | 20.379245 min_exec_time | 0.062924 max_exec_time | 9.044859 mean_exec_time | 1.8526586363636364 stddev_exec_time | 2.7114879328796 rows | 4094 shared_blks_hit | 4155 shared_blks_read | 2 shared_blks_dirtied | 18 shared_blks_written | 18 local_blks_hit | 0 local_blks_read | 0 local_blks_dirtied | 0 local_blks_written | 0 temp_blks_read | 0 temp_blks_written | 0 blk_read_time | 0 blk_write_time | 0 wal_records | 4094 wal_fpi | 0 wal_bytes | 257922
重置统计数据:
select pg_stat_statements_reset();
4. pg_stat_statements 内部实现原理
4.1 数据如何获取
通过在加载插件时安装 hook 函数,在 SQL 执行的不同阶段获取对应的数据。
主要 hook 函数如下:
/* * Install hooks. */ prev_shmem_startup_hook = shmem_startup_hook; shmem_startup_hook = pgss_shmem_startup; prev_post_parse_analyze_hook = post_parse_analyze_hook; post_parse_analyze_hook = pgss_post_parse_analyze; prev_planner_hook = planner_hook; planner_hook = pgss_planner; prev_ExecutorStart = ExecutorStart_hook; ExecutorStart_hook = pgss_ExecutorStart; prev_ExecutorRun = ExecutorRun_hook; ExecutorRun_hook = pgss_ExecutorRun; prev_ExecutorFinish = ExecutorFinish_hook; ExecutorFinish_hook = pgss_ExecutorFinish; prev_ExecutorEnd = ExecutorEnd_hook; ExecutorEnd_hook = pgss_ExecutorEnd; prev_ProcessUtility = ProcessUtility_hook; ProcessUtility_hook = pgss_ProcessUtility;
4.2 数据如何存储
基于共享内存的 hash 表 pgss_hash 存储数据,在加载插件时计算需要的共享内存大小。
_PG_init() RequestAddinShmemSpace()
当参数 pg_stat_statements.save 设置为 on 时,关闭数据库会将 pgss 的统计信息存储在文件中,启动数据库时从文件读取到共享内存里。
文章评论
共0条评论