気が付いたらmysqlサーバがswapしてた
昨日の夜にmuninをフラフラーっと見てたんです。とあるDBサーバで今度作業するっていういので今の状況を確認しておこうと見たら・・・・
2GBもswapしてるじゃないですか!
アタヽ(д`ヽ彡ノ´д)ノフタ
うーん、swap I/Oの頻度はそこまで多くないから死にはしないけど原因見つけて対処しないとなっと。
前に読んだhttp://d.hatena.ne.jp/fat47/20121121/1353495937:【メモ】MySQLでのswap発生とNUMAアーキテクチャを思い出しました。
「お、確かにR410でCPU2個詰めるからもしかしたら・・・」
と思ったので搭載CPUの数を調べようと/proc/cpuinfoを見たら
1個しか搭載してませんでした・・・
# cat /proc/cpuinfo | grep physical | grep id
physical id : 1
physical id : 1
physical id : 1
physical id : 1
physical id : 1
physical id : 1
physical id : 1
physical id : 1
8coreだったのはHTしてるっぽいですね・・・構築は他の人がやったので細かいところは知らなかったのでちょうどいい機会。
innodb_buffer_poolの設定が間違ってるのかと思いましたが、実メモリ32GBに対して24GB割り当ててたので間違ってはないようだ。他のmy.cnfの設定とか見ても特別変なところはない。
結論 vm.swappinessの設定がデフォルトでした。
kernel 2.6から追加されたkernelパラメータらしいのですが、swap領域の扱いを制御するパラメータとのこと。
このパラメータの値が小さければ小さいほどswapしにくいと。
mysqlでは0にするのを推奨しているようです。まぁmysqlもメモリに乗り切らなかったら(古いキャッシュ)結局Diskにアクセスしに行くんだからswapしようが、普通にDiskIOが発生しようが変わらないんじゃないかと。
でも既にswapしてるしってことで対応手順を
kernel パラメータのvm.swappinessを設定
vm.swappinessはsysctl.confに記述してやらないと再起動したら設定が消えちゃうのでこいつを使ってやる。
# vim /etc/sysctl.confvm.swappiness = 0 #この1行を追記
保存したら
# sysctl -p
で/etc/sysctl.confの設定を反映。サーバの再起動とか何もいらないです。sysctl -w hogehoge = xxxとかでもできた気がするけど、今回は記憶にある方法でこれを採用。まぁあとは、記述した設定がそのまま反映されるので再起動時と全く同じになるというメリットもあります。
上記コマンドでも反映されたパラメータが出力されるのですが、一応確認で
# sysctl -a | grep swappiness
vm.swappiness = 0
これで設定が反映されていることが確認できました。
が!
swapしてることには変わらないのでそれの対応。swapしたデータをメモリに戻してやる。
swapしたデータをメモリに戻す
# cat /proc/swaps
でどのデバイスをswapに割り当ててるか確認する。
今回は/dev/sda2だったので対象はこいつ
# swappoff /dev/sda2
こいつを実行してやればswapにあるデータがメモリに戻ります。メモリに乗らなければ破棄されるらしい。
戻すというかswap領域をなくしてるだけなのですが。
基本メモリは消えても困らないデータを乗せるところなので破棄されてもデータロスは起きないはず。
別のターミナルでtopコマンドとか実行しながら進捗を確認するといいと思います。
swap領域はないならないで困るので戻してやります。
# swapon -a
freeなりなんなりコマンドを実行してswap領域が戻ってることを確認したらめでたしめでたしです。
muninで確認してもswap領域が空いたことを確認できました。
これでもswapするようならmysqlの設定を1から見直す必要があります。
ちなみにこの作業を全てやるのに40分ほどかかりました。mysqlが稼働してて更新が走ってる状態なので完全に止まってる状態ならもう少し早く終るかもです。
こんな設定は1台見つけるとゴキブリの様にうじゃうじゃと他のサーバでも同じ設定になっているのが見つかるので洗い出す仕事が増えました・・・
既に10台以上確認している・・・
まだswapしてなきゃいいけど、swapしてるとやっかい・・・