web-dev-qa-db-ja.com

MySQLリレーログが破損しています。どうすれば修正できますか?試したが失敗した

マシンが突然シャットダウンすると、MySQL v5.1.61リレーが破損しました。直そうとしたのですが、うまくいきませんでした。
—どうすれば修正できますか?私は何か間違ったことをしましたか?

私が読んだ限りでは、破損したMySQLリレーログは簡単に修正できます。

change master to master_log_file='<Relay_Master_Log_File>',
                 master_log_pos=<Exec_Master_Log_Pos>;

どこ Relay_Master_Log_FileおよびExec_Master_Log_Posは以下によってリストされます:
mysql> show slave status;

しかし、私がしたときchange master status ...、主キー違反エラーが発生しました。そんなことがあるものか?上記の手順は正しくありませんか? +1がありませんか?

(今のところ、--master-data mysqldumpをマスターからスレーブに再インポートしただけで、これで問題が解決しました。ただし、将来的には、そうすることが適切ではなくなる可能性があります。)


これが私の特定の問題の詳細です:

mysql> show slave status \G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: the-master-Host
                  Master_User: replication
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000021
          Read_Master_Log_Pos: 33639968
               Relay_Log_File: mysql-relay-bin.000271
                Relay_Log_Pos: 2031587
        Relay_Master_Log_File: mysql-bin.000020
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
              Replicate_Do_DB: the_database
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 1594
                   Last_Error: Relay log read failure: Could not parse relay log event entry. The possible reasons are: the master's binary log is corrupted (you can check this by running 'mysqlbinlog' on the binary log), the slave's relay log is corrupted (you can check this by running 'mysqlbinlog' on the relay log), a network problem, or a bug in the master's or slave's MySQL code. If you want to check the master's binary log or slave's relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' on this slave.
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 66395191
              Relay_Log_Space: 36559177
              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
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 1594
               Last_SQL_Error: Relay log read failure: Could not parse relay log event entry. The possible reasons are: the master's binary log is corrupted (you can check this by running 'mysqlbinlog' on the binary log), the slave's relay log is corrupted (you can check this by running 'mysqlbinlog' on the relay log), a network problem, or a bug in the master's or slave's MySQL code. If you want to check the master's binary log or slave's relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' on this slave.

そして、これは私がやったことです:

mysql> stop slave;
mysql> reset slave;
mysql> change master to master_Host='the-master-Host', master_user='replication', master_password='the-password', master_log_file='mysql-bin.000020', master_log_pos=66395191;
mysql> start slave;

そしてこれが起こったのです、PKエラー:

131122 15:17:29 [Note] Slave I/O thread: connected to master 'replication@the-master-Host:3306',replication started in log 'mysql-bin.000020' at position 66395191
131122 15:17:29 [ERROR] Slave SQL: Error 'Duplicate entry '71373' for key 'PRIMARY'' on query. Default database: 'the_database'. Query: 'insert into ...  values ...', Error_code: 1062
131122 15:17:29 [Warning] Slave: Data truncated for column 'date' at row 1 Error_code: 1265
131122 15:17:29 [Warning] Slave: Duplicate entry '71373' for key 'PRIMARY' Error_code: 1062

