2013/02/10

【ゼロから構築するRedmine】 第五回 Redmineの定期バックアップとリストアをするよ!(`・ω・´)

Redmineのデータベースと添付ファイルをcronサービスにより定期的にバックアップし、
Windowsのクライアント環境へ時々バックアップを同期するような方法を実践してみました(`・ω・´)

FreeBSD(Ver.8.1)に、portsからRedmine(Ver.1.1.1)を導入して使っている環境でのお話なので、
Linux上に構築したRedmineの場合だと添付ファイルの保存場所とかshのパスとかが違うかも・・。

データベースと添付ファイルをバックアップ
初めに、サーバーにSSH接続してバックアップ用のフォルダを作っておきます。
$ mkdir backup
$ mkdir backup/redmine

Redmineのデータベース(MySQL)をバックアップします。
$ mysqldump -uredmine -p(パスワード) redmine > backup/redmine/db_`date +%Y%m%d`.dump
(パスワード)にはredmineのデータベースを作成する際に設定したパスワードを入力します。

FreeBSD上で稼働するRedmineの場合、添付ファイルは「/usr/local/www/redmine/files」フォルダに格納されます。
これをtgzファイルに圧縮してバックアップします。
$ tar -cvzf backup/redmine/files_`date +%Y%m%d`.tgz /usr/local/www/redmine/files

これらに「バックアップから30日以上だったものは削除」という処理を加えて、シェルスクリプトにまとめると以下のようになります。
#!/bin/sh

mysqldump -uredmine -p(パスワード) redmine > backup/redmine/db_redmine_`date +%Y%m%d`.dump
tar -cvzf backup/redmine/files_`date +%Y%m%d`.tgz /usr/local/www/redmine/files
find backup/redmine -name "db_redmine_*" -mtime +30 -exec rm {} \;
find backup/redmine -name "files_*" -mtime +30 -exec rm {} \;

これを「backup_redmine.sh」として保存して、実行権限を付加します。
chmod +x backup_redmine.sh

cronを使った定期バックアップ
$ which mysqldump
/usr/local/bin/mysqldump
$ which tar
/usr/bin/tar
コマンドのパスは上記のようにwhichコマンドで調べることができます。
今回使用するコマンドはmysqldumpとtarで、crontabで「/usr/local/bin」と「/usr/bin」にパスを通す必要があります。

cronの設定情報が記述されているcrontabファイルを開きます。suコマンドで管理者になってからcrontabをエディタで開きます。
$ ee /etc/crontab

私の環境ではmysqldumpがある「/usr/local/bin」へのパスがなかったので、以下の太字部分を追記しました。
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin

さらに、crontabの末尾に以下の行を追記します。毎日午前2時30分にバックアップします☆
# Backup for redmine.
30 02 * * * Homura /usr/home/Homura/backup_redmine.sh

バックアップを別PCにミラーリング
SSH接続で、バックアップしたdumpファイルとtgzファイルをWindows環境にコピーします。

scpでコピーしても良いのですが、せっかくサーバーの方でバックアップの世代管理してるので
rsyncコマンドでそのまま同期する形でコピーをしたいと思います。

前回構築した自分のcygwin環境には、まだrsyncが入っていなかったのでインストールします。
$ apt-cyg install rsync

rsyncではSSH接続を伴うためパスフレーズの入力が必要です。
毎回入力するのは面倒なので、以下のようなスクリプトを作成してcygwin上で実行しますw
#!/usr/bin/expect

set user (ユーザー名)
set host (ホスト名)
set pass (パスフレーズ)
set timeout -5

spawn rsync -av --delete $user@$host:~/backup/redmine/ backup/redmine/
expect "Enter passphrase for key"
send "$pass\r"
interact
(ユーザー名)、(ホスト名)、(パスフレーズ)には、SSH接続時と同じ情報で書き換えてご使用ください。

これを「rsync_redmine.sh」ファイルに保存して実行権限を付加します。バックアップファイルをコピーするフォルダも作っておきましょうw
$ chmod +x rsync_redmine.sh
$ mkdir ~/backup
$ mkdir ~/backup/redmine
「./rsync_redmine.sh」で同期処理を実行してみましょう。
「receiving incremental file list」というメッセージとともに、同期処理でコピーされたファイル一覧が表示されます。

データベースと添付ファイルをリストア
トラブルなく運用出来るとハッピーなのですが、「ちょっと失敗しちゃった・・前の状態に戻したい」って時もあるかもしれません。
いざって時に失敗しないように、予行演習をしておきましょう(`・ω・´)

初めに、Redmineのデータベース(MySQL)をリストアします。
mysql -uredmine -p(パスワード) redmine < backup/redmine/db_redmine_(日付).dump
(日付)には復旧したい日付を入力します。 (例:db_redmine_20130210.dump)

次に、Redmineの添付ファイルフォルダの中身を削除し、復元したい圧縮ファイルを展開します。suコマンドで管理者になってから行います。
$ rm -f /usr/local/www/redmine/files/*
$ tar -xvf backup/redmine/files_20130210.tgz -C /

困ったときは
Q.「rsync: not found」と出てrsyncの同期処理が中断してしまうよ?(´・ω・`)
A.サーバーにrsyncがインストールされてないかも。FreeBSDなら、以下のようにインストールできます。(`・ω・´)
cd /usr/ports/net/rsync
make config-recursive
make install clean

Q.バックアップ用のシェルスクリプトを実行すると「Command not found.」と出て実行出来ないよ?(´・ω・`)
A.shのパスが間違ってるかもしれません。FreeBSDの場合、Linuxと違って「#!/bin/bash」ではなく「#!/bin/sh」を使いましょう(`・ω・´)

Q.別環境のredmineやアップグレードしたredmineにリストアした後、ログインするとInternal Errorになるよ?(´・ω・`)
A.自分はこのパターンでハマりました。以下の様な対処で解決できる・・・かも。
  • プラグインやテーマなどを前の環境と同じにしてからリストアする。
  • db:migrateの実行時エラー内容に沿って対処する。
以下のページに助けていただきました!(`・ω・´)

参考文献
今回もたくさんの素敵な記事にお世話になりました(`・ω・´)ありがとうございます~

そして何を隠そう、「バックアップやらなきゃ!」というモチベーションの発端はSoftware Design 2012年 03月号なのでした。
せいぞ~ん、せんりゃく~( `・□・´)


※ 2014/04/15: リストアする際のコマンドの向きが間違っていました。お詫びして訂正致しますm(_ _)m
※ 2014/04/18: 「困ったときは」に情報を追記しました。プラグインありのredmineでデータ移行する時は要注意です。