Java-87 深入浅出 MySQL 从架构到线程:剖析存储引擎、线程模模型

点一下关注吧!!!非常感谢!!持续更新!!!

🚀 AI篇持续更新中!(长期更新)

AI炼丹日志-30-新发布【1T 万亿】参数量大模型!Kimi‑K2开源大模型解读与实践,持续打造实用AI工具指南!📐🤖

💻 Java篇正式开启!(300篇)

目前2025年07月28日更新到:
Java-83 深入浅出 MySQL 连接、线程、查询缓存与优化器详解
MyBatis 已完结,Spring 已完结,Nginx已完结,Tomcat已完结,分布式服务正在更新!深入浅出助你打牢基础!

📊 大数据板块已完成多项干货更新(300篇):

包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈!
大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解

请添加图片描述

新版本演化

在这里插入图片描述

MySQL 5.7 存储引擎优化

Undo 日志表空间改进

MySQL 5.7 将 Undo 日志表空间从共享的 ibdata 文件中独立出来,这项改进带来了以下优势:

  • 用户可以灵活配置 Undo 表空间的数量和大小,通过参数 innodb_undo_tablespaces 设置表空间数量(默认0,范围0-128)
  • 支持独立管理 Undo 空间,避免 ibdata 文件过大导致的性能问题
  • 每个 Undo 表空间默认初始大小为10MB,可通过 innodb_undo_directory 指定存储路径
  • 实际应用场景:当系统需要支持大量并发事务时,可以配置多个 Undo 表空间减少争用

Temporary 临时表空间

新增的临时表空间特性包含以下改进:

  • 通过独立的临时表空间文件(ibtmp1)存储临时表数据
  • 默认存储在数据目录,可通过 innodb_temp_data_file_path 配置路径和大小
  • 支持存储临时表、排序缓存等临时数据
  • 实际应用:大表排序操作会优先使用临时表空间而非内存,避免内存溢出
  • 注意:该文件会随使用增长,需要定期监控其大小

动态 Buffer Pool 调整

Buffer Pool 内存管理的重要改进:

  • 支持通过 SET GLOBAL innodb_buffer_pool_size=X 在线调整大小(单位字节)
  • 调整过程分为多个区块(chunk)逐步完成,避免性能剧烈波动
  • 建议调整幅度不超过当前大小的1倍,且总大小不超过物理内存的80%
  • 监控命令:SHOW STATUS LIKE 'Innodb_buffer_pool_resize_status'
  • 应用场景:业务高峰期可临时扩大缓冲池,低谷期可缩小以释放内存资源

这些改进显著提升了 MySQL 5.7 的运维灵活性和性能表现,使数据库管理员可以更灵活地根据业务需求进行资源配置。

MySQL 8.0 存储架构优化

InnoDB 表空间分离

MySQL 8.0 对 InnoDB 存储引擎进行了重大架构改进,将数据字段(data)和Undo日志从共享表空间ibdata中完全分离。在之前的版本中,必须保持ibdata中的数据字典与独立表空间(.ibd文件)中的数据字段严格一致。而8.0版本通过重构存储架构,消除了这一限制,大大提升了管理的灵活性和可靠性。

临时表空间增强

MySQL 8.0 对临时表空间进行了多项改进:

  1. 支持配置多个物理文件作为临时表空间
  2. 所有临时表均使用InnoDB存储引擎
  3. 支持在临时表上创建索引
    这些改进显著提升了复杂查询、排序操作和临时表处理的性能。例如,在大数据量排序时,优化后的临时表空间可以更高效地处理临时数据。

表空间管理优化

MySQL 8.0 引入了类似Oracle的表空间管理功能:

  • 用户可以创建多个表空间,每个表空间可以包含多个物理数据文件
  • 一个表空间可以被多个表共享使用
  • 但每个表只能存放在一个特定的表空间中
    这种架构允许更灵活的存储管理,例如可以将不同业务的数据分配到不同的表空间,或者将热数据单独存放以优化I/O性能。

Doublewrite Buffer 分离

MySQL 8.0 将 Doublewrite Buffer 从共享表空间ibdata中分离出来,形成了一个独立的存储区域。这个改进带来了以下优势:

  1. 减少了ibdata文件的I/O压力
  2. 提高了崩溃恢复的效率
  3. 允许对Doublewrite Buffer进行独立的配置优化
    Doublewrite Buffer是InnoDB确保数据页完整性的重要机制,分离后可以更好地发挥其作用。

