MySQL技术内幕-InnoDB存储引擎读书笔记
第1章 MySQL体系结构和存储引擎
1.1 定义数据库和实例
- 数据库:物理操作系统文件或其他形式文件类型的集合;
- 实例:MySQL数据库由后台线程以及一个共享内存区组成;在系统上的表现就是一个进程。
1.2 MySQL体系结构
- 数据库是由一个个文件组成,要对这些文件执行增删查改等数据库操作是不能通过简单的操作文件来更改数据库的内容,需要通过数据库实例来完成对数据库的操作。
- 存储引擎是基于表的,而不是数据库。
1.3 MySQL存储引擎
- MySQL数据库的核心在于存储引擎;
- InnoBD
- 支持事务、行锁设计、支持外检、非锁定读;
- 只要面向在线事务处理(OLTP)
- 后续详细介绍
- MyISAM
- 不支持事务、表锁设计
- 支持全文索引,只要面向 OLAP 数据库应用
- 缓冲池只缓冲索引文件,而不缓冲数据文件,数据文件的缓冲交给操作系统完成
- NDB
- 集群存储引擎
- 数据全放在内存中(MySQL5.1 开始非索引数据放磁盘),因此主键查找极快
- 添加NDB数据存储节点可以线性提高数据库性能,是高可用、高性能的集群系统
- Memory
- 将表中数据存放在内存中
- 适用于存储临时数据的临时表
- 默认使用哈希索引,而非 B+ 索引
- 只支持表锁,并发性能差,不支持 TEXT和BLOB列类型
- 浪费内存
- Archive
- 只支持 INSERT 和 SELECT
- 设计目标:提供高速的插入和压缩功能
- Federated
- 只支持 MySQL 数据库表,不支持异构数据库表
- Maria
- 设计目标:用来取代 MyISAM 从而成为 MySQL 的默认存储引擎。
- 支持缓存数据和索引文件,应用了行锁设计,提供 MVCC 功能,支持事务和非事务安全的选项,以及更好的 BLOB 字符类型的处理性能
- 问题?
- 为什么 MySQL 不支持全文索引?
- 答:支持,MyISAM、InnoDB都支持
- MySQL 数据库快是因为不支持事务?
- 答:MyISAM 不支持,但是 InnoDB 支持。“快”是相对于不同应用来说的,对于 ETL 这种操作,MyISAM 更有优势,但在 OLTP 环境中,InnoDB 效率更高;
1.4 连接 MySQL
- 连接 MySQL操作是一个连接进程和 MySQL 数据库实例进行通信;
- 从程序设计的角度来看,本质上是进程通信。
第2章 InnoDB存储引擎
2.1 概述
- 第一个完整支持 ACID 事务的 MySQL 存储引擎
- 特点:行锁设计、MVCC、支持外键,提供一致性非锁定读,同时被设计用来最有效地利用以及使用内存和 CPU。
2.3 InnoDB 体系架构
- 后台线程的主要作用是负责刷新内存池中的数据,保证缓冲池中的内存缓存的是最近的数据;
- 此外,将已修改的数据文件刷新到磁盘文件,同时保证在数据库发生异常的情况下 InnoDB 能恢复到正常运行状态。
2.3.1 后台线程
InnoDB 是多线程模型,顾后台有多个不同的后台线程;
- Master Thread
非常核心的后台线程,主要负责将缓冲池中的数据异步刷新到磁盘,保证数据一致性。包括脏页的刷新、合并插入缓冲。UNDO 页的回收。
- IO Thread
在 InnoDB 存储引擎中大量使用 AIO(Async IO)来处理写 IO 请求,这样可以极大提高数据库的性能。该线程主要负责这些 IO 请求的回调处理。
- Purge Thread
事务被提交后,其所使用的 undolog 可能不再需要,因此需要该线程来回收已经使用并分配的 undo 页。从 InnoDB 1.2 开始,支持多个 Purge Thread,为了进一步加快 undo 页的回收,由于该线程需要离散读取 undo 页,这样也能更进一步利用磁盘的随机读取性能。
mysql> show variables like 'innodb_purge_threads';
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| innodb_purge_threads | 4 |
+----------------------+-------+
1 row in set, 1 warning (0.21 sec)
- Page Cleaner Thread
在 InnoDB 1.2.x 版本引入。作用是将之前版本中脏页的刷新操作都放到单独的线程中完成。目的是为了减轻原 Master Thread 的工作及对于用户查询线程的阻塞,进一步提高 InnoDB 存储引擎的性能。
2.3.2 内存
- 缓冲池
InnoDB 基于磁盘存储,可看做基于磁盘的数据库系统。由于 CPU 与磁盘之间速度的鸿沟,基于磁盘的数据库系统通常采用缓冲池技术来提高数据库的整体性能。
缓冲池简单来说是一块内存区域,通过内存的速度来弥补磁盘速度较慢对数据库性能的影响。
对于数据库中页的修改操作,首先修改在缓冲池中的页,然后再以一定的频率刷新到磁盘上。
- LRU List、Free List 和 Flush List
数据库中的缓冲池是通过 **LRU(Least Recently Used 最近最少使用算法)**进行管理。即最频繁使用的页在 LRU 列表的前端,最少使用的在尾端。当缓冲池不能存放新读取到的页时,首先释放 LRU 列表尾部的页。
InnoDB 对 LRU 进行改进,引入 midpoint 位置,将新读取到的页放入这个位置,该位置之前为 new 列表,之后为 old 列表。还引入 innodb_old_blocks_time 用于表示页读取到 mid 位置后需要等待多久时间才会被加入到 LRU 的热端,可以避免 LRU 列表中的热点数据被刷出。
- 重做日志缓冲
重做日志缓冲刷新到外部磁盘的重做日志文件
- Master Thread 每一秒将缓冲刷新到日志;