マスターがmysql 5.5バージョンでスレーブがmysql 5.1であるレプリケーションシステムがあります。スレーブバージョンはマスターバージョンよりも大きいはずなので、これはサポートされていませんが、まだアップグレードできません。
マスターで新しいデータベースが作成されるまですべてが正常に行われ、その後スレーブレプリケーションが失敗してエラーが表示されます。
Query caused different errors on master and slave.
Error on master: message (format)=
'Column count of mysql.%s is wrong. Expected %d, found %d. Created with MySQL %d, now running %d.
Please use mysql_upgrade to fix this error.' error code=1558 ; Error on slave: actual message='no error', error code=0. Default database: 'newdb'. Query: 'DROP DATABASE newdb'
私の回避策は:
set global sql_slave_skip_counter=2;
create database newdb;
start slave
すべてのデータベーステーブルのチェックサムを実行した後、すべてが問題ないように見えますが、データベースを頻繁に作成するひどいアプリケーションがあるので、データベースを手動で作成せずに問題を解決するコーディングを意味しない方法があるかどうか知りたいです。
マスターによって生成されたすべてのレプリケーションイベントには、イベントを生成したクエリの実行から生じたエラーコードが含まれます。これは通常「成功」です(0、エラーなし)。
スレーブがクエリを実行するとき、スレーブは、発生したエラーがマスターが発生したエラーと同じであることを期待します(ここでも、通常「エラーなし」)。これが起こらないと、レプリケーションが停止します。マスターからのエラーmessageは、コードだけが保持されないことに注意してください。スレーブがエラーメッセージのsprintf()
テンプレートを表示するため、エラーメッセージにプレースホルダーが表示されるのはそのためです。
ただし、エラーがどこにあるのか注意してください。
マスターサーバーのエラーログを確認してください。
マスターがMySQL 5.5に正しくアップグレードされなかったかのように見えます。具体的には、MySQL 5.5と完全に互換性を持つようにシステムテーブルをアップグレードするためにmysql_upgrade
ユーティリティが使用されなかったようです。
http://dev.mysql.com/doc/refman/5.5/en/mysql-upgrade.html
新しいマスターと古いスレーブで、サポートされていない構成を実行しています...しかし、この場合、masterに問題があるようですこれは実際にはレプリケーションとは無関係です。
Error on master:
message (format)=
'Column count of mysql.%s is wrong. Expected %d, found %d. Created with MySQL %d, now running %d.
Please use mysql_upgrade to fix this error.'
error code=1558 ;
マスターでエラーが発生しました。マスターのログに同様のエラーが見つかる場合がありますが、起動時にのみ発生する可能性があります。いずれにせよ、アプリケーションでもこのエラーが発生しているはずです...おそらくそれを無視しています。 :(
スレーブは、実際のクエリの実行中にエラーに遭遇しませんでした。
Error on slave: actual message='no error', error code=0.
スレーブサーバーが古いため、mysql_upgrade
によって実行されるアクションを安全にレプリケートできないことが非常に重要であることに気付きました。結局のところ、これは設計で予想されていたため、mysql_upgrade
ユーティリティは、スレーブが古い(または既にアップグレードされている)場合でも、スレーブを切断せずにマスターで安全に実行できるようです。 mysql_upgrade.c
のソースコードのこのコメントによると:
Master and slave should be upgraded separately.
All statements executed by mysql_upgrade will not be binlogged.
政治的に正しい答えは、新しいマスターから古いスレーブへのMySQLレプリケーションを実行できないことです。あなたは政治的に正しい答えが間違っていることを証明しました。それにも関わらず、正解は少なくとも長い間は、すべきではありません。その結果、非常に強力な警告が表示されます:非常に不安定になる可能性があるため、できるだけ早くアップグレードする必要があります。どうして ?
本 "Understanding MySQL Internals"(ISBN 0-596-00957-7)
バイナリログイベントに関するセクションがあります(ページ223-227)。これらのイベントには、次のように解釈される一意のコードがあります。
表示されているエラーメッセージは、レプリケーションスレッドによるその妥当性チェックからのものです。
これについておかしいのは、私が引用した本が2007年4月に作成されたということです。その本の出版以来、MySQLにはさらに多くのbinlogイベントが追加されています。したがって、スレーブがbinlogイベントを解釈できず、リレーログが破損していると見なす場合があります。 (それは、イギリスとブルックリンUSA、またはブラジルとポルトガル、またはスペインとプエルトリコの2人の会話のようなものです)。 MySQLの2つの異なるバージョンのバイナリログ間での語彙のわずかな変化は、それらの間で理解できないと誤って解釈されています。
約6週間前、クライアントは5.5.30マスターと5.6.21スレーブを使用していました(MySQL 5.6.21(マスターとすべてのスレーブ)への移行パス)。現在、このレプリケーション設定は機能しますが、スレーブが古いマスターからbinlogイベントをアンパックできなかったためにスレーブが壊れる場合がありました。上司からエラーログにエラーが表示されたときに、この現象を知りました。 Word Unpack
(MySQLレプリケーションがリレーログを開始またはローテーションする場合)というかなり不可解なエラーメッセージがありました(grep -i unpack error.log
を実行して、これが当てはまるかどうかを確認してください)。そのエラーログからの抜粋:
Thread pointer: 0x7ff048000990
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 7ff14cb347e0 thread_stack 0x40000
/usr/sbin/mysqld(my_print_stacktrace+0x35)[0x8dbbb5]
/usr/sbin/mysqld(handle_fatal_signal+0x494)[0x665f24]
/lib64/libpthread.so.0(+0xf710)[0x7ff14c8b8710]
/usr/sbin/mysqld(_Z10unpack_rowPK14Relay_log_infoP5TABLEjPKhPK9st_bitmapPS5_PmS5_+0x43f)[0x898b7f]
/usr/sbin/mysqld(_ZN14Rows_log_event24do_index_scan_and_updateEPK14Relay_log_info+0x100)[0x873c50]
/usr/sbin/mysqld(_ZN14Rows_log_event14do_apply_eventEPK14Relay_log_info+0x852)[0x877c32]
/usr/sbin/mysqld(_ZN9Log_event11apply_eventEP14Relay_log_info+0x74)[0x87fb54]
/usr/sbin/mysqld(_Z26apply_event_and_update_posPP9Log_eventP3THDP14Relay_log_info+0x263)[0x8aefd3]
/usr/sbin/mysqld[0x8b0cf2]
/usr/sbin/mysqld(handle_slave_sql+0xb09)[0x8b27c9]
/usr/sbin/mysqld(pfs_spawn_thread+0x12a)[0xb0526a]
/lib64/libpthread.so.0(+0x79d1)[0x7ff14c8b09d1]
/lib64/libc.so.6(clone+0x6d)[0x7ff14b61986d]
これらの4行に注意してください
/usr/sbin/mysqld(_Z10unpack_rowPK14Relay_log_infoP5TABLEjPKhPK9st_bitmapPS5_PmS5_+0x43f)[0x898b7f]
/usr/sbin/mysqld(_ZN14Rows_log_event24do_index_scan_and_updateEPK14Relay_log_info+0x100)[0x873c50]
/usr/sbin/mysqld(_ZN14Rows_log_event14do_apply_eventEPK14Relay_log_info+0x852)[0x877c32]
/usr/sbin/mysqld(_ZN9Log_event11apply_eventEP14Relay_log_info+0x74)[0x87fb54]
/usr/sbin/mysqld(_Z26apply_event_and_update_posPP9Log_eventP3THDP14Relay_log_info+0x263)[0x8aefd3]
私の特定のケースでは、スレーブはbinlogイベントを解釈しようとしてクラッシュしました。
次のようになります。
この狂気を正すために、私は次のことをしなければなりませんでした:
kill -9
を実行しますservice mysql start --skip-slave-start
を実行しますCHANGE MASTER TO
を実行しますSTART SLAVE;
を実行しますそこから、レプリケーションはオフで実行されていました。これは上司と私に一度だけ起こりました。もちろん、私はマスターからデータを完全にリロードしてスレーブを同期させました(データベースが100MB未満だったのは良いことです)。
このクレイジーなシナリオがMySQL 5.5.30マスターからMySQL 5.6.21スレーブに可能であった場合(私が示したように、2つのメンテナンスサイクルを修正する必要があります)、逆の可能性がはるかに高くなります(逆が新しいマスターであり、古いスレーブ)。
健全性とデータベーストポロジーのために、アップグレードしてください。
スレーブよりも新しいバージョンのMYSQLレプリケーションサーバーを作成すると、互換性の問題が発生します。バイナリログとSQL
ベースの一部の変更により、今のところ回避策で問題が解決する可能性がありますが、多くの問題が発生します将来は
SQLの非互換性:複製するステートメントがマスターで使用可能なSQL機能を使用している場合、ステートメントベースの複製を使用して新しいマスターから古いスレーブに複製することはできません奴隷ではありません。
行ベースのレプリケーションの使用:行ベースのレプリケーションはMySQL 5.1.5で実装されたため、MySQL 5.5から行ベースのレプリケーションを使用してレプリケートすることはできません以降、MySQL 5.1.5より古いスレーブにマスターします。
参照: http://dev.mysql.com/doc/refman/5.5/en/replication-compatibility.html
マスターとスレーブで同じmysqlバージョンを使用する必要がありますか?
提案された解決策:
1)マスターバージョンをスレーブと同じバージョンにアップグレードします。最良の解決策
2)スレーブエラーをスキップslave-skip-errors=
(最善の解決策ではなく、最後のオプションに任せます)