用了那么久的mysql,你真的了解mysql架构吗?

86 阅读6分钟

知其然要知其所以然,探索每一个知识点背后的意义,你知道的越多,你不知道的越多,一起学习,一起进步,如果文章感觉对您有用的话,关注、收藏、点赞,有困惑的地方可以评论,我们一起探讨!

一、MySQL架构层次

MySQL采用分层架构,主要分为四层:

  1. 连接层(Connector Layer)
  2. 服务层(Server Layer)
  3. 存储引擎层(Storage Engine Layer)
  4. 存储层(Storage Layer)
+---------------------+
|     连接层           | 处理客户端连接、认证、线程管理
+---------------------+
|     服务层           | SQL解析、优化、缓存、内置函数
+---------------------+
|     存储引擎层        | InnoDB、MyISAM等引擎,负责数据存取
+---------------------+
|     存储层           | 磁盘文件(数据文件、日志文件)
+---------------------+

二、核心组件详解

1. 连接层
  • 功能
    • 管理客户端连接(TCP/IP、Socket、命名管道等)。
    • 认证用户权限(基于用户名、密码、主机)。
    • 线程池管理(thread_handling参数控制线程模型)。
  • 关键机制
    • 连接池:复用连接,减少创建销毁开销(如Java中的HikariCP)。
    • SSL/TLS支持:加密数据传输(require_secure_transport参数)。
2. 服务层
  • 组件与流程

    1. SQL接口(SQL Interface):接收并返回客户端请求。
    2. 解析器(Parser):语法解析,生成抽象语法树(AST)。
    3. 优化器(Optimizer):生成执行计划(基于成本模型)。
      • 成本估算:统计信息(information_schema)、索引选择。
      • 优化策略:索引合并、子查询优化、JOIN顺序调整。
    4. 执行器(Executor):调用存储引擎接口执行查询。
    5. 查询缓存(Query Cache,8.0移除):缓存SELECT结果(Key为SQL语句哈希值),连接建立完成后,你就可以执行 select 语句了。执行逻辑就会来到第二步:查询缓存。MySQL 拿到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。之前执行过的语句及其结果可能会以 key-value 对的形式,被直接缓存在内存中。key 是查询的语句,value 是查询的结果。如果你的查询能够直接在这个缓存中找到 key,那么这个 value 就会被直接返回给客户端。如果语句不在查询缓存中,就会继续后面的执行阶段。执行完成后,执行结果会被存入查询缓存中。你可以看到,如果查询命中缓存,MySQL 不需要执行后面的复杂操作,就可以直接返回结果,这个效率会很高。但是大多数情况下我会建议你不要使用查询缓存,为什么呢?因为查询缓存往往弊大于利。查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空。因此很可能你费劲地把结果存起来,还没使用呢,就被一个更新全清空了。对于更新压力大的数据库来说,查询缓存的命中率会非常低。除非你的业务就是有一张静态表,很长时间才会更新一次。比如,一个系统配置表,那这张表上的查询才适合使用查询缓存。好在 MySQL 也提供了这种“按需使用”的方式。你可以将参数 query_cache_type 设置成 DEMAND,这样对于默认的 SQL 语句都不使用查询缓存。而对于你确定要使用查询缓存的语句,可以用 SQL_CACHE 显式指定,像下面这个语句一样:mysql> select SQL_CACHE * from T where ID=10;需要注意的是,MySQL 8.0 版本直接将查询缓存的整块功能删掉了,也就是说 8.0 开始彻底没有这个功能了。
  • 关键机制

    • 二进制日志(Binlog):记录所有数据变更(用于主从复制、Point-in-Time Recovery)。
    • 慢查询日志(Slow Query Log):记录执行时间超过阈值的SQL(long_query_time参数)。
3. 存储引擎层
  • 插件式架构:支持多引擎(通过default_storage_engine指定默认引擎)。
  • 主流引擎对比
特性InnoDBMyISAM
事务支持支持(ACID)不支持
锁粒度行级锁表级锁
外键支持不支持
崩溃恢复Redo Log + Undo Log
缓存Buffer Pool(数据页缓存)Key Buffer(索引缓存)
  • InnoDB核心机制
    • Buffer Pool:缓存数据页,减少磁盘IO(innodb_buffer_pool_size)。
    • Redo Log:保证事务持久性(WAL机制,顺序写入)。
    • Undo Log:实现事务回滚和多版本控制(MVCC)。
    • 自适应哈希索引(AHI):自动优化频繁访问的索引。
4. 存储层
  • 文件类型
    • 数据文件
      • InnoDB:.ibd(表数据+索引)、.ibdata(系统表空间)。
      • MyISAM:.MYD(数据)、.MYI(索引)。
    • 日志文件
      • Redo Log:ib_logfile0/1
      • Binlog:mysql-bin.000001
    • 配置文件my.cnf/my.ini

三、关键机制分析

1. 事务与ACID实现
  • 原子性(Atomicity):通过Undo Log回滚未提交事务。
  • 隔离性(Isolation)
    • 锁机制:行级锁(InnoDB)、间隙锁(防止幻读)。
    • MVCC:多版本并发控制,基于Undo Log生成读视图。
  • 持久性(Durability):Redo Log保证事务提交后数据不丢失。
  • 一致性(Consistency):由应用层与数据库共同维护。
2. 主从复制
  • 流程
    1. Master将变更写入Binlog。
    2. Slave通过IO线程拉取Binlog。
    3. Slave SQL线程重放Binlog中的事件。
  • 复制模式
    • 异步复制:默认模式,Master不等待Slave确认。
    • 半同步复制:Master至少等待一个Slave接收日志(rpl_semi_sync_master_enabled)。
3. 高可用与扩展
  • 读写分离:通过Proxy(如MySQL Router)分发读请求到Slave。
  • 分库分表
    • 垂直拆分:按业务模块划分数据库。
    • 水平拆分:按数据范围或哈希分片(如ShardingSphere)。
  • 集群方案
    • InnoDB Cluster:基于Group Replication的MySQL官方方案。
    • Galera Cluster:多主同步复制集群。

四、性能优化要点

1. 索引优化
  • B+树结构:支持范围查询、排序和高效IO(3-4层树高可存储TB级数据)。
  • 覆盖索引:避免回表(查询列均在索引中)。
  • 索引失效场景:函数转换、隐式类型转换、前导通配符(LIKE '%abc')。
2. 参数调优
  • 内存分配
    innodb_buffer_pool_size = 系统内存的70%-80%
    innodb_log_file_size = 1-2GB(Redo Log大小)
    
  • 并发控制
    innodb_thread_concurrency = CPU核心数 × 2
    max_connections = 根据应用需求调整(避免过高导致资源争抢)
    
3. 慢查询分析
  • EXPLAIN工具:解析执行计划(关注typekeyrows字段)。
  • OPTIMIZER TRACE:查看优化器决策过程。
    SET optimizer_trace="enabled=on";
    SELECT * FROM information_schema.optimizer_trace;
    

五、总结

MySQL的架构设计体现了模块化与灵活性:

  • 连接层确保安全高效的客户端交互。
  • 服务层通过优化器生成高效执行计划。
  • 存储引擎层插件化设计支持多样化场景(InnoDB兼顾事务与性能)。
  • 存储层依赖日志机制保障数据可靠性。