面试二十四、mysql之mvcc
1、mvcc:(multi-version concurrency control)多版本并发控制
主要为了提高数据库并发性能
2、同一行数据在读写请求时会上锁阻塞住,mvcc实现了不需要加锁
解决读写冲突的请求。
注:这个读指的是快照读而不是当前读,当前读是一种加锁操作(悲观锁)
3、当前读:读取的数据记录都是当前最新版本,会对当前读取的行加锁防止事务修改。
如下操作都是当前读:
1)select * from db for update;
2)update
3)insert
4)delete
4、快照读:基于mvcc实现,读到的数据记录有可能是历史版本。
如:不加锁的select
5、数据库并发场景
读-读:不需要并发控制
读-写:有线程安全问题,可能造成事务隔离性问题(脏读、不可重复读、幻读)
写-写:有线程安全问题,可能丢失更新记录
6、mvcc解决的问题
1)解决了读操作不阻塞写操作,写操作不阻塞读操作
2)解决了脏读、不可重复读、幻读的事务隔离性问题
7、mvcc原理
通过版本链、undo日志、read view实现。mvcc会给每个事物分配一个单向
增长的时间戳,每次数据修改都会记录一个版本,版本和时间戳关联。
数据库隐藏字段:
1)db_trx_id:最近修改此行数据事务id
2)db_roll_pointer:回滚指针,指向上一个版本
3)row_id:隐藏自增主键ID
undolog:记录数据被修改过之前的旧数据,在表信息被修改前会将之前的数据拷贝进入undolog里,
当事务回滚时可通过undolog数据还原
1)结构:roll_pointer指针同样指向上个版本记录
2)用途:
保证事务进行回滚时的一致性和原子性,可通过undolog数据还原
用于mvcc快照读的数据,通过undolog的历史版本数据可实现不同事务拥有自己的独立快照数据版本
3)两种undolog
insert undo log:insert时产生,只在事务回滚时需要,事务提交后丢弃
update undo log:update时产生,事务回滚和快照读时都需要
read view:在事务进行快照读时,会给当前数据系统生成一个快照版本
1)属性
trx_ids:记录当前系统活跃事务版本号集合
low_limit_id:记录创建该读视图时最大的事务版本号+1
up_limit_id:记录创建读视图时活跃事务中最小的版本号
creator_trx_id:记录创建读视图的事务版本号
2)可见性判断
db_trx_id<up_limit_id || db_trx_id=creator_trx_id(可见)
当前行数据记录的事务id小于创建读试图时的最小活跃事务id,即数据是在事务前就存在的
当前行数据记录的事务id等于创建读视图的事务id,说明数据是自己修改的
db_trx_id>=low_limit_id(不可见)
当前行数据记录的事务id大于场景读视图时最大事务id,即数据是在事务后产生的
db_trx_id是否在trx_ids中:
不存在,说明事务已提交(可见)
存在,说明我生成read view时,修改数据的事务未提交(不可见)
rc和rr级别下快照读的区别:
1)rc:每次快照读都会生成新的read view,所以会看到别的事务新提交的数据
2)rr:只有在第一次快照读时会生成新的read view,并且记录下当时活跃的事务id列表,
同一个事务在下一次快照读时直接读取之前生成的read view,所以看不到别的
事务新提交的数据。
posted on 2021-09-02 10:47 Iversonstear 阅读(515) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!