2010/09/30

Unbreakable Enterprise KernelのI/Oスケジューラ

Unbreakable Enterprise KernelにUpgradeして気づいたのですがkernelのI/Oスケジューラが変更されていますね。
Upgrade前(OEL5.5)ではないのですが、多分5.3? 5.4?の時のI/Oスケジューラは以下でした。

[oracle@kshinkub ~]# uname -a
Linux kshinkub 2.6.18-164.el5 #1 SMP Fri Sep 17 15:51:48 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux

[oracle@kshinkub ~]# cat /sys/block/sda/queue/scheduler
noop anticipatory deadline [cfq]



Upgrade後は以下のようになっていました。
[oracle@kshinkub ~]$ uname -a
Linux kshinkub 2.6.32-100.0.19.el5 #1 SMP Fri Sep 17 17:51:41 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux

[oracle@kshinkub ~]$ cat /sys/block/sda/queue/scheduler
noop anticipatory [deadline] cfq


確か、deadlineはDBMSなどに向くと聞いたような気がするが。ちょっと時間のある時に調べることにする

Unbreakable Enterprise Kernelのチューニングは非同期I/Oか?

小幡さん、yohei-aさん、wmo6hashさんなど、いろいろご意見がありましたが、一度、Oracleの非同期I/Oの実装はどうだったのか再確認が必要だと思いちょっと調べてみます。

手当たり次第やってもしょうがないので、以下の3つの観点で調査してみます。多分、何回かに分けて調査すると思うのですが、今回は初期化パラメータfilesystemio_options = [none|directio|asynch|setall]でどのようにI/Oに関するシステムコールが変化するか見てみます。

1. データファイルへの書き込み
    これは、DBWRが行っていますので、filesystemio_optionsの各モードでDBWRがopen|writeを
    どのように実行しているか?

2.REDOへの書き込み
    これは、LGWRが行っていますので、filesystemio_optionsの各モードでLGWRがopen|writeを
    どのように実行しているか?

3. データファイルの読み込み
    これは、shadowプロセスが行っていますので、filesystemio_optionsの各モードでshadowプロセス
    がopen|writeをどのように実行しているか?

1、2のトレースを取るには以下のような感じです。
# openのシステムコールを確認
strace -f -o /tmp/oracle.trc -e open sqlplus / as sysdba << EOF
startup
EOF

# 別ターミナルで
strace -o /tmp/oracle_dbwr.trc -p 
strace -o /tmp/oracle_lgw.trc -p 

# 別ターミナルで
sqlplus xxx/yyyy
SQL> insert into xxxx values (xxxx);
SQL> -- lgwに書き出させる
SQL> commit;
SQL> -- dbwの書き出させる
SQL> alter system flush buffer_cache;

3のトレースを取るには以下のような感じです。
strace -f -o /tmp/shadown.trc sqlplus xxx/yyy
SQL> -- direct path readとなるように
SQL> select /*+ full */ count(*) from big_table;

では、結果です。

