hymn

忽有故人心头过,回首山河已是秋。

  menu
132 文章
0 浏览
2 当前访客
ღゝ◡╹)ノ❤️

MySQL innodb并发高原因

普通锁:太暴力,不允许其他的并发任务操作
共享锁(s锁):读取数据时加锁,读读可以并行,共享锁之间不互斥
排它锁(x锁):修改数据时加锁,读写,读读,不可以并行,排它锁与其他任何锁互斥。


普通锁:串行执行
读写锁:读读并行
数据多版本:读写并行(写数据时,clone一份数据,其他的读的线程读取旧数据)


ACID
原子性:Atomicity,事务执行要么成功,要么失败。
一致性:Consistency,a+b=10,如果一个事务改变了a,那么随之b也要改变。
独立性(隔离性):Isolation,事务不会出现交替执行的情况。
持久性:Durability,事务在执行完成后会保存在数据库中,不会无缘无故回滚。
MySQL redo日志和undo日志
redo日志:将修改行为先写到redo日志中,然后在一起写到磁盘中,将随机写改为顺序写,提高性能,
		  如果MySQL突然宕机,重启是会先写redo日志中的数据,避免数据丢失。
		  一句话,redo用于保证已提交事务的ACID	特性
undo日志:用于数据回滚,在执行事务时,将旧数据写到undo日志中,如果要回滚数据的话,会使用到undo中的数据,
		  对于insert操作,undo会记录主键id,回滚时直接删除主键id,
		  对于delete和update,undo记录行,回滚时直接回复。
		  一句话:undo用于保证未提交事务对数据	ACID 产生的影响。

undo日志和回滚段和InnoDB的MVCC密切相关
MVCC(Multi Version Concurrency Control):多版本并发控制。

回滚段:存储undo日志的地方
		当未执行事务时,回滚段为空,当执行事务前,回滚段记录执行事务的主键(insert)或者row(delete和update)
		当事务回滚时,从回滚段恢复数据,删除回滚段中对应数据。
MVCC: 通过读取旧版本数据来降低并发事务的冲突,提高并发度。
这些旧数据在回滚段中。

innodb对数据的row数据增加三个属性:
DB_TRX_ID:6字节,记录每一行最近修改他的事务id
DB_ROW_PRT:7字节,记录指向回滚段undo日志的指针,用于回滚时快速定位到undo日志的日志。
DB_ROW_ID:单调递增的行号。

innodb为什么可以做这么高的并发?
存储在回滚段中undo日志,其实就是历史数据的快照,这些数据不会被修改,select可以肆无忌惮的并发检索。
快照读:一致性不加锁的读,是innodb并发高的一个原因。

普通的select都是快照读,除服显示加锁,比如select id from t1 where id > 2 lock in share mode;
									   select id from t1 where id > 2 for update;

总结

(1)常见并发控制保证数据一致性的方法有锁,数据多版本;

(2)普通锁串行,读写锁读读并行,数据多版本读写并行;

(3)redo日志保证已提交事务的ACID特性,设计思路是,通过顺序写替代随机写,提高并发;

(4)undo日志用来回滚未提交的事务,它存储在回滚段里;

(5)InnoDB是基于MVCC的存储引擎,它利用了存储在回滚段里的undo日志,即数据的旧版本,提高并发;

(6)InnoDB之所以并发高,快照读不加锁;

(7)InnoDB所有普通select都是快照读;

参考


标题:MySQL innodb并发高原因
作者:hymn
地址:https://dxyhymn.com/articles/2020/06/24/1592993745169.html