MySQL ストレージ エンジンの概要と InnoDB エンジン構造の理解

ストレージ エンジンの概要

実際にデータが格納されるディスクファイルを扱うのはデータエンジンであり、その上位層(サービス層)が処理したSQL命令(SQLの処理や分析結果)をデータエンジンに渡し、データエンジンはデータに応じてディスクファイルにデータを格納します。指示に従って、またはディスクファイルデータを読み取ります。したがって、データ エンジンは DBMS 全体の中核であり、データの読み取りとデータの保存という最も重要な機能を備えています。

表处理器テーブルごとに異なるストレージ エンジンを選択でき、ストレージ エンジンごとにデータ処理方法、テーブル構造、ファイル形式などが異なるため、ストレージ エンジンはテーブルのタイプ (ストレージ エンジンの元の名前) とみなすこともできます。

MySQL のデータ ストレージ エンジンはプラグ可能です。つまり、自由に切り替えることができます。データ ストレージ エンジンの動作単位はテーブルであり、テーブルごとに適切なストレージ エンジンを選択できます。
MySQL5.5 以降のデフォルトのストレージ エンジンは InnoDB エンジン (以前の MyISAM) です。これには他のデータ エンジンと比較して多くの利点があります (具体的な利点については後で説明します)。そのため、非常に特殊なシナリオを除いて、多くの場合、両方のエンジンを使用することが推奨されます。テーブルはデフォルトのストレージ エンジン InnoDB を使用します

SQL ステートメントの一般的な実行フロー
ここに画像の説明を挿入
データベースを操作する場合、グラフィカル クライアントまたはコマンド ラインを使用して、まずデータベース サービスに接続する必要があります。つまり、接続するには、接続層が接続を提供する必要があります。および認証、認可およびその他のサービス。
接続完了後、SQLを入力して操作することになりますが、このときサービス層は入力したSQL文の意味や文法をチェックし、構文解析ツリーを作成し、自動最適化を行います(バージョン5.7以前ではキャッシュクエリが必要な場合、キャッシュが Yes の場合は、キャッシュされた結果を直接返します。ヒット率が低すぎるため、バージョン 8 以降は破棄されました)。そして、処理したデータをエンジン層に引き渡し、
エンジン層は上位層の結果に応じてデータを保存したり抽出したりする役割を担い、ストレージ
層は実際にデータやログを保存し、エンジン層で管理します。

各ストレージ エンジンの紹介

コマンドラインからMySQLでサポートされているすべてのコマンドラインをshow engines確認
ここに画像の説明を挿入
。図に示すように、MySQLは8種類のデータストレージエンジンをサポートしていることがわかります。このエンジンはデフォルトで使用されます。最大の特徴はInnoDBトランザクションをサポートしていることです。分散トランザクション、行レベルのロックをサポート、外部キーをサポート
オープンソースであるため、各エンジンには独自の特徴があり、大企業は特定のビジネスに応じてエンジンをカスタマイズできます
データベースで最も重要なのは InnoDB ですエンジンと MyISAM エンジン、それぞれに独自の利点があります。 欠点、置き換えの関係ではありません。現在のバージョンで 1 つのエンジンが使用され、古いバージョンで 1 つのエンジンが使用されます。

InnoDB

このエンジンは MySQL 3.2 以降に登場し、MySQL 5.5 以降のデフォルトのストレージ エンジンです。

InnoDB の利点

  1. InnoDB エンジンは外部キーをサポートしていますが、外部キーはパフォーマンスの問題を引き起こす可能性があります
  2. InnoDB エンジンはトランザクション (非常に重要) をサポートし、コミットとロールバックという 2 つの操作を導入します。重要なデータの場合、トランザクションを持つことでデータの ACID (原子性、一貫性、分離性、耐久性) を保証できます。クラッシュ後は自動的に回復し、コミットされていないデータをロールバックできます。
  3. InnoDB は行レベルのロックをサポートしています。複数のスレッドが並行している場合、スレッドセーフの問題を解決するには、ロックする必要があります。他のエンジンは通常、テーブル レベルのロックを使用しますが、第 2 に、InnoDB は特定の操作行をロックできるため、テーブル全体の他のデータの同時操作に影響を与えず、同時実行効率が向上します。そのため、データ量が多く同時実行量が多い場合に特にその特徴が顕著になります。

