3

これがシナリオです...

最新バージョンの ODAC (Oracle クライアント) を実行している内部 Web サイトがあります。データベース接続を開き、ストアド プロシージャまたはパッケージ化されたメソッドを実行してから、切断します。接続プーリングがオンになっており、現在、開発環境とテスト環境の両方でバージョン 11g を使用していますが、運用環境では 10gR2 を使用しています。これは本番環境で発生します。

数日前、あるプロセスで ORA-2020 エラーが発生し始めました。このプロセスは、当社の内部 Web サイトの Web ページから呼び出されます。ユーザーが日付を設定し、ボタンを押すだけで、Web サイトとは別の別のシステムでジョブが開始されます。ただし、呼び出し自体はデータベース リンクを使用して関数を実行します。

SQL を精査したところ、その 1 つのデータベース リンクのみが使用されていることがわかりました。これらのリンクはセッション単位であり、ユーザーはデフォルトの制限である 4 を超えていないため、ORA-2020 エラーが発生する可能性はあります。

デフォルトの制限である 4 を超えるように、多くのテストを実行しました。ODAC は、私が思い出す限り、接続ごとにコミットを実行します。4 つの DB リンクを実行してから、SQL を実行することはできないようです。エラーが発生した直後に 1 つの DB リンクがあります。このエラーを発生させる唯一の方法は、4 つの DB リンクを使用してクエリを実行し、次にデータベース リンクを含む関数または動的 SQL を実行することです。この問題は散発的であるため、その問題はありません。それは常に起こっているわけではありません。

質問

  1. 接続プールにより、最初のプロセスの実行後にユーザー B がユーザー A の接続を使用できるようになり、ユーザー B がより多くのデータベース リンクを使用して SQL ステートメントを実行すると、開いているリンクの数が増える可能性はありますか?
  2. これは、制限を 4 を超えて引き上げる必要があるシナリオですか? 数を増やすデメリットは?
  3. データベースから切断する前に、開いているデータベース リンクを明示的に閉じる必要がありますか? Oracleのドキュメントでは、自動的に発生するはずだと示唆しているようですが、「場合によっては」...そうではありません。
4

2 に答える 2

2

まず、簡単な解決策です。本番データベースでデフォルトのリンクの数が実際には4であることを再確認します。

select *
  from v$system_parameter
 where name = 'OPEN_LINKS'

あなたがそれを軽く降りるつもりはないと仮定すると:

接続プールにより、最初のプロセスの実行後にユーザーBがユーザーAの接続を使用できるようになり、ユーザーBがより多くのデータベースリンクを含むSQLステートメントを実行した場合、オープンリンク番号が追加される可能性はありますか?

あなたは、セッションを明示的に閉じると言います。これは、ドキュメントによると、そのセッションに関連付けられているすべてのリンクが閉じられることを意味するはずです。それ以外は、この点については完全に無知であると告白します。

これは、4を超えて制限を引き上げる必要があるシナリオですか?数を増やすことの欠点は何ですか?

私が考えることができる不利な点はありません。Tom Kyteは、かなり前のことですが、開いているデータベースリンクごとに500kのPGAメモリを使用することを提案しています。何も持っていない場合、これは明らかに問題を引き起こしますが、ほとんどの状況では問題ないはずです。

select * from my_massive_tableただし、意図しない結果が発生します。この数を100に増やしたと想像してください。誰かが継続的にリンクを開き、それらすべてまたは同様のものを介して大量のデータを引き出す何かをコーディングします。これを行う4つのセッションの代わりに、100があり、数百ギガバイトを同時に転送しようとしています。あなたのネットワークは緊張の下で死にます...

おそらくもっとありますが、あなたは絵を手に入れます。

データベースから切断する前に、開いているデータベースリンクを明示的に閉じる必要がありますか?Oracleのドキュメントは、それが自動的に発生することを示唆しているようですが、「時々」...そうではありません。

お気づきのように、最良の答えは「おそらくそうではない」ですが、これはあまり役に立ちません。セッションをどのように終了するかについては正確には言及していませんが、優雅に終了するのではなく、セッションを終了する場合は間違いなく終了します。

データベースリンクを使用すると、リモートサーバー上に子プロセスが生成されます。サーバーがこのプロセスを絶対的に担当しなくなったため、サーバーが孤立したり、親プロセスの終了時に閉じられなかったりする可能性のあるものが無数にあります。これが常に発生するわけではありませんが、発生する可能性があります。

私は2つのことをします。

  1. プロセスで例外が発生した場合は、次のクエリの結果を自分宛てに電子メールで送信してください。

    select * 
      from v$dblink
    

    少なくとも、セッションで開いているデータベースリンクを把握し、それらをトレースする方法を提供します。

  2. ドキュメントのアドバイスに従ってください。具体的には次のとおりです。

    「リンクを手動で閉じる場合があります。たとえば、次の場合にリンクを閉じます。

    • リンクによって確立されたネットワーク接続は、アプリケーションで使用されることはめったにありません。
    • ユーザーセッションを終了する必要があります。」

最初のものはあなたの状況にぴったり合っているようです。あなたのプロセスが時間に敏感でない限り、そうではないようですが、あなたは何を失う必要がありますか?構文は次のとおりです。

alter session close database link <linkname>
于 2012-04-04T20:31:23.780 に答える
1

最終的にリンク数を増やしましたが、根本的な原因は見つかりませんでした。

于 2012-10-24T15:03:16.767 に答える