如何优化 Autovacuum,让垃圾元组的清理更高效?

数据库 PostgreSQL
PostgreSQL 中的自动清理是一个绕不过去的话题,那我们应该如何优化 autovacuum,以高效清理死元组?

autovacuum 最典型的任务是清理由UPDATE或DELETE操作产生的死元组。如果autovacuum无法清理死元组,您可以按照以下三个步骤进行调优:

确保没有任何事情阻止 autovacuum 回收死元组

有时,autovacuum 不会删除死元组。大多数情况下,问题原因在那些长时间运行的事务。除非您能消除这些障碍,否则调整 autovacuum 将毫无用处。

如果您无法从根本上解决问题,则可以使用配置参数 idle_in_transaction_session_timeout,让 PostgreSQL 终止那些停留在 “idle in transaction” 时间过长的会话。这会导致客户端出现错误,但如果没有其他方法来保持数据库正常运行,那可能也是合理的。同样,要消除长时间运行的查询,您可以使用参数 statement_timeout。

优化 autovacuum 以加速运行

如果 autovacuum 无法跟上清理死元组的步伐,解决方案是让它工作得更快。这样看来是显而易见的,但许多人会陷入这样的陷阱,即认为,让 autovacuum 更早启动或更频繁地运行可以解决问题。

VACUUM是一种资源密集型操作,因此默认情况下 autovacuum 故意运行缓慢。目的是让它在后台工作,而不妨碍正常的数据库操作。但是,如果你的工作负载创建了大量的死元组,你将不得不使它更积极地工作:

  • • 调大 autovacuum_vacuum_cost_limit 的值,该参数默认值为 200(这是温和的方式)。
  • • 降低 autovacuum_vacuum_cost_delay 的值,该参数从默认值 2 毫秒(在旧版本中为 20 毫秒)(这是有效的方式)。

将autovacuum_vacuum_cost_delay设置为 0,将使 autovacuum 与手动VACUUM一样快,也就是尽可能的快。

由于不是所有表都以相同的速度增加死元组,因此通常最好不要更改postgresql.conf中的全局设置,而是单独更改那些繁忙的表的设置:

ALTER TABLE busy_table SET (autovacuum_vacuum_cost_delay = 1);

对表进行分区也有助于更快地完成清理工作。这样做的好处是,您可以让多个 autovacuum 工作进程并行处理多个分区,这样清理这些分区表的完成速度就比单个 autovacuum 工作进程要更快。

优化业务负载,以产生更少的死元组

如果其他方法都不起作用,则必须看下能否产生更少的死元组。也许一行的多次UPDATE可以合并成一次UPDATE?

通常,您可以使用 “HOT 更新” 来显著减少死元组的数量:

  • • 设置表的 fillfactor 为一个小于 100 的值,以便INSERT时在每个块中留下一些空闲空间。
  • • 请确保您在UPDATE中修改的列,是没有索引的列。

然后,任何SELECT或 DML 语句都可以清理死元组,这样就不太需要VACUUM了。

责任编辑:武晓燕 来源: 红石PG
相关推荐

2023-09-12 16:20:04

边缘AI深度学习

2021-12-10 11:46:33

无线网络

2018-05-08 14:58:07

戴尔

2010-12-12 09:40:00

Android UI设

2010-01-14 16:35:31

C++优化

2015-04-02 12:42:26

HDFS分层存储高效

2019-04-19 08:18:37

神经网络数据图形

2023-11-24 11:20:04

functoolsPython

2019-04-19 08:47:00

前端监控数据

2016-06-30 16:54:49

UCloud爱数云计算

2010-12-23 15:55:00

上网行为管理

2011-07-21 13:52:43

组策略网络打印机

2017-11-02 10:23:48

冷热分层存储

2023-11-16 08:55:14

CSS前端

2013-07-23 10:50:24

C程序

2024-08-19 00:35:00

Pythondict遍历列表推导式

2015-09-30 14:22:44

Qlik数据

2011-08-29 09:33:48

2015-12-31 11:57:17

华为eLTE物联网

2019-08-12 08:37:45

点赞
收藏

51CTO技术栈公众号