当前位置: 首页 > postgresql, 锁模块 > 正文

书本上为什么这么说?(单一资源视角的逻辑)】

教材里说表锁不会死锁,是因为表锁把“粒度”提到了最高。

如果是行锁,进程 A 锁行 1,进程 B 锁行 2,两人互相去要对方的行,就会死锁。

但如果是纯粹的表锁,进程 A 直接把整张表霸占了,进程 B 连进都进不来,只能在表门口乖乖排队。因为没有了“微观交织”的空间,所以在单一表资源的范围内,确实斩断了死锁的可能。

【PG/openGauss 的工业真实环境(多资源事务闭环)】

但在真实的 PG 生产环境中,表级锁依然会发生死锁

  1. 物理原因:PG 是支持多语句事务的。重量级锁(表锁)一旦加上,必须等到事务 COMMITROLLBACK 才会释放(两阶段封锁协议 2PL)。
  2. 推导死锁闭环
    • 业务线程 1:开启事务 $\rightarrow$ 锁住表 A(拿到 A 的表锁)$\rightarrow$ 执行一堆逻辑 $\rightarrow$ 尝试去锁表 B。
    • 业务线程 2:开启事务 $\rightarrow$ 锁住表 B(拿到 B 的表锁)$\rightarrow$ 执行一堆逻辑 $\rightarrow$ 尝试去锁表 A。
    • 碰撞发生:线程 1 在表 B 门口排队,线程 2 在表 A 门口排队。两人互相拿着对方下一步急需的全局表级锁,进入死循环。
  3. 内核兜底:正因为 PG 的表锁会死锁,所以我们前面推导过,重量级锁的底层必须配备全库唯一的“死锁检测器(Deadlock Detector)”。

高级 DBA 面试话术: “纯理论上的‘一次性封锁协议’确实不会死锁,但在 PG 的多表事务流转中,表级锁(重量级锁)由于生命周期较长,极易发生交叉表死锁。绝不能盲目认为用表锁就高枕无忧。”


了解 www.876873.xyz 的更多信息

订阅后即可通过电子邮件收到最新文章。

PG 里的表级锁真的不会死锁吗?:等您坐沙发呢!

发表评论