MySQL 5.5 を使って、レプリケーション設定を行いましたので、記録しておきます。
かなり便利な機能ですので、必要に応じて積極的に使えるかと思います。
インフラ環境
今回は、マスターとスレーブの2台構成でレプリケーションを行います。
利用したバージョンは、MySQL 5.5.31 Community Server です。
OSはLinuxです(AWS EC2環境を利用)。
概念図は以下になります。(IPアドレスは分かりやすく置き換えています。)
なお、マスター側の「TCP 3306」に対して、スレーブ側からのアクセスを許可しておきます。
MySQLレプリケーションの特徴
MySQLのレプリケーションは一方向性の非同期複製です。
- マスターを更新、スレーブを読み取り専用とする等の使い分けが可能です。
- バックアップ取得の負荷対策として、スレーブ側でバックアップを取得する等の構成も可能です。
- スレーブは常にマスターに接続している必要はありません。遠隔地でも複製を行いやすいです。
設定手順
以降では、「マスター」と「スレーブ」に対する設定を時系列で記載していきます。
1.MySQLインストール(マスター&スレーブ)
まず、マスターとスレーブに、yumを使ってMySQLをインストールします。
# yum install mysql # yum install mysql-server # rpm -qa | grep mysql mysql55-common-5.5.31-1.32.amzn1.x86_64 mysql55-5.5.31-1.32.amzn1.x86_64 mysql55-server-5.5.31-1.32.amzn1.x86_64 mysql55-libs-5.5.31-1.32.amzn1.x86_64 mysql-5.5-1.3.amzn1.noarch mysql-server-5.5-1.3.amzn1.noarch #
以上で、MySQLのインストールは終了です。
2.MySQL起動とrootパスワード設定(マスター&スレーブ)
mysql-server をインストールすると、起動スクリプト「/etc/init.d/mysqld」が用意されますので、以下の手順でMySQLを起動します。
# /etc/init.d/mysqld start
次に、MySQL の rootアカウントにパスワードを設定します。(パスワード部分は適切な値で設定します)
# /usr/bin/mysqladmin -u root password 'hogehoge'
次からは、マスター、スレーブのそれぞれ個別での設定が入ってきます。
3.レプリケーション用アカウントの作成(マスター側)
マスター側でMySQLにログインし、スレーブ側から接続する為のアカウントを作成します。
mysql> grant replication slave on *.* to 'replication'@'192.168.0.2' identified by 'hogehoge'; Query OK, 0 rows affected (0.00 sec) mysql>
4.my.cnf 設定(マスター側)
マスター側の /etc/my.cnf で、レプリケーション用の設定を行います。
[mysqld] log-bin=mysql-bin server-id=101
my.cnf を変更したら、MySQLサーバを再起動します。
# /etc/init.d/mysqld stop Stopping mysqld: [ OK ] # /etc/init.d/mysqld start Starting mysqld: [ OK ] #
5.my.cnf 設定(スレーブ側)
次にスレーブ側の /etc/my.cnf で、レプリケーション用の設定を行います。
[mysqld] server-id=102
server-id は、マスター側とは異なる一意の値にする必要があります。
スレーブ側でも my.cnf を変更したので、MySQLを再起動します。
# /etc/init.d/mysqld status mysqld (pid 1642) is running... # /etc/init.d/mysqld stop Stopping mysqld: [ OK ] # /etc/init.d/mysqld status mysqld is stopped # /etc/init.d/mysqld start Starting mysqld: [ OK ] # /etc/init.d/mysqld status mysqld (pid 2031) is running... #
6.確認用データベースとテーブルデータの作成(マスター側)
後ほど、レプリケーション状況を確認する為に、確認用のデータベースとテーブル、データを作成します。
mysql> create database repltest; Query OK, 1 row affected (0.00 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | repltest | | test | +--------------------+ 5 rows in set (0.00 sec) mysql> connect repltest; Connection id: 3 Current database: repltest mysql> create table test(id int(8),title varchar(32)); Query OK, 0 rows affected (0.05 sec) mysql> insert into test values(1,'test'); Query OK, 1 row affected (0.03 sec) mysql> insert into test values(2,'checksite.jp'); Query OK, 1 row affected (0.03 sec) mysql> select * from test; +------+--------------+ | id | title | +------+--------------+ | 1 | test | | 2 | checksite.jp | +------+--------------+ 2 rows in set (0.00 sec) mysql>
7.念のため、スレーブ側でもDBを確認(スレーブ側)
スレーブ側で「repltest」データベースがない事を確認しておきます。
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | +--------------------+ 4 rows in set (0.00 sec) mysql>
まだ、「repltest」データベースはないです。よしよし。
8.スナップショットを作成(マスター側)
マスター側データベースのダンプデータを、スレーブ側に一旦持っていく為、ロックを掛けます。
mysql> flush tables with read lock; Query OK, 0 rows affected (0.00 sec) mysql>
ロックをかけた後に、マスター側のバイナリログの位置情報を取得しておきます。
mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 717 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) mysql>
このFile情報「mysql-bin.000001」とPosition情報「717」は、後ほどスレーブ側で行う設定で利用します。
次に別のターミナルで、マスター側データベースのダンプデータを取得します。
# /usr/bin/mysqldump -u root -p --all-databases --lock-all-tables > /root/dbdump.db Enter password: -- Warning: Skipping the data of table mysql.event. Specify the --events option explicitly. #
ダンプデータを取得したので、元のターミナルにてロックを外します。
mysql> unlock tables; Query OK, 0 rows affected (0.00 sec) mysql>
9.取得したダンプデータをスレーブ側に転送する(マスター側)
マスター側で取得したダンプデータをスレーブ側にscpで転送します。
# scp -i hogehoge.pem dbdump.db dba@192.168.0.2:/home/dba/ dbdump.db 100% 513KB 513.2KB/s 00:00 #
※アカウント名などは環境に合わせて置き換えてください。
10.ダンプデータの取り込み(スレーブ側)
スレーブ側でダンプデータを取り込みます。
# /usr/bin/mysql -u root -p < /home/dba/dbdump.db
取り込んだ結果をmysqlでログインして確認します。
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | repltest | | test | +--------------------+ 5 rows in set (0.00 sec) mysql> mysql> use repltest; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +--------------------+ | Tables_in_repltest | +--------------------+ | test | +--------------------+ 1 row in set (0.00 sec) mysql> select * from test; +------+--------------+ | id | title | +------+--------------+ | 1 | test | | 2 | checksite.jp | +------+--------------+ 2 rows in set (0.00 sec) mysql>
マスター側で取得したダンプデータを取り込む事が出来ています。
11.マスタ側の情報を登録(スレーブ側)
スレーブ側で、マスター情報を登録します。ここで、「8.スナップショットを作成(マスター側)」で取得したマスター側のバイナリログの位置情報を利用します。
mysql> change master to master_host='192.168.0.1', master_user='replication', master_password='hogehoge', master_log_file='mysql-bin.000001', master_log_pos=717; Query OK, 0 rows affected (0.08 sec) mysql>
次に以下のコマンドでレプリケーションを開始します。
mysql> start slave; Query OK, 0 rows affected (0.00 sec) mysql>
この時点で、スレーブ側はマスター側に接続して、最後のスナップショット位置以降の更新を取得します。
12.マスタ側でデータを登録してみる(マスター側)
レプリケーションの機能確認の為、マスター側でレコードを追加します。
mysql> select database(); +------------+ | database() | +------------+ | repltest | +------------+ 1 row in set (0.00 sec) mysql> mysql> show tables; +--------------------+ | Tables_in_repltest | +--------------------+ | test | +--------------------+ 1 row in set (0.00 sec) mysql> insert into test values(3,'Replication Start!'); Query OK, 1 row affected (0.01 sec) mysql> insert into test values(4,'Replication TEST'); Query OK, 1 row affected (0.03 sec) mysql> select * from test; +------+--------------------+ | id | title | +------+--------------------+ | 1 | test | | 2 | checksite.jp | | 3 | Replication Start! | | 4 | Replication TEST | +------+--------------------+ 4 rows in set (0.00 sec) mysql>
マスター側で手動でレコードを追加しました。
13.スレーブ側にレプリケーションされているか確認する(スレーブ側)
スレーブ側で、テーブルの内容を参照してみます。
mysql> select * from test; +------+--------------------+ | id | title | +------+--------------------+ | 1 | test | | 2 | checksite.jp | | 3 | Replication Start! | | 4 | Replication TEST | +------+--------------------+ 4 rows in set (0.00 sec) mysql>
ちゃんとID「3」「4」のレコードが登録されていました。レプリケーションが出来ているという事です。
/var/log/mysqld.log を確認してみると、以下のログが確認できました。
[Note] Slave I/O thread: connected to master 'replication@192.168.0.1:3306',replication started in log 'mysql-bin.000001' at position 717
補足1:レプリケーション状況の操作(スレーブ側)
スレーブ側で、レプリケーションの停止や開始の操作が可能です。
mysql> stop slave; Query OK, 0 rows affected (0.02 sec) mysql> mysql> start slave; Query OK, 0 rows affected (0.00 sec) mysql>
また、以下のコマンドで、スレーブ側のステータスを確認できます。
mysql> show slave status;
補足2:バイナリログ内のイベント確認
show binlog events コマンドで、バイナリログ内のイベントを参照できます。
以下は、マスター側での確認結果です。
mysql> show binlog events; +------------------+------+-------------+-----------+-------------+-----------------------------------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +------------------+------+-------------+-----------+-------------+-----------------------------------------------------------------+ | mysql-bin.000001 | 4 | Format_desc | 101 | 107 | Server ver: 5.5.31-log, Binlog ver: 4 | | mysql-bin.000001 | 107 | Query | 101 | 198 | create database repltest | | mysql-bin.000001 | 198 | Query | 101 | 311 | use `repltest`; create table test(id int(8),title varchar(32)) | | mysql-bin.000001 | 311 | Query | 101 | 383 | BEGIN | | mysql-bin.000001 | 383 | Query | 101 | 483 | use `repltest`; insert into test values(1,'test') | | mysql-bin.000001 | 483 | Xid | 101 | 510 | COMMIT /* xid=10 */ | | mysql-bin.000001 | 510 | Query | 101 | 582 | BEGIN | | mysql-bin.000001 | 582 | Query | 101 | 690 | use `repltest`; insert into test values(2,'checksite.jp') | | mysql-bin.000001 | 690 | Xid | 101 | 717 | COMMIT /* xid=12 */ | | mysql-bin.000001 | 717 | Query | 101 | 788 | FLUSH TABLES | | mysql-bin.000001 | 788 | Query | 101 | 860 | BEGIN | | mysql-bin.000001 | 860 | Query | 101 | 974 | use `repltest`; insert into test values(3,'Replication Start!') | | mysql-bin.000001 | 974 | Xid | 101 | 1001 | COMMIT /* xid=339 */ | | mysql-bin.000001 | 1001 | Query | 101 | 1073 | BEGIN | | mysql-bin.000001 | 1073 | Query | 101 | 1185 | use `repltest`; insert into test values(4,'Replication TEST') | | mysql-bin.000001 | 1185 | Xid | 101 | 1212 | COMMIT /* xid=346 */ | +------------------+------+-------------+-----------+-------------+-----------------------------------------------------------------+ 16 rows in set (0.00 sec) mysql>
補足3:レプリケーション設定
レプリケーションのデフォルト設定は以下になっています。
- スレーブ側からマスター側への接続ポート
- TCP 3306
- retry-time
- 60
- retries
- 86400
レプリケーションのデフォルト設定や設定方法はもう少し詰めておきたいと思います。