Bug #115355 SQLs in procedure make replication throw error

Submitted: 17 Jun 2024 8:58 Modified: 17 Jun 2024 14:53
Reporter: Malt Chen Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Replication Severity:S3 (Non-critical)
Version:8.4, 8.0.37 OS:Any
Assigned to: CPU Architecture:Any

[17 Jun 2024 8:58] Malt Chen
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'
[17 Jun 2024 14:53] MySQL Verification Team
Hello Malt Chen,

Thank you for the report and test case.
Issue can be seen even on 8.0.37.

regards,
Umesh

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.