MySQL 体系结构和存储引擎 – [笔记]
MySQL 官方手册:https://dev.mysql.com/doc/
定义数据库和实例
- 数据库
- 物理操作系统文件或其他形式文件类型的集合。数据库文件可以是 frm、MYD、MYI、ibd 结尾的文件。
- 实例
- 数据库实例才是真正用于操作数据库文件的。
MySQL 被设计为一个单进程多线程架构的数据库,MySQL 数据库实例在系统上的表现就是一个进程
MySQL 体系结构
- MySQL 体系结构图(摘自官方手册)
- 体系结构组成
- 连接池组件
- 管理服务和工具组件
- SQL 接口组件
- 查询分析器组件
- 优化器组件
- 缓冲组件
- 插件式存储引擎(特点)
- 物理文件
存储引擎是基于表的,而非数据库
MySQL 存储引擎
- InnoDB
- https://dev.mysql.com/doc/refman/5.6/en/innodb-storage-engine.html
- 面向 OLTP(面向在线事务处理) 应用
- 行锁设计、支持事务、外键
- 支持非锁定读,即默认读取操作不会产生锁
- 通过 MVCC(多版本并发控制)提高并发性
- 使用 next-key-locking 避免幻读
- 表存放于独立的 ibd 文件中
- 提供插入缓冲、二次写、自适应哈希索引、预读等高性能和高可用功能
- MyISAM
- 不支持事务、表锁设计。支持全文索引
- 缓冲池只缓存索引文件,不缓冲数据文件(由操作系统本身来完成)
- MYD 用来存放数据文件,MYI 用来存放索引文件
- Memory
- 表数据存放于内存
- 默认哈希索引
- 只支持表锁,并发性较差
- Federated
- 不存放数据,指向一台远程 MySQL 数据库服务器上的表
- 各存储引擎特性比较
连接 MySQL
- 本质是进程通信,常用的有管道、命名管道、命名字、TCP/IP套接字、UNIX域套接字
后台线程
- InnoDB 是多线程模型
- Master Thread
- 核心后台线程,主要负责将缓冲池中的数据异步刷新到磁盘,保证数据一致性,包括脏页的刷新、合并插入缓冲、undo页回收等
- IO Thread
- InnoDB 中大量使用 AIO(Async IO) 处理 IO 请求。可以通过
show engine innodb status
观察 IO Thread
- InnoDB 中大量使用 AIO(Async IO) 处理 IO 请求。可以通过
- Purge Thread
- 事务被提交之后,其所使用的 undolog 可能不再需要,回收已经使用并分配的 undo 页
- Page Cleaner Thread
- 脏页刷新放到单独的线程
- Master Thread
内存
- 缓冲池
- InnoDB 是基于磁盘存储的,并将其中的记录按照页的方式进行管理
- 基于磁盘的数据库系统通常使用缓冲池来提高整体性能(由于CPU与磁盘之间的速度鸿沟)。缓冲池就是一块内存区域,通过内存的速度弥补磁盘速度对数据库性能的影响。
- 在数据库进行读页操作,首先将磁盘的页存放到缓冲池中,这个过程称为将页
FIX
到缓冲池中。写一次再读相同的页时,首先判断页是否在缓冲池中,如果存在,直接命中该页,并读取。否则,读取磁盘上的页。- 使用
show engine innodb stauts
查看 buffer pool and memory 中的 buffer pool hit rate 显示的缓冲池命中率
- 使用
- 对于数据库中页的修改操作,首先修改缓冲池中的页,再以一定频率刷新到磁盘上(通过Checkpoint机制)。
- 缓冲池中缓存的数据页类型有:索引页、数据页、undo 页、插入缓冲、自适应哈希索引、锁信息、数据字典等
- InnoDB 内存数据对象
-
允许多个缓冲池实例,减少内部资源竞争,增加数据库并发能力。可以通过
innodb_buffer_pool_instances
进行配置 - 可以通过 information_schema 架构下的表 innodb_buffer_pool_stats 观察缓冲状态
select pool_id,pool_size,free_buffers,database_pages from innodb_buffer_pool_stats
show engine innodb stauts
显示的不是当前的状态,而是过去某时间范围内innodb引擎的状态(Per Second averages...)
- LRU List、Free List、Flush List
- 通常来说,数据库中的缓冲池是通过 LRU(Lastest Rencent Used,最近最少使用)算法进行管理的。即最频繁使用的页在 LRU 列表的前端,最少使用的页在 LRU 列表的尾端,当缓冲池不能存放新读取到的页时,首先释放 LRU 列表中尾端的页。
- InnoDB 对传统的 LRU 算法做了一些优化。增加了Midpoint。
- LRU 列表用来管理已经读取的页,但当数据库刚启动时,LRU 列表是空的,即没有任何的页。
- 当页从 LRU 列表的 Old 部分加入到 New 部分,此时发生的操作为 page made young
当 LRU 列表中的页被修改之后,该页成为脏页,即缓冲池的页和磁盘上的页的数据产生了不一致。这时数据库会通过 CheckPoint 机制将脏页刷新回磁盘。
- 通常来说,数据库中的缓冲池是通过 LRU(Lastest Rencent Used,最近最少使用)算法进行管理的。即最频繁使用的页在 LRU 列表的前端,最少使用的页在 LRU 列表的尾端,当缓冲池不能存放新读取到的页时,首先释放 LRU 列表中尾端的页。
- 重做日志缓存
- InnoDB引擎的的内存区除了有缓冲池外,还有重做日志缓存(看上面的内存数据对象图)。InnoDB 引擎首先将重做日志信息先放入到这个缓冲区,然后再一定频率刷新到重做日志文件。
CheckPoin 技术
持续更新