🔍 一、核心功能总结
✅ MySQL 8.0.16 起的重大改进:运行时可动态重载 TLS 配置
以前的问题:在 MySQL 8.0.16 之前,要修改 SSL/TLS 设置(比如证书、密钥、协议版本等),必须重启 MySQL 服务。这在生产环境中非常不方便,尤其是当证书过期时。
现在的解决方案 :从 MySQL 8.0.16 开始,你可以:
- 动态设置
ssl_xxx
和tls_xxx
系统变量(如ssl_cert
,tls_version
等); - 使用命令
ALTER INSTANCE RELOAD TLS
来"热更新"服务器用于新连接的 TLS 上下文(TLS context),而无需重启 MySQL。
📌 意义:避免因证书过期或需要升级加密策略而导致服务中断。
🧩 二、关键概念解析
1. 什么是 TLS Context?
TLS Context 是指 MySQL 服务器用来建立安全连接的一组参数,包括:
- CA 证书(
ssl_ca
) - 服务器证书(
ssl_cert
) - 私钥(
ssl_key
) - 支持的 TLS 版本(
tls_version
) - 加密套件(
tls_ciphersuites
)
这些参数共同决定了客户端能否成功建立一个加密连接。
2. 系统变量 vs 状态变量
类型 | 示例 | 说明 |
---|---|---|
系统变量 (System Variables) | ssl_cert , tls_version |
可通过 SET GLOBAL 修改,控制下一次 TLS 上下文加载时使用的值 |
状态变量 (Status Variables) | Current_tls_cert , Current_tls_version |
表示当前正在生效的 TLS 上下文的实际值 |
🔧 比如:
sql
-- 修改配置(但不会立即生效)
SET PERSIST ssl_cert = '/new/path/to/cert.pem';
-- 使新配置生效
ALTER INSTANCE RELOAD TLS;
执行后,Current_tls_cert
才会变成 /new/path/to/cert.pem
。
3. 如何热更新 TLS 配置?(三步法)
sql
-- 第一步:修改系统变量(内存+持久化)
SET PERSIST ssl_cert = '/path/to/new-cert.pem';
SET PERSIST ssl_key = '/path/to/new-key.pem';
-- 第二步:重新加载 TLS 上下文
ALTER INSTANCE RELOAD TLS;
-- 第三步(可选):断开旧连接(让客户端重连以使用新证书)
-- KILL CONNECTION <id>;
✅ 效果:
- 新连接使用新的证书;
- 已有连接不受影响(仍用旧的 TLS 上下文);
- 不需要重启 MySQL!
4. 特殊情况:只替换文件内容,不改变量
如果你的
ssl_cert
指向的是某个文件路径(如/var/lib/mysql/server-cert.pem
),你甚至可以:
- 直接替换这个文件的内容为新的未过期证书;
- 执行
ALTER INSTANCE RELOAD TLS
; - MySQL 会重新读取该文件并应用新证书。
📌 这种方式特别适合自动化证书更新(如 Let's Encrypt 自动续签)。
🔐 三、TLS 协议支持演进(重点!)
MySQL 版本 | 支持的 TLS 协议 |
---|---|
≤ 8.0.15 | TLSv1, TLSv1.1, TLSv1.2 |
8.0.16~8.0.25 | TLSv1, TLSv1.1, TLSv1.2, TLSv1.3 ✅ |
8.0.26~8.0.27 | TLSv1 ❌, TLSv1.1 ❌, TLSv1.2, TLSv1.3(标记为 deprecated) |
≥ 8.0.28 | 仅支持 TLSv1.2 和 TLSv1.3 ✅✅ |
📌 结论:
- 从 MySQL 8.0.28 起,彻底禁用 TLSv1 和 TLSv1.1,因为它们不安全(见 RFC 8996)。
- 要使用 TLSv1.3 ,必须满足:
- MySQL 服务端和客户端都使用 OpenSSL 1.1.1 或更高版本编译;
- 并且
tls_version
包含TLSv1.3
。
⚙️ 四、如何配置允许的 TLS 版本?
1. 查看当前设置
sql
SHOW GLOBAL VARIABLES LIKE 'tls_version';
输出示例:
+---------------+-----------------------+
| Variable_name | Value |
+---------------+-----------------------+
| tls_version | TLSv1.2,TLSv1.3 |
+---------------+-----------------------+
2. 配置方式
方法一:启动时配置(my.cnf)
ini
[mysqld]
tls_version = TLSv1.2,TLSv1.3
方法二:运行时动态修改(MySQL 8.0.16+)
sql
SET PERSIST tls_version = 'TLSv1.2,TLSv1.3';
ALTER INSTANCE RELOAD TLS;
⚠️ 注意:不要有"空洞",比如
TLSv1,TLSv1.2
缺少TLSv1.1
是不推荐的。
🔤 五、加密套件(Ciphersuites)配置
TLSv1.2 及以下
使用 ssl_cipher
控制:
sql
SET PERSIST ssl_cipher = 'ECDHE-RSA-AES128-GCM-SHA256';
TLSv1.3(OpenSSL 1.1.1+)
使用 tls_ciphersuites
(注意是 :
分隔):
sql
SET PERSIST tls_ciphersuites = 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384';
ALTER INSTANCE RELOAD TLS;
✅ 默认启用的 TLSv1.3 套件:
TLS_AES_128_GCM_SHA256
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
📊 六、监控当前会话的加密情况
sql
SELECT
VARIABLE_NAME,
VARIABLE_VALUE
FROM performance_schema.session_status
WHERE VARIABLE_NAME IN ('Ssl_version', 'Ssl_cipher');
输出示例:
+---------------+---------------------------+
| VARIABLE_NAME | VARIABLE_VALUE |
+---------------+---------------------------+
| Ssl_cipher | TLS_AES_256_GCM_SHA384 |
| Ssl_version | TLSv1.3 |
+---------------+---------------------------+
📌 如果两个值为空 → 表示当前连接未加密。
🔄 七、其他组件的影响(重要!)
❗ 注意:ALTER INSTANCE RELOAD TLS
不影响以下组件
组件 | 是否受影响 | 如何更新 |
---|---|---|
主从复制 (Replication) | ❌ 不自动更新 | 需要 STOP SLAVE; START SLAVE; |
Group Replication | ❌ 不自动更新 | 需要 STOP GROUP_REPLICATION; START GROUP_REPLICATION; |
X Plugin (MySQL X Protocol) | ❌ 不更新 | 需重启插件 |
Admin Interface | ✅ 可单独更新 | ALTER INSTANCE RELOAD TLS FOR CHANNEL 'admin' |
💡 从 MySQL 8.0.21 起,支持
FOR CHANNEL
子句,可以分别更新主接口和管理接口的 TLS 上下文。
🛑 八、错误处理:配置失败怎么办?
默认情况下:
- 如果新的 TLS 配置无效(如证书格式错误),
ALTER INSTANCE RELOAD TLS
会失败并回滚; - 旧的 TLS 上下文继续使用。
但你可以加 NO ROLLBACK ON ERROR
强制执行:
sql
ALTER INSTANCE RELOAD TLS NO ROLLBACK ON ERROR;
👉 结果:如果失败,会产生警告,但禁用新连接的加密功能(降级为非加密连接)。
⚠️ 慎用!可能导致安全风险。
🧪 九、实际应用场景举例
场景:SSL 证书到期了,不想重启 MySQL
✅ 解决方案:
bash
# 1. 用新证书覆盖旧文件(假设路径是 /var/lib/mysql/server-cert.pem)
cp new-cert.pem /var/lib/mysql/server-cert.pem
cp new-key.pem /var/lib/mysql/server-key.pem
# 2. 登录 MySQL
mysql -u root -p
# 3. 重载 TLS 上下文
ALTER INSTANCE RELOAD TLS;
✅ 完成!新连接自动使用新证书,无需重启。
📚 十、性能 Schema 监控(MySQL 8.0.21+)
查看所有 TLS 通道的状态:
sql
SELECT * FROM performance_schema.tls_channel_status;
输出包含:
- 主连接接口(main)
- 管理接口(admin)
- 各自的证书、协议、加密套件等信息
✅ 总结:你应该记住的 10 个要点
要点 | 内容 |
---|---|
1 | MySQL 8.0.16+ 支持运行时修改 TLS 配置 |
2 | ALTER INSTANCE RELOAD TLS 是热更新命令 |
3 | 修改系统变量后必须执行 reload 才生效 |
4 | 8.0.28+ 已完全移除 TLSv1 和 TLSv1.1 |
5 | 使用 TLSv1.3 需 OpenSSL 1.1.1+ |
6 | Current_tls_xxx 状态变量显示当前生效值 |
7 | 更换证书文件后只需 RELOAD TLS |
8 | 主从复制、Group Replication 需手动重启才能应用新 TLS 配置 |
9 | NO ROLLBACK ON ERROR 可防止失败回滚,但可能禁用加密 |
10 | 用 Ssl_version 和 Ssl_cipher 查看当前会话加密详情 |
如果你是 DBA 或运维人员,掌握这些知识可以帮助你:
- 实现零停机更新 SSL 证书;
- 提高数据库安全性;
- 应对合规审计要求(如禁用弱协议);
- 快速排查加密连接问题。
如有具体场景(如"如何让主从也更新证书"),欢迎继续提问!