2012-12-13

チケットを復旧する

消えたチケット

先日、『Redmineのチケットを間違って削除してしまいました、どうしましょう』というお問い合わせをいただきました。残念ながら、Redminの場合はデータは物理削除されてしまうので、そのままでは復旧できません...。

生まれて間もないチケットなら、新規作成しなおして貰うという方法が一番早いのですが、今回は自分も参照していたチケットで、本文に加えて注記も40件くらい溜まっていました。削除してしまった直前までの状況を聞いたところ、最終更新が前日で、今回は更新時の自分の注記を修正しようとしてチケット毎削除してしまったとのこと。

幸い、日々のバックアップ&前日時点のレプリカのRedmineがあるので、そちらでチケットを確認していただき、前日までの記録を戻せば大丈夫との印象でした。(各テーブルのモデルは連番で採番されるので、チケット番号に基づくデータがごっそり抜けちゃった状態です)

 

削除前のデータを取り出す

開発環境サーバへは、毎朝4時に、バックアップデータをもとにDBへ再インポートを行っています。
さらに、それに加えて、次回バージョンアップ予定のRedmineを使って、標準的な状態でうまくマイグレーションを実施し、Redmineのサービスを起動できるかを確認しています。(テストコードを書いている訳ではありませんが、実質、バージョンアッップ時に問題が発生しないかどうか、バックアップデータが健全で正しくリストアできるかを、継続的に検証できるようにしています


ということで、開発環境でレプリカとして公開しているRedmineは、メインに使っていただいているバージョンよりも1つもしくは複数進んだもので稼働させています。

基本的には構造に大きな変更はありませんので、ブラウザから削除されていない時点のチケットがどんなふうに表示されているかを確認しつつ、MySQLから削除されてしまったIDにまつわるチケットのデータ一式を抽出しました。

 

抽出にはMySQL WorkBench


MacにはMySQLとクライアント一式はインストールしていません。コマンドラインで操作するためにインストールしようかとも思いましたが、誤操作も心配なので、GUIのMySQL Workbenchをインストールして、そこからデータの確認や操作を行うことにしました。

開発機のMySQLポートはアクセス制限を行っているので、ここは便利になったMacの環境を利用して、localhost:3306にポートフォワードして確認します。

MySQL WorkBenchだと、抽出したレコードをcsvの形でなく、Insert文のようなSQLに書き出す機能があるので、今回はこちらを使って復旧用SQLを用意しました。

 

復元にもMySQL WorkBench


復旧用のSQLが出来たので、こんどは本番のMySQLにつなぎ直します。これもポートフォワードで。Redmineの作業用DBに接続し、Insert文でデータを戻してあげて、Redmineのweb画面からチケットが復活していることが確認できればOKです。

 

ファイルはscpで戻します

チケットはほぼ戻りましたが、添付ファイルの場合は実際のファイルを、Redmineのファイル格納用フォルダに戻してあげないといけません。また、フォルダ上のファイル名と、チケットで表示されるファイル名は違いがあります。(タイムスタンプとハッシュ値、拡張子で生成されています)

こちらは、issue_attachements テーブルで定義された、実際のファイル名を指定して、リストアしてあげます。これも直接はscpできないサーバなので、ポートフォワード+ scp で対応しました。

Redmineの添付ファイルは、わたしの環境の場合、config.ymlで/data/redmine_binary/と指定してあるので、ここに転送します。まず、localhostの4321番を、転送先のscp port 22番に繋がるようにして、そのあと localhost:4321 を指定すると転送先に繋がってくれます。
Exp.
$ ssh -p 22 -t -L 4321:localhost:1234 中継ユーザ@中継ホスト ssh -t -L 1234:localhost:22 転送先ユーザ@転送先ホスト
$ scp -P 4321  消しちゃったファイル.xls 転送先ユーザ@localhost:/data/redmine_binary/ハッシュ値で格納する名前.xls
以上でデータ復旧は完了です。
ちなみに、ファイルのパーミッションは注意!
Redmineのプロセスを稼働させているユーザに権限が無いと、チケットを本当に削除したいときにPermission Errorになります。(現環境だとredmine:redmineです)

* * *
今回はsqlを使ってInsertで復旧していますが、mysqlのコマンドラインツールでcsvに書き出してインポートするのでも問題はないと思いますので、再発するようなら自動化しておこうかなと考えています。

ちなみに、大規模な環境なら、こんな記事は全然目新しくもないでしょうけれど...(^^;
いちおう事例として、恥ずかしいですが公開してみます。

できるだけすぐに直前の環境を再現できるようにしておいたことで、ワークフローのおかしいところを見直したり、プラグインの評価をする際にも利用できたりと、いろいろメリットはありますので、なんにしても用意しておいて良かった、と思った次第です。

1 件のコメント:

  1. 備えあれば憂いなし。転ばぬ先の杖、ですね。口先のべき論でなく、実態として備えが出来ている状態がキープされているのが素晴らしいです。

    返信削除