InnoDB 线程模型

IO Thread 详解

InnoDB 存储引擎为了提高数据库的并发性能,采用了异步IO(AIO)机制来处理各种读写操作。这种设计可以显著降低I/O等待时间,提高整体吞吐量。

IO Thread 的发展历史

  • 早期版本(1.0之前):InnoDB 使用4个固定的IO线程:
    • 1个 write thread
    • 1个 read thread
    • 1个 insert buffer thread
    • 1个 log thread
  • 1.0版本之后:为了进一步提升性能,将 read thread 和 write thread 的数量都扩展到了4个,使总线程数增加到10个。这种扩展能够更好地处理高并发的读写请求。

各线程的详细功能

1. Read Thread
  • 数量:4个(默认)
  • 主要职责:负责从磁盘读取数据页到缓冲池(Buffer Pool)
  • 具体工作流程
    1. 当查询需要访问不在缓冲池中的数据页时
    2. read thread 从磁盘读取相应页到内存
    3. 数据页被加载到缓冲池后供SQL线程使用
  • 性能影响:多个read thread可以并行处理读请求,减少读操作的等待时间
2. Write Thread
  • 数量:4个(默认)
  • 主要职责:将缓冲池中的脏页(修改过的页)刷新到磁盘
  • 具体工作流程
    1. 当页在缓冲池中被修改后标记为脏页
    2. 根据刷新策略(如LRU或flush list),write thread 将脏页写入磁盘
    3. 写入完成后清除脏页标记
  • 性能影响:多个write thread可以并行刷盘,避免单个线程成为性能瓶颈
3. Log Thread
  • 数量:1个
  • 主要职责:负责重做日志(redo log)缓冲区的刷新
  • 具体工作流程
    1. 事务提交时产生redo log记录
    2. log thread 将redo log从日志缓冲区刷新到磁盘文件
    3. 确保事务的持久性(Durability)
  • 关键特性:采用顺序写方式,性能较高,对事务提交速度有重要影响
4. Insert Buffer Thread
  • 数量:1个
  • 主要职责:处理变更缓冲(Change Buffer)的合并操作
  • 具体工作流程
    1. 对非唯一二级索引的修改首先写入change buffer
    2. 当相关页被读取时,insert buffer thread 将change buffer中的修改合并到数据页
    3. 定期将change buffer的内容刷新到磁盘
  • 性能优势:减少随机IO,特别适合写多读少的场景

配置参数

可以通过以下参数调整IO线程数量:

  • innodb_read_io_threads:控制read thread数量(默认4)
  • innodb_write_io_threads:控制write thread数量(默认4)

实际应用场景

在高并发OLTP系统中:

  • 读密集型应用可以适当增加read thread数量
  • 写密集型应用可以增加write thread数量
  • 对于大量非唯一索引更新的场景,insert buffer thread能显著提升性能
  • log thread对事务提交性能至关重要,需要确保redo log所在的磁盘有良好的顺序写性能

这些IO线程协同工作,共同构成了InnoDB高效处理I/O操作的基础架构。

Purge Thread

InnoDB 存储引擎中的 Purge Thread 是一个后台线程,主要负责清理已经完成事务的 undo 日志。当事务提交后,这些 undo 日志就不再需要了,因为它们已经完成了回滚或 MVCC(多版本并发控制)的历史记录功能。Purge Thread 会定期扫描 undo 日志空间,回收那些可以被重用的 undo 页。

工作原理

  1. 当事务提交后,InnoDB 会在 undo 日志中标记这些记录为"可清除"状态
  2. Purge Thread 会周期性地检查这些标记
  3. 对于确定不再需要的 undo 日志,Purge Thread 会释放对应的存储空间
  4. 被释放的 undo 页会被放入空闲列表,供新事务重用

配置参数

可以通过以下 SQL 命令查看 Purge Thread 的相关配置:

show variables like '%innodb_purge_threads%'

这个命令会显示以下重要参数:

  • innodb_purge_threads: 指定 Purge Thread 的数量(默认为4)
  • innodb_purge_batch_size: 每次清理的 undo 日志数量

性能优化

在以下场景中可能需要调整 Purge Thread 配置:

  1. 高并发写入系统:可以适当增加线程数量
  2. 大数据量事务:可能需要增大 batch size
  3. 系统空闲时段:可以降低线程数量以节省资源

