#At file:///C:/source/bzr/mysql-6.0-bug-33414/
2675 Chuck Bell 2008-08-18
BUG#33414 : Backup: DDL hangs indefinitely if ongoing backup
Added ability to set a timeout for blocked DDL operations. The
timeout is the number of seconds a blocked DDL operation will
wait before aborting with an error message. The variable can be
set only as a session variable.
Note: timeout must be set before DDL is executed.
added:
mysql-test/r/backup_timeout.result
mysql-test/t/backup_timeout.test
modified:
sql/ddl_blocker.cc
sql/mysql_priv.h
sql/set_var.cc
sql/set_var.h
sql/share/errmsg.txt
sql/sql_class.cc
sql/sql_class.h
sql/sql_parse.cc
per-file messages:
mysql-test/r/backup_timeout.result
New result file.
mysql-test/t/backup_timeout.test
New test for backup timeout functionality.
sql/ddl_blocker.cc
Added ability to timeout based on the variable backup_wait_timeout.
sql/mysql_priv.h
Added backup wait timeout default definition.
sql/set_var.cc
Added session variable backup_wait_timeout.
sql/set_var.h
Added session variable backup_wait_timeout class.
sql/share/errmsg.txt
Added new error message for DDL timeout.
sql/sql_class.cc
Added default value setting for backup_wait_timeout.
sql/sql_class.h
Added thread variable backup_wait_timeout.
sql/sql_parse.cc
Modified code to check for a failed return which indicates the
ddl blocker has timed out.
Corrected possible extra call to end_ddl() if timeout occurs on CREATE TABLE.
=== added file 'mysql-test/r/backup_timeout.result'
--- a/mysql-test/r/backup_timeout.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/backup_timeout.result 2008-08-18 19:39:53 +0000
@@ -0,0 +1,73 @@
+SET DEBUG_SYNC= 'reset';
+DROP DATABASE IF EXISTS bup_ddl_blocker;
+CREATE DATABASE bup_ddl_blocker;
+con1: Creating tables
+CREATE TABLE bup_ddl_blocker.t1 (col_a CHAR(40)) ENGINE=INNODB;
+con1: Loading data
+INSERT INTO bup_ddl_blocker.t1 VALUES ("01 Some data to test");
+INSERT INTO bup_ddl_blocker.t1 VALUES ("02 Some data to test");
+INSERT INTO bup_ddl_blocker.t1 VALUES ("03 Some data to test");
+SHOW VARIABLES LIKE 'backup_wait%';
+Variable_name Value
+backup_wait_timeout 50
+Part A
+con1: Activate synchronization points for backup.
+SET DEBUG_SYNC= 'after_block_ddl SIGNAL bup_blocked WAIT_FOR timeout_done';
+con1: Get a backup going and stop after the DDL blocker is fired.
+BACKUP DATABASE bup_ddl_blocker TO "bup_ddl_blocker.bak";
+SET DEBUG_SYNC= 'now WAIT_FOR bup_blocked';
+Set ddl timeout to 1 second
+SET backup_wait_timeout = 1;
+SHOW VARIABLES LIKE 'backup_wait%';
+Variable_name Value
+backup_wait_timeout 1
+con2: Try a ddl operation and watch it expire
+CREATE TABLE bup_ddl_blocker.t2 (col_a CHAR(40)) ENGINE=MEMORY;
+ERROR HY000: The backup wait timeout has expired for query 'CREATE TABLE bup_ddl_blocker.t2 (col_a CHAR(40)) ENGINE=MEMORY'.
+release the lock.
+con5: Resume all.
+SET DEBUG_SYNC= 'now SIGNAL timeout_done';
+backup_id
+#
+Part B
+con1: Activate synchronization points for backup.
+SET DEBUG_SYNC= 'after_block_ddl SIGNAL bup_blocked WAIT_FOR timeout_done';
+con1: Get a backup going and stop after the DDL blocker is fired.
+BACKUP DATABASE bup_ddl_blocker TO "bup_ddl_blocker.bak";
+SET DEBUG_SYNC= 'now WAIT_FOR bup_blocked';
+Set ddl timeout to 0 seconds
+SET backup_wait_timeout = 0;
+SHOW VARIABLES LIKE 'backup_wait%';
+Variable_name Value
+backup_wait_timeout 0
+con2: Try a ddl operation and it should expire
+CREATE TABLE bup_ddl_blocker.t3 (col_a CHAR(40)) ENGINE=MEMORY;
+ERROR HY000: The backup wait timeout has expired for query 'CREATE TABLE bup_ddl_blocker.t3 (col_a CHAR(40)) ENGINE=MEMORY'.
+SET backup_wait_timeout = 100;
+SHOW VARIABLES LIKE 'backup_wait%';
+Variable_name Value
+backup_wait_timeout 100
+con3: Try a ddl operation and it should not expire
+CREATE TABLE bup_ddl_blocker.t3 (col_a CHAR(40)) ENGINE=MEMORY;
+release the lock.
+con5: Resume all.
+SET DEBUG_SYNC= 'now SIGNAL timeout_done';
+backup_id
+#
+USE bup_ddl_blocker;
+SHOW FULL TABLES;
+Tables_in_bup_ddl_blocker Table_type
+t1 BASE TABLE
+t3 BASE TABLE
+Part C
+Show that the variable can be reset to its timeout value using
+SET backup_wait_timeout = DEFAULT;
+SET backup_wait_timeout = 1;
+SHOW VARIABLES LIKE 'backup_wait%';
+Variable_name Value
+backup_wait_timeout 1
+SET backup_wait_timeout = DEFAULT;
+SHOW VARIABLES LIKE 'backup_wait%';
+Variable_name Value
+backup_wait_timeout 50
+DROP DATABASE bup_ddl_blocker;
=== added file 'mysql-test/t/backup_timeout.test'
--- a/mysql-test/t/backup_timeout.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/backup_timeout.test 2008-08-18 19:39:53 +0000
@@ -0,0 +1,162 @@
+#
+# This test is for the DDL blocker timeout feature.
+#
+
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/not_embedded.inc
+--source include/have_debug_sync.inc
+
+SET DEBUG_SYNC= 'reset';
+
+#
+# Remove backup files (if they exist)
+#
+
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/bup_ddl_blocker.bak;
+
+#
+# Connections used in this test
+#
+# con1 used to create data, load data, and run the backup
+# con2-con4 used for DDL statements: 2 before backup and 2 during backup
+# con5 used for setting and releasing breakpoints
+#
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+connect (con3,localhost,root,,);
+connect (con4,localhost,root,,);
+connect (con5,localhost,root,,);
+
+connection con1;
+
+# Create data for this test and tailor it to the test.
+--disable_warnings
+DROP DATABASE IF EXISTS bup_ddl_blocker;
+--enable_warnings
+
+CREATE DATABASE bup_ddl_blocker;
+
+# Create a table and load it with data.
+--echo con1: Creating tables
+CREATE TABLE bup_ddl_blocker.t1 (col_a CHAR(40)) ENGINE=INNODB;
+
+--echo con1: Loading data
+INSERT INTO bup_ddl_blocker.t1 VALUES ("01 Some data to test");
+INSERT INTO bup_ddl_blocker.t1 VALUES ("02 Some data to test");
+INSERT INTO bup_ddl_blocker.t1 VALUES ("03 Some data to test");
+
+SHOW VARIABLES LIKE 'backup_wait%';
+
+#
+# Part A - test timeout for one session
+#
+--echo Part A
+
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/bup_ddl_blocker.bak
+
+connection con1;
+
+--echo con1: Activate synchronization points for backup.
+SET DEBUG_SYNC= 'after_block_ddl SIGNAL bup_blocked WAIT_FOR timeout_done';
+
+--echo con1: Get a backup going and stop after the DDL blocker is fired.
+send BACKUP DATABASE bup_ddl_blocker TO "bup_ddl_blocker.bak";
+
+connection con2;
+
+SET DEBUG_SYNC= 'now WAIT_FOR bup_blocked';
+
+--echo Set ddl timeout to 1 second
+SET backup_wait_timeout = 1;
+SHOW VARIABLES LIKE 'backup_wait%';
+
+--echo con2: Try a ddl operation and watch it expire
+--error ER_DDL_TIMEOUT
+CREATE TABLE bup_ddl_blocker.t2 (col_a CHAR(40)) ENGINE=MEMORY;
+
+connection con5;
+--echo release the lock.
+--echo con5: Resume all.
+SET DEBUG_SYNC= 'now SIGNAL timeout_done';
+
+# Reconnect to con1 and let backup finish.
+
+connection con1;
+--replace_column 1 #
+reap;
+
+#
+# Part B - test timeout for a session with a timeout,
+# and a session with no timeout (backup_wait_timeout = 0)
+#
+--echo Part B
+
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/bup_ddl_blocker.bak
+
+connection con1;
+
+--echo con1: Activate synchronization points for backup.
+SET DEBUG_SYNC= 'after_block_ddl SIGNAL bup_blocked WAIT_FOR timeout_done';
+
+--echo con1: Get a backup going and stop after the DDL blocker is fired.
+send BACKUP DATABASE bup_ddl_blocker TO "bup_ddl_blocker.bak";
+
+connection con2;
+
+SET DEBUG_SYNC= 'now WAIT_FOR bup_blocked';
+
+--echo Set ddl timeout to 0 seconds
+SET backup_wait_timeout = 0;
+SHOW VARIABLES LIKE 'backup_wait%';
+
+--echo con2: Try a ddl operation and it should expire
+--error ER_DDL_TIMEOUT
+CREATE TABLE bup_ddl_blocker.t3 (col_a CHAR(40)) ENGINE=MEMORY;
+
+connection con3;
+
+SET backup_wait_timeout = 100;
+SHOW VARIABLES LIKE 'backup_wait%';
+
+--echo con3: Try a ddl operation and it should not expire
+send CREATE TABLE bup_ddl_blocker.t3 (col_a CHAR(40)) ENGINE=MEMORY;
+
+connection con5;
+--echo release the lock.
+--echo con5: Resume all.
+SET DEBUG_SYNC= 'now SIGNAL timeout_done';
+
+# Reconnect to con1 and let backup finish.
+
+connection con1;
+--replace_column 1 #
+reap;
+
+connection con3;
+reap;
+
+USE bup_ddl_blocker;
+SHOW FULL TABLES;
+
+#
+# Part C - test default behavior: set backup timeout = default
+#
+--echo Part C
+
+connection con1;
+
+--echo Show that the variable can be reset to its timeout value using
+--echo SET backup_wait_timeout = DEFAULT;
+SET backup_wait_timeout = 1;
+SHOW VARIABLES LIKE 'backup_wait%';
+SET backup_wait_timeout = DEFAULT;
+SHOW VARIABLES LIKE 'backup_wait%';
+
+DROP DATABASE bup_ddl_blocker;
+
+--remove_file $MYSQLTEST_VARDIR/master-data/bup_ddl_blocker.bak
=== modified file 'sql/ddl_blocker.cc'
--- a/sql/ddl_blocker.cc 2008-06-25 13:39:04 +0000
+++ b/sql/ddl_blocker.cc 2008-08-18 19:39:53 +0000
@@ -101,29 +101,49 @@ void DDL_blocker_class::end_DDL()
/**
check_DDL_blocker
- Check to see if we are blocked from continuing. If so,
- wait until the blocked process signals the condition.
+ Check to see if we are blocked from continuing. If so, wait until block is
+ removed or the timeout specified by backup_wait_timeout variable occurs.
+
+ @param[in] thd The THD object from the caller.
- @param thd The THD object from the caller.
- @returns TRUE
+ @note: This operation blocks DDL operations until end_ddl() is called.
+
+ @returns TRUE if not blocked
+ @returns FALSE if ddl is blocked and timeout occurs
*/
my_bool DDL_blocker_class::check_DDL_blocker(THD *thd)
{
+ int ret = 0;
+ struct timespec ddl_timeout;
DBUG_ENTER("check_DDL_blocker()");
DEBUG_SYNC(thd, "before_check_ddl_blocked");
+ set_timespec(ddl_timeout, thd->backup_wait_timeout);
+
/*
Check the ddl blocker condition. Rest until ddl blocker is released.
*/
pthread_mutex_lock(&THR_LOCK_DDL_is_blocked);
thd->enter_cond(&COND_DDL_blocker, &THR_LOCK_DDL_is_blocked,
"DDL blocker: DDL is blocked");
- while (DDL_blocked && !thd->DDL_exception)
- pthread_cond_wait(&COND_DDL_blocker, &THR_LOCK_DDL_is_blocked);
- start_DDL();
- thd->exit_cond("DDL blocker: Ok to run DDL");
- DEBUG_SYNC(thd, "after_start_ddl");
- DBUG_RETURN(TRUE);
+ while (DDL_blocked && !thd->DDL_exception && (ret == 0))
+ {
+ if (thd->backup_wait_timeout == 0)
+ ret = -1;
+ else
+ ret= pthread_cond_timedwait(&COND_DDL_blocker, &THR_LOCK_DDL_is_blocked,
+ &ddl_timeout);
+ }
+ thd->exit_cond("DDL blocker: DDL is not blocked");
+ if (ret == 0)
+ {
+ start_DDL();
+ DEBUG_SYNC(thd, "after_start_ddl");
+ }
+ else
+ my_error(ER_DDL_TIMEOUT, MYF(0), thd->query);
+
+ DBUG_RETURN(ret == 0);
}
/**
=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h 2008-07-26 16:38:20 +0000
+++ b/sql/mysql_priv.h 2008-08-18 19:39:53 +0000
@@ -637,6 +637,8 @@ extern void debug_sync(THD *thd, const c
#define DEBUG_SYNC(_thd_, _sync_point_name_) /* disabled DEBUG_SYNC */
#endif /* defined(ENABLED_DEBUG_SYNC) */
+#define BACKUP_WAIT_TIMEOUT_DEFAULT 50;
+
/* BINLOG_DUMP options */
#define BINLOG_DUMP_NON_BLOCK 1
=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc 2008-08-11 16:06:30 +0000
+++ b/sql/set_var.cc 2008-08-18 19:39:53 +0000
@@ -230,6 +230,7 @@ static sys_var_long_ptr sys_concurrent_i
static sys_var_long_ptr sys_connect_timeout(&vars, "connect_timeout",
&connect_timeout);
static sys_var_const_str sys_datadir(&vars, "datadir", mysql_real_data_home);
+static sys_var_backup_wait_timeout sys_backup_wait_timeout(&vars, "backup_wait_timeout");
#ifndef DBUG_OFF
static sys_var_thd_dbug sys_dbug(&vars, "debug");
#endif
@@ -2833,6 +2834,61 @@ bool sys_var_insert_id::update(THD *thd,
{
thd->force_one_auto_inc_interval(var->save_result.ulonglong_value);
return 0;
+}
+
+
+/**
+ Get value.
+
+ Returns the value for the backup_wait_timeout session variable.
+
+ @param[IN] thd Thread object
+ @param[IN] type Type of variable
+ @param[IN] base Not used
+
+ @returns value of variable
+*/
+uchar *sys_var_backup_wait_timeout::value_ptr(THD *thd, enum_var_type type,
+ LEX_STRING *base)
+{
+ thd->sys_var_tmp.ulong_value= thd->backup_wait_timeout;
+ return (uchar*) &thd->sys_var_tmp.ulonglong_value;
+}
+
+
+/**
+ Update value.
+
+ Set the backup_wait_timeout variable.
+
+ @param[IN] thd Thread object
+ @param[IN] var Pointer to value from command.
+
+ @returns 0
+*/
+bool sys_var_backup_wait_timeout::update(THD *thd, set_var *var)
+{
+ if (var->save_result.ulong_value > (LONG_MAX/1000))
+ thd->backup_wait_timeout= LONG_MAX/1000;
+ else
+ thd->backup_wait_timeout= var->save_result.ulong_value;
+ return 0;
+}
+
+
+/**
+ Set default value.
+
+ Set the backup_wait_timeout variable to the default value.
+
+ @param[IN] thd Thread object
+ @param[IN] type Type of variable
+
+ @returns 0
+*/
+void sys_var_backup_wait_timeout::set_default(THD *thd, enum_var_type type)
+{
+ thd->backup_wait_timeout= BACKUP_WAIT_TIMEOUT_DEFAULT;
}
=== modified file 'sql/set_var.h'
--- a/sql/set_var.h 2008-08-08 17:21:31 +0000
+++ b/sql/set_var.h 2008-08-18 19:39:53 +0000
@@ -655,6 +655,31 @@ public:
};
+/**
+ Backup_wait_timeout system variable class.
+
+ This class consolidates the mechanism to manage the backup_wait_timeout
+ system variable. It is a session only variable thus we check the type for
+ check_type() and check_default() to ensure it isn't accessed as a global.
+
+ A set_default() method is provided to allow the SET command :
+ SET backup_wait_TIMEOUT = DEFAULT;
+*/
+class sys_var_backup_wait_timeout :public sys_var
+{
+public:
+ sys_var_backup_wait_timeout(sys_var_chain *chain, const char *name_arg)
+ :sys_var(name_arg)
+ { chain_sys_var(chain); }
+ bool update(THD *thd, set_var *var);
+ bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
+ bool check_default(enum_var_type type) { return type == OPT_GLOBAL; }
+ SHOW_TYPE show_type() { return SHOW_LONG; }
+ uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
+ void set_default(THD *thd, enum_var_type type);
+};
+
+
class sys_var_insert_id :public sys_var
{
public:
=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt 2008-08-11 16:06:30 +0000
+++ b/sql/share/errmsg.txt 2008-08-18 19:39:53 +0000
@@ -6374,3 +6374,5 @@ ER_BACKUP_RELEASE_NAME_LOCK_FAILED
eng "Restore failed to release the name locks on the tables."
ER_BACKUP_BACKUPDIR
eng "The path specified for the system variable backupdir cannot be accessed or is invalid. ref: %-.64s"
+ER_DDL_TIMEOUT
+ eng "The backup wait timeout has expired for query '%-64s'."
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2008-07-25 17:21:55 +0000
+++ b/sql/sql_class.cc 2008-08-18 19:39:53 +0000
@@ -536,6 +536,7 @@ THD::THD()
when the DDL blocker is engaged.
*/
DDL_exception(FALSE),
+ backup_wait_timeout(50),
#if defined(ENABLED_DEBUG_SYNC)
debug_sync_control(0),
#endif /* defined(ENABLED_DEBUG_SYNC) */
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2008-07-26 16:38:20 +0000
+++ b/sql/sql_class.h 2008-08-18 19:39:53 +0000
@@ -1925,6 +1925,7 @@ public:
when the DDL blocker is engaged.
*/
my_bool DDL_exception; // Allow some DDL if there is an exception
+ ulong backup_wait_timeout;
Locked_tables_list locked_tables_list;
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2008-08-11 16:06:30 +0000
+++ b/sql/sql_parse.cc 2008-08-18 19:39:53 +0000
@@ -2422,7 +2422,11 @@ mysql_execute_command(THD *thd)
TABLE in the same way. That way we avoid that a new table is
created during a gobal read lock.
*/
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ {
+ res= 1;
+ goto ddl_blocker_err;
+ }
if (!thd->locked_tables_mode &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
{
@@ -2548,6 +2552,7 @@ mysql_execute_command(THD *thd)
/* put tables back for PS rexecuting */
end_with_restore_list:
DDL_blocker->end_DDL();
+ddl_blocker_err:
lex->link_first_table_back(create_table, link_to_local);
break;
}
@@ -2563,7 +2568,8 @@ end_with_restore_list:
table without having to do a full rebuild.
*/
{
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
/* Prepare stack copies to be re-execution safe */
HA_CREATE_INFO create_info;
Alter_info alter_info(lex->alter_info, thd->mem_root);
@@ -2631,7 +2637,8 @@ end_with_restore_list:
case SQLCOM_ALTER_TABLE:
{
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
ulong priv=0;
ulong priv_needed= ALTER_ACL;
@@ -2743,7 +2750,8 @@ end_with_restore_list:
goto error;
}
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
if (mysql_rename_tables(thd, first_table, 0))
{
DDL_blocker->end_DDL();
@@ -2843,7 +2851,8 @@ end_with_restore_list:
if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, FALSE, FALSE, UINT_MAX))
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
res= mysql_repair_table(thd, first_table, &lex->check_opt);
DDL_blocker->end_DDL();
/* ! we write after unlocking the table */
@@ -2895,7 +2904,8 @@ end_with_restore_list:
if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, FALSE, FALSE, UINT_MAX))
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ?
mysql_recreate_table(thd, first_table) :
mysql_optimize_table(thd, first_table, &lex->check_opt);
@@ -3136,7 +3146,8 @@ end_with_restore_list:
goto error;
}
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
res= mysql_truncate(thd, first_table, 0);
DDL_blocker->end_DDL();
@@ -3239,7 +3250,8 @@ end_with_restore_list:
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
thd->options|= OPTION_KEEP_LOG;
}
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
/* DDL and binlog write order protected by LOCK_open */
res= mysql_rm_table(thd, first_table, lex->drop_if_exists,
lex->drop_temporary);
@@ -3485,7 +3497,8 @@ end_with_restore_list:
if (check_access(thd,CREATE_ACL,lex->name.str, 0, 1, 0,
is_schema_db(lex->name.str)))
break;
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias :
lex->name.str), &create_info, 0);
DDL_blocker->end_DDL();
@@ -3523,7 +3536,8 @@ end_with_restore_list:
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
goto error;
}
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0);
DDL_blocker->end_DDL();
break;
@@ -3561,7 +3575,8 @@ end_with_restore_list:
goto error;
}
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
res= mysql_upgrade_db(thd, db);
DDL_blocker->end_DDL();
if (!res)
@@ -3601,7 +3616,8 @@ end_with_restore_list:
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
goto error;
}
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
res= mysql_alter_db(thd, db->str, &create_info);
DDL_blocker->end_DDL();
break;
| Thread |
|---|
| • bzr commit into mysql-6.0 branch (cbell:2675) Bug#33414 | Chuck Bell | 18 Aug |