redo log和undo log、事务
redo log
如果系统突然崩溃,一些在缓存中的修改还没来的及同步到磁盘中,用redo log就可以恢复这些修改,Redo log就是记录这些修改的日志。这些对页面的修改有一些是原子操作,比如有些插入伴随着页面分裂和页的新建(悲观插入),此时这些分裂和修改必须一气呵成,这样的操作叫mini-transition,一条语句可能包含多个mini-transition,而一个又包含多个redo日志,这种原子性用一个特殊位来标记,在恢复时读到标志位才恢复之前的内容,否则放弃之前的日志。每次的redo日志也是存到buffer pool中,选择合适的时机刷新到磁盘,可以选择事务提交时同步到磁盘或写入缓存。
(LSN:记录的一个字段,一个redo日志对应的编号,一个页的LSN越大说明刚刚修改过)
undo log
为了事务回滚而记录的日志信息,undo日志有几种类型,插入数据、删除数据、更新数据都会产生不同的undo log,记录有一个roll_pointer的指针指向它的undo log,所有关于这条记录的undo log都连成一条链表,称为版本链,根据undo log的事务ID来判断是哪个事务中修改了该记录,事务回滚时找到对应事务ID的undo log恢复数据除此之外,undo log还可以用来维护MVCC(多版本并发控制)。
(mysql删除时实际上分两步,第一步是标记删除,如果事务提交再将其放入垃圾链表中)
事务
事务的隐式提交:一些DDL语言(create、drop、alter)、使用表的语句(带table的)、开启另一个事务等。。。
创建保存点:savepoint 保存点名
回滚到保存点:rollback to 保存点名
事务的使用:start transaction、commit、rollback
隔离级别的实现
Read uncommitted的实现:每次读时都读最新的那个版本,并发问题最严重
Read committed的实现:避免脏写,在每次读取数据时都生成一个readview,readview其中存有创建当前结构的事务ID,活跃事务ID,然后从记录开始读每个undo log,如果某个undo log刚好是事务的创建ID或不在readview的活跃事务列表中就可以读,这样就避免了脏读。
Repeatable read的实现:在事务第一次读的时候生成readview,然后读记录,这样就能保证读到的数据不可能不一样。
Serializable的实现:依赖mysql的锁
原文地址:https://www.cnblogs.com/shizhuoping/p/11562879.html