Details
-
Bug
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Fixed
-
10.5.1
Description
A crash with the following (abbreviated) call stack was observed:
#10 0x0000558a21f88cef in memcpy (__len=<optimized out>, __src=0x14af1c3f0740, __dest=0x14af1c3f0670)
|
at /usr/include/x86_64-linux-gnu/bits/string_fortified.h:34
|
#11 dict_acquire_mdl_shared<false> (table=table@entry=0x14aee838fef0, thd=thd@entry=0x558a24399468,
|
mdl=mdl@entry=0x558a24285b00, table_op=table_op@entry=DICT_TABLE_OP_NORMAL)
|
at /test/10.5_opt/storage/innobase/dict/dict0dict.cc:904
|
#12 0x0000558a21f84110 in dict_table_open_on_id (table_id=98, dict_locked=dict_locked@entry=false,
|
table_op=table_op@entry=DICT_TABLE_OP_NORMAL, thd=0x558a24399468, mdl=mdl@entry=0x558a24285b00)
|
at /test/10.5_opt/storage/innobase/dict/dict0dict.cc:946
|
#13 0x0000558a21e867e6 in row_purge_parse_undo_rec (thr=0x558a24285780,
|
updated_extern=0x14af1c3f0abe, undo_rec=0x558a24357470 "", node=0x558a24285960)
|
at /test/10.5_opt/storage/innobase/row/row0purge.cc:933
|
When I debugged a different occurrence of this, I noticed that tbl_len was uninitialized in the memcpy() call:
size_t db1_len, tbl1_len; |
|
table->parse_name<!trylock>(db_buf1, tbl_buf1, &db1_len, &tbl1_len);
|
|
if (*mdl) |
{
|
if (db_len == db1_len && tbl_len == tbl1_len && |
!memcmp(db_buf, db_buf1, db_len) && |
!memcmp(tbl_buf, tbl_buf1, tbl_len)) |
return table; |
|
/* The table was renamed. Release MDL for the old name and |
try to acquire MDL for the new name. */
|
mdl_context->release_lock(*mdl);
|
*mdl= nullptr;
|
}
|
|
db_len= db1_len;
|
tbl_len= tbl1_len;
|
|
memcpy(tbl_buf, tbl_buf1, tbl_len + 1); |
memcpy(db_buf, db_buf1, db_len + 1); |
goto retry; |
}
|
When the function parse_name() returns false, it would leave tbl1_len uninitialized. The following patch should help:
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
|
index e7cb05307d0..76537b2f41d 100644
|
--- a/storage/innobase/dict/dict0dict.cc
|
+++ b/storage/innobase/dict/dict0dict.cc
|
@@ -758,7 +758,10 @@ bool dict_table_t::parse_name(char (&db_name)[NAME_LEN + 1],
|
|
if (tbl_len > TEMP_FILE_PREFIX_LENGTH
|
&& !strncmp(tbl_buf, TEMP_FILE_PREFIX, TEMP_FILE_PREFIX_LENGTH))
|
+ {
|
+ *tbl_name_len= tbl_len;
|
return false;
|
+ }
|
|
if (char* is_part= strchr(tbl_buf, '#'))
|
*is_part= '\0'; |
It looks like db_len would always be initialized.
Attachments
Issue Links
- is caused by
-
MDEV-16678 Use MDL for innodb background threads instead of dict_operation_lock
- Closed