MySQL レプリケーションの設定
目次 |
MySQL レプリケーションの特徴
- MySQL のレプリケーションは非同期。
- 1つのマスターに対して、1つ以上のスレーブが可能。
- 更新系のクエリはマスターのみで実行しなければならい。更新系クエリをスレーブで実行するとスレーブが破損する。
- スレーブを停止しても、スレーブを開始するだけでレプリケーションが再開される。
- スレーブは他のスレーブのマスタになる事が可能。
これらレプリケーションの特徴を利用する事で、MySQL の処理をスケールアウトさせたり、データベースをバックアップしたり、遠隔地にスレーブを設置したりなどに利用することができる。
MySQL レプリケーションの動作概要
MySQL のレプリケーションの動きは大まかに次のような動作となっている。
- マスターサーバの動作
- データベースを更新したすべての SQL コマンドをログファイル(バイナリログ)に記録する。
- スレーブサーバの動作
- マスタに接続しバイナリログを読み込みリレーログとして保存する。(I/O スレッド)
- 保存したリレーログをスレーブで実行し、スレーブとマスタのデータベースを同じ内容にする。(SQL スレッド)
レプリケーションのセットアップ
MySQL でレプリケーションをセットアップするには、次のような操作をすればよい。
- マスター、スレーブのそれぞれの my.cnf にレプリケーション用の追加記述をする。
- マスターにレプリケーション専用のユーザーを登録する。
- マスターデータベースのスナップショットを作成する。
- マスターデータベースのスナップショットを元に、スレーブを作成する。
レプリケーション用の my.cnf 設定
マスターとスレーブのバージョンは、必ずしも同じにする必要は無いが、同じにしておいた方がトラブルは少ない。MySQL 5.1 リファレンス - 5.4.2. MySQL バージョン間のレプリケーション互換性 |
スレーブでは log-bin の設定をする必要は無いが、スレーブをマスターに昇格させる場合などのために、マスターもスレーブも同じ設定にしておく。 |
マスター、スレーブそれぞれの my.cnf に下記の設定を追記して、MySQL を再起動する。
[mysqld] server-id = 一意の数字 log-bin = mysql-bin relay-log = relay-log
- server-id
- 1 から 2^23 - 1 までの整数値で、マスター、スレーブで一意の数値にする必要がある。
- log-bin
- バイナリログのファイル名を指定する。
- relay-bin
- リレーログのファイル名を指定する。
マスターにレプリケーション専用のユーザーを登録する
マスターサーバに、レプリケーション専用のユーザを登録するには、次のような SQL を実行する。
GRANT REPLICATION SLAVE ON *.* TO repl@'192.168.1.0/255.255.255.0' IDENTIFIED BY 'password';
レプリケーション専用ユーザ repl パスワード password 接続許可するホストのアドレス 192.168.1.0/255.255.255.0
マスターサーバのスナップショットを作成する
マスターサーバのスナップショットを作成するには、MySQL サーバ稼動時にデータベースを読み込み専用状態にし(書き込みさせないようにして)、データベースファイルのあるディレクトリを丸ごと tar で固めてしまう。
echo "FLUSH TABLES WITH READ LOCK;" | mysql -u root -pパスワード cd /var/lib/mysql tar cpf /var/tmp/db-master-snapshot.tar . echo "SHOW MASTER STATUS\G" | mysql -u root -pパスワード >> /var/tmp/db-master-snapshot_show-master-status.txt echo "UNLOCK TABLES;" | mysql -u root -pパスワード
- FLUSH TABLES WITH READ LOCK を実行し、すべてのデータベースを読み込み専用にする。
- データベースファイルのあるディレクトリに移動。
- データベースのディレクトリを丸ごと tar で固める。(/var/tmp/db-master-snapshot.tar)
- SHOW MASTER STATUS を実行し、バイナリログの Position 値を調べる。(/var/tmp/db-master-snapshot_show-master-status.txt)
- UNLOCK TABLES を実行し、読み込み専用にしていたデータベースのロックを解除する。
db-master-snapshot_show-master-status.txt の内容はこのような感じになる。
*************************** 1. row *************************** File: mysql-bin.000020 Position: 79 Binlog_Do_DB: Binlog_Ignore_DB:
この内容(SHOW MASTER STATUS の内容)は、スレーブサーバでマスターサーバへの接続設定をする時に使用する。 |
マスターサーバのスナップショットを元に、スレーブを作成する
マスターサーバのスナップショットを元にスレーブの作成をおこなうことになるが、スナップショット作成後、すぐにスレーブの作成をおこなう必要は無い。数時間後、数日後でも問題は無い。 |
スレーブサーバにあるデータベースを全て削除しておき、マスターサーバのスナップショット db-master-snapshot.tar をスレーブサーバにコピー&展開する。 次に、スレーブサーバでマスターサーバへの接続設定をし、スレーブを実行すれば、レプリケーションが開始される。
/etc/init.d/mysqld stop cd /var/lib/mysql rm -rf * tar -xpf /var/tmp/db-master-snapshot.tar -C /var/lib/mysql/ /etc/init.d/mysqld start
- MySQL サーバを停止。
- データベースのあるディレクトリに移動。
- データベースファイルを全て削除。
- マスターサーバのスナップショットをデータベースディレクトリに展開。
- MySQL サーバを開始。
スレーブサーバへ接続し、次の SQL を実行する。
CHANGE MASTER TO MASTER_HOST='192.168.1.2', MASTER_USER='repl', MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000020', MASTER_LOG_POS=79; START SLAVE;
- CHANGE MASTER TO でマスターサーバに接続する設定をする。この時に、マスターサーバのスナップショットを作成した時に記録した File: mysql-bin.000020 と Position: 79 を指定する。
- START SLAVE でスレーブを開始する。
レプリケーションが正常に行われているか確認する方法
MySQL のレプリケーションは、スレーブサーバからマスターサーバへ接続し、スレーブサーバ内で I/Oスレッド と SQLスレッド を実行する。このため、レプリケーションが正常に動作しているかを確認するには、スレーブサーバ内の I/Oスレッド と SQLスレッド のステータスを調べればよい。
- スレーブサーバに接続
- SHOW SLAVE STATUS\G でスレーブの状態を表示
$ mysql -u root -p mysql> SHOW SLAVE STATUS\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.1.2 省略 Slave_IO_Running: Yes Slave_SQL_Running: Yes 省略
Slave_IO_Running: と Slave_SQL_Running: が両方とも YES になっていると、スレーブは問題なく動作していることになる。
- Slave_IO_Running: No の場合
- I/O スレッドに問題が発生している。
- マスターサーバに接続できない(接続ユーザー名が間違っているなど)や、ディスクに空きがないなど。
- Slave_SQL_Running: No の場合
- SQL スレッドに問題が発生している。
- クライアントがスレーブサーバに更新系の SQL を発行したなど。
マスターのバイナリログの削除
マスターサーバでは、バイナリログ(mysql-bin.xxxxxxx)が増え続けるので、削除する必要がある。
バイナリログを rm
コマンドなどで削除するのではなく、PURGE MASTER LOGS
構文でパージする。
まずは、SHOW MASTER STATUS;
でバイナリログのファイル名を確認する。
mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000010 | 118263 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec)
次に、PURGE MASTER LOGS
でパージする。
mysql> purge master logs to 'mysql-bin.000010'; Query OK, 0 rows affected (5.08 sec)
実行すると mysql-bin.000010 が残り、それより古い mysql-bin.000009, mysql-bin.000008, ... が削除できる。
参考ページ
- 現場指向のレプリケーション詳説
- http://www.irori.org/doc/mysql-rep.html
- MySQL 4.1 リファレンスマニュアル - 4 データベース管理 - 4.11 MySQL のレプリケーション
- http://dev.mysql.com/doc/refman/4.1/ja/replication.html
- MySQL 5.1 リファレンスマニュアル - 5 レプリケーション
- http://dev.mysql.com/doc/refman/5.1/ja/replication.html
MySQL 関連のページ
- Cacti に MySQL サーバの統計情報を記録する . . カテゴリ: Cacti | MySQL | rrdtool | システム監視
- CentOS/MySQL InnoDB Plugin を追加インストールする . . カテゴリ: CentOS | MySQL
- Mediawiki/Tips . . カテゴリ: Mediawiki | MySQL
- MySQL のメンテナンスコマンド . . カテゴリ: MySQL
- MySQL スレーブで SQL スレッドが停止した場合の対処方法 . . カテゴリ: MySQL
- phpMyAdminのインストール . . カテゴリ: MySQL | Webアプリ