MySQL 8.0.16+ 支持 tls_version 配置,但仅 8.0.28+ 彻底移除 TLSv1/TLSv1.1;需通过 SELECT VERSION()、SHOW VARIABLES LIKE 'tls_version' 和 SHOW VARIABLES LIKE 'have_ssl' 验证版本与SSL支持,并重启mysqld生效配置。

确认 MySQL 版本是否真正支持 TLSv1.3
MySQL 8.0.16+ 才开始支持 tls_version 配置项,但只有 8.0.28+ 彻底移除 TLSv1/TLSv1.1;低于 8.0.16 的版本设了 tls_version = TLSv1.3 也无效,变量只读。执行以下命令验证:
-
SELECT VERSION();—— 确保返回类似8.0.33这样的版本号 -
SHOW VARIABLES LIKE 'tls_version';—— 若值为空或为TLSv1,TLSv1.1,说明版本太低或未启用 SSL 模块 -
SHOW VARIABLES LIKE 'have_ssl';—— 必须为YES,DISABLED表示编译时没带 OpenSSL 支持,重装官方二进制包最省事
配置 tls_version 并重启 mysqld
在 /etc/my.cnf 或 /etc/mysql/my.cnf 的 [mysqld] 段末尾添加:
tls_version = TLSv1.3
注意三点:
- 值必须是逗号分隔、无空格的字符串,比如
TLSv1.2,TLSv1.3合法,TLSv1.3,(带空格)会导致启动失败 - MySQL 8.0.28+ 不接受
TLSv1或TLSv1.1,写了也忽略,无需删——但写错协议名(如TLSv13)会直接拒绝启动 -
systemctl restart mysqld是必须的,mysqladmin reload或SIGHUP不会重载 TLS 配置
客户端能否连上 TLSv1.3?关键看 OpenSSL 和驱动
服务端配了 TLSv1.3,不代表客户端能协商成功。典型失败现象是报错:
SSL connection error: Unsupported protocolSSL handshake failed
原因多在客户端侧:
- Linux 系统级 OpenSSL 版本必须 ≥ 1.1.1(运行
openssl version确认),OpenSSL 1.0.2 不支持 TLSv1.3 - Java 应用:JDK 8u261+ 默认支持 TLSv1.3,但旧版
mysql-connector-java 默认禁用,需显式加连接参数:enabledTLSProtocols=TLSv1.3 - Python:
pymysql和mysqlclient默认不指定 TLS 版本,会 fallback 到最低可用协议;必须传ssl={'tls_versions': ['TLSv1.3']} - 命令行客户端:
mysql --tls-version=TLSv1.3 -h host -u user -p,否则可能用 TLSv1.2 尝试连接(取决于客户端默认行为)
验证实际协商结果,别只信 SHOW VARIABLES
SHOW VARIABLES LIKE 'tls_version' 只表示“服务端允许哪些协议”,不是当前连接用的。真正要看的是会话级协商结果:
- 连接后立即执行:
STATUS;,在输出中找SSL:行,例如SSL: Cipher in use is TLS_AES_256_GCM_SHA384→ 这才是 TLSv1.3 - 或者查性能表:
SELECT VARIABLE_VALUE FROM performance_schema.status_by_thread WHERE VARIABLE_NAME = 'Ssl_version' AND THREAD_ID = CONNECTION_ID(); - 如果
STATUS显示SSL: Not in use,说明根本没走加密通道——这时跟tls_version无关,先检查require_secure_transport = ON和证书路径权限
证书私钥文件(如 server-key.pem)权限必须是 600 且属主为 mysql 用户,否则 MySQL 启动时静默失败,Ssl_cipher 始终为空,日志里也不报错。











