web-dev-qa-db-ja.com

データベース作成時のMySQLレプリケーションマスター5.5スレーブ5.1エラー

マスターが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

すべてのデータベーステーブルのチェックサムを実行した後、すべてが問題ないように見えますが、データベースを頻繁に作成するひどいアプリケーションがあるので、データベースを手動で作成せずに問題を解決するコーディングを意味しない方法があるかどうか知りたいです。

4
MazarD

マスターによって生成されたすべてのレプリケーションイベントには、イベントを生成したクエリの実行から生じたエラーコードが含まれます。これは通常「成功」です(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.
2

政治的に正しい答えは、新しいマスターから古いスレーブへのMySQLレプリケーションを実行できないことです。あなたは政治的に正しい答えが間違っていることを証明しました。それにも関わらず、正解は少なくとも長い間は、すべきではありません。その結果、非常に強力な警告が表示されます:非常に不安定になる可能性があるため、できるだけ早くアップグレードする必要があります。どうして ?

"Understanding MySQL Internals"(ISBN 0-596-00957-7)

sdhkbs

バイナリログイベントに関するセクションがあります(ページ223-227)。これらのイベントには、次のように解釈される一意のコードがあります。

  • sQLコマンドを抽出して表示すると、コードがmysqlbinlogによって解釈される
  • MySQLレプリケーション
    • IOスレッドはイベントを解釈し、イベントをバイナリログに保存します
    • SQLスレッドはリレーログからのイベントを解釈および検証し、コマンドを実行します

表示されているエラーメッセージは、レプリケーションスレッドによるその妥当性チェックからのものです。

これについておかしいのは、私が引用した本が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イベントを解釈しようとしてクラッシュしました。

次のようになります。

  • STEP 01:スレーブが認識されないイベントでクラッシュしました
  • STEP 02mysqld_safe 再起動 mysqld
  • STEP 03mysqld はレプリケーションを再開しようとします( skip -slave-start 構成されていません)
  • STEP 04STEP 01に戻ります

この狂気を正すために、私は次のことをしなければなりませんでした:

  • mysqld_safe プロセスでkill -9を実行します
  • service mysql start --skip-slave-startを実行します
  • 次に利用可能なポジションCHANGE MASTER TOを実行します
  • START SLAVE;を実行します

そこから、レプリケーションはオフで実行されていました。これは上司と私に一度だけ起こりました。もちろん、私はマスターからデータを完全にリロードしてスレーブを同期させました(データベースが100MB未満だったのは良いことです)。

このクレイジーなシナリオがMySQL 5.5.30マスターからMySQL 5.6.21スレーブに可能であった場合(私が示したように、2つのメンテナンスサイクルを修正する必要があります)、逆の可能性がはるかに高くなります(逆が新しいマスターであり、古いスレーブ)。

健全性とデータベーストポロジーのために、アップグレードしてください。

1
RolandoMySQLDBA

スレーブよりも新しいバージョンの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=(最善の解決策ではなく、最後のオプションに任せます)

0
Ahmad Abuhasna