MySQLの···InnoDBエンジン特性分析データ・ページ

MySQLの···InnoDBエンジン特性分析データ・ページ

序文

 

撮影http://mysql.taobao.org/monthly/2018/04/03/

導入前の月次レポート、InnoDBのバッファプールの実装の詳細の詳細は、バッファー・プールは、主に店舗のデータページに使用され、データページは、動的メモリに格納され、静的なページの記事では説明しているか、ディスク上のデータストレージおよび関連事業。データページの構造がコードの根底にあるのInnoDBに向けられているので、それぞれのMySQLバージョンを参照することができます。主に、関連するコード・ページのディレクトリに集中。

基本

データのページに編成されたデータの形式でデータベース。非圧縮データページは16キロバイトであるデフォルトのMySQL。中間IBDにおいて、0〜16キロバイトのデータ・ページ0の数であり、16キロバイト、32キロバイトのページデータが1であり、そうでオフセット。ヘッドと、いくつかのメタ情報を除き、尾のデータページ、およびチェックサムチェック値、ディスクに書き込む前に計算されたチェック値、ディスクから読み出され、データページに保存されているチェックサム値を再計算これとは対照的に、我々は別のを見つけた場合、それはMySQLのクラッシュの原因となります。バックアップが利用できない場合、このようなケースでは、多くの場合、あなたは、バックアップデータからの回復に注力する必要がある、唯一の使用innodb_force_recoveryを開始した後、可能な限りデータをエクスポートすることを余儀なく。この月報は、物理的なドキュメントからデータを回復する方法を説明している、それは絶望的な状況で使用することができます。

ページデータ

厳密に言えば、多くのInnoDBデータページがあり、例えば、インデックスページ、取り消しページ、等iノード・ページ、ページ、BLOBページ、10種類の合計。本論文では、最も一般的なインデックスページを記述する。以下では、特別な命令は、データページは、ページの人差し指ません。データページには、7つの部分、データページヘッダ、ページヘッダデータ、最大値と最小値を記録、顧客レコード、空き領域、データディレクトリ、データページ尾から構成されています。単純な、データページが記録を介して接続されているレコードポインタの大きさに応じて格納されたデータ・レコードの二種類があります。ストアデータページへのディレクトリの別の部分は、検索を高速化するために使用しました。このディレクトリはディレクトリではないすべてのレコードがインデックスを持っている、すべての6つのレコードの平均値は、ディレクトリを持っていること、まばらであることに注意してください。データディレクトリの反対側の一部ながら、データ記録部は、低アドレスからのアドレス空間の高成長です。このデータ構造は、比較的高い挿入、削除、検索効率を保証します。で詳述具体的な方法核心函数のセクション。この月報最後の画像は、データ・ページの構造を詳細に、読者はまず自分自身を見ることができ、次回、記事ではどのような各セクションについて説明します。

データ・ページ・ヘッダ(フィルヘッダ)

この部分は主に表スペースに関連した情報を格納するために使用されます。主にこのファイルfil0fil.hインチ

FIL_PAGE_SPACE_OR_CHKSUM: チェックサムは、主に店舗のデータページに使用され、4つのバイトを占めました。チェックサム値を計算する際に、全体ではなくデータページがカウントされることに注意してください、に算出されていないいくつかの場所がある(buf_calc_page_crc32buf_calc_page_new_checksum)、そのようなspace_id場所(歴史的な理由)を維持する頭部と尾デポジットチェックサム場所として。詳述チェックサム計算方法数据页Corruptionこのセクション。

FIL_PAGE_OFFSET: 対応するデータ・ページは、ファイルの開始オフセット0から、すなわち、値がデータページを取得することができるデータ・ページのサイズが乗算された各表領域を、開始、ページ番号です。fio_ioこのルールに依存するときに、データ・ページを読み書きする機能。

FIL_PAGE_PREV,FIL_PAGE_NEXT: これは、データ・ページの後に、前のページとデータへのポインタ2点です。、ここでは利用者の順序に従ってフロントとリアのソート、レコードを指しますが、順序はロジックです。InnoDBのデータページ連続分布と解放するには、論理的に連続したデータ・ページになりますので、物理的に連続していないです。これは、リンクポインタに必要です。前と後の二つのポインタ一緒に二重にリンクされたリストを構築します。

