InnoDB中事务隔离

 

事务的特性:ACID(Atomicity、Consistency、Isolation、Durability,即原子性、一致性、隔离性、持久性)

 

由于在数据库中多事务同时执行时,会有脏读、不可重复读、幻读的问题,为了处理这些问题,就有了隔离级别的概念。

 

我们熟知的4种隔离级别:读不提交、读提交、可重复读、串行化。

读未提交是指,一个事务还没提交时,它做的变更就能被别的事务看到。

读提交是指,一个事务提交之后,它做的变更才会被其他事务看到。

可重复读是指,一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。当然在可重复读隔离级别下,未提交变更对其他事务也是不可见的。

串行化,顾名思义是对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。

 

InnoDB存储引擎是遵守ACID的,特别在隔离性方面。

 

读提交和可重复读是解决方案,那又是如何实现的呢?

读提交:每一次操作都生成一个快照;

可重复读:每一个事物开始时生成一个快照,中间的操作不生成新的快照,但是会生成undo log(回滚日志)。

 

InnoDB中事务隔离

 

其中的U1、U2、U3就是回滚日志。比如,时间执行到V4版本后,transaction_id的事物select * from t 。根据可重复读原则,同一个事物中,查询同一条数据不会改变,即k = 10。实现方式是,先查到改行当前数据k = 22,通过U3回滚计算得到k = 11,再通过U2回滚计算得到k = 10.这样就实现了可重复读,实现方式一般称之为MVCC(多版本并发控制)。

 

该处有几点可以关注:

1.每个数据库对于锁的实现不一样,所以性能上差异很大,在InnoDb中,读提交和可重复读在性能差距不大。

2.从图中可以看出,undo log无处不在,并且不同事物会记录在同一张page中(节省空间),因此需要考虑undo log的清理。

 

undo log

事物需要回滚操作,这时需要undo log。

redo存放在重做日志文件中,与redo不同,undo存放在数据库内部的一个特殊段(segment)中,这个段称之为undo段(undo segment)。undo段位于共享表空间内。

用户通常对undo有这样的误解:undo用于将数据库物理地恢复到执行语句或事务之前的样子。

事实上,undo是逻辑日志,由于一页日志内会有多个事务同时操作,一个事务回滚,不能影响其他事务的正常工作。

undo log会产生redo log,这时因为undo也需要持久化的保护。

 

undo log的删除

insert undo log是指在insert操作中产生undo log。因为insert操作的记录,只对事务本身可见,对其他事务不可见(理解下处理幻读过程),故该undo log可以在事务提交后直接删除。

update undo log是指在update和delete操作中产生undo log。该undo log可能需要提供MVCC机制,因此不能在事务提交时就进行删除。提交时放入undo log链表,等待purge线程进行最后的删除。

 

purge

purge用于最终完成delete和update操作。

 

上一篇:Informed RRT* with improved converging rate by adopting wrapping procedure


下一篇:MySQL事务中的redo与undo