max_allowed_packetエラーでSlave_IO_Running: No の状態を無事に解決。

MySQLレプリケーションでスレーブの同期が突然止まってしまいました。
「SHOW SLAVE STATUS¥G」で調べると

> SHOW SLAVE STATUS¥G
              Master_Log_File: mysqld-bin.000053
          Read_Master_Log_Pos: 403430270
             Slave_IO_Running: No
            Slave_SQL_Running: Yes
                Last_IO_Errno: 1236
                Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'log event entry exceeded max_allowed_packet; Increase max_allowed_packet on master'

こんな感じで、マスターDBサーバーでバイナリーログに「max_allowed_packet」容量をオーバーするログの記録が行われ、スレーブDBのIOスレッドが読めなくなってしまったようです。

マスターDBの設定でケチった結果…

今回の問題は、マスターのDBでメモリを節約しようとmax_allowed_packetを余分に制限してしまった場合に起こる可能性があります。
たとえば、プログラムで添付ファイルをDB格納する場合に1ファイル10MBに制限していても、添付ファイルを3つ添付できるようになっていた場合は、それを一気にDBに書き込もうとすると最低でも10MB×3=30MBがパケットとして使われます。

そんなときに「max_allowed_packet = 20M」に設定していたりするとエラーが起こってレプリケーションがストップします。

レプリケーションの設定だけ増やしてもダメ

このような過容量のログが記録された場合、レプリケーションの「max_allowed_packet」を「256M」のように大容量にしてもダメで「Slave_IO_Running」は「No」のままです。

マスター側も同じ容量にして、スレッドに通せるパケットの制限を緩める必要があります。

マスターDBを動的に変更する場合はログインして以下のコマンドを実行します。

>SET GLOBAL max_allowed_packet = 268435456;
この設定のポイント
容量は「268435456 = 256 × 1024 × 1024 = 256M」で計算しています。
また、動的に変更した後の「SHOW VARIABLES …」で確認しても変わっていないように見えるのは、セッション内では変更されていないせいで、一度ログアウトして再度ログインすると変わっています。

バックアップからリストアするのがベスト

もしマスターDBサーバーにバイナリーログが残されていて、そのバイナリーログから最新まで同期できるバックアップファイルがあるのであれば、スレーブDBサーバーを停止させてバックアップからリストアしてください。

IOスレッドは正常になっていますから、「Slave_IO_Running」は「YES」になり、正しく最新版まで同期されるでしょう。

このページをシェアする

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

2017-02-12