導入 いつものように、シーンから始めましょう〜
さて、本題に戻りましょう。トランザクションの 4 つの主要な特性である、原子性、一貫性、独立性、永続性については、多くの人が理解しています。しかし、もう少し具体的に考えてみましょう。これらの 4 つの機能はデータベースにどのように実装されているのでしょうか?すると、この質問に答えられる人はほとんどいないでしょう。したがって、この記事では、MySQL の 4 つの主要機能の実装原則に焦点を当てます。 文章 ACID の 4 つの主要な特性を説明するために、口座 A から口座 B に 50 元を送金する例を見てみましょう。 原子性 定義上、アトミック性とは、トランザクションがすべての操作が実行されるか、まったく操作が実行されない、分割できない作業単位であることを意味します。つまり、転送は成功するか失敗するかのどちらかであり、中間の状態はありません。 原子性が保証できない場合はどうなりますか? データの不整合が発生し、アカウント A は 50 元減額され、アカウント B は 50 元増加し、操作は失敗します。システムは理由もなく50元を失います〜 分離 定義上、分離とは、複数のトランザクションが同時に実行される場合、トランザクション内の操作が他のトランザクションから分離され、同時に実行されるトランザクションが互いに干渉できないことを意味します。 分離が保証できない場合はどうなりますか? さて、口座 A に 200 元、口座 B に 0 元があるとします。口座Aは口座Bに合計50元を2回送金し、それぞれ2回の取引で実行しました。隔離が保証できない場合、次のような状況が発生する可能性があります。 図に示すように、分離が保証されていない場合、A は 2 回お金を差し引きますが、B は 1 回だけお金を追加し、50 元が突然消えてしまい、データの不整合が依然として発生します。 追記: 注意深い読者は、MySQL が分離の問題を解決するためにロックに依存していることに気付いたかもしれません。まあ、それは後で説明します。 持続性 定義上、耐久性とは、トランザクションがコミットされると、データベースへの変更が永続的になることを意味します。その後の他の操作や障害は、これに何ら影響を与えないはずです。 永続性が保証できない場合はどうなりますか? MySQL では、CPU とディスクの速度が一致しない問題を解決するために、ディスク上のデータをメモリにロードし、メモリ上で操作してからディスクに書き戻します。さて、この時点でサーバーがクラッシュすると、メモリ内で変更されたデータはすべて失われ、永続性が保証されなくなります。 転送が成功したことをシステムが通知すると想像してください。しかし、金額がまったく変わっていないことがわかります。このとき、データは不正な状態にあります。この状態をデータの不整合とみなします。 一貫性 定義上、一貫性とは、トランザクションが実行される前と実行後にデータが正当な状態にあることを意味します。この状態は、構文的ではなく意味的です。 わかりました。この状態は、事前に決められた制約を満たしている場合、合法的な状態と呼ばれます。より一般的な言葉で言えば、この状態はあなたによって定義されます。この状態が満たされると、データは一貫しています。この状態が満たされない場合、データは不整合です。 一貫性が保証できない場合はどうなりますか? 例1:口座Aに200元があり、300元が送金されます。このとき、口座Aの残高は-100元です。この時点では、当然ながらデータに矛盾があることがわかります。なぜでしょうか?状態を定義したため、残高列は 0 より大きくなければなりません。 例 2: 口座 A に 200 元があり、50 元が口座 B に振り込まれます。口座 A のお金は差し引かれますが、さまざまな予期しないイベントにより口座 B の残高は増加しません。現時点ではデータが矛盾していることもご存知ですが、その理由は何ですか? A + B のバランスが変化しないことを要求する状態を定義したためです。 実用的な答え 質問 1: Mysql はどのようにして一貫性を確保するのでしょうか? さて、この質問は 2 つのレベルに分けることができます。 データベース レベルでは、データベースは原子性、分離性、永続性を通じて一貫性を保証します。つまり、ACID の 4 つの主要特性のうち、C (一貫性) は目的であり、A (原子性)、I (独立性)、D (永続性) は、一貫性を確保するためにデータベースによって提供される手段です。一貫性を実現するには、データベースで AID の 3 つの主要な特性を実装する必要があります。たとえば、原子性は保証できず、当然一貫性も保証できません。 ただし、トランザクション内の制約に違反するコードを意図的に記述すると、一貫性は保証されません。たとえば、転送の例では、コードが意図的にアカウント B に資金を追加しない場合、一貫性は保証されません。そのため、アプリケーション層も考慮する必要があります。 アプリケーション レベルでは、コードを使用してデータベース データが有効かどうかを判断し、データをロールバックするかコミットするかを決定します。 質問 2: Mysql はどのようにして原子性を保証するのでしょうか? OK、Innodb の undo ログを使用することです。 UNDO ログはロールバック ログと呼ばれ、アトミック性を実現するための鍵となります。トランザクションがロールバックされると、正常に実行されたすべての SQL ステートメントが取り消されます。ロールバックする対応するログ情報を記録する必要があります。 例えば
UNDO ログには、ロールバックに必要な情報が記録されます。トランザクションが失敗した場合、またはロールバックが呼び出されてトランザクションがロールバックされた場合、UNDO ログの情報を使用して、データを変更前の状態にロールバックできます。 ps: 具体的な元に戻すログはどのようになっているのでしょうか? これは記事に書くことができます。さらに、書いても読む人はあまりいないので、とりあえずシンプルにしておきましょう。 質問 3: Mysql はどのようにして永続性を確保するのでしょうか? OK、Innodb の redo ログを使用します。 前述したように、MySQL はまずディスク上のデータをメモリにロードし、メモリ内のデータを変更してから、それをディスクにフラッシュします。このときにコンピュータが突然クラッシュすると、メモリ内のデータが失われます。 この問題を解決するにはどうすればいいでしょうか? 簡単です。トランザクションをコミットする前にデータをディスクに書き込むだけです。 こうすると何が問題なのですか?
そこで、上記の問題を解決するためにREDOログを使用することが決定されました。データが変更されると、メモリ内で実行されるだけでなく、REDO ログにも記録されます。トランザクションがコミットされると、REDO ログがディスクにフラッシュされます (REDO ログの一部はメモリ内にあり、一部はディスク上にあります)。データベースがクラッシュして再起動すると、REDO ログの内容がデータベースに復元され、UNDO ログと binlog の内容に基づいてデータをロールバックするかコミットするかが決定されます。 REDO ログを使用する利点は何ですか? 実際、REDOログをディスクにフラッシュする方がデータページをディスクにフラッシュするよりも効率的であるという利点があります。具体的なパフォーマンスは次のとおりです。
追伸: 内容が多すぎるため、REDO ログがどのようになっているかについては詳しく説明したくありません。 質問 4: Mysql はどのようにして分離を確保するのでしょうか? OK、ロックと MVCC メカニズムが使用されます。振替の例を例に挙げて説明しましょう。次のような口座表があります。 テーブル名 t_balance
このうち、id は主キー、user_id はアカウント名、balance は残高です。次の図に示すように、2回送金する例を見てみましょう。 MVCC (Multi Version Concurrency Control) の場合、レコード データ行には複数のバージョンのスナップショット データが含まれており、これらのスナップショット データは UNDO ログに保持されます。 トランザクションが DELETE または UPDATE 中の行を読み取る場合、読み取り操作は行のロックが解除されるのを待たずに、行のスナップショット バージョンを読み取ります。 MVCC の仕組みは、Repeatable Read と Read Commited MVCC で表現が異なるため、詳細には触れません。 ただし、注意すべき点の 1 つは、トランザクション分離レベルが Read Committed の場合、トランザクションは別のトランザクションによってコミットされたデータを読み取ることができ、分離要件を満たさないことです。ただし、トランザクション分離レベルが Repeatable Read の場合、分離は満たされます。 要約する この記事では、MySQL トランザクションの 4 つの主要な ACID 特性の実装原則について説明します。ご参考になれば幸いです。 さて、今回の記事は以上です。この記事の内容が皆さんの勉強や仕事に少しでも参考になれば幸いです。123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: CentOS 8 に Postfix メール サーバーをインストールして設定する方法
>>: WeChatアプレットは固定ヘッダーとリストテーブルコンポーネントを実装します
1. ubuntu16.04 イメージと対応する ubuntu16.04 カーネル バージョンのソー...
目次ユニオンクエリ1. 中国の各省のIDと名前を照会する2. 湖南省のすべての地級市のIDと名称3....
1. jmeterの基本イメージを構築するDockerfile は次のとおりです。 # Java 8...
効率的に要件を満たし、コンポーネント ライブラリの肥大化や車輪の再発明を避けるために、私は以前、大画...
リアルタイム レプリケーションは、企業データをバックアップする最も重要な方法です。主に、ユーザーが送...
目次序文1. レンダリング2. コード3. 背景画像素材要約する序文Threejs は、Web ベー...
以前、あるプロジェクトでMysql FIND_IN_SET関数を使用したことがありますが、非常に便利...
目次非同期を理解するフェッチ(url)レスポンス.json() asyncとawaitを組み合わせる...
以下のように表示されます。上記のように、置き換えるだけです。 Python3.6-MySql でファ...
インターネット技術の発展に伴い、ユーザーはますます Web ページに依存するようになり、Web フロ...
コンピューターに Linux Ubuntu システムをインストールしました。初めてインストールしまし...
1. AデータベースとBデータベースの同期ステータスを確認する次のコマンドを入力すると多くの情報が表...
序文Vue Router は、Vue.js の公式ルーティング マネージャーです。 Vue.js の...
1. はじめに(1)vw/vhの紹介使用する前に、vw と rem とは何か、その機能について簡単に...
1. MavenをダウンロードするMaven 公式サイト: http://maven.apache...