MySQL的MVCC和InnoDB的非一致性锁定读

MySQL并发事务导致的死锁中提到InnoDB存储引擎默认事务隔离级别为 Repeatable Read,在这种情况下,select 查询记录时,不会存在锁,除非显示的调用lock in share mode或者for update。本文来说一下为什么查询记录时不存在锁。

  • InnoDB事务回滚时,从哪里获取旧数据?

    事务具有4个特性:原子性、一致性、隔离性和持久性。
    事务的隔离性由锁实现,原子性、一致性和持久性通过数据库的redo logundo log来实现。redo log称为重做日志,用来保证事务的原子性和持久性,undo log用来保证事务的一致性。
    一致性是事务回滚时,数据还原为事务开始前的状态。 也就是说,undo log中存放的是历史数据集,历史数据集中的每行数据也叫做快照数据

  • InnoDB的一致性非锁定读

    InnoDB中,不加lock in share modefor update的查询,都叫做普通查询,即查询数据时,数据行没有锁。这种读取数据的方式称之为一致性非锁定读

    一致性非锁定读是指InnoDB存储引擎通过查询数据的历史数据作为查询的结果集,这里所说的历史数据即为undo log中的历史数据。这种方式读取数据的好处在于:如果读取的行正在执行updatedelete时,读取操作不会等待锁的释放,而是去读取一个快照数据,提高数据库的并发性。一行记录的历史数据可能有多个版本(例如:当前行可能多次执行update,每次执行都是一个版本),称之为数据的多版本并发控制(Multi Version Concurrency Control,MVCC),行数据的每个版本都称为一个快照数据
    InnoDDB存储引擎中,不同的事务隔离级别下,读取的方式不同,对快照数据的定义也不同。InnoDB中常用的事务隔离级别有Read CommittedRepeatable Read,它们都使用一致性非锁定读,但是它们对于快照数据的定义却不相同。

    select * from a ;
    +----+-----+
    | id | num |
    +----+-----+
    |  1 |  1  |
    +----+-----+
    

    Read Committed事务隔离级别下,对于快照数据,非一致性锁定读总是读取被锁定行的最新一份数据。例如:

    时间会话A会话B会话C
    1begin;
    2update a set num = 2 where id = 1;
    3begin;
    4commit;
    5select num from a where id = 1;返回2
    6begin;
    7update a set num = 3 where id = 1;
    8commit;
    9select num from a where id = 1;返回3
    10commit;

    InnoDB默认的Repeatable Read下,对于快照数据,非一致性锁定读总是读取一个事务开始时的行数据版本。例如:

    时间会话A会话B会话C
    1begin;
    2update a set num = 2 where id = 1;
    3begin;
    4commit;
    5select num from a where id = 1;返回1
    6begin;
    7update a set num = 3 where id = 1;
    8commit;
    9select num from a where id = 1;返回1
    10commit;
  • InnoDB的一致性锁定读

    一致性锁定读即每次读取行数据时,对数据行加锁。例如:显示的调用lock in share mode或者for update

     select * from a where id = 1 lock in share mode;
     select * from a where id = 1 for update;
    

总结

  1. 事务回滚时,旧数据是从事务的undo log中获取
  2. undo log中的数据集称为快照数据集
  3. InnoDB存储引擎中的查询不需要加锁,是因为使用的是一致性非锁定读,这也是为什么很多书使用锁查询数据时,调用lock in share modefor update来实现数据的锁定。
  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值