vitess: Bug Report: Cannot create a JSON value from a string with CHARACTER SET 'binary' in online ddl
Overview of the Issue
When running a Vitess onlineddl schema migration with json generated columns, the migration fails in the copy phase with Cannot create a JSON value from a string with CHARACTER SET 'binary'
Reproduction Steps
Create table:
CREATE TABLE `orders` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`orderPaymentMethod` json DEFAULT NULL,
`stripePaymentMethod` tinyint(4) GENERATED ALWAYS AS (json_unquote(json_extract(`orderPaymentMethod`,'$.paymentMethod'))) STORED,
PRIMARY KEY (`id`)
) ENGINE=InnoDB
Insert:
insert into orders(orderPaymentMethod) values (convert('{\"customerId\": \"cus_Il7WwbIODMoaE1\"}' using utf8mb4))
Note that if orderPaymentMethod
is null here, the error does not surface, nor does it surface if there are no json generated columns
Run migration:
vtctl ApplySchema -- --ddl_strategy "vitess" --sql "ALTER TABLE orders ENGINE=INNODB;" TestKeyspace
See failures:
executor.go:4069] updateMigrationMessage: uuid=f3387b12_5323_11ee_8c7e_0a4b134e1d27, message=task error: failed inserting rows: Cannot create a JSON value from a string with CHARACTER SET 'binary'. (errno 3144) (sqlstate 22032) during query: insert into _f3387b12_5323_11ee_8c7e_0a4b134e1d27_20230914172717_vrepl(id,orderPaymentMethod) values (1,convert(JSON_OBJECT(_utf8mb4'customerId', _utf8mb4'cus_Il7WwbIODMoaE1') using utf8mb4))
executor.go:2082] cancelMigrations: cancelling f3387b12_5323_11ee_8c7e_0a4b134e1d27; reason: task error: failed inserting rows: Cannot create a JSON value from a string with CHARACTER SET 'binary'. (errno 3144) (sqlstate 22032) during query: insert into _f3387b12_5323_11ee_8c7e_0a4b134e1d27_20230914172717_vrepl(id,orderPaymentMethod) values (1,convert(JSON_OBJECT(_utf8mb4'customerId', _utf8mb4'cus_Il7WwbIODMoaE1') using utf8mb4))
controller.go:261] vreplication stream 5 going into error state due to Cannot create a JSON value from a string with CHARACTER SET 'binary'. (errno 3144) (sqlstate 22032) during query: insert into _f3387b12_5323_11ee_8c7e_0a4b134e1d27_20230914172717_vrepl(id,orderPaymentMethod) values (1,convert(JSON_OBJECT(_utf8mb4'customerId', _utf8mb4'cus_Il7WwbIODMoaE1') using utf8mb4))
Binary Version
v18
Operating System and Environment details
Centos8, Linux 5.4.141-hs22.el8.x86_64
Log Fragments
No response
About this issue
- Original URL
- State: open
- Created 10 months ago
- Comments: 17 (17 by maintainers)
Wondering if changing the generated column query to something like, will help, in case the issue is with how MySQL internally processes json for generated columns.
Ok so I tested with mysql 8 and my migration worked, even the v14 version, and also Rohit’s workaround works (with 5.7 and v14) - but would require us to change the schemas of everyone with json generated columns. I also tested changing the line that does
set names binary
toset names utf8mb4
in the table copy and that worked, but of course that probably has unintended side-effects (the comment explains that we need this becauseTables may have varying character sets. To ship the bits without interpreting them we set the character set to be binary.
).So perhaps this is a mysql 5.7 +
set names binary
+ json generated columns bug