1. DBWRの動作
   filesystemio_options=none
   オープンモード
       open("/oracle_ssd/oradata/soe_ssd.dbf", O_RDWR|O_SYNC) = 25

   書き込み
       pwrite(25, " \242\0\0\370\360\261\1\236\235\277\0\0\0\1\4\233\376\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536, 26812022784) = 65536

   filesystemio_options=directio
   オープンモード
       open("/oracle_ssd/oradata/soe_ssd.dbf", O_RDWR|O_SYNC|O_DIRECT) = 25


   書き込み
       pwrite(25, "\6\242\0\0\377\360\261\1\207\355\277\0\0\0\1\6\317\352\0\0\1\0\0\0\204\37\1\0{\355\277\0"..., 8192, 26812080128) = 8192

   filesystemio_options=asynch
   オープンモード
       open("/oracle_ssd/oradata/soe_ssd.dbf", O_RDWR|O_SYNC) = 25


   書き込み
       io_submit(140371209195520, 1, {{0x7faab86dfc00, 0, 1, 0, 20}}) = 1
       io_getevents(140371209195520, 1, 128, {{0x7faab86dfc00, 0x7faab86dfc00, 8192, 0}}, {600, 0}) = 1

    filesystemio_options=setall
   オープンモード
       open("/oracle_ssd/oradata/soe_ssd.dbf", O_RDWR|O_SYNC|O_DIRECT) = 25


   書き込み
       io_submit(139687490887680, 58, {{0x7f0b87a667c0, 0, 1, 0, 20}, ... {0x7f0b87a5caf8, 0, 1, 0, 25}}) = 58
       io_getevents(139687490887680, 4, 128, {{0x7f0b87a5caf8, 0x7f0b87a5caf8, 8192, 0}, ... {0x7f0b87a63718, 0x7f0b87a63718, 8192, 0}}, {600, 0}) = 4

2. LGWRの動作
   filesystemio_options=none
   オープンモード
       open("/oracle_local/oradata/redo06.log", O_RDWR|O_SYNC) = 22


   書き込み
       pwrite(22, "\1\"\0\0\246W\2\0K\0\0\0\20\2007\250\220\1\0\0\r\0\0\0\312\235\277\0\1\0\0\0"..., 512, 78597120) = 512

   filesystemio_options=directio
   オープンモード
       open("/oracle_local/oradata/redo06.log", O_RDWR|O_SYNC|O_DIRECT) = 22


   書き込み
       pwrite(22, "\1\"\0\0\312\0\0\0L\0\0\0\20\200Es\360\1\0\0\r\0\0\0\252\355\277\0\1\0\0\0"..., 512, 103424) = 512

   filesystemio_options=asynch
   オープンモード
       open("/oracle_local/oradata/redo06.log", O_RDWR|O_SYNC) = 22


   書き込み
       io_submit(140134974480384, 1, {{0x7f73b5153c50, 0, 1, 0, 21}}) = 1
       io_getevents(140134974480384, 1, 128, {{0x7f73b5153c50, 0x7f73b5153c50, 512, 0}}, {600, 0}) = 1

   filesystemio_options=setall
   オープンモード
       open("/oracle_local/oradata/redo06.log", O_RDWR|O_SYNC|O_DIRECT) = 22


   書き込み
       io_submit(139658147393536, 1, {{0x7f04aff94c50, 0, 1, 0, 22}}) = 1
       io_getevents(139658147393536, 1, 128, {{0x7f04aff94c50, 0x7f04aff94c50, 512, 0}}, {600, 0}) = 1

3. shadowプロセスの動作
   filesystemio_options=none
   オープンモード
       open("/oracle_ssd/oradata/soe_ssd.dbf", O_RDWR|O_SYNC) = 12

   読み込み
       pread(12, "#\242\0\0\203\36\240\1\353\37\276\0\0\0\1\4\n\257\0\0\0\0\0\0\0\0\0\0\353\331\240\1"..., 8192, 17243856896) = 8192

   filesystemio_options=directio
   オープンモード
       open("/oracle_ssd/oradata/soe_ssd.dbf", O_RDWR|O_SYNC|O_DIRECT) = 12


   読み込み
       pread(12, "#\242\0\0\203\36\240\1\353\37\276\0\0\0\1\4\n\257\0\0\0\0\0\0\0\0\0\0\353\331\240\1"..., 8192, 17243856896) = 8192

   filesystemio_options=asynch
   オープンモード
       open("/oracle_ssd/oradata/soe_ssd.dbf", O_RDWR|O_SYNC) = 12


   読み込み
       pread(12, "#\242\0\0\203\36\240\1\353\37\276\0\0\0\1\4\n\257\0\0\0\0\0\0\0\0\0\0\353\331\240\1"..., 8192, 17243856896) = 8192

    filesystemio_options=setall
   オープンモード
       open("/oracle_ssd/oradata/soe_ssd.dbf", O_RDWR|O_SYNC|O_DIRECT) = 12


   読み込み
       pread(12, "#\242\0\0\203\36\240\1\353\37\276\0\0\0\1\4\n\257\0\0\0\0\0\0\0\0\0\0\353\331\240\1"..., 8192, 17243856896) = 8192

ちょっと見づらいかもしれませんが。。。ただ、基本的に想定通りの動きです。

ただ1点、不思議な点があります。
私の認識ではio_submit(2)はO_DIRECTをつけてopenしないと同期I/Oとなると思っていたのですが、上記結果からfilesystemio_options=asynchの場合は、O_DIRECTフラグが付いていません。それにも関わらずio_submit(2)で非同期I/Oを行う(こと意図していると思う)動作になっています。

本当に非同期I/Oになっているのだろうか?

2010/09/26

続 Smart Flash Cacheの謎

先日、Smart Flash Cacheを実行した際に2回目が必ず遅いと書きましたが、あれから、ちょっと調べてみました。原因は単純なのですが。一応、ご報告です。

先日のテストを再度実行し、その時のv$sysstatのflash cache 周りの統計情報を見てみます。

flash cache insert skip: DBWR overloaded physical read flash cache hits flash cache inserts flash cache insert skip: exists
1回目 147593 2 206803 398
2回目 0 207038 147880 206680
3回目 0 354529 90 354406


正直、上記のイベントに関してキチンとしたドキュメントが存在しないので、想像の域を超えませんが、前回、x$bhから、対象セグメントのサイズの全てが、flash cache上に乗っていないと言いました。その原因が示されているようです。

それは、flash cache insert skip: DBWR overloadedだったから。というわけでしょう。DBWRが忙しすぎると、flash cacheに乗せる(というよりもきっとflash cache上に存在するのか?flash cache上に空きがあるのか?といった管理)作業をスキップするようです。結果として、flash cache上に全データが乗っていなかったと(ある意味)納得がいきました。

もう少し、見てみます。
1回目は、基本的にデータファイルから、buffer cache(このテストでは小さくしてあるので、ほぼ、flash cache)に乗せる作業となります。なので、flash cacheのデータにヒット(physical read flash cache hits)することは無く、また、flash cacheにはデータが存在しないので、既存データとしてスキップする(flash cache insert skip: exists)ことなく、全て、flash cacheにデータを乗せています(flash cache inserts)。ただし、DBWRが忙しかったので、一部のデータはflash cacheの乗せることをスキップしています(flash cache insert skip: DBWR overloaded)

2回目となると様相が変わります。
それは、かいつまんで言うと、physical read flash cache hitsと、flash cache insert skip: existsが増加し、さらに、flash cache insertsもソコソコ存在するということです。これは、簡単にいうとflash cache上でread / writeが、相当競合したであろうことを示しています。

3回目になると。
言わずもがな、ですが、flash cache insertsが激減(全部、flash cacheに乗ってしまった)し、ほぼreadのみの状態となりました。

ここまでで、お分かりのように、Smart Flash Cacheにおける、ready boost的なフラッシュキャッシュは、buffer cacheと同様に扱われます。が、SSDは物理メモリではありません。なので、物理メモリよりは随分遅いのです(普通のディスクよりはかなり高速なのですが)なので、物理メモリの補助として使用することを忘れると大変なことになります。
このテストの場合、buffer cacheを小さく設定しているので、ほとんどをflash cacheに頼っています。flash cacheでは自分のI/O性能を超えるもの要求されて、ニッチもサッチも行かない状況なのがうかがえます。特にこれは2回目のread / writeの競合で顕著にみえたということでしょう。

一応、その際のiostatの状況をまとめてみます。

Chart build on http://charts.hohli.com

Chart build on http://charts.hohli.com

Chart build on http://charts.hohli.com

2010/09/25

Smart Flash Cacheの謎

そろそろ、Smart Flash Cacheのテストに戻ります。

基本的に、Smart Flash CacheはOLTP系で使うものだ。と先日書きました。しかし、テストでOLTP系のSQL(要はindex scan)を実行したら、なかなかbuffer cacheも汚れませんし、当然、flash cacheもキレイなままです。なので、通常はdirect path readを使ってしまうfull scanをscattered readに変える裏技を使って、一気に、buffer cacheを使いまくってみます。

そうすると、一つ、不思議な現象が起こっています。

"2回目のアクセスが、遅い"

ORDER_ITEMS表をfull scan(db file scattered read)させた際の経過時間を示してみます。

Chart build on http://charts.hohli.com

当然、1回目のアクセスはディスクから物理読み込みが発生しているので、遅いのは当たり前です。しかし、2回目のアクセスはbuffer cacheもしくは、flash cacheに乗っているはずなので、速い。ということを期待していたのですが。。。1回目のアクセスよりも遅くなってしまっています。

ちなみに3回目以降は、想定通りのスピードです。

何故なのだ!?

理由を考える前に、そもそも、flash cacheにちゃんとデータが乗っているのか?を見てみる。

ORDER_ITEMSのセグメントサイズは3840MBでした。これが、全部buffer cache(+flash cache)に乗っているのかを確認してみます。

以下のSQLでx$bhからサイズを確認します。

/* block sizeは8KB */
select  decode(state, 0, 'free', 1, 'xcur', 2, 'scur', 3, 'cr', 4, 'read', 5,
  'mrec', 6, 'irec', 7, 'write', 8, 'pi', 9, 'memory', 10, 'mwrite', 11,
  'donated', 12, 'protected', 13, 'securefile', 14, 'siop', 15,
  'recckpt', 16, 'flashfree', 17, 'flashcur', 18, 'flashna',state) status
,count(*)*8 / 1024 MB 
from x$bh
group by state

Chart build on http://charts.hohli.com

1: 起動直後
2: 1回目のアクセス
3: 2回目のアクセス
4: 3回目のアクセス
5: 4回目のアクセス

注目は、1回目のアクセスです。
セグメントサイズが3840MBにも関わらず、flashcur(これが、flash cahceにカレントモードで乗っているステータス)のブロックは2500MBにも満たない状況です。つまり、全部乗り切らなかった。2回、3回とアクセスすると、やっと、全ブロックがflash cacheに乗ったことが分かります。 

flash cacheに乗り切らなかった原因も謎なのですが、なぜ、ディスクからの物理読み込みが発生している1回目のアクセスより、2回目のアクセスが遅くなっているのか?

今後、もう少しちゃんと見てみる必要がありそうです。

2010/09/23

続 Unbreakable Enterprise Kernel

昨日に続き、もう少しUnbreakable Enterprise Kernelをテストしてみます。kernelのupdateでちょっとビックリしたのは以下の問題です。
kernel アップデート後、再起動を行うと、起動はしているようだがコンソールが表示されない(udevサービス起動で固まっている)

回避策) 
/etc/grub.confの起動オプションにnomodesetを追加する。 
kernel /vmlinuz-2.6.32-100.0.19.el5 ro root=LABEL=/ rhgb quiet nomodeset

