1. mysql引擎分类及区别
- innodb
从mysql5.5开始innodb作为mysql的默认存储引擎,实现了四个隔离级别(读已提交,读未提交,可重复读,可串行化),默认是可重复读,并且用
MVCC(多版本并发控制)和间隙锁来防止幻影读。 - myisam
5.5之前都是myisam作为默认引擎,设计简单,在简单表的效率上要比innodb高,但是不支持事务,也不支持行锁,支持的是表锁,读取时会对需要读到的所有表
加共享锁,写入时则对表加排它锁。 - 区别
Innodb支持事务,
行级锁,外键,而myisam不支持事务也不支持行级锁,支持的是表级锁,但是myisam相对简单,小型应用可以使用myisam。2. 什么是事务
事务就是满足A(原子性) C(一致性) I(隔离性) D(持久性)的一组操作
原子性:要么全部执行,要么全部不执行
一致性:事务执行前后保持一致性状态,所有事务读取数据一样
隔离性:事务未提交,别的事务不可见
持久性:事务提交以后,修改会保存到数据库
## 3. 事务隔离级别 - 读未提交 事务可以看到其他事务修改了而未提交的数据 造成的结果就是脏读
- 读已提交 事务只能看到其他事务提交之后的数据 造成结果就是不可重复读
- 可重复读 在一个事务中多次读取到的数据是一样的 可能造成幻影读MySQL默认的隔离级别就是可重复读
- 可串行化 事务串行执行
4. 脏读,幻读,不可重复读,丢失修改
在并发环境下,事务的隔离性很难保证,可能会出现并发一致性问题
丢失修改,两个事务同时进行,一个事务先修改一个数据,另一个事务后修改这个数据,前一个事务的修改被覆盖了。
脏读,T1先修改,再撤销,T2在这两个操作之间读数据,读的就是脏数据
不可重复读,T2先读一个数据,然后T1修改了这个数据,T2再读这个数据,前后两次读的数据不一样
幻读,T1读取某个范围的数据,T2在这个范围中插入了一条数据,T1再次读取这个范围的数据,读取的数据和第一次并不一样5. 排它锁和共享锁
一个事务对数据对象A加了排它锁,其他事务不能对A加任何锁
一个事务对数据对象A加了共享锁,其他事务可以读A,给A加共享锁,但是不能给A加排它锁6. MVCC多版本并发控制
MVCC是Mysql用来实现可重复读和已提交读的一种手段。未提交读总是读取最新的行,可串行化需要对所有用到的行加锁,所以这两种并不需要MVCC。 - 版本号
系统版本号 一个递增的数字 每开始一个新的事务,系统版本号就会递增
事务版本号 事务开始的系统版本号 - 隐藏的列
在每行数据后面都有两个隐藏的列
创建版本号:一个数据行快照创建时的系统版本号
删除版本号:如果删除版本号大于当前的事务版本号则快照有效,否则该快照已经被删除
mysql通过undo日志保存快照,该日志通过回滚指针把一个数据行(Record)的所有快照连接起来。
一个事务开始时的版本号要大于所有数据行的版本号,Select
事务T读取的数据快照的创建版本号必须是小于等于T的版本号,如果大于等于T,就说明是其他事务修改过的,不能读取
删除版本号一定是大于等于T的版本号,如果小于等于T就说明已经被删除insert
插入数据的创建版本号就是当前的系统版本号delete
删除版本号为当前系统版本号update
将当前系统版本号作为更新前的数据行快照的删除版本号,并将当前系统版本号作为更新后的数据行快照的创建版本号。
可以理解为先执行 DELETE 后执行 INSERT。
间隙锁+mvcc实现可重复读Record Locks
锁定一个记录上的索引,而不是记录本身。
如果表没有设置索引,InnoDB 会自动在主键上创建隐藏的聚簇索引,因此 Record Locks 依然可以使用。Gap Locks
锁定索引之间的间隙,但是不包含索引本身。例如当一个事务执行以下语句,其它事务就不能在 t.c 中插入 15。
SELECT c FROM t WHERE c BETWEEN 10 and 20 FOR UPDATE;Next-Key Locks
Next-Key Locks 是 MySQL 的 InnoDB 存储引擎的一种锁实现。
MVCC 不能解决幻影读问题,Next-Key Locks 就是为了解决这个问题而存在的。在可重复读(REPEATABLE READ)隔离级别下,使用 MVCC + Next-Key Locks 可以解决幻读问题。
它是 Record Locks 和 Gap Locks 的结合,不仅锁定一个记录上的索引,也锁定索引之间的间隙。例如一个索引包含以下值:10, 11, 13, and 20,那么就需要锁定以下区间:
(-∞, 10]
(10, 11]
(11, 13]
(13, 20]
(20, +∞)
本文只是是看了CYC大佬的博客,自己做的一波总结,并不是原创
CS-NOTES连接:cs-notes