sexta-feira, 12 de julho de 2019

MySQL Binlogs :: Como recuperar

Então percebi que não havia feito um post sobre isso depois dessa situação que surgiu recentemente.

Aqui está o cenário: Um backup foi feito à meia-noite, eles usaram o MySQL Dumps por banco de dados. Então, às dez da manhã do dia seguinte, o banco de dados caiu. Uma série de eventos aconteceu antes de eu ser chamado, mas eles conseguiram uma versão do banco de dados com tabelas MyISAM e os arquivos IBD faltando no tablespace.

Portanto, a opção 1, a restauração do backup, nos levaria à meia-noite e perderíamos horas de dados. Opção 2, nós reimportamos os milhares de arquivos ibd e mantemos tudo. Em seguida, tivemos a opção 3, restaurar a partir do backup e, em seguida, aplicar os logs binários para alterações recentes.

Para torná-lo mais interessante, eles não tinham todos os arquivos ibd que me contaram, e eu vi alguns desaparecidos. Portanto, não tenho certeza de como isso foi possível, mas a opção 2 se tornou uma opção inválida. Eles, claro, queriam a menor perda de dados possível, então fomos com a opção 3.

Para fazer isso com segurança, iniciei outra instância do MySQL na porta 3307. Isso me permitiu um local seguro para trabalhar enquanto o tráfego tinha acesso de leitura aos dados do MyISAM na instância da porta 3306.

Depois que todos os arquivos de backup foram descompactados e importados para a instância 3307, consegui me concentrar nos arquivos do log binário.

A princípio, esse conceito parece muito mais arriscado do que realmente é. Na verdade, é bem direto e simples.

Então, primeiro você tem que encontrar os dados depois. Uma revisão dos arquivos binlogs lhe dá uma vantagem sobre quais arquivos são relevantes. No meu caso, de alguma forma eles conseguiram redefinir o log binário para que o arquivo 117 tivesse 2 intervalos de datas dentro dele.

Primeiro para a revisão do binlog, o comando a seguir exibe os dados em formato legível.
mysqlbinlog --defaults-file=/root/.my.cnf --base64-output=DECODE-ROWS --verbose mysql-bin.000117 > review_mysql-bin.000117.sql

* Nota ... Tenha cuidado ao executar o comando acima. Observe que eu tenho que despejar o arquivo diretamente no mesmo local que o log binário. Então, VALIDAR que seu nome de arquivo é válido. Este mysql-bin.000117.sql é diferente deste mysql-bin.000117 .sql. Você perderá seu log binário com a 2ª opção e um espaço antes de .sql.

Agora, salve os dados para que possam ser aplicados. Desde que eu tinha vários binlogs eu criei um arquivo e queria verificar novamente os intervalos de tempo de qualquer maneira.


mysqlbinlog --defaults-file=/root/.my.cnf --start-datetime="2019-07-09 00:00:00" --stop-datetime="2019-07-10 00:00:00" mysql-bin.000117 > binlog_restore.sql
mysqlbinlog --defaults-file=/root/.my.cnf mysql-bin.000118 >> binlog_restore.sql
mysqlbinlog --defaults-file=/root/.my.cnf mysql-bin.000119 >> binlog_restore.sql
mysqlbinlog --defaults-file=/root/.my.cnf --start-datetime="2019-07-10 00:00:00" --stop-datetime="2019-07-10 10:00:00" mysql-bin.000117 >> binlog_restore.sql
mysqlbinlog --defaults-file=/root/.my.cnf --stop-datetime="2019-07-10 10:00:00" mysql-bin.000120 >> binlog_restore.sql
mysqlbinlog --defaults-file=/root/.my.cnf --stop-datetime="2019-07-10 10:00:00" mysql-bin.000121 >> binlog_restore.sql

mysql --socket=/var/lib/mysql_restore/mysql.sock -e "source /var/lib/mysql/binlog_restore.sql"

Agora eu apliquei todos os dados desses binlogs para os intervalos de tempo fornecidos. O cliente checou novamente todos os dados e ficou muito feliz em tê-los de volta.

Várias opções diferentes existiam para esta situação, isso aconteceu para treinar melhor com o cliente.

Uma vez que o validado estava tudo bem na versão restaurada, era simples parar ambos os bancos de dados, mover os diretórios de dados (queria manter os padrões de datadir intactos), chover os diretórios apenas para serem seguros e iniciar o MySQL. Agora a instância restaurada estava na porta 3306.