FIL_PAGE_LSN: 最新の現在のデータページがLSN修正されます。このフィールドは、InnoDBのredoログの電力およびその他の特性は、この分野に依存して、非常に重要です。回収段階のアプリケーションログでベンの崩壊LSNのredoログが少なく、この値に等しい以上見つかった場合、あなたは最高redoログを再度適用する必要はありません。

FIL_PAGE_TYPE: 現在のページは、データ・ページのどのタイプです。インデックスページ、[元に戻す]ページ、iノード・ページ、ページ、BLOBページのようなダース、を含みます。

FIL_PAGE_FILE_FLUSH_LSN: データ作るの最初のページには、ibdata文書を感知し、ブラシLSNディスクにibdata成功を記録します。

FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID: 現在のバージョンはspaceidを維持するために使用されます。

データヘッダ(ページヘッダ)

ビューの情報記憶ポイントから、データ・ページのこの部分は、関連付けられたメタ情報が格納されます。page0page.h中で定義されています。

PAGE_N_DIR_SLOTS: これは、データディレクトリ内のデータ・ページの数を表します。新しい空のデータページ、二つのディレクトリ、最大値と最小値を記録レコードへのポイントがあります。非空のデータ・ページでは、ディレクトリは、常にポイント最初のレコードの最小値と、最大値は常に最後のディレクトリレコードを指します。この値がインクリメントされたときにカタログが増大した場合。

PAGE_HEAP_TOP: 空き領域のデータ・ページの開始アドレスにこれがポイント。空間データディレクトリは、アドレスが割り当てられていないよりも、それはその後の使用とすることができるより大きく、小さいです。しかし、無料のレコードリスト(以降PAGE_FREE現在)アドレスを再利用することができるよりも小さくなっています。

PAGE_N_HEAP: 現在、レコードの数が通常のレコードを含め、スペースで使用されており、(に置か削除されていPAGE_FREEたレコード)です。すべての空き領域レコードが増加したときにコードのロジックから参照してください、この値は、軽減されていません。新しい空のページを作成し、デフォルトは、最大値と最小値の記録であること、2に設定されています。さらに、最上位ビットは、新しいフォーマットで記録保存されたデータページをマークするために使用されている場合(コンパクトおよび冗長)。

PAGE_FREE: 削除レコードのリストは、レコードが削除され、それはあなたがこのページにレコードを挿入したい場合、あなたはスペースのみフリーアドレス(から、十分でない場合は、ここから始めスペースを割り当てることができ、このリストの先頭に置きますPAGE_HEAP_TOP配布)。注内部に、このリストには、パージスレッドが完全に削除レコードがあることを、削除マークされたレコードが、ここではありません。

PAGE_GARBAGE: すべてのサイズは、レコードがスペースを取る削除されています。主に空き領域の計算を容易にするためです。

PAGE_LAST_INSERT: 最新の挿入されたレコードを指します。主に、後続の挿入作業を加速するために使用。

PAGE_DIRECTION: 左から右に最後のレコードは、一方向に、次いでインサートから両方向における電流、およびインサートを挿入しました。その後の挿入作業を加速するために使用されます。

PAGE_N_DIRECTION: レコードの同じ数を挿入する方法。主に、後続の挿入作業を加速するために使用。

PAGE_N_RECS: 記録された最大と最小を含まない、現在のページのレコードのユーザーデータ、。そして、PAGE_N_HEAPレコードが削除マーク付きのためにマークされている場合、この値は異なるデクリメントされます。

PAGE_MAX_TRX_ID: このデータ・ページの現在の最大トランザクションIDを変更します。

PAGE_LEVEL: ページかどうかリーフノードBツリーです。それが0であれば、それは、リーフノードです。

PAGE_INDEX_ID: インデックスのインデックス・ページID。

PAGE_BTR_SEG_LEAF,PAGE_BTR_SEG_TOP: セクションの先頭ページのアドレスリーフノードと非リーフノードです。

