MySQLのレプリケーション(MyISAM)

2004/11/09

MySQLのレプリケーションをやってみましたので、メモとして残しておきます。

今回はMyISAMだけのデータベースでやってみました。innoDBを利用している場合、以下の方法ではうまくいきませんので注意してください。

なお、以下の設定方法はマニュアルに同様のことが書かれていますので、そちらも参照されることをお勧めします。

また、MySQL4.1のSSLによるレプリケーションはMySQLをSSLでレプリケーションのほうを参照してください。


レプリケーションとは

レプリケーションとは、複数サーバ間でデータを複製する機能だと私は思います。また、それに付随した機能も含めることがあるようです。


MySQLのレプリケーション機能について

MySQLでは、一方方向でのレプリケーションが利用できます。

マスター・サーバからスレーブ・サーバへのコピーだけができます。スレーブ・サーバからマスター・サーバへのコピー機能はありません。ですから、スレーブ・サーバ側でデータベース更新はできません。

マスター・サーバでのデータベース更新はスレーブ・サーバへ自動的に反映されます。

また、スレーブ・サーバーは複数指定ができますが、マスター・サーバーは1つのみです。


server-idについて

MySQLではmy.cnfに設定したserver-idを利用して複製されるようです。このID設定を間違えるとレプリケーションがうまく機能しないようです。 私自身、server-idの設定を間違えて、ハマりましたのでこれから準備される方は充分注意してください。

server-idは、IPアドレスと同じ考え方でユニークな値にする必要があります。


マスター・サーバーの準備と設定

  1. Vine Linuxなどで、rpmからインストールしているとmy.cnfが初期値では存在しません。現在、my.cnfが存在するかを確認します。
    $ su -
    # ls /etc/my.cnf
  2. my.cnfが無かった場合、my.cnfのヒナ方をコピーしておきましょう。
    # cp /usr/share/mysql/my-medium.cnf /etc/my.cnf
  3. my.cnfを編集します。
    # emacs /etc/my.cnf
    [mysqld]
    # 以下の行があるかを確認する。なければ追加しておく。
    log-bin
     
    # 以下の行があるかを確認。なければ追加しておく。
    # なお「1」は間違えやすいので適当に変えるほうがいいでしょう。
    server-id = 1
     
    # MySQLクライアント・サーバ間のパケットサイズ
    # この設定値はマスター、スレーブとも同じにしておく必要があります。
    max_allowed_packet=16M
    my.cnfを変更したら、MySQLサーバを再起動して設定値を有効にします。
    # /etc/init.d/mysql restart
    # exit
  4. MySQLのデータベースが保存されているディレクトリを調べます。
    $ echo 'show variables' | mysql -u root -p | grep datadir
    datadir /var/lib/mysql/
    上記のように表示されると思います。このディレクトリをひかえておきます。
  5. レプリケーション用のMySQLユーザーを作成します。以下ではslave_userをユーザー名、'ABCD'をパスワードにしていますので、ご自身で適当に値を変えてください。
    $ mysql -u root -p
    mysql> GRANT REPLICATION SLAVE ON *.* TO slave_user@'%' IDENTIFIED BY 'ABCD';
  6. キャッシュされている書き込みをフラッシュし、データベースへの書き込みを禁止します。
    mysql> FLUSH TABLES WITH READ LOCK;
  7. マスター・サーバーのログ名とオフセット値を調べます。
    mysql> SHOW MASTER STATUS;
    以下のように表示されるので、FileとPositionを正確に控えてください。
    +-----------------+----------+--------------+------------------+
    | File			  | Position | Binlog_do_db | Binlog_ignore_db |
    +-----------------+----------+--------------+------------------+
    | server1-bin.065 | 4		 |				|				   |
    +-----------------+----------+--------------+------------------+
    1 row in set (0.00 sec)
    上記例では「server1-bin.065」「4」をひかえておくことになります。
    この後、mysqlコマンドからぬけないようにしてください。ロックしたままの状態で、別コンソールを起動して以下の操作してください。
  8. 現在のデータベースの状態をtarを使って圧縮保存しておきます。ここではdatadirが/var/lib/mysqlとして書いてありますので、ご自身の環境に変えてください。

    すべてのデータベースをレプリケーションするのなら、次のようにして先ほど調べたディレクトリをすべて保存しておきます。
    $ su -
    # cd /var/lib
    # tar cpzf db.tar.gz mysql

    一部のデータベースをレプリケーションするのなら、次のようにして先ほど調べたディレクトリの中の1つのディレクトリを保存しておきます。DATABASE_NAMEはレプリケーションしたいデータベース名です。
    $ su -
    # cd /var/lib
    # tar cpzf db.tar.gz mysql/DATABASE_NAME

  9. マスター・サーバのロックを解除します。さきほど、mysqlコマンドを入力したままの状態で放置してあるコンソールに切り替えて、次のようにします。
    mysql> UNLOCK TABLES;
    これで、マスター・サーバ側は通常どおり使えます。データ更新をしても問題ありません。

