2. DDL会被写事务堵塞,但后续新的写事务不会被DDL阻塞
Oracle中,DDL会被写事务阻塞,但此时后续新的写事务不会被该DDL阻塞。而在MySQL中,由于MDL-X锁具有较高的优先级,因此一旦DDL被未提交的事务阻塞,后续该表上的所有新事务都将被阻塞以防止MDL-X锁饥饿。
3. 被阻塞的DDL不会被后续新事务阻塞
当DDL被事务1阻塞后,新进的事务3正常执行,当事务1回滚后DDL将执行完成,而不会被未提交的事务3阻塞。
但值得注意的是,在该场景下似乎出现了DD和数据不一致的情形,列C有NOT NULL NUMBER约束,但是查询出来的数据列C没有值(该行由事务3写入)。但对该问题我们未做深入探究。
从以上几个特征可以看出,Oracle的add column的约束比MySQL要弱,它不保证DD的事务特性。与DML事务的并发能力比MySQL要强很多,也不会出现MySQL常见的锁表问题。
我们在一个会话中开启一个新的事务,在表t1中插入数据,但不提交。
开启一个新的会话,我们首先查询数据,在RC的隔离级别下,未提交事务写入的数据不可见。然后做add column操作,该操作可以立即完成,而不会被未提交的事务阻塞。
2. 保持DD的事务一致性,跨DDL的事务只能访问到一个版本的DD
回到第一个会话,查看表结构并继续插入数据,此时由于该事务开始时间在add column之前,所以新增的列对其不可见。提交该事务后重新查询,我们将看到最新的表结构。
切换到第二个会话,当第一个会话的事务提交之后,查询将看到最新的已提交数据。
1. DD多版本技术
说到多版本技术,最为人熟知的就是数据库的MVCC。Innodb MVCC的基本原理是允许每一行数据保持多个历史版本,这些版本通过undo链组织,每个事务在读取数据时都持有一个read view,通过read view判断该事务应该读取哪个版本的数据。通过MVCC,Innodb解决了数据读写相互阻塞的问题。但是,当我们把眼光投向DDL的时候,我们就会发现DD的读写仍然是相互阻塞的:DDL本质上是DD的写操作,而DML/DQL则是DD的读操作。因此为了实现DDL的Nonblock,我们需要在DD中引入MVCC技术,为每一个DD的元素赋予版本信息,允许同时存在DD元素的多个版本,同时为每一个事务绑定一个DD的read view。在访问DD时通过DD的read view判断DD元素的可见性并读取相应的版本。
在MySQL8.0,所有表的DD信息都存储于Innodb中,以表的形式组织。整个DD的存储体系如下所示
从这些表名,我们可以看到,MySQL将DD的信息分门别类的存储在不同的表中,例如columns表存储列的定义信息,indexes表存储索引的定义信息,这些DD的不同子项就是我们所说的DD元素,DD的多版本就是DD中这些元素的多版本。实际上在内部我们曾讨论过多版本信息的粒度问题。
- 细粒度的实现特定元素的多版本存储,对表而言仅有一个版本,但是列/索引等DD元素存储多版本信息。以列信息为例,在该方案下表中的列具有如下图所示的逻辑结构。
虽然细粒度的方案实现起来细节更多,但考虑的工程上的可迭代性,我们仍然选择了方案2。依据该方案的思路,我们率先实现了列信息的多版本:每个表有一个单调递增的唯一版本号,每个列在创建/修改时会从该版本号中分配一个。
3. 事务的DD ReadView
Innodb事务中存储了m_low_limit_id,m_up_limit_id,以及活跃事务列表m_ids等核心信息,用来选择数据的确切版本。因为我们不支持DDL本身的并行,也就是说任意时刻某个表上活跃的DD事务一个,所以DD的read view只需要记录目标表上单调递增的版本号就可以了,因此一个事务的DD ReadView有如下逻辑结构。为了保持MySQL DD语意的一致性,对DML/DQL事务来说,DD的读取总是RR的,当事务第一次访问到某个表时,DD ReadView中就记录了相应的版本,后续直到事务提交,该事务都只能看到该版本的DD信息(对Oracle来说,DD的读取可以认为是RC的,DDL事务提交后,非DDL事务可以立即看到最新的DD)。
4. 一次DDL和DML的并发过程
我们在下文抽象出DDL和DML的事务并发过程,该过程的一个实际例子在前文已有展示。
从上述流程中,我们可以看到,非DDL事务在open table时将构建DD ReadView并绑定,随后DDL的执行将不被未提交的事务阻塞,DDL提交后,事务利用ReadView仍然能保证随后看到同一个版本的DD。
2. 限制的放宽
目前Nonblock DDL仅在普通表上得到了支持,在分区表或者含有Trigger/FTS/Foreign key等的表上还无法使用,这些类型的表在MySQL内部实现中关联了多个内部数据结构,具有更复杂的DD操作流程,后续我们将对这些特殊的的表进行适配和支持。