DELETE FROM テーブル WHERE id=xx
のxxを間違ってしまった、みたいなときに軽くバイナリログから復旧する方法です。
そもそもWHERE句を入れてなくて100万件消えたとか、ディスクを読み取り専用にしてextundeleteして、みたいなガチな内容ではありません。
バイナリログってなに?
INSERT/UPDATE/DELETEなどの変更SQLを保存するログファイルです。
MySQLのデータフォルダにデータベース名-bin.000001
みたいなファイルがあればバイナリログです。
レプリケーションにも使うので、レプリケーション環境であれば存在するはずです。
バイナリログがなかったら、以下の手段は使えないのでがんばってどうにかしてください。
バイナリログをテキストにする
バイナリログは名前のとおりバイナリなので、そのまま見ようとしても全く読めません。
まずはテキスト形式に変換する必要があります。
環境によっては000001
とか000002
のように複数のバイナリログファイルがありますが、その場合は更新日時を見てどのあたりが必要なログか確認しましょう。
mysqlbinlog -v /path/to/mysql/database-bin.000001 > /tmp/log.txt
実際はなんだかよくわからないデータも残っていたりするのですが、これで一応人間が読めるテキストファイルになりました。
DELETE文を抽出
cat -n /tmp/log.txt | grep "DELETE FROM `DB名`.`テーブル名`"
これでDELETE文が入っている行が抽出されます。
たくさん見つかった場合は、その中からどこが該当のDELETE文なのかを探す仕事が始まります。
head -n 行数+30 /tmp/log.txt | tail -40
こんなかんじでDELETE文の前後の行を取り出せます。
そしてポイントですが、バイナリログではDELETE文にも全てのカラムの内容が入っています。
すなわち、うっかりDELETEしてしまった中身を取り出すことができます。
あとは取り出せた値をINSERTしなおせば復旧完了です。
めでたし。
未確認
TEXT型は取り出せることを確認していますが、BLOBのようなバイナリ型はこれで取り出せるかはわかりません。
ON DELETE CASCADE
などで巻き込まれて削除された場合にバイナリログがどうなるかは確認していません。
今回は調べる必要がなかったからね。