最大値と最小値の記録(InfimumとSupremumレコード)

このレコードの最大値が記録された最大論理データ・ページで、すべてのユーザーのレコードは、それ未満です。最小記録記録データページの最小値は、すべてのユーザーのレコードが、それよりも大きいです。データ・ページが作成され、削除することはできませんとき、彼らが作成されました。彼らは、ページ内の操作を容易にするために、主に導入しました。

ユーザ記録(ユーザー・レコード)

レコードの挿入、ユーザーはすべてのレコード間の隙間なくデフォルトで記録し、ここに格納されていますが、スペースの削除されたレコードを再利用する場合はスペースデブリにつながります。各レコードは、レコードへのポインタを次のレコードへのポインタポイントがありますが、ありません。記録が主キーの順序を並べ替えます。つまり、ユーザーはすべての通常のレコードを含む最小、レコードの最大までを、記録されたデータ・ページから横断を開始し、すべての削除・マークを記録したが、(削除されたレコードにアクセスすることはできませんすることができますPAGE_FREE)。

フリースペース(フリースペース)

PAGE_HEAP_TOPスタート、フリースペースの間のスペースである最後のデータディレクトリは、ユーザーがレコードを挿入する必要がある場合、適切なスペースを見つけられない場合は、まず最初に、削除されたレコードにスペースを見つけるために、ゼロにリセットされ、ここで割り当て上から。レコードに割り当てられたスペースの後、あなたはインクリメントする必要があるPAGE_N_RECSPAGE_N_HEAP

データディレクトリ(ページディレクトリ)

ユーザーレコードは上位アドレスに下から延長したが、逆にデータディレクトリされます。データ・ページが初期化されると、データ・ページには、最大値と最小値の記録を指し、二つのデータディレクトリを作成するには(チェックサムの前に当然の)最後になります。新しいデータを挿入した後、そのようなディレクトリの数を増やす際に、必要に応じて、このディレクトリを維持する必要性。各ディレクトリには、対応するレコードのオフセットをページ内に記憶されたデータの2つのバイトを占有します。カタログN、記録およびカタログN、N、我々はこれらのレコードを呼び出す独自のカタログ間のNディレクトリ管理ディレクトリN-1(含まれていない)を前提としています。Nは、レコードを所有する記録フィールドの数で指されるディレクトリに記録します。このように、記録ディレクトリは、ディレクトリが良く、クエリの効率を改善していないが、また、職業増加にディレクトリの数を導くことができ、あまりにも所有することはできません、あまりにも希薄であることをあまりにも多くの単語ので、その手段、あまり所有することはできませんあまりにも多くのスペース。実施InnoDB内で、ディレクトリの数は、4,8、6つのレコードの平均を含む、4~8間自身の記録します。あなたがこの数を超えた場合、我々はディレクトリの数のバランスを再調整する必要があります。追加と削除ディレクトリは、メモリをコピーする必要があるかもしれませんが、全体的なスペースは、ディレクトリによって占められると小さいため、オーバーヘッドはごくわずかです。

データ・ページ・テール(フィルトレーラー)

この部分は、データページの最終位置にのみ8バイトです。FIL_PAGE_LSN 4バイト格納されたチェックサム値が低いアドレス、上位アドレスの下位4バイトの4バイトに格納されています。必ずしも同じではないチェックサムFIL_PAGE_SPACE_OR_CHKSUMの値は、異なる計算方法は、チェックサムを依存していることに留意されたいです。

カーネル

このセクションでは、データ・ページは、いくつかのコア機能に関連した内容の詳細な分析を提供します。

レコードの挿入

