Fix crashing innodb due to innobase_share usage_count not being reduced for temp table accesses #5212
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
The MySQL engine is designed with the assumption that accesses to temporary tables will only ever occur from the thread that created the temporary table. Cross thread accesses of temporary tables are not expected and are therefore not designed for. However, if the information schema is queried for details about a temporary table, then the temporary table gets accessed from a thread that is different from the thread that created the temporary table, breaking the design assumption.
When this cross-thread accesss of a temporary table happens for engines that use the InnoDB storage engine, the INNOBASE_SHARE use_count for the table gets incremented, but never gets decremented when the none-owning thread completes. In certain situations, this can lead to a crash of the database engine, when invariants in the function innobase_build_index_translation fail on assertion. For example we found a use case that cause MySQL
to crash with the assertion failure below:
The above issue is fixed by allowing the use_count for an INNODB_SHARE object of a temporary table to be decremented during
query cleanup, whenever a temporary table is accessed from a none-owning thread. Care is taken to make sure that the use_count decrement is done inside of the a critical region protected by the innobase_share_mutex mutex.
Testing
Environment Preparation
Run the following commands in MySQL 5.7.x
Reproduction of conditions that would cause a crash due to cross-thread temporary table access
Session 1:
In one terminal session, run the below mysqlslap command to send 2 ALTER statements one, after another in a continuous loop to the MySQL 5.7.x instance:
Session 2:
Open another terminal session, connect to the MySQL instance and:
Here are the id's in my case:
Calculate Hex of both processlist_id and pid
Connect to MySQL and run the following query such that table_name is #sql-<hex(pid)_hex(processlist_id); Below is the example in my case.
Without the fix, the first session will exit as the server was crashed, but with the fix, the crash does not occur.
All new code of the whole pull request, including one or several files that are either new files or modified ones, are contributed under the BSD-new license. I am contributing on behalf of my employer Amazon Web Services, Inc.