一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

如何解决MySQL 8.0中由于JSON格式不兼容导致的同步报错?

时间:2026-09-03 20:36:50 编辑:袖梨 来源:一聚教程网

查Last_SQL_Error含JSON关键词可锁定复制中断为JSON解析兼容性问题,需比对主从MySQL小版本和sql_mode,实测JSON_EXTRACT与->>行为一致性,并修复binary字符集导致的JSON插入失败。

查 Last_SQL_Error 里是否含 JSON 关键词

复制中断时,Last_SQL_Error 是唯一可信的线索。只要里面出现以下任意字符串,基本可断定是 JSON 解析兼容性问题:Invalid JSON textJSON document may not contain NULL member namesMalformed JSON pathCannot create a JSON value from a string with CHARACTER SET 'binary'。这类错误不会伴随主键冲突或 GTID 跳变,而是直接卡死 SQL 线程,Slave_SQL_Running 变为 NoSeconds_Behind_Master 停滞不动。

比对主从 MySQL 小版本和 sql_mode

MySQL 8.0.x 不同小版本对 JSON 的容忍度差异极大:比如 ->> 在 8.0.22+ 严格模式下对缺失路径返回空字符串 '',而 8.0.21 可能返回 NULL;主库启用了 PIPES_AS_CONCAT,从库没启用,会导致含 || 的 JSON 构造表达式被当作逻辑或运算报错。

  1. 执行 SELECT VERSION(), @@sql_mode; 在主从分别运行,逐字比对结果
  2. 特别注意 STRICT_TRANS_TABLESPIPES_AS_CONCATANSI_QUOTES 是否完全一致
  3. 若不一致,统一在 my.cnf 中显式设置:sql_mode = STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,PIPES_AS_CONCAT

验证 JSON_EXTRACT 和 ->> 的行为是否一致

别只信文档,要实测。在主库和从库上同时执行:

SELECT JSON_EXTRACT('{"a": null}','$.a') AS ex, '{"a": null}'->>'$.a' AS arrow, '{"b": 1}'->>'$.a' AS missing;

三列结果必须完全相同。常见不一致场景:

  1. ex 主库返回 NULL,从库返回 "null"(字符串)→ 字符集或 collation 错配
  2. arrow 主库返回 NULL,从库返回空字符串 → sql_mode 差异或版本 bug
  3. missing 主库返回 NULL,从库报错 → 从库版本过低或 strict mode 过严

修复 binary 字符集导致的 JSON 插入失败

MyBatis 或 JDBC 写 JSON 时抛出 Cannot create a JSON value from a string with CHARACTER SET 'binary',根本原因是客户端传入的字符串被 MySQL 当作 binary 处理,而非 utf8mb4。

  1. 确保表字段定义显式指定 collation:json_col JSON COLLATE utf8mb4_0900_as_cs
  2. JDBC URL 加参数:?characterEncoding=utf8mb4&serverTimezone=UTC
  3. MyBatis TypeHandler 中,序列化后必须调用 new String(bytes, StandardCharsets.UTF_8) 再传给 PreparedStatement
  4. 临时绕过:在 INSERT/UPDATE 前加 SET NAMES utf8mb4;(不推荐长期使用)

真正容易被忽略的,不是“怎么写 JSON”,而是主从 sql_mode 和字段 COLLATE 是否咬合、以及客户端传入字节流的编码是否被 MySQL 正确识别——差一个配置项,同步就静默失败。

热门栏目