8 IM列ストアの再移入の最適化

IM列ストアでは、変更されたオブジェクトが定期的にリフレッシュされます。初期化パラメータおよびDBMS_INMEMORYパッケージを使用して、この動作を制御できます。

この章のトピックは、次のとおりです:

8.1 IM列ストアの再移入について

大幅な変更の後の列データの自動リフレッシュは、再移入と呼ばれます。

インメモリー圧縮単位(IMCU)は、読取り専用の構造であり、DMLが表に対して発生したときに適所のデータの変更は行われません。かわりに、各IMCUに関連付けられたスナップショット・メタデータ単位(SMU)により、トランザクション・ジャーナル内で行変更が追跡されます。問合せで、データにアクセスし、変更された行を見つけた場合は、対応するROWIDをトランザクション・ジャーナルから取得し、その後、変更された行をバッファ・キャッシュから取得できます。

変更数が増加すると、SMUのサイズ、およびトランザクション・ジャーナルまたはデータベース・バッファ・キャッシュからフェッチする必要があるデータの量も増加します。ジャーナル・アクセスにより問合せパフォーマンスが低下しないようにするために、バックグラウンド・プロセスで、変更されたオブジェクトを再移入します。

自動再移入には、しきい値ベース再移入トリクル再移入という2つの形式があります。1つ目の形式は、IMCUのトランザクション・ジャーナル内の失効エントリのパーセンテージによって異なります。トリクル再移入は、しきい値に達していない場合でも失効列データを定期的にリフレッシュすることで、しきい値ベース再移入を補完します。

再移入中は、従来のアクセス・メカニズムを使用可能です。データには、常にバッファ・キャッシュまたはディスクからアクセスできます。また、IM列ストアは、ディスク上のデータとトランザクションの一貫性が常に保たれています。問合せでアクセスするデータの場所を問わず、データベースでは、常に、一貫性のある結果が返されます。

8.2 データ・ロードはどのようにIM列ストアと連携するか

IM列ストアでは、従来型DML、ダイレクト・パス・ロードおよびパーティション交換ロードといったデータ・ロード・タイプに応じて、様々なメカニズムが使用されます。

この項では、次の項目について説明します。

8.2.1 従来型DMLはどのようにIM列ストアと連携するか

従来型DMLでは、一度に1つの行または行配列が処理され、最高水位標より下の行が挿入されます。IM列ストアが有効になっているかどうかに関係なく、データベースでは、バッファ・キャッシュを使用してDMLが処理されます。

IMCUは読取り専用です。文によってIMCU内の行が変更されると、IM列ストアにより、関連するSMU内のROWIDが記録されます。

列圧縮単位(CU)エントリは、その値が対応するジャーナル・エントリの値と異なる場合に失効になります。たとえば、トランザクションによって従業員の週給が1000から1200に変更されますが、IMCU内の実際の値は1000のままです。トランザクション・ジャーナルにより、失効行のROWIDおよびそのSCNが記録されます。

注意:

トランザクション・ジャーナルでは、新しい値は記録されません。正確に述べると、対応する行が、特定のSCNの時点で失効として示されます。

この項では、次の項目について説明します。

関連トピック

8.2.1.1 失効しきい値

IMCU内の失効エントリの数が増えるほど、IMCUのスキャンの速度は低下します。

データベースでは、変更された行をIM列ストアからではなくバッファ・キャッシュまたはディスクからフェッチする必要があるため、パフォーマンスが低下します。このため、IMCU内の失効エントリの数が内部失効しきい値に達すると、Oracle Databaseにより、IMCUが再移入されます。

データベースでは、IMCUアクセスの頻度および失効行の数を考慮する経験則を使用して、そのしきい値が決定されます。頻繁にアクセスされる、または失効行の割合が高いIMCUでは、再移入がより頻繁に行われます。

関連項目:

8.2.1.2 ダブル・バッファリング

ダブル・バッファリングでは、バックグラウンド・プロセスにより、元の行と最後に変更された行を組み合せることで、新しいIMCUバージョンが作成されます。

