Skip to content

Commit 84c205f

Browse files
author
Mattias Jonsson
committed
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.)
1 parent b4c213c commit 84c205f

File tree

5 files changed

+49
-6
lines changed

5 files changed

+49
-6
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CREATE TABLE t1 (a INT) ENGINE = InnoDB PARTITION BY HASH(a);
2+
INSERT INTO t1 VALUES (0), (1), (2);
3+
START TRANSACTION;
4+
UPDATE t1 SET a = 5 WHERE a = 1;
5+
# Connection con1
6+
# InnoDB lock timeout and monitor thread runs every 15 seconds
7+
SET innodb_lock_wait_timeout = 20;
8+
START TRANSACTION;
9+
UPDATE t1 SET a = 3 WHERE a = 1;
10+
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
11+
COMMIT;
12+
# Connection default
13+
COMMIT;
14+
DROP TABLE t1;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--innodb-status-file=1
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--source include/have_innodb.inc
2+
--source include/have_partition.inc
3+
4+
CREATE TABLE t1 (a INT) ENGINE = InnoDB PARTITION BY HASH(a);
5+
INSERT INTO t1 VALUES (0), (1), (2);
6+
START TRANSACTION;
7+
UPDATE t1 SET a = 5 WHERE a = 1;
8+
connect (con1, localhost, root,,);
9+
--echo # Connection con1
10+
--echo # InnoDB lock timeout and monitor thread runs every 15 seconds
11+
SET innodb_lock_wait_timeout = 20;
12+
START TRANSACTION;
13+
--error ER_LOCK_WAIT_TIMEOUT
14+
UPDATE t1 SET a = 3 WHERE a = 1;
15+
COMMIT;
16+
disconnect con1;
17+
connection default;
18+
--echo # Connection default
19+
COMMIT;
20+
DROP TABLE t1;

sql/sql_table.cc

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,8 @@ uint explain_filename(THD* thd,
291291
{
292292
if (explain_mode == EXPLAIN_ALL_VERBOSE)
293293
{
294-
to_p= strnmov(to_p, ER(ER_DATABASE_NAME), end_p - to_p);
294+
to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_DATABASE_NAME),
295+
end_p - to_p);
295296
*(to_p++)= ' ';
296297
to_p= add_identifier(thd, to_p, end_p, db_name, db_name_len);
297298
to_p= strnmov(to_p, ", ", end_p - to_p);
@@ -304,7 +305,7 @@ uint explain_filename(THD* thd,
304305
}
305306
if (explain_mode == EXPLAIN_ALL_VERBOSE)
306307
{
307-
to_p= strnmov(to_p, ER(ER_TABLE_NAME), end_p - to_p);
308+
to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_TABLE_NAME), end_p - to_p);
308309
*(to_p++)= ' ';
309310
to_p= add_identifier(thd, to_p, end_p, table_name, table_name_len);
310311
}
@@ -321,18 +322,22 @@ uint explain_filename(THD* thd,
321322
if (name_type != NORMAL)
322323
{
323324
if (name_type == TEMP)
324-
to_p= strnmov(to_p, ER(ER_TEMPORARY_NAME), end_p - to_p);
325+
to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_TEMPORARY_NAME),
326+
end_p - to_p);
325327
else
326-
to_p= strnmov(to_p, ER(ER_RENAMED_NAME), end_p - to_p);
328+
to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_RENAMED_NAME),
329+
end_p - to_p);
327330
to_p= strnmov(to_p, " ", end_p - to_p);
328331
}
329-
to_p= strnmov(to_p, ER(ER_PARTITION_NAME), end_p - to_p);
332+
to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_PARTITION_NAME),
333+
end_p - to_p);
330334
*(to_p++)= ' ';
331335
to_p= add_identifier(thd, to_p, end_p, part_name, part_name_len);
332336
if (subpart_name)
333337
{
334338
to_p= strnmov(to_p, ", ", end_p - to_p);
335-
to_p= strnmov(to_p, ER(ER_SUBPARTITION_NAME), end_p - to_p);
339+
to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_SUBPARTITION_NAME),
340+
end_p - to_p);
336341
*(to_p++)= ' ';
337342
to_p= add_identifier(thd, to_p, end_p, subpart_name, subpart_name_len);
338343
}

sql/unireg.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@
4646
#define ER(X) CURRENT_THD_ERRMSGS[(X) - ER_ERROR_FIRST]
4747
#define ER_DEFAULT(X) DEFAULT_ERRMSGS[(X) - ER_ERROR_FIRST]
4848
#define ER_SAFE(X) (((X) >= ER_ERROR_FIRST && (X) <= ER_ERROR_LAST) ? ER(X) : "Invalid error code")
49+
#define ER_THD(thd,X) ((thd)->variables.lc_messages->errmsgs->errmsgs[(X) - \
50+
ER_ERROR_FIRST])
51+
#define ER_THD_OR_DEFAULT(thd,X) ((thd) ? ER_THD(thd, X) : ER_DEFAULT(X))
4952

5053

5154
#define ERRMAPP 1 /* Errormap f|r my_error */

0 commit comments

Comments
 (0)