Purge Thread 的高效运作对 InnoDB 存储引擎的整体性能至关重要,它确保了 undo 日志空间的及时回收,避免了存储空间的浪费和性能下降。

对应的内容如下:

Page Cleaner Thread

Page Cleaner Thread 是 InnoDB 存储引擎中的一个重要后台线程,主要负责将缓冲池中的脏页(Dirty Page)刷新到磁盘。这个线程在数据库性能调优中起着关键作用。

主要功能细节

  1. 脏页刷新机制

    • 周期性地检查缓冲池中的脏页
    • 根据脏页比例和系统负载决定刷新速率
    • 采用自适应刷新算法,避免I/O突发
  2. 与Redo Log的关系

    • 脏页刷盘后,对应的redo log就可以被覆盖
    • 实现了redo log的循环使用机制
    • 确保数据持久性和崩溃恢复能力

工作流程

  1. 扫描缓冲池中的脏页列表
  2. 计算需要刷新的脏页数量(考虑系统负载)
  3. 调用write thread线程执行实际的I/O操作
  4. 更新相关元数据信息

配置参数

可以通过以下SQL查看和设置相关参数:

-- 查看当前配置的Page Cleaner线程数量
show variables like '%innodb_page_cleaners%';

-- 其他相关参数
show variables like '%innodb_lru_scan_depth%';
show variables like '%innodb_io_capacity%';

最佳实践

  1. 在多核服务器上,可以适当增加page cleaner线程数
  2. 通常建议设置为CPU核心数的1/4到1/2
  3. 需要平衡I/O能力和CPU资源消耗

监控指标

可以通过以下方式监控Page Cleaner的工作状态:

-- 查看刷新统计信息
show engine innodb status\G
-- 查找"BUFFER POOL AND MEMORY"部分

对应的内容如下所示:
在这里插入图片描述

Master Thread

InnoDB 的主线程(Master Thread)是存储引擎的核心调度线程,负责协调和管理其他后台线程的工作,在 MySQL 服务器中拥有最高优先级。其主要职责是将内存缓冲池(Buffer Pool)中的修改数据异步刷新到磁盘文件,确保内存数据与磁盘数据的最终一致性,同时维持数据库的高性能运行。

主要功能模块包括:

  1. 脏页刷新(page cleaner thread):负责将修改过的数据页(dirty page)写入磁盘
  2. undo 页回收(purge thread):清理不再需要的undo日志页
  3. redo 日志刷新(log thread):将redo日志缓冲区内容持久化到磁盘
  4. 写缓冲合并(change buffer merge):合并对二级索引的变更操作

Master Thread 采用周期性任务调度机制,主要包含两个处理周期:

每秒执行的操作(每秒触发一次):

  1. 日志缓冲区刷新

    • 将redo log buffer中的内容刷新到磁盘redo log文件
    • 确保事务的持久性(Durability)
    • 示例:当事务提交时,虽然数据页可能还在内存中,但redo log已持久化
  2. 写缓冲区合并

    • 根据当前系统I/O压力动态调整合并策略
    • 将change buffer中缓存的二级索引变更应用到磁盘
    • 应用场景:对非唯一索引的DML操作可先缓存在change buffer中
  3. 脏页刷新

    • 当缓冲池中脏页比例达到innodb_max_dirty_pages_pct(默认75%)时触发
    • 采用自适应刷新算法,避免I/O突发
    • 例如:当系统负载较低时可能提前刷新脏页

每10秒执行的操作(每10秒触发一次):

  1. 强制脏页刷新

    • 无论脏页比例如何,都会刷新一定数量的脏页
    • 防止长时间未刷新导致恢复时间过长
  2. 全量写缓冲区合并

    • 执行完整的change buffer合并操作
    • 确保长时间运行的更新操作最终被应用
  3. 日志缓冲区强制刷新

    • 保证即使没有事务提交,redo log也能定期持久化
    • 为潜在的崩溃恢复提供更多保障
  4. undo页清理

    • 删除不再需要的旧版本数据(undo页)
    • 通过purge操作回收存储空间
    • 例如:当事务提交且没有其他事务需要读取旧版本时

注意:在MySQL 5.6+版本中,许多功能已拆分为独立的后台线程(如page cleaner thread),但Master Thread仍负责整体协调工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

武子康

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值