で、昨日のSSDでのOLTPベンチマークをUnbreakable Enterprise Kernelで実行してみます。

結果は以下。

Redhat Compatible Kernel)
平均のTPMで17822、最高のTPMで20062、レスポンスタイムは12ms

Unbreakable Enterprise Kernel)
平均のTPMで20411、最高のTPMで22966、レスポンスタイムは8ms

一応、ASH Viewerの結果)


TPMはDBのリソース(AAS)が余っているので、参考程度なのですが、レスポンスタイムが12(ms) -> 8(ms)と約33.3%のパフォーマンスアップとなっています。

レスポンスタイムは(当然ですが)I/Oレイテンシーだけで決定するわけではないので、33.3%のパフォーマンスアップという結果は、Oracleが言っている75%のI/Oパフォーマンスアップという謳い文句が大きくハズレていないことを示しているようです。

* ただし、これは再検証をしっかり行ったものではありません。参考程度にしてください...

参考ついでに、HDDも同様にベンチマーク結果を示しておきます。

ベンチマーク結果)

ASH Viewerの結果)


Redhat Compatible Kernel)
平均のTPMが4692で、最高のTPMでも6696、レスポンスタイムは159

Unbreakable Enterprise Kernel)
平均のTPMが5363で、最高のTPMでも6843、レスポンスタイムは138

