株式会社クイックのWebサービス開発blog

HAPPYなエンジニア&デザイナーのブログです

MySQLをメモリ(tmpfs)にして、3倍速くした話

弊社ではXenServerを使用してますが、結構メモリが余ってる事に気付き
MySQLをメモリ上(tmpfs)に置いて爆速にしてやろう、と思いつきました。
インメモリよりオンメモリMySQLを実現させます。

雨はくせっ毛の敵、よって雨は敵。
matsBです。

HDDよりメモリの方が何をどう考えても速いのですが、メモリ特有の懸念点があります。
メモリ上に置くのでサーバ自体が再起動した時に、データが全て無くなるってところです。
リードレプリカなどで実践したほうが無難な運用になるかと思いますが、そんなのかんけーねー!
って方は、是非本番で試して下さい(๑•̀ㅂ•́)و✧

環境

CentOS 6.5
MySQL 5.6
メモリ 20GB

前提

rsyncをインストール
実データより、メモリが大きい
ここから下のコマンド類はrootで実行しています

下準備

メモリ(tmpfs)をマウント

$ mkdir /mnt/ramdisk/
$ mount -t tmpfs -o size=12G  tmpfs /mnt/ramdisk/

MySQL用のディレクトリを作成

$ mkdir /mnt/ramdisk/mysql
$ mkdir /mnt/ramdisk/tmp
$ chown mysql: /mnt/ramdisk/mysql
$ chown mysql: /mnt/ramdisk/tmp



MySQLの移動

MySQLをストップ

$ /etc/init.d/mysqld stop

MySQLの実データを移行

$ /usr/bin/rsync -avz --delete /var/lib/mysql/ /mnt/ramdisk/mysql/

MySQLのmy.cnfの書き換え

$ vim /etc/my.cnf
[mysqld]
datadir = /mnt/ramdisk/mysql    # データディレクトリをtmpfsに指定
tmpdir = /mnt/ramdisk/tmp     # tmpディレクトリをtmpfsに指定

MySQLをスタート

$ /etc/init.d/mysqld start


とりあえずこれでメモリ上でMySQLが動いて、SQL文を流してみると早さを実感できます。
ここから、再起動してもデータが消えないようにする作業をしていきます。


後処理

シャットダウン時にメモリ上からHDD上にデータを移行

$ vim /etc/rc.d/init.d/halt
/usr/bin/rsync -avz --delete /mnt/ramdisk/mysql/ /var/lib/mysql/

起動時にMySQLがメモリ上(tmpfs)で起動するように追記

$ vim /etc/rc.local
mount -t tmpfs -o size=12G  tmpfs /mnt/ramdisk/
mkdir /mnt/ramdisk/mysql
mkdir /mnt/ramdisk/tmp
chown mysql:mysql /mnt/ramdisk/mysql
chown mysql:mysql /mnt/ramdisk/tmp
/usr/bin/rsync -avz --delete /var/lib/mysql/ /mnt/ramdisk/mysql/
/etc/init.d/mysqld start1

これで、「shutdown -h now」や「reboot」コマンドでサーバを停止しても、シャットダウン時にHDDにデータが移動して起動時にメモリにデータが移動するようになります。




※1
rc.localでmysqldを起動させているのは、デフォルトのまま自動起動にするとrc.localよりもmysqldの方が早く起動します。
となると、メモリをマウントするに起動してしまうため必ず起動に失敗します。
rc.localの起動順をmysqldより前に変更してしまえばいいじゃん!って思いましたが、/etc/rc3.d/ 内でのrc.local起動順番は「S99local」となっており、最後に起動することを想定しています。

$ ls -l /etc/rc3.d/
~中略~
lrwxrwxrwx. 1 root root 16  421 16:58 2016 S64mysqld -> ../init.d/mysqld
lrwxrwxrwx 1 root root 11  319  2015 S99local -> ../rc.local

別の誰かがrc.localに書くときは起動の最後に動くことを想定するはずなので、起動順を変えずにrc.localでmysqldを起動させてます。