Studio3104::BLOG.new

uninitialized constant Studio3104 (NameError)

既存レプリケーション環境に新スレーブ追加



MySQL Casual Advent Calendar 2011の27日目として更新します。
皆さんがまったくcasualじゃないので、バシッとコンセプト通りの記事をあげます。

ちなみに今日は熱出して会社を休んでおります。
アタマがぼーっとしている中書いてますので、変な事書いてたらスミマセン・・・


マスタ-スレーブ-スレーブ構成のMySQLで、サービスを停止せずにスレーブを追加する方法を紹介します。
参照が多くなってきたなーってときに、ピークタイムを避けて作業すればメンテナンスを入れなくてもスレーブを増やせます。

環境、構成
この構成に、スレーブCを追加する
MySQLマスタ】ー【MySQLスレーブA】

MySQLスレーブB】


サービスからMySQLスレーブAを切り離す
スレーブAのコネクションをモニタ
netstatコマンドで、スレーブAのmysqlコネクションをモニタリングしておく
この間に、スレーブAへのselectがすべてスレーブBに向くようにする

[root@slaveA ~]# watch 'netstat|grep mysql'
tcp  0  0  slaveA:mysql  web01:34586   ESTABLISHED
tcp  0  0  slaveA:mysql  web05:40998   ESTABLISHED
tcp  0  0  slaveA:mysql  web02:57635   ESTABLISHED
tcp  0  0  slaveA:34660  master:mysql  ESTABLISHED
・
・
・

select先の変更作業が終わったら、以下のようにマスタとの間でのみmysqlセッションが張られている状態になるまでモニタリング

[root@slaveA ~]# watch 'netstat|grep mysql'
tcp  0  0  slaveA:34660  master:mysql  ESTABLISHED

念のための確認
しばらくモニタリングして新規の接続が来ないことを確認できたら、今度はtcpdumpコマンドで通信をモニタリング

 [root@slaveA ~]# tcpdump port 3306|grep -v master
 tcpdump: WARNING: eth0: no IPv4 address assigned
 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
 listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes

何も出力されないことを確認したら、以下コマンドでカレントコネクション数が1であることを確認

 [root@slaveA ~]# mysqladmin -u root extended-status | grep Threads_connected
 | Threads_connected                 | 1         |
 [root@slaveA ~]#

スレーブAを停止し、スレーブAのデータをスレーブCにコピーする
スレーブAを停止
以下のコマンドを発行

 [root@slaveA ~]# mysqladmin --password='rootパスワード' shutdown
 [root@slaveA ~]#

スレーブAからスレーブCにデータディレクトリごとコピーする
同時にbinlogとrelaylogもコピーしておく~
回線が弱い環境では、scpの帯域を制限して転送する~
※tarで固めてから送ったほうがいいかも?

 [root@slaveC ~]# cd /var/lib/mysql
 [root@slaveC mysql]# scp -pr -l 30000 slaveA:/var/lib/mysql/* ./ &
 [1] 17855
 [root@slaveC mysql]# cd ../mysql-bin/
 [root@slaveC mysql-bin]# scp -pr -l 5000 slaveA:/var/lib/mysql-bin/* ./ 
 mysql-bin.000013                                                                     100%  117     0.1KB/s   00:00    
 mysql-bin.000014                                                                     100%  117     0.1KB/s   00:00    
 mysql-bin.index                                                                      100%   72     0.1KB/s   00:00    
 mysql-relay-bin.000715                                                               100%  105MB 484.8KB/s   03:41    
 mysql-relay-bin.index                                                                100%   42     0.0KB/s   00:00
 [root@slaveC mysql-bin]# jobs
 [1]+  Running                 scp -pr -l 30000 slaveA:/var/lib/mysql/* ./ &  (wd: /var/lib/mysql)
 [root@slaveC mysql-bin]# fg %1
 scp -pr -l 30000 slaveA:/var/lib/mysql/* ./	(wd: /var/lib/mysql)
 tbl.ibd                                                                  34% 2709MB   3.1MB/s   28:06 ETA
 ・
 ・
 ・
 [root@slaveC mysql-bin]#

スレーブA再開、スレーブC起動
スレーブA再開
mysqldを起動して、以下のシェルスクリプトを実行する

 #!/bin/bash
 
 echo "`date` START SLAVE"
 mysql -e "START SLAVE"
 sleep 1
 
 BEHIND=1
 while [ ${BEHIND} -gt 0 ]
 do
   echo "`date` STOP SLAVE"
   mysql -e --password='rootパスワード' "STOP SLAVE IO_THREAD"
   sleep 5
   echo "`date` START SLAVE"; mysql -e --password='rootパスワード' "START SLAVE IO_THREAD"
   sleep 1
   BEHIND=`mysql -e --password='rootパスワード' "show slave status\G" |grep Seconds_Behind_Master|cut -f 2 -d ':'`
   echo "`date` Seconds_Behind_Master:${BEHIND}"
 done

'START SLAVE'して1秒後に'STOP SLAVE IO_THREAD'、5秒後にまた'START SLAVE'する処理が、'Seconds_Behind_Master'が0になるまで繰り返される
こうすることで、スレーブが停止していた間に発生したマスタの更新をゆっくり追いかけるので、マスタへの負荷を最小限に抑えることができる
'STOP SLAVE IO_THREAD'の場合、'Slave_SQL_Running'は継続されるので、マスタの更新イベントの反映は止まらない
つまり、'START SLAVE'している1秒間の間に取得した更新クエリは止まることなく実行され続ける
※'Seconds_Behind_Master'は'show slave status\G'で得られる、レプリケーションの遅延秒数

スレーブC起動
スレーブAと同じ手順で行う~
このとき、設定ファイルでユニークなserver_idを割り当てた状態で起動すること
master.info、relay.infoファイルのルールでレプリケーション プロセスが開始されるので、'CHANGE MASTER TO ・・・'でマスタ情報を登録する作業は不要




advent calendarは初参戦で、かつ、エンジニアとしても雑魚の極みですが、27日目はこんな感じです。。
myfinderさんのお計らいで記事をあげる機会をいただいて感謝です。