MySQL データベース分離レベルと MVCC の詳細な説明

MySQL データベース分離レベルと MVCC の詳細な説明

MySQL は、日常の制作や学習で最もよく使用されるデータベースの 1 つです。今日は、MySQL (または他の同様のデータベース) の分離レベルと、効率性を向上させるために使用されるマルチバージョン同時実行制御 (MVCC) について説明します。

1. 分離レベル

まず、「トランザクション」という概念について説明する必要があります。トランザクションとは何ですか?トランザクションは、基本的な操作を完了する一連の操作ステートメントの集合です。たとえば、口座 A から口座 B に 200 元を送金したい場合は、次のようにします。
a. 口座Aの残高が200元を超えていることを確認します。
b. 口座Aの残高を200人民元減らします。
c. 口座Bの残高に200人民元を追加します。
上記の 3 つの操作 abc を 1 つのトランザクションに結合します。
この時点で、ここで取り上げているトランザクションは複数のステートメントで構成されている可能性があり、トランザクションはアトミックである、つまりトランザクションの実行は中断できないことに気付くでしょう。ここで疑問が生じます。これらの 3 つのステップの実行に別のステートメントが挿入された場合、この時点でトランザクションのアトミック性が破壊されるため、結果に影響が出るのでしょうか。この種の挿入は並行環境では非常に一般的です。したがって、私たち (またはデータベース エンジン) は、トランザクションの実行中にトランザクションを「保護」する必要があります。つまり、他の外部トランザクションからのステートメントが、実行中のトランザクション ステートメントに勝手に挿入されないようにし、トランザクションが正常に実行されるようにする必要があります。このとき、「ロック」という方法を思いつくのは簡単です。これは実は非常に一般的な発言です。ロックによってトランザクションの正常な実行が保証される一方で、多くの追加オーバーヘッドが発生するからです。したがって、適切なタイミングで適切なロック方法を選択すると、検索効率に大きな影響を与えます。 「ロック」の厳密さによって、さまざまな分離レベルが決まります。

コミットされていない読み取り

この分離レベルでは、データの読み取りはまったく影響を受けません。つまり、他のトランザクションによって変更されているデータも読み取ることができ、いつでも読み取って変更することができます。確かにオーバーヘッドはほとんどありませんが、「ダーティ リード」などの多くの問題が発生する可能性があります。つまり、変更中だがまだ送信されていないデータが読み取られ、データ読み取りエラーが発生します。パフォーマンスの面では、READ UNCOMMITED は他のレベルと比べてそれほど優れているわけではありませんが、多くの厄介な問題を引き起こすため、実際にはほとんど使用されません。

READ COMMITED (コミット読み取り/非反復読み取り)

このレベルでは、READ UNCOMMITED に基づいていくつかの規定が追加され、一部のデータベースのデフォルトの分離レベルになります。 READ UNCOMMITED との違いは、読み取り中に読み取られるデータはコミットされたデータのみであると規定されている点です。たとえば、最後の送信後のデータ a の値は 1 です。このとき、スレッドが a を変更するために入ってきて、a を 2 に変更しますが、この時点ではトランザクション (COMMIT) はコミットされません。この場合、READ UNCOMMITED レベルで読み取られた a の値は現在の値 2 ですが、READ COMMITED レベルで読み取られた値は最後の送信後の値、つまり a が 1 のままです。a の値が 2 になるためには、変更スレッドが a の値を 2 に変更し、トランザクションがコミットされた後に a の値が読み取られる必要があります。このレベルによってもたらされる問題は、反復不可能な読み取りです。つまり、前回読み取った a の値は 1 だったが、変更スレッドがトランザクションをコミットしたため、a の値は 2 に変わり、今回読み取った値は 2 だった、つまり、同じ読み取り操作を 2 回実行して得られた値は異なるということです。
非反復読み取りとダーティ読み取りの違いは、ダーティ読み取りは別の未完了のトランザクションの実行中にデータを読み取るトランザクションであるのに対し、非反復読み取りは、あるトランザクションの実行中に別のトランザクションが現在のトランザクションによって読み取られているデータをコミットして変更する場合である点です。

繰り返し読む

REPEATED READ は、READ COMMITED に基づいていくつかの制限ルールを追加します。これは、MySQL データベースのデフォルトの分離レベルでもあります。簡単に言えば、トランザクションの実行中は、他のトランザクションが対応するデータを変更することを禁止します。これにより、トランザクションの実行中にクエリされたデータの一貫性が確保され、ダーティ リードや非反復リードの問題が解決されます。ただし、これにより「ファントム リード」という新しい問題が発生します。
「ファントム リード」とは、トランザクションの実行中に対応するデータの変更が禁止されているにもかかわらず、他のトランザクションがデータを挿入できることを意味します。このとき、最初のトランザクションは、あたかも錯覚が起こったかのように、何らかの追加データが「不可解に」現れることに気付きます。ファントム リードと非反復読み取りはどちらも、コミットされた別のトランザクションを読み取ります (ダーティ リードとは異なります)。違いは、非反復読み取りは同じデータ項目をクエリするのに対し、ファントム リードはデータのバッチ全体 (データの数など) をクエリすることです。

シリアル化可能

これは最も厳格な分離レベルです。トランザクションを強制的に連続して実行することで、ファントム リードの問題を回避します。ただし、この分離レベルは非常にコストがかかるため、あまり使用されません。

