mysql之MVCC

MVCC

         Mysql中MVCC是在Innodb存储引擎中得到支持的,Innodb为每行记录都实现了三个隐藏字段:
         DB_TRX_ID:  6字节的事务ID, 用来标识该行所述的事务。

         DB_ROLL_PTR: 7字节的回滚指针。

         DB_ROW_ID:隐藏的ID,随着数据的增加而增加。

redo log

        redo log就是保存执行的SQL语句到一个指定的Log文件,当Mysql执行recovery时重新执行redo log记录的SQL操作即可。当执行每条SQL(更新语句)时,redo log会被首先写入redo buffer,redo buffe是一个环形缓冲;当执行COMMIT命令时,redo buffer中的内容会被视情况刷新到磁盘redo log。redo log在磁盘上作为一个独立的文件存在,即Innodb的log文件。

        每次操作都先记录到redo日志中,当出现实例故障(像断电),导致数据未能更新到数据文件,则数据库重启时须redo,重新把数据更新到数据文件。因为每次commit时,将数据的修改立即写到redo log中,但是并不一定同时将该数据的修改写到数据文件中。因为该数据已经提交,但是只存在联机日志文件中,所以在恢复时需要将数据从联机日志文件中找出来,重新应用一下,使已经更改数据在数据文件中也改过来。

undo log

         记录更改前的一份copy,当系统rollback时,把这份copy重新覆盖到原来的数据。与redo log相反,undo log是为回滚而用,具体内容就是copy事务前的数据库内容(行)到undo buffer,在适合的时间把undo buffer中的内容刷新到磁盘(如果采取日志立即刷入磁盘,那么数据的一致性得到保证,若不是则也会存在丢数据风险)。undo buffer与redo buffer一样,也是环形缓冲,当缓冲满的时候,undo buffer中的内容会也会被刷新到磁盘;与redo log不同的是,磁盘上不存在单独的undo log文件,所有的undo log均存放在主ibd数据文件中(表空间)。

       undo log 分为insert undo log  和 update undo log ,Insert undo logs只会在事务回滚的时候使用,事务一旦提交,就可以丢弃相应的undo logs。但是update undo logs还会在一致读操作中使用,只有当系统中所有现存的事务使用的快照版本不需要依赖update undo logs来构建数据行的历史版本时,才会进行物理删除。

        当使用delete操作时,并不会立即执行行物理删除。只有当该delete操作对应的update undo log可以被丢弃时,才会物理删除这一行。这个删除操作被称为purge。

segment

        回滚段这个概念来自Oracle的事物模型,在Innodb中,undo log被划分为多个段,具体某行的undo log就保存在某个段中,称为回滚段。可以认为undo log和回滚段是同一意思。

update的事务过程

1. 初始数据行

2:事务1更改该行的各字段的值

此时进行了如下操作: 

  • 用排他锁锁定该行
  • 记录redo log
  • 把该行修改前的值Copy到undo log,即上图中下面的行
  • 修改当前行的值,填写事务编号,使回滚指针指向undo log中的修改前的行

3:另一个事务修改该行的值

与事务1相同,此时undo log中有两行记录,并且通过回滚指针连在一起。

因此,如果undo log一直不删除,则会通过当前记录的回滚指针回溯到该行创建时的初始内容,所幸的是在Innodb中存在purge线程,它会查询那些比现在最老的活动事务还早的undo log,并删除它们,从而保证undo log文件不至于无限增长。

Insert 事务

       当insert时,原始的数据并不存在,所以回滚时把insert undo log丢弃即可,而update undo log则必须遵守上述过程。

MVCC优点

        与悲观锁相比,避免了大粒度和长时间的锁定,能更好地适应对读的响应速度和并发性要求高的场景。

MVCC缺点

         Innodb的实现真算不上MVCC,因为并没有实现核心的多版本共存,undo log中的内容只是串行化的结果,记录了多个事务的过程,不属于多版本共存。但理想的MVCC是难以实现的,当事务仅修改一行记录使用理想的MVCC模式是没有问题的,可以通过比较版本号进行回滚;但当事务影响到多行数据时,理想的MVCC据无能为力了。

 

 

 

相关链接:

 MySQL · 引擎特性 · InnoDB redo log漫游

理解数据库中的undo日志、redo日志、检查点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值