データベースでしきい値ベース再移入またはトリクル再移入のどちらかが開始されると、IM列ストアでダブル・バッファリングが使用されます。次の図で示すように、IM列ストアでは、同時に2つのバージョンのIMCUが保持され、元の失効IMCUは引き続き問合せでアクセス可能となります。

図8-1 ダブル・バッファリング

図8-1の説明が続きます
「図8-1 ダブル・バッファリング」の説明

ダブル・バッファリングの基本手順は、次のとおりです。

  1. 元のSMUでは、データベースにより、特定のSCNの時点で既存のIMCUが元のバージョンとしてマークされます。

  2. バックグラウンド・プロセスにより、変更された行の最新バージョンと元の行を組み合せることで、IMCUの新しいバージョンが作成されます。

  3. 新しいSMUのジャーナルでは、データベースにより、IMCU作成中に起こるDML操作が追跡されます。

このようにして、元のIMCUはオンラインのままになります。データベースでは、IMCUの古いバージョンと新しいバージョンは、それらが役立つかぎり、またはIM列ストアに領域が必要になるまで、どちらも保持されます。

8.2.2 ダイレクト・パス・ロードはどのようにIM列ストアと連携するか

ダイレクト・パス・ロードは、INSERT /*+APPEND*/文、またはDIRECT=trueでのSQL*Loader操作です。

ダイレクト・パス・ロードでは、データベース・バッファ・キャッシュを迂回し、データベースにより、フォーマットされたデータ・ブロックがデータ・ファイルに直接書き込まれます。データベースにより、セグメント内の使用領域と未使用領域との境界である最高水位標より上のデータが付加されます。ダイレクト・パス・ロードは、すべてのデータを挿入するかまったく挿入しないという、オール・オア・ナッシングの操作です。

図8-2 ダイレクト・パス・ロードと最高水位標

図8-2の説明が続きます
「図8-2 ダイレクト・パス・ロードと最高水位標」の説明

セグメントがIM列ストアに移入される場合、ダイレクト・パス・ロードは次のように機能します。

  1. CREATE TABLE AS SELECTまたはINSERT /*+APPEND*/文を使用してデータをロードします。現在のセッションのみが、DMLを認識しています。

  2. 文をコミットします。

  3. 最高水位標が、新しいデータを含むよう移動します。それにより、データが欠落しているIMCUが警告されます。V$IM_SEGMENTS.BYTES_NOT_POPULATEDで、新しく挿入されたデータのサイズが示されるようになります。

  4. IM列ストアで、次のアルゴリズムに基づいて再移入が管理されます。

    • 影響を受けたオブジェクトのPRIORITYNONE以外の値に設定されている場合は、データベースにより、データが再移入されます。

    • 影響を受けたオブジェクトのPRIORITYNONEに設定されている場合は、データベースにより、次回のオブジェクトの全体スキャンで再移入されます。

8.2.3 パーティション交換ロードはどのようにIM列ストアと連携するか

パーティション交換ロードは、表をパーティションと交換する技術です。交換ロードは、データではなくメタデータを変更するため、ほとんど一瞬です。

交換ロードを実行するには、次の手順に従います。

  1. ソース表と呼ばれる、パーティション化されていない表を作成します。

  2. ソース表に行をロードします。

  3. ターゲット・パーティションと呼ばれる既存の表パーティションをその表と交換します。

交換後にターゲット・パーティションをIM列ストアに移入する場合は、ソース表を、交換前にIM列ストアに移入する必要があります。ターゲット・パーティションが移入されているかどうかに応じて、次のシナリオが可能となります。

  • 交換前に、ターゲット・パーティションがIM列ストアに移入されていません。たとえば、そのパーティションが空だとします。

    交換後は、ソース表は、もうIM列ストアに移入されていません。ソースIMCUは、現在はターゲット・パーティションに関連付けられています。

  • 交換前に、ターゲット・パーティションがIM列ストアに移入されています。

    交換後は、ソース表は、IM列ストアに移入されたままとなります。

