web-dev-qa-db-ja.com

奇妙なMySQLレプリケーションエラー1146(テーブルが存在しません)

スレーブホストのREPLACE INTOクエリで非常に奇妙なMySQLレプリケーションエラーNo. 1146が発生し、マスターからすべてのデータベースのすべてのテーブルをレプリケートします。理由を理解するのに少し苦労しています。

これが私のシナリオです:

  1. 新しいデータは、マスターサーバーであるMySQL 5.5.40でのみ生成されます。
  2. スレーブA、MySQL 5.5.38は、すべてのデータベースのすべてのテーブルをこのマスターから長期間正常に複製しており、いかなる種類のエラーも発生していません。
  3. IO_THREADがスレーブAで一時停止されました。Relay_Master_Log_Fileの値がMaster_Log_FileおよびExec_Master_Log_Posの値がRead_Master_Log_Posの値と一致することが確認されました。
  4. スレーブAでFLUSH TABLES WITH READ LOCKが発行され、その後mysqldump -v -h localhost -u root -p --all-databases --opt --single-transaction --hex-blob --no-autocommit > dump.sqlを使用してスレーブAからすべてのデータベースのダンプが生成されました。ダンプが完了した後にのみロックが解放され、スレーブIO_THREADが再起動されました。マスターからのレプリケーションは問題なく再開され、スレーブAで現在までスムーズに実行され続けます。
  5. ダンプはスレーブB、MySQL 5.5.34に転送され、この2番目のホストにターゲットデータベースが存在しないことを確認した後、単純なmysql -h localhost -u root -p < dump.sqlコマンドを使用して正常にロードされました(実際にはmysql db以外のdbはありません)および情報とパフォーマンスのスキーマ)。また、スレーブBへの転送後に、両方のホストでRMD160チェックサムを一致させることにより、ダンプファイルの整合性を確認できます。
  6. スレーブBは、MASTER_LOG_FILEおよびMASTER_LOG_POS座標がRelay_Master_Log_FileおよびExec_Master_Log_Posは、それぞれスレーブAから上記の手順3で記録されたものです。
  7. レプリケーションはスレーブBで開始され、データは問題なく流れ始めました。

しかし、約1日のスムーズな操作の後、スレーブBはSQL_THREADに次のエラーを生成しました。

Error 'Table 'knet.course_location_tracks' doesn't exist' on query. Default database: 'knet'. Query: 'REPLACE INTO `course_location_tracks` (`userid`,`courseid`,`lesson_location`,`datestamp`) VALUES (val1,val2,val3,val4)'

(実際の行の値は編集されています)

knet.course_location_tracksテーブルがスレーブBに存在することだけでなく、その定義がの定義と同じであることを確認できるため、このエラーをあまり理解できませんスレーブAの対応するテーブル。スレーブAは、上で指摘したように、マスターからこの日まで問題なくレプリケートを続けます。

スレーブBでレプリケーションが正常に開始した場合、ダンプの時点でスレーブAの状態から初期レプリケーション座標が正しく計算されたと信じるようになったのに、次に存在するテーブルでこのエラーが発生するのはなぜですか?ホスト?さらに、スレーブAがまだスムーズに複製しているときにスレーブBでエラーが発生するのはなぜですか?

3つのホスト間でMySQLのバージョンが一致しないこと(問題をデバッグしようとしたときに最近気づいたこと、そしてできるだけ早く修正できること)を除いて、何が間違っているのでしょうか?

そして最後に、問題が特定されて修正されたら、スレーブBが正しい時点でレプリケーションを再開してマスターと完全に同期するようにするにはどうすればよいですか?

助けてくれてありがとう!

PS:必要に応じて、マスターAのすべてのデータベースとテーブルを同様の方法で転送することにより、スレーブAのレプリケーションが最初にセットアップされました。つまり、最初にマスターのすべてのテーブルを読み取りロックでフラッシュしてブロックし、mysqldump(同じフラグ)、最後にそれらを同じmysqlコマンドラインクライアント呼び出しでスレーブにロードします。

2
jmpp

それでも理由は定かではありませんが、この問題は、原因を特定するために行ったトラブルシューティングの手順をいくつか実行した後、解消されました。おそらく、Rackspaceのクラウドバックアップなど、slave2サーバーで実行されている他のサービスのアクティビティが高いために、MyISAMテーブルを開いているときにエラーを引き起こしたのは、開いているファイルの制限でした...しかし、どちらの場合でも、レプリケーションはスムーズに実行されています私の元の質問で説明したのと同じ方法で、slave1から取得した新しいデータスナップショットを使用してもう一度ロードした後、数週間、私のマスターサーバーからslave2をオフにします。

ですから、残念ながら明確な答えは出せませんが、問題は解決したようです。とりあえずこの記事を閉じます。

0
jmpp

元のポスターの問題の原因はわかりませんが、私の場合は大文字と小文字の区別の問題でした。レプリケーショントポロジのマスターサーバーは、クエリで指定するときにテーブル名にPascalCaseを使用していましたが、ディスク上の実際のテーブル名ファイルは小文字でした。たとえば、私のエラーメッセージを参照してください。

Slave SQL for channel 'master1': Error 'Table 'master_db.TableName' doesn't exist' on query. Default database: master_db'. Query: 'insert into TableName (field1, field2, field3) values ('value1', 'value2', 'value3')', Error_code: 1146

「master1」はWindowsシステムであるため、テーブル名の大文字と小文字の違いは問題になりません。ただし、私のスレーブはLinuxシステムなので、明らかに問題はありません。ステートメントはマスターでは正常に実行されますが、スレーブでは実行されません。私にとっての修正は、lower_case_table_names = 1my.cnfスレーブ上。これにより問題が修正され、レプリケーションはスムーズに再開されました。

0
Dusty Vargas