MySQLインスタンスクラッシュ事例の詳細な分析

MySQLインスタンスクラッシュ事例の詳細な分析

[問題の説明]

私たちの実稼働環境には、複数の MySQL サーバー (MySQL 5.6.21) のクラスターがあり、時々クラッシュします。ただし、エラー ログには再起動情報のみが記録され、クラッシュ スタックは記録されません。

mysqld_safe 現在実行中のプロセス数: 0
mysqld_safe mysqld が再起動しました

次に、システムログ /var/log/message ファイルを確認します。クラッシュ時に他の異常な情報はなく、OOM が原因ではありません。

【トラブルシューティングのアイデア】

ログには貴重な情報が記録されないためです。クラッシュの原因を特定するには、まず MySQL コア ダンプ機能を有効にします。

コア ダンプを有効にする手順は次のとおりです。

1. my.cnfファイルに2つの設定項目を追加します。

[mysqld]

コアファイル

[mysqld_safe]

コアファイルサイズ=無制限

2. システムパラメータを変更し、suid_dumpableを構成する

エコー 1 >/proc/sys/fs/suid_dumpable

3. MySQLサービスを再起動すると設定が有効になります

【問題分析】

コア ダンプを有効にすると、サーバーが再度クラッシュしたときにコア ファイルが生成されます。

gdb を使用して生成されたコア ファイルを分析すると、クラッシュ時のスタック情報を次のように確認できます。


関数table_esms_by_digest::delete_all_rowsから、クラッシュはテーブル events_statements_summary_by_digest の切り捨て操作によってトリガーされたことがわかります。

当社には、1 分あたりの追加、削除、変更、クエリのデータベース アクセス数をカウントするために使用される内部 DML 分析ツールがあります。このツールのデータ ソースは events_statements_summary_by_digest テーブルです。収集プログラムは 1 分ごとにこのテーブルからデータを収集し、収集が完了した後に切り捨て操作を実行します。

このクラスター グループで DML コレクション プログラムを一時停止すると、MySQL がクラッシュしなくなりました。

複数のコア ファイルをさらに分析すると、最終的な関数呼び出しはすべて _lf_pinbox_real_free 関数で発生していることが明らかになりました。

現場環境と合わせて、分析する価値のある場所が 2 つあります。

1. メモリ値が異常です。変数を印刷すると、ここでの変数のアドレスは低く、これは正常ではありません。

(gdb) p ピン->ピンボックス

$2 = (LF_PINBOX *) 0x1367208

2. 赤い部分は、ダイジェスト レコードを 1 つずつ解放する pfs の操作です。データ行を解放するときにエラーが発生しました。

void reset_esms_by_digest()

{

uint インデックス;

if (statements_digest_stat_array == NULL)

戻る;

PFS_thread * スレッド = PFS_thread::get_current_thread();

if (unlikely(thread == NULL))

戻る;

(インデックス = 0; インデックス < digest_max; インデックス++)

{

statements_digest_stat_array[インデックス].reset_index(スレッド);

ステートメントダイジェスト統計配列[インデックス].reset_data();

}

ダイジェストインデックス = 1;

}

エラーの原因としては、次の 2 つが考えられます。

1. 同時実行性が高い場合、メモリアクセスで競合が発生します。

2. 特殊なSQLによりハッシュ処理時にエラーが発生します。

同様の問題をオンラインで検索すると、さらに進展があり、基本的にこの問題はバグによって引き起こされていることが確認されました。

次のMysqlバグレポートでは同様の問題について説明しています。

参考:

環境のより詳細な説明は次のリンクにあります。

https://bugs.launchpad.net/percona-server/+bug/1351148

5.6.35 のバグ修正は、私たちが遭遇した状況と非常に似ていることが判明しました。

_lf_pinbox_real_free の変更と比較すると、この部分は確かに大きな調整が加えられています。

以下は、MySQL 5.6.35 関数 _lf_pinbox_real_free のコード スニペットです。

static void _lf_pinbox_real_free(LF_PINS ピン)

{

LF_PINBOX pinbox= ピン->pinbox;

構造体 st_match_and_save_arg arg = {pins、pinbox、pins->purgatory};

ピン->煉獄 = NULL;

ピン->purgatory_count = 0;

lf_dynarray_iterate(&pinbox->pinarray,

(lf_dynarray_func)match_and_save、&arg);

(arg.old_purgatory) の場合

{

void *last = arg.old_purgatory;

(pnext_node(ピンボックス、最後))

最後 = pnext_node(ピンボックス、最後);

pinbox->free_func(arg.old_purgatory, last, pinbox->free_func_arg);

}

}

以下はMySQL 5.6.21関数_lf_pinbox_real_freeのコードスニペットです。

static void _lf_pinbox_real_free(LF_PINS ピン)

