MySQL5.1.30 でレプリケーション構成

MySQL5.1.30 でレプリケーション構成をテストしてみた。2台のマシンが確保できなかったので、同一マシンに2インスタンスを立てている。


レプリケーション設定を行うと、ユーザ名とパスワードは master.info ファイル内のテキスト ファイルに保存されるため、本来は、レプリケーション プロセスにだけ権限があるユーザを作成するべきである。今回は検証に使用するだけなので、特に専用のユーザは作成しない。作成する場合は、
http://dev.mysql.com/doc/refman/5.1/ja/replication-howto-repuser.html
に、ユーザの作成と、権限の GRANT について書いてある。


MySQLレプリケーション設定には、各サーバインスタンス毎の server-id 設定が必要。おそらくこの設定は my.cnf にしか設定できない。通常これは問題にならない。それぞれのサーバインスタンスの my.cnf に設定すればいいだけである。
しかし、今回、起動時の引数を変えるだけで同一マシン上に 2 インスタンス建ている。つまり、同じ my.cnf を参照しているので、異なる server-id を設定できない。

MySQL の my.cnf は以下のようなルールとなっている。

1 /etc/my.cnf グローバルオプション
2 $MYSQL_HOME/my.cnf サーバ固有オプション(MySQL5 以降くらいから?DATADIR ではなく MYSQL_HOME)
3 defaults-extra-file --defaults-extra-file=path で指定されたファイル
4 ~/.my.cnf ユーザ固有オプション

設定ファイルを 1 から 4 の順番で読み込みし、後から読み込んだ設定で、前の設定を上書きする。このルールの詳細についてはMySQL :: MySQL 5.6 リファレンスマニュアル :: 4.2.6 オプションファイルの使用を参照のこと。かなりややこしいので、あれ?と思ったらここを熟読のこと。


/etc/my.cnf しかない状態なので、/home/mysql/data の下に、新たに my.cnf を作成し、
スレーブ用の設定ファイルを置くことにした。

$ vi /home/mysql/data/my.cnf
[mysqld]
server-id=2


で、まず、マスタサーバを起動。

# mysqld_safe --user=mysql &

マスタに既存のデータがある場合は、まず最初にそのデータの同期を行って、データの状態をマスタ・スレーブ間で一致しておいてやる。マスタにログインし、データのフラッシュとステートメントのロックを行う。

# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.1.30-log Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000020 |      106 |              |                  | 
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

ここまでやったら、別のセッションで(別のtelnet窓で)、以下を実行し、データベースのダンプを取る。

# mysqldump --all-databases --lock-all-tables >dbdump.db


スレーブを --skip-slave オプション付きで起動し、取得した生ダンプをスレーブにインポートする。先ほど作成した、スレーブ用の my.cnf も指定する。--defaults-extra-file オプションで指定するのだが、mysqld_safe を使用する場合、最初の引数として指定しないとエラーになる。なんじゃそれは・・・。

# mysqld_safe \
--defaults-extra-file=/home/mysql/data/my.cnf \
--datadir=/home/mysql/data/ \
--basedir=/usr/local \
--user=mysql \
--socket=/tmp/mysqld-new.sock \
--port=3308 \
--skip-slave &

# mysql --socket=/tmp/mysqld-new.sock < dbdump.db

マスタ ステータス情報でスレーブを設定し、スレーブスレッドを立ち上げる。マスタ側で show master status; して取得した値を使用する。

# mysql --socket=/tmp/mysqld-new.sock
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.1.30-log Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> CHANGE MASTER TO
    -> MASTER_HOST='localhost',
    -> MASTER_PORT=3307,
    -> MASTER_USER='root',
    -> MASTER_PASSWORD='mysql',
    -> MASTER_LOG_FILE='mysql-bin.000020',
    -> MASTER_LOG_POS=106;
Query OK, 0 rows affected (0.20 sec)

mysql> START SLAVE;
Query OK, 0 rows affected (0.00 sec)


これで任意のマスタDBのテーブルに行追加、削除等を行うと、スレーブの方にもその修正が反映される。