我正在运行 Linux 2.6.36 内核,并且看到一些随机错误。例如
ls: error while loading shared libraries: libpthread.so.0: cannot open shared object file: Error 23
是的,我的系统无法持续运行“ls”命令。:(
我注意到 dmesg 输出中有几个错误:
# dmesg | tail
[2808967.543203] EXT4-fs (sda3): re-mounted. Opts: (null)
[2837776.220605] xv[14450] general protection ip:7f20c20c6ac6 sp:7fff3641b368 error:0 in libpng14.so.14.4.0[7f20c20a9000+29000]
[4931344.685302] EXT4-fs (md16): re-mounted. Opts: (null)
[4982666.631444] VFS: file-max limit 1231582 reached
[4982666.764240] VFS: file-max limit 1231582 reached
[4982767.360574] VFS: file-max limit 1231582 reached
[4982901.904628] VFS: file-max limit 1231582 reached
[4982964.930556] VFS: file-max limit 1231582 reached
[4982966.352170] VFS: file-max limit 1231582 reached
[4982966.649195] top[31095]: segfault at 14 ip 00007fd6ace42700 sp 00007fff20746530 error 6 in libproc-3.2.8.so[7fd6ace3b000+e000]
显然,文件最大错误看起来很可疑,因为它们聚集在一起并且是最近发生的。
# cat /proc/sys/fs/file-max
1231582
# cat /proc/sys/fs/file-nr
1231712 0 1231582
这也让我感觉有点奇怪,但问题是,我不可能在这个系统上打开 120 万个文件。我是唯一使用它的人,本地网络之外的任何人都看不到它。
# lsof | wc
16046 148253 1882901
# ps -ef | wc
574 6104 44260
我看到一些文献说:
文件最大值和文件编号:
内核动态分配文件句柄,但目前还不会再次释放它们。
file-max 中的值表示 Linux 内核将分配的最大文件句柄数。当您收到大量有关文件句柄用尽的错误消息时,您可能需要增加此限制。
从历史上看,file-nr 中的三个值分别表示已分配的文件句柄数、已分配但未使用的文件句柄数以及最大文件句柄数。Linux 2.6 始终将可用文件句柄数报告为 0 —— 这不是错误,它只是表示已分配的文件句柄数与已使用的文件句柄数完全匹配。
使用 printk 报告尝试分配比文件最大值更多的文件描述符,查找“VFS:已达到文件最大值限制”。
我对此的第一印象是内核基本上存在内置文件描述符泄漏,但我发现这很难令人相信。这意味着任何正在使用的系统都需要每隔一段时间重新启动以释放文件描述符。正如我所说,我无法相信这是真的,因为对我来说,Linux 系统一次运行数月(甚至数年)是正常的。另一方面,我也不敢相信我几乎空闲的系统竟然打开了超过一百万个文件。
有人有什么想法吗,无论是修复还是进一步诊断?当然,我可以重新启动系统,但我不想每隔几周就出现一次这个问题。作为权宜之计,我退出了 Firefox,尽管我只打开了一个窗口,但它却输出了近 2000 行 lsof(!),现在我可以再次运行“ls”,但我怀疑这能否长期解决问题。(编辑:哎呀,说得太早了。当我打完这个问题时,症状又回来了)
在此先感谢您的帮助。
还有另一个更新:我的系统基本上无法使用,所以我决定除了重新启动之外别无选择。但在我这样做之前,我小心翼翼地一次退出一个进程,并/proc/sys/fs/file-nr
在每次终止后进行检查。我发现,正如可以预见的那样,随着我关闭进程,打开的文件数量逐渐减少。不幸的是,效果并不大。是的,我能够清除 5000-10000 个打开的文件,但仍然有超过 120 万个文件。我关闭了几乎所有的东西。所有交互式 shell,除了我为了完成关闭而打开的一个 ssh、httpd,甚至 nfs 服务。基本上进程表中不是内核进程的所有内容,并且仍然有大量文件显然处于打开状态。
重启后,我发现显示/proc/sys/fs/file-nr
打开了大约 2000 个文件,这更合理。像往常一样启动 2 个 Xvnc 会话,加上我喜欢保持打开的十几个监视窗口,总数达到大约 4000 个文件。当然,我认为这没什么问题,但我显然没有找到根本原因。
我仍在寻找想法,因为我确实希望它再次发生。
第二天又有一次更新:
我仔细观察了系统,发现/proc/sys/fs/file-nr
每小时打开文件数增长了约 900 个。我晚上关闭了系统唯一的 NFS 客户端,文件数增长就停止了。请注意,这并没有释放资源,但至少停止了更多消耗。这是 NFS 的已知错误吗?我今天将使 NFS 客户端重新上线,并进一步缩小范围。
如果有人熟悉这种行为,请随意说“是的,NFS4 有这个问题,请回到 NFS3”或类似的话。
答案1
经过进一步测试,我相信这是一个 NFS 服务器错误。当 NFS 客户端上的进程对文件设置写锁定时,服务器会保留一个打开的文件句柄(这可能是错误的术语——我向阅读本文的任何真正的内核专家致歉)。如果服务器在释放锁定时释放句柄,这可能是可以的,但显然不是。
我最初的问题发生在 rrdtool 上。rrdtool 打开一个文件进行读写,锁定文件进行写入,进行更改,然后退出。每次我运行 rrdtool 时,服务器上打开的文件数都会增加一个。(挑剔的细节——服务器实际上以 32 个块为单位进行分配,因此更像是“32 次运行产生 32 个打开的文件描述符”,但从长远来看,这是一个无关紧要的细节)
我编写了一个最小测试程序来验证此行为。事实上,打开文件、锁定文件然后退出就足以触发此行为。在退出前明确释放锁定不会有任何帮助。打开文件而不锁定文件会不是引发问题。
到目前为止,除了重新启动之外,我还没有找到释放服务器上资源的方法。如上所述,重新启动 NFS 服务是不够的。
我还没有测试过 NFS 版本 3。也许它运行得更好。
无论如何,感谢您的尝试。希望我的经验将来能对其他人有所帮助。
最后更新:NFSv4 开发人员之一 J. Bruce Fields 已确认这是一个错误,并表示该错误仅限于 NFSv4。显然我是第一个报告此问题的人。他希望很快能有一个补丁。
记住,孩子们:当你发现一个错误时,找到合适的地方报告它,它很有可能得到修复。为开源欢呼。:-)
答案2
我晚上关闭了系统唯一的 NFS 客户端,增长停止了。请注意,它并没有释放资源,但至少停止了更多的消耗。
看使用 NFS 被认为有害,特别是第 III.B 点。当您的 NFS 客户端不可用时,其锁定不会被释放,因此打开文件的数量不会减少。如果您踢出 NFS 服务器(或更准确地说,锁定守护进程),您会看到打开文件数减少。
我认为您可以放心地将问题归因于 NFS 客户端正在执行的操作,据我所知,您尚未在上面的问题中提及这一点。
出现错误的error loading shared libraries
原因是您已达到可打开的最大文件数;当您运行时ls
,内核尝试打开一个ls
动态链接的库;显然这会失败,因为您已达到该文件系统的最大打开文件数限制,因此出现错误。
您的客户正在做的一件事是每小时打开 900 个文件。这不是在 NFS 导出上运行 Spotlight 的 Mac,对吗?
答案3
我遇到了同样的问题。安装了 HA 服务器集群,我们将其用作中央网络存储。在此 DRBD 集群上,NFS4 服务器正在运行。
每个小时,我们都会生成数千个小数据文件,并将它们存储在这台 NFS4 服务器上。
从我们启动 NFS4 服务器的那一刻起,大约需要 30 天的时间,fs.file-nr 才会达到 120 万个文件的限制,然后在 24 小时内整个机器就会崩溃。
刚才,HA 备份机在崩溃后接管两个小时后,显示
fs.文件编号 = 19552 0 488906
20分钟内增加率+3000。
HA 备份机待机 30 天,一直有 580 0 488906。唯一改变的是启动了 NFS4 服务器。
如果有解决方案的话我会非常高兴。
我正在运行 MDV 2010,使用自定义编译的 x64 2.6.37 RC3 内核