されたかどうか?』をどうやって区別してると思う?」Aさん「どうやって?!」たろー「うん。それは分からない・・・。されたかどうか?』を区別しているんだ。」Aさん「ITL??」たろー「うん。データブロック単位に存在するんだけど、ここでは分かりやすくするため、レコード単位で表すことにするね。」Aさん「おお、なるほど。フラグみたいなもんか。」たろー「そう思ってもらって差し支えない。されたかどうか?』を区別しているんだ。データファイルに書き出すんだ。」たろー「以上が基本動作だ。ここまでで何か質問はあるかい?」Aさん「いや、大丈夫だ。遅延ブロッククリーンアウトとは?たろー「ここからが本番だ。ついてきてよ?」Aさん「ああ、任せとけ。」たろー「さっき説明したのは一番簡単なケースだけど、実際には色んな処理が並列で動作しているから、バッファキャッシュの負荷が高くなるケースがあるんだ。状態のままでデータファイルに書き出すんだ。」Aさん「ほう・・・・・・。ある『Dさん』が返却される。ここでもきちんと読み取り一貫性を保証しているんだ。」たろー「さて、ここで。バッファキャッシュ上にはもうさっきのデータは存在しないよね?。済に更新して、」Aさん「こんな風にデータファイルに書き出すんじゃないかな?」たろー「普通に考えるとそうだよね。高速化のために敢えてその動作をしないんだ。トランザクション表(トランザクションスロット)に記録しておくんだよ。」Aさん「ちょっと待て。はいつ更新されるんだ??」たろー「さすがAさん、いい質問だ。更新されるのは、次回アクセスがあった時だ。」Aさん「次回アクセスがあった時?」たろー「そう。動きを説明すると、まず、バッファキャッシュにデータファイルから該当のデータブロックを読み込む。状態を示していることに気付くんだ。トランザクションスロットにアクセスする。済に変更して、データファイルの更新を行うんだ。更新がかかることになるのか??」たろー「そういうことだ。これが『遅延ブロッククリーンアウト』のメカニズムだ。SELECTたろー「という処理を行っていて、かつ、他にも処理が流れていてバッファキャッシュに負担がかかっているよね?」Aさん「ああ、そうだな。状態になったデータブロックがデータファイルに大量に書き出されているんだ。トランザクションスロットに大量にアクセスしなければならない。アクセスはマルチブロックではなく、シングルブロックで行われる仕様なんだ。read』が大量に発生している原因はそこにあったんだよ。」Aさん「な、なるほど・・・。シングルブロックリードだ。」た、たしかに・・・。して遅延が起きないんだ?」たろー「だってAさん、考えてもみてよ。つきまとうよね?」Aさん「ああ、そうだな。なんて発生しないじゃん。比べて注意しなければいけないことがあるんだ。権限等を他のスキーマに付与していた場合は権限を付与し直さなければならないし、インデックスも作り直さなければならない。なってしまう恐れもある。そこはちゃんと見極めて使う必要があるよ。」Aさん「うむ、そうだな。置き換えられたからよかったけど、それが出来ない場合は、素直にバッファキャッシュを増やすしか回避手段がないよ。状態のままキャッシュアウトされるのを極力避けて『遅延ブロッククリーンアウト』が発生しないようにするしかないんだ。」Aさん「な、なるほど・・・。今回はすごく勉強になったよ。ありがとう、たろーちゃん!!」クリーンアウト処理が行われるタイミングたろーちゃんの説明の繰り返しとなりますが、クリーンアウト処理が行われるのは、対象データブロックに次回アクセスがあった時です。データベースを正常停止したとしても、対象のデータブロックにはアクセスしていないため、クリーンアウト処理は行われません。「対象データブロックに次回アクセスがあった時」のみに、クリーンアウト処理が行われます。データファイルが無くてもデータベースを復旧できるケースをご紹介しましたが、仮に未クリーンアウトブロックが存在した場合、データベースは正しく動作しないので、注意して下さい。今回の「心臓外科医の術式」いかがだったでしょうか?遅延ブロッククリーンアウトは発見しづらい症状の一つです。環境でも同様の事象は起こり得ます。遅く感じられる場合は、今回ご紹介した遅延ブロッククリーンアウトを視野に入れてみてください。それでは、次回も頑張りますので、応援よろしくお願い致します。インフラソリューション事業部に在籍するPlatinumホルダー。Databaseのパフォーマンスチューニングを得意とする。以外興味がないという変わり者。infra-db@sts-inc.co.jp「DBひとりでできるもん」運営チームです。社員等の情報をお届けします。60名弱の事業部員で鋭意、執筆中です。