InnoDBの特徴

  • .frmMySQL8 より前は、テーブル ストレージ ファイルはテーブル構造、テーブル データ、インデックスの2 つのカテゴリに分割されていましたが、.idbMySQL8 バージョン以降は、テーブル構造、テーブル データ、テーブル インデックスがすべて 1 つのファイルにまとめられて.idb保存されます。
  • InnoDB の主キー インデックスはデータ全体をリーフ ノードに保存します

MyISAM と比較した InnoDB の欠点

  • バッチクエリはMyISAMほど優れていません
  • メモリ使用量が多い: InnoDB はデータとインデックスをまとめて配置するため、リーフ ページをロードするときにこのページのデータもロードされます。ただし、MyISAM はこのページ データのアドレス アドレスをロードするため、データに比べて多くのスペースが節約され、そのため InnoDB のメモリ要件が高くなります。

InnoDB はハッシュ インデックスをサポートしていませんが、エンジンは自動的に最適化し、エンジン内のクエリに基づいて適応型ハッシュ インデックスを作成します。人間の介入は不可能です。大量のデータを追加する場合は、最初にテーブル内のすべてのインデックスを削除し、追加することができます
。追加時にインデックスのメンテナンスが不要となり、効率が向上します。

マイサイアム

MySIAMの利点

  • より高速なアクセス
  • count(*) は、統計計算用の変数があり、InnoDB を使用して O(n) レベルを 1 つずつチェックするため、O(1) レベルでより効率的です。

InnoDB と比較した MySIAM の欠点:

  • 外部キー、トランザクション、行レベルのロックはサポートされません (MyISAM はテーブルレベルのロックです)。

MySIAM 処理は、小規模で同時実行性が低い場合に適しており (テーブル ロックが同時実行性に影響するため)、データ整合性要件がありません (トランザクションをサポートしていないため、パフォーマンスが高いため)、クエリと追加はテーブルの変更や削除よりもはるかに高速で、メモリを節約できます。リソースを削減し、アクセス効率を向上させます (ほとんどのシナリオには InnoDB データ エンジンが推奨されます)

記憶

  • テーブルの構造はディスクに、テーブルのデータはメモリに格納され、メモリ上にあるため高速ですが、メモリのサイズにも制限があるため、テーブルのデータをメモリに格納することはできません。大量のデータ。
  • デフォルトのインデックス構造はハッシュ インデックスです。これは、データの一部を検索する場合は非常に高速であるという特徴がありますが、範囲を検索する場合は B+ ツリー インデックスほど優れていません。
  • メモリ サイズや停電などの物理的要因の影響を受けるため、一時データの保存またはキャッシュとしてのみ使用できます。ただし、これらの機能は Redis などの他のサーバー ソフトウェアに置き換えられています。したがって、使用量を減らします。

3つのエンジンの比較

特徴 InnoDB マイISAM 記憶
事務 サポート サポートしません サポートしません
外部キー サポート サポートしません サポートしません
ロックレベル 行レベルのロック テーブルレベル テーブルレベル
B+ ツリー インデックス サポート サポート サポート
ハッシュインデックス サポートされていませんが、内部最適化が作成され、介入することはできません サポートしません サポート (デフォルト)
挿入速度 遅い 真ん中 速い(メモリレベル)
メモリ使用量 中(インデックス構造) 低い 高 (データはメモリに保存されます)
使用するシーン 大量のデータ、同時書き込み、トランザクション要件 データが小さく、リソース消費を節約、ビジネスがシンプル、データのトランザクション要件なし データ量が少なく、データのセキュリティを気にせず、高いパフォーマンス要件がある

リレーショナル データベースを使用する主な理由は、そのトランザクション機能によりデータをより安全にできるためです。データにトランザクション機能が必要ない場合は、代わりに NoSQL が考慮されます。

他のエンジン

  • アーカイブ: めったに参照されない大量の履歴情報、アーカイブ情報、またはセキュリティ監査情報を保存および取得するための完璧なソリューションを提供します。インデックス、更新はサポートされず、行レベルのロックはサポートされません。一度も変更されず、クエリが少ないデータを挿入するのに適しています。
  • CSV エンジン: csv ファイルは mysql テーブルとして処理できます。保存形式は通常の CSV ファイル
    とその他のめったに使用されないエンジンです