これは、もしかすると誤差の範囲かもしれませんが、平均TPM、レスポンスタイムで、13%~14%程度のパフォーマンスアップとなっていました。


2010/09/22

Unbreakable Enterprise Kernel

海の向こうでOOWが賑やかに開催されていますが、Oracle LinuxでSSDを使った検証している自分にちょっとタイムリーな情報が入ってきました。Oracleが、良くも悪くもOracleデータベースに向けてカリカリにチューニングしたLinux Kernelを発表しました。それがUnbreakable Enterprise Kernelです。

Delivers Better than 75 Percent Performance Gain Over Red Hat Enterprise Linux 5 Compatible Kernel

これは、ちょっと聞き捨てなりませんよね。詳細は、Oracleの発表資料を見て欲しいのですが、SSDに対するチューニングも施されているようです。

このkernelは、Oracleのサポート契約無しで、public yum リポジトリからインストールできます。詳細は、こちらで詳しく説明されています。

時間のある時に、きちんと検証してみたいと思います。

* カーネルを一気に現在のメイン ラインに近いところまで持ってくる思い切りの良さは、個人的には嫌いではないです。


SSDでのOLTP性能

前回、HDDを使ったOLTPとHDD + SSD(Smart Flash Cache)のパフォーマンス比較を行ないましたが、せっかくなので、SSDにデータを配置した場合のパフォーマンスも計測してみます。

結果は、当然ながら最速となりました。

ベンチマークの結果)
平均のTPMで17822、最高のTPMで20062を記録しました。


ASH Viewerで確認)
まず目を引くのはAASの値の低さです。まだまだ、余裕です。今回は、前回と条件を合わすため、15セッションでベンチマークを行っていますが、全く余裕でした。


一応、前回同様にUser I/Oの待機イベントの出しておきます。


ここまでのパフォーマンス結果をまとめてみます。ただ、SSDを使用した場合はパフォーマンス限界まで達していないので、ベンチマークでの平均レスポンスタイムを示しておきます。


2010/09/21

Smart Flash Cache の使い道

Smart Flash Cache自体、現在のBuffer Cacheの代替キャッシュ(L2 キャッシュ)という位置づけでしかないが、使い道はそれなりに多い。メインメモリ(DDR3)4GBが10000円前後であるのに比べ、SSD 64GBは15000円前後です。SSDは、Buffer Cacheの不足を補うには、もってこいのデバイスと言えるでしょう。

ただし、これは、"あくまでもOLTP系の処理"に限定したものです。OLTP系の処理では、インデックスを使用したアクセスが前提です。またインデックスアクセスは、基本的にバッファ上に存在する(してほしい)事も前提です。DWHのようなシステムでは、バッファ上に乗り切らないので、バッファを迂回したdirect path readを使用します。(が、これもin memory parallel Queryの登場で変わってくるかも知れません)

あと、OLTP系のシステムで、SQL文がそれなりにチューニングされている場合、全体のスループットを上げる方法として、メモリを大容量にする。か、ちょろちょろ発生するディスクアクセスを超高速にする。しかありません。実際、現在のディスクで最速なものはSSDとなるわけですが、SSDへデータを移動するには通常のデータ移行にみられるような、システムの停止を含む業務への影響や、データ移行に伴う様々のリスクが存在します。

Smart Flash Cacheは、WindowsのReady Boostなみに簡単にパフォーマンスアップが望めます。それもリスクなしで。SSD 64GB程度を15000円程度で購入し、デバイスごとOracleに認識させるだけです。本当にそれだけです。(といっても、街の電気屋さんで買って、すぐに商用環境にくっつけるには勇気がいるでしょうが...)

