[前][次][番号順一覧][スレッド一覧]

mysql:9805

From: Yasumitsu Ito <Yasumitsu Ito <y-ito@xxxxxxxxxx>>
Date: Fri, 9 Jul 2004 23:43:23 +0900
Subject: [mysql 09805] Re: レプリケーションスレーブの能動的な同期

ひろせ様。
ご助言頂き、ありがとうございます。

On Fri, 09 Jul 2004 19:06:39 +0900
"HIROSE, Masaaki" <hirose31@xxxxxxxxxx> wrote:

> > [問題点]
> > 何らかの原因で、ネットワークが切断されるため、
> > 同期がとれず、同期回復まで待たなければならない。
> > そこで、スレーブから能動的に同期をあわせたい。
> 
> ネットワーク接続が回復すれば、マスターとスレーブ(のI/Oスレッド)のやり
> とりも再開されて、待てばマスターに追いつきませんか?

現状では slave_net_timeout をデフォルトの3600に設定しているため、
それまで待たなくては再開されません。
ネットワークが頻繁に切断されるため
(この原因は他にあると思うのですが、
ここでは切断されることを前提として、処置策を考えたいのです)
スレーブからどうにかできれば、と思っています。

> > [質問]
> > スレーブ側で
> > 
> > slave$ mysql --user=root --password=pass -e "show slave status"
> > slave$ mysql --user=slave_account --host=master --password=pass -e "show master status"
> > 
> > を行い、ポジションの違いを発見した場合に、
> 
> 『同期がとれていない』と判断するのは、『ポジションが一致しない場合』じゃ
> なくて『ポジションがある程度以上離れている場合』としないとまずいと思い
> ます。
> 
> なぜなら、
>   o MySQLのレプリケーションは非同期である。
>   o 『同時に』SHOW MASTER STATUS と SHOW SLAVE STATUS が実行できるわけ
>     ではない。
> の 2 つの理由からです。

そうでした。
今の環境ではそれほど頻繁にマスターのポジションが進むわけではないので、
一致しなければレプリケートされていないと判断できる、
と勘違いしていました。

> > slave$ mysql_synchronise
> > 
> > の様な自作コマンドを発行して、強制的に同期をあわせる作業を行いたい。
> > 
> > たとえば、その中身を
> > slave mysql> slave stop;
> > slave mysql> slave start;
> > slave mysql> select master_pos_wait('master_log_file', master_log_pos);
> > 
> > などと考えるのですが、どうでしょうか?
> 
> SELECT MASTER_POS_WAIT を実行したからといって、レプリケーションの処理が
> 速くなるわけでも遅くなるわけでもありません。単に、指定したポジションに
> 達した時点でスレーブのレプリケート処理が停止するだけです。
> 
> どうしても同期させたいのであれば、
> 
> 『Q: スレーブが追いつくまでマスタの更新をブロックするにはどうしますか。』
> http://dev.mysql.com/doc/mysql/ja/Replication_FAQ.html
> 
> にあるように、マスターで更新ロックをしてから SELECT MASTER_POS_WAIT し
> ないといけませんが、先にも述べたように、SHOW SLAVE STATUS で確認して
> I/O スレッドと SQL スレッドが動いていれば、放っておけばマスターに追いつ
> くはずです。

show slave status でI/Oスレッドと SQL スレッドがYESであっても、
エラーログを見ると
'Can't connect to MySQL...'
と出力がされており、レプリケートされていない状態が生まれています。
そして、上記エラーが出力されるのは最後の通信より
slave_net_timeout秒後だと認識しているのですが。

今、実験環境を作っているのですが、
slave_net_timeout=30
master-retry-connect=60
に設定している状態でレプリケーション環境を作り、
LANケーブルを抜いて放置すると、
30秒以内に
エラーログに 'Can't connect to MySQL...' errno: 2003
そしてその約1分後に
'Lost connection to MySQL..' errno: 2013
と出ますが、show slave status はどちらも
Slave_IO_Running: YES
Slave_SQL_Running: YES
となっています。

