summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMattias Jonsson <mattias.jonsson@sun.com>2010-02-10 10:47:14 +0100
committerMattias Jonsson <mattias.jonsson@sun.com>2010-02-10 10:47:14 +0100
commitdca6700620d5f4b325c3aadbbf5ab30c5b888a8c (patch)
tree1abc5a1adcb9a036100dcca4f13555cc20c8fd1f
parentf5311bba7e1847210d365bc476d2973dd39da3bd (diff)
downloadmariadb-git-dca6700620d5f4b325c3aadbbf5ab30c5b888a8c.tar.gz
Bug#50201: Server crashes in explain_filename on an InnoDB partitioned table
Problem was that in mysql-trunk the ER() macro is now dependent on current_thd and the innodb monitor thread has no binding to that thd object. This cause the crash because of bad derefencing. Solution was to add a new macro which take the thd as an argument (which the innodb thread uses for the call). (Updated according to reviewers comments, i.e. added ER_THD_OR_DEFAULT and moved test to suite parts.) mysql-test/suite/parts/r/partition_innodb_status_file.result: Bug#50201: Server crashes in explain_filename on an InnoDB partitioned table New test result file mysql-test/suite/parts/t/partition_innodb_status_file-master.opt: Bug#50201: Server crashes in explain_filename on an InnoDB partitioned table New test opt file mysql-test/suite/parts/t/partition_innodb_status_file.test: Bug#50201: Server crashes in explain_filename on an InnoDB partitioned table New test. Note that the innodb monitor thread only runs every 15 seconds, so this test will take at least 15 seconds, so I have moved it to the parts suite. sql/sql_table.cc: Bug#50201: Server crashes in explain_filename on an InnoDB partitioned table Using thd safe ER macro. sql/unireg.h: Bug#50201: Server crashes in explain_filename on an InnoDB partitioned table Added ER macros for use with specified thd pointer.
-rw-r--r--mysql-test/suite/parts/r/partition_innodb_status_file.result14
-rw-r--r--mysql-test/suite/parts/t/partition_innodb_status_file-master.opt1
-rw-r--r--mysql-test/suite/parts/t/partition_innodb_status_file.test20
-rw-r--r--sql/sql_table.cc17
-rw-r--r--sql/unireg.h3
5 files changed, 49 insertions, 6 deletions
diff --git a/mysql-test/suite/parts/r/partition_innodb_status_file.result b/mysql-test/suite/parts/r/partition_innodb_status_file.result
new file mode 100644
index 00000000000..29b5a3b3766
--- /dev/null
+++ b/mysql-test/suite/parts/r/partition_innodb_status_file.result
@@ -0,0 +1,14 @@
+CREATE TABLE t1 (a INT) ENGINE = InnoDB PARTITION BY HASH(a);
+INSERT INTO t1 VALUES (0), (1), (2);
+START TRANSACTION;
+UPDATE t1 SET a = 5 WHERE a = 1;
+# Connection con1
+# InnoDB lock timeout and monitor thread runs every 15 seconds
+SET innodb_lock_wait_timeout = 20;
+START TRANSACTION;
+UPDATE t1 SET a = 3 WHERE a = 1;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+COMMIT;
+# Connection default
+COMMIT;
+DROP TABLE t1;
diff --git a/mysql-test/suite/parts/t/partition_innodb_status_file-master.opt b/mysql-test/suite/parts/t/partition_innodb_status_file-master.opt
new file mode 100644
index 00000000000..779962e8fca
--- /dev/null
+++ b/mysql-test/suite/parts/t/partition_innodb_status_file-master.opt
@@ -0,0 +1 @@
+--innodb-status-file=1
diff --git a/mysql-test/suite/parts/t/partition_innodb_status_file.test b/mysql-test/suite/parts/t/partition_innodb_status_file.test
new file mode 100644
index 00000000000..f066ce5d485
--- /dev/null
+++ b/mysql-test/suite/parts/t/partition_innodb_status_file.test
@@ -0,0 +1,20 @@
+--source include/have_innodb.inc
+--source include/have_partition.inc
+
+CREATE TABLE t1 (a INT) ENGINE = InnoDB PARTITION BY HASH(a);
+INSERT INTO t1 VALUES (0), (1), (2);
+START TRANSACTION;
+UPDATE t1 SET a = 5 WHERE a = 1;
+connect (con1, localhost, root,,);
+--echo # Connection con1
+--echo # InnoDB lock timeout and monitor thread runs every 15 seconds
+SET innodb_lock_wait_timeout = 20;
+START TRANSACTION;
+--error ER_LOCK_WAIT_TIMEOUT
+UPDATE t1 SET a = 3 WHERE a = 1;
+COMMIT;
+disconnect con1;
+connection default;
+--echo # Connection default
+COMMIT;
+DROP TABLE t1;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index b17edbdd234..6006c818725 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -291,7 +291,8 @@ uint explain_filename(THD* thd,
{
if (explain_mode == EXPLAIN_ALL_VERBOSE)
{
- to_p= strnmov(to_p, ER(ER_DATABASE_NAME), end_p - to_p);
+ to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_DATABASE_NAME),
+ end_p - to_p);
*(to_p++)= ' ';
to_p= add_identifier(thd, to_p, end_p, db_name, db_name_len);
to_p= strnmov(to_p, ", ", end_p - to_p);
@@ -304,7 +305,7 @@ uint explain_filename(THD* thd,
}
if (explain_mode == EXPLAIN_ALL_VERBOSE)
{
- to_p= strnmov(to_p, ER(ER_TABLE_NAME), end_p - to_p);
+ to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_TABLE_NAME), end_p - to_p);
*(to_p++)= ' ';
to_p= add_identifier(thd, to_p, end_p, table_name, table_name_len);
}
@@ -321,18 +322,22 @@ uint explain_filename(THD* thd,
if (name_type != NORMAL)
{
if (name_type == TEMP)
- to_p= strnmov(to_p, ER(ER_TEMPORARY_NAME), end_p - to_p);
+ to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_TEMPORARY_NAME),
+ end_p - to_p);
else
- to_p= strnmov(to_p, ER(ER_RENAMED_NAME), end_p - to_p);
+ to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_RENAMED_NAME),
+ end_p - to_p);
to_p= strnmov(to_p, " ", end_p - to_p);
}
- to_p= strnmov(to_p, ER(ER_PARTITION_NAME), end_p - to_p);
+ to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_PARTITION_NAME),
+ end_p - to_p);
*(to_p++)= ' ';
to_p= add_identifier(thd, to_p, end_p, part_name, part_name_len);
if (subpart_name)
{
to_p= strnmov(to_p, ", ", end_p - to_p);
- to_p= strnmov(to_p, ER(ER_SUBPARTITION_NAME), end_p - to_p);
+ to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_SUBPARTITION_NAME),
+ end_p - to_p);
*(to_p++)= ' ';
to_p= add_identifier(thd, to_p, end_p, subpart_name, subpart_name_len);
}
diff --git a/sql/unireg.h b/sql/unireg.h
index a390b755772..e915b234a6b 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -46,6 +46,9 @@
#define ER(X) CURRENT_THD_ERRMSGS[(X) - ER_ERROR_FIRST]
#define ER_DEFAULT(X) DEFAULT_ERRMSGS[(X) - ER_ERROR_FIRST]
#define ER_SAFE(X) (((X) >= ER_ERROR_FIRST && (X) <= ER_ERROR_LAST) ? ER(X) : "Invalid error code")
+#define ER_THD(thd,X) ((thd)->variables.lc_messages->errmsgs->errmsgs[(X) - \
+ ER_ERROR_FIRST])
+#define ER_THD_OR_DEFAULT(thd,X) ((thd) ? ER_THD(thd, X) : ER_DEFAULT(X))
#define ERRMAPP 1 /* Errormap f|r my_error */