Bug #117691 | MySQL 8.4 and 9 are not taking advantage of the Linux Page Cache (contrarily to 8.0). | ||
---|---|---|---|
Submitted: | 12 Mar 19:12 | Modified: | 26 Mar 14:41 |
Reporter: | Jean-François Gagné | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | MySQL Server: InnoDB storage engine | Severity: | S2 (Serious) |
Version: | 8.4.0, 8.4.4, 9.2.0 | OS: | Linux |
Assigned to: | CPU Architecture: | Any | |
Tags: | regression |
[12 Mar 19:12]
Jean-François Gagné
[14 Mar 7:45]
MySQL Verification Team
Default changed: https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_flush_method https://dev.mysql.com/doc/refman/8.4/en/innodb-parameters.html#sysvar_innodb_flush_method
[24 Mar 12:38]
Jean-François Gagné
This bug has been in Analyzing since Thu, Mar 13. Anything I can help you with for verifying if ?
[24 Mar 13:08]
MySQL Verification Team
Hello Jean-François, My apologies, was caught up in other bugs and I missed this. I'll verify this by tomorrow(will request you if I have any issues while reproducing). Thank you. Also, my senior colleague Shane mentioned to me that defaults have changed from 8.0 to 8.4/9.2 and that might be the reason here(will check while verifying): Default changed: https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_flush_method https://dev.mysql.com/doc/refman/8.4/en/innodb-parameters.html#sysvar_innodb_flush_method regards, Umesh
[25 Mar 15:09]
MySQL Verification Team
Hello Jean-François, My apologies for the delay on this(Was occupied in some other bugs, later needed compute with sudo) Verified as described. Later tonight will check 8.4.4 with innodb_flush_method=fsync and update my findings. regards, Umesh
[25 Mar 15:50]
MySQL Verification Team
Hello Jean-François, I checked 8.4.4 with --innodb-flush-method=fsync and conclusion from my tests i.e. 8.4.4 with --innodb-flush-method=fsync is same as that of 8.0.41 i.e When the table is in cache, both 8.4 and 8.0 have fast IOs. Could you please check this from your end as well? Thank you. Joining the test results shortly. Sincerely, Umesh
[25 Mar 15:56]
MySQL Verification Team
8.0.41, 8.4.4 test results
Attachment: 117691.results (application/octet-stream, text), 11.17 KiB.
[26 Mar 14:41]
Jean-François Gagné
Thanks for verifying this bug Umesh. I confirm that with innodb-flush-method=fsync, I get the cache effect back with 8.4, details below. So as I suspected, this was caused by the new defaults in 8.4, and you and Shane narrowed this down to innodb-flush-method, thanks again for investigating that. Now I think the question is: Is this intended or not ? The new default of innodb_flush_method=O_DIRECT might be better for flushing (see below quote from LeFred post about new default [1]), but this coming with the drawback of not caching reads might impact a lot of MySQL installations. [1]: https://lefred.be/content/mysql-8-4-lts-new-production-ready-defaults-for-innodb/ > When supported, O_DIRECT has always been the preferred value and we recommended using it to bypass the filesystem cache to flush InnoDB changes to disk (for data files and log files). Note that not caching reads with innodb-flush-method=O_DIRECT might be "working as intended", see below quotes from the documentation [2], the important part being "InnoDB uses O_DIRECT to open the data files". But it is unclear from the documentation that this also applies for reading datafiles, and it is probably something that needs clarification. [2]: https://dev.mysql.com/doc/refman/8.4/en/innodb-parameters.html#sysvar_innodb_flush_method > O_DIRECT or 4: InnoDB uses O_DIRECT (or directio() on Solaris) to open the data files, and uses fsync() to flush both the data and log files. This option is available on some GNU/Linux versions, FreeBSD, and Solaris. Penalizing reads for making writes faster is not a tradeoff that I would have imposed to all MySQL users (maybe it was a blindspot when changing the default, or maybe it was actually intended). So maybe the default for innodb-flush-method should be rethought, even thought changing it is not a small thing as 8.4 is not supposed to get incompatible changes. Also, unclear if it makes sense to have O_DIRECT for flushing and not have it for reading (or also have a parameter for reading), I will let you and other Oracle Engineers think about this. In all cases, the impact remains: when upgrading from 8.0 to 8.4, someone who was leveraging the Linux Page Cache in 8.0 (not allocating RAM to the Buffer Pool) will see degraded performances after the upgrade, and either has to set innodb-flush-method to fsync or tune the Buffer Pool. There might be another more convoluted impact when running MySQL in containers. With a container with little RAM on a host with a lot of RAM, a data file might not fit in the memory allocated to the container, but might fit in the RAM of the host. I do not know enough about how Linux manages the Page Cache with containers to predict the impact, and I do not have time to test. ################### # With 8.4 default. ./use -N <<< "show global variables like 'innodb_flush_method'" innodb_flush_method O_DIRECT [...same results as before...] ################### # With 8.0 default. echo "innodb-flush-method=fsync" >> my.sandbox.cnf ./stop; ./start [...Generating load and Monitoring IOs (see How to repeat)...] # Making sure nothing is in the page cache. sudo bash -c "echo 3 > /proc/sys/vm/drop_caches" # Without a cache. Wed Mar 26 14:17:03 UTC 2025 11 8023.97 729.451 Wed Mar 26 14:17:05 UTC 2025 15 11568.4 771.23 Wed Mar 26 14:17:06 UTC 2025 12 8487.53 707.294 # Loading the table in cache. Wed Mar 26 14:17:43 UTC 2025 4.63GiB 0:00:36 [ 128MiB/s] # With innodb-flush-method=fsync, we see the cache effect. Wed Mar 26 14:18:28 UTC 2025 14 169.589 12.1135 Wed Mar 26 14:18:29 UTC 2025 14 158.048 11.2891 Wed Mar 26 14:18:30 UTC 2025 15 153.433 10.2289
[28 Mar 7:44]
MySQL Verification Team
Hello Jean-François, Thank you for verifying and confirming that with innodb-flush-method=fsync you get the cache effect back with 8.4. Sincerely, Umesh