zoukankan      html  css  js  c++  java
  • Mysql之MVCC系列

    MySQL数据库的日志系统共有三种日志,具有不同的作用,承担着不同的角色,共同保障数据库的稳定。它们分别是redo log(重做日志,用于断电后数据的灾后恢复),bin log(归档日志,用于将数据恢复到之前任意时间节点的状态)以及undo log(用于事务提交前的数据回滚)。本文主要对MVCC及undo log进行详细的说明。

    • 概念

    MVCC的全称是 multi version concurrency control ,即多版本并发控制,通过undo log进行实现, 是innodb实现事务并发与回滚的重要功能。

    1.1我们首先需要明确undo log是什么?

    undo log不同于binlog和redo log,binlog采用的是逻辑记法,row模式记录的是行的内容,修改前后都有,记两条;statement模式记录的是sql语句。

    redo log采用的是逻辑+物理记法,专业术语称为physiological logging,即先记录innnodb需要修改的page页,在对page页里面内容采用逻辑记法,记录page里的哪一行被修改了。

    Undo log指的是在对表中的数据进行修改前,需要先把原数据写入undo log日志。对于insert而言,由于原来没有历史数据,所以只需要把该记录的主键ID记入undo log;update和delete则需要将历史数据记入undo log。

    Undo log更应该称为记录的备份数据,即在事务未提交之前的时间里的备份数据,一旦事务提交后,没有其它事务引用历史版本了,其对应的undo log也就可以删除了。Undo log的实现原理会在后面进行详述。

    1.2我们应该知道为什么需要undo log?

    因为若某事务对内存中的某条记录进行修改,其它事务使用该记录时,完全可以从磁盘中取得原始记录。首先是因为page刷盘的策略决定的,如表1-1所示。

    表1-1 page刷盘的四种策略

        未提交事务可以

    写入磁盘

    已提交事务

    必须立刻写入磁盘

    不需要日志

    Undo log

    Redo log

    Redo log+ Undo log

    由于innodb采用的是第四种策略,未提交的数据也可以刷入磁盘,你不能确定盘中的数据是否为脏数据。

    其次,就算能确定磁盘中的数据是否为脏数据,事务将记录读入内存会进行随机IO,影响IO的读取效率,采用undo log将历史数据先写内存,在异步刷入磁盘,都是顺序IO,因此提高了IO效率,redo log也是同理。

    • undo log实现原理

      innodb表中记录除了主键ID和列数据外,还有两个隐藏字段。一个叫做DB_TRX_ID,用于记录事务的ID;一个是DB_ROLL_PTR,记录上条记录在undo log中的地址。如下图所示:

      图2-1undo log原理图

      如图所示,数据库中的每条记录只要被事务修改,就会将原来的历史数据写入undo log中,因此多个事务是随机向undo log中并行写入的,每条记录都会形成一个版本链。而某一个事务在读取该行记录时是如何知道自己需要读取的版本的?这是通过readview来判断的,设定了判断规则得到事务需要获取的版本。

  • 相关阅读:
    jQuery碎语(1) 基础、选择要操作的元素、处理DOM元素
    C#位运算符的基本用法
    如何使用==操作符,Equals方法,ReferenceEquals方法,IEquatable接口比较2个对象
    C#实现ATM自动取款机
    如何使用C#关键字const,readonly,static
    用最简单的例子理解适配器模式(Adapter Pattern)
    前缀方式增1和后缀方式增1的区别
    抽象类可以有构造函数吗
    为什么使用抽象类,什么时候使用抽象类
    checked和unchecked的区别
  • 原文地址:https://www.cnblogs.com/1995stone/p/13458255.html
Copyright © 2011-2022 走看看