mysqld_multiを使い、MySQLを複数起動して、Master-Slave構成でReplicationを取るまで

経緯

一つの開発用サーバでmysqlのreplicationを利用したscriptを作成しなくてはならなくなり、戦友:id:maroekunから教えてもらった mysqld_multiを利用してみることにした。

mysqld_multiとは

MySQL MySQL 4.1 リファレンスマニュアル 4.8.3 mysqld_multi(複数の MySQL サーバを管理するプログラム)

mysqld_multi は、さまざまな Unix ソケットおよび TCP/IP ポートをリッスンする複数の mysqld プロセスを管理するためのプログラムです。

ようは、一つのmysqld で複数プロセスを立ち上げることができます。

もちろん、複数プロセス間でreplicationを取ることも可能です。

設定

/etc/my.cnf
の設定はこんな感じです

[mysqld_multi]
mysqld     = /usr/bin/mysqld_safe
mysqladmin = /usr/bin/mysqladmin

[mysqld]
default-character-set = utf8
user=mysql

[mysqld1]
server-id = 1
port      = 3306
datadir   = /data/var/lib/mysql
socket    = /var/lib/mysql/mysql.sock
pid-file  = /var/run/mysqld/mysqld.pid

[mysqld2]
server-id = 2
port      = 3307                       <= netstat で使われていないportであることを確認しましょう
datadir   = /var/db_multi/db           <= 自分で理解しやすい名前なら、どこに作ってもいいです
socket    = /var/db_multi/mysql.sock
pid-file  = /var/db_multi/mysqld.pid

同時起動したい数だけ、[mysqld*]を追加しましょう。
共通の設定項目は、[mysqld]にかけばおk。
[mysqld_multi]には、mysqld_safeとmysqladminを記載。


※[mysqld1]は既に設定済みで稼動していたので、[mysqld2]の設定をします

dir作っておきましょう。

mkdir -P /var/db_multi/db


mysqlユーザにして

chown mysql:mysql /var/db_multi/


datadirの初期化ー

mysql_install_db --datadir=/var/db_multi/db --user=mysql
起動
mysqld_multi start 1,2
  もしくは
mysqld_multi start 1-2

で起動します

mysqld_multi report

叩けば

Reporting MySQL servers
MySQL server from group: mysqld1 is running
MySQL server from group: mysqld2 is running

こんな風に複数起動が確認できるはず。

ps aux | grep mysql

でも確認できるかな

使ってみる

[mysqld1]を Master として利用し、
[mysqld2]を Slave として利用してみます。


これらはPort番号で区別できるので、Portを指定してmysqlコマンドを実行します

Masterへ

mysql -u user_name -P 3306 -h 127.0.0.1

Slaveへ

mysql -u user_name -P 3307 -h 127.0.0.1

-h 127.0.0.1 をかかないとSlaveにログインできないのでご注意を

Replication

ここから、Replication設定。
とはいっても、普通のReplication設定と同じです。
mysqld_multiだからといって、特別な意識はいらないです。

1./etc/my.cnfに追加

/etc/my.cnf

[mysqld1]
server-id = 1
port      = 3306
datadir   = /data/var/lib/mysql
socket    = /var/lib/mysql/mysql.sock
pid-file  = /var/run/mysqld/mysqld.pid
sync_binlog=1
log-bin=mysql-bin
log-bin-index=mysql-bin
relay-log=relay-bin
relay-log-index=relay-bin

[mysqld2]
server-id = 2
port      = 3307
datadir   = /var/db_multi/db/
socket    = /var/db_multi/mysql.sock
pid-file  = /var/db_multi/mysqld.pid
read_only
log-slave-updates
log-bin=mysql-bin
log-bin-index=mysql-bin
relay-log=relay-bin
relay-log-index=relay-bin

このように、binlogの設定など、Replicationの準備をします。

2.Replication用Userの作成

Master側に、Replication用のUserを作っておきましょう

mysql> GRANT REPLICATION SLAVE ON *.* TO
   repl@10.0.0.0 IDENTIFIED BY 'password';

ユーザ名は、【repl】である必要はありません。
接続元IPは、MasterとSlaveは同じなので、普通にサーバIPをかけば問題ありません。

3.Masterデータの更新lock

データをslaveに移すので、masterの更新をlockします

mysql> FLUSH TABLES WITH READ LOCK;
4.logのposiの確認

Masterで【show master status】を実行します

mysql> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 |  2283327 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.10 sec)

[File]と[Position]をメモしましょう。
あとで使います。

5.データのコピー

では、lockしたまま、MasterデータをSlaveに移しましょう

cp -aR /data/var/lib/mysql/* /var/db_multi/db/
6.masterのunlock

ここまできたら、Masterの更新Lockを戻してあげましょう

mysql> UNLOCK TABLES;
7.Slave側でReplicationのためのパラメータ設定
mysql> CHANGE MASTER TO
        MASTER_HOST='10.0.0.0',             <=今回はMasterもSlaveも同一サーバなので自分のIP
        MASTER_USER='repl',                 <=2で作ったUser名
        MASTER_PASSWORD='password',         
        MASTER_LOG_FILE='mysql-bin.000003', <=4で記録した[File]名
        MASTER_LOG_POS=2283327 ;            <=4で記録した[Position]
8.Replication start
mysql> start slave;


起動したかどうかは、

mysql> show slave status;

で確かめましょう。

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

であれば正常に動いています。


もし、
[IO_Running]だけが No の場合は、Replicationがうまく設定できていない可能性が、
[SQL_Running]だけが No の場合は、何らかのSQLによりReplicationエラーになっている可能性が高いです