MySQL 5.7.12 import 无法从具有 CHARACTER SET 'binary' 的字符串创建 JSON 值

MySQL 5.7.12 import cannot create a JSON value from a string with CHARACTER SET 'binary'

我导出了包含 JSON 列的数据库。在我迁移到新服务器后,我的导入每次都崩溃并出现如下错误:

cannot create a JSON value from a string with CHARACTER SET 'binary'

在 Whosebug 上,我找到了这个 post 但对我不起作用: mysqlimport issues "set @@character_set_database=binary" which prevents loading json values

文件大小为 2GB,无法打开文件。

有人知道导入我的数据库文件吗?

所有 MySQL JSON 数据类型信息必须是 UTF8MB4 字符集而不是 BINARY。

您可以将正则表达式应用于导出的 SQL 文本,这会将二进制字符串转换为可插入格式。当我遇到这个问题时,这是我快速而肮脏的修复

(X'[^,\)]*')
CONVERT( using utf8mb4)

应用此正则表达式意味着

INSERT INTO json_table (json_column) VALUES (X'7B22666F6F223A2022626172227D');

现在将变为

INSERT INTO json_table (json_column) VALUES (CONVERT(X'7B22666F6F223A2022626172227D' using utf8mb4));

这对我有用(我也控制了向 sql 文件的导出)。有很多注意事项;例如我知道这些字段永远不会超过 1000,并且不会包含任何非 ascii 字符。 请发表评论并告诉我为什么这太糟糕了:)

导出前

alter table <table> modify <json_column> varchar(1000);

导入后

alter table <table> modify <json_column> json;

我在处理 Sequel Pro 的导出时遇到了这个问题。我取消选中 Output BLOB fields as hex 选项,问题就消失了。目视检查导出显示清晰 JSON 而不是二进制。

将排序规则更改为 utf8_general_ci。为我工作。

我遇到了转储问题。我能够通过更改转储文件中的行来修复它:

/*!40101 SET NAMES binary*/;

/*!40101 SET NAMES utf8mb4*/;

对于像我这样使用 Symfony 4 / Doctrine 到达这里的人:出于某些原因,可以在 longtext MySQL 类型存储 JSON 中解析相同的实体;或 json MySQL 类型存储 json。手动设置 longtext MySQL 类型解决了我的特定情况下的问题。

我今天遇到了同样的问题。以下是我的案例的调查结果,

我请我的一位朋友生成一个 SQL 转储供我导入。他使用 sequel-pro 生成转储(导出数据库)。当我进行导入时,它抛出了一个错误

Cannot create a JSON value from a string with CHARACTER SET 'binary'

因此,生成的转储存在问题,所有 json 字段都被转换为某种原始格式,即不是值

"{'key1':'value1', 'key2':'value2'}"

它是,

X'nfdsklsdsklnfjkbvkjsdbvkjhdfsbvkjdsbnvljkdsbvkjhdfbvkjdfbvjkdfb'

因此,当导入转储时,即 运行 insert 语句 mysql 无法处理数据,因为它不是 json 类型。

这是 link 报告的 bug
https://github.com/sequelpro/sequelpro/issues/2397

您需要取消选中 Output BLOB fields as hex 选项。

对于那些在 2019 年 6 月左右使用 Sequel Pro 的用户,除了取消选中 "Output BLOB fields as hex option"(如上所述)之外 - 您还需要使用夜间构建,它增加了对 [=13 的支持=] 类型 2 年前。此支持尚未正式发布。

这个奇怪的问题发生在 运行 一个简单的 UPDATE 查询时:

update some_table set json_attr = '{"test":168}' where id = 123456;

重新启动 MySQL 修复了它。无法查明原因。

编辑:我们正在使用 Aurora。看起来这与我们有一个奇怪的配置有关,其中同一个实例同时处理主连接和 slave/reader 连接。

vim 版本对于 Lorcan O'Neill 的回答

vi xxxx.sql
:%s/\(X'[^,\)]*'\)/CONVERT( using utf8mb4)/g

一开始的答案确实对我很有帮助,但是转换 all 二进制值会产生一堆其他错误消息,例如 Duplicate entry [...] for key 'PRIMARY'。最后我发现 JSON 条目都是以 5B 或 7B 开头,以 5D 或 7D 结尾,这当然意味着它们以 [{ 开头并以 [=15= 结尾] 或 }。所以对我有用的是 regex-replace 只有那些条目:

Find:    (X'5B[^,\)]*5D')
Replace: CONVERT( using utf8mb4)

然后

Find:    (X'7B[^,\)]*7D')
Replace: CONVERT( using utf8mb4)

Et voilá,所有导入错误都消失了! (至少对我而言)