指示に従ってもレプリケーションセットアップが機能しない場合、最初に行うことはエラーログでメッセージを確認することです。多くのユーザーは、問題が発生したあとにこれを十分に実行せずに、時間を失います。
エラーログから何が問題だったのかがわからない場合は、次の手法を試してください。
マスターでバイナリロギングが有効になっていることを、
SHOW MASTER STATUS
ステートメントを発行して確認します。ロギングが有効であると、Position
はゼロではありません。バイナリロギングが有効でない場合、--log-bin
オプションでマスターを実行していることを確認してください。マスターとスレーブの両方が
--server-id
オプションで起動されたこと、および ID 値が各サーバーで一意であることを確認します。スレーブが動作していることを確認します。
SHOW SLAVE STATUS
を使用して、Slave_IO_Running
およびSlave_SQL_Running
の値が両方ともYes
であるかどうかを確認してください。そうでない場合、スレーブサーバーを起動するときに使用したオプションを確認してください。たとえば、--skip-slave-start
は、START SLAVE
ステートメントを発行するまでスレーブスレッドが起動するのを妨げます。-
スレーブが動作している場合、マスターとの接続が確立されたかどうかを確認します。
SHOW PROCESSLIST
を使用して I/O スレッドと SQL スレッドを見つけ、それらのState
カラムをチェックしてそれらに何が表示されているかを確認してください。セクション17.2.1「レプリケーション実装の詳細」を参照してください。I/O スレッド状態がConnecting to master
である場合、次のことを確認してください。マスター上でレプリケーションに使用されているユーザーの権限を確認します。
マスターのホスト名前が正しいこと、正しいポートを使用してマスターに接続していることを確認します。レプリケーションに使用されるポートは、クライアントネットワーク通信に使用されるポートと同じです (デフォルトは
3306
です)。ホスト名の場合、その名前が正しい IP アドレスに解決されることを確認してください。ネットワークがマスターまたはスレーブ上で無効化されていないことを確認します。構成ファイルで
skip-networking
オプションを探してください。存在する場合、コメントアウトするか、削除してください。マスターにファイアウォールまたは IP フィルタリング構成がある場合、MySQL に使用されるネットワークポートがフィルタリングされていないことを確認します。
ping
またはtraceroute
/tracert
を使用してホストに到達することで、マスターに到達できることを確認します。
スレーブが以前は動作していたのに停止した場合、通常はマスターで成功したステートメントの一部がスレーブで失敗したことが原因です。マスターの適切なスナップショットを作成し、スレーブスレッド以外にスレーブでそのデータを変更しなかった場合、これは決して発生しないはずです。スレーブが突然停止する場合、それはバグであるか、またはセクション17.4.1「レプリケーションの機能と問題」で説明した既知のレプリケーション制限のいずれかが発生しています。バグの場合は、報告方法の説明をセクション17.4.5「レプリケーションバグまたは問題を報告する方法」で参照してください。
-
マスター上で成功したステートメントがスレーブ上で実行することを拒否する場合に、スレーブのデータベースを削除してマスターから新しいスナップショットをコピーすることによる完全なデータベース再同期を実行できない場合は、次の手順を試みてください。
スレーブ上の影響されるテーブルがマスターテーブルと異なるかどうかを判断します。これがどのように発生したかを理解しようとしてください。それから、スレーブのテーブルをマスターのものと同じにして
START SLAVE
を実行してください。前述の手順が機能しない、または当てはまらない場合は、手動で更新を行ってから (必要な場合)、マスターからの次のステートメントを無視することが安全かどうかを理解しようとしてください。
-
スレーブがマスターからの次のステートメントをスキップできると判断した場合、次のステートメントを発行します。
mysql> SET GLOBAL sql_slave_skip_counter = N; mysql> START SLAVE;
マスターからの次のステートメントが
AUTO_INCREMENT
またはLAST_INSERT_ID()
を使用しない場合、N
の値は 1 であるべきです。そうでない場合は、値は 2 であるべきです。AUTO_INCREMENT
またはLAST_INSERT_ID()
を使用するステートメントに値 2 を使用する理由は、それらがマスターのバイナリログ内で 2 つのイベントを必要とすることです。セクション13.4.2.4「SET GLOBAL sql_slave_skip_counter 構文」も参照してください。
スレーブがマスターと完全に同期された状態で起動したこと、およびスレーブスレッド以外で使用されるテーブルをだれも更新しなかったことがわかっている場合は、おそらくこの矛盾はバグの結果です。最新バージョンの MySQL を実行している場合は、この問題を報告してください。古いバージョンを実行している場合は、最新の本番環境リリースにアップグレードして問題が持続するかどうかを判断してみてください。