[MDEV-15020] Server hangs due to InnoDB persistent statistics or innodb_stats_auto_recalc Created: 2018-01-22 Updated: 2023-08-22 Resolved: 2021-08-31 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Optimizer, Storage Engine - InnoDB |
| Affects Version/s: | None |
| Fix Version/s: | 10.6.5 |
| Type: | Bug | Priority: | Critical |
| Reporter: | Marko Mäkelä | Assignee: | Marko Mäkelä |
| Resolution: | Fixed | Votes: | 6 |
| Labels: | hang, performance, replication, statistics, upstream | ||
| Issue Links: |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description |
|
InnoDB in MySQL 5.6 introduced persistent statistics, to help the optimizer choose query plans. The statistics are stored in two tables: mysql.innodb_index_stats and mysql.innodb_table_stats, using the InnoDB-internal SQL parser while holding an exclusive lock on the InnoDB data dictionary cache. This architecture involves a number of workarounds to locking problems. It could also break replication when users modify the statistics tables directly from SQL, because the internal transactions to modify the statistics tables are not replicated. The natural place to store the statistics is within the data file. If there is a real need to tweak the statistics other than by running ANALYZE TABLE, then an external tool could be written for that. |
| Comments |
| Comment by Marko Mäkelä [ 2018-01-22 ] | |||||||
|
Should we decide to keep using transactions for updating the statistics, there are some work-in-progress patches attached to The .ibd file format change should also involve making the .ibd files self-contained with respect to metadata that is not stored in the SQL layer (a prerequisite for MDEV-11655). That is, we must store inside the .ibd file the root page number of each secondary index (and the location of the fulltext index files). | |||||||
| Comment by Marko Mäkelä [ 2018-10-19 ] | |||||||
|
| |||||||
| Comment by Marko Mäkelä [ 2020-01-28 ] | |||||||
|
MySQL Bug #83079, which was reported by the former InnoDB QA engineer, indicates that there could be an actual locking problem with the InnoDB persistent statistics. It seems that the report was mistakenly closed as a duplicate of the bug that was introduced by SX-locks in MySQL 5.7 (which we fixed in The original report states:
If it were a genuine duplicate of the SX-lock related bugs, then the server should always hang, and it should not affect MySQL version 5.6. Note: Already MySQL 5.6 enabled both innodb_stats_persistent and innodb_stats_auto_recalc by default. | |||||||
| Comment by Marko Mäkelä [ 2020-04-22 ] | |||||||
|
A reasonable course of action, which would address the problems related to the use of the InnoDB internal SQL parser, would be to rewrite the interface to the persistent tables that store the InnoDB statistics. We should try to update the code so that the handler API (or even the MariaDB SQL parser) will be used for accessing the tables. This would also allow the statistics tables to be created in any storage engine. | |||||||
| Comment by Marko Mäkelä [ 2020-05-29 ] | |||||||
|
psergey, can you please implement an interface that InnoDB can invoke to read or write mysql.innodb_table_stats and mysql.innodb_index_stats? We would need that so that the problematic interface to the InnoDB internal SQL parser can be removed. Such a change should be technically possible in GA releases, because we would not be changing any file format. | |||||||
| Comment by Sergei Petrunia [ 2020-07-17 ] | |||||||
What exactly is wrong with class handler? It probably has a lot of extra stuff. Do I factor index navigation functions out of class handler? I think I don't understand the request. We should schedule a meeting to discuss it. | |||||||
| Comment by Marko Mäkelä [ 2020-09-17 ] | |||||||
|
psergey, I need some sample code that would perform the equivalent of SELECT, INSERT, UPDATE, DELETE on those two tables, say, in the beginning of the ha_innobase::write_row() function. (For obvious reasons, that code should be skipped when writing to either of the tables.) In other words, the above requested code patch to ha_innobase::write_row() would implement a trigger that would be executed on any INSERT into any InnoDB table. Once I have such proof of concept code, I can adapt and move it to the appropriate place in the InnoDB code base. | |||||||
| Comment by Jan Lindström (Inactive) [ 2020-09-18 ] | |||||||
|
marko If transactions (InnoDB) are used this should be designed so that locking of rows/columns do not increase lock waits especially on Galera multi-master case. We could have multiple concurrent Galera appliers executing changes to same table possible causing changes to persistent statistics for same table or same index. Consider for a example two transactions deleting huge amount of rows from a table so that these deletes do not conflict each other. However, their change on table/index statistics could access same row causing a lock wait. Similarly, it is not desired feature that local table/index statistic change is rolled-back because it is holding locks that conflict with applier thread changes (brute force). For Galera it would be better if only one master will update table/index statistics and update on other nodes is handled by Galera replication, this naturally requires these tables to use InnoDB storage engine and some code changes so that applier nodes do not update persistent statistics during normal table operations. | |||||||
| Comment by Marko Mäkelä [ 2020-09-23 ] | |||||||
|
jplindst, with this change, the tables could be created in any storage engine (such as Aria or MyISAM). I suppose that moving to other storage engines (which might use table-level locking) might increase the possibility of lock waits. If I remember correctly, in the existing implementation there are some tweaks for disabling Galera replication. The final code can surely be reviewed by the Galera team. | |||||||
| Comment by Sergei Petrunia [ 2021-02-16 ] | |||||||
Use cases to handleLet's list the usage scenarios of stat tables:
How EITS does it
Use1: How EITS reads the statisticsTODO. Use2: How EITS updates statisticsUse2 is done as follows: 1. Statistics is collected.
note that the above is run while holding a lock on the table being analyzed. Updating statistics inside InnoDB.Currently InnoDB is using its own internal SQL interpreter to perform statistics updates. The new implementation is expected to use SQL-level objects for doing this. Like get an MDL lock, call open_table (or similar) to get TABLE object and a ha_innobase object. Is this right? | |||||||
| Comment by Marko Mäkelä [ 2021-08-31 ] | |||||||
|
Related to | |||||||
| Comment by Marko Mäkelä [ 2022-04-08 ] | |||||||
|
Side note: I see that MySQL Bug #83079 was incorrectly closed as fixed in MySQL 5.7.23, most likely mistaking it to be a duplicate of a regression that was introduced in MySQL 5.7 (the fix of Oracle Bug #29390736 was the basis of the MariaDB fix of The root cause of these hangs is older (present since the introduction of InnoDB persistent statistics in MySQL 5.6 and MariaDB 10.0). They were fixed in MariaDB 10.6 by | |||||||
| Comment by Marko Mäkelä [ 2022-10-26 ] | |||||||
|
Some hangs related to all types of InnoDB statistics (including the ‘transient’ ones that STATS_PERSISTENT replaced) were possible due to |