エンジン関連の SQL ステートメント

  • 現在のシステムのデフォルトのストレージ エンジンを表示する show variables like '%storage_engine%';
    ここに画像の説明を挿入
  • システムのデフォルトのストレージ エンジンを変更しますSET DEFAULT_STORAGE_ENGINE=引擎名称;。この設定は、サーバーの再起動後に元の設定に戻ります。SQL 構成構成ファイルでmy.cnf変更できます。
    ここに画像の説明を挿入
  • テーブルの作成時にテーブルのストレージ エンジンを指定します。デフォルトのストレージ エンジンは指定しないでください。CREATE TABLE 表名( 建表语句; ) ENGINE = 存储引擎名称;
  • テーブルのストレージエンジンを変更するALTER TABLE 表名 ENGINE = 存储引擎名称;

InnoDB エンジン

推奨読書

論理ストレージ構造

InnoDB エンジンは、大きいものから小さいものまで、テーブル スペース、セグメント、エリア、ページ、行テーブル
スペースの 5 つのレベルの構造に分かれています。
テーブル スペースは、InnoDB 論理ストレージの最上位の構造であり、システム テーブル スペースに分割されます。 、独立テーブルスペース、一般テーブルスペース、一時テーブルスペース、およびUNDOテーブルスペース
MySQL 8以降、デフォルトでは、各テーブルは独立テーブルスペースに存在し(構造は引き続きシステムテーブルスペースに配置されます)、保存されます。ディスク上の別のファイルにあります。0に設定すると、各テーブルのデータがシステムテーブルスペースに配置されます。数据索引xx.ibdinnodb_file_per_tableibdata1


セグメントはデータセグメント、インデックスセグメント、ロールバックセグメントなどに分かれています。表のデータとインデックスは表スペースに配置され、表スペースではインデックスとデータも異なるセグメントに分割されて格納されます。インデックス B+ ツリーの構造によれば、データ セグメントはインデックス ツリー に格納され叶子节点、インデックス セグメントはインデックス ツリー に格納されます非叶子节点
セグメントのスペースは、テーブルのサイズ、テーブルのサイズ、セグメントのサイズに応じて拡張されます。セグメントには少なくとも 1 つのエリアが含まれており、セグメントの最小拡張単位はエリアです。エリアのデフォルトのサイズは 1M、つまり連続 64 ページです。領域拡張を行う場合、ページの連続性を確保し、ランダムIOを極力避けるため、毎回ディスクに対して4~5個の領域を要求します。各ページのデフォルト サイズは, 正確に, InnoDB のページは, オペレーティング システムは 4 回読み取りまたは書き込みを行います。インデックス ツリー上の各ノードは 1 ページであり、少なくとも 2 つのデータ項目が 1 ページに格納されます。フル データ ページにデータを連続して挿入すると、エクステントから新しいページが再割り当てされます。インデックス ツリーの途中からデータを挿入すると、ページがいっぱいになるとページ分割が発生します。



16K是Linux页大小的4倍磁盘与内存交互的最小单位

  • ページ分割
    リーフへの行データの格納は順序通りに格納する必要があり、順序を間違えて挿入したり、ページ全体に挿入したりするとページ分割が発生します。考える?新しいページに挿入してみませんか? データの保存がシーケンシャルであるためです。ページ分割を避けるにはどうすればよいでしょうか? 途中でいっぱいになったデータ ページにデータを挿入しないでください (つまり、順次挿入)。
    ここに画像の説明を挿入
    全ページの途中から直接切り離し、2ページに分割し、1ページに順番に挿入します。
    ここに画像の説明を挿入
    分割後、ページにスペースが余った状態で、挿入するデータを挿入します。
    ここに画像の説明を挿入
    最後に、挿入するデータを接続します。新しく開かれたページが順番に表示されます。InnoDB であることに注意してください。エンジンは bB+ ツリーを最適化しました。ページは双方向に接続されます。ページ
    ここに画像の説明を挿入
    分割により、大量のページが残り、スペースが無駄になります。ページ分割はパフォーマンスを消費するため、データを挿入するときは順番に挿入するようにしてください。

  • ページのマージ
    データが削除されると、InnoDB エンジンはマークを付けるだけで、ページ内の削除数がページの 50% に達すると、前後のページを検索してマージできるかどうかを判断します。
    ここに画像の説明を挿入
    いっぱいではない 2 つのページをマージします。テーブル内のデータ行はその行に保存されます。各行の保存サイズは、テーブルのフィールド設計と行のデータ サイズによって異なります。InnoDB は 、および a の単位で保存します。ページには複数の行が含まれています。
    ここに画像の説明を挿入


