direct path readについて思うこと [オプティマイザ]

Exadataを使い始めたのは2014年、X4-2からだ。当初はOracleに毛が生えたもの程度にしか思っていなかった。しかし、使い込んでいくうちに、DB層の下のストレージサーバ層に独自の機能が作りこまれていることがだんだんわかってきた。これを知ったのはExpert Oracle Exadata[1]という一冊の本に出会ってからである。

この本は英語でかなり厚く、お値段もそれなりにするので敷居が高いが、Exadataの内部動作をここまで紐解いてわかりやすく説明している点は他に類を見ない。もっと早くこの本に出会っていれば、よりExadataを有効活用し、トラブル対応も違った形でできたのではという忸怩たる思いがある。

さて、この本を読み進める中でわかったのは、Exadataを使う(使いこなす)上での一つのポイントが、direct path readである、ということである。ご存知の通りdirect path readとはバッファキャッシュをバイパスしてストレージ上のブロックをサーバプロセスのPGAに読み込むことで、フルスキャンなどのマルチブロックを高速に実現する方法である。もともとパラレルクエリのメカニズムであったが、11gからシリアルクエリでもdirect path readが使えるようになった。

なぜdirect path readがExadataにおいて重要なのか?スマートスキャンなど、ストレージからDBサーバのブロック転送量を減らす仕組み(具体的にはpredicate filteringやcolumn projection、storage indexなどを指す)が有効になるのは、すべてdirect path readであることが前提となる。Exadataのスマートスキャンが有効となるのは、以下の3つの条件がすべて揃わなければならない。

 1.セグメントのフルスキャンであること
 2.direct path readであること
 3.オブジェクトはExadataに格納されていること

上記のうち、1は実行計画を確認すれば簡単にわかるだろう。3も環境により自明であることが多い。しかし、2については一番わかりにくい。なぜなら、direct path readの発動条件が公開されておらず、また、Oracleのバージョンによってロジックが異なるためである。少なくとも、条件としては、バッファキャッシュのサイズとオブジェクトのサイズ、バッファキャッシュに乗っているオブジェクトのブロック数が関係しているといわれる。

例えば、私の利用している環境(Exadata X7-2/Oracle12.2.0.1)では、セグメントサイズがバッファキャッシュの約2%を超えるとdirect path readが発生し始めることを確認している。このため、Oracle社の技術資料の中にはスマートスキャンを使うためにはパラレルヒントを入れることを促す資料があるほどである。嘘ではないが若干荒っぽいチューニング手法であると個人的には思う。

direct path readが発生していることは実行計画からは判別ができない。このため、一般的にはSQLトレース(10046トレース)を確認することが確実だろう。あるいは、セッション統計(v$sesstat, v$mystat)の統計の変化を確認することも有効だろう。いずれにしても本番環境で確認するのはいささかハードルが高い。

direct path readのデメリットといえば、バッファキャッシュに乗らないため、毎回ストレージに負荷がかかる点である。特にアクセス頻度が高いSQLではストレージサーバ側の負荷に注意が必要だろう。

例えば、ある表に対するHASH結合をプロセス多重で実行するようなケースを考えてみよう。HASH結合ではフルスキャンが走るため、上記条件を満たせばdirect path readとなり、Exadataではスマートスキャンによるストレージサーバへのオフロード機能の恩恵を受けられる。しかし、これを多重で実行すると、バッファキャッシュに乗らないため、ストレージサーバへ負荷が集中することとなる。このような場合は、あえてdirect path readを実行されないような考慮が必要かもしれない(具体的にはセッションレベルで_serinal_direct_readをNEVERにするなど)。

また、経年でセグメントサイズが増加するようなテーブルでは、DBサーバ再起動後からdirect path readに切り替わってしまうということが起きうる。これは、バッファキャッシュ上にセグメントブロックがある程度乗っているうちは、direct path readは発生しないという特性による。運用中にセグメントが閾値(具体的には_small_table_thresholdのブロック数から導出される閾値)を超え、インスタンス再起動によりバッファキャッシュがクリアされると途端にdirect path readになってしまい、ストレージサーバの負荷が高くなるという事象が起こりうる。性能が向上すればよいが、ストレージサーバの負荷によっては性能劣化を引き起こす可能性があるため、このような特性は理解しておく必要がある。

参考文献:[1]Expert Oracle Exadata

Expert Oracle Exadata

Expert Oracle Exadata

  • 作者: Martin Bach
  • 出版社/メーカー: Apress
  • 発売日: 2015/08/28
  • メディア: ペーパーバック



nice!(0)  コメント(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。