例8-1 INMEMORYパーティション交換ロード

この例では、パーティション化されているsales表のINMEMORY属性は表レベルで設定されています。この表内の空でないすべてのパーティションは、現在移入されています。sales_p042616パーティションは、現在は空になっています。目的は、空のパーティションsales_p042616に、テキスト・ファイルに含まれているデータを移入することです。次の図では、シナリオの前と後を示します。

図8-3 パーティション交換

図8-3の説明が続きます
「図8-3 パーティション交換」の説明

この交換を実行するには、次の手順を実行します。

  1. CREATE TABLE ... ORGANIZATION EXTERNAL文を使用して、外部表sales_tmp_extを作成します。

    この外部表は、データベース内には存在せず、アクセス・ドライバが提供されている任意の形式にすることができます。この表は、読取り専用です。

  2. CREATE TABLE ... AS SELECT * FROM sales_tmp_extを使用して、sales_tmp_ldというパーティション化されていない表を作成します。

    sales_tmp_ld表は外部ではなく、これは、それにデータ・ファイル内の行が格納されることを意味します。

  3. ALTER TABLE文を使用して、sales_tmp_ld内にINMEMORY属性を設定します。

    sales_tmp_ld表は、現在はINMEMORYとしてマークされていますが、まだIM列ストアには移入されていません。

  4. 表の全体スキャンを強制的に実行することで、sales_tmp_ldをIM列ストアに移入します。

    たとえば、次の問合せは、全体スキャンを強制的に実行します。

    SELECT /*+ FULL(s) NO_PARALLEL(s) */ COUNT(*) FROM sales_tmp_ld s;
  5. sales_p042616パーティションをsales_tmp_ld表と交換します。

    たとえば、次のようにsales表を変更します。

    ALTER TABLE sales EXCHANGE PARTITION sales_p042616 WITH TABLE sales_tmp_ld;

交換の完了後は、sales_p042616パーティションはIM列ストアに移入されており、sales_tmp_ldはもう移入されていません。

関連項目:

パーティション交換ロードの詳細は、『Oracle Database VLDBおよびパーティショニング・ガイド』を参照してください。

8.3 データベースでIM列ストアが再移入される時期

データベースでは、内部アルゴリズムに従って、IM列ストアが自動的に再移入されます。手動で再移入を無効にして、その積極性に影響を与えることができます。

注意:

この項では、自動再移入について説明します。DBMS_INMEMORY.REPOPULATEプロシージャを使用することで、再移入を手動で強制実行できます。

この項では、次の項目について説明します。

関連項目:

DBMS_INMEMORY.REPOPULATEプロシージャの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

8.3.1 しきい値ベース再移入とトリクル再移入

自動再移入には、しきい値ベース再移入トリクル再移入という2つの形式があります。

自動再移入では、必ず、失効ジャーナル・エントリがチェックされ、ダブル・バッファリングが使用されます。ただし、再移入には、様々なトリガーがあります。

  • しきい値ベース再移入

    データベースでは、トランザクション・ジャーナルで記録された変更の数が内部失効しきい値に達したときに、IMCUが移入されます。しきい値ベース再移入は、INMEMORY_MAX_POPULATE_SERVERS初期化パラメータが0以外の値に設定されている場合は、自動的に起こります。

  • トリクル再移入

    IMCO (インメモリー・コーディネータ)バックグラウンド・プロセスでは、定期的に、失効行が存在するかどうかがチェックされてから、IMCUが再移入キューに追加されます。このメカニズムは、失効しきい値に達しているかどうかには依存しませんINMEMORY_TRICKLE_REPOPULATE_SERVERS_PERCENT初期化パラメータは、トリクル再移入に使用されるバックグラウンド・プロセスの数を制限します。このパラメータを0に設定すると、トリクル再移入が無効になります。