要約する
ここに画像の説明を挿入

建築

ここに画像の説明を挿入

InnoDB エンジンは、メモリ プール、バックグラウンド スレッド、ディスク ファイルの 3 つの部分で構成されます。

メモリ部分

ここに画像の説明を挿入
図からわかるように、メモリは主にBuffer PoolChange buffer、の 4 つの部分で構成されています。Log BufferAdaptive Hash Index

Buffer Pool:
最初の注意: バッファ プール查询缓存は同じものではありません (開始時にこれについて混乱していたため)
クエリ キャッシュ: サービス層がクエリ タイプを実行する SQL を受け取ると、まずメモリ クエリ キャッシュにアクセスして、このようなクエリがあります。 SQL キャッシュの結果がセマンティック構文などによって解析されない場合、それらは最終的にエンジン層に渡されて処理されます。バッファプールはエンジンレベルにあります。そして、この種のクエリ キャッシュは非常に非インテリジェントです。つまり、同じセマンティクスの SQL であるにもかかわらず、わずかな変更 (スペースの追加など) があると、前の SQL のキャッシュが見つからなくなり、ヒット率が低下します。これは非常に低いですが、MySQL8 バージョンでは削除されました。
バッファプールを導入する理由:
あらゆる種類のデータとインデックスがページの形式でテーブルスペースに配置され、テーブルスペースはディスク上のファイルの抽象化でもあります。つまり、データはディスク上に配置されます。
ただし、ディスク速度とメモリの間にはギャップがあり、特定のデータにアクセスする場合、そのデータが配置されているページ全体がディスクにロードされるため、効率が大幅に向上します。ただし、アクセス後、ページはすぐにディスクにフラッシュされません。第一に、このような頻繁なフラッシュ ディスクのランダム IO はパフォーマンスに大きな影響を与えます。第二に、メモリ内のデータは読み取られないようにまだ使用されている可能性があります。また。
バッファ プールの概要:
バッファ プールのデフォルト サイズは です128M。メモリのサイズが大きいほど、データが多くなり、ディスクへのクエリの可能性が低くなり、パフォーマンスが向上します。したがって、デバイスで許可されている場合は、大きいほど、よりいい。バッファ プールは複数存在できます。デフォルトは 1 つですが、その数は変更することもできます。
バッファ プールはページに基づいており、各ページのサイズはディスクのサイズと同じです16K。ページの機能に従って、索引页ページ数据页の取り消し、挿入キャッシュ、アダプティブ ハッシュ、ロック情報、
ページの状態に応じて、さらに次のように分類されます

  • 空きページ: メモリ内の空きページ、未使用のページ
  • clean page : データがディスクからメモリにロードされた後、ページは変更されておらず、ディスクと一貫性があります。
  • ダーティ: ページ内のデータは変更されており、ページはディスクに更新されていません。つまり、メモリ データがディスクと一致していないページです。MySQL が使用するメモリでは、通常、領域の 80% 以上が空き領域になります
    。バッファ プールに与えられ、そのサイズは全体のパフォーマンスに直接影響します。メモリが十分でない場合、InnoDB エンジンはLRU页面置换算法最も最近使用されていないページを使用して、最近使用されていないページをディスクから削除し、ディスクに更新します。ただし、InnoDB エンジンは LUR アルゴリズムを最適化します。たとえば、select * はテーブル全体のスキャンを実行し、使用頻度の低いデータをスキャンして最新の使用データにすることができます。InnoDB エンジンは、この状況に合わせて最適化されています。

