mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
ffe7f19fa6
The purpose of this task is to ensure that CREATE TRIGGER is atomic When a trigger is created, we first create a trigger_name.TRN file and then create or update the table_name.TRG files. This is done by creating .TRN~ and .TRG~ files and replacing (or creating) the result files. The new logic is - Log CREATE TRIGGER to DDL log, with a marker if old trigger existsted - If old .TRN or .TRG files exists, make backup copies of these - Create the new .TRN and .TRG files as before - Remove the backups Crash recovery - If query has been logged to binary log: - delete any left over backup files - else - Delete any old .TRN~ or .TRG~ files - If there was orignally some triggers (old .TRG file existed) - If we crashed before creating all backup files - Delete existing backup files - else - Restore backup files - end - Delete .TRN and .TRG file (as there was no triggers before One benefit of the new code is that CREATE OR REPLACE TRIGGER is now totally atomic even if there existed an old trigger: Either the old trigger will be replaced or the old one will be left untouched. Other things: - If sql_create_definition_file() would fail, there could be memory leaks in CREATE TRIGGER, DROP TRIGGER or CREATE OR REPLACE TRIGGER. This is now fixed.
89 lines
1.9 KiB
Text
89 lines
1.9 KiB
Text
--source include/have_debug.inc
|
|
|
|
#
|
|
# Testing of atomic CREATE TRIGGER when write fails in create_definition_file
|
|
#
|
|
|
|
let $MYSQLD_DATADIR= `SELECT @@datadir`;
|
|
|
|
let $engine_count=1;
|
|
let $engines='aria';
|
|
let $old_debug=`select @@debug_dbug`;
|
|
|
|
let $e=0;
|
|
--disable_query_log
|
|
|
|
create table t1 (a int not null, b int not null);
|
|
insert into t1 values(1,1);
|
|
flush tables;
|
|
|
|
# sql_create_definition_file is called twice per CREATE TRIGGER and 1 more
|
|
# in case we drop an existing trigger, so we need to test 3*2 +1 failures
|
|
# and also when there is no failures (= 8)
|
|
let $try_count=8;
|
|
|
|
let $r=0;
|
|
while ($r < $try_count)
|
|
{
|
|
inc $r;
|
|
|
|
echo "position: $r";
|
|
--eval set @@debug_dbug="+d,definition_file_simulate_write_error",@debug_error_counter=$r;
|
|
let $errno=0;
|
|
delimiter |;
|
|
--error 0,3
|
|
create trigger t1_trg before insert on t1 for each row
|
|
begin
|
|
if isnull(new.a) then
|
|
set new.a:= 1000;
|
|
end if;
|
|
end|
|
|
delimiter ;|
|
|
let $error=$errno;
|
|
if ($error == 0)
|
|
{
|
|
delimiter |;
|
|
--error 0,3
|
|
create or replace trigger t2_trg before insert on t1 for each row
|
|
begin
|
|
if isnull(new.b) then
|
|
set new.b:= 2000;
|
|
end if;
|
|
end|
|
|
delimiter ;|
|
|
let $error=$errno;
|
|
}
|
|
if ($error == 0)
|
|
{
|
|
delimiter |;
|
|
--error 0,3
|
|
create or replace trigger t2_trg before insert on t1 for each row
|
|
begin
|
|
if isnull(new.b) then
|
|
set new.b:= 3000;
|
|
end if;
|
|
end|
|
|
delimiter ;|
|
|
let $error=$errno;
|
|
}
|
|
--eval set @@debug_dbug="$old_debug"
|
|
|
|
# Check which tables still exists
|
|
--list_files $MYSQLD_DATADIR/test *TR*
|
|
--list_files $MYSQLD_DATADIR/test *sql*
|
|
|
|
--replace_column 7 #
|
|
--error 0,ER_TRG_DOES_NOT_EXIST
|
|
SHOW CREATE TRIGGER t1_trg;
|
|
--replace_column 7 #
|
|
--error 0,ER_TRG_DOES_NOT_EXIST
|
|
SHOW CREATE TRIGGER t2_trg;
|
|
--disable_warnings
|
|
drop trigger if exists t1_trg;
|
|
drop trigger if exists t2_trg;
|
|
--enable_warnings
|
|
}
|
|
|
|
drop table t1;
|
|
|
|
--enable_query_log
|