MySQL Replication

レプリケーションの作り方について。
MySQL レプリケーションの設定 – とみぞーノートさま
現場指向のレプリケーション詳説 – IRORI.ORGさま
と、参考になるところはいっぱいあるのだが、自分で書かないと覚えられないたちなので仕方がない。
MySQLのドキュメントだと5.1.1. レプリケーションのセットアップ方法とか12.6. 複製ステートメントとかの辺り。

要はMasterで発行されたSQLをSlaveでもそのまま実行するということ。
とりあえず作り方。

  1. まず、普通に2台作る。
  2. [MASTER] my.cnf にサーバーIDなどを書き足す
    [mysqld]
    log-bin=mysql-bin
    server-id=168001012

    「log-bin」はバイナリログを取っておく、という指定。
    「server-id」は適当にSlaveとかぶらないものを指定する。
    required unique id between 1 and 2^32 – 1
    ということなので、1 から 4,294,967,295 の範囲内で。
    今回はサーバのIPアドレス、下3つを採用。

  3. [MASTER] ログイン
    mysql -u root -p
  4. [MASTER] SlaveからMasterに接続する際のユーザーを作成する
    mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.13' IDENTIFIED BY 'slave_password';

    「repl」はユーザー名。ほかの用途に使わないようなものを指定する。
    「192.168.1.13」はSlave側のアドレス。
    Slaveが複数ある場合には「192.168.1.0/255.255.255.0」とかのほうがいいかも。

    mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.0/255.255.255.0' IDENTIFIED BY 'slave_password';

    こんなカンジで。

  5. [MASTER] 書き込みをブロックする
    mysql> FLUSH TABLES WITH READ LOCK;

    この状態だと読み込みはOKということになる。

  6. [MASTER] データのバックアップを取る
    mysqldumpが使える環境であれば、こちらの方が容量が少なくなるのでオススメ。
    –all-databases → すべてのデータベースをDumpする。
    –add-drop-database → それぞれのデータベースをCREATEする前に「DROP DATABASE …」文を書き加える。
    –add-drop-table → それぞれのテーブルをCREATEする前に「DROP TABLE …」文を書き加える。
    –add-drop-trigger → それぞれのトリガをCREATEする前に「DROP TRIGGER …」文を書き加える。
    ※ –add-drop-database 、 –add-drop-table 、 –add-drop-trigger をつけた場合、
    当然だけど既存の同名データベース・同名テーブル・同名トリガは削除される。
    -x → 「–lock-all-tables」と同義でDump中、全てのデータベースをロックする。
    –master-data=1 → 「CHANGE MASTER TO …」文でMasterへ接続するためのパラメータも書いてくれる。「–master-data=2」にすると、「CHANGE MASTER TO …」文をコメントアウトして書き残す。
    デフォルトは「1」なので「–master-data」だけで良い。

    mysqldump -u root -p --all-databases --add-drop-database --add-drop-table -x >> /tmp/sqldump_20120807.sql

    個別のデータベースのDUMPを出力する場合は以下のようにする
    –databases [db_name] → [db_name] で指定したデータベースのみDumpする。

    mysqldump -u root -p --databases db_name --add-drop-database --add-drop-table -x >> /tmp/sqldump_20120807_db_name_only.sql

    mysqldumpが使えない時は「/var/lib/mysql」配下をすべてtarで固める。

    tar -cpf /var/tmp/mysql.tar /var/lib/mysql
  7. [MASTER] Master側のステータスを確認しておく
    この値はあとでSlaveからMasterへ接続するときに使用する。

    mysql > SHOW MASTER STATUS;
    +------------------+----------+--------------+------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +------------------+----------+--------------+------------------+
    | mysql-bin.000024 | 49005253 | test         | manual,mysql     |
    +------------------+----------+--------------+------------------+
  8. [MASTER] バックアップをMasterからSlaveにコピー
    scp -Cqp /tmp/mysqldump_20120807.sql root@192.168.1.13:/tmp/mysqldump_20120807.sql
    scp -Cqp /var/tmp/mysql.tar root@192.168.1.13:/var/tmp/mysql.tar
  9. [MASTER] 読み込みロックを解除する
    mysql> UNLOCK TABLES;
  10. [MASTER] 終わったらMySQLからログアウトする。
  11. [SLAVE] my.cnf にサーバーIDなどを書き足す
    [mysqld]
    log-bin=mysql-bin
    server-id=168001013

    「log-bin」はSlaveのみであれば特に必要ないが、
    binary logging – not required for slaves, but recommended
    という記述があるので、一応つけておく。
    Masterがコケた時、このSlaveがMasterになる可能性があるなら付けておく。
    「server-id」はMasterとかぶらないものを指定する。

  12. [SLAVE] コピーされたデータのバックアップを展開する
    mysql -u root -p < /tmp/sqldump_20120807.sql
    cd /var/lib/mysql
    rm -fr *
    tar xpf /var/tmp/mysql.tar
  13. [SLAVE] ログインし、Masterへ接続するためのパラメータを設定する
    mysqldumpで「–master-data」を1に設定した場合は上記で読み込ませた時に同時に実行されているはず。

    mysql> CHANGE MASTER TO MASTER_HOST='192.168.1.12', 
                            MASTER_USER='repl', 
                            MASTER_PASSWORD='password', 
                            MASTER_LOG_FILE='mysql-bin.000024', 
                            MASTER_LOG_POS=49005253;

    いきおい余って MASTER_LOG_POS の数値を「’」で囲まないように。
    文字列として認識されてハマります。
    実際に小1時間ハマりました。。。

  14. [SLAVE] Slaveを起動する
    mysql> START SLAVE;
  15. [SLAVE] Slaveの状態を確認する
    mysql> SHOW SLAVE STATUS;

    Slave_IO_Running と、 Slave_SQL_Running が両方ともYesになっていることを確認。
    Seconds_Behind_Master が0であれば、マスターに対する遅延も発生していない、ということになる、はず。

ここまでで Master <-> Slave の構築はできたかな?と。