Changer Pool是针对非主键索引插入的优化:通常、主キーは順番に挿入されるため、挿入バッファー プールとも呼ばれます。これは、主キー インデックス ツリーのインデックスを再作成するときに便利です。(必要に応じてリーフ ノードを追加するだけです)。挿入の際、非主キーインデックスが設定されている場合は、主キーインデックスツリーに挿入するだけでなく、非主キーインデックスツリーにも挿入する必要があります。非主キー インデックスのインデックス キーは多くの場合、順序どおりに挿入されず、非主キー インデックスへの個別のアクセスにより、ランダムな IO がパフォーマンスの低下につながります。変更プールを使用して、非主キーインデックスを挿入する場合、まず挿入に使用されたインデックスツリーのページがメモリ内にあるかどうかを確認し、存在する場合は直接挿入し、存在しない場合は対応するインデックスページをメモリに配置しますディスクから読み取った後、挿入します。データを読み取るときは、変更バッファとバッファ プールをマージし、特定の頻度でバッファ プールをディスクに更新します。たとえば、
id=2 および name='zs' のデータを挿入するには、id は主キーインデックス、名前は共通インデックスです。データを挿入するとき、ID は順序付けされて主キーのインデックス ページに直接挿入されますが、名前を挿入するとき、名前は通常順序が崩れるため、インデックスの一部を挿入バッファ プールに入れて最初に挿入する必要がありますchanger Pool。 、一緒にディスクにフラッシュします。提高非主键索引的插入性能


自适应哈希索引 AHI: エンジンはホット ページのハッシュ インデックスをユニット単位で。ハッシュ インデックスはハッシュ衝突なしでデータに 1 回しかアクセスできないのに対し、B+ ツリー主キー インデックスは通常 1 ~ 3 回必要なためです。ただし、ハッシュ インデックスは範囲クエリをサポートしていないため、エンジンが状況を判断して適切なデータのハッシュ インデックスを構築する必要があります。无需人为干预


logo buffer: ログ バッファ、REDO ログなどのメモリ部分がここにあり、デフォルトのサイズは 16M、メモリ内のデータは指定された頻度でディスクに更新されます。オプションは 3 つあります。最初のタイプは共有され、1 秒ごとにディスクにフラッシュされます。2 番目のタイプはトランザクションがコミットされた後にディスクにフラッシュされ、最初のタイプも同時に使用されます。3 つ目は、トランザクションがコミットされた後、システムのキャッシュ ページに渡され、指定された時刻にシステムがトランザクションをディスクに更新する方法で、最初の方法も同時に使用されます。

ディスク部分

ここに画像の説明を挿入
ディスク構造は主に次​​の部分で構成されます。

  • システム テーブルスペース: システム テーブルスペース
    システム テーブルスペースには 1 つ以上のデータ ファイルを含めることができます。デフォルトでは、ibdata1という名前の。
    システム テーブルスペースには、データ ディクショナリ (メタデータを含む)、二重書き込みバッファ (バージョン 8 以降はストレージ領域なし)、変更バッファ、UNDO ログ、およびシステム テーブルスペースに作成されたテーブルのデータとインデックス (システム テーブルスペースに保存されたものではない) が含まれます。別のテーブルスペース)。

  • File-Per-Table テーブルスペース: 独立したテーブルスペース
    各テーブルは、ディスク上の 1 つの.idbファイルに対応するデータとインデックスを保存するために、デフォルトで独立したテーブルスペースを使用します。

  • 一般テーブルスペース: 一般テーブルスペース
    は、複数のテーブルを格納できる共有テーブルスペースです。

  • REDO ログ
    REDO の 2 つのループは、ファイル ib_logfile0 および ib_logfile1 を書き込みます。

バックグラウンドスレッド

これは、メモリとディスクの間を移動し、それに応じてスケジュールを設定し、データ サービスを提供するスレッドであり、主に
に分かれています。Master ThreadIO ThreadPurge ThreadPage Cleaner Thread

マスター スレッドの
コア バックグラウンド スレッドは、他のスレッドのスケジューリングを担当し、マージbuffer poolchange bufferマージ、ダーティ ページ ストレージ、アンドゥ ページの回復なども担当します。
IO スレッド
ここに画像の説明を挿入
パージ スレッド
は、主にトランザクション後にアンドゥ ログ ログを回復します。送信により、マスター スレッド
ページへの負荷が軽減されます。 クリーナー スレッド
メモリ内のダーティ ページ データをディスクにフラッシュして、マスター スレッドへの負荷を軽減します。

