InnoDB存储引擎
逻辑存储结构
架构
- 内存结构
- Buff Pool
-
- Change Buffer
-
- Adaptive Hash Index
-
- Log Buffer
- 磁盘结构
- System Tablespace、File-Per-Table Tablespace
-
- General Tablespace、Undo TableSpace Temporary TableSpace
-
- Double Buffer Files、Redo log
- 后台线程
事务原理
- 持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
在整个系统发生崩溃、数据库进程直接被杀死后,当用户再次启动数据库进程时,通过重写日志将之前已完成的事务写入磁盘,从而保证持久性。
- 原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被恢复(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
在 MySQL 中,恢复机制是通过回滚日志(undo log)实现的,所有事务进行的修改都会先记录到这个回滚日志中,然后在对数据库中的对应行进行写入。 当事务已经被提交之后,就无法再次回滚了。已提交的事务记录到重写日志中。
- 一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏,从一个一致性状态到另一个一致性状态,修改必须完全符合所有的预设规则。
undo log和redo log共同实现,通过回滚日志将之前未完成的事务进行回滚,通过重写日志将之前已完成的事务写入磁盘
- 隔离性:数据库允许多个并发事务并发执行,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括未提交读(Read uncommitted)、提交读(read committed)、重复读(repeatable read)和可串行化(Serializable)。
锁 + MVCC实现
MVCC
- 基本概念
- 当前读
读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。对于我们日常的操作,如:select ... lock in share mode(共享锁),select ... for update、 update、insert、delete(排他锁)都是一种当前读。
-
- 快照读
简单的select(不加锁)就是快照读,读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读,通过undo log实现
Read Committed: 每次select,都生成一个快照读。
Repeatable Read: 开启事务后第一个select语句才是快照读的地方。因为要消除不可重复读,所以这样之后的每次select都是第一个相同select的快照读。
Serializable:快照读会退化为当前读。
-
- MVCC
全称 Multi-Version Concurreny ontrol,多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突,快照读为mysql实现MVCC提供了一个非阻塞读功能。MVCC的实现,还需要依赖于数据库记录中的三个隐式字段、undo log日志、readview。
- 隐藏字段
- undo log
回滚日志,在insert、update、delete的时候产生的便于数据回滚的日志。
当insert的时候,产生的undo log日志只在回滚时需要,在事务提交后,可被立即删除。
而update、delete的时候,产生的undo log日志不仅在回滚时需要,在快照读时也需要,不会立即被删除。
-
- undo log版本链
- readview
-
- 提交读隔离级别:当前事务中需要查询的sql语句将生成的快照读与undo log版本链中的数据进行对比,如果满足一定的条件,则返回满足条件的数据
事务5中第一个select返回db_trx_id为2的数据,第二个select返回db_trx_id为3的数据
-
- 重复读隔离级别:仅在第一次查询时生成快照读,之后复用,流程与上述相同