12C新特性___In-Memory列式儲存的總結

lusklusklusk發表於2020-03-08

官方文件


The IM column store encodes data in a columnar format: each column is a separate structure. The columns are stored contiguously, which optimizes them for analytic queries. The database buffer cache can modify objects that are also populated in the IM column store. However, the buffer cache stores data in the traditional row format. Data blocks store the rows contiguously, optimizing them for transactions.

When you enable an IM column store, the SGA manages data in separate locations: the In-Memory Area and the database buffer cache. 

The IM column store maintains copies of tables, partitions, and individual columns in a special compressed columnar format that is optimized for rapid scans. 

In-Memory Column Store意思就是In-Memory列式儲存,每一列都是一個單獨的結構,它的優點就是隻需要訪問表的部分列,不像database buffer cache以傳統的行格式儲存資料,需要訪問表的所有列。但是傳統的database buffer cache也可以修改填充在In-Memory記憶體中的物件。

In-Memory列式儲存特性開啟後資料庫啟動時會在SGA中分配一塊靜態的記憶體池In-Memory Area,用於存放以In-Memory列式儲存的使用者表。

In-Memory列式儲存以一種特殊的壓縮列格式維護表、分割槽和單個列的副本,這種格式是為快速掃描而最佳化的。


In memory記憶體中的資料的同步機制

一旦載入到In memory記憶體中的表涉及DML了,就需要一種機制保證In memory記憶體中的資料的一致性,因為DML語句的修改在記憶體中僅修改database buffer cache和log buffer,如何把這些修改的資料同步到In memory記憶體中呢。Oracle 是透過Transaction journal來確保資料的一致性的。如果DML語句修改的表已經存在In memory記憶體中,在DML提交後就把該DML的後設資料比如表名tablename和行號rowid記錄到transaction journal,並把該表在In memory記憶體中的SCN標識為過期。如果後面新的查詢需要訪問該表在In memory記憶體中的資料,就會根據該表原來在In memory記憶體中的資料+transaction journal+database buffer cache進行訪問

當然,如果DML語句不斷髮生的話,就會使transaction journal的資料越來越多,甚至出現In memory記憶體中的大部分資料都是過期的舊資料,這對於in memory查詢的效能傷害是很大的。所以,Oracle定義了一個閥值staleness threshold,當in memory中舊資料的比例達到這個閥值時就會觸發Repopulate的過程,oracle預設2分鐘就會檢查一次是否觸發了該閥值



In-Memory列式儲存涉及引數


In-Memory列式儲存涉及的檢視



關於In-Memory的一些總結

1、資料庫級別啟用In-Memory列式儲存的兩個前提條件:MEMORY_TARGET必須設定且大於100M;COMPATIBLE引數必須設定且大於12.1.0

2、表空間、表、分割槽和物化檢視都可以啟用In-Memory列式儲存,當前表空間啟用In-Memory列式儲存後,預設為該表空間下以後新增所有表和物化檢視都啟用了In-Memory列式儲存,該表空間下之前已經存在的表不受影響,設定表空間啟用In-Memory列式儲存時INMEMORY關鍵字前面必須加default

3、表級別啟用In-Memory列式儲存的前提條件:create table或alter table時指定了INMEMORY

4、查詢表是否啟用In-Memory列式儲存,參見USER_TABLES.INMEMORY是否等於'ENABLED',等於ENABLED說明啟用了

5、 表已經啟用In-Memory列式儲存不代表該表的資料就已經自動載入到In-Memory記憶體中,只有在例項啟動或訪問該物件時才會載入到In-Memory記憶體中,如果想把表資料立即載入到In-Memory記憶體中,則對該表強制執行全表掃描或使用DBMS_INMEMORY.POPULATE即可。 只要物件In-Memory列式儲存的PRIORITY的級別不是none,則例項啟動或該物件對應的PDB啟動時會自動載入該物件到In-Memory記憶體中,檢視錶的資料是否已經進入了In-Memory記憶體區,參見V$IM_SEGMENTS.SEGMENT_NAME。 某表已經存在V$IM_SEGMENTS的話,truncate table後V$IM_SEGMENTS中該表記錄消失,delete table後V$IM_SEGMENTS中該表記錄還在

