MySQL 8.0Notes

第 05 章:连接与线程模型

zjc 于 2026-01-05 发布

这是《MySQL 8.0 源码与内核实战》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 连接是 SQL 执行的入口。理解连接、线程、会话上下文和调度方式,有助于排查连接风暴、慢查询阻塞和线程资源问题。

5.1 连接路径

Client connect()
  -> TCP / Unix socket
     -> connection_accept
        -> Connection Handler
           -> create / reuse THD
              -> authenticate
                 -> command loop
                    -> dispatch_command

一次连接包含:

  1. 网络事件;
  2. 线程分配;
  3. 会话上下文;
  4. 认证授权;
  5. 字符集协商;
  6. 命令循环;
  7. 断开清理。

5.2 THD

THD 是 Server 层最重要的会话上下文:

区域 内容
连接信息 socket、客户端地址、协议
安全上下文 用户、host、权限
语句状态 query、lex、command
事务状态 transaction、XA、savepoint
调度状态 killed、stage、time
变量 session variables
诊断 diagnostics area
资源 tables、MDL、临时表

排查时可通过 processlist 观察其外部表现:

SELECT id,user,host,db,command,time,state,info
FROM information_schema.processlist;

5.3 线程模型

传统连接模型是一个客户端连接对应一个服务线程。

Listener
  -> accept connection
     -> thread cache hit?
        |-- yes: wake cached thread
        +-- no: create thread

相关参数:

参数 说明
max_connections 最大连接数
thread_cache_size 空闲线程缓存
thread_handling 线程调度模型
back_log 连接等待队列
max_connect_errors 错误主机限制
connect_timeout 握手超时

线程不等于用户线程池。MySQL 企业版或 Percona 等发行版可能提供线程池插件。

5.4 命令循环

核心入口:

do_command
  -> dispatch_command
     -> COM_QUERY
        -> mysql_parse
     -> COM_STMT_PREPARE
        -> mysql_stmt_prepare
     -> COM_QUIT
        -> close connection

断点示例:

b dispatch_command
commands
bt
c
end

可以观察 command type、包长度和会话状态。

5.5 认证与权限

handshake
  -> auth plugin
     -> check credentials
        -> ACL cache
           -> assign Security_context

相关对象:

  1. Security_context
  2. ACL_USER
  3. LEX_USER
  4. auth plugin

权限检查贯穿 SQL 执行,不只发生在连接时。视图、存储过程、动态 SQL 和 DEFINER 都会影响上下文。

5.6 断开与清理

连接退出时要释放:

  1. 打开的表;
  2. 元数据锁;
  3. 事务资源;
  4. 预处理语句;
  5. 临时表;
  6. 线程资源;
  7. 诊断信息;
  8. performance_schema 会话行。

如果事务未提交,连接断开会触发回滚。大事务回滚可能耗时,不能简单理解为“断开立即结束”。

5.7 连接观测

SHOW GLOBAL STATUS LIKE 'Threads_%';
SHOW GLOBAL STATUS LIKE 'Connections';
SHOW GLOBAL STATUS LIKE 'Aborted_%';

SELECT *
FROM performance_schema.threads
WHERE type='foreground';

指标含义:

指标 说明
Threads_connected 当前连接
Threads_running 正在执行命令
Threads_created 累计创建线程
Aborted_clients 客户端异常断开
Aborted_connects 连接失败
Connection_errors_max_connections 达到上限

5.8 连接风暴

典型现象:

  1. Threads_connected 快速上升;
  2. CPU 用于线程创建和调度;
  3. 大量连接等待锁或执行 SQL;
  4. 应用连接池失效;
  5. max_connections 拒绝服务。

排查:

SELECT host, count(*) AS cnt
FROM information_schema.processlist
GROUP BY host
ORDER BY cnt DESC;

处理顺序:

  1. 识别来源;
  2. kill 异常会话;
  3. 应用限流或重启发布;
  4. 缩短慢查询;
  5. 调整连接池;
  6. 评估线程池;
  7. 拆分读写入口。

5.9 KILL 与取消

KILL query 设置 THD 的 killed 标记,执行过程中在安全点检查:

KILL QUERY
  -> set killed status
     -> executor / storage engine check
        -> stop returning rows
           -> cleanup

有些操作不能立即响应取消,例如某些 DDL 阶段、I/O、锁等待或大事务回滚。

5.10 生产注意事项

  1. 应用侧必须使用连接池;
  2. 监控 Threads_running 而不只连接数;
  3. 为管理员保留连接配额;
  4. 避免用超小 wait_timeout 强制业务频繁重连;
  5. 大规模连接来源要有审计;
  6. 云环境关注代理层连接模型;
  7. 变更 max_connections 要同步评估内存和 CPU。

本章小结

MySQL 传统模型以连接线程为中心,THD 保存会话的语句、权限、事务和诊断上下文。连接调优要同时看网络、认证、线程、锁等待和业务连接池,避免只调大 max_connections

思考题

  1. THD 中哪些状态会贯穿整个 SQL 生命周期?
  2. Threads_connectedThreads_running 有什么区别?
  3. 为什么连接断开后事务回滚可能继续占用资源?
  4. KILL QUERY 如何传递到执行器?
  5. 连接风暴的处理顺序是什么?