From 2ef3597c59daac77509d951905a73afa560b288e Mon Sep 17 00:00:00 2001 From: Dave Gosselin Date: Tue, 4 Nov 2025 18:19:01 -0500 Subject: [PATCH] MDEV-38003: Intermittent Replication Failure on a multi-table DELETE When deleting from multiple tables, the DELETE operator uses a temporary table to collect the row IDs of rows that will be deleted. If this table grows too large, then we convert it from a heap temporary table to a persistent (on-disk) temporary table to avoid unbounded memory usage. There are several error codes that gate creating this persistent temporary table but themselves don't indicate a problem with the DELETE operation. However, regardless of this error code value, we need to clear it after deciding whether or not to create the persistent temporary table. If we don't clear this value, then the error code's stale state prevents binlog replication when its value is muxed with local_error during multi_delete::send_eof. --- .../suite/rpl/r/rpl_multi_delete_join.result | 60 +++++++++++++++++++ .../suite/rpl/t/rpl_multi_delete_join.test | 46 ++++++++++++++ sql/sql_delete.cc | 1 + 3 files changed, 107 insertions(+) create mode 100644 mysql-test/suite/rpl/r/rpl_multi_delete_join.result create mode 100644 mysql-test/suite/rpl/t/rpl_multi_delete_join.test diff --git a/mysql-test/suite/rpl/r/rpl_multi_delete_join.result b/mysql-test/suite/rpl/r/rpl_multi_delete_join.result new file mode 100644 index 0000000000000..8e23ba56fa85b --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_multi_delete_join.result @@ -0,0 +1,60 @@ +include/master-slave.inc +[connection master] +# +# MDEV-38003 Intermittent Replication Failure on a multi-table DELETE +# +connection master; +set sql_log_bin=1; +connection slave; +set sql_log_bin=1; +reset master; +connection master; +create database mdev38003; +use mdev38003; +create table t1 (pk int, num int); +create table t2 (pk int, num int); +create table t3 (pk int, num int); +insert into t1 (pk, num) values (1,1900),(2,1901); +insert into t2 (pk, num) values (2,2001),(2,2002); +insert into t3 (pk, num) values (1,40),(2,42); +select * from t1 left join t2 on t1.pk = t2.pk left join t3 on t2.pk = t3.pk; +pk num pk num pk num +2 1901 2 2001 2 42 +2 1901 2 2002 2 42 +1 1900 NULL NULL NULL NULL +select * from t1 left join t2 on t1.pk = t2.pk left join t3 on t2.pk = t3.pk where t2.num <= 2002; +pk num pk num pk num +2 1901 2 2001 2 42 +2 1901 2 2002 2 42 +connection slave; +use mdev38003; +select * from t1 left join t2 on t1.pk = t2.pk left join t3 on t2.pk = t3.pk; +pk num pk num pk num +2 1901 2 2001 2 42 +2 1901 2 2002 2 42 +1 1900 NULL NULL NULL NULL +select * from t1 left join t2 on t1.pk = t2.pk left join t3 on t2.pk = t3.pk where t2.num <= 2002; +pk num pk num pk num +2 1901 2 2001 2 42 +2 1901 2 2002 2 42 +connection master; +use mdev38003; +delete t1, t2, t3 from t1 left join t2 on t1.pk = t2.pk left join t3 on t2.pk = t3.pk where t2.num <= 2002; +select * from t1 left join t2 on t1.pk = t2.pk left join t3 on t2.pk = t3.pk; +pk num pk num pk num +1 1900 NULL NULL NULL NULL +select * from t1 left join t2 on t1.pk = t2.pk left join t3 on t2.pk = t3.pk where t2.num <= 2002; +pk num pk num pk num +connection slave; +use mdev38003; +select * from t1 left join t2 on t1.pk = t2.pk left join t3 on t2.pk = t3.pk; +pk num pk num pk num +1 1900 NULL NULL NULL NULL +select * from t1 left join t2 on t1.pk = t2.pk left join t3 on t2.pk = t3.pk where t2.num <= 2002; +pk num pk num pk num +connection master; +use mdev38003; +drop table t1, t2, t3; +drop database mdev38003; +# End of 11.8 tests +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_multi_delete_join.test b/mysql-test/suite/rpl/t/rpl_multi_delete_join.test new file mode 100644 index 0000000000000..5e98cd5ca65bc --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_multi_delete_join.test @@ -0,0 +1,46 @@ +source include/master-slave.inc; + +--echo # +--echo # MDEV-38003 Intermittent Replication Failure on a multi-table DELETE +--echo # +connection master; +set sql_log_bin=1; +sync_slave_with_master; +set sql_log_bin=1; +reset master; +connection master; +create database mdev38003; +use mdev38003; +create table t1 (pk int, num int); +create table t2 (pk int, num int); +create table t3 (pk int, num int); +insert into t1 (pk, num) values (1,1900),(2,1901); +insert into t2 (pk, num) values (2,2001),(2,2002); +insert into t3 (pk, num) values (1,40),(2,42); +select * from t1 left join t2 on t1.pk = t2.pk left join t3 on t2.pk = t3.pk; +select * from t1 left join t2 on t1.pk = t2.pk left join t3 on t2.pk = t3.pk where t2.num <= 2002; + +sync_slave_with_master; +use mdev38003; +select * from t1 left join t2 on t1.pk = t2.pk left join t3 on t2.pk = t3.pk; +select * from t1 left join t2 on t1.pk = t2.pk left join t3 on t2.pk = t3.pk where t2.num <= 2002; + +connection master; +use mdev38003; +delete t1, t2, t3 from t1 left join t2 on t1.pk = t2.pk left join t3 on t2.pk = t3.pk where t2.num <= 2002; +select * from t1 left join t2 on t1.pk = t2.pk left join t3 on t2.pk = t3.pk; +select * from t1 left join t2 on t1.pk = t2.pk left join t3 on t2.pk = t3.pk where t2.num <= 2002; + +sync_slave_with_master; +use mdev38003; +select * from t1 left join t2 on t1.pk = t2.pk left join t3 on t2.pk = t3.pk; +select * from t1 left join t2 on t1.pk = t2.pk left join t3 on t2.pk = t3.pk where t2.num <= 2002; + +connection master; +use mdev38003; +drop table t1, t2, t3; +drop database mdev38003; + +--echo # End of 11.8 tests + +--source include/rpl_end.inc diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 347cb4ccabbee..9f012c0898aa5 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -1474,6 +1474,7 @@ int multi_delete::send_data(List &values) } found++; } + error= 0; } } }