では、再度、Smart Flash Cacheのパフォーマンス比較をしてみましょう。

環境)
memory_target = 4.5GB
swingbenchにてTPC-Cベースの負荷を掛けます(swingbench用スキーマは約30GB程度です)
セッション数は15

1) 普通にベンチマークを実施

ベンチマークの結果)
平均のTPMが4692で、最高のTPMでも6696に留まっています

ASH Viewerの結果)
15セッションのほとんどがUser I/Oクラスの待機イベントで待たされていることが分かります。


またUser I/Oクラスの内訳はdb file sequential read(index scan)であることが分かります。


以前、「まず初めに」で述べたようにswingbenchはかなりチューニングされているベンチマークソフトですが、index scanでかなりの待機が発生しています。この答えを先にいってしまうと、TPC-Cはorder - entryのシステムをシミュレーションしているので、多くの「発注」と「確認」が発生します。「発注」は主にinsertとなるのですが、重複発注を防ぐようにUniqueチェックが入ります。ここで、index scanが多く発生し、結果、待たされる。ことになります。
これは、小幡さんのブログにもありましたね。


2) Smart Flash Cacheを使用してベンチマーク実施

- Smart Flash Cacheを50GB分確保
alter system set db_flash_cache_size=50G scope=both; 

- いくつか大事なオブジェクトをFlash Cache上にキープさせる(前に50GBで大丈夫か確認)
select segment_name, sum(bytes)/1024/1024 segment_size_MB
from user_segments
where  segment_name in ('CUSTOMERS', 'CUSTOMERS_PK', 'ORDER_ITEMS'
                                    ,'ORDER_ITEMS_PK', 'ORDERS', 'ORDER_PK')
group by segment_name;

SEGMENT_NAME                    SEGMENT_SIZE_MB
------------------------------ ----------------
CUSTOMERS                                  3072
ORDER_ITEMS                                3776
ORDER_PK                                    790
CUSTOMERS_PK                                703
ORDERS                                     2752
ORDER_ITEMS_PK                             2808

- いくつか大事なオブジェクトをFlash Cache上にキープさせる
/* これは、Flash Cacheに事前に乗せる際にdirect path readでバッファーを迂回しないおまじない */
alter session set events '10949 trace name context forever ,level 1';
alter session set "_very_large_object_threshold"=1000000;

/* 以下は大事なオブジェクトをFlash Cache上に乗せる */
alter table customers storage(flash_cache keep);
select /*+ no_parallel index(c customers_pk) */ count(*) 
from customers c where customer_id>=0;
alter index customers_pk storage(flash_cache keep);
select /*+ no_parallel no_index(c) */ count(*) 
from customers c;

alter table order_items storage(flash_cache keep);
select /*+ no_parallel no_index(c) */ count(*) 
from order_items c;
alter index order_items_pk storage(flash_cache keep);
select /*+ no_parallel index(c order_items_pk) */ count(*) 
from order_items c where line_item_id >=0 and order_id>=0;

alter table orders storage(flash_cache keep);
select /*+ no_parallel no_index(c) */ count(*) 
from orders c;
alter index order_pk storage(flash_cache keep);
select /*+ no_parallel index(c order_pk) */ count(*) 
from orders c where order_id >= 0;

ベンチマークの結果)
平均のTPMが9726で、最高のTPMで15045と、平均のTPMで約2倍のパフォーマンスアップとなっています。

ASH Viewerの結果)
User I/Oの待機が減って、その分、多少CPUを使えるようになりました。

User I/Oの待機は以前、db file sequential readですが、全体的に減少しています。

ただ、もう少し、チューニングの余地はありそうです。

2010/09/19

Smart Flash Cache 簡単なパフォーマンス比較

SSDも新しくなったことで、快調に検証が進みそうです。
まず、Smart Flash Cache単体のパフォーマンスを比較するため、以下の3パターンのパフォーマンスを測定してみます。

1) 大きなテーブルをdirect path readで検索する
2) 大きなテーブルをdb file scattered readで検索する
3) 大きなテーブルをdb flash cache multiblock physical readで検索する

3)は見慣れないイベントですが、基本的には、全て同じテーブル(大きなテーブル)に対して

1) バッファーキャッシュを迂回してディスクを直接読み込む
2) バッファーキャッシュを経由してディスクを間接的に読み込む
3) バッファーキャッシュ+フラッシュキャッシュを経由して、ディスクを間接的に読み込む

ただし、今回のテストは、Smart Flash Cacheのパフォーマンスチェックなので、以下の条件を付けました。

* ご存知の方も多いと思いますが、11gR2から、通常のフルスキャン
   (今ままでのdb file scattered read)は、ある条件によりdirect path readに置き換えられます。
    これは、バッファーの再利用性が低いSQLだと(ある意味Oracleが勝手に)判断できる場合は、
    バッファー経由のI/Oを諦めてディスクと直接I/Oすることを意味します
