web-dev-qa-db-ja.com

複製エラー

次のエラーのためにレプリケーションを停止したスレーブサーバーがあります。

Slave SQL: Query caused different errors on master and slave.

このエラーの原因は何ですか?そしてそれを修正する方法は何でしょうか?

マスターとスレーブの両方のバージョンはMySQL 5.5.30です

130726 23:55:45 [Note] C:\Program Files\MySQL\MySQL Server 5.5\bin\mysqld: Shutdown complete

130726 23:58:39 [Note] Plugin 'FEDERATED' is disabled.
130726 23:58:39 [Warning] C:\Program Files\MySQL\MySQL Server 5.5\bin\mysqld: ignoring option '--innodb-file-per-table' due to invalid value 'ON'
130726 23:58:39 [Note] Plugin 'InnoDB' is disabled.
130726 23:58:39 [Note] Server hostname (bind-address): '0.0.0.0'; port: 3306
130726 23:58:39 [Note]   - '0.0.0.0' resolves to '0.0.0.0';
130726 23:58:39 [Note] Server socket created on IP: '0.0.0.0'.
130726 23:58:39 [Note] Slave SQL thread initialized, starting replication 
    in log 'mysql-bin.000234' at position 1065421256, 
    relay log '.\slave-relay-bin.000917' position: 1065421402
130726 23:58:39 [Note] Slave I/O thread: connected to master '[email protected]:3306',
    replication started in log 'mysql-bin.000235' at position 166680598
130726 23:58:39 [Note] Event Scheduler: Loaded 0 events
130726 23:58:39 [Note] C:\Program Files\MySQL\MySQL Server 5.5\bin\mysqld: 
    ready for connections.
Version: '5.5.30-log'  socket: ''  port: 3306  MySQL Community Server (GPL)
130726 23:59:04 [ERROR] Slave SQL: Query caused different errors on master and slave.
    Error on master: message (format)='Incorrect key file for table '%-.200s'; 
    try to repair it' error code=1034 ; 
    Error on slave: actual message='no error', error code=0. 
    Default database: 'shared'. 
    Query: 'CREATE TEMPORARY TABLE tmp_grades (
                        vehsysid INT(11),
                        grade INT(1),
                        dt TIMESTAMP,
                        INDEX(vehsysid),
                        INDEX(grade),
                        INDEX(dt)
                    ) SELECT vehsysid, Grade, MAX(dt) AS dt
                        FROM shared.tbl_valuations 
                        GROUP BY vehsysid, grade', Error_code: 0
130726 23:59:04 [ERROR] Error running query, slave SQL thread aborted. Fix the problem,
   and restart the slave SQL thread with "SLAVE START". 
   We stopped at log 'mysql-bin.000234' position 1065421256

他に理解できないことは、一時テーブルがどのようにして(マスターで)そのようなエラーを引き起こすかです:
'Incorrect key file for table '%-.200s'; try to repair it' error code=1034

マスターエラーログの最後の行:

130725 23:15:57 [Warning] Warning: Enabling keys got errno 120 on shared.tmp_grades, retrying
130726 23:15:58 [Warning] Warning: Enabling keys got errno 137 on shared.tmp_grades, retrying

追加情報:

  • マスターとスレーブの両方がWindowsで実行されます(それが関連しているかどうかはわかりません)。
  • 両方のディスクには十分なスペースがあります。
  • レプリケーション形式はMIXEDです
  • innodbは、マスターとスレーブのすべてのインスタンスでスキップされます。 MyISAMがデフォルトです。
7
ypercubeᵀᴹ

私はこれのいくつかが明白であることを述べていると思います。申し訳ありませんが、万全を期すために含めたいと思います。

この状態で停止するスレーブは、予想される動作です。

Binlogに書き込まれるすべてのクエリには、binlogイベントを生成したサーバーでクエリが返したエラーコードを含むメタデータがあります。通常、エラーコードは「エラーなし」の場合は0です。 mysqlbinlogを介してログを実行すると、このエラーコードとその他のメタデータを確認できます。

#130727 10:52:46 server id 10 end_log_pos 166 Query thread_id=673471 exec_time=1 error_code=0

クエリが実行の特定のポイントに達した後にエラーが発生した場合でも、クエリはエラーコードとともにbinlogに書き込まれます。

スレーブは、マスターが遭遇したのと同じエラー(通常は常にではないが0)が発生することを期待し、値が一致しない場合に停止して、このような状況が発生した後にレプリケーションを続行できる場合に発生する可能性があるデータの不整合を回避します。

Binlogデータ構造には、エラーメッセージやメッセージにsprintf()された値(コードのみ)の場所がないように見えるため、スレーブはそのコードを人間が読める形式に変換する必要があります。マスターがメッセージにプラグインしたはずの値がない場合は、プレースホルダーを含む生のメッセージ形式を表示するだけです。

