mvcc机制

我们知道,mysql的innodb采用的是行锁,而且采用了多版本并发控制来提高读操作的性能。

什么是多版本并发控制呢 ?其实就是在每一行记录的后面增加两个隐藏列,记录创建版本号和删除版本号,

而每一个事务在启动的时候,都有一个唯一的递增的版本号。 

1、在插入操作时 : 记录的创建版本号就是事务版本号。 

比如我插入一条记录, 事务id 假设是1 ,那么记录如下:也就是说,创建版本号就是事务版本号。

idnamecreate versiondelete version
1test1 

2、在更新操作的时候,采用的是先标记旧的那行记录为已删除,并且删除版本号是事务版本号,然后插入一行新的记录的方式。 

比如,针对上面那行记录,事务Id为2 要把name字段更新

update table set name= 'new_value' where id=1;

idnamecreate versiondelete version
1test12
1new_value2 

 

3、删除操作的时候,就把事务版本号作为删除版本号。比如

delete from table where id=1; 

 

idnamecreate versiondelete version
1new_value23

 

 

4、查询操作: 

从上面的描述可以看到,在查询时要符合以下两个条件的记录才能被事务查询出来: 

1) 删除版本号 大于 当前事务版本号,就是说删除操作是在当前事务启动之后做的。 

2) 创建版本号 小于或者等于 当前事务版本号 ,就是说记录创建是在事务中(等于的情况)或者事务启动之前。

这样就保证了各个事务互不影响。从这里也可以体会到一种提高系统性能的思路,就是: 

通过版本号来减少锁的争用。

另外,只有read-committed和 repeatable-read 两种事务隔离级别才能使用mVcc

read-uncommited由于是读到未提交的,所以不存在版本的问题

而serializable 则会对所有读取的行加锁。 

### MVCC机制详解 #### 什么是MVCCMVCC(Multi-Version Concurrency Control),即多版本并发控制,是一种用于提高数据库系统并发性能的技术。它允许多个事务在同一时间访问不同的数据版本,从而减少锁的使用频率并提升系统的吞吐量[^1]。 #### MVCC的核心概念 为了支持多版本的数据管理,MVCC通常依赖以下几个核心组件: 1. **Undo Log** Undo log 是一种记录旧数据版本的日志文件。当某个事务修改了一条记录时,原数据会被保存到 undo log 中,而新数据则会覆盖原有的存储位置。这样可以确保即使当前事务未完成提交,其他事务仍然能够看到该记录的历史版本[^3]。 2. **Version Chain (版本链)** 每一条记录可能有多个历史版本,这些版本按照时间顺序链接成一个链条结构称为 version chain。最新版本指向其前驱节点直到最初的创建状态为止。通过这种方式维护了完整的变更轨迹以便不同事务可以根据各自需求获取合适的时间点视图[^4]。 3. **Read View (读取视图)** Read view 定义了一个特定时刻下的全局一致性快照。对于每一个正在运行中的只读操作来说,都需要基于此快照决定哪些数据是可以被安全地读取出来的。具体而言,read view 包含如下几个重要属性: - m_ids: 当生成 read view 的瞬间活跃的所有事务 ID 列表; - min_trx_id: 所有可能影响本次查询结果集最小编号; - max_trx_id: 下一次分配给新的写入型事务的最大编号; - creator_trx_id: 创建这个 read view 自身所属的那个事务 id 值; 根据上述参数组合起来判断某一行是否可见于当前上下文中。 #### 不同隔离级别的行为差异 - 在 `READ COMMITTED` 隔离级别下,每当另一个事务提交更改之后,本事务就会依据最新的数据库状况重建一个新的 read view 来反映外部变化情况。 - 而在 `REPEATABLE READ` 或更高严格程度上,则整个生命周期内只会固定采用最初建立好的那个单一不变版次作为参照标准直至结束为止。 #### 实现细节举例说明 以下是关于 MySQL InnoDB 存储引擎内部是如何利用以上提到的各种技术手段共同协作达成高效稳定目的的一个简化描述过程: 假设存在两条独立执行路径 A 和 B 各自尝试更新相同字段 X=5 -> Y=7 并最终都成功 commit 结束后... ##### 场景模拟: 初始状态下有一张简单的表格 T 如下所示: | Primary Key | Column Value | |-------------|--------------| | Pk | V | 此时如果发生以下事件序列将会触发相应动作: 1. Transaction-A 开始并将 column value 修改为 NewValueA; ```sql UPDATE table SET col=new_value WHERE pk=pk; ``` 2. System 将 OriginalRowData(PK,V) 记录至 UNDO_LOG 表格形成 VersionChainHeadNode; 3. Insert ModifiedDataRow Into TableSpace As CurrentVisibleRecord; 4. Commit Txn-A; Clear MarkedForDeletion Flag On OldVersions If Necessary. 5. Shortly Afterward, Another Concurrently Running Process Called Transaction-B Also Attempts To Perform Similar Operations But With Distinct Final Values Instead. 6. Repeat Steps Similar To Those Performed By First Actor Until Both Are Fully Completed Without Conflict Occurring Between Them Due Entirely Thanks To Mechanism Provided Above! ```python def mvcc_update(row_key, new_val): old_version = fetch_current_row(row_key) create_undo_log_entry(old_version) updated_record = { 'key': row_key, 'value': new_val, 'trx_id': get_active_transaction_id() } insert_into_table(updated_record) mark_old_versions_invisible_if_needed(row_key) ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值