新久保浩二さんのブログの以下のエントリを読んで、自分なりに理解したことをまとめてみた。
小幡さん、yohei-aさん、wmo6hashさんなど、いろいろご意見がありましたが、一度、Oracleの非同期I/Oの実装はどうだったのか再確認が必要だと思いちょっと調べてみます。
手当たり次第やってもしょうがないので、以下の3つの観点で調査してみます。多分、何回かに分けて調査すると思うのですが、今回は初期化パラメータfilesystemio_options = [none|directio|asynch|setall]でどのようにI/Oに関するシステムコールが変化するか見てみます。
10046 trace name context forever: Unbreakable Enterprise Kernelのチューニングは非同期I/Oか?
まとめ
初期化パラメータfilesystemio_optionsの値によってどのようにI/Oに関するシステムコールが変化するか
- open()システムコールのフラグ
filesystemio_options | open()システムコールのフラグ(DBWR,LGWR,サーバープロセス) |
---|---|
none | O_RDWR, O_SYNC |
directio | O_RDWR, O_SYNC, O_DIRECT |
async | O_RDWR, O_SYNC |
setall | O_RDWR, O_SYNC, O_DIRECT |
- 読み書きに使われるシステムコール
filesystemio_options | 読み込み(サーバープロセス) | 書き込み(DBWR,LGWR) |
---|---|---|
none | pread() | pwrite() |
directio | pread() | pwirte() |
async | pread() | io_submit(), io_getevents() |
setall | pread() | io_submit(), io_getevents() |
妄想
- どのプロセス(DBWR,LGWR,サーバープロセス)も同じフラグでファイルをオープンする
- ファイルをオープンする際は、常に O_SYNC がついている
- ファイルシステムのページキャッシュのデータだけ変更して、電源が瞬断したときなどにディスクにデータが書かれておらずデータが飛ぶといったことが発生しないようにしている。
- O_SYNC vs O_SYNC + O_DIRECT の性能差
- どちらも同期処理なので、ディスクに物理的に書き込まれるまで待つ。
- O_SYNC のみの場合はページキャッシュ経由でディスクに書き込むのに対して、O_SYNC + O_DIRECT は直接ディスクに書き込む。
- どちらが性能面で優れているのか気になる。
非同期処理(filesystemio_options=setall)を行う場合、書き込み完了を待たずに次に処理を進めるので、電源が瞬断した場合などにデータが飛んでしまうが、どのような場合に使うのか例えば、開発環境で速さのみを求めて、データはちょっとくらい飛んでも良い場合とか、本番環境だけどUPSついてるから電源の瞬断は発生しないとか。とはいっても人為的なミスでは電源の瞬断は発生しうるから本番環境はこわいな。- ↑は誤解だった。下の手書きの絵に書いている通り、個々のI/Oは非同期だが、最後に全てのI/Oの完了を確認してから次の処理に進むので、データロストは発生しない。
補足
io_submit(2)はO_DIRECTをつけてopenしないと同期I/Oとなる
ただ1点、不思議な点があります。
私の認識ではio_submit(2)はO_DIRECTをつけてopenしないと同期I/Oとなると思っていたのですが、上記結果からfilesystemio_options=asynchの場合は、O_DIRECTフラグが付いていません。それにも関わらずio_submit(2)で非同期I/Oを行う(こと意図していると思う)動作になっています。本当に非同期I/Oになっているのだろうか?
10046 trace name context forever: Unbreakable Enterprise Kernelのチューニングは非同期I/Oか?
と新久保さんがブログに書かれていたので、手元の本を調べてみると、
詳解 Linuxカーネル 第3版 P.718
16.4.1 Linux 2.6 における非同期I/O
(中略)
しかし、Linux カーネル 2.6.11 では、非同期機能はまだ開発中であり、O_DIRECT フラグを指定してオープンしたファイルのみ、非同期で処理できます
なるほど、そう書かれていますね。
現在の Oracle Enterprise Kernel では O_DIRECT フラグを指定しなくても非同期処理できるようになってたりしないかな。
追記(2010/10/09):
同期I/Oと非同期I/Oのイメージを絵に描いてみた。
追記(2010/10/10):
id:sh2 さんがスバラシイ絵を書いてくださったのでいただき!
私のイメージはこう http://nessa.dip.jp/aio.pdf RT @yoheia: 非同期I/Oのイメージ http://f.hatena.ne.jp/yohei-a/20101009225704
Twitter. It's what's happening.