MySQL のロックとトランザクションの簡単な分析

MySQL のロックとトランザクションの簡単な分析

MySQL 自体はファイルシステムに基づいて開発されましたが、ロックの存在が異なります。

データベース ソフトウェアである MySQL では、共有リソースへの同時アクセスが避けられません。異なるリソースへの同時アクセスを調整および管理するために、ロック メカニズムが作成されます。ロック メカニズムの存在により、データベースのデータの整合性と一貫性が確保されるためです。

ロック レベルに応じて、ロックは行レベル ロック、テーブル レベル ロック、ページ レベル ロックに分類されます。
ロックの種類によって、共有ロックと排他ロック(排他ロック)に分けられます。
行ロックとテーブルロックを調整するために、インテンションロック(テーブルレベルロック)が生成されます。

共有ロック。トランザクションがデータを読み取ることを可能にします。
排他ロック。トランザクションによるデータの変更または削除を可能にします。
インテンション ロックは、行レベルのロックを取得するときに自動的に追加されるテーブル レベルのロックで、インテンション共有ロックとインテンション排他ロックが含まれます。

MyISAM ストレージ エンジンではテーブル ロックのみがサポートされますが、InnoDB ストレージ エンジンでは行ロックとテーブル ロックがサポートされます。

MyISAM ストレージ エンジンがデータを変更または削除すると、排他ロックが生成され、テーブル全体がロックされるため、同時書き込みのパフォーマンスが低下します。読み取り時には共有ロックが生成され、テーブルがロックされず、読み取りパフォーマンスが向上します。

InnoDB ストレージ エンジンがデータを変更または削除すると、排他ロックが生成されます。ロックされた特定のインデックス レコードは、通常、テーブル内の他の行に影響を与えず、同時書き込みのパフォーマンスが向上します。読み取り時には、共有ロックが生成され、テーブルと行がロックされないため、読み取りパフォーマンスが向上します。

行ロックは、レコード行ではなくインデックス レコードをロックします。インデックスがない場合、暗黙的なインデックスがロックに使用されます。

テーブルの一部の行が排他ロックを取得した場合、テーブルに意図的排他ロックが生成されます。このとき、トランザクションがテーブル全体をロックしようとすると、意図的排他ロックの存在が判明するとトランザクションがブロックされます。意図的ロックは、各行をトラバースして排他ロックがあるかどうか確認する必要がなく、テーブルをロックできるかどうかを直接判断できます。意図的ロックは、行ロックとテーブル ロックの関係を効率的に調整します。

行レベル ロックは、ロック範囲に応じて 3 つのタイプに分けられます。

  • レコード ロック レコードの 1 行に対するロック。
  • ギャップ ロック ギャップ ロックは、レコード自体を含まない範囲をロックします。
  • Next-Key Lock は、レコード自体を含む範囲をロックして、ファントム読み取りの問題を解決します。

もちろん、ロックには長所と短所があり、デッドロックが発生する可能性もあります。
実行中に 2 つ以上のトランザクションがリソースを競合し、お互いに待機状態になる場合、デッドロックと呼ばれます。

最後に、ロックの存在により、後続のトランザクションの機能が強化されます。

MySQL は、データをある一貫性状態から別の一貫性状態に完全に切り替えることができるメカニズムを設計しています。このメカニズムはトランザクションと呼ばれます。

トランザクションには、原子性 (A)、一貫性 (C)、独立性 (I)、永続性 (D) という 4 つの主要な特性があり、これらは ACID と呼ばれます。

  • 原子性: トランザクション内のすべての操作は成功するか失敗するかのいずれかであり、分割することはできません。
  • 一貫性: トランザクションは、データベースをある一貫性のある状態から別の一貫性のある状態に変換し、データの整合性を保証します。
  • 分離: 同時実行制御とも呼ばれ、トランザクションはコミットされる前に他のトランザクションからは見えません。
  • 永続性: トランザクションがコミットされると、その結果は永続的になり、データベース障害によってデータが失われることはありません。

原子性と耐久性は REDO ログによって実現され、一貫性は UNDO ログによって実現され、分離性はロック メカニズムによって実現されます。

本質的に、アトミック性は永続性をサポートするために存在します。トランザクションの一部が REDO ログに書き込まれ、クラッシュや停電が発生した場合、トランザクションはアトミック性に従って復元される必要があります。この場合、ログ ファイルに永続化されたデータは、バックトラックによって元に戻す必要があります。 InnoDB ストレージ エンジンでは、REDO ログは ib_logfile0 と ib_logfile1 に対応します。

次に、トランザクションをロールバックする必要がある場合、一貫性を保証する必要があり、一貫性を実現するために UNDO ログが使用されます。UNDO ログには、トランザクションの複数のバージョンの情報の一部が保存されます。UNDO ログを通じて、トランザクションを変更前の状態にロールバックできます。

ここで、MySQL の MVCC マルチバージョン同時実行制御について言及する必要があります。これは、UNDO ログを通じても実装されます。
MVCC は、各データ行の最後に 2 つの隠しフィールド (作成バージョンと削除バージョン) を追加し、トランザクションが開かれるたびにトランザクション ID を初期化することによって実現されます。新しいデータを追加する場合、作成バージョンの値はトランザクション ID と等しくなります。データを削除する場合、削除バージョンの値はトランザクション ID と等しくなります。データを更新する場合、最初に削除されてから追加されます。元に戻すログには 2 つのデータがあり、1 つの削除バージョンはトランザクション ID と等しく、もう 1 つの作成バージョンの値はトランザクション ID と等しくなります。

