diff options
-rw-r--r-- | mysql-test/r/timeout.result | 67 | ||||
-rw-r--r-- | mysql-test/suite/innodb/r/innodb-timeout.result | 60 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/innodb-timeout.test | 83 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/r/innodb_lock_wait_timeout_basic.result | 4 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/r/lock_wait_timeout_basic.result | 16 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/r/sysvars_innodb.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/r/sysvars_server_embedded.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result | 2 | ||||
-rw-r--r-- | mysql-test/t/timeout.test | 60 | ||||
-rw-r--r-- | sql/lex.h | 1 | ||||
-rw-r--r-- | sql/mdl.cc | 8 | ||||
-rw-r--r-- | sql/sql_lex.cc | 30 | ||||
-rw-r--r-- | sql/sql_lex.h | 2 | ||||
-rw-r--r-- | sql/sql_plugin.cc | 3 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 2 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 47 | ||||
-rw-r--r-- | sql/sys_vars.cc | 2 | ||||
-rw-r--r-- | sql/table.h | 3 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 2 | ||||
-rw-r--r-- | storage/innobase/include/lock0lock.h | 26 | ||||
-rw-r--r-- | storage/innobase/lock/lock0lock.cc | 15 | ||||
-rw-r--r-- | storage/innobase/srv/srv0srv.cc | 5 |
22 files changed, 369 insertions, 73 deletions
diff --git a/mysql-test/r/timeout.result b/mysql-test/r/timeout.result new file mode 100644 index 00000000000..8d1ca137043 --- /dev/null +++ b/mysql-test/r/timeout.result @@ -0,0 +1,67 @@ +# +# MDEV-11379 - AliSQL: [Feature] Issue#8: SELECT FOR UPDATE WAIT +# MDEV-11388 - AliSQL: [Feature] Issue#15 DDL FAST FAIL +# +CREATE TABLE t1(a INT, b TEXT, c MULTIPOLYGON NOT NULL); +CREATE INDEX i1 ON t1(a) WAIT 1; +CREATE FULLTEXT INDEX i2 ON t1(b) WAIT 1; +CREATE SPATIAL INDEX i3 ON t1(c) WAIT 1; +ALTER TABLE t1 WAIT 1 COMMENT='test'; +OPTIMIZE TABLE t1 WAIT 1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +DROP INDEX i1 ON t1 WAIT 1; +TRUNCATE TABLE t1 WAIT 1; +RENAME TABLE t1 WAIT 1 TO t2; +RENAME TABLE t2 NOWAIT TO t1; +connect con1, localhost, root,,; +LOCK TABLE t1 WRITE WAIT 31536001; +Warnings: +Warning 1292 Truncated incorrect lock_wait_timeout value: '31536001' +connection default; +CREATE INDEX i1 ON t1(a) WAIT 0; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +CREATE INDEX i1 ON t1(a) NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +CREATE FULLTEXT INDEX i2 ON t1(b) WAIT 0; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +CREATE FULLTEXT INDEX i2 ON t1(b) NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +CREATE SPATIAL INDEX i3 ON t1(c) WAIT 0; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +CREATE SPATIAL INDEX i3 ON t1(c) NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +ALTER TABLE t1 WAIT 0 COMMENT='test'; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +ALTER TABLE t1 NOWAIT COMMENT='test'; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +OPTIMIZE TABLE t1 WAIT 0; +Table Op Msg_type Msg_text +test.t1 optimize Error Lock wait timeout exceeded; try restarting transaction +test.t1 optimize status Operation failed +OPTIMIZE TABLE t1 NOWAIT; +Table Op Msg_type Msg_text +test.t1 optimize Error Lock wait timeout exceeded; try restarting transaction +test.t1 optimize status Operation failed +DROP INDEX i1 ON t1 WAIT 0; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +DROP INDEX i1 ON t1 NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +TRUNCATE TABLE t1 WAIT 0; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +TRUNCATE TABLE t1 NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +RENAME TABLE t1 WAIT 0 TO t2; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +RENAME TABLE t1 NOWAIT TO t2; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +DROP TABLE t1 WAIT 0; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +DROP TABLE t1 NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +LOCK TABLE t1 WRITE WAIT 0; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +LOCK TABLE t1 WRITE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +disconnect con1; +DROP TABLE t1 WAIT 1; diff --git a/mysql-test/suite/innodb/r/innodb-timeout.result b/mysql-test/suite/innodb/r/innodb-timeout.result index f252ebac314..52ed1a6f9b4 100644 --- a/mysql-test/suite/innodb/r/innodb-timeout.result +++ b/mysql-test/suite/innodb/r/innodb-timeout.result @@ -57,3 +57,63 @@ disconnect a; connection default; drop table t1; set global innodb_lock_wait_timeout=<initial_timeout>; +# +# MDEV-11379 - AliSQL: [Feature] Issue#8: SELECT FOR UPDATE WAIT +# +CREATE TABLE t1 (c1 INT, c2 INT) ENGINE=InnoDB; +INSERT INTO t1 (c1,c2) values (1,1),(2,2),(3,3),(4,4); +CREATE VIEW v1 AS SELECT * FROM t1 WHERE c1=4 FOR UPDATE NOWAIT; +ERROR HY000: View's SELECT contains a '[NO]WAIT' clause +CREATE VIEW v1 AS SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 0; +ERROR HY000: View's SELECT contains a '[NO]WAIT' clause +CREATE PROCEDURE p1() SELECT * FROM t1 WHERE c1=4 FOR UPDATE NOWAIT; +ERROR 0A000: [NO]WAIT is not allowed in stored procedures +CREATE PROCEDURE p1() SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 0; +ERROR 0A000: [NO]WAIT is not allowed in stored procedures +connect con1,localhost,root,,; +LOCK TABLE t1 WRITE; +connect con2,localhost,root,,; +SELECT * FROM t1 WHERE c1=4 FOR UPDATE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 0; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +PREPARE stmt FROM 'SELECT * FROM t1 WHERE c1=4 FOR UPDATE NOWAIT'; +EXECUTE stmt; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +DEALLOCATE PREPARE stmt; +PREPARE stmt FROM 'SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 0'; +EXECUTE stmt; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +DEALLOCATE PREPARE stmt; +connection con1; +INSERT INTO t1 VALUES(5,5); +UNLOCK TABLES; +set AUTOCOMMIT=0; +SELECT * FROM t1 WHERE c1=4 FOR UPDATE; +connection con2; +set AUTOCOMMIT=0; +SET INNODB_LOCK_WAIT_TIMEOUT=1; +SELECT * FROM t1 WHERE c1=4 FOR UPDATE; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 WHERE c1=4 FOR UPDATE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 0; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +connection con1; +UPDATE t1 SET c2=5 WHERE c1=4; +COMMIT; +set AUTOCOMMIT=0; +SELECT * FROM t1 WHERE c1=4 FOR UPDATE; +c1 c2 +4 5 +connection con2; +set AUTOCOMMIT=0; +SET INNODB_LOCK_WAIT_TIMEOUT=1; +SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 10; +connection con1; +COMMIT; +connection con2; +disconnect con1; +disconnect con2; +connection default; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb-timeout.test b/mysql-test/suite/innodb/t/innodb-timeout.test index 0beeea8f39e..0f8bbbec559 100644 --- a/mysql-test/suite/innodb/t/innodb-timeout.test +++ b/mysql-test/suite/innodb/t/innodb-timeout.test @@ -1,3 +1,5 @@ +# Save the initial number of concurrent sessions. +--source include/count_sessions.inc --source include/have_innodb.inc let $initial_timeout=`select @@innodb_lock_wait_timeout`; @@ -115,3 +117,84 @@ connection default; drop table t1; --replace_result $initial_timeout <initial_timeout> eval set global innodb_lock_wait_timeout=$initial_timeout; + +--echo # +--echo # MDEV-11379 - AliSQL: [Feature] Issue#8: SELECT FOR UPDATE WAIT +--echo # +CREATE TABLE t1 (c1 INT, c2 INT) ENGINE=InnoDB; +INSERT INTO t1 (c1,c2) values (1,1),(2,2),(3,3),(4,4); + +# Not supported in view/sp +--error ER_VIEW_SELECT_CLAUSE +CREATE VIEW v1 AS SELECT * FROM t1 WHERE c1=4 FOR UPDATE NOWAIT; +--error ER_VIEW_SELECT_CLAUSE +CREATE VIEW v1 AS SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 0; +--error ER_SP_BADSTATEMENT +CREATE PROCEDURE p1() SELECT * FROM t1 WHERE c1=4 FOR UPDATE NOWAIT; +--error ER_SP_BADSTATEMENT +CREATE PROCEDURE p1() SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 0; + +connect(con1,localhost,root,,); +LOCK TABLE t1 WRITE; + +connect(con2,localhost,root,,); +# The following statement should hang because con1 is locking the table +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 WHERE c1=4 FOR UPDATE NOWAIT; +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 0; +PREPARE stmt FROM 'SELECT * FROM t1 WHERE c1=4 FOR UPDATE NOWAIT'; +--error ER_LOCK_WAIT_TIMEOUT +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +PREPARE stmt FROM 'SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 0'; +--error ER_LOCK_WAIT_TIMEOUT +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +connection con1; +INSERT INTO t1 VALUES(5,5); +UNLOCK TABLES; +set AUTOCOMMIT=0; +--disable_result_log +SELECT * FROM t1 WHERE c1=4 FOR UPDATE; +--enable_result_log + +connection con2; +set AUTOCOMMIT=0; +SET INNODB_LOCK_WAIT_TIMEOUT=1; +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 WHERE c1=4 FOR UPDATE; +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 WHERE c1=4 FOR UPDATE NOWAIT; +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 0; + +connection con1; +UPDATE t1 SET c2=5 WHERE c1=4; +COMMIT; +set AUTOCOMMIT=0; +SELECT * FROM t1 WHERE c1=4 FOR UPDATE; + +connection con2; +set AUTOCOMMIT=0; +SET INNODB_LOCK_WAIT_TIMEOUT=1; +--send +--disable_result_log +SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 10; + +connection con1; +COMMIT; + +connection con2; +--reap + + +disconnect con1; +disconnect con2; + +# clear +connection default; +DROP TABLE t1; + +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/sys_vars/r/innodb_lock_wait_timeout_basic.result b/mysql-test/suite/sys_vars/r/innodb_lock_wait_timeout_basic.result index 74b1d21d475..3218c096c2b 100644 --- a/mysql-test/suite/sys_vars/r/innodb_lock_wait_timeout_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_lock_wait_timeout_basic.result @@ -99,7 +99,7 @@ Warnings: Warning 1292 Truncated incorrect innodb_lock_wait_timeout value: '-1024' SELECT @@global.innodb_lock_wait_timeout; @@global.innodb_lock_wait_timeout -1 +0 SET @@global.innodb_lock_wait_timeout=1073741825; Warnings: Warning 1292 Truncated incorrect innodb_lock_wait_timeout value: '1073741825' @@ -131,7 +131,7 @@ Warnings: Warning 1292 Truncated incorrect innodb_lock_wait_timeout value: '-1024' SELECT @@session.innodb_lock_wait_timeout; @@session.innodb_lock_wait_timeout -1 +0 SET @@session.innodb_lock_wait_timeout=1073999999; Warnings: Warning 1292 Truncated incorrect innodb_lock_wait_timeout value: '1073999999' diff --git a/mysql-test/suite/sys_vars/r/lock_wait_timeout_basic.result b/mysql-test/suite/sys_vars/r/lock_wait_timeout_basic.result index bc127bf339a..f5d66b7c561 100644 --- a/mysql-test/suite/sys_vars/r/lock_wait_timeout_basic.result +++ b/mysql-test/suite/sys_vars/r/lock_wait_timeout_basic.result @@ -54,17 +54,15 @@ SELECT @@session.lock_wait_timeout; 65535 '#------------------FN_DYNVARS_002_05-----------------------#' SET @@global.lock_wait_timeout = 0; -Warnings: -Warning 1292 Truncated incorrect lock_wait_timeout value: '0' SELECT @@global.lock_wait_timeout; @@global.lock_wait_timeout -1 +0 SET @@global.lock_wait_timeout = -1024; Warnings: Warning 1292 Truncated incorrect lock_wait_timeout value: '-1024' SELECT @@global.lock_wait_timeout; @@global.lock_wait_timeout -1 +0 SET @@global.lock_wait_timeout = 31536001; Warnings: Warning 1292 Truncated incorrect lock_wait_timeout value: '31536001' @@ -87,17 +85,15 @@ SELECT @@global.lock_wait_timeout; @@global.lock_wait_timeout 31536000 SET @@session.lock_wait_timeout = 0; -Warnings: -Warning 1292 Truncated incorrect lock_wait_timeout value: '0' SELECT @@session.lock_wait_timeout; @@session.lock_wait_timeout -1 +0 SET @@session.lock_wait_timeout = -2; Warnings: Warning 1292 Truncated incorrect lock_wait_timeout value: '-2' SELECT @@session.lock_wait_timeout; @@session.lock_wait_timeout -1 +0 SET @@session.lock_wait_timeout = 31537000; Warnings: Warning 1292 Truncated incorrect lock_wait_timeout value: '31537000' @@ -137,11 +133,9 @@ SELECT @@global.lock_wait_timeout; @@global.lock_wait_timeout 1 SET @@global.lock_wait_timeout = FALSE; -Warnings: -Warning 1292 Truncated incorrect lock_wait_timeout value: '0' SELECT @@global.lock_wait_timeout; @@global.lock_wait_timeout -1 +0 '#---------------------FN_DYNVARS_001_09----------------------#' SET @@global.lock_wait_timeout = 10; SET @@session.lock_wait_timeout = 11; diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result index 74ceb7e631c..48d39ed2a87 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result +++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result @@ -1386,7 +1386,7 @@ DEFAULT_VALUE 50 VARIABLE_SCOPE SESSION VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout. -NUMERIC_MIN_VALUE 1 +NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1073741824 NUMERIC_BLOCK_SIZE 0 ENUM_VALUE_LIST NULL diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result index 89a6d8448fc..7813391ad98 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -1599,7 +1599,7 @@ DEFAULT_VALUE 86400 VARIABLE_SCOPE SESSION VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Timeout in seconds to wait for a lock before returning an error. -NUMERIC_MIN_VALUE 1 +NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 31536000 NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index c4018b39a8f..a999112ab41 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -1725,7 +1725,7 @@ DEFAULT_VALUE 86400 VARIABLE_SCOPE SESSION VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Timeout in seconds to wait for a lock before returning an error. -NUMERIC_MIN_VALUE 1 +NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 31536000 NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL diff --git a/mysql-test/t/timeout.test b/mysql-test/t/timeout.test new file mode 100644 index 00000000000..9f6e692b148 --- /dev/null +++ b/mysql-test/t/timeout.test @@ -0,0 +1,60 @@ +--echo # +--echo # MDEV-11379 - AliSQL: [Feature] Issue#8: SELECT FOR UPDATE WAIT +--echo # MDEV-11388 - AliSQL: [Feature] Issue#15 DDL FAST FAIL +--echo # +CREATE TABLE t1(a INT, b TEXT, c MULTIPOLYGON NOT NULL); +CREATE INDEX i1 ON t1(a) WAIT 1; +CREATE FULLTEXT INDEX i2 ON t1(b) WAIT 1; +CREATE SPATIAL INDEX i3 ON t1(c) WAIT 1; +ALTER TABLE t1 WAIT 1 COMMENT='test'; +OPTIMIZE TABLE t1 WAIT 1; +DROP INDEX i1 ON t1 WAIT 1; +TRUNCATE TABLE t1 WAIT 1; +RENAME TABLE t1 WAIT 1 TO t2; +RENAME TABLE t2 NOWAIT TO t1; + +connect(con1, localhost, root,,); +LOCK TABLE t1 WRITE WAIT 31536001; + +connection default; +--error ER_LOCK_WAIT_TIMEOUT +CREATE INDEX i1 ON t1(a) WAIT 0; +--error ER_LOCK_WAIT_TIMEOUT +CREATE INDEX i1 ON t1(a) NOWAIT; +--error ER_LOCK_WAIT_TIMEOUT +CREATE FULLTEXT INDEX i2 ON t1(b) WAIT 0; +--error ER_LOCK_WAIT_TIMEOUT +CREATE FULLTEXT INDEX i2 ON t1(b) NOWAIT; +--error ER_LOCK_WAIT_TIMEOUT +CREATE SPATIAL INDEX i3 ON t1(c) WAIT 0; +--error ER_LOCK_WAIT_TIMEOUT +CREATE SPATIAL INDEX i3 ON t1(c) NOWAIT; +--error ER_LOCK_WAIT_TIMEOUT +ALTER TABLE t1 WAIT 0 COMMENT='test'; +--error ER_LOCK_WAIT_TIMEOUT +ALTER TABLE t1 NOWAIT COMMENT='test'; +OPTIMIZE TABLE t1 WAIT 0; +OPTIMIZE TABLE t1 NOWAIT; +--error ER_LOCK_WAIT_TIMEOUT +DROP INDEX i1 ON t1 WAIT 0; +--error ER_LOCK_WAIT_TIMEOUT +DROP INDEX i1 ON t1 NOWAIT; +--error ER_LOCK_WAIT_TIMEOUT +TRUNCATE TABLE t1 WAIT 0; +--error ER_LOCK_WAIT_TIMEOUT +TRUNCATE TABLE t1 NOWAIT; +--error ER_LOCK_WAIT_TIMEOUT +RENAME TABLE t1 WAIT 0 TO t2; +--error ER_LOCK_WAIT_TIMEOUT +RENAME TABLE t1 NOWAIT TO t2; +--error ER_LOCK_WAIT_TIMEOUT +DROP TABLE t1 WAIT 0; +--error ER_LOCK_WAIT_TIMEOUT +DROP TABLE t1 NOWAIT; +--error ER_LOCK_WAIT_TIMEOUT +LOCK TABLE t1 WRITE WAIT 0; +--error ER_LOCK_WAIT_TIMEOUT +LOCK TABLE t1 WRITE NOWAIT; + +disconnect con1; +DROP TABLE t1 WAIT 1; diff --git a/sql/lex.h b/sql/lex.h index 35c9e33d7d9..2e105eb89ec 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -409,6 +409,7 @@ static SYMBOL symbols[] = { { "NEXT", SYM(NEXT_SYM)}, { "NO", SYM(NO_SYM)}, { "NO_WAIT", SYM(NO_WAIT_SYM)}, + { "NOWAIT", SYM(NOWAIT_SYM)}, { "NODEGROUP", SYM(NODEGROUP_SYM)}, { "NONE", SYM(NONE_SYM)}, { "NOT", SYM(NOT_SYM)}, diff --git a/sql/mdl.cc b/sql/mdl.cc index c05fdc0157b..e453ad956eb 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -2086,6 +2086,14 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout) */ lock= ticket->m_lock; + if (lock_wait_timeout == 0) + { + mysql_prlock_unlock(&lock->m_rwlock); + MDL_ticket::destroy(ticket); + my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0)); + DBUG_RETURN(TRUE); + } + lock->m_waiting.add_ticket(ticket); /* diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 24c08f1985a..0df25e5ec27 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -5334,3 +5334,33 @@ Item *st_select_lex::build_cond_for_grouping_fields(THD *thd, Item *cond, } return 0; } + + +int set_statement_var_if_exists(THD *thd, const char *var_name, + size_t var_name_length, ulonglong value) +{ + sys_var *sysvar; + if (thd->lex->sql_command == SQLCOM_CREATE_VIEW) + { + my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "[NO]WAIT"); + return 1; + } + if (thd->lex->sphead) + { + my_error(ER_SP_BADSTATEMENT, MYF(0), "[NO]WAIT"); + return 1; + } + if ((sysvar= find_sys_var_ex(thd, var_name, var_name_length, true, false))) + { + Item *item= new (thd->mem_root) Item_uint(thd, value); + set_var *var= new (thd->mem_root) set_var(thd, OPT_SESSION, sysvar, + &null_lex_str, item); + + if (!item || !var || thd->lex->stmt_var_list.push_back(var, thd->mem_root)) + { + my_error(ER_OUT_OF_RESOURCES, MYF(0)); + return 1; + } + } + return 0; +} diff --git a/sql/sql_lex.h b/sql/sql_lex.h index e2c6f4aaaaf..0f52b84bffd 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -3351,6 +3351,8 @@ extern bool is_lex_native_function(const LEX_STRING *name); void my_missing_function_error(const LEX_STRING &token, const char *name); bool is_keyword(const char *name, uint len); +int set_statement_var_if_exists(THD *thd, const char *var_name, + size_t var_name_length, ulonglong value); #endif /* MYSQL_SERVER */ #endif /* SQL_LEX_INCLUDED */ diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index aea83f41527..438834284e6 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -2813,7 +2813,8 @@ sys_var *find_sys_var_ex(THD *thd, const char *str, size_t length, mysql_mutex_unlock(&LOCK_plugin); if (!throw_error && !var) - my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (int)length, (char*) str); + my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), + (int) (length ? length : strlen(str)), (char*) str); DBUG_RETURN(var); } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 303460a5fb4..e99cf15f447 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -3701,7 +3701,7 @@ void Prepared_statement::cleanup_stmt() { DBUG_ENTER("Prepared_statement::cleanup_stmt"); DBUG_PRINT("enter",("stmt: 0x%lx", (long) this)); - thd->restore_set_statement_var(); + lex->restore_set_statement_var(); cleanup_items(free_list); thd->cleanup_after_query(); thd->rollback_item_tree_changes(); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e0739ea848e..56ec7139c9d 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1407,6 +1407,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token NOW_SYM %token NO_SYM /* SQL-2003-R */ %token NO_WAIT_SYM +%token NOWAIT_SYM %token NO_WRITE_TO_BINLOG %token NTILE_SYM %token NULL_SYM /* SQL-2003-R */ @@ -1982,7 +1983,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); parse_vcol_expr vcol_opt_specifier vcol_opt_attribute vcol_opt_attribute_list vcol_attribute opt_serial_attribute opt_serial_attribute_list serial_attribute - explainable_command + explainable_command opt_lock_wait_timeout END_OF_INPUT %type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt @@ -2565,7 +2566,7 @@ create: if (Lex->add_create_index($2, $5, $6, $1 | $4)) MYSQL_YYABORT; } - '(' key_list ')' normal_key_options + '(' key_list ')' opt_lock_wait_timeout normal_key_options opt_index_lock_algorithm { } | create_or_replace fulltext INDEX_SYM opt_if_not_exists ident ON table_ident @@ -2575,7 +2576,7 @@ create: if (Lex->add_create_index($2, $5, HA_KEY_ALG_UNDEF, $1 | $4)) MYSQL_YYABORT; } - '(' key_list ')' fulltext_key_options + '(' key_list ')' opt_lock_wait_timeout fulltext_key_options opt_index_lock_algorithm { } | create_or_replace spatial INDEX_SYM opt_if_not_exists ident ON table_ident @@ -2585,7 +2586,7 @@ create: if (Lex->add_create_index($2, $5, HA_KEY_ALG_UNDEF, $1 | $4)) MYSQL_YYABORT; } - '(' key_list ')' spatial_key_options + '(' key_list ')' opt_lock_wait_timeout spatial_key_options opt_index_lock_algorithm { } | create_or_replace DATABASE opt_if_not_exists ident { @@ -7131,7 +7132,7 @@ alter: Lex->create_info.storage_media= HA_SM_DEFAULT; DBUG_ASSERT(!Lex->m_sql_cmd); } - alter_options TABLE_SYM table_ident + alter_options TABLE_SYM table_ident opt_lock_wait_timeout { if (!Lex->select_lex.add_table_to_list(thd, $5, NULL, TL_OPTION_UPDATING, @@ -8221,7 +8222,7 @@ optimize: /* Will be overridden during execution. */ YYPS->m_lock_type= TL_UNLOCK; } - table_list + table_list opt_lock_wait_timeout { LEX* lex= thd->lex; DBUG_ASSERT(!lex->m_sql_cmd); @@ -8271,13 +8272,13 @@ table_to_table_list: ; table_to_table: - table_ident TO_SYM table_ident + table_ident opt_lock_wait_timeout TO_SYM table_ident { LEX *lex=Lex; SELECT_LEX *sl= lex->current_select; if (!sl->add_table_to_list(thd, $1,NULL,TL_OPTION_UPDATING, TL_IGNORE, MDL_EXCLUSIVE) || - !sl->add_table_to_list(thd, $3,NULL,TL_OPTION_UPDATING, + !sl->add_table_to_list(thd, $4, NULL, TL_OPTION_UPDATING, TL_IGNORE, MDL_EXCLUSIVE)) MYSQL_YYABORT; } @@ -8684,14 +8685,14 @@ select_option: opt_select_lock_type: /* empty */ - | FOR_SYM UPDATE_SYM + | FOR_SYM UPDATE_SYM opt_lock_wait_timeout { LEX *lex=Lex; lex->current_select->lock_type= TL_WRITE; lex->current_select->set_lock_for_tables(TL_WRITE); lex->safe_to_cache_query=0; } - | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM + | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM opt_lock_wait_timeout { LEX *lex=Lex; lex->current_select->lock_type= TL_READ_WITH_SHARED_LOCKS; @@ -12118,9 +12119,9 @@ drop: YYPS->m_lock_type= TL_UNLOCK; YYPS->m_mdl_type= MDL_EXCLUSIVE; } - table_list opt_restrict + table_list opt_lock_wait_timeout opt_restrict {} - | DROP INDEX_SYM opt_if_exists_table_element ident ON table_ident {} + | DROP INDEX_SYM opt_if_exists_table_element ident ON table_ident opt_lock_wait_timeout { LEX *lex=Lex; Alter_drop *ad= (new (thd->mem_root) @@ -12686,7 +12687,7 @@ truncate: YYPS->m_lock_type= TL_WRITE; YYPS->m_mdl_type= MDL_EXCLUSIVE; } - table_name + table_name opt_lock_wait_timeout { LEX* lex= thd->lex; DBUG_ASSERT(!lex->m_sql_cmd); @@ -14794,6 +14795,7 @@ keyword_sp: | NEXT_SYM {} | NEW_SYM {} | NO_WAIT_SYM {} + | NOWAIT_SYM {} | NODEGROUP_SYM {} | NONE_SYM {} | NUMBER_SYM {} @@ -15444,10 +15446,27 @@ lock: my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "LOCK")); lex->sql_command= SQLCOM_LOCK_TABLES; } - table_lock_list + table_lock_list opt_lock_wait_timeout {} ; +opt_lock_wait_timeout: + /* empty */ + {} + | WAIT_SYM ulong_num + { + if (set_statement_var_if_exists(thd, C_STRING_WITH_LEN("lock_wait_timeout"), $2) || + set_statement_var_if_exists(thd, C_STRING_WITH_LEN("innodb_lock_wait_timeout"), $2)) + MYSQL_YYABORT; + } + | NOWAIT_SYM + { + if (set_statement_var_if_exists(thd, C_STRING_WITH_LEN("lock_wait_timeout"), 0) || + set_statement_var_if_exists(thd, C_STRING_WITH_LEN("innodb_lock_wait_timeout"), 0)) + MYSQL_YYABORT; + } + ; + table_or_tables: TABLE_SYM { } | TABLES { } diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 9a9e920c6dd..2608b665ae6 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1145,7 +1145,7 @@ static Sys_var_ulong Sys_lock_wait_timeout( "lock_wait_timeout", "Timeout in seconds to wait for a lock before returning an error.", SESSION_VAR(lock_wait_timeout), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(24 * 60 * 60), BLOCK_SIZE(1)); + VALID_RANGE(0, LONG_TIMEOUT), DEFAULT(24 * 60 * 60), BLOCK_SIZE(1)); #ifdef HAVE_MLOCKALL static Sys_var_mybool Sys_locked_in_memory( diff --git a/sql/table.h b/sql/table.h index a94fcef2316..655177e703a 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2078,9 +2078,6 @@ struct TABLE_LIST /* Don't associate a table share. */ OPEN_STUB } open_strategy; - /* For transactional locking. */ - int lock_timeout; /* NOWAIT or WAIT [X] */ - bool lock_transactional; /* If transactional lock requested. */ /** TRUE if an alias for this table was specified in the SQL. */ bool is_alias; /** TRUE if the table is referred to in the statement using a fully diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 4a3cdb8af6b..7385de8a0d7 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -905,7 +905,7 @@ static MYSQL_THDVAR_BOOL(ft_enable_stopword, PLUGIN_VAR_OPCMDARG, static MYSQL_THDVAR_ULONG(lock_wait_timeout, PLUGIN_VAR_RQCMDARG, "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.", - NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0); + NULL, NULL, 50, 0, 1024 * 1024 * 1024, 0); static MYSQL_THDVAR_STR(ft_user_stopword_table, PLUGIN_VAR_OPCMDARG|PLUGIN_VAR_MEMALLOC, diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index b211b24d7ff..f3f1f39d1a6 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -299,32 +299,6 @@ lock_rec_insert_check_and_lock( record */ MY_ATTRIBUTE((warn_unused_result)); -/*********************************************************************//** -Enqueues a waiting request for a lock which cannot be granted immediately. -Checks for deadlocks. -@return DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED, or -DB_SUCCESS_LOCKED_REC; DB_SUCCESS_LOCKED_REC means that -there was a deadlock, but another transaction was chosen as a victim, -and we got the lock immediately: no need to wait then */ -dberr_t -lock_rec_enqueue_waiting( -/*=====================*/ - ulint type_mode,/*!< in: lock mode this - transaction is requesting: - LOCK_S or LOCK_X, possibly - ORed with LOCK_GAP or - LOCK_REC_NOT_GAP, ORed with - LOCK_INSERT_INTENTION if this - waiting lock request is set - when performing an insert of - an index record */ - const buf_block_t* block, /*!< in: buffer block containing - the record */ - ulint heap_no,/*!< in: heap number of the record */ - dict_index_t* index, /*!< in: index of record */ - que_thr_t* thr, /*!< in: query thread */ - lock_prdt_t* prdt); /*!< in: Minimum Bounding Box */ - /*************************************************************//** Removes a record lock request, waiting or granted, from the queue and grants locks to other transactions in the queue if they now are entitled diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 11c1bedd39a..7e70e9a846b 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -2232,11 +2232,11 @@ queue is itself waiting roll it back, also do a deadlock check and resolve. @param[in, out] wait_for The lock that the joining transaction is waiting for @param[in] prdt Predicate [optional] -@return DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED, or - DB_SUCCESS_LOCKED_REC; DB_SUCCESS_LOCKED_REC means that - there was a deadlock, but another transaction was chosen - as a victim, and we got the lock immediately: no need to - wait then */ +@return DB_LOCK_WAIT, DB_LOCK_WAIT_TIMEOUT, DB_DEADLOCK, or + DB_QUE_THR_SUSPENDED, or DB_SUCCESS_LOCKED_REC; DB_SUCCESS_LOCKED_REC + means that there was a deadlock, but another transaction was chosen + as a victim, and we got the lock immediately: no need to wait then; + DB_LOCK_WAIT_TIMEOUT means no need to wait */ dberr_t RecLock::add_to_waitq(const lock_t* wait_for, const lock_prdt_t* prdt) { @@ -2244,6 +2244,11 @@ RecLock::add_to_waitq(const lock_t* wait_for, const lock_prdt_t* prdt) ut_ad(m_trx == thr_get_trx(m_thr)); ut_ad(trx_mutex_own(m_trx)); + if (m_trx->mysql_thd && thd_lock_wait_timeout(m_trx->mysql_thd) == 0) { + m_trx->error_state = DB_LOCK_WAIT_TIMEOUT; + return(DB_LOCK_WAIT_TIMEOUT); + } + DEBUG_SYNC_C("rec_lock_add_to_waitq"); m_mode |= LOCK_WAIT; diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index 9794146460b..d8de29a909d 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -536,11 +536,6 @@ UNIV_INTERN ulong srv_buf_dump_status_frequency = 0; mutex_exit(&srv_sys->mutex); \ } while (0) -#define fetch_lock_wait_timeout(trx) \ - ((trx)->lock.allowed_to_wait \ - ? thd_lock_wait_timeout((trx)->mysql_thd) \ - : 0) - /* IMPLEMENTATION OF THE SERVER MAIN PROGRAM ========================================= |