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クエリトランザクション処理へのノード接続の実装

推薦する

MySQL 制約の超詳細な説明

目次MySQL 制約操作1. 非ヌル制約2. ユニーク制約3. 主キー制約4. 外部キー制約5. カ...

Jsonフォーマットの詳細な説明

目次JSON は次の 2 つの構造に基づいて構築されます。 2. JSON形式1. オブジェクト2....

Dockerコンテナの紹介

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

MySQL での SQL モードの表示と設定の詳細な説明

MySQL での SQL モードの表示と設定MySQL はさまざまなモードで実行でき、さまざまなシナ...

Linux で推奨される 9 つの優れたコード比較ツールの概要

コードを書くとき、2 つのファイル間の違い、または同じファイルの異なるバージョン間の違いを知る必要が...

HTML Web ページ リスト タグ学習チュートリアル

HTML Web ページ リスト タグの学習チュートリアル。 HTML ページでは、リストはアウトラ...

Linux Autofs 自動マウント サービスのインストールと展開のチュートリアル

目次1. autofs サービスの紹介2. Autofsのインストールと展開3. Autofs効果の...

HTML の META タグの使用に関するヒントの例

HTML メタタグHTML メタタグは、Web ページのコンテンツに関する情報をブラウザや検索エンジ...

vue3 カスタムディレクティブの詳細

目次1. カスタム指示の登録1.1. グローバルカスタム指示1.2. ローカルカスタム指示2. カス...

InnoDB のアーキテクチャと機能の詳細な説明 (InnoDB ストレージ エンジンの読書メモの要約)

背景スレッド•マスタースレッドコア バックグラウンド スレッドは主に、バッファー プール データをデ...

React 星評価コンポーネントの実装

要件は、製品の評価データを渡すことであり、ページには対応する星の数が表示されます。 1. 異なる評価...

JS を使用した簡単な雪効果の例の詳細な説明

目次序文主な実装コードHTMLコードJSコード序文南の友達の多くは、雪をほとんど見たことがない、ある...

VUE v-for の :key の詳細な説明

v-for タグにキーが追加されていない場合。 <!DOCTYPE html> <...

MySQL でタイムスタンプを日付に変換する例

序文職場で次のような状況に遭遇しました。ログ システムのテーブルでは、時間フィールドには日付データで...

Nginx は高可用性クラスタ構築を実装します (Keepalived+Haproxy+Nginx)

1. コンポーネントと実装機能Keepalived: Haproxy サービスの高可用性を実現し、...