Last_Errno: 1677 根本原因是主从字符集不一致,需同步修正服务端配置、表定义、复制连接层三处;确认方法是检查 SHOW SLAVE STATUS 中的 Last_SQL_Error 及主从 SHOW CREATE TABLE 的 DEFAULT CHARSET 和字段级 CHARACTER SET/COLLATE。

直接改 SET NAMES 或只调 character_set_database 不能解决主从字符集不一致报错,必须同步修正服务端配置、表定义、复制连接层三处字符集,否则 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 是唯一安全的全量迁移方式,它会同时转换列数据、列定义、索引和默认校对规则。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 别用
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 中补充:
init_connect = 'SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci'
并确保该设置对复制线程生效(部分版本需配合 skip-slave-start + 手动 START REPLICA 触发重连)。
最容易被忽略的是:即使所有配置都改对了,如果某张表在主库创建时没显式声明 CHARACTER SET,而主从 character_set_database 不同,binlog 中又不记录字符集信息,那从库建表就会继承自己的默认值——这种隐式差异不会报错,但会在第一次插入 emoji 或四字节 UTF-8 字符时突然触发 Last_Errno: 1677。

















