Files
cs-note/hhs/MySQL/01-入门基础/01-MySQL 架构与入门.md
2026-05-24 11:42:38 +08:00

9.2 KiB
Raw Permalink Blame History

tags, create time
tags create time
MySQL
架构
进程模型
Server
2026-05-16 00:00

MySQL 架构与进程模型

概述

理解 MySQL 的内部架构是性能调优和故障排查的前提。本文将从 Client-Server 模型出发,逐层拆解 MySQL 的四大功能层以及不同存储引擎下的线程调度机制。

四层架构

MySQL 遵循经典的三层 Client-Server 架构,但在服务端内部被清晰划分为四层:

graph BT
    subgraph "应用层"
        A["应用程序<br/>(Go / Java / Python)"]
    end

    subgraph "连接层<br/>Connection Layer"
        B["Thread Pool"]
        C["Authentication"]
        D["Connection Management"]
    end

    subgraph "SQL 层<br/>SQL Layer"
        E["Query Cache ⚠️ 8.0 已移除"]
        F["Parser → Preprocessor"]
        G["Optimizer"]
        H["Executor"]
    end

    subgraph "存储引擎层<br/>Storage Engine"
        I["InnoDB"]
        J["MyISAM"]
        K["Memory"]
        L["Archive"]
    end

    subgraph "文件系统"
        M["Data Files"]
        N["Binlog"]
        O["Redo Log"]
    end

    A --> B
    B --> F
    F --> G --> H --> I
    H --> J
    H --> K
    H --> L
    I --> M
    I --> N
    I --> O

各层职责

连接层负责处理客户端的连接请求,包括身份验证、权限校验、SSL/TLS 协商以及线程分配。MySQL 采用「一连接一线程」模型——每个客户端连接对应一个独立的服务器线程,这意味着万级并发时会产生巨大的线程开销。

[!NOTE] 为什么高并发场景要考虑线程池? MySQL 原生没有内置线程池(Percona Server 提供)。当并发量超过数千时,上下文切换的开销会成为瓶颈。解决方案有三:

  • ProxySQL / MaxScale:前端代理层做连接复用
  • MySQL Thread Pool Plugin:企业版功能或 Percona 分支
  • 连接池:在应用层控制并发连接数(如 Go 的 sql.DB)

SQL 层是整个数据库的核心,完成 SQL 语句的解析、优化和执行。这一层实现了 SQL 标准语法、查询优化策略、函数系统和事务管理。值得注意的是,很多用户熟悉的 SQL 特性其实都在这一层实现——比如子查询改写、JOIN 顺序优化等。

存储引擎层提供了可插拔的存储方案。不同的引擎对索引、锁、事务的支持各不相同。InnoDB 承担了默认的事务型负载,而 MyISAM、Memory 等引擎则针对特定场景做了优化。由于大多数生产环境只使用 InnoDB,现代运维中这一层其实非常安静。

文件系统层将页(Page,默认 16KB)写入磁盘。InnoDB 有自己的 Buffer Pool 来管理数据缓存,同时也依赖操作系统的 Page Cache。Linux 内核的 I/O 调度器对 MySQL 性能有直接影响。

线程模型详解

MySQL 服务启动时会创建一组后台线程,同时为每个连接分配专用线程:

classDiagram
    class MasterThread {
        +binlog dump
        +purge redo log
        +truncate binary log
        +DD event cleanup
        +change buffer merge
    }

    class ConnectionThread {
        +parse query
        +optimize
        +execute
        +send result
    }

    class WorkerThreads {
        +InnoDB read worker
        +InnoDB log writer
        +InnoDB page cleaner
    }

    class ThreadPool {
        <<optional>>
        +acceptor thread
        +worker pool
        +idle stack management
    }

    MasterThread ..> WorkerThreads : "coordinates"
    ThreadPool --> ConnectionThread : "dispatches"

关键后台线程

线程 职责
Master Thread InnoDB 专属,协调写操作、刷新脏页、合并 Change Buffer
Log Thread 将 Redo Log Buffer 刷入 Redo Log File
Page Cleaner 主动将脏页从 Buffer Pool 刷盘,避免崩溃恢复时间过长
Purge Thread 删除 Undo Log 中标记为废弃的行记录
DD Event Cleanup 清理数据字典中的过期对象信息

连接线程生命周期

stateDiagram-v2
    [*] --> New: 客户端发起 TCP 连接
    New --> Handshake: 握手协议 + 认证
    Handshake --> Authenticated: 认证成功
    Handshake --> Closed: 认证失败
    Authenticated --> Sleeping: 发送命令
    Sleeping --> Executing: 收到新命令
    Executing --> Sending: 执行完毕
    Sending --> Sleeping: 返回结果集
    Sleeping --> Closed: 客户端断开 / 超时
    Sleeping --> Killed: 管理员 kill 掉

[!QUESTION] 什么是 MySQL 连接超时? 如果客户端空闲太久不发消息会发生什么?MySQL 有两个关键超时参数:

  • wait_timeout(默认 28800 秒 = 8 小时):非交互式连接的闲置超时
  • interactive_timeout(默认 28800 秒):交互式连接(如 mysql CLI)的闲置超时

