summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/atomic/drop_db.result95
-rw-r--r--mysql-test/suite/atomic/drop_db.test112
-rw-r--r--mysql-test/suite/atomic/drop_db_long_names.opt1
-rw-r--r--mysql-test/suite/atomic/drop_db_long_names.result11
-rw-r--r--mysql-test/suite/atomic/drop_db_long_names.test108
-rw-r--r--mysql-test/suite/atomic/drop_sequence.result75
-rw-r--r--mysql-test/suite/atomic/drop_sequence.test18
-rw-r--r--mysql-test/suite/atomic/drop_table.result110
-rw-r--r--mysql-test/suite/atomic/drop_view.result10
-rw-r--r--sql/ddl_log.cc360
-rw-r--r--sql/ddl_log.h30
-rw-r--r--sql/handler.cc5
-rw-r--r--sql/handler.h2
-rw-r--r--sql/sql_db.cc182
-rw-r--r--sql/sql_db.h4
-rw-r--r--sql/sql_table.cc68
-rw-r--r--sql/sql_table.h6
-rw-r--r--sql/sql_view.cc2
18 files changed, 913 insertions, 286 deletions
diff --git a/mysql-test/suite/atomic/drop_db.result b/mysql-test/suite/atomic/drop_db.result
new file mode 100644
index 00000000000..43bb2d32f62
--- /dev/null
+++ b/mysql-test/suite/atomic/drop_db.result
@@ -0,0 +1,95 @@
+call mtr.add_suppression("InnoDB: .* does not exist in the InnoDB internal");
+"engine: aria crash point: ddl_log_drop_before_delete_table position: 1"
+t1v.frm
+t2.MAD
+t2.MAI
+t2.frm
+Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
+foo STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `foo`()
+insert into test.t1 values (42) latin1 latin1_swedish_ci latin1_swedish_ci
+master-bin.000002 # Query # # use `test2`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
+"engine: aria crash point: ddl_log_drop_before_delete_table position: 2"
+t1v.frm
+t2.MAD
+t2.MAI
+t2.frm
+Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
+foo STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `foo`()
+insert into test.t1 values (42) latin1 latin1_swedish_ci latin1_swedish_ci
+master-bin.000002 # Query # # use `test2`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
+master-bin.000002 # Query # # use `test2`; DROP VIEW IF EXISTS `t1v` /* generated by ddl log */
+"engine: aria crash point: ddl_log_drop_before_delete_table position: 3"
+Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
+foo STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `foo`()
+insert into test.t1 values (42) latin1 latin1_swedish_ci latin1_swedish_ci
+master-bin.000002 # Query # # use `test2`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
+master-bin.000002 # Query # # use `test2`; DROP VIEW IF EXISTS `t1v` /* generated by ddl log */
+"engine: aria crash point: ddl_log_drop_after_drop_tables position: 1"
+Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
+foo STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `foo`()
+insert into test.t1 values (42) latin1 latin1_swedish_ci latin1_swedish_ci
+master-bin.000002 # Query # # use `test2`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
+master-bin.000002 # Query # # use `test2`; DROP VIEW IF EXISTS `t1v` /* generated by ddl log */
+"engine: aria crash point: ddl_log_drop_before_ha_drop_database position: 1"
+master-bin.000002 # Query # # DROP DATABASE IF EXISTS `test2` /* generated by ddl log */
+"engine: aria crash point: ddl_log_drop_before_drop_db_routines position: 1"
+master-bin.000002 # Query # # DROP DATABASE IF EXISTS `test2` /* generated by ddl log */
+"engine: aria crash point: ddl_log_drop_after_drop_db_routines position: 1"
+master-bin.000002 # Query # # DROP DATABASE IF EXISTS `test2` /* generated by ddl log */
+"engine: aria crash point: ddl_log_drop_before_drop_option_file position: 1"
+master-bin.000002 # Query # # DROP DATABASE IF EXISTS `test2` /* generated by ddl log */
+"engine: aria crash point: ddl_log_drop_before_drop_dir position: 1"
+master-bin.000002 # Query # # DROP DATABASE IF EXISTS `test2` /* generated by ddl log */
+"engine: aria crash point: ddl_log_drop_after_drop_dir position: 1"
+master-bin.000002 # Query # # DROP DATABASE IF EXISTS `test2` /* generated by ddl log */
+"engine: aria crash point: ddl_log_drop_before_binlog position: 1"
+master-bin.000002 # Query # # DROP DATABASE IF EXISTS `test2` /* generated by ddl log */
+"engine: aria crash point: ddl_log_drop_after_binlog position: 1"
+master-bin.000001 # Query # # DROP DATABASE test2
+"engine: innodb crash point: ddl_log_drop_before_delete_table position: 1"
+t1v.frm
+t2.frm
+t2.ibd
+Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
+foo STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `foo`()
+insert into test.t1 values (42) latin1 latin1_swedish_ci latin1_swedish_ci
+master-bin.000002 # Query # # use `test2`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
+"engine: innodb crash point: ddl_log_drop_before_delete_table position: 2"
+t1v.frm
+t2.frm
+t2.ibd
+Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
+foo STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `foo`()
+insert into test.t1 values (42) latin1 latin1_swedish_ci latin1_swedish_ci
+master-bin.000002 # Query # # use `test2`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
+master-bin.000002 # Query # # use `test2`; DROP VIEW IF EXISTS `t1v` /* generated by ddl log */
+"engine: innodb crash point: ddl_log_drop_before_delete_table position: 3"
+Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
+foo STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `foo`()
+insert into test.t1 values (42) latin1 latin1_swedish_ci latin1_swedish_ci
+master-bin.000002 # Query # # use `test2`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
+master-bin.000002 # Query # # use `test2`; DROP VIEW IF EXISTS `t1v` /* generated by ddl log */
+"engine: innodb crash point: ddl_log_drop_after_drop_tables position: 1"
+Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
+foo STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `foo`()
+insert into test.t1 values (42) latin1 latin1_swedish_ci latin1_swedish_ci
+master-bin.000002 # Query # # use `test2`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
+master-bin.000002 # Query # # use `test2`; DROP VIEW IF EXISTS `t1v` /* generated by ddl log */
+"engine: innodb crash point: ddl_log_drop_before_ha_drop_database position: 1"
+master-bin.000002 # Query # # DROP DATABASE IF EXISTS `test2` /* generated by ddl log */
+"engine: innodb crash point: ddl_log_drop_before_drop_db_routines position: 1"
+master-bin.000002 # Query # # DROP DATABASE IF EXISTS `test2` /* generated by ddl log */
+"engine: innodb crash point: ddl_log_drop_after_drop_db_routines position: 1"
+master-bin.000002 # Query # # DROP DATABASE IF EXISTS `test2` /* generated by ddl log */
+"engine: innodb crash point: ddl_log_drop_before_drop_option_file position: 1"
+master-bin.000002 # Query # # DROP DATABASE IF EXISTS `test2` /* generated by ddl log */
+"engine: innodb crash point: ddl_log_drop_before_drop_dir position: 1"
+master-bin.000002 # Query # # DROP DATABASE IF EXISTS `test2` /* generated by ddl log */
+"engine: innodb crash point: ddl_log_drop_after_drop_dir position: 1"
+master-bin.000002 # Query # # DROP DATABASE IF EXISTS `test2` /* generated by ddl log */
+"engine: innodb crash point: ddl_log_drop_before_binlog position: 1"
+master-bin.000002 # Query # # DROP DATABASE IF EXISTS `test2` /* generated by ddl log */
+"engine: innodb crash point: ddl_log_drop_after_binlog position: 1"
+master-bin.000001 # Query # # DROP DATABASE test2
+Warnings:
+Note 1008 Can't drop database 'test2'; database doesn't exist
diff --git a/mysql-test/suite/atomic/drop_db.test b/mysql-test/suite/atomic/drop_db.test
new file mode 100644
index 00000000000..96f6a0dd76a
--- /dev/null
+++ b/mysql-test/suite/atomic/drop_db.test
@@ -0,0 +1,112 @@
+--source include/have_debug.inc
+--source include/have_innodb.inc
+--source include/have_log_bin.inc
+--source include/not_valgrind.inc
+
+#
+# Testing of atomic DROP DATABASE 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=2;
+let $engines='aria','innodb';
+
+let $crash_count=10;
+let $crash_points='ddl_log_drop_before_delete_table','ddl_log_drop_after_drop_tables','ddl_log_drop_before_ha_drop_database','ddl_log_drop_before_drop_db_routines','ddl_log_drop_after_drop_db_routines','ddl_log_drop_before_drop_option_file','ddl_log_drop_before_drop_dir','ddl_log_drop_after_drop_dir','ddl_log_drop_before_binlog','ddl_log_drop_after_binlog';
+
+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;
+ }
+
+ # Number of tables that should be dropped (we try to crash after each drop)
+ let $drops=3;
+
+ 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 database test2;
+ use test2;
+ --eval set @@default_storage_engine=$default_engine;
+ --eval create table t1 (a int not null) $extra_option;
+ create view t1v as select * from t1;
+ --eval create table t2 (b int not null) $extra_option;
+ create procedure foo()
+ insert into test.t1 values (42);
+
+ flush tables;
+ use test;
+
+ 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 DATABASE test2;
+ 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!";
+ }
+ use test;
+ # Check which tables still exists
+ --error 0,1
+ --list_files $MYSQLD_DATADIR/test2 t*
+ --error 0,ER_SP_DOES_NOT_EXIST
+ show create procedure test2.foo;
+
+ --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
+ --error 0, ER_DB_DROP_EXISTS
+ DROP DATABASE test2;
+ --enable_warnings
+ }
+ # We only need to test drops for all tables for the first crash point
+ let $drops=1;
+ }
+}
+drop database if exists test2;
+
+--enable_query_log
diff --git a/mysql-test/suite/atomic/drop_db_long_names.opt b/mysql-test/suite/atomic/drop_db_long_names.opt
new file mode 100644
index 00000000000..968c8f1a56a
--- /dev/null
+++ b/mysql-test/suite/atomic/drop_db_long_names.opt
@@ -0,0 +1 @@
+--max-allowed-packet=1024 --net-buffer-length=1024
diff --git a/mysql-test/suite/atomic/drop_db_long_names.result b/mysql-test/suite/atomic/drop_db_long_names.result
new file mode 100644
index 00000000000..415ce717bf7
--- /dev/null
+++ b/mysql-test/suite/atomic/drop_db_long_names.result
@@ -0,0 +1,11 @@
+"engine: aria crash point: ddl_log_drop_after_drop_tables position: 1"
+master-bin.000002 # Query # # use `test2`; DROP TABLE IF EXISTS `tABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB`,`tACCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC`,`tADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD`,`tAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE`,`tAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF`,`tAGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG`,`tAHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH`,`tAIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII`,`tAJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ`,`tAKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK`,`tALLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL` /* generated by ddl log */
+master-bin.000002 # Query # # use `test2`; DROP VIEW IF EXISTS `tABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBv`,`tACCCCCCCCCCCCCCCCCCCCCCCCCCCCCCv`,`tADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDv`,`tAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEv`,`tAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFv`,`tAGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGv`,`tAHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHv`,`tAIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIv`,`tAJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJv`,`tAKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKv` /* generated by ddl log */
+master-bin.000002 # Query # # use `test2`; DROP TABLE IF EXISTS `tAMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM`,`tANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN`,`tAOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO`,`tAPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP`,`tAQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ`,`tARRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`,`tASSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS`,`tATTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT`,`tAUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU`,`tAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV`,`tAWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW` /* generated by ddl log */
+master-bin.000002 # Query # # use `test2`; DROP VIEW IF EXISTS `tALLLLLLLLLLLLLLLLLLLLLLLLLLLLLLv`,`tAMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMv`,`tANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNv`,`tAOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOv`,`tAPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPv`,`tAQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQv`,`tARRRRRRRRRRRRRRRRRRRRRRRRRRRRRRv`,`tASSSSSSSSSSSSSSSSSSSSSSSSSSSSSSv`,`tATTTTTTTTTTTTTTTTTTTTTTTTTTTTTTv`,`tAUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUv`,`tAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVv` /* generated by ddl log */
+master-bin.000002 # Query # # use `test2`; DROP TABLE IF EXISTS `tAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX`,`tAYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY`,`tAZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ`,`tBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`,`tBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB`,`tBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC`,`tBDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD`,`tBEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE` /* generated by ddl log */
+master-bin.000002 # Query # # use `test2`; DROP VIEW IF EXISTS `tAWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWv`,`tAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXv`,`tAYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYv`,`tAZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZv`,`tBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv`,`tBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBv`,`tBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCv`,`tBDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDv`,`tBEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEv` /* generated by ddl log */
+"engine: aria crash point: ddl_log_drop_before_binlog position: 1"
+master-bin.000002 # Query # # DROP DATABASE IF EXISTS `test2` /* generated by ddl log */
+Warnings:
+Note 1008 Can't drop database 'test2'; database doesn't exist
diff --git a/mysql-test/suite/atomic/drop_db_long_names.test b/mysql-test/suite/atomic/drop_db_long_names.test
new file mode 100644
index 00000000000..c96e59fb4b9
--- /dev/null
+++ b/mysql-test/suite/atomic/drop_db_long_names.test
@@ -0,0 +1,108 @@
+--source include/have_debug.inc
+--source include/have_log_bin.inc
+--source include/not_valgrind.inc
+
+#
+# Testing of atomic DROP DATABASE when the generated query could be too long
+#
+
+let $engine_count=1;
+let $engines='aria';
+
+let $crash_count=2;
+let $crash_points='ddl_log_drop_after_drop_tables','ddl_log_drop_before_binlog';
+
+let $max_tables=30;
+
+let $old_debug=`select @@debug_dbug`;
+
+let $keep_include_silent=1;
+let $grep_script=DROP;
+--disable_query_log
+
+let $e=0;
+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 < 1)
+ {
+ inc $r;
+ create database test2;
+ use test2;
+ --eval set @@default_storage_engine=$default_engine
+ let $t=0;
+ while ($t < $max_tables)
+ {
+ inc $t;
+ let $name=`select concat("t",char(floor(65+$t/26)),repeat(char(65+mod($t,26)),60))`;
+ let $view=`select concat("t",char(floor(65+$t/26)),repeat(char(65+mod($t,26)),30),'v')`;
+ --eval create table $name (a int not null) $extra_option
+ --eval create view $view as select * from $name
+ }
+
+ flush tables;
+ use test;
+
+ 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 DATABASE test2;
+ 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!";
+ }
+ use test;
+ # Check which tables still exists
+ --error 0,1
+ --list_files $MYSQLD_DATADIR/test2 t*
+ --error 0,ER_SP_DOES_NOT_EXIST
+
+ --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
+ --error 0, ER_DB_DROP_EXISTS
+ DROP DATABASE test2;
+ --enable_warnings
+ }
+ }
+}
+drop database if exists test2;
+
+--enable_query_log
diff --git a/mysql-test/suite/atomic/drop_sequence.result b/mysql-test/suite/atomic/drop_sequence.result
index 73c535cbda1..4e92659d112 100644
--- a/mysql-test/suite/atomic/drop_sequence.result
+++ b/mysql-test/suite/atomic/drop_sequence.result
@@ -1,104 +1,105 @@
call mtr.add_suppression("InnoDB: .* does not exist in the InnoDB internal");
+create database test2;
"engine: aria crash point: ddl_log_drop_before_delete_table position: 1"
+ts.MAD
+ts.MAI
+ts.frm
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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`test2`.`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`test2`.`t2`,`ts` /* generated by ddl log */
"engine: aria crash point: ddl_log_drop_after_delete_table position: 1"
+ts.MAD
+ts.MAI
+ts.frm
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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`test2`.`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`test2`.`t2`,`ts` /* generated by ddl log */
"engine: aria crash point: ddl_log_drop_before_drop_trigger position: 1"
+ts.MAD
+ts.MAI
+ts.frm
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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`test2`.`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`test2`.`t2`,`ts` /* generated by ddl log */
"engine: aria crash point: ddl_log_drop_before_drop_trigger2 position: 1"
+ts.MAD
+ts.MAI
+ts.frm
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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`test2`.`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`test2`.`t2`,`ts` /* generated by ddl log */
"engine: aria crash point: ddl_log_drop_after_drop_trigger position: 1"
+ts.MAD
+ts.MAI
+ts.frm
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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`test2`.`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`test2`.`t2`,`ts` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`test2`.`t2`,`ts` /* generated by ddl log */
"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 */
+master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`test2`.`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 */
+master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`test2`.`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 */
+master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`test2`.`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 */
+master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`test2`.`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 */
+master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`test2`.`t2`,`ts` /* generated by server */
Warnings:
-Note 1051 Unknown table 'test.t1,test.t2,test.ts'
+Note 1051 Unknown table 'test.t1,test2.t2,test.ts'
diff --git a/mysql-test/suite/atomic/drop_sequence.test b/mysql-test/suite/atomic/drop_sequence.test
index b2fd60e8649..a7a398a1200 100644
--- a/mysql-test/suite/atomic/drop_sequence.test
+++ b/mysql-test/suite/atomic/drop_sequence.test
@@ -4,11 +4,14 @@
#
# Testing of atomic drop with crashes in a lot of different places
+# We also test having the tables in different databases
#
call mtr.add_suppression("InnoDB: .* does not exist in the InnoDB internal");
let $MYSQLD_DATADIR= `SELECT @@datadir`;
+create database test2;
+
let $engine_count=1;
let $engines='aria';
@@ -53,10 +56,10 @@ while ($e < $engine_count)
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;
+ --eval create table test2.t2 (b int not null) $extra_option;
create sequence ts;
insert into t1 values(1);
- insert into t2 values(2);
+ insert into test2.t2 values(2);
flush tables;
delimiter |;
@@ -66,7 +69,7 @@ while ($e < $engine_count)
set new.a:= 1000;
end if;
end|
- create trigger t2_trg before insert on t2 for each row
+ create trigger test2.t2_trg before insert on test2.t2 for each row
begin
if isnull(new.b) then
set new.b:= 2000;
@@ -82,7 +85,7 @@ while ($e < $engine_count)
--eval set @@debug_dbug="+d,$crash",@debug_crash_counter=$r
let $errno=0;
--error 0,2013
- drop table t1,t2,ts;
+ drop table t1,test2.t2,ts;
let $error=$errno;
--enable_reconnect
--source include/wait_until_connected_again.inc
@@ -95,6 +98,7 @@ while ($e < $engine_count)
}
# Check which tables still exists
--list_files $MYSQLD_DATADIR/test t*
+ --list_files $MYSQLD_DATADIR/test2 t*
--let $binlog_file=master-bin.000001
--source include/show_binlog_events.inc
@@ -105,11 +109,11 @@ while ($e < $engine_count)
}
# Really drop the tables. The warnings will show what was dropped
--disable_warnings
- drop table if exists t1,t2,ts;
+ drop table if exists t1,test2.t2,ts;
--enable_warnings
}
}
}
-drop table if exists t1,t2,ts;
-
+drop table if exists t1,test2.t2,ts;
+drop database test2;
--enable_query_log
diff --git a/mysql-test/suite/atomic/drop_table.result b/mysql-test/suite/atomic/drop_table.result
index 096323df8f2..210ec234cfa 100644
--- a/mysql-test/suite/atomic/drop_table.result
+++ b/mysql-test/suite/atomic/drop_table.result
@@ -5,47 +5,47 @@ t2.MYI
t2.TRG
t2.frm
t2_trg.TRN
-master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 */
@@ -60,47 +60,47 @@ t2.MAI
t2.TRG
t2.frm
t2_trg.TRN
-master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 */
@@ -115,47 +115,47 @@ t2.MAI
t2.TRG
t2.frm
t2_trg.TRN
-master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 */
@@ -169,43 +169,43 @@ t2.TRG
t2.frm
t2.ibd
t2_trg.TRN
-master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 */
@@ -220,47 +220,47 @@ t2.CSV
t2.TRG
t2.frm
t2_trg.TRN
-master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by ddl log */
"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 */
diff --git a/mysql-test/suite/atomic/drop_view.result b/mysql-test/suite/atomic/drop_view.result
index dcc4ba4f3cf..6dad41389e8 100644
--- a/mysql-test/suite/atomic/drop_view.result
+++ b/mysql-test/suite/atomic/drop_view.result
@@ -1,15 +1,15 @@
"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 log */
+master-bin.000002 # Query # # use `test`; DROP VIEW IF EXISTS `v1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP VIEW IF EXISTS `v1`,`v2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP VIEW IF EXISTS `v1` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP VIEW IF EXISTS `v1`,`v2` /* generated by ddl log */
"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 log */
+master-bin.000002 # Query # # use `test`; DROP VIEW IF EXISTS `v1`,`v2` /* generated by ddl log */
"engine: aria crash point: ddl_log_drop_before_binlog position: 2"
"No crash!"
master-bin.000001 # Query # # use `test`; DROP VIEW v1,v2
diff --git a/sql/ddl_log.cc b/sql/ddl_log.cc
index 81598a2bf9c..24168e5a7e1 100644
--- a/sql/ddl_log.cc
+++ b/sql/ddl_log.cc
@@ -27,6 +27,7 @@
#include "sql_view.h" // mysql_rename_view()
#include "strfunc.h" // strconvert
#include "sql_show.h" // append_identifier()
+#include "sql_db.h" // drop_database_objects()
#include <mysys_err.h> // EE_LINK
@@ -86,13 +87,16 @@ const char *ddl_log_action_name[DDL_LOG_LAST_ACTION]=
"partitioning replace", "partitioning exchange",
"rename table", "rename view",
"initialize drop table", "drop table",
- "initialize drop view", "drop view", "drop trigger",
+ "drop view", "drop trigger", "drop db",
};
/* Number of phases per entry */
const uchar ddl_log_entry_phases[DDL_LOG_LAST_ACTION]=
{
- 0, 1, 1, 2, 3, 4, 1, 1, 3, 1, 1, 1
+ 0, 1, 1, 2,
+ (uchar) EXCH_PHASE_END, (uchar) DDL_RENAME_PHASE_END, 1, 1,
+ (uchar) DDL_DROP_PHASE_END, 1, 1,
+ (uchar) DDL_DROP_DB_PHASE_END
};
@@ -109,8 +113,17 @@ struct st_global_ddl_log
bool open;
};
-st_global_ddl_log global_ddl_log;
-String ddl_drop_query; // Used during startup recovery
+/* The following structure is only used during startup recovery */
+class st_ddl_recovery {
+public:
+ String drop_table;
+ String drop_view;
+ size_t drop_table_init_length, drop_view_init_length;
+ char current_db[NAME_LEN];
+};
+
+static st_global_ddl_log global_ddl_log;
+static st_ddl_recovery recovery_state;
mysql_mutex_t LOCK_gdl;
@@ -757,6 +770,8 @@ static bool ddl_log_increment_phase_no_lock(uint entry_pos)
Ignore errors from the file system about:
- Non existing tables or file (from drop table or delete file)
- Error about tables files that already exists.
+ - Error from delete table (from Drop_table_error_handler)
+ - Wrong trigger definer (from Drop_table_error_handler)
*/
class ddl_log_error_handler : public Internal_error_handler
@@ -764,8 +779,10 @@ class ddl_log_error_handler : public Internal_error_handler
public:
int handled_errors;
int unhandled_errors;
+ int first_error;
- ddl_log_error_handler() : handled_errors(0), unhandled_errors(0)
+ ddl_log_error_handler() : handled_errors(0), unhandled_errors(0),
+ first_error(0)
{}
bool handle_condition(THD *thd,
@@ -776,11 +793,14 @@ public:
Sql_condition ** cond_hdl)
{
*cond_hdl= NULL;
- if (non_existing_table_error(sql_errno) || sql_errno == EE_LINK)
+ if (non_existing_table_error(sql_errno) || sql_errno == EE_LINK ||
+ sql_errno == EE_DELETE || sql_errno == ER_TRG_NO_DEFINER)
{
handled_errors++;
return TRUE;
}
+ if (!first_error)
+ first_error= sql_errno;
if (*level == Sql_condition::WARN_LEVEL_ERROR)
unhandled_errors++;
@@ -819,6 +839,77 @@ static bool build_filename_and_delete_tmp_file(char *path, size_t path_length,
}
+static LEX_CSTRING end_comment=
+{ STRING_WITH_LEN(" /* generated by ddl log */")};
+
+
+/**
+ Log DROP query to binary log with comment
+
+ This function is only run during recovery
+*/
+
+static void ddl_log_to_binary_log(THD *thd, String *query)
+{
+ LEX_CSTRING thd_db= thd->db;
+
+ lex_string_set(&thd->db, recovery_state.current_db);
+ query->length(query->length()-1); // Removed end ','
+ query->append(&end_comment);
+ mysql_mutex_unlock(&LOCK_gdl);
+ (void) thd->binlog_query(THD::STMT_QUERY_TYPE,
+ query->ptr(), query->length(),
+ TRUE, FALSE, FALSE, 0);
+ mysql_mutex_lock(&LOCK_gdl);
+ thd->db= thd_db;
+}
+
+
+/**
+ Log DROP TABLE/VIEW to binary log when needed
+
+ @result 0 Nothing was done
+ @result 1 Query was logged to binary log & query was reset
+
+ Logging happens in the following cases
+ - This is the last DROP entry
+ - The query could be longer than max_packet_length if we would add another
+ table name to the query
+
+ When we log, we always log all found tables and views at the same time. This
+ is done to simply the exceute code as otherwise we would have to keep
+ information of what was logged.
+*/
+
+static bool ddl_log_drop_to_binary_log(THD *thd, DDL_LOG_ENTRY *ddl_log_entry,
+ String *query)
+{
+ DBUG_ENTER("ddl_log_binary_log");
+ if (mysql_bin_log.is_open())
+ {
+ if (!ddl_log_entry->next_entry ||
+ query->length() + end_comment.length + NAME_LEN + 100 >
+ thd->variables.max_allowed_packet)
+ {
+ if (recovery_state.drop_table.length() >
+ recovery_state.drop_table_init_length)
+ {
+ ddl_log_to_binary_log(thd, &recovery_state.drop_table);
+ recovery_state.drop_table.length(recovery_state.drop_table_init_length);
+ }
+ if (recovery_state.drop_view.length() >
+ recovery_state.drop_view_init_length)
+ {
+ ddl_log_to_binary_log(thd, &recovery_state.drop_view);
+ recovery_state.drop_view.length(recovery_state.drop_view_init_length);
+ }
+ DBUG_RETURN(1);
+ }
+ }
+ DBUG_RETURN(0);
+}
+
+
/**
Execute one action in a ddl log entry
@@ -829,10 +920,6 @@ static bool build_filename_and_delete_tmp_file(char *path, size_t path_length,
@retval FALSE Success
*/
-static LEX_CSTRING end_comment=
-{ STRING_WITH_LEN(" /* generated by ddl log */")};
-
-
static int ddl_log_execute_action(THD *thd, MEM_ROOT *mem_root,
DDL_LOG_ENTRY *ddl_log_entry)
{
@@ -848,10 +935,11 @@ static int ddl_log_execute_action(THD *thd, MEM_ROOT *mem_root,
mysql_mutex_assert_owner(&LOCK_gdl);
DBUG_PRINT("ddl_log",
- ("entry type: %u action type: %u phase: %u next: %u "
+ ("entry type: %u action type: %u (%s) phase: %u next: %u "
"handler: '%s' name: '%s' from_name: '%s' tmp_name: '%s'",
(uint) ddl_log_entry->entry_type,
(uint) ddl_log_entry->action_type,
+ ddl_log_action_name[ddl_log_entry->action_type],
(uint) ddl_log_entry->phase,
ddl_log_entry->next_entry,
ddl_log_entry->handler_name.str,
@@ -1147,17 +1235,32 @@ static int ddl_log_execute_action(THD *thd, MEM_ROOT *mem_root,
(void) update_phase(entry_pos, DDL_LOG_FINAL_PHASE);
}
break;
- case DDL_LOG_DROP_TABLE_INIT_ACTION:
+ /*
+ Initialize variables for DROP TABLE and DROP VIEW
+ In normal cases a query only contains one action. However in case of
+ DROP DATABASE we may get a mix of both and we have to keep these
+ separate.
+ */
+ case DDL_LOG_DROP_INIT_ACTION:
{
LEX_CSTRING *comment= &ddl_log_entry->tmp_name;
- ddl_drop_query.length(0);
- ddl_drop_query.set_charset(default_charset_info);
- ddl_drop_query.append(STRING_WITH_LEN("DROP TABLE IF EXISTS "));
+ recovery_state.drop_table.length(0);
+ recovery_state.drop_table.set_charset(default_charset_info);
+ recovery_state.drop_table.append(STRING_WITH_LEN("DROP TABLE IF EXISTS "));
if (comment->length)
{
- ddl_drop_query.append(comment);
- ddl_drop_query.append(' ');
+ recovery_state.drop_table.append(comment);
+ recovery_state.drop_table.append(' ');
}
+ recovery_state.drop_table_init_length= recovery_state.drop_table.length();
+
+ recovery_state.drop_view.length(0);
+ recovery_state.drop_view.set_charset(default_charset_info);
+ recovery_state.drop_view.append(STRING_WITH_LEN("DROP VIEW IF EXISTS "));
+ recovery_state.drop_view_init_length= recovery_state.drop_view.length();
+
+ strmake(recovery_state.current_db,
+ ddl_log_entry->from_db.str, sizeof(recovery_state.current_db)-1);
/* We don't increment phase as we want to retry this in case of crash */
break;
}
@@ -1200,37 +1303,31 @@ static int ddl_log_execute_action(THD *thd, MEM_ROOT *mem_root,
(void) ddl_log_sync_no_lock();
/* Fall through */
- case DDL_DROP_PHASE_COLLECT:
- append_identifier(thd, &ddl_drop_query, &db);
- ddl_drop_query.append('.');
- append_identifier(thd, &ddl_drop_query, &table);
- ddl_drop_query.append(',');
+ case DDL_DROP_PHASE_COLLECT:
+ if (strcmp(recovery_state.current_db, db.str))
+ {
+ append_identifier(thd, &recovery_state.drop_table, &db);
+ recovery_state.drop_table.append('.');
+ }
+ append_identifier(thd, &recovery_state.drop_table, &table);
+ recovery_state.drop_table.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())
+ if (ddl_log_drop_to_binary_log(thd, ddl_log_entry,
+ &recovery_state.drop_table))
{
- /* Last drop table. Write query to binlog */
- 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);
+ if (ddl_log_increment_phase_no_lock(entry_pos))
+ break;
}
break;
+ case DDL_DROP_PHASE_RESET:
+ /* We have already logged all previous drop's. Clear the query */
+ recovery_state.drop_table.length(recovery_state.drop_table_init_length);
+ recovery_state.drop_view.length(recovery_state.drop_view_init_length);
+ break;
}
break;
}
- case DDL_LOG_DROP_VIEW_INIT_ACTION:
- {
- ddl_drop_query.length(0);
- ddl_drop_query.set_charset(default_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;
@@ -1239,23 +1336,29 @@ static int ddl_log_execute_action(THD *thd, MEM_ROOT *mem_root,
/* 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 && mysql_bin_log.is_open())
+ if (ddl_log_entry->phase == 0)
{
- /* Last drop view. Write query to binlog */
- ddl_drop_query.length(ddl_drop_query.length()-1);
- ddl_drop_query.append(&end_comment);
+ mysql_file_delete(key_file_frm, path.str, MYF(MY_WME|MY_IGNORE_ENOENT));
+ if (strcmp(recovery_state.current_db, db.str))
+ {
+ append_identifier(thd, &recovery_state.drop_view, &db);
+ recovery_state.drop_view.append('.');
+ }
+ append_identifier(thd, &recovery_state.drop_view, &table);
+ recovery_state.drop_view.append(',');
- 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);
+ if (ddl_log_drop_to_binary_log(thd, ddl_log_entry,
+ &recovery_state.drop_view))
+ {
+ if (ddl_log_increment_phase_no_lock(entry_pos))
+ break;
+ }
+ }
+ else
+ {
+ /* We have already logged all previous drop's. Clear the query */
+ recovery_state.drop_table.length(recovery_state.drop_table_init_length);
+ recovery_state.drop_view.length(recovery_state.drop_table_init_length);
}
break;
}
@@ -1294,24 +1397,27 @@ static int ddl_log_execute_action(THD *thd, MEM_ROOT *mem_root,
&ddl_log_entry->from_name,
MYF(0));
- ddl_drop_query.length(0);
- ddl_drop_query.set_charset(default_charset_info);
+ recovery_state.drop_table.length(0);
+ recovery_state.drop_table.set_charset(default_charset_info);
if (ddl_log_entry->tmp_name.length)
{
/* We can use the original query */
- ddl_drop_query.append(&ddl_log_entry->tmp_name);
+ recovery_state.drop_table.append(&ddl_log_entry->tmp_name);
}
else
{
/* Generate new query */
- ddl_drop_query.append(STRING_WITH_LEN("DROP TRIGGER IF EXISTS "));
- append_identifier(thd, &ddl_drop_query, &ddl_log_entry->from_name);
- ddl_drop_query.append(&end_comment);
+ recovery_state.drop_table.append(STRING_WITH_LEN("DROP TRIGGER IF "
+ "EXISTS "));
+ append_identifier(thd, &recovery_state.drop_table,
+ &ddl_log_entry->from_name);
+ recovery_state.drop_table.append(&end_comment);
}
mysql_mutex_unlock(&LOCK_gdl);
thd->db= ddl_log_entry->db;
- (void) thd->binlog_query(THD::STMT_QUERY_TYPE, ddl_drop_query.ptr(),
- ddl_drop_query.length(), TRUE, FALSE,
+ (void) thd->binlog_query(THD::STMT_QUERY_TYPE,
+ recovery_state.drop_table.ptr(),
+ recovery_state.drop_table.length(), TRUE, FALSE,
FALSE, 0);
thd->db= thd_db;
mysql_mutex_lock(&LOCK_gdl);
@@ -1319,6 +1425,45 @@ static int ddl_log_execute_action(THD *thd, MEM_ROOT *mem_root,
(void) update_phase(entry_pos, DDL_LOG_FINAL_PHASE);
break;
}
+ case DDL_LOG_DROP_DB_ACTION:
+ {
+ LEX_CSTRING db, path;
+ db= ddl_log_entry->db;
+ path= ddl_log_entry->tmp_name;
+
+ switch (ddl_log_entry->phase) {
+ case DDL_DROP_DB_PHASE_INIT:
+ drop_database_objects(thd, &path, &db,
+ !my_strcasecmp(system_charset_info,
+ MYSQL_SCHEMA_NAME.str, db.str));
+
+ strxnmov(to_path, sizeof(to_path)-1, path.str, MY_DB_OPT_FILE, NullS);
+ mysql_file_delete_with_symlink(key_file_misc, to_path, "", MYF(0));
+
+ (void) rm_dir_w_symlink(path.str, 0);
+ if (ddl_log_increment_phase_no_lock(entry_pos))
+ break;
+ /* Fall through */
+ case DDL_DROP_DB_PHASE_LOG:
+ {
+ String *query= &recovery_state.drop_table;
+
+ query->length(0);
+ query->append(STRING_WITH_LEN("DROP DATABASE IF EXISTS "));
+ append_identifier(thd, query, &db);
+ query->append(&end_comment);
+
+ mysql_mutex_unlock(&LOCK_gdl);
+ (void) thd->binlog_query(THD::STMT_QUERY_TYPE,
+ query->ptr(), query->length(),
+ TRUE, FALSE, FALSE, 0);
+ mysql_mutex_lock(&LOCK_gdl);
+ (void) update_phase(entry_pos, DDL_LOG_FINAL_PHASE);
+ break;
+ }
+ }
+ break;
+ }
default:
DBUG_ASSERT(0);
break;
@@ -1326,7 +1471,8 @@ static int ddl_log_execute_action(THD *thd, MEM_ROOT *mem_root,
end:
delete file;
- error= no_such_table_handler.unhandled_errors > 0;
+ if ((error= no_such_table_handler.unhandled_errors > 0))
+ my_errno= no_such_table_handler.first_error;
thd->pop_internal_handler();
DBUG_RETURN(error);
}
@@ -1446,9 +1592,10 @@ static bool ddl_log_execute_entry_no_lock(THD *thd, uint first_entry)
action_type= 0;
/* Write to error log and continue with next log entry */
- sql_print_error("Failed to execute action for entry %u of type '%s' "
- "from ddl log",
- read_entry, ddl_log_action_name[action_type]);
+ sql_print_error("Got error %d when trying to execute action for entry %u "
+ "of type '%s'",
+ (int) my_errno, read_entry,
+ ddl_log_action_name[action_type]);
break;
}
read_entry= ddl_log_entry.next_entry;
@@ -1482,7 +1629,6 @@ bool ddl_log_write_entry(DDL_LOG_ENTRY *ddl_log_entry,
DDL_LOG_MEMORY_ENTRY **active_entry)
{
bool error;
- uchar *pos, *end;
DBUG_ENTER("ddl_log_write_entry");
*active_entry= 0;
@@ -1500,20 +1646,18 @@ bool ddl_log_write_entry(DDL_LOG_ENTRY *ddl_log_entry,
DBUG_RETURN(TRUE);
error= FALSE;
- pos= global_ddl_log.file_entry_buf + global_ddl_log.name_pos;
- end= global_ddl_log.file_entry_buf + global_ddl_log.io_size;
DBUG_PRINT("ddl_log",
- ("type: %c next: %u handler: %s "
- "to_name: '%s.%s' from_name: '%s.%s' "
- "tmp_name: '%s'",
- (char) global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS],
+ ("entry type: %u action type: %u (%s) phase: %u next: %u "
+ "handler: '%s' name: '%s' from_name: '%s' tmp_name: '%s'",
+ (uint) ddl_log_entry->entry_type,
+ (uint) ddl_log_entry->action_type,
+ ddl_log_action_name[ddl_log_entry->action_type],
+ (uint) ddl_log_entry->phase,
ddl_log_entry->next_entry,
- get_string(&pos, end).str, // Handler
- get_string(&pos, end).str, // to db.table
- get_string(&pos, end).str,
- get_string(&pos, end).str, // From db.table
- get_string(&pos, end).str,
- get_string(&pos, end).str)); // Tmp name
+ ddl_log_entry->handler_name.str,
+ ddl_log_entry->name.str,
+ ddl_log_entry->from_name.str,
+ ddl_log_entry->tmp_name.str));
if (unlikely(write_ddl_log_file_entry((*active_entry)->entry_pos)))
{
@@ -1595,8 +1739,9 @@ bool ddl_log_write_execute_entry(uint first_entry,
DBUG_RETURN(FALSE);
}
+
/**
- Increment phase for enty. Will deactivate entry after all phases are done
+ Increment phase for entry. Will deactivate entry after all phases are done
@details see ddl_log_increment_phase_no_lock.
@@ -1756,7 +1901,8 @@ int ddl_log_execute_recovery()
}
thd->thread_stack= (char*) &thd;
thd->store_globals();
- ddl_drop_query.free();
+ recovery_state.drop_table.free();
+ recovery_state.drop_view.free();
thd->set_query(recover_query_string, strlen(recover_query_string));
@@ -1778,7 +1924,8 @@ int ddl_log_execute_recovery()
}
}
}
- ddl_drop_query.free();
+ recovery_state.drop_table.free();
+ recovery_state.drop_view.free();
close_ddl_log();
mysql_mutex_unlock(&LOCK_gdl);
thd->reset_query();
@@ -1885,12 +2032,13 @@ void ddl_log_complete(DDL_LOG_STATE *state)
ddl_log_disable_execute_entry(&state->execute_entry);
ddl_log_release_entries(state);
mysql_mutex_unlock(&LOCK_gdl);
+ state->list= 0;
DBUG_VOID_RETURN;
};
/**
- Revert all entries in the ddl log
+ Revert (execute) all entries in the ddl log
*/
void ddl_log_revert(THD *thd, DDL_LOG_STATE *state)
@@ -1908,6 +2056,7 @@ void ddl_log_revert(THD *thd, DDL_LOG_STATE *state)
}
ddl_log_release_entries(state);
mysql_mutex_unlock(&LOCK_gdl);
+ state->list= 0;
DBUG_VOID_RETURN;
}
@@ -2045,6 +2194,7 @@ bool ddl_log_rename_view(THD *thd, DDL_LOG_STATE *ddl_state,
static bool ddl_log_drop_init(THD *thd, DDL_LOG_STATE *ddl_state,
ddl_log_action_code action_code,
+ const LEX_CSTRING *db,
const LEX_CSTRING *comment)
{
DDL_LOG_ENTRY ddl_log_entry;
@@ -2053,26 +2203,26 @@ static bool ddl_log_drop_init(THD *thd, DDL_LOG_STATE *ddl_state,
bzero(&ddl_log_entry, sizeof(ddl_log_entry));
ddl_log_entry.action_type= action_code;
- ddl_log_entry.next_entry= 0;
+ ddl_log_entry.from_db= *const_cast<LEX_CSTRING*>(db);
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 *db,
const LEX_CSTRING *comment)
{
- return ddl_log_drop_init(thd, ddl_state, DDL_LOG_DROP_TABLE_INIT_ACTION,
- comment);
+ return ddl_log_drop_init(thd, ddl_state, DDL_LOG_DROP_INIT_ACTION,
+ db, comment);
}
-bool ddl_log_drop_view_init(THD *thd, DDL_LOG_STATE *ddl_state)
+bool ddl_log_drop_view_init(THD *thd, DDL_LOG_STATE *ddl_state,
+ const LEX_CSTRING *db)
{
- LEX_CSTRING comment= {0,0};
- return ddl_log_drop_init(thd, ddl_state, DDL_LOG_DROP_VIEW_INIT_ACTION,
- &comment);
+ return ddl_log_drop_init(thd, ddl_state, DDL_LOG_DROP_INIT_ACTION,
+ db, &empty_clex_str);
}
static bool ddl_log_drop(THD *thd, DDL_LOG_STATE *ddl_state,
@@ -2157,7 +2307,7 @@ bool ddl_log_drop_trigger(THD *thd, DDL_LOG_STATE *ddl_state,
char path[FN_REFLEN+1];
off_t frm_length= 0;
size_t max_query_length;
- DBUG_ENTER("ddl_log_drop");
+ DBUG_ENTER("ddl_log_drop_trigger");
build_table_filename(path, sizeof(path)-1, db->str, table->str, TRG_EXT, 0);
@@ -2184,3 +2334,27 @@ bool ddl_log_drop_trigger(THD *thd, DDL_LOG_STATE *ddl_state,
DBUG_RETURN(ddl_log_write(ddl_state, &ddl_log_entry));
}
+
+
+/**
+ Log DROP DATABASE
+
+ This is logged after all DROP TABLE's for the database.
+ As now know we are going to log DROP DATABASE to the binary log, we want
+ to ignore want to ignore all preceding DROP TABLE entries. We do that by
+ linking this entry directly after the execute entry and forgetting the
+ link to the previous entries (not setting ddl_log_entry.next_entry)
+*/
+
+bool ddl_log_drop_db(THD *thd, DDL_LOG_STATE *ddl_state,
+ const LEX_CSTRING *db, const LEX_CSTRING *path)
+{
+ DDL_LOG_ENTRY ddl_log_entry;
+ DBUG_ENTER("ddl_log_drop_db");
+
+ bzero(&ddl_log_entry, sizeof(ddl_log_entry));
+ ddl_log_entry.action_type= DDL_LOG_DROP_DB_ACTION;
+ ddl_log_entry.db= *const_cast<LEX_CSTRING*>(db);
+ ddl_log_entry.tmp_name= *const_cast<LEX_CSTRING*>(path);
+ DBUG_RETURN(ddl_log_write(ddl_state, &ddl_log_entry));
+}
diff --git a/sql/ddl_log.h b/sql/ddl_log.h
index 2f36431d9b5..b8e2c3fc91d 100644
--- a/sql/ddl_log.h
+++ b/sql/ddl_log.h
@@ -78,11 +78,11 @@ enum ddl_log_action_code
*/
DDL_LOG_RENAME_TABLE_ACTION= 5,
DDL_LOG_RENAME_VIEW_ACTION= 6,
- DDL_LOG_DROP_TABLE_INIT_ACTION= 7,
+ DDL_LOG_DROP_INIT_ACTION= 7,
DDL_LOG_DROP_TABLE_ACTION= 8,
- DDL_LOG_DROP_VIEW_INIT_ACTION= 9,
- DDL_LOG_DROP_VIEW_ACTION= 10,
- DDL_LOG_DROP_TRIGGER_ACTION= 11,
+ DDL_LOG_DROP_VIEW_ACTION= 9,
+ DDL_LOG_DROP_TRIGGER_ACTION= 10,
+ DDL_LOG_DROP_DB_ACTION=11,
DDL_LOG_LAST_ACTION /* End marker */
};
@@ -94,13 +94,15 @@ extern const uchar ddl_log_entry_phases[DDL_LOG_LAST_ACTION];
enum enum_ddl_log_exchange_phase {
EXCH_PHASE_NAME_TO_TEMP= 0,
EXCH_PHASE_FROM_TO_NAME= 1,
- EXCH_PHASE_TEMP_TO_FROM= 2
+ EXCH_PHASE_TEMP_TO_FROM= 2,
+ EXCH_PHASE_END
};
enum enum_ddl_log_rename_table_phase {
DDL_RENAME_PHASE_TRIGGER= 0,
DDL_RENAME_PHASE_STAT,
DDL_RENAME_PHASE_TABLE,
+ DDL_RENAME_PHASE_END
};
enum enum_ddl_log_drop_table_phase {
@@ -111,6 +113,12 @@ enum enum_ddl_log_drop_table_phase {
DDL_DROP_PHASE_END
};
+enum enum_ddl_log_drop_db_phase {
+ DDL_DROP_DB_PHASE_INIT=0,
+ DDL_DROP_DB_PHASE_LOG,
+ DDL_DROP_DB_PHASE_END
+};
+
/*
Setting ddl_log_entry.phase to this has the same effect as setting
action_type to DDL_IGNORE_LOG_ENTRY_CODE
@@ -199,8 +207,10 @@ bool ddl_log_rename_view(THD *thd, DDL_LOG_STATE *ddl_state,
const LEX_CSTRING *new_db,
const LEX_CSTRING *new_alias);
bool ddl_log_drop_table_init(THD *thd, DDL_LOG_STATE *ddl_state,
+ const LEX_CSTRING *db,
const LEX_CSTRING *comment);
-bool ddl_log_drop_view_init(THD *thd, DDL_LOG_STATE *ddl_state);
+bool ddl_log_drop_view_init(THD *thd, DDL_LOG_STATE *ddl_state,
+ const LEX_CSTRING *db);
bool ddl_log_drop_table(THD *thd, DDL_LOG_STATE *ddl_state,
handlerton *hton,
const LEX_CSTRING *path,
@@ -215,5 +225,13 @@ bool ddl_log_drop_trigger(THD *thd, DDL_LOG_STATE *ddl_state,
const LEX_CSTRING *table,
const LEX_CSTRING *trigger_name,
const LEX_CSTRING *query);
+bool ddl_log_drop_view(THD *thd, DDL_LOG_STATE *ddl_state,
+ 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 *db);
+bool ddl_log_drop_db(THD *thd, DDL_LOG_STATE *ddl_state,
+ const LEX_CSTRING *db, const LEX_CSTRING *path);
extern mysql_mutex_t LOCK_gdl;
#endif /* DDL_LOG_INCLUDED */
diff --git a/sql/handler.cc b/sql/handler.cc
index 13616d0b949..1a8f9d2d96f 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -837,9 +837,10 @@ static my_bool dropdb_handlerton(THD *unused1, plugin_ref plugin,
}
-void ha_drop_database(char* path)
+void ha_drop_database(const char* path)
{
- plugin_foreach(NULL, dropdb_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, path);
+ plugin_foreach(NULL, dropdb_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN,
+ (char*) path);
}
diff --git a/sql/handler.h b/sql/handler.h
index 76a8ad82dd1..12f36b7a4e1 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -5110,7 +5110,7 @@ int ha_panic(enum ha_panic_function flag);
void ha_close_connection(THD* thd);
void ha_kill_query(THD* thd, enum thd_kill_levels level);
bool ha_flush_logs();
-void ha_drop_database(char* path);
+void ha_drop_database(const char* path);
void ha_checkpoint_state(bool disable);
void ha_commit_checkpoint_request(void *cookie, void (*pre_hook)(void *));
int ha_create_table(THD *thd, const char *path,
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index fe95b54cbc9..278ec83fa41 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -40,6 +40,7 @@
#include "events.h"
#include "sql_handler.h"
#include "sql_statistics.h"
+#include "ddl_log.h" // ddl_log functions
#include <my_dir.h>
#include <m_ctype.h>
#include "log.h"
@@ -58,7 +59,7 @@ static bool find_db_tables_and_rm_known_files(THD *, MY_DIR *, const char *,
const char *, TABLE_LIST **);
long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path);
-static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error);
+my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error);
static void mysql_change_db_impl(THD *thd,
LEX_CSTRING *new_db_name,
privilege_t new_db_access,
@@ -952,6 +953,56 @@ bool mysql_alter_db(THD *thd, const LEX_CSTRING *db,
/**
+ Drop database objects
+
+ @param thd THD object
+ @param path Path to database (for ha_drop_database)
+ @param db Normalized database name
+ @param rm_mysql_schema If the schema is 'mysql', in which case we don't
+ log the query to binary log or delete related
+ routines or events.
+*/
+
+void drop_database_objects(THD *thd, const LEX_CSTRING *path,
+ const LEX_CSTRING *db,
+ bool rm_mysql_schema)
+{
+ debug_crash_here("ddl_log_drop_before_ha_drop_database");
+
+ ha_drop_database(path->str);
+
+ /*
+ We temporarily disable the binary log while dropping the objects
+ in the database. Since the DROP DATABASE statement is always
+ replicated as a statement, execution of it will drop all objects
+ in the database on the slave as well, so there is no need to
+ replicate the removal of the individual objects in the database
+ as well.
+
+ This is more of a safety precaution, since normally no objects
+ should be dropped while the database is being cleaned, but in
+ the event that a change in the code to remove other objects is
+ made, these drops should still not be logged.
+ */
+
+ debug_crash_here("ddl_log_drop_before_drop_db_routines");
+
+ query_cache_invalidate1(thd, db->str);
+
+ if (!rm_mysql_schema)
+ {
+ tmp_disable_binlog(thd);
+ (void) sp_drop_db_routines(thd, db->str); /* @todo Do not ignore errors */
+#ifdef HAVE_EVENT_SCHEDULER
+ Events::drop_schema_events(thd, db->str);
+#endif
+ reenable_binlog(thd);
+ }
+ debug_crash_here("ddl_log_drop_after_drop_db_routines");
+}
+
+
+/**
Drop all tables, routines and events in a database and the database itself.
@param thd Thread handle
@@ -967,41 +1018,31 @@ bool mysql_alter_db(THD *thd, const LEX_CSTRING *db,
*/
static bool
-mysql_rm_db_internal(THD *thd, const LEX_CSTRING *db, bool if_exists, bool silent)
+mysql_rm_db_internal(THD *thd, const LEX_CSTRING *db, bool if_exists,
+ bool silent)
{
ulong deleted_tables= 0;
bool error= true, rm_mysql_schema;
char path[FN_REFLEN + 16];
MY_DIR *dirp;
- uint length;
+ uint path_length;
TABLE_LIST *tables= NULL;
TABLE_LIST *table;
+ DDL_LOG_STATE ddl_log_state;
Drop_table_error_handler err_handler;
+ LEX_CSTRING rm_db;
+ char db_tmp[SAFE_NAME_LEN+1];
+ const char *dbnorm;
DBUG_ENTER("mysql_rm_db");
- char db_tmp[SAFE_NAME_LEN+1];
- const char *dbnorm= normalize_db_name(db->str, db_tmp, sizeof(db_tmp));
+ dbnorm= normalize_db_name(db->str, db_tmp, sizeof(db_tmp));
+ lex_string_set(&rm_db, dbnorm);
+ bzero(&ddl_log_state, sizeof(ddl_log_state));
if (lock_schema_name(thd, dbnorm))
DBUG_RETURN(true);
- length= build_table_filename(path, sizeof(path) - 1, db->str, "", "", 0);
- strmov(path+length, MY_DB_OPT_FILE); // Append db option file name
- del_dbopt(path); // Remove dboption hash entry
- /*
- Now remove the db.opt file.
- The 'find_db_tables_and_rm_known_files' doesn't remove this file
- if there exists a table with the name 'db', so let's just do it
- separately. We know this file exists and needs to be deleted anyway.
- */
- if (mysql_file_delete_with_symlink(key_file_misc, path, "", MYF(0)) &&
- my_errno != ENOENT)
- {
- my_error(EE_DELETE, MYF(0), path, my_errno);
- DBUG_RETURN(true);
- }
-
- path[length]= '\0'; // Remove file name
+ path_length= build_table_filename(path, sizeof(path) - 1, db->str, "", "", 0);
/* See if the directory exists */
if (!(dirp= my_dir(path,MYF(MY_DONT_SORT))))
@@ -1052,7 +1093,10 @@ mysql_rm_db_internal(THD *thd, const LEX_CSTRING *db, bool if_exists, bool silen
}
}
- /* mysql_ha_rm_tables() requires a non-null TABLE_LIST. */
+ /*
+ Close active HANDLER's for tables in the database.
+ Note that mysql_ha_rm_tables() requires a non-null TABLE_LIST.
+ */
if (tables)
mysql_ha_rm_tables(thd, tables);
@@ -1062,41 +1106,45 @@ mysql_rm_db_internal(THD *thd, const LEX_CSTRING *db, bool if_exists, bool silen
thd->push_internal_handler(&err_handler);
if (!thd->killed &&
!(tables &&
- mysql_rm_table_no_locks(thd, tables, true, false, true, false, true,
- false)))
+ mysql_rm_table_no_locks(thd, tables, &rm_db, &ddl_log_state, true, false,
+ true, false, true, false)))
{
+ debug_crash_here("ddl_log_drop_after_drop_tables");
+
+ LEX_CSTRING cpath{ path, path_length};
+ ddl_log_drop_db(thd, &ddl_log_state, &rm_db, &cpath);
+
+ drop_database_objects(thd, &cpath, &rm_db, rm_mysql_schema);
+
/*
- We temporarily disable the binary log while dropping the objects
- in the database. Since the DROP DATABASE statement is always
- replicated as a statement, execution of it will drop all objects
- in the database on the slave as well, so there is no need to
- replicate the removal of the individual objects in the database
- as well.
-
- This is more of a safety precaution, since normally no objects
- should be dropped while the database is being cleaned, but in
- the event that a change in the code to remove other objects is
- made, these drops should still not be logged.
+ Now remove the db.opt file.
+ The 'find_db_tables_and_rm_known_files' doesn't remove this file
+ if there exists a table with the name 'db', so let's just do it
+ separately. We know this file exists and needs to be deleted anyway.
*/
-
- ha_drop_database(path);
- tmp_disable_binlog(thd);
- query_cache_invalidate1(thd, dbnorm);
- if (!rm_mysql_schema)
+ debug_crash_here("ddl_log_drop_before_drop_option_file");
+ strmov(path+path_length, MY_DB_OPT_FILE); // Append db option file name
+ if (mysql_file_delete_with_symlink(key_file_misc, path, "", MYF(0)) &&
+ my_errno != ENOENT)
{
- (void) sp_drop_db_routines(thd, dbnorm); /* @todo Do not ignore errors */
-#ifdef HAVE_EVENT_SCHEDULER
- Events::drop_schema_events(thd, dbnorm);
-#endif
+ thd->pop_internal_handler();
+ my_error(EE_DELETE, MYF(0), path, my_errno);
+ error= true;
+ ddl_log_complete(&ddl_log_state);
+ goto end;
}
- reenable_binlog(thd);
+ del_dbopt(path); // Remove dboption hash entry
+ path[path_length]= '\0'; // Remove file name
/*
If the directory is a symbolic link, remove the link first, then
remove the directory the symbolic link pointed at
*/
+ debug_crash_here("ddl_log_drop_before_drop_dir");
error= rm_dir_w_symlink(path, true);
+ debug_crash_here("ddl_log_drop_after_drop_dir");
}
+
thd->pop_internal_handler();
update_binlog:
@@ -1112,6 +1160,7 @@ update_binlog:
if (mysql_bin_log.is_open())
{
int errcode= query_error_code(thd, TRUE);
+ int res;
Query_log_event qinfo(thd, query, query_length, FALSE, TRUE,
/* suppress_use */ TRUE, errcode);
/*
@@ -1126,7 +1175,14 @@ update_binlog:
These DDL methods and logging are protected with the exclusive
metadata lock on the schema.
*/
- if (mysql_bin_log.write(&qinfo))
+ debug_crash_here("ddl_log_drop_before_binlog");
+ thd->binlog_xid= thd->query_id;
+ ddl_log_update_xid(&ddl_log_state, thd->binlog_xid);
+ res= mysql_bin_log.write(&qinfo);
+ thd->binlog_xid= 0;
+ debug_crash_here("ddl_log_drop_after_binlog");
+
+ if (res)
{
error= true;
goto exit;
@@ -1176,13 +1232,21 @@ update_binlog:
*query_pos++ = ',';
}
- if (query_pos != query_data_start)
+ if (query_pos != query_data_start) // If database was not empty
{
+ int res;
/*
These DDL methods and logging are protected with the exclusive
metadata lock on the schema.
*/
- if (write_to_binlog(thd, query, (uint)(query_pos -1 - query), db->str, db->length))
+ debug_crash_here("ddl_log_drop_before_binlog");
+ thd->binlog_xid= thd->query_id;
+ ddl_log_update_xid(&ddl_log_state, thd->binlog_xid);
+ res= write_to_binlog(thd, query, (uint)(query_pos -1 - query), db->str,
+ db->length);
+ thd->binlog_xid= 0;
+ debug_crash_here("ddl_log_drop_after_binlog");
+ if (res)
{
error= true;
goto exit;
@@ -1191,6 +1255,7 @@ update_binlog:
}
exit:
+ ddl_log_complete(&ddl_log_state);
/*
If this database was the client's selected database, we silently
change the client's selected database to nothing (to have an empty
@@ -1202,6 +1267,7 @@ exit:
mysql_change_db_impl(thd, NULL, NO_ACL, thd->variables.collation_server);
thd->session_tracker.current_schema.mark_as_changed(thd);
}
+end:
my_dirend(dirp);
DBUG_RETURN(error);
}
@@ -1332,22 +1398,24 @@ static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp,
1 ERROR
*/
-static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error)
+my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error)
{
char tmp_path[FN_REFLEN], *pos;
char *path= tmp_path;
DBUG_ENTER("rm_dir_w_symlink");
unpack_filename(tmp_path, org_path);
-#ifdef HAVE_READLINK
- int error;
- char tmp2_path[FN_REFLEN];
- /* Remove end FN_LIBCHAR as this causes problem on Linux in readlink */
+ /* Remove end FN_LIBCHAR as this causes problem on Linux and OS/2 */
pos= strend(path);
if (pos > path && pos[-1] == FN_LIBCHAR)
*--pos=0;
- if (unlikely((error= my_readlink(tmp2_path, path, MYF(MY_WME))) < 0))
+#ifdef HAVE_READLINK
+ int error;
+ char tmp2_path[FN_REFLEN];
+
+ if (unlikely((error= my_readlink(tmp2_path, path,
+ MYF(send_error ? MY_WME : 0))) < 0))
DBUG_RETURN(1);
if (likely(!error))
{
@@ -1359,11 +1427,7 @@ static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error)
path= tmp2_path;
}
#endif
- /* Remove last FN_LIBCHAR to not cause a problem on OS/2 */
- pos= strend(path);
- if (pos > path && pos[-1] == FN_LIBCHAR)
- *--pos=0;
if (unlikely(my_rmdir(path) < 0 && send_error))
{
my_error(ER_DB_DROP_RMDIR, MYF(0), path, errno);
diff --git a/sql/sql_db.h b/sql/sql_db.h
index c9f1ed068e6..3c037d668e0 100644
--- a/sql/sql_db.h
+++ b/sql/sql_db.h
@@ -47,6 +47,10 @@ void my_dbopt_cleanup(void);
const char *normalize_db_name(const char *db, char *buffer,
size_t buffer_size);
+void drop_database_objects(THD *thd, const LEX_CSTRING *path,
+ const LEX_CSTRING *db,
+ bool rm_mysql_schema);
+my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error);
#define MY_DB_OPT_FILE "db.opt"
#endif /* SQL_DB_INCLUDED */
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 99b5e299077..f201e62a4a9 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1039,7 +1039,9 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, bool if_exists,
/* mark for close and remove all cached entries */
thd->push_internal_handler(&err_handler);
- error= mysql_rm_table_no_locks(thd, tables, if_exists, drop_temporary,
+ error= mysql_rm_table_no_locks(thd, tables, &thd->db, (DDL_LOG_STATE*) 0,
+ if_exists,
+ drop_temporary,
false, drop_sequence, dont_log_query,
false);
thd->pop_internal_handler();
@@ -1100,6 +1102,11 @@ static uint32 comment_length(THD *thd, uint32 comment_pos,
@param thd Thread handler
@param tables Tables to drop
+ @param current_db Current database, used for ddl logs
+ @param ddl_log_state DDL log state, for global ddl logging (used by
+ DROP DATABASE. If not set, an internal ddl log state
+ will be used. If set then the caller must call
+ ddl_log_complete(ddl_log_state);
@param if_exists If set, don't give an error if table doesn't exists.
In this case we give an warning of level 'NOTE'
@param drop_temporary Only drop temporary tables
@@ -1128,7 +1135,10 @@ static uint32 comment_length(THD *thd, uint32 comment_pos,
not all.
*/
-int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
+int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables,
+ const LEX_CSTRING *current_db,
+ DDL_LOG_STATE *ddl_log_state,
+ bool if_exists,
bool drop_temporary, bool drop_view,
bool drop_sequence,
bool dont_log_query,
@@ -1138,7 +1148,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
char path[FN_REFLEN + 1];
LEX_CSTRING alias= null_clex_str;
StringBuffer<160> unknown_tables(system_charset_info);
- DDL_LOG_STATE ddl_log_state;
+ DDL_LOG_STATE local_ddl_log_state;
const char *comment_start;
uint32 comment_len;
uint not_found_errors= 0, first_table= 0;
@@ -1156,6 +1166,12 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
String built_trans_tmp_query, built_non_trans_tmp_query;
DBUG_ENTER("mysql_rm_table_no_locks");
+ if (!ddl_log_state)
+ {
+ ddl_log_state= &local_ddl_log_state;
+ bzero(ddl_log_state, sizeof(*ddl_log_state));
+ }
+
unknown_tables.length(0);
comment_len= comment_length(thd, if_exists ? 17:9,
&comment_start);
@@ -1210,14 +1226,13 @@ 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.copy(built_trans_tmp_query);
}
- bzero(&ddl_log_state, sizeof(ddl_log_state));
for (table= tables; table; table= table->next_local)
{
bool is_trans= 0, temporary_table_was_dropped= 0;
bool table_creation_was_logged= 0;
bool local_non_tmp_error= 0, wrong_drop_sequence= 0;
- bool table_dropped= 0;
+ bool table_dropped= 0, res;
const LEX_CSTRING db= table->db;
const LEX_CSTRING table_name= table->table_name;
LEX_CSTRING cpath= {0,0};
@@ -1377,7 +1392,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
if (!first_table++)
{
LEX_CSTRING comment= {comment_start, (size_t) comment_len};
- if (ddl_log_drop_table_init(thd, &ddl_log_state, &comment))
+ if (ddl_log_drop_table_init(thd, ddl_log_state, current_db, &comment))
{
error= 1;
goto err;
@@ -1436,12 +1451,18 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
bool enoent_warning= !dont_log_query && !(hton && hton->discover_table);
- if (ddl_log_drop_table(thd, &ddl_log_state, hton, &cpath, &db,
- &table_name))
+ if (was_view)
+ res= ddl_log_drop_view(thd, ddl_log_state, &cpath, &db,
+ &table_name);
+ else
+ res= ddl_log_drop_table(thd, ddl_log_state, hton, &cpath, &db,
+ &table_name);
+ if (res)
{
- error= -1;
- goto err;
+ 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);
@@ -1513,7 +1534,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
int ferror= 0;
DBUG_ASSERT(!was_view);
- if (ddl_log_drop_table(thd, &ddl_log_state, hton, &cpath, &db,
+ if (ddl_log_drop_table(thd, ddl_log_state, 0, &cpath, &db,
&table_name))
{
error= -1;
@@ -1553,9 +1574,12 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
if (thd->replication_flags & OPTION_IF_EXISTS)
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 (!was_view)
+ {
+ 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))
{
@@ -1620,7 +1644,8 @@ report_error:
table_name.str, (uint)table_name.length);
mysql_audit_drop_table(thd, table);
}
- ddl_log_update_phase(&ddl_log_state, DDL_DROP_PHASE_COLLECT);
+ if (!was_view)
+ ddl_log_update_phase(ddl_log_state, DDL_DROP_PHASE_COLLECT);
if (!dont_log_query &&
(!error || table_dropped || non_existing_table_error(error)))
@@ -1726,7 +1751,7 @@ err:
built_query.append(generated_by_server);
int error_code = non_tmp_error ? thd->get_stmt_da()->sql_errno() : 0;
thd->binlog_xid= thd->query_id;
- ddl_log_update_xid(&ddl_log_state, thd->binlog_xid);
+ ddl_log_update_xid(ddl_log_state, thd->binlog_xid);
error |= (thd->binlog_query(THD::STMT_QUERY_TYPE,
built_query.ptr(),
built_query.length(),
@@ -1737,7 +1762,8 @@ err:
debug_crash_here("ddl_log_drop_after_binlog");
}
}
- ddl_log_complete(&ddl_log_state);
+ if (ddl_log_state == &local_ddl_log_state)
+ ddl_log_complete(ddl_log_state);
if (!drop_temporary)
{
@@ -4217,7 +4243,9 @@ int create_table_impl(THD *thd, const LEX_CSTRING &orig_db,
*/
(void) trans_rollback_stmt(thd);
/* Remove normal table without logging. Keep tables locked */
- if (mysql_rm_table_no_locks(thd, &table_list, 0, 0, 0, 0, 1, 1))
+ if (mysql_rm_table_no_locks(thd, &table_list, &thd->db,
+ (DDL_LOG_STATE*) 0,
+ 0, 0, 0, 0, 1, 1))
goto err;
/*
@@ -4435,7 +4463,9 @@ int mysql_create_table_no_lock(THD *thd, const LEX_CSTRING *db,
{
DBUG_ASSERT(thd->is_error());
/* Drop the table as it wasn't completely done */
- if (!mysql_rm_table_no_locks(thd, table_list, 1,
+ if (!mysql_rm_table_no_locks(thd, table_list, &thd->db,
+ (DDL_LOG_STATE*) 0,
+ 1,
create_info->tmp_table(),
false, true /* Sequence*/,
true /* Don't log_query */,
diff --git a/sql/sql_table.h b/sql/sql_table.h
index a1661086ce5..7ac5cc90f04 100644
--- a/sql/sql_table.h
+++ b/sql/sql_table.h
@@ -37,6 +37,7 @@ typedef struct st_key KEY;
typedef struct st_key_cache KEY_CACHE;
typedef struct st_lock_param_type ALTER_PARTITION_PARAM_TYPE;
typedef struct st_order ORDER;
+typedef struct st_ddl_log_state DDL_LOG_STATE;
enum enum_explain_filename_mode
{
@@ -177,7 +178,10 @@ bool mysql_checksum_table(THD* thd, TABLE_LIST* table_list,
bool mysql_rm_table(THD *thd,TABLE_LIST *tables, bool if_exists,
bool drop_temporary, bool drop_sequence,
bool dont_log_query);
-int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
+int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables,
+ const LEX_CSTRING *db,
+ DDL_LOG_STATE *ddl_log_state,
+ bool if_exists,
bool drop_temporary, bool drop_view,
bool drop_sequence,
bool dont_log_query, bool dont_free_locks);
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 8c9bc35e538..5cd8ad07c58 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -1870,7 +1870,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
}
if (!first_table++)
{
- if (ddl_log_drop_view_init(thd, &ddl_log_state))
+ if (ddl_log_drop_view_init(thd, &ddl_log_state, &thd->db))
DBUG_RETURN(TRUE);
}
if (ddl_log_drop_view(thd, &ddl_log_state, &cpath, &view->db,