Bug #115355 SQLs in procedure make replication throw error
Description:
When using the master-slave synchronization mode with binlog_format=statement, the SQL statement "UPDATE dd_table set name = 't3' where name COLLATE utf8_tolower_ci = id" in the stored procedure will be rewritten by the subst_spvars(in sql/sp_instr.cc) as "UPDATE dd_table set name = 't3' where name COLLATE utf8_tolower_ci = NAME_CONST('id',_utf8mb3't1' COLLATE 'utf8mb3_general_ci')"" and executed on the slave database. The error "Illegal mix of collations (utf8mb3_tolower_ci,EXPLICIT) and (utf8mb3_general_ci,EXPLICIT) for operation '='' on query" is reported.
The problem can be reproduced using the latest version 8.4
How to repeat:
Build one master and one slave, use 'binlog_format=statement'
1、my.cnf example
[mysqld]
log_bin=binlog # Enable binlog
binlog_format=statement # Use statement format
2、execute sql on master
CREATE TABLE dd_table (name VARCHAR(64) COLLATE utf8mb3_tolower_ci, UNIQUE KEY(name));
INSERT INTO dd_table VALUES('t1'), ('t2');
delimiter //
CREATE PROCEDURE sub(id CHAR(10) CHARACTER SET utf8)
BEGIN
UPDATE dd_table set name = 't3' where name COLLATE utf8_tolower_ci = id;
END;//
delimiter ;
call sub('t1');
3、The replication on slave has already failed.
select * from performance_schema.replication_applier_status_by_worker where last_error_number > 0;
The error message on slave replication is like : Worker 1 failed executing transaction '01204e7c-2c6b-11ef-8e95-5254004b04d4:34' at source log binlog.000005, end_log_pos 2143; Error 'Illegal mix of collations (utf8mb3_tolower_ci,EXPLICIT) and (utf8mb3_general_ci,EXPLICIT) for operation '='' on query. Default database: 'test'. Query: 'UPDATE dd_table set name = 't3' where name COLLATE utf8_tolower_ci = NAME_CONST('id',_utf8mb3't1' COLLATE 'utf8mb3_general_ci')'
Suggested fix:
Some solutions, I'm not sure is there some corner cases may be error.
1. Remove append 'collate' in sp_get_item_value(see sql/sp.cc)
sql with 'UPDATE dd_table set name = 't3' where name COLLATE utf8_tolower_ci = NAME_CONST('id',_utf8mb3't1')' is ok
2. Throw warning warning instead of error for 'Illegal mix of collations'
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.049 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.
Description: When using the master-slave synchronization mode with binlog_format=statement, the SQL statement "UPDATE dd_table set name = 't3' where name COLLATE utf8_tolower_ci = id" in the stored procedure will be rewritten by the subst_spvars(in sql/sp_instr.cc) as "UPDATE dd_table set name = 't3' where name COLLATE utf8_tolower_ci = NAME_CONST('id',_utf8mb3't1' COLLATE 'utf8mb3_general_ci')"" and executed on the slave database. The error "Illegal mix of collations (utf8mb3_tolower_ci,EXPLICIT) and (utf8mb3_general_ci,EXPLICIT) for operation '='' on query" is reported. The problem can be reproduced using the latest version 8.4 How to repeat: Build one master and one slave, use 'binlog_format=statement' 1、my.cnf example [mysqld] log_bin=binlog # Enable binlog binlog_format=statement # Use statement format 2、execute sql on master CREATE TABLE dd_table (name VARCHAR(64) COLLATE utf8mb3_tolower_ci, UNIQUE KEY(name)); INSERT INTO dd_table VALUES('t1'), ('t2'); delimiter // CREATE PROCEDURE sub(id CHAR(10) CHARACTER SET utf8) BEGIN UPDATE dd_table set name = 't3' where name COLLATE utf8_tolower_ci = id; END;// delimiter ; call sub('t1'); 3、The replication on slave has already failed. select * from performance_schema.replication_applier_status_by_worker where last_error_number > 0; The error message on slave replication is like : Worker 1 failed executing transaction '01204e7c-2c6b-11ef-8e95-5254004b04d4:34' at source log binlog.000005, end_log_pos 2143; Error 'Illegal mix of collations (utf8mb3_tolower_ci,EXPLICIT) and (utf8mb3_general_ci,EXPLICIT) for operation '='' on query. Default database: 'test'. Query: 'UPDATE dd_table set name = 't3' where name COLLATE utf8_tolower_ci = NAME_CONST('id',_utf8mb3't1' COLLATE 'utf8mb3_general_ci')' Suggested fix: Some solutions, I'm not sure is there some corner cases may be error. 1. Remove append 'collate' in sp_get_item_value(see sql/sp.cc) sql with 'UPDATE dd_table set name = 't3' where name COLLATE utf8_tolower_ci = NAME_CONST('id',_utf8mb3't1')' is ok 2. Throw warning warning instead of error for 'Illegal mix of collations'