AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / user-25326

mattbasta's questions

Martin Hope
mattbasta
Asked: 2024-07-23 01:30:41 +0800 CST

Postgres 查询延迟出现神秘峰值

  • 7

在工作中,我们遇到了一种神秘的问题。每隔几个小时,我们的一个表(tasks)就会出现查询延迟增长(由 CPU 使用率引起),随后出现爆发式增长LWLock:BufferContent,然后又下降到正常水平。以下是 RDS 性能洞察的屏幕截图:

图表显示 CPU 使用率增加,随后 BufferContent 锁定并返回稳定状态

我们做了大量工作来尝试缓解这种情况,这些工作已经导致事故发生的频率(据传闻)降低,严重程度也降低。然而,问题并没有消失。

首先,我们注意到有些查询没有命中索引。我花了一些时间确保针对此表的所有查询都执行索引和仅索引扫描。查询通常如下所示:

SELECT COUNT(1) FROM tasks WHERE status = 'PENDING' AND NOT deleted

status并且我们在条件上有相应的索引status = 'PENDING' AND deleted = FALSE。EXPLAIN ANALYZE表明索引正在被正确使用。

我们确实发现,当用户有大量记录时,一些在我们的列上指定条件的查询userId会有一个糟糕的查询计划。这个问题通过修复查询和索引改进得到了解决。据我们所知,没有任何查询对任何值都有糟糕的查询计划(但问题仍然存在)。

在峰值期间,传入负载没有增加。在事件发生之前、期间和之后,受影响的查询在 RDS 性能洞察中显示相同的“调用次数/秒”,并且我们的客户端应用程序显示稳定的 QPS,因此这不是由查询增加引起的。

我确实观察到,EXPLAIN ANALYZE这些查询的结果确实表明在这些峰值期间堆提取有所增加,即使对于仅索引扫描也是如此。我读到在索引扫描期间堆仍然会受到影响,因为可见性图可能表明包含索引引用的元组的页面可能不可见。这似乎是一个强烈的信号:PENDING任务(如上面的查询所示)通常是接收许多更新的“热”行,因此包含这些行的页面的可见性图需要提取是有道理的。

为了弥补这一缺陷,我们调整了自动清理设置,使清理频率大大提高。现在我们每隔几个小时就会看到一次自动清理,但问题并没有消失。我看到这些峰值出现在表的自动清理完成 20 分钟后。此外,EXPLAIN ANALYZE峰值期间报告的堆提取次数可能比任务记录数高出 1-2 个数量级PENDING:总数很少超过 200,我们可以看到在仅包含PENDING记录的索引的索引扫描中存在数千次堆提取。

在调试过程中,我注意到查询规划器确实倾向于随着时间的推移调整查询的索引,即使负载保持不变。它有时会选择允许索引扫描但不允许仅索引扫描的索引。例如,它可能会选择 上的索引,而忽略上的条件status索引,即使后者完全满足查询。我将和设置调整为 而不是 Postgres 默认值(分别为 1 和 4),这应该会指示 Postgres 优先使用索引扫描。不幸的是,问题仍然存在(尽管可能频率较低)。上面的屏幕截图是在设置调整之后的。statusstatus = 'PENDING' and not deletedseq_page_costrandom_page_cost1.0

一些附加信息:

  1. 该问题仅影响此一张表(或者我应该说,此一张表的查询)。
  2. 峰值期间表上的所有查询都会受到影响,而不是单个查询。

到目前为止,我几乎没有主意了。作为参考,我们在 Postgres 14.10 上运行db.m5.16xlargeGP2 SSD 卷。我怀疑我们的 Postgres 版本只需要更新(计划中的工作),但这不是一个令人满意的解决方案。

我有点困惑的是,为什么造成延迟的资源使用是 CPU。您可以在上面的屏幕截图中看到绿色(CPU)的增加。基本上每个查询都应该扫描很少的记录。所有查询都是计数聚合,查询的条件都是简单的相等。这是没有峰值时受影响的查询输出之一:

Aggregate  (cost=46.02..46.03 rows=1 width=8) (actual time=0.362..0.362 rows=1 loops=1)
"  ->  Index Only Scan using ""tasks_globalPending"" on tasks  (cost=0.25..37.54 rows=3393 width=0) (actual time=0.239..0.353 rows=128 loops=1)"
        Heap Fetches: 178
Planning Time: 0.161 ms
Execution Time: 0.377 ms

非常快!可以说是非常高效(尽管我更喜欢零堆提取)。对于COUNT()~never 返回值大于 300 的程序来说,令人费解的是,它如何从每个查询 0.4 毫秒增加到 10-20 毫秒,并将这段时间浪费在 CPU 使用上。它在做什么?

postgresql
  • 1 个回答
  • 27 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve