t_connect 是一个 服务器端初始化命令参数,用于在每个非超级用户连接建立时自动执行的 SQL 语句。


一、核心作用

在每个普通用户会话建立时,自动执行 SET NAMES utf8mb4,确保:

  • character_set_client = utf8mb4

  • character_set_connection = utf8mb4

  • character_set_results = utf8mb4

目标:强制未指定字符集的客户端连接统一使用 utf8mb4,防止乱码


二、使用场景与限制

✅ 适用场景(MySQL 5.7 及以下)

  • 遗留应用无法修改连接字符串

  • 大量客户端分散管理,难以统一配置

  • 临时快速解决字符集不一致问题

⚠️ 致命限制

  1. 对超级用户(SUPER 权限)无效:root 等管理员账户 不会执行此命令

  2. 执行失败会导致连接中断:若 SET NAMES 执行失败,客户端将无法连接

  3. 无法覆盖客户端主动设置:客户端在连接后手动修改字符集会覆盖此设置


三、现代替代方案

MySQL 8.0+ 官方推荐(已废弃 t_connect)

[mysqld]
# 无需 t_connect,只需确保以下两项
character-set-server = utf8mb4
collation-server = utf8mb4_0900_ai_ci

# 客户端连接时自动协商字符集
skip-character-set-client-handshake  # 可选:强制使用服务器字符集

应用层配置(最佳)

在 连接字符串 中明确指定字符集:

# Java JDBC
jdbc:mysql://host/db?characterEncoding=utf8mb4

# Python
mysql+pymysql://user:pass@host/db?charset=utf8mb4

# PHP PDO
mysql:host=localhost;dbname=test;charset=utf8mb4

四、配置示例与验证

完整配置(仅建议 MySQL 5.7 及以下)

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
t_connect = 'SET NAMES utf8mb4'  # 最后一道防线

验证是否生效

-- 使用普通用户登录(非 root)
SHOW VARIABLES LIKE 'character_set_%';

-- 应看到以下三个值为 utf8mb4
+--------------------------+---------+
| Variable_name            | Value   |
+--------------------------+---------+
| character_set_client     | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_results    | utf8mb4 |
+--------------------------+---------+

五、关键对比:t_connect vs 现代方案

特性

t_connect

连接字符串指定

MySQL 8.0+ 支持

❌ 已废弃

✅ 推荐

对 root 用户生效

❌ 永远跳过

✅ 全部生效

失败是否阻断连接

❌ 会阻断

✅ 仅该连接失败

维护复杂度

高(依赖服务器)

低(应用自治)

性能影响

每次连接额外执行

连接时一次性设置


六、总结与建议

MySQL 8.0+ 用户

直接删除 t_connect,依赖服务器默认值和应用层配置。

MySQL 5.7 及以下用户

  1. 首选:修改应用连接字符串指定字符集

  2. 备选:使用 t_connect 作为临时兜底方案

  3. 必须:确保所有非超级用户已授予 EXECUTE 权限(否则无法执行 SET NAMES

迁移步骤

-- 1. 检查哪些用户会跳过 t_connect
SELECT user, host FROM mysql.user WHERE Super_priv = 'Y';

-- 2. 降低用户权限(如需)
REVOKE SUPER ON *.* FROM 'app_user'@'%';

核心记忆点t_connect 是 旧时代的妥协方案 ,现代 MySQL 应通过 服务器默认值+应用层显式指定来管理字符集。