MySQL 5.7 の同時レプリケーションにおける暗黙のバグの分析

MySQL 5.7 の同時レプリケーションにおける暗黙のバグの分析

序文

当社の MySQL オンライン環境のほとんどはバージョン 5.7.18 を使用しています。このバージョンでは多くのバグが修正されていますが、マスター スレーブ レプリケーション、特にグループ レプリケーションと並列レプリケーションにはまだ多くのバグが残っています。バージョン 5.7.19 では、対応する改善と修正が行われました。したがって、5.7.19 より前のバージョンでは mgr および同時レプリケーション機能を使用しないことをお勧めします。これらを使用する場合は、5.7.19 (含む) 以降のバージョンにアップグレードすることをお勧めします。

ここで遭遇した主な問題は、説明のつかないデータ同期の問題、stop slave の実行不能、データの不整合などの現象でした。調べたところ、バージョン バグが原因であることがわかったので、オンライン スレーブ ライブラリの同時レプリケーションを閉じ、オンラインでないシステムのバージョンをアップグレードしました。リスクは非常に高いので、真剣に受け止めてください。

5.7.19 で修正された特定のレプリケーション バグは次のとおりです。

リファレンスマニュアル: https://dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-19.html

参考資料: バグ #84107 も参照してください。

レプリケーション: シングルプライマリ モードでデプロイされたグループ レプリケーション プラグインの遅延初期化の場合、セカンダリは非同期レプリケーション チャネルを介して書き込みを取得できましたが、これはグループ レプリケーション プラグインの通常の初期化では許可されません。(バグ #26314756)

レプリケーション: インシデント ログ イベントに対して生成された GTID では、レプリケーション スレーブで --slave-skip-errors=1590 起動オプションを使用しても、MySQL エラー コード 1590 (ER_SLAVE_INCIDENT) をスキップできませんでした。(バグ #26266758)

レプリケーション: SET GTID_NEXT ステートメントに続く USE ステートメントが効果を持たないことがありました。(バグ #26128931)

レプリケーション: グループには、異なるサーバー バージョンを実行しているメンバーを含めることができるようになりました。これにより、レプリケーション グループのオンライン アップグレードが可能になります。グループ内の異なるバージョンのメンバーを組み合わせるためのルールは次のとおりです。

8.0のメンバーがいるグループの場合、5.7のメンバーを追加することはできません。

5.7 メンバーを含むグループがある場合、8.0 メンバーを追加できますが、読み取り専用モードのままになります。グループに複数のサーバー バージョンが含まれている場合、このメンバーへの書き込みは危険なので避けてください。

単一プライマリ グループでは、現在のプライマリがグループを離れ、新しいプライマリを選出する必要がある場合、プライマリはまず下位バージョンのメンバーから選択されます。下位バージョンのメンバーが見つからない場合は、プライマリは新しいバージョンのメンバーから選択されます。(バグ #25876807)

レプリケーション: 起動後に MySQL サーバーで binlog_checksum=NONE が設定され、その後グループ レプリケーションが開始された場合、エラーが発生すると、サーバーは RECOVERING 状態のままになり、シャットダウンできませんでした。(バグ #25793366、バグ #85667)

レプリケーション: 異なるレプリケーション グループのメンバー間で循環非同期レプリケーションが実装されているグループ レプリケーション設定では、ビュー変更ログ イベントがグループ間で繰り返しレプリケートされ、そのたびに新しい GTID が生成されていました。この修正により、ビュー変更ログ イベントは、発生した名前付きレプリケーション グループ外では無視され、新しい GTID が生成されなくなります。(バグ #25674926)

参考資料: バグ #26049695、バグ #25928854、バグ #25721175 も参照してください。

レプリケーション: RPM からのインストール後に MySQL サーバーを初めて起動すると、パスワード検証プラグインがデフォルトで有効になります (RPM インストールの場合のみ)。この時点でバイナリ ログがすでに有効になっている場合は、プラグインのアクティベーションがバイナリ ログに記録されるべきではないにもかかわらず、アクティベーションがログに記録されます。(バグ #25672750)

レプリケーション: シングルプライマリ グループ レプリケーションが非同期レプリケーションと組み合わされたセットアップでは、たとえば S1 と S2 がグループを形成し、S2 と S3 がマスターとスレーブとして機能する場合、S2 などのセカンダリがトランザクションを受け入れ、それがグループに入る可能性があります。この修正により、シングルプライマリ グループに属するセカンダリが非同期レプリケーション チャネルを作成することがなくなり、非同期レプリケーションの実行中はグループ レプリケーションを開始できなくなります。(バグ #25574200、バグ #85047)

参考資料: バグ #86325、バグ #26078602 も参照してください。

レプリケーション: メンバーがグループに参加できなかった場合、メンバーは停止せず、トランザクションを受け入れ続けます。これを回避するには、my.cfg ファイルでメンバーに super_read_only=1 を設定します。グループ レプリケーションは、正常に起動するとこの設定を確認し、super_read_only=0 を設定します。これにより、グループに参加できなかったメンバーはトランザクションを受け入れることができなくなります。(バグ #25474736、バグ #84728)

レプリケーション: マスター サーバーのバイナリ ログがローテーションされ、バイナリ ログ ファイルが格納されているパーティションでディスクがいっぱいになった場合、サーバーが予期せず停止する可能性があります。この修正により、ダンプ スレッドが次のバイナリ ログ ファイルに切り替わるときに、バイナリ ログの存在を確認する機能が追加されました。バイナリ ログが無効になっている場合は、現在のアクティブ ログまでのすべてのバイナリ ログがスレーブに送信され、受信スレッドにエラーが返されます。(バグ #25076007)

レプリケーション: トランザクション分離レベルが REPEATABLE-READ に設定されている場合、インターリーブされたトランザクションによってスレーブ アプライヤがデッドロックすることがありました。(バグ #25040331)

レプリケーション: リレー ログ インデックス ファイルに存在しないリレー ログ ファイルの名前が付けられている場合、RESET SLAVE ALL を実行しても完全にクリーンアップされないことがあります。(バグ #24901077)

レプリケーション: slave_skip_errors システム変数は、3000 を超えるエラー番号を許可しませんでした。パッチを提供してくれた Tsubasa Tanaka に感謝します。(バグ #24748639、バグ #83184)

レプリケーション: mysqlbinlog は、--raw オプションで呼び出された場合、プロセスが終了するまで出力ファイルをフラッシュしません。ただし、--stop-never オプションで呼び出された場合、プロセスは終了しないため、出力ファイルに何も書き込まれません。現在は、各イベントの後に出力がフラッシュされます。(バグ #24609402)

レプリケーション: mysqlbinlog のメモリ リークが修正されました。このリークは、偽の回転イベントを処理するとき、または --raw を使用して宛先ログ ファイルを作成できなかったときに発生しました。リークは、リモート サーバーからのイベントを処理するときにのみ発生しました。このバグの修正に貢献してくれた Laurynas Biveinis に感謝します。(バグ #24323288、バグ #82283)

レプリケーション: MASTER_AUTO_POSITION=0 で、両方のレプリケーション スレッドが停止し、CHANGE MASTER TO MASTER_DELAY=N を使用してアプライヤの遅延が変更された場合、スレーブ サーバーはまだ適用されていないイベントを失う可能性があります。(バグ #23203678、バグ #81232)

参考資料: バグ #25340185、バグ #84375 も参照してください。

レプリケーション: 大きな GCS メッセージの送信に時間がかかりすぎて、送信者が死んだように見えることがありました。(バグ #22671846)

レプリケーション: マルチスレッド スレーブは、そのサイズより大きいトランザクションを処理する必要がある場合、slave_pending_jobs_size_max を使用して小さいキュー サイズで構成できませんでした。slave_pending_jobs_size_max より大きいパケットは、パケットが slave_max_allowed_pa​​cket によって設定された制限より小さい場合でも、エラー ER_MTS_EVENT_BIGGER_PENDING_JOBS_SIZE_MAX で拒否されました。

この修正により、slave_pending_jobs_size_max はハード リミットではなくソフト リミットになります。パケットのサイズが slave_pending_jobs_size_max を超えても、slave_max_allowed_pa​​cket より小さい場合、トランザクションはすべてのスレーブ ワーカーのキューが空になるまで保留され、その後処理されます。後続のすべてのトランザクションは、大きなトランザクションが完了するまで保留されます。したがって、スレーブ ワーカーのキュー サイズを制限しながら、時折大きなトランザクションを許可することができます。(バグ #21280753、バグ #77406)

レプリケーション: レプリケーションを中断したインシデント イベントは、GTID 付きのバイナリ ログに書き込まれなかったため、SET gtid_next=value を使用してイベントをスキップできませんでした。代わりに、リレー ログ ファイルとリレー ログの位置を直接設定する必要がありました。つまり、自動配置が有効になっている場合は、最初に自動配置を無効にし、次にリレー ログ ファイルと位置を設定し、最後に自動配置を再度有効にする必要がありました。

このような場合、MySQL はインシデント イベントをステートメント キャッシュに書き込みます。これにより、フラッシュ前に GTID が生成されて書き込まれ、スレーブ アプライヤが変更を処理するようになります。その後、ユーザーは SQL ステートメント SET gtid_next=value に続いて BEGIN と COMMIT を使用することでイベントをスキップできます。(バグ #19594845)

レプリケーション: 場合によっては、マスターがバイナリ ログに書き込む last_committed 値が本来よりも小さい値になることがあります。これにより、スレーブが本来実行すべきではない並列トランザクションを実行し、不整合やその他のエラーが発生する可能性があります。(バグ #84471、バグ #25379659)

レプリケーション: group_replication_ip_whitelist=AUTOMATIC を使用すると、プライベート ネットワーク内の IP は自動的に許可されますが、一部のクラス C IP アドレスが正しく許可されませんでした。(バグ #84329、バグ #25503458)

レプリケーション: 既存の GTID_NEXT トランザクションにサーバーによって競合する GTID が割り当てられると、グループ レプリケーションは同じ GTID を持つ 2 つのトランザクションを検出するとアサートを生成しました。これは、グループ レプリケーションが競合検出後に GTID を生成するためで、これはマスター/スレーブ レプリケーションよりも遅いです。この修正により、コミットが完了したときにのみ呼び出されるように条件が緩和され、GTID がすでに使用されている場合に警告するメッセージが追加されました。(バグ #84153、バグ #25232042)

レプリケーション: レプリケーション アプライア スレッドは、予想されるエラー番号と実際のエラー番号が異なる場合にエラー 3002 ER_INCONSISTENT_ERROR を返します。slave_skip_errors で 3002 を使用することで、このエラーを無視できるようになりました。(バグ #83186、バグ #24753281)

レプリケーション: mysqldump からのダンプを使用してデータをロードした場合、再起動後に MySQL の GTID 位置が失われました。

この問題の発生を防ぐために、mysql.gtid_executed テーブルは、mysqldump によって作成されるダンプから自動的に除外されるようになりました。(バグ #82848、バグ #24590891)

参考資料: バグ #87455、バグ #26643180 も参照してください。

レプリケーション: マルチソース レプリケーションで 1 つのチャネルのリレー ログが破損したため、サーバーの再起動時に正常なチャネルが初期化されませんでした。さらに、--skip-slave-start=false で実行すると、サーバーはすべての正常なチャネルのスレーブ スレッドを開始する必要があったにもかかわらず、正常な状態のチャネルのスレーブ スレッドを開始できませんでした。

現在、他のチャネルのエラーに関係なく、サーバーは良好な状態のチャネルの作成と初期化を試み、--skip-slave-start が無効になっている場合は良好なチャネルのスレーブ スレッドを開始します。この修正の一環として、すべてのチャネルで動作することを意図した START SLAVE と STOP SLAVE も変更され、不良チャネルが見つかった場合でも、すべての良好なチャネルで実行が継続されます。(バグ #82209、バグ #24285104)

レプリケーション: SQL スレッドは部分的なトランザクションを GTID スキップできませんでした。(バグ #81119、バグ #25800025)

Debian クライアント パッケージには、akonadi-backend-mysql パッケージとの競合に関する情報がありませんでした。(バグ #26002288)

要約する

上記はこの記事の全内容です。この記事の内容が皆さんの勉強や仕事に一定の参考学習価値を持つことを願っています。ご質問があれば、メッセージを残してコミュニケーションしてください。123WORDPRESS.COM を応援していただきありがとうございます。

以下もご興味があるかもしれません:
  • PHP+MySQL の高同時ロックトランザクション処理問題の解決方法
  • MySQL の同時実行性の問題と解決策の分析
  • MySQLデータの同時更新を処理する方法

<<:  Angular環境構築と簡単な体験のまとめ

>>:  ワンクリックで雨や雪のエフェクトを実現する ThingJS パーティクルエフェクト

推薦する

MySQL が外部キーを作成できない理由と解決策

2 つのテーブルを関連付けるときに、外部キーを作成できませんでした。このブログから、問題は、ポイント...

IDEA で Linux コマンドを使用する方法

Windows システムと比較して、Linux システムは多数の豊富なコマンドライン ツールを提供し...

MySQL マルチテーブルクエリの詳細な説明

いつも、気づかないうちに時間というのは驚くほど早く過ぎていきます。小暑が過ぎ、中暑に突入しました。太...

Docker で Java 8 Spring Boot アプリケーションを開発する方法

この記事では、ローカル マシンに Java 8 をインストールせずに、Java 8 を使用して簡単な...

MySql バージョンの問題に対する完璧なソリューション sql_mode=only_full_group_by

1. sql_modeを確認する @@sql_mode を選択照会された値は次のとおりです。 ON...

純粋なCSSを使用してスクロールシャドウ効果を実現します

端的に言うと、スクロール可能な要素には非常によくある状況があります。通常、スクロールすると、要素が現...

Win10 への MySQL 5.7 のインストール MSI 版のチュートリアル(画像とテキスト付き)

主にインストール後に my.ini ファイルを確認するために、msi 形式でインストールしました。フ...

TypeScript で時間を費やした場所の概要

TS で時間を過ごした場所をいくつか記録します。 (まず、文句を言わせてください。stackover...

2017 最新バージョンの Windows インストール MySQL チュートリアル

1. まず、MySQL の公式サイトから最新バージョンの MySQL をダウンロードします。リンクを...

nginxを使用してドメイン名ベースの仮想ホストを構成する

1. 仮想ホストとは何ですか?仮想ホストは、特殊なテクノロジーを使用して、実行中のサーバーを論理的に...

forループ内のvarの問題の解決

序文var は ES5 における変数宣言方法です。var で変数を宣言するとループ変数がグローバル変...

JavaScript 文字列の一般的なメソッドの詳細な説明

目次1. キャラクター文法パラメータ索引戻り値2. 連結文法パラメータ文字列2 [, …文字列N]戻...

Vue で Baidu Map を呼び出して経度と緯度を取得する

プロジェクトでは、現在地の緯度経度を取得したり、場所を検索して緯度経度情報を取得したりする必要があり...

Windows サービス 2016 Datacenter\Stand\Embedded アクティベーション方法 (2021)

管理者権限でcmdを実行する slmgr /ipk CB7KF-BWN84-R7R2Y-793K2-...

Dockerコンテナのログ分析

コンテナログを表示するまず、 docker run -it --rm -d -p 80:80 ngi...