Mysql se estrelló y no arranca

19

Nuestro servidor mysql de producción acaba de fallar y no volverá a funcionar. Está dando un error de segfault. Intenté reiniciar, y no sé qué más probar. Aquí está el stacktrace:

140502 14:13:05 [Nota] El complemento 'FEDERADO' está deshabilitado.
InnoDB: la exploración de registros progresó más allá del punto de control lsn 108 1057948207
140502 14:13:06 InnoDB: ¡La base de datos no se cerró normalmente!
InnoDB: Iniciando la recuperación de fallos.
InnoDB: leyendo información de espacio de tabla de los archivos .ibd ...
InnoDB: Restaurando posibles páginas de datos a medio escribir desde la doble escritura
InnoDB: buffer ...
InnoDB: Haciendo recuperación: escaneada hasta el número de secuencia de registro 108 1058059648
InnoDB: 1 transacción (es) que deben revertirse o limpiarse
InnoDB: en total 15 operaciones de fila para deshacer
InnoDB: el contador de identificación de Trx es 0 562485504
140502 14:13:06 InnoDB: Iniciar un lote de aplicación de registros a la base de datos ...
InnoDB: Progreso en porcentajes: 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 
InnoDB: Aplicar lote completado
InnoDB: comenzando en segundo plano la reversión de transacciones no confirmadas
140502 14:13:06 InnoDB: deshacer trx con id 0 562485192, 15 filas para deshacer
140502 14:13:06 InnoDB: Iniciado; número de secuencia de registro 108 1058059648
140502 14:13:06 InnoDB: Error de aserción en el hilo 1873206128 en el archivo ../../../storage/innobase/fsp/fsp0fsp.c línea 1593
InnoDB: Aserción fallida: frag_n_used> 0
InnoDB: Generamos intencionalmente una trampa de memoria.
InnoDB: envíe un informe detallado de errores a http://bugs.mysql.com.
InnoDB: si obtiene fallos o bloqueos repetidos de aserciones, incluso
InnoDB: inmediatamente después del inicio de mysqld, puede haber
InnoDB: corrupción en el espacio de tabla de InnoDB. Por favor refiérase a
InnoDB: http://dev.mysql.com/doc/refman/5.1/en/forcing-recovery.html
InnoDB: sobre forzar la recuperación.
140502 14:13:06 - mysqld recibió la señal 6;
Esto podría ser porque golpeó un error. También es posible que este binario
o una de las bibliotecas con las que se vinculó está corrupta, está construida incorrectamente,
o mal configurado. Este error también puede ser causado por un mal funcionamiento del hardware.
Haremos todo lo posible para recopilar información que esperamos ayude a diagnosticar
el problema, pero como ya nos hemos estrellado, algo está definitivamente mal
Y esto puede fallar.

key_buffer_size = 16777216
read_buffer_size = 131072
max_used_connections = 0
max_threads = 151
threads_connected = 0
Es posible que mysqld pueda usar hasta 
key_buffer_size + (read_buffer_size + sort_buffer_size) * max_threads = 345919 K
bytes de memoria
Espero que esté bien; si no, disminuya algunas variables en la ecuación.