* 今回のテストでは、db file scattered read と direct path readを使い分けたかったので、
   非公開のパラメータ"_very_large_object_threshold"を変えています。
* "_very_large_object_threshold"の単位は多分MBだと思いますが、このサイズを超える場合、
   大きいオブジェクトだと判断してdirect path readを選択するようです。なので、この値を非常に
   大きくすると、今ままで通り、db file scattered readを選択する可能性が高いということです。

1) テーブルのサイズは、必ずbuffer cacheのサイズを超える
2) テーブルのサイズは、flash cacheのサイズを超えない

つまり、buffer cacheを超える読み込みが発生するので、2)はパフォーマンス的に不利になるはずで、1)が多少有利になるはず。さらにSmart Flash Cacheの実力が本物なら3)のパフォーマンスが最高になるはずです。
まずは、結果を示します。



Smart Flash Cacheを使用したパフォーマンスが最高となっています。

では、いつものようにASH Viewerでその時の様子を見てみます。
* 1)のテストが図中のAに該当
* 2)のテストが図中のBに該当
* 3)のテストが図中のDに該当




その時の待機イベントも見てみましょう。(上記グラフの青で示されているUser I/Oを見てみます)

一応、思ったとおりの結果となっているようです。パターンAでは、待機クラスUser I/Oのdirect path readで待機しています。またパターンBでは、db file scattered read、パターンDでは、db flash cache multiblock physical readで待機しています。
以前の検証にてDiskとSSDの基本性能の違いをチェックしましたが、1MBのsequential readの性能で約3倍のパフォーマンスが違います。今回は(まだ、きちんと検証できていませんが)multiblock read count分のsequential readだとして16 * 8K = 128Kくらいのsequential readじゃないかと推察できます。1MBほど大きなサイズではないことが言いたいのですが、それにしてもDiskと比較して3倍のパフォーマンスアップにはなっていません。SSDをL2キャッシュとして使うSmart Flash Cacheはそれなりのオーバーヘッドがあるのかも知れません。

Flash Cacheのデバイスが壊れたら

先日、Smart Flash Cacheのテストを行うようテスト環境をセットアップしたのですが、その前からテストで使用するSSDの調子が悪いことも書いていました。とりあえず、そのままの状態で、Smart Flash Cacheをテストしてみます。まず、テストを始める前に、Smart Flash Cacheが有効になっているか、軽く確認してみることにします。

簡単なSQLを実行して、パフォーマンスを比較、(そもそもエラーにならないか確認)してみます。

set timing on

select * from soe.order_items;
細かいテストは次回以降で見ていくとして、ざっくりエラーは発生しません。しかし、パフォーマンスが尋常ではないくらい悪い。何かあるはずだと、アラートログを確認してみます。

ORA-27072: File I/O error
Linux-x86_64 Error: 5: Input/output error
Additional information: 4
Additional information: 1287652
Additional information: -1

flash cacheへのアクセスに失敗したので、Smart Flash Cache機能を無効にして、通常のBuffer Cacheのみの動作をしているようです。なので、かなり、パフォーマンスが悪化していたのだと思います。

このままでは、どうにもならないので、新たにSSDを調達しました。

今回、調達したSSDはCFDのCSSD-S6M64NMQにしました。
前回、使用していたreal SSDと同じものですが、128GBを64GBにして構成しています。

とりあえず、これで、テストに支障はないようです。次からしっかりテストします。

2010/09/15

OTNのチューニングセミナー資料

1年くらい前に、オラクルOTNでセミナーを行う機会があり、そのセミナーの内容がOTNに公開されています。その時に使用した資料をブログにも公開しておきたいと思います。
(1年前の古い資料をいまさら公開するな。と言われそうですが。。。)

確か、当時は、いろいろなセミナー(Oracleだけではなく)で話しをさせてもらう機会も多く、久しぶりのOracleに関するセミナーだったので話していて(個人的には)楽しかった気がします。チューニングの話しになると、とかく細かい話しになりがち(しがち)ですが、そうではない概念的な話しも何かのお役に立つかも知れません。

どうもIEだと上手くPDFが見えないことがあるみたいです。firefoxならちゃんと見えています。(どうなっているの??)

2010/09/14

Smart Flash Cache

小幡さんよりSSDを使ったSmart Flash Cacheのテストについてコメントをもらったので、テストをしてみる予定です。

OEL(Oracle Enterprise Linux)でSmart Flash Cacheを使用できるようにするには、ひとつパッチが必要になります。

Patch 8974084
META BUG FOR FLASH CACHE 11.2PL BUGS TO BACKPORT TO 11.2.0.1 OEL

では軽く手順を示しておきます。

1. 上記のOracleの個別パッチをopatchで適用します
2. 初期化パラメータ db_flash_cache_fileを設定します
3. 初期化パラメータ db_flash_cache_sizeを設定します
4. DBの再起動

