MySQLレプリケーション覚書

環境

OS MySQL host(仮)
マスター側 Fedora Core5 4.0.27(RPM mymas.ter
スレーブ側 CentOS4(X86_64) 4.0.27(RPM mysla.ve
  • マスターは稼働中、スレーブはMySQLインストール直後
  • マスターではlog-binは有効にしていない
  • 一部データベースにInnoDBテーブル有り

事前準備

マスター側のMySQLを参照するスクリプトを停止(メンテ中表示)し、全てのクエリが発行されないようにしておく。

【マスター側】

1.スレーブサーバが接続に使用するMySQLユーザーを設定し、REPLICATION SLAVE権限のみ与える。
ユーザー(仮) replic
パスワード(仮) reprep
ホスト 全てのホスト


mysql> GRANT REPLICATION SLAVE ON *.* TO replic@'%' IDENTIFIED BY 'reprep';

2.MySQLへログインし、以下のコマンドを発行


mysql> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW MASTER STATUS;
Empty set (0.00 sec)

今回のマスターサーバは、log-binを有効にせずに稼働していたので、SHOW MASTER STATUSはEmptyとなった。
この場合、ログ名は空白文字列('')、オフセット値は4となる。

log-binが有効の場合は、SHOW MASTER STATUS は以下のような出力を返す
Fileカラムがログ名を、Positionがオフセット値を示す。


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

3.テーブルのロックを解除せずにMySQLサーバをシャットダウンする。


# mysqladmin -p***** shutdown

4.カレントディレクトリをマスターサーバのデータディレクトリに変更し、MySQLデータのスナップショットを撮る


# cd /var/lib/mysql
# tar cpf /tmp/mysql-snapshot.tar .

作成されたtarファイルは、556MB。ほとんど一瞬で作成された。
(既にバイナリログがある場合は、--excludeオプションでバイナリログをコピー対象から除外する)
これを、スレーブサーバ側にコピーする


# cd /tmp
# scp mysql-snapshot.tar user@mysla.ve:/tmp/mysql-snapshot.tar
これには5分ほどかかった。
マスターサーバの停止時間を最小限にとどめたいならば、これは『6.マスターサーバを再起動する』の後で行う。

5.マスターサーバのmy.cnfにlog-binオプション追加


# vi /etc/my.cnf

[mysqld]
log-bin
server-id = 1
6.MySQLサーバを再起動する


# /usr/bin/mysqld_safe --user=mysql &

7.事前準備で停止状態にしておいたスクリプトを復活


☆マスター側は、ここで通常稼働に戻る。ここまで約10分。思ったよりあっけなかった。


【スレーブサーバ】

8.スレーブサーバのMySQLを停止し、そのmy.cnfファイルに以下を追加


# mysqladmin -p***** shutdown
# vi /etc/my.cnf

[mysqld]
server-id = 2
9.カレントディレクトリをスレーブのMySQLデータディレクトリに変更し、マスターサーバからコピーしたtarファイルをアンパックする。


# cd /var/lib/mysql
# tar xpf /tmp/mysql-snapshot.tar

マスター用のエラーログは不要なので削除


# rm -f mymas.ter.err

10.スレーブサーバを起動する


# /usr/bin/mysqld_safe --user=mysql --log-warnings &

あ、あれ?起動しない。。。


# vi /usr/lib/mysql/mysla.ve.err

...
070818 11:18:32  mysqld started
InnoDB: Error: log file /var/lib/mysql/ib_logfile0 is of different size 0 67108864 bytes
InnoDB: than specified in the .cnf file 0 5242880 bytes!
070818 11:18:32 Can't init databases
070818 11:18:32 Aborting

070818 11:18:32  InnoDB: Warning: shutting down a not properly started
                 InnoDB: or created database!
070818 11:18:32 /usr/sbin/mysqld: Shutdown Complete

070818 11:18:32  mysqld ended

そうか、InnoDBのログファイルサイズがマスターとスレーブで違うからエラーになったんだ。


# vi /etc/my.cnf

innodb_log_file_size = 64M (←マスターサーバと同じにする)


# /usr/bin/mysqld_safe --user=mysql --log-warnings &

OK. 今度は起動した。

11.スレーブで以下のコマンドを実行


mysql> CHANGE MASTER TO
-> MASTER_HOST='mymas.ter',
-> MASTER_USER='replic',
-> MASTER_PASSWORD ='reprep',
-> MASTER_LOG_FILE='', (←2.で取得したログ名)
-> MASTER_LOG_POS=4; (←2.で取得したオフセット値)

12.スレーブスレッドを開始


mysql> START SLAVE

念のため、エラーログをチェック


# vi /usr/lib/mysql/mysla.ve.err

...
070818 11:40:27 Slave I/O thread: connected to master 'replic@mymas.ter:3306',
 replication started in log 'FIRST' at position 4


おしまい。