PostgreSQL multixact日志管理器说明
MultiXactID日志是uxdb系统用来记录组合事务ID的一种日志。由于uxdb采用了多版本并发控制,因此同一个元组相关联的事务ID可能有多个,为了在加锁(行共享锁)的时候统一操作,uxdb将与该元组相关联的多个事务ID组合起来用一个MultiXactID代替来管理。同CLOG、Subtrans日志一样,MultiXact日志也是利用SLRU缓冲池来实现。
MultiXact日志管理器相关数据结构
MultiXactID是一个多对一的映射关系,需要在事务ID数组中标记哪一段映射到一个MultiXactID。所以在映射的过程中需要存储两种信息,即需要标志一段事务ID的偏移量(Offset),还需要激励这段偏移量的大小(nMembers)。
由于需要对MultiXactdID的分配进行维护,于是定义了数据结构MultiXactStateData。
MultiXactStateData用来管理和维护MultiXactID,另外还需要定义一个统一的接口来操作MultiXactID,即存储这种多对一的映射关系,uxdb定义mXactCacheEnt来完成此工作。
multixact日志存储在uxdata/ux_multixactd/目录下,其中会有两个子目录members和offset,分别存储XactID成员和偏移量。从一个MultiXactID映射到具体的存储位置是通过下面的变换来完成的:
TODO
MultiXact日志的缓冲区用两个slru缓冲池来实现,分别是MultiXactOffsetCtl和MultiXactMemberCtl,分别记录Members和Offsets。在uxdb启动后,就注册在共享内存中,管理全局的MultiXactID。
MultiXact日志管理器主要操作
同CLOG日志管理器一样,MultiXact日志管理器的操作包括Multixact日志系统的启动、关闭、检查点操作,以及MultiXactID的创建、扩增等。
Multixact的创建
改操作定义在函数MultiXactIdCreate中。MultiXactID的创建指的是将两个XID组合成一个整体,结果返回一个MultiXactID,用来代替这两个XID。创建过程如下:
-
首先在当前进程MXactCache中查找这两种XID的组合是不是已经生成了一个MultixactID,如果已经生成,直接返回MultiXactID即可。
-
调用GetNewMultiXactId函数从共享内存MultiXactState中获得一个新的MultiXactID,并更新MultiXactState中的nextMXact和nextOffset。
-
向XLOG中写入当前操作的日志,记录当前分配得到的MultiXactID以及组合成该MultiXactID的Xids链表和数量。
-
最后将该MultiXactID以及相关Xids更新到本地缓存中,返回MultiXactID。
Multixact的扩增
该操作定义在函数MultiXactIdExpand中。我们知道,一个MultiXactID可以对应多个Xid,而上面的MultiXactID的创建只能完成两个Xid到一个MultiXactID的映射过程,于是定义了MultiXactIdExpand()来完成MultiXactdID的扩增,即将一个Xid加入到该MultiXactID对应的Xids队列中。
-
首先有MultiXactID找到对应的Xids队列和数量。
-
检查该MultiXactID是否有对应成员存在,若不存在,创建一个仅由该Xid组成的MultiXactID返回即可。
-
检查该Xid是否已经在当前MultiXactID对应的Xids中,若存在,直接返回即可。
-
将该MultiXactID对应的Xids链表取出,将新增的Xid放到其末尾,然后重新调用MultiXactdIdCreate()得到新的MultiXactID,最后返回该值。
检测MultiXact是否在运行中
该操作定义在函数MultiXactIdIsRunning中,其逻辑比较简单,当该MultiXactID中的任何一个成员属于当前事务ID或者正在运行中,则认为该MultiXactID也在运行中。
4)Multixact日志系统的启动
该操作定义在函数StartupMultiXact中,一般在Uxdbmaster启动时通过调用StartupXlog进而调用StartupMultiXact。主要功能是用来初始化管理MultiXactID的偏移量和成员的两个slru缓冲池。
5)Multixact日志系统的关闭
该操作在函数ShutdownMultiXact中定义,用来完成MultiXactID日志系统的关闭。通过调用SimpleLruFlush函数将管理MultiXactID的偏移量和成员的两个slru缓冲池刷新到磁盘即可。
6)MultiXact日志系统检查点操作
在创建检查点时,MultiXactID日志系统也需要刷新到磁盘,所以CheckPointMultiXact用来将管理MultiXactID的偏移量和成员的两个slru缓冲池刷新到磁盘。与MultiXact日志的关闭不同的是,在这个刷新的过程中,允许其他进程向缓冲池中写日志。