mysql并发控制——数据多版本
2018-08-21 17:27
260 查看
内容提取自 58沈剑公众号:架构师之路
1、共享锁和排他锁
因为普通锁不能并发,所以出现了共享和排它锁
共享锁(Share Locks,记为S锁),读取数据时加S锁
排他锁(exclusive Locks)修改数据时加X锁
兼容互斥表
S X
S 兼容 互斥
X 互斥 互斥
这种情况下,如果写数据的任务没有完成,数据不能被任务读取的。这回阻塞读取任务。
画外音:对应到数据库,可以理解为,写事务没有提交,读取相关数据的select会被阻塞
2、数据多版本
核心原理:
1)写任务发生时,将数据克隆一份,以版本号区分
2)写任务操作新克隆的数据,直至提交;(提交时覆盖原来版本?提交方式有待思考)
3)并发读任务可以继续读取旧版本的数据,不至于阻塞
3、redo,undo,回滚段
在进一步介绍InnoDB如何使用“读取旧版本数据”极大提高任务的并发度之前,有必要先介绍下redo日志,undo日志,回滚段(rollback segment)。
为什么要有redo日志?
数据库事务提交后,必须将更新后的数据刷到磁盘上,以保证ACID特性。磁盘随机写性能较低,如果每次都刷盘,会极大影响数据库的吞吐量。
优化方式是,将修改行为先写到redo日志里(此时变成了顺序写),再定期将数据刷到磁盘上,这样能极大提高性能。
画外音:这里的架构设计方法是,随机写优化为顺序写,思路更重要。
假如某一时刻,数据库崩溃,还没来得及刷盘的数据,在数据库重启后,会重做redo日志里的内容,以保证已提交事务对数据产生的影响都刷到磁盘上。
一句话,redo日志用于保障,已提交事务的ACID特性。
为什么要有undo日志?
数据库事务未提交时,会将事务修改数据的镜像(即修改前的旧版本)存放到undo日志里,当事务回滚时,或者数据库奔溃时,可以利用undo日志,即旧版本数据,撤销未提交事务对数据库产生的影响。
画外音:更细节的,
对于insert操作,undo日志记录新数据的PK(ROW_ID),回滚时直接删除;
对于delete/update操作,undo日志记录旧数据row,回滚时直接恢复;
他们分别存放在不同的buffer里。
一句话,undo日志用于保障,未提交事务不会对数据库的ACID特性产生影响。
什么是回滚段?
存储undo日志的地方,是回滚段。
如果事务未提交,修改数据的记录就可以在回滚段中的undo日志中找回原来的记录,如果rollback则可以保证数据正确,数据提交之后回滚段的日志可以删除
核心问题:
旧版本的数据存储在哪里-----------------回滚段里面
存储旧版本数据,对MySQL 和InnoDB原有的架构是否有巨大冲击?----冲击不大
InnoDB的内核,会对所有row数据增加三个内部属性:
(1)DB_TRX_ID,6字节,记录每一行最近一次修改它的事务ID;
(2)DB_ROLL_PTR,7字节,记录指向回滚段undo日志的指针;
(3)DB_ROW_ID,6字节,单调递增的行ID;
InnoDB为何能够做到这么高的并发?
回滚段里的数据,其实是历史数据的快照(snapshot),这些数据是不会被修改,select可以肆无忌惮的并发读取他们。
快照读(Snapshot Read),这种一致性不加锁的读(Consistent Nonlocking Read),就是InnoDB并发如此之高的核心原因之一。
这里的一致性是指,事务读取到的数据,要么是事务开始前就已经存在的数据(当然,是其他已提交事务产生的),要么是事务自身插入或者修改的数据。
什么样的select是快照读?
除非显示加锁,普通的select语句都是快照读,例如:
select * from t where id>2;
这里的显示加锁,非快照读是指:
select * from t where id>2 lock in share mode;
select * from t where id>2 for update;
问题来了,这些显示加锁的读,是什么读?会加什么锁?和事务的隔离级别又有什么关系?
本节的内容已经够多了,且听下回分解。
总结
(1)常见并发控制保证数据一致性的方法有锁,数据多版本;
(2)普通锁串行,读写锁读读并行,数据多版本读写并行;
(3)redo日志保证已提交事务的ACID特性,设计思路是,通过顺序写替代随机写,提高并发;
(4)undo日志用来回滚未提交的事务,它存储在回滚段里;
(5)InnoDB是基于MVCC的存储引擎,它利用了存储在回滚段里的undo日志,即数据的旧版本,提高并发;
(6)InnoDB之所以并发高,快照读不加锁;
(7)InnoDB所有普通select都是快照读;
画外音:本文的知识点均基于MySQL5.6。
1、共享锁和排他锁
因为普通锁不能并发,所以出现了共享和排它锁
共享锁(Share Locks,记为S锁),读取数据时加S锁
排他锁(exclusive Locks)修改数据时加X锁
兼容互斥表
S X
S 兼容 互斥
X 互斥 互斥
这种情况下,如果写数据的任务没有完成,数据不能被任务读取的。这回阻塞读取任务。
画外音:对应到数据库,可以理解为,写事务没有提交,读取相关数据的select会被阻塞
2、数据多版本
核心原理:
1)写任务发生时,将数据克隆一份,以版本号区分
2)写任务操作新克隆的数据,直至提交;(提交时覆盖原来版本?提交方式有待思考)
3)并发读任务可以继续读取旧版本的数据,不至于阻塞
3、redo,undo,回滚段
在进一步介绍InnoDB如何使用“读取旧版本数据”极大提高任务的并发度之前,有必要先介绍下redo日志,undo日志,回滚段(rollback segment)。
为什么要有redo日志?
数据库事务提交后,必须将更新后的数据刷到磁盘上,以保证ACID特性。磁盘随机写性能较低,如果每次都刷盘,会极大影响数据库的吞吐量。
优化方式是,将修改行为先写到redo日志里(此时变成了顺序写),再定期将数据刷到磁盘上,这样能极大提高性能。
画外音:这里的架构设计方法是,随机写优化为顺序写,思路更重要。
假如某一时刻,数据库崩溃,还没来得及刷盘的数据,在数据库重启后,会重做redo日志里的内容,以保证已提交事务对数据产生的影响都刷到磁盘上。
一句话,redo日志用于保障,已提交事务的ACID特性。
为什么要有undo日志?
数据库事务未提交时,会将事务修改数据的镜像(即修改前的旧版本)存放到undo日志里,当事务回滚时,或者数据库奔溃时,可以利用undo日志,即旧版本数据,撤销未提交事务对数据库产生的影响。
画外音:更细节的,
对于insert操作,undo日志记录新数据的PK(ROW_ID),回滚时直接删除;
对于delete/update操作,undo日志记录旧数据row,回滚时直接恢复;
他们分别存放在不同的buffer里。
一句话,undo日志用于保障,未提交事务不会对数据库的ACID特性产生影响。
什么是回滚段?
存储undo日志的地方,是回滚段。
如果事务未提交,修改数据的记录就可以在回滚段中的undo日志中找回原来的记录,如果rollback则可以保证数据正确,数据提交之后回滚段的日志可以删除
核心问题:
旧版本的数据存储在哪里-----------------回滚段里面
存储旧版本数据,对MySQL 和InnoDB原有的架构是否有巨大冲击?----冲击不大
InnoDB的内核,会对所有row数据增加三个内部属性:
(1)DB_TRX_ID,6字节,记录每一行最近一次修改它的事务ID;
(2)DB_ROLL_PTR,7字节,记录指向回滚段undo日志的指针;
(3)DB_ROW_ID,6字节,单调递增的行ID;
InnoDB为何能够做到这么高的并发?
回滚段里的数据,其实是历史数据的快照(snapshot),这些数据是不会被修改,select可以肆无忌惮的并发读取他们。
快照读(Snapshot Read),这种一致性不加锁的读(Consistent Nonlocking Read),就是InnoDB并发如此之高的核心原因之一。
这里的一致性是指,事务读取到的数据,要么是事务开始前就已经存在的数据(当然,是其他已提交事务产生的),要么是事务自身插入或者修改的数据。
什么样的select是快照读?
除非显示加锁,普通的select语句都是快照读,例如:
select * from t where id>2;
这里的显示加锁,非快照读是指:
select * from t where id>2 lock in share mode;
select * from t where id>2 for update;
问题来了,这些显示加锁的读,是什么读?会加什么锁?和事务的隔离级别又有什么关系?
本节的内容已经够多了,且听下回分解。
总结
(1)常见并发控制保证数据一致性的方法有锁,数据多版本;
(2)普通锁串行,读写锁读读并行,数据多版本读写并行;
(3)redo日志保证已提交事务的ACID特性,设计思路是,通过顺序写替代随机写,提高并发;
(4)undo日志用来回滚未提交的事务,它存储在回滚段里;
(5)InnoDB是基于MVCC的存储引擎,它利用了存储在回滚段里的undo日志,即数据的旧版本,提高并发;
(6)InnoDB之所以并发高,快照读不加锁;
(7)InnoDB所有普通select都是快照读;
画外音:本文的知识点均基于MySQL5.6。
相关文章推荐
- MySQL 多版本并发控制(MVCC)
- mysql的mvcc(多版本并发控制)
- 深度解析MySQL—InnoDB多版本并发控制(MVCC)
- 大数据技术-HBase:HBase并发版本控制MVCC
- MySQL多版本并发控制分析
- MySQL多版本并发控制分析
- 《高性能MySQL》读书笔记之 MySQL锁、事务、多版本并发控制的基础知识
- mysql的mvcc(多版本并发控制)
- MySQL多版本并发控制分析
- 高性能MySQL -MySQL架构,MVCC多版本并发控制和一些基本概念
- mysql-innoDB-多版本并发控制(MVCC)
- mysql的mvcc(多版本并发控制)
- mysql的mvcc(多版本并发控制)
- 第三十一天 MySQL并发控制、存储引擎介绍、用户权限管理、缓存管理和数据类型选择
- MySQL 架构 - MVCC多版本并发控制
- mysql的mvcc(多版本并发控制)
- 【MySQL】MVCC(多版本并发控制)
- 【MySQL】多版本并发控制
- mysql的mvcc(多版本并发控制)
- MySQL的多版本并发控制