postgresql.conf
pg_stat_statements.max = 1000000
pg_stat_statements.track = all
pg_stat_statements.track_utility = off
pg_stat_statements.save = on
shared_preload_libraries='pg_stat_statements'
track_io_timing = on
track_activity_query_size = 2048

create extension pg_stat_statements;

select * from pg_stat_statements;

一、pg_stat_statements模块简介
pg_stat_statements模块提供一种方法追踪一个服务器所执行的所有 SQL 语句的执行统计信息,可以用于统计数据库的资源开销,分析TOP SQL。

该模块必须通过在postgresql.conf的shared_preload_libraries中增加pg_stat_statements来载入,因为它需要额外的共享内存。

这意味着增加或移除该模块需要一次服务器重启。
当pg_stat_statements被载入时,它会跟踪该服务器 的所有数据库的统计信息。

该模块提供了一个视图 pg_stat_statements以及函数pg_stat_statements_reset 和pg_stat_statements用于访问和操纵这些统计信息。

这些视图 和函数不是全局可用的,但是可以用CREATE EXTENSION pg_stat_statements 为特定数据库启用它们。

二、安装使用pg_stat_statements
pg_stat_statements是PostgreSQL的核心插件之一。
可以在编译PostgreSQL时安装,也可以单独安装。

编译时安装
make world
make install-world

单独安装
cd src/contrib/pg_stat_statements/
make; make install

然后,由于pg_stat_statements 既使用了hook,同时又是以 extension 形式被使用,所以需要再作两件事情:

1.修改配置参数
vi $PGDATA/postgresql.conf
------
shared_preload_libraries='pg_stat_statements'
#加载pg_stat_statements模块

track_io_timing = on
#如果要跟踪IO消耗的时间,需要打开如上参数

track_activity_query_size = 2048
#设置单条SQL的最长长度,超过被截断显示(可选)

#以下配置pg_stat_statements采样参数

pg_stat_statements.max = 10000
# 在pg_stat_statements中最多保留多少条统计信息,通过LRU算法,覆盖老的记录。

pg_stat_statements.track = all
# all - (所有SQL包括函数内嵌套的SQL), top - 直接执行的SQL(函数内的sql不被跟踪), none - (不跟踪)

pg_stat_statements.track_utility = off
# 是否跟踪非DML语句 (例如DDL,DCL),on表示跟踪, off表示不跟踪

pg_stat_statements.save = on
# 重启后是否保留统计信息

------
重启数据库
pg_ctl restart -m fast

2.创建pg_stat_statements extension
在需要查询TOP SQL的数据库中,创建extension
create extension pg_stat_statements;

三、分析TOP SQL
查询pg_stat_statements视图,可以得到统计信息
SQL语句中的一些过滤条件在pg_stat_statements中会被替换成变量,减少重复显示的问题。
pg_stat_statements视图包含了一些重要的信息。

例如:
1. SQL的调用次数,总的耗时,最快执行时间,最慢执行时间,平均执行时间,执行时间的方差(看出抖动),总共扫描或返回或处理了多少行;
2. shared buffer的使用情况,命中,未命中,产生脏块,驱逐脏块;
3. local buffer的使用情况,命中,未命中,产生脏块,驱逐脏块;
4. temp buffer的使用情况,读了多少脏块,驱逐脏块;
5. 数据块的读写时间。

常用的统计sql参考
最耗IO SQL,单次调用最耗IO SQL TOP 5
select userid::regrole, dbid, query from pg_stat_statements order by (blk_read_time+blk_write_time)/calls desc limit 5;

总最耗IO SQL TOP 5
select userid::regrole, dbid, query from pg_stat_statements order by (blk_read_time+blk_write_time) desc limit 5;

最耗时 SQL,单次调用最耗时 SQL TOP 5
select userid::regrole, dbid, query from pg_stat_statements order by mean_time desc limit 5;

总最耗时 SQL TOP 5
select userid::regrole, dbid, query from pg_stat_statements order by total_time desc limit 5;

响应时间抖动最严重 SQL
select userid::regrole, dbid, query from pg_stat_statements order by stddev_time desc limit 5;

最耗共享内存 SQL
select userid::regrole, dbid, query from pg_stat_statements order by (shared_blks_hit+shared_blks_dirtied) desc limit 5;

最耗临时空间 SQL
select userid::regrole, dbid, query from pg_stat_statements order by temp_blks_written desc limit 5;

