クエリを実行してからディスクに送られるまでのデータの流れを明確にしたいと思います。 (私はそれがバッファに行き、次にログをやり直し、次にディスクファイルに行くだろうという大まかな考えを持っています)しかし、それからbin_log_cacheがどのように使われるのか。
私はこれをググってみましたが、このトピックについてはあまり見つかりませんでした。このコミュニティの人々の間で、ここでいくつかの説明があることを願っています。
Googleの "peter zaitsev"ファイルシステムバッファリング二重書き込み はいくつかの優れたリファレンスを提供します(Peter ZaitsevはbigのPerconaで動作します) MySQLの世界の打者。
これらのうち、私は4を特に興味深いものとして選択しました[ 1 、 2 、、 4 ]。
最初の参考資料で、ザイツェフは、部分的なページ書き込みが発生する可能性のあるさまざまな理由を説明しています(「部分的なページ書き込みについて少し話しましょう」というタイトルのセクション)。
次にZaitsevは、二重書き込みのしくみに関するセクションに進みますが、参考文献2に、特にこのビットについて、より適切な説明があると思います。
データファイルでページの部分的な書き込みが発生した場合、InnoDB/XtraDBは、データファイル内のページのチェックサムがダブルライトバッファー内のページのチェックサムと異なる場合にリカバリをチェックし、ページが破損しているか、またはない。破損している場合、回復プロセスでは、二重書き込みバッファに格納されているページを使用して正しいデータを復元します。
二重書き込みバッファーで部分的な書き込みが発生した場合、元のページは変更されず、REDOログで使用してデータを回復できます。
基本的に、この動作は innodb_flush_log_at_trx_commit と呼ばれるシステムパラメータによって制御されます。このセクションは大きすぎるため、ここでは全体を引用することはできません。デフォルト値について少しだけ引用します(概要を理解するために、全体を読むことを強くお勧めします)。
A ACIDに完全に準拠するには、デフォルト値の1が必要です。この値を使用すると、InnoDBログバッファーの内容がトランザクションのコミットごとにログファイルに書き出され、ログファイルがディスクにフラッシュされます。
ただし、マニュアルのこのセクションには次のようにも書かれています。
コミット操作の厳密なACIDコンプライアンスと、コミット関連のI/O操作が再配置されてバッチで実行される場合に可能なより高いパフォーマンスとの間のバランスを制御します。デフォルト値を変更することでパフォーマンスを向上させることができますが、クラッシュで最大1秒のトランザクションが失われる可能性があります。
平易な英語では、これは「あなたがあなたがあなたが支払うものを手に入れる」ことを意味します-つまり、データの完全性とパフォーマンスとの間でバランスを取る必要があるのです。ただし、高低を検索しているにもかかわらず、詳細に関してはこれ以上見つけることはできませんでした。コードをあちこち探したくなければ(私の給与水準より上だと私は恐れています:-))。
パラメーター innodb_doublewrite をオフに切り替えると、これにより1つが別のシステムパラメーター innodb_flush_method につながります。ここでも、パフォーマンスとデータの整合性がすべてです。私の参考文献3と4はこれについて詳しく説明しています。基本的に、これらの2つの参考文献での議論は、トランザクションファイルシステムがある場合に、二重書き込みをオフにするのが適切かどうかについてです。
コンセンサスは、ZFS(およびおそらく他の難解なファイルシステム/デバイス)を使用している場合、バッテリーで動作するディスクキャッシュを備えたRAIDを想定して、二重書き込みを安全にオフにすることであると思われます。参考文献4 IMHOは、ext4が安全であるかどうかについての議論がまだ開かれていることを示唆しています。 here も参照してください。
以下の図は、 MySQLのInnoDBアーキテクチャ の概要を示しています。
厳密にバイナリログを見ると、フォローできるフローがあります
MySQLドキュメントが binlog_cache_size について述べていることに注意してください:
トランザクション中にバイナリログへの変更を保持するキャッシュのサイズ。サーバーがトランザクションストレージエンジンをサポートし、サーバーでバイナリログが有効になっている場合(--log-binオプション)、各クライアントにバイナリログキャッシュが割り当てられます。大きなトランザクションを頻繁に使用する場合は、このキャッシュサイズを増やしてパフォーマンスを向上させることができます。 Binlog_cache_useおよびBinlog_cache_disk_useステータス変数は、この変数のサイズを調整するのに役立ちます。セクション5.4.4「バイナリログ」を参照してください。
この設定はトランザクションの使用に影響するため、トランザクションのライフサイクルでバイナリログが書き込まれることがあります。あなたの質問は本当に「バイナリログはいつInnoDBの配管で機能するのですか?」
VeraceはすでにInnoDBの図解表現を示しています であるため、バイナリログについての言及がないことがわかります。 MySQLドキュメントでは、バイナリログがトランザクション内でいつ相互作用するかについて実際に言及しています。
The Binary Log
MySQLドキュメントから :
バイナリロギングは、ステートメントまたはトランザクションが完了した直後、ただしロックが解放されるかコミットが行われる前に行われます。これにより、ログがコミット順に記録されます。
別の段落は次のように述べています:
コミットされていないトランザクション内では、サーバーがCOMMITステートメントを受信するまで、InnoDBテーブルなどのトランザクションテーブルを変更するすべての更新(UPDATE、DELETE、またはINSERT)がキャッシュされます。その時点で、COMMITが実行される前に、mysqldはトランザクション全体をバイナリログに書き込みます。
別の段落では、binlogのバッファキャッシングについて次のように述べています。
トランザクションを処理するスレッドが開始すると、binlog_cache_sizeのバッファーをバッファーステートメントに割り当てます。ステートメントがこれより大きい場合、スレッドは一時ファイルを開いてトランザクションを保存します。一時ファイルは、スレッドが終了すると削除されます。
あなたは言った:もしそうなら、このプロセスで停電が起こった場合、データは失われないでしょうか?
私は言う:これはあなたのtxが完全に赤いログファイルに書かれているかどうかに依存します。
ここで、トランザクションがREDOログファイルに完全に書き込まれた場合、ディスクにフラッシュされるため(つまり、ディスクによって、iblogfileが保存されます)、データファイルに到達します。電源障害が発生しても、データの損失はありません。データはREDOログにコミットされます)
サーバーがクラッシュし、txnがREDOログに完全に書き込まれていない場合、mysqlの再起動時にロールバックされます。エラーログファイルの「クラッシュとmysqlサーバーの再起動」で同じことを確認できます。ここで、MySQLはクラッシュリカバリモードになり、REDOログ、データファイル、バイナリログを互いに同期させようとします。
したがって、データがバッファプールに入ってログバッファに送られ、「タイムアウト時のinnodbフラッシュログとタイムアウト時のinnodbフラッシュログ」の値に従って、データがやり直しログ(iblog01ファイル)に到達することを述べたように、ディスクにフラッシュし、データファイルに到達します。
したがって、これはトランザクションフローです。私はブログで同じことを説明的に述べました。私のブログを参照してください。