今回はmlocate.dbが肥大化した時の対処方法を3つご紹介します。検証で使用した環境はRHEL6.10です。
目次
検証で使用した環境
古いRHELで実施したかったので、RHEL6.10のAMIからEC2作成して検証しました。
# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 6.10 (Santiago)
# locate --version
mlocate 0.22.2
# locate -S
Database /var/lib/mlocate/mlocate.db:
5,317 directories
60,518 files
2,736,967 bytes in file names
1,186,850 bytes used to store database
mlocate.dbとは
mlocate.dbとは、locateコマンド用のデータベースファイルです。locateコマンドとはfindコマンドのようにファイルを探すコマンドですが、このデータベースを使用してファイルを検索するためとても高速です。実際にコマンドを打ってみれば速さが分かります。(以下、コマンドの例)
# locate /etc/hosts
/etc/hosts
/ets/hosts.allow
/ets/hosts.deny
例えばファイルが新規作成されたり、削除されたりしたらこのデータベースへ反映させないといけませんね。これは標準では1日1回cron.daily(/etc/cron.daily/mlocate.cron)で実行されるようになっています。この反映コマンドが「updatedb」というコマンドになります。
mlocate.dbの肥大化
勘の言い方ならもうわかっていると思いますが、データベースの容量は「ファイルやディレクトリの数」に依存します。つまり、ファイルが増え続けていると、mlocate.dbも大きくなり続けます。試しに10万ファイル作って使用量の変化をチェックします。
1. 事前の状態
# locate -S
Database /var/lib/mlocate/mlocate.db:
5,317 directories
60,518 files
2,736,967 bytes in file names
1,186,850 bytes used to store database
# ls -l /var/lib/mlocate/mlocate.db
-rw-r-----. 1 root slocate 1186850 Oct 25 04:13 /var/lib/mlocate/mlocate.db
2. 10万ファイル作成
作成前後でdfコマンドでiノードの使用状況を確認します。またリアルタイムではmlocate.dbが更新されないことも分かります。
[1] iノード使用量
# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/xvda1 983040 56745 926295 6% /
tmpfs 127261 1 127260 1% /dev/shm
[2] 10万ファイル作成
# for i in $(seq 100000)
do
touch tmpfile.$i
done
[3] iノード使用量
# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/xvda1 983040 156745 826295 16% /
tmpfs 127261 1 127260 1% /dev/shm
10万ファイル作成したので、iノードが10万ふえました。
[4] mlocate.dbの確認
# locate -S
Database /var/lib/mlocate/mlocate.db:
5,317 directories
60,518 files
2,736,967 bytes in file names
1,186,850 bytes used to store database
データベースのサイズは変わっていませんね。
[5] 作成したファイルが見つけられるか確認
# locate tmpfile.12345
# echo $?
1
見つけられませんね。
3. データベース更新
ここでupdatedbコマンドでデータベースを更新します。直接updatedbコマンドを打ってもいいですが、cronで動くスクリプトを起動します。
[1] updatedbの実行
# /etc/cron.daily/mlocate.cron
[2] mlocate.dbのサイズ確認
# locate -S
Database /var/lib/mlocate/mlocate.db:
5,287 directories
159,986 files
4,616,541 bytes in file names
2,669,912 bytes used to store database
[3] 作成したファイルが見つけられるか確認
# locate tmpfile.12345
/root/tmpfile.12345
サイズは1MB程増え、先ほど見つけられなかったファイルが見つけられるようになりました。
本題:肥大化にどう対応するか
案1:locateコマンドの使用をやめる
簡単ですね。locateの使用をやめれば、データベースは必要なくなります。
[1] cronの削除
# rm -f /etc/cron.daily/mlocate.cron
[2] mlocate.dbの削除
# rm -f /var/lib/mlocate/mlocate.db
こうすることで、以下のようにlocateコマンドは失敗するようになります。
# locate /etc/hosts
locate: can not stat () `/var/lib/mlocate/mlocate.db': No such file or directory
もし、復活させたければ、mlocate.cronを再度格納するか、updatedbコマンドを直接打てばOKです。
案2:データベースに登録する対象を絞る
locateコマンドで検索可能な範囲を絞ることが出来ます。設定ファイルは/etc/updatedb.confです。標準ではこのように設定されています。
# cat /etc/updatedb.conf
PRUNE_BIND_MOUNTS = "yes"
PRUNEFS = "9p afs anon_inodefs auto autofs bdev binfmt_misc cgroup cifs coda configfs cpuset debugfs devpts ecryptfs exofs fuse fusectl gfs gfs2 gpfs hugetlbfs inotifyfs iso9660 jffs2 lustre mqueue ncpfs nfs nfs4 nfsd pipefs proc ramfs rootfs rpc_pipefs securityfs selinuxfs sfs sockfs sysfs tmpfs ubifs udf usbfs"
PRUNENAMES = ".git .hg .svn"
PRUNEPATHS = "/afs /media /net /sfs /tmp /udev /var/cache/ccache /var/spool/cups /var/spool/squid /var/tmp"
PLUNEとはこのような意味があります。取り除く、削るといった意味合いで、PRUNEFSなら除外するファイルシステムを指定します。
〈枝・根などを〉切り取る,おろす(back,away,down,off);〈木を〉刈り込む,剪定せんていする(back);自剪定する
〈物から〉(余計な物を)取り除く≪of≫;〈人員などを〉削る;〈費用などを〉切り詰める;〈文章などを〉簡潔にする(down);自(余計なものを)取り除く
先ほど、10万ファイルを作成した/rootをPLUNEPATHSに登録して再度updatedbコマンドを実行してみます。
[1] 事前の状態
# locate -S
Database /var/lib/mlocate/mlocate.db:
5,317 directories
160,523 files
4,625,972 bytes in file names
2,675,797 bytes used to store database
[2] 除外パスに/rootを追加
# diff /etc/updatedb.conf /etc/updatedb.conf.org
4c4
< PRUNEPATHS = "/afs /media /net /sfs /tmp /udev /var/cache/ccache /var/spool/cups /var/spool/squid /var/tmp /root"
---
> PRUNEPATHS = "/afs /media /net /sfs /tmp /udev /var/cache/ccache /var/spool/cups /var/spool/squid /var/tmp"
[3] updatedb実施
# updatedb
[4] 事後の状態
# locate -S
Database /var/lib/mlocate/mlocate.db:
5,315 directories
60,518 files
2,737,015 bytes in file names
1,186,810 bytes used to store database
/rootが除外されたことで使用量がかなり削減されました。この要領で、パスであったりファイル名であったりから除外していくことで、mlocate.dbの使用量を削減することが出来ます。
案3:mlocate.dbを別ファイルシステムに移動してシンボリックリンクを貼る
/varはログ領域として個別のファイルシステムにしていることが多いと思います。なので、そのファイルシステムを拡張することを検討しますが、オンプレシステムの場合、容易に拡張できなかったりします。そんな時にこの案3がおすすめです。また、案1,案2と違い、機能面での影響を与えていないので、locateコマンドをどこかで使ってるかもしれない・・・といったときにも使える案です。
とりあえず対処するにはこの案3がおすすめです。
注意
以下手順はディレクトリごと別ファイルシステムに移動していますが、mlocate.dbファイルを移動してファイルにリンクを貼る、という方法だと、updatedbコマンド実行時にリンクが消えてファイルが作成されてしまいました。手順の通りディレクトリを移動してください。
※移動後のファイルシステムを/FS2としています。
[1] ディレクトリ移動
# mv -f /var/lib/mlocate /FS2/mlocate
[2] シンボリックリンク作成
# ln -s /FS2/mlocate /var/lib/mlocate
[3] シンボリックリンク確認
# ls -l /var/lib/mlocate
lrwxrwxrwx. 1 root root 12 Oct 25 07:01 /var/lib/mlocate -> /FS2/mlocate
念のため稼働確認しておきます。
[4] 状態確認
# locate -S
Database /var/lib/mlocate/mlocate.db:
5,315 directories
60,518 files
2,737,015 bytes in file names
1,186,810 bytes used to store database
[5] updatedb確認
# /etc/cron.daily/mlocate.cron;echo $?
0
[6] locateコマンド確認
# locate /root/tmpfile.12345
/root/tmpfile.12345
最後に
とてもニッチなlocate/mlocateの話でしたが、どなたかの助けになったら嬉しいです。
コメント