vagrantでmysqlレプリケーション実験環境をお手軽作成


mysqlのレプリケーション設定をする機会があったので、実環境で試す前に実験してみたいと思い、vagrantを使ってレプリケーション設定用のサーバを立ててみました。

結構長くなってしまいましたが、手順をまとめておきます。

vagrantを使うと手軽に実験環境を作れていいですね。

目標

  • マスター1台、スレーブ1台のレプリケーション設定をする
  • DBはmysql5.5を使用

vagrantで複数のvmを作成する

  • 適当にディレクトリを追加
mkdir -p ~/Vagrants/repl/
cd ~/Vagrants/repl
  • vagrant初期化
vagrant init
  • Vagrantfile修正

db_masterとdb_slaveの設定を追加

vi Vagrant

Vagrant::Config.run do |config|
  config.vm.box = "base"

  config.ssh.timeout = 60

  config.vm.define :db_master do |vm_config|
    vm_config.vm.network :hostonly, "192.168.50.13"
  end
  config.vm.define :db_slave do |vm_config|
    vm_config.vm.network :hostonly, "192.168.50.14"
  end
end
  • 起動
    db_master, db_slaveの順で起動します
vagrant up
  • ssh設定
vagrant ssh-config db_master --host vagrantdbm >> ~/.ssh/config
# ssh vagrantdbm で db_master にアクセスできるようになります

vagrant ssh-config db_slave --host vagrantdbs >> ~/.ssh/config
# ssh vagrantdbs で db_slave にアクセスできるようになります

chef設定

sudo mv ~/vagrant/my-chef-repo/chef-repo /etc/chef
sudo chown `whoami` /etc/chef
cd /etc/chef
  • knife.rbの設定
vi .chef/knife.rb

cookbook_path ["cookbooks", "site-cookbooks", "vendor/cookbooks"]
role_path     "roles"
data_bag_path "data_bags"
#encrypted_data_bag_secret "data_bag_key"
  • Berksfileにmysql追加
vi Berksfile

site :opscode

cookbook 'yum'
cookbook 'mysql'
  • cookbook取得
bundle exec berks install --path vendor/cookbooks
  • リモートサーバにchef-soloをセットアップ
./bin/knife solo prepare vagrantdbm

./bin/knife solo prepare vagrantdbs
  • json設定
# db_master設定
vi nodes/vagrantdbm.json

{
  "mysql": {
    "server_root_password": "xxx",
    "server_repl_password": "xxx",
    "server_debian_password": "xxx"
  },
  "run_list":[
    "yum::remi",  # yum::remiをインストールしておかないとmysql5.1がインストールされる
    "mysql::server"
  ]
}

# db_slave設定
vi nodes/vagrantdbs.json

{
  "mysql": {
    "server_root_password": "xxx",
    "server_repl_password": "xxx",
    "server_debian_password": "xxx"
  },
  "run_list":[
    "yum::remi",
    "mysql::server"
  ]
}
  • recipe実行
# db_master
./bin/knife solo cook vagrantdbm

# db_slave
./bin/knife solo cook vagrantdbs
  • mysqlインストール確認
# db_master
ssh vagrantdbm

mysqladmin -V
mysqladmin  Ver 8.42 Distrib 5.5.31, for Linux on x86_64

# db_slave
ssh vagrantdbs

mysqladmin -V
mysqladmin  Ver 8.42 Distrib 5.5.31, for Linux on x86_64

レプリケーション設定

マスター設定(db_master)

  • sshログイン
ssh vagrantdbm
  • mysqlユーザ一覧
mysql -uroot -p
mysql>
select Host, User, Password from mysql.user;
# cookbookに指定したユーザが追加されている
  • テストデータを追加してみる
    mysqlslapコマンドを使ってテストデータを作ってみる
mysqlslap -u root -p --create-schema=mysqlslap -a --no-drop --auto-generate-sql-add-autoincrement --auto-generate-sql-load-type=write --number-int-cols=2 --number-char-cols=2 --auto-generate-sql-secondary-indexes=3 --auto-generate-sql-execute-number=1000 --auto-generate-sql-write-number=1000 -c 100 -e InnoDB
  • テストデータをさらに追加
mysql>
use mysqlslap
insert into t1 (intcol1,intcol2,charcol1,charcol2) select intcol1,intcol2,charcol1,charcol2 from t1;
  • my.cnfを変更
sudo vi /etc/my.cnf

[mysqld]
server-id = 1
log-bin
  • mysql再起動
sudo /etc/init.d/mysqld restart
  • バイナリログが出力されているか確認
ls -l /var/lib/mysql/

mysqld-bin.000001が表示されている
  • レプリケーションユーザ追加
#GRANT REPLICATION SLAVE ON *.* TO repl@{slave ip} IDENTIFIED BY '{password}';

mysql>
GRANT REPLICATION SLAVE ON *.* TO repl@192.168.50.14 IDENTIFIED BY 'xxx';
  • ユーザ登録確認
mysql>
select user,host,password from mysql.user;

192.168.50.14         | repl | *XXXXXXXXXXXXXXXXXXXXXX
  • テーブルロック
mysql>
FLUSH TABLES WITH READ LOCK;
  • ポジション確認
mysql>
SHOW MASTER STATUS;

+-------------------+----------+--------------+------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| mysqld-bin.000001 |      255 |              |                  |
+-------------------+----------+--------------+------------------+
  • 別ターミナルを開いてdbのダンプをとる
ssh vagrantdbm
mysqldump -uroot -p --all-databases --lock-all-tables > dbdump.db
  • 元のターミナルに戻ってテーブルロック解除
mysql>
UNLOCK TABLES;
  • ローカルにダンプをダウンロード
# db_masterからログアウト
exit

scp vagrantdbm:~/dbdump.db .

スレーブ設定(db_slave)

  • sshログイン
ssh vagrantdbm
  • my.cnfを変更
sudo vi /etc/my.cnf

[mysqld]
server-id = 2
  • mysql再起動
sudo /etc/init.d/mysqld restart
  • ローカルからマスターのダンプをスレーブにコピー
# db_slaveからログアウト
exit

scp dbdump.db vagrantdbs:~/
  • インポート
ssh vagrantdbs

mysql -uroot -p < dbdump.db
  • レプリケーション設定
mysql>
CHANGE MASTER TO
       MASTER_HOST='192.168.50.13',
       MASTER_USER='repl',
       MASTER_PASSWORD='xxx',
       MASTER_LOG_FILE='mysqld-bin.000001',
       MASTER_LOG_POS=255;

START SLAVE;
  • スレーブ設定確認
SHOW SLAVE STATUS\G

# Slave_IO_Running: Yes
# Slave_SQL_Running: Yes
# になっていればOK

テストしてみる

  • マスター側にデータ追加
mysql>
use mysqlslap
insert into t1 (intcol1,intcol2,charcol1,charcol2) select intcol1,intcol2,charcol1,charcol2 from t1 limit 100;

SHOW MASTER STATUS;
+-------------------+----------+--------------+------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| mysqld-bin.000007 |      412 |              |                  |
+-------------------+----------+--------------+------------------+
  • スレーブ側も更新されていることを確認
mysql>
SHOW SLAVE STATUS\G
Master_Log_File: mysqld-bin.000007
Read_Master_Log_Pos: 412

レプリケーションできました

準同期レプリケーションに設定する場合

通常レプリケーションの動作
通常レプリケーション特筆すべき点は、マスターサーバはログを出力するだけで自己完結していることです。スレーブサーバの片思い的な動作方式です。

準同期レプリケーションの動作
準同期レプリケーションではマスターはスレーブの面倒を見ます。毎朝登校時間に起こしに来てくれる幼馴染型の動作をします。

  • マスター側の my.cnf に追記
vi /etc/my.cnf

[mysqld]
server-id = 1
log-bin
expire_logs_days = 14 # 追加
plugin-load=rpl_semi_sync_master=semisync_master.so # 追加
rpl_semi_sync_master_enabled=1 # 追加
rpl_semi_sync_master_timeout=1500 # 追加
  • スレーブ側の my.cnf に追記
vi /etc/my.cnf

[mysqld]
server-id = 2
plugin-load=rpl_semi_sync_slave=semisync_slave.so # 追加
rpl_semi_sync_slave_enabled=1 # 追加
  • マスター、スレーブを再起動すれば有効になる
sudo /etc/init.d/mysqld restart
  • 準同期レプリケーションになっているか確認
#マスター側で
mysql>
SHOW STATUS LIKE 'Rpl_semi_sync_master_clients';
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| Rpl_semi_sync_master_clients | 1     |
+------------------------------+-------+

# 1になっていればOK
# 0だと準同期が崩れている

マスターに接続できないエラーが発生した場合

  • エラー内容
error connecting to master
  • マスターのbind-addressを修正する
sudo vi /etc/my.cnf

[mysqld]
bind-address            = 192.168.50.13 #マスターのIP
  • それでもうまくいかない場合はiptablesの設定を見直してみる
sudo vi /etc/sysconfig/iptables

-A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT # 追加

# iptables再起動
sudo /etc/init.d/iptables restart

参考URL