2016-06-13 25 views
5

Recentemente aggiornato a MySQL 5.7.12 su Debian (Debian 3.2.78-1 x86_64 GNU/Linux) e eseguito nel server sospeso ogni poche ore . Questo è sempre allagato nel syslog e mysql.log:MySQL - 0 [ERRORE] Errore nell'accettazione: descrittore di file errato

2016-06-13T18:05:20.261209Z 0 [ERROR] Error in accept: Bad file descriptor

informazioni MySQL: mysql Ver 14.14 Distrib 5.7.12-5, per debian-linux-gnu (x86_64) usando 6.2

pezzi di my.cnfmysqld sezione che possono guidare un po 'di assistenza sui valori tweaking:

[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 

risposta

1

Abbiamo avuto lo stesso problema su un sistema Ubuntu 16.04 con mysql 5.7.13. Abbiamo aumentato il nostro parametro di file aperto max in systemd come questo:

/etc/systemd/system/mysql.service.d/10-ulimit.conf

[Service] 
LimitNOFILE=1000000 

Finora il problema non è accaduto ancora. Forse mysql ha bisogno in qualche modo di più descrittori di file ora.

+0

Solo un heads-up-Sul mio sistema FC24 quando si aggiorna MariaDB con DNF, il file di systemd è stato sovrascritto e questo problema si ripresentò. – glyph

+0

Purtroppo questa correzione non ha funzionato qui. Ho riscontrato questo errore su nuove versioni di Ubuntu 16.04 e Ubuntu 16.10 con MySQL 5.7.17. (Credo che sia necessario prima creare la cartella mysql.service ed eseguire 'systemctl daemon-reload'). – mahemoff

0

Ho lo stesso problema dopo l'aggiornamento a Percona Cluster 5.7.14-26.17-1.trusty.

Il suggerimento ulimit.conf non è di aiuto, e mi sono assicurato che ci siano sufficienti handle di file, per quanto posso dire, modificando /etc/security/limits.conf e/etc/sysctl. conf.

Posso riprodurlo facilmente tramite telnet per postare 3306 e quindi disconnettere; il server quindi esegue uno spin registrando questo errore.

Una soluzione orribile per questo, che sembra promettente nel mio ambiente, è di evitare l'uso delle connessioni TCP sulla porta 3306, e utilizzare invece i socket unix.

È possibile delega dalla porta 3306 alla presa cambiando il numero di porta in /etc/mysql/my.cnf e quindi utilizzando socat

nohup socat TCP4-LISTEN:3306,fork UNIX-CONNECT:/var/run/mysqld/mysqld.sock& 

Se dunque io telnet sulla porta 3306 e staccare, ho non può provocare il problema Intendo riferire quanto bene si alza nel tempo.

FWIW, il codice sembra come se si aspetta che questo accada a volte:

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; 
} 
+0

La soluzione alternativa, anche se brutta, è valida, quindi la consiglio a chiunque la stia colpendo. Sembra che questo sia un problema che dura da un po 'e che deve interessare solo alcuni ambienti (vedi Google e @Roel in basso). –

+0

Un aggiornamento. Con la soluzione di socializzazione in atto, vedo ancora alcuni loop che producono questi errori, ma alla fine sembrano terminare e quindi il sistema è sostanzialmente stabile. –

1

ricercato un po 'e hanno trovato successivo;

  1. Presente in MariaDB anche

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

  2. Percona Server/Percona XtraDB Cluster

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

  3. Vecchio bug dal 2010/2012

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

  4. Alcune informazioni interessanti (non dovrebbe mai accadere)

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

[Io lavoro per Percona]

2

ho trovato il problema (o, eventualmente, una delle I problemi). Ecco un estratto da strace su mysqld:

