【问题标题】:See and clear Postgres caches/buffers?查看并清除 Postgres 缓存/缓冲区?
【发布时间】:2010-11-16 01:02:54
【问题描述】:

有时我运行 Postgres 查询需要 30 秒。然后,我立即运行相同的查询,它需要 2 秒。 Postgres 似乎有某种缓存。我能以某种方式看到该缓存保存的是什么吗?我可以强制清除所有缓存以进行调整吗?

我基本上是在寻找以下 SQL Server 命令的 Postgres 版本:

DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS

但我也想知道如何查看该缓冲区中实际包含的内容。

【问题讨论】:

  • 这是一个对调试查询(速度)非常有用的功能。我不知道为什么 postgres 开发人员不提供它。

标签: postgresql caching optimization


【解决方案1】:

最初的标题是“查看并清除”缓冲区。

带有 pg_buffercache 扩展的 Postgres 13 提供了一种查看 doc page 的方法

【讨论】:

    【解决方案2】:

    如果您有一个专用的测试数据库,您可以将参数:shared buffers 设置为 16。这应该会禁用所有查询的缓存。

    【讨论】:

    • 我试过这样做,但出现了“没有可用的未固定缓冲区”错误,你还需要在测试数据库中做些什么吗?
    【解决方案3】:

    您可以使用 pg_buffercache 模块查看 PostgreSQL 缓冲区缓存中的内容。我做了一个名为“Inside the PostgreSQL Buffer Cache”的演示文稿,解释了您所看到的内容,并展示了一些更复杂的查询来帮助解释随之而来的信息。

    在某些系统上也可以查看操作系统缓存,请参阅 [pg_osmem.py] 中的一个粗略示例。

    没有办法轻松清除缓存。在 Linux 上,您可以停止数据库服务器并使用drop_caches 工具来清除操作系统缓存;请务必注意那里的警告以先运行同步。

    【讨论】:

    • 是否可以在单个会话中简单地绕过缓存?我们经常需要对不同的查询进行性能测试,而这种缓存使得评估一种方法是否优于另一种方法变得非常困难(除非比较缓存的性能!)
    • 没有办法绕过或刷新数据库的缓存。要清除它,您所能做的就是重新启动服务器。
    • 是否有可能让这成为可能,例如在未来的开发中?或者这只是当前系统(PG 和 Linux)无法尝试的事情吗?
    • 当使用托管 PostgreSQL 安装(如 Amazon RDS)时,无法访问操作系统,并且出于测试目的清空操作系统缓存可能非常困难,因此此功能在 PostgreSQL 中非常有用.
    • 无法重现慢速查询这是个问题,我如何确定我的查询在调整后正在执行?重新启动服务器不是一个选项我在 prod 中测试查询,因为只有 prod 具有足够的并发性、锁定和记录来重现问题
    【解决方案4】:

    我还没有看到任何用于刷新 PostgreSQL 中的缓存的命令。您看到的可能只是从磁盘读取并保存在内存中的普通索引和数据缓存。通过 postgresql 和操作系统中的缓存。为了摆脱这一切,我知道的唯一方法是:

    你应该做的是:

    1. 关闭数据库服务器(pg_ctl、sudo service postgresql stopsudo systemctl stop postgresql等)
    2. echo 3 > /proc/sys/vm/drop_caches 这将清除操作系统文件/块缓存 - 非常重要,尽管我不知道如何在其他操作系统上执行此操作。 (如果权限被拒绝,请尝试sudo sh -c "echo 3 > /proc/sys/vm/drop_caches",如that question
    3. 启动数据库服务器(例如sudo service postgresql startsudo systemctl start postgresql

    【讨论】:

    • 认为这会有所帮助:如果 Postgres 的数据目录不在挂载 '/' 的同一卷上,您可能需要在上述操作之前/之后卸载(不确定哪个, 真的)。此外(也许有点巫术)尝试在这些步骤之前和之后运行“同步”。
    【解决方案5】:

    我遇到了这个错误。

    psql:/cygdrive/e/test_insertion.sql:9: 错误:参数类型 53 (t_stat_gardien) 与准备计划时不匹配 (t_stat_avant)

    我正在寻找刷新当前计划并发现了这个:

    DISCARD PLANS

    我在插入之间有这个,它解决了我的问题。

    【讨论】:

    • 放弃计划没有为我解决,查询看起来已经缓存了
    • 正确的语法是DISCARD PLANS;。而且,正如文档所述:“DISCARD 释放与数据库会话相关的内部资源”。
    【解决方案6】:

    是的,可以同时清除共享缓冲区 postgres 缓存操作系统缓存。以下解决方案适用于Windows...其他人已经给出了linux解决方案。

    正如许多人已经说过的,要清除共享缓冲区,您只需重新启动 Postgres(无需重新启动服务器)。但这样做不会清除操作系统缓存。

    要清除 Postgres 使用的操作系统缓存,请在停止服务后,使用 优秀的 Sysinternals Suite 中的优秀 RamMap (https://technet.microsoft.com/en-us/sysinternals/rammap)。 执行 RamMap 后,只需点击主菜单中的“Empty”->“Empty Standby List”即可。

    重新启动 Postgres,您现在会看到由于根本没有缓存,您的下一个查询将非常缓慢。

    您也可以在不关闭 Postgres 的情况下执行 RamMap,并且可能会得到您想要的“无缓存”结果,因为正如人们已经说过的,与操作系统缓存相比,共享缓冲区通常影响不大。但是为了进行可靠的测试,我宁愿在清除操作系统缓存之前停止 postgres 以确保。

    注意:AFAIK,我不建议在使用 RamMap 时清除“备用列表”之外的其他内容,因为其他数据正在以某种方式被使用,如果这样做可能会导致问题/数据丢失。请记住,您不仅要清除 postgres 文件使用的内存,还要清除任何其他应用程序和操作系统使用的内存。

    问候,蒂亚戈 L.

    【讨论】:

    • 很高兴它有帮助 ;)
    【解决方案7】:

    pg_buffercache 模块可以查看shared_buffers 缓存。在某些时候,我需要删除缓存以对“冷”缓存进行一些性能测试,因此我编写了一个 pg_dropcache 扩展来完成此操作。请检查一下。

    【讨论】:

      【解决方案8】:

      这是我的捷径

      echo 1 > /proc/sys/vm/drop_caches; echo 2 > /proc/sys/vm/drop_caches; echo 3 > /proc/sys/vm/drop_caches; rcpostgresql stop; rcpostgresql start;
      

      【讨论】:

        【解决方案9】:

        Greg Smith 关于 drop_caches 的回答非常有帮助。除了删除缓存之外,我确实发现有必要停止和启动 postgresql 服务。这是一个可以解决问题的shell脚本。 (我的环境是 Ubuntu 14.04 和 PostgreSQL 9.3。)

        #!/usr/bin/sudo bash
        
        service postgresql stop
        sync
        echo 3 > /proc/sys/vm/drop_caches
        service postgresql start
        

        我用第一次耗时 19 秒的查询进行了测试,随后的尝试耗时不到 2 秒。运行此脚本后,查询再次耗时 19 秒。

        【讨论】:

          【解决方案10】:

          我在我的 linux 机器上使用这个命令:

          sync; /etc/init.d/postgresql-9.0 stop; echo 1 > /proc/sys/vm/drop_caches; /etc/init.d/postgresql-9.0 start
          

          它完全摆脱了缓存。

          【讨论】:

          • 如果 Postgresql 版本不是 9.0:同步; sudo 服务 postgresql 停止;回声 1 > /proc/sys/vm/drop_caches; sudo service postgresql start
          • @rusllonrails 这只有在服务被命名为postgresql 时才有效,可能不是这样。
          • 我认为,sync 应该在停止服务器之后,紧接在drop_caches 之前完成,因为 Postgres 可以在停止过程中再次写入一些东西。
          【解决方案11】:

          是的,postgresql 肯定有缓存。大小由设置 shared_buffers 控制。除此之外,正如前面的答案所提到的,还使用了 OS 文件缓存。

          如果您想查看缓存中的内容,有一个名为 pg_buffercache 的 contrib 模块可用(在源代码树中的 contrib/ 中,在 contrib RPM 中,或者任何适合您的地方安装它)。如何使用它在标准 PostgreSQL 文档中列出。

          除了重新启动服务器之外,没有其他方法可以清除缓冲区缓存。您可以使用另一个答案中提到的命令删除操作系统缓存 - 只要您的操作系统是 Linux。

          【讨论】:

            猜你喜欢
            • 2014-02-25
            • 2010-10-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-01-26
            • 2012-10-12
            • 1970-01-01
            相关资源
            最近更新 更多