postgresql慢查询排查和复现

postgresql慢查询排查和复现

一. 介绍一张表:pg_stat_activity

pg_stat_activity 是 PostgreSQL 中一个非常有用的系统视图,提供了有关当前数据库连接和活动查询的信息。通过查询这个视图,你可以获取有关正在执行的查询、连接的用户、进程 ID 等信息。以下是 pg_stat_activity 视图中的一些关键列:

  1. datid: 数据库标识符,表示正在连接的数据库的唯一标识符。
  2. datname: 数据库名称。
  3. pid: 进程 ID,表示数据库连接的唯一标识符。
  4. usesysid: 连接用户的系统标识符。
  5. usename: 连接用户名。
  6. application_name: 连接的应用程序名称(如果应用程序设置了名称)。
  7. client_addr: 客户端的 IP 地址。
  8. client_hostname: 客户端的主机名。
  9. client_port: 客户端连接使用的端口。
  10. backend_start: 连接开始时的时间戳。
  11. xact_start: 事务开始时的时间戳。
  12. query_start: 查询开始执行的时间戳。
  13. state: 连接状态(例如,idle、active、idle in transaction 等)。
    • active: 表示当前连接正在执行查询或事务。
    • idle: 表示当前连接处于空闲状态,没有正在执行的查询或事务。
    • idle in transaction: 表示当前连接处于事务中,但没有正在执行的查询。可能是事务开始后一段时间没有活动。
    • idle in transaction (aborted): 表示当前连接处于事务中,但由于某种原因事务已被中止。
    • fastpath function call: 表示当前连接正在执行一个快速路径函数调用。
    • disabled: 表示当前连接的活动状态已被禁用。
  14. query: 当前正在执行的查询文本。
  15. waiting: 是否在等待锁。

pg_stat_activity 视图,可以监视当前数据库连接的活动状态,了解哪些查询正在执行及运行时间等信息。

二. 复现慢查询

在查询中引入延迟,pg_sleep() 是 PostgreSQL 中的一个函数,用于在查询中引入延迟。这个函数会使查询进程休眠指定的秒数。如果不提供参数,默认为 0 秒。切记不要再生产环境使用.

sql 复制代码
SELECT pg_sleep(100); -- 这将使查询休眠100秒钟
三. 排查慢查询语句

总的来说,这个查询可以识别数据库中运行时间较长的查询(下面是排查超过30秒的sql,可根据实际需要修改)。

sql 复制代码
SELECT pid, datname, usename, query, extract(epoch from (now() - query_start)) as total_time, count(1) AS slowsql_count FROM pg_stat_activity where state not in('idle') and query !='' and extract(epoch from (now() - query_start)) > 30  GROUP BY pid, datname, usename, query, total_time;
  1. SELECT pid, datname, usename, query, extract(epoch from (now() - query_start)) as total_time, count(1) AS slowsql_count
    • pid: 进程ID,表示数据库连接的唯一标识符。
    • datname: 数据库名称。
    • usename: 执行查询的用户名称。
    • query: 正在执行的查询文本。
    • extract(epoch from (now() - query_start)) as total_time: 通过计算当前时间与查询开始时间的差值,获取查询已运行的总时间(以秒为单位)。
    • count(1) AS slowsql_count: 用于计算相同查询的数量,即慢查询的数量。
  2. FROM pg_stat_activity
    • 从 PostgreSQL 的 pg_stat_activity 视图中选择活跃的数据库连接信息。这个视图包含了关于当前数据库会话和查询的统计信息。
  3. WHERE state NOT IN ('idle') AND query != '' AND extract(epoch from (now() - query_start)) > 10
    • state NOT IN ('idle'): 确保排除处于空闲状态的数据库连接,只选择活跃的连接。
    • query != '': 排除空查询,确保只选择正在执行的查询。
    • extract(epoch from (now() - query_start)) > 30: 选择运行时间超过30秒的查询。
  4. GROUP BY pid, datname, usename, query, total_time
    • 对选择的结果进行分组,以便聚合相同查询的统计信息。

查询结果 :成功定位到慢查询语句:SELECT pg_sleep(100);

四. 慢查询优化方案
  1. 查询优化 :
    • 通过使用 EXPLAIN 分析查询计划,了解 PostgreSQL 是如何执行查询的。优化查询计划可以提高查询性能。
    • 调整查询,避免不必要的全表扫描,确保正确使用索引。
  2. 索引优化 :
    • 确保表上的索引是合理的,并涵盖了查询中用于筛选和排序的列。
    • 避免过多的索引,因为它们可能会导致性能下降。
  3. 统计信息更新 :
    • 确保 PostgreSQL 统计信息是最新的。自动化统计信息更新可以通过 PostgreSQL 的自动统计信息收集器来完成。
  4. 分区表 :
    • 对大型表进行分区,可以提高查询性能,尤其是对那些经常使用范围查询的表。
  5. 调整内存配置 :
    • 调整 shared_bufferseffective_cache_size 参数,以确保数据库能够充分利用系统内存。
  6. 定期维护 :
    • 定期执行 VACUUMANALYZE 操作,以确保表的空间得到优化,同时更新统计信息。
  7. 使用连接池 :
    • 考虑使用连接池,例如 PgBouncer,以减轻数据库服务器的负载。
  8. 日志和监控 :
    • 启用 PostgreSQL 的查询日志,并使用工具如 pgBadger 分析日志,以便及时发现慢查询。
    • 使用监控工具,如 pg_stat_statements 扩展,监视查询性能。
  9. 升级 PostgreSQL 版本 :
    • 考虑升级到最新的 PostgreSQL 版本,因为新版本通常包含性能改进和优化。
  10. 使用扩展 :
    • 考虑使用一些性能优化的扩展,例如 pg_repack 用于表重组,pg_partman 用于表分区等。

常包含性能改进和优化。

  1. 使用扩展 :
  • 考虑使用一些性能优化的扩展,例如 pg_repack 用于表重组,pg_partman 用于表分区等。
相关推荐
运维行者_9 小时前
企业无线网络监控的挑战与智能化演进趋势
大数据·运维·服务器·网络·数据库
国强_dev9 小时前
技术探讨:使用 stunnel 加密转发数据库连接时,如何获取客户端真实 IP?
数据库·网络协议·tcp/ip
@insist12310 小时前
系统规划与管理师-信息系统规划核心工作要点解析
数据库·软考·系统规划与管理师·软件水平考试·系统规划与管理工程师
超级数据查看器10 小时前
超级数据查看器 v10.0 发布
java·大数据·数据库·sqlite·安卓
数安3000天10 小时前
增量数据如何自动分类分级,避免目录“过期“?
大数据·数据库
南墙上的石头11 小时前
麒麟 V10 重装人大金仓 V8R6 踩坑实录(含 MySQL 兼容模式)
数据库·mysql
画中有画12 小时前
论向量数据库在项目中的应用
数据库
spider_xcxc12 小时前
Redis 数据库高质量实践指南(一)
运维·数据库·redis·oracle·云计算
l1t13 小时前
在linux和windows中解决duckdb 1.6dev版本输出执行计划报错问题
linux·运维·数据库·windows·duckdb
执子手 吹散苍茫茫烟波13 小时前
RC 隔离级别下 MySQL InnoDB 死锁典型案例
数据库·mysql