今まで、MySQL のバックアップは自作の cron スクリプトでバックアップをしていたが、ZRM(Zmanda Recovery Manager) という便利そうなツールを知ったので、試してみた。
その前に、現在の MySQL のバックアップ状況を説明しておく。普通の MySQL レプリケーションを組んだシステムで、Master と Slave 1台に、それぞれに自作の cron を使ってバックアップしている。
- Master 側: flush logs したあと、リレーログを rsync バックアップして一カ月以上の前のリレーログを削除している
- Slave 側: レプリケーションを停止して、flush tables したあと /var/lib/mysql ディレクトリ以下をまとめて rsnyc バックアップ
今は Master 側と Slave 側のバックアップ時間はほぼ同じなっていることが、さっき問題だと気がついたが、この状態で Master がクラッシュした場合 Slave 側でバックアップしている /var/lib/mysql を使ってから Master 側のリレーログで流し込めば復旧する手はずにした。
しかし、昨日リカバリを試してみたところ、なぜか InnoDB が壊れていてすぐにリカバリをすることができなかった。ここにあるとおり強制的に InnoDB を復旧させるとリカバリされたっぽいが、どうも不安。
というわけで、自作のシェルスクリプトを修正しようと、インターネットを調べていたら ZRM を知ったというのが経過。
ZRM を試してみて問題がなければ、Slave 側のバックアップを ZRM に置き換えたい。
ZRM について日本語の情報はほとんどないが、ZRM の特徴は次のとおり。

