-
what
MVCC multi-version concurrent control是用于实现事务隔离同时提高并发的关键技术,允许事务同时访问同一数据而不冲突,通过为数据对象创建多个版本实现。
-
工作原理
原理是允许事务读取事务的某一个版本,而不是最新版本,来避免读写冲突。
当数据被更新时,不直接覆盖旧数据,而是创建一个新版本。这样子不同的事务可以看到同一数据的不同版本,从而实现并发控制。
-
事务ID
事务为每一个事务分配一个唯一的事务 ID ,用于记录事务的开始时间,反应事务间的执行顺序,帮助判断数据版本的可见性
-
数据版本控制
当事务更新数据时,不直接覆盖旧数据,而是创建一个新版本。这样子不同的事务可以看到同一数据的不同版本,从而实现并发控制。
每条记录会多两个字段
- 事物id(trx_id)
- 回滚指针(roll_pointer)
通过对比trx_id在[m_up_limit_id , m_low_limit_id] 区间的左边、中间还是右边,用来决定记录是否可见
-
快照读
当事务读取数据时,会根据当前事务 ID 来获取快找数据,即事务只能看到在它开始前已提交的数据,不能看到在它之后开始的事务数据
-
Read-view
class Readview (
bool changes_visible(trx id_t id, const table_name_t& name) const MY_ATTRIBUTE((warn_unused result))
{...}
//元组的可见性判断。重要函数,详细内容参见12.2节
trx_id_t m_low_limit_id;
//一个快照,有左右边界,左边界是最小值,右边界是最大值。此变量是右边界
trx_id_t m_up_limit_id;
//左边界,小于此值,表示发生得更早
trx_id_t m_creator_trx_id;
// 当前创建事务的事务id
ids_t m_ids;
//快照创建时,处于活动尚未完成的读写事务的集合
}
-
m_up_limit_id
快照左边界,是创建快照时,未提交的最小事务 id, target_id < 左边界,都可见
-
m_low_limit_id
快照右边界,创建快照时,最大事务 ID+1, target_id > 有边界,不可见
-
m_creator_trx_id
当前事务 id
-
m_ids
创建快照时,活动的但未提交的事务 id 集合,这个集合用于可见性判断,特别在于 RC 隔离级别下,这个集合会根据新的事务开始或者现有事务结束而变化。
-
可见性规则
-
确认隔离级别
-
读未提交(Read Uncommitted):事务可以看到其他事务未提交的更改。
-
读提交(Read Committed):事务只能看到其他事务已提交的更改。
-
可重复读(Repeatable Read):事务看到的是它开始时数据库的快照,不会看到其他事务在其执行期间所做的更改。
-
可串行化(Serializable):尝试强制事务序列化执行。
-
流程
-
如果是 RU,可见
因为有了事务,说明事务开始了,就可以读未提交
-
target_id < min_id 可见
可见,在事务之前发生且提交
-
target_id在活跃列表中 不可见
不可见
-
max < target_id 不可见
不可见,在事务之后发生
-
min < target_id < max 可见
说明已经提交了
参考
cloud.tencent.com/developer/a…
《数据库事务处理的艺术:事务管理与并发控制》