sql >> データベース >  >> RDS >> Oracle

カーソル:ピンSはXで待機

    私のメインの本番RACデータベースでは、速度が低下している期間があり、システム全体での主要な待機イベントは「カーソル:ピンSがXで待機」です。イベントは行ったり来たりしますが、私は時々それを見ます。だから私はこれの底を取得する必要がありました。これはRACの問題ではないことに注意してください。このイベントは、単一インスタンスのデータベースでも簡単に確認できます。 Oracle RACデータベースの複数のインスタンスでこれが見られるのは、同じアプリケーションからの複数のセッションがインスタンス間で分散していて、すべて同じことを行っているため、すべて同じ問題が発生しているためです。

    まず、待機イベントとは何ですか? 「cursor:」待機はいずれも、SQL領域の共有プールのボトルネックです。ずっと前に、共有プールのこの部分はラッチによって保護されていました。しかし、共有プールの多くの領域の場合と同様に、Oracleは現在ミューテックスを使用しています。保護メカニズムの変更により、新しい待機イベントが発生しました。

    この特定の待機イベントの場合、共有ピンが必要なカーソルがありますが、別のセッションがその排他的ミューテックスを解放するのを待つ必要があります。カーソルを解析しようとしています。ただし、別のセッションが同じミューテックスを保持しているため、解析できません。

    このイベントを待機しているセッションには、主に3つの原因があります。

    • 高ハード解析
    • SQLステートメントの多数のバージョン
    • バグ

    残念ながら、この待機イベントに関連するバグがいくつかあります。私が見たもののほとんどは11.2.0.4または12.1.0.1で修正されているため、バージョンが遅れている場合は、最新のOracleバージョンの1つにアップグレードすることを検討してください。

    それでは、問題の原因を特定するために例を見ていきましょう。そのために、次のクエリを使用しました:

    select s.inst_id as inst,
           s.sid as blocked_sid, 
           s.username as blocked_user,
           sa.sql_id as blocked_sql_id,
           trunc(s.p2/4294967296) as blocking_sid,
           b.username as blocking_user,
           b.sql_id as blocking_sql_id
    from gv$session s
    join gv$sqlarea sa
      on sa.hash_value = s.p1
    join gv$session b
      on trunc(s.p2/4294967296)=b.sid
     and s.inst_id=b.inst_id
    join gv$sqlarea sa2
      on b.sql_id=sa2.sql_id
    where s.event='cursor: pin S wait on X';

    これを本番RACデータベースの1つで実行すると、次の出力が得られます。

    INST BLOCKED_SID BLOCKED_USER BLOCKED_SQL_ID BLOCKING_SID BLOCKING_USER BLOCKING_SQL_ID
    ---- ----------- ------------ -------------- ------------ ------------- ---------------
       4         723 USER12345    cn7m7t6y5h77g          1226 USER12345     cn7m7t6y5h77g 
       4         723 USER12345    cn7m7t6y5h77g          1226 USER12345     cn7m7t6y5h77g 
       4         723 USER12345    cn7m7t6y5h77g          1226 USER12345     cn7m7t6y5h77g 
       4         723 USER12345    cn7m7t6y5h77g          1226 USER12345     cn7m7t6y5h77g 
       4        1226 USER12345    cn7m7t6y5h77g          1796 USER12345     cn7m7t6y5h77g 
       4        1226 USER12345    cn7m7t6y5h77g          1796 USER12345     cn7m7t6y5h77g 
       4        1226 USER12345    cn7m7t6y5h77g          1796 USER12345     cn7m7t6y5h77g 
       4        1226 USER12345    cn7m7t6y5h77g          1796 USER12345     cn7m7t6y5h77g
    >

    最初に注意することは、ミューテックスはOracleRACデータベースのそのインスタンス内にのみ存在するということです。シングルインスタンスデータベースの場合、上記のクエリは引き続き機能します。 Oracle RACの場合、このクエリの出力には、問題が発生しているインスタンスが表示されます。

    上記の例では、セッション723がセッション1226によってブロックされています。セッション1226はセッション1796によってさらにブロックされています。3つのセッションすべてがSQL ID cn7m7t6y5h77gで同じクエリを発行していることに注意してください。 。

    SQL IDがわかったので、V $ SQLを簡単に照会して、問題に関係するSQLステートメントを判別できます。このクエリを使用して、より多くの情報を取得しました。

    select sql_id,loaded_versions,executions,loads,invalidations,parse_calls
    from gv$sql 
    where inst_id=4 and sql_id='cn7m7t6y5h77g';

    V$SQLのクエリからの出力は次のとおりです。

    SQL_ID        LOADED_VERSIONS EXECUTIONS LOADS      INVALIDATIONS PARSE_CALLS
    ------------- --------------- ---------- ---------- ------------- -----------
    cn7m7t6y5h77g               1        105        546           308        3513

    これで、このクエリのSQL領域にバージョンが1つしかないことがわかります。そのため、すぐに、潜在的な問題領域の1つを排除しました。今後のブログ投稿では、SQL領域に多数のバージョンがあるクエリについて説明します。しかし、それは今日の私たちの問題ではないので、先に進みます。

    上記から、非常に多くの解析呼び出しがあることは明らかです。クエリは105回しか実行されていませんが、3513回解析されています。うわぁ!無効化の場合の高い数値は、おそらくこれにも関係しています。

    この例では、問題が何であるかがわかりました。これはアプリケーションの問題です。アプリケーションがクエリを解析しすぎています。そこで、これを開発に送り返し、アプリケーションコードを掘り下げます。過剰解析の通常の理由を調べる必要があります。

    バージョンの数が少なく、過度の解析/無効化/ロードが問題ではなかった場合は、バグを疑ってOracleサポートにSRを提出します。


    1. 一般的なER図の間違い

    2. PostgreSQL:PostgreSQLですべてのテーブルのOWNERを同時に変更します

    3. pg gemのインストールに失敗すると、mkmf.rbはrubyのヘッダーファイルを見つけることができません(Mac OSX 10.6.5)

    4. より高速なデータベースのためのSQLVARCHARデータ型の推奨事項と禁止事項