【问题标题】:Why does vacuum full wait after it is "done"?为什么“完成”后真空完全等待?
【发布时间】:2017-01-18 22:47:02
【问题描述】:

我正在一张非常大的桌子上抽真空。

当我运行它时,它会说:

bacula=# VACUUM FULL VERBOSE file_partition_19
bacula-# ;
INFO:  vacuuming "public.file_partition_19"
INFO:  "file_partition_19": found 16242451 removable, 21024161 nonremovable row versions in 900380 pages
DETAIL:  0 dead row versions cannot be removed yet.
CPU 5.14s/14.42u sec elapsed 19.61 sec.
VACUUM
Time: 163784.767 ms
bacula=# 

当它这样做时,它会很快显示到CPU 行,然后等待很长时间才显示最后两行(+ 提示符)。这反映在时间上的差异 - “经过 19.61 秒”,与 163 秒的“时间:”相比(显示是因为我设置了 \timing on)。

虽然我没有给它们计时,但两个时间都差不多 - 启动命令,等待 20 秒,然后显示到“CPU”行,然后等待大约 3 分钟,然后打印其余时间。

这正常吗?为什么会这样?

【问题讨论】:

    标签: postgresql postgresql-9.3 vacuum


    【解决方案1】:

    它主要是重建表上的所有索引,它必须这样做,因为基本上“VACUUM FULL”会完全重写表。如果您从表中删除所有 indizes,则“CPU”行之后应该几乎没有延迟。

    AFAICT,CPU 使用率行由一个通用例程打印,该例程为其他(非 FULL)真空模式完成大部分工作。在“VACUUM FULL”的情况下是没有意义的。

    如果您担心花费的时间太长,我建议您查看 PostgreSQL wiki 中的“When to use VACUUM FULL and when not to”。当人们使用 VACUUM FULL 时,10 次中有 9 次实际上不应该使用。

    【讨论】:

      【解决方案2】:

      根据您用于问题的标签“postgres-9.3”,我假设您拥有 Postgres 9.3 版本。

      您可以参考此链接以了解有关 Postgres 9.0 之前版本的“VACUUM”和“VACUUM FULL”的知识。

      VACUUM VS VACUUM FULL For Pre-9.0 versions of Postgres

      因此,当您拥有 Postgres-9.3 时,文档说明如下:

      为清楚起见,9.0 更改了 VACUUM FULL。如文档中所述,VACUUM FULL 实现已更改为类似于在旧版本中使用 CLUSTER 的实现。这与此处描述的较旧的 VACUUM FULL 略有不同。虽然此更改消除了通过索引膨胀导致数据库变慢的可能性,但由于 VACUUM FULL 的锁定和一般性能开销,您可能仍希望避免这样做。

      根据当前文档,VACUUM FULL 操作不仅从表中检索记录被标记为已删除的空间,而且还触及表中的每条有效记录并尝试在 DB 页面中重新组织它们,从而释放更多空间然后只是 VACUUM 操作。所以在 VERBOS 结果中,当我们看到这一行时

      CPU 5.14s/14.42u sec elapsed 19.61 sec
      

      是系统进程遍历表并分析表并检索已标记的空间所花费的时间。然后它开始将记录组织到页面文件中,因此根据表页面碎片的数量,该过程将花费时间。

      例如,如果您有一个新表并不断增加/按顺序添加新记录,以便在页面底部添加新记录(基于定义的主键)。现在您以相反的顺序执行删除操作,以便只从页面底部删除记录。假设您从表中删除了一半的记录。在这种情况下,没有太多的页面碎片(实际上是 0),因此当 VACUMME FULL 运行第二阶段时,它仍然会尝试组织有效记录,但是因为没有碎片,因此它不必实际移动任何记录并且会更快完成。

      但是,上面解释的情况不是更新/删除在现实世界中发生的方式。表上的实字更新/删除会产生大量页面碎片,因此在第二阶段 VACUUM FULL 过程必须在每个页面的开头实际将有效记录移动到空闲空间中,因此需要更多时间。

      检查以下示例输出,

      我为非常小的虚拟桌子奔跑。即使它只有 7 行。 VACUME PROCESS (第一阶段)在 0.03 秒(30 毫秒)内完成,但 总查询报告在 61 毫秒内完成。所以这告诉我,即使没有什么可以重组的过程仍然检查它是否可以重组,因此需要时间。但是,如果我实际上有很多碎片和重组发生,那么完成时间会更长,具体取决于页面碎片。

      【讨论】:

        猜你喜欢
        • 2020-06-08
        • 1970-01-01
        • 2019-12-18
        • 2013-01-02
        • 1970-01-01
        • 2012-12-13
        • 1970-01-01
        • 2016-07-21
        • 1970-01-01
        相关资源
        最近更新 更多