Bug #96472 | Memory leak after 'innodb.alter_crash' | ||
---|---|---|---|
Submitted: | 8 Aug 2019 13:05 | Modified: | 8 Aug 2019 16:24 |
Reporter: | Yura Sorokin (OCA) | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | MySQL Server: InnoDB storage engine | Severity: | S7 (Test Cases) |
Version: | 5.7.27 | OS: | Any |
Assigned to: | CPU Architecture: | Any |
[8 Aug 2019 13:05]
Yura Sorokin
[8 Aug 2019 16:24]
MySQL Verification Team
Thank you for the bug report.
[12 Aug 2019 13:19]
Erlend Dahl
Posted by developer: Repeatable with clang 7 on recent 5.7. Not repeatable on 8.0.
[14 Jan 2020 13:16]
Marcelo Altmann
If online alter fails to allocate undo log, heap memory allocated to the index object won't be freed. This can be simulated by using debug point 'ib_create_table_fail_too_many_trx' prior to an alter table. To fix it, prior to set index pointer to null at row_merge_create_index, we should call dict_mem_index_free to correctly free memory objects allocated by the index.
[14 Jan 2020 13:17]
Marcelo Altmann
Suggested fix: diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 5d0919a..c626c50 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -4209,6 +4209,7 @@ row_merge_create_index( this index, to ensure read consistency. */ ut_ad(index->trx_id == trx->id); } else { + dict_mem_index_free(index); index = NULL; }
[17 Jan 2020 11:40]
Marcelo Altmann
(*) I confirm the code being submitted is offered under the terms of the OCA, and that I am authorized to contribute it.
[8 Apr 2020 13:49]
Marcelo Altmann
an enhanced version of the fix to avoid double free: diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 5d0919a322b..29f2ea993f1 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -4209,6 +4209,11 @@ row_merge_create_index( this index, to ensure read consistency. */ ut_ad(index->trx_id == trx->id); } else { + /* In case we were unable to assign an undo record for this index + we won't free index memory object */ + if (err == DB_TOO_MANY_CONCURRENT_TRXS) { + dict_mem_index_free(index); + } index = NULL; } (*) I confirm the code being submitted is offered under the terms of the OCA, and that I am authorized to contribute it.