この状況で、LANケーブルを接続し、
netstat -p
を実行すると、mysqlに該当するTCPコネクションは消えています。

そして、master-retry-connect の時間が経過すると、
レプリケーションが再び始まるようです。

> > LANケーブルを引っこ抜いてしまったあとに、
> > slave stop;
> > slave start;
> > を実行しても、すんなりと通ってしまったり、
> > 逆に slave stop; を実行したときにプロンプトがかえってくるまでに
> > 非常に多くの時間がかかったりと、
> > いまいち挙動が掴めていないのが現状です。
> 
> SLAVE STOPに時間がかかるのはわかりませんが、
> マスターで ifconfig down (/etc/init.d/network stop) しても、スレーブで
> は I/O、SQL スレッド共に動いたままなので、マスターで ifconfig up すれ
> ば STOP/START SLAVE などしなくてもレプリケーションは再開されました。

この状況はこちらでも再現できました。

> > slave_net_timeout の時間を小さくする方法も考えられますが、
> > あまり小さな値では、無駄なトラフィックを生むだけのような気がします。
> > デフォルトでは3600秒になっているのですが、
> > たとえば、これを10秒などとしてしまうと、なにか弊害があったりするのでしょうか?
> 
> slave_net_timeout が使われるのは最初の1回だけなので、小さくしても問題
> ないんじゃないかと思います。
> 
> ただ、slave_net_timeout や master-connect-retry を小さくしてもしなくて
> も、マスターが復活すれば程なくレプリケーションは再開されます。そのため
> にはスレーブで I/O と SQL スレッドが動いている必要があるので、SHOW
> SLAVE STATUS で両スレッドの状態を監視する必要はあります。

master-retry-connectのタイマーがくると、
レプリケーションが再開することは理解できたのですが、
これを、スレーブ側のタイミングで行いたいのです。

マスターに書き込みを行ったあと、
書き込んだはずのデータがスレーブに存在しておらず、
エラーログに Lost connection/ Can't connect... が表示されている場合に
スレーブ側から能動的にレプリケーションを開始する動作を行いたいのです。

このような需要は一般的では無いのでしょうか?

今のところ
slave_net_timeout=10
master-connect-retry=10
として対処しようと考えています。

> ふと思ったのですが、もし、回線復旧後になかなかレプリケーションが再開さ
> れないのが問題なのであれば、回線復旧後の stunnel の再接続がうまくいっ
> てないという問題だったりしませんか?

現在は、実験環境として、stunnelを使わずに実験しています。
(これも問題になるかもしれません)

ところで、レプリケーションが取れている状態で
マスターであるテーブルに値をインサートし、
直後にスレーブ側で

mysql> show processlist;

を実行すると、私の環境では以下のように、
Time: 欄が非常に大きく表示されてしまいます。

*************************** 2. row ***************************
     Id: 75
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 4294967273
  State: Has read all relay log; waiting for the I/O slave thread to update it
   Info: NULL
*************************** 3. row ***************************

バグかと思い、 MySQL-4.0.20 (OS: VineLinux 2.93) で試したのですが、
やはり同じ値です。
バグなのでしょうか?
ちなみに、
2^32 = 4294967296
でした。

最後に、ひろせ様、ご助言頂きありがとうございました。

[前][次][番号順一覧][スレッド一覧]

      9789 2004-07-07 15:33 [Yasumitsu Ito <y-ito] レプリケーションスレーブの能動的な同期  
      9790 2004-07-07 21:58 ┣["Ohashi Koji" <ohash] mysqldumpの出力結果を取り込もうとするとUnknwon command
      9804 2004-07-09 19:06 ┗["HIROSE, Masaaki" <h]                                       
->    9805 2004-07-09 23:43  ┗[Yasumitsu Ito <y-ito]                                     
      9845 2004-07-14 00:22   ┗[Yasumitsu Ito <y-ito]                                   
      9866 2004-07-16 00:08    ┗["HIROSE, Masaaki" <h]