[MDEV-17492] Benchmark AHI to find cases where it's useful Created: 2018-10-18 Updated: 2023-10-12 Resolved: 2019-09-03 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Storage Engine - InnoDB |
| Fix Version/s: | N/A |
| Type: | Task | Priority: | Critical |
| Reporter: | Eugene Kosov (Inactive) | Assignee: | Axel Schwenke |
| Resolution: | Fixed | Votes: | 1 |
| Labels: | None | ||
| Attachments: |
|
||||||||||||||||
| Issue Links: |
|
||||||||||||||||
| Description |
|
AHI is probably a subject to removal. It's clear that managing a hash table costs some performance but it's not clear where it could be beneficial. One example of harm was found in https://jira.mariadb.org/browse/MDEV-16796 where TRUNCATE was slowed down. axel please find cases where AHI improves server speed. Then we can measure whether it's needed at all or not. |
| Comments |
| Comment by Marko Mäkelä [ 2018-10-20 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
For the record, there was this change in MySQL 5.7:
A more appropriate fix (which I was not allowed to consider at that time) would have been to investigate why the sorted inserts (into a table that did not have any secondary indexes) end up performing AHI lookups at all, and to fix that. InnoDB should remember and take advantage of the last insert position, both in the cursor (table handle) and in each index page. It could be useful to test the described scenario (unfortunately no more details are available) with both values of innodb_adaptive_hash_index. It could have been a BIGINT UNSIGNED key (8 bytes). Without the above patch in 5.7 (that code was removed by me earlier during the 5.7 development), the AHI would not be used much, or at all. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2019-06-25 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
wlad is says that on Windows, testing with 16 to 64 concurrent users, with the thread pool enabled, the AHI is not helping much. This seems to be in line with a benchmark by Mark Callaghan from 5 years ago. Because of the above mentioned MySQL 5.7 change, I tried a similar INSERT benchmark:
invoked like this:
There was some variation in the execution times, but the adaptive hash index was not systematically faster. I also rebuilt the server without the adaptive hash index altogether:
The execution time remained similar. I believe that corruption reports, such as Theoretically, disabling the adaptive hash index could cause some loss of performance in a special case. Here is some analysis. But is this worth the added code complexity and hard-to-chase bugs? | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2019-06-25 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
For the record: Traditionally, the adaptive hash index was always enabled in InnoDB. The option innodb_adaptive_hash_index for disabling it was introduced in the MySQL 5.1 series. Later, it became possible to change it with SET GLOBAL while the server is running. I would suggest to disable the adaptive hash index by default. I would also deprecate&ignore the parameter and remove the code in a future version. Perhaps we could change the build option to default to WITH_INNODB_AHI=OFF in 10.5 already? | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Axel Schwenke [ 2019-07-02 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I've run a sysbench OLTP benchmark on 10.4.6 with 3 different AHI configurations: 01 ... AH enabled, 16 partitions
-> rather small advantage with the AHI enabled
-> undecided
-> visible improvement from disabling the AHI, partitioned AHI behaves better. Very probably a locking issue.
-> same conclusion as for write-only workload
-> much smaller effect as for the other update-only workload. This is probably due to the nature of those updates. update-index just increments an INT column where update-non-index overwrites a CHAR(120) column. This second UPDATE moves much more data around which kind of masks most effects from the AHI. I'm going to do more tests with TPCC. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Manjot Singh (Inactive) [ 2019-07-17 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Just a note that unless you have 32+ cores, many threads, and many tables, in my experience 16 is high. I have rarely seen more than 4 partitions in production use. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Axel Schwenke [ 2019-07-17 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
manjot - thanks for your feedback. As a matter of fact I have done systematic testing how the number of AHI partitions affects performance. I couldn't find any drawback from having many AHI partitions (unlike having many buffer pool instances). It is true that going from say 8 AHI partitions to 16 didn't have much positive effect on performance. But I've never seen any negative effect as well. I have some more results in the pipeline. From this it looks that the main problem with the AHI is the btr_search_latch that protects shared AHI data structures. This latch becomes hot when the workload contains writes. Partitioning the AHI can help to reduce (but not remove) contention on this latch. Conclusion: unless your workload is strictly read-only, the AHI should be partitioned. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2019-07-19 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
The adaptive hash index is disabled for temporary tables in MariaDB Server 10.2+. Starting with MariaDB Server 10.2, the btr_search_latch has been partitioned into btr_search_latches[] of innodb_adaptive_hash_index_parts (btr_ahi_parts) elements, default 8, ranging from 1 to 512. The adaptive hash index itself is still global; only the latch has been partitioned by essentially index_id (which is still global; in MySQL 5.7, on my suggestion, some previsions were implemented to allow each tablespace to have their own domain of index_id):
So, all requests for a particular index will always use the same btr_search_latches[] element. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Axel Schwenke [ 2019-08-27 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I tested now a lot more workloads to find cases where the AHI increases performance. The biggest improvements could be found for strictly read-only workloads. But even then it depends a lot of the specific queries. From the sysbench OLTP query mix only the point-select workload benefits from the AHI. Depending on thread count I see up to 7% improvement when the AHI is enabled. None of the range queries profits from the AHI. Details are in attached spreadsheet AHI_point-select.ods I also tested a modified read-only workload where rows are accessed via secondary key. Now point selects don't benefit from the AHI. Range queries benefit from the AHI at low thread counts but are considerably slower at thread counts higher than 8. The reason is the btr_search_latch that becomes extremely busy. This can be seen in detail in attached spreadsheet AHI_secondary_range.ods | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Axel Schwenke [ 2019-08-27 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Another tested workload is TPC-C, using the Lua implementation for sysbench 1.0. Since this workload includes heavy writes (about 50% of the queries are writes) the btr_search_latch becomes the bottleneck. Even partitioning the AHI does not help with that. Here are the TPC-C queries per scond for different thread counts using AHI with 16/1 partitions vs. no AHI:
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Axel Schwenke [ 2019-09-03 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Now here is a final set of results, testing a mixture of point-selects (which benefit from AHI) and writes (which lead to contention of the btr_search_latch). The dataset and queries are from sysbench OLTP, the writes are updates on indexed/non-indexed columns. I vary the percentage of writes between 1% and 20%. For details, look at the attached spread sheet AHI_vs_writes.ods Some observations:
I'm trying to draw a conclusion: the AHI has the potential to increase performance by up to 10% - but only with perfectly matching workload. Further more this workload must be (almost) read-only. Even 2% writes is enough to cancel any positive effect of the AHI. I'd say it's OK to remove the AHI from InnoDB. It's causing more trouble than it's worth. |