前言
周五晚上和朋友一起去外面吃饭,本来想着不加班早点回家过周末,谁又能想到突然就接到一个电话,mysqldump逻辑备份导入时报错,具体错误为“ERROR 3144 (22032): Cannot create a JSON value from a string with CHARACTER SET 'binary'.”
下面就和大家简单分享一下这个案例,由于涉及业务数据,这里将通过自己模拟场景的方式来进行分享;关于真实场景或模拟场景分享,之前也说过,能够自己模拟复现出故障场景,往往才更加证明已经完全了解清楚其中的原理和解决办法。
案例分享
(1)创建一张含JSON列的表,并插入一条记录
mysql> select version(); +------------+ | version() | +------------+ | 5.7.18-log | +------------+ 1 row in set (0.00 sec) mysql> show create table json_test\G *************************** 1. row *************************** Table: json_test Create Table: CREATE TABLE `json_test` ( `id` int NOT NULL, `name` varchar(10) DEFAULT NULL, `a` json DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci 1 row in set (0.00 sec) mysql> insert into json_test(id,name,a) values(1,'1','{"id":"1","name":"1"}'); Query OK, 1 row affected (0.01 sec)
(2)通过mysqldump导出该表
$ mysqldump -uroot -p --set-gtid-purged=off test json_test > json_test.sql
(3)尝试导入数据,报错如下,看起来似乎是与字符集有关
mysql> source json_test.sql ... ERROR 3144 (22032): Cannot create a JSON value from a string with CHARACTER SET 'binary'. ...
(4)查看该SQL文件,发现里面 /*!50503 SET NAMES binary */; 这条SQL比较可疑,和报错相关
(5)进一步查阅文档,发现与官方两个bug相关,Bug #86709和Bug #88288
Bug #86709:https://bugs.mysql.com/bug.php?id=86709 Bug #88288:https://bugs.mysql.com/bug.php?id=88288
(6)尝试修改SQL文件,将 /*!50503 SET NAMES binary */; 改为 /*!50503 SET NAMES utf8mb4 */; 并导入成功,问题解决
mysql> source /tmp/backup/cdb-dki7pq4r_backup_20200828202032.sql ... Query OK, 1 row affected (0.01 sec) ... mysql> select * from json_test; +----+------+--------------------------+ | id | name | a | +----+------+--------------------------+ | 1 | 1 | {"id": "1", "name": "1"} | +----+------+--------------------------+ 1 row in set (0.00 sec)
总结
关于这个问题,我们可以通过修改SQL文件中的字符集解决;后续我也对MySQL新版本(5.7.30和8.0.20),进行了测试,已经修复该bug。