MySQL レプリケーションの設定

提供:maruko2 Note.
移動: 案内, 検索

目次

MySQL レプリケーションの特徴

mysql-replication-1.png

これらレプリケーションの特徴を利用する事で、MySQL の処理をスケールアウトさせたり、データベースをバックアップしたり、遠隔地にスレーブを設置したりなどに利用することができる。

MySQL レプリケーションの動作概要

mysql-replication-2.png

MySQL のレプリケーションの動きは大まかに次のような動作となっている。

マスターサーバの動作
データベースを更新したすべての SQL コマンドをログファイル(バイナリログ)に記録する。
スレーブサーバの動作
マスタに接続しバイナリログを読み込みリレーログとして保存する。(I/O スレッド)
保存したリレーログをスレーブで実行し、スレーブとマスタのデータベースを同じ内容にする。(SQL スレッド)

レプリケーションのセットアップ

MySQL でレプリケーションをセットアップするには、次のような操作をすればよい。

  1. マスター、スレーブのそれぞれの my.cnf にレプリケーション用の追加記述をする。
  2. マスターにレプリケーション専用のユーザーを登録する。
  3. マスターデータベースのスナップショットを作成する。
  4. マスターデータベースのスナップショットを元に、スレーブを作成する。

レプリケーション用の my.cnf 設定

重要

マスターとスレーブのバージョンは、必ずしも同じにする必要は無いが、同じにしておいた方がトラブルは少ない。MySQL 5.1 リファレンス - 5.4.2. MySQL バージョン間のレプリケーション互換性
アーキテクチャの違いは問題ない。(i386, x86_64, ppc など。)

スレーブでは 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パスワード
  1. FLUSH TABLES WITH READ LOCK を実行し、すべてのデータベースを読み込み専用にする。
  2. データベースファイルのあるディレクトリに移動。
  3. データベースのディレクトリを丸ごと tar で固める。(/var/tmp/db-master-snapshot.tar)
  4. SHOW MASTER STATUS を実行し、バイナリログの Position 値を調べる。(/var/tmp/db-master-snapshot_show-master-status.txt)
  5. 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
  1. MySQL サーバを停止。
  2. データベースのあるディレクトリに移動。
  3. データベースファイルを全て削除。
  4. マスターサーバのスナップショットをデータベースディレクトリに展開。
  5. 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;
  1. CHANGE MASTER TO でマスターサーバに接続する設定をする。この時に、マスターサーバのスナップショットを作成した時に記録した File: mysql-bin.000020Position: 79 を指定する。
  2. START SLAVE でスレーブを開始する。

レプリケーションが正常に行われているか確認する方法

MySQL のレプリケーションは、スレーブサーバからマスターサーバへ接続し、スレーブサーバ内で I/OスレッドSQLスレッド を実行する。このため、レプリケーションが正常に動作しているかを確認するには、スレーブサーバ内の I/OスレッドSQLスレッド のステータスを調べればよい。

  1. スレーブサーバに接続
  2. 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 関連のページ

LINEで送る このエントリーをはてなブックマークに追加
個人用ツール
名前空間
変種
表示
操作
案内
ツールボックス

注目のページ

このサイトのはてなブックマーク数