PostgreSQL函数执行期间表更新阻塞原因咨询
PostgreSQL函数执行期间表更新阻塞的原因解析
核心原因:事务内持有的表级独占锁未释放
- 函数的事务边界:PostgreSQL中PL/pgSQL函数默认运行在单个事务上下文里,
test_func从删除触发器、两次查询、休眠到重建触发器的所有步骤,都属于同一个事务,只有当函数完全执行完毕,事务才会结束(提交或回滚)。 - 删除触发器的锁行为:执行
DROP TRIGGER操作时,PostgreSQL会自动获取目标表的ACCESS EXCLUSIVE锁——这是最严格的表级锁类型,会阻塞所有针对该表的写操作(INSERT/UPDATE/DELETE),以及其他需要表级锁的操作(如创建触发器、ALTER TABLE等)。 - 锁的持有时间:这个
ACCESS EXCLUSIVE锁会被持有到整个事务结束,也就是函数执行完(包括pg_sleep(20)的20秒休眠期)才会释放。此时其他会话对experiment表的更新操作需要获取ROW EXCLUSIVE锁(写操作的默认锁),但由于ACCESS EXCLUSIVE锁优先级更高且未释放,这些更新操作只能进入等待队列,直到锁被释放后才能继续执行。
补充说明
如果要避免这种长时间阻塞,你可以将操作拆分为多个独立事务(比如删除触发器后立即提交事务,再执行查询和休眠,最后开启新事务重建触发器),但这样会存在触发器暂时失效的窗口,需要根据业务场景权衡风险。
内容的提问来源于stack exchange,提问作者Rishabh Agarwal
相关产品推荐
相关产品推荐