私は推奨手順に従っていたと思います(すぐ下のリンクを参照)、それでもPKエラーがありました: ?---(http://bugs.mysql.com/bug.php?id=26489 、検索「回避策」の場合 http://mhbarr.wordpress.com/2013/07/26/mysql-slave-corrupted-relay-log/https://stackoverflow.com/ a/14438408

26
KajMagnus

エラー:Last_SQL_Errno:1594 Last_SQL_Error:リレーログ読み取りエラー:リレーログイベントエントリを解析できませんでした。

このエラーは、マスターログファイルが破損しているか、リレーログファイルが破損していることを意味します。

  • 何かを行う前に、すべてのデータベース、ログ、画像サーバーをバックアップし、数回繰り返して、自己責任で続けてください。

最初にスレーブで「show slave status\G」を実行し、次のことに注意してください。

Master_Log_File: mysql-bin.000026
Read_Master_Log_Pos: 2377104
Relay_Log_File: mysqld-relay-bin.000056
Relay_Log_Pos: 1097303
Relay_Master_Log_File: mysql-bin.000026
Exec_Master_Log_Pos: 1097157

最初に、マスターログファイルが完全であることを確認したいので、マスターサーバーに移動し、Relay_Master_Log_Fileを見つけ(/ var/log/mysqlを確認)、次のコマンドを実行します。

mysqlbinlog mysql-bin.000026

ログは表示されますが、エラーメッセージが表示されないことを願っています。エラーメッセージが表示される場合は、マスターログが破損しているため、イメージを再作成する必要があります。

次に、スレーブリレーログ(多くの場合、/ var/lib/mysql)で同じコマンドを実行します。

mysqlbinlog mysqld-relay-bin.000056

次のような、レプリケーションを停止した破損を示すいくつかのエラーが表示されます。

ERROR: Error in Log_event::read_log_event(): 'read error', data_len: 336, event_type: 2
ERROR: Could not read entry at offset 1097414: Error in log format or read error.
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
root@db:/var/lib/mysql#

エラーが表示された場合、マスターでのログは問題なく、スレーブのリレーログのみが破損しています。これは朗報です。スレーブをリセットして、マスターに詳細と続行先を伝えることができます。エラーが表示されない場合は、今すぐ読み進めないでください。別の問題があります。

スレーブリレーログにエラーがある場合は、次のコマンドを実行してスレーブをリセットし、破損したログをマスターに再接続し、okログを取得して再度スレーブを開始します。 MASTER_LOG_POSはExec_Master_Log_Pos、およびMASTER_LOG_FILEはRelay_Master_Log_File[〜#〜] not [〜#〜]最初のコマンド。これは、フェッチされて破棄する必要があるリレーログに一致します)両方の最初のコマンドから。

mysql> stop slave;
Query OK, 0 rows affected (0.14 sec)

mysql> reset slave all;
Query OK, 0 rows affected (0.43 sec)

mysql>  CHANGE MASTER TO MASTER_Host='master.Host.com', MASTER_USER='masteruser', MASTER_PASSWORD='masterpass', MASTER_LOG_FILE='mysql-bin.000026', MASTER_LOG_POS=1097157;
Query OK, 0 rows affected (0.93 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
35
A.Badger

[スレーブのリレーログが破損した後のMySQLレプリケーションの修正]

スレーブ(バージョン5.XX)でのMySQLレプリケーションが停止しました。 Slave_IO_RunningはYesとマークされていましたが、Slave_SQL_RunningはNoとマークされていました。単純な停止/開始スレーブは役に立たなかったため、さらに問題を分析する必要がありました。 「mysqlbinlog」を使用したテストでエラーが出力されたため、現在のスレーブのリレーログが破損しているようです。したがって、解決策は、現在のリレーbinlogを破棄し、スレーブが最後のマスターbinlog位置を指すようにすることでした。

エラーを修正するには、スレーブ上の現在のbinlogファイルを破棄して、新しい位置を設定する必要があります。新しいbinlog位置を設定する前に、コマンドSHOW SLAVE STATUS\Gを使用して、破損したスレーブサーバーからのRelay_Master_Log_FileおよびExec_Master_Log_Posの値を覚えておくことが重要です。

Relay_Master_Log_File: mysql-bin.002045
Exec_Master_Log_Pos: 103641119

OK、この値で、新しいbinlogの位置を設定できます:

# stop slave
mysql> stop slave;

# make slave forget its replication position in the master's binary log
mysql> reset slave;

# change slave to start reading from stopped position
mysql> change master to master_log_file='mysql-bin.002045', master_log_pos=103641119;

# start slave
mysql> start slave;

reset slavemaster.inforelay-log.info、およびすべてのリレーログファイルを削除するため、/var/lib/mysqlディレクトリの残りをクリーンアップする必要はありません。

9
Mohamed Ayas

私はそれが1年以上経過していることを知っていますが、この特定の問題に何が起こったのかを以下に示します。

mysql> stop slave;
mysql> reset slave;
mysql> change master to master_Host='the-master-Host', master_user='replication', master_password='the-password', master_log_file='mysql-bin.000020', master_log_pos=66395191;
mysql> start slave;

破損したリレーログが削除されたため、問題は修正されたようです。

次に、PKエラー1062が発生します。なぜですか?

MySQL 5.5でまだアクティブな未解決のバグ( http://bugs.mysql.com/bug.php?id=60847 )があります

バグはmysql --single-transaction --flush-logsの使用に関連していますが、関連する癖があります。

先週、MySQL 5.5.15でクライアントのスレーブとして実行されている一部のEC2サーバーの癖を見てきました

マスターでは、挿入されている各タプルがSELECTである奇妙な複数行拡張INSERTがありました。何が起こったかというと、リレーログのLAST_INSERT_IDは、割り当てられる次の自動インクリメントを形成しますが、複数行が事前に挿入されているため、スレーブですでに使用されていました。

リレーログのシリアル化されたINSERTは次のようになりました

INSERT INTO tablname (column,column) VALUES (value,value,...)

列リストに数値の主キーが含まれていませんでした。 1062エラーが返されたとき、失敗したのと同じクエリを使用し、クエリを手動で実行します。 1062エラーは発生しませんでした。次に、通常のスキップスレーブコマンドを実行しました。

STOP SLAVE;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
START SLAVE;
SET @sleepnumber = SLEEP(3);
SHOW SLAVE STATUS\G

その後、レプリケーションが追いついた。

私のアドバイスは、このバグのような状況は実際にはかなり回避できるため、マスターでのINSERTを適切にシリアル化することです。

3
RolandoMySQLDBA

あなたはそれを(他の人がすでに言ったように)かなり正しくやった。

唯一の問題は、master.infoファイル(マスターのmysql-bin.log内の位置に関する情報が含まれている)にあります。このファイルは、各クエリの処理後にディスクに同期されないためです。

したがって、マスターのログ内の位置に関する情報は古くなっており、SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;でスキップする必要がある既に処理されたクエリを処理しています。

残念ながら、UPDATE table SET counter=counter+1 WHERE id = 12345のようなクエリを使用し、binlog_format=STATEMENTを使用すると、データベースが同期しなくなる可能性があります。

変数 sync_master_info を設定することで、すべてのイベントの後にmaster.infoを同期するようにMySQLサーバーに指示できますが、パフォーマンスに大きな影響を与える可能性があります。

1
Dragonn