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

PostgreSQL特性矩阵解析系列16之Parallelized VACUUM for Indexes

644

概述

The VACUUM process can be parallelized for indexes. The number of VACUUM jobs for an index can be specified.

PostgreSQL13开始支持索引并行vacuum

VACUUM PARALLEL

    VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
    VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ]

    其中option可以是下列之一:

    FULL [ boolean ]
    FREEZE [ boolean ]
    VERBOSE [ boolean ]
    ANALYZE [ boolean ]
    DISABLE_PAGE_SKIPPING [ boolean ]
    SKIP_LOCKED [ boolean ]
    INDEX_CLEANUP [ boolean ]
    TRUNCATE [ boolean ]
        PARALLEL integer   PostgreSQL13 新增的 PARALLEL 参数

    而table_and_columns是:

    table_name [ ( column_name [, ...] ) ]
    复制

    PostgreSQL12(含)及以前的版本,vacuum还是一个表一个表,一个索引一个索引的进行清理,PostgreSQL13 新增的 PARALLEL 参数。

    PARALLEL参数解释(白嫖自官方手册文档)

    使用integer后台处理器并行执行VACUUM 的索引真空和索引清理阶段。 用于执行操作的处理器数量等于关系上支持并行清理的索引数量,该数量受PARALLEL 选项指定的工人数量的限制,如果有的话,该数量还受到max_parallel_maintenance_workers限制。当且仅当索引的大小大于min_parallel_index_scan_size时,索引才能参与并行清理。 

    请注意,不保证在执行期间会使用integer中指定的并行工作线程数。清理运行时可能需要比指定的更少的处理器,甚至根本没有处理器。每个索引只能使用一名处理器。所以只有当表中至少有2索引时才会启动并行工作程序。在每个阶段开始之前启动清理工作进程,并在阶段结束时退出。这些行为可能会在未来的版本中发生变化。此选项不能与FULL选项一起使用。

    概括总结:

    目前仅限于索引,每个索引可以分配一个vacuum worker。

    不支持在加上FULL选项后使用。

    只有在至少有2个以上索引的表上使用parallel选项才有效。

    VACUUM处理阶段

    1.初始化,VACUUM正在准备开始扫描堆。这个阶段应该很简短。

    2.扫描堆, VACUUM正在扫描堆。如果需要,它将会对每个页面进行修建以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。

    3.清理索引,VACUUM当前正在清理索引。如果一个表拥有索引,那么每次清理时这个阶段会在堆扫描完成后至少发生一次。如果maintenance_work_mem不足以存放找到的死亡元组,则每次清理时会多次清理索引。

    4.清理堆,VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每一次清理索引的实例之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始清理索引。

    5.清除索引,VACUUM当前正在清除索引。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。

    6.截断堆,VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在清除完索引之后。

    7.执行最后的清除,VACUUM在执行最终的清除。在这个阶段中,VACUUM将清理空闲空间映射、更新pg_class中的统计信息并且将统计信息报告给统计收集器。当这个阶段完成时,VACUUM也就结束了。

    实验

      创建测试表
      postgres=# create table test(id int,info text);
      CREATE TABLE
      postgres=# insert into test select generate_series(1,1000000),md5(random()::text);
      INSERT 0 1000000
      postgres=# create index idx_test on test(id);
      CREATE INDEX
      postgres=# create index idx_test_info on test(info);
      CREATE INDEX

      并行清理测试:Postgresql 13
      postgres=# vacuum (parallel 4) test;
      VACUUM
      Time: 64.417 ms

      postgres=# vacuum (verbose true) test;
      INFO: vacuuming "public.test"
      INFO: launched 1 parallel vacuum worker for index cleanup (planned: 1)
      INFO: "test": found 0 removable, 40 nonremovable row versions in 1 out of 8334 pages
      DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 491
      There were 0 unused item identifiers.
      Skipped 0 pages due to buffer pins, 0 frozen pages.
      0 pages are entirely empty.
      CPU: user: 0.00 s, system: 0.03 s, elapsed: 0.04 s.
      INFO: vacuuming "pg_toast.pg_toast_16384"
      INFO: "pg_toast_16384": found 0 removable, 0 nonremovable row versions in 0 out of 0 pages
      DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 491
      There were 0 unused item identifiers.
      Skipped 0 pages due to buffer pins, 0 frozen pages.
      0 pages are entirely empty.
      CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
      VACUUM
      Time: 61.257 ms

      清理测试:Postgresql 12
      postgres=# \timing on
      Timing is on.
      postgres=# vacuum test;
      VACUUM
      Time: 6388.633 ms (00:06.389)
      postgres=#
      复制

      参考

      https://www.postgresql.org/about/featurematrix/detail/340/

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

      评论