6、12.2.0版本開始可以使用ILM ADO POLICY對In-Memory列式儲存進行相應設定,ILM ADO POLICY在資料庫級別生效,而不是例項級別,Information Lifecycle Management (ILM) Automatic Data Optimization (ADO) POLICY資訊生命週期管理自動資料最佳化政策意思就是可以決定In-Memory列式儲存在哪張表上什麼時候什麼情況下生效,什麼時候什麼情況下失效。ALTER TABLE TABLE_NAME ILM ADD POLICY SET|MODIFY|NO INMEMORY

7、可以只把表的特定欄位列啟用In-Memory,使用inmemory指定這些特定欄位,同時必須使用no inmemory把剩餘的列寫進去,欄位列啟用In-Memory的話,其中列的型別不能是LONG or LONG RAW column, an out-of-line column (LOB, varray, nested table column), or an extended data type column,某表只有部分欄位列啟用In-Memory的話,透過USER_TABLES.INMEMORY='ENABLED'查不到該表,可以透過V$IM_COLUMN_LEVEL.INMEMORY_COMPRESSION<>'NO INMEMORY'來查

8、無法使用In-Memory列式儲存的物件有:Indexes、Index-organized tables、Hash clusters、Objects owned by the SYS user and stored in the SYSTEM or SYSAUX tablespace、If you enable a table for the IM column store and it contains any of the following types of columns, then these columns will not be populated in the IM column store:Out-of-line columns (varrays, nested table columns, and out-of-line LOBs)、Columns that use the LONG or LONG RAW data types、Extended data type columns

9、如果不指定inmemory的priority優先順序別,預設是none,則只有全表掃描訪問物件時才會把該物件放入In-Memory記憶體中。透過索引掃描或透過rowid獲取該物件都不會把該物件放入In-Memory記憶體中。如果priority級別不是none,則在資料庫啟動過程中會自動把物件In-Memory放入記憶體中,或根據優先順序別把物件放入In-Memory記憶體中

10、如果不指定inmemory的MEMCOMPRESS壓縮級別,預設是MEMCOMPRESS FOR QUERY LOW

11、如果不指定DUPLICATE時,預設就是NO DUPLICATE,只有RAC環境且是Oracle Engineered System環境才能使用DUPLICATE或DUPLICATE ALL,否則就算是使用了DUPLICATE或DUPLICATE ALL也不起作用,還是當成NO DUPLICATE.

12、如果不指定distribute時,預設是auto,預設存在IM中的表會分佈在各個節點之中。只有RAC環境才能使用distribute

13、關於populate和repopulate的區別,populate是把磁碟上的現有資料轉換為列格式並存放到In-Memory記憶體中,repopulate是把將新資料載入到In-Memory記憶體中,可以簡單理解為populate初始化全量刷資料進入In-Memory記憶體中,repopulate是增量刷資料進入In-Memory記憶體中




一些實驗結果

1、表空間設定為inmemory

建立表空間或修改表空間為inmemory,inmemory關鍵字前面必須加上default

SQL> create tablespace tablespace1 datafile '/u02/data/tablespace2.dbf' size 100M inmemory;

ERROR at line 1:

ORA-02180: invalid option for CREATE TABLESPACE

SQL> create tablespace tablespace1 datafile '/u02/data/tablespace2.dbf' size 100M default inmemory;

Tablespace created.

SQL> alter tablespace USERS inmemory;

ERROR at line 1:

ORA-02142: missing or invalid ALTER TABLESPACE option

SQL> alter tablespace USERS default inmemory;

Tablespace altered.


2、表設定為inmemory

如果create table as方式,則inmemory放在as前面

create table table1 (hid number(10)) inmemory;

alter table table2 inmemory;

create table t4 inmemory as select * from t1;--t4啟用了In-Memory列式儲存

create table t5 as select * from t1 inmemory;--t5沒有啟用了In-Memory列式儲存


3、物化檢視設定為inmemory

create materialized view mview1 inmemory as select * from table1;

alter materialized view mview2 inmemory 


4、分割槽表某些分割槽設定為inmemory

建表是最後兩個分割槽SALES_Q4_2019、SALES_Q1_2020都沒有啟用In-Memory列式儲存,參見user_tab_partitions.inmemory,最後修改SALES_Q4_2019分割槽啟用In-Memory列式儲存

CREATE TABLE sales1( prod_id NUMBER(6),time_id DATE,channel_id varchar2(100)) 

PARTITION BY RANGE (time_id)

