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

推薦する

見落とされがちなMETAタグの特殊効果(ページ遷移効果)

Web デザインで js を使用すると、多くのページ効果を実現できますが、HTML タグの META...

Ubuntu 18.04 MySQL 8.0 のインストールと設定方法のグラフィックチュートリアル

この記事では、MySQL 8.0のインストールと設定方法を参考までに紹介します。具体的な内容は以下の...

擬似分散グラフィックを実現するための VMware 構成 Hadoop チュートリアル

1. 実験環境シリアルナンバープロジェクトソフトウェアとバージョン1オペレーティング·システムCen...

MySQL 圧縮版 zip のインストールに関する問題の解決策

本日、MySQLの圧縮版をインストールする際に問題が発生しました。サービスが起動できず、2、3時間苦...

Kubernetes コントローラーとラベルの簡単な分析

目次01 k8sの一般的なコントローラーRCコントローラーデプロイメント コントローラーステートフル...

LinuxベースのLVMシームレスディスク水平拡張の詳細な説明

環境名前財産CPU 5650 円メモリ4Gディスク20G+4TB この時点で、サーバーにはすでに次の...

Linux lsof コマンドの使用方法の詳細な説明

lsof (開いているファイルのリスト) は、プロセスによって開かれたファイルを表示するツールです。...

HTMLシールドの右クリックメニューと左クリック入力機能の例

右クリックメニューを無効にする <body oncontextmenu=self.event....

ウェブデザインの教育または学習プログラム

セクションコース内容営業時間1 ウェブデザインの概要2 2 HTML 基本タグとフォーマットタグ 2...

Reactのようなフレームワークをゼロから作成する

最近、インターネットで「Build your own React」という記事を見ました。著者は、シン...

CentOS システムの rpm インストールと Nginx の設定

目次CentOS rpm のインストールと Nginx の設定導入rpm パッケージのインストールサ...

コメント付きのスネークゲームを実装する js

この記事の例では、スネークゲームを実装するためのjsの具体的なコードを参考までに共有しています。具体...

MySQL 5.7.13 のインストールと設定方法の Mac でのグラフィック チュートリアル

MySQL 5.7.13 Mac用インストールチュートリアル、非常に詳細で、以下のように記録されてい...

クラウド CentOS で Docker リモート サービス リンクを有効にするための実装手順

ここでは、dockerがインストールされたcentosサーバーを紹介し、リモートリンクサービスを開始...

MySQL で自動インクリメントシーケンスを実装するためのサンプルコード

1. シーケンステーブルを作成する テーブル `sequence` を作成します ( `name` ...