コア・エントリー機能page_cur_insert_rec_low次のようにコアの手順は次のとおりです。

  1. レコードの長さを取得します。関数のパラメータの受け渡しは、メタデータレコードを取得することができますので、ちょうどから、完全なレコードの良い組み合わせがありました。
  2. 最初からPAGE_FREEリストに十分なスペースを取得しよう。記録空間が記録スペースを挿入する必要よりも大きい場合にのみ、記録ヘッドの比較リストは、この空間は、他から、(heap_no含む)多重化PAGE_HEAP_TOPに割り当てられたスペース。これらの2つの場所が空でない場合に返されます。最初のhead要素フリーリストを決定するため、アルゴリズムは、操作を容易にするために推定された空間の非常に高い使用率、ではないので、ここでは、注意してください。データ・ページは、最初のいくつかの大きなレコードを削除することを前提としたが、最後に削除されたレコードのAは、フリーリストを使用するためのレコードよりも小さいだけレコードサイズの比較的小さい、その後の挿入です。例えば、その後、と仮定するは、4Kのサイズの記録、3K、5K、2Kを削除した未満2Kの記録時間を挿入する場合にのみ、その後、削除されたスペースは、新しいレコードが0.5Kに挿入されると仮定すると、最大使用されます2Kフリーリストのヘッド、および再利用することができますが、唯一の0.5Kの目の前で、1.5Kはまだ無駄になります残り、唯一5Kレコードによって占有されるスペースを使用することができ、次のインサートは、それが残りの1.5を入れていませんKも利用されます。これらの機能は、なぜ断片化にInnoDBはそうなりやすい説明するために、下から、多くの場合、スペースを整理する必要があります。
  3. フリーリストが十分でない場合は、上のPAGE_HEAP_TOP割り当て、割り当てが成功した場合、およびインクリメントPAGE_N_HEAP
  4. データページに十分なスペースがある場合は、指定された空間にレコードをコピーします。
  5. この新たに挿入されたレコードポインタnextポインタを修正しながら、新たに挿入されたレコードの前駆体の次のポインタを変更します。これらの2つのステップは、リスト上の記録の連続性を確保するために主にあります。
  6. インクリメントPAGE_N_RECSセットheap_no。0が設定値を所有していました。
  7. 更新PAGE_LAST_INSERT、、 PAGE_DIRECTIONPAGE_N_DIRECTIONこれらのパラメータを設定した後、あなたが継続的にあなたが検索をスピードアップすることができますこの情報を挿入する前に挿入位置を配置する必要があるため、ある程度のインサートパフォーマンスを向上させることができます。レコードのコード分析を見つけるために参照してください。
  8. データディレクトリを変更します。新しいレコードを増加するので、レコード数は、いくつかのディレクトリが最大(現在8)を超えて所有して、あなたはデータディレクトリページを再配置する必要があります(page_dir_split_slot)。アルゴリズムは、部屋を作るために、中間ノードは、新しいディレクトリを再構築し、新しいディレクトリを中間ノードを見つけることです、我々はすべてのディレクトリの翻訳を実行する必要があり、これはmomove操作を必要とする(比較的簡単であるpage_dir_split_slotpage_dir_add_slot)。
  9. redoログは、ログ、永続操作を記述します。
  10. そこBLOBフィールドの場合、プロセスのオフページの独立しました。

レコードの削除

削除操作ではなく、削除マークとして記録マークよりも、実際に削除物理レコードを参照していることに注意してください。コア機能入力機能page_cur_delete_rec次のステップ:

  1. レコードを削除する必要がある場合は、このデータのレコード最後のページで、このデータは、直接ページに空のページへの再初期化(page_create_empty)することができます。
  2. そうでない場合は、最後の一つであり、通常のパスを左に。最初のレコードのredoログログ。
  3. リセットPAGE_LAST_INSERTと増分はクロックブロックを変更します。後者は、楽観的なクエリが失敗にするために主にあります。
  4. ポインタを記録前任者と後継者の記録を削除し、修正する必要性、後継者への直接の前駆体を探します。このレコードは、リストにはそのようなレコードではありません。
  5. ディレクトリは、この削除されたレコードを指している場合は自分のこのカタログ内のレコードの数を削減しながら、そう、前駆体の削除レコードをこのディレクトリのポイントを聞かせて。
  6. このレコードは、オフページのブロブを持っていた場合は、削除します。
  7. 記録PAGE_FREEリストの先頭、その後インクリメントPAGE_GARBAGE低減、サイズをPAGE_N_RECSユーザ・レコードの値。
  8. 第五のステップは、独自の値をデクリメントするので、レコードの数が自身の(現在は4つ)の最小値未満である引き起こし得ます。(あなたには、いくつかのディレクトリを削除する必要があり、ディレクトリをリバランスする必要がありますpage_dir_balance_slot)。アルゴリズムは、まず、あなたが直接、フロントとリアのディレクトリへのポインタを調整することができます場合は、レコードディレクトリの周りから上に移動できるかどうかを判断する、比較的簡単です。この単純な調整はさておきカタログが自身の記録レコードの十分な数を設定するために必要な、十分な記録がない場合、あなたはディレクトリを削除する必要がありますされ、その後、カタログの裏には、前方の翻訳(ありますpage_dir_delete_slot)。

録音/測位位置を探します

InnoDBのでは、必要が条件レコードを検索するには、関数page_cur_search_with_matchを呼び出す必要がありますが、そのような特定のレコードよりも最初のレコードの大きいとして、特定の場所を見つけるために必要がある場合、また同じ機能を使用する必要があります。PAGE_CUR_G、PAGE_CUR_GE、PAGE_CUR_L、PAGE_CUR_LE四種類、それぞれ、より大きい、大きい等しい、未満未満、又は位置4種類に等しく、よりを標的場所。データ・ページ・ディレクトリが存在するため、位置決め2つのディレクトリの外周を位置決めする、第二分探索で、比較的容易に見つけることであり、線形サーチモード最終記録位置または位置を使用します。各挿入する前に、効率を向上させるために、挿入位置を決定するために、この関数を呼び出す必要があるため、また、InnoDBは主キー用に最適化され少しシーンの順序に従って挿入されました。それはマスターに係るキー配列に挿入されている場合ので、各時刻データは、この最後のページに挿入されることを保証するために、直接データページ(の最終位置に直接配置するのに必要なだけであるPAGE_LAST_INSERTことに)。挿入の順序に応じて現在のマスタキーかどうかを決定する方法については、依存PAGE_N_DIRECTIONPAGE_LAST_INSERTPAGE_DIRECTIONこれらの情報、現在のコードは、5つの基準を満たすために必要な。

  1. 現在のデータ・ページは、リーフノードであります
  2. 場所クエリモードPAGE_CUR_LE
  3. 同じ方向に挿入されている(3より大きいpage_header_get_field(page, PAGE_N_DIRECTION) > 3
  4. オフセット最後に挿入された記録が空です(page_header_get_ptr(page, PAGE_LAST_INSERT) != 0
  5. (右から挿入page_header_get_field(page, PAGE_DIRECTION) == PAGE_RIGHT

その他の機能

:挿入、削除、検索に加えて、のような重要な機能の数もあり、それらの両方のメタ情報を初期化するために、この関数を呼び出す必要があり、新しい空のページを作成しますが。、再結合へのデータページのニーズは、別のデータ・ページからデータをコピーする必要性は、この時間は、使用する必要がある場合。同様の機能がありますが、二つの異なる方法が機能をコピーし、傷が指定された記録にコピーされ、追加の記録は、最後のページに、指定されたデータからコピーを開始します。この機能は、主に損傷検査機能のデバッグモードでのデータページをチェックしている、任意の実際の作業を行いませんが、これらの機能は、読むために非常に時間の初心者です、構造を理解して迅速にデータ・ページを読み込むことができます。この関数は、Bツリー変化バッファがいっぱいになったときに、現在のロジックがマージ、ランダムに選択されたレコードであり、ランダム記録の位置に配置されています。 page_create page_move_rec_list_endpage_move_rec_list_start page_validate page_cur_open_on_rnd_user_rec

データ・ページ・破損

データページに依存するパラメータのチェックサム値を算出する方法innodb_checksum_algorithm現在、3つのチェックサム計算方法を提供しています、最初の1は、CRCチェック(あるbuf_calc_page_crc32比較的新しい計算方法は、CPUのハードウェア命令を加速するために使用することができるです)、。互換性のために、コードを必要としている古いバリアントと互換性を持つようにするためには、Aの算出方法は、独自に開発されたが、二つの変種の新旧、異なる計算結果の二つの変種があるInnoDBの第2のチェックは、InnoDBのです。第三モードはなし、この計算は、各データ・ページのチェックサムが、高速このように指定された値が移入チェックサムフィールドの利用を計算しないが、データの正確性を確保することができません。ではではinnodb_checksum_algorithm、InnoDBは、CRC32、なしの3つのオプションだけでなく、厳格なオプションに加えて、リードを取ります。リードチェック値のみチェックの方法で指定する必要がある場合、厳格なオプションは、示されている、されていない他の列、例えば、対応するデータ・ページをチェックインときに計算されたチェックサムを読み出し、strict_crc32を指定値も、CRC32を通じてCRC32使用可能でなければなりませんが、指定された場合は保存された結果が、InnoDBのまたはnoneである場合、また、チェックすることができます。このオプションは、MySQLの古いバージョンとの互換性のためであるオファーや、チェックアルゴリズムがデータを得られた修飾され妨げる理由は利用できません。ここでリマインダーは、厳格なモードに計算の比較的少量を使用して、効率は比較的高いです。

コードのチェックサム検証の詳細の書き込み、読み出しを分析し、引き継ぎました。データ・ページがディスクにフラッシュされようとしているとき、それは関数を呼び出しますbuf_flush_init_for_writingメタ情報を変更します。ここでは、newest_lenとチェックサムを含んでいます。まず、関数にFIL_PAGE_LSNしてUNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM、それぞれnewest_lsn、8つのバイトを書き込み、その後、チェックサム、塗りつぶしを計算FIL_PAGE_SPACE_OR_CHKSUMカバーしながら、UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM4つの最初のバイトを。それはInnoDBのであれば、アルゴリズムは、CRC32またはnoneである場合、2つのチェックサムの前と後に同じ内容が格納されていることを私たちを見つける、バックにはチェックサム値の古いバージョンを維持します。データ・ページがディスクから読み込まれると、IOスレッドのコールバックbuf_page_io_complete、それが読み取り操作である場合、この関数は、この関数が呼び出されますbuf_page_is_corrupted正確性チェックデータ・ページを。buf_page_is_corrupted第1のヘッドとテールは4つのバイトが(同じ下げるnewest_lsnチェックしますFIL_PAGE_LSN4 UNIV_PAGE_SIZE- FIL_PAGE_END_LSN_OLD_CHKSUM直接損傷し、同一ではない、データページ場合、4)。LSNは8バイトを完了します引き継いだ大電流の比場合は、現在のシステムとのLSNコントラストを読み出し、だけでなく、データ・ページが壊れていること。彼は、チェックサムが読み出されて終了し、プット・エンドを引き継いだ、我々は0で、更なるページが空であるかどうかを判定する見つけた場合、ページが空の場合、これは(おそらく空のページの外にファイルを拡張)、通常のデータ・ページと見なされます。次に、チェック値は、データ・ページを計算し、そしてエンドデータトップに格納された値を比較しています。厳密アルゴリズムの下で、完全に一致すべきであれば値の一致があるように、非厳密モードでデータの完全なページを考慮する。チェックサム値であれば、そのデータページ無傷でいます。データ・ページが損傷している場合は、関数が呼び出されますbuf_page_print、我々は多くの場合、エラー・ログ・データ・ページを参照してください理由でエラーログ出力データページへの情報。この機能は、すべてのデータ・ページ・コンテンツ、space_id、page_no、頭と尾LSN、最終チェックサムとチェックサムの計算アルゴリズムの終わりにはほかに、に基づいて行われます、印刷されていますFIL_PAGE_TYPE簡単にトラブルシューティングするために、データ・ページの可能なタイプの憶測。

概要

全体的に、構造的な妥協のInnoDBデータ・ページ・インサートの設計、削除、および検索効率は、データ構造が学習の価値があるです。また、その構造や原理の理解、データ・ページが損傷している、と冷静に、データの名残を見つけるために全力を行うことができたときに、これは良いDBA不可欠な資質です。

おすすめ

転載: www.cnblogs.com/zhangfengshi/p/12511263.html