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

ブログ    

推薦する

React NativeとiOSの相互作用の詳細な説明

目次前提条件RNはiOSに価値を渡す方法1: ネイティブに値を通常通り渡す方法2: コールバック関数...

Vueでキャッシュされたページを管理する方法

目次問題1: 破壊1. 破壊する方法2. いつ破壊するか2.1 解決策1: route.queryを...

CentOS7 64ビットインストールmysqlグラフィックチュートリアル

MySQL をインストールするための前提条件: CentOS 7 64 ビットをインストールし、Ce...

Docker を使用して Spring Boot をデプロイする方法

Docker テクノロジの開発により、マイクロサービスの実装にさらに便利な環境が提供されます。Doc...

JS配列の一般的な方法とテクニックを学び、マスターになりましょう

目次splice() メソッドjoin() メソッド逆() メソッドevery() メソッド削減()...

MySQL はどのようにしてマスターとスレーブの一貫性を確保するのでしょうか?

目次MySQLマスタースレーブの基本原理3つのbinlog形式の比較混合形式のバイナリログが存在する...

mysql 8.0.20 winx64.zip 圧縮版のインストールと設定方法のグラフィックチュートリアル

mysql 8.0.20 winx64.zip圧縮版のインストールチュートリアルは以下のように記録さ...

MySQL の完全バックアップとクイックリカバリ方法

過去 15 日間のデータをバックアップするシンプルな MySQL 完全バックアップ スクリプト。バッ...

MySQL ストアド プロシージャの使用例の分析

この記事では、MySQL ストアド プロシージャの使用方法について説明します。ご参考までに、詳細は以...

HTML テーブルタグチュートリアル (44): テーブルヘッダータグ

<br />ソース コード内で表の構造を明確に区別するために、HTML 言語では、表のヘ...

優れたウェブワイヤーフレーム設計・制作ツール13選を紹介

プロジェクトの作業を開始するときは、ワイヤーフレームを使用してアイデアをスケッチすることが重要です。...

MySQLがOracleのnvlと同様の機能を持つことができるかどうかについての簡単な議論

isnullの代わりにifnullを使用するisnull は、null かどうかを判断するために使用...

MySQL FAQ シリーズ: 一時テーブルを使用する場合

一時テーブルの概要一時テーブルとは: MySQL は中間結果セットを保存するために使用されます。一時...

MySQLはinet_atonとinet_ntoaを使用してIPアドレスデータを処理します。

この記事では、適切な形式を使用して IP アドレス データをデータベースに保存し、IP アドレスを簡...

MySQL 8.0.26 のインストールと簡易チュートリアル (インターネット上で最も完全)

目次1. MySQLをダウンロードする1.1 ダウンロード1.2 インストール1. MySQLをダウ...