トランザクションの原子性、一貫性、耐久性の実現原理

序文

トランザクションには4つの特性があることは誰でも知っています。

  • 原子性

    原子性とは、データベーストランザクション全体が不可分の作業単位であることを意味します。トランザクション内のすべてのデータベース操作が正常に実行された場合のみ、トランザクション全体が成功したと見なされます。トランザクション内のSQLステートメントの実行が失敗した場合、正常に実行されたSQLステートメントもキャンセルする必要があり、データベースの状態はトランザクションが実行される前の状態に戻る必要があります。

  • 一貫性

    一貫性とは、トランザクションがデータベースをある状態から次の一貫した状態に変換することを意味します。トランザクションの開始前とトランザクションの終了後、データベースの整合性制約は破棄されていません。

  • 隔離

    トランザクションがコミットされるまで、トランザクションの影響は他のトランザクションには見えません。これはロックによって実現されます。

  • 耐久性(耐久性)

    トランザクションがコミットされると、結果は永続的なものになります。ダウンタイムなどの障害が発生した場合でも、データベースはデータを回復できます。

分離の実現については、この記事を参照してください:InnoDBロックとトランザクションの簡単な分析

この記事では主に、他の3つの機能がどのように実現されるかについて説明しますデータベースのやり直しと元に戻すことですこの記事で特別な指示を行わない場合、デフォルトはmysqlのInnoDBストレージエンジンを指します。

成し遂げる

基本知識

  1. REDOログに記録された各ページ(ページ)の変更の物理ステータス
  2. 元に戻すログとやり直しログのレコードは、物理ログは同じではなく、論理ログです。レコードが削除されると、対応する挿入レコードが取り消しログに記録され、逆の場合も、レコードが更新されると、対応する更新レコードが記録されると考えることができます。
  3. LSNはログシーケンス番号(ログシーケンス番号)と呼ばれ、innodbストレージエンジンでは、lsnは8バイトを占有します。LSNの値は、ログが書き込まれるにつれて徐々に増加します。トランザクションの更新操作により、新しいLSNが生成されます。LSNはREDOログに存在するだけでなく、データページにも存在します。
  4. チェックポイントチェックポイント、つまりダーティページがディスクに書き込まれるとき

全体的なプロセス

ここに画像の説明を挿入
ログとデータの両方がバッファで変更され、ディスクに同期されます。

  1. トランザクションが開始された後、変更されたデータがログバッファーにない場合は、ディスクからログバッファーに読み取られます

  2. メモリ内のデータを変更する前に、元のデータを元に戻すログに記録します

  3. メモリ内のデータページを変更し、LSNをメモリデータページに記録し、とりあえずそれをdata_in_buffer_lsnと呼びます。

  4. データページの変更中に(ほぼ同時に)REDOログをバッファー内のREDOログに書き込み、当面はredo_log_in_buffer_lsnと呼ばれる対応するLSNを記録します。

  5. ログのフラッシュとデータのフラッシュ

    ログのフラッシュのルールは次のとおりです。

    • コミットアクションが発行されたとき

    • 1秒に1回ブラシをかける

    • ログバッファで使用されるメモリが半分を超えた場合

    • チェックポイントがあるとき

    データフラッシュのルールは次のとおりです。

    • チェックポイントがあるとき

    ログフラッシュの数は、データフラッシュの数よりも多くなります。さらに、チェックポイント中であっても、innoDBは**データを書き込む前にログを書き込む必要があることを保証します。このメソッドは、先読みロギング(先読みロギング、 WAL)。** InnoDBストレージエンジンは、ログを事前に書き込むことにより、トランザクションの整合性を保証します。

    ログ先行書き込み方式で整合性を保証できるのは、ログおよびデータページにLSNがあり、LSNを介してログおよびデータページ内のデータレコードの順序を比較できるためです。ログファイルは実際のコアです。

インスタンス

ソース:MySQLトランザクションログの詳細な分析(redoログとundoログ)

ここに画像の説明を挿入
上の図では、上から下への水平線が時間軸、バッファーのデータページに記録されたLSN(data_in_buffer_lsn)、ディスクのデータページに記録されたLSN(data_page_on_disk_lsn)、およびバッファーREDOログに記録されたLSNを表しています。 redo_log_in_buffer_lsn)、ディスク上のREDOログファイルに記録されたLSN(redo_log_on_disk_lsn)、およびチェックポイントによって記録されたLSN(checkpoint_lsn)。

開始時(12:0:00)にすべてのログページとデータページがフラッシュされ、チェックポイントのLSNも記録されていると仮定すると、これらのLSNは完全に一貫しています。

この時点でトランザクションが開始され、すぐに更新操作が実行され、実行が完了すると、データページとREDOログのバッファに、更新されたLSN値(110と想定)が記録されます。このとき、show engine innodb statusを実行して、各LSNの値、つまり図の①の位置ステータスを表示すると、結果は次のようになります。

log sequence number(110) > log flushed up to(100) = pages flushed up to = last checkpoint at

次に、削除ステートメントが実行され、LSNが150に増加しました。12:00:01まで待機し、REDOログフラッシュルールをトリガーします(その1つは、innodb_flush_log_at_timeoutによって制御されるデフォルトのログフラッシュ頻度が1秒であることです)。その後、ディスク上のREDOログファイルのLSNがに更新され、REDOログになります。バッファー内のLSNは同じであるため、すべて150に等しくなります。このとき、図の②の位置であるエンジンのinnodbステータスを表示すると、次のようになります。

log sequence number(150) = log flushed up to > pages flushed up to(100) = last checkpoint at

その後、更新文が実行され、キャッシュのLSNが図の③の位置である300に増加します。

前述のように、チェックポイントが図の④の位置に続いて表示されると仮定すると、チェックポイントはデータページとログページのフラッシュをトリガーしますが、完了するまでに一定の時間がかかるため、データページのフラッシュが完了する前にチェックしてください。ポイントのLSNは最後のチェックポイントのLSNのままですが、現時点では、ディスク上のデータページとログページのLSNが増加しています。

log sequence number > log flushed up to 和 pages flushed up to > last checkpoint at

ただし、ログのフラッシュはデータのフラッシュよりも速い場合や、データのフラッシュと同じか遅い場合があるため、フラッシュされたログとフラッシュされたページのサイズを特定することはできません。ただし、チェックポイントメカニズムは、データのフラッシュ速度がログのフラッシュより遅いことを保護します。データのフラッシュ速度がログのフラッシュを超えると、データのフラッシュは一時的に停止し、ログのフラッシュの進行がデータのフラッシュを超えるのを待ちます。

データページとログページがフラッシュされると、つまり位置⑤に到達すると、すべてのLSNは300になります。

時間が経つと、図の位置1である12:00:02に到達します。これにより、ログフラッシュルールがトリガーされますが、現時点では、バッファー内のログLSNはディスク内のログLSNと同じであるため、ログフラッシュは実行されません。このとき、ディスク、つまり、すべてのlsnsはshow engine innodbステータスで同じです。

次に、バッファー内のLSNが800(図の位置⑦)に増加したと想定して、insertステートメントが実行されます。現時点では、さまざまなLSNのサイズと位置は同じです。

送信アクションの後続の実行、つまりポジション⑧。デフォルトでは、送信アクションはログのフラッシュをトリガーしますが、データのフラッシュはトリガーしません。そのため、show engine innodb statusの結果は次のとおりです。

log sequence number = log flushed up to > pages flushed up to = last checkpoint at

最後に、時間の経過とともにチェックポイント、つまり図の位置appearedが再び現れました。ただし、チェックポイントが発生する前にログのLSNが同期されているため、このチェックポイントはログのフラッシュをトリガーしません。今回はデータのフラッシュ速度が非常に速いと仮定すると、それは一瞬のうちに完了し、ステータスの変更をキャプチャできなくなり、show engine innodb statusの結果は同じLSNになります。

戻す

mysqlのリカバリ戦略は次のとおりです。

  1. 回復するときは、最初に、コミットされていないトランザクションを含め、すべてのトランザクションをやり直しに従ってやり直します。
  2. 次に、取り消しに従って、コミットされていないトランザクションをロールバックします。

この戦略により、トランザクションの原子性、一貫性、持続性が保証されます。

また、チェックポイントメカニズムが導入されており、復元時にはチェックポイントの位置から復元するだけで済みます。

感想

  1. インターネット上のコンテンツの多くは不正確である可能性があります。私が書いたこの記事でも不正確である可能性があります。この問題を解決する最善の方法は、ソースコード読むことです。
  2. 異なる技術が異なる達成することができるが、基本原則は、多くの場合、連結されており、これらのコア原則は、一般的に上に構築された知識を基
  3. 知識を学ぶことでさまざまな深さを学ぶことができます。「MySQL Technical Insider:InnoDB Storage Engine」を読んだ後は、mysqlの使用法の一般的な理解を得ることができますが、理解は十分ではありません。これら2つの記事を書くことで、MySQLの理解はより深くなります深く掘り下げる必要がある場合は、実際にソースコードを確認する必要がある人もいます。したがって、理解する必要があるレベルを把握し、限られた時間でより費用対効果の高いことを行う必要があります。選択は非常に重要です。

データ

  1. MySQLトランザクションの詳細な調査:ACID機能の実現原理
  2. MySQLトランザクションログの詳細分析(ログのやり直しとログの取り消し)
  3. https://blog.csdn.net/suerge_storm/article/details/90484944
  4. https://blog.csdn.net/qq_41151659/article/details/99559397

やっと

私の記事が気に入ったら、私のパブリックアカウント(プログラマーMala Tang)をフォローできます。

以前の記事のレビュー:

  1. トランザクションの原子性、一貫性、耐久性の実現原理
  2. あなたの記憶を行使する方法
  3. CDNリクエストプロセスの詳細な説明
  4. プログラマーのキャリア開発についての考え
  5. ブログサービスが崩壊した歴史
  6. 一般的なキャッシングテクニック
  7. サードパーティ決済と効率的に接続する方法
  8. ジンフレームワークの簡潔なバージョン
  9. コードレビューについて考える
  10. InnoDBロックとトランザクションの簡単な分析
  11. Markdownエディターのレコメンデーション-タイポラ

おすすめ

転載: blog.csdn.net/shida219/article/details/106970517