什么是 MultiXactId?
  xaeiTka4h8LY 2024年03月22日 167 0

并发事务实现中,有时某个事务需要对上万行加锁,此时锁对象不适于放在内存中,PG采取的策略是,将加锁事务的ID设置到被锁记录的xmax中,同时设置t_infomask表示记录被锁,以此表示记录被锁住(共享锁或互斥锁)。

但是,当多个事务都要对某行记录,加共享锁时,又怎样表达呢?上述的机制,看起来没法表示多个事务对记录加共享锁的情况。

解决办法就是,用一个特殊的事务ID(MultiXactId)代替所有加锁的事务ID,然后建立MultiXactId与这些事务ID的对应关系。例如:

什么是 MultiXactId?

对于上图的场景,如果又有一个事务T4要对这行记录加锁,PG内核会怎么办呢?它会再创建一个新MultiXactId,在MutiXactOffsetCtl和MultiXactMemberCtl中建立它与新的事务集合(T1、T2、T3、T4)的映射,并用新的MultiXactId替换xmax中旧的值。而旧MultiXactId在MutiXactOffsetCtl和MultiXactMemberCtl中的数据就留在那里,不再使用,直到vacuum时删除。

 当加锁的事务执行完时,并不会对记录“解锁”,记录xmax中的MultiXactId仍然保留,对于要读写或者加锁这条记录的事务而言,它必须查询映射信息(MutiXactOffsetCtl和MultiXactMemberCtl)和snapshot,判断这条记录是否仍然被某个事务加锁。

映射信息(MutiXactOffsetCtl和MultiXactMemberCtl)存储在文件中,在数据目录的pg_multixact目录下,同时在内存中有缓存,它的存储机制由SLRU模块管理,与事务日志CLOG的存储机制相同。

参考:Notes on some PostgreSQL implementation details

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2024年03月22日 0

暂无评论

推荐阅读
  xaeiTka4h8LY   2024年05月31日   28   0   0 PostgreSQL
  xaeiTka4h8LY   2024年03月22日   168   0   0 PostgreSQL内核
xaeiTka4h8LY