在多版本控制以前,数据库仅通过锁机制来实现并发控制。数据库对读操作上共享锁,写操作上排他锁,这种锁机制虽然解决了并发问题,但影响了并发性。例如,当对一个事务对表进行查询时,另一个对表更新的事务就必须等待。DM 数据库的多版本实现完全消除了行锁对系统资源的消耗,查询永远不会被阻塞也不需要上行锁,并通过 TID 锁机制消除了插入、删除、更新操作的行锁。数据库的读操作与写操作不会相互阻塞,并发度大幅度提高。
本文只分析DM8的默认的表,索引组织表的MVCC实现原理。
MVCC的实现主要依赖于数据库在每个表中添加的两个隐藏字段(TRXID、ROLPTR),
以及事务启动时创建的活动事务视图(v$trx)来判断事务的可见性和数据库的数据版本链(Undo Log)。
索引组织表 会为每个使用索引组织表表添加三个隐藏字段
17:19:40 SYSDBA@LOCALHOST:5236 > select ROWID,TRXID from TEST.T1;
AAAAAAAAAAAAAAAAAB 20264
AAAAAAAAAAAAAAAAAC 20236
AAAAAAAAAAAAAAAAAD 20236
AAAAAAAAAAAAAAAAAE 20236
AAAAAAAAAAAAAAAAAF 20275
在DM8中,索引组织表会为每个使用索引组织表的表添加三个隐藏字段,分别是:TRXID、ROLPTR和ROWID。隐藏字段TRXID、ROLPTR用于实现多版本并发控制(MVCC)。
表1-1 一条记录的隐藏部分系统列
序号 | 列 | 说明 |
---|---|---|
1 | TRXID | 本行数据的事务版本,表明本行记录是被那个实务操作生成的 |
2 | ROLPTR | 前一个版本在undo log中的位置 |
3 | ROWID | 隐藏单调自增ID,用于默认聚簇索引 |
Undo Log主要用于记录被修改之前的数据。在表信息修改时,会先把数据拷贝到Undo Log中。当一个事务需要读取行记录时,如果当前记录行不可见,可以通过回滚指针顺着Undo Log链找到满足其可见性条件的记录行版本;或者当事务进行回滚时,可以通过Undo Log里的日志还原数据。Undo Log一方面可用于MVCC读时构建记录,在MVCC多版本控制中,通过读取Undo Log的历史版本数据可以实现不同事务版本号都拥有自己独立的数据版本。另一方面,保证事务进行回滚时的原子性和一致性,当事务进行回滚时可以用Undo Log的数据进行恢复。
在DM8中,判断事务的可见性是通过活动事务视图(v$trx)来实现的。活动事务视图是在事务启动时创建的,并收集了活动的事务的TRXID。它主要包含三个字段:TRXID、MAX_TRXID和MIN_TRXID。
TRXID用以表明本条记录是哪个事务操作时生成的, 这样就便于与快照中的事务左右边界进行比较,是否在[MIN_TRXID,MAX_TRXID]区间的左侧、中间、还是右侧,用以决定所读到的记录是否可见)
通过比较物理TRXID与活动事务视图中的MIN_TRXID和MAX_TRXID,可以确定事务对某条记录的可见性。具体规则如下:
在读未提交级别下,所有事务都是可见的,即物理TRXID小于等于MIN_TRXID或大于等于MAX_TRXID。
在其他隔离级别下,根据物理TRXID与MIN_TRXID和MAX_TRXID的关系来确定可见性:
通过使用活动事务视图和隐藏字段来实现MVCC,DM8能够同时支持多个事务对同一数据的并发访问,并且在事务提交或回滚时能够保证数据的一致性和可靠性。
达梦社区技术https://eco.dameng.com
文章
阅读量
获赞