mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +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:
@ -56,6 +56,9 @@
|
|||||||
#
|
#
|
||||||
# $filter_script
|
# $filter_script
|
||||||
# If set, rows matching this regexp will be filtered out
|
# If set, rows matching this regexp will be filtered out
|
||||||
|
#
|
||||||
|
# $grep_script
|
||||||
|
# If set, only include rows matching this regexp
|
||||||
|
|
||||||
--let $include_filename= filter_file.inc
|
--let $include_filename= filter_file.inc
|
||||||
--source include/begin_include_file.inc
|
--source include/begin_include_file.inc
|
||||||
@ -71,6 +74,7 @@ if ($rpl_debug)
|
|||||||
--let _FF_PRE_SCRIPT= $pre_script
|
--let _FF_PRE_SCRIPT= $pre_script
|
||||||
--let _FF_SCRIPT= $script
|
--let _FF_SCRIPT= $script
|
||||||
--let _FF_FILTER_SCRIPT= $filter_script
|
--let _FF_FILTER_SCRIPT= $filter_script
|
||||||
|
--let _FF_GREP_SCRIPT= $grep_script
|
||||||
--let _FF_INPUT_FILE= $input_file
|
--let _FF_INPUT_FILE= $input_file
|
||||||
--let _FF_OUTPUT_FILE= $output_file
|
--let _FF_OUTPUT_FILE= $output_file
|
||||||
--let _FF_SELECT_COLUMNS= $select_columns
|
--let _FF_SELECT_COLUMNS= $select_columns
|
||||||
@ -85,6 +89,7 @@ perl;
|
|||||||
$pre_script =~ s/DOLLAR/\$/g;
|
$pre_script =~ s/DOLLAR/\$/g;
|
||||||
my $script = $ENV{'_FF_SCRIPT'};
|
my $script = $ENV{'_FF_SCRIPT'};
|
||||||
my $filter_script = $ENV{'_FF_FILTER_SCRIPT'};
|
my $filter_script = $ENV{'_FF_FILTER_SCRIPT'};
|
||||||
|
my $grep_script = $ENV{'_FF_GREP_SCRIPT'};
|
||||||
$script =~ s/DOLLAR/\$/g;
|
$script =~ s/DOLLAR/\$/g;
|
||||||
my $input_file = $ENV{'_FF_INPUT_FILE'};
|
my $input_file = $ENV{'_FF_INPUT_FILE'};
|
||||||
my $output_file = $ENV{'_FF_OUTPUT_FILE'};
|
my $output_file = $ENV{'_FF_OUTPUT_FILE'};
|
||||||
@ -129,7 +134,8 @@ perl;
|
|||||||
{
|
{
|
||||||
' . $script . '
|
' . $script . '
|
||||||
}
|
}
|
||||||
if (!$filter_script || ! m/$filter_script/)
|
if ((!$filter_script || ! m/$filter_script/) &&
|
||||||
|
(!$grep_script || m/$grep_script/))
|
||||||
{
|
{
|
||||||
$filtered_contents .= $_."\n";
|
$filtered_contents .= $_."\n";
|
||||||
}
|
}
|
||||||
|
104
mysql-test/suite/atomic/drop_sequence.result
Normal file
104
mysql-test/suite/atomic/drop_sequence.result
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
call mtr.add_suppression("InnoDB: .* does not exist in the InnoDB internal");
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_delete_table position: 1"
|
||||||
|
t2.MAD
|
||||||
|
t2.MAI
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
ts.MAD
|
||||||
|
ts.MAI
|
||||||
|
ts.frm
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_delete_table position: 2"
|
||||||
|
ts.MAD
|
||||||
|
ts.MAI
|
||||||
|
ts.frm
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_delete_table position: 3"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2`,`test`.`ts` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_after_delete_table position: 1"
|
||||||
|
t2.MAD
|
||||||
|
t2.MAI
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
ts.MAD
|
||||||
|
ts.MAI
|
||||||
|
ts.frm
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_after_delete_table position: 2"
|
||||||
|
ts.MAD
|
||||||
|
ts.MAI
|
||||||
|
ts.frm
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_after_delete_table position: 3"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2`,`test`.`ts` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_drop_trigger position: 1"
|
||||||
|
t2.MAD
|
||||||
|
t2.MAI
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
ts.MAD
|
||||||
|
ts.MAI
|
||||||
|
ts.frm
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_drop_trigger position: 2"
|
||||||
|
ts.MAD
|
||||||
|
ts.MAI
|
||||||
|
ts.frm
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_drop_trigger position: 3"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2`,`test`.`ts` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_drop_trigger2 position: 1"
|
||||||
|
t2.MAD
|
||||||
|
t2.MAI
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
ts.MAD
|
||||||
|
ts.MAI
|
||||||
|
ts.frm
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_drop_trigger2 position: 2"
|
||||||
|
ts.MAD
|
||||||
|
ts.MAI
|
||||||
|
ts.frm
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_drop_trigger2 position: 3"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2`,`test`.`ts` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_after_drop_trigger position: 1"
|
||||||
|
t2.MAD
|
||||||
|
t2.MAI
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
ts.MAD
|
||||||
|
ts.MAI
|
||||||
|
ts.frm
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_after_drop_trigger position: 2"
|
||||||
|
ts.MAD
|
||||||
|
ts.MAI
|
||||||
|
ts.frm
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_after_drop_trigger position: 3"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2`,`test`.`ts` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_binlog position: 1"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2`,`test`.`ts` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_binlog position: 2"
|
||||||
|
"No crash!"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2`,`ts` /* generated by server */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_binlog position: 3"
|
||||||
|
"No crash!"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2`,`ts` /* generated by server */
|
||||||
|
"engine: aria crash point: ddl_log_drop_after_binlog position: 1"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2`,`ts` /* generated by server */
|
||||||
|
"engine: aria crash point: ddl_log_drop_after_binlog position: 2"
|
||||||
|
"No crash!"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2`,`ts` /* generated by server */
|
||||||
|
"engine: aria crash point: ddl_log_drop_after_binlog position: 3"
|
||||||
|
"No crash!"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2`,`ts` /* generated by server */
|
||||||
|
Warnings:
|
||||||
|
Note 1051 Unknown table 'test.t1,test.t2,test.ts'
|
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
|
273
mysql-test/suite/atomic/drop_table.result
Normal file
273
mysql-test/suite/atomic/drop_table.result
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
call mtr.add_suppression("InnoDB: .* does not exist in the InnoDB internal");
|
||||||
|
"engine: myisam crash point: ddl_log_drop_before_delete_table position: 1"
|
||||||
|
t2.MYD
|
||||||
|
t2.MYI
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: myisam crash point: ddl_log_drop_before_delete_table position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: myisam crash point: ddl_log_drop_after_delete_table position: 1"
|
||||||
|
t2.MYD
|
||||||
|
t2.MYI
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: myisam crash point: ddl_log_drop_after_delete_table position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: myisam crash point: ddl_log_drop_before_drop_trigger position: 1"
|
||||||
|
t2.MYD
|
||||||
|
t2.MYI
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: myisam crash point: ddl_log_drop_before_drop_trigger position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: myisam crash point: ddl_log_drop_before_drop_trigger2 position: 1"
|
||||||
|
t2.MYD
|
||||||
|
t2.MYI
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: myisam crash point: ddl_log_drop_before_drop_trigger2 position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: myisam crash point: ddl_log_drop_after_drop_trigger position: 1"
|
||||||
|
t2.MYD
|
||||||
|
t2.MYI
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: myisam crash point: ddl_log_drop_after_drop_trigger position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: myisam crash point: ddl_log_drop_before_binlog position: 1"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: myisam crash point: ddl_log_drop_before_binlog position: 2"
|
||||||
|
"No crash!"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2` /* generated by server */
|
||||||
|
"engine: myisam crash point: ddl_log_drop_after_binlog position: 1"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2` /* generated by server */
|
||||||
|
"engine: myisam crash point: ddl_log_drop_after_binlog position: 2"
|
||||||
|
"No crash!"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2` /* generated by server */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_delete_table position: 1"
|
||||||
|
t2.MAD
|
||||||
|
t2.MAI
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_delete_table position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_after_delete_table position: 1"
|
||||||
|
t2.MAD
|
||||||
|
t2.MAI
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_after_delete_table position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_drop_trigger position: 1"
|
||||||
|
t2.MAD
|
||||||
|
t2.MAI
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_drop_trigger position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_drop_trigger2 position: 1"
|
||||||
|
t2.MAD
|
||||||
|
t2.MAI
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_drop_trigger2 position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_after_drop_trigger position: 1"
|
||||||
|
t2.MAD
|
||||||
|
t2.MAI
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_after_drop_trigger position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_binlog position: 1"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_binlog position: 2"
|
||||||
|
"No crash!"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2` /* generated by server */
|
||||||
|
"engine: aria crash point: ddl_log_drop_after_binlog position: 1"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2` /* generated by server */
|
||||||
|
"engine: aria crash point: ddl_log_drop_after_binlog position: 2"
|
||||||
|
"No crash!"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2` /* generated by server */
|
||||||
|
"engine: aria_notrans crash point: ddl_log_drop_before_delete_table position: 1"
|
||||||
|
t2.MAD
|
||||||
|
t2.MAI
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: aria_notrans crash point: ddl_log_drop_before_delete_table position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: aria_notrans crash point: ddl_log_drop_after_delete_table position: 1"
|
||||||
|
t2.MAD
|
||||||
|
t2.MAI
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: aria_notrans crash point: ddl_log_drop_after_delete_table position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: aria_notrans crash point: ddl_log_drop_before_drop_trigger position: 1"
|
||||||
|
t2.MAD
|
||||||
|
t2.MAI
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: aria_notrans crash point: ddl_log_drop_before_drop_trigger position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: aria_notrans crash point: ddl_log_drop_before_drop_trigger2 position: 1"
|
||||||
|
t2.MAD
|
||||||
|
t2.MAI
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: aria_notrans crash point: ddl_log_drop_before_drop_trigger2 position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: aria_notrans crash point: ddl_log_drop_after_drop_trigger position: 1"
|
||||||
|
t2.MAD
|
||||||
|
t2.MAI
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: aria_notrans crash point: ddl_log_drop_after_drop_trigger position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: aria_notrans crash point: ddl_log_drop_before_binlog position: 1"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: aria_notrans crash point: ddl_log_drop_before_binlog position: 2"
|
||||||
|
"No crash!"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2` /* generated by server */
|
||||||
|
"engine: aria_notrans crash point: ddl_log_drop_after_binlog position: 1"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2` /* generated by server */
|
||||||
|
"engine: aria_notrans crash point: ddl_log_drop_after_binlog position: 2"
|
||||||
|
"No crash!"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2` /* generated by server */
|
||||||
|
"engine: innodb crash point: ddl_log_drop_before_delete_table position: 1"
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2.ibd
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: innodb crash point: ddl_log_drop_before_delete_table position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: innodb crash point: ddl_log_drop_after_delete_table position: 1"
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2.ibd
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: innodb crash point: ddl_log_drop_after_delete_table position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: innodb crash point: ddl_log_drop_before_drop_trigger position: 1"
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2.ibd
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: innodb crash point: ddl_log_drop_before_drop_trigger position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: innodb crash point: ddl_log_drop_before_drop_trigger2 position: 1"
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2.ibd
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: innodb crash point: ddl_log_drop_before_drop_trigger2 position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: innodb crash point: ddl_log_drop_after_drop_trigger position: 1"
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2.ibd
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: innodb crash point: ddl_log_drop_after_drop_trigger position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: innodb crash point: ddl_log_drop_before_binlog position: 1"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: innodb crash point: ddl_log_drop_before_binlog position: 2"
|
||||||
|
"No crash!"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2` /* generated by server */
|
||||||
|
"engine: innodb crash point: ddl_log_drop_after_binlog position: 1"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2` /* generated by server */
|
||||||
|
"engine: innodb crash point: ddl_log_drop_after_binlog position: 2"
|
||||||
|
"No crash!"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2` /* generated by server */
|
||||||
|
"engine: csv crash point: ddl_log_drop_before_delete_table position: 1"
|
||||||
|
t2.CSM
|
||||||
|
t2.CSV
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: csv crash point: ddl_log_drop_before_delete_table position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: csv crash point: ddl_log_drop_after_delete_table position: 1"
|
||||||
|
t2.CSM
|
||||||
|
t2.CSV
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: csv crash point: ddl_log_drop_after_delete_table position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: csv crash point: ddl_log_drop_before_drop_trigger position: 1"
|
||||||
|
t2.CSM
|
||||||
|
t2.CSV
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: csv crash point: ddl_log_drop_before_drop_trigger position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: csv crash point: ddl_log_drop_before_drop_trigger2 position: 1"
|
||||||
|
t2.CSM
|
||||||
|
t2.CSV
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: csv crash point: ddl_log_drop_before_drop_trigger2 position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: csv crash point: ddl_log_drop_after_drop_trigger position: 1"
|
||||||
|
t2.CSM
|
||||||
|
t2.CSV
|
||||||
|
t2.TRG
|
||||||
|
t2.frm
|
||||||
|
t2_trg.TRN
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
|
||||||
|
"engine: csv crash point: ddl_log_drop_after_drop_trigger position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: csv crash point: ddl_log_drop_before_binlog position: 1"
|
||||||
|
master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1`,`test`.`t2` /* generated by ddl recovery */
|
||||||
|
"engine: csv crash point: ddl_log_drop_before_binlog position: 2"
|
||||||
|
"No crash!"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2` /* generated by server */
|
||||||
|
"engine: csv crash point: ddl_log_drop_after_binlog position: 1"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2` /* generated by server */
|
||||||
|
"engine: csv crash point: ddl_log_drop_after_binlog position: 2"
|
||||||
|
"No crash!"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2` /* generated by server */
|
||||||
|
Warnings:
|
||||||
|
Note 1051 Unknown table 'test.t1,test.t2'
|
116
mysql-test/suite/atomic/drop_table.test
Normal file
116
mysql-test/suite/atomic/drop_table.test
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
--source include/have_debug.inc
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
--source include/have_csv.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=5;
|
||||||
|
let $engines='myisam','aria','aria_notrans','innodb','csv';
|
||||||
|
|
||||||
|
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=2;
|
||||||
|
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
--enable_warnings
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
drop table if exists t1,t2;
|
||||||
|
|
||||||
|
--enable_query_log
|
20
mysql-test/suite/atomic/drop_view.result
Normal file
20
mysql-test/suite/atomic/drop_view.result
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
"engine: aria crash point: ddl_log_drop_before_delete_view position: 1"
|
||||||
|
v2.frm
|
||||||
|
master-bin.000002 # Query # # DROP VIEW IF EXISTS `test`.`v1` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_delete_view position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP VIEW IF EXISTS `test`.`v1`,`test`.`v2` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_after_delete_view position: 1"
|
||||||
|
v2.frm
|
||||||
|
master-bin.000002 # Query # # DROP VIEW IF EXISTS `test`.`v1` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_after_delete_view position: 2"
|
||||||
|
master-bin.000002 # Query # # DROP VIEW IF EXISTS `test`.`v1`,`test`.`v2` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_binlog position: 1"
|
||||||
|
master-bin.000002 # Query # # DROP VIEW IF EXISTS `test`.`v1`,`test`.`v2` /* generated by ddl recovery */
|
||||||
|
"engine: aria crash point: ddl_log_drop_before_binlog position: 2"
|
||||||
|
"No crash!"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP VIEW v1,v2
|
||||||
|
"engine: aria crash point: ddl_log_drop_after_binlog position: 1"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP VIEW v1,v2
|
||||||
|
"engine: aria crash point: ddl_log_drop_after_binlog position: 2"
|
||||||
|
"No crash!"
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP VIEW v1,v2
|
98
mysql-test/suite/atomic/drop_view.test
Normal file
98
mysql-test/suite/atomic/drop_view.test
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
--source include/have_debug.inc
|
||||||
|
--source include/have_log_bin.inc
|
||||||
|
--source include/not_valgrind.inc
|
||||||
|
|
||||||
|
#
|
||||||
|
# Testing of atomic drop of view with crashes in a lot of different places
|
||||||
|
#
|
||||||
|
|
||||||
|
let $MYSQLD_DATADIR= `SELECT @@datadir`;
|
||||||
|
let $engine_count=1;
|
||||||
|
let $engines='aria';
|
||||||
|
|
||||||
|
let $crash_count=4;
|
||||||
|
let $crash_points='ddl_log_drop_before_delete_view', 'ddl_log_drop_after_delete_view', '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 ;
|
||||||
|
--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;
|
||||||
|
}
|
||||||
|
|
||||||
|
--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;
|
||||||
|
insert into t1 values(1);
|
||||||
|
insert into t2 values(2);
|
||||||
|
flush tables;
|
||||||
|
|
||||||
|
let $c=0;
|
||||||
|
while ($c < $crash_count)
|
||||||
|
{
|
||||||
|
inc $c;
|
||||||
|
let $crash=`select ELT($c, $crash_points)`;
|
||||||
|
let $r=0;
|
||||||
|
while ($r < $drops)
|
||||||
|
{
|
||||||
|
inc $r;
|
||||||
|
create view v1 as select * from t1;
|
||||||
|
create view v2 as select * from t1;
|
||||||
|
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 VIEW v1,v2;
|
||||||
|
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 v*
|
||||||
|
--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 views
|
||||||
|
--disable_warnings
|
||||||
|
drop view if exists v1,v2;
|
||||||
|
--enable_warnings
|
||||||
|
}
|
||||||
|
}
|
||||||
|
drop table t1,t2;
|
||||||
|
}
|
||||||
|
|
||||||
|
--enable_query_log
|
@ -506,6 +506,7 @@ master-bin.000001 # Query # # COMMIT
|
|||||||
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
master-bin.000001 # Query # # use `mysql`; DELETE FROM db WHERE host='localhost' AND user='@#@'
|
master-bin.000001 # Query # # use `mysql`; DELETE FROM db WHERE host='localhost' AND user='@#@'
|
||||||
master-bin.000001 # Query # # COMMIT
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Rotate # # master-bin.000002;pos=POS
|
||||||
drop table t1,t2,t3,tt1;
|
drop table t1,t2,t3,tt1;
|
||||||
reset master;
|
reset master;
|
||||||
create table t1 (a int not null auto_increment, primary key (a)) engine=myisam;
|
create table t1 (a int not null auto_increment, primary key (a)) engine=myisam;
|
||||||
|
@ -39,9 +39,9 @@ stop slave 'master1';
|
|||||||
|
|
||||||
--let $datadir = `SELECT @@datadir`
|
--let $datadir = `SELECT @@datadir`
|
||||||
|
|
||||||
let read_master_log_pos=`select $binlog_start_pos + 590`;
|
let read_master_log_pos=`select $binlog_start_pos + 599`;
|
||||||
let relay_log_pos=`select 2*$binlog_start_pos + 634`;
|
let relay_log_pos=`select 2*$binlog_start_pos + 643`;
|
||||||
let relay_log_space=`select 3*$binlog_start_pos + 696`;
|
let relay_log_space=`select 3*$binlog_start_pos + 705`;
|
||||||
--replace_result $SERVER_MYPORT_1 MYPORT_1 $read_master_log_pos <read_master_log_pos> $relay_log_pos <relay_log_pos> $relay_log_space <relay_log_space>
|
--replace_result $SERVER_MYPORT_1 MYPORT_1 $read_master_log_pos <read_master_log_pos> $relay_log_pos <relay_log_pos> $relay_log_space <relay_log_space>
|
||||||
show slave 'master1' status;
|
show slave 'master1' status;
|
||||||
--list_files $datadir mysqld*
|
--list_files $datadir mysqld*
|
||||||
|
305
sql/ddl_log.cc
305
sql/ddl_log.cc
@ -26,6 +26,7 @@
|
|||||||
#include "sql_statistics.h" // rename_table_in_stats_tables
|
#include "sql_statistics.h" // rename_table_in_stats_tables
|
||||||
#include "sql_view.h" // mysql_rename_view()
|
#include "sql_view.h" // mysql_rename_view()
|
||||||
#include "strfunc.h" // strconvert
|
#include "strfunc.h" // strconvert
|
||||||
|
#include "sql_show.h" // append_identifier()
|
||||||
#include <mysys_err.h> // EE_LINK
|
#include <mysys_err.h> // EE_LINK
|
||||||
|
|
||||||
|
|
||||||
@ -81,17 +82,19 @@ uchar ddl_log_file_magic[]=
|
|||||||
|
|
||||||
/* Action names for ddl_log_action_code */
|
/* Action names for ddl_log_action_code */
|
||||||
|
|
||||||
const char *ddl_log_action_name[DDL_LOG_LAST_ACTION]=
|
const char *ddl_log_action_name[]=
|
||||||
{
|
{
|
||||||
"Unknown", "partitioning delete", "partitioning rename",
|
"Unknown", "partitioning delete", "partitioning rename",
|
||||||
"partitioning replace", "partitioning exchange",
|
"partitioning replace", "partitioning exchange",
|
||||||
"rename table", "rename view"
|
"rename table", "rename view",
|
||||||
|
"initialize drop table", "drop table",
|
||||||
|
"initialize drop view", "drop view"
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Number of phases per entry */
|
/* Number of phases per entry */
|
||||||
const uchar ddl_log_entry_phases[DDL_LOG_LAST_ACTION]=
|
const uchar ddl_log_entry_phases[DDL_LOG_LAST_ACTION]=
|
||||||
{
|
{
|
||||||
1, 1, 2, 3, 4, 1
|
0, 1, 1, 2, 3, 4, 1, 1, 3, 1, 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -109,6 +112,7 @@ struct st_global_ddl_log
|
|||||||
};
|
};
|
||||||
|
|
||||||
st_global_ddl_log global_ddl_log;
|
st_global_ddl_log global_ddl_log;
|
||||||
|
String ddl_drop_query; // Used during startup recovery
|
||||||
|
|
||||||
mysql_mutex_t LOCK_gdl;
|
mysql_mutex_t LOCK_gdl;
|
||||||
|
|
||||||
@ -285,6 +289,19 @@ static bool update_phase(uint entry_pos, uchar phase)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool update_next_entry_pos(uint entry_pos, uint next_entry)
|
||||||
|
{
|
||||||
|
uchar buff[4];
|
||||||
|
DBUG_ENTER("update_next_entry_pos");
|
||||||
|
|
||||||
|
int4store(buff, next_entry);
|
||||||
|
DBUG_RETURN(mysql_file_pwrite(global_ddl_log.file_id, buff, sizeof(buff),
|
||||||
|
global_ddl_log.io_size * entry_pos +
|
||||||
|
DDL_LOG_NEXT_ENTRY_POS,
|
||||||
|
MYF(MY_WME | MY_NABP)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool update_xid(uint entry_pos, ulonglong xid)
|
static bool update_xid(uint entry_pos, ulonglong xid)
|
||||||
{
|
{
|
||||||
uchar buff[8];
|
uchar buff[8];
|
||||||
@ -1130,6 +1147,122 @@ static int ddl_log_execute_action(THD *thd, MEM_ROOT *mem_root,
|
|||||||
(void) update_phase(entry_pos, DDL_LOG_FINAL_PHASE);
|
(void) update_phase(entry_pos, DDL_LOG_FINAL_PHASE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case DDL_LOG_DROP_TABLE_INIT_ACTION:
|
||||||
|
{
|
||||||
|
LEX_CSTRING *comment= &ddl_log_entry->tmp_name;
|
||||||
|
ddl_drop_query.length(0);
|
||||||
|
ddl_drop_query.set_charset(system_charset_info);
|
||||||
|
ddl_drop_query.append(STRING_WITH_LEN("DROP TABLE IF EXISTS "));
|
||||||
|
if (comment->length)
|
||||||
|
{
|
||||||
|
ddl_drop_query.append(comment);
|
||||||
|
ddl_drop_query.append(' ');
|
||||||
|
}
|
||||||
|
/* We don't increment phase as we want to retry this in case of crash */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DDL_LOG_DROP_TABLE_ACTION:
|
||||||
|
{
|
||||||
|
LEX_CSTRING db, table, path;
|
||||||
|
db= ddl_log_entry->db;
|
||||||
|
table= ddl_log_entry->name;
|
||||||
|
/* Note that path is without .frm extension */
|
||||||
|
path= ddl_log_entry->tmp_name;
|
||||||
|
|
||||||
|
switch (ddl_log_entry->phase) {
|
||||||
|
case DDL_DROP_PHASE_TABLE:
|
||||||
|
if (hton)
|
||||||
|
{
|
||||||
|
if ((error= hton->drop_table(hton, path.str)))
|
||||||
|
{
|
||||||
|
if (!non_existing_table_error(error))
|
||||||
|
break;
|
||||||
|
error= -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error= ha_delete_table_force(thd, path.str, &db, &table);
|
||||||
|
if (error <= 0)
|
||||||
|
{
|
||||||
|
/* Not found or already deleted. Delete .frm if it exists */
|
||||||
|
strxnmov(to_path, sizeof(to_path)-1, path.str, reg_ext, NullS);
|
||||||
|
mysql_file_delete(key_file_frm, to_path, MYF(MY_WME|MY_IGNORE_ENOENT));
|
||||||
|
}
|
||||||
|
if (ddl_log_increment_phase_no_lock(entry_pos))
|
||||||
|
break;
|
||||||
|
(void) ddl_log_sync_no_lock();
|
||||||
|
/* Fall through */
|
||||||
|
case DDL_DROP_PHASE_TRIGGER:
|
||||||
|
Table_triggers_list::drop_all_triggers(thd, &db, &table,
|
||||||
|
MYF(MY_WME | MY_IGNORE_ENOENT));
|
||||||
|
if (ddl_log_increment_phase_no_lock(entry_pos))
|
||||||
|
break;
|
||||||
|
(void) ddl_log_sync_no_lock();
|
||||||
|
/* Fall through */
|
||||||
|
|
||||||
|
case DDL_DROP_PHASE_BINLOG:
|
||||||
|
append_identifier(thd, &ddl_drop_query, &db);
|
||||||
|
ddl_drop_query.append('.');
|
||||||
|
append_identifier(thd, &ddl_drop_query, &table);
|
||||||
|
ddl_drop_query.append(',');
|
||||||
|
/* We don't increment phase as we want to retry this in case of crash */
|
||||||
|
|
||||||
|
if (!ddl_log_entry->next_entry && mysql_bin_log.is_open())
|
||||||
|
{
|
||||||
|
/* Last drop table. Write query to binlog */
|
||||||
|
LEX_CSTRING end_comment=
|
||||||
|
{ STRING_WITH_LEN(" /* generated by ddl recovery */")};
|
||||||
|
ddl_drop_query.length(ddl_drop_query.length()-1);
|
||||||
|
ddl_drop_query.append(&end_comment);
|
||||||
|
|
||||||
|
mysql_mutex_unlock(&LOCK_gdl);
|
||||||
|
(void) thd->binlog_query(THD::STMT_QUERY_TYPE, ddl_drop_query.ptr(),
|
||||||
|
ddl_drop_query.length(), TRUE, FALSE,
|
||||||
|
FALSE, 0);
|
||||||
|
mysql_mutex_lock(&LOCK_gdl);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DDL_LOG_DROP_VIEW_INIT_ACTION:
|
||||||
|
{
|
||||||
|
ddl_drop_query.length(0);
|
||||||
|
ddl_drop_query.set_charset(system_charset_info);
|
||||||
|
ddl_drop_query.append(STRING_WITH_LEN("DROP VIEW IF EXISTS "));
|
||||||
|
/* We don't increment phase as we want to retry this in case of crash */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DDL_LOG_DROP_VIEW_ACTION:
|
||||||
|
{
|
||||||
|
LEX_CSTRING db, table, path;
|
||||||
|
db= ddl_log_entry->db;
|
||||||
|
table= ddl_log_entry->name;
|
||||||
|
/* Note that for views path is WITH .frm extension */
|
||||||
|
path= ddl_log_entry->tmp_name;
|
||||||
|
|
||||||
|
mysql_file_delete(key_file_frm, path.str, MYF(MY_WME|MY_IGNORE_ENOENT));
|
||||||
|
append_identifier(thd, &ddl_drop_query, &db);
|
||||||
|
ddl_drop_query.append('.');
|
||||||
|
append_identifier(thd, &ddl_drop_query, &table);
|
||||||
|
ddl_drop_query.append(',');
|
||||||
|
|
||||||
|
if (!ddl_log_entry->next_entry)
|
||||||
|
{
|
||||||
|
/* Last drop view. Write query to binlog */
|
||||||
|
LEX_CSTRING end_comment=
|
||||||
|
{ STRING_WITH_LEN(" /* generated by ddl recovery */")};
|
||||||
|
ddl_drop_query.length(ddl_drop_query.length()-1);
|
||||||
|
ddl_drop_query.append(&end_comment);
|
||||||
|
|
||||||
|
mysql_mutex_unlock(&LOCK_gdl);
|
||||||
|
(void) thd->binlog_query(THD::STMT_QUERY_TYPE, ddl_drop_query.ptr(),
|
||||||
|
ddl_drop_query.length(), TRUE, FALSE,
|
||||||
|
FALSE, 0);
|
||||||
|
mysql_mutex_lock(&LOCK_gdl);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
break;
|
break;
|
||||||
@ -1298,9 +1431,14 @@ bool ddl_log_write_entry(DDL_LOG_ENTRY *ddl_log_entry,
|
|||||||
uchar *pos, *end;
|
uchar *pos, *end;
|
||||||
DBUG_ENTER("ddl_log_write_entry");
|
DBUG_ENTER("ddl_log_write_entry");
|
||||||
|
|
||||||
|
*active_entry= 0;
|
||||||
mysql_mutex_assert_owner(&LOCK_gdl);
|
mysql_mutex_assert_owner(&LOCK_gdl);
|
||||||
if (!global_ddl_log.open)
|
DBUG_ASSERT(global_ddl_log.open);
|
||||||
|
if (unlikely(!global_ddl_log.open))
|
||||||
|
{
|
||||||
|
my_error(ER_INTERNAL_ERROR, MYF(0), "ddl log not initialized");
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
ddl_log_entry->entry_type= DDL_LOG_ENTRY_CODE;
|
ddl_log_entry->entry_type= DDL_LOG_ENTRY_CODE;
|
||||||
set_global_from_ddl_log_entry(ddl_log_entry);
|
set_global_from_ddl_log_entry(ddl_log_entry);
|
||||||
@ -1383,7 +1521,7 @@ bool ddl_log_write_execute_entry(uint first_entry,
|
|||||||
if (ddl_log_get_free_entry(active_entry))
|
if (ddl_log_get_free_entry(active_entry))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
got_free_entry= TRUE;
|
got_free_entry= TRUE;
|
||||||
}
|
}
|
||||||
if (write_ddl_log_file_entry((*active_entry)->entry_pos))
|
if (write_ddl_log_file_entry((*active_entry)->entry_pos))
|
||||||
{
|
{
|
||||||
if (got_free_entry)
|
if (got_free_entry)
|
||||||
@ -1509,6 +1647,7 @@ bool ddl_log_close_binlogged_events(HASH *xids)
|
|||||||
{
|
{
|
||||||
if (read_ddl_log_entry(i, &ddl_log_entry))
|
if (read_ddl_log_entry(i, &ddl_log_entry))
|
||||||
break; // Read error. Stop reading
|
break; // Read error. Stop reading
|
||||||
|
DBUG_PRINT("xid",("xid: %llu", ddl_log_entry.xid));
|
||||||
if (ddl_log_entry.entry_type == DDL_LOG_EXECUTE_CODE &&
|
if (ddl_log_entry.entry_type == DDL_LOG_EXECUTE_CODE &&
|
||||||
ddl_log_entry.xid != 0 &&
|
ddl_log_entry.xid != 0 &&
|
||||||
my_hash_search(xids, (uchar*) &ddl_log_entry.xid,
|
my_hash_search(xids, (uchar*) &ddl_log_entry.xid,
|
||||||
@ -1562,6 +1701,7 @@ int ddl_log_execute_recovery()
|
|||||||
thd->store_globals();
|
thd->store_globals();
|
||||||
thd->init(); // Needed for error messages
|
thd->init(); // Needed for error messages
|
||||||
thd->log_all_errors= (global_system_variables.log_warnings >= 3);
|
thd->log_all_errors= (global_system_variables.log_warnings >= 3);
|
||||||
|
ddl_drop_query.free();
|
||||||
|
|
||||||
thd->set_query(recover_query_string, strlen(recover_query_string));
|
thd->set_query(recover_query_string, strlen(recover_query_string));
|
||||||
|
|
||||||
@ -1599,6 +1739,7 @@ int ddl_log_execute_recovery()
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ddl_drop_query.free();
|
||||||
close_ddl_log();
|
close_ddl_log();
|
||||||
mysql_mutex_unlock(&LOCK_gdl);
|
mysql_mutex_unlock(&LOCK_gdl);
|
||||||
thd->reset_query();
|
thd->reset_query();
|
||||||
@ -1682,6 +1823,7 @@ void ddl_log_release_entries(DDL_LOG_STATE *ddl_log_state)
|
|||||||
next= log_entry->next_active_log_entry;
|
next= log_entry->next_active_log_entry;
|
||||||
ddl_log_release_memory_entry(log_entry);
|
ddl_log_release_memory_entry(log_entry);
|
||||||
}
|
}
|
||||||
|
ddl_log_state->list= 0;
|
||||||
|
|
||||||
if (ddl_log_state->execute_entry)
|
if (ddl_log_state->execute_entry)
|
||||||
{
|
{
|
||||||
@ -1779,6 +1921,33 @@ bool ddl_log_update_xid(DDL_LOG_STATE *state, ulonglong xid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Write ddl_log_entry and write or update ddl_execute_entry
|
||||||
|
*/
|
||||||
|
|
||||||
|
static bool ddl_log_write(DDL_LOG_STATE *ddl_state,
|
||||||
|
DDL_LOG_ENTRY *ddl_log_entry)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
DDL_LOG_MEMORY_ENTRY *log_entry;
|
||||||
|
DBUG_ENTER("ddl_log_write");
|
||||||
|
|
||||||
|
mysql_mutex_lock(&LOCK_gdl);
|
||||||
|
error= ((ddl_log_write_entry(ddl_log_entry, &log_entry)) ||
|
||||||
|
ddl_log_write_execute_entry(log_entry->entry_pos,
|
||||||
|
&ddl_state->execute_entry));
|
||||||
|
mysql_mutex_unlock(&LOCK_gdl);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
if (log_entry)
|
||||||
|
ddl_log_release_memory_entry(log_entry);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
add_log_entry(ddl_state, log_entry);
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Logging of rename table
|
Logging of rename table
|
||||||
*/
|
*/
|
||||||
@ -1791,13 +1960,10 @@ bool ddl_log_rename_table(THD *thd, DDL_LOG_STATE *ddl_state,
|
|||||||
const LEX_CSTRING *new_alias)
|
const LEX_CSTRING *new_alias)
|
||||||
{
|
{
|
||||||
DDL_LOG_ENTRY ddl_log_entry;
|
DDL_LOG_ENTRY ddl_log_entry;
|
||||||
DDL_LOG_MEMORY_ENTRY *log_entry;
|
|
||||||
DBUG_ENTER("ddl_log_rename_file");
|
DBUG_ENTER("ddl_log_rename_file");
|
||||||
|
|
||||||
bzero(&ddl_log_entry, sizeof(ddl_log_entry));
|
bzero(&ddl_log_entry, sizeof(ddl_log_entry));
|
||||||
|
|
||||||
mysql_mutex_lock(&LOCK_gdl);
|
|
||||||
|
|
||||||
ddl_log_entry.action_type= DDL_LOG_RENAME_TABLE_ACTION;
|
ddl_log_entry.action_type= DDL_LOG_RENAME_TABLE_ACTION;
|
||||||
ddl_log_entry.next_entry= ddl_state->list ? ddl_state->list->entry_pos : 0;
|
ddl_log_entry.next_entry= ddl_state->list ? ddl_state->list->entry_pos : 0;
|
||||||
lex_string_set(&ddl_log_entry.handler_name,
|
lex_string_set(&ddl_log_entry.handler_name,
|
||||||
@ -1808,20 +1974,7 @@ bool ddl_log_rename_table(THD *thd, DDL_LOG_STATE *ddl_state,
|
|||||||
ddl_log_entry.from_name= *const_cast<LEX_CSTRING*>(org_alias);
|
ddl_log_entry.from_name= *const_cast<LEX_CSTRING*>(org_alias);
|
||||||
ddl_log_entry.phase= DDL_RENAME_PHASE_TABLE;
|
ddl_log_entry.phase= DDL_RENAME_PHASE_TABLE;
|
||||||
|
|
||||||
if (ddl_log_write_entry(&ddl_log_entry, &log_entry))
|
DBUG_RETURN(ddl_log_write(ddl_state, &ddl_log_entry));
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (ddl_log_write_execute_entry(log_entry->entry_pos,
|
|
||||||
&ddl_state->execute_entry))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
add_log_entry(ddl_state, log_entry);
|
|
||||||
mysql_mutex_unlock(&LOCK_gdl);
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
|
|
||||||
error:
|
|
||||||
mysql_mutex_unlock(&LOCK_gdl);
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1835,13 +1988,10 @@ bool ddl_log_rename_view(THD *thd, DDL_LOG_STATE *ddl_state,
|
|||||||
const LEX_CSTRING *new_alias)
|
const LEX_CSTRING *new_alias)
|
||||||
{
|
{
|
||||||
DDL_LOG_ENTRY ddl_log_entry;
|
DDL_LOG_ENTRY ddl_log_entry;
|
||||||
DDL_LOG_MEMORY_ENTRY *log_entry;
|
|
||||||
DBUG_ENTER("ddl_log_rename_file");
|
DBUG_ENTER("ddl_log_rename_file");
|
||||||
|
|
||||||
bzero(&ddl_log_entry, sizeof(ddl_log_entry));
|
bzero(&ddl_log_entry, sizeof(ddl_log_entry));
|
||||||
|
|
||||||
mysql_mutex_lock(&LOCK_gdl);
|
|
||||||
|
|
||||||
ddl_log_entry.action_type= DDL_LOG_RENAME_VIEW_ACTION;
|
ddl_log_entry.action_type= DDL_LOG_RENAME_VIEW_ACTION;
|
||||||
ddl_log_entry.next_entry= ddl_state->list ? ddl_state->list->entry_pos : 0;
|
ddl_log_entry.next_entry= ddl_state->list ? ddl_state->list->entry_pos : 0;
|
||||||
ddl_log_entry.db= *const_cast<LEX_CSTRING*>(new_db);
|
ddl_log_entry.db= *const_cast<LEX_CSTRING*>(new_db);
|
||||||
@ -1849,18 +1999,117 @@ bool ddl_log_rename_view(THD *thd, DDL_LOG_STATE *ddl_state,
|
|||||||
ddl_log_entry.from_db= *const_cast<LEX_CSTRING*>(org_db);
|
ddl_log_entry.from_db= *const_cast<LEX_CSTRING*>(org_db);
|
||||||
ddl_log_entry.from_name= *const_cast<LEX_CSTRING*>(org_alias);
|
ddl_log_entry.from_name= *const_cast<LEX_CSTRING*>(org_alias);
|
||||||
|
|
||||||
|
DBUG_RETURN(ddl_log_write(ddl_state, &ddl_log_entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Logging of DROP TABLE and DROP VIEW
|
||||||
|
|
||||||
|
Note that in contrast to rename, which are re-done in reverse order,
|
||||||
|
deletes are stored in a linked list according to delete order. This
|
||||||
|
is to ensure that the tables, for the query generated for binlog,
|
||||||
|
is in original delete order.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static bool ddl_log_drop_init(THD *thd, DDL_LOG_STATE *ddl_state,
|
||||||
|
ddl_log_action_code action_code,
|
||||||
|
const LEX_CSTRING *comment)
|
||||||
|
{
|
||||||
|
DDL_LOG_ENTRY ddl_log_entry;
|
||||||
|
DBUG_ENTER("ddl_log_drop_file");
|
||||||
|
|
||||||
|
bzero(&ddl_log_entry, sizeof(ddl_log_entry));
|
||||||
|
|
||||||
|
ddl_log_entry.action_type= action_code;
|
||||||
|
ddl_log_entry.next_entry= 0;
|
||||||
|
ddl_log_entry.tmp_name= *const_cast<LEX_CSTRING*>(comment);
|
||||||
|
ddl_log_entry.phase= 0;
|
||||||
|
|
||||||
|
DBUG_RETURN(ddl_log_write(ddl_state, &ddl_log_entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ddl_log_drop_table_init(THD *thd, DDL_LOG_STATE *ddl_state,
|
||||||
|
const LEX_CSTRING *comment)
|
||||||
|
{
|
||||||
|
return ddl_log_drop_init(thd, ddl_state, DDL_LOG_DROP_TABLE_INIT_ACTION,
|
||||||
|
comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ddl_log_drop_view_init(THD *thd, DDL_LOG_STATE *ddl_state)
|
||||||
|
{
|
||||||
|
LEX_CSTRING comment= {0,0};
|
||||||
|
return ddl_log_drop_init(thd, ddl_state, DDL_LOG_DROP_VIEW_INIT_ACTION,
|
||||||
|
&comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ddl_log_drop(THD *thd, DDL_LOG_STATE *ddl_state,
|
||||||
|
ddl_log_action_code action_code,
|
||||||
|
uint phase,
|
||||||
|
handlerton *hton,
|
||||||
|
const LEX_CSTRING *path,
|
||||||
|
const LEX_CSTRING *db,
|
||||||
|
const LEX_CSTRING *table)
|
||||||
|
{
|
||||||
|
DDL_LOG_ENTRY ddl_log_entry;
|
||||||
|
DDL_LOG_MEMORY_ENTRY *log_entry;
|
||||||
|
DBUG_ENTER("ddl_log_drop");
|
||||||
|
|
||||||
|
DBUG_ASSERT(ddl_state->list);
|
||||||
|
bzero(&ddl_log_entry, sizeof(ddl_log_entry));
|
||||||
|
|
||||||
|
ddl_log_entry.action_type= action_code;
|
||||||
|
if (hton)
|
||||||
|
lex_string_set(&ddl_log_entry.handler_name,
|
||||||
|
ha_resolve_storage_engine_name(hton));
|
||||||
|
ddl_log_entry.db= *const_cast<LEX_CSTRING*>(db);
|
||||||
|
ddl_log_entry.name= *const_cast<LEX_CSTRING*>(table);
|
||||||
|
ddl_log_entry.tmp_name= *const_cast<LEX_CSTRING*>(path);
|
||||||
|
ddl_log_entry.phase= (uchar) phase;
|
||||||
|
|
||||||
|
mysql_mutex_lock(&LOCK_gdl);
|
||||||
if (ddl_log_write_entry(&ddl_log_entry, &log_entry))
|
if (ddl_log_write_entry(&ddl_log_entry, &log_entry))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (ddl_log_write_execute_entry(log_entry->entry_pos,
|
(void) ddl_log_sync_no_lock();
|
||||||
&ddl_state->execute_entry))
|
if (update_next_entry_pos(ddl_state->list->entry_pos,
|
||||||
|
log_entry->entry_pos))
|
||||||
|
{
|
||||||
|
ddl_log_release_memory_entry(log_entry);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
add_log_entry(ddl_state, log_entry);
|
|
||||||
mysql_mutex_unlock(&LOCK_gdl);
|
mysql_mutex_unlock(&LOCK_gdl);
|
||||||
|
add_log_entry(ddl_state, log_entry);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
mysql_mutex_unlock(&LOCK_gdl);
|
mysql_mutex_unlock(&LOCK_gdl);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ddl_log_drop_table(THD *thd, DDL_LOG_STATE *ddl_state,
|
||||||
|
handlerton *hton,
|
||||||
|
const LEX_CSTRING *path,
|
||||||
|
const LEX_CSTRING *db,
|
||||||
|
const LEX_CSTRING *table)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("ddl_log_drop_table");
|
||||||
|
DBUG_RETURN(ddl_log_drop(thd, ddl_state,
|
||||||
|
DDL_LOG_DROP_TABLE_ACTION, DDL_DROP_PHASE_TABLE,
|
||||||
|
hton, path, db, table));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ddl_log_drop_view(THD *thd, DDL_LOG_STATE *ddl_state,
|
||||||
|
const LEX_CSTRING *path,
|
||||||
|
const LEX_CSTRING *db,
|
||||||
|
const LEX_CSTRING *table)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("ddl_log_drop_view");
|
||||||
|
DBUG_RETURN(ddl_log_drop(thd, ddl_state,
|
||||||
|
DDL_LOG_DROP_VIEW_ACTION, 0,
|
||||||
|
(handlerton*) 0, path, db, table));
|
||||||
|
}
|
||||||
|
@ -46,8 +46,8 @@ enum ddl_log_entry_code
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
When adding things below, also add an entry to ddl_log_entry_phases in
|
When adding things below, also add an entry to ddl_log_action_names and
|
||||||
ddl_log.cc
|
ddl_log_entry_phases in ddl_log.cc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum ddl_log_action_code
|
enum ddl_log_action_code
|
||||||
@ -77,7 +77,11 @@ enum ddl_log_action_code
|
|||||||
*/
|
*/
|
||||||
DDL_LOG_RENAME_TABLE_ACTION= 5,
|
DDL_LOG_RENAME_TABLE_ACTION= 5,
|
||||||
DDL_LOG_RENAME_VIEW_ACTION= 6,
|
DDL_LOG_RENAME_VIEW_ACTION= 6,
|
||||||
DDL_LOG_LAST_ACTION /* End marker */
|
DDL_LOG_DROP_TABLE_INIT_ACTION= 7,
|
||||||
|
DDL_LOG_DROP_TABLE_ACTION= 8,
|
||||||
|
DDL_LOG_DROP_VIEW_INIT_ACTION= 9,
|
||||||
|
DDL_LOG_DROP_VIEW_ACTION= 10,
|
||||||
|
DDL_LOG_LAST_ACTION /* End marker */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -97,6 +101,14 @@ enum enum_ddl_log_rename_table_phase {
|
|||||||
DDL_RENAME_PHASE_TABLE,
|
DDL_RENAME_PHASE_TABLE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum enum_ddl_log_drop_table_phase {
|
||||||
|
DDL_DROP_PHASE_TABLE=0,
|
||||||
|
DDL_DROP_PHASE_TRIGGER,
|
||||||
|
DDL_DROP_PHASE_BINLOG,
|
||||||
|
DDL_DROP_PHASE_RESET, /* Reset found list of dropped tables */
|
||||||
|
DDL_DROP_PHASE_END
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Setting ddl_log_entry.phase to this has the same effect as setting
|
Setting ddl_log_entry.phase to this has the same effect as setting
|
||||||
the phase to the maximum phase (..PHASE_END) for an entry.
|
the phase to the maximum phase (..PHASE_END) for an entry.
|
||||||
@ -204,6 +216,17 @@ bool ddl_log_rename_view(THD *thd, DDL_LOG_STATE *ddl_state,
|
|||||||
const LEX_CSTRING *org_alias,
|
const LEX_CSTRING *org_alias,
|
||||||
const LEX_CSTRING *new_db,
|
const LEX_CSTRING *new_db,
|
||||||
const LEX_CSTRING *new_alias);
|
const LEX_CSTRING *new_alias);
|
||||||
|
bool ddl_log_drop_table_init(THD *thd, DDL_LOG_STATE *ddl_state,
|
||||||
|
const LEX_CSTRING *comment);
|
||||||
|
bool ddl_log_drop_view_init(THD *thd, DDL_LOG_STATE *ddl_state);
|
||||||
|
bool ddl_log_drop_table(THD *thd, DDL_LOG_STATE *ddl_state,
|
||||||
|
handlerton *hton,
|
||||||
|
const LEX_CSTRING *path,
|
||||||
|
const LEX_CSTRING *db,
|
||||||
|
const LEX_CSTRING *table);
|
||||||
|
bool ddl_log_drop_view(THD *thd, DDL_LOG_STATE *ddl_state,
|
||||||
|
const LEX_CSTRING *path,
|
||||||
|
const LEX_CSTRING *db,
|
||||||
|
const LEX_CSTRING *table);
|
||||||
extern mysql_mutex_t LOCK_gdl;
|
extern mysql_mutex_t LOCK_gdl;
|
||||||
#endif /* DDL_LOG_INCLUDED */
|
#endif /* DDL_LOG_INCLUDED */
|
||||||
|
@ -566,7 +566,13 @@ static int hton_drop_table(handlerton *hton, const char *path)
|
|||||||
char tmp_path[FN_REFLEN];
|
char tmp_path[FN_REFLEN];
|
||||||
handler *file= get_new_handler(nullptr, current_thd->mem_root, hton);
|
handler *file= get_new_handler(nullptr, current_thd->mem_root, hton);
|
||||||
if (!file)
|
if (!file)
|
||||||
return ENOMEM;
|
{
|
||||||
|
/*
|
||||||
|
If file is not defined it means that the engine can't create a
|
||||||
|
handler if share is not set or we got an out of memory error
|
||||||
|
*/
|
||||||
|
return my_errno == ENOMEM ? ENOMEM : ENOENT;
|
||||||
|
}
|
||||||
path= get_canonical_filename(file, path, tmp_path);
|
path= get_canonical_filename(file, path, tmp_path);
|
||||||
int error= file->delete_table(path);
|
int error= file->delete_table(path);
|
||||||
delete file;
|
delete file;
|
||||||
|
@ -9982,6 +9982,7 @@ int TC_LOG::using_heuristic_recover()
|
|||||||
int TC_LOG_BINLOG::open(const char *opt_name)
|
int TC_LOG_BINLOG::open(const char *opt_name)
|
||||||
{
|
{
|
||||||
int error= 1;
|
int error= 1;
|
||||||
|
DBUG_ENTER("TC_LOG_BINLOG::open");
|
||||||
|
|
||||||
DBUG_ASSERT(total_ha_2pc > 1);
|
DBUG_ASSERT(total_ha_2pc > 1);
|
||||||
DBUG_ASSERT(opt_name);
|
DBUG_ASSERT(opt_name);
|
||||||
@ -9991,7 +9992,7 @@ int TC_LOG_BINLOG::open(const char *opt_name)
|
|||||||
{
|
{
|
||||||
/* There was a failure to open the index file, can't open the binlog */
|
/* There was a failure to open the index file, can't open the binlog */
|
||||||
cleanup();
|
cleanup();
|
||||||
return 1;
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (using_heuristic_recover())
|
if (using_heuristic_recover())
|
||||||
@ -10001,12 +10002,12 @@ int TC_LOG_BINLOG::open(const char *opt_name)
|
|||||||
open(opt_name, 0, 0, WRITE_CACHE, max_binlog_size, 0, TRUE);
|
open(opt_name, 0, 0, WRITE_CACHE, max_binlog_size, 0, TRUE);
|
||||||
mysql_mutex_unlock(&LOCK_log);
|
mysql_mutex_unlock(&LOCK_log);
|
||||||
cleanup();
|
cleanup();
|
||||||
return 1;
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
error= do_binlog_recovery(opt_name, true);
|
error= do_binlog_recovery(opt_name, true);
|
||||||
binlog_state_recover_done= true;
|
binlog_state_recover_done= true;
|
||||||
return error;
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This is called on shutdown, after ha_panic. */
|
/** This is called on shutdown, after ha_panic. */
|
||||||
@ -10536,6 +10537,7 @@ int TC_LOG_BINLOG::recover(LOG_INFO *linfo, const char *last_log_name,
|
|||||||
Query_log_event *query_ev= (Query_log_event*) ev;
|
Query_log_event *query_ev= (Query_log_event*) ev;
|
||||||
if (query_ev->xid)
|
if (query_ev->xid)
|
||||||
{
|
{
|
||||||
|
DBUG_PRINT("QQ", ("xid: %llu xid"));
|
||||||
DBUG_ASSERT(sizeof(query_ev->xid) == sizeof(my_xid));
|
DBUG_ASSERT(sizeof(query_ev->xid) == sizeof(my_xid));
|
||||||
uchar *x= (uchar *) memdup_root(&mem_root,
|
uchar *x= (uchar *) memdup_root(&mem_root,
|
||||||
(uchar*) &query_ev->xid,
|
(uchar*) &query_ev->xid,
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
#include "tztime.h"
|
#include "tztime.h"
|
||||||
#include "sql_insert.h" // binlog_drop_table
|
#include "sql_insert.h" // binlog_drop_table
|
||||||
#include "ddl_log.h"
|
#include "ddl_log.h"
|
||||||
|
#include "debug_sync.h" // debug_crash_here()
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
@ -1139,9 +1140,11 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
char path[FN_REFLEN + 1];
|
char path[FN_REFLEN + 1];
|
||||||
LEX_CSTRING alias= null_clex_str;
|
LEX_CSTRING alias= null_clex_str;
|
||||||
StringBuffer<160> unknown_tables(system_charset_info);
|
StringBuffer<160> unknown_tables(system_charset_info);
|
||||||
uint not_found_errors= 0;
|
DDL_LOG_STATE ddl_log_state;
|
||||||
|
const char *comment_start;
|
||||||
|
uint not_found_errors= 0, table_count= 0, non_temp_tables_count= 0;
|
||||||
int error= 0;
|
int error= 0;
|
||||||
int non_temp_tables_count= 0;
|
uint32 comment_len;
|
||||||
bool trans_tmp_table_deleted= 0, non_trans_tmp_table_deleted= 0;
|
bool trans_tmp_table_deleted= 0, non_trans_tmp_table_deleted= 0;
|
||||||
bool non_tmp_table_deleted= 0;
|
bool non_tmp_table_deleted= 0;
|
||||||
bool is_drop_tmp_if_exists_added= 0;
|
bool is_drop_tmp_if_exists_added= 0;
|
||||||
@ -1154,6 +1157,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
DBUG_ENTER("mysql_rm_table_no_locks");
|
DBUG_ENTER("mysql_rm_table_no_locks");
|
||||||
|
|
||||||
unknown_tables.length(0);
|
unknown_tables.length(0);
|
||||||
|
comment_len= get_comment(thd, if_exists ? 17:9, &comment_start);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Prepares the drop statements that will be written into the binary
|
Prepares the drop statements that will be written into the binary
|
||||||
log as follows:
|
log as follows:
|
||||||
@ -1204,6 +1209,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
built_non_trans_tmp_query.set_charset(system_charset_info);
|
built_non_trans_tmp_query.set_charset(system_charset_info);
|
||||||
built_non_trans_tmp_query.copy(built_trans_tmp_query);
|
built_non_trans_tmp_query.copy(built_trans_tmp_query);
|
||||||
}
|
}
|
||||||
|
bzero(&ddl_log_state, sizeof(ddl_log_state));
|
||||||
|
|
||||||
for (table= tables; table; table= table->next_local)
|
for (table= tables; table; table= table->next_local)
|
||||||
{
|
{
|
||||||
@ -1213,6 +1219,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
bool table_dropped= 0;
|
bool table_dropped= 0;
|
||||||
const LEX_CSTRING db= table->db;
|
const LEX_CSTRING db= table->db;
|
||||||
const LEX_CSTRING table_name= table->table_name;
|
const LEX_CSTRING table_name= table->table_name;
|
||||||
|
LEX_CSTRING cpath= {0,0};
|
||||||
handlerton *hton= 0;
|
handlerton *hton= 0;
|
||||||
Table_type table_type;
|
Table_type table_type;
|
||||||
size_t path_length= 0;
|
size_t path_length= 0;
|
||||||
@ -1347,6 +1354,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lex_string_set3(&cpath, path, (size_t) (path_end - path));
|
||||||
|
|
||||||
{
|
{
|
||||||
char engine_buf[NAME_CHAR_LEN + 1];
|
char engine_buf[NAME_CHAR_LEN + 1];
|
||||||
LEX_CSTRING engine= { engine_buf, 0 };
|
LEX_CSTRING engine= { engine_buf, 0 };
|
||||||
@ -1363,6 +1372,17 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
|
|
||||||
thd->replication_flags= 0;
|
thd->replication_flags= 0;
|
||||||
was_view= table_type == TABLE_TYPE_VIEW;
|
was_view= table_type == TABLE_TYPE_VIEW;
|
||||||
|
|
||||||
|
if (!table_count++)
|
||||||
|
{
|
||||||
|
LEX_CSTRING comment= {comment_start, (size_t) comment_len};
|
||||||
|
if (ddl_log_drop_table_init(thd, &ddl_log_state, &comment))
|
||||||
|
{
|
||||||
|
error= 1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((table_type == TABLE_TYPE_UNKNOWN) || (was_view && !drop_view) ||
|
if ((table_type == TABLE_TYPE_UNKNOWN) || (was_view && !drop_view) ||
|
||||||
(table_type != TABLE_TYPE_SEQUENCE && drop_sequence))
|
(table_type != TABLE_TYPE_SEQUENCE && drop_sequence))
|
||||||
{
|
{
|
||||||
@ -1376,6 +1396,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
was_table|= wrong_drop_sequence;
|
was_table|= wrong_drop_sequence;
|
||||||
error= table_type == TABLE_TYPE_UNKNOWN ? ENOENT : -1;
|
error= table_type == TABLE_TYPE_UNKNOWN ? ENOENT : -1;
|
||||||
tdc_remove_table(thd, db.str, table_name.str);
|
tdc_remove_table(thd, db.str, table_name.str);
|
||||||
|
if (wrong_drop_sequence)
|
||||||
|
goto report_error;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1411,7 +1433,17 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
log_if_exists= 1;
|
log_if_exists= 1;
|
||||||
|
|
||||||
bool enoent_warning= !dont_log_query && !(hton && hton->discover_table);
|
bool enoent_warning= !dont_log_query && !(hton && hton->discover_table);
|
||||||
error= ha_delete_table(thd, hton, path, &db, &table_name, enoent_warning);
|
|
||||||
|
if (ddl_log_drop_table(thd, &ddl_log_state, hton, &cpath, &db,
|
||||||
|
&table_name))
|
||||||
|
{
|
||||||
|
error= -1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
debug_crash_here("ddl_log_drop_before_delete_table");
|
||||||
|
error= ha_delete_table(thd, hton, path, &db, &table_name,
|
||||||
|
enoent_warning);
|
||||||
|
debug_crash_here("ddl_log_drop_after_delete_table");
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
table_dropped= 1;
|
table_dropped= 1;
|
||||||
@ -1473,11 +1505,18 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
scan all engines try to drop the table from there.
|
scan all engines try to drop the table from there.
|
||||||
This is to ensure we don't have any partial table files left.
|
This is to ensure we don't have any partial table files left.
|
||||||
*/
|
*/
|
||||||
if (non_existing_table_error(error) && !wrong_drop_sequence)
|
if (non_existing_table_error(error))
|
||||||
{
|
{
|
||||||
int ferror= 0;
|
int ferror= 0;
|
||||||
DBUG_ASSERT(!was_view);
|
DBUG_ASSERT(!was_view);
|
||||||
|
|
||||||
|
if (ddl_log_drop_table(thd, &ddl_log_state, hton, &cpath, &db,
|
||||||
|
&table_name))
|
||||||
|
{
|
||||||
|
error= -1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
/* Remove extension for delete */
|
/* Remove extension for delete */
|
||||||
*path_end= '\0';
|
*path_end= '\0';
|
||||||
ferror= ha_delete_table_force(thd, path, &db, &table_name);
|
ferror= ha_delete_table_force(thd, path, &db, &table_name);
|
||||||
@ -1509,13 +1548,19 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
if (thd->replication_flags & OPTION_IF_EXISTS)
|
if (thd->replication_flags & OPTION_IF_EXISTS)
|
||||||
log_if_exists= 1;
|
log_if_exists= 1;
|
||||||
|
|
||||||
|
debug_crash_here("ddl_log_drop_before_drop_trigger");
|
||||||
|
ddl_log_update_phase(&ddl_log_state, DDL_DROP_PHASE_TRIGGER);
|
||||||
|
debug_crash_here("ddl_log_drop_before_drop_trigger2");
|
||||||
|
|
||||||
if (likely(!error) || non_existing_table_error(error))
|
if (likely(!error) || non_existing_table_error(error))
|
||||||
{
|
{
|
||||||
if (Table_triggers_list::drop_all_triggers(thd, &db, &table_name,
|
if (Table_triggers_list::drop_all_triggers(thd, &db, &table_name,
|
||||||
MYF(MY_WME | MY_IGNORE_ENOENT)))
|
MYF(MY_WME | MY_IGNORE_ENOENT)))
|
||||||
error= error ? error : -1;
|
error= error ? error : -1;
|
||||||
}
|
}
|
||||||
|
debug_crash_here("ddl_log_drop_after_drop_trigger");
|
||||||
|
|
||||||
|
report_error:
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
StringBuffer<FN_REFLEN> tbl_name(system_charset_info);
|
StringBuffer<FN_REFLEN> tbl_name(system_charset_info);
|
||||||
@ -1565,6 +1610,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
table_name.str, (uint)table_name.length);
|
table_name.str, (uint)table_name.length);
|
||||||
mysql_audit_drop_table(thd, table);
|
mysql_audit_drop_table(thd, table);
|
||||||
}
|
}
|
||||||
|
ddl_log_update_phase(&ddl_log_state, DDL_DROP_PHASE_BINLOG);
|
||||||
|
|
||||||
if (!dont_log_query &&
|
if (!dont_log_query &&
|
||||||
(!error || table_dropped || non_existing_table_error(error)))
|
(!error || table_dropped || non_existing_table_error(error)))
|
||||||
@ -1621,6 +1667,7 @@ err:
|
|||||||
query_cache_invalidate3(thd, tables, 0);
|
query_cache_invalidate3(thd, tables, 0);
|
||||||
if (!dont_log_query && mysql_bin_log.is_open())
|
if (!dont_log_query && mysql_bin_log.is_open())
|
||||||
{
|
{
|
||||||
|
debug_crash_here("ddl_log_drop_before_binlog");
|
||||||
if (non_trans_tmp_table_deleted)
|
if (non_trans_tmp_table_deleted)
|
||||||
{
|
{
|
||||||
/* Chop of the last comma */
|
/* Chop of the last comma */
|
||||||
@ -1648,8 +1695,6 @@ err:
|
|||||||
if (non_tmp_table_deleted)
|
if (non_tmp_table_deleted)
|
||||||
{
|
{
|
||||||
String built_query;
|
String built_query;
|
||||||
const char *comment_start;
|
|
||||||
uint32 comment_len;
|
|
||||||
|
|
||||||
built_query.set_charset(thd->charset());
|
built_query.set_charset(thd->charset());
|
||||||
built_query.append(STRING_WITH_LEN("DROP "));
|
built_query.append(STRING_WITH_LEN("DROP "));
|
||||||
@ -1659,8 +1704,7 @@ err:
|
|||||||
built_query.append(STRING_WITH_LEN("IF EXISTS "));
|
built_query.append(STRING_WITH_LEN("IF EXISTS "));
|
||||||
|
|
||||||
/* Preserve comment in original query */
|
/* Preserve comment in original query */
|
||||||
if ((comment_len= get_comment(thd, if_exists ? 17:9,
|
if (comment_len)
|
||||||
&comment_start)))
|
|
||||||
{
|
{
|
||||||
built_query.append(comment_start, comment_len);
|
built_query.append(comment_start, comment_len);
|
||||||
built_query.append(' ');
|
built_query.append(' ');
|
||||||
@ -1670,13 +1714,18 @@ err:
|
|||||||
normal_tables.chop();
|
normal_tables.chop();
|
||||||
built_query.append(normal_tables.ptr(), normal_tables.length());
|
built_query.append(normal_tables.ptr(), normal_tables.length());
|
||||||
built_query.append(generated_by_server);
|
built_query.append(generated_by_server);
|
||||||
|
thd->binlog_xid= thd->query_id;
|
||||||
|
ddl_log_update_xid(&ddl_log_state, thd->binlog_xid);
|
||||||
error |= (thd->binlog_query(THD::STMT_QUERY_TYPE,
|
error |= (thd->binlog_query(THD::STMT_QUERY_TYPE,
|
||||||
built_query.ptr(),
|
built_query.ptr(),
|
||||||
built_query.length(),
|
built_query.length(),
|
||||||
TRUE, FALSE, FALSE, 0) > 0);
|
TRUE, FALSE, FALSE, 0) > 0);
|
||||||
|
thd->binlog_xid= 0;
|
||||||
}
|
}
|
||||||
|
debug_crash_here("ddl_log_drop_after_binlog");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ddl_log_complete(&ddl_log_state);
|
||||||
|
|
||||||
if (!drop_temporary)
|
if (!drop_temporary)
|
||||||
{
|
{
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "sql_derived.h"
|
#include "sql_derived.h"
|
||||||
#include "sql_cte.h" // check_dependencies_in_with_clauses()
|
#include "sql_cte.h" // check_dependencies_in_with_clauses()
|
||||||
#include "opt_trace.h"
|
#include "opt_trace.h"
|
||||||
|
#include "ddl_log.h"
|
||||||
#include "wsrep_mysqld.h"
|
#include "wsrep_mysqld.h"
|
||||||
#include "debug_sync.h" // debug_crash_here
|
#include "debug_sync.h" // debug_crash_here
|
||||||
|
|
||||||
@ -1817,9 +1818,12 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
|
|||||||
bool delete_error= FALSE, wrong_object_name= FALSE;
|
bool delete_error= FALSE, wrong_object_name= FALSE;
|
||||||
bool some_views_deleted= FALSE;
|
bool some_views_deleted= FALSE;
|
||||||
bool something_wrong= FALSE;
|
bool something_wrong= FALSE;
|
||||||
uint not_exists_count= 0;
|
uint not_exists_count= 0, view_count= 0;
|
||||||
|
DDL_LOG_STATE ddl_log_state;
|
||||||
DBUG_ENTER("mysql_drop_view");
|
DBUG_ENTER("mysql_drop_view");
|
||||||
|
|
||||||
|
bzero(&ddl_log_state, sizeof(ddl_log_state));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We can't allow dropping of unlocked view under LOCK TABLES since this
|
We can't allow dropping of unlocked view under LOCK TABLES since this
|
||||||
might lead to deadlock. But since we can't really lock view with LOCK
|
might lead to deadlock. But since we can't really lock view with LOCK
|
||||||
@ -1838,9 +1842,12 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
|
|||||||
|
|
||||||
for (view= views; view; view= view->next_local)
|
for (view= views; view; view= view->next_local)
|
||||||
{
|
{
|
||||||
|
LEX_CSTRING cpath;
|
||||||
bool not_exist;
|
bool not_exist;
|
||||||
build_table_filename(path, sizeof(path) - 1,
|
size_t length;
|
||||||
view->db.str, view->table_name.str, reg_ext, 0);
|
length= build_table_filename(path, sizeof(path) - 1,
|
||||||
|
view->db.str, view->table_name.str, reg_ext, 0);
|
||||||
|
lex_string_set3(&cpath, path, length);
|
||||||
|
|
||||||
if ((not_exist= my_access(path, F_OK)) || !dd_frm_is_view(thd, path))
|
if ((not_exist= my_access(path, F_OK)) || !dd_frm_is_view(thd, path))
|
||||||
{
|
{
|
||||||
@ -1861,8 +1868,18 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
|
|||||||
not_exists_count++;
|
not_exists_count++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!view_count++)
|
||||||
|
{
|
||||||
|
if (ddl_log_drop_view_init(thd, &ddl_log_state))
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
if (ddl_log_drop_view(thd, &ddl_log_state, &cpath, &view->db,
|
||||||
|
&view->table_name))
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
debug_crash_here("ddl_log_drop_before_delete_view");
|
||||||
if (unlikely(mysql_file_delete(key_file_frm, path, MYF(MY_WME))))
|
if (unlikely(mysql_file_delete(key_file_frm, path, MYF(MY_WME))))
|
||||||
delete_error= TRUE;
|
delete_error= TRUE;
|
||||||
|
debug_crash_here("ddl_log_drop_after_delete_view");
|
||||||
|
|
||||||
some_views_deleted= TRUE;
|
some_views_deleted= TRUE;
|
||||||
|
|
||||||
@ -1890,10 +1907,16 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
|
|||||||
/* if something goes wrong, bin-log with possible error code,
|
/* if something goes wrong, bin-log with possible error code,
|
||||||
otherwise bin-log with error code cleared.
|
otherwise bin-log with error code cleared.
|
||||||
*/
|
*/
|
||||||
|
debug_crash_here("ddl_log_drop_before_binlog");
|
||||||
|
thd->binlog_xid= thd->query_id;
|
||||||
|
ddl_log_update_xid(&ddl_log_state, thd->binlog_xid);
|
||||||
if (unlikely(write_bin_log(thd, !something_wrong, thd->query(),
|
if (unlikely(write_bin_log(thd, !something_wrong, thd->query(),
|
||||||
thd->query_length())))
|
thd->query_length())))
|
||||||
something_wrong= 1;
|
something_wrong= 1;
|
||||||
|
thd->binlog_xid= 0;
|
||||||
|
debug_crash_here("ddl_log_drop_after_binlog");
|
||||||
}
|
}
|
||||||
|
ddl_log_complete(&ddl_log_state);
|
||||||
|
|
||||||
if (unlikely(something_wrong))
|
if (unlikely(something_wrong))
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user