web-dev-qa-db-ja.com

停電後のMySQLレプリケーションの問題

データセンターの停電後、スレーブMySQLデータベースは苦労しています。

これは、スレーブの1つのログにあります。

100118 10:05:56 [Note] Slave I/O thread: connected to master 'repl@db1:3306',  replication started in log 'bin-log.004712' at position 724207814
100118 10:05:56 [ERROR] Error reading packet from server: Client requested master to start replication from impossible position ( server_errno=1236)
100118 10:05:56 [ERROR] Got fatal error 1236: 'Client requested master to start replication from impossible position' from master when reading data from binary log
100118 10:05:56 [Note] Slave I/O thread exiting, read up to log 'bin-log.004712', position 724207814

そして、コンソールにはもう少し詳細が表示されます。

mysql> show slave status \G;
*************************** 1. row ***************************
             Slave_IO_State:
                Master_Host: db1
                Master_User: repl
                Master_Port: 3306
              Connect_Retry: 10
            Master_Log_File: bin-log.004712
        Read_Master_Log_Pos: 724207814
             Relay_Log_File: mysqld-relay-bin.000105
              Relay_Log_Pos: 98
      Relay_Master_Log_File: bin-log.004712
           Slave_IO_Running: No
          Slave_SQL_Running: Yes
            Replicate_Do_DB: mmplive1,mmpjcr,fui
        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: 724207814
            Relay_Log_Space: 98
            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: NULL
1 row in set (0.00 sec)

ERROR:
No query specified

マスターのビンログを見ると、次のようになっています。

-rw-rw---- 1 mysql mysql  724200412 Jan 18 09:22 bin-log.004712
-rw-rw---- 1 mysql mysql       1904 Jan 18 09:27 bin-log.index
-rw-rw---- 1 mysql mysql    5046830 Jan 18 11:22 slow-log
-rw-rw---- 1 mysql mysql  198249613 Jan 18 11:24 bin-log.004713
  1. スレーブステータスは、Exec_Master_Log_PosとRead_Master_Log_Posが両方とも724207814であり、バイナリログbin-log.004712であることを示しています。この値がバイナリログファイルのバイト位置であると理解しています。
  2. そのbin-log.004712ファイルはわずか724200412バイトであるため、スレーブは、ファイル(ext3 fs、RAID-10、RHEL5上にある)に実際に保持されているよりも7402バイト多くの作業を行ったと考えます。したがって、不可能なログ位置などに関するエラーメッセージ。

スレーブを修正する最良の方法は何ですか?

私が検討しているオプション:

  1. 次のbin-logファイル(bin-log.004713)の位置0を指すように各スレーブを設定し、それらを放しますが、それがどれほど安全であるか、またはどれだけのデータが失われる可能性があるかはわかりません。
  2. 代わりに、完全なバックアップと復元を行う必要がありますか(InnoDBテーブルのテーブルロックによる関連するダウンタイムが推定されます)?できればそれは避けたいと思います。

更新:

別のオプションを見逃しました。各スレーブの実行位置を少し後ろに向けて、bin-log.004712からすでに処理したコマンドを複製しようとするようにしました。

6
jabley

私は最初の選択肢を選びました。

これは、スレーブが主キーと競合する挿入を実行しようとするところまで機能しました。前述のように、スレーブはマスターのbin-logが保持していたよりも多くの作業を実行していました。私が予期していなかった1つの側面は、スレーブにマスターにないデータが含まれていることでした。つまり、スレーブは、マスターが停止する前にいくつかのトランザクションを持続しましたHAD NOT持続しました。

私の場合、これらのトランザクションは支払い関連などではなかったため、スレーブからデータを削除することを選択しました(これにより、発生したがマスターには存在しなかったデータが失われます)、レプリケーションを再度実行します。これにより、スレーブは完全に最新の状態になりました。データがより重要だった場合は、データを手動でラングリングし、参照整合性が損なわれないようにするための余裕を持たせるのに十分な自動インクリメントオフセットがあります。ありがたいことに、この場合はそれを行う必要はありませんでした。

この窮地にあった(パッシブ)マスター-マスター構成のマシンについては、同様のアプローチを選択しました。パッシブマスターマスターとは、すべての書き込みが行われるアクティブマスター(serverA)と、ダウンタイムなしでスキーマの更新を実行できるようにするパッシブマスター(serverB)があることを意味します。アクティブマスター(serverA)のデータが真の値として選択されましたが、これは、重要とは見なされなかった永続的なトランザクションがいくつか失われたことを意味することを知っていました。

  • スレーブ上のログファイルと位置を変更しました。

    CHANGE MASTER MASTER_LOG_FILE='bin-log.004713', MASTER_LOG_POS=0; -- on serverB
    
  • 他のスレーブと同様に、主キー制約違反で失敗するまで、パッシブマスター(serverB)でスレーブレプリケーションを再開しました。

     START SLAVE; -- on serverB
    
  • パッシブマスター(serverB)からアクティブマスター(serverA)へのスレーブレプリケーションを停止しました。

    STOP SLAVE; -- on serverA
    
  • ServerAのマスターに存在しなかったスレーブ(serverB)の行を削除します。

    DELETE FROM SOME_TABLE WHERE ID IN (???,????); -- on serverB
    SHOW MASTER STATUS\G; -- get the new master log position on serverB
    
  • アクティブマスター(serverA)スレーブexec位置を移動して、パッシブマスター(serverB)からの削除をスキップします。

    CHANGE MASTER TO MASTER_LOG_POS=???; --on serverA; use the value just obtained from serverB
    
  • アクティブマスター(serverA)とパッシブマスターの両方でレプリケーションを再開します。

    START SLAVE; -- on both machines. serverA does nothing and serverB starts catching up.
    
2
jabley

スレーブがマスターの正確なレプリカであることがどれほど重要かによって異なります。最初のオプションはある程度機能しますが、スレーブはマスターからの情報を見逃している可能性があります。データが一時的なものであるなどの理由でそれを受け入れることができる場合は、それを選択してください。スレーブが適切なレプリカであることが重要な場合は、2番目のオプションがおそらく唯一の選択肢です。残念ながら、MySQLレプリケーションは、予期しない中断を一切受けません。これらの種類の問題は、レプリケーションアーキテクチャで望むよりもはるかに頻繁に発生することがわかりました。

0