metrics
是一个未记录的表,大约有 3M 行,我刚刚执行了ALTER TABLE metrics SET LOGGED
以记录这些数据。但它似乎被一些 autovacuum 运行进程锁定。
pid | usename | blocked_by | blocked_query
-------+----------+------------+------------------------------------------
13462 | postgres | {32090} | ALTER TABLE sensors.metrics SET LOGGED;
duration | query | pid
-----------------+------------------------------------------------------------------------+-------
02:03:08.131365 | autovacuum: VACUUM pg_toast.pg_toast_315873283 (to prevent wraparound) | 32090
我的 32 核和 98gigs RAM 的 autovacuum 设置:
autovacuum_max_workers
------------------------
12
autovacuum_vacuum_cost_limit
------------------------------
-1
autovacuum_vacuum_cost_delay
------------------------------
20ms
vacuum_cost_page_hit
----------------------
1
vacuum_cost_page_miss
-----------------------
10
vacuum_cost_page_dirty
------------------------
20
我可以做些什么来避免锁定,或者在不终止正在登录数据的 alter table 进程的情况下修复此锁定吗?
您可以终止 autovacuum (32090)。你不应该养成这样做的习惯,但在这种情况下应该没问题。
您可能想先运行:
并确保报告的价值远低于 20 亿。
您可能还想检查 pg_toast_315873283 是否是sensors.metrics 的toast 表。我不明白为什么它会首先阻止,但事实并非如此,但验证这些假设并没有什么坏处。
另一方面,您可以耐心等待,让 autovacuum 完成。真空需要发生,如果你在它仍然未记录的情况下完成真空,它将产生更少的 WAL 流量。
另一方面,您可能希望
VACUUM FREEZE sensors.metrics
在一个会话中开始手动操作,然后取消 ALTER TABLE 和 autovac,然后在真空完成后执行 ALTER TABLE。这将比 autovac 更快地完成(手动清理的默认设置不使用 IO 节流),并且再次完成最终需要完成的工作,并且在 table 仍设置为 UNLOGGED 时可能会做得更好。