必须从服务端配置、库表定义、复制连接三处同时对齐字符集,否则会触发last_errno: 1677或索引失效;需统一character-set-server、用convert to修复表、校准复制线程连接层字符集。

直接改表结构或只调 SET NAMES 无法根治主从字符集不匹配问题,必须从服务端配置、库表定义、复制连接三处同时对齐,否则随时可能触发 Last_Errno: 1677 或索引失效。
确认是不是字符集导致的 Last_Errno: 1677
先看从库 SHOW SLAVE STATUS\G 中的 Last_SQL_Error,如果包含类似 cannot be converted from type 'varchar(1536)' to type 'varchar(2048) utf8mb4',基本锁定字符集问题。再分别执行:
- 主库:
SHOW CREATE TABLE your_db.your_table\G - 从库:
SHOW CREATE TABLE your_db.your_table\G
重点比对两处输出里的 DEFAULT CHARSET 和字段定义中显式写的 CHARACTER SET 与 COLLATE ——别只看 character_set_database,它只是默认值,真正起作用的是表和列自身的定义。
统一主从 character_set_server 和 collation_server
这是所有新建库/表的默认源头,不一致会导致后续建表自动继承不同字符集。在主从两端的 my.cnf 的 [mysqld] 段落里都加上:
character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci
然后重启 MySQL。注意:SET GLOBAL character_set_server = 'utf8mb4' 只对新连接生效,且不持久,不能替代配置文件修改。
用 CONVERT TO 修复已有表,不是 MODIFY COLUMN
ALTER TABLE your_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci 是唯一安全的全量迁移方式,它会同时转换列数据、列定义、索引和默认校对规则。
- 别用
MODIFY COLUMN xxx VARCHAR(255) CHARACTER SET utf8mb4:只改单列定义,不改已有数据编码,也不影响其他列和索引 - 漏掉
COLLATE很危险:比如只写CONVERT TO CHARACTER SET utf8mb4,MySQL 会用默认utf8mb4_general_ci,但如果主库原表是utf8mb4_unicode_ci,从库重放时可能因比较逻辑差异报错 - 含外键或全文索引的表要提前验证:
CONVERT TO可能失败,需先删后加
检查并修正复制线程自身的连接层字符集
复制线程本质是一个特殊客户端连接,它的行为受从库的 @@character_set_client、@@collation_connection 控制。执行:
SELECT @@character_set_client, @@collation_connection;
如果返回不是 utf8mb4 和 utf8mb4_unicode_ci,说明复制线程正在用错误的编码解析 binlog 字节流——哪怕表结构完全一致,也会导致隐式转换、索引失效甚至二次编码乱码(如查出来是 æ–‡)。此时需在从库 my.cnf 的 [client] 和 [mysql] 段落也配好 default-character-set = utf8mb4,并确保启动时加载。
最容易被忽略的是:字符集不一致的影响不在“存不存得下”,而在“比不比得准”——同一张表,主库走索引查得快,从库因 collation 不兼容被迫全表扫描,延迟越滚越大,最后连 EXPLAIN 都看不出问题根源。