ここで、ひとつ注意が必要です。通常、SSDを使用する場合、/dev/sd*のようなデバイスをdb_flash_cache_fileに設定すると思いますが、このようなデバイスファイルには、ORACLEインストールユーザーへ直接、読み書き権限がついていません。

今回、私の検証環境では、SSDは/dev/sdcでした。

$ ls -l /dev/sdc
brw-r----- 1 root disk 8, 32 9月 14 01:58 /dev/sdc

この状態で、Oracleを起動すると

Errors in file /home/oracle/app/oracle/diag/rdbms/ora1120/ora1120/trace/ora1120_dbw0_23097.trc:
ORA-27041: unable to open file
Linux-x86_64 Error: 13: Permission denied
Additional information: 1
DBW0 (ospid: 23097): terminating the instance due to error 27041
Instance terminated by DBW0, pid = 23097

のように、Permission deniedでDBWRが停止して、インスタンスも停止します。
そこで、/dev/sdcに権限をつけてあげるわけですが、これではOSの再起動とともに権限が落ちます。

ということで、適切に/etc/udev/rules.d/*.rulesを設定します。

今回、私は検証環境ということもあり
/etc/udev/rules.d/99-flash-cache.rulesを作成し

KERNEL=="sdc", MODE="0777"

の設定をしておきました。

これで、めでたくOELでSmart Flash Cacheのテストが可能になりました。

SQL> show parameter db_flash_cache
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_flash_cache_file                  string      /dev/sdc
db_flash_cache_size                  big integer 100G

これから、しばらくSmart Flash Cacheについてテストしていきます。

2010/09/12

Linuxのファイルシステムで最適なものは?

Linuxでは多くのファイルシステムがあり、現在も様々なものが開発中です。

メジャーなものとしてext2、ext3がありますが、現在ext4が主流になろうとしています。また、oracleが開発したBtrfs(B-tree file system)などのような、SSDへの最適化やCOW(Copy on Write)など次世代のファイルシステムが沢山あります。

そこで、あまり最新のものは今後やるとして、昔からあるファイルシステムと今のファイルシステムでどの程度パフォーマンスに差があるのか検証してみます。

* 本当はBtrfsも検証したかったのですが、SSDが不調なのとDIRECT I/Oが未サポートだったので断念しました
Linux 2.6.35 released, with Btrfs Direct I/O support and -ENOSPC handling of volume management operations, completing the -ENOSPC support.

ext2からext3がLinuxの主流になったとき、ext3のジャーナリング機能を嫌い、Oracle構築でxfsを使う方も多かったのではないでしょうか?何せ、xfsはメタデータのみジャーナリングを行い、実データに関しては基本知らんぷりという仕様だからです。そんな中途半端?なジャーナリングを備えたファイルシステムがなぜ、好まれるのか?

答えは簡単です。Oracleにとって実データのジャーナルは必要ないからです。OracleはデータベースのファイルをO_SYNCオプションを付けて、オープンします。それは、OSのファイルキャッシュが危ないことを知っているからです。Oracleが「書いた!」と思っても、実はファイルキャッシュにしか書かれておらず、実際のファイルには「書かれていない!」こともあり得るわけです。これを確実に「書いた!」もしくは「失敗した!」とするため(白黒はっきりさせるため)にO_SYNCオプションを付けてオープンしているわけです。

とりあえず、上記のように、ファイルシステムは沢山あって、ジャーナリングなど高機能を提供するものも多い。ただ、そのような高機能が不必要な場合もあるわけで、システムによって、特性を見極めてファイルシステムを選択する必要もあるかも知れない。というわけで、今回はファイルシステムの性能を測定してみました。

1. ext4(writeback)
2. ext4(ordered)
3. ext3(writeback)
4. ext3(ordered)
5. xfs
6. ext2

6パターンのパフォーマンスを比較してみます。前回と同じ測定方法です。

結果は、xfsが大健闘、甲乙つけがたい感じで、ext4のパフォーマンスが素晴らしい。逆にext3は、かなり苦戦を強いられている。xfsやext4はエクステントでブロックを確保するが、これが、読み込み時に有利に働くと思われます。

ただ、これを書いていて思ったのですが、今時みんなASMですかね。。。












SSD自体が不安定

先日、SSDで非同期I/Oって大丈夫か?と書きましたが、非同期I/Oが問題なのでなく、ディスク自体が問題になっているようでした。

最初は、ファイルシステムがオカシイのか?(実は、OEL(kernel:2.6.18)では、experimentalレベルのext4を使っていたので)と思ったのですが、そんなレベルではないようでした。

smartctlで、SSDの状態を見てみるとエラーを示す値が大きくなっていました。これでは、かなり不安定になるのもうなづけます。。。(実際には、OSをインストールしていたディスクも非常に不安定になっていました。こちらは、ディスクを買い替えました)



ということで、SSDを使った検証は後回しにして、HDDベースで、検証を進めることにします。が、最初にファイルシステムを疑ったついでに、少しファイルシステムについても検証してみることにします。

2010/09/06

SSDで非同期I/Oって大丈夫か?

TPC-Cベースのベンチマークを以下の条件の下、4回実施した

クライアントPCから100セッションでswingbenchを実行

A: HDDにベンチマーク用データを格納し、非同期I/Oをオフ(Oracleのデフォルト値)
B: SSDにベンチマーク用データを格納し、非同期I/Oをオフ(Oracleのデフォルト値)
C: HDDにベンチマーク用データを格納し、非同期I/Oをオン
D: SSDにベンチマーク用データを格納し、非同期I/Oをオン

その際の、swingbenchの結果を示してみる

HDDを使用したベンチマークでは、TPMの結果が非常に不安定であることが一目瞭然(A、C)。SSDを使用したベンチマークでは、それなりに安定しているものの(B、D)、非同期I/Oをオンにしたベンチマークが群を抜いてスコアが高く、安定性が高いことがわかる(D)。
 この、秘密は何なのか?

このベンチマークの際に取得しておいたASH viewerの結果も合わせて見てみようと思う。





まず、非同期I/Oを使用しないベンチマーク(A、B)では、断続的にcommit(詳細はlog file sync)の待機が発生している。また、同様にconfigration(詳細はfree buffer waitsとlog file switch(checkpoint incomplete))で待機している。log file syncはREDOへの負荷が高まっている。つまり、REDOへ書き出しているLGWRがスムーズに書き込めていないことを示してる。一般的にはREDOログが配置されているディスクが遅い場合や、頻繁なコミットによるshort I/Oが引き金になることが多い。

また、free buffer waitsは、必要なブロックをBuffer Cache上から検索するが、存在しない場合、ディスクから読み込んでBuffer Cache上に乗せる必要がでてくる。その際、Buffer上がダーティブロックで一杯だった場合、DBWRに一回、ディスクに書き込んでBuffer Cacheをキレイにしてくれ。とお願いする必要が出てくる。それを待っているのがfree buffer waitsで、log file switch(checkpoint incomplete)は読んで字の如しだが、REDOログをスイッチしようとしたが、次のREDOログのチェックポイントが完了していないので待機しているということ。両者に共通することは、free buffer waitsもlog file switch(checkpoint incomplete)もDBWRがスムーズなI/Oができずに、詰まっているために引き起こされている現象だということ。

ちょっと整理してみると、

1. どうも、LGWRはスムーズにI/Oが行えていない(log file syncで待機中)
2. どうも、DBWRもスムーズにI/Oが行えていない(free buffer waitsとlog file switch(checkpoint incomplete)で待機中)

ということで、書き込み要求をスムーズに処理させる(可能性のある)filesystemへの非同期I/Oを有効にしてみることにする。(Oracleのデフォルトでは使用されない)

SQL> alter system set filesytemio_options=asynch scope=spfile;

結果は、一目瞭然(C、D)、commit(log file sync)は無くなった。これにより、TPCベンチマークのスコアも高くなっている。




しかし、HDDを使用したベンチマークでは、LGWRがスムーズにI/Oできるようになった分、自分自身のI/O要求が高まり(User I/O(db file sequential read))更に、HDDの限界値を超えるI/Oは当然できないので、log switchの発生と共に、DBWRのI/Oが飽和状態になり、TPCのベンチマークも下降線を示している。

一方、SSDを使用したベンチマーク(D)では、I/Oに余裕があるため、LGWRとDBWRのI/Oスループット向上が、そのままTPCのスコア向上に寄与している。

しかし、このベンチマークを走らせるようにしてから、OS kernelがI/O関連のエラーを出力するようになっている。原因はSSDへの非同期I/Oのようだが。。。更には、filesystem全体が破壊されてしまっている。。。

確かにパフォーマンス向上が驚くほどだが、二度と起動しないようでは。。。

ということで、もう少し詳細に調べることにする。



2010/09/01

検証の部品

昨日に引き続き、検証のための部品の説明です。

検証を行うにあたって、そのボトルネックの把握とチューニング作業は非常に大切な作業
です。別に検証といった限定的な話しでなくても普通に大切ですよね。

Oracleでボトルネックと言えばWait Eventを見ることになるわけですが、普通はActive
Session History(ASH : v$active_session_history)を見ることになります。

ASH自体はSQL文で見れば良いのですが(Enterprise Managerという手もあります...)
GUIでキレイに見たい。

ということで、自分は、ASH Viewerを使います。

ASH Viewer
  Javaで書かれたASH viewerです。結構キレイに見えます。ASH Viewer自体の
  ライセンスはGPLですが、実際ASHの参照にはOracleのライセンス制限が適用
  されますので、商用で無邪気に使えませんのでご注意ください。

ざっとイメージはこんな感じです。


ASHって何だ?チューニングって何だ?的な話しもまとめてドキュメント化して共有したいと思ってます。
(どこかで)

こんな感じで、そろそろ、検証やら、それにまつわる考察やらを書いていくことにします。