InnoDBの3大特徴

推奨記事
InnoDBの 3 つの主な特徴はdouble write、 、 でありBuffer pool自适应哈希索引
後の 2 つは上で紹介されており、ここでは二重書き込みメカニズムのみを紹介します。
なぜ二重書き込みと呼ばれるのでしょうか?メモリ上のデータはまず顺序ディスク上の二重書き込みバッファに書き込まれるため、書き込みが成功したことを確認した後、メモリ上の同じデータを离散対応するテーブルスペースに書き込みます。

なぜ二重書き込みメカニズムがあるのですか?
まず、二重書き込みメカニズムの欠点について説明します: 同じデータがディスクに 2 回書き込まれ、追加の IO が実行されます。書き込みはシーケンシャルですが、追加の IO により全体のパフォーマンスが 5 ~ 10% 低下します。
二重書き込みメカニズムが導入された理由について話しましょう。根本的な理由は、メモリ データをリフレッシュするプロセスで発生するページ破損の問題、つまり部分写问题
ページ破損の問題を解決するためです。InnoDB エンジンはページを単位として使用し、各ページのサイズは 16K です。オペレーティング システム ( Linux) もページを単位として使用しますが、そのサイズは 4K です。つまり、メモリ内のデータをディスクに更新する場合は、まずオペレーティング システムのページに渡され、その後オペレーティング システムのページに渡される必要があります。ディスクに更新されます。これは、メモリ データのページが更新されるたびに、そのデータをオペレーティング システムに 4 回書き込む必要があることを意味します。しかし、この 4 回の間にダウンタイムなどの事故が発生すると、メモリ内の不完全なページがディスクに書き込まれ、ページ破損が発生します ( 部分写问题)。現時点では、永続性の原則に違反することはできません。ダウンタイムなどによりディスクに正しく書き込まれなかったデータをどのように回復するか?
まず最初に考えたのは、メモリ データがディスクに書き込まれ、REDO ログが存在することを確認することでした。しかし、REDO ログには何が記録されるのでしょうか? 物理レコード、つまりオフセットがxxxであるxxxページのアドレスデータはxxxxですが、ダウンタイムの原因となったレコードのページが完全に書き込まれておらず、ページが破損しているため、データレコードが壊れていることを意味します已经损坏!。対応するページアドレスも無効となります。では、REDO では binlog は使用できないのでしょう
か? binlog の機能はデータのバックアップとマスター/スレーブ レプリケーションですが、メモリとディスクのデータにはまったく注目せず、どれがディスクに書き込まれ、どれがダーティ ページにあるかを区別できません。
フルリカバリを行えば大丈夫なようです。しかし、コストが高すぎて現実的ではありません。
このとき、書き込みプロセス中に事故が発生した後にやり直しに記録されたページが破損して無効になることを防ぐために、二重書き込みメカニズムが導入されています。つまり、やり直しログに記録されているページが最初に操作されないということです。 。
では、最初にデータをどこに書き込むか? 書き込む場所はディスク上になければ意味がありません。なぜなら、私たちが行っているのはメモリとディスク間の対話型バックアップだからです。
InnoDB エンジンは、注文が最初にシステム テーブル スペースに書き込まれ、成功後に対応する独立したテーブル スペースに個別に書き込まれることを示します。また、InnoDB は二重書き込みの書き込み速度を最適化します。これは、この方法での書き込みはシーケンシャル書き込みであり、IO 操作が 1 つ追加され、それによるパフォーマンスの損失も最小限に抑えられるためです。
以上が導入理由です双写机制


二重書き込みファイル
このメカニズムでは、対応するストレージ ファイルが存在する必要があります。
二重書き込みキャッシュには、メモリ内の部分とディスク内の部分という共有部分があります。各部分は 2M に固定されており、
二重書き込みバッファーはディスク表スペース上の 128 ページ、つまり 1M ずつの領域が 2 つあり、合計 2M になります。バッファプールのデータをコピーする場合は、まず二重書き込みキャッシュのメモリ部分にデータをコピーし、次にメモリ部分を2回に分けて、ディスク部分の二重書き込みファイルを最初に書き込みます。毎回サイズ 1M のファイルを二重に書き込み、書き込みが成功した後、同じデータを対応する独立した表スペースに個別に書き込みます。