连接池中如果未正确配置这些参数,可能出现大量 ZOMBIE 连接占满 MaxConnections。这就是为什么 Go 的 sql.DB.ConnMaxLifetime 应该设为比 wait_timeout 更短的值。

mysqld 启动流程

flowchart TD
    A["加载 my.cnf 配置"] --> B["初始化全局变量"]
    B --> C["加载插件"]
    C --> D["初始化存储引擎<br/>innodb_init()"]
    D --> E["打开数据目录"]
    E --> F["恢复未提交事务<br/>redo log crash recovery"]
    F --> G["启动后台线程"]
    G --> H["监听端口"]
    H --> I["就绪 ✨"]

启动过程中的关键阶段:

  1. 配置加载:按优先级读取配置文件 /etc/my.cnf → /etc/mysql/my.cnf → ~/.my.cnf,命令行参数优先级最高
  2. 引擎初始化:InnoDB 会在启动时进行 Crash Recovery——重放 Redo Log 恢复到一致状态。如果数据文件损坏严重,这一步会卡住或报错
  3. Crash Recovery:innodb_force_recovery 参数可以在恢复期间限制操作级别(1~6),用于紧急导出数据

核心架构图

graph TB
    subgraph "连接管理"
        C1["Accept Thread"] --> C2["Connection Pool"]
        C2 --> C3["Read Command"]
    end

    subgraph "SQL 处理流水线"
        C3 --> P1["Syntax Parser"]
        P1 --> P2["AST Semantic Check"]
        P2 --> P3["Preprocessing"]
        P3 --> P4["Optimization"]
        P4 --> P5["Execution"]
    end

    subgraph "InnoDB 执行路径"
        P5 --> I1["Buffer Pool Read Page"]
        I1 --> I2{"Hit?"}
        I2 -->|"Yes"| I3["Return Result"]
        I2 -->|"No"| I4["Read from Disk"]
        I4 --> I1
        I5["Change Buffer"] -.-> I1
    end

    C1 --> C3
    style P4 fill:#FF9F43,color:#000
    style I1 fill:#00B6BC,color:#fff
    style I3 fill:#00D866,color:#fff

实战:在线诊断工具

在生产环境中快速定位问题,需要掌握以下几组命令行工具。它们分别作用于不同的架构层级:

1. SHOW PROCESSLIST — SQL 层视角

-- 最基础的线程状态查看
SHOW FULL PROCESSLIST;

-- 等效的 SQL 查询(可结合 WHERE 过滤)
SELECT * FROM information_schema.processlist WHERE COMMAND != 'Sleep';

每个线程在 PROCESSLIST 中表现为一条记录,关键列:

列 含义 常见值
ID 线程 ID,KILL id 使用
State 当前执行阶段 Sending data, Creating sort index, Locked
Time 当前状态的持续秒数 > 5s 需警惕
Info 正在执行的 SQL NULL 表示空闲

[!TIP] State 解读口诀

  • Waiting for handler lock → 行锁竞争,配合 Innodb_row_lock_waits 排查
  • Creating sort index → 大 ORDER BY/GROUP BY,检查是否缺少索引
  • Sending data → 不仅是在"发送结果",而是正在扫描和生成数据,往往是最耗时的阶段

2. SHOW STATUS — 全局计数器

-- 查看慢查询总数(取决于 slow_query_log 配置)
SHOW GLOBAL STATUS LIKE 'Slow_queries';

-- 当前并发连接数 vs 上限
SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW GLOBAL STATUS LIKE 'Max_connections';

-- InnoDB 缓冲池命中率(接近 100% 为佳)
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%';

[!QUESTION] 为什么 Buffer Pool 命中率不是越高越好? 理论上 Hit Rate 越接近 100% 越好,但当数据集小于 Buffer Pool 时,Hit Rate 会固定在 100% 以上(因为缓存了多次)。生产环境中 98%~99% 已经足够优秀,不必盲目增大 innodb_buffer_pool_size。

3. Performance Schema — MySQL 5.7+ 的深层监控

performance_schema 是 MySQL 内置的性能采集框架,比 SHOW STATUS 更细粒度:

-- 当前等待事件(锁、I/O、网络)TOP 10
SELECT EVENT_NAME, COUNT_STAR, AVG_TIMER_WAIT
FROM performance_schema.events_waits_summary_global_by_event_name
ORDER BY COUNT_STAR DESC LIMIT 10;

-- 最近 10 条耗时 > 1s 的语句
SELECT DIGEST_TEXT, COUNT_STAR, AVG_TIMER_WAIT/1e12 AS avg_ms
FROM performance_schema.events_statements_summary_by_digest
WHERE AVG_TIMER_WAIT > 1e12
ORDER BY AVG_TIMER_WAIT DESC LIMIT 10;

[!NOTE] Performance Schema 的性能代价 开启 PS 会带来约 5%~15% 的 CPU 开销。建议在低峰期采样分析,或仅对目标线程启用 instrumentation。


关联笔记