スレーブ・サーバーの設定

  1. マスター・サーバと同様にmy.cnfがあるかをチェックします。
    # ls /etc/my.cnf
  2. my.cnfが無かった場合、my.cnfのヒナ方をコピーしておきましょう。
    # cp /usr/share/mysql/my-medium.cnf /etc/my.cnf
  3. my.cnfを編集します。
    # emacs /etc/my.cnf
    [mysqld]
    # 以下の行があるかを確認する。なければ追加しておく。
    log-bin
     
    # 以下の行があるかを確認。なければ追加しておく。
    # なお、レプリケーションするサーバ間でユニーク値にしてください。
    server-id = 200
     
    # レプリケーションしたいデータベース名。
    # 全データベースをレプリケーションするなら指定の必要はありません。
    # 複数のデータベースをレプリケーションする場合は以下のように複数行記入します。
    replicate-do-db=DATABASE_NAME1
    replicate-do-db=DATABASE_NAME2
     
    # MySQLクライアント・サーバ間のパケットサイズ
    # この設定値はマスター、スレーブとも同じにしておく必要があります。
    max_allowed_packet=16M
    my.cnfを変更したら、MySQLサーバを再起動して設定値を有効にします。
    # /etc/init.d/mysql restart
    # exit
  4. MySQLのデータベースが保存されているディレクトリを調べます。
    $ echo 'show variables' | mysql -u root -p | grep datadir
    datadir /var/lib/mysql/
    上記のように表示されると思います。このディレクトリをひかえておきます。
  5. MySQLデーモンを停止しておきます。
    $ su -
    # /etc/init.d/mysql stop
  6. 先ほどマスター・サーバー側で作成したデータベースのtar圧縮データ(この例ではdb.tar.gz)をスレーブ・サーバへftpなどでコピーします。
  7. 圧縮されたファイルを、先ほど調べたdatadir以下に解凍します。ここではdatadirが/var/lib/mysqlとして書いてありますので、ご自身の環境に変えてください。
    # cd /var/lib
    # tar zxvf db.tar.gz
  8. スレーブ・サーバーを起動します。
    # /etc/init.d/mysql start
    # exit
  9. スレーブ・サーバにマスター・サーバの情報を設定します。
    $ mysql -u root -p
    mysql> CHANGE MASTER TO
        -> MASTER_HOST='マスターのホスト名',
        -> MASTER_USER='slave_user',
        -> MASTER_PASSWORD='マスター側のパスワード',
        -> MASTER_LOG_FILE='ログ名(Fileの値)',
        -> MASTER_LOG_POS=4 (Positionの値);
  10. スレーブ・スレッドを開始します。
    mysql> START SLAVE;
    mysql> exit

念のため、マスター・サーバ側で更新操作をしてみましょう。スレーブ・サーバにも更新は反映されるはずです。

なお、一度、マスターサーバ側でデータベースの保存操作(この例ではdb.tar.gz)をしていれば、いくつでもスレーブ・サーバを作っていくことができます。マスター側で行われた更新は、自動的にスレーブ側も追随します。


参考にした情報

Copyright©2001-2019 釣ったよ! All Right Reserved.    sg@tsuttayo.jpn.org