定位执行时间较长的慢查询
pg_stat_statements
插件能够记录数据库服务器上所有SQL语句在优化和执行阶段的统计信息。由于该插件需要使用共享内存,因此插件名已经被配置在shared_preload_libraries
参数中。
说明 如果当前数据库中没有创建pg_stat_statements
插件,执行以下命令,创建该插件。该过程将会注册插件提供的函数及视图:
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
pg_stat_statements
插件和数据库系统本身都会不断累积统计信息。为了排查CPU异常升高后这段时间内的问题,需要将数据库和插件中留存的统计信息清空,然后开始收集从当前时刻开始的统计信息:
-- 清空当前数据库的统计信息
SELECT pg_stat_reset();
-- 清空 pg_stat_statements 插件截止目前收集的统计信息
SELECT pg_stat_statements_reset();
等待1~2分钟,使数据库和插件充分采集这段时间内的统计信息。
统计信息收集完毕后,参考以下命令查询执行时间最长的5条SQL。
SELECT * FROM pg_stat_statements ORDER BY total_plan_time DESC LIMIT 5;
SELECT * FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 5;
定位读取Buffer数量较多的慢查询
当一张表缺少索引,而对该表的查询基本上都是点查时,数据库将不得不使用全表扫描,并在内存中使用过滤条件来过滤掉大量的无效记录,导致CPU使用率大幅上升。
通过pg_stat_statements
插件的统计信息,参考以下命令,查询截止目前读取Buffer数量最多的5条SQL。
SELECT * FROM pg_stat_statements
ORDER BY shared_blks_hit + shared_blks_read DESC
LIMIT 5;
通过PolarDB PostgreSQL版内置系统视图pg_stat_user_tables
中的统计信息,也可以统计出使用全表扫描时扫描次数最多的表。
参考以下命令,查询具备一定规模数据量(元组约为10万个)且使用全表扫描获取到的元组数量最多的5张表。
SELECT * FROM pg_stat_user_tables
WHERE n_live_tup > 100000 AND seq_scan > 0
ORDER BY seq_tup_read DESC
LIMIT 5;
定位长时间执行不结束的慢查询
通过系统内置视图pg_stat_activity
,可以查询出长时间执行不结束的SQL,这些SQL有极大可能造成CPU使用率过高。
参考以下命令,查询执行时间最长,且当前还未退出的5条SQL。
SELECT
*,
extract(epoch FROM (NOW() - xact_start)) AS xact_stay,
extract(epoch FROM (NOW() - query_start)) AS query_stay
FROM pg_stat_activity
WHERE state NOT LIKE 'idle%'
ORDER BY query_stay DESC
LIMIT 5;
结合前一步中排查到的使用全表扫描次数最多的表,参考以下命令,获取在该表上执行时间超过一定阈值(例如10s)的慢查询。
SELECT * FROM pg_stat_activity
WHERE
state NOT LIKE 'idle%' AND
query ILIKE '%表名%' AND
NOW() - query_start > interval '10s';