重置统计信息
pg_stat_statements是累积的统计,如果要查看某个时间段的统计,需要打快照
用户也可以定期清理历史的统计信息,通过调用如下SQL
select pg_stat_statements_reset();

四、手册提供的示例验证过程:
修改相关配置参数
# postgresql.conf
shared_preload_libraries = 'pg_stat_statements'
pg_stat_statements.max = 10000
pg_stat_statements.track = all

重启数据库,使参数生效
pg_ctl restart -m fast

[postgres@hgdb01 ~]$ createdb bench

[postgres@hgdb01 ~]$ pgbench -i bench
NOTICE: table "pgbench_history" does not exist, skipping
NOTICE: table "pgbench_tellers" does not exist, skipping
NOTICE: table "pgbench_accounts" does not exist, skipping
NOTICE: table "pgbench_branches" does not exist, skipping
creating tables...
100000 of 100000 tuples (100%) done (elapsed 2.84 s, remaining 0.00 s)
vacuum...
set primary keys...
done.

[postgres@hgdb01 ~]$ pgbench -c10 -t300 bench
starting vacuum...end.
transaction type: TPC-B (sort of)
scaling factor: 1
query mode: simple
number of clients: 10
number of threads: 1
number of transactions per client: 300
number of transactions actually processed: 3000/3000
latency average: 16.183 ms
tps = 617.923361 (including connections establishing)
tps = 625.803049 (excluding connections establishing)

[postgres@hgdb01 data]$ psql bench
psql (9.5.7)
Type "help" for help.

bench=# \x
Expanded display is on.
bench=# SELECT query, calls, total_time, rows, 100.0 * shared_blks_hit /
nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent
FROM pg_stat_statements ORDER BY total_time DESC LIMIT 5;
-[ RECORD 1 ]-------------------------------------------------------------------
query | UPDATE pgbench_branches SET bbalance = bbalance + ? WHERE bid = ?;
calls | 3000
total_time | 19268.9709999999 #该语句执行总时间,毫秒!
rows | 3000 #检索或影响的行总数
hit_percent | 99.9816828849456211 #缓冲池命中率
-[ RECORD 2 ]-------------------------------------------------------------------
query | UPDATE pgbench_tellers SET tbalance = tbalance + ? WHERE tid = ?;
calls | 3000
total_time | 13394.484
rows | 3000
hit_percent | 99.9780364594772677
-[ RECORD 3 ]-------------------------------------------------------------------
query | vacuum analyze pgbench_accounts
calls | 1
total_time | 2093.405
rows | 0
hit_percent | 99.9002991026919242
-[ RECORD 4 ]-------------------------------------------------------------------
query | alter table pgbench_accounts add primary key (aid)
calls | 1
total_time | 1159.96
rows | 0
hit_percent | 100.0000000000000000
-[ RECORD 5 ]-------------------------------------------------------------------
query | UPDATE pgbench_accounts SET abalance = abalance + ? WHERE aid = ?;
calls | 3000
total_time | 1055.42399999999
rows | 3000
hit_percent | 98.4236453201970443

#调用函数清理历史的统计信息
bench=# SELECT pg_stat_statements_reset();
pg_stat_statements_reset
--------------------------

(1 row)

#此时收集信息已做清清理
bench=# SELECT query, calls, total_time, rows, 100.0 * shared_blks_hit /
bench-# nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent
bench-# FROM pg_stat_statements ORDER BY total_time DESC LIMIT 5;
query | calls | total_time | rows | hit_percent
------------------------------------+-------+------------+------+-------------
SELECT pg_stat_statements_reset(); | 1 | 0.925 | 1 |
(1 row)

至此本实验结束!

附:pg_stat_statements视图
由该模块收集的统计信息可以通过一个名为 pg_stat_statements的视图使用。
这个视图为每 一个可区分的数据库 ID、用户 ID 和查询 ID(最多到该模块可以追 踪的可区分语句的数量)的组合都包含一行。

