summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <tsmith/tim@siva.hindu.god>2006-12-19 16:57:51 -0700
committerunknown <tsmith/tim@siva.hindu.god>2006-12-19 16:57:51 -0700
commit20e9b4907a316f519491136e1b4847122bf12e90 (patch)
tree9d22a6e3d1f813ebfd932d958ebe02a7a5519099
parent4cf2b8e1ae2223b602f439992697d336bd84dfee (diff)
downloadmariadb-git-20e9b4907a316f519491136e1b4847122bf12e90.tar.gz
Added innodb_rollback_on_timeout option to restore the 4.1
InnoDB timeout behavior (Bug #24200) mysql-test/t/innodb_mysql-master.opt: Set --innodb-lock-wait-timeout=2, since test for bug #24200 times out. This *could* cause random test failures if some long-running transaction concurrency is being tested. However, such a test really should go in innodb-big or some other test file.
-rw-r--r--innobase/include/row0mysql.h2
-rw-r--r--innobase/row/row0mysql.c11
-rw-r--r--mysql-test/include/innodb_rollback_on_timeout.inc37
-rw-r--r--mysql-test/r/innodb_mysql.result36
-rw-r--r--mysql-test/r/innodb_timeout_rollback.result35
-rw-r--r--mysql-test/t/innodb_mysql-master.opt1
-rw-r--r--mysql-test/t/innodb_mysql.test2
-rw-r--r--mysql-test/t/innodb_timeout_rollback-master.opt1
-rw-r--r--mysql-test/t/innodb_timeout_rollback.test5
-rw-r--r--sql/ha_innodb.cc7
-rw-r--r--sql/ha_innodb.h1
-rw-r--r--sql/mysqld.cc7
-rw-r--r--sql/set_var.cc1
13 files changed, 144 insertions, 2 deletions
diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h
index 7d8740db044..9e28fabe491 100644
--- a/innobase/include/row0mysql.h
+++ b/innobase/include/row0mysql.h
@@ -19,6 +19,8 @@ Created 9/17/2000 Heikki Tuuri
#include "btr0pcur.h"
#include "trx0types.h"
+extern ibool row_rollback_on_timeout;
+
typedef struct row_prebuilt_struct row_prebuilt_t;
/***********************************************************************
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index efbb93ba9f5..4bc5f39359c 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -35,6 +35,9 @@ Created 9/17/2000 Heikki Tuuri
/* A dummy variable used to fool the compiler */
ibool row_mysql_identically_false = FALSE;
+/* Provide optional 4.x backwards compatibility for 5.0 and above */
+ibool row_rollback_on_timeout = FALSE;
+
/* List of tables we should drop in background. ALTER TABLE in MySQL requires
that the table handler can drop the table in background when there are no
queries to it any more. Protected by the kernel mutex. */
@@ -514,7 +517,9 @@ handle_new_error:
return(TRUE);
} else if (err == DB_DEADLOCK
- || err == DB_LOCK_TABLE_FULL) {
+ || err == DB_LOCK_TABLE_FULL
+ || (err == DB_LOCK_WAIT_TIMEOUT
+ && row_rollback_on_timeout)) {
/* Roll back the whole transaction; this resolution was added
to version 3.23.43 */
@@ -522,6 +527,10 @@ handle_new_error:
} else if (err == DB_OUT_OF_FILE_SPACE
|| err == DB_LOCK_WAIT_TIMEOUT) {
+
+ ut_ad(!(err == DB_LOCK_WAIT_TIMEOUT
+ && row_rollback_on_timeout));
+
if (savept) {
/* Roll back the latest, possibly incomplete
insertion or update */
diff --git a/mysql-test/include/innodb_rollback_on_timeout.inc b/mysql-test/include/innodb_rollback_on_timeout.inc
new file mode 100644
index 00000000000..73c7374c79e
--- /dev/null
+++ b/mysql-test/include/innodb_rollback_on_timeout.inc
@@ -0,0 +1,37 @@
+#
+# Bug #24200: Provide backwards compatibility mode for 4.x "rollback on
+# transaction timeout"
+#
+show variables like 'innodb_rollback_on_timeout';
+create table t1 (a int unsigned not null primary key) engine = innodb;
+insert into t1 values (1);
+commit;
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+
+connection con2;
+begin work;
+insert into t1 values (2);
+select * from t1;
+
+connection con1;
+begin work;
+insert into t1 values (5);
+select * from t1;
+# Lock wait timeout set to 2 seconds in <THIS TEST>-master.opt; this
+# statement will time out; in 5.0.13+, it will not roll back transaction.
+--error ER_LOCK_WAIT_TIMEOUT
+insert into t1 values (2);
+# On 5.0.13+, this should give ==> 1, 5
+select * from t1;
+commit;
+
+connection con2;
+select * from t1;
+commit;
+
+connection default;
+select * from t1;
+drop table t1;
+disconnect con1;
+disconnect con2;
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
index 012f9492d8d..f150af4b6c2 100644
--- a/mysql-test/r/innodb_mysql.result
+++ b/mysql-test/r/innodb_mysql.result
@@ -383,4 +383,40 @@ EXPLAIN SELECT SQL_BIG_RESULT b, SUM(c) FROM t1 GROUP BY b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 128 Using filesort
DROP TABLE t1;
+show variables like 'innodb_rollback_on_timeout';
+Variable_name Value
+innodb_rollback_on_timeout OFF
+create table t1 (a int unsigned not null primary key) engine = innodb;
+insert into t1 values (1);
+commit;
+begin work;
+insert into t1 values (2);
+select * from t1;
+a
+1
+2
+begin work;
+insert into t1 values (5);
+select * from t1;
+a
+1
+5
+insert into t1 values (2);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+select * from t1;
+a
+1
+5
+commit;
+select * from t1;
+a
+1
+2
+commit;
+select * from t1;
+a
+1
+2
+5
+drop table t1;
End of 5.0 tests
diff --git a/mysql-test/r/innodb_timeout_rollback.result b/mysql-test/r/innodb_timeout_rollback.result
new file mode 100644
index 00000000000..b25a2bbd815
--- /dev/null
+++ b/mysql-test/r/innodb_timeout_rollback.result
@@ -0,0 +1,35 @@
+show variables like 'innodb_rollback_on_timeout';
+Variable_name Value
+innodb_rollback_on_timeout ON
+create table t1 (a int unsigned not null primary key) engine = innodb;
+insert into t1 values (1);
+commit;
+begin work;
+insert into t1 values (2);
+select * from t1;
+a
+1
+2
+begin work;
+insert into t1 values (5);
+select * from t1;
+a
+1
+5
+insert into t1 values (2);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+select * from t1;
+a
+1
+commit;
+select * from t1;
+a
+1
+2
+commit;
+select * from t1;
+a
+1
+2
+drop table t1;
+End of 5.0 tests
diff --git a/mysql-test/t/innodb_mysql-master.opt b/mysql-test/t/innodb_mysql-master.opt
new file mode 100644
index 00000000000..205c733455d
--- /dev/null
+++ b/mysql-test/t/innodb_mysql-master.opt
@@ -0,0 +1 @@
+--innodb-lock-wait-timeout=2
diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test
index 06cfe71ef11..45a2ede091b 100644
--- a/mysql-test/t/innodb_mysql.test
+++ b/mysql-test/t/innodb_mysql.test
@@ -384,4 +384,6 @@ EXPLAIN SELECT SQL_BIG_RESULT b, SUM(c) FROM t1 GROUP BY b;
DROP TABLE t1;
+--source include/innodb_rollback_on_timeout.inc
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/innodb_timeout_rollback-master.opt b/mysql-test/t/innodb_timeout_rollback-master.opt
new file mode 100644
index 00000000000..50921bb4df0
--- /dev/null
+++ b/mysql-test/t/innodb_timeout_rollback-master.opt
@@ -0,0 +1 @@
+--innodb_lock_wait_timeout=2 --innodb_rollback_on_timeout
diff --git a/mysql-test/t/innodb_timeout_rollback.test b/mysql-test/t/innodb_timeout_rollback.test
new file mode 100644
index 00000000000..99890971064
--- /dev/null
+++ b/mysql-test/t/innodb_timeout_rollback.test
@@ -0,0 +1,5 @@
+-- source include/have_innodb.inc
+
+--source include/innodb_rollback_on_timeout.inc
+
+--echo End of 5.0 tests
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 9f367313fb0..456fd27d9d9 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -173,6 +173,7 @@ my_bool innobase_use_large_pages = FALSE;
my_bool innobase_use_native_aio = FALSE;
my_bool innobase_file_per_table = FALSE;
my_bool innobase_locks_unsafe_for_binlog = FALSE;
+my_bool innobase_rollback_on_timeout = FALSE;
my_bool innobase_create_status_file = FALSE;
static char *internal_innobase_data_file_path = NULL;
@@ -467,6 +468,10 @@ convert_error_code_to_mysql(
latest SQL statement in a lock wait timeout. Previously, we
rolled back the whole transaction. */
+ if (thd && row_rollback_on_timeout) {
+ ha_rollback(thd);
+ }
+
return(HA_ERR_LOCK_WAIT_TIMEOUT);
} else if (error == (int) DB_NO_REFERENCED_ROW) {
@@ -1380,6 +1385,8 @@ innobase_init(void)
os_use_large_pages = (ibool) innobase_use_large_pages;
os_large_page_size = (ulint) innobase_large_page_size;
+ row_rollback_on_timeout = (ibool) innobase_rollback_on_timeout;
+
srv_file_per_table = (ibool) innobase_file_per_table;
srv_locks_unsafe_for_binlog = (ibool) innobase_locks_unsafe_for_binlog;
diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h
index 95d7a9437ad..60bc0e9c7cf 100644
--- a/sql/ha_innodb.h
+++ b/sql/ha_innodb.h
@@ -216,6 +216,7 @@ extern my_bool innobase_log_archive,
innobase_use_large_pages,
innobase_use_native_aio,
innobase_file_per_table, innobase_locks_unsafe_for_binlog,
+ innobase_rollback_on_timeout,
innobase_create_status_file;
extern my_bool innobase_very_fast_shutdown; /* set this to 1 just before
calling innobase_end() if you want
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 9411ba2ef12..5890a2af21d 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -4692,7 +4692,8 @@ enum options_mysqld
OPT_LOG_SLOW_ADMIN_STATEMENTS,
OPT_TABLE_LOCK_WAIT_TIMEOUT,
OPT_PORT_OPEN_TIMEOUT,
- OPT_MERGE
+ OPT_MERGE,
+ OPT_INNODB_ROLLBACK_ON_TIMEOUT
};
@@ -4968,6 +4969,10 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite,
(gptr*) &srv_max_purge_lag,
(gptr*) &srv_max_purge_lag, 0, GET_LONG, REQUIRED_ARG, 0, 0, ~0L,
0, 1L, 0},
+ {"innodb_rollback_on_timeout", OPT_INNODB_ROLLBACK_ON_TIMEOUT,
+ "Roll back the complete transaction on lock wait timeout, for 4.x compatibility (disabled by default)",
+ (gptr*) &innobase_rollback_on_timeout, (gptr*) &innobase_rollback_on_timeout,
+ 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"innodb_status_file", OPT_INNODB_STATUS_FILE,
"Enable SHOW INNODB STATUS output in the innodb_status.<pid> file",
(gptr*) &innobase_create_status_file, (gptr*) &innobase_create_status_file,
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 23afef742a6..5bbab6224ef 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -904,6 +904,7 @@ struct show_var_st init_vars[]= {
{sys_innodb_max_purge_lag.name, (char*) &sys_innodb_max_purge_lag, SHOW_SYS},
{"innodb_mirrored_log_groups", (char*) &innobase_mirrored_log_groups, SHOW_LONG},
{"innodb_open_files", (char*) &innobase_open_files, SHOW_LONG },
+ {"innodb_rollback_on_timeout", (char*) &innobase_rollback_on_timeout, SHOW_MY_BOOL},
{sys_innodb_support_xa.name, (char*) &sys_innodb_support_xa, SHOW_SYS},
{sys_innodb_sync_spin_loops.name, (char*) &sys_innodb_sync_spin_loops, SHOW_SYS},
{sys_innodb_table_locks.name, (char*) &sys_innodb_table_locks, SHOW_SYS},