[MDEV-25606] Concurrent CREATE TRIGGER statements mix up in binlog and break replication Created: 2021-05-05  Updated: 2022-10-20  Resolved: 2021-05-10

Status: Closed
Project: MariaDB Server
Component/s: Replication, Triggers
Affects Version/s: N/A
Fix Version/s: 10.5.11

Type: Bug Priority: Major
Reporter: Elena Stepanova Assignee: Michael Widenius
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to MDEV-25708 THD::cleanup(): Assertion `!mdl_conte... Closed
relates to MDEV-25738 Assertion `ticket->m_duration == MDL_... Closed
relates to MDEV-17567 Atomic DDL Closed

 Description   

The test case is non-deterministic and for reproducing purposes only, not suitable for the regression suite.

--source include/master-slave.inc
 
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (b INT);
 
--let $run= 100
--disable_abort_on_error
while ($run)
{
  --send
    CREATE TRIGGER tr AFTER INSERT ON t1 FOR EACH ROW SET @b = 1;
  --connection master1
  CREATE TRIGGER tr AFTER INSERT ON t2 FOR EACH ROW SET @b = 1;
  --connection master
  --reap  
  DROP TRIGGER IF EXISTS tr;
  --dec $run
}
 
--sync_slave_with_master
 
# Cleanup
--connection master
DROP TABLE t1, t2;
--source include/rpl_end.inc

It very quickly ends up with something like this in the binary log:

bb-10.6-monty 387d673ed

master-bin.000001	653	Query	1	836	use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER tr AFTER INSERT ON t1 FOR EACH ROW SET @b = 1
master-bin.000001	836	Gtid	1	878	GTID 0-1-4
master-bin.000001	878	Query	1	979	use `test`; DROP TRIGGER IF EXISTS tr
master-bin.000001	979	Gtid	1	1021	GTID 0-1-5
master-bin.000001	1021	Query	1	1204	use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER tr AFTER INSERT ON t2 FOR EACH ROW SET @b = 1
master-bin.000001	1204	Gtid	1	1246	GTID 0-1-6
master-bin.000001	1246	Query	1	1429	use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER tr AFTER INSERT ON t1 FOR EACH ROW SET @b = 1
master-bin.000001	1429	Gtid	1	1471	GTID 0-1-7
master-bin.000001	1471	Query	1	1572	use `test`; DROP TRIGGER IF EXISTS tr

which naturally makes the replication fail with

2021-05-06  0:44:33 8 [ERROR] Slave SQL: Error 'Trigger 'test.tr' already exists' on query. Default database: 'test'. Query: 'CREATE DEFINER=`root`@`localhost` TRIGGER tr AFTER INSERT ON t1 FOR EACH ROW SET @b = 1', Gtid 0-1-6, Internal MariaDB error code: 1359
2021-05-06  0:44:33 8 [Warning] Slave: Trigger 'test.tr' already exists Error_code: 1359

There was some problem with this on 10.2, but nothing bad happens on 10.3-10.6. However, on bb-10.6-monty starting from the patch below it fails very reliably.

commit d9fe53cfe71443c645862f62b389b4e7b56a5953
Author: Monty
Date:   Mon Mar 22 16:05:08 2021 +0200
 
    Check if we can rename triggers before doing an ALTER TABLE ... RENAME



 Comments   
Comment by Michael Widenius [ 2021-05-10 ]

The reason for this is that we don't have a a lock on the trigger name, so it is possible for
two threads to try to create the same trigger at the same time and both thinks that they
have succeed.

There is also a possibility for a problem with DROP TRIGGER:

  • One threads wants to drop a trigger and reads the .TRN file
    Another thread does in the mean time drop of the .TRN file and creates a new trigger for another table with the same name
  • The first thread drops the trigger but does not update the files for the new table, which can cause strange issues.
Comment by Michael Widenius [ 2021-05-10 ]

I have given Elana a patch to test that fixes both drop and create

Comment by Michael Widenius [ 2021-05-10 ]

The fix uses now code that only exists in 10.5 and up.
As this is probably not a critical bug, better to fix this only in 10.5 to not get into
merge issues with the patch.

Comment by Michael Widenius [ 2021-05-10 ]

Fixed by adding a mdl lock for the trigger name

Generated at Thu Feb 08 09:38:57 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.