ディスク容量不足による MySQL レプリケーション障害の解決方法

ディスク容量不足による MySQL レプリケーション障害の解決方法

ケースシナリオ

本日、オンラインで問題が発見されました。監視範囲が不足していたため、特定のマシンのディスクがいっぱいになり、オンラインの MySQL マスター スレーブ レプリケーションに問題が発生しました。問題は次のとおりです。

localhost.(なし)>スレーブステータスを表示\G
************************** 1. 行 ****************************
               スレーブ_IO_状態:
                  マスターホスト: 10.xx.xx.xx
                  Master_User: レプリカ
                  マスターポート: 5511
                接続再試行: 60
              マスターログファイル:
          読み取りマスターログ位置: 4
               リレーログファイル: リレーbin.001605
                リレーログ位置: 9489761
        リレーマスターログファイル:
             スレーブIO実行中: いいえ
            スレーブSQL実行中: いいえ
                   最終エラー番号: 13121
                   Last_Error: リレー ログの読み取り失敗: リレー ログ イベント エントリを解析できませんでした。
 考えられる原因は、マスターのバイナリログが破損していることです(これを確認するには、
 バイナリログの「mysqlbinlog」が壊れている場合、スレーブのリレーログが破損しています(これを確認するには、
 リレーログで「mysqlbinlog」を実行中)、ネットワークの問題により、サーバーは
 暗号化されたリレーログファイルを開くために必要なキーリングキー、またはマスターまたは
 スレーブのMySQLコード。マスターのバイナリログまたはスレーブのリレーログを確認したい場合は、
 このスレーブに対して「SHOW SLAVE STATUS」を発行すると、それらの名前を知ることができます。

そこでエラー ログを確認したところ、エラー ログに次の内容が見つかりました。

2021-03-31T11:34:39.367173+08:00 11 [警告] [MY-010897] [Repl] MySQLユーザー名または
 マスター情報リポジトリ内のパスワード情報は安全ではないため、
 推奨。START SLAVE には USER および PASSWORD 接続オプションの使用を検討してください。
 詳細については、MySQL マニュアルの「START SLAVE 構文」を参照してください。

2021-03-31T11:34:39.368161+08:00 12 [ERROR] [MY-010596] [Repl] リレーログの読み取りエラー
 チャネル '' のイベント: イベントの途中でバイナリログが切り捨てられました。ディスク容量不足を考慮します

2021-03-31T11:34:39.368191+08:00 12 [エラー] [MY-013121] [Repl] チャネル '' のスレーブ SQL: リレー
 ログ読み取り失敗: リレーログイベントエントリを解析できませんでした。考えられる原因: マスターの
 バイナリ ログが破損しています (バイナリ ログで 'mysqlbinlog' を実行すると確認できます)。
 スレーブのリレーログが破損しています(リレーログで「mysqlbinlog」を実行すると確認できます)。
 ネットワークの問題により、サーバーは暗号化されたファイルを開くために必要なキーリングキーを取得できませんでした。
 リレーログファイル、またはマスターまたはスレーブのMySQLコードのバグ。
 マスターのバイナリログまたはスレーブのリレーログの場合は、「SHOW」を発行することで名前を知ることができます。
 このスレーブの SLAVE STATUS です。Error_code: MY-013121

2021-03-31T11:34:39.368205+08:00 12 [ERROR] [MY-010586] [Repl] クエリ実行エラー、スレーブSQL
 スレッドが中止されました。問題を修正し、スレーブSQLスレッドを「SLAVE START」で再起動してください。
 ログ 'mysql-bin.000446' の位置 9489626 で停止しました

説明からわかるように、エラー ログは非常にインテリジェントです。ディスクの問題を検出し、「ディスク領域不足を考慮する」ように促します。

問題を解決する

サーバーにログインすると、MySQL が配置されているサーバーのディスク使用率が 100% に達していることがすぐにわかりました。問題の原因は、エラー ログの内容と一致していました。

今すぐこの問題を解決してください。基本的な考え方は、ディスク ファイルをクリーンアップしてからレプリケーション関係を再構築することです。このプロセスは比較的単純に見えますが、実際の操作では、レプリケーション関係を構築するときに次のエラーが発生します。

### gtid レプリケーションに基づいて、レプリケーション関係を再構築します。localhost.(none)>reset slave;
エラー 1371 (HY000): 古いリレー ログの削除に失敗しました: ログのリセット中に失敗しました

localhost.(none)>スレーブをすべてリセットします。
エラー 1371 (HY000): 古いリレー ログの削除に失敗しました: ログのリセット中に失敗しました

ステップ 1: レプリケーションは gtid に基づいているため、show slave status のステータスを直接記録した後、スレーブをリセットし、change master ステートメントを使用してレプリケーション関係を再構築できます。

しかし、上記のエラーメッセージが表示されます。エラーメッセージから判断すると、MySQL がリレーログの消去操作を完了できないようですが、これは科学的ではないようです。さて、リレー ログの消去操作を自分で完了することはできないので、私がお手伝いします。

ステップ 2: rm -f を使用してすべてのリレー ログを手動で削除すると、エラー メッセージが次のようになることがわかります。

localhost.(none)>スレーブをすべてリセットします。
エラー 1374 (HY000): ログ インデックス ファイルの読み取り中に I/O エラーが発生しました

まあ、そうですね、問題は解決しませんでした。

それから考えてみたのですが、スレーブを手動でリセットしてもリレーログをクリーンアップできなかったので、そのまま停止しました。

スレーブからマスターに変更することは可能ですか?

ステップ 3: スレーブを直接停止し、reset slave all ステートメントを実行せずにマスターを変更します。結果は次のようになります。

localhost.(なし)>マスターをmaster_host='10.13.224.31'に変更します。
    -> master_user='レプリカ',
    -> マスターパスワード = 'eHnNCaQE3ND',
    -> マスターポート=5510、
    -> マスター自動位置 = 1;
エラー 1371 (HY000): 古いリレー ログの削除に失敗しました: ログのリセット中に失敗しました

まあ、問題は残っています。

ステップ 4: とにかく、レプリケーションはエラーで切断されたので、start slave を実行して何が起こるかを確認します。その結果、ドラマチックなシーンが現れます。

localhost.(none)>スレーブを起動します。
エラー 2006 (HY000): MySQL サーバーが消えました
接続できません。再接続を試行しています...
接続ID: 262
現在のデータベース: *** なし ***


クエリは正常、影響を受けた行は 0 行 (0.01 秒)


localhost.(なし)>
[ルート@ ~]#

start slave を実行した後、インスタンスが直接ハングします。

この時点で、レプリケーションは完全に切断され、スレーブ インスタンスはクラッシュしています。

ステップ 5: インスタンスを再起動できるかどうかを確認します。インスタンスを再起動して、インスタンスが再び起動できるかどうかを確認します。インスタンスを再起動した後、レプリケーション関係を確認すると、結果は次のようになります。

localhost.(なし)>スレーブステータスを表示\G
************************** 1. 行 ****************************
               Slave_IO_State: マスターイベントをリレーログにキューイング
                  マスターホスト: 10.xx.xx.xx
                  Master_User: レプリカ
                  マスターポート: 5511
                接続再試行: 60
              マスターログファイル:
           読み取りマスターログ位置: 4
               リレーログファイル: リレーbin.001605
                リレーログ位置: 9489761
        リレーマスターログファイル:
             スレーブIO実行中: はい
            スレーブSQL実行中: いいえ
                   最終エラー番号: 13121
                   Last_Error: リレー ログの読み取り失敗: リレー ログ イベント エントリを解析できませんでした。
 考えられる原因は、マスターのバイナリログが破損している(これを確認するには、
 バイナリログの「mysqlbinlog」が壊れている場合、スレーブのリレーログが破損しています(これを確認するには、
 リレーログで「mysqlbinlog」を実行中)、ネットワークの問題により、サーバーは
 暗号化されたリレーログファイルを開くために必要なキーリングキー、またはマスターまたはスレーブのバグ
 MySQLコード。マスターのバイナリログまたはスレーブのリレーログを確認したい場合は、
 このスレーブで「SHOW SLAVE STATUS」を発行して、それらの名前を確認します。
                 スキップカウンタ: 0

関係をコピーすると、依然としてエラーが発生します。

ステップ 6: すべてのスレーブをリセットし、成功するかどうかを確認します。

localhost.(なし)>スレーブを停止します。
クエリは正常、影響を受けた行は 0 行 (0.00 秒)


localhost.(none)>スレーブをすべてリセットします。
クエリは正常、影響を受けた行は 0 行 (0.03 秒)

ステップ7: レプリケーション関係を再確立し、レプリケーションを開始する

localhost.(なし)>マスターをmaster_host='10.xx.xx.xx'に変更します。
    -> master_user='レプリカ',
    -> マスターパスワード='xxxxx',
    -> マスターポート=5511、
    -> マスター自動位置 = 1;
クエリは正常、影響を受けた行は 0 行、警告は 2 件 (0.01 秒)


localhost.(none)>スレーブを起動します。
クエリは正常、影響を受けた行は 0 行 (0.00 秒)


localhost.(なし)>スレーブステータスを表示\G
************************** 1. 行 ****************************
               Slave_IO_State: マスターがイベントを送信するのを待機中
                  マスターホスト: 10.xx.xx.xx
                  Master_User: レプリカ
                  マスターポート: 5511
                接続再試行: 60
                          ...
             スレーブIO実行中: はい
            スレーブSQL実行中: はい

インスタンスのレプリケーション関係を確立できることがわかります。

まとめ

ディスクがいっぱいになると、MySQL サービスはメタ情報テーブルにデータを書き込むことができず、リレー ログが不完全になる可能性があります。サーバー上のディスク データを直接クリーンアップし、マスターを再度変更してマスター スレーブ レプリケーション関係を変更すると、通常のマスター スレーブ レプリケーション関係の破損シナリオではないため、エラーが発生し、直接修復できない可能性があります。

したがって、正しいアプローチは次のようになります。

1. サーバーのディスクをクリーンアップする

2. レプリケーション関係が切断されたスレーブライブラリを再起動します。

3. スレーブをすべてリセットし、マスターを変更してマスターとスレーブのレプリケーション関係を構築します。

もっと良い方法があれば教えてください。

上記は、ディスクがいっぱいになったために MySQL レプリケーションが失敗する問題の解決方法の詳細な内容です。MySQL レプリケーションが失敗する問題の解決方法の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MySql マスタースレーブレプリケーションメカニズムの包括的な分析
  • MySQL マスタースレーブレプリケーションと読み取り書き込み分離の詳細な説明
  • MySQLテーブルをコピーする方法
  • MySQL 8.0.23 のレプリケーション アーキテクチャにおけるスレーブ ノードの自動フェイルオーバー
  • MYSQL データベース GTID はマスタースレーブレプリケーションを実現します (超便利)
  • MySql マスタースレーブレプリケーションの実装原理と構成
  • MySQL の WriteSet 並列レプリケーションの簡単な分析
  • MySQL マスタースレーブレプリケーションの原理と注意点
  • MySQL でレプリケーション フィルターを動的に変更する方法
  • MySQL 並列レプリケーションの簡単な分析
  • MySQL レプリケーション問題の 3 つのパラメータの分析

<<:  CSS -webkit-box-orient: コンパイル後に垂直プロパティが失われる

>>:  Dockerがsudo操作を使用する必要がある問題を解決する

推薦する

MySQLデータベースを定期的に自動バックアップする方法

データは貴重なものであることは誰もが知っています。データをバックアップしなければ、データをそのまま放...

一般的な XHTML タグの使用方法の紹介

XHTML には多くのタグがありますが、頻繁に使用されるのはごくわずかであり、習得する必要があるのは...

Nginx は gzip 圧縮に基づいてアクセス速度を向上します

1. nginx はなぜ gzip を使用するのですか? 1. 圧縮の役割:ページがgzipで圧縮さ...

Python Django アプリケーションを Docker 化する方法

Docker は、開発者やシステム管理者がアプリケーションを軽量コンテナとして構築およびパッケージ化...

IDEA が MySQL データベースに接続できない問題の 6 つの解決策

この記事では、IDEA が MySQL データベースに接続できない問題に対する 6 つの解決策を主に...

MySQL データベースのバックアップをスケジュールするいくつかの方法 (包括的)

目次1. データをバックアップするためのmysqldumpコマンド2. 一般的なmysqldump操...

ボタンのタイプが送信として指定されていません。ボタンをクリックしても、指定された URL にジャンプしません。

現在、プロジェクトの要件により、フォームの送信を制御し、送信前にデータを検証および処理するために j...

iframe テクニックを使用して訪問者 QQ 実装のアイデアとサンプル コードを取得する

今日、仕事中に、一時的に追加した友人から、Web ページを使用して訪問者の QQ を取得する方法を尋...

MySQL 5.7.19 インストールディレクトリに my.ini ファイルを作成する方法

前回の記事では、MySQL 5.7.19 無償インストール版 (64 ビット) の設定方法についての...

Alibaba Cloud イメージリポジトリの Docker 構成変更の実装

docker リポジトリ自体は非常に遅いですが、中国の Alibaba Cloud ミラー リポジト...

6秒でMySQLに100万件のレコードを挿入する方法を教えます

1. アイデアMySQL に 1,000,000 件のレコードを挿入するのにたった 6 秒しかかかり...

Ubuntu 16.04 に Docker と nvidia-docker をインストールするための詳細なチュートリアル

目次DockerのインストールNvidia-docker のインストールDockerのインストール1...

インラインブロックを使用した複数のdiv間の間隔はプログラミング方法とは異なります

inline-block について学習しているときに、境界線と inline-block を持つ複数...

Windows で MySQL インストーラーを使用して MySQL サービスをインストールするチュートリアル図

MYSQL は、MYSQL サービスやその他のコンポーネントをインストールするためのインストーラ方式...

MySQLを安全にシャットダウンする方法

MySQL サーバーをシャットダウンする場合、シャットダウン方法に応じてさまざまな問題が発生する可能...