执行手动 vacuum 冻结 - Amazon Relational Database Service

执行手动 vacuum 冻结

您可能需要对已具有正在运行的 vacuum 进程的表执行手动 vacuum 操作。如果您已使用接近 20 亿个事务(或高于您监控的任何阈值)的期限标识表,则这会很有用。

以下步骤是指导原则,此过程存在几种变化。例如,在测试期间,假设您发现设定的 maintenance_work_mem 参数值过小,并且您需要立即对表采取措施。不过,可能您不希望此时恢复实例。通过使用前几节中的查询,您可以确定哪个表存在问题,并找到长时间运行的 Autovacuum 会话。您知道您需要更改 maintenance_work_mem 参数设置,但您还需要立即采取行动,对有问题的表执行 vacuum 操作。以下过程说明了在此情况下应采取的措施。

手动执行 vacuum 冻结
  1. 打开针对包含要执行 vacuum 操作的表的数据库的两个会话。对于第二个会话,使用“screen”或其他维护会话的实用工具 (如果您的连接已中断)。

  2. 在第一个会话中,获取正在表上运行的 autovacuum 会话的进程 ID (PID)。

    运行以下查询可获取 Autovacuum 会话的 PID。

    SELECT datname, usename, pid, current_timestamp - xact_start AS xact_runtime, query FROM pg_stat_activity WHERE upper(query) LIKE '%VACUUM%' ORDER BY xact_start;
  3. 在第二个会话中,计算该操作所需的内存量。在此示例中,我们确定自己最多可以为该操作使用 2GB 的内存,因此,我们将当前会话的 maintenance_work_mem 设置为 2 GB。

    SET maintenance_work_mem='2 GB'; SET
  4. 在第二个会话中,为表发出 vacuum freeze verbose 命令。详细设置很有用,因为虽然 PostgreSQL 中当前没有进度报告,但您可以查看活动。

    \timing on Timing is on. vacuum freeze verbose pgbench_branches;
    INFO: vacuuming "public.pgbench_branches" INFO: index "pgbench_branches_pkey" now contains 50 row versions in 2 pages DETAIL: 0 index row versions were removed. 0 index pages have been deleted, 0 are currently reusable. CPU 0.00s/0.00u sec elapsed 0.00 sec. INFO: index "pgbench_branches_test_index" now contains 50 row versions in 2 pages DETAIL: 0 index row versions were removed. 0 index pages have been deleted, 0 are currently reusable. CPU 0.00s/0.00u sec elapsed 0.00 sec. INFO: "pgbench_branches": found 0 removable, 50 nonremovable row versions in 43 out of 43 pages DETAIL: 0 dead row versions cannot be removed yet. There were 9347 unused item pointers. 0 pages are entirely empty. CPU 0.00s/0.00u sec elapsed 0.00 sec. VACUUM Time: 2.765 ms
  5. 在第一个会话中,如果 autovacuum 阻止 vacuum 会话,您将在 pg_stat_activity 中看到 vacuum 会话的等待为“T”。在此情况下,您需要终止 autovacuum 过程,如下所示。

    SELECT pg_terminate_backend('the_pid');

    此时,您的会话将开始。由于此表可能位于其工作列表中的最高位置,因此,了解 Autovacuum 将立即重新启动很重要。

  6. 在第二个会话中启动您的 vacuum freeze verbose 命令,然后终止第一个会话中的 autovacuum 过程。