mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
MDEV-23844 Atomic DROP TABLE (single table)
Logging logic: - Log tables, just before they are dropped, to the ddl log - After the last table for the statement is dropped, log an xid for the whole ddl log event In case of crash: - Remove first any active DROP TABLE events from the ddl log that matches xids found in binary log (this mean the drop was successful and was propery logged). - Loop over all active DROP TABLE events - Ensure that the table is completely dropped - Write a DROP TABLE entry to the binary log with the dropped tables. Other things: - Added code to ha_drop_table() to be able to tell the difference if a get_new_handler() failed because of out-of-memory or because the handler refused/was not able to create a a handler. This was needed to get sequences to work as sequences needs a share object to be passed to get_new_handler() - TC_LOG_BINLOG::recover() was changed to always collect Xid's from the binary log and always call ddl_log_close_binlogged_events(). This was needed to be able to collect DROP TABLE events with embedded Xid's (used by ddl log). - Added a new variable "$grep_script" to binlog filter to be able to find only rows that matches a regexp. - Had to adjust some test that changed because drop statements are a bit larger in the binary log than before (as we have to store the xid) Other things: - MDEV-25588 Atomic DDL: Binlog query event written upon recovery is corrupt fixed (in the original commit).
This commit is contained in:
115
mysql-test/suite/atomic/drop_sequence.test
Normal file
115
mysql-test/suite/atomic/drop_sequence.test
Normal file
@@ -0,0 +1,115 @@
|
||||
--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
|
||||
#
|
||||
|
||||
call mtr.add_suppression("InnoDB: .* does not exist in the InnoDB internal");
|
||||
let $MYSQLD_DATADIR= `SELECT @@datadir`;
|
||||
|
||||
let $engine_count=1;
|
||||
let $engines='aria';
|
||||
|
||||
let $crash_count=7;
|
||||
let $crash_points='ddl_log_drop_before_delete_table', 'ddl_log_drop_after_delete_table', 'ddl_log_drop_before_drop_trigger', 'ddl_log_drop_before_drop_trigger2', 'ddl_log_drop_after_drop_trigger', 'ddl_log_drop_before_binlog', 'ddl_log_drop_after_binlog';
|
||||
|
||||
# Number of drops in the tested statement
|
||||
let $drops=3;
|
||||
|
||||
let $old_debug=`select @@debug_dbug`;
|
||||
|
||||
let $e=0;
|
||||
let $keep_include_silent=1;
|
||||
let $grep_script=DROP TABLE;
|
||||
--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) $extra_option;
|
||||
--eval create table t2 (b int not null) $extra_option;
|
||||
create sequence ts;
|
||||
insert into t1 values(1);
|
||||
insert into t2 values(2);
|
||||
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 t2 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;
|
||||
--error 0,2013
|
||||
drop table t1,t2,ts;
|
||||
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 t*
|
||||
|
||||
--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
|
||||
}
|
||||
# Really drop the tables. The warnings will show what was dropped
|
||||
--disable_warnings
|
||||
drop table if exists t1,t2,ts;
|
||||
--enable_warnings
|
||||
}
|
||||
}
|
||||
}
|
||||
drop table if exists t1,t2,ts;
|
||||
|
||||
--enable_query_log
|
||||
Reference in New Issue
Block a user