该视图的列如下表中所示。
名称 类型 引用 描述
userid oid pg_authid.oid 执行该语句的用户的 OID
dbid oid pg_database.oid 在其中执行该语句的数据库的 OID
queryid bigint   内部哈希码,从语句的解析树计算得来
query text   语句的文本形式
calls bigint   被执行的次数
total_time double precision   在该语句中花费的总时间,以毫秒计
min_time double precision   在该语句中花费的最小时间,以毫秒计
max_time double precision   在该语句中花费的最大时间,以毫秒计
mean_time double precision   在该语句中花费的平均时间,以毫秒计
stddev_time double precision   在该语句中花费时间的总体标准偏差,以毫秒计
rows bigint   该语句检索或影响的行总数
shared_blks_hit bigint   该语句造成的共享块缓冲命中总数
shared_blks_read bigint   该语句读取的共享块的总数
shared_blks_dirtied bigint   该语句弄脏的共享块的总数
shared_blks_written bigint   该语句写入的共享块的总数
local_blks_hit bigint   该语句造成的本地块缓冲命中总数
local_blks_read bigint   该语句读取的本地块的总数
local_blks_dirtied bigint   该语句弄脏的本地块的总数
local_blks_written bigint   该语句写入的本地块的总数
temp_blks_read bigint   该语句读取的临时块的总数
temp_blks_written bigint   该语句写入的临时块的总数
blk_read_time double precision   该语句花在读取块上的总时间,以毫秒计(如果track_io_timing被启用,否则为零)
blk_write_time double precision   该语句花在写入块上的总时间,以毫秒计(如果track_io_timing被启用,否则为零)

F.29.2. 函数
pg_stat_statements_reset() 返回 void
pg_stat_statements_reset抛弃目前由pg_stat_statements收集的所有统计信息。默认情况下,这个函数只能被超级用户执行。

pg_stat_statements(showtext boolean) returns setof record
pg_stat_statements视图按照一个也叫 pg_stat_statements的函数来定义。客户端可以直接调用 pg_stat_statements函数,并且通过指定 showtext := false来忽略查询文本(即,对应于视图的 query列的OUT参数将返回空值)。 这个特性是为了支持不想重复接收长度不定的查询文本的外部工具而设计的。 这类工具可以转而自行缓存第一个观察到的查询文本,因为这就是 pg_stat_statements自己所做的全部工作,并且只在需要的 时候检索查询文本。因为服务器会把查询文本存储在一个文件中,这种方法可 以降低重复检查pg_stat_statements数据的物理 I/O。

F.29.3. 配置参数
pg_stat_statements.max (integer)
pg_stat_statements.max是由该模块跟踪的语句的最大数目(即pg_stat_statements视图中行的最大数量)。如果观测到的可区分的语句超过这个数量,最少被执行的语句的信息将会被丢弃。默认值为 5000。这个参数只能在服务器启动时设置。

pg_stat_statements.track (enum)
pg_stat_statements.track控制哪些语句会被该模块计数。
指定top可以跟踪顶层语句(那些直接由客户端发出的语句)
指定all还可以跟踪嵌套的语句(例如在函数中调用的语句)
指定none可以禁用语句统计信息收集。
默认值是top。 只有超级用户能够改变这个设置。

pg_stat_statements.track_utility (boolean)
pg_stat_statements.track_utility控制该模块是否会跟踪工具命令。工具命令是除了SELECT、INSERT、 UPDATE和DELETE之外所有的其他命令。默认值是on。 只有超级用户能够改变这个设置。

pg_stat_statements.save (boolean)
pg_stat_statements.save指定是否在服务器关闭之后还保存语句统计信息。如果被设置为off,那么关闭后不保存统计信息并且在服务器启动时也不会重新载入统计信息。默认值为on。这个参数只能在postgresql.conf文件中或者在服务器命令行上设置。

