MySQL が大規模トランザクションを避けるべき理由とその解決方法

MySQL が大規模トランザクションを避けるべき理由とその解決方法

何が大問題ですか?

長時間実行され、長時間コミットされないトランザクションは、大規模トランザクションと呼ばれます。

大企業の原因

  • 操作するデータがさらにあります
  • ロック競合が多い
  • トランザクションにはDB以外の時間のかかる操作が他にもある
  • 。 。 。

大きな出来事の影響

  • 同時実行状況では、データベース接続プールがバーストする傾向がある
  • ロックするデータが多すぎるため、ブロックやロックタイムアウトが頻繁に発生する
  • 実行時間が長く、マスタースレーブ遅延が発生する可能性がある
  • ロールバックには長い時間がかかります
  • UNDOログの拡張
  • 。 。 。

大規模なトランザクションをクエリする方法

**注**: この記事のSQL操作はMySQLバージョン5.7に基づいています。

クエリ実行時間が 10 秒を超える場合を例に挙げます。

information\_schema.innodb\_trx から TIME\_TO\_SEC(timediff(now(),trx\_started))>10 となる \* を選択します。

大きな取引を避ける方法

一般的な解決策

  • トランザクションで一度に大量のデータを処理しないようにする
  • トランザクションでは、不要なクエリを避けるようにしてください
  • トランザクションでは、トランザクション タイムアウトを引き起こす可能性のある、時間のかかる操作をあまり多く実行しないようにしてください。 RPC 呼び出しやメッセージ キュー操作などの一部の非 DB 操作をトランザクションの外部に配置するようにしてください。

mysql5.7 に基づくソリューション

  • InnoDB トランザクションでは、行ロックは必要な場合にのみ追加されますが、不要になったときにすぐには解放されません。代わりに、トランザクションが終了したときにのみ解放されます。 **トランザクションで複数の行をロックする必要がある場合は、ロックの競合を引き起こし、同時実行性に影響を与える可能性が最も高いロックをできるだけ後ろに配置します**
  • SETMAX_EXECUTION_TIME コマンドを使用して、各ステートメントの最大クエリ時間を制御し、単一のステートメントによるクエリが誤って長時間実行されるのを防ぎます。
  • information_schema.Innodb_trxテーブルを監視し、長いトランザクションのしきい値を設定し、それを超過すると警告または強制終了する
  • 業務機能のテストフェーズでは、すべての general_logs を出力し、ログの動作を分析して事前に問題を見つける必要があります。
  • innodb_undo_tablespaces 値を設定して、UNDO ログを別のテーブルスペースに分離します。大規模なトランザクションによってロールバック セグメントが大きくなりすぎる場合は、設定後にクリーンアップする方が簡単になります。

付録 クエリトランザクション関連ステートメント

**注**: SQL文はMySQL 5.7バージョンに基づいています

# 実行中のすべてのトランザクションとその実行時間を照会します。 select t.\*,to\_seconds(now())-to\_seconds(t.trx\_started) idol\_time from INFORMATION\_SCHEMA.INNODB\_TRX t



# トランザクションの詳細と実行されたSQLを照会する

information\_schema.innodb\_trx a から now(),(UNIX\_TIMESTAMP(now()) - UNIX\_TIMESTAMP(a.trx\_started)) diff\_sec,b.id,b.user,b.host,b.db,d.SQL\_TEXT を選択し、information\_schema.innodb\_trx a を内部結合し information\_schema.PROCESSLIST b を生成します。

a.TRX\_MYSQL\_THREAD\_ID=b.id かつ b.command = 'Sleep' の場合

内部結合パフォーマンス\_schema.threads c ON b.id = c.PROCESSLIST\_ID

内部結合 performance\_schema.events\_statements\_current d ON d.THREAD\_ID = c.THREAD\_ID;



# トランザクションによって実行されたすべての履歴SQLレコードをクエリする SELECT

 ps.id 'プロセスID'、

 追伸:ユーザー様、

 追伸:ホスト、

 esh.EVENT_ID、

 trx.trx_started、

 esh.event\_name 'イベント名',

 esh.sql\_text 'SQL'、

 追伸時間 

から

 パフォーマンス\_SCHEMA.イベント\_ステートメント\_履歴 esh

 PERFORMANCE\_SCHEMA.threads th を esh.thread\_id = th.thread\_id に結合します

 information\_schema.PROCESSLIST ps を ps.id = th.processlist\_id に結合します。

 LEFT JOIN information\_schema.innodb\_trx trx ON trx.trx\_mysql\_thread\_id = ps.id 

どこ

 trx.trx_id は NULL ではありません 

 かつ ps.USER != 'SYSTEM\_USER' 

