Database In-MemoryのCPUリソースを制御する(DBRM)
2016-06-23
対応バージョン
Oracle Database 12.1.0.2
2016-06-23記事公開
Database In-Memoryのデータのポピュレーションについて、メモリ上に乗り切らない場合の動作について説明します。(ポピュレーションとは、物理ディスクからインメモリ用のメモリ領域にデータを移入する処理です。)
インメモリに入れるデータの準備を行います。
初期化パラメータにて、100MBのメモリ領域を指定しています。
1 2 3 4 |
SQL> alter system set inmemory_size = 100M scope=spfile; SQL> alter system set inmemory_clause_default = 'INMEMORY MEMCOMPRESS FOR QUERY LOW PRIORITY MEDIUM' scope=spfile; SQL> shutdown immediate SQL> startup |
TESTという名前のユーザを作成し、INMEMというテーブルをインメモリ化することでテストを行います。データは適当にDBA_TABELSのデータを増幅しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
SQL> create user TEST identified by test default tablespace USERS; SQL> grant create session to TEST; SQL> grant unlimited tablespace to TEST; SQL> grant create table to TEST; SQL> SQL> create table TEST.INMEM as select * from DBA_TABLES inmemory; SQL> column OWNER format a10 SQL> column TABLE_NAME format a30 SQL> column TABLESPACE_NAME format a15 SQL> select OWNER 2 , TABLE_NAME 3 , TABLESPACE_NAME 4 , INMEMORY 5 , INMEMORY_PRIORITY 6 from DBA_TABLES 7 where owner = 'TEST' 8 and table_name = 'INMEM'; OWNER TABLE_NAME TABLESPACE_NAME INMEMORY INMEMORY ---------- ------------------------------ --------------- -------- -------- TEST INMEM USERS ENABLED MEDIUM |
作成後の状態です。データが少ないためすぐにポピュレーションが完了し、メモリ上にデータが移入されていることが確認できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
SQL> set line 180 trim on pages 10000 SQL> column SEGMENT_NAME format a30 SQL> select OWNER 2 , SEGMENT_NAME 3 , TABLESPACE_NAME 4 , POPULATE_STATUS 5 , INMEMORY_SIZE / 1024 / 1024 as MBYTES_INMEMORY 6 , BYTES / 1024 / 1024 as MBYTES_POPULATED 7 , BYTES_NOT_POPULATED / 1024 / 1024 as MBYTES_NOT_POPULATED 8 , INMEMORY_COMPRESSION 9 from V$IM_SEGMENTS 10 order by 1,2; OWNER SEGMENT_NAME TABLESPACE_NAME POPULATE_ MBYTES_INMEMORY MBYTES_POPULATED MBYTES_NOT_POPULATED INMEMORY_COMPRESS ---------- ------------------------------ --------------- --------- --------------- ---------------- -------------------- ----------------- TEST INMEM USERS COMPLETED 1.125 2 0 FOR QUERY LOW SQL> select POOL 2 , ALLOC_BYTES / 1024 / 1024 as ALLOC_MBYTES 3 , USED_BYTES / 1024 / 1024 as USED_MBYTES 4 , POPULATE_STATUS 5 from V$INMEMORY_AREA 6 order by 1; POOL ALLOC_MBYTES USED_MBYTES POPULATE_STATUS -------------------------- ------------ ----------- -------------------------- 1MB POOL 79 1 DONE 64KB POOL 16 .125 DONE |
データの追加を行なった際の変化を確認します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
SQL> insert into TEST.INMEM select * from TEST.INMEM; SQL> commit; SQL> select OWNER 2 , SEGMENT_NAME 3 , TABLESPACE_NAME 4 , POPULATE_STATUS 5 , INMEMORY_SIZE / 1024 / 1024 as MBYTES_INMEMORY 6 , BYTES / 1024 / 1024 as MBYTES_POPULATED 7 , BYTES_NOT_POPULATED / 1024 / 1024 as MBYTES_NOT_POPULATED 8 , INMEMORY_COMPRESSION 9 from V$IM_SEGMENTS 10 order by 1,2; OWNER SEGMENT_NAME TABLESPACE_NAME POPULATE_ MBYTES_INMEMORY MBYTES_POPULATED MBYTES_NOT_POPULATED INMEMORY_COMPRESS ---------- ------------------------------ --------------- --------- --------------- ---------------- -------------------- ----------------- TEST INMEM USERS COMPLETED 20.375 629 309.78125 FOR QUERY LOW SQL> -- MBYTES_NOT_POPULATED が増加し、ポピュレーションが終わっていないデータが存在することが確認できます。 SQL> select POOL 2 , ALLOC_BYTES / 1024 / 1024 as ALLOC_MBYTES 3 , USED_BYTES / 1024 / 1024 as USED_MBYTES 4 , POPULATE_STATUS 5 from V$INMEMORY_AREA 6 order by 1; POOL ALLOC_MBYTES USED_MBYTES POPULATE_STATUS -------------------------- ------------ ----------- -------------------------- 1MB POOL 79 20 DONE 64KB POOL 16 .375 DONE SQL> -- V$INMEMORY_AREA の POPULATE_STATUS は変化せず、 DONE のままです。 |
2分毎にトリクル再移入(自動的に差分のポピュレーションを行う処理)を行っているため、2分間待ちます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
SQL> select OWNER 2 , SEGMENT_NAME 3 , TABLESPACE_NAME 4 , POPULATE_STATUS 5 , INMEMORY_SIZE / 1024 / 1024 as MBYTES_INMEMORY 6 , BYTES / 1024 / 1024 as MBYTES_POPULATED 7 , BYTES_NOT_POPULATED / 1024 / 1024 as MBYTES_NOT_POPULATED 8 , INMEMORY_COMPRESSION 9 from V$IM_SEGMENTS 10 order by 1,2; OWNER SEGMENT_NAME TABLESPACE_NAME POPULATE_ MBYTES_INMEMORY MBYTES_POPULATED MBYTES_NOT_POPULATED INMEMORY_COMPRESS ---------- ------------------------------ --------------- --------- --------------- ---------------- -------------------- ----------------- TEST INMEM USERS COMPLETED 37.5 629 0 FOR QUERY LOW SQL> -- MBYTES_NOT_POPULATED が 0 となっていることが確認できます。 SQL> select POOL 2 , ALLOC_BYTES / 1024 / 1024 as ALLOC_MBYTES 3 , USED_BYTES / 1024 / 1024 as USED_MBYTES 4 , POPULATE_STATUS 5 from V$INMEMORY_AREA 6 order by 1; POOL ALLOC_MBYTES USED_MBYTES POPULATE_STATUS -------------------------- ------------ ----------- -------------------------- 1MB POOL 79 37 DONE 64KB POOL 16 .5 DONE SQL> -- POPULATE_STATUS に変化はありませんが、 USED_MBYTES についても増加しています。 |
DBMS_INMEMORY.POPULATEを実行し、手動によるポピュレーション処理を実施します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
SQL> insert into TEST.INMEM select * from TEST.INMEM; SQL> commit; SQL> exec DBMS_INMEMORY.POPULATE('TEST', 'INMEM'); PL/SQL procedure successfully completed. SQL> -- ポピュレーション完了を待たずに、即操作が戻ります。 SQL> select OWNER 2 , SEGMENT_NAME 3 , TABLESPACE_NAME 4 , POPULATE_STATUS 5 , INMEMORY_SIZE / 1024 / 1024 as MBYTES_INMEMORY 6 , BYTES / 1024 / 1024 as MBYTES_POPULATED 7 , BYTES_NOT_POPULATED / 1024 / 1024 as MBYTES_NOT_POPULATED 8 , INMEMORY_COMPRESSION 9 from V$IM_SEGMENTS 10 order by 1,2; OWNER SEGMENT_NAME TABLESPACE_NAME POPULATE_ MBYTES_INMEMORY MBYTES_POPULATED MBYTES_NOT_POPULATED INMEMORY_COMPRESS ---------- ------------------------------ --------------- --------- --------------- ---------------- -------------------- ----------------- TEST INMEM USERS COMPLETED 41.6875 1284 447.023438 FOR QUERY LOW SQL> select POOL 2 , ALLOC_BYTES / 1024 / 1024 as ALLOC_MBYTES 3 , USED_BYTES / 1024 / 1024 as USED_MBYTES 4 , POPULATE_STATUS 5 from V$INMEMORY_AREA 6 order by 1; POOL ALLOC_MBYTES USED_MBYTES POPULATE_STATUS -------------------------- ------------ ----------- -------------------------- 1MB POOL 79 38 POPULATING 64KB POOL 16 .625 POPULATING SQL> -- POPULATE_STATUS が POPULATING に変化しています。(完了したら DONE に変化します) |
さらにデータを追加し、メモリサイズ以上のデータを投入します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
SQL> insert into TEST.INMEM select * from TEST.INMEM; SQL> commit; SQL> select OWNER 2 , SEGMENT_NAME 3 , TABLESPACE_NAME 4 , POPULATE_STATUS 5 , INMEMORY_SIZE / 1024 / 1024 as MBYTES_INMEMORY 6 , BYTES / 1024 / 1024 as MBYTES_POPULATED 7 , BYTES_NOT_POPULATED / 1024 / 1024 as MBYTES_NOT_POPULATED 8 , INMEMORY_COMPRESSION 9 from V$IM_SEGMENTS 10 order by 1,2; OWNER SEGMENT_NAME TABLESPACE_NAME POPULATE_ MBYTES_INMEMORY MBYTES_POPULATED MBYTES_NOT_POPULATED INMEMORY_COMPRESS ---------- ------------------------------ --------------- --------- --------------- ---------------- -------------------- ----------------- TEST INMEM USERS COMPLETED 75.9375 1796 511.5 FOR QUERY LOW SQL> -- しばらくたっても MBYTES_NOT_POPULATED が変化しません。 SQL> select POOL 2 , ALLOC_BYTES / 1024 / 1024 as ALLOC_MBYTES 3 , USED_BYTES / 1024 / 1024 as USED_MBYTES 4 , POPULATE_STATUS 5 from V$INMEMORY_AREA 6 order by 1; POOL ALLOC_MBYTES USED_MBYTES POPULATE_STATUS -------------------------- ------------ ----------- -------------------------- 1MB POOL 79 75 DONE 64KB POOL 16 .9375 DONE SQL> -- 手動でポピュレーションをしてみます。 SQL> exec DBMS_INMEMORY.POPULATE('TEST', 'INMEM'); PL/SQL procedure successfully completed. SQL> select OWNER 2 , SEGMENT_NAME 3 , TABLESPACE_NAME 4 , POPULATE_STATUS 5 , INMEMORY_SIZE / 1024 / 1024 as MBYTES_INMEMORY 6 , BYTES / 1024 / 1024 as MBYTES_POPULATED 7 , BYTES_NOT_POPULATED / 1024 / 1024 as MBYTES_NOT_POPULATED 8 , INMEMORY_COMPRESSION 9 from V$IM_SEGMENTS 10 order by 1,2; OWNER SEGMENT_NAME TABLESPACE_NAME POPULATE_ MBYTES_INMEMORY MBYTES_POPULATED MBYTES_NOT_POPULATED INMEMORY_COMPRESS ---------- ------------------------------ --------------- --------- --------------- ---------------- -------------------- ----------------- TEST INMEM USERS COMPLETED 75.9375 1796 511.5 FOR QUERY LOW SQL> select POOL 2 , ALLOC_BYTES / 1024 / 1024 as ALLOC_MBYTES 3 , USED_BYTES / 1024 / 1024 as USED_MBYTES 4 , POPULATE_STATUS 5 from V$INMEMORY_AREA 6 order by 1; POOL ALLOC_MBYTES USED_MBYTES POPULATE_STATUS -------------------------- ------------ ----------- -------------------------- 1MB POOL 79 77 DONE 64KB POOL 16 .9375 DONE SQL> -- 特に変化が起きません。 |
INMEMORY化を一度解除し、再度メモリに載せます。これにより、OUT OF MEMORYのステータスとなることを確認します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
SQL> -- インメモリ対象から一度除外 SQL> alter table TEST.INMEM no inmemory; SQL> select OWNER 2 , SEGMENT_NAME 3 , TABLESPACE_NAME 4 , POPULATE_STATUS 5 , INMEMORY_SIZE / 1024 / 1024 as MBYTES_INMEMORY 6 , BYTES / 1024 / 1024 as MBYTES_POPULATED 7 , BYTES_NOT_POPULATED / 1024 / 1024 as MBYTES_NOT_POPULATED 8 , INMEMORY_COMPRESSION 9 from V$IM_SEGMENTS 10 order by 1,2; no rows selected SQL> select POOL 2 , ALLOC_BYTES / 1024 / 1024 as ALLOC_MBYTES 3 , USED_BYTES / 1024 / 1024 as USED_MBYTES 4 , POPULATE_STATUS 5 from V$INMEMORY_AREA 6 order by 1; POOL ALLOC_MBYTES USED_MBYTES POPULATE_STATUS -------------------------- ------------ ----------- -------------------------- 1MB POOL 79 0 DONE 64KB POOL 16 0 DONE SQL> -- 再度メモリ化 SQL> alter table TEST.INMEM inmemory; SQL> -- ポピュレーション開始 SQL> select OWNER 2 , SEGMENT_NAME 3 , TABLESPACE_NAME 4 , POPULATE_STATUS 5 , INMEMORY_SIZE / 1024 / 1024 as MBYTES_INMEMORY 6 , BYTES / 1024 / 1024 as MBYTES_POPULATED 7 , BYTES_NOT_POPULATED / 1024 / 1024 as MBYTES_NOT_POPULATED 8 , INMEMORY_COMPRESSION 9 from V$IM_SEGMENTS 10 order by 1,2; no rows selected SQL> select POOL 2 , ALLOC_BYTES / 1024 / 1024 as ALLOC_MBYTES 3 , USED_BYTES / 1024 / 1024 as USED_MBYTES 4 , POPULATE_STATUS 5 from V$INMEMORY_AREA 6 order by 1; POOL ALLOC_MBYTES USED_MBYTES POPULATE_STATUS -------------------------- ------------ ----------- -------------------------- 1MB POOL 79 0 POPULATING 64KB POOL 16 0 POPULATING SQL> -- 少し時間がたつと、 POPULATE_STATUS が STARTED となりポピュレーション開始 SQL> select OWNER 2 , SEGMENT_NAME 3 , TABLESPACE_NAME 4 , POPULATE_STATUS 5 , INMEMORY_SIZE / 1024 / 1024 as MBYTES_INMEMORY 6 , BYTES / 1024 / 1024 as MBYTES_POPULATED 7 , BYTES_NOT_POPULATED / 1024 / 1024 as MBYTES_NOT_POPULATED 8 , INMEMORY_COMPRESSION 9 from V$IM_SEGMENTS 10 order by 1,2; OWNER SEGMENT_NAME TABLESPACE_NAME POPULATE_ MBYTES_INMEMORY MBYTES_POPULATED MBYTES_NOT_POPULATED INMEMORY_COMPRESS ---------- ------------------------------ --------------- --------- --------------- ---------------- -------------------- ----------------- TEST INMEM USERS STARTED 49.5 1796 913.570313 FOR QUERY LOW SQL> select POOL 2 , ALLOC_BYTES / 1024 / 1024 as ALLOC_MBYTES 3 , USED_BYTES / 1024 / 1024 as USED_MBYTES 4 , POPULATE_STATUS 5 from V$INMEMORY_AREA 6 order by 1; POOL ALLOC_MBYTES USED_MBYTES POPULATE_STATUS -------------------------- ------------ ----------- -------------------------- 1MB POOL 79 58 POPULATING 64KB POOL 16 .5625 POPULATING SQL> -- さらに待つと、V$IM_SEGMENTS の POPULATE_STATUS が STARTED から COMPLETED に変化 SQL> select OWNER 2 , SEGMENT_NAME 3 , TABLESPACE_NAME 4 , POPULATE_STATUS 5 , INMEMORY_SIZE / 1024 / 1024 as MBYTES_INMEMORY 6 , BYTES / 1024 / 1024 as MBYTES_POPULATED 7 , BYTES_NOT_POPULATED / 1024 / 1024 as MBYTES_NOT_POPULATED 8 , INMEMORY_COMPRESSION 9 from V$IM_SEGMENTS 10 order by 1,2; OWNER SEGMENT_NAME TABLESPACE_NAME POPULATE_ MBYTES_INMEMORY MBYTES_POPULATED MBYTES_NOT_POPULATED INMEMORY_COMPRESS ---------- ------------------------------ --------------- --------- --------------- ---------------- -------------------- ----------------- TEST INMEM USERS COMPLETED 76.625 1796 459.382813 FOR QUERY LOW SQL> -- V$INMEMORY_AREA の POPULATE_STATUS は "OUT OF MEMORY" となる SQL> select POOL 2 , ALLOC_BYTES / 1024 / 1024 as ALLOC_MBYTES 3 , USED_BYTES / 1024 / 1024 as USED_MBYTES 4 , POPULATE_STATUS 5 from V$INMEMORY_AREA 6 order by 1; POOL ALLOC_MBYTES USED_MBYTES POPULATE_STATUS -------------------------- ------------ ----------- -------------------------- 1MB POOL 79 79 OUT OF MEMORY 64KB POOL 16 .625 DONE |
OUT OF MEMORY となることを確認できました。こちらの検証から、新規追加時でないとOUT OF MEMORYのステータスとならないことが確認できます。
また、ポピュレーションが終わらない場合はMBYTES_NOT_POPULATEDの値がいつまでも残ったままとなることが確認できました。