Tuesday, January 13, 2009

Linux FILESYSTEMIO_OPTIONS=directIO, asynch, setall

http://www.oracle.co.jp/2shin/ora83/22_23.html

Oracleのマニュアルによると

Direct Writes to Disk

On both UNIX and Windows platforms, bypassing the file system buffer cache ensures data is written to disk.

On UNIX, Oracle Database uses the O_SYNC flag to bypass the file system buffer cache. The flag name depends on the UNIX port.

On Windows, Oracle Database bypasses the file system buffer cache completely.

つまり全てのオラクル書き込み操作はキャッシュをスキップしている。
なるほど、だからIO Slave、directIO, asynchなどオプションが存在するのだ。

Linux版のOracleは、 Oracle9i Database R2より非同期I/OとDirect I/Oをサポートしています。ただし、Linux版のOracleデータベースはデフォルトでは非同期I/Oを使用できません。また、Direct I/Oに関しては、OS自体がMIRACLE LINUX V3.0(以下、ML3.0)、RedHat Enterprise Linux 3.0(以下、RHEL3.0)以降で対応しています。

今回は、非同期I/O、Direct I/Oを使用する効果と、Oracle Database 10g for Linuxでこれらの機能を使用するための設定方法について説明していきます。

非同期I/Oとは

大量のI/Oが発生するシステムでは、read(), write()システムコールがI/Oボトルネックになりがちです。データを複数のディスクに分散しても、read(), write()システムコールが完了するまでプロセスはスリープしてしまいI/O待ち状態にするため、あまり効果が上がりません。非同期I/Oは、プロセ スがI/O処理の完了を待つことなく作業完了をシグナルで通知させる仕組みです。この機能により、プロセスはCPU処理とI/O処理を並列しておこなうこ とを可能とします。

ファイルシステムの場合、基本的にプロセスのデータ書込み処理はOSバッファ・キャッシュへの書き出しで完了するため、同期処理でもI/O性能は向 上しています。しかし、Oracleデータベースの場合、データの整合性を保つためO_SYNCフラグでファイルをオープンします。この場合、ディスクへ の書き出しが完了するまでプロセスはスリープすることになり、同期I/Oは直接パフォーマンスの低下につながります。

非同期I/Oの設定

Oracle Database 10gで非同期I/Oを使用するには、以下の手順が必要です。

1. PSR10.1.0.3の適応をおこないます。

Oracleデータベースで非同期I/Oを使用するためには、oracleの再リンクをおこないます。

10.1.0.2環境のメイクファイルに問題があり、PSR10.1.0.3で修正されています。

2. oracleの再リンクをおこないます。

次のコマンドを実行し、oracleの再リンクをおこないます。

oracleの再リンク

次のコマンドを実行し、下記の状況を確認します。

状況を確認
※リンク作業前のコマンドの実行結果は「w io_getevents」になります

3. Oracleの初期化パラメータを以下のように設定します。

DISK_ASYNC_IO true (デフォルト)
FILESYSTEMIO_OPTIONS async (デフォルト:none)

4. カーネルパラメータを以下のように設定します。

非同期I/Oのリクエストごとの最大データ量を、ある程度大きく設定します。

この値が小さい場合、I/Oのパフォーマンスが低下してしまいます。

カーネルパラメータを設定
※ML3.0ではデフォルトで最適化されています。

非同期I/Oが動作しているかどうかの確認をおこなうには、ltraceコマンドでdbw0プロセスのトレースを取る方法があります。そのトレース結果のなかで「submit_io」が呼び出されていれば、非同期I/Oが動作しているということです。

ltraceコマンドでトレースを取る
※ltraceの使用方法についてはmanコマンドで確認してください

Direct I/Oとは

ファイルシステムは、OSバッファ・キャッシュを使用してディスクへのI/Oを軽減します。データを書き出すときに、いったんOSバッファ・キャッシュに記憶しておき、実際にディスクに書き出すときにはあとでまとめておこないます。

このバッファ・キャッシュの使用は、小さいデータをたくさん読み書きする場合には有効に働きますが、大きなデータを一度に読み書きする場合には、逆にオーバーヘッドになることがあります。

Direct I/Oを使用する場合、OSバッファ・キャッシュをバイパスし、ファイルシステムのデータを直接プロセスのメモリ空間にコピーするため、カーネルとプロセ ス間のデータ読み書きのオーバーヘッドを抑えられます。とくに、Oracleデータベースの場合はO_SYNCで書込みをおこなうため、OSバッファ・ キャッシュを経由する作業はたんにオーバーヘッドとなります。また、OracleデータベースがOSバッファ・キャッシュを使用しない分だけ、OSバッ ファ・キャッシュに余裕ができ、別の処理に利用することができます。

Direct I/Oの設定

Oracle 10gでDirect I/Oを使用するには、以下の作業が必要です。

1. OSはML3.0(RHEL3.0)を使用します。また、Oracle本体とデータベースファイルはext3上に作成します。

2. SCSIドライバがvaryio機能をサポートしている、以下のドライバを使用します。

・qla2200, qla2300   ・cciss   ・aic7xxx, aic79xx
・aacraid   ・megaraid

3. Oracleの初期化パラメータを以下のように設定します。

DISK_ASYNC_IO true (デフォルト)
FILESYSTEMIO_OPTIONS directIO (デフォルト:none)
Direct I/Oが動作しているかどうかの確認をおこなうには、straceコマンドでdbw0プロセスのトレースを取る方法があります。そのトレース結果のなかで「O_DIRECT」フラグが指定されていれば、Direct I/Oが動作しているということになります。

ltraceコマンドでトレースを取る
※straceの使用方法についてはmanコマンドで確認してください

同時に使えば二者択“逸”!

この2つの機能はさらに、ML3.0 + Oracle Database 10gでは、非同期I/OとDirect I/Oを同時に使用することができます。上記の手順でOSの設定をおこない、Oracleの初期化パラメータを次のように設定します。

DISK_ASYNC_IO true (デフォルト)
FILESYSTEMIO_OPTIONS setall (デフォルト:none)

2つの機能を同時に利用することで、データの読み込み、書込みのパフォーマンスが向上し、余分なオーバーヘッドを回避できます。図1からわかるように、非同期I/OとDirect I/Oを同時に使用することで、よりI/Oパフォーマンスの効果が上がります。

図1 100,000行insert-commit作業時の非同期I/OとDirect I/Oのパフォーマンス比較
図1
図2 「FILESYSTEMIO_OPTIONS = setall」のCPU使用率とプロセスステータス
図2
図3 「FILESYSTEMIO_OPTIONS = none」のCPU使用率とプロセスステータス
図3

図2図3の結果からもわかるように、今回はそれぞれご紹介した非同期I/OとDirect I/Oですが、さらに同時に使用することで実行待ちプロセスが減少し、CPU性能を効率的に向上させることができるのです。

No comments: