If you expect your InnoDB data to grow, you should prepare for it by having a larger InnoDB Buffer Pool.
Where does the idea of having additional 10% extra space for the Buffer Pool come from ???
Please note the following diagram of the InnoDB Architecture
Look in the upper left hand corner where you see the buffer pool. There is a section of it called the "Insert Buffer Part". The purpose of the Insert Buffer is to populate changes to non-unique indexes into the Insert Buffer inside the system tablespace file (a.k.a. ibdata1).
From the diagram, up to 50% of the Buffer Pool can be used to manage the Insert Buffer. That being the case, it would be in your best interests to assign a lot more memory to the Buffer Pool. With a data set of 60M, 256M would be a great place to start,
You have a read/write ratio of 26:1 (based on 10869877 divided by 406010), which is 96% reads.
I think you might be suffering from what I call READ AHEAD FUTILITY. Sounds like I made that up. Well, you are right. I did. What do I mean ? According to the MySQL Documentation on the status variable Innodb_buffer_pool_read_ahead_evicted
The number of pages read into the InnoDB buffer pool by the read-ahead background thread that were subsequently evicted without having been accessed by queries.
Tons of SELECTs may read too many pages of data for the purposes of doing read ahead. Those pages may never be accessed and are simply evicted from the Buffer Pool. It's like blowing up a gigantic balloon without tying a knot. The air will eventually come out. This is true even for a full Buffer Pool. Pages are not allowed to lie dormant. They must be removed to make room for other moving parts of the InnoDB Architecture
For example, look at the diagram. Were you aware that up to 25% of the Buffer Pool is used as a scratch pad for non-unique index changes? It forms a conduit that migrates those changes into the system tablespace. This can crash InnoDB if there are heavy INSERTs and UPDATEs into tables that have many nonunique indexes. You would drop those indexes, do your INSERTs, and create the indexes again to circumvent this. I wrote about this before
Looking back at your chart, your miscellaneous is non existent. What does that indicate?
According to MySQL Documentation on Innodb_buffer_pool_pages_misc
The number of pages that are busy because they have been allocated for administrative overhead such as row locks or the adaptive hash index. This value can also be calculated as Innodb_buffer_pool_pages_total – Innodb_buffer_pool_pages_free – Innodb_buffer_pool_pages_data.
Apparently, you are not doing frequent searches for the same data. Your SELECTs must be doing
SUGGESTIONS
- You probably need to tune your queries so they do not request so much data.
- You should also avoid doing mysqldumps in the middle of the business day and this tends to load every data page and its grandmother into the Buffer Pool, only to have those pages quietly evicted. If you have to run mysqldumps, setup a MySQL Slave and o your dump from the Slave.
- You could experiment with disabling the change buffering (set innodb_change_buffering to 0).
UPDATE 2014-08-11 16:45 EDT
Please look back at the comment section. Derek Downey gave you a link to my 3 year old post. Based on the 2012 update in my post, you need to set innodb_buffer_pool_instances = 2. This will help curb mysqld's swap behavior.
From your SHOW ENGINE INNODB STATUS\G
, you have too few read and write threads
--------
FILE I/O
--------
I/O thread 0 state: waiting for completed aio requests (insert buffer thread)
I/O thread 1 state: waiting for completed aio requests (log thread)
I/O thread 2 state: waiting for completed aio requests (read thread)
I/O thread 3 state: waiting for completed aio requests (read thread)
I/O thread 4 state: waiting for completed aio requests (read thread)
I/O thread 5 state: waiting for completed aio requests (read thread)
I/O thread 6 state: waiting for completed aio requests (write thread)
I/O thread 7 state: waiting for completed aio requests (write thread)
I/O thread 8 state: waiting for completed aio requests (write thread)
I/O thread 9 state: waiting for completed aio requests (write thread)
You only have 4 read and 4 write I/O threads. Bump up your threads
innodb_read_io_threads = 16
innodb_write_io_threads = 16
If you had more that 2 cores, I would use 32 or 64. You can try 16 for now.
InnoDB is always at odds with the Query Cache. Please disable it.
query_cache_size = 0
You need a bigger log buffer for better InnoDB write performance
innodb_log_buffer_size = 256M
These are all the changes
[mysqld]
innodb_buffer_pool_instances = 2
innodb_log_buffer_size = 256M
innodb_read_io_threads = 16
innodb_write_io_threads = 16
query_cache_size = 0
Best Answer
I have written a few posts on loading index pages into the InnoDB Buffer Pool
Feb 04, 2012
: MySQL warm procedureNov 21, 2011
: Cache MySQL database in memoryHere is an example of a SELECT that will generate all possible SELECTs you would want to run to read InnoDB Index Pages:
The main idea with these posts is this: Run SELECT queries whose columns are indexed. This will force index pages into the InnoDB Buffer Pool. Unfortunately, when doing SELECTs against non-indexed columns will push out old index pages out of the InnoDB Buffer Pool. There is no perfect solution for this but to get as many InnoDB index pages as possible.
You may want to limit the tables in the WHERE clause to a specific list of tables.
UPDATE 2021-02-02 10:13 EST
I have some additional advice: If the InnoDB tables don't change all that often, you may want to take a snapshot of the InnoDB Buffer Pool. This is on by default in MySQL 8.0.
For those using MySQL 5.7 and back, please do the following:
STEP 01 : Configure MySQL to Dump the InnoDB Buffer Pool on Shutdown and Load the InnoDB Buffer Pool on Startup
Add these two lines to my.cnf under the
[mysqld]
group headerSTEP 02 : Configure Running Instance to Dump the Buffer on Shutdown
STEP 03 : Dump the Buffer Pool Now
That's it. The dump of the Buffer Pool is just a binary file with a list of tablespace IDs. The size of such a file is usually in the 100K-120K range and dumps in seconds.