所谓 慢 SQL 是指在数据库中执行时间超过指定阈值的语句。慢查询太多,对于业务而言,是有很大风险的,可能随时都会因为某种原因而被触发,并且根据我们的经验,数据库最常出现的问题,都是因为慢查询导致数据库慢了,进而导致整个实例 “雪崩” 从而导致线上故障。 本篇文章将介绍 PostgreSQL 慢 SQL 如何定位排查。
1. 日志参数设置
2. pg_stat_statements 插件
2.1 确认是否安装插件
输出:
总用量 52
-rw-r--r-- 1 root root 1246 9月 14 15:38 pg_stat_statements--1.0--1.1.sql
-rw-r--r-- 1 root root 1336 9月 14 15:38 pg_stat_statements--1.1--1.2.sql
-rw-r--r-- 1 root root 1454 9月 14 15:38 pg_stat_statements--1.2--1.3.sql
-rw-r--r-- 1 root root 345 9月 14 15:38 pg_stat_statements--1.3--1.4.sql
-rw-r--r-- 1 root root 305 9月 14 15:38 pg_stat_statements--1.4--1.5.sql
-rw-r--r-- 1 root root 1427 9月 14 15:38 pg_stat_statements--1.4.sql
-rw-r--r-- 1 root root 376 9月 14 15:38 pg_stat_statements--1.5--1.6.sql
-rw-r--r-- 1 root root 806 9月 14 15:38 pg_stat_statements--1.6--1.7.sql
-rw-r--r-- 1 root root 191 9月 14 15:38 pg_stat_statements.control
-rw-r--r-- 1 root root 449 9月 14 15:38 pg_stat_statements--unpackaged--1.0.sql
-rw-r--r-- 1 root root 310 9月 5 10:21 plpgsql--1.0.sql
-rw-r--r-- 1 root root 179 9月 5 10:21 plpgsql.control
-rw-r--r-- 1 root root 370 9月 5 10:21 plpgsql--unpackaged--1.0.sql
可以看到一些关于 pg_stat_statements 文件信息,表示插件已被安装完成。如果看到相关文件表示插件没有被编译,需要编译后才能使用。
2.2 编译插件
2.3 载入插件
查询插件状态:
postgres=# SELECT * FROM pg_available_extensions WHERE name = 'pg_stat_statements';
name | default_version | installed_version | comment
--------------------+-----------------+-------------------+-----------------------------------------------------------
pg_stat_statements | 1.7 | 1.7 | track execution statistics of all SQL statements executed
2.4 插件使用
SELECT pgsa.datname AS database_name
, pgsa.usename AS user_name
, pgsa.client_addr AS client_addr
, pgsa.application_name AS application_name
, pgsa.state AS state
, pgsa.backend_start AS backend_start
, pgsa.xact_start AS xact_start
, extract(epoch FROM now() - pgsa.xact_start) AS xact_time, pgsa.query_start AS query_start
, extract(epoch FROM now() - pgsa.query_start) AS query_time
, pgsa.query AS query_sql
FROM pg_stat_activity pgsa
WHERE pgsa.state != 'idle'
AND pgsa.state != 'idle in transaction'
AND pgsa.state != 'idle in transaction (aborted)'
ORDER BY query_time DESC
LIMIT 5;
3.2 查看 TOP SQL
查看 TOP SQL:
-- 总查询时间 TOP
select * from pg_stat_statements order by total_time desc limit 5;
-- 总 IO 消耗 TOP
select * from pg_stat_statements order by blk_read_time+blk_write_time desc limit 5;
-- 总调用次数 TOP
select * from pg_stat_statements order by calls desc limit 5;