您可能认为我实际上必须指的是其他工具,例如pg_repack。不我不是。我真的指的是在非阻塞模式下运行VACUUM FULL命令。WHAT!?#$%@!
开始了:
1、在同一屏幕上设置 2 个 psql 会话窗口。
2、第一个窗口每隔几秒显示一次活动连接的状态(使用\watch命令),通过对pg_stat_activity表运行查询来查看是否有任何活动连接正在等待(wait_event和wait_event_type)。
3、第二个窗口对臃肿的表执行实际的 VACUUM FULL VERBOSE 命令,一次一个。
4、如果第一个窗口中出现等待条件,请立即取消第二个窗口中的真空 ( Ctrl-C ),除非您确定等待条件与vacuum full.无关。
5、继续清理下一张表。
好的,你是对的:vacuum full 确实会锁定一个表,并且可能会导致其他活动事务的阻塞条件,但可以通过增加几秒钟的额外等待其他活动事务将其最小化到不会真正造成伤害的程度交易一些时间!显然,这种方法应该通过此处所示的主动监控来完成,尽管也许您可以通过编程方式进行,但我不会冒险。它确实需要特殊的 PG DBA 能够不间断地一遍又一遍地完成一项平凡的、重复性的任务而不会感到不耐烦。
当然,由于长时间的VACUUM FULL 持续时间(非常大的表)或冲突,某些表不符合以这种方式进行碎片整理的资格。这些情况需要特殊工具,例如pg_repack可以以编程方式/调度运行而不会中断。
与其他真正的非阻塞工具相比,VACUUM FULL 的主要优势在于时间和成本。由于其他非阻塞碎片整理程序如何工作以规避锁定问题,因此使用 VACUUM FULL 进行碎片整理速度更快且使用更少的资源。
膨胀候选是通过运行可用于 PG 的许多膨胀检测查询之一来确定的。你的选择。我个人喜欢Jehan-Guillaume De Rorthais的 pgsql- bloat-estimation。
监视窗口执行一次查询,然后是 \watch 命令:
select coalesce(datname,'N/A') as datname, pid, coalesce(usename, 'N/A') as usename, substring(coalesce(application_name, 'N/A'),1,15) as app, wait_event, wait_event_type as we_type, CASE WHEN state = 'idle in transaction' THEN 'idle in trans' ELSE state END as state, (case when backend_type = 'logical replication launcher' then 'logical rep launcher' when backend_type = 'autovacuum launcher' then 'autovac launcher' when backend_type = 'autovacuum worker' then 'autovac wrkr' else backend_type end) as backend_type, to_char(backend_start, 'YYYY-MM-DD HH24:MI:SS') as backend_start, coalesce(to_char(query_start, 'YYYY-MM-DD HH24:MI:SS'), 'N/A') as query_start, (case when state in ('active','idle in transaction') then cast(EXTRACT(EPOCH FROM (now() - query_start)) as integer) else -1 end) as seconds, regexp_replace(replace(regexp_replace(substring(query,1,65), E'[\\n\\r]+', ' ', 'g' ),' ',''), '[^\x20-\x7f\x0d\x1b]', '', 'g') as query from pg_stat_activity where state in ('active','idle in transaction') order by seconds;
\watch 3
原文标题:Running VACUUM FULL in Non-blocking Mode
原文作者:Michael Vitale
原文链接:https://elephas.io/running-vacuum-full-in-non-blocking-mode/




