You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何PostgreSQL中带ONLY的ALTER TABLE修改默认值会锁表?

问题原因

当你使用ALTER TABLE ONLY修改列默认值时,PostgreSQL会强制获取ACCESS EXCLUSIVE锁——这是PostgreSQL中级别最高的表锁,会阻塞该表上的所有读写操作,所以你会感觉到"锁表"。

而不带ONLY的语句,在目标表没有子表的情况下,PostgreSQL会使用SHARE UPDATE EXCLUSIVE锁,这个锁级别更低,不会阻塞普通的SELECT、INSERT、UPDATE、DELETE操作,所以你观察不到锁表现象。

深层逻辑

虽然你的t_cats没有子表,但ONLY关键字会改变PostgreSQL的执行路径:

  • 不带ONLY时,PostgreSQL会先检查表是否有子表。如果没有,它会将修改默认值的操作视为轻量级元数据变更,使用低级别锁即可完成——因为修改默认值只需要更新系统表pg_attribute中的attdefault字段,不需要触碰实际的数据行。
  • 带ONLY时,PostgreSQL会进入"仅修改主表"的执行分支,这个分支会强制使用ACCESS EXCLUSIVE锁。哪怕当前没有子表,它也要确保在操作期间不会有新的子表被创建(防止出现主表和子表默认值不一致的情况),所以会持有最高级别的锁,导致其他操作被阻塞。

验证方式

你可以通过查询pg_locks视图确认两种语句的锁级别差异:

  1. 执行带ONLY的语句时,在另一个会话查询:
SELECT mode FROM pg_locks WHERE relation = 't_cats'::regclass;

会返回AccessExclusiveLock。

  1. 执行不带ONLY的语句时,同样查询会返回ShareUpdateExclusiveLock。

内容的提问来源于stack exchange,提问作者Ярослав Ведерников

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 23:12:15