t2.nano で MySQL5.6 を動かすために

結論から

MySQL5.6.6 以降でパフォーマンススキーマがデフォで有効になっており、これが大量にメモリを喰うので、t2.nano では起動すらできない。無効にすれば起動可能。

パフォーマンススキーマを利用したい場合は、table_definition_cache とそれに付随する table_open_cache の設定を見直せば起動可能

※ 大したデータ量入れてないので、どこまで使える物なのかは未検証です…

本文

最近、ちょっとした検証等で t2.nano インスタンスをよく使いますが、MySQL5.6 をデフォルトの設定のまま動かそうとしたら

[Note] InnoDB: Initializing buffer pool, size = 128.0M
InnoDB: mmap(137363456 bytes) failed; errno 12
[ERROR] InnoDB: Cannot allocate memory for the buffer pool

こんな感じで「メモリ足りねー」と文句を言って起動してくれませんでした。

ちなみに MySQL5.5 はデフォルト設定でもちゃんと起動はしてくれます。

$ ps aux | grep ^mysql
mysql 3074 0.0 8.8 540796 44512 pts/0 Sl 02:44 0:00 /usr/libexec/mysql55/mysqld (snip)

なんでだろー?と思ってたら、MySQL5.6 デフォルトで起動直後、実メモリ約 460MB も使ってる!

$ ps aux | grep ^mysql
mysql 3026 3.8 45.0 1065144 459540 pts/0 Sl 03:06 0:00 /usr/libexec/mysql56/mysqld (snip)

そりゃ nano じゃ起動しないですわ…

5.5 と 5.6 でメモリ利用量 10 倍違うってどういうことなの…と思いつつ調べてみたら、MySQL 5.6.6 からパフォーマンススキーマがデフォルトで有効になったらしい。
あーなるほど。
https://dev.mysql.com/doc/refman/5.6/ja/performance-schema-quick-start.html

performance_schema = off

を設定すれば 5.5 レベルのメモリ使用量に落ち着いて、nano でもちゃんと起動できるようになります。

$ ps aux | grep ^mysql
mysql 24097 0.5 9.0 651256 45456 pts/0 Sl 03:35 0:00 /usr/libexec/mysql56/mysqld (snip)

もちろん、performance schema を利用できないというデメリットはありますが、まぁ nano や micro で起動するような環境で、そこまでは要らないだろ…と。

どうしてもパフォーマンススキーマ使いたい場合

MySQL5.6がメモリを沢山お召し上がりになる件 – メモOFF

こちらの記事で触れられている table_definition_cache と それに付随する table_open_cache の設定見直しが有効です。

デフォルトだとこんな感じ。

mysql> show variables LIKE 'table\_%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| table_definition_cache     | 1400  |
| table_open_cache           | 2000  |
| table_open_cache_instances | 1     |
+----------------------------+-------+
3 rows in set (0.00 sec)

table_definition_cache のデフォルト値は「400 + (table_open_cache / 2)」となるので、
table_open_cache を小さめに設定すれば table_definition_cache の値もそれに準じた値に変わります。
https://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_table_definition_cache

table_open_cache = 400 を my.cnf に設定して mysql 再起動するとこうなる。

mysql> show variables LIKE 'table\_%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| table_definition_cache     | 600   |
| table_open_cache           | 400   |
| table_open_cache_instances | 1     |
+----------------------------+-------+
3 rows in set (0.00 sec)

この時のメモリ利用量はこれ。

$ ps aux | grep ^mysql
mysql 25635 0.4 24.0 727040 121080 pts/0 Sl 04:58 0:00 /usr/libexec/mysql56/mysqld (snip)

これぐらいなら nano でも起動はできます。