如何避免Postgres 13中仅插入表被自动清理锁阻塞写入?
问题:避免PostgreSQL仅插入表被防XID回卷自动清理阻塞写入
我运行着Postgres 13实例,其中包含一张仅插入表。应用写入该表时会手动获取SHARE ROW EXCLUSIVE锁(作为并发控制手段,确保客户端读写期间无其他插入操作)。多数情况下运行正常,但当Postgres执行防XID回卷的激进自动清理时,会阻塞该表的写入操作,且自动清理耗时可达数分钟,导致无法写入的时间过长,无法接受。
曾以为Postgres 13的默认设置可避免该问题,相关内容提到:
与其他自动清理运行不同,防回卷自动清理在阻塞并发事务时不会放弃,甚至会阻塞需要
ACCESS EXCLUSIVE锁的短操作(如表上的DDL语句),被阻塞的操作会进一步阻塞所有表访问,导致处理停滞。
从PostgreSQL v13开始,默认设置应已能保护您免受此问题影响。
我的当前推测是,常规自动清理进程并未扫描多数页面——根据官方文档:
[VACUUM]会跳过无任何死行版本的页面,即便这些页面可能仍包含具有旧XID值的行版本
由于这是仅插入表,多数/所有页面都无死行版本,因此会被自动清理进程跳过。自动清理从未访问这些页面,行也从未被冻结,最终触发需要执行激进自动清理以防止XID回卷。
我希望避免自动清理阻塞该表的写入操作:
- 一种方案是为该表将
autovacuum_freeze_max_age设置为极低值,使激进自动清理更频繁触发(每次处理的工作量更少,阻塞时间更短),但这仍会存在一定阻塞时间,我希望尽可能避免。 - 不愿使用带
DISABLE PAGE SKIPPING的手动VACUUM,因为官方警告:仅应在……存在导致数据库损坏的硬件或软件问题时使用此选项
我觉得扫描所有页面与防XID回卷及“激进”设置绑定在一起的设计很奇怪,若我对系统工作原理有误解,请告知!我希望能执行更“彻底”的无阻塞自动清理,冻结所有行。
如何避免该表的写入操作被阻塞?
内容的提问来源于stack exchange,提问作者Parker
相关产品推荐
相关产品推荐

