MySQL 架构与实现
MySQL 是最流行的开源关系数据库,理解其架构有助于更好地使用和调优。MySQL 的独特之处在于插件式存储引擎架构,它将 SQL 解析、优化、执行与数据存储分离,使得不同的存储引擎可以共存。
整体架构
MySQL 采用分层架构,从上到下是连接层、服务层、引擎层、存储层。
连接层
连接层负责处理客户端连接,包括连接认证、线程管理、连接池。每个连接对应一个服务线程(或线程池中的线程)。MySQL 使用自定义的二进制协议,支持 TCP/IP 和 Unix Socket 传输。
服务层
服务层包含大多数 MySQL 的核心功能:连接器、查询缓存(8.0 已移除)、分析器、优化器、执行器。这一层与存储引擎无关,被称为 MySQL Server。
连接器负责建立连接、校验身份、获取用户权限。权限在连接建立时读取,后续修改权限不影响已建立的连接。
分析器进行词法分析和语法分析,识别 SQL 语句的类型(SELECT/INSERT/UPDATE/DELETE)、提取表名、列名、条件等语法元素,构建语法树。如果语法错误,在这一阶段报错。
预处理器进一步检查:表是否存在、列是否存在、用户是否有权限等。预处理还会展开视图引用、处理子查询嵌套、优化 COUNT(*) 等。
优化器生成执行计划。MySQL 使用基于成本的优化器(CBO),统计信息包括表的行数、索引的选择性、数据分布等。优化器考虑访问方法(全表扫描、索引扫描)、连接顺序(小表驱动大表)、连接算法(嵌套循环、哈希连接)等。EXPLAIN 可以查看优化器的选择。
执行器根据执行计划调用存储引擎的 API。执行过程中,执行器会检查行级权限,对于不符合条件的记录,调用引擎的接口过滤。
存储引擎层
存储引擎层负责数据的存储和检索,是插件式的。MySQL 支持多种存储引擎,常见的有 InnoDB、MyISAM、Memory、CSV。每个表在创建时可以指定存储引擎,不同引擎可以共存于同一个数据库中。
存储层
存储层是文件系统,MySQL 将数据存储在磁盘文件中。不同的引擎有不同的文件格式。InnoDB 使用表空间(.ibd 文件)存储数据和索引,MyISAM 使用 .MYD(数据文件)和 .MYI(索引文件)。
InnoDB 存储引擎
InnoDB 架构
InnoDB 是 MySQL 的默认存储引擎,支持事务、行锁、外键、崩溃恢复。其架构包含后台线程和内存池。
后台线程包括 Master Thread、IO Thread、Purge Thread、Page Cleaner Thread。Master Thread 负责刷新脏页、合并插入缓冲、刷新日志;IO Thread 处理 I/O 请求;Purge Thread 清理 undo log;Page Cleaner Thread 刷新脏页。
内存池包括缓冲池、重做日志缓冲、额外内存池。缓冲池缓存数据页和索引页,是 InnoDB 内存最大的组件。重做日志缓冲缓存 redo log,定期刷盘。额外内存池用于分配数据结构本身占用的内存。
InnoDB 锁机制
InnoDB 实现了行级锁,包括记录锁、间隙锁、临键锁。行锁是索引记录锁,如果查询没有使用索引,会退化为表锁。间隙锁防止幻读,临键锁是记录锁和间隙锁的组合。
InnoDB 的锁是"意向锁",表级锁(IS/IX)与行级锁(S/X)配合使用。意向锁不需要显式申请,在申请行锁时自动添加。
InnoDB MVCC
InnoDB 通过 undo log 实现 MVCC。每行记录隐藏两个列:DB_TRX_ID(最近修改事务 ID)和 DB_ROLL_PTR(回滚指针)。回滚指针指向 undo log,形成版本链。事务通过 Read View 判断版本的可见性。
InnoDB 的 RC 和 RR 隔离级别都基于 MVCC 实现,区别在于生成 Read View 的时机:RC 每次查询生成新的 Read View,RR 只在第一次查询时生成。
InnoDB 脏页刷盘策略
InnoDB 的脏页刷盘策略复杂,涉及性能和持久化的权衡。主要策略包括:redo log 快满时主动刷盘,避免覆盖未刷盘的页;缓冲池不足时淘汰脏页触发刷盘;Master Thread 定期刷盘;通过 innodb_io_capacity 控制刷盘速率。
InnoDB Adaptive Hash Index
自适应哈希索引是 InnoDB 的优化特性。热点页的访问频繁,InnoDB 会自动在内存中构建哈希索引,加速点查询。自适应哈希索引是自动管理的,不需要手动干预。
MyISAM 存储引擎
MyISAM 是 MySQL 早期的默认引擎,不支持事务、行锁、外键,但访问速度快。MyISAM 使用表锁,并发度低。MyISAM 支持全文索引(InnoDB 5.6+ 也支持)。MyISAM 的数据文件和索引文件分离,便于备份。
MyISAM 适合读多写少、不要求事务的场景,如内容管理系统。但由于不支持事务和行锁,现代应用很少使用。
MySQL 查询执行
查询执行经历连接器 → 分析器 → 优化器 → 执行器 → 存储引擎。执行器调用存储引擎的接口,接口包括:定位索引、读取记录、更新记录、插入记录、删除记录。存储引擎根据接口实现具体的存储逻辑。
理解 MySQL 的架构,有助于定位性能瓶颈:如果是 CPU 瓶颈,考虑优化查询、增加缓存;如果是 I/O 瓶颈,考虑增加内存、升级 SSD;如果是锁等待,考虑优化事务、减少锁持有时间。