※ パクレゼルヴではWeb開発エンジニアを大募集中!詳細はこちら

Archive

Archive for 2008/3

MySQLのレプリケーション  

2008/3/19 水曜日 14:35:07

姜子牙です。新サービスの規約作りから現実逃避中です。

MySQLのレプリケーション設定について書きます。覚書です。

MySQLは基本機能としてDBのレプリケーションができる機能を備えています。
現在アプリケーション側から更新されているDBをMySQL自身が設定したコピー先(以下SlaveDB)に
順次コピーしていく機能です。この設定を行うことで、SlaveDB自身は基本的にコピー元(以下MasterDB)と全く同じDBを持つことになります。

行った手順は以下のようになります。

1、MasterDBサーバに対してバイナリログを取得するように設定を変更します。
※MySQL5.0より前は更新ログと呼ばれていました。
MasterDBサーバの/etc/my.cnfに以下のような2行を追加します

server-id=1
log-bin=/var/lib/mysql/binary.log

server-idはMySQL同士がお互いを認識するための番号で、MasterDBとSlaveDBで同じ数字を設定しないようにしてください。
log-binにはバイナリログの出力先を指定します。MySQLがファイルを出力できる場所であればどこでも構わないと思います。

2、MasterDBにレプリケーションを行うユーザを作成します。
新規で作らなくてもレプリケーションができるユーザがあればOKです。ただ運用を考えた場合、レプリケーション専用の
ユーザが居るとわかりやすいため、今回は新規作成しています。
MySQLに新規ユーザが作れる権限のユーザでログインし、以下のSQL文を実行します。

mysql > GRANT REPLICATION SLAVE ON *.* TO 'backuper'@'%' IDENTIFIED BY '<password>';

ユーザ名の’backuper’や’ ‘は適当に変更してください。

3、MasterDBを再起動し、設定を有効にします。
以下のコマンドを実行

% /etc/init.d/mysqld restart

4、SlaveDBサーバに以下の設定を追加します。
SlaveDBサーバの/etc/my.cnfに以下のような5行を追加します。

server-id=2
master-host=MasterDB
master-user=backuper
master-password=</password><password>
master-port = 3306

server-idはMySQL同士がお互いを認識するための番号で、MasterDBとSlaveDBで同じ数字を設定しないようにしてください。
master-hostは通信先のMasterDBを認識できるホスト名です。IPアドレスを直接書いてもOKです。
master-userは2で作成したユーザ名を設定します。
master-passwordは2で作成したユーザのパスワードを設定します。
master-portはレプリケーションを行う際に使用するポート番号です。この設定ではデフォルトの3306ポートを使用しています。
もし、Firewall等のフィルタリングでこのポートが使えない場合は設定を変えてください。

また、server-id以外の部分についてはMySQLコマンド内で

mysql> CHANGE MASTER TO
-> MASTER_HOST = 'MasterDB',
-> MASTER_USER = 'backuper',
-> MASTER_PASSWORD = '</password><password>',

といった形でも指定可能です。これらの設定はレプリケーション開始後、SlaveDBサーバにmaster.infoとして登録され
MySQLはそれを見て接続を行うため、コマンド上で変えた物を逐一my.cnfに反映する必要はありません。
(master.infoファイルを消すと、my.cnfの情報を使ってmaster.infoを再度作るので全く必要ないわけではないです)

5、SlaveDBにMasterDBのデータを反映する。
レプリケーションを実行する前に、SlaveDBをMasterDBと同じ状態にします。
今回私がやったのはバックアップ(定期実行しているmysqldump結果)から復元しています。

本来であれば、MasterDBに対してロックをかけ、その状態のダンプとバイナリログ位置の記録をします。

mysql> FLUSH TABLES WITH READ LOCK;

% mysqldump > temp.sql

mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_do_db | Binlog_ignore_db |
+------------------+----------+--------------+------------------+
| binary.001       | 489      |              |                  |
+------------------+----------+--------------+------------------+

mysql> UNLOCK TABLES;

その後、dump結果のtemp.sqlをSlaveDBサーバの方へ移し、ダンプの展開とバイナリログ位置を合わせます。

% mysql < temp.sql

mysql > CHANGE MASTER TO
-> MASTER_LOG_POS=489;

(実はこの辺りちゃんとやってなくてレプリケーション開始後にゴニョゴニョする羽目になりました)

6、SlaveDBサーバでレプリケーション実行を行う。
SlaveDBサーバにて

mysql > START SLAVE;

以上で、レプリケーションを行うための手順になります。
実行状況を確認したい時は、SlaveDBサーバで

mysql > SHOW SLAVE STATUS\G

を実行すると、現在のレプリケーション状況が出力されます。エラーなんかが発生した場合は

Last_Error: *********

としてなんらかのエラーが出力されます。
もしエラーをスキップしたいなら、SlaveDBサーバのmy.cnfに

slave-skip-errors=1062

と追加し、スキップしたいエラー番号をコンマ区切りで書いておけば、そのエラーを無視してレプリケーションを続行します。

slave-skip-errors=ALL

なんかも可能です。(それが健全な状態であるかは別問題ですが)

[Mr.マカー](#゚Д゚) < 新サービスの見積もり数字違うぞ。
[姜子牙 ](;'-') < マジっすか。

はい、行ってきます。

姜子牙 Linux, MySQL, その他