You can kind of do this from MySQL 5.6 and onwards using information_schema
. I have an example of finding the ideal buffer pool size on my blog here: http://www.tocker.ca/2013/05/31/estimating-mysqls-working-set-with-information_schema.html
The caveat is that you may need to either restart or lower the buffer pool size first. Inactive pages will just stay in memory if there is no need to make free space - which could skew your result on a server that's been running for a while, yet has plenty of memory.
I addressed this issue 1.5 years ago : innodb_file_format Barracuda
Just from reading the documentation, I was able to figure out mathematically that the smaller you make the key_block_size, the less extra space you need to add to the InnoDB Buffer Pool.
Here is the chart I made up in that earlier post
- You have a DB Server with a 8G Buffer Pool
- You ran compression with
key_block_size=8
8
is 50.00%
of 16
50.00%
of 8G
is 4G
- raise
innodb_buffer_pool_size
to 12G
(8G
+ 4G
)
- You ran compression with
key_block_size=4
4
is 25.00%
of 16
25.00%
of 8G
is 2G
- raise
innodb_buffer_pool_size
to 10G
(8G
+ 2G
)
- You ran compression with
key_block_size=2
2
is 12.50%
of 16
12.50%
of 8G
is 1G
- raise
innodb_buffer_pool_size
to 9G
(8G
+ 1G
)
- You ran compression with
key_block_size=1
1
is 06.25%
of 16
06.25%
of 8G
is 0.5G
(512M
)
- raise
innodb_buffer_pool_size
to 8704M
(8G
(8192M
) + 512M
)
Given the following
- BPS = Buffer Pool Size
- KBS = key_block_size
- BPSFC = Buffer Pool Size For Compression
The ideal size for the Buffer Pool in a perfect world would be
BPSFC = BPS * (16 + KBS) / 16
From this formula, less is more. The smaller KBS is, the smaller the increase in BPS needs to be. Additoinally, it would appear that the CPU would worker a little harder in response to tighter compression. How ?
- For KBS=8, evicting one uncompressed page leaves room for 02 compressed pages
- For KBS=4, evicting one uncompressed page leaves room for 04 compressed pages
- For KBS=2, evicting one uncompressed page leaves room for 08 compressed pages
- For KBS=1, evicting one uncompressed page leaves room for 16 compressed pages
- For KBS=X, evicting one uncompressed page leaves room for 16/X compressed pages
I can see the CPU working harder to introduce more compressed pages with tighter compression. This could result in evicting LRU compressed pages more often.
If this is the case, it would appear that making the BPS even bigger than the suggested values from these formulas would give CPU some relief as well as reduce the rate of the eviction of compressed pages from the Buffer Pool.
EXAMPLE: From my first chart, an 8GB Buffer Pool would need to be 12GB for key_block_size=8. Making the Buffer Pool larger than 12GB would relieve the CPU of a lot of this heavy lifting (in the form of evicting uncompressed pages). Perhaps doubling the Buffer Pool Size may be need to be explored.
As for your question
will enabling compression on tables without changing the buffer pool size hurt or benefit the buffer pool hit rate?
I would say it would hurt, no such much because of the hit rate against the compressed pages, but because of the additional house cleaning in terms of the management of uncompressed pages and the CPU usage required for it. This would lower InnoDB performance no matter how much tuning the rest of the Storage Engine gets.
Best Answer
Flushing and evicting are entirely different.
https://dev.mysql.com/doc/refman/5.5/en/glossary.html#glos_flush
MySQL will flush dirty pages in accordance with innodb_max_dirty_pages_pct. The default database page size default in InnoDB is 16KB and the maximum setting for innodb_max_dirty_pages_pct is 99 so there isn't a whole lot of tolerance for the build up of dirty pages (although, as you know from the link you cite the actual flushing schedule calculation is a bit more complicated).
After they are flushed they will then be evicted when they are the LRU.
The documentation states, "When room is needed to add a new page to the buffer pool". So I would imagine it waits until it is pretty close to full. Regarding the characteristics of LRU in general, you can read up on that elsewhere as it is not MySQL specific. MySQL Does however use the "Midpoint insertion strategy" which makes things not a true LRU in order to deprioritize superfluous pages.
https://dev.mysql.com/doc/refman/5.5/en/glossary.html#glos_midpoint_insertion_strategy