设备或资源繁忙 - getaddrinfo

设备或资源繁忙 - getaddrinfo

我在运行 PG、MariaDB、sidekiq 和 apache httpd 的 CentOS 7 VM 上。有时我的日志中充满了错误,例如:

unable to resolve address: System error

WARN: Mysql2::Error::ConnectionError: Unknown MySQL server host 'mariadb' (16)

WARN: PG::ConnectionBad: could not translate host name "postgres" to address: System error

WARN -- : Unable to record event with remote Sentry server (Errno::EBUSY - Failed to open TCP connection to o383708.ingest.sentry.io:443 (Device or resource busy - getaddrinfo)):

所有这些主机(哨兵服务除外)在我的 /etc/hosts 文件中都设置为 127.0.0.1。

Ping 主机名似乎可以从控制台进行,这些错误在运行时会在各种应用程序日志中弹出。

lsof | wc -l => 700k(最大 1.6M)

VM 没有明显负载(平均负载为 10%)。没有攻击或 rootkit 或类似的东西。

我的主机文件:

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

127.0.0.1 mariadb
127.0.0.1 postgres
127.0.0.1 mongodb
127.0.0.1 redis
127.0.0.1 memcached
127.0.0.1 socketcluster

/etc/nsswitch.com 的内容

passwd:     files sss
shadow:     files sss
group:      files sss

hosts:      files mdns4_minimal [NOTFOUND=return] dns myhostname

bootparams: nisplus [NOTFOUND=return] files

ethers:     files
netmasks:   files
networks:   files
protocols:  files
rpc:        files
services:   files sss

netgroup:   nisplus sss

publickey:  nisplus

automount:  files nisplus sss
aliases:    files nisplus

有人知道发生了什么事吗?为什么getaddrinfo打不开hosts文件???

为这个问题添加悬赏。请不要贪图便宜。

答案1

我认为您通过讨论找到了正确的根本原因/etc/hosts。事实上,其中一些失败主机中的域配置正确主机首先出现nsswitch.conf表明故障发生在打开之前/期间/etc/hosts


您的第一个障碍是在命令行重现问题。

我会调查这些服务是否正在运行挂载命名空间。我在某处读到 Centos 为其服务使用了更多的挂载命名空间。我依稀记得原因是它改变了一些东西,/etc/但我可能完全错了。因此,对于 mariadb 检查这三个的输出是否匹配:

# systemd
ls -lh /proc/1/ns/mnt
# console 
ls -lh /proc/self/ns/mnt 
# mariadb / mysql
ls -lh /proc/$(pidof mysqld)/ns/mnt

如果 mariadb 与您的控制台不匹配,那么它位于不同的命名空间中。您应该能够通过以下方式输入该名称空间:

nsenter -mt $(pidof mysqld) /bin/bash

这将使您进一步调查发生了什么。希望它能为您提供一个与 mysql 遇到相同问题的命令行。

笔记如果问题是暂时的,那么您将需要在“中断”期间执行此操作。


下一步是寻找到底是什么失败了。目前我们猜测是这样,/etc/hosts但在此之前还读取了其他文件。真正有用的命令是斯特雷斯

如果您可以在命令行上重现错误,则使用 strace 和一个简单的命令。例如,如果 ping 命令失败,请查看以下命令生成的输出文件:

strace -o output_file ping mariadb

如果您无法重现该错误,那么您可以 strace mariadb 本身。其输出文件将非常大,但可能会给您一些可以使用的东西

strace -o output_file -p $(pidof mysqld)

获得 strace 输出后,您可以在其中搜索失败的确切系统调用和上下文。根据您要查找的错误消息忙碌

grep -nC5 EBUSY output_file

这将为您提供失败的系统调用以及两侧 5 行以祝您好运。这可能需要一些取证工作,但它应该告诉您到底是什么被卡住了。

答案2

这是由于只有 4096 个 inotify 处理程序造成的。我增加了限制,问题就消失了。

fs.file-max = 131070
fs.inotify.max_user_watches = 65536

相关内容