... 
socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP) = 20 
write(2, "2017-01-29T22:22:45.433033Z 0 [N"..., 72) = 72 
setsockopt(20, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 
setsockopt(20, SOL_IPV6, IPV6_V6ONLY, [0], 4) = 0 
bind(20, {sa_family=AF_INET6, sin6_port=htons(3306), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0 
listen(20, 70)       = 0 
fcntl(20, F_GETFL)      = 0x2 (flags O_RDWR) 
fcntl(20, F_SETFL, O_RDWR|O_NONBLOCK) = 0 
... 
accept(20, {sa_family=AF_INET6, sin6_port=htons(58332), inet_pton(AF_INET6, "::ffff:127.0.0.1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 37 
rt_sigaction(SIGCHLD, {SIG_DFL, [CHLD], SA_RESTORER|SA_RESTART, 0x7f3ddeac84b0}, {SIG_DFL, [], 0}, 8) = 0 
getpeername(37, {sa_family=AF_INET6, sin6_port=htons(58332), inet_pton(AF_INET6, "::ffff:127.0.0.1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0 
getsockname(37, {sa_family=AF_INET6, sin6_port=htons(3306), inet_pton(AF_INET6, "::ffff:127.0.0.1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0 
open("/etc/hosts.allow", O_RDONLY)  = 38 
fstat(38, {st_mode=S_IFREG|0644, st_size=589, ...}) = 0 
read(38, "# /etc/hosts.allow: list of host"..., 4096) = 589 
read(38, "", 4096)      = 0 
close(38)        = 0 
open("/etc/hosts.deny", O_RDONLY)  = 38 
fstat(38, {st_mode=S_IFREG|0644, st_size=704, ...}) = 0 
read(38, "# /etc/hosts.deny: list of hosts"..., 4096) = 704 
close(38)        = 0 
socket(PF_LOCAL, SOCK_DGRAM|SOCK_CLOEXEC, 0) = 38 
connect(38, {sa_family=AF_LOCAL, sun_path="/dev/log"}, 110) = 0 
sendto(38, "<36>Jan 29 14:23:08 mysqld[13052"..., 72, MSG_NOSIGNAL, NULL, 0) = 72 
shutdown(20, SHUT_RDWR)     = 0 
close(20)        = 0 

poll([{fd=20, events=POLLIN}, {fd=22, events=POLLIN}], 2, -1) = 1 ([{fd=20, revents=POLLNVAL}]) 
accept(-1, 0x7ffe6ebd7160, 0x7ffe6ebd70fc) = -1 EBADF (Bad file descriptor) 
write(2, "2017-01-29T22:23:08.109451Z 0 [E"..., 75) = 75 
... rinse and repeat *REALLY* fast! 

In bloccando il mio sistema con tcp_wrappers avevo inavvertitamente preso mysqld fuori sia hosts.allow e hosts.deny. Sembra che dopo aver controllato sia hosts.allow che hosts.deny mysqld arresta e chiude il socket come ci si potrebbe aspettare. Tuttavia, iniziano immediatamente a interrogare il socket (ora inesistente) per l'attività.

Ho appena fatto un altro test in cui i miei tcp_wrappers sono stati configurati correttamente. Quando mi connetto da un host autorizzato, tutto va bene; tuttavia quando mi collego da un indirizzo bloccato si verifica lo stesso problema. Sulla base di questo, ti consiglio di usare altri strumenti per proteggere mysqld e rendere la tua configurazione di tcp_wrappers più aperta rispetto al tuo firewall. Detto questo, il bug dovrebbe ancora essere corretto!

Questa correzione deve ancora superare la prova del tempo così, come al solito, YMMV. Speranza che aiuta comunque

Nick

+0

Ho avuto lo stesso identico problema (log inondato dal messaggio "bad file descriptor" e MySQL non funzionante) e ho cercato molto fino a quando ho trovato questo post. Nel mio caso, è stato fail2ban che per qualche ragione ha aggiunto 127.0.0.1 a /etc/hosts.deny per incasinare completamente il sistema! Non appena l'ho rimosso (e ho aggiunto localhost a /etc/hosts.allow per impedire che ciò accada in futuro), le cose sono tornate alla normalità. E il morale della storia: come precauzione, aggiungi 127.0.0.1 a /etc/hosts.allow solo per assicurarti che fail2ban non si metta sulla tua strada! –

+0

Ho aggiunto alcune opzioni mysqld a hosts.allow e hosts.deny, quindi le ho rimosse quando ho scoperto che MySQL Workbench non si connetteva correttamente. I messaggi menzionati nella domanda hanno riempito il mio file error.log fino a quando non ho esaurito lo spazio su disco. Ho interrotto il servizio mysql, ho compresso il file di log e riavviato. Tutto sembra bene ora. Grazie. – user208145

Problemi correlati