MySQLサーバを二重化し、マスター機からスレーブ機へレプリケーションする。MySQLでは、1台のマスタと複数台のスレーブの間でレプリケーションをすることができる。更新処理はマスタで行い、検索処理はマスタとスレーブで行えるが、普通はパフォーマンスを上げるためにマスタは更新専用にする。データの更新は非同期なので、スレーブの台数やパフォーマンスにマスタの動作が引っ張られることはない。そのかわり常にすべてのサーバで同じ情報があることは保障されない。
まず、マスターの設定をする。
[root@db1 ~]# vi /etc/my.cnf ... [mysqld] log-bin = mysql-bin server-id = 1 ...
マスターは更新処理の内容をバイナリログというファイルに書き込み、スレーブはそのファイルを読み込んで自分のデータを更新する。server-idは何でもよいが、ユニークな値を付与する。
マスターでMySQLを再起動し、レプリケーション用のユーザを追加する。
mysql>root@db1 ~]# service mysqld restart Stopping MySQL: [ OK ] Starting MySQL: [ OK ] [root@db1 ~]# mysql -u root -p Enter password: mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%.grandarbre.net' IDENTIFIED BY 'PASSWORD123'; Query OK, 0 rows affected (0.00 sec)
次にマスターでレプリケーション情報を取得する。まずすべてのデータをフラッシュし、書き込みステートメントをブロックする。
[root@db1 ~]# mysql -u root -p Enter password: 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.000001 | 158995 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) mysql>
そうして、スレーブに初期同期させるためのデータダンプを取得する。
[root@db1 ~]# mysqldump --all-databases --lock-all-tables -u root -p > /tmp/dbdump.db Enter password:
次にスレーブの設定をする。
[root@db2 ~]# vi /etc/my.cnf ... [mysqld] server-id=2 ...
設定例によっては、my.cnfにマスターのホスト名や認証情報などを書いている場合もある。しかしいったんスレーブが設定されると、これらの情報は/var/lib/mysql/master.infoに保存されてmy.cnfは無視されるので、my.cnfに書く必要はない。
ここでスレーブのMySQLを再起動する。
[root@db2 ~]# service mysqld restart Stopping MySQL: [ OK ] Starting MySQL: [ OK ]
先ほどマスターで取得したダンプをFTPなどでスレーブにコピーし、MySQLに読み込ませる。
[root@db2 ~]# mysql -u root -p < /tmp/dbdump.db Enter password:
スレーブのDBをマスターに接続する。
[root@db2 ~]# mysql -u root -p
Enter password:
mysql> CHANGE MASTER TO
-> MASTER_HOST='db1',
-> MASTER_USER='repl',
-> MASTER_PASSWORD='replpass123',
-> MASTER_LOG_FILE='mysql-bin.000001',
-> MASTER_LOG_POS=158995;
Query OK, 0 rows affected (0.16 sec)
スレーブを開始する。
mysql> start slave; Query OK, 0 rows affected (0.00 sec)
ここまでの作業でレプリケーションはできているはず。
マスターの状態を表示する。
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000002
Position: 186113
Binlog_Do_DB:
Binlog_Ignore_DB:
1 row in set (0.00 sec)
スレーブの状態を表示する。Slave_IO_Running:とSlave_SQL_Running:がyesだとslaveとして動いている。
mysql>
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: db1
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000002
Read_Master_Log_Pos: 186113
Relay_Log_File: db2-relay-bin.000004
Relay_Log_Pos: 186250
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 186113
Relay_Log_Space: 186250
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
1 row in set (0.00 sec)
mysql>
マスターでプロセスを見てみる。Binlog Dumpがあればよい。
mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
Id: 22
User: root
Host: localhost
db: mt
Command: Query
Time: 0
State: NULL
Info: SHOW PROCESSLIST
*************************** 2. row ***************************
Id: 41
User: repl
Host: db2.grandarbre.net:56174
db: NULL
Command: Binlog Dump
Time: 323
State: Has sent all binlog to slave; waiting for binlog to be updated
Info: NULL
2 rows in set (0.00 sec)
mysql>
スレーブでもプロセスを見ると、2つのConnectがある。
mysql> show processlist\G
*************************** 1. row ***************************
Id: 2
User: root
Host: localhost
db: mt
Command: Query
Time: 0
State: NULL
Info: show processlist
*************************** 2. row ***************************
Id: 3
User: system user
Host:
db: NULL
Command: Connect
Time: 191
State: Waiting for master to send event
Info: NULL
*************************** 3. row ***************************
Id: 4
User: system user
Host:
db: NULL
Command: Connect
Time: 11
State: Has read all relay log; waiting for the slave I/O thread to update it
Info: NULL
3 rows in set (0.00 sec)
mysql>