summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorYasufumi Kinoshita <yasufumi.kinoshita@oracle.com>2012-01-10 14:18:58 +0900
committerYasufumi Kinoshita <yasufumi.kinoshita@oracle.com>2012-01-10 14:18:58 +0900
commit115f5e8551b9243ef3ca98ce882993fb78c426e1 (patch)
treeeb3e73644289ee45d9adcc3caba490fbd1311178 /storage
parent13b265483e0aeefdc6de8bd227ca0dfc7cd91736 (diff)
downloadmariadb-git-115f5e8551b9243ef3ca98ce882993fb78c426e1.tar.gz
Bug#12400341 INNODB CAN LEAVE ORPHAN IBD FILES AROUND
If we meet DB_TOO_MANY_CONCURRENT_TRXS during the execution tab_create_graph from row_create_table_for_mysql(), .ibd file for the table should be created already but was not deleted for the error handling. rb:875 approved by Jimmy Yang
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/handler/ha_innodb.cc10
-rw-r--r--storage/innobase/include/trx0rseg.ic9
-rw-r--r--storage/innobase/include/trx0sys.h5
-rw-r--r--storage/innobase/row/row0mysql.c12
-rw-r--r--storage/innobase/trx/trx0sys.c4
-rw-r--r--storage/innodb_plugin/ChangeLog5
-rw-r--r--storage/innodb_plugin/handler/ha_innodb.cc10
-rw-r--r--storage/innodb_plugin/include/trx0rseg.ic9
-rw-r--r--storage/innodb_plugin/include/trx0sys.h6
-rw-r--r--storage/innodb_plugin/row/row0mysql.c14
-rw-r--r--storage/innodb_plugin/trx/trx0sys.c5
11 files changed, 87 insertions, 2 deletions
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index a4d79a5934e..573e0a4455a 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -9060,6 +9060,13 @@ static MYSQL_SYSVAR_UINT(change_buffering_debug, ibuf_debug,
NULL, NULL, 0, 0, 1, 0);
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
+#ifdef UNIV_DEBUG
+static MYSQL_SYSVAR_UINT(trx_rseg_n_slots_debug, trx_rseg_n_slots_debug,
+ PLUGIN_VAR_RQCMDARG,
+ "Debug flags for InnoDB to limit TRX_RSEG_N_SLOTS for trx_rsegf_undo_find_free()",
+ NULL, NULL, 0, 0, 1024, 0);
+#endif /* UNIV_DEBUG */
+
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(additional_mem_pool_size),
MYSQL_SYSVAR(autoextend_increment),
@@ -9105,6 +9112,9 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
MYSQL_SYSVAR(change_buffering_debug),
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
+#ifdef UNIV_DEBUG
+ MYSQL_SYSVAR(trx_rseg_n_slots_debug),
+#endif /* UNIV_DEBUG */
NULL
};
diff --git a/storage/innobase/include/trx0rseg.ic b/storage/innobase/include/trx0rseg.ic
index 577cd0dee7b..5b01b2f197d 100644
--- a/storage/innobase/include/trx0rseg.ic
+++ b/storage/innobase/include/trx0rseg.ic
@@ -8,6 +8,7 @@ Created 3/26/1996 Heikki Tuuri
#include "srv0srv.h"
#include "mtr0log.h"
+#include "trx0sys.h"
/**********************************************************************
Gets a rollback segment header. */
@@ -113,7 +114,13 @@ trx_rsegf_undo_find_free(
ulint i;
ulint page_no;
- for (i = 0; i < TRX_RSEG_N_SLOTS; i++) {
+ for (i = 0;
+#ifndef UNIV_DEBUG
+ i < TRX_RSEG_N_SLOTS;
+#else
+ i < (trx_rseg_n_slots_debug ? trx_rseg_n_slots_debug : TRX_RSEG_N_SLOTS);
+#endif
+ i++) {
page_no = trx_rsegf_get_nth_undo(rsegf, i, mtr);
diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h
index 7ea981eb85c..aedeb51d3b3 100644
--- a/storage/innobase/include/trx0sys.h
+++ b/storage/innobase/include/trx0sys.h
@@ -47,6 +47,11 @@ extern ibool trx_doublewrite_buf_is_being_created;
extern ibool trx_doublewrite_must_reset_space_ids;
extern ibool trx_sys_multiple_tablespace_format;
+#ifdef UNIV_DEBUG
+/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */
+extern uint trx_rseg_n_slots_debug;
+#endif
+
/********************************************************************
Creates the doublewrite buffer to a new InnoDB installation. The header of the
doublewrite buffer is placed on the trx system header page. */
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index cee97871470..6148b01af9d 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -1948,6 +1948,18 @@ row_create_table_for_mysql(
FALSE);
}
+ } else if (err == DB_TOO_MANY_CONCURRENT_TRXS) {
+ /* We already have .ibd file here. it should be deleted. */
+ if (table->space
+ && !fil_delete_tablespace(table->space)) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Error: not able to"
+ " delete tablespace %lu of table ",
+ (ulong) table->space);
+ ut_print_name(stderr, trx, TRUE, table->name);
+ fputs("!\n", stderr);
+ }
} else if (err == DB_DUPLICATE_KEY) {
ut_print_timestamp(stderr);
diff --git a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c
index 137771b71ed..09b1b5d8198 100644
--- a/storage/innobase/trx/trx0sys.c
+++ b/storage/innobase/trx/trx0sys.c
@@ -54,6 +54,10 @@ InnoDB. */
char trx_sys_mysql_bin_log_name[TRX_SYS_MYSQL_LOG_NAME_LEN];
ib_longlong trx_sys_mysql_bin_log_pos = -1;
+#ifdef UNIV_DEBUG
+/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */
+uint trx_rseg_n_slots_debug = 0;
+#endif
/********************************************************************
Determines if a page number is located inside the doublewrite buffer. */
diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog
index 1385da94bfb..d33dfd33043 100644
--- a/storage/innodb_plugin/ChangeLog
+++ b/storage/innodb_plugin/ChangeLog
@@ -1,3 +1,8 @@
+2012-01-04 The InnoDB Team
+
+ * row/row0mysql.c:
+ Fix Bug#12400341: INNODB CAN LEAVE ORPHAN IBD FILES AROUND
+
2011-12-21 The InnoDB Team
* include/ut0rnd.ic:
diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
index 122bf1f7846..149e660e36e 100644
--- a/storage/innodb_plugin/handler/ha_innodb.cc
+++ b/storage/innodb_plugin/handler/ha_innodb.cc
@@ -11033,6 +11033,13 @@ static MYSQL_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold,
"trigger a readahead.",
NULL, NULL, 56, 0, 64, 0);
+#ifdef UNIV_DEBUG
+static MYSQL_SYSVAR_UINT(trx_rseg_n_slots_debug, trx_rseg_n_slots_debug,
+ PLUGIN_VAR_RQCMDARG,
+ "Debug flags for InnoDB to limit TRX_RSEG_N_SLOTS for trx_rsegf_undo_find_free()",
+ NULL, NULL, 0, 0, 1024, 0);
+#endif /* UNIV_DEBUG */
+
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(additional_mem_pool_size),
MYSQL_SYSVAR(autoextend_increment),
@@ -11094,6 +11101,9 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(random_read_ahead),
MYSQL_SYSVAR(read_ahead_threshold),
MYSQL_SYSVAR(io_capacity),
+#ifdef UNIV_DEBUG
+ MYSQL_SYSVAR(trx_rseg_n_slots_debug),
+#endif /* UNIV_DEBUG */
NULL
};
diff --git a/storage/innodb_plugin/include/trx0rseg.ic b/storage/innodb_plugin/include/trx0rseg.ic
index daffa92fc7d..5e8d2b41120 100644
--- a/storage/innodb_plugin/include/trx0rseg.ic
+++ b/storage/innodb_plugin/include/trx0rseg.ic
@@ -25,6 +25,7 @@ Created 3/26/1996 Heikki Tuuri
#include "srv0srv.h"
#include "mtr0log.h"
+#include "trx0sys.h"
/******************************************************************//**
Gets a rollback segment header.
@@ -131,7 +132,13 @@ trx_rsegf_undo_find_free(
ulint i;
ulint page_no;
- for (i = 0; i < TRX_RSEG_N_SLOTS; i++) {
+ for (i = 0;
+#ifndef UNIV_DEBUG
+ i < TRX_RSEG_N_SLOTS;
+#else
+ i < (trx_rseg_n_slots_debug ? trx_rseg_n_slots_debug : TRX_RSEG_N_SLOTS);
+#endif
+ i++) {
page_no = trx_rsegf_get_nth_undo(rsegf, i, mtr);
diff --git a/storage/innodb_plugin/include/trx0sys.h b/storage/innodb_plugin/include/trx0sys.h
index 78bb6fc349b..56fb801ee42 100644
--- a/storage/innodb_plugin/include/trx0sys.h
+++ b/storage/innodb_plugin/include/trx0sys.h
@@ -229,6 +229,12 @@ trx_id_t
trx_sys_get_new_trx_no(void);
/*========================*/
#endif /* !UNIV_HOTBACKUP */
+
+#ifdef UNIV_DEBUG
+/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */
+extern uint trx_rseg_n_slots_debug;
+#endif
+
/*****************************************************************//**
Writes a trx id to an index page. In case that the id size changes in
some future version, this function should be used instead of
diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c
index 6f689f9909d..36aad4f8ca2 100644
--- a/storage/innodb_plugin/row/row0mysql.c
+++ b/storage/innodb_plugin/row/row0mysql.c
@@ -1900,6 +1900,20 @@ err_exit:
}
break;
+ case DB_TOO_MANY_CONCURRENT_TRXS:
+ /* We already have .ibd file here. it should be deleted. */
+
+ if (table->space && !fil_delete_tablespace(table->space)) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Error: not able to"
+ " delete tablespace %lu of table ",
+ (ulong) table->space);
+ ut_print_name(stderr, trx, TRUE, table->name);
+ fputs("!\n", stderr);
+ }
+ /* fall through */
+
case DB_DUPLICATE_KEY:
default:
/* We may also get err == DB_ERROR if the .ibd file for the
diff --git a/storage/innodb_plugin/trx/trx0sys.c b/storage/innodb_plugin/trx/trx0sys.c
index 352fa6af219..e9328b27bba 100644
--- a/storage/innodb_plugin/trx/trx0sys.c
+++ b/storage/innodb_plugin/trx/trx0sys.c
@@ -127,6 +127,11 @@ static const char* file_format_name_map[] = {
static const ulint FILE_FORMAT_NAME_N
= sizeof(file_format_name_map) / sizeof(file_format_name_map[0]);
+#ifdef UNIV_DEBUG
+/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */
+uint trx_rseg_n_slots_debug = 0;
+#endif
+
#ifndef UNIV_HOTBACKUP
/** This is used to track the maximum file format id known to InnoDB. It's
updated via SET GLOBAL innodb_file_format_check = 'x' or when we open