DTIの仮想専用サーバServersMan@VPSを借りてみました。
Entryプランはメモリが256MBでまあ足りるだろうと思っていたのですが、ServersMan@VPSではOpenVZという仮想化ソフトウェアを使っていて、なんとスワップの利用が禁止されているのだそうです。つまりなにがなんでも総メモリ使用量を256MB以下に抑える必要があります。ちょっと難しそうです。
とりあえずMySQL 5.1.45をインストールして、すべてデフォルトで起動するとこんな感じです。
# free -m total used free shared buffers cached Mem: 256 23 232 0 0 0 -/+ buffers/cache: 23 232 Swap: 0 0 0 # service mysql start Starting MySQL. SUCCESS! # free -m total used free shared buffers cached Mem: 256 142 113 0 0 0 -/+ buffers/cache: 142 113 Swap: 0 0 0 (# top) PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 11692 mysql 20 0 124m 13m 3216 S 0.0 5.2 0:00.02 mysqld
このように、MySQLにメモリを半分ほど持っていかれてしまいます。これは厳しい。
InnoDB Pluginを有効にすると事態はさらに悪化します。InnoDB Pluginではinnodb_buffer_pool_sizeのデフォルト値が128MBになっているのでそのままでは起動すらできず、設定を絞ってみても…
[mysqld] ignore-builtin-innodb plugin-load = innodb=ha_innodb_plugin.so;innodb_trx=ha_innodb_plugin.so;innodb_l ocks=ha_innodb_plugin.so;innodb_lock_waits=ha_innodb_plugin.so;innodb_cmp=ha_inn odb_plugin.so;innodb_cmp_reset=ha_innodb_plugin.so;innodb_cmpmem=ha_innodb_plugi n.so;innodb_cmpmem_reset=ha_innodb_plugin.so (plugin-loadは実際には1行) innodb_buffer_pool_size = 8M
# free -m total used free shared buffers cached Mem: 256 189 66 0 0 0 -/+ buffers/cache: 189 66 Swap: 0 0 0 (# top) PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 7457 mysql 20 0 172m 20m 3200 S 0.0 8.1 0:00.03 mysqld
と、かなりひどいことになります。これで運用するのはまず無理ですね。
ちなみにInnoDBを無効にするとほぼ問題がなくなります。Virtuozzo/OpenVZ環境ではこの構成で運用しているところが多いようです。
[mysqld] skip-innodb
# free -m total used free shared buffers cached Mem: 256 45 210 0 0 0 -/+ buffers/cache: 45 210 Swap: 0 0 0 (# top) PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 18331 mysql 20 0 28780 4388 2748 S 0.0 1.7 0:00.00 mysqld
Virtuozzo/OpenVZでInnoDB Pluginをあきらめない設定例
というわけで限界までダイエットしてみました。
[mysqld] character_set_server = utf8 collation_server = utf8_general_ci transaction_isolation = READ-COMMITTED ignore-builtin-innodb plugin-load = innodb=ha_innodb_plugin.so;innodb_trx=ha_innodb_plugin.so;innodb_l ocks=ha_innodb_plugin.so;innodb_lock_waits=ha_innodb_plugin.so;innodb_cmp=ha_inn odb_plugin.so;innodb_cmp_reset=ha_innodb_plugin.so;innodb_cmpmem=ha_innodb_plugi n.so;innodb_cmpmem_reset=ha_innodb_plugin.so (plugin-loadは実際には1行) default_storage_engine = InnoDB innodb_file_per_table = 1 innodb_flush_log_at_trx_commit = 1 innodb_buffer_pool_size = 4M innodb_log_buffer_size = 1M innodb_log_file_size = 128MB #server_id = 1 #log_bin = mysql-bin #binlog_format = MIXED #binlog_cache_size = 128K #sync_binlog = 1 slow_query_log = 1 long_query_time = 0.1 query_cache_type = 1 query_cache_size = 1M key_buffer_size = 512K sort_buffer_size = 512K read_buffer_size = 128K max_allowed_packet = 16M max_connections = 64 thread_cache_size = 8 table_open_cache = 4096 [client] default_character_set = utf8
内訳は以下の通りです。
- サーバあたりで確保されるメモリ設定
- コネクションあたりで確保されるメモリ設定
- sort_buffer_size = 512K
- read_buffer_size = 128K
- binlog_cache_size = 128K
innodb_log_file_sizeを128MBにしていますが、このパラメータにinnodb_buffer_pool_sizeより大きな値を指定しても基本的には意味がありません。将来ServersMan@VPSの上位プランに移行したときにdatadir以下をそのまま持っていけるように、あえて大きめの値にしています。
もう一つ、/etc/init.d/mysqlの以下の場所にulimit -s 192を書き加えて、スレッドごとのスタックサイズを192KBに設定します。
case "$mode" in 'start') # Start daemon ulimit -s 192 # Safeguard (relative paths, core dumps..) cd $basedir manager=$bindir/mysqlmanager
本来MySQLではthread_stackというパラメータでスレッドごとのスタックサイズを設定できるのですが、どうもInnoDBスレッドにはこの設定が効かないようです。バグかもしれませんのであとで調べてOracleに報告しておきます。
CentOS 5におけるデフォルトのスタックサイズは10MBですので、ulimitで強制的に絞ることによって約9.8MB×InnoDBスレッド数のメモリを節約できることになります。InnoDB Pluginで初期状態におけるメモリ使用量が多かったのは、ファイルI/Oスレッド数がオリジナルのInnoDBよりも増えているためです。
# free -m total used free shared buffers cached Mem: 256 41 214 0 0 0 -/+ buffers/cache: 41 214 Swap: 0 0 0 (# top) PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 26364 mysql 18 0 25148 9552 3212 S 0.0 3.6 0:01.52 mysqld
ここまでの設定を行った結果、InnoDB Pluginを有効にした状態でメモリ使用量を25MBまで抑えることができました。他のソフトウェアを動かしてもまだ余裕があるようであれば、innodb_buffer_pool_sizeを16〜32MB程度に増やしてもよいと思います。