トリクル再移入は、Javaガベージ・コレクションに似ています。このメカニズムは、次のように機能します。

  1. IMCOが起動します。

  2. IMCOでは、IMCUに関連付けられているトランザクション・ジャーナルに失効エントリが存在するかどうかも含めて、移入タスクを実行する必要性の有無が判断されます。

  3. IMCOによって失効エントリが見つかった場合は、領域管理ワーカー・プロセス(Wnnn)がトリガーされてIMCUの新しいバージョンが作成されます。

    IMCUの作成中に、データベースにより、変更された行のROWIDがトランザクション・ジャーナルに記録されます。

  4. IMCOは2分間スリープしてから、手順1に戻ります。

図8-4 トリクル再移入

図8-4の説明が続きます
「図8-4 トリクル再移入」の説明

たとえば、データベースは、1日当たり8時間ビジー状態になるとします。ほとんどのSMUに、少数のトランザクション・ジャーナル・エントリが含まれています(失効しきい値未満)。データベースが静止状態のときに、IMCOが起動し、ジャーナルをチェックしてどのIMCUに失効エントリがあるかを判断してから、トリクル再移入を使用してそれらのIMCUをリフレッシュします。

関連項目:

8.3.2 再移入に影響する要素

再移入をトリガーするアルゴリズムは、内部的であり、いくつかの要素によって異なります。

再移入に影響する主な要素は、次のとおりです。

  • DML変更の率

    変更された行の数が増えると、失効した列データの割合が増加します。トランザクション・ジャーナルが拡大し、問合せを満たすためにバッファ・キャッシュを使用する必要性が増加します。

  • DML操作のタイプ

    一般的に、挿入は新しいデータ・ブロックに対して行われることが多いため、挿入には、削除や更新よりもパフォーマンス・オーバーヘッドはありません。

  • データ・ブロック内での変更された行の位置

    同じデータベース・ブロックまたは表パーティション内でグループ化された変更は、表全体にわたり分散された変更よりも影響は少なくなります。すべてのIMCUのバージョニングは、少数のIMCUをバージョニングするよりも影響が大きくなります。

  • INMEMORYオブジェクトに適用された圧縮レベル

    ダブル・バッファリングにより、表に適用された圧縮レベルが高いほど、再移入中に問合せおよびDMLのオーバーヘッドが大きくなります。たとえば、MEMCOMPRESS FOR CAPACITY HIGHでは、MEMCOMPRESS FOR DMLよりも大きなオーバーヘッドがもたらされます。

  • アクティブなワーカー・プロセスの数

    ワーカー・プロセスの数が増加すると、並列で起こる処理が多くなります。それにより、再移入率が増加します。

関連項目:

8.4 IM列ストアの再移入の制御

デフォルトでは、再移入は自動的に起こりますが、その積極性を制御することや、完全に無効にすることができます。

初期化パラメータ

次の初期化パラメータは、バックグラウンド・プロセスの挙動に影響します。

  • INMEMORY_MAX_POPULATE_SERVERS

    このパラメータは、移入および再移入(しきい値ベースおよびトリクル)に使用可能なWnnnプロセスの最大数を制限します。デフォルト値は、CPU_COUNTの半分です。このパラメータは、スロットルの役割を果たし、これらのサーバー・プロセスで残りのデータベースがオーバーロードされないようにします。このパラメータを0に設定すると、移入および再移入が無効になります。

    注意:

    このパラメータの値の設定が高くなりすぎないように注意してください。コア数に近い値またはそれより大きい値に設定すると、残りのシステムの実行に使用可能なCPUがなくなる可能性があります。

  • INMEMORY_TRICKLE_REPOPULATE_SERVERS_PERCENT

    このパラメータは、トリクル再移入を実行する、移入プロセスと再移入プロセスの合計パーセンテージを制限します。その趣旨は、2分間にトリクル再移入によって再移入されるIMCUの数を制限することです。

    このパラメータの値は、INMEMORY_MAX_POPULATE_SERVERS値のパーセンテージです。たとえば、INMEMORY_TRICKLE_REPOPULATE_SERVERS_PERCENT5パーセントで、INMEMORY_MAX_POPULATE_SERVERS20の場合、IM列ストアでは、平均値である1コア(.05 * 20)がトリクル再移入のために使用されます。

    バックグラウンドCPUの増加という犠牲を払いスループットを向上させるには、このパラメータを510などの大きい値に設定します。INMEMORY_MAX_POPULATE_SERVERSプロセスの半分以上を他のタスクで使用可能なよう、50より大きい値は許可されていません。

    このパラメータを0に設定すると、トリクル移入が無効になります。

