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 5.7.17 winx64 解凍版のインストールと設定方法のグラフィックチュートリアル

この記事では、MySQL 5.7.17 winx64解凍版のインストールと設定方法を紹介します。具体...

Docker Hubの動作原理と実装プロセスの分析

GitHub が提供するコード ホスティング サービスと同様に、Docker Hub はイメージ ホ...

Ubuntu 20.04は静的IPアドレスを設定します(異なるバージョンを含む)

Ubuntu 20.04はnetplanを通じてネットワークを管理するため、以前のバージョンとは少...

CSS における位置指定の概要

CSS には 4 種類の配置方法があり、シナリオによって効果が異なります。ここでは、これら 4 種類...

jsはタイトルと説明のキーワードを検出し、見つかった場合は置換するか他のページにジャンプします。

キーワード 一般タイトルには、クラック、キー、シリアル番号、キージェネレータなどの単語を含めることは...

MySQLの起動と接続方法の例分析

目次mysqldの起動方法方法 1: mysqld方法 2: mysqld_safe方法3: mys...

ハイパーリンクを開くターゲットのテスト

リンクのターゲット属性は、リンクが開く場所を決定します。その値は通常、_blank、_self、_p...

ウェブページの背景色を制御する CSS コード

誰もが自分の Web ページの背景にふさわしい画像を見つけることに悩むことが多いと思います。これは事...

MySql 共通クエリコマンド操作リスト

MYSQL でよく使用されるクエリ コマンド: mysql> select version()...

Linux Crontab シェル スクリプトを使用して第 2 レベルのスケジュールされたタスクを実装する方法

1. シェルスクリプトcrontab.shを書く #!/bin/bash step=1 #ステップ間...

VMware 仮想マシン ブリッジ モードでインターネットにアクセスできない問題を解決する方法

ステップ1: ローカルイーサネットプロパティをチェックして、VMwareブリッジプロトコルがインスト...

MySQL MHA の高可用性構成とフェイルオーバーの詳細な導入手順

目次1. MHAの紹介1. MHAとは何ですか? 2. MHAの構成3. MHAの特徴2. MySQ...

mysqlは時間を自動的に追加し、時間を自動的に追加および更新する操作を実装します

時間フィールドは、データベースの使用時によく使用されます。よく使われるのは作成時間と更新時間です。し...

Ajax は CORS レスポンス ヘッダーを設定してクロスドメインの問題を解決し、クロスドメインのケース スタディを実現します。

1. クロスドメインを実現するためにCORSレスポンスヘッダーを設定するクロスオリジンリソース共有...

MacでDockerがホストマシンにpingできない問題を解決する

解決Docker for Macに付属するLinux仮想マシン(軽量ですが、ソケットファイルを使用し...