thd: 0x0
Intentando retroceder. Puede usar la siguiente información para averiguar
donde murió mysqld. Si no ves mensajes después de esto, algo salió
terriblemente equivocado...
stack_bottom = (nil) thread_stack 0x30000
140502 14:13:06 [Nota] Programador de eventos: cargado 0 eventos
140502 14:13:06 [Nota] / usr / sbin / mysqld: listo para las conexiones.
Versión: '5.1.41-3ubuntu12.10' socket: '/var/run/mysqld/mysqld.sock' puerto: 3306 (Ubuntu)
/ usr / sbin / mysqld (my_print_stacktrace + 0x2d) [0xb7579cbd]
/ usr / sbin / mysqld (handle_segfault + 0x494) [0xb7245854]
[0xb6fc0400]
/lib/tls/i686/cmov/libc.so.6(abort+0x182) [0xb6cc5a82]
/ usr / sbin / mysqld (+ 0x4867e9) [0xb74647e9]
/ usr / sbin / mysqld (btr_page_free_low + 0x122) [0xb74f1622]
/ usr / sbin / mysqld (btr_compress + 0x684) [0xb74f4ca4]
/ usr / sbin / mysqld (btr_cur_compress_if_useful + 0xe7) [0xb74284e7]
/ usr / sbin / mysqld (btr_cur_pessimistic_delete + 0x332) [0xb7429e72]
/ usr / sbin / mysqld (btr_node_ptr_delete + 0x82) [0xb74f4012]
/ usr / sbin / mysqld (btr_discard_page + 0x175) [0xb74f41e5]
/ usr / sbin / mysqld (btr_cur_pessimistic_delete + 0x3e8) [0xb7429f28]
/ usr / sbin / mysqld (+ 0x526197) [0xb7504197]
/ usr / sbin / mysqld (row_undo_ins + 0x1b1) [0xb7504771]
/ usr / sbin / mysqld (row_undo_step + 0x25f) [0xb74c210f]
/ usr / sbin / mysqld (que_run_threads + 0x58a) [0xb74a31da]
/ usr / sbin / mysqld (trx_rollback_or_clean_all_without_sess + 0x3e3) [0xb74ded43]
/lib/tls/i686/cmov/libpthread.so.0(+0x596e) [0xb6f9f96e]
/lib/tls/i686/cmov/libc.so.6(clone+0x5e) [0xb6d65a4e]
La página del manual en http://dev.mysql.com/doc/mysql/en/crashing.html contiene
información que debería ayudarlo a descubrir qué está causando el bloqueo.

¿Alguna recomendación?

tilleryj
fuente
Lo primero es lo primero; ¿Alguien ha cambiado la configuración de MySQL de alguna manera? Vea la última fecha de modificación para más /etc/mysql/my.cnfo menos.
Janne Pikkarainen
No. Terminé teniendo que configurar innodb_force_recovery = 3 para hacer un mysqldump, luego solté y volví a leer el DB. Esto lo solucionó.
tilleryj

Respuestas:

26

Ay.

InnoDB: immediately after the mysqld startup, there may be
InnoDB: corruption in the InnoDB tablespace. Please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.1/en/forcing-recovery.html
InnoDB: about forcing recovery.

Consulte la página web sugerida: http://dev.mysql.com/doc/refman/5.1/en/forcing-recovery.html .

Básicamente, intente iniciar el servidor MySQL en modo de recuperación y haga una copia de seguridad de sus tablas bloqueadas .

Edite su /etc/my.cnfy agregue:

 innodb_force_recovery = 1

... para ver si puede ingresar a su base de datos y obtener sus datos / encontrar la tabla dañada.

Por lo general, cuando esto sucede es una reconstrucción (al menos de una o dos tablas corruptas).

De http://chepri.com/mysql-innodb-corruption-and-recovery/ :

  1. Parar mysqld( service mysql stop).
  2. Apoyo /var/lib/mysql/ib*
  3. Agregue la siguiente línea en /etc/my.cnf:

    innodb_force_recovery = 1
    

    (sugieren 4, pero es mejor comenzar con 1 e incrementar si no comienza)

  4. Reiniciar mysqld( service mysql start).

  5. Volcar todas las tablas: mysqldump -A > dump.sql
  6. Descarte todas las bases de datos que necesitan recuperación.
  7. Parar mysqld( service mysql stop).
  8. Eliminar /var/lib/mysql/ib*
  9. Comenta innodb_force_recoveryen/etc/my.cnf
  10. Reiniciar mysqld. Mira el registro de errores de mysql. Por defecto debería ser /var/lib/mysql/server/hostname.com.errpara ver cómo crea nuevos ib*archivos.
  11. Restaurar bases de datos del volcado: mysql < dump.sql