さまざまな分離レベルと発生する可能性のある問題の関係は次のとおりです。

分離レベルダーティリード繰り返し不可能な読み取りファントムリードロック
コミットされていない読み取りはいはいはいいいえ
コミットされた読み取りいいえはいはいいいえ
繰り返し読むいいえいいえはいいいえ
シリアル化可能いいえいいえいいえはい

MVCC

データの一貫性と正確性を確保するために、各 SQL 操作で行レベルのロックを追加する必要がある場合、信頼性は非常に高くなりますが、結果として生じるシステム オーバーヘッドと検索効率の低下も明らかです。そのため、この矛盾を解決するために MVCC が作成されました。
まず、MVCC はテーブルの各行の後ろに 2 つの隠し列を保存します。1 つは行の作成時刻を保存するためのもので、もう 1 つは行の有効期限 (削除) 時刻を保存するためのものです。この時間値は実時間ではなく、システムのバージョン番号です。トランザクションの開始時のシステム バージョン番号がトランザクション バージョン番号として使用され、照会されたレコードの各行のバージョン番号と比較されます。

  • INSERT: 新しく挿入された各行の行バージョン番号として現在のシステム バージョン番号を保存します。
  • DELETE: 削除された各行の行削除バージョン番号として現在のシステム バージョン番号を保存します。
  • 更新: 更新は、実際には、新しいデータを挿入し、元のデータを削除するプロセスとして理解する必要があります。つまり、現在のシステム バージョン番号を新しく挿入されたデータの行バージョン番号として保存し、現在のシステム バージョン番号を削除されたデータの削除バージョン番号として保存します。
  • SELECT: 次の条件を満たす行のみをクエリします。

a. 行バージョン番号がトランザクションバージョン番号以下である
b. 削除バージョン番号が未定義か、トランザクションバージョン番号より大きい

これら 2 つのバージョン番号を保存すると、ほとんどの操作をロックせずに正しく実行できるようになり、パフォーマンスと効率が確保されます。
MVCC は、READ COMMITED と REPEATABLE READ の 2 つの分離レベルでのみ機能することに注意してください。

以上がMySQLデータベース分離レベルとMVCCの詳細な説明です。MySQLデータベース分離レベルとMVCCの詳細については、123WORDPRESS.COMの他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MySQL トランザクション分離レベルと MVCC の詳細な説明
  • MySQL MVCCメカニズム原理の詳細な説明
  • MySQLのMVCCマルチバージョン同時実行制御の実装
  • MySQL における楽観的ロック、悲観的ロック、MVCC の包括的な分析
  • MySQL の簡単な分析 - MVCC
  • MySQL マルチバージョン同時実行制御 MVCC の実装
  • MySQL の分離レベル、ロック、MVCC の紹介
  • MySQL マルチバージョン同時実行制御メカニズム (MVCC) ソースコードの詳細な説明

<<:  ウェブページコンテンツの閲覧設計手法に関する議論

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

推薦する

Angularの親子コンポーネント通信の詳細な説明

目次概要1. 入力および出力プロパティの概要2. 入力属性3. プロパティバインディングは親コンポー...

HTML コード作成ガイド

共通コンベンションタグ自己終了タグ。閉じる必要はありません (例: img input br hr ...

Vue 仮想 Dom から実際の Dom への変換

別のツリー構造があるJavascriptオブジェクトでは、このツリーが本物であると伝えるだけでよいD...

Vueは開始時間と終了時間の範囲クエリを実装します

この記事では、Vueで開始時間と終了時間の範囲を照会する方法を参考までに紹介します。具体的な内容は次...

N キロメートル以内のデータを検索する MySQL の簡単な例

地球の円周率と半径、検索ポイントの経度と緯度から、検索ポイントと検索データテーブル間の距離はNキロメ...

MYSQL データベースの基礎 - 結合操作の原理

結合では、ネスト ループ結合アルゴリズムが使用されます。ネスト ループ結合には 3 つの種類がありま...

WeChatアプレットは日付と時刻に基づいた並べ替え機能を実装

最近、小さなプログラム プロジェクトを引き継いだのですが、リストを日付と時刻で並べ替えるという要件が...

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

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

MySQL実行計画の詳細な分析

序文前回の面接では、実行計画について質問されたとき、多くの人がそれが何なのか知りませんでした。実行計...

js を使用してウォーターフォール効果を実現する

この記事の例では、滝の流れの効果を実現するためのjsの具体的なコードを参考までに共有しています。具体...

Webフロントエンドベクターアイコンの使い方

序文フロントエンドページを書くとき、小さなアイコンなどの画像を使うことが多いです。画像を使うとコード...

Vueはel-tree遅延読み込みを使用して、追加、削除、変更、クエリ機能を実装します。

Vue のツリー表示については、プロジェクトが使用されています: エフェクト ダイアグラムがツリー...

Cronジョブを使用してCpanelでPHPを定期的に実行する方法

cpanel 管理バックエンドを開き、「詳細」オプションの下に「Clock Guardian Job...

ブラウザが登録できるイベントの概要

HTML イベント リスト一般イベント: onClick HTML: マウスクリックイベント。主にオ...

Deepin で virtualenv をインストールして使用するチュートリアル

virtualenv は、分離された Python 仮想環境を作成するためのツールです。独立したディ...