20c 新機能:自動インメモリー機能の HIGH オプション

はじめに

2020年2月に Oracle Database 20c の検証用のプレビュー版がDatabase Cloud Service 上で提供開始されました。本記事では、この 20c リリースの目玉機能のひとつとなる自動インメモリー機能に追加されたHIGH オプションをピックアップしてご紹介します。

自動インメモリー機能とは

自動インメモリー機能はインメモリー内のオブジェクトに対し自動的な管理を提供する機能で、Oracle Database 18c から導入されました。自動インメモリー機能が有効な場合、利用度の高いセグメント(ホット・セグメント)をインメモリーに移入したり、その逆に利用度の低いセグメント(コールド・セグメント)を排除したりという動作が自動的に実施されます。これによりインメモリー列ストア(IM 列ストア)と呼ばれる高速アクセス領域内のセグメントが最適化されることでパフォーマンス向上を期待することができます。

自動インメモリー機能は初期化パラメーター INMEMORY_AUTOMATIC_LEVEL により制御されていて、デフォルトでは自動インメモリー機能が無効(OFF)になっています。20c 以前ではINMEMORY_AUTOMATIC_LEVEL を LOW または MEDIUM に設定することで自動インメモリー機能を有効にすることができます。

LOW
インメモリー内のセグメント領域の合計が使用可能なメモリーサイズを超えると IM 列ストアからコールド・セグメントが削除されます。
MEDIUM
メモリー不足のために移入されなかったホット・セグメントが最初に移入されるようにする追加の最適化も含まれます。

※注意

LOW や MEDIUM の値は、クラウドベース・システムと Exadata システムのみ設定可能です。オンプレミス・システムではこれらの値を設定しようとすると以下のエラーが発生し、設定することができません。

 ORA-32017: SPFILEの更新中に障害が発生しました
 ORA-12754: 機能'Automatic In-Memory'は、機能'Runtime Environment'がないため無効化されています

なお、自動インメモリー機能が無効の場合、以下のような動作になっています。

動作確認例

1. インメモリー関連パラメーター値の確認

 SQL> show parameter INMEMORY_AUTOMATIC_LEVEL
 NAME                                 TYPE        VALUE
 ------------------------------------ ----------- ------------------------------
 inmemory_automatic_level             string      OFF
 
 SQL> show parameter INMEMORY_SIZE
 NAME                                 TYPE        VALUE
 ------------------------------------ ----------- ------------------------------
 inmemory_size                        big integer 100M ※

--※インメモリー領域のサイズを 100M に設定しています。

2. 現在インメモリー領域の使用状況の確認

 SQL> select * from V$INMEMORY_AREA;
 POOL                       ALLOC_BYTES USED_BYTES   POPULATE_STATUS    CON_ID
 -------------------------- ----------- ------------ ----------------- -------
 1MB POOL                      66060288   65011712   DONE                    3※
 64KB POOL                     33554432    2818048   DONE                    3

--※インメモリー領域のほとんどが使われており、空き容量があまりない状況となります。

3. 例として t 表に対しインメモリーを有効化し、t へ問い合わせすることで表データを IM 列 ストアに移入します

 SQL> alter table t inmemory;
 SQL> select /*+ FULL(t) NO_PARALLEL(t) */ count(*) from t;

4. 表 t のデータが IM 列ストア移入されたかを確認します

 SQL> select SEGMENT_NAME,INMEMORY_SIZE,BYTES,BYTES_NOT_POPULATED
      from V$IM_USER_SEGMENTS
      where SEGMENT_NAME='T';

 レコードが選択されませんでした。--※

--※この時点の状態ではインメモリー領域が不足しているため、ホット・セグメント t のデータがインメモリー領域へ移入することができませんでした。このとき、自動インメモリー機能が有効に設定されていると移入できなかったホット・セグメント t のデータを移入しようとする最適化タスクがデータベースにより自動的に発行されます。

20c 新機能: 自動インメモリー機能の HIGH オプション

今年リリース予定の Oracle Database 20c では自動インメモリーに HIGH オプションが追加されました。INMEMORY_AUTOMATIC_LEVEL にHIGHが設定される場合、ユーザによりインメモリーを有効にするオブジェクトの選択が必要なくなります。つまり、alter table … inmemory 句の明示的な設定がなくとも、データベースによりインメモリーを有効にするオブジェクトおよび圧縮レベルが自動的に設定されます。これによりインメモリー領域を最適に使用し、可能な限り最高のパフォーマンスを自動的に提供することができます。

自動インメモリー機能が HIGH に設定される場合の動作詳細につきまして、以下の例をベースに説明します。

動作確認例

0. 検証用表の作成、データの挿入

 SQL> drop table t purge;
 SQL> create table t(c char(256)); --※INMEMORY として指定していません

-- 10M ほどのデータを挿入

 SQL> begin
      for i in 1..30960
      loop
      insert into t values('a');
      end loop;
      commit;
      end;
      /

