暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

清理更新频繁的表

飞象数据 2022-12-03
237

在我之前的帖子(https://dataegret.com/2022/01/accelerating-vacuum-in-postgres/)中,我概述了一些在标准设置中运行良好的通用参数。它们可能具有攻击性,但会允许其他进程不间断地工作。

当涉及到VACUUM(https://www.postgresql.org/docs/current/routine-vacuuming.html)时,更新密集型表需要特别注意,因此在这篇文章中我将重点关注这一点。

幸运的是,Postgres 允许为每个表分别设置 VACUUM 参数,因此即使使用一般的、相对紧凑的配置,仍然可以更积极地配置单独的表。

什么是更新密集型表?

更新频繁的表是包含基于特定业务需求的数据的表,这些数据预计会非常频繁地更新以保持相关性。一个很好的例子是客户的银行账户余额、火车上的乘客数量、可用的剧院门票、在特定区域流通的可用出租车数量等。

现在我们退一步思考,为什么频繁更新的表还要特别注意?

VACUUM 是如何工作的?

MVCC(多版本并发控制:https://www.postgresql.org/docs/current/mvcc-intro.html)模式下,PostgreSQL 保留了以前版本的修改记录。这些版本仍然占用该表中的空间,尽管它们对事务不可见。

VACUUM(和 AUTOVACUUM)的目的是恢复被这些过时记录占用的空间,以便重新利用。

简而言之,VACUUM进程将过期记录占用的空间标记为空闲并准备好重新利用。除此之外,还有其他支持过程发生:

可见性映射(https://www.postgresql.org/docs/14/storage-vm.html正在更新,自由空间映射(https://www.postgresql.org/docs/14/storage-fsm.html等。

更新

要更新记录,PostgreSQL 会检查包含该记录的页面以搜索合适大小的可用空间。如果空间已被识别,则新记录将输入到同一页面上。如果未找到空间,则从上到下检查表格以搜索合适大小的空白空间。

如果找到了空间——新记录就放在那里。如果不是——数据被输入到表格的底部。如果需要,将创建新的数据页。

同时,对于以前版本的记录,系统列xmax被设置为对新事务不可见。

VACUUM

VACUUM 审查数据并检查其可见性。如果数据过期,则该数据占用的空间被标记为空闲。这不是 VACUUM-ing 期间执行的唯一功能,但是对于我们的目的而言,最重要的部分是它将此空间标记为可用。

对于普通表,VACUUM 设法处理数据,因此新记录或记录的新版本将被插入到可用的“间隙”中。

VACUUM 用于频繁更新的表

对于更新频繁的表,由于时间限制,VACUUM 不会遍历表中的所有数据,因此新记录(或更新版本的记录)被放置在表的末尾。这会导致保留不必要的记录和典型的表格 膨胀https://dataegret.com/2018/03/postgresql-bloatbusters/。这不仅会影响相关表,还会影响 TOAST 和索引,因此每个额外的操作都会因需要处理的数据量增加而变慢。

为频繁更新的表优化 VACUUM

由于上述过程,为了避免表膨胀,对于频繁更新的表,VACUUM 应该更积极地优化,从而使这些表更频繁地被 AUTOVACUUM 审查。

这可以通过为特定表设置参数来实现,以便执行以下命令:

ALTER TABLE table_name SET (autovacuum_vacuum_scale_factor = 0, autovacuum_vacuum_threshold = 1000);

此命令在更新后或删除 1000 行后触发 AUTOVACUUM,无论表中总共有多少行。这些参数可以在建表阶段设置。

可以在此处https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS找到存储参数的完整列表。由于参数列表如此广泛,可以根据需要微调 AUTOVACUUM 设置。

填充因子

我想在这里强调的另一个参数是 fillfactor。它负责在创建新页面之前调节具有数据的页面的占用。这样在正常的数据插入过程中,表将继续以更快的速度增长,因为页面上会有计划的间隙。

但是,在更新时,如果有足够的空间,将尝试将新版本的数据放在同一页上。由于在那种情况下可用空间是预先分配的,因此将数据插入同一页的可能性大大增加。

与创建插入到不同页面的空白空间或插入到新添加的页面相比,这提高了性能。对于需要频繁更新的表,这个参数的值可以设置在100以下。

推荐

对表参数进行全面审核并偶尔检查以确定膨胀将使您能够保持经常更新的表完好无损并优化数据库性能。

延伸阅读

VACUUM 配置并不是频繁更新表的唯一建议。需要识别和消除膨胀,我建议查看这篇关于该过程的帖子。

https://dataegret.com/2018/03/postgresql-bloatbusters/

文章转载自飞象数据,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论