Optimize MySql On Low Memory Servers
Cloud computing makes it very affordable to get your own private virtual server on the Internet. Digital Ocean offers an entry level droplet for USD$5 per month, and Amazon.com has a micro instance tier on the EC2 platform that is free for the first year. These instances are rather useful if you want to test out some new technologies (multi source replication?) or put together a proof of concept.
However, these servers comes with a very low amount of RAM, usually between half GB to one GB. These days, it is common to see production grade database servers with literally 100x that amount. 100MB of memory usage makes no significant difference to one of these servers, but definitely noticible to a 512MB virtual machine.
I recently encountered an issue where MySQL would not start up. The interesting part was the lack of any errors from MySQL:
140521 08:26:40 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql 140521 08:26:41 mysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended
Yet if we check our kernel messages, we clearly see an out of memory event:
May 21 08:26:41 aes2 kernel: Out of memory: Kill process 24774 (mysqld) score 842 or sacrifice child May 21 08:26:41 aes2 kernel: Killed process 24774, UID 0, (mysqld) total-vm:549180kB, anon-rss:437324kB, file-rss:44kB
Or in other cases, we see errors about InnoDB not being able to allocate buffer pool:
2014-05-21 08:33:23 25042 [Note] InnoDB: Initializing buffer pool, size = 128.0M InnoDB: mmap(137363456 bytes) failed; errno 12 2014-05-21 08:33:23 25042 [ERROR] InnoDB: Cannot allocate memory for the buffer pool
But we do have RAM available:
[[email protected] ~]# free -m total used free shared buffers cached Mem: 490 86 403 0 7 32 -/+ buffers/cache: 46 443 Swap: 0 0 0 [[email protected] ~]#
Well, the issue here is Performance Schema, and not making it obvious.
When starting up, it allocates all the RAM it needs. By default, it will use around 400MB of RAM, which isn't noticible with a database server with 64GB of RAM, but it is quite significant for a small virtual machine. If you add in the default InnoDB buffer pool setting of 128MB, you're well over your 512MB RAM allotment and that doesn't include anything from the operating system.
We can easily disable Performance Schema by putting this under the [mysqld] section configuration:
performance_schema = off
It is possible to customize which monitors are used in Performance Schema to reduce the memory footprint. But with limited RAM, it will probably be much better to use all of that for other things, like the buffer pool.
There is a MySQL bug report that provides a pretty decent description about Performance Schema: http://bugs.mysql.com/bug.php?id=68514
And there is a feature request to print out the amount of memory used for Performance Schema, that would have made this whole problem more visable: http://bugs.mysql.com/bug.php?id=69665
Comments area, use one of your social accounts to log-in and post a comment.
Responses to the post
- MySql: How to build a performant search engine
- Install HHVM + Nginx on Ubuntu 14.04
- PHP: Storing arrays in database
- PHP Recursive Backup of MySql Database
- Million of visitors per day with a super cheap php mysql server using nginx and varnish
- Memcache: Installation and Usage on Ubuntu 12.10
- Mysql:Guide To The MySql Query Cache
- MySql: Setup Master Slave Replication in Ubuntu