トランザクションの実行中には、同時に他のトランザクションが存在する可能性があり、複数のトランザクションを互いに分離する、つまり同時実行制御を実現する必要があります。分離を実現するためにロックが使用されます。 MySQL のトランザクション分離レベルには、Read Uncommitted、Read Committed、Read Repeatable、および Serializable があります。このうち、コミット読み取りと繰り返し読み取りは、MVCC マルチバージョン同時実行制御に基づいて実装されています。

ロックはトランザクションの同時実行制御に利点をもたらしますが、ダーティ リード、反復不可能なリード、ファントム リードなどの欠点ももたらします。

ダーティ リードとは、トランザクションが別のトランザクションのコミットされていないコンテンツを読み取ることを意味します。別のトランザクションがロールバックされると、ダーティ データが表示されます。
反復不可能な読み取りとは、同じトランザクションが同じ SQL ステートメントを使用して複数の読み取りを実行し、異なる結果を返すことを意味します。
ファントム リードとは、トランザクションがレコードを追加または削除しているときに、表示されないはずのレコードが突然表示される状況を指します。

ダーティ リード問題を解決するには、分離レベルを少なくとも Read Committed に設定する必要があります。
繰り返し不可能な読み取りの問題を解決するには、少なくとも分離レベルを「繰り返し可能な読み取り」に設定する必要があります。
ファントム リード問題を解決するには、分離レベルを Serializable に設定するか、Next-Key Lock を使用する必要があります。

上記は、MySQL のロックとトランザクションの詳細についての簡単な分析です。MySQL のロックとトランザクションの詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MySQLデータベースのトランザクションとロックの詳細な分析
  • Mysql トランザクションで Update を実行するとテーブルがロックされますか?
  • MySQL トランザクション、分離レベル、ロックの使用例の分析
  • MySql のインデックス、ロック、トランザクションの知識ポイントのまとめ
  • MySql の知識ポイント: トランザクション、インデックス、ロックの原則、使用状況の分析
  • トランザクションとロックを表示するための MySQL の一般的なステートメント

<<:  Dockerを使用して完全な開発環境を構築するための詳細なチュートリアル

>>:  Vue のルータールーティングの 2 つのモード (ハッシュと履歴) の詳細な説明

推薦する

WeChatアプレット開発の章:落とし穴の記録

最近、会社初のミニプログラムの開発に参加しました。開発経験は基本的にWebViewをベースとしたハイ...

Dockerコンテナにホストディレクトリへの書き込み権限がない場合の解決策

Docker コンテナを適用する場合、多くの場合、ホスト ディレクトリを Docker コンテナにマ...

Vue は Websocket カスタマー サービス チャット機能を実装します

この記事では主に基本的なチャットの実装方法を紹介します。今後は絵文字や写真のアップロードなどの機能も...

Element UI を使用してページにページング ナビゲーション バーを追加する方法

必要ページング バーを追加します。これにより、ページにジャンプしたり、ページ番号に従って特定のページ...

VMware12 で Ubuntu19.04 デスクトップ版をインストールする (インストール チュートリアル)

1. 実験の説明仮想マシンに、 Ubuntu 19.04オペレーティングシステムを手動でインストー...

MySQL 8.0.18コマンドの詳細な説明

解凍したフォルダ C:\web\mysql-8.0.11 を開き、フォルダ内に my.ini 構成フ...

Linux のスケジュールタスク Crontab コマンドの使用に関する詳細な説明と概要

crontab コマンドは、Unix および Linux で定期的な実行命令を設定するために使用され...

MySQLクエリトランザクション処理へのノード接続の実装

目次トピックmysqlの追加、削除、変更、クエリを入力しますMySQL トランザクション処理私は M...

jQueryチェーン呼び出しの詳細な説明

目次チェーン呼び出し小さなケースチェーン呼び出しjQuery オブジェクトが任意のメソッド (ノード...

MySQL 8.0.13 で日付を 0000-00-00 00:00:00 に設定すると発生する問題を解決する

データベース操作を学び始めたばかりです。今日、データを保存していたところ、エラーが発生していることに...

Linux bash: ./xxx: バイナリ ファイルを実行できません エラー

今日、Ubuntu 用の小さなツールを顧客に送りましたが、ユーザーはそれを受け取った後、実行できませ...

MySQL データベースにおける高同時実行性の問題を解決する方法

序文スタートアップ企業が最初はモノリシック アプリケーションを主要なアーキテクチャとして使用し、通常...

Vue3カプセル化メッセージメッセージプロンプトインスタンス関数の詳細な説明

目次Vue3 カプセル化メッセージプロンプトインスタンス関数スタイルレイアウトカプセル化メッセージ....

Dockerfile の一般的なコマンドの概要

構文の構成: 1 注釈情報2 コマンド --- パラメータ [通常は大文字 | 実際には大文字と小文...

2048 ゲームを実装するためのネイティブ js

2048ミニゲーム、参考までに具体的な内容は以下のとおりですまず、2048ゲームは16のグリッドか...