InnoDB uses a lot more CPU per query in MySQL 8.0 which makes it a lot slower for low-concurrency workloads that are CPU-bound. That is offset by improvements which reduce mutex contention which means it might not be slower for high-concurrency workloads?
It would be great to get the reduction in mutex contention without the increase in CPU overhead. Alas, I don't think that is ever going to happen and this makes me sad. I doubt the performance regressions for InnoDB in MySQL 8.0 will ever be fixed and the workarounds are: MyRocks, MariaDB, MySQL 5.7 forever, Postgres.
I explained in a recent post that the problems are code bloat:
- MySQL 8.0 uses more instructions per query
- MySQL 8.0 wastes more time on cache and TLB activity per query
I have spent much time trying to find a way to undo some of the bloat and I have learned multiple times that I can't undo the damage via compile-time options, even though there are a few things that might make things 5% to 20% faster. But some of those things also make older MySQL faster.
- v1 of this post claimed that InnoDB started to use Boost in MySQL 8.0.2. That is incorrect, it started to use STL (unordered_map, array) in 8.0.2
- see Bloat in 8.0.2 from STL below for details on the impact of the diff that adds STL in 8.0.2
- 201b2b20d1
- adds the usage of STL. But it is a squash merge that combines many commits. So STL remains a suspect but I am still not certain. Regardless, the results show that things grow a lot from this commit.
- 817379925c
- the diff prior to 201b2b20d1.
- libinnobase.a grows by ~5M from 26492K to 31518K
- fil0fil.o grows by 2.6X from 548K to 1440K
A short summary of things I tried:
- MySQL 5.7 started to use -fPIC while compiling the server. That was not used in 5.6. Alas, switching from -fPIC to -fpic doesn't have a big impact.
- Avoiding -fPIC via -DDISABLE_SHARED (in the cases where that doesn't break the build) also doesn't have a big impact.
- Compiling with -DWITH_LTO=ON makes things ~5% faster
- PGO can be a big deal, but needs more evaluation to understand whether I need PGO build per workload which is costly to maintain
- lines of code (yes, this is far from perfect)
- size of libinnobase.a for MySQL compiled with CMAKE_BUILD_TYPE=Release
- size of object files for MySQL compiled with CMAKE_BUILD_TYPE=Release
This comment has been removed by the author.
ReplyDeleteAt this point it is more correlation than causation. I know that the usage of STL arrives in fil0fil.cc in 8.0.2. Will update the blog posts after I attempt to compile it at that commit and the prior commit.
Delete> InnoDB started to use STL in MySQL 8.0.2-dmr and that is definitely part of the code-bloat problem.
ReplyDeleteHmm I realize how could that be a problem. Templatized code would lead to code bloat. So you may ignore my previous and this comment.
I wouldn't over-index on code bloat for performance: while you typically won't ever get the size of software back to where is was (very hard to undo adding features), you can get back performance. For example, MongoDB gradually got slower from 4.4 version to 7.3, as new features and capabilities slowed hot code paths. However in 8.0, we addressed most of those regressions and improved performance for some important workloads to heights not seen before. As you can slow performance through hundreds of tiny regressions, you can also improve it. Additionally, you need to shift from just fighting regressions to looking holistically at areas you can claw back perf.
ReplyDeleteThe focus on code bloat is motivated by results (linked in this blog post) showing that iTLB and icache activity is greatly increased over time.
DeleteWhile I am all for clawing back performance, I don't have to capacity to do that on my own. And if it is done without cooperation from upstream, then it will all get undone.
Interesting you are mentioning fil0fil.cc, I am spending a lot of time in there for MySQL Startup with many tables. From what I understand, the new data dictionary in 8.0 generated part of that code bloat, unclear if this impacted runtime.
ReplyDeletehttps://jfg-mysql.blogspot.com/2024/09/blog-post.html
Thanks for making MySQL better.
DeleteIt is very expensive to map regressions back to diffs so long after the fact. Anything older than MySQL 8.0.24 needs patches to compile on modern Ubuntu and while I already have the patches archived for the point releases, those patches are usually not sufficient for the diffs in between point releases.