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


25

マシンが突然シャットダウンすると、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_FileExec_Master_Log_Posリストは次のとおりです。
mysql> show slave status;

しかし、私がやったとき change master status ...そうすると、プライマリキー違反エラーが発生しました。そんなことがあるものか?上記の手順は正しくありませんか?

(今のところ、マスターからスレーブに--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/ /programming//a/14438408


1
はい、動作するはずのように見えますが、実際にはおそらく実際に動作しているように見えます。おそらく、破損したセクションの前の元のリレーログは、そのマスターログの位置で既に挿入を行っていましたが、そのポインターはリレーログ(破損している)に格納されているため、次のポインターへのマスター位置を表示しました。したがって、そのイベントをスキップして次のイベントに移動し、マスターとスレーブが実際に同一のデータ...質問を十分に詳しくレビューする機会がまだありません。
マイケル-sqlbot

1
@ Michael-sqlbotに感謝します。この問題が再び発生した場合SET GLOBAL sql_slave_skip_counter = 1; START SLAVE;、スレーブで1つのイベントをスキップし、それが役立つことを願っています。それでも解決しない場合(まだPKエラーがある場合)、--master-data再度ダンプをインポートします。
-KajMagnus

回答:


35

エラー: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_FileNOT最初のコマンドの両方から取り出され、捨てることの必要性となっているリレーログに一致する最初の1、)。

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)

2
こんにちは、ご回答ありがとうございます。質問を注意深く読むと、「リレーログが破損しています」というメッセージが表示されます。これはmysqlbinlog、既に提案した方法で既に使用しており、リレーログ(マスターログではない)が破損していることがわかったためです。提案する修正を納得させる—質問を注意深く読むと、提案する修正がまさに私たちがすでに試みたものであることに気付くでしょう。しかし、それはうまくいきませんでした。それが問題です。—しかし、あなたの答えは、同様の問題を抱えている他の人々にとって役に立つかもしれません。
KajMagnus

2
MASTER_LOG_FILEin CHANGE MASTERはからRelay_Master_Log_Fileではなくから取得されることに注意してくださいMaster_Log_File。通常は同じですが、常にそうであるとは限りません(percona.com/blog/2008/07/07/…を参照)。
-brablc

@brablcは正しいです。Relay_Master_Log_Fileではなく使用する必要がありますMaster_Log_File。参照:percona.com/blog/2008/07/07/...
ミルチャVutcovici

ほとんどの場合、何のために必要ありませんreset slave allマスターの設定は(例えばMASTER_HOST、master_user、master_password)を変更する必要はありませんので、唯一のMASTER_LOG_FILEとMASTER_LOG_POSは、その後、reset_slave十分です
ympostor

この質問と回答はすでに数回私のお尻を救いました。ありがとうございました。
Artem Russakovskii

8

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

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

エラーを修正するには、スレーブ上の現在のbinlogファイルを破棄して、新しい位置を設定する必要があります。新しいbinlogの位置を設定する前に、コマンドSHOW SLAVE STATUS \ Gを使用して、破損したスレーブサーバーのRelay_Master_Log_FileExec_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ディレクトリ内の残り物を削除する必要はありません。


1
良い答え-通常、マスターホスト、パスワードなどを変更する必要はありません。
andy250

3

私はそれが一年以上経ったことを知っていますが、ここにこの特定の問題に起こったかもしれないものがあります。

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を受け取りました。なぜですか?

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

バグは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を適切にシリアル化することです。


1

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

唯一の問題は、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サーバーに指示できますが、パフォーマンスに大きな影響を与える可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.