InnoDB事务和MVCC实现

事务(ACID)定义:
  • Atomicity 一组sql要么全部都执行成功要么全部失败。比如A、B两人转账,扣款和增加同时成功或者失败。
  • Consistency 写入的结果和预设结果相同。比如转账前和转账后AB两人总额是不变的。
  • Isolation 事务对其他事务是不可见的,而且互不影响。
  • Durability 一旦提交,就算宕机也不会出现数据丢失的情况。
事务实现:
  • 依靠undo_log和redo_log实现,如果发生失败就回滚到undo_log,成功就提交redo_log。undo_log实现了事务的原子性,redo_log实现了事务的一致性和持久性。而事务的隔离性依靠加锁来实现。(挖坑,再写一篇事务隔离级别)

    undo_log记录的是事务执行前的数据

    redo_log记录的是事务执行后的数据

    数据库锁包括共享锁(S)和排他锁(X)

举个栗子:

A:1000元 B:1000元,两人转账时底层是如何操作的

1. undo记录A=1000元,set A=500元(在内存中进行),redo记录A=500元

2. undo记录B=1000元,set B=1500元(在内存中进行),redo记录B=1500元

3. 成功:刷新redo日志到数据库中,失败刷新undo日志到数据库

4. commit事务


多版本并发控制(MVCC)

因为数据中存在共享锁和排他锁,而二者是互斥的关系。在查询时会获得共享锁,修改时会获取排他锁,这按理来说会阻塞。但Mysql做了一个处理使得二者可以同时进行。

当进行修改时,生成了undo和redo日志,而并发读读的就是这个undo日志,所以读到的是修改前的数据。