最近在Debian(Debian 3.2.78-1 x86_64 GNU / Linux)上升级到MySQL 5.7.12并且每隔几个小时就一直在服务器上运行。这会在syslog和mysql.log中泛滥:
2016-06-13T18:05:20.261209Z 0 [ERROR] Error in accept: Bad file descriptor
MySQL信息: mysql Ver 14.14 Distrib 5.7.12-5,debian-linux-gnu(x86_64)使用6.2
my.cnf mysqld 部分可以为调整值提供一些帮助:
[mysqld]
max_allowed_packet = 64M
thread_stack = 256K
thread_cache_size = 8
max_connections = 150
max_connect_errors = 10000
connect_timeout = 30
wait_timeout = 86400
table_open_cache = 2048
open_files_limit = 65535
query_cache_limit = 4M
query_cache_size = 128M
query_cache_type = 1
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
expire_logs_days = 10
max_binlog_size = 100M
# * InnoDB
innodb_file_per_table
innodb_buffer_pool_instances=2
innodb_buffer_pool_size=2G
thread_pool_size = 24
答案 0 :(得分:2)
我们在使用mysql 5.7.13的Ubuntu 16.04系统上遇到了同样的问题。我们在systemd中增加了我们的max open files参数,如下所示:
<强> /etc/systemd/system/mysql.service.d/10-ulimit.conf 强>
[Service]
LimitNOFILE=1000000
到目前为止,这个问题并未再次发生。也许mysql现在需要更多的文件描述符。
答案 1 :(得分:2)
我发现了问题(或者可能是其中一个问题)。以下是来自mysqld的strace的摘录:
def to_hsv r, g, b
r, g, b = [r, g, b].map{ |component| component.fdiv 255 }
min, max = [r, g, b].minmax
chroma = max - min
[
60.0 * ( chroma.zero? ? 0 : case max
when r ; (g - b) / chroma
when g ; (b - r) / chroma + 2
when b ; (r - g) / chroma + 4
else 0
end % 6 ),
chroma / max,
max,
]
end
在使用tcp_wrappers锁定我的系统时,我无意中将mysqld从hosts.allow和hosts.deny中取出。似乎在检查hosts.allow和hosts.deny后,mysqld会关闭并关闭套接字,如您所料。然而,它们立即开始轮询(现在不存在的)套接字以进行活动。
我刚做了另一个测试,我的tcp_wrappers配置正确。当我从授权主机连接时,一切都很好;但是,当我从阻塞的地址连接时,会出现同样的问题。基于此,我建议使用其他工具来保护mysqld并使您的tcp_wrappers配置比防火墙更开放。据说这个bug还应该修复!
这个修复还没有经受住时间的考验,所以像往常一样,YMMV。希望它无论如何都有帮助
尼克
答案 2 :(得分:1)
研究了一下,发现了以下内容;
也出现在MariaDB中
https://lists.launchpad.net/maria-discuss/msg03060.html https://mariadb.atlassian.net/browse/MDEV-8995
Percona Server / Percona XtraDB群集
https://groups.google.com/forum/#!topic/percona-discussion/Tu0S2OvYqKA
2010/2012年的旧版
https://bugs.mysql.com/bug.php?id=48929 http://lists.mysql.com/commits/96472
一些有趣的信息(绝不应该发生)
[我为Percona工作]
答案 3 :(得分:0)
升级到Percona Cluster 5.7.14-26.17-1.trusty后,我遇到了同样的问题。
ulimit.conf建议没有帮助,我通过编辑/etc/security/limits.conf和/ etc确保有足够的文件句柄,据我所知。 /sysctl.conf。
我可以通过远程登录到3306然后断开连接来轻松复制这个内容;然后服务器进入旋转记录此错误。
在我的环境中看起来很有希望的一个可怕的解决方法是避免在端口3306上使用TCP连接,而是使用unix套接字。
您可以通过更改/etc/mysql/my.cnf中的端口号然后使用socat
从端口3306代理到套接字nohup socat TCP4-LISTEN:3306,fork UNIX-CONNECT:/var/run/mysqld/mysqld.sock&
如果我然后在端口3306上远程登录并断开连接,我就无法解决问题。我打算报告这种情况随着时间的推移会有多好。
FWIW,代码看起来好像有时会发生这种情况:
for (uint retry= 0; retry < MAX_ACCEPT_RETRY; retry++)
{
socket_len_t length= sizeof(struct sockaddr_storage);
connect_sock= mysql_socket_accept(key_socket_client_connection, listen_sock,
(struct sockaddr *)(&cAddr), &length);
if (mysql_socket_getfd(connect_sock) != INVALID_SOCKET ||
(socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN))
break;
}
if (mysql_socket_getfd(connect_sock) == INVALID_SOCKET)
{
/*
accept(2) failed on the listening port, after many retries.
There is not much details to report about the client,
increment the server global status variable.
*/
connection_errors_accept++;
if ((m_error_count++ & 255) == 0) // This can happen often
sql_print_error("Error in accept: %s", strerror(errno));
if (socket_errno == SOCKET_ENFILE || socket_errno == SOCKET_EMFILE)
sleep(1); // Give other threads some time
return NULL;
}
答案 4 :(得分:0)
我带着同样的错误来到这里,但没有一个解决方案奏效,但经过我们的一些研究,我们发现是 apparmor 拒绝了我们的日志记录目录,导致了错误的文件描述符错误消息。