{

int ピン数;

無効リスト;

void **addr = NULL;

void 最初= NULL、最後= NULL;

LF_PINBOX pinbox= ピン->pinbox;

npins = ピンボックス->pins_in_array + 1;

if (pins->stack_ends_here != NULL)

{

int alloca_size = sizeof(void)LF_PINBOX_PINSnpins;

(利用可能なスタックサイズ(&ピンボックス、*ピン->スタック終了位置)>alloca_size)の場合

{

構造体st_harvesterhv;

引数は (void **) alloca(alloca_size);

hv.granary = アドレス;

hv.npins = nピン;

_lf_dynarray_iterate(&ピンボックス->ピン配列,

(lf_dynarray_func) 収穫ピン、 &hv);

npins = hv.granary-addr;

(ピン数)の場合

qsort(addr, npins, sizeof(void *), (qsort_cmp)ptr_cmp);

}

}

同時に、問題のあるクラスターでは、QPS が 6000 未満、Threads_connected が 8000 近くと異常な指標が見られることが確認されました。 (他の高同時実行クラスターと比較すると、QPS は 20,000 を超え、Threads_connected は 300 程度にすぎません)。

アプリケーション側の接続方法を確認したところ、アプリケーションの 1 つに 100 台近くのアプリケーション サーバーがあり、適切な接続の再利用なしに同時にリクエストを開始する可能性があることがわかりました。多数の接続スレッドを維持すると、バグが発生する可能性が高くなります。

修正されたバグの説明は次のとおりです。

qsort 操作のメモリ要件の計算ミスにより、多数の同時サーバー接続がある状況でスタック オーバーフロー エラーが発生する可能性があります。(バグ #73979、バグ #19678930、バグ #23224078)

【解決】

クラッシュ時のコア ファイルを分析し、クラッシュの原因となる条件を特定し、DML コレクション プログラム (テーブル events_statements_summary_by_digest 操作の切り捨て) を一時停止してから再開しました。

後で、これは MySQL のバグであり、MySQL バージョン 5.6.35 で修正されたことがわかりました。このバグは、アプリケーションがデータベースへの接続を大量に確立したときに発生する可能性が高くなります。

要約する

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

<<:  Centos Docker ブリッジ モードでホスト Redis サービスにアクセスできないというトラブルシューティングの経験

>>:  ロンボク実装 JSR-269

推薦する

...

マージンのマージの問題を解決する

1. 兄弟要素の余白を結合する効果は次のようになります: (2 つの間の間隔は 150 ピクセルでは...

Linux でパスワードの有効期限を表示および設定する方法

適切な設定を行うことで、Linux ユーザーにパスワードを定期的に変更させることができます。パスワー...

RedHat 6.5/CentOS 6.5 に MySQL 5.7.20 をインストールするための詳細なチュートリアル

rpmインストールパッケージをダウンロードするMySQL公式サイト: https://dev.mys...

MySQL の自動増分主キーが使い果たされた場合の対処方法

面接では、次のようなシナリオを経験する必要があります。インタビュアー: 「MySQL を使用したこと...

AngularとIonicのライフサイクルとフック関数を素早く理解するための記事

目次角度成し遂げる呼び出し順序知らせイオニックionic はページのライフサイクルをどのように処理し...

MySQLがlocalhost経由でデータベースに接続できない問題に対する完璧な解決策

問題:あるサーバー上の PHP プログラムは、localhost アドレス経由でデータベースに接続で...

Linux での tcpdump コマンド例の詳細な説明

序文簡単に言えば、tcpdump は、ネットワーク上のトラフィックをダンプし、ユーザーの定義に従って...

シームレスなカルーセル効果を実現するネイティブ js

参考までに、ネイティブjsでカルーセル効果(シームレススクロール)を実現しています。具体的な内容は以...

Flinkのフォールトトレラントメカニズムに関する簡単な説明:ジョブ実行とデーモン

目次1. ジョブ実行のフォールトトレランス1.1 タスクフェイルオーバー戦略1.2 ジョブ再開戦略2...

vsCodeはワンクリックでvueテンプレートを生成します

1. ショートカットCtrl + Shift + Pを使用してコンソールを呼び出します 2、「スニペ...

W3C チュートリアル (5): W3C XML アクティビティ

XML は、データを記述、保存、送信、交換するために設計されています。 XML 1.0 は XML ...

セマンティックウェブページ XHTML セマンティックマークアップ

構造とプレゼンテーションを分離するもう 1 つの重要な側面は、セマンティック マークアップを使用して...

Tomcatの再構成後に起動が遅くなる問題を迅速に解決

Jenkins+Tomcatサーバーの設定中に、Tomcat設定ファイルが変更され、サーバーのTom...

Div はフラッシュを覆います。フラッシュ透過方式により、フラッシュ上に DIV レイヤーを配置できます。

2つのタイプがあります: (異なるブラウザ) 1. IEブラウザで利用可能コードをコピーコードは次の...