As I search to explain why MySQL is getting (too much) slower over time I collect a lot of data from many servers and then get overwhelmed trying to summarize it. Here I focus on one microbenchmark (table scan) on one server (ax162-s from Hetzner) using upstream MySQL with InnoDB and FB MyRocks.
While my primary goal is to explain the regressions in MyRocks, many of them are inherited from upstream MySQL so I must first explain them in upstream MySQL with InnoDB.
My focus is on a test that does full table scans so the ratio of (time spent in storage engine / time spent elsewhere) is much larger for that test than many of the other tests I use with sysbench.
The basic problem is that the table scan done by my tests is
- ~1.5X faster for InnoDB in MySQL 5.6.51 vs 8.0.39
- ~1.5X faster for MyRocks in FB MySQL 5.6.35 vs 8.0.32
The problem is spread over many releases, but the summary is:
- Code bloat - more instructions are executed per SQL statement
- InnoDB 8.0.28 uses ~1.3X more instructions/query than InnoDB 5.6.51
- MyRocks 8.0.32 uses ~1.3X more instructions/query than MyRocks 5.6.35
- Memory system bloat - more TLB and cache misses per SQL statement
- InnoDB 8.0.28 has a lot more cache & TLB loads & misses relative to InnoDB 5.6.51. The difference ranges from ~1.6X more cache-misses to ~1700X more iTLB-loads.
- MyRocks 8.0.32 has a lot more cache & TLB loads & misses relative to MyRocks 5.6.35. The difference ranges from ~1.6X more cache-misses to ~22X more iTLB-loads.
The benchmark
I used sysbench but not as described here. Instead I just did load, a few point-query tests and then the full scan test. Here I focus on the full scan. I ran a subset of the tests to get more results in less time.
Tests are run with 1 thread, 1 table and 50M rows. While modern MySQL suffers from new CPU overheads it also benefits from a reduction in mutex contention. Alas, I don't highlight the improvements here. And modern MySQL would be even faster if it could reduce mutex contention without increasing CPU overheads.
I ran things 3 times:
- plain - just run the test, don't use perf to get HW counters or flamegraphs
- stat - run perf stat to collect HW counters
- svg - run perf record -e cycles -F 1999 -g -p $pid to generate flame graphs
Database versions tested
For upstream MySQL I tested InnoDB from 5.6.51, 5.7.1, 5.7.3, 5.7.5, 5.7.7, 5.7.9, 5.7.10, 5.7.19, 5.7.35, 5.7.44, 8.0.0, 8.0.2, 8.0.4, 8.0.11, 8.0.13, 8.0.15, 8.0.17, 8.0.19, 8.0.20, 8.0.21, 8.0.23, 8.0.25, 8.0.27, 8.0.28, 8.0.39.
For MyRocks I tested:
- 5635.old - MyRocks 5.6.35 from Apr 7, 2021 at git hash f896415f with RocksDB 6.19.0
- 5635.new - MyRocks 5.6.35 from Oct 16, 2023 at git hash 4f3a57a1 with RocksDB 8.7.0
- 8028.old - MyRocks 8.0.28 from Aug 29 2022 at git hash a35c8dfe with RocksDB 7.5.2
- 8028.new - MyRocks 8.0.28 from Dec 2 2023 at git hash 4edf1eec with RocksDB 8.7.0
- 8032.old - MyRocks 8.0.32 from Dec 4 2023 at git hash e3a854e8 with RocksDB 8.7.0
- 8032.new - MyRocks 8.0.32 from May 29 2024 at git hash 49b37dfe with RocksDB 9.2.1
I assume that the 10-second sample is representative and that is more true for read-heavy tests and less true for write-heavy tests because write-heavy has intermittent background work (b-tree write back, LSM compaction).
- InnoDB 5.6.51 to 5.7.44
- see here. The gist has two parts -- first is the counters that might explain the regression and the second is all of the counters. Everything uses relative values.
- InnoDB 5.7.44 to 8.0.39
- see here. The gist has three parts -- first is the counters (as relative values) that might explain the regressions, the second is the absolute values for those counters and the third is all of the counters as relative values.
- MyRocks 5.6.35 to 8.0.32
- see here. The gist has two parts -- first is the counters that might explain the regression and the second is all of the counters. Everything uses relative values.
- MySQL 8.0.28 uses ~1.3 times more instructions/query than 5.6.51
- MySQL 8.0.28 has 1.6X or more cache & TLB misses and loads per query than 5.6.51. The worst ratio is for iTLB-loads (over 1700X) but I don't know whether the absolute cost from that is more significant than for the other counters.
- MyRocks 8032.new uses ~1.3X more instructions/query vs 5635.old
- MyRocks 8032.new has 1.6X or more cache & TLB misses and loads per query than 5635.old. The worst ratio is for iTLB-loads (over 22X) but I don't know whether the absolute cost from that is more significant than for the other counters.
No comments:
Post a Comment