Below is the list of changes that have just been committed into a local
6.0 repository of cbell. When cbell does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2008-05-01 13:27:39-04:00, cbell@mysql_cab_desk. +11 -0
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.
include/mysql_com.h@stripped, 2008-05-01 13:27:25-04:00, cbell@mysql_cab_desk. +2 -0
BUG#33414 : Backup: DDL hangs indefinitely if ongoing backup
Added maximum ddl timeout value.
mysql-test/r/backup_ddl_blocker_timeout.result@stripped, 2008-05-01 13:27:33-04:00, cbell@mysql_cab_desk. +139 -0
BUG#33414 : Backup: DDL hangs indefinitely if ongoing backup
New result file.
mysql-test/r/backup_ddl_blocker_timeout.result@stripped, 2008-05-01 13:27:33-04:00, cbell@mysql_cab_desk. +0 -0
mysql-test/t/backup_ddl_blocker_timeout.test@stripped, 2008-05-01 13:27:33-04:00, cbell@mysql_cab_desk. +259 -0
BUG#33414 : Backup: DDL hangs indefinitely if ongoing backup
Added new test for DDL timeout.
mysql-test/t/backup_ddl_blocker_timeout.test@stripped, 2008-05-01 13:27:33-04:00, cbell@mysql_cab_desk. +0 -0
mysql-test/t/disabled.def@stripped, 2008-05-01 13:27:26-04:00, cbell@mysql_cab_desk. +1 -0
BUG#33414 : Backup: DDL hangs indefinitely if ongoing backup
Disabled new test for same reason as others: Waiting for BUG#34235.
sql/ddl_blocker.cc@stripped, 2008-05-01 13:27:27-04:00, cbell@mysql_cab_desk. +28 -10
BUG#33414 : Backup: DDL hangs indefinitely if ongoing backup
Added ability to timeout based on the variable ddl_wait_timeout.
sql/set_var.cc@stripped, 2008-05-01 13:27:27-04:00, cbell@mysql_cab_desk. +19 -0
BUG#33414 : Backup: DDL hangs indefinitely if ongoing backup
Added session variable ddl_wait_timeout.
sql/set_var.h@stripped, 2008-05-01 13:27:28-04:00, cbell@mysql_cab_desk. +13 -0
BUG#33414 : Backup: DDL hangs indefinitely if ongoing backup
Added session variable ddl_wait_timeout class.
sql/share/errmsg.txt@stripped, 2008-05-01 13:27:32-04:00, cbell@mysql_cab_desk. +3 -0
BUG#33414 : Backup: DDL hangs indefinitely if ongoing backup
Added new error message for DDL timeout.
sql/sql_class.cc@stripped, 2008-05-01 13:27:29-04:00, cbell@mysql_cab_desk. +2 -1
BUG#33414 : Backup: DDL hangs indefinitely if ongoing backup
Added default value setting for ddl_wait_timeout.
sql/sql_class.h@stripped, 2008-05-01 13:27:30-04:00, cbell@mysql_cab_desk. +1 -0
BUG#33414 : Backup: DDL hangs indefinitely if ongoing backup
Added thread variable ddl_wait_timeout.
sql/sql_parse.cc@stripped, 2008-05-01 13:27:31-04:00, cbell@mysql_cab_desk. +27 -12
BUG#33414 : Backup: DDL hangs indefinitely if ongoing backup
Modified code to check for a failed return which indicates the
ddl blocker has timed out.
diff -Nrup a/include/mysql_com.h b/include/mysql_com.h
--- a/include/mysql_com.h 2008-04-01 09:44:50 -04:00
+++ b/include/mysql_com.h 2008-05-01 13:27:25 -04:00
@@ -219,6 +219,8 @@ enum enum_server_command
#define NET_WRITE_TIMEOUT 60 /* Timeout on write */
#define NET_WAIT_TIMEOUT 8*60*60 /* Wait for new query */
+#define DDL_WAIT_TIMEOUT LONG_MAX/1000 /* Wait for ddl blocker */
+
#define ONLY_KILL_QUERY 1
struct st_vio; /* Only C */
diff -Nrup a/mysql-test/r/backup_ddl_blocker_timeout.result b/mysql-test/r/backup_ddl_blocker_timeout.result
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/r/backup_ddl_blocker_timeout.result 2008-05-01 13:27:33 -04:00
@@ -0,0 +1,139 @@
+SET GLOBAL debug="d,backup_debug:d,backup";
+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;
+CREATE TABLE bup_ddl_blocker.t2 (col_a CHAR(40)) ENGINE=MYISAM;
+CREATE TABLE bup_ddl_blocker.t3 (col_a CHAR(40)) ENGINE=INNODB;
+CREATE TABLE bup_ddl_blocker.t4 (col_a CHAR(40)) ENGINE=MYISAM;
+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");
+INSERT INTO bup_ddl_blocker.t2 VALUES ("01 Some data to test");
+INSERT INTO bup_ddl_blocker.t2 VALUES ("02 Some data to test");
+INSERT INTO bup_ddl_blocker.t2 VALUES ("03 Some data to test");
+INSERT INTO bup_ddl_blocker.t3 VALUES ("01 Some data to test");
+INSERT INTO bup_ddl_blocker.t3 VALUES ("02 Some data to test");
+INSERT INTO bup_ddl_blocker.t3 VALUES ("03 Some data to test");
+INSERT INTO bup_ddl_blocker.t4 VALUES ("01 Some data to test");
+INSERT INTO bup_ddl_blocker.t4 VALUES ("02 Some data to test");
+INSERT INTO bup_ddl_blocker.t4 VALUES ("03 Some data to test");
+DROP TABLE IF EXISTS bup_ddl_blocker.t1, bup_ddl_blocker.t2,
+bup_ddl_blocker.t3, bup_ddl_blocker.t4;
+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");
+Part A
+con5: Getting lock on DDL in progress.
+SELECT get_lock("DDL_blocked", 0);
+get_lock("DDL_blocked", 0)
+1
+con1: Get a backup going and stop after the DDL blocker is fired.
+BACKUP DATABASE bup_ddl_blocker TO "bup_ddl_blocker.bak";
+con6: Checking locks
+SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE info LIKE "BACKUP DATABASE%";
+state info
+debug_sync_point: DDL_blocked BACKUP DATABASE bup_ddl_blocker TO "bup_ddl_blocker.bak"
+Set ddl timeout to 1 second
+SET ddl_wait_timeout = 1;
+SHOW VARIABLES LIKE 'ddl%';
+Variable_name Value
+ddl_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 DDL operation has timed out for query CREATE TABLE bup_ddl_blocker.t2 (col_a CHAR(40)) ENGINE=MEMORY.
+release the lock.
+con5: Releasing lock
+SELECT release_lock("DDL_blocked");
+release_lock("DDL_blocked")
+1
+backup_id
+#
+Part B
+con5: Getting lock on DDL in progress.
+SELECT get_lock("DDL_blocked", 0);
+get_lock("DDL_blocked", 0)
+1
+con1: Get a backup going and stop after the DDL blocker is fired.
+BACKUP DATABASE bup_ddl_blocker TO "bup_ddl_blocker.bak";
+con6: Checking locks
+SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE info LIKE "BACKUP DATABASE%";
+state info
+debug_sync_point: DDL_blocked BACKUP DATABASE bup_ddl_blocker TO "bup_ddl_blocker.bak"
+Set ddl timeout to 0 seconds
+SET ddl_wait_timeout = 0;
+SHOW VARIABLES LIKE 'ddl%';
+Variable_name Value
+ddl_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 DDL operation has timed out for query CREATE TABLE bup_ddl_blocker.t3 (col_a CHAR(40)) ENGINE=MEMORY.
+SET ddl_wait_timeout = 100;
+SHOW VARIABLES LIKE 'ddl%';
+Variable_name Value
+ddl_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;
+con6: Checking locks
+SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE info LIKE "CREATE TABLE bup_ddl_blocker.t3%";
+state info
+DDL blocker: DDL is blocked CREATE TABLE bup_ddl_blocker.t3 (col_a CHAR(40)) ENGINE=MEMORY
+release the lock.
+con5: Releasing lock
+SELECT release_lock("DDL_blocked");
+release_lock("DDL_blocked")
+1
+backup_id
+#
+USE bup_ddl_blocker;
+SHOW FULL TABLES;
+Tables_in_bup_ddl_blocker Table_type
+t1 BASE TABLE
+t3 BASE TABLE
+Part C
+con5: Getting lock on DDL in progress.
+SELECT get_lock("DDL_blocked", 0);
+get_lock("DDL_blocked", 0)
+1
+con1: Get a backup going and stop after the DDL blocker is fired.
+BACKUP DATABASE bup_ddl_blocker TO "bup_ddl_blocker.bak";
+con6: Checking locks
+SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE info LIKE "BACKUP DATABASE%";
+state info
+debug_sync_point: DDL_blocked BACKUP DATABASE bup_ddl_blocker TO "bup_ddl_blocker.bak"
+Set ddl timeout to 0 seconds
+SET ddl_wait_timeout = 0;
+SHOW VARIABLES LIKE 'ddl%';
+Variable_name Value
+ddl_wait_timeout 0
+con2: Try a ddl operation and it should expire
+CREATE TABLE bup_ddl_blocker.t4 (col_a CHAR(40)) ENGINE=MEMORY;
+ERROR HY000: The DDL operation has timed out for query CREATE TABLE bup_ddl_blocker.t4 (col_a CHAR(40)) ENGINE=MEMORY.
+SET ddl_wait_timeout = 0;
+SHOW VARIABLES LIKE 'ddl%';
+Variable_name Value
+ddl_wait_timeout 0
+con3: Try a ddl operation and it should expire
+CREATE TABLE bup_ddl_blocker.t4 (col_a CHAR(40)) ENGINE=MEMORY;
+ERROR HY000: The DDL operation has timed out for query CREATE TABLE bup_ddl_blocker.t4 (col_a CHAR(40)) ENGINE=MEMORY.
+release the lock.
+con5: Releasing lock
+SELECT release_lock("DDL_blocked");
+release_lock("DDL_blocked")
+1
+backup_id
+#
+USE bup_ddl_blocker;
+SHOW FULL TABLES;
+Tables_in_bup_ddl_blocker Table_type
+t1 BASE TABLE
+t3 BASE TABLE
+DROP DATABASE bup_ddl_blocker;
diff -Nrup a/mysql-test/t/backup_ddl_blocker_timeout.test b/mysql-test/t/backup_ddl_blocker_timeout.test
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/backup_ddl_blocker_timeout.test 2008-05-01 13:27:33 -04:00
@@ -0,0 +1,259 @@
+#
+# This test is for the DDL blocker timeout feature.
+# TODO : Add a native driver to the test when one becomes available
+#
+# Notes
+# You must use a dedicated connection for getting and releasing locks.
+# Do not issue a get_lock() or release_lock() in the same connection
+# (thread) as code that calls BACKUP_BREAKPOINT(). Using the same connection
+# to get/release locks and run code that issues BACKUP_BREAKPOINTs will result
+# in an assertion using DEBUG_ASSERT(thd->ull == NULL) from debug_sync_point()
+# in item_func.cc.
+#
+
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/not_embedded.inc
+
+#
+# Remove backup files (if they exist)
+#
+
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/bup_ddl_blocker_orig.bak;
+--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-con5 used for DDL statements: 2 before backup and 2 during backup
+# con6 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,,);
+connect (con6,localhost,root,,);
+
+connection con1;
+
+# Setup the server to use the backup breakpoints
+SET GLOBAL debug="d,backup_debug:d,backup";
+
+# Create data for this test and tailor it to the test.
+--source include/backup_ddl_create_data.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS bup_ddl_blocker.t1, bup_ddl_blocker.t2,
+ bup_ddl_blocker.t3, bup_ddl_blocker.t4;
+--enable_warnings
+
+# 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");
+
+#
+# Part A - test timeout for one session
+#
+--echo Part A
+
+connection con5;
+
+# Set the breakpoint for DDL in progress.
+--echo con5: Getting lock on DDL in progress.
+SELECT get_lock("DDL_blocked", 0);
+
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/bup_ddl_blocker.bak
+
+connection con1;
+
+--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 con6;
+
+--echo con6: Checking locks
+let $wait_condition = SELECT state = "debug_sync_point: DDL_blocked"
+ FROM INFORMATION_SCHEMA.PROCESSLIST
+ WHERE info LIKE "BACKUP DATABASE%";
+--source include/wait_condition.inc
+
+SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE info LIKE "BACKUP DATABASE%";
+
+connection con2;
+
+--echo Set ddl timeout to 1 second
+SET ddl_wait_timeout = 1;
+SHOW VARIABLES LIKE 'ddl%';
+
+--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: Releasing lock
+SELECT release_lock("DDL_blocked");
+
+# 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 (ddl_wait_timeout = 0)
+#
+--echo Part B
+
+connection con5;
+
+# Set the breakpoint for DDL in progress.
+--echo con5: Getting lock on DDL in progress.
+SELECT get_lock("DDL_blocked", 0);
+
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/bup_ddl_blocker.bak
+
+connection con1;
+
+--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 con6;
+
+--echo con6: Checking locks
+let $wait_condition = SELECT state = "debug_sync_point: DDL_blocked"
+ FROM INFORMATION_SCHEMA.PROCESSLIST
+ WHERE info LIKE "BACKUP DATABASE%";
+--source include/wait_condition.inc
+
+SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE info LIKE "BACKUP DATABASE%";
+
+connection con2;
+
+--echo Set ddl timeout to 0 seconds
+SET ddl_wait_timeout = 0;
+SHOW VARIABLES LIKE 'ddl%';
+
+--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 ddl_wait_timeout = 100;
+SHOW VARIABLES LIKE 'ddl%';
+
+--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 con6;
+
+--echo con6: Checking locks
+let $wait_condition = SELECT state = "DDL blocker: DDL is blocked"
+ FROM INFORMATION_SCHEMA.PROCESSLIST
+ WHERE info LIKE "CREATE TABLE bup_ddl_blocker.t3%";
+--source include/wait_condition.inc
+
+SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE info LIKE "CREATE TABLE bup_ddl_blocker.t3%";
+
+connection con5;
+
+--echo release the lock.
+--echo con5: Releasing lock
+SELECT release_lock("DDL_blocked");
+
+# 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: timeout if ddl_wait_timeout = 0
+#
+--echo Part C
+
+connection con5;
+
+# Set the breakpoint for DDL in progress.
+--echo con5: Getting lock on DDL in progress.
+SELECT get_lock("DDL_blocked", 0);
+
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/bup_ddl_blocker.bak
+
+connection con1;
+
+--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 con6;
+
+--echo con6: Checking locks
+let $wait_condition = SELECT state = "debug_sync_point: DDL_blocked"
+ FROM INFORMATION_SCHEMA.PROCESSLIST
+ WHERE info LIKE "BACKUP DATABASE%";
+--source include/wait_condition.inc
+
+SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE info LIKE "BACKUP DATABASE%";
+
+connection con2;
+
+--echo Set ddl timeout to 0 seconds
+SET ddl_wait_timeout = 0;
+SHOW VARIABLES LIKE 'ddl%';
+
+--echo con2: Try a ddl operation and it should expire
+--error ER_DDL_TIMEOUT
+CREATE TABLE bup_ddl_blocker.t4 (col_a CHAR(40)) ENGINE=MEMORY;
+
+connection con3;
+
+SET ddl_wait_timeout = 0;
+SHOW VARIABLES LIKE 'ddl%';
+
+--echo con3: Try a ddl operation and it should expire
+--error ER_DDL_TIMEOUT
+CREATE TABLE bup_ddl_blocker.t4 (col_a CHAR(40)) ENGINE=MEMORY;
+
+connection con5;
+
+--echo release the lock.
+--echo con5: Releasing lock
+SELECT release_lock("DDL_blocked");
+
+# Reconnect to con1 and let backup finish.
+
+connection con1;
+--replace_column 1 #
+reap;
+
+USE bup_ddl_blocker;
+SHOW FULL TABLES;
+
+DROP DATABASE bup_ddl_blocker;
+
+--remove_file $MYSQLTEST_VARDIR/master-data/bup_ddl_blocker.bak
diff -Nrup a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
--- a/mysql-test/t/disabled.def 2008-04-21 06:45:26 -04:00
+++ b/mysql-test/t/disabled.def 2008-05-01 13:27:26 -04:00
@@ -27,6 +27,7 @@ user_limits : Bug#23921 2007-12
backup :BUG#34235 pending replacement of test facility with WL#4259
backup_commit_blocker :BUG#34235 pending replacement of test facility with WL#4259
backup_ddl_blocker :BUG#34235 pending replacement of test facility with WL#4259
+backup_ddl_blocker_timeout :BUG#34235 pending replacement of test facility with WL#4259
backup_progress :BUG#34235 pending replacement of test facility with WL#4259
backup_security :BUG#34235 pending replacement of test facility with WL#4259
backup_snapshot :BUG#34235 pending replacement of test facility with WL#4259
diff -Nrup a/sql/ddl_blocker.cc b/sql/ddl_blocker.cc
--- a/sql/ddl_blocker.cc 2007-12-12 15:13:23 -05:00
+++ b/sql/ddl_blocker.cc 2008-05-01 13:27:27 -04:00
@@ -101,29 +101,47 @@ 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 ddl_block_timeout variable occurs.
+
+ @param[in] thd The THD object from the caller.
- @param thd The THD object from the caller.
- @returns TRUE
+ @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()");
BACKUP_BREAKPOINT("DDL_not_blocked");
+ set_timespec(ddl_timeout, thd->ddl_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");
- BACKUP_BREAKPOINT("DDL_in_progress");
- DBUG_RETURN(TRUE);
+ while (DDL_blocked && !thd->DDL_exception && (ret == 0))
+ {
+ if (thd->ddl_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();
+ BACKUP_BREAKPOINT("DDL_in_progress");
+ }
+ else
+ my_error(ER_DDL_TIMEOUT, MYF(0), thd->query);
+
+ DBUG_RETURN(ret == 0);
}
/**
diff -Nrup a/sql/set_var.cc b/sql/set_var.cc
--- a/sql/set_var.cc 2008-04-01 09:44:53 -04:00
+++ b/sql/set_var.cc 2008-05-01 13:27:27 -04:00
@@ -227,6 +227,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_ddl_wait_timeout sys_ddl_wait_timeout(&vars, "ddl_wait_timeout");
#ifndef DBUG_OFF
static sys_var_thd_dbug sys_dbug(&vars, "debug");
#endif
@@ -2644,6 +2645,24 @@ uchar *sys_var_last_insert_id::value_ptr
bool sys_var_insert_id::update(THD *thd, set_var *var)
{
thd->force_one_auto_inc_interval(var->save_result.ulonglong_value);
+ return 0;
+}
+
+
+uchar *sys_var_ddl_wait_timeout::value_ptr(THD *thd, enum_var_type type,
+ LEX_STRING *base)
+{
+ thd->sys_var_tmp.ulong_value= thd->ddl_wait_timeout;
+ return (uchar*) &thd->sys_var_tmp.ulonglong_value;
+}
+
+
+bool sys_var_ddl_wait_timeout::update(THD *thd, set_var *var)
+{
+ if (var->save_result.ulong_value > (LONG_MAX/1000))
+ thd->ddl_wait_timeout= LONG_MAX/1000;
+ else
+ thd->ddl_wait_timeout= var->save_result.ulong_value;
return 0;
}
diff -Nrup a/sql/set_var.h b/sql/set_var.h
--- a/sql/set_var.h 2008-03-27 06:13:13 -04:00
+++ b/sql/set_var.h 2008-05-01 13:27:28 -04:00
@@ -620,6 +620,19 @@ public:
};
+class sys_var_ddl_wait_timeout :public sys_var
+{
+public:
+ sys_var_ddl_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; }
+ SHOW_TYPE show_type() { return SHOW_LONG; }
+ uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
+};
+
+
class sys_var_insert_id :public sys_var
{
public:
diff -Nrup a/sql/share/errmsg.txt b/sql/share/errmsg.txt
--- a/sql/share/errmsg.txt 2008-04-21 06:45:27 -04:00
+++ b/sql/share/errmsg.txt 2008-05-01 13:27:32 -04:00
@@ -6350,3 +6350,6 @@ ER_BACKUP_GET_META_TS
eng "Failed to obtain meta-data for tablespace %-.64s."
ER_BACKUP_CATALOG_ADD_TS
eng "Failed to add tablespace `%-.64s` to the catalog"
+
+ER_DDL_TIMEOUT
+ eng "The DDL operation has timed out for query %-64s."
diff -Nrup a/sql/sql_class.cc b/sql/sql_class.cc
--- a/sql/sql_class.cc 2008-04-07 11:26:38 -04:00
+++ b/sql/sql_class.cc 2008-05-01 13:27:29 -04:00
@@ -524,7 +524,8 @@ THD::THD()
This is needed to ensure the restore (which uses DDL) is not blocked
when the DDL blocker is engaged.
*/
- DDL_exception(FALSE)
+ DDL_exception(FALSE),
+ ddl_wait_timeout(50)
{
ulong tmp;
diff -Nrup a/sql/sql_class.h b/sql/sql_class.h
--- a/sql/sql_class.h 2008-04-01 09:44:53 -04:00
+++ b/sql/sql_class.h 2008-05-01 13:27:30 -04:00
@@ -1771,6 +1771,7 @@ public:
when the DDL blocker is engaged.
*/
my_bool DDL_exception; // Allow some DDL if there is an exception
+ ulong ddl_wait_timeout;
#ifdef WITH_PARTITION_STORAGE_ENGINE
partition_info *work_part_info;
diff -Nrup a/sql/sql_parse.cc b/sql/sql_parse.cc
--- a/sql/sql_parse.cc 2008-04-17 06:42:27 -04:00
+++ b/sql/sql_parse.cc 2008-05-01 13:27:31 -04:00
@@ -2282,7 +2282,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 end_with_restore_list;
+ }
if (!thd->locked_tables &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
{
@@ -2423,7 +2427,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);
@@ -2493,7 +2498,8 @@ end_with_restore_list:
case SQLCOM_ALTER_TABLE:
DBUG_ASSERT(first_table == all_tables && first_table != 0);
{
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
ulong priv=0;
ulong priv_needed= ALTER_ACL;
/*
@@ -2605,7 +2611,8 @@ end_with_restore_list:
goto error;
}
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0))
{
DDL_blocker->end_DDL();
@@ -2663,7 +2670,8 @@ end_with_restore_list:
UINT_MAX, FALSE))
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 */
@@ -2718,7 +2726,8 @@ end_with_restore_list:
UINT_MAX, FALSE))
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);
@@ -2963,7 +2972,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();
@@ -3068,7 +3078,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);
@@ -3316,7 +3327,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();
@@ -3359,7 +3371,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;
@@ -3402,7 +3415,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)
@@ -3442,7 +3456,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 |
|---|
| • bk commit into 6.0 tree (cbell:1.2614) BUG#33414 | cbell | 1 May |