diff options
author | Monty <monty@mariadb.org> | 2020-12-14 15:57:04 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2021-05-19 22:54:13 +0200 |
commit | 407e9b78cf64a3b8aca441ab585601e173f9ba32 (patch) | |
tree | 242f7059e66a0a08ace9183e07e87284e6f412b6 /mysql-test/suite | |
parent | e3cfb7c8034f4281029f81996cff8d938f06ec67 (diff) | |
download | mariadb-git-407e9b78cf64a3b8aca441ab585601e173f9ba32.tar.gz |
MDEV-24395 Atomic DROP TRIGGER
The purpose of this task is to ensure that DROP TRIGGER is atomic.
Description of how atomic drop trigger works:
Logging of DROP TRIGGER
Log the following information:
db
table name
trigger name
xid /* Used to check if query was already logged to binary log */
initial length of the .TRG file
query if there is space for it, if not log a zero length query.
Recovery operations:
- Delete if exists 'database/trigger_name.TRN~'
- If this file existed, it means that we crashed before the trigger
was deleted and there is nothing else to do.
- Get length of .TRG file
- If file length is unchanged, trigger was not dropped. Nothing else to
do.
- Log original query to binary, if it was stored in the ddl log. If it was
not stored (long query string), log the following query to binary log:
use `database` ; DROP TRIGGER IF EXISTS `trigger_name`
/* generated by ddl log */;
Other things:
- Added trigger name and DDL_LOG_STATE to drop_trigger()
Trigger name was added to make the interface more consistent and
more general.
Diffstat (limited to 'mysql-test/suite')
-rw-r--r-- | mysql-test/suite/atomic/drop_trigger.result | 49 | ||||
-rw-r--r-- | mysql-test/suite/atomic/drop_trigger.test | 123 |
2 files changed, 172 insertions, 0 deletions
diff --git a/mysql-test/suite/atomic/drop_trigger.result b/mysql-test/suite/atomic/drop_trigger.result new file mode 100644 index 00000000000..265f06f31ed --- /dev/null +++ b/mysql-test/suite/atomic/drop_trigger.result @@ -0,0 +1,49 @@ +"engine: aria crash point: ddl_log_drop_before_drop_trigger position: 1" +t1.TRG +t1_trg.TRN +t2_trg.TRN +"engine: aria crash point: ddl_log_drop_before_drop_trigger position: 2" +t1.TRG +t2_trg.TRN +master-bin.000001 # Query # # use `test`; DROP TRIGGER t1_trg +"engine: aria crash point: ddl_log_drop_before_drop_trn position: 1" +t1.TRG +t2_trg.TRN +master-bin.000002 # Query # # use `test`; DROP TRIGGER t1_trg +"engine: aria crash point: ddl_log_drop_before_drop_trn position: 2" +master-bin.000001 # Query # # use `test`; DROP TRIGGER t1_trg +master-bin.000002 # Query # # use `test`; DROP TRIGGER t2_trg /* some comment */ +"engine: aria crash point: ddl_log_drop_after_drop_trigger position: 1" +t1.TRG +t2_trg.TRN +master-bin.000002 # Query # # use `test`; DROP TRIGGER t1_trg +"engine: aria crash point: ddl_log_drop_after_drop_trigger position: 2" +master-bin.000001 # Query # # use `test`; DROP TRIGGER t1_trg +master-bin.000002 # Query # # use `test`; DROP TRIGGER t2_trg /* some comment */ +"engine: aria crash point: definition_file_after_create position: 1" +t1.TRG +t1_trg.TRN +t2_trg.TRN +"engine: aria crash point: definition_file_after_create position: 2" +"No crash!" +master-bin.000001 # Query # # use `test`; DROP TRIGGER t1_trg +master-bin.000001 # Query # # use `test`; DROP TRIGGER t2_trg /* some comment */ +"engine: aria crash point: ddl_log_drop_before_binlog position: 1" +t1.TRG +t2_trg.TRN +master-bin.000002 # Query # # use `test`; DROP TRIGGER t1_trg +"engine: aria crash point: ddl_log_drop_before_binlog position: 2" +master-bin.000001 # Query # # use `test`; DROP TRIGGER t1_trg +master-bin.000002 # Query # # use `test`; DROP TRIGGER t2_trg /* some comment */ +"engine: aria crash point: ddl_log_drop_after_binlog position: 1" +t1.TRG +t2_trg.TRN +master-bin.000001 # Query # # use `test`; DROP TRIGGER t1_trg +"engine: aria crash point: ddl_log_drop_after_binlog position: 2" +master-bin.000001 # Query # # use `test`; DROP TRIGGER t1_trg +master-bin.000001 # Query # # use `test`; DROP TRIGGER t2_trg /* some comment */ + +# Test deleting not existing trigger +# +Warnings: +Note 1360 Trigger does not exist diff --git a/mysql-test/suite/atomic/drop_trigger.test b/mysql-test/suite/atomic/drop_trigger.test new file mode 100644 index 00000000000..24c44cd2f2a --- /dev/null +++ b/mysql-test/suite/atomic/drop_trigger.test @@ -0,0 +1,123 @@ +--source include/have_debug.inc +--source include/have_log_bin.inc +--source include/not_valgrind.inc + +# +# Testing of atomic drop with crashes in a lot of different places +# + +let $MYSQLD_DATADIR= `SELECT @@datadir`; + +let long_comment=`select repeat('a',16384)`; +let $engine_count=1; +let $engines='aria'; + +let $crash_count=6; +let $crash_points='ddl_log_drop_before_drop_trigger', 'ddl_log_drop_before_drop_trn','ddl_log_drop_after_drop_trigger', 'definition_file_after_create', 'ddl_log_drop_before_binlog', 'ddl_log_drop_after_binlog'; + +# Number of drops in the tested statement +let $drops=2; + +let $old_debug=`select @@debug_dbug`; + +let $e=0; +let $keep_include_silent=1; +let $grep_script=DROP TRIGGER; +--disable_query_log + +while ($e < $engine_count) +{ + inc $e; + let $engine=`select ELT($e, $engines)`; + let $default_engine=$engine; + let $extra_option=; + + if ($engine == "aria") + { + let $extra_option=transactional=1; + } + if ($engine == "aria_notrans") + { + let $default_engine="aria"; + let $extra_option=transactional=0; + } + let $c=0; + while ($c < $crash_count) + { + inc $c; + let $crash=`select ELT($c, $crash_points)`; + let $r=0; + while ($r < $drops) + { + inc $r; + + --eval set @@default_storage_engine=$default_engine + --eval create table t1 (a int not null, b int not null) $extra_option; + insert into t1 values(1,1); + flush tables; + delimiter |; + create trigger t1_trg before insert on t1 for each row + begin + if isnull(new.a) then + set new.a:= 1000; + end if; + end| + create trigger t2_trg before insert on t1 for each row + begin + if isnull(new.b) then + set new.b:= 2000; + end if; + end| + delimiter ;| + + RESET MASTER; + + echo "engine: $engine crash point: $crash position: $r"; + --exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + --disable_reconnect + --eval set @@debug_dbug="+d,$crash",@debug_crash_counter=$r + let $errno=0; + let $crashed=1; + --error 0,2013 + DROP TRIGGER t1_trg; + let $error=$errno; + if ($error == 0) + { + --error 0,2013 + --eval DROP TRIGGER t2_trg /* $long_comment */; + let $error=$errno; + } + --enable_reconnect + --source include/wait_until_connected_again.inc + --disable_query_log + --eval set @@debug_dbug="$old_debug" + + if ($error == 0) + { + echo "No crash!"; + } + # Check which tables still exists + --list_files $MYSQLD_DATADIR/test *TR* + + --let $binlog_file=master-bin.000001 + --source include/show_binlog_events.inc + if ($error) + { + --let $binlog_file=master-bin.000002 + --source include/show_binlog_events.inc + } + --disable_warnings + drop table if exists t1; + --enable_warnings + } + let long_comment=some comment; + } +} + +--echo +--echo # Test deleting not existing trigger +--echo # + +drop trigger if exists `t1_trg`; + +--enable_query_log |