howard_shooter 2023-05-24 17:54 采纳率: 0%
浏览 33

PG两阶段锁和LWLock

李老师,有个问题想请教一下,按照《数据库事务处理的艺术》所说,PG的DDL使用两阶段锁,而PG中有spinlock,lwlock,regularlock三种锁,两阶段锁用的应该是regularlock。

我调试了一个例子:create table t1 (a int)

按照我的理解:代码中应该先调用LockAcquire,并且LockAcquire之间没有LockRelease调用。

但是实际上,LockAcquire之间有LockRelease,LockRelease后又有LockAcquire调用。

这样是不是不符合两阶段锁协议?还是我的理解有问题。

另外还有一个问题,PG在DDL时,也多次调用LWLockAcquire和LWLockRelease,也并没有遵守两阶段协议,

代码中访问共享的数据结构时(如获取事务id),LWLockAcquire后,读写完就LWLockRelease了,也并不遵守两阶段协议,

而我的理解,应该是DDL事务中,读写所有对象的加锁(例如对锁表的增删操作本身也需要锁吧),都应该遵守2PL,才能保证DDL的一致性。

还是我的理解有问题,只要对核心对象的访问遵守2PL,其它对象只要保证单个对象访问的原子性就可以了?这个地方我有些迷惑。

谢谢!

  • 写回答

2条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-05-25 12:10
    关注
    不知道你这个问题是否已经解决, 如果还没有解决的话:
    • 以下回答来自chatgpt:

      对于第一个问题,PG的两阶段锁确实包含LockAcquire和LockRelease两个步骤,但是在DDL操作中,PG采取的是DDL拆分方式,在先申请锁再执行DDL操作的过程中,可能会有LockRelease的过程出现。这是由于PG为了保证DDL操作的原子性,采取的拆分方式是先申请为LWLock,再申请为Lock,最后生成代码执行。在这个过程中,为了确保环境一致性,必须释放LWLock,这就有可能导致LockRelease的出现,这是正常情况,符合两阶段锁机制的。

      对于第二个问题,PG在DDL操作中使用了LWLockAcquire和LWLockRelease,这与两阶段锁是不同的。两阶段锁是指在事务中对于任何访问数据的操作都需要先申请锁,直到事务结束后再执行释放锁的操作。而LWLock是在进程之间互斥共享内存的一种锁机制,类似于悲观锁,在对象访问时也会申请LWLock,但是并不需要遵守两阶段协议。

      对于锁表增删操作等操作,PG采用的是重做日志和检查点的方式来保证原子性,而不是两阶段锁机制。因此,在这些操作中,并不需要遵守两阶段协议。对于核心对象的访问,PG采用的是两阶段锁机制来保证事务的隔离性和原子性。因此,在这些操作中,需要遵守两阶段协议。

      总之,在PG中,不同的操作需要采用不同的锁机制来保证事务的隔离性和原子性。而对于DDL操作,其特殊性导致了在锁的申请和释放上可能会产生LockRelease的情况,这是正常情况,不符合两阶段锁机制的要求。


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 创建了问题 5月24日

悬赏问题

  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?