【问题标题】:Postgresql Hstore and Toast BloatPostgresql Hstore 和 Toast 膨胀
【发布时间】:2014-05-17 05:49:08
【问题描述】:

我使用 hstore(Postgresql 9.3.4)来存储给定日期内每次发生事件的计数,更新如下。

days_count = days_count || hstore('x', (coalesce((days_count -> 'x')::integer, 0) + 1)::text)

其中 x 是一年中的某一天。 在对生产环境的预期行为进行模拟后,我最终得到了一个 150MB + 2GB Toast + 25-30MB 用于索引的表,在分析和抽真空之后。

我现在将上面的列拆分为每个月的列,如下所示

y_month_days_count = y_month_days_count || hstore('x', (coalesce((y_month_days_count -> 'x')::integer, 0) + 1)::text)

其中 x 是月份中的某天,y 是一年中的月份。 我现在仍在运行模拟,但到目前为止,我已经完成了 60MB + 相当稳定的 20-30MB Toast + 25-30MB 的索引。这意味着最后我应该在分析和清理之后得到大约 180MB + 30-40MB 用于 Toast + 25MB-30MB 用于索引

那么首先,Hstore 和 Toast 膨胀是否有任何已知问题可以解释我在第一次设置时遇到的问题?

其次,由于一张表上的 hstore 列数,我当前的拆分列的解决方案是否会在将来导致 hstore 和性能出现任何类型的问题?现在似乎稳定了,行数在十万,虽然我知道更多的列会使事情变慢,但我不确定 hstore 列是否会更糟。

我终于找到了一些东西。我有一个 hstore 列,最终代表一天中的每个小时,因此它有 24 个不同的键。当我只为这一列运行模拟时,我最终在 KB 中几乎没有吐司,但是当我运行整个模拟时,将天分成几个月列,我最大的 hstore 有 52 个键。

因此,对于一个计数器或一两个单词的简单存储,在我看到 hstore 的任何数量的 toast 之前的最大键数是 24 到 52 个键。

【问题讨论】:

    标签: postgresql hstore postgresql-9.3


    【解决方案1】:

    首先,Hstore 和 Toast 膨胀是否有任何已知问题可以解释我在第一次设置时遇到的问题?

    是的。

    当您更新外联存储的 TOASTed 字段的任何部分时,例如 texthstorejson整个字段必须重写为新行版本。这是MVCC 的结果 - 有必要保留可能对另一个事务仍然可见的行的每个版本的副本。

    当任何正在运行的事务不再需要旧的 vacuumed 时,它可以被删除,因此在实践中,只要 autovacuum 足够积极地运行,这影响很小。

    因此,如果您要使用大 texthstorejson 字段更新大量行,或者频繁更新它们,请调整 autovacuum 使其运行更频繁并且运行更快。确保您没有长时间运行的<IDLE> in transaction 连接。

    你说你引用的表大小是“在分析和清理之后”,但我猜你只运行了一个普通的vacuum,所以表膨胀会被 PostgreSQL 释放以供重用,但不会被释放回来到操作系统。看看VACUUM FULL 是否压缩它。

    由于一张表上的 hstore 列数,我当前的拆分列的解决方案是否会在将来导致任何类型的 hstore 和性能问题?

    取决于您的查询模式和工作量,但可能不是。

    【讨论】:

    • 我认为它会是这样的,它看起来如此激进,以至于我认为它是 hstore 的补充和独特的东西。我想我会分解事情,因为它们将基于月份我最终不必一直重写所有内容,只需当前月份的计数器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-23
    • 2018-09-26
    • 1970-01-01
    相关资源
    最近更新 更多