アカウントOracleアカウントサインアウトOracleアカウントアカウントを管理して、パーソナライズされたコンテンツにアクセスできます。アカウントを作成クラウド・アカウントクラウド・ダッシュボードへのアクセス、ご注文の管理など、さまざまな操作を行えます。皆さんがご存知のとおり、現実のシステムは刻々とその状態を変えます。そのような現実のシステムの運用において本当に大事なのは、遅延している瞬間の状態を確認することです。30分間ずっと同じ状態(均一)のままというトラブルであれば、瞬間を確認する必要はないでしょう。現実のトラブルは「あるタイミングで」「たまに」「ある処理が」といった具合に不均一なケースが多いはずです。トラブルが起こったその瞬間の情報を押さえる必要があるのです。これらビューの概要は表1、表2を参照してください。V$SESSION_WAITの定義(抜粋)注1:セッションに関する情報が載っている動的パフォーマンスビュー。注2:セッションごとの現在の待機イベントが載っている動的パフォーマンスビュー。Oracleは遅延しているタイミングで自動的に情報をとってくれませんので、管理者が適切な間隔でこれらのビューを繰り返し検索し、ログに残しておく必要があります。そのためのスクリプトは、LIST1、LIST2のようになります(環境や目的に合わせて適宜変更してください)。V$SESSION_WAITを定期的に実行するスクリプトなお、V$SESSION_WAITやV$SESSIONはメモリ中の情報にアクセスするものであり、アイドルの情報さえ表示させなければ、参照しても負荷はほとんどありません(詳しくは後述)。V$SESSION_WAITとV$SESSIONを結合して一緒に情報を採ることも可能です。注意すべき点は、あくまで瞬間の情報を定期的に採っているため、瞬間と瞬間の間については分からないことです。連続する情報を取得するためには、後述するSTATSPACKかSQLトレースを使います。ログの取得方法にはいくつかコツがあります。それらを簡単に紹介します。タイムスタンプを適切に入れましょう。dualとV$SESSION_WAITビューの検索をセットにして実行します。vmstatなどでは、実行前に1回dateコマンドで時刻を記録しておきます。コマンドによっては初回のデータは無視しなければなりません。OSコマンドの一部は、初回のデータはOS起動時からの平均が表示されます。長い時間、同じファイルにデータを入れるのはやめましょう。見づらくなりますし、何らかのエラーで止まったときにデータのロスが大きくなります。時刻を自動的に表示してくれないコマンドに関しては、時刻の計算が難しくなります。OSやDB再起動時にも、自動的にログの取得を再スタートするようにしておきましょう。自動的にログは削除されるようにしておきましょう。土日や祝日を考えて約1週間程度は残し、それ以上は自動的に削除されるようにするのも一案です。筆者はdbms_job(Oracleのジョブスケジューリング機能)によるログの取得は使いません。理由は、使用することにより余計にプロセスが立ち上がってしまうことと、パフォーマンス情報が見にくくなってしまうことです。ページTOPに戻るそもそもDBの問題なのか次に、瞬間の情報がどう役立つのかを説明します。DBエンジニアの悩みの1つに、パフォーマンストラブルの発生場所がDBなのかDB以外なのか、その切り分けが難しいことがあると思います。システムのパフォーマンスが悪く、まず「DBが遅いのではないか」と言われた経験もあるのではないでしょうか。実際にはDBより手前で詰まっていることも多いものです。した切り分けを行なう際にも瞬間の情報が使えます。実行中のSQL文を見つけるスクリプトV$SESSIONビューには「STATUS」という列があり、その列は主に「ACTIVE」と「INACTIVE」という2つの値をとります。「ACTIVE」は“SQL文を実行中”という意味で、SQL文は受け取っていますが、まだ処理結果を返していない状態です。逆に言うと「INACTIVE」などのアイドル状態では、「DBにはSQL文が届いていない」と言えます(図1)。図2の状況において、エンドユーザーから見た時刻0:00:05から0:00:10までの間にシステムが遅延しているとします。注3:1つの処理が複数のSQL文で構成されていることも多いため、断定まではできません。情報をある程度繰り返し取得しても同じであれば、断言して構わないと思います。LIST1のスクリプトを実行した結果の例(LIST3)を見てください。SQL文が実行されていれば「ACTIVE」と表示されます。LIST3のように、定期的に検索してもずっと表示されているセッションとSQL文は、DBでの処理に時間がかかっている可能性が高いと言えます。分析の際にはV$SESSIONビューを検索しているセッション自身も表示されることに気を付けてください。問題のあるSQL文を特定するためのスクリプト処理に時間がかかっているSQL文があることが分かれば、それがどれか知りたくなると思います。それには、LIST4のスクリプトを用います。ハッシュ値とアドレスからSQL文を表示するスクリプトさらに、そのSQL文がどのくらいリソースやI/Oや時間を使用したのかは、LIST5のスクリプトで分かります。Oracleの内部構造の関係で、長い時間実行されなかったSQL文の情報は消えてしまいます。ハッシュ値とアドレスから該当SQL文の実行時間、CPU時間、読み込みブロック数を表示するスクリプト注意:V$SQLやV$SQLAREAは頻繁に検索してはいけません。理由は処理が重いからです。V$SESSIONなどと結合させて頻繁に検索をしているケースがありますが、負荷をかけ過ぎて、ミイラ取りがミイラになってしまうことがあります。poolと呼ばれるメモリにキャッシュします。このキャッシュは一定のサイズのため、SQL文が長く使われずにいたり、頻繁にいろいろなSQL文が実行されるとSQL文がキャッシュ落ちしてしまいます。キャッシュ落ちしたSQL文の情報はV$SQLやV$SQLAREAに表示されません。ページTOPに戻る遅延している瞬間のOracleの状態は?ここまでの説明で、SQL文がDBに届いていないのか、届いていて処理に長く時間がかかっているかをおおまかに確認する方法まで分かりました。DBにSQL文が届いていることが分かれば、次は遅延している瞬間のDBの状態を知りたくなります。そのときに有効なのが、V$SESSION_WAITビューです。待たされ続けるセッションに注目LIST6は、V$SESSION_WAITビューを参照するLIST2のスクリプトを実行した結果の例です。enqueue待ちになっていて、長く待たされていることが分かります。注5:SECONDS_IN_WAIT列の単位は秒です。トランザクションが少ないシステムでは、まれに情報の反映が最大3秒遅れることがあります。R2では待機イベントが終了していないのに、数秒経つとSECONDS_IN_WAIT列の値が0に戻るという動作をするため、同じ待機イベントで待っているか(引数も同じか)で判定してください。分析方法ですが、同じ待機イベントで長時間待っている、もしくはずっと同じ待機イベントが繰り返し出ているセッションがあれば、それに着目します。V$SESSION_WAITビューの意味を図示すると、図3および図4のようになります。「6:59:30から6:59:40まで遅延した」とエンドユーザーから言われた場合、V$SESSION_WAITビューの情報から、サーバープロセス1の「enqueue」が原因の可能性があると言えます。待機イベントにはいろいろありますが、それらの意味はOracleのリファレンスマニュアルで確認できます。そこで待機イベントの引数を見ると、イベントの詳細情報がある程度分かります。注意事項として、STATE列が「WAITING」である行だけが現在の待機イベントを表わしていることに気を付けてください。WAITING以外の行は過去の待機イベントなので、無視します。見方を変えると、STATE列がWAITING以外の場合、Oracleとしてはサーバープロセスが処理中だと言えます。イベント名が表示されているから待たされていると考えずに、必ずSTATE列を確認するようにしてください。LIST2のスクリプトでは、WHERE句に「STATE='WAITING'」を指定して、実際に待機しているイベントだけを表示させています。セッション数が多いとV$SESSION_WAITビューの参照も負荷(特に端末への表示やファイルへの書き出し)が高くなるので、WHERE句を使って表示する情報を適宜絞ってください。事実、マルチCPU環境ではありますが、筆者が1000セッション以上で1秒ごとに参照したときでも、大きな負荷はかかりませんでした(負荷は1%未満)。この点は、V$SESSIONも同様です。message」に加え、バックグラウンドプロセスのアイドルイベントも表示対象から外しています。ミイラ取りがミイラになってはいけません。そのため、本特集ではできる限り注意事項や指標となる負荷情報を書きました。Oracleの全バージョンで確認したわけではありませんが、V$SQLやV$SQLAREAは適切にWHERE句を指定していても、入っている行数(SQL文の数)に比例して重くなることがあります。そのため、SQL文が少ない(数百SQL文程度の)システムか、業務が流れていない時間帯もしくは事前にパフォーマンスを確かめた上で、これらのビューにアクセスすることをお勧めします。これらのビューにアクセスするSQL文を定期的に実行するように促している書籍や記事もありますが、利用のしかたには十分注意してください。V$SESSION_WAITで待ち行列も確認できる待ち行列の確認も、このV$SESSION_WAITビューからできます。Oracleがリクエストを受け付けて以降のどこかの処理で詰まっているのであれば、図5のように待ち行列になっているセッションが、待機状態としてV$SESSION_WAITビューに表示されます。待ち行列の確認方法また、Oracle内のボトルネックだけではなく、Oracleより先に原因がある待ち行列についても、一部読みとれることに注目してください。ディスクがボトルネックになっているとします。