如何控制PostgreSQL中的Autovacuum频率
#postgres #database #apacheage #postgressql

Postgresql

PostgreSQL是一个功能强大且可靠的数据库系统,可提供许多功能和好处。但是,它也有一些挑战和缺点,例如桌子膨胀问题。当表或索引占用的空间大于实际数据大小时,就会发生表面膨胀。这可能会影响数据库的性能和效率,并增加备份和恢复时间。

桌子膨胀的主要原因之一是死亡元组的积累。死元组是已删除或更新的行,但在并发交易中仍然可以看到。 PostgreSQL使用一种称为MVCC(多次并发控制)的机制来确保交易隔离和一致性。 MVCC允许每个事务在某个时间点看到数据库的快照,而无需锁定行或表。这意味着旧版本的行没有立即删除,而是标记为死亡和不可见的新交易。

要收回死亡元组占据的空间,PostgreSQL运行了一个称为真空的过程。真空从桌子和索引中删除了死去的分组,并将空间标记为免费的重复使用。真空还更新了可见度图,该图跟踪表的哪些页面仅包含可见元组。这有助于加快仅索引扫描的速度,如果可见性图表示不需要它们,可以避免阅读表页。

Autovacuum

PostgreSQL具有称为Autovacuum的自动真空守护程序,该守护程序在后台运行并在需要它的桌子上进行真空。 Autovacuum是由各种因素触发的,例如死元数,交易ID的年龄和表格的大小。 Autovacuum还执行分析,该分析更新了查询计划者选择最佳执行计划的统计信息。

但是,有时Autovacuum可能无法频繁运行某些桌子,尤其是那些具有大量元组以及高更新或删除速率的表。这可能导致桌子过多,查询性能不佳。在此博客文章中,我们将向您展示如何使用存储参数来控制特定表的Autovacuum的频率。

存储参数

存储参数是可以为每个表或索引设置的选项,以控制其物理存储特性。其中一些参数会影响自动载体在给定关系中的行为。我们将重点关注的两个参数是:

  • autovacuum_vacuum_threshold :在Autovacuum之前,桌子中的最小死元数将在其上发出真空命令。默认值为50。
  • autovacuum_vacuum_scale_factor :表格中将添加到autovacuum_vacuum_threshold的表中总数的一小部分,以确定autovacuum是否应在其上发出真空命令。默认值为0.2。

何时在表上运行autovacuum的公式为:

(the number of dead tuples)> autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor * (the number of tuples)

例如,如果一张桌子有100,000个元组和20,000个死亡元组,则autovacuum将在以下情况下运行:

20,000> 50 + 0.2 * 100,000

简化为:

20,000> 20,050

是错误的,因此Autovacuum不会在此表上运行。

但是,如果我们将此表的存储参数更改为:

  • autovacuum_vacuum_threshold = 1000
  • autovacuum_vacuum_scale_factor = 0

然后,当autovacuum将在以下情况下运行:

20,000> 1000 + 0 * 100,000

简化为:

20,000> 1000

是真的,因此Autovacuum将在此表上运行。

通过调整这些参数,我们可以根据我们的需求和偏好使Autovacuum更具侵略性或更保守。

例子

让我们以示例在实践中查看这是如何工作的。我们将使用PGBENCH_ACCOUNTS表中的PGBENCH基准测试工具。该表有100,000行,经常通过PGBench交易进行更新。

我们可以使用psql中的\ d+命令检查此表的当前存储参数:

postgres =#\d+ pgbench_accounts

table “ public.pgbench_accounts”

   Column   |     Type      | Collation | Nullable | Default | Storage | Stats target | Description 
------------+---------------+-----------+----------+---------+---------+--------------+-------------
 aid        | integer       |           | not null |         | plain   |              | 
 bid        | integer       |           |          |         | plain   |              | 
 abalance   | integer       |           |          |         | plain   |              | 
 filler     | character(84) |           |          |         | extended|              | 
Indexes:
    "pgbench_accounts_pkey" PRIMARY KEY, btree (aid)
    "pgbench_accounts_bid_index" btree (bid)
Options: autovacuum_vacuum_threshold=1000, autovacuum_vacuum_scale_factor=0

我们可以看到该表具有我们要用于此示例的存储参数。如果我们想更改它们,我们可以使用Alter表命令:

postgres=# ALTER TABLE pgbench_accounts SET (autovacuum_vacuum_threshold = 1000);
ALTER TABLE
postgres=# ALTER TABLE pgbench_accounts SET (autovacuum_vacuum_scale_factor = 0.0);
ALTER TABLE

现在,让我们通过更新表中的一些行来生成一些死元组:

postgres=# update pgbench_accounts set abalance = 1 where aid < 1002;
UPDATE 1001

我们可以使用PG_STAT_ALL_TABLES查看该表的死元数和最后一个autovacuum的时间:

postgres=# SELECT relname, n_dead_tup, last_autovacuum FROM pg_stat_all_tables WHERE relname = 'pgbench_accounts';
     relname      | n_dead_tup |        last_autovacuum        
------------------+------------+-------------------------------
 pgbench_accounts |       1001 | 2023-07-01 00:32:23.627931+09
(1 row)

我们可以看到桌子有1001个死亡元素,最后一个自动武器是在00:32:23。如果我们等待几分钟,我们可以看到Autovacuum再次在此表上运行:


postgres=# SELECT relname, n_dead_tup, last_autovacuum FROM pg_stat_all_tables WHERE relname = 'pgbench_accounts';
     relname      | n_dead_tup |        last_autovacuum        
------------------+------------+-------------------------------
 pgbench_accounts |          0 | 2023-07-01 00:43:24.498598+09
(1 row)

我们可以看到,死亡元素的数量现在为零,最后一个autovacuum在00:43:24。这意味着Autovacuum一旦达到我们的1000个死亡元组的阈值就在这张桌子上运行。

Apache年龄:

Apache Age是PostgreSQL的图形数据库扩展名,可让您在关系数据库中存储,查询和分析图形数据。图数据由代表实体和关系的节点和边缘组成。访问他们的Official WebsiteGithub Repo了解更多信息。

结论

在这篇博客文章中,我们学会了如何使用存储参数来控制特定表的Autovacuum的频率。我们看到了如何调整autovacuum_vacuum_threshold和autovacuum_vacuum_scale_factor参数,以使autovacuum在给定表中更具侵略性或更保守。我们还看到了一个示例,说明了使用PGBENCH_ACCOUNTS表中的pgbench基准测试工具中的示例。

我们希望这篇博客文章对您有所帮助且内容丰富。如果您有任何疑问或反馈,请随时在下面发表评论。谢谢您的阅读!