TOC

Error:达到了 inotify 观察数限制

使用 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),查到很多类似问题,比如:

  1. kernel - How can I tell if I am out of inotify watches? - Ask Ubuntu
  2. linux - Kernel inotify watch limit reached - Unix & Linux Stack Exchange
  3. Inotify Watches Limit - IntelliJ IDEA - Confluence
  4. Inotify Watches Limit | MonoDevelop
  5. 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 watchesget inotify watch number 等,查到:

总之,结论大概如下:

查看哪些程序在监听文件

方法 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?