メモリがチェックポニット メカニズムをトリガーすると、いくつかのページのディスクへの書き込みが開始されます。具体的なプロセスは次のとおりです。

  1. メモリに書き込むダーティページをコピーして double writeメモリ部にコピー
  2. 二重書き込みメモリ部分は一度に 1 つの領域、つまり 1M に書き込まれ、システムテーブルスペース部分には 2 つの順序で書き込まれます。
  3. 書き込みが成功したことを確認した後、二重書き込みのメモリ部分は、対応する独立したテーブルスペースに同じデータを離散的に書き込みます。

二重書き込みプロセスで事故が発生した場合はどうなりますか?
最初の書き込みで事故が発生しました: 1 回目は、バックアップのためにメモリ データ (二重書き込みメモリ バッファ) をシステム テーブル ファイルに書き込むことです。
このプロセスで事故が発生した場合、 REDO を使用して、2 番目の書き込み時の 2 番目の事故を直接復元できます: 2 番目の書き込みでは、メモリ データ (二重書き込みメモリ バッファ) を対応する独立したテーブル スペースに書き込みます。ディスクへの書き込み中に事故が発生すると、ページが破損し但redo记载的页没有发生损坏ます。となり、やり直しで記録したページもこの時点で無効となります。ただし、ファイルがシステム テーブルスペースにある場合、システムの再起動時に、プロセス ページが損傷していないかどうかがチェックされ、ページが破損していることが判明した場合は、システム テーブルスペースから復元されますやり直しページが正常に書き込まれた後でのみ、ビジネスが完了したとみなされるため、事故です。


例: user テーブルがあり、id が主キー、name が共通インデックス、age が共通フィールドです。MySQL に接続し、ユーザー テーブルへのトランザクションを開き修改、「zs」という名前のユーザーの年齢を 10 歳に送信すると、MySQL の一般的な内部プロセスが次のようになります。MySQL の接続層はクライアントとの接続を確立し、次のチェックを行います
。 SQL ステートメントの構文とセマンティクス 最後に、それをエンジン層に渡します。このテーブルを見つけたエンジンは InnoDB エンジンです。InnoDB エンジンは、名前が 'zs' であるユーザーをバッファ プールから探します。見つからない場合は、非クラスター化インデックスを使用してその名前をテーブルとして使用します。インデックス値を使用して、このデータ行の ID を見つけます。id は、クラスタード インデックスに移動xxx.ibd文件中して、このデータ行が配置されているページ ( 内 ) を見つけ、それを にロードしBuffer Pool、これに書き込みロック、MDL ロックなどを設定します。 row (このプロセスには、このデータ行を読み取る MVCC メカニズムがあります)。同時に、トランザクションが開かれる前に、データ内のアンドゥ ログ ポインタがアンドゥ ログ レコードを指すようにし、同時に新しいアンドゥ ログを開きます。次に、バッファ プールの経過時間を 10 に変更します。このとき、REDO はディスク アドレスのデータの変更を記録し、UNDO は元の記録操作を復元する方法を記録し、binlog はユーザーのコマンド操作を記録します。 、redo および binlog はすぐに実行されます。バッファーの内容はディスクにフラッシュされ、undo はリサイクルのためにパージ スレッド スレッドに渡されます。ただし、メモリ内の変更されたデータはディスクにフラッシュされない場合があり、他に読み取るデータがある場合は、バッファ プール内のデータが直接返されます。このデータのダーティ ページがcheakPointメカニズムをトリガーすると、ダーティ ページがバッファ プールからメモリ バッファにコピーされdouble writer、メモリ内のシステム テーブルにデータが 2 回書き込まれます。メモリ内のデータを対応するページに書き込みます。 。対応する REDO ログ レコードは役に立たないため、新しいデータによって上書きされます。

おすすめ

転載: blog.csdn.net/m0_52889702/article/details/128359565