1. INMEMORY_AUTOMATIC_LEVELの を HIGH に設定

 SQL> alter system set INMEMORY_AUTOMATIC_LEVEL=HIGH scope=spfile;
 SQL> shutdown immediate
 SQL> startup
 SQL> show parameter INMEMORY_AUTOMATIC_LEVEL
 NAME                                 TYPE        VALUE
 ------------------------------------ ----------- ------------------------------
 inmemory_automatic_level             string      HIGH

2. 現在のインメモリー領域の使用状況の確認

SQL> select SEGMENT_NAME,INMEMORY_SIZE/1024/1024 "INMEMORY_SIZE(MB)",BYTES/1024/1024 "size(MB)",
      BYTES_NOT_POPULATED
      from V$IM_USER_SEGMENTS order by 1;
      
      SEGMENT_NAME    INMEMORY_SIZE(MB)   size(MB) BYTES_NOT_POPULATED
      --------------- ----------------- ---------- -------------------
      T1                           1.25         19                   0
      T10                          1.25         10                   0
      T2                           1.25         10                   0
      ...
      T9                           1.25         10                   0
      
      10 rows selected.

--※10 個のセグメントのデータが格納されている

3. t へ問い合わせを行い、IM 列 ストアへの移入を試みます

   SQL> select /*+ FULL(t) NO_PARALLEL(t) */ count(*) from t;
   ...

実際に表 t のデータが IM 列ストアに移入されたかを確認してみましょう。

   SQL> select SEGMENT_NAME,INMEMORY_SIZE/1024/1024 "INMEMORY_SIZE(MB)",BYTES/1024/1024 "size(MB)",
        BYTES_NOT_POPULATED
        from V$IM_USER_SEGMENTS
        where SEGMENT_NAME= 'T';
        SEGMENT_NAME    INMEMORY_SIZE(MB)   size(MB) BYTES_NOT_POPULATED
        --------------- ----------------- ---------- -------------------
        T                            1.25         10                   0

表 t に対しては明示的に inmemory が指定されていないにもかかわらず、ホット・セグメントとして t のデータが IM 列ストア移入されていることがわかります。

4. 実行されたインメモリーの最適化タスクを確認してみます

SQL> select * from DBA_INMEMORY_AIMTASKS;

   TASK_ID CREATION_TIME                   STATE
   ------- ------------------------------- -------
         1 08-JUL-20 04.28.46.000000 PM    DONE
   ...
        21 09-JUL-20 02.18.22.000000 PM    DONE
        22 09-JUL-20 02.20.24.000000 PM    DONE
        23 09-JUL-20 02.22.24.000000 PM    DONE
        24 09-JUL-20 02.24.24.000000 PM    DONE
        25 09-JUL-20 02.26.24.000000 PM    DONE
        26 09-JUL-20 02.28.24.000000 PM    DONE
        27 09-JUL-20 02.30.25.000000 PM    DONE
        28 09-JUL-20 02.32.25.000000 PM    DONE
        29 09-JUL-20 02.34.25.000000 PM    DONE
        30 09-JUL-20 02.36.25.000000 PM    DONE

2秒間隔で統計情報に基づいた最適化タスクが自動的に発行されていることが確認できます。

   SQL> select * from DBA_INMEMORY_AIMTASKDETAILS where task_id=30;

   TASK_ID OBJECT_OWNER    OBJECT_NAME  SUB ACTION        STATE
   ------- --------------- ------------ --- ------------- ------
        30 T               T                POPULATE★    DONE
        30 T               T1               POPULATE      DONE
        30 T               T10              POPULATE      DONE
        30 T               T2               EVICT   ★    DONE
   ...

コールド・セグメント T2 が排除(EVICT)され、ホット・セグメント T が移入(POPULATE)される動作が実行されていることが確認できました。

INMEMORY_AUTOMATIC_LEVEL 初期化パラメーターが HIGH に設定されると、上記の例の結果の通り既存のすべてのオブジェクトは自動的に INMEMORY MEMCOMPRESS AUTO に設定されインメモリー圧縮も行われる動作になっています。また、特定のオブジェクトを IM 列ストアに入れたくない場合は、手動で NO INMEMORY に設定し除外することも可能です。そして、パラメーター値を HIGH 以外の値に設定すると、MEMCOMPRESS AUTO に設定されたすべてのセグメントがNO INMEMORY に設定されます。

まとめ

本記事は Oracle Database 18c 機能の1つである自動インメモリーおよび 20c で当該機能に追加された HIGH オプションについて紹介させていただきました。これらの機能によりデータベース管理者の手間を省いてデータベースの高速化を容易に実現できます。今注目されている Oracle Cloud Infrastructure 上でデータベースをご利用される際にぜひ自動インメモリー機能も合わせてご検討いただければと思います。

なお、Oracle Database 20c のリリース予定についての公式な情報は MOS(My Oracle Support)からご確認いただけます。

Oracle Database 20c には様々な新機能が実装されています。新機能リストは下記のマニュアル「Database New Features Guide」からご参照いただけます。

参考文書

(オラクル事業部 技術担当 喬)

20c 新機能:自動インメモリー機能の HIGH オプション