小工具知识网

当前位置: 首页 > 行业知识 > postgresql 内核源码分析 表锁relation lock的使用,session lock会话锁的应用场景,操作表不再困难

行业知识

postgresql 内核源码分析 表锁relation lock的使用,session lock会话锁的应用场景,操作表不再困难

2026-11-02 03:56:48 来源:互联网转载

​专���内容:

postgresql内核源码分析

手写数据库toadb

并发编程

个人主页:我的主页

座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.

==================================================================

表锁介绍

当表打开,或者操作表时,都需要对表relation 进行加锁,表锁定义了8种级互斥级别,另外还有会话级表锁 session lock。

表锁的标识

  • 锁类型 LOCKTAG_RELATION
  • locktag的取值

    locktag_field1 = dboid 当relation 为共享表时 dboid = 0

    locktag_field2 = reloid

    表锁相关接口

    extern void LockRelationOid(Oid relid, LOCKMODE lockmode);extern void LockRelationId(LockRelId *relid, LOCKMODE lockmode);extern bool ConditionalLockRelationOid(Oid relid, LOCKMODE lockmode);extern void UnlockRelationId(LockRelId *relid, LOCKMODE lockmode);extern void UnlockRelationOid(Oid relid, LOCKMODE lockmode);extern void LockRelation(Relation relation, LOCKMODE lockmode);extern bool ConditionalLockRelation(Relation relation, LOCKMODE lockmode);extern void UnlockRelation(Relation relation, LOCKMODE lockmode);extern bool CheckRelationLockedByMe(Relation relation, LOCKMODE lockmode,bool orstronger);extern bool LockHasWaitersRelation(Relation relation, LOCKMODE lockmode);extern void LockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode);extern void UnlockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode);

    表锁申请方式

    表锁的申请,有两种,首先打开表时锁定系统字典中的记录,然后再对目标表加锁;

    当然,在加锁时,会检查系统字典变更,在postgresql 就是通过invalidmessage来同步变更;

    实际调用LockAcquireExtended,如果获得表锁后,首先进行invalidmessage同步处理;

    首次打开表时

    • 表的OID作为参数

      接口有 LockRelationOid,ConditionalLockRelationOid,UnlockRelationOid

      实际调用LockAcquireExtended,

      用于打开表时,锁定relcache中的数据

      • 表relid作为参数

        接口有 LockRelationId, UnlockRelationId

        实际调用LockAcquireExtended获取锁,

        用于打开表时,锁定表; 解锁时UnlockRelationId比UnlockRelationOid速度要快,建议用前者

        再次加表锁时

        • locktag使用 relation结构初始化

          接口有 LockRelation, ConditionalLockRelation, UnlockRelation;

          此时表已经 open ,实际调用LockAcquireExtended,加锁时也需要检查invalidate message。

          用途

          在访问表、索引时,先是open处理

          调用关系

          • 表的打开和关闭调用关系
            table_open->relation_open->LockRelationOidtable_close->relation_close->UnlockRelationId
            • 索引的打开和关闭调用关系 与表是类似的
              index_open->relation_open->LockRelationOidindex_close->relation_close->UnlockRelationId

              会话锁的操作

              会话锁与当前会话相关,也就是锁的持有可以跨多个事务;

              释放时,调用接口释放, 或者当会话结束时会自动释放,或者是发生了ERROR级别的错误也会自动释放。

              接口 LockRelationIdForSession 申请和 UnlockRelationIdForSession 释放

              其中调用 LockAcquire来获取常规锁,其实也是LockAcquireExtended的也一个包装,固定了最后两个参数;

              会话锁的入参 LockRelId 指定了dbid, relid;

              会话锁的用途

              • 创建索引

                在concurrent 方式创建索引时,会再次加session lock;

                • 删除索引 drop index
                • 重建索引 reindex
                • 清理表 vacuum

                  结尾

                  非常感谢大家的支持,在浏览的同时别忘了留下您宝贵的评论,如果觉得值得鼓励,请点赞,收藏,我会更加努力!

                  作者邮箱:study@senllang.onaliyun.com

                  如有错误或者疏漏欢迎指出,互相学习。

                  注:未经同意,不得转载!

上一篇:装win7找不到任何驱动程序怎么办?

下一篇:揭秘音乐大师朱载?,名字读音、释义及背后故事全解析