Jonathan
fuente
Primero consideraría que puede tener corrupción del sistema de archivos o un disco defectuoso.
bombardeo
1
pruebe todos los valores innodb_force_recovery hasta 6. Y agregue innodb_purge_threads = 0 - a veces el hilo principal no puede iniciar ninguno, lo verá en el registro de errores
akuzminsky
2
Sé que este es un hilo viejo, pero ¿alguna explicación para determinar qué bases de datos necesitan recuperación?
nkanderson
@nicolekanderson También me gustaría alguna aclaración sobre ese punto. Después de ejecutar mysqldump, no me indica de ninguna manera que alguna de las bases de datos esté dañada.
Andrew Thaddeus Martin
punto 10 en la respuesta: intente reiniciar el servidor de la base de datos y lea el registro de errores, debería dar el nombre de las tablas bloqueadas. mysqldump solo te da una copia de las tablas, nada esle.
Jonathan
2

Estaba enfrentando este mismo error al usar mysql: 5.7 docker image. El error principal fue intentar crear un usuario root que existe por defecto. Más información: https://github.com/docker-library/mysql/issues/129

Como se indica en el enlace anterior, la solución fue NO configurar MYSQL_USER y MYSQL_PASSWORD en las variables de entorno al iniciar la imagen del acoplador.

rahuljain1311
fuente
1

Esto me sucedió en Laravel Homestead (Vagabundo después de un kernel panic ejecutando Mac OS Sierra 10.12.4 (16E195):

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.3 LTS
Release:    14.04
Codename:   trusty

$ mysql -V
mysql  Ver 14.14 Distrib 5.7.9, for Linux (x86_64) using  EditLine 
wrapper

Aquí hay algunos recursos que puede probar, aunque ninguna de las opciones de reparación funcionó para mí :

https://dev.mysql.com/doc/refman/5.7/en/forcing-innodb-recovery.html

https://forums.mysql.com/read.php?22,603093,604631#msg-604631

https://support.plesk.com/hc/en-us/articles/213939865-How-to-fix-InnoDB-corruption-cases-for-the-MySQL-database

Intenté agregar la recuperación de fuerza a la configuración de mysql (comience en 1 y vaya progresivamente más alto ya que los números supuestamente más altos pueden causar corrupción permanente):

sudo nano /etc/mysql/my.cnf

[mysqld]
innodb_force_recovery = 1
#innodb-read-only=1
#innodb_purge_threads=0
#key_buffer_size=16M
#event-scheduler=disabled

En otra ventana, ejecute:

tail -f /var/log/mysql/error.log

Luego intente reiniciar mysqld con las diversas opciones habilitadas:

sudo /etc/init.d/mysql restart

Si se agota el tiempo de espera, puede forzar el reinicio de los procesos mysql con:

# process id is first column with number, just ignore lines with grep because they list the process running 'grep mysql'
ps aux | grep mysql
sudo kill -9 <process-id>
sudo /etc/init.d/mysql restart

Si funciona, el registro mostrará algo como:

Version: '5.7.9' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)

Si falla, el registro mostrará algo como:

InnoDB: Assertion failure in thread 140049488692992 in file log0recv.cc line 1420


Cuando las cosas empeoraron, intenté eliminar las bases de datos que probablemente estén corruptas:

sudo ls -alt /var/lib/mysql

Resultó que la base de datos en la que había estado trabajando era la más recientemente modificada en la parte superior de la lista. Afortunadamente, tuve un volcado de SQL desde ese día, así que pude eliminarlo:

sudo rm -rf /var/lib/mysql/<database_name>

Dejé todos los demás archivos y mysql pudo comenzar de todos modos.

ACTUALIZACIÓN: asegúrese de deshabilitar innodb_force_recovery = 1una vez que mysql vuelva a funcionar; de lo contrario, obtendrá errores cuando intente modificar bases de datos y tablas.

Luego recreé la base de datos con Sequel Pro, reimporté mis datos y pude seguir adelante sin tener que tirar todas las bases de datos de mis otros proyectos.

En el futuro, debo asumir que cualquier base de datos mysql puede corromperse y tratar de mantener copias de seguridad diarias y tener el script de recreación de la base de datos documentado o codificado en mis herramientas de integración continua.

Zack Morris
fuente