最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何解决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 text、JSON document may not contain NULL member names、Malformed JSON path、Cannot create a JSON value from a string with CHARACTER SET 'binary'。这类错误不会伴随主键冲突或 GTID 跳变,而是直接卡死 SQL 线程,Slave_SQL_Running 变为 No,Seconds_Behind_Master 停滞不动。
比对主从 MySQL 小版本和 sql_mode
MySQL 8.0.x 不同小版本对 JSON 的容忍度差异极大:比如 ->> 在 8.0.22+ 严格模式下对缺失路径返回空字符串 '',而 8.0.21 可能返回 NULL;主库启用了 PIPES_AS_CONCAT,从库没启用,会导致含 || 的 JSON 构造表达式被当作逻辑或运算报错。
- 执行
SELECT VERSION(), @@sql_mode;在主从分别运行,逐字比对结果 - 特别注意
STRICT_TRANS_TABLES、PIPES_AS_CONCAT、ANSI_QUOTES是否完全一致 - 若不一致,统一在 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;
三列结果必须完全相同。常见不一致场景:
-
ex主库返回NULL,从库返回"null"(字符串)→ 字符集或 collation 错配 -
arrow主库返回NULL,从库返回空字符串 → sql_mode 差异或版本 bug -
missing主库返回NULL,从库报错 → 从库版本过低或 strict mode 过严
修复 binary 字符集导致的 JSON 插入失败
MyBatis 或 JDBC 写 JSON 时抛出 Cannot create a JSON value from a string with CHARACTER SET 'binary',根本原因是客户端传入的字符串被 MySQL 当作 binary 处理,而非 utf8mb4。
- 确保表字段定义显式指定 collation:
json_col JSON COLLATE utf8mb4_0900_as_cs - JDBC URL 加参数:
?characterEncoding=utf8mb4&serverTimezone=UTC - MyBatis TypeHandler 中,序列化后必须调用
new String(bytes, StandardCharsets.UTF_8)再传给 PreparedStatement - 临时绕过:在 INSERT/UPDATE 前加
SET NAMES utf8mb4;(不推荐长期使用)
真正容易被忽略的,不是“怎么写 JSON”,而是主从 sql_mode 和字段 COLLATE 是否咬合、以及客户端传入字节流的编码是否被 MySQL 正确识别——差一个配置项,同步就静默失败。
相关文章
- TPLink TLWDR4320 无线路由器打印服务器设置指南 09-03
- TPLink TLWDR8620 52 无线路由器当作交换机使用教程 09-03
- TPLink TLWDR8620 52 无线路由器映射服务器到外网操作方法 09-03
- 本地使用docker搭建minio 09-03
- 《我的勇者》勇者启程玩法说明 09-03
- 《我的勇者》阿兔回归礼包兑换码分享 09-03