注文する

 esh.EVENT_ID;

 

 # 単純なクエリトランザクションロック select \* from sys.innodb\_lock\_waits

 

 #トランザクションロックの詳細を照会するSELECT

 tmp.\*,

 c.SQL\_テキストブロッキング\_sql\_text、

 p.HOST ブロッキング\_ホスト 

から

 (

 選択

 r.trx_state 監視中のtrx_state、

 r.trx_id 待機中のtrx_id、

 r.trx\_mysql\_thread\_Id 待機中\_スレッド、

 r.trx_query 待機クエリ、

 b.trx_state ブロッキングtrx_state、

 b.trx_id ブロッキングtrx_id、

 b.trx\_mysql\_thread\_id ブロッキング\_スレッド、

 b.trx_query ブロッキングクエリ 

 から

 情報\_schema.innodb\_lock\_waits w

 INNER JOIN information\_schema.innodb\_trx b ON b.trx\_id = w.blocking\_trx\_id

 INNER JOIN information\_schema.innodb\_trx r ON r.trx\_id = w.requesting\_trx\_id 

 ) 一時、

 情報\_schema.PROCESSLIST p、

 パフォーマンス\_SCHEMA.イベント\_ステートメント\_現在のc、

 PERFORMANCE\_SCHEMA.threads t 

どこ

 tmp.blocking_thread = p.id 

 かつ t.thread_id = c.THREAD_ID 

 かつ t.PROCESSLIST_ID = p.id

上記は、MySQL で大規模トランザクションを回避する方法と大規模トランザクションを解決する方法の詳細です。MySQL の大規模トランザクションの詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MySQLにおけるトランザクション分離レベルの実装原理の詳細な説明
  • MySQLトランザクションを実行するための構文とプロセスの詳細な説明
  • mysql と oracle のデフォルトのトランザクション分離レベルの説明
  • MySQL トランザクション自動コミット自動コミット操作
  • トランザクションとロックを表示するための MySQL の一般的なステートメント
  • MySQL マスタースレーブ同期、トランザクションロールバックの実装原理
  • MySQLデータベースのトランザクションとロックの詳細な分析
  • Mysql トランザクションで Update を実行するとテーブルがロックされますか?
  • PHP+MySQL 分散トランザクションとソリューションに関する深い理解
  • MySQL は ACID トランザクションをどのように実装しますか?
  • MySQLにおけるトランザクションの永続性実装原理の詳細な説明

<<:  単一マシン上での Tomcat の複数インスタンスの実装

>>:  ReactプロジェクトでのTypeScriptの実装

推薦する

MacでのMySQL初期化パスワード操作

Macでデータベースを操作する際に個人が遭遇するデータベース起動の問題の簡単な記録1. Apple-...

MySQL ビューの一貫性を確保する方法の詳細な説明 (チェック オプション付き)

この記事では、例を使用して、MySQL ビューの一貫性を確保する方法 (チェック オプションを使用)...

Centos8環境でSSHポート番号を変更する方法

目次序文始める序文サーバーのデフォルトの SSH ポート番号は通常 22 であるため、ほとんどのユー...

データベース接続のURLの詳細な説明と概要

データベース接続のURLの詳細な説明と概要JDBC URL = プロトコル名 + サブプロトコル名 ...

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

この記事では、MySQL 8.0.13のインストールと設定のチュートリアルを参考までに紹介します。具...

MYSQL 文字列強制変換メソッドの例

序文2 つのテーブル内の同じフィールドの型が異なっていたり、エンコード タイプが異なっていたりするた...

Navicat for MySQL チュートリアル

まず、Navicat for MySQL をダウンロードしてインストールする必要があります。正規版の...

Vue3の組み込みコンポーネントであるTeleportの使い方を詳しく説明します

目次1. テレポートの使用2. モーダルダイアログコンポーネントを完成させる3. コンポーネントのレ...

TypeScriptのインストールと使用方法と基本的なデータ型

最初のステップはTypeScriptをグローバルにインストールすることですnpmを使用してインストー...

aタグのhref属性とonclickイベントの比較

まず、href 属性と onclick イベントの実行順序について説明します。マウスが a タグをク...

Centos7 への mysql8.0rpm のインストール チュートリアル

まず、図をダウンロードしてください 1. まず、centos7に付属しているmariadbをアンイン...

VirtualBox6上のCentOS7で静的IPを設定する方法と注意点

VirtualBox をインストールした後、CentOS 7 をインストールします。ここでは詳細には...

階段効果を実現するためのWeChatアプレットカスタムメニューナビゲーション

設計意図ページを開発する際には、ページ上のナビゲーション メニューをクリックしたときにページを対応す...