関連項目:

DBMS_INMEMORY.REPOPULATEプロシージャ

表、パーティションまたはサブパーティションを手動で再移入するには、DBMS_INMEMORY.REPOPULATEプロシージャを使用します。IM列ストアに現在移入されているオブジェクトのみが、再移入の対象となります。

次の値をforceパラメータで使用可能です。

  • FALSE: データベースにより、変更された行を含むIMCUのみが再移入されます。これはデフォルトです。

  • TRUE: データベースにより、セグメントが削除されてから再構築されます。データベースにより、統計が増分され、最初の移入に関連するその他すべてのタスクが実行されます。

たとえば、IMCU 1には行1から500,000までが含まれ、IMCU 2には行500,001から1,000,000までが含まれています。文により、行600,000が変更されます。forceFALSEの場合は、データベースにより、IMCU 2のみが再移入されます。forceTRUEの場合は、データベースにより、両方のIMCUが再移入されます。

さらにINMEMORY_VIRTUAL_COLUMNS初期化パラメータがENABLEに設定されており、アプリケーションによって新しい仮想列が作成されるとします。forceFALSEの場合は、データベースにより、新しい列とともにIMCU 2のみが再移入されます。forceTRUEの場合は、データベースにより、新しい列とともに両方のIMCUが再移入されます。

関連項目:

DBMS_INMEMORY.REPOPULATEの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

8.5 トリクル再移入の最適化: チュートリアル

このチュートリアルでは、トリクル再移入に使用可能なバックグラウンド・プロセスのパーセンテージを増加させます。

前提

このチュートリアルでは、次のことが前提となっています。

  • IM列ストアが有効になっている。

  • トリクル再移入を実行する領域管理ワーカー・プロセス(Wnnn)に、より多くのCPUを充てる必要があります。

  • データベース・サーバーには、12個のCPUコアがあります。

再移入の積極性を向上させるには、次の手順を実行します。

  1. SQL*PlusまたはSQL Developerで、管理者権限を持つユーザーとしてデータベースにログインします。

  2. 再移入に関連する初期化パラメータについて設定を表示します(出力例が含まれています)。

    SHOW PARAMETER POPULATE_SERVERS
    
    NAME                                        TYPE        VALUE
    ------------------------------------        ----------- -----------
    inmemory_max_populate_servers               integer     12
    inmemory_trickle_repopulate_servers_percent integer     1
    

    上の出力では、12個のコアを移入タスクおよび再移入タスクに使用可能であることが示されています。INMEMORY_TRICKLE_REPOPULATE_SERVERS_PERCENTは、INMEMORY_MAX_POPULATE_SERVERS値の1%です。移入タスクと再移入タスクに使用可能なサーバー・プロセスについては、IM列ストアでは、トリクル再移入に最大0.12個のCPUコア(.01 * 12)を使用できます。

  3. トリクル再移入の最大値を、INMEMORY_MAX_POPULATE_SERVERS初期化パラメータ値の25%に増加させます。

    たとえば、次の文を使用します。

    ALTER SYSTEM SET INMEMORY_TRICKLE_REPOPULATE_SERVERS_PERCENT=25;

    結果として、IM列ストアで、移入処理と再移入処理に使用可能な合計12個のうち、最大3個のCPUコア(.25 * 12)をトリクル再移入に使用するようになりました。

関連項目: