トランザクションには、原子性、一貫性、分離性、耐久性という 4 つの特性があります。では、取引の4つの特徴はどのような仕組みに基づいているのでしょうか?
- トランザクションの分離は
锁机制
によって実現されます。 - トランザクションのアトミック性、一貫性、耐久性は、トランザクションの REDO ログと UNDO ログによって保証されます。
- REDO LOG は と呼ばれ
重做日志
、再書き込み操作を提供し、送信されたトランザクションによって変更されたページ操作を復元し、トランザクションの耐久性を確保するために使用されます。 回滚日志
UNDO LOG は、トランザクションのアトミック性と一貫性を確保するために、行レコードを特定のバージョンにロールバックすることと呼ばれます。
- REDO LOG は と呼ばれ
DBA の中には、UNDO が REDO の逆のプロセスであると考える人もいますが、そうではありません。
1.やり直しログ
1.1 REDO ログが必要な理由
一方で、バッファ プールは CPU とディスク間のギャップをなくすのに役立ち、チェックポイント メカニズムはデータの最終配置を保証しますが、チェックポイントのため、マスター スレッドは一定の間隔でデータを処理します并不是每次变更的时候就触发
。したがって、最悪のシナリオは、トランザクションがコミットされた後、バッファー プールに書き込まれたばかりでデータベースがダウンし、このデータが失われ、回復できなくなることです。
一方、トランザクションには、コミットされたトランザクションの場合、トランザクションの送信後にシステムがクラッシュしても、そのトランザクションによってデータベースに加えられた変更が失われることがないという持久性
特性があります。
では、この耐久性を確保するにはどうすればよいでしょうか? 一个简单的做法
: トランザクションがコミットされる前に、トランザクションによって変更されたすべてのページをディスクにフラッシュしますが、この単純かつ粗雑なアプローチにはいくつかの問題があります。
另一个解决的思路
: 送信されたトランザクションによってデータベース内のデータに加えられた変更を永続的に有効にしたいだけです。後でシステムがクラッシュしたとしても、この変更は再起動後に復元できます。したがって、実際には、トランザクションがコミットされるたびに、トランザクションによってメモリ内で変更されたすべてのページをディスクに更新する必要はなく、変更される内容のみを変更する必要があり修改
ます记录一下
。たとえば、トランザクションは、第10号
システム表スペースのオフセットにある100
バイトの値を1
に変更します2
。記録する必要があるのは、表スペース 0 のページ 10 のオフセット 100 の値を 2 に更新することだけです。
1.2 REDO ログの利点と特徴
1. メリット
- REDO ログにより、ディスクフラッシュの頻度が減少します。
- REDO ログが占有するスペースはほとんどありません
2. 特徴
- REDO ログはディスクに順番に書き込まれます
- トランザクション実行中、REDO ログが継続的に記録されます
1.3 REDOの構成
REDO ログは単純に次の 2 つの部分に分けることができます。
重做日志的缓冲 (redo log buffer)
はメモリに保存されており、揮発性です。
パラメータ設定: innodb_log_buffer_size:
REDO ログ バッファ サイズ、デフォルト16M
、最大値は 4096M、最小値は 1M です。
mysql> show variables like '%innodb_log_buffer_size%';
+------------------------+----------+
| Variable_name | Value |
+------------------------+----------+
| innodb_log_buffer_size | 16777216 |
+------------------------+----------+
- ハードディスクに保存される REDO ログ ファイル (REDO ログ ファイル) は永続的です。
1.4 やり直しの全体的なプロセス
更新トランザクションを例にとると、REDO ログ フロー プロセスは次の図に示すようになります。
ステップ1: まず、元のデータをディスクからメモリに読み取り、データのメモリ コピーを変更します
ステップ 2: REDO ログを生成し、それを REDO ログ バッファに書き込み、データの変更された値を記録します。
3 : トランザクションがコミットされると、REDO ログ バッファの内容を REDO ログ ファイルにリフレッシュし、REDO ログ ファイルへの追加書き込みを使用します
ステップ 4: メモリ内の変更されたデータを定期的にディスクにリフレッシュします。
経験: 先行書き込みログ (ログ前の永続化): データ ページを永続化する前に、まず対応するログ ページをメモリ内に永続化します。
1.5 REDO ログのフラッシュ戦略
REDO ログの書き込みはディスクに直接書き込まれず、InnoDB エンジンは REDO ログを書き込むときに最初に REDO ログ バッファに書き込み、次にそれを一定的频率
実際の REDO ログ ファイルにフラッシュします。ここでの一定の周波数についてはどう考えますか?これが私たちが話しているブラシ戦略です。
REDO ログ バッファを REDO ログ ファイルにフラッシュするプロセスは、実際にはディスクにフラッシュするのではなく、(ページ キャッシュ)にフラッシュするだけであることに注意してください文件系统缓存
(これは、ファイルの書き込み効率を向上させるために最新のオペレーティング システムによって行われる最適化です)。実際の書き込みはシステム自体に任せられます (たとえば、ページ キャッシュが十分な大きさであるなど)。次に、InnoDB の問題ですが、同期をシステムに任せていると、システムがダウンした場合、データも失われます (システム全体がダウンする確率はまだ比較的小さいですが)。
この状況に対応して、InnoDB は、innodb_flush_log_at_trx_commit
commit がトランザクションをコミットするときに、REDO ログ バッファ内のログを REDO ログ ファイルにフラッシュする方法を制御するパラメータを提供します。次の 3 つの戦略がサポートされています。
设置为0
: トランザクションが送信されるたびにフラッシュ操作が実行されないことを示します。(システムのデフォルトでは、マスタースレッドが 1 秒ごとに REDO ログを同期します)设置为1
: トランザクションが送信されるたびに同期とディスクのフラッシュ操作が実行されることを示します (默认值
)设置为2
: トランザクションが送信されるたびに、同期せずに REDO ログ バッファの内容のみがページ キャッシュに書き込まれることを示します。いつディスク ファイルと同期するかは OS によって決定されます。
1.6 さまざまなブラッシング戦略のデモンストレーション
1. フローチャート
1.7 REDO ログ ファイル
1. 関連パラメータの設定
-
innodb_log_group_home_dir
: REDO ログ ファイル グループが存在するパスを指定します。デフォルト値は で./
、データベースのデータ ディレクトリ内にあることを意味します。MySQL のデフォルト データ ディレクトリ ( ) には、とvar/lib/mysql
という名前の 2 つのファイルがあり、ログ バッファ内のログはデフォルトでこれら 2 つのディスク ファイルにフラッシュされます。この REDO ログ ファイルの場所は変更することもできます。ib_logfile0
ib_logfile1
-
innodb_log_files_in_group
: REDO ログ ファイルの数を指定します。命名方法は ib_logfile0、iblogfile1...iblogfilen です。デフォルトは 2、最大値は 100 です。mysql> show variables like 'innodb_log_files_in_group'; +---------------------------+-------+ | Variable_name | Value | +---------------------------+-------+ | innodb_log_files_in_group | 2 | +---------------------------+-------+ #ib_logfile0 #ib_logfile1
-
innodb_flush_log_at_trx_commit
: REDO ログをディスクにフラッシュする戦略を制御します。デフォルトは 1 です。 -
innodb_log_file_size
: 単一 REDO ログ ファイルのサイズを設定します。デフォルト値は です48M
。最大値は 512G です。最大値は REDO ログ シリーズ ファイル全体の合計を指すことに注意してください。つまり、(innodb_log_files_in_group * innodb_log_file_size) は最大値 512G を超えることはできません。mysql> show variables like 'innodb_log_file_size'; +----------------------+----------+ | Variable_name | Value | +----------------------+----------+ | innodb_log_file_size | 50331648 | +----------------------+----------+
大規模なトランザクションに対応できるように、ビジネスに基づいてサイズを変更します。以下に示すように、my.cnf ファイルを編集し、データベースを再起動して有効にします。
[root@localhost ~]# vim /etc/my.cnf
innodb_log_file_size=200M
2. ログファイルグループ
実際の REDO ログ ファイルの合計サイズは次のとおりですinnodb_log_file_size × innodb_log_files_in_group
。
REDO ログ ファイル グループに循環的にデータを書き込むと、後で書き込まれた REDO ログが先に書き込まれた REDO ログを上書きしますか? 確かに!そこで、InnoDB の設計者はチェックポイントの概念を提案しました。
3. チェックポイント
書き込みポスがチェックポイントに追いついた場合、チェック日志文件组
ポイントがいっぱいであることを意味します。現時点では、新しい REDO ログ レコードを書き込むことはできません。MySQL は停止し、いくつかのレコードをクリアして、チェックポイントを進める必要があります。
2. アンドゥログ
REDO ログはトランザクションの耐久性を保証し、UNDO ログはトランザクションのアトミック性を保証します。トランザクション内のデータを更新するための事前操作は、実際には
最初に元に戻すログを書き込むことです。
2.1 Undoログの見方
トランザクションはアトミックである必要があります。つまり、トランザクション内のすべての操作が完了するか、何も行われない必要があります。ただし、トランザクションの実行途中で次のような状況が発生する場合があります。
- 状況 1: トランザクションの実行中に、 や突然のエラーなど、さまざまなエラーが発生する可能性が
服务器本身的错误
あり操作系统错误
ます断电
。 - シナリオ 2: プログラマは、トランザクションの実行中にステートメントを手動で入力して
ROLLBACK
、現在のトランザクションの実行を終了できます。
上記の状況が発生した場合、データを元の外観に戻す必要があります。このプロセスは "トランザクション" と呼ばれます。これにより、このトランザクションは何も行われていないように見えるため、要件を回滚
満たしているかのような錯覚が生じる可能性があります。原子性
2.2 アンドゥログの役割
- 機能 1: データのロールバック
- 機能 2: MVCC
2.3 アンドゥの格納構造
1. セグメントのロールバックとページの取り消し
InnoDB はセグメントを使用して UNDO ログ、つまり を管理します回滚段(rollback segment)
。1024
各ロールバックセグメントは記録されundo log segment
、各アンドゥ ログ セグメント内にアプリケーションが作成されますundo页
。
-
(バージョン 1.1 を除く)では
InnoDB1.1版本之前
、ロールバック セグメントが 1 つしかないため、サポートされる同時オンライン トランザクションの数は に制限されます1024
。ただし、ほとんどのアプリケーションにはこれで十分です。 -
バージョン 1.1 以降、InnoDB は最大数をサポートするようになった
128个rollback segment
ため、サポートされる同時オンライン トランザクションの制限が増加しました128*1024
。mysql> show variables like 'innodb_undo_logs'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | innodb_undo_logs | 128 | +------------------+-------+
2. セグメントとトランザクションのロールバック
- 各トランザクションは 1 つのロールバック セグメントのみを使用し、1 つのロールバック セグメントは同時に複数のトランザクションを処理できます。
- トランザクションが開始されると、ロールバック セグメントが作成され、トランザクション中にデータが変更されると、元のデータがロールバック セグメントにコピーされます。
- ロールバック セグメントでは、トランザクションが終了するかすべての領域が使い果たされるまで、トランザクションはエクステントを埋め続けます。現在のエクステントが十分でない場合、トランザクションはセグメント内の次のエクステントの拡張を要求します。割り当てられたエクステントがすべて使用されている場合、トランザクションは元のエクステントを上書きするか、ロールバック セグメントが許可する場合は新しいエクステントを拡張します。使用するパネル。
- ロールバック・セグメントはUNDO表スペースに存在します。データベース内に複数のUNDO表スペースが存在できますが、同時に使用できるUNDO表スペースは1つだけです。
- トランザクションがコミットされると、InnoDB ストレージ エンジンは次の 2 つのことを実行します。
- 後続のパージ操作のためにリストに元に戻すログを追加します。
- アンドゥログが存在するページが再利用可能かどうか、また次のトランザクションに割り当てられるかどうかを判断します。
3. ロールバックセグメントのデータ分類
未提交的回滚数据(uncommitted undo information)
已经提交但未过期的回滚数据(committed undo information)
事务已经提交并过期的数据(expired undo information)
2.4 アンドゥの種類
InnoDB ストレージ エンジンでは、UNDO ログは次のように分割されます。
- アンドゥログを挿入
- アンドゥログを更新する
2.5 アンドゥログのライフサイクル
1. 簡単な生成プロセス
バッファプールのみが処理します:
Redo ログと Undo ログがある後:
2. 詳細な生成プロセス
INSERT を実行すると、次のようになります。
begin;
INSERT INTO user (name) VALUES ("tom");
UPDATE を実行すると、次のようになります。
UPDATE user SET id=2 WHERE id=1;
3. アンドゥログをロールバックする方法
上記の例で、ロールバックが実行されると仮定すると、対応するプロセスは次のようになります。
- 元に戻す no=3 のログを通じて id=2 のデータを削除します
- undo no=2のログからid=1のデータのdeletemarkを0に戻す
- undo no=1のログからid=1のデータ名をTomに復元します。
- 元に戻す no=0 のログを通じて id=1 のデータを削除します
4. アンドゥログの削除
-
挿入取り消しログの場合
挿入操作のレコードはトランザクション自体にのみ表示され、他のトランザクションには表示されないためです。したがって、UNDO ログはトランザクションの送信後に直接削除でき、パージ操作は必要ありません。
-
更新取り消しログの場合、
取り消しログは MVCC メカニズムを提供する必要がある場合があるため、トランザクションがコミットされたときに削除できません。送信するときは、それを元に戻すログ リストに入れて、パージ スレッドが最終的な削除を実行するまで待ちます。
2.6 概要
Undo ログは論理ログであり、トランザクションをロールバックする場合、データベースを論理的に元の状態に復元するだけです。
REDO ログは、データ ページの物理的な変更を記録する物理ログです。Undo ログは、REDO ログの逆のプロセスではありません。