关于 PolarDB PostgreSQL 版
PolarDB PostgreSQL 版是一款阿里云自主研发的云原生关系型数据库产品,100% 兼容 PostgreSQL,高度兼容Oracle语法;采用基于 Shared-Storage 的存储计算分离架构,具有极致弹性、毫秒级延迟、HTAP 、Ganos全空间数据处理能力和高可靠、高可用、弹性扩展等企业级数据库特性。同时,PolarDB PostgreSQL 版具有大规模并行计算能力,可以应对 OLTP 与 OLAP 混合负载。
事务类型WAL
在前述介绍WAL日志的文档中,我们介绍了PolarDB PostgreSQL数据库中关于WAL日志的组织形式、内部结构,WAL日志高效的结构设计,使其可以承载多种不同种类的WAL日志,覆盖数据库内部的所有主要数据结构:事务系统、数据表、BTree索引、Hash索引、Gin索引、Gist索引等。
这篇文章对于事务类型的WAL日志进行介绍,该类型的WAL日志记录了数据库事务信息的变化,比如:事务XID的状态、CLOG文件、MultiXact文件、CommitTs文件等重要事务信息的变化,接下来进行一一介绍。
事务类型WAL的分类
PolarDB PostgreSQL 15版本中,共有5大类事务信息记录的WAL日志:Transaction类型、CLOG类型、MultiXact类型、CommitTs类型、CSNLOG类型。其中CSNLOG类型的日志集成在了XLOG大类下,在之前XLOG类型WAL日志文档中已经介绍过,接下来对剩余的4类WAL日志做简单的介绍。
Transaction类型
该类型WAL日志记录了一个事务XID的状态变化,包括:prepare状态、commit状态、abort状态等,不仅涉及常规事务,也涉及两阶段事务和子事务。一共包括7个子类型的WAL日志,接下来对每种子类型做简单的介绍。
XLOG_XACT_COMMIT
COMMIT状态表示事务当前的修改已经生效,一旦这个类型的WAL日志被写到存储上,则表明该COMMIT状态的事务被持久化,进而说明了该事务执行的一切修改操作都已经被持久化,即使当前数据库发生崩溃,事务所做的修改也可以从WAL日志恢复出来。
从前述介绍WAL日志的文档中可知,WAL日志的头部结构中包含了产生这个日志的事务XID。而该类型WAL日志的main data结构中还记录有8个重要的信息,如下所示:
- xact_time:事务提交时记录的时间戳,可用于按时间点恢复等需求。
- DBINFO:可选项,当需要记录RELFILENODES、DROPED_STATS、INVALS时,需要记录对应的数据库信息。备库的backend根据这个信息来决定是否执行失效消息。逻辑复制也使用这里记录的数据库信息,来判断是否是目标复制对象。
- SUBXACTS:记录了当前事务XID的子事务信息,包含数量和每个子事务的XID。如果当前父事务产生了多个子事务,那么父事务提交时,也必须将子事务设置为COMMIT状态,保证父子事务状态的一致性。
- RELFILENODES:如果事务执行过程中,删除了一些表,则涉及到的需要删除的表文件都会记录到XLOG_XACT_COMMIT日志中,该日志在备库回放时,会将这里记录的文件全部删除掉。
- DROPED_STATS:记录了需要被删除掉的统计信息对象,该日志在备库回放时,会将这里记录的统计信息全部都删除掉。
- INVALS:记录了一组失效消息,比如:事务替换了一个表的文件名,则备库在回放日志时,需要通知其他backend进程失效掉本地的relcache,重新从系统表中加载正确的表信息。
- TWOPHASE:记录了两阶段事务的XID,只在子类型XLOG_XACT_COMMIT_PREPARED/XLOG_XACT_ABORT_PREPARED中使用。
- ORIGIN:记录了origin_lsn和origin_timestamp,只在逻辑复制中使用。
XLOG_XACT_ABORT
ABORT状态表示事务已经会滚,事务的修改将被撤销,一旦这个类型的WAL日志被写到存储上,则表明该ABORT状态的事务被持久化,进一步说明了该事务执行的一切修改操作都已经被会滚掉。
XLOG_XACT_ABORT子类型的WAL日志中包含的信息和XLOG_XACT_COMMIT是一致的,含义和作用也是一致的,只不过备库在回放时,处理逻辑稍有不同而已。
XLOG_XACT_PREPARE
通过PREPARE开启一个两阶段事务时,会产生该类型的WAL日志,日志头部包含两阶段事务的XID、日志的开始位点和大小,于是不需要使用main data来存储额外的信息。
备库在回放该WAL日志时,会将两阶段事务的信息维护在共享内存的数据结构TwoPhaseState中,以便于后期backend判断可见性时使用。
XLOG_XACT_COMMIT_PREPARED
两阶段事务的提交操作,main data中保存的信息和XLOG_XACT_COMMIT一致,提交过程执行的逻辑也保持一致。
相比于普通事务,多出了从共享内存的数据结构TwoPhaseState中摘除该两阶段事务的操作。
XLOG_XACT_ABORT_PREPARED
两阶段事务的会滚操作,main data中保存的信息和XLOG_XACT_ABORT一致,会滚过程执行的逻辑也保持一致。
相比于普通事务,多出了从共享内存的数据结构TwoPhaseState中摘除该两阶段事务的操作。
XLOG_XACT_ASSIGNMENT
由于共享内存中一个父事务可以保存的子事务的数量是有限的,当子事务数量超过这个限制后,会生成该WAL日志,并在子事务在pg_subtrans存储路径下对应的文件中,标记好该子事务对应的父事务XID,以便于后续根据该文件来查找对应的父事务XID。
同时标记当前存在子事务溢出现象,当可见性判断需要一个事务XID的状态时,也需要考虑其父事务的状态。
XLOG_XACT_INVALIDATIONS
只用于逻辑复制过程。
CLOG类型
和之前介绍的CSNLOG类型的WAL日志一样,CLOG类型的WAL日志是为了事务XID状态记录文件的扩展与回收操作。主要包含两个子类型:CLOG_ZEROPAGE和CLOG_TRUNCATE。
CLOG_ZEROPAGE
该类型WAL日志是为了扩展一个新的CLOG文件的页面,并且初始化为全零状态。
其main data中包含了一个int类型的整数,表示需要扩展出来的页面号。
CLOG_TRUNCATE
该类型WAL日志是为了回收一些老的CLOG文件的页面,同时更新全局最老的事务XID。
其mian data中包含了一个int类型的整数,表示需要回收的最新的页面号,小于该页面号的CLOG都需要被删除掉,同时共享内存中小于该页面号的CLOG page都需要被淘汰掉。
其main data中还包含了oldestXact,表示当前系统中最老的事务XID,用于更新共享内存中全局最老的事务XID。以便于备库上的backend可以快速的进行可见性判断。
MultiXact类型
主节点上,不同的的事务XID使用共享行锁来锁定同一个元组时,会产生MultiXact ID,MultiXact ID中记录了锁定同一个元组的事务XID,并且保存了这些事务XID在MultiXact中的状态。
MultiXact事务的状态信息主要存储在两个子路径下:pg_multixact/offsets和pg_multixact/members。offsets路径下保存了一个偏移量,该偏移量指向了members路径下的某个文件的具体位置,该位置上存储了MultiXid所对应的事务XID及其状态。
该类型WAL日志共包含4个子类型:
XLOG_MULTIXACT_ZERO_OFF_PAGE
与CLOG_ZEROPAGE类似,只不过该子类型WAL日志用于扩展pg_multixact/offsets下的文件。
XLOG_MULTIXACT_ZERO_MEM_PAGE
与CLOG_ZEROPAGE类似,只不过该子类型WAL日志用于扩展pg_multixact/members下的文件。
XLOG_MULTIXACT_CREATE_ID
当主节点生成一个新的MultiXact ID时,会产生该子类型的WAL日志。其main data中包含了具体的MultiXact ID和其对应的事务XID数组,备库通过回放该WAL日志,将MultiXact ID和其成员,记录到pg_multixact对应的路径下。
另外,回放时还需要更新共享内存中最新的MultiXact ID的值。
XLOG_MULTIXACT_TRUNCATE_ID
与XLOG_MULTIXACT_CREATE_ID相反,该类型的WAL日志是用于回收pg_multiscat路径下的文件。其main data中分别记录了需要删除的offsets路径和members路径页面号的范围。
另外,回放时还需要更新共享内存中最老的MultiXact ID的值。
CommitTs类型
CommitTS类型的WAL日志,主要用于记录事务提交/会滚时的时间戳,主节点在事务XID提交/会滚时,会将当前时间戳记录到CommitTs的存储路径下。
由于该时间戳的记录会加重事务提交阶段的逻辑,对TPS不友好,于是PG提供了参数track_commit_timestamp来控制是否打开该功能,默认是关闭状态。
该类型的WAL日志包含两个子类型:COMMIT_TS_ZEROPAGE和COMMIT_TS_TRUNCATE,作用与CLOG类型的WAL日志相似,只不过一个是维护CLOG文件,一个是维护CommitTs文件。
总结
文章介绍了PolarDB PostgreSQL数据库中事务类型的WAL日志,共介绍了4种不同的事务类型日志,包含15种子类型,每种WAL日志子类型都有不同的用途。事务类型的WAL日志主要用于同步数据库中的事务信息,经过文章中的分析可知,涉及到的信息有:事务XID的状态、CLOG文件的变化、CommitTs文件的变化、事务提交时一些额外的重要操作、子事务、MultiXact事务等。