(PARTITION SALES_Q1_2019 

      VALUES LESS THAN (TO_DATE('01-APR-2019','DD-MON-YYYY')) INMEMORY,

 PARTITION SALES_Q2_2019

      VALUES LESS THAN (TO_DATE('01-JUL-2019','DD-MON-YYYY')) INMEMORY,

 PARTITION SALES_Q3_2019 

      VALUES LESS THAN (TO_DATE('01-OCT-2019','DD-MON-YYYY')) INMEMORY,

 PARTITION SALES_Q4_2019 

      VALUES LESS THAN (TO_DATE('01-JAN-2020','DD-MON-YYYY')) NO INMEMORY,

 PARTITION SALES_Q1_2020 

      VALUES LESS THAN (MAXVALUE));

alter table sales1 modify partition SALES_Q4_2019 inmemory;


5、欄位列設定為inmemory

如下建立的表table1,只有CREATED_APPID欄位沒有啟用In-Memory列式儲存,其他列都啟用了

所以一張表只要某些列設定為inmemory時,必須使用no inmemory把剩餘的列寫進去

create table table1 as select * from dba_objects;

alter table table1 inmemory (OWNER) no inmemory (CREATED_APPID);





When a database is restarted, all of the data for database objects with a priority level other than NONE are populated in the IM column store during startup. 

重新啟動資料庫後,在啟動期間,優先順序比NONE高的資料庫物件的所有資料都將載入進入In-Memory中。


Population

The operation of reading existing data blocks from data files, transforming the rows into columnar format, and then writing the columnar data to the IM column store. In contrast, loading refers to bringing new data into the database using DML or DDL.

Population, which transforms existing data on disk into columnar format, is different from repopulation, which loads new data into the IM column store. Because IMCUs are read-only structures, Oracle Database does not populate them when rows change. Rather, the database records the row changes in a transaction journal, and then creates new IMCUs as part of repopulation

從資料檔案讀取現有資料塊,將行轉換為列格式,然後將列資料寫入IM列儲存的操作。 相反,loading是指使用DML或DDL將新資料帶入資料庫。

Population是將磁碟上的現有資料轉換為列格式,Population不同於將新資料載入到IM列儲存中的repopulation。 因為IMCU是隻讀結構,所以當行更改時,Oracle資料庫不會填充它們。 而是,資料庫將行更改記錄在transaction journal中,然後建立新的IMCU作為repopulation的一部分


IMCU

An In-Memory Compression Unit (IMCU) is a compressed, read-only storage unit that contains data for one or more columns.

記憶體中壓縮單元(IMCU)是一種壓縮的只讀儲存單元,其中包含一個或多個列的資料。


Transaction journal

Metadata in a Snapshot Metadata Unit (SMU) that keeps the IM column store transactionally consistent.

快照後設資料單元(SMU)中的後設資料,可以使IM列儲存在事務上保持一致。


Every SMU contains a transaction journal. The database uses the transaction journal to keep the IMCU transactionally consistent.

The database uses the buffer cache to process DML, just as when the IM column store is not enabled. For example, an UPDATE statement might modify a row in an IMCU. In this case, the database adds the rowid for the modified row to the transaction journal and marks it stale as of the SCN of the DML statement. If a query needs to access the new version of the row, then the database obtains the row from the database buffer cache.

The database achieves read consistency by merging the contents of the column, transaction journal, and buffer cache. When the IMCU is refreshed during repopulation, queries can access the up-to-date row directly from the IMCU.

每個SMU都包含一個transaction journal。 資料庫使用transaction journal來使IMCU保持事務一致。

與未啟用IM列儲存時一樣,資料庫使用緩衝區快取記憶體來處理DML。 例如,一條UPDATE語句可能會修改IMCU中的一行。 在這種情況下,資料庫將已修改行的行標識新增到transaction journal中,並從DML語句的SCN開始將其標記為過期。 如果查詢需要訪問該行的新版本,則資料庫從資料庫緩衝區快取記憶體中獲取該行。

資料庫透過合併列,transaction journal和緩衝區快取記憶體的內容來實現讀取一致性。 在重新填充期間重新整理IMCU時,查詢可以直接從IMCU訪問最新行。


Repopulation

The automatic refresh of a currently populated In-Memory Compression Unit (IMCU) after its data has been significantly modified. In contrast, population is the initial creation of IMCUs in the IM column store.

在當前populated記憶體中壓縮單元(IMCU)的資料進行了重大修改之後,它會自動重新整理。 相反,population是IM列儲存中IMCU的初始建立。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30126024/viewspace-2679039/,如需轉載,請註明出處,否則將追究法律責任。

相關文章