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

PostgreSQL特性矩阵解析系列11之Inserted data can trigger autovacuum

820

概述

This new behavior reduces the work necessary when the table needs to be frozen and allows pages to be set as all-visible. All-visible pages allow index-only scans to access fewer heap rows.

为减少了需要冻结表时所需的工作量,并允许将页设置为全部可见。所有可见页都允许仅索引扫描访问较少的堆行。

官网中对该特性解释,理解上真的不是很直观,我来白话翻译下O(∩_∩)O~

在插入数据时可自动触发autovacumm,从而可以生成表的vm文件而无需手工触发vacumm,vm文件可以加快VACUUM清理的速度。

Inserted data can trigger autovacuum,为PostgreSQL13新增加的特性。

概念

VM

vacuum过程是一种维护过程,它的两个主要任务是删除死元组,以及冻结事物标识,由于清理过程设计全表扫描,因此该过程代价高昂,在PG8.4版本中引入了可见性映射(VM)文件来提高移除死元组的效率,在PG9.6版本中增强了VM,从而改善了冻结的过程。

FSM

插入堆或索引元组时,PostgreSQL使用表与索引相应的FSM来选择可供插入的页面。

表和索引都有各自的FSM,每个FSM存储着相应表或索引文件中每个页面可用空间容量的信息。

冻结

冻结的过程有两种模式,依特定条件而择其一执行。一种为惰性模式另一种为迫切模式。

惰性模式下,冻结过程仅适用目标表对应的VM扫描包含死元组的页面。

迫切模式会扫描所有的页面,无论其是否包含死元组,都会更新与冻结过程相关的系统视图,并在可能的情况下删除不必要的CLOG文件。

死元祖

当元组被修改时,元组会复制出多个版本(MVCC),当事物提交后,历史的版本对其它事物不可见,被标记为死元祖,等待autovacuum清理。死元组的产生也是因为PostgreSQL中没有单独的回滚段,而是将历史版本直接记录在数据页面中。

CLOG(XACT)

$PGDATA/pg_clog(xact)包含了事务的元数据。这种日志用于告诉PostgreSQL哪个事务已经完成、哪个还没有完成。clog是比较小的并且没有任何理由会膨胀,所以,你应该没有任何理由去碰触它。在任何时候你都不应该从pg_clog里删除文件,如果你这样子做,还不如完全地删除整个数据库目录。缺少clog是不可恢复的。请注意,这意味着,如果你在$PGDATA目录里备份文件,你应该确定同时包含pg_clog和pg_xlog,否则你可能会发现你的备份是不可用的。

VACUUM

并发清理

1.从指定的表中依次处理每一张表。

2.获取表上的ShareUpdateExclusiveLock锁,此锁允许其他事物对该表进行读取。

3.扫描表中所有的页面,以获取所有的死元组,并在必要时冻结旧的元组。

4.删除指向相应死元组的索引元组。

5.对表的每个页面执行步骤6和7中的操作。

6.删除死元组,并重新分配页面中的活元组。

7.更新目标表对应的FSM与VM。

8.如果最后一个页面没有任何元组,则截断最后一页。

9.更新与目标表清理过程相关的统计数据和系统视图。

10.更新与清理过程相关的统计数据和系统视图。

11.如果可能,移除CLOG中非必要的文件与页面。

完整清理

会移除整个文件中,所有的死元组,还会对整个文件中所有的活元组进行碎片整理。其他事物在完整清理运行时无法访问该表。

试验

    实验基于PostgreSQL13.3
    postgres=# create table test3(id int);
    CREATE TABLE
    insert into test4 select id from generate_series(1,1250) t(id);
    INSERT 0 1250
    postgres=# select pg_relation_filepath('test4');
    pg_relation_filepath
    ----------------------
    base/13580/17284
    (1 row)

    控制插入数据触发autovacuum的的阈值,默认值为1000
    postgres=# show autovacuum_vacuum_insert_threshold;
    autovacuum_vacuum_insert_threshold
    ------------------------------------
    1000
    (1 row)

    控制插入数据时超过什么比例会触发autovacuum,默认值为20%
    postgres=# show autovacuum_vacuum_insert_scale_factor;
    autovacuum_vacuum_insert_scale_factor
    ---------------------------------------
    0.2
    (1 row)

    postgres@bogon-> ll 17284*
    -rw------- 1 postgres postgres 48K Jul 7 20:41 17284
    -rw------- 1 postgres postgres 24K Jul 7 20:41 17284_fsm
    -rw------- 1 postgres postgres 8.0K Jul 7 20:41 17284_vm

    复制

    代码导读

      源码路径
      src/backend/commands/vacuum.c
      /*
       * VACUUM和ANALYZE命令执行的主要入口点
      *
      * This is mainly a preparation wrapper for the real operations that will
      * happen in vacuum().
      */
      void
      ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel){... ...}

      /*
      * Internal entry point for VACUUM and ANALYZE commands.
      *
      * 如果不是NIL,则为进程的VacuumRelation列表;否则,我们将处理数据库中所有相关的表。
       * 对于每个VacuumRelation,如果提供了一个有效的OID,则该OID的表是要处理的,否则,VacuumRelation的RangeVar表示要处理的。
      *
       * params包含一组可用于自定义行为的参数。
      *
       * bstrategy通常被指定为NULL,但在autovacuum中它可以被传递在多个vacuum()调用中使用相同的缓冲区策略对象。
      *
       * isTopLevel应该从ProcessUtility传递下来。
      *
      * It is the caller's responsibility that all parameters are allocated in a
      * memory context that will not disappear at transaction commit.
      */
      void
      vacuum(List *relations, VacuumParams *params,
           BufferAccessStrategy bstrategy, bool isTopLevel){... ...}
      /*
      * vac_truncate_clog() -- attempt to truncate the commit log
      *
      * 扫描pg_database以确定系统范围内最早的datfrozenxid,并使用它来截断事务提交日志(pg_xact)。
      * 还要更新由varsup.c维护的XID换行限制信息。同样datminmxid。
      *
      * 传递的frozenXID和minMulti是我自己的pg_database条目的更新值。它们用于初始化“min”计算。
      * 调用者还传递“最后一个正常的”XID和MXID,因为它手边已经有了这些XID和MXID。
      *
      * 只有在我们成功更改了数据库的datfrozenxid/datminmxid值,
      * 或者发现共享的XID-wrap-limit信息过期时才会被调用。
      */
      static void
      vac_truncate_clog(TransactionId frozenXID,
      MultiXactId minMulti,
      TransactionId lastSaneFrozenXid,
                MultiXactId lastSaneMinMulti){... ...}
      复制

      参考

      http://amitkapila16.blogspot.com/2020/05/improved-autovacuum-in-postgresql-13.html

      https://www.postgresql.org/about/featurematrix/#backend

      《PostgreSQL指南-内幕探索》

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

      评论