MySQL での大規模トランザクションによって発生する挿入の遅延ケースの分析

MySQL での大規模トランザクションによって発生する挿入の遅延ケースの分析

【質問】

INSERT 文は最も一般的な SQL 文の 1 つです。最近、MySQL サーバーが同時スレッド アラートを定期的に報告するようになりました。ログ情報から、実行に数十秒かかり、ログのフラッシュを待機し、クエリ終了状態にある、低速の挿入クエリが多数あることがわかります。

[予備分析]

リソース待ちの観点から見ると、ほとんどの時間が innodb_log_file ステージで費やされており、ディスクの問題が原因ではないかと疑われています。調査の結果、サーバー自体にハードウェアの問題は見つかりませんでした。

その後、スレッドが増えると、MySQL スレッドが待機している位置を特定するために、pstack の自動収集が有効になります。

【分析プロセス】

pstackの自動クロールを導入後、スレッド同時実行数>=50のアラーム(アラームが発行されるたびに大量の低速クエリが生成される)が6件発生し、そのうち3件は現場で捕捉されました。

同時スレッド数が増えると、 Stage_manager::enroll_for関数のグループコミットステージで50以上のスレッドがスタックします。

スレッド0x519c5940に対応するSQL文は次の通りであり、18秒間実行されている。

Stage_manager::enroll_for関数の目的は、flush_stage ステージで複数のスレッドのキューイングを実装することです。簡単に言えば、グループ化されたトランザクションの場合、リーダー スレッドによって送信され、他のスレッドはキュー待機状態になり、リーダー スレッドがスレッドのトランザクションを送信するのを待機します。

最初のスレッドの実行が遅い場合、後続のスレッドは待機状態になり、トランザクションのグループ全体をコミットできません。

このプロセスは次のように理解することもできます。

セッション A COMMIT --> ロックを取得 --> binlog を書き込む --> コミットが完了

セッション B COMMIT-->ロックを待機--------------------------->ロックを取得-->binlog を書き込む-->コミット完了

最初のスレッドの実行が遅いのはなぜでしょうか? アラーム期間中にログ ファイルを分析したところ、ログ ファイル内に 15M と 20M の 2 つの大きなトランザクションがあることがわかりました。

ログの詳細を確認してください。約 230,000 件のレコードを含む「delete from」という大規模なトランザクション削除ステートメントがあります。ROW モードで 230,000 件のレコードを削除すると、約 20 MB のログ ファイルが生成されます。ディスク フラッシュ時間が長いため、同じグループ内の他のトランザクションの送信がブロックされます。

取引の開始時間はアラーム時間と一致する

バックログされたグループ化されたトランザクションは、集中的にディスクにフラッシュされます。これはディスク インデックスに反映されます。問題発生期間中、disk_write_kbytes インデックスは大幅に増加します。

【最適化計画】

1. 開発者は、テーブル全体の大規模なトランザクションを削除するために delete from ステートメントを使用しないことをお勧めします。

[その他の回避策]

2. ROW モードの Binlog レコードでは大量のログが生成されます。MIXED モードに変更すると、理論的には問題を解決できます。

3. よりパフォーマンスの良いディスクに交換する

要約する

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

以下もご興味があるかもしれません:
  • MySQL 8.0 の統計が不正確である理由
  • MySQLにデータを素早くインポートする方法
  • データベース管理に役立つ 5 つの MySQL GUI ツール
  • Centos7 MySQL データベースのインストールと設定のチュートリアル
  • Python で 51cto データをクロールして MySQL に保存する方法
  • MYSQL SERVER のログファイルを縮小する方法
  • MySQL が大規模トランザクションを避けるべき理由とその解決方法

<<:  nginx がアップストリーム アドレスにジャンプしない問題の解決方法

>>:  Zabbix で複数の JVM プロセスを監視する方法

推薦する

HTML でスクロールバーを非表示にしたり削除したりする方法

1. 属性付きHTMLタグXML/HTML コードコンテンツをクリップボードにコピー< htm...

Vue.jsフレームワークはショッピングカート機能を実装します

この記事では、ショッピングカートを実装するためのVue.jsフレームワークの具体的なコードを参考まで...

mysql データベースの作成、ユーザーの追加、ユーザー認証の実用的な方法

1. MySQLデータベースを作成する1. データベース構文を作成する --「testdb」という名...

HTMLウェブページテーブル構造化マークアップの応用に関する簡単な説明

Web テーブルの構造マークアップについて説明する前に、いくつかの画像を見てみましょう。 HTML ...

Centos8 システムの VMware インストール チュートリアル図 (中国語グラフィカル モード)

目次1. ソフトウェアとシステムイメージ2. 仮想マシンを作成する3. CentOS8をインストール...

Echarts 基本入門: 棒グラフと折れ線グラフの一般的な構成

1eChartsの基本手順4つのステップ1 DOMコンテナを見つける2 初期化3 設定オプション4 ...

HTML+CSS+JavaScript でガールフレンド版のスクラッチ カードを作成します (一度見ればすぐに覚えられます)

誰もがスクラッチ チケットで遊んだことがあると思います。子供の頃、ポケットにお金が入るとすぐに友達に...

要素を中央に配置するための配置方法 (Web ページ レイアウトのヒント)

ブラウザウィンドウの中央に要素を配置する方法まず、コード ブロックを示します。すでにコードを理解して...

Dockerコンテナの紹介

1. 概要1.1 基本概念: Docker は、Go 言語をベースにしたオープンソースのアプリケーシ...

MySQL シリーズ 12 バックアップとリカバリ

目次チュートリアルシリーズ1. バックアップ戦略の説明1. バックアップの種類2. バックアップで考...

blockquote タグの使用に関する注意

<br />セマンティクス化は一言で説明することはできないし、まだ公式かつ厳密な定義もあ...

JSはjQueryのappend関数を実装します

目次コードを見せてください効果をテストする効果追伸別のアプローチコードを見せてください HTMLEl...

nginx/apache 静的リソースのクロスドメインアクセスの問題を解決する詳細な説明

1. Apache 静的リソースのクロスドメイン アクセスApache設定ファイルhttpd.con...

vue+iviewのメニューとタブの連携方法

Vue+iview メニューとタブのリンク現在、vue+iview を使用してバックエンド管理システ...

CentOS 8 インストール図 (超詳細なチュートリアル)

CentOS 8 が正式にリリースされました! CentOS は Red Hat の再配布ポリシー...