MySQL - 0 [ERROR]接受错误:文件描述符错误

时间:2016-06-13 18:24:23

标签: mysql linux debian

最近在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

5 个答案:

答案 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)

研究了一下,发现了以下内容;

  1. 也出现在MariaDB中

    https://lists.launchpad.net/maria-discuss/msg03060.html https://mariadb.atlassian.net/browse/MDEV-8995

  2. Percona Server / Percona XtraDB群集

    https://groups.google.com/forum/#!topic/percona-discussion/Tu0S2OvYqKA

  3. 2010/2012年的旧版

    https://bugs.mysql.com/bug.php?id=48929 http://lists.mysql.com/commits/96472

  4. 一些有趣的信息(绝不应该发生)

    https://lists.mysql.com/mysql/97275

  5. [我为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 拒绝了我们的日志记录目录,导致了错误的文件描述符错误消息。