MySQL のバックアップ手法いろいろ
mysqldump
mysqldump コマンドを使うだけなのだが、バックアップ専用のアカウントをつくるたびに、どの権限が必要だったろうかと迷う。
1. サーバ側で dump 用ユーザを作成する。ここではユーザ名を backup とする。SELECT, SHOW VIEW, LOCK TABLES, RELOAD 権限が必要。ローカルサーバで mysqldump する場合は、さらに FILE 権限も必要。
<pre>mysql> grant select, show view, lock tables, reload on . to backup@192.168.0.111 identified by ‘<パスワード>';
SELECT
バックアップ対象テーブルを読み取るのに必要。
SHOW VIEW
VIEWをダンプするのに必要。
LOCK TABLES
整合性を持った状態でダンプするのに必要。mysqldump 実行時に --skip-lock-tables を付ける場合は不要。
RELOAD
mysqldump が FLUSH TABLES を実行するために必要。
</pre>
ネットワーク接続を TCP wrapper や iptables で制限している場合はそちらの解除も忘れずに。
<pre>$ cat /etc/hosts.allow
...
mysqld: 192.168.0.111
</pre>
2. クライアント(リモート)側で mysqldump を実行する。
<pre>mysqldump --host=192.168.0.100 --user=backup --password=<パスワード> --lock-all-tables
</pre>
ダンプ中の insert などで整合性が保てなくなっても良い場合は、--skip-lock-tables をつける。この場合は LOCK TABLES 権限は不要だし、ダンプ中に更新が止まることもない。
mysqlhotcopy
テーブルをロックして、データベースディレクトリをそのままコピーする。mysqldump よりもコストが低いが、同じホスト内でしか使えない。また、MyISAM と ARCHIVE テーブルでのみ利用可能。
ファイルシステムのスナップショット
MySQL 上で FLUSH TABLES WITH READ LOCK した上で、ファイルシステムレベルでスナップショットを取る。同じホスト内でしか使えないが、更新停止時間は mysqldump や mysqlhotcopy よりも格段に短い。スナップショットを取るのは一瞬ということになっているが、Amazon EBS の場合はコマンドが Java で書かれているため、実際には数秒止まる。経験上10秒を超えたことはない。ファイルシステムに XFS を用いて、こんなスクリプトでバックアップしている。
<pre>#!/bin/sh
EC2_HOME=/usr/local/ec2/ec2-api-tools-1.3-41620
EC2_PRIVATE_KEY=/mnt/pk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx.pem
EC2_CERT=/mnt/cert-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.pem
MYSQL_USER=<ユーザ名>
MYSQL_PW=<パスワード>
MOUNT_POINT=/mnt/vol1
VOLUME=vol-xxxxxxxx
MYSQL_CRED="-u$MYSQL_USER -p$MYSQL_PW"
mysql $MYSQL_CRED -e "flush tables with read lock;"
mysql $MYSQL_CRED -Nse "show master status" > $MOUNT_POINT/mysql/master_snapshot_position
mysql $MYSQL_CRED -Nse "show slave status" > $MOUNT_POINT/mysql/slave_snapshot_position
xfs_freeze -f $MOUNT_POINT
ec2-create-snapshot $VOLUME
xfs_freeze -u $MOUNT_POINT
mysql $MYSQL_CRED -e "unlock tables;"
</pre>
レプリケーションしてスレーブ側でバックアップする
レプリケーション構成で、バックアップ専用のスレーブを設ける。そのスレーブでどんなに長時間ロックしようとも、システムには影響が出ない。
レプリケーション
上記の他の手法とは意味合いが異なるが、レプリケーションもバックアップのひとつだ。リアルタイムに別サーバにバックアップされるので、ハードウェア障害に強く、最新のデータまで守れる。ただし間違って DROP TABLE したなどの操作ミスもリアルタイムに伝播するので、人為的ミスやアプリケーションバグには弱い。
RAID, DRBD, ...
デバイスレベルでリアルタイムバックアップという意味で、MySQL のレプリケーションと同じ強みと弱みを持つ。
バックアップ手法は、リアルタイム系(フロー)とスナップショット系(ストック)に大きく分かれる。データを守るという観点からは、リアルタイムバックアップ(レプリケーション、RAID)でハードウェア障害に備えつつ、スナップショットで操作ミスに備えるという構成でシステムを組むことになる。
パスワード>ユーザ名>
SSD で Windows 7
ThinkPad X61 に、再発売されたばかりの SSD、Intel X25-M (34nm) と、Windows 7 RC ビルド7100 を入れてみた。
<p>インストールはすんなり。まったく問題なし。OS の起動と終了がめちゃくちゃ速くなった。電源ボタンを入れてからユーザが操作できるようになるまで約30秒。シャットダウンを開始してから電源が切れるまで約15秒。これで、スキマ時間に PC を立ち上げるのが苦で無くなる。</p>
<p>ウイルス対策ソフトをまだ入れてない。各社とも、あと半月もすれば Windows7 対応正式版を出してくるだろうから、それまで待つ。</p>
RelaxDB をインストールする
CouchDB クライアントの Ruby 実装である relaxdb (http://github.com/paulcarey/relaxdb/) をインストールした。 ソースをローカルに持ってきて、sudo rake install する。
<p>エラーメッセージに従って、足りない gem を追加インストールした。</p>
<pre class='prettyprint'>$ sudo gem install extlib
$ sudo gem install uuid
</pre>
CouchDB の Ruby クライアント - ActiveCouch と RelaxDB の比較
Rails から CouchDB を使おうと、既存のライブラリを物色した。ActiveCouch と RelaxDB が目に付いたので、試してみた。
- ActiveCouch: http://github.com/arunthampi/activecouch
- RelaxDB: http://github.com/paulcarey/relaxdb/
<p>パッケージの形態としては、ActiveCouch は rails (2.x) のプラグインとして作られている。一方、RelaxDB は Ruby のライブラリ。それに加えて、Merb のプラグインが存在する。Rails からの利用も、特に問題なし</p>
<p>設計思想的に、一番大きく違うのは、DB を作成する単位であるように思う。ActiveCouch はモデル毎に DB を作成することを前提に作られている。RelaxDB は、ひとつの DB に全てのモデルを格納し、document に持たせた relaxdb_class field でモデルを識別する。CouchDB はスキーマレスであり、型(そもそも型なんて無いが)の異なる document をすべて一緒に保存しておけるのが特徴なので、RelaxDB の方が、より CouchDB が期待する使い方に近いと思われる。</p>
<p>例えば MySQL であれば、ひとつのデータベースサーバが複数の DB を持ち、DB の中には複数のテーブルがあり、テーブルの中に複数のデータがある、という階層構造を持つ。CouchDB は、ひとつのデータベースサーバが複数の DB を持ち、DB の中に複数のドキュメント(データ)を持つという階層なので、ActiveCouch のような DB の使い方をすると、複数のアプリケーションから CouchDB を使うときに困りそう。</p>
<p>他に気になった点。ActiveCouch は ActiveRecord であらんとするのを目標としている。使う者としては ActiveRecord 的な動作を期待するのだが、結局のところドキュメントに書かれている範囲を超えては ActiveRecord として振舞ってくれないので、あちこちで裏切られる。発展途上なのだろうから仕方がないが、RelaxDB のように「私は別に ActiveRecord ってわけじゃありませんけど」と装いながら、ActiveRecord 的に使うことのできるライブラリのほうが、先入観を持たされない分、よいかもしれない。とはいえ、ActiveRecord のように振舞ってくれる度合いは、ActiveCouch も RelaxDB も、似たようなもの。</p>
<p>結局、DB を作成する単位を重視して、RelaxDB を使うことにした。</p>
Apache CouchDB のインストール
CentOS5 に Apache CouchDB をインストールした。
<pre class='prettyprint'>■ ビルドする
$ wget http://ftp.riken.jp/net/apache/couchdb/0.9.1/apache-couchdb-0.9.1.tar.gz
$ tar zxvf apache-couchdb-0.9.1.tar.gz
$ cd apache-couchdb-0.9.1
$ ./configure
$ make
$ sudo make install
■ RPM としてインストールする
$ sudo checkinstall
(snip)
This package will be built according to these values:
1 - Summary: [ CouchDB ]
2 - Name: [ apache-couchdb ]
3 - Version: [ 0.9.1 ]
4 - Release: [ 1 ]
5 - License: [ GPL ]
6 - Group: [ Applications/System ]
7 - Architecture: [ i386 ]
8 - Source location: [ apache-couchdb-0.9.1 ]
9 - Alternate source location: [ ]
10 - Requires: [ ]
11 - Provides: [ apache-couchdb ]
(snip)
$ sudo rpm -i /usr/src/redhat/RPMS/i386/apache-couchdb-0.9.1-1.i386.rpm
■ service, chkconfig コマンドから開始、停止できるようにする
$ ln -s /usr/local/etc/rc.d/couchdb /etc/init.d/couchdb
$ adduser couchdb
$ sudo chown -R couchdb:couchdb /usr/local/var/lib/couchdb
$ sudo chown -R couchdb:couchdb /usr/local/var/log/couchdb
$ sudo /sbin/chkconfig –add couchdb
■ 他のクライアントPCのブラウザから見えるようにする - セキュリティに気をつかう環境の場合は注意!
$ sudo vi /usr/local/etc/couchdb/default.ini
[httpd]
port = 5984
bind_address = 0.0.0.0 ← 127.0.0.1 から 0.0.0.0 に書き換えた
$ sudo vi /etc/sysconfig/iptables
-A RH-Firewall-1-INPUT -m state –state NEW -m tcp -p tcp –dport 5984 -j ACCEPT ← 追加した
$ sudo /sbin/service iptables restart
</pre>
<h3>動作確認</h3>
<pre class='prettyprint'>$ sudo /sbin/service couchdb start
Starting database server couchdb
$ curl http://localhost:5984/
{“couchdb”:”Welcome”,”version”:”0.9.1”}
</pre>
<h3>configure中のエラーとその対処</h3>
<pre class='prettyprint'>$ ./configure
(snip)
checking whether to build static libraries… no
checking whether ln -s works… yes
checking for pthread_create in -lpthread… yes
checking for JS_NewContext in -ljs… no
checking for JS_NewContext in -lmozjs… no
configure: error: Could not find the js library.
Is the Mozilla SpiderMonkey library installed?
$ sudo yum install js-devel
(snip)
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
js-devel i386 1.60-1.el5.rf rpmforge 531 k
Installing for dependencies:
js i386 1.60-1.el5.rf rpmforge 1.0 M
Transaction Summary
================================================================================
Install 2 Package(s)
Update 0 Package(s)
Remove 0 Package(s)
Total download size: 1.6 M
</pre>
<pre class='prettyprint'>$ ./configure
(snip)
checking for JS_NewContext in -ljs… yes
checking jsapi.h usability… yes
checking jsapi.h presence… yes
checking for jsapi.h… yes
checking for icu-config… no
* The icu-config script could not be found. Make sure it is
* in your path, and that taglib is properly installed.
* Or see http://ibm.com/software/globalization/icu/
configure: error: Library requirements (ICU) not met.
$ sudo yum install libicu-devel
(snip)
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
libicu-devel i386 3.6-5.11.4 updates 571 k
Installing for dependencies:
libicu i386 3.6-5.11.4 updates 5.2 M
Transaction Summary
================================================================================
Install 2 Package(s)
Update 0 Package(s)
Remove 0 Package(s)
Total download size: 5.8 M
</pre>
<pre class='prettyprint'>$ ./configure
(snip)
checking ICU_LIBS… -licui18n -licuuc -licudata -lpthread -lm
checking for curl-config… no
* The curl-config script could not be found. Make sure it is
* in your path, and that curl is properly installed.
* Or see http://curl.haxx.se/
configure: error: Library requirements (curl) not met.
$ sudo yum install curl-devel
(snip)
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
curl-devel i386 7.15.5-2.1.el5_3.5 updates 307 k
Installing for dependencies:
libidn-devel i386 0.6.5-1.1 base 239 k
Transaction Summary
================================================================================
Install 2 Package(s)
Update 0 Package(s)
Remove 0 Package(s)
Total download size: 545 k
</pre>