【问题标题】:Postgres Upsert - fragmentation issuesPostgres Upsert - 碎片问题
【发布时间】:2020-01-14 11:52:33
【问题描述】:

总结

我在我们的 ETL 中使用 Postgres UPSERT,我在写入的表上遇到了碎片和膨胀问题,这会减慢包括读取在内的所有操作。

上下文

我每小时将批量 ETL 更新插入到表中(表 ~ 数百万,upsert ~ 数万),我们在 AWS 上将自动清理设置为阈值。

我不得不运行 FULL Vacuums 以收回空间并防止进程挂起。随着我们其中一个 ETL 的频率增加,这种情况现在更加严重,它填充了一些核心表,这些表是许多非规范化视图的来源。 似乎正在发生的事情是,在下一次 ETL 运行之前,表没有机会被清空,从而产生了最终导致完全减速的螺旋。

问题!

Upsert 是否从根本上对碎片化产生负面影响?如果是,其他人在使用什么?我热衷于实现一些物化视图并将我们的大部分索引移动到新视图,同时只保留我们正在写入的表上的 PK 索引,但我不相信这会解决我看到的膨胀问题.

我对这个问题做了一些阅读,但没有任何结论,例如 --> https://www.targeted.org/articles/databases/fragmentation.html

感谢您的帮助

【问题讨论】:

  • @LaurenzAlbe 在下面给出了很好的建议。此外,请确保没有长时间运行的事务会阻止 autovacuum 清理表。
  • “自动吸尘器设置为阈值”这是什么意思?
  • @jjanes 我的意思是说,在 AWS 中适当地设置了真空阈值。具有非常低比例因子的大表,具有合理的阈值以避免不得不清理小表。

标签: postgresql amazon-rds database-administration upsert vacuum


【解决方案1】:

这取决于。如果没有违反约束,INSERT ... ON CONFLICT 不会导致任何膨胀。如果它执行更新,它将产生一个死行。

你可以采取的措施:

  • 设置 autovacuum_vacuum_cost_delay = 0 以加快自动清空速度

  • 使用略小于 100 的 fillfactor 并且在更新的列上没有索引,这样您就可以获得 HOT 更新,这使得 autovacuum 变得不必要

【讨论】:

    【解决方案2】:

    不清楚您实际看到的是什么。您能否打开 track_io_timing,然后为您认为因膨胀而减慢的查询执行EXPLAIN (ANALYZE, BUFFERS)

    膨胀和碎片化不是一回事。在某些情况下,索引的碎片化问题更多,而不是表本身。

    似乎正在发生的事情是在下一次 ETL 运行之前表没有机会被清理

    这个可能很容易修复。在每次 ETL 运行结束或开始时运行“手动”VACUUM(不是 VACUUM FULL)。由于您有一个明确定义的工作流程,因此无需尝试让 autovacuum 做正确的事情,因为将手动真空注入您的工作流程应该非常容易。还是您认为每个 ETL 一个 VACUUM 是多余的?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-22
      相关资源
      最近更新 更多