この章では、パフォーマンスとスケーラビリティをデータベースおよびデータベース・アプリケーションに組み込む設計技術について説明します。
内容は次のとおりです。
内容は次のとおりです。
ここでは、データ・モデリングの重要な概念について簡単に説明します。この点については各種の参考書籍があるため、詳細やガイドについてはそれらを参照してください。
次の基本手順に従って、最も頻繁に実行する重要な問合せのパフォーマンスを最適化するためのデータ・モデルを設計します。
アプリケーションのデータ要件を次の基本手順に従って分析します。
データを収集します。
インタビューを通じてビジネスの内容、アプリケーションの性質、情報の使用者と使用方法、エンドユーザーの要求を把握します。人事フォーム、請求フォーム、注文フォームなどのビジネス・ドキュメントを収集して、ビジネスにおける情報の使用方法を学びます。
収集したデータを分析します。
このボトムアップ・プロセスには、データの正規化、エンティティ関連のモデリングおよびトランザクション分析が含まれます。
データの機能分析を行います。
このトップダウン・プロセスの結果はデータ・フロー・ダイアグラムで、メインのプロセス・ブロックと、各ブロックでの存続期間中のデータの出入りが示されます。
データベース設計を次の基本手順に従って作成します。
論理設計を作成します。
論理設計を物理設計に変換します。
内容は次のとおりです。
参照: パフォーマンスを考慮した設計と開発の詳細は、『Oracle Databaseパフォーマンス・チューニング・ガイド』を参照してください |
論理設計はデータベースのグラフィカルな表現です。論理設計は、アプリケーションのデータベース・オブジェクトとトランザクション・アクティビティ間の両方の関係をモデル化します。効果的な論理設計では、データの所有、アクセス、更新を必要とするユーザーごとに要件を考慮します。
データベース・オブジェクト間の関係をモデル化する手順:
データ要件をデータ項目(列)に変換します。
関連列を表内にグループ化します。
列と表の間の関係をマッピングして、各表に対する主キーおよび外部キー属性を決定します。
冗長性と依存性を最小限にするために表を正規化します。
トランザクション・アクティビティをモデル化する手順:
代表的なトランザクションと、ユーザーにとって最重要と想定されるトランザクションを理解します。
論理モデルを通じてトランザクション・パスを追跡します。
SQLでトランザクションをプロトタイプ化し、データベースのサイズを示すボリューム表を開発します。
どのユーザーがどの順序でどの表にアクセスするか、そしてどのトランザクションがデータを読み取り、どのトランザクションがデータを書き込むかを決定します。
アプリケーションがデータの読取りと書込みのどちらを主に行うかを決定します。
データベース・アプリケーションを次の基本手順に従って実装します。
アプリケーションをテスト環境で実装します。
本番環境と可能なかぎり一致するテスト環境で、物理データベース設計を実装するスクリプトを作成します。データを物理スキーマ内にロードします。アプリケーションを開発するためのプログラミング言語を選択し、ユーザー・インタフェースを開発して、トランザクションの作成とテストなどを行います。
アプリケーションが仕様に即して稼働するようにします。
すべてのコンポーネントが機能していること、アプリケーションが完全に動作すること、そしてアプリケーションで使用されるデータベース機能が適切に構成されていることを確認します。パフォーマンスのテスト用ツールの詳細は、2.2項を参照してください。
アプリケーションでベンチマーク・テストを実行します。
ベンチマーク・テストでは、データおよびユーザーの追加など、リアルタイムの操作をシミュレーションすることで様々なワークロード(ピーク・アクティビティを含む)下で予定どおりにアプリケーションが稼働するかどうかを確認できます。アプリケーションが幅広く順応することを確認します。アプリケーションのベンチマーク操作の詳細は、2.1.3項を参照してください。
アプリケーションがベンチマークを下回る場合、最初はワークロードがない状態から徐々にワークロードを増やすことで、最適に動作するようにSQL文を調整します。
参照:
|
アプリケーションを本番環境で実装します。
参照: 新しいアプリケーションのデプロイの詳細は、『Oracle Databaseパフォーマンス・チューニング・ガイド』を参照してください |
データベース、データベース・アプリケーション、オペレーティング・システムのメンテナンスは、データベース管理者、アプリケーション開発者およびシステム管理者がそれぞれ行う継続的なタスクです。ビジネスがメンテナンスに割り当てるリソースは、データベースとデータベース・アプリケーションの重要性、成長に関する潜在的な能力、対応が必要なユーザー数などによって異なります。
メンテナンスの担当者は、システムを定期的に監視し、メンテナンス期間をスケジューリングして、予定されているメンテナンス期間をユーザーに通知する必要があります。メンテナンス期間に停止時間が必要な場合は、データベース・アクティビティがないか少ない時間帯にスケジューリングします。
アプリケーションのメンテナンスには、不具合の修正、パッチの適用、アップグレードのリリースが含まれます。メンテナンス作業は、本番システムに実装する前に、テスト環境で事前にテストして問題を捕捉して解決します。
次のようなパフォーマンス目標(メトリック)を設定して、アプリケーション開発プロジェクトを開始します。
予想されるアプリケーション・ユーザー数
予想されるピーク・ロード時の1秒当たりのトランザクション数
予想されるピーク・ロード時の問合せレスポンス時間
予想される単位時間(1日、1か月、1年など)当たりの表ごとのレコード数
これらのメトリックを使用してベンチマーク・テストを作成します。
ベンチマークは、アプリケーションの性能の局面を測定するテストです。ベンチマークの結果によって、アプリケーション設計が検証されるか、アプリケーションの本番稼働前に解決できる問題が発見されます。
通常は、他の要因による干渉を最小限にするために、分離した単一のユーザー・システムに対して最初にベンチマークを実行します。ベンチマークの結果は、アプリケーションのパフォーマンス・ベースラインになります。意味のあるベンチマーク結果を得るには、アプリケーションを実行する予定の環境でアプリケーションをテストする必要があります。
最も重要なトランザクションのパフォーマンスを測定し、パフォーマンス上の問題に対する複数のソリューションを比較して、パフォーマンスに影響し得る設計上の問題の解決を手助けする小さいベンチマークを作成できます。
ピークのユーザー負荷時やピークのトランザクション負荷時、あるいはその両方でアプリケーションのパフォーマンスを測定するには、それより大きい複雑なベンチマークを開発する必要があります。このようなベンチマークは、ユーザーまたはトランザクションの負荷が徐々に増加する場合は特に重要です。このベンチマークの予算を確保し、計画する必要があります。
アプリケーションの本番環境での稼働後、本番環境でベンチマークを定期的に実行してその結果をデータベース表に保存します。各ベンチマークの実行後、パフォーマンスの低下を許容できないトランザクションの旧レコードと新レコードを比較します。この方式を使用することで、問題の発生時にそれを隔離できます。ユーザーがパフォーマンスに関する不満を述べるまで待っていると、問題の発生時点を判断できなくなる可能性があります。
参照: アプリケーションのベンチマークの詳細は、『Oracle Databaseパフォーマンス・チューニング・ガイド』を参照してください |
内容は次のとおりです。
アプリケーションに関する実行時パフォーマンス情報を得られるツールがいくつかあります。
参照: データベースのチューニング用のツールに関する詳細は、『Oracle Database Testingガイド』を参照してください |
SQLトレース機能(2.2.2項で説明)およびOracle TraceとともにDBMS_APPLICATION_INFO
パッケージを使用して、実行しているモジュールまたはトランザクションの名前をデータベースに記録します。システム管理者およびパフォーマンス・チューニング担当者はこの記録された情報を使用して、個々のモジュールのパフォーマンスをデバッグ目的のために追跡できます。システム管理者は、モジュール別のリソース使用率をこの情報から追跡することもできます。
アプリケーションをデータベースに登録すると、その名前およびアクションがV$SESSION
およびV$SQLAREA
のビューに記録されます。
DBMS_APPLICATION_INFO
パッケージは、V$SESSION
ビューで次の列を設定するサブプログラムを提供します。
MODULE
(アプリケーションまたはパッケージの名前)
ACTION
(トランザクションまたはパッケージされたサブプログラムの名前)
CLIENT_INFO
(現在のセッションの初期バインド変数値などの、クライアント・アプリケーションに関する追加情報)
DBMS_APPLICATION_INFO
パッケージは、現在のセッションの先行するV$SESSION
列から情報を返すサブプログラムも提供します。
DBMS_APPLICATION_INFO
パッケージは、結果の表示に数秒以上かかるコマンド(索引の作成や多数の行の更新など)の進行状況の追跡にも使用できます。DBMS_APPLICATION_INFO
パッケージは、コマンドに関する情報をV$SESSION_LONGOPS
ビューに保存するサブプログラムを提供します。V$SESSION_LONGOPS
ビューには、コマンドの開始時刻、処理の進んだ段階、完了までの推定時間などが表示されます。
参照:
|
アプリケーションで実行されるすべてのSQL文とPL/SQLブロックを追跡するには、SQLのトレース機能であるSQL_TRACE
を使用します。単一の文またはモジュールに対してSQLトレース機能を有効にし、文またはモジュールの実行後に無効にすると、その文またはモジュールのみのトレース情報を取得できます。
最適な結果を得るには、SQLトレース機能をTKPROF
およびEXPLAIN
PLAN
文とともに使用します。SQLトレース機能は、個々のSQL文に関するパフォーマンス情報を提供します。TKPROF
はトレース・ファイルの内容を読取り可能なファイルにフォーマットします。EXPLAIN
PLAN
文は、オプティマイザによって選択された実行計画を表示し、現在のセッションで実行された場合には指定したSQL文の実行計画を表示します(詳細は2.2.3項を参照)。
トレースする内容と、本番稼働前のアプリケーションのパフォーマンス状況がわかるように、SQLトレース機能はアプリケーションの設計時に使用します。本番環境でパフォーマンス上の問題が大きくなるまで待つと、アプリケーション構造が原因でSQLトレース機能を使用するのがほとんど不可能になる可能性があります。
参照: SQL_TRACE およびTKPROF の詳細は、Oracle Database SQLチューニング・ガイドを参照してください |
SQL文を実行すると、オプティマイザは可能な実行計画をいくつか生成して、各計画のコストを計算し、最もコストの低い計画を使用します。
計画のコストは、SQL文がアクセスする表、索引およびパーティションのデータ分散および記憶特性などの統計に基づいて計算されます。アクセス・パスや結合順序のコストは、I/O、CPU、メモリーなどのコンピュータ・リソースの使用見積りに基づいています。
EXPLAIN
PLAN
FOR
statement
文をstatement
の実行前に使用すると、EXPLAIN
PLAN
文はstatement
の実行計画を計画表に格納します。計画表を問い合せると、オプティマイザで選択された実行計画を調べることができます。
計画表は実行計画を行ソース・ツリーとして表し、これはSQL文を実行するためにOracle Databaseで使用されるステップを示します。行ソース・ツリーには、文が表を参照する順序、結合操作に影響される表の結合メソッドの他に、フィルタ、ソート、集計などのデータ操作が示されます。また計画表には、最適化に関する情報(各操作のコストやカーディナリティなど)、パーティショニング情報(アクセスされるパーティションのセットなど)、およびパラレル実行情報(結合入力の分散メソッドなど)が含まれます。この情報からは、オプティマイザが実行計画を選択した経緯と理由について、重要な洞察を得ることができます。
データについてオプティマイザで認識されていない情報がある場合、オプティマイザにヒントを提供すると、実行計画が変更されるときがあります。テストによってそのヒントがパフォーマンスを向上させることが確認された場合は、コードでそのヒントを維持します。
注意: データベースの状態の変化や以降のリリースにおける問合せパフォーマンスの向上によって、ヒントがパフォーマンスに及ぼす影響が大きく変化する場合があるため、ヒントが含まれるコードは定期的にテストする必要があります。 |
EXPLAIN PLAN
文は、EXPLAINされたSQL文をOracle Databaseがどのように実行するかのみを示します。実行環境またはEXPLAIN PLAN環境が変化する場合、オプティマイザは別の実行計画を使用する可能性があります。したがって、SQL計画管理を使用して、SQL計画ベースライン(許容されたSQL文の一連の実行計画)を作成することをお薦めします。
最初に、EXPLAIN PLAN
文を使用して文の実行計画を参照します。次に、実行計画をテストし、文の実際のリソース使用量を考慮しながらその適性を検証します。最後に、計画が最適ならば、SQL計画管理を使用します。
参照:
|
Oracle Databaseには、データベースの管理とチューニングが可能なアドバイザおよび強力なツールが用意されています。
内容は次のとおりです。
自動データベース診断モニター(ADDM)は、自動ワークロード・リポジトリ(AWR)で取得されたデータの分析を行うアドバイザです。ADDMとAWRはOracle Diagnostic Packの一部です。
ADDMはデータベース・パフォーマンス上の問題が存在する可能性がある場所と、実際に存在する場所を判断し、その修正事項を推奨します。
ADDMは各AWRスナップショットの後に分析を実行し、結果をデータベースに保存します。デフォルトでは、AWRスナップショットの間隔は1時間で、ADDM結果の保存期間は8日間です。
Oracle Enterprise Manager Cloud Control (Cloud Control)ではADDM結果が「データベース」ホームページに表示されます。このAWRスナップショット・データではADDM結果を確認できますが、ADDMで提供される分析と推奨事項はありません。(AWRスナップショット・データは、データベース管理者がパフォーマンス分析のために使用したStatspackデータと同様です。)
参照: ADDMの構成、ADDM分析の確認、ADDM結果の解釈、ADDM推奨事項の実装、およびEnterprise Managerによるスナップショット統計の表示の詳細は、『Oracle Database 2日でパフォーマンス・チューニング・ガイド』を参照してください |
Oracle Enterprise Manager Cloud Control (Cloud Control)を使用すると、「パフォーマンス」ページからリアルタイムのデータベース・パフォーマンスを監視できます。「パフォーマンス」ページから、パフォーマンス上の問題を特定するページにアクセスし、次のADDM分析を待たずにその問題を解決することができます。
参照: データベースのパフォーマンスのリアルタイムの監視の詳細は、『Oracle Database 2日でパフォーマンス・チューニング・ガイド』を参照してください |
Oracle Enterprise Manager Cloud Control (Cloud Control)の「データベース」ホームページには、データベースによって生成されたパフォーマンス関連のアラートが表示されます。これらのアラートによって示された問題を解決すると、データベース・パフォーマンスが向上します。Oracle Databaseのデフォルトでは、表領域の使用状況、古すぎるスナップショット、リカバリ領域の空き容量低下、再開可能なセッションの一時停止などについてアラートが有効です。メトリックとしきい値の表示、メトリックしきい値の設定、アラートへの対応、アラートのクリア、アラートのダイレクト電子メール通知などを実行できます。このような組込みのアラート・インフラストラクチャを使用すれば、パフォーマンス関連の特殊なアラートについて通知を受信できます。
参照:
|
Oracle Databaseには、データベース・パフォーマンスの向上に効果を発揮するSQLアドバイザとメモリー・アドバイザが用意されています。
SQLアドバイザには、SQLチューニング・アドバイザとSQLアクセス・アドバイザがあり、どちらもOracle Database Tuning Packの一部です。
SQLチューニング・アドバイザは、1つ以上のSQL文を入力として受け取り、特定のチューニング推奨を返します。各推奨には論理および予測されるメリットが含まれます。推奨事項は、オブジェクト統計、新しい索引の作成、SQL文の再構成、およびSQLプロファイルの作成に基づいています。
SQLアクセス・アドバイザを使用すると、指定したSQLワークロードに対して一連のマテリアライズド・ビュー、ビュー・ログ、索引およびパーティションが推奨されるため、SQL問合せのデータ・アクセス・パスを最適化できます。
メモリー・アドバイザには、メモリー・アドバイザ、SGAアドバイザ、共有プール・アドバイザ、バッファ・キャッシュ・アドバイザおよびPGAアドバイザがあります。メモリー・アドバイザは、合計メモリーのターゲット設定、SGAおよびPGAターゲット設定、およびSGAコンポーネントのサイズ設定の分析結果をグラフィカルに表示します。この分析結果は、データベース・パフォーマンスのチューニングや可能性のある状況の計画に使用できます。
参照:
|
インスツルメンテーションを使用することは、アプリケーションを通じてデバッグ・コードを追加することです。有効な場合、このコードは、問題の特定に役立つ情報が含まれるトレース・ファイルを生成します。トレース・ファイルは、問題のある層の特定に役立つため、多層アプリケーションをデバッグする際に特に有効です。
アプリケーションのパフォーマンスをテストする際は、次のガイドラインに従います。
自動データベース診断モニター(ADDM)とSQLチューニング・アドバイザを使用した設計の検証。
ADDMはデータベース・パフォーマンス上の問題が存在する可能性がある場所を判断し、修正事項を推奨します。たとえば、ADDMが負荷の高いSQL文を発見した場合は、SQLチューニング・アドバイザを使用してその文を分析し、チューニングの推奨を提供できます。
ADDMおよびSQLチューニング・アドバイザの詳細は、それぞれ2.3.1項および2.3.4項を参照してください。
参照: SQLチューニング・アドバイザを使用したSQL文のチューニングの詳細は、『Oracle Database 2日でパフォーマンス・チューニング・ガイド』を参照してください |
現実的なデータ量とデータ配分によるテスト。
テスト用データベースには、本番システムと同様のデータを入れておく必要があります。表は完全に移入され、本番システムで使用される表間のデータ量やカーディナリティを表すものである必要があります。本番と同様の索引をすべて作成し、スキーマ統計を正しく入力する必要があります。
本番環境で使用されるオプティマイザ・モードによるテスト。
Oracle Databaseの研究開発の取組みは問合せオプティマイザに重点が置かれているため、テスト環境および本番環境の両方で問合せオプティマイザを使用することをお薦めします。
シングル・ユーザーのパフォーマンスの最初のテスト。
アイドル状態または使用率の低いデータベースで、シングル・ユーザーのテストから開始します。シングル・ユーザーのパフォーマンスが理想的な条件下で許容範囲に達しない場合、実際の条件下で複数のユーザーが許容可能なパフォーマンスを得ることはできません。
各SQL文の実行計画の取得。
オプティマイザが最適な実行計画を使用しているか、および各SQL文の相対コストがCPU時間と物理I/O数の観点から把握されているかを検証します。最もチューニングを活用する、頻繁に使用されるトランザクションを識別します。
複数のユーザーでのテスト。
ユーザーのワークロードやプロファイルがまだ完全に定量化されていない可能性があるため、このテストを正確に実行するのは困難です。しかし、複数ユーザー環境でDMLトランザクションをテストして、ロックの競合やシリアライズの問題がないことを確認する必要があります。
可能なかぎり本番システムに近いハードウェア構成でのテスト。
実際的なシステムでのテストは、ネットワーク待機時間、I/Oサブシステム帯域幅およびプロセッサのタイプと速度についてテストする場合に特に重要です。非現実的なシステムでのテストでは、潜在的なパフォーマンスの問題を見落とす可能性があります。
安定した状態でのパフォーマンスの測定。
各ベンチマークの実行には開始フェーズが必要です。このフェーズでは、ユーザーがデータベースに接続し、アプリケーションを使用して開始します。このフェーズによって、安定した状態に達する前に、頻繁にキャッシュされるデータをキャッシュに初期化し、1回のみ実行する操作(解析など)を完了しておくことができます。同様に、各ベンチマークの実行終了時には終了フェーズが必要です。このフェーズでは、リソースをシステムから解放し、ユーザーはアプリケーションを終了してデータベースから接続を切断します。
参照:
|
SQL文またはPL/SQLブロックにおけるバインド変数プレースホルダは、実行時にデータを提供する場所を示します。
たとえば、次の文で作成された表にアプリケーションからデータを挿入する場合を考えます。
CREATE TABLE test (x VARCHAR2(30), y VARCHAR2(30));
データは実行時まで未知であるため、動的なSQLを使用する必要があります。
次の文は1つの行をtest
表内に挿入し、x列とy列の文字列リテラルを結合します。
INSERT INTO test (x,y) VALUES ( ''' || REPLACE (x, '''', '''''') || ''', ''' || REPLACE (y, '''', '''''') || ''');
次の文は、x列およびy列のバインド変数:x
および:y
を使用して、1つの行をtest
表内に挿入します。
INSERT INTO test (x,y) VALUES (:x, :y);
コーディングがより容易なのは、バインド変数プレースホルダを使用する文です。
次に、前述したそれぞれの方法を使用して表test
に1,000行を挿入する、動的な一括ロード操作を想定します。
文字列リテラルを結合する方法は1,000のINSERT
文を使用し、それぞれはハード解析、修飾、セキュリティ・チェック、最適化およびコンパイルが行われる必要があります。それぞれの文はハード解析されるため、ラッチの数も大幅に増えます。ラッチは相互排除ロック・メカニズム、つまりシリアライズ・デバイスで、同時実行が禁止されています。
バインド変数プレースホルダを使用する方法は、1つのINSERT
文のみを使用します。文はソフト解析、修飾、セキュリティ・チェック、最適化およびコンパイルが行われてから共有プールにキャッシュされます。コンパイルされた文は共有プールから、1,000個の挿入のそれぞれに使用されます。この文キャッシュはバインド変数を使用する大きな利点です。
バインド変数プレースホルダを使用するアプリケーションは、文字列結合を使用するアプリケーションよりもスケーラブルで、サポートするユーザー数は増加し、必要なリソースは減少し、実行速度は向上します。そして、SQLインジェクション攻撃を受ける可能性も減少します。SQL文で文字列結合が使用されていると、エンド・ユーザーがその文を改変し、なんらかの不正行為にアプリケーションを利用することが可能になります。
入力変数用のバインド変数プレースホルダは、DELETE
文、INSERT
文、SELECT
文およびUPDATE
文と、式またはリテラルが使用可能なPL/SQLブロック内の任意の位置で使用できます。PL/SQLでは、出力変数にもバインド変数プレースホルダを使用できます。バインドは、問合せ以外の操作では入力変数と出力変数の両方に使用されます。
参照:
|
内容は次のとおりです。
C、C++、Java (JDBC-OCI)、PHP、Python、RubyおよびPerlを含むOCIライブラリに基づいて構築されたOracle Databaseドライバおよびアダプタを使用するアプリケーションでは、クライアント結果キャッシュを使用することで、繰返しの問合せレスポンス時間を改善できます。
クライアント結果キャッシュにより、クライアント側でのSQL問合せ(SELECT
文)結果セットのクライアント・メモリーへのキャッシュが可能になります。クライアント・プロセスから結果を取り出す処理は、データベースのコールおよび問合せの再実行よりも高速で行われるため、頻繁な問合せの実行では、結果がキャッシュされている場合パフォーマンスが大幅に向上します。クライアント結果キャッシュは、問合せの処理で使用されていたサーバーCPU時間も短縮するため、サーバーのスケーラビリティが向上します。
スキーマ、SQLテキスト、バインド変数、セッション設定が類似している場合には、複数のセッションのOCI文が、OCIプロセス・メモリーにキャッシュされた同じ結果セットに一致することもあります。そうでない場合には、問合せの実行はサーバーに送られます。
クライアント結果キャッシュはアプリケーションに対して透過的であり、結果セット・データのキャッシュは、結果セット・データに影響するセッションまたはデータベースの変更内容と整合性が保たれます。
クライアント結果キャッシュを使用するアプリケーションでは、キャッシュ・ヒットがある問合せのパフォーマンスが向上します。このようなアプリケーションは、クライアントまたは中間層でキャッシュされた同じ結果セットを使用します。
クライアント結果キャッシュは、OCIセッション・プール、OCI接続プール、DRCP、およびOCI透過的アプリケーション・フェイルオーバー(TAF)などのOCI機能と連携します。
クライアント結果キャッシュを使用する場合、アプリケーション・レベルでもOCI文キャッシュまたはキャッシュ文を有効化する必要があります。
参照:
|
クライアント結果キャッシュの利点は次のとおりです。
クライアント結果キャッシュはクライアント上にあるため、キャッシュ・ヒットが起こると、フェッチ(OCIStmtFetch2()
)と実行(OCIStmtExecute()
)の呼出しがローカルで処理され、サーバーのラウンド・トリップは不要になります。サーバーのラウンド・トリップが不要になることで、サーバー・リソース(サーバーCPUやサーバーI/Oなど)の使用量が減少し、パフォーマンスが大幅に向上します。
クライアント結果キャッシュは透過的で一貫性があります。
クライアント結果キャッシュはあらゆるプロセスに使用可能なため、複数のクライアント・セッションで一致するキャッシュ内の結果セットを同時に使用できます。
クライアント結果キャッシュにより、各OCIアプリケーションが独自のカスタム結果キャッシュを持つ必要性が最小限に抑えられます。
クライアント結果キャッシュは次の局面を透過的に管理します。
複数のスレッド、複数の文、複数のセッションによる同時アクセス
データベースの変更による影響を受けている、キャッシュされた結果セットの無効化
キャッシュされた結果セットのリフレッシュ
キャッシュ・メモリー管理
クライアント結果キャッシュは、JDBC OCI、ODP.Net、OCCI、Pro*C/C++、Pro*COBOLおよびODBCなどの、OCIライブラリを使用するアプリケーションおよびドライバで自動的に使用可能になります。
クライアント結果キャッシュでは、サーバー・メモリーよりコストがかからないOCIクライアント・メモリーが使用されます。
クライアントのローカル・キャッシュでは、そのクライアントにより実行される問合せについて参照の局所性が向上します。
参照: 『Oracle Call Interfaceプログラマーズ・ガイド』のOCIStmtExecute() とOCIStmtFetch2() を参照してください |
クライアント結果キャッシュは、次の3つのレベル(優先度が降順で示されています)で有効化または無効化できます。
問合せ
特定の問合せの場合、SQLヒントでクライアント結果キャッシュを有効化または無効化できます(詳細は2.7.3.1項を参照)。SQLヒントを追加または変更するには、アプリケーションを変更する必要があります。
表
特定の表におけるすべての問合せの場合、アプリケーションを変更せずに、表注釈でクライアント結果キャッシュを有効化または無効化できます(詳細は2.7.3.2項を参照)。
セッション
データベース・セッション内のすべての問合せの場合、アプリケーションを変更せずに、セッション・パラメータでクライアント結果キャッシュを有効化または無効化できます(詳細は2.7.3.3項を参照)。
上位レベルの設定は下位レベルの設定より優先されます。例は、第2.7.3.6項を参照してください。
クライアント結果キャッシュは、読取り専用の表と、ほとんど読み取られない表(めったに更新されない表)での問合せに対してのみ、有効化することをお薦めします。つまり、次の場合にクライアント結果キャッシュを有効化します。
読取り専用の表と、ほとんど読み取られない表の問合せに対する問合せレベルのみ
読取り専用の表と、ほとんど読み取られない表に対する表レベルのみ
読取り専用の表、またはほとんど読み取られない表のみを問い合せるアプリケーションを実行中のセッション・レベルのみ
結果セットが大きい、またはバインド値のセット数が多い問合せに対してクライアント結果キャッシュを有効にすると、大量のクライアント結果キャッシュ・メモリーが使用されることがあります。バインド値の各セットでは、(同じSQLテキストに対して)異なるキャッシュ結果セットが作成されます。
クライアントの結果キャッシュが問合せに対して有効な場合、クライアント、サーバー、またはその両方で結果セットをキャッシュできます。クライアント結果キャッシュは、サーバー結果キャッシュ(デフォルトで有効)が無効化されている場合でも有効化できます。
OCIの場合、すべてのOCI文ハンドル・コールにおける最初のOCIStmtExecute()
のコールは、キャッシュ内に有効な結果セットがある場合でも、必ずサーバーに対して行われます。各文ハンドルをキャッシュ内の結果セットと照合できるようにするには、OCIStmtExecute()
をコールする必要があります。アプリケーションがOCI文ハンドルについて独自の文キャッシュを持つようにするか、またはOCI文キャッシュを使用し、OCIStmtPrepare2()
が一度実行されたOCI文ハンドルを戻せるようにすることをお薦めします。同一または異なるセッションからの複数のOCI文ハンドルは、キャッシュ内の同一の結果セットからデータを同時にフェッチできます。
OCIに対して結果セットをキャッシュする場合は、このキャッシュ結果セットを透過的に作成するOCIStmtExecute()
コールまたはOCIStmtFetch2()
コールで、ORA-01403(「データが見つかりません。」)が返されるまで行をフェッチする必要があります。ローカルにキャッシュされた結果セットと一致する後続のOCIStmtExecute()
またはOCIStmtFetch2()
のコールでは、最後までフェッチする必要はありません。
参照: 『Oracle Call Interfaceプログラマーズ・ガイド』のOCIStmtExecute() 、OCIStmtPrepare2() 、OCIStmtFetch2() を参照してください |
内容は次のとおりです。
SQLヒントRESULT_CACHE
またはNO_RESULT_CACHE
は単一の問合せに適用され、そのためにクライアント結果キャッシュが有効化または無効化されます。これらのヒントは、両方の表注釈とRESULT_CACHE_MODE
サーバー初期化パラメータよりも優先されます。
OCIの場合、OCIStmtPrepare()
コールとOCIStmtPrepare2()
コールに渡されるSQLテキストで、SQLヒントの/*+ result_cache */
または/*+ no_result_cache */
を設定する必要があります。
JDBC OCIの場合、問合せ文字列の一部として、SQLヒント/*+ result_cache */
または/*+ no_result_cache */
が問合せ(SELECT
文)に含まれます。
参照:
|
表注釈は特定の表におけるすべての問合せのクライアント結果キャッシュを有効化または無効化します。表注釈はRESULT_CACHE_MODE
サーバー初期化パラメータよりも優先されますが、SQLヒント/*+ RESULT_CACHE */
および/*+ NO_RESULT_CACHE */
は表注釈よりも優先されます。
RESULT_CACHE
句を使用して、CREATE
TABLE
またはALTER
TABLE
文のどちらかで表に注釈を付けます。クライアント結果キャッシュを有効にするには、RESULT_CACHE
(MODE
FORCE)
を指定します。無効にするには、RESULT_CACHE
(MODE
DEFAULT)
を使用します。
表2-1に、表注釈の結果キャッシュ・モードをまとめます。
表2-1 表注釈の結果キャッシュ・モード
モード | 説明 |
---|---|
|
デフォルト値です。結果キャッシュは表レベルでは決定されません。この値を使用して、表注釈を消去できます。 |
|
問合せのすべての表名がこの設定になっている場合は、問合せに |
参照:
|
セッション・パラメータRESULT_CACHE_MODE
は、データベース・セッションにおけるすべての問合せのクライアント結果キャッシュを有効化または無効化します。RESULT_CACHE_MODE
は、特定の表については表注釈より、特定の問合せについてはSQLヒントより優先度が下がります。
RESULT_CACHE_MODE
は、サーバー・パラメータ・ファイル(init.ora
)、あるいはALTER
SESSION
またはALTER
SYSTEM
文のいずれかに設定できます。クライアント結果キャッシュを有効にするにはRESULT_CACHE_MODE
をFORCE
に設定し、無効にするにはRESULT_CACHE_MODE
をMANUAL
に設定します。
参照: RESULT_CACHE_MODE の詳細は、『Oracle Databaseリファレンス』を参照してください |
表の有効な結果キャッシュ・モードは、表2-2に示すように、表注釈の結果キャッシュ・モードとRESULT_CACHE_MODE
セッション・パラメータ設定の双方によって異なります。
表2-2 有効な結果キャッシュ表モード
表注釈の結果キャッシュ・モード | RESULT_CACHE_MODE = MANUAL | RESULT_CACHE_MODE = FORCE |
---|---|---|
|
|
|
|
|
|
有効なモードがFORCE
の場合、問合せにNO_RESULT_CACHE
ヒントがないかぎり全問合せが結果キャッシュの対象となりますが、実際の結果キャッシュはクライアントおよびサーバーのキャッシュの内部制限、問合せの再利用可能性、およびクライアント結果キャッシュで使用可能な領域によって異なります。
有効な表結果キャッシュ・モードFORCE
は、双方が単なるリクエストであるという点で、SQLヒントRESULT_CACHE
に類似しています。
1つ以上の表の結果キャッシュ・モードを表示するには、*_TABLES
静的データ・ディクショナリ・ビューのRESULT_CACHE
列を参照してください。次に例を示します。
この問合せは表T
の結果キャッシュ・モードを表示します。
SELECT result_cache FROM all_tables WHERE table_name = T
この問合せは所有するすべてのリレーショナル表の結果キャッシュ・モードを表示します。
SELECT table_name, result_cache FROM user_tables
結果キャッシュ・モードがDEFAULT
の場合、表に注釈は付けられません。
結果キャッシュ・モードがFORCE
の場合、表はCREATE
TABLE
またはALTER
TABLE
文のRESULT_CACHE
(MODE
FORCE)
句で注釈が付けられます。
結果キャッシュ・モードがMANUAL
の場合、セッション・パラメータRESULT_CACHE_MODE
は、サーバー・パラメータ・ファイル(init.ora
)、あるいはALTER
SESSION
またはALTER
SYSTEM
文のいずれかでMANUAL
に設定されています。
参照: 静的データ・ディクショナリ・ビュー*_TABLES の詳細は、『Oracle Databaseリファレンス』を参照してください |
SQLヒントが表注釈およびRESULT_CACHE_MODE
セッション・パラメータより優先される場合の例を次に示します。
emp
表がALTER
TABLE
emp
RESULT_CACHE
(MODE
FORCE
)として注釈され、セッション・パラメータがデフォルト値のMANUAL
である場合は、emp
に対する問合せは結果キャッシュの対象となります。
ただし、問合せSELECT
/*+ no_result_cache */
empno
FROM
emp
の結果はキャッシュされません。これは、SQLヒントが表注釈およびセッション・パラメータより優先されているためです。
emp
表が注釈されていないか、ALTER
TABLE
emp
RESULT_CACHE
(MODE
DEFAULT
)として注釈され、セッション・パラメータがデフォルト値のMANUAL
である場合は、emp
に対する問合せは結果キャッシュされません。
ただし、問合せSELECT
/*+ result_cache */
*
FROM
emp
の結果はキャッシュの対象となります。これは、SQLヒントが表注釈およびセッション・パラメータより優先されているためです。
セッション・パラメータRESULT_CACHE_MODE
がFORCE
に設定され、それより優先される表注釈もSQLヒントもない場合は、すべての表に対するすべての問合せが問合せキャッシュの対象となります。
次の問合せの結果は、(問合せにRESULT_CACHE
ヒントが含まれる場合でも)クライアント結果キャッシュではキャッシュされません。
次のいずれかが含まれる問合せ:
リモート・オブジェクト
選択リストの複合型
PL/SQLファンクション
スナップショットベースの問合せ
フラッシュバック問合せ
シリアライズ可能の読取り専用トランザクション内で実行される問合せ
仮想プライベート・データベース(VPD)ポリシーが有効な表の問合せ
サーバーの結果キャッシュ機能が有効である場合、こうした問合せはデータベースにキャッシュされる可能性があります。詳細は、『Oracle Database概要』を参照してください。
クライアント結果キャッシュでは、結果セットに影響を与えるすべてのデータベースまたはセッション状態の変更と一致するように、結果セットを透過的に維持します。
トランザクションにより、キャッシュされた結果セットの作成に使用されたデータベース・オブジェクトのデータまたはメタデータが変更された場合、そのキャッシュされた結果セットの無効化が、サーバーへの次のラウンド・トリップ時に送信されます。アプリケーションで一定時間にわたりデータベース・コールが行われない場合、こうした無効化の有無を確認するため、クライアント結果キャッシュの遅延設定により次のOCIStmtExecute()
コールによるデータベース・コールが強制的に実行されます。
データベースの無効化に関連するキャッシュされた結果セットはただちに無効化されます。キャッシュされた結果セットからフェッチしているOCI文ハンドルは、その無効化の受信時にフェッチを続行できますが、後続のOCIStmtExecute()
コールは結果セットと照合されません。
クライアント結果キャッシュに使用可能な領域がある場合、プロセスによる次回のOCIStmtExecute()
コールにより、新規結果セットをキャッシュできます。クライアント結果キャッシュでは、未使用のメモリーが定期的に再生されます。
セッションにオープン・トランザクションがある場合、OCIでは、このトランザクションで変更されたデータベース・オブジェクトを参照する問合せが、クライアント結果キャッシュではなくサーバーに対して行われます。
一貫性を保つこのメカニズムにより、クライアント結果キャッシュはコミットされたデータベースの変更に常に近い状態になります。キャッシュできない問合せ(DML、OCILob
コールなど)のため、データベース・ラウンド・トリップに伴う比較的頻繁なコールをアプリケーションが実行する場合、これらのコールによりクライアント結果キャッシュがデータベースの変更と整合するように透過的に保たれます。
表が変更されるとき、トリガーにより別の表が変更されることがあります。クライアント結果キャッシュは、このような変化の影響を受けやすい性質があります。
セッション状態が変わる、たとえばNLSセッション・パラメータが変更されると、問合せ結果が異なる場合があります。クライアント結果キャッシュはこのような変化の影響を受けやすく、それ以降に問合せを実行すると、正しい結果セットが返されます。ただし、プロセス内の他のセッションが一致するように、クライアント結果キャッシュは現在のキャッシュされた結果セットを維持します(そして、無効化しません)。他のプロセスが一致しない場合、これらの結果セットはしばらくして「支配」状態になります。新しいセッション状態に対応する結果セットがキャッシュされます。
アプリケーションにとって、問合せ結果セットに影響するデータベースおよびセッション状態の変化を追跡することは煩雑でエラーも起きやすい処理ですが、クライアント結果キャッシュはそのような変化と結果セットの一貫性を透過的に保ちます。
クライアント結果キャッシュでは、クライアントにおけるスレッドのサポートは必要ありません。
参照: 『Oracle Call Interfaceプログラマーズ・ガイド』のOCIStmtExecute() を参照してください |
アプリケーションをデプロイする際は、(アプリケーションに変更を加えることなく)クライアント結果キャッシュについて次の要素を設定できます。
サーバー初期化パラメータ(2.7.5.1項を参照)
クライアント構成パラメータ(2.7.5.2項を参照)
表注釈(2.7.3.2項を参照)
RESULT_CACHE_MODE
セッション・パラメータ(2.7.3.3項を参照)
アプリケーションのデプロイ時に、クライアント結果キャッシュに設定するサーバー初期化パラメータを次に示します。
互換性を維持しておくOracle Databaseのリリースを指定します。クライアント結果キャッシュを有効にするには、COMPATIBLE
が11.0.0.0以上である必要があります。ビューのクライアント結果キャッシュを有効にするには、COMPATIBLE
が11.2.0.0以上である必要があります。
OCIクライアント・プロセスごとにクライアント結果セット・キャッシュの最大サイズを指定します。デフォルト値は0(ゼロ)であり、クライアント結果キャッシュが無効であることを示します。クライアント結果キャッシュを有効にするには、CLIENT_RESULT_CACHE_SIZE
を32768バイト(32KB)以上に設定します。
CLIENT_RESULT_CACHE_SIZE
によってクライアント結果キャッシュがサーバーで有効化されている場合、その値はsqlnet.ora
構成パラメータOCI_RESULT_CACHE_MAX_SIZE
によって上書きできます。クライアント結果キャッシュがサーバーで無効化されている場合、OCI_RESULT_CACHE_MAX_SIZE
は無視され、クライアント結果キャッシュはクライアントで有効化できません。
すべてのOracle Real Application Clusters (Oracle RAC)ノードでクライアント結果キャッシュを有効にするか、すべてのOracle RACノードでクライアント結果キャッシュを無効にすることをお薦めします。そうしないと、1つのクライアント・プロセス内で、一部のセッションではキャッシュが有効で、他のセッションではキャッシュが無効である(したがってサーバーから最新の結果を取得する)可能性があります。この組合せによって、データベースの一貫性のないビューがアプリケーションに提供されることがあります。
CLIENT_RESULT_CACHE_SIZE
は静的パラメータです。したがって、ALTER
SYSTEM
文を使用してCLIENT_RESULT_CACHE_SIZE
の値を変更する場合は、SCOPE
=
SPFILE
句を含める必要があり、変更を有効にするにはデータベースの再起動が必要です。
CLIENT_RESULT_CACHE_SIZE
の最大値は次の値以上になります。
使用可能なクライアント・メモリー
((キャッシュされる結果セットの可能な数) * (結果セット内の行の平均サイズ) * (結果セット内の行の平均数))
2ギガバイト(GB)
2GBより大きい値を指定すると、値は2GBになります。
注意: データベースの作成中は、CLIENT_RESULT_CACHE_SIZE パラメータを設定しないでください。エラーになる場合があります。 |
クライアント構成パラメータはオプションですが、設定されていると、サーバー初期化ファイルinit.ora
内の等価のパラメータを上書きします。
クライアント構成パラメータはoraaccess.xml
ファイル(『Oracle Call Interfaceプログラマーズ・ガイド』を参照)、sqlnet.ora
ファイル、あるいはその両方で設定できます。等価のパラメータを両方のファイルで設定した場合、oraaccess.xml
設定の方が、対応するsqlnet.ora
の設定より優先されます。パラメータがoraaccess.xml
で設定されていないと、プロセスはsqlnet.ora
内の設定を検索します。
クライアント構成パラメータをoraaccess.xml
およびsqlnet.ora
の両方で設定できる場合は、oraaccess.xml
でパラメータを設定することをお薦めします。ただし、ネットワーク構成の場合は、oraaccess.xml
がネットワーク・レベル設定をサポートしないため、sqlnet.ora
がプライマリ・ファイルです。
表2-3では、等価のoraaccess.xml
およびsqlnet.ora
クライアント構成パラメータについて説明します。
表2-3 クライアント構成パラメータ(オプション)
oraacess.xmlパラメータ | sqlnet.oraパラメータ | 説明 |
---|---|---|
|
|
各プロセスのクライアント結果キャッシュの最大サイズ(バイト数)。
|
|
|
各プロセスのクライアント結果キャッシュ内の結果セットの最大サイズ(バイト数)。 |
|
|
各プロセスのクライアント結果キャッシュ内の結果セットの最大サイズ(行数)。 |
クライアントでは結果キャッシュの遅延を設定できません。
OCIクライアントからサーバーへのラウンド・トリップで、OCIはクライアント結果キャッシュ統計を定期的にサーバーに送信します。この統計は、CLIENT_RESULT_CACHE_STATS$
ビューで示され、正常にキャッシュされた結果セット数、キャッシュ・ヒット数および無効化されたキャッシュ内の結果セット数などが含まれます。問合せのキャッシュ・ミスの数は、クライアント結果キャッシュ統計内の作成数の数以上になります。より正確には、キャッシュ・ミス数はサーバーの自動ワークロード・リポジトリ(AWR)レポート内のサーバー実行数と等しくなります。
参照:
|
クライアント結果キャッシュの検証手段を次に示します。
まず、RESULT_CACHE
ヒントなしで問合せの実行時間を測定します。次に、RESULT_CACHE
ヒントを問合せに追加して、実行時間を再測定します。実行時間の差異がパフォーマンスの向上分に該当します。
注意: V$MYSTAT ビューを問い合せるには、そのビューでのSELECT 権限が必要です。 |
次の問合せを5回実行します。
SELECT count(*) FROM table_name
V$MYSTAT
を問い合せます。
SELECT * FROM V$MYSTAT
次の問合せを5回実行します。
SELECT /*+ result_cache */ count(*) FROM table_name
問合せ結果はキャッシュされているため、このステップで必要なクライアントおよびサーバー間のラウンド・トリップ数はステップ1の場合より少なくなります。
V$MYSTAT
を問い合せます。
SELECT * FROM V$MYSTAT
この問合せの列の値を、ステップ2の問合せの列の値と比較します。
ステップ3の問合せにヒントを追加するかわりに、表注釈RESULT_CACHE
(MODE
FORCE)
をtable_name
にステップ3で追加してから、ステップ1の問合せを数回実行できます。
注意: V$SQLAREA ビューを問い合せるには、そのビューでのSELECT 権限が必要です。 |
次の問合せを5回実行します。
SELECT count(*) FROM table_name
V$SQLAREA
を問い合せます。
SELECT executions, fetches, parse_calls FROM V$SQLAREA
WHERE sql_text LIKE '% FROM table_name'
次の問合せを5回実行します。
SELECT /*+ result_cache */ count(*) FROM table_name
V$SQLAREA
を問い合せます。
SELECT executions, fetches, parse_calls FROM V$SQLAREA
WHERE sql_text LIKE '% FROM table_name'
この問合せの列executions
、fetches
およびparse_calls
の値を、ステップ2の問合せの列の値と比較します。実行時間の差異がパフォーマンスの向上分に該当します。
ステップ3の問合せにヒントを追加するかわりに、表注釈RESULT_CACHE
(MODE
FORCE)
をtable_name
にステップ3で追加してから、ステップ1の問合せを数回実行できます。
クライアント結果キャッシュは、サーバー結果キャッシュとは異なります。クライアント結果キャッシュでは、トップレベルのSQL問合せの結果がOCIクライアント・メモリーにキャッシュされますが、サーバー結果キャッシュでは、結果セットおよび問合せの断片がサーバーSGAメモリーにキャッシュされます。
クライアント結果キャッシュはサーバー結果キャッシュとは関係なく有効化できますが、どちらも結果キャッシュSQLヒント、表注釈、セッション・パラメータRESULT_CACHE_MODE
を共有します。表2-4に、結果キャッシュ・パラメータ、PL/SQLパッケージDBMS_RESULT_CACHE
および結果キャッシュ・ビューに対する結果キャッシュの関連付けを示します。サーバー結果キャッシュの詳細は、『Oracle Database概要』を参照してください。
表2-4 クライアント結果キャッシュとサーバー結果キャッシュの設定
パラメータ、PL/SQLパッケージおよびデータベース・ビュー | 結果キャッシュの関連付け |
---|---|
|
クライアント結果キャッシュ |
SQLヒント:
|
クライアント結果キャッシュ、サーバー結果キャッシュ |
|
クライアント結果キャッシュ |
|
クライアント結果キャッシュ |
|
クライアント結果キャッシュ、サーバー結果キャッシュ |
他のすべての |
サーバー結果キャッシュ |
|
サーバー結果キャッシュ |
|
サーバー結果キャッシュ |
|
クライアント結果キャッシュ、サーバー結果キャッシュ |
|
クライアント結果キャッシュ、サーバー結果キャッシュ |
OCIアプリケーションの場合、クライアント結果キャッシュのデモ用ファイルは、cdemoqc.sql
、cdemoqc.c
およびcdemoqc2.c
です(オペレーティング・システムのdemo
ディレクトリ内)。
クライアント結果キャッシュを使用するには、アプリケーションのリンクをOracle Database 11gリリース1 (11.1)以上のクライアント・ライブラリに再設定し、Oracle Database 11gリリース1 (11.1)以上のデータベース・サーバーに接続する必要があります。クライアント結果キャッシュは、JDBC Type IIドライバ、OCCI、Pro*C/C++およびODP.NETを含むすべてのOCIアプリケーションで使用できます。OCIドライバは、SQLヒントRESULT_CACHE
をOCIStmtPrepare()
およびOCIStmtPrepare2()
コールに自動的に渡します。
参照: 『Oracle Call Interfaceプログラマーズ・ガイド』のOCIStmtPrepare() 、OCIStmtPrepare2() を参照してください |
クライアント結果キャッシュの詳細は、次のドキュメントを参照してください。
『Oracle Call Interfaceプログラマーズ・ガイド』
『Oracle C++ Call Interfaceプログラマーズ・ガイド』
『Oracle Database JDBC開発者ガイド』
Oracle Databaseパフォーマンス・チューニング・ガイド
『Oracle Database概要』
SQLヒントとALTER
TABLE
およびCREATE
TABLE
のRESULT_CACHE
句の詳細は、『Oracle Database SQL言語リファレンス』を参照してください
RESULT_CACHE_MODE
初期化パラメータとCLIENT_RESULT_CACHE_STAT$
ビューの詳細は、『Oracle Databaseリファレンス』を参照してください
文キャッシュは、セッションごとの文のキャッシュを確立して管理する機能です。サーバーでは、文キャッシュによって文を再解析しなくてもカーソルを使用できるので、繰り返して文を解析する必要がなくなります。文キャッシュは、接続プーリングおよびセッション・プーリングの両方とともに使用でき、パフォーマンスおよびスケーラビリティが向上します。文キャッシュは、セッション・プーリングを使用せずにOCIで、あるいは接続プーリングを使用せずにOCCIで使用でき、またJDBCインタフェースやODP.NETインタフェースでも使用できます。また、動的SQL文を使用するOracleプリコンパイラ・アプリケーション、たとえばPro*C/C++やProCOBOLなどでは、動的SQL文キャッシュも使用できます。
JDBCインタフェースでは、暗黙的および明示的な文キャッシュを互いに関係なく有効または無効にできます。どちらかを使用するか、どちらも使用しないか、または両方とも使用することもできます。暗黙的文キャッシュと明示的文キャッシュは、各接続に対して1つのキャッシュを共有します。特定の文に対して暗黙的なキャッシュを無効にすることも可能です。
参照:
|
OCIクライアント文キャッシュの自動チューニングは、中間層アプリケーションのOCIクライアント・セッション機能を最適化することで、OCIアプリケーションを変更することなく、パフォーマンスを向上できます。
自動チューニングを使用しないと、OCIクライアントの文キャッシュ・サイズ設定は最適状態に及ばなくなる可能性があります。たとえば、ワークロードの変更によってSQL文の別のワーキング・セットが発生する場合です。サイズが小さすぎると、ネットワーク・アクティビティが過剰になり、サーバーでの解析量が増大します。サイズが大きすぎると、メモリーの使用量が超過します。クライアント・アプリケーションが、キャッシュ・サイズを最適に維持することは困難です。
自動チューニングでは、OCI文キャッシュ・サイズが定期的に自動で再構成されることで、このようなパフォーマンス上の潜在的な問題が解決されます。
自動チューニングは、OCI文キャッシュを再構成するオプションを提供するデプロイメント時間設定を指定することで行われます。これらの設定は、クライアントのoraaccess.xml
ファイルで接続文字列に基づくデプロイ設定として用意されており、OCI機能のユーザー構成に対するプログラム設定より優先されます。
中間層アプリケーションの開発者とデータベース管理者(DBA)は、それぞれのシステムでOCIクライアントの文キャッシュ・パラメータ設定を自動チューニングすることによって、パフォーマンス上の問題の診断と修正に要する時間と労力の軽減を期待できます。
OCI自動チューニング・パラメータ、実装および使用方法については、『Oracle Call Interfaceプログラマーズ・ガイド』を参照してください。
Oracle Database Release 12cリリース1 (12.1.0.1)以降では、『Oracle Call Interfaceプログラマーズ・ガイド』で説明するように、新しい構成ファイルoraaccess.xml
内でOCIデプロイメント・パラメータを使用できます。
連続問合せ通知(CQN)を使用すると、クライアント・アプリケーションがデータベースに問合せを登録し、オブジェクトに対するDMLまたはDDL変更の通知(オブジェクト変更通知(OCN))、あるいは問合せに関連付けられた結果セット変更の通知(問合せ結果変更通知(QRCN))を受信できます。データベースは、DMLトランザクションまたはDDLトランザクションのコミット時に通知を発行します。
CQN登録により、1つ以上の問合せが通知タイプ(OCNまたはQRCN)および通知ハンドラに関連付けられます。CQN登録は、次の方法で作成できます。
PL/SQLインタフェース
PL/SQLインタフェースを使用する場合、通知ハンドラはサーバー側PL/SQLストアド・プロシージャです。PL/SQL登録は、PHPのような非スレッド型の言語およびシステムで使用できます。PHPの場合、PL/SQLリスナーがデータベース通知を受信した段階でPHPコールバックを呼び出します。
Oracle Call Interface(OCI)
OCIを使用する場合、通知ハンドラはクライアント側Cコールバック・プロシージャです。
Javaデータベース接続(JDBC)インタフェース
JDBCインタフェースを使用する場合は、JDBCドライバによってサーバー上に登録が作成されます。JDBCドライバは、サーバーからの通知を(専用チャネルを介して)リスニングする新しいスレッドを起動し、それをJavaイベントに変換してから、この登録に登録されているすべてのリスナーに通知を送ります。
データベース常駐接続プール(DRCP)は、データベース接続を取得し、比較的短時間データベースで作業した後、接続を解放するような一般的なWebアプリケーション使用に対して、データベース・サーバーの接続プールを提供します。
内容は次のとおりです。
DRCPプール・サーバーのプロセスは、それぞれが専用サーバー・プロセスとデータベース・セッションを組み合せたものと同等であり、これをプール・サーバーと呼びます。プール・サーバーは、同じホストまたは複数のホストで実行されている複数のアプリケーションによる共有が可能です。接続ブローカ・プロセスは、プール・サーバーをデータベース・インスタンスのレベルで管理します。
DRCPはアプリケーション実行時に選択される構成可能な機能です。従来型とDRCPベースの接続アーキテクチャを同時に使用できるようになります。
DRCPは、中間層接続プーリングを実行できないマルチプロセス・シングル・スレッド・アプリケーション・サーバー(PHPやApacheなど)を含むアーキテクチャに特に有効です。DRCPは、数百から数千単位のWebサーバーまたは中間層がデータベース・アクセスとクライアント側プールを必要とする大規模なWebデプロイメントでもきわめて効果的です(Javaのようなマルチスレッド・システムと言語でも)。DRCPを使用すると、データベースは同時接続数を数万にまで増やすことができます。多数の接続に伴ってデータベースWebアプリケーションのスケーリングが必要な場合、接続プーリング・ソリューションとしてDRCPが適しています。
DRCPは、中間層プロセス内のスレッド間で接続を共有する中間層接続プールを補完します。また、DRCPを使用すると、同じ中間層ホスト上の中間層プロセス間でも、複数の中間層ホスト間でも、あるいは複数の中間層(Webサーバー、コンテナ)間でもデータベース接続を共有でき、異なる言語で書かれたアプリケーションにも対応できます。この共有によって、大量のクライアント接続をサポートするために必要となるデータベース・リソースが大幅に減少するため、データベース層のメモリー・フットプリントが縮小し、中間層とデータベース層の両方のスケーラビリティが向上します。すぐに使用できるサーバーのプールを保持することで、クライアント接続の作成と解放のコストも削減されます。
クライアントはDRCPから接続を取得し、これは接続ブローカと呼ばれるOracle Databaseバックグラウンド・プロセスに接続されます。接続ブローカはプール機能を実装し、クライアントからの永続インバウンド接続間でプール・サーバーを多重化します。
クライアントでデータベース・アクセスが必要な場合、接続ブローカがプールからサーバー・プロセスを取得してクライアントに渡します。クライアントはその後、サーバーに直接接続されます。サーバーがクライアント・プロセスを実行すると、サーバー・プロセスはプールに戻され、クライアントからの接続は、接続ブローカに対してクライアント・プロセスからの永続インバウンド接続としてリストアされます。DRCPでは、リソースを解放しても、セッションはそのまま残されますが、接続(サーバー・プロセス)との関連付けは失われます。このセッションは、システム・グローバル領域(SGA)ではなくプログラム・グローバル領域(PGA)にユーザー・グローバル領域(UGA)を格納するため、クライアントはアクティビティの検出時に透過的に接続を再確立できます。
DRCPは通常、接続数の多いアプリケーションで多用されます。共有サーバーは接続数が中程度のアプリケーションに効果的であり、専用セッションは接続数が少ないアプリケーションに適しています。しきい値サイズは、データベース・ホストで使用できるメモリー量によって異なります。
DRCPには次の利点があります。
DRCPでは複数のクライアント・アプリケーション間と、中間層アプリケーション・サーバー間でリソース共有が可能です。
DRCPではデータベース・ホストでリソース使用量が減少するため、データベースとアプリケーションのスケーラビリティが向上します。
クライアント側接続プーリングおよび共有サーバーと比較した場合は次のとおりです。
DRCPは、クライアント側接続プーリングによって用意されるデータベース・サーバーへの直接接続を提供します(クライアント側接続プーリングと同様だが、共有サーバーとは異なる)。
DRCPは、データベース・サーバーをプールできます(クライアント側接続プーリングおよび共有サーバーと同様)。
DRCPは、セッションをプールできます(クライアント側接続プーリングと同様だが、共有サーバーとは異なる)。
DRCPは、中間層の境界間で接続を共有できます(クライアント側接続プーリングとは異なる)。
DRCPは、データベース・リソースの使用率を最小限に抑えたまま、多数の接続が必要となる環境でのスケーラビリティ要件に対応できる、独自の接続プーリング・ソリューションです。
参照: DRCPアーキテクチャの詳細は、『Oracle Database概要』を参照してください |
DRCPはデフォルトでインストールされますが、DBAはDBMS_CONNECTION_POOL
パッケージを使用してDRCPを起動および構成する必要があります。構成オプションには、プール・サーバーの最小数と最大数、接続ブローカの数、各接続ブローカが処理する接続の最大数などがあります。
OCIセッション・プールAPIは、DRCPと相互運用するために拡張されています。
参照:
|
Oracle Database 12cリリース1 (12.1.0.1)から、Oracle JDBCドライバはDRCPをサポートしています。DRCPの実装によってサーバー側にプールが作成され、それが複数のクライアント・プール間で共有されます。これらのクライアント・プールは、JDBCのユニバーサル接続プールを使用します。ユニバーサル接続プールを使用することで、(サーバー上でサーバー・プロセスの数が減少するために)メモリー消費量が少なくなり、データベース・サーバーのスケーラビリティが向上します。
サーバー側接続のチェックインおよびチェックアウト操作を追跡するために、Javaアプリケーションはクライアント側プール(JDBCのユニバーサル接続プールまたは任意のサードパーティのJava接続プールなど)を使用する必要があります。
2.12.6項で、DBAがサーバー側でDRCPを起動する方法を説明します。
クライアント側でDRCPを有効にするには、次の操作を行う必要があります。
NULL
以外で空でないString
値を接続プロパティoracle.jdbc.DRCPConnectionClass
に渡します。
長い接続文字列で(SERVER=POOLED
)を渡します。
次のように、短いURLフォームでも(SERVER=POOLED
)を指定できます。
jdbc:oracle:thin:@//<host>:<port>/<service_name>[:POOLED]
次に例を示します。
jdbc:oracle:thin:@//localhost:5221/orcl:POOLED
クライアント側でJDBCを有効にする方法の例は、『Oracle Database JDBC開発者ガイド』の、クライアント側でDRCPを有効にする手順に関する項を参照してください。
接続プロパティoracle.jdbc.DRCPConnectionClass
を使用して、サーバー上のすべてのプール・サーバー・プロセスに同じDRCP接続クラス名を設定すると、複数の接続プール間でサーバー上のプール・サーバー・プロセスを共有できます。
DRCPでは、特定の接続にタグを適用し、タグ付き接続を後から簡単に取得することもできます。DRCPで接続のタグ付けを有効にする方法の詳細は、『Oracle Database JDBC開発者ガイド』を参照してください。
OCIセッション・プールAPIのOCISessionPoolCreate()
、OCISessionGet()
およびOCISessionRelease()
は、DRCPと相互運用されます。
OCIアプリケーションは、OCISessionPoolCreate()
を呼び出して、DRCP用のOCIセッション・プールの環境を初期化します。これは『Oracle Call Interfaceプログラマーズ・ガイド』に説明があります。
DRCP用のOCIセッション・プールからセッションを取得するため、OCIアプリケーションはOCI_SESSGET_SPOOL
をmode
パラメータに指定してOCISessionGet()
を呼び出します。OCISessionGet()
の詳細は『Oracle Call Interfaceプログラマーズ・ガイド』を参照してください。
DRCP用のOCIセッション・プールにセッションを解放するため、OCIアプリケーションはOCISessionRelease()
を呼び出します。これは『Oracle Call Interfaceプログラマーズ・ガイド』に説明があります。
パフォーマンスを向上するため、OCIセッション・プールは接続ブローカへの接続を透過的にキャッシュできます。OCIアプリケーションは、authInfop
パラメータをOCI_ATTR_CONNECTION_CLASS
に設定してOCISessionGet()
を呼び出し、接続クラス名を指定するか、またはOCISessionGet()
を呼び出す前にOCIAuthInfo
ハンドルを使用することで、類似の状態でアプリケーションがセッションを終了したセッションを再利用できます。詳細は、2.12.5項を参照してください。
DRCPは、タグ付け、文キャッシュおよびTAFなどの、従来のクライアント側OCIセッション・プールにより提供されていた機能もサポートします。
Oracle Database 11gリリース1 (11.1)では、OCISessionGet()
を使用してセッションを取得するときに指定できる2つの設定、つまりセッション純正値と接続クラスがOCIに導入されました。
内容は次のとおりです。
セッション純正値では、OCIアプリケーションがプールされたセッションを再利用できる(OCI_SESSGET_PURITY_SELF
)か、新しいセッションを使用する必要がある(OCI_SESSGET_PURITY_NEW
)かを指定します。
アプリケーションは、OCISessionGet()
を呼び出す前にOCIAuthInfo
ハンドルで、あるいはOCISessionGet()
を呼び出すときにmode
パラメータ内で、セッション純正値を設定できます。
例2-1では、接続プーリング・アプリケーションで新規セッションを設定する方法を示しています。
例2-1 新規セッションのセッション純正値の設定
/* OCIAttrSet method */ ub4 purity = OCI_ATTR_PURITY_NEW; OCIAttrSet (authInfop, OCI_HTYPE_AUTHINFO, &purity, sizeof (purity), OCI_ATTR_PURITY, errhp); OCISessionGet (envhp, errhp, &svchp, authInfop, poolName, poolNameLen, NULL, 0, NULL, NULL, NULL, OCI_SESSGET_SPOOL); /* poolName is the name returned by OCISessionPoolCreate() */ /* OCISessionGet mode method */ OCISessionGet (envhp, errhp, &svchp, authInfop, poolName, poolNameLen, NULL, 0, NULL, NULL, NULL, OCI_SESSGET_SPOOL | OCI_SESSGET_PURITY_NEW); /* poolName is the name returned by OCISessionPoolCreate() */
注意: プールされたセッションを再利用する場合、サーバーのNLS属性がクライアントのNLS属性よりも優先されます。たとえば、クライアントで この問題を回避するには、接続クラスを使用して共有を制限します。 |
接続クラスには、OCIアプリケーションで必要な接続のタイプの論理名を定義します。プールされたセッションに接続クラスがある場合、OCIはセッションがその接続クラス外で共有されないように保証します。
たとえば、接続クラスはプールされたセッションを次の要素が共有することを防止します。
異なるユーザー
(ユーザーHR
に対して最初に作成されたセッションは、ユーザーHR
による後続のリクエストのみに割り当てられます。)
同じユーザーの異なるセッション
同じユーザーによって実行中の異なるアプリケーション
(各アプリケーションは固有の接続クラスを保有できます。)
接続クラスを設定するには、OCIAuthInfo
ハンドルのOCI_ATTR_CONNECTION_CLASS
属性を使用します。接続クラス名は最大長1024バイトの文字列で、アスタリスク(*)は使用できません。
例2-2は、HRMSアプリケーションが接続クラスHRMS
のセッションを必要としていることを示します。
例2-2 HRMSとして接続クラスを設定
OCISessionPoolCreate (envhp, errhp, spoolhp, &poolName, &poolNameLen, "HRDB", strlen("HRDB"), 0, 10, 1, "HR", strlen("HR"), "HR", strlen("HR"), OCI_SPC_HOMOGENEOUS); OCIAttrSet (authInfop, OCI_HTYPE_AUTHINFO, "HRMS", strlen ("HRMS"), OCI_ATTR_CONNECTION_CLASS, errhp); OCISessionGet (envhp, errhp, &svchp, authInfop, poolName, poolNameLen, NULL, 0, NULL, NULL, NULL, OCI_SESSGET_SPOOL);
例2-3は、採用アプリケーションが接続クラスRECMS
のセッションを必要としていることを示します。
例2-3 RECMSとして接続クラスを設定
OCISessionPoolCreate (envhp, errhp, spoolhp, &poolName, &poolNameLen, "HRDB", strlen("HRDB"), 0, 10, 1, "HR", strlen("HR"), "HR", strlen("HR"), OCI_SPC_HOMOGENEOUS); OCIAttrSet (authInfop, OCI_HTYPE_AUTHINFO, "RECMS", strlen("RECMS"), OCI_ATTR_CONNECTION_CLASS, errhp); OCISessionGet (envhp, errhp, &svchp, authInfop, poolName, poolNameLen, NULL, 0, NULL, NULL, NULL, OCI_SESSGET_SPOOL);
表2-5に、OCIアプリケーションがOCIセッション・プール(OCISessionGet()
を使用して)および他のソースから取得する接続の属性および設定のデフォルトを示します。
表2-5 セッション純正値および接続クラスのデフォルト
属性または設定 | OCIセッション・プールからの接続のデフォルト値 | OCIセッション・プール以外からの接続のデフォルト値 |
---|---|---|
|
|
|
|
OCIセッション・プールのすべての接続についてデフォルトの接続クラスとして使用されるクライアント側の各セッション・プールに対する、OCIで生成されたグローバル一意名 |
|
セッションの共有 |
OCIセッション・プールからのセッションを要求するスレッド |
|
DBAはSYSDBA
としてログオンし、DBMS_CONNECTION_POOL.START_POOL
をデフォルト設定で使用して、デフォルト・プールSYS_DEFAULT_CONNECTION_POOL
を開始する必要があります。
プールの構成の詳細は、『Oracle Database管理者ガイド』を参照してください。
アプリケーションでDRCPを有効にするには、簡易接続文字列で:POOLED
を指定(例2-4を参照)するか、TNS接続文字列で(SERVER=POOLED)
を指定(例2-5を参照)します。
次のOCIアプリケーション・シナリオと、DRCPがそれぞれにもたらすメリットについて検討します。
アプリケーションがOCIセッション・プールを使用せず、接続クラスや純正値設定も指定(またはPURITY=NEW
を指定)しない場合。
アプリケーションはDRCPから新規セッションを取得します。アプリケーションが接続をプールに戻す場合、デフォルトによりこのセッションは同じアプリケーションの他のインスタンスと共有されません。したがって、クライアント・セッションが存続する間、プールされたサーバーはクライアントに割り当てられたままになります。(SQL*Plusは、OCIセッション・プールを使用しないクライアントの一例です。SQL*Plusは接続がアイドルのときでも、接続を保持し続けます。)
アプリケーションは既存のプール・サーバーを再利用できるというメリットを得られます。
アプリケーションがOCIセッション・プール外のOCISessionGet()
を呼び出すか、接続クラスおよびPURITY=SELF
を指定する場合。
アプリケーションは、DRCPプール・サーバーおよびセッションを両方とも再利用できます。ただし、OCISessionRelease()
コールの後、OCIは接続ブローカへの接続を終了します。次回のOCISessionGet()
コールでは、アプリケーションはブローカに再接続して、DRCPは指定された接続クラスに属するプール・サーバー(およびセッション)を割り当てます。再接続では接続の確立および再認証のコストが発生します。
アプリケーションはDRCPリソース(プロセスおよびセッション)をより効率的に共有できますが、接続ブローカへの接続のキャッシュからメリットは得られません。
アプリケーションがOCIセッション・プールAPIを使用し、接続クラスを指定し、PURITY=SELF
を指定する場合。
アプリケーションは、プール・サーバーおよび関連付けられたセッションの両方を再利用して、接続ブローカへのキャッシュされた接続からメリットを得ることで、すべてのDRCP機能を使用します。キャッシュされた接続では、OCISessionGet()
コールで再認証のコストが発生しません。
参照: OCISessionPoolCreate() 、OCISessionGet() 、OCISessionRelease() 、OCISessionPoolDestroy() の詳細は、『Oracle Call Interfaceプログラマーズ・ガイド』を参照してください |
JavaアプリケーションはOCIと同様(2.12.8項を参照)にDRCPからメリットを得られます。
ユニバーサル接続プール(UCP)を使用する、または接続ファクトリとしてConnectionPoolDataSourceを使用しているユーザーは、(コードではなく)構成のみを変更することでDRCPを使用するようにアップグレードできます。
DRCPがもたらすメリットを享受できるアプリケーションを設計する手順は、OCIセッション・プールを使用するアプリケーションの設計手順とよく似ています(詳細は『Oracle Call Interfaceプログラマーズ・ガイド』を参照してください)。
唯一の追加ステップとして、DRCPとともに動作するようデプロイされた場合、最大限のパフォーマンスを得るために、アプリケーションで明示的に接続クラスを指定する必要があります。
最大限のパフォーマンスを得て、さらにDRCPリソースの共有機能を強化するため、同じアプリケーションの複数のインスタンスは、同じ接続クラスを指定する必要があります。アプリケーションの複数のインスタンスでデータベース・セッションを共有できることを確認してください。
例2-6は、DRCPアプリケーションを示しています。
例2-6 DRCPアプリケーション
/* Assume that all necessary handles are allocated. */ /* This middle tier uses a single database user. Create a homogeneous client-side session pool */ OCISessionPoolCreate (envhp, errhp, spoolhp, &poolName, &poolNameLen, "BOOKSDB", strlen("BOOKSDB"), 0, 10, 1, "SCOTT", strlen("SCOTT"), "password", strlen("password"), OCI_SPC_HOMOGENEOUS); while (1) { /* Process a client request */ WaitForClientRequest(); /* Application function */ /* Set the Connection Class on the OCIAuthInfo handle that is passed as argument to OCISessionGet*/ OCIAttrSet (authInfop, OCI_HTYPE_AUTHINFO, "BOOKSTORE", strlen("BOOKSTORE"), OCI_ATTR_CONNECTION_CLASS, errhp); /* Purity need not be set, as default is OCI_ATTR_PURITY_SELF for OCISessionPool connections */ /* You can get a SCOTT session released by Middle-tier 2 */ OCISessionGet(envhp, errhp, &svchp, authInfop, poolName, poolNameLen, NULL, 0, NULL, NULL, NULL, OCI_SESSGET_SPOOL); /* Database calls using the svchp obtained above */ OCIStmtExecute(...) /* This releases the pooled server on the database for reuse */ OCISessionRelease (svchp, errhp, NULL, 0, OCI_DEFAULT); } /* Middle tier is done - exiting */ OCISessionPoolDestroy (spoolhp, errhp, OCI_DEFAULT);
例2-7と例2-8では、例2-6からBOOKSTORE
アプリケーションを提供する10個の中間層ホストにコードをデプロイする接続文字列を示しています。
例2-7では、データベースが専用サーバー・モードでDRCPは有効化されていないOracle Database 12c (またはそれ以下)であり、クライアントに12cライブラリがあると仮定しています。アプリケーションはデータベースから専用サーバー接続を取得します。
例2-7 専用サーバー・モードでDRCPを使用しないデプロイメントに対する接続文字列
BOOKSDB = (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=oraclehost.company.com) (PORT=1521))(CONNECT_DATA = (SERVICE_NAME=books.company.com)))
例2-8では、Oracle Database 12cデータベースでDRCPが有効であると仮定します。すべての中間層プロセスがDRCPのプーリング機能を利用できます。DRCPのデータベース・リソース要件は、専用サーバー・モードでの要件より大幅に少なくなります。
Oracle Database 12cクライアント・ライブラリにリンクされたOCIアプリケーションは、次のそれぞれに対して変更なしで動作します。
DRCPを無効にしたOracle Database 12cデータベース
Oracle Database 12cより前のリリースのデータベース・サーバー
DRCPを有効にしたOracle Database 12cデータベース・サーバー(DRCP接続文字列を使用してデプロイした場合)
前述のとおりにOCIセッション・プールAPIを接続クラスおよび純正値設定とともに使用するようクライアントが適切に変更されていれば、そのクライアントはDRCPにより提供される高度なスケーラビリティを利用できます。
Oracle Database 12cリリース1 (12.1.0.1)から、Oracle JDBCドライバはDRCPをサポートしています。詳細は、『Oracle Database JDBC開発者ガイド』を参照してください。
プール・サーバーでは、次の操作を実行できません。
データベースの停止
DRCPの停止
接続済ユーザーのパスワードの変更
共有データベース・リンクを使用した、異なるインスタンスにあるDRCPへの接続
TCPSによるアドバンスト・セキュリティ・オプション(ASO)の使用
DRCPによるエンタープライズ・ユーザー・セキュリティの使用
(OCI_MIGRATE
オプションを使用して)直接的に、または(OCISessionPoolCreate()
を起動して)間接的に、サーバー側の移行可能なセッションを使用
初期クライアント・ロールの使用
(OCI_ATTR_APPCTX_NAME
およびOCI_ATTR_APPCTX_VALUE
などの)アプリケーション・コンテキスト属性の使用
DRCPによるトランザクション・ガード(第25章で説明)の使用
DRCPによるアプリケーション・コンティニュイティ(第26章で説明)の使用
DDL文実行の前に作成されたセッションは、DDL文実行後にクライアントに割当てできます。したがって、プール内のデータベース・ユーザーに影響するDDL文の実行時は注意してください。たとえば、ユーザーを削除する前に、そのユーザーのセッションがプール内に存在せず、そのユーザーとして認証されたブローカへの接続がないことを確認します。
明示的なロールが有効なセッションがプールに解放される場合、後でデフォルトのログイン・ロールを必要とする(同じユーザーの)接続に割り当てることができます。したがって、明示的なロールのあるセッションは解放せずに、かわりにセッションを終了してください。
注意: 暗号化やDRCPを使用した厳密認証などのOracle Advanced Security機能を使用できます。 |
ユーザーは、データの暗号化とデータの整合性の組合せを混在させることができます。ただし、ユーザーは接続クラスを使用して、このような組合せをそれぞれ分離する必要があります。たとえば、ユーザー・アプリケーションが、暗号化メカニズムとして、ある接続セットにAES256を指定し、別の接続セットにはDESを指定する必要がある場合、アプリケーションは各セットに異なる接続クラスを指定する必要があります。
すでにDRCP、FANおよびRLBと統合されている、OCIセッション・プールを使用することを強くお薦めします。ただし、次のいずれかがtrueの場合、OCIセッション・プールを使用しないアプリケーションではDRCPを引き続き使用できます。
アプリケーションが独自のカスタム接続プールを使用して作成されている場合。
アプリケーションでプールは使用されないが、セッションを使用しない期間があり(したがってそれをプールに解放でき)、同じセッションを取り戻すことに依存しない場合
DRCPをこのようなアプリケーションで使用するには、セッションがステートフルである必要があります。つまり、セッションにはOCI_ATTR_SESSION_STATE
属性(『Oracle Call Interfaceプログラマーズ・ガイド』に説明があります)が必要です。アプリケーションがステートフルでDRCPが有効な場合、OCIはDRCPプールから適切なセッションを透過的に割り当てます。アプリケーションがステートレス(OCI_SESSION_STATELESS
属性がある)でDRCPが有効な場合、OCIはセッションを透過的にDRCPプールに返します。
基本のデータベース・リソースの効率的な利用のために、アプリケーションではセッション状態をできるだけ速やかに識別する必要があります。詳細は、2.12.14項を参照してください。
注意: 属性OCI_ATTR_SESSION_STATE またはOCI_SESSION_STATELESS を指定するアプリケーションは、2.12.5項で説明されているセッション純正値および接続クラスも指定する必要があります。 |
通常、アプリケーションは、1つの作業単位の期間において特定のデータベース・セッションを必要とします。この期間中、セッションはステートフルです。この期間の後、後続の作業単位のために特定のセッションを維持することにアプリケーションが依存しない場合、セッションはステートレスです。
ステートフルからステートレス(あるいは逆)へのセッションの変化をアプリケーションまたはコール元が検出すると、アプリケーションはOCI_ATTR_SESSION_STATE
またはOCI_SESSION_STATELESS
属性を使用して変化をOCIに明示的に通知できます。この情報によってOCIおよびOracle Databaseは、アプリケーションが使用していないセッションを別のユーザーに再度割り当てて、必要になった場合はアプリケーションに新規セッションを割り当てるなどの、スケーラビリティ最適化を透過的に実行します。
例2-9は、セッションの状態を明示的にマークするコードの一部を示しています。
例2-9 明示的なステートフルまたはステートレス・セッションのマーキング
wait_for_transaction_request(); do { ub1 state; /* mark database session as STATEFUL */ state = OCI_SESSION_STATEFUL; checkerr(errhp, OCIAttrSet(usrhp, OCI_HTYPE_SESSION, &state, 0, OCI_ATTR_SESSION_STATE, errhp)); /* do database work consisting of one or more related calls to the database */ ... /* done with database work, mark session as stateless */ state = OCI_SESSION_STATELESS; checkerr(errhp, OCIAttrSet(usrhp, OCI_HTYPE_SESSION, &state, 0,OCI_ATTR_SESSION_STATE, errhp)); wait_for_transaction_request(); } while(not _done);
OCIセッション・プールの外部で取得されたセッションは、OCI_SESSION_STATEFUL
とマークされ、アプリケーションによって明示的にOCI_SESSION_STATELESS
とマークされないかぎり、OCI_SESSION_STATEFUL
が保たれます。
OCIセッション・プールから取得されたセッションは、最初のコールがそのセッションで開始されるときに、デフォルトでOCI_SESSION_STATEFUL
とマークされます。セッションがプールに解放されるときは、デフォルトでOCI_SESSION_STATELESS
とマークされます。したがって、OCIセッション・プールの使用時はセッションをステートフルまたはステートレスとして明示的にマークする必要はありません。
参照: OCI_ATTR_SESSION_STATE の詳細は、『Oracle Call Interfaceプログラマーズ・ガイド』を参照してください |
Oracle Real Application Clusters (Oracle RAC)は、単一データベースを複数ノードにある複数インスタンスで管理するデータベース・オプションです。Oracle RAC環境のデータベースでDRCPが構成されているとき、プールの構成は各データベース・インスタンスに適用されます。1つのインスタンスでプールを起動または停止すると、すべてのインスタンスのプールが起動または停止されます。
マルチテナント・コンテナ・データベース(CDB)でのDRCPは、ルート・コンテナで構成および管理されます。プールの構成、開始および停止は、ルート・コンテナに接続しているときに実行できます。このプールは、クライアントが様々なサービス名を使用して接続する、様々なプラガブル・データベースのプール・サーバーを管理します。
Data Guard環境でDRCPが動作する場合は次のようになります。
フィジカル・スタンバイ・データベースの場合、次のように実行します。
プールを起動できるのは、プールがプライマリ・データベースで実行中の場合のみです。
プールを停止できるのは、プールがプライマリ・データベースで停止している場合のみです。
プール・パラメータの構成、デフォルトへの復元または変更を行うことはできません。
物理スタンバイ・データベースがプライマリ・データベースになると、前述した制限事項は物理スタンバイ・データベースに適用されなくなります。
ロジカル・スタンバイ・データベースでは、すべてのプール操作を行うことができます。
内容は次のとおりです。
Oracle Real Application Clusters (Oracle RAC)は、単一データベースを複数ノードにある複数インスタンスで管理するデータベース・オプションです。Oracle RACの共有ディスク方式でデータベースをクラスタ化すると、スケーラビリティが向上します。現在の必要性に応じてノードを簡単に追加または解放でき、いずれかのノードで障害が発生しても別のノードがワークロードを引き継ぐので、可用性が向上します。すべてのインスタンスがデータベース全体にアクセスできるため、Oracle RACではデータベースに高可用性機能とフェイルオーバー機能が追加されます。
作業リクエストのバランシングは、接続時(Oracle Net Servicesで提供される接続時ロード・バランシング)と実行時(ランタイム接続ロード・バランシング)の両方で発生します。Oracle RAC環境の場合、アプリケーションのセッション要求を均等に分散させるために、セッション・プールは、高速アプリケーション通知(FAN)イベントを介してOracle RACロード・バランシング・アドバイザから受信されるサービス・メトリックを使用します。セッション・プールに入ってくる作業要求は、現在のサービス・パフォーマンスを使用して、サービスを提供しているOracle RACのインスタンス全体で分散できます。
接続時ロード・バランシングは、アプリケーションがセッションを作成するときに発生します。プールされたセッションは、各インスタンスでセッションが作業を実行できるようにするため、セッションの作成時にOracle RACインスタンス間で適切に分散される必要があります。
ランタイム接続ロード・バランシングは、アプリケーションが既存のセッション・プールからセッションを選択する際に発生します(したがって頻度の高いアクティビティです)。ランタイム接続ロード・バランシングは、セッション・プール内で作業の処理に最も適切なセッションに作業リクエストをルーティングします。単一インスタンスでのみサービスをサポートするセッション・プールの場合は、プール内で使用可能な最初のセッションで十分です。プールが複数インスタンスにまたがるサービスをサポートしている場合は、適切なサービスを提供できる、または容量の大きいインスタンスが多数のリクエストを取得するように、作業をインスタンス間で分散する必要があります。
OCI、OCCI、JDBC、ODP.NETのクライアント・アプリケーションはすべて、ランタイム接続ロード・バランシングをサポートしています。
参照:
|
クライアントでのランタイム接続ロード・バランシングの有効化と無効化は、クライアント環境によって異なります。
内容は次のとおりです。
OCIクライアント・アプリケーションの場合、ランタイム接続ロード・バランシングは、アプリケーションがサービス時間に基づいてサービス・メトリックを受信するように、次の操作の実行時にOracle Database 11gリリース1 (11.1)以上のクライアントとOracle Database 10gリリース2 (10.2)以上のサーバーとの通信においてデフォルトで有効になります。
アプリケーションをスレッド・ライブラリにリンクしている。
OCI環境をOCI_EVENTS
およびOCI_THREADED
モードで作成している。
セッション・プールで使用されるサービスに対して、ロード・バランシング・アドバイザの目標と接続ロード・バランシングの目標を構成している。
OCIクライアントのランタイム接続ロード・バランシングを無効にするには、OCISessionPoolCreate()
をコールする際にmode
パラメータをOCI_SPC_NO_RLB
に設定します。
OCI用のFAN HA (FCF)では、サービスがTRUE
になるにはAQ_HA_NOTIFICATIONS
が必要です。
参照: OCISessionPoolCreate() の詳細は、『Oracle Call Interfaceプログラマーズ・ガイド』を参照してください |
OCCIクライアント・アプリケーションの場合、ランタイム接続ロード・バランシングは、次の操作の実行時にOracle Database 11gリリース1 (11.1)以上のクライアントとOracle Database 10gリリース2 (10.2)以上のサーバーとの通信においてデフォルトで有効になります。
アプリケーションをスレッド・ライブラリにリンクしている。
OCCI環境をEVENTS
およびTHREADED_MUTEXED
モードで作成している。
セッション・プールで使用されるサービスに対して、ロード・バランシング・アドバイザの目標と接続ロード・バランシングの目標を構成している。
OCCIクライアントのランタイム接続ロード・バランシングを無効にするには、NO_RLB
オプションをStatelessConnectionPool
Class
のPoolType
属性に対して使用します。
OCCI用のFAN HA (FCF)では、サービスがTRUE
になるにはAQ_HA_NOTIFICATIONS
が必要です。
参照: OCCIインタフェースを使用するランタイム・ロード・バランシングの詳細は、『Oracle C++ Call Interfaceプログラマーズ・ガイド』を参照してください |
JDBC環境で、ランタイム接続ロード・バランシングは、高速接続フェイルオーバー(FCF)の有効時にOracle Database 11gリリース1 (11.1)以上のクライアントとOracle Database 10gリリース2 (10.2)以上のサーバーとの通信においてデフォルトで有効になります。
JDBC環境で、ランタイム接続ロード・バランシングは、FCF処理で使用するのと同じバンド外ONSイベント・メカニズムを使用する、Oracle Notification Service(ONS)インフラストラクチャに依存します。ランタイム接続ロード・バランシングが機能するためにONSの追加設定や構成は必要ありません。
JDBC環境でランタイム接続ロード・バランシングを無効にするには、値をfalseに設定してsetFastConnectionFailoverEnabled()
をコールします。
参照: JDBCインタフェースを使用するランタイム・ロード・バランシングの詳細は、『Oracle Database JDBC開発者ガイド』を参照してください |
ODP.NETクライアント・アプリケーションの場合は、ランタイム接続ロード・バランシングがデフォルトで無効です。ランタイム接続ロード・バランシングを有効にするには、接続文字列に、"Load Balancing=true
"を含めます。
ODP.NET用のFAN HA (FCF)では、サービスがTRUE
になるにはAQ_HA_NOTIFICATIONS
が必要です。
参照: ランタイム・ロード・バランシングの詳細は、『Oracle Data Provider for .NET開発者ガイドfor Microsoft Windows』を参照してください |
アプリケーションでは、次の要件がすべて満たされている場合のみロード・バランシング・アドバイザFANイベントを受信できます。
サーバーが、イベント通知を発行するように構成されていること。
アプリケーションがスレッド・ライブラリとリンクされていること。
OCI環境がOCI_EVENTS
およびOCI_THREADED
モードで作成されていること。
OCCI環境がTHREADED_MUTEXED
およびEVENTS
モードで作成されていること。
DBMS_SERVICE
パッケージを使用してOracle RAC環境を構成または変更していること。
サービスの目的および接続ロード・バランシングの目的を設定するため、サービスを次のように変更する必要があります。
EXEC DBMS_SERVICE.MODIFY_SERVICE("myService", DBMS_SERVICE.GOAL_SERVICE_TIME, clb_goal => DBMS_SERVICE.CLB_GOAL_SHORT);
定数GOAL_SERVICE_TIME
は、ロード・バランシング・アドバイザがサービスでの処理の実行に要する時間およびサービスで使用可能な帯域幅に基づくことを指定します。
定数CLB_GOAL_SHORT
は、接続ロード・バランシングでロード・バランシング・アドバイザを使用し、ロード・バランシング・アドバイザが有効であることを指定します。接続バランシングの目標はCLB_GOAL_LONG
に設定します。ただし、CLB_GOAL_LONG
はクローズされたワークロードに対して(つまり、完了した作業の割合と新しく始める作業の割合が等しいときに)最も有効です。
参照:
|