segunda-feira, 13 de março de 2017

Recuperação MySQL Innodb após Problemas Elétricos e/ou Corrompimento de alguma base de Dados


Eu me deparei com um problema em meu servidor Zabbix, onde quando se tentava levantar o serviço do MySQL ele dava uma falha. Então deu uma olhada no arquivo de LOG e eis o que tinha:

------------------------------------------------------------------------------------------------------------
InnoDB: stored checksum 3103110567, prior-to-4.0.14-form stored checksum 438929502
InnoDB: Page lsn 66 2543532480, low 4 bytes of lsn at page end 2544351964
InnoDB: Page number (if stored to page already) 131080,
InnoDB: space id (if created with >= MySQL-4.1.1 and stored already) 0
InnoDB: Page may be an index page where index id is 0 381
InnoDB: Database page corruption on disk or a failed
InnoDB: file read of page 131080.
------------------------------------------------------------------------------------------------------------

Utilizar o programa mysqlcheck não era uma opção, pois ele precisa que o MySQL esteja iniciado e operacional.
Então utilizamos o parâmetro innodb_force_recovery, que possui os níveis de 0 a 6, sendo que 0 é o padrão e significa que não haverá uma recuperação forçada, e 6 pode ser considerado o mais agressivo, pois com este valor nenhuma recuperação é executada.
Coloquei esse parâmetro dentro do my.cnf no meu cado é um servidor linux no caminho /etc/mysql/my.cnf no grupo [mysqld]  innodb_force_recovery = "0 a 6".
A intenção deste parâmetro é que caso não haja um backup recente disponível e o MySQL possa ser iniciado e ter seus dados exportados. É uma opção para ser utilizada em último caso, contando com a sorte para que os dados possam ser exportados. No meu caso eu tinha backups, mas existem muitos casos que não possuem.
Fui então incrementando o valor do parâmetro progressivamente e tentando iniciar o MySQL, mas só consegui com o 6.

Depois de tudo isso passado, eu segui os seguintes passos:
1.   Parei o serviço do MySQL que tinha sido executado com o modo recovery.
2.   Comentei a linha do recovery = dentro do my.cnf
3.   Removi todo o conteúdo da pasta mysql que no meu caso o caminho era /var/lib/mysql.
4.   Reinstalei a base e os arquivos de controle com os seguintes comandos: mysql_installdb --user=mysql  (Isso vai recriar a base mysql).
5.   Levantei o serviço do mysql: servise mysql start. (isso vai criar o ibdata, iblogfile* (tem que aguardar um pouco).
6.   Pronto, agora criei as bases de dados novamente e restaurei os backups.

Referências: 
innodb_force_recovery: http://dev.mysql.com/doc/refman/5.5/en/forcing-innodb-recovery.html

mysqlcheck: http://dev.mysql.com/doc/refman/5.5/en/mysqlcheck.html