Postgresql 监控sql之 pg_stat_statements模块的更多相关文章

  1. 监控 SQL Server (2005/2008) 的运行状况

    Microsoft SQL Server 2005 提供了一些工具来监控数据库.方法之一是动态管理视图.动态管理视图 (DMV) 和动态管理函数 (DMF) 返回的服务器状态信息可用于监控服务器实例的 ...

  2. Performance Monitor3:监控SQL Server的内存压力

    SQL Server 使用的资源受到操作系统的调度,同时,SQL Server在内部实现了一套调度算法,用于管理从操作系统获取的资源,主要是对内存和CPU资源的调度.一个好的数据库系统,必定在内存中缓 ...

  3. 用脚本定时监控SQL Server主从一致性

    用脚本定时监控SQL Server主从一致性 首先说一下我们的环境 我们使用的是事务复制,复制是单向的,主服务器和从服务器都在同一个机房,当然不同机房也可以,只需要改一下IP和端口 下面的脚本在我们的 ...

  4. JavaMelody监控SQL

    前言 前面讲过了Javamelody的基本配置,这里简单的介绍下,如何使用Javamelody来监控JDBC以及SQL. 手码不易,转载请注明:xingoo 在网上搜索很多资料,仅有开源社区上的两篇帖 ...

  5. 第三篇——第二部分——第六文 监控SQL Server镜像

    原文:第三篇--第二部分--第六文 监控SQL Server镜像 原文出处:http://blog.csdn.net/dba_huangzj/article/details/26846203 要优化, ...

  6. SpringMVC4+MyBatis+SQL Server2014+druid 监控SQL运行情况

    前言 在基于SpringMVC+MyBatis的开发过程中,我们希望能看到自己手写SQL的执行情况,在开发阶段我们可以配置log4j在控制台里基于debug模式查看,那么上线后,在生产声我们想查看SQ ...

  7. 采用Opserver来监控你的ASP.NET项目系列(二、监控SQL Server与Asp.Net项目)

    前言 之前有过2篇关于如何监控ASP.NET core项目的文章,有兴趣的也可以看看. 今天我们主要来介绍一下,如何使用Opserver监控我们的SQL Server 和ASP.NET项目的异常监控 ...

  8. 【转】SQL Server 运行状况监控SQL语句

    SQL Server 运行状况监控SQL语句   Microsoft SQL Server 2005 提供了一些工具来监控数据库.方法之一是动态管理视图.动态管理视图 (DMV) 和动态管理函数 (D ...

  9. SQL Server 运行状况监控SQL语句

    Microsoft SQL Server 2005 提供了一些工具来监控数据库.方法之一是动态管理视图.动态管理视图 (DMV) 和动态管理函数 (DMF) 返回的服务器状态信息可用于监控服务器实例的 ...

随机推荐

  1. 一、Django入门

    1.安装: 下载地址:https://www.djangoproject.com/download/ 原文节选: How to get Django Django is available open- ...

  2. 2018蓝桥杯C/C++组第4题第几个幸运数

    题目4标题:第几个幸运数 到x星球旅行的游客都被发给一个整数,作为游客编号.x星的国王有个怪癖,他只喜欢数字3,5和7.国王规定,游客的编号如果只含有因子:3,5,7,就可以获得一份奖品. 我们来看前 ...

  3. Codeforces 785 E. Anton and Permutation(分块,树状数组)

    Codeforces 785 E. Anton and Permutation 题目大意:给出n,q.n代表有一个元素从1到n的数组(对应索引1~n),q表示有q个查询.每次查询给出两个数l,r,要求 ...

  4. zookeeper系列(八)zookeeper客户端的底层详解

    作者:leesf    掌控之中,才会成功:掌控之外,注定失败.出处:http://www.cnblogs.com/leesf456/p/6098255.html 尊重原创,共同学习进步:  一.前言 ...

  5. Java官方操纵byte数组的方式

    java官方提供了一种操作字节数组的方法——内存流(字节数组流)ByteArrayInputStream.ByteArrayOutputStream ByteArrayOutputStream——by ...

  6. python文件夹中pycache文件是什么

    python(pycache文件的问题):python属于脚本语言,执行python文件需要通过python解释器将源码转换为字节码,然后供cpu读取,pycache文件夹里面保存的就是py文件对应的 ...

  7. 软工团队Git现场编程实战

    组员职责分工 成员 分工 鲍子涵 分配职责,整合代码 吴宜航 UI设计与实现 钟博 UI设计与实现(Main Coder) 黄海东 数据整理 王镇隆 前端api接口分析和使用(Main Coder) ...

  8. mysql字符串函数:FIND_IN_SET()使用方法详解

    语法: FIND_IN_SET(str,strlist) 第一个参数str是要查找的字符串. 第二个参数strlist是要搜索的逗号分隔的字符串列表. 假如字符串str 在由N 子链组成的字符串列表s ...

  9. laravel中跟据某个特定顺序去排序查出来的数据:FIND_IN_SET

    //返回有顺序的客户id $customer_ids = $customer->bespeakTime($uid); $res = Customer::with('customer_indust ...

  10. Java-JVM 运行时内存结构(Run-Time Data Areas)

    Java 虚拟机定义了在程序执行期间使用的各种运行时数据区域. 其中一些数据区域所有线程共享,在 Java 虚拟机(JVM)启动时创建,仅在 Java 虚拟机退出时销毁. 还有一些数据区域是每个线程的 ...