List:Commits« Previous MessageNext Message »
From:Chuck Bell Date:August 18 2008 7:39pm
Subject:bzr commit into mysql-6.0 branch (cbell:2675) Bug#33414
View as plain text  
#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#33414Chuck Bell18 Aug