El domingo pasado recibí el correo de un cliente: su sistema de marcación predictiva con vicidial había tenido fallas eléctricas durante el fin de semana, ocasionando que las tablas de MySQL se corrompieran y que el sistema quedara inservible (al menos lo relacionado con la marcación predictiva).
Tras cerca de una hora reparé todas las tablas usando unos comandos simples como los que siguen:
/etc/init.d/mysql stop cd /var/lib/mysql/asterisk myisamchk -r *.MYI /etc/init.d/mysql start
Sin embargo, me percaté que al hacer esto, estaba solo reparando las tablas una por una. El sistema tenía 4 núcleos, por lo que era posible hacer mucho más trabajo al mismo tiempo (4 tareas a la vez) en vez de ir una por una.
El sistema terminó de manera habitual tras el paso de 1 1/2 hrs. Para evitar que tanto tiempo se perdiera en nuevas ocasiones, decidí crear un script en bash que reparara todas las tablas de manera simultánea (limitándose a 1 proceso por cada núcleo del sistema), y me quedó el código así:
#!/bin/bash # Editar estos valores: ## CORES debe ser igual al número de núcleos en el sistema ## (revisar el comando "cat /proc/cpuinfo") ## MYSQLDBDIR debe ser igual a la carpeta de MySQL que contiene la BD ## que debamos reparar (default: "/var/lib/mysql/asterisk") CORES=4 MYSQLDBDIR=/var/lib/mysql/asterisk # Enlistar los archivos FILES=`ls $MYSQLDBDIR/*.MYI` RUNS=0 for i in $FILES do SALIR=0 while [ $SALIR -eq 0 ] do # Obtener la cantidad de procesos en el sistema PROCS=`ps -eF|grep myisamchk|egrep -v "grep"|wc -l` # Ejecutamos el while los procesos activos sean menor a CORES if [ $CORES -gt $PROCS ] then echo `date +"%X"` Revisando/Reparando tabla $i myisamchk -r $i & # Descansamos 1 segundo sleep 1 SALIR=1 else # Esperamos 3 segundos sleep 3 fi done done # Ya se terminaron de correr todas las instrucciones de reparación, # pero existe la posibilidad de que algunas de ellas aún estén ejecutándose. # Revisamos para ver si hay procesos corriendo y avisar al usuario while [ $SALIR -eq 0 ] do # Obtener la cantidad de procesos en el sistema PROCS=`ps -eF|grep myisamchk|egrep -v "grep"|wc -l` if [ $PROCS -gt 0 ] then echo `date +"%X"` Hay $PROCS procesos corriendo. Esperando 10s... sleep 10 else echo "No hay procesos corriendo" SALIR=1 fi done echo `date +"%X"` Fin. Ya puedes reiniciar MySQL
Los siguientes pasos son algo obvios:
- Hay que guardar este script como un archivo checar.sh
- Editamos el archivo y cambiamos el número de cores de nuestro sistema, así como la ubicación de la carpeta de MySQL que contiene los archivos de la BD
- Darle permisos de ejecución (chmod 755 checar.sh)
- Ejecutarlo: ./checar.sh