使用 tail/tailf 查看 MongoDB 日志的时候发生以下错误:
$ tailf /var/log/mongodb/mongodb.log
...
tailf: tailf: /var/log/mongodb/mongodb.log:无法添加 inotify 观察(达到了 inotify 观察数限制)。
:无法添加 inotify 观察(达到了 inotify 观察数限制)。
$ tail -F /var/log/mongodb/mongodb.log
...
tail: inotify 资源耗尽
tail: 无法使用 inotify 机制,回归为 polling 机制
关掉一些可能在使用 inotify 监听文件的程序之后,问题(症状)就消失了。
但是老出现这个问题(每天都会遇到),也不是个事儿啊!
解决问题
百度中只搜到这个感觉有参考价值:新浪博客:[转]Linux下用inotify-tool实时监控服务器文件系统。
那就,只能,到墙外借助 G 哥的力量了。
首先 Google:无法添加 inotify 观察 site:translations.launchpad.net/ubuntu/
,查到:
%s: cannot add inotify watch (limit of inotify watches was reached).
%s:无法添加 inotify 观察(达到了 inotify 观察数限制)。
然后接着 Google:cannot add inotify watch (limit of inotify watches was reached)
,查到很多类似问题,比如:
- kernel - How can I tell if I am out of inotify watches? - Ask Ubuntu
- linux - Kernel inotify watch limit reached - Unix & Linux Stack Exchange
- Inotify Watches Limit - IntelliJ IDEA - Confluence
- Inotify Watches Limit | MonoDevelop
- cannot add inotify watch (limit of inotify watches was reached) | My ...
查看之后,大致上都是说调用 inotify 跟踪文件超出系统设置的上限了,可以通过修改这个上限来解决问题。
查看 inotify 的配置
$ sysctl fs.inotify
fs.inotify.max_queued_events = 16384
fs.inotify.max_user_instances = 128
fs.inotify.max_user_watches = 65536
# 也可以通过 proc 文件系统查看,比如:
cat /proc/sys/fs/inotify/max_user_watches
find /proc/sys/fs/inotify -type f -exec sh -c 'echo -n `basename {}` "\t" && cat {}' \;
临时解决问题(关机之后又是原来的设置):
sudo sysctl -w fs.inotify.max_user_watches=524288
长期修改 inotify 文件监听上限:
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
# 重载配置文件,使之马上生效
sudo sysctl -p
后续
六万多个名额都不够用,是哪个程序在搞我啊!
Google:list inotify watches
、get inotify watch number
等,查到:
- StackOverflow,How do I find out what inotify watches have been registered?
- ArchLinux,Index» Kernel & Hardware» How to list inotify watches
- StackExchage,Who's consuming my inotify resources?
- Super User,How to get current number of opened inotify watches?
- 等等
总之,结论大概如下:
查看哪些程序在监听文件
方法 1:能查到进程号
for foo in /proc/*/fd/*; do readlink -f $foo; done | grep inotify | sort | uniq -c | sort -nr
方法 2:显示进程
ps -fp $(find /proc/*/fd/* -type l -lname 'anon_inode:inotify' -print 2> /dev/null | sed -e 's/^\/proc\/\([0-9]*\)\/.*/\1/')
查看当前哪些文件被监听
没有思路。
查看当前 inotify 文件监听数
有人说机制如此,没办法解决。
参考:How to get current number of opened inotify watches?