- MySQL のデータをスケジュールしてフルバックアップすることが可能(スケジューラは、ZRM に含まれている)
- スナップショット経由でのバックアップツール(無料の Community Edition では Linux の LVM のみサポート、有償版では Windows VSS, Solaris ZFS, Veritas VxFS をサポートしている)、mysqldump を使ってのバックアップもできる
- バックアップできる MySQL のストレージエンジンの制限はない
- ファイアーウォール越し(プラグインを使って SSH 経由とか)でもバックアップすることが可能
- MySQL 4.1.x と 5.x に対応している
- encrypt-plugin を使うと、データを暗号化してバックアップすることができる
- perl で書かれている
ということで、今導入してようとしているサーバにぴったり。LVM にしていてよかったと思った。
特徴をざっとみたところで、さっそくインストールしてみる。
- ZRM は、RPM がちゃんと用意されているので RPM をダウンロードする
- RPM は、フル版とクライアント版があるが、フル版をインストールする
- 今日の時点での安定最新版は、2.0.1
- ZRM をインストールするとき、 perl-XML-Parser が必要なので事前に yum でさくっとインストールしておく
RPM で提供されていると、ビルドする手間がないので、とてもありがたい。先日の bacula は、ビルドにとても苦労したので、本当に助かる。頭の中では、FreeBSD だと port で一発なんだけれどもふと思うけれど、Linux なので仕方がない。
環境は、OS は CentOS 5.2 final x86_64 + MySQL 5.0.51b。Slave は、ちゃんとレプリケーションができている状態。
ZRM のマニュアルは、Zmanba Recovery Manager for MySQL Users Manual に詳しくまとまっているので、参考にしながら設定してみる。
ZRM は、MySQL のバックアップツールなので、すべてのコマンドは mysql ユーザで実行する。
- /etc/my.cnf に client セクションを追加して、バックアップするユーザアカウントを設定する
- ZRM の共通設定ファイルは、/etc/mysql-zrm/mysql-zrm.conf にあるが、変更したパラメータは次のとおり。
- compress(gzip で圧縮する設定)を 1 にする
- ZRM は、「バックアップセット」というバックアップする単位セットを定義できるようになっていて、その設定ファイルを /etc/mysql-zrm/バックアップセット名/mysql-zrm.conf で定義できるので、次のパラメータを追加した、バックアップセットは hoge としておく
- backup-mode(バックアップするときのモード、raw or logical、logical のときはバイナリログが必要)を raw に設定する
- host(バックアップ先のホスト)は、もちろん localhost
- user(バックアップするときに使用するユーザ名)を root にする(localhost でバックアップするためと LOCK TABLES, SELECT, FILE, RELOAD, SUPER 権限が必要なので、バックアップ専用ユーザを作ってもいいと思う)
- password を設定する
- database(バックアップ対象のデータベース)をバックアップしたいデータベースに設定する
- replication(slave でバックアップするときは必須の設定)を 1 に変更
- retention-policy(バックアップデータのローテーション間隔)を 1M(一カ月)に変更
- destination(バックアップ先)を変更できるが、デフォルトの /var/lib/mysql-zrm のままにした
- lvm snapshot でとりたいので、snapshot プラグインと snapshot size を指定した
- snapshot-plugin=”/usr/share/mysql-zrm/plugins/lvm-snapshot.pl”
snapshot-size=30G
- lvm snapshot のときは、mysql ユーザで lvdisplay とかのコマンドをパスワード入力なしで実行しないと自動的に実行できないので、/etc/sudoers に次の内容を追加する
- mysql ALL = NOPASSWD:/bin/mount, NOPASSWD:/bin/umount, NOPASSWD:/bin/d
f, NOPASSWD:/usr/sbin/lvdisplay, NOPASSWD:/usr/sbin/lvcreate, NOPASSWD:/usr/sbin
/lvremove
設定ファイルを変更したら、設定ミスがないかどうかチェックする
- sudo -u mysql mysql-zrm –action check –backup-set hoge
次のように表示されれば問題なし。
check:INFO: ZRM for MySQL Community Edition – version 2.0
neoad:check:WARNING: Binary logging is off.
neoad:check:INFO: Configuration check successful
さっそく、すぐにバックアップしてみる。backup-level というのは、バックアップするレベルで 0 がフルバックアップ、1 がインクリメンタルバックアップになる。インクリメンタルバックアップには、バイナリログが必要。
$ sudo -u mysql mysql-zrm-scheduler –now –backup-set hoge –backup-level 0
schedule:INFO: ZRM for MySQL Community Edition – version 2.0
Logging to /var/log/mysql-zrm/mysql-zrm-scheduler.log
backup:INFO: ZRM for MySQL Community Edition – version 2.0
hoge:backup:INFO: START OF BACKUP
hoge:backup:INFO: PHASE START: Initialization
hoge:backup:WARNING: Binary logging is off.
hoge:backup:INFO: backup-set=hoge
…
ERROR: /usr/bin/mysql-zrm did not finish successfully
バックアップに失敗した。どうやら、snaoshot を作成できないらしい。
form にあったとおり、手動で lvcreate してみた。
$ sudo /usr/sbin/lvcreate -L30G -s -n zrmS3LYb7LAEu /dev/vg00/lvol1 Insufficient free extents (0) in volume group vg00: 960 required
ああそうか、空き領域がないのか、これはインストールしたときに全部割り当てしまったからだ。。。
うーむ、今から本番稼働しているサーバの lvm 設定を変更するのは、とてもリスクが大きい。
lvm のスナップショットを使ったことがないので、調べてみたところどうやらローカルのバックアップとして使えないらしい。そうすると、当初の目的を達成することができない。
ZRM には、replication という設定があって、slave でのバックアップオプションがあるけれどバックアップするときのポジションなどの情報を取得するためにバイナリログが必要とのこと。stop slave したあと、show slave status で解析すれば分かるけれど perl なのでなおすには時間がかかりそう。。。
ということで、slave 側はシェルスクリプトで slave を止めたあと、mysqldump してバックアップすることにした。
Master 側だとバイナリログは出力しているので、Master 側のバックアップは ZRM を使うといいかもしれない、しかしすでに稼働しているサーバで導入するのはやめておこう。現行のシェルスクリプトで充分だし。
で、それぞれのバックアップ用のシェルスクリプトを bacula と連携できるように頑張ってみよう。
Tags: mysql