数据库
@(MySQL 笔记)[MySQL, InnoDB,数据库]
存储引擎
InnoDB 引擎与 MyISAM 引擎区别
- 在存储限制方面,MyISAM 没有存储限制,InnoDB 大概为 64TB
- 在事务支持方面,MyISAM 不支持,InnoDB 支持事务及四种隔离级别,默认为可重复写
- 在锁力度方面,MyISAM 支持表锁,InnoDB 支持表锁和行锁
- 在索引支持方面,MyISAM 支持 B+ 树索引与全文索引,InnoDB 支持 B+ 树索引及哈希索引
- 在 MVCC 支持方面,MyISAM 不支持 MVCC,InnoDB 支持
- 在缓存方面,MyISAM 只缓存数据,InnoDB 同时缓存索引与数据
- 在内存消耗方面,MyISAM 低,InnoDB 高
- 在外键方面,MyISAM 不支持,InnoDB 支持
InnoDB 引擎与 MyISAM 引擎相同点
- 都支持 B+ 树索引
- 都支持索引的缓存
- 都支持数据加密
- 都支持备份与恢复
- 都支持查询缓存
InnoDB 引擎体系架构
主要由后台线程,InnoDB存储引擎内存池和文件构成。
后台线程
包括 Master Thread,IO Thread,Purge Thread
1. Master Thread
主要负责将缓冲池中的数据异步刷新到磁盘,保证数据一致性。包括:
- 脏页刷新
- 合并插入缓冲(Insert Buffer)
- UNDO 页回收
2. IO Thread
主要使用 AIO 来实现 IO请求的回调
3. Purge Thread
事务提交后,undolog 不再需要,使用 Purge Thread 回收 undo 页
4. Purge Clean Thread
InnoDB 1.2.x 引入,将之前版本中的脏页刷新操作放入到单独线程中实现,减轻 Master Thread 负载
InnoDB存储引擎内存池
1. 缓冲池
一块内存,用于弥补磁盘速度较慢对数据库性能的影响
- 读操作时,首先从磁盘读入缓冲池,再从缓冲池读取页。下次读相同页时,直接从缓冲池中读取。
- 写操作时,先写入缓冲池中的页,在以一定频率写回到磁盘。Checkpoint 机制刷新回磁盘。
- 缓冲池中主要保存:索引页,数据页,undo 页,插入缓冲,自适应哈希索引,锁信息,数据字典信息
2. LRU List,Free List,Flush List
- 缓冲池通过 LRU(最近最少使用)算法进行管理,频繁使用的页在 LRU 列表前端。16KB。最新访问的页不是直接插入 LRU List 首部,而是先放在 midpoint 位置,大约是LRU List 长度的 5/8处。直接放在首部,某些 SQL 操作缓冲池中的页被刷新,影响效率。
- Free List:管理 Free Buffer
- Flush List:脏页列表。脏页即存在 LRU 中,也存在 Flush 中。LRU 用来管理页的可用性,Flush 管理将页刷新回磁盘,二者互不影响
3. 重做日志缓冲
重做日志先放入缓冲区,之后写入重做日志文件
4. 额外的缓冲池
对一些数据结构本身的内存分配时,先从额外的内存池申请,不够再从缓冲池中申请
InnoDB 存储引擎关键特性
- 插入缓冲
- 两次写
- 自适应哈希索引
- 异步 IO
- 刷新临近页
- 插入缓冲:内部实现为 B+ 树,保证非聚集索引插入的性能。InnoDB 插入行顺序按主键递增顺序,因此插入聚集索引一般是顺序的。但每个表有多个非聚集的辅助索引,插入不再是顺序的,访问时需要离散访问非聚集索引页。Insert Buffer 作用:
- 对于非聚集索引的插入与更新操作,不是每一次插入到索引页中,而是预判索引页是否在缓冲池中,若在则直接插入。
- 若不在,先放入一个 Insert Buffer 对象中,再以一定的频率或情况进行 Insert Buffer 和辅助索引页子节点的 merge 操作。
- 这样可以把多个插入合并到一个操作中,提高非聚集索引插入性能
- 两次写:保证数据页的可靠性。对缓冲池的脏页进行刷新时,不是直接写磁盘,而是通过 memcpy 函数将脏页复制到内存中的
doublewrite buffer中,之后通过doublewrite buffer再分两次,每次 1MB 的顺序写入共享表空间的物理磁盘上 - 自适应哈希索引:InnoDB 会监控各索引页的查询操作,若发现对这些索引页建立哈希索引可以加快查找,便建立哈希索引,这就是自适应哈希索引(AHI)。
- 异步 IO:InnoDB 中,read ahead 方式的读取时通过 AIO 完成的,脏页的刷新也是通过 AIO 完成的。
- 刷新临近页:当刷新一个临近页时,会检测改页所在的区是否由别的脏页,若有则放入一个 IO 操作刷新。