Last_Errno: 1677 根本原因是主从表级字符集(CHARSET)与校对规则(COLLATION)不一致,导致ROW格式复制时类型转换失败;须通过对比主从show create table输出确认差异,并用CONVERT TO统一表字符集,再重置relay log重新同步。

Last_Errno: 1677 报错本质是主从表级字符集不匹配,不是库级或连接级问题;必须让主从两端同一张表的 CHARSET 和 COLLATION 完全一致,否则 ALTER、INSERT、UPDATE 都可能触发类型转换失败。
怎么确认是不是字符集导致的 1677 报错
先看从库 show slave status\G 中的 Last_SQL_Error,如果包含类似 cannot be converted from type 'varchar(1536)' to type 'varchar(2048) utf8mb4',基本锁定字符集问题。
再分别查主从库上出错表的建表语句:
- 主库执行:
show create table wjq.test_profile\G→ 注意输出里DEFAULT CHARSET=xxx和字段定义中显式指定的字符集 - 从库执行同样命令 → 对比两处
CHARSET是否不同(如主是utf8,从是utf8mb4) - 别只看
character_set_database,它只是默认值,表创建时没显式指定才会继承;真正起作用的是表自身的CHARSET
改表字符集要用 CONVERT TO,不是 MODIFY 或 CHANGE
ALTER TABLE ... CONVERT TO CHARACTER SET utf8mb4 会同时转换列数据、列定义、索引和默认校对规则,是安全的全量迁移方式。
以下操作容易踩坑:
面向 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可能失败,需先删再加,生产环境务必提前验证
主从字符集不一致的根因在建表逻辑和 binlog 记录方式
当建表语句没写 CHARACTER SET 时:
- 主库按
character_set_database创建表(比如utf8) - binlog 中不记录字符集信息(Statement 格式下尤其明显)
- 从库收到建表语句后,按自己的
character_set_database(比如utf8mb4)创建同名表 → 表结构已不一致
后续主库插入一行含 emoji 的数据(需要 utf8mb4),从库解析时发现目标列只支持 utf8(最多 3 字节),直接报 Last_Errno: 1677。
所以不能只修当前报错表,要统一主从库的 character_set_server 和新建库的默认字符集,并在所有 DDL 中显式声明 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci。
修复后必须重置 relay log 并重新同步
改完表字符集只是解决“未来同步”,已积压的 relay log 里还存着旧格式的变更,不清理会持续报错。
- 从库停复制:
STOP SLAVE; - 清空 relay log:
RESET SLAVE ALL;(注意不是RESET SLAVE,后者不清除 master.info) - 主库重新 dump(带
--master-data=2 --single-transaction)并导入从库 - 再
CHANGE MASTER TO指向新 binlog 位置,START SLAVE;
跳过错误(sql_slave_skip_counter)在这里不可取——1677 是结构性不兼容,跳过一条只会让下一条继续报,根本没解决问题。

















