MySQL事务篇
一、Insert语句的执行流程
undo log:数据的旧版本
记录undo_log的redo log:将undo log记录到redo log,防止需要回滚但服务器宕机导致的回滚失败。
二、事务
2.1 ACID特性
2.2 设置当前会话的隔离级别
//设置read uncommitted级别: set session transaction isolation level read uncommitted; //设置read committed级别: set session transaction isolation level read committed; //设置repeatable read级别: set session transaction isolation level repeatable read; //设置serializable级别: set session transaction isolation level serializable;
三、事务并发控制
不可重复读问题。
解决方案:
3.1 LBCC(Based Concurrency Control) 基于锁的并发控制
事务A开启并读取某行数据,准备在此基础上更新
mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> select * from user where id = 1 for update; +----+------+------+ | id | name | age | +----+------+------+ | 1 | a | 10 | +----+------+------+ 1 row in set (0.00 sec)
事务B同样操作,此时会阻塞,不会返回查询结果,直到超时或者事务A提交。
mysql> begin; mysql> select * from user where id = 1 for update;
3.2 MVCC(Multiversion concurrency control)多版本并发控制
3.3 InnoDB的MVCC
1.当前读和快照读
当前读:读取最新的数据,update、select ... for update、select ... lock in share mode 等
快照读:读取的是一份快照,select
2. 一致性非锁定读
如果快照读取的数据被其他事务锁定了(比如执行delete或update等操作),则根据undo log寻找最新的可读版本
3. 回滚段 undo log
回滚日志根据记录的操作类型分为两种,insert undo log和update undo log
insert操作产生新的数据,在当前事务提交前,只有当前事务可见。所以事务提交后,insert undo log可以直接删除。
update/delete操作的是旧数据,可能被其他事务使用,所以在修改事物提交后,update undo log不能立即删除,会放入undo log链表(新数据有一个回滚指针,指向undo log中备份的旧数据),等待purge线程删除。
undo log的落盘和脏页落盘一致,都使用checkpoint机制。
四、事务回滚和数据恢复
事务恢复:如果事务提交后服务器宕机,部分脏页没有及时落盘。服务器重启后,根据redo log file,将这部分数据落盘。
事务回滚:如果事务提交前服务器宕机,
倘若redo log buffer内容尚未写入redo log file,那么根据redo log file恢复,损坏的事务不会产生影响。
倘若redo log buffer内容已经写入redo log file,此时redo log file即包含了损坏的事务的修改操作,也包括了undo log对应的redo log。首先恢复事务对数据的修改,然后恢复undo log,查看undo log发现事务未提交,则使用undo log进行回滚。
关于undo log更详细的内容,请参考:https://blog.csdn.net/bohu83/article/details/81568341