innodb事务的实现

1.redo
redo是innodb引擎对事务的记录,叫做重做日志,和redo相关的有redo log buffer 和 redo log file, 作用是对事务的持久化。

(1)redo log buffer 的刷新到磁盘是由同步策略参数(INNODB_FLUSH_LOG_AT_TRX_COMMIT) 决定
(2)redo log file是持久化的数据,是log buffer的镜像
(3)LSN 是 log sequence number记录的是执行事务要写入redo日志的字节数
innodb事务的实现_第1张图片
这里 log sequence number是刷入到redo log buffer中的总字节数
log flushed up to 是刷新到log file中的字节数
last checkpoint at 是语句已经执行成功的字节数
LSN记录的地方有:
(1)重写日志redo log file表示总量
(2)checkpoint点的位置
(3)重写日志页在写入的时候的LSN的值
因此恢复的时候,只需要找到checkpoint 的字节数对应的redo log file中的页节点的地方,然后往后一直执行,即可恢复。

另外,注意redo页是和mysql SQL层的二进制文件不同,二进制文件是逻辑语句,可用于主从复制,和引擎无关,而redo页是和引擎的事务有关,主要存储的是对表的
物理操作,而且执行速度特别快。

2. undo
undo在事务执行的时候,每一句都会加入一个与其相反的语句,因此undo页是逻辑语句,不像redo那样是物理语句,undo页在以下情景中会使用到:
(1)当前事务rollback
(2)当前事务1执行中,事务2也开始执行,事务1修改表中的X行结束后, 事务2开始查询这个X行,会使用到undo页。

undo是属于一个rollback segment,存储在共享表中,也可以通过设置全局参数来设置其存储地址。
INNODB_UNDO_DIRECTORY redo段的存储路径
INNODB_UNDO_LOGS rollback segment个数
INNODB_UNDO_TABLESPACES 把所有的redo段分配到该数量的文件中保存

3.purge
这个purge过程会在master主线程中或者某些特定条件下进行,收复一些无用的undo页。

4.MVCC
参考: http://www.cnblogs.com/chenpingzhao/p/5065316.html
MVCC的基本用意是多版本并发控制,即理想中是多并发无阻塞模型,innodb实现的MVCC并不是真正意义上的并发模型。
首先,先讲述innodb的读写如何实现的, 写是阻塞写,读为非阻塞共享读,只实现的非阻塞读。innodb是通过在行末尾加入3个字段
6字节的DATA_TRX_ID , 表示哪个事务修改
7字节的DATA_ROLL_PTR 指向当前记录项的rollback segment的undo log记录
6字节的DB_ROW_ID, 记录行的事务的开始修改时间或者删除时间
1字节的DELETE BIT, 用于标识该记录是否被删除
在共享读的时候,事务也会记录一个开始时间DB_ROW_ID,通过对比时间的顺序来计算得到事务开始的时候的行数据,从而达到共享读的效果。

然后,真正的MVCC是通过乐观锁,其实就是写的时候也不加锁,但是innodb这种在直接在行数据上修改的方式很难达到,其原因是很有可能多个事务对同行数据进行修改,因此在undo段恢复的时候,可能有些事务已经被别的数据给覆盖了。因此乐观锁的实现模型可以为事务都有自己的临时行数据修改的记录,原数据不修改,因此共享读没问题,当第一个事务提交后,其他事务发现其修改后,立即回滚,因此,虽然保证了MVCC,但是带来了两种问题:
(1)回滚次数可能会很多
(2)临时的数据可能会非常大
因此,带来的开销也特别大,所以innodb引擎并未使用乐观锁,达到MVCC的理想模型。

你可能感兴趣的:(mysql,乐观锁,并发,数据库)