1.1二重書き込みとは
MySQLのデフォルトのデータページは16K、ファイルシステムのデータページは4K、IO操作はページ単位で読み書きされます。データベースが16Kデータページを変更した後、オペレーティングシステムがディスクへの書き込みを開始する可能性がありますが、このプロセス中にデータベースがダウンし、16Kデータページがディスクに完全に書き込まれません。データベースを再起動した後、データページを確認し、不完全なデータページがあるため、起動できません。
この問題を解決するために、MySQLは二重書き込み機能を導入しました。二重書き込みはダーティデータ用であり、InnoDBの信頼性を向上させ、部分的なページ書き込みの失敗を解決するために使用されます。データを永続化するには、ダーティデータをディスクにフラッシュする必要があり、ダーティデータをフラッシュするプロセスで二重書き込みが発生します。フラッシュは、共有テーブルスペースibdataに書き込まれたダーティデータのコピーであり、永続ストレージ用に実データファイルに書き込まれたコピーです。2回書き込まれたダーティデータは、ダブルライトと呼ばれます。
1.2二重書き込み原理
簡単に言うと、ダブルライトとは、変更したダーティページを最初にダブルライトバッファ領域に配置することです。この領域は2Mのメモリスペースを占有します。バッファスペースがいっぱいであるか、他の条件によってトリガーされるため、ダブルライトバッファに格納されているダーティページが最初に共有テーブルスペースに書き込まれます。 (MySQL 8.0.20より前は、ダブルライトバッファストレージ領域はInnoDB
システムテーブルスペースにあります。MySQL8.0.20以降、ダブルライトバッファストレージ領域はダブルライトファイルにあります)、次にデータファイルを書き込みます。このとき、不完全なページが書き込まれると、共有テーブルスペースの完全なページで上書きされる可能性があります。データページが完了すると、データベースがプルアップされます。以降のすべてのリカバリは、REDOログに依存します。REDOログは、ログをデータブロックの形式で記録し、オフセットに従って変更を記録します。データは2回書き込まれますが、二重書き込みバッファーは2倍のI / Oオーバーヘッドまたは2倍のI / O操作を必要としません。fsync()
オペレーティングシステムを呼び出す必要があるのは1回だけです。データはバッファのdoublewriteに書き込むことができます(シーケンシャルブロックが大きいinnodb_flush_method
セットを除くO_DIRECT_NO_FSYNC
)。
8.0.20以降、デフォルトでは、バッファプールインスタンスごとに2つの二重書き込みファイルが作成されます。更新リストの二重書き込みファイルとLRUリストの二重書き込みファイルです。
-
更新リストの二重書き込みファイルは、リスト内で更新されたページをバッファープールから更新するために使用されます。リストを更新するためのdoublewriteファイルのデフォルトサイズは、InnoDBページサイズ* doublewriteページバイトです。
-
LRUリストの二重書き込みファイルは、バッファープールのLRUリストからページを更新するために使用されます。また、単一ページの更新用のスロットも含まれています。LRUリストのdoublewriteファイルのデフォルトサイズはInnoDBページサイズ*(doublewriteページ+(512 /バッファプールインスタンスの数))です。ここで、512は単一ページの更新用に予約されているスロットの総数です。
少なくとも2つの二重書き込みファイルがあります。二重書き込みファイルの最大数は、バッファープールインスタンスの数の2倍です。
redologによって書き込まれる単位は512バイトであり、これはディスクIOの最小単位であるため、データの破損はありません。
1.3二重書き込み回復プロセス
データ回復には3つのシナリオがあります
ダーティデータがディスクに正常に書き込まれました
フラッシュが成功した場合は、チェックポイントを見つけ、ロールフォワードおよびロールバックします。
共有テーブルスペースibdata書き込みエラー
共有テーブルスペースへの書き込みに失敗した場合、データはデータファイルに書き込まれず、データベースはこのフラッシュディスクが発生したことがないと見なします。MySQLはこの時点でディスクから元のデータをロードし、チェックポイントを見つけてログをやり直します。ロールフォワードしてロールバックするだけです。
ダーティデータでデータファイルをフラッシュできませんでした
共有テーブルスペースへの書き込みは成功しますが、データファイルへの書き込みは失敗します。リカバリ時に、MySQLはページのチェックサムを直接比較します。正しくない場合は、共有テーブルスペースの二重書き込みからページの最近のコピーを直接見つけて、にコピーします。テーブルスペースファイルを作成し、REDOログを適用すると、リカバリプロセスが完了します。コピーがあるので、テーブルスペースのデータページが破損する心配はありません。
1.4ダブルライトロード
二重書き込みはバッファですが、実際には物理ファイル(実際にはファイル)で開かれるバッファであるため、システムでより多くのfsync操作が発生し、ハードディスクのfsyncパフォーマンスが非常に遅いため、低下します。 mysqlの全体的なパフォーマンス。
2.二重書き込みワークロードを監視します
mysql> show global status like '%dblwr%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Innodb_dblwr_pages_written | 44 |
| Innodb_dblwr_writes | 8 |
+----------------------------+-------+
2 rows in set (0.00 sec)
懸念事項:Innodb_dblwr_pages_written / Innodb_dblwr_writesダブルライトを
有効にすると、ダーティページが更新されるたびにダブルライトを書き込む必要があります。ダブルライトはディスク上に2つの連続した領域として存在し、各領域は連続したページで構成されます。通常、1つの領域が最も多くなります。 64ページあるため、1回のIO書き込みで最大64ページを書き込むことができるはずです。
二重書き込みを閉じるのに適しています
-
マスDML
-
データの破損と損失を恐れない
-
システム書き込み負荷が主負荷になります
1.5関連パラメータ
mysql> show variables like '%double%';
+-------------------------------+-------+
| Variable_name | Value |
+-------------------------------+-------+
| innodb_doublewrite | ON |
| innodb_doublewrite_batch_size | 0 |
| innodb_doublewrite_dir | |
| innodb_doublewrite_files | 2 |
| innodb_doublewrite_pages | 8 |
+-------------------------------+-------+
5 rows in set (0.00 sec)
#innodb_doublewrite:是否开启doublewrite
#innodb_doublewrite_batch_size:定义要批量写入的双写页面数
#innodb_doublewrite_dir:定义双写缓冲区文件目录
#innodb_doublewrite_files:定义双写文件的数量
#innodb_doublewrite_pages:定义批量写入时每个线程的最大双写页数