# from source file include/mysqld_ername.h
{ "ER_NOT_KEYFILE", 1034, "Incorrect key file for table \'%-.200s\'; try to repair it" },

したがって、スレーブでの最後のレプリケーションエラーとして表示されるのは、マスターでエラーが発生した場合の通常の動作ですが、同じクエリがスレーブでエラーを生成しません。

SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; START SLAVE;を使用してエラーをスキップできます。これはおそらくすでに完了しているはずですが、それを超える回復は、一時テーブルの結果をどのように処理したかによって異なります。一時テーブルが1つのステートメントベースのイベントによって作成および入力され、それ以降のテーブルの更新に使用されなかった場合、レプリケーションは通常DROP TEMPORARY TABLEを試行したときに発生するエラーを無視するため、問題ない可能性があります。スレーブテーブルにはCREATE TEMPORARY TABLEステートメントが実際にbinlogに実際に現れたかどうか、またはスレーブがCREATEおよびDROPイベント(これにより、停止/開始前にスレーブSQLスレッドによって作成された一時テーブルが破壊されます)。一方、一時テーブルが他のテーブルの更新に使用された場合、MIXED binlog形式なので、これらの更新が行ベースのイベントとして書き込まれた可能性があるため、問題はないかもしれませんが、一時テーブルの結果から更新したテーブルがある場合は、その一貫性を確認します。

マスターで発生したエラーについて:

130725 23:15:57 [Warning] Warning: Enabling keys got errno 120 on shared.tmp_grades, retrying
130726 23:15:58 [Warning] Warning: Enabling keys got errno 137 on shared.tmp_grades, retrying

これらについて最初は見逃していたことがあります-1秒間隔であると思いましたが、これらのエラーは実際には25日と26日という2つの異なる日に発生したように見えるため、24時間と1秒間隔で... 2つの異なる警告同じ一時テーブル上nameですが、実際には2つの異なる一時テーブルが1日おきに生成されます。

MySQL error code 120: Didn't find key on read or update (HA_ERR_KEY_NOT_FOUND)
MySQL error code 137: No more records (read after end of file) (HA_ERR_END_OF_FILE)

最初は、マスターのログに「不正なキーファイル」メッセージがないのは奇妙だと思いましたが、それらはログにはありません。それらは、クエリを発行したクライアントに返されるエラーです。

私のサーバーのエラーログでそのようなエラーを見たのを覚えていますが、私が知ることができることから、これらの「不正なキーファイル」エラーは、slave_sqlスレッドまたはエラーが発生するのはクライアント接続がない場合のみなので、イベントスケジューラによって実行されるクエリです。一時テーブルを作成するクエリを実行していると、エラーのログが生成される可能性があります。興味。

クエリのSELECT部分が独自の暗黙的な一時テーブルを作成した場合、「不正なキーファイル」エラーが発生したのは「tmp_grades」テーブルであったとは技術的に想定できません...代わりにthat tableを使用すると、クエリに影響するエラーが発生します。

内部を少し見ると、CREATE TEMPORARY TABLE ... SELECTステートメントでインデックスを使用してMyISAM一時テーブルを作成すると、テーブルはインデックスを無効にして作成され、サーバーはデータを挿入するときにインデックスを更新する必要はなく、データが書き込まれた後のインデックス...そして、表示されている警告mayがインデックスを構築する時点であったようです( "有効化keys ... ")...そしてそれが正しいと仮定すると、特定の順序でリストされていない可能性のほんの一部が示唆されますが、それらはすべて、一時テーブルが破損しているという考えに関係しています。

  • 同時に実行中の別のジョブが明示的または暗黙的に大規模な一時テーブルも作成しているため(Using temporary)、一時的なディスク容量不足状態が発生し、他のジョブが終了するとすぐに消えます
  • 一時テーブルにデータを入力しているクエリのSELECT部分は、一時的なディスク容量不足状態を引き起こし、スペースについて明示的なテーブルと競合する別の暗黙的な一時テーブルを構築しています
  • システムメモリに問題があるため、一時テーブルがOSキャッシュで破損しています
  • ディスクに問題があり、一時テーブルが大きすぎてOSキャッシュに残っていないため、一時テーブルがディスクにフラッシュされたときに破損しています。

もちろん、ここでの最大の問題は、これらの説明がどれも特にありそうにないように見えることです。 2つのマシン間のデータが現在一貫していることを確認した後、不幸な次のステップは、データが再び発生するのを待つことです。ただし、システムメモリと一時ディスクの整合性を確認したい場合は、自分で確認します。

9