Oracle Database 12c In-Memory(內存數據庫) 基本原理與簡介

轉    https://blog.csdn.net/stevensxiao/article/details/51437274html

參考文獻算法

https://www.zhihu.com/question/19883454sql

https://blog.csdn.net/zhangzheng0413/article/details/8271322/數據庫

 

Database In-Memory是Oracle數據庫的選項,相似於RAC,ADG,發佈於12.0.1.2。
它的主要目的是利用內存的速度和優化的列格式來加速分析。如下咱們用DBIM或IM做爲Database In-Memory的縮寫。後端

Oracle Database In-Memory 選件

行格式與列格式

傳統的數據庫概念中,行式數據庫適合於OLTP的DML操做,如Oracle, Mysql;而列式數據庫適合於分析,如Sybase IQ, SAP HANA。
而在一個混合負載的環境中,就會面臨兩難的選擇。
DBIM在Oracle傳統的行式存儲以外提供了內存中的列式存儲,而後自動的爲用戶訪問選擇後端的行式或列式存儲,從而解決了此難題。緩存

換句話說,在磁盤上只有一份數據,而在內存中則存在行式的Cache和列式的IM內存數據。
新的IM存儲不會增長雙倍的內存需求,首先由於咱們無需將全部的列式數據都載入內容,其次內存中列式數據能夠壓縮,並且因爲重複值較多,壓縮的比率也較高。
增長了DBIM,一般內存需求會增長20%,具體可使用In-Memory Advisor計算。oracle

雖然列式數據適合於只讀的情形,但並不意味數據不可修改,數據修改後,DBIM自動維護數據的一致性,自動在後臺刷新列式存儲,這一切對於應用都是透明的。app

再次強調,列式數據不是Cache,所以也就沒有Cache中Aging的概念。加載時須要將指定列的全部行數據加載,而不能選擇某些行。性能

內存中列存儲

DBIM在內存中須要預留空間,屬於SGA中的靜態池分,是純列式存儲。列存儲不會取代緩衝區緩存,而是做爲一種補充,以便數據如今可同時以行格式和列格式存儲在內存中。
經過INMEMORY_SIZE控制DBIM內存的大小,至少爲100M,當其大於0時,啓用DBIM功能。
做爲靜態池,對 INMEMORY_SIZE 參數所作的任何更改在重啓數據庫實例後纔會生效。優化

內存中區域可分爲兩個池:一個 1MB 池,用於存儲填充到內存中的實際列格式數據,稱爲In Memory Compression Units (IMCUs);一個 64K 池,用於存儲填充到 IM 列存儲的對象的元數據以及交易的狀態, 稱爲 Snapshot Metadata Units (SMUs)。當數據被修改是,SCU能夠記錄哪些列式數據是過時的,須要修改。

填充內存中列存儲

填充內存中列存儲又稱爲populate。DBIM爲表和物化視圖添加了一個新的 INMEMORY 屬性,具備 INMEMORY 屬性的對象能夠加載到 IM 列存儲。
能夠在表空間、表、(子)分區或物化視圖上指定 INMEMORY 屬性。能夠經過排除法的方式選擇部分列和部分分區,但不能選擇部分行。

ALTER TABLESPACE ts_data INMEMORY; -- 全部表空間中的表 ALTER TABLE sales INMEMORY; -- 表的全部列 ALTER TABLE sales INMEMORY NO INMEMORY(prod_id); -- 表的全部列,除去prod_id ALTER TABLE sales MODIFY PARTITION SALES_Q1_1998 NO INMEMORY; -- 表的全部分區,除去SALES_Q1_1998分區
  • 1
  • 2
  • 3
  • 4

IM 列存儲經過一組稱爲工做進程 (ora_w001_orcl) 的後臺進程進行填充。填充時,數據庫可徹底訪問。
而其它廠商的純內存中數據庫,須要等到全部數據都填充到內存中後,纔可訪問數據庫,但這會引發嚴重的可用性問題。

填充是一種流式機制,填充的同時對數據採用列格式並進行壓縮。
與磁盤上的表空間由多個區段構成同樣,IM 列存儲由多個內存中壓縮單元 (IMCU) 構成。
每一個工做進程分配本身的IMCU,並在其中填充部分數據庫塊。在填充過程當中,數據不以任何特定的方式進行排序或排列。以在行格式中的顯示順序讀取數據。

在數據庫打開後當即以按優先級順序將對象填充到 IM 列存儲,或首次掃描(查詢)對象後將其填充到 IM 列存儲。對象的加載順序經過關鍵字 PRIORITY 進行控制,關鍵字 PRIORITY 有五個級別。默認 PRIORITY 爲 NONE,這表示只在首次掃描對象後纔將其填充。

對於索引組織表 (IOT)和集羣表,因爲其特性是面向OLTP的,DBIM不支持,另外如LONG何out-of-line LOB也不支持。
目前DBIM還沒法再ADG的standby實例中使用,將來會支持,這樣能夠利用災備站點作分析,提高其ROI。

內存中壓縮

一般只將壓縮視爲節省空間的一種機制。可是,填充到 IM 列存儲的數據是使用一組新壓縮算法進行壓縮的,這謝新壓縮算法不只有助於節省空間,並且還能提升查詢性能。這種新的 Oracle 內存中壓縮格式容許直接對壓縮的列執行查詢。這意味着,將對很是少許的數據執行全部掃描和篩選操做。僅當結果集須要數據時才解壓縮數據。 使用關鍵字 MEMCOMPRESS(INMEMORY 屬性的分子句)指定內存中壓縮。有六個級別,每一個級別提供不一樣的壓縮級別和性能。

默認狀況下,使用 FOR QUERY LOW 選項壓縮數據,該選項提供最佳的查詢性能。這種方式的壓縮對於性能影響不大的緣由是其使用的是字典壓縮,其實就是重複數據刪除。

能夠對一個表內的各個列或各個分區使用不一樣的壓縮技術,例如:

CREATE TABLE employees ( c1 NUMBER, c2 NUMBER, c3 VARCHAR2(10), c4 CLOB ) INMEMORY MEMCOMPRESS FOR QUERY NO INMEMORY(c4) INMEMORY MEMCOMPRESS FOR CAPCITY HIGH(c2);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

使用何種壓縮可使用Oracle Compression Advisor (DBMS_COMPRESSION)來評估。

內存中掃描

內存中掃描速度快取決於如下因素。

列式存儲

這時最根本的,分析只訪問部分列,這樣避免了大量I/O,好處相似於分區,只不過是垂直分區。

Storage Index

在Exadata中已經出現過此技術,在DBIM中原理是同樣的。內存中存儲索引跟蹤 IMCU 中各列的最小值和最大值,好處相似於分區修剪。

存儲索引自動的維護在內存中,不過每次重啓不知道是否須要從新算。

SIMD 向量處理

SIMD又稱爲single instruction processing multiple data。SIMD並不是Oracle的技術,最初用於計算機生成動畫和高性能計算。

好處是SIMD 向量處理容許發出一條 CPU 指令來估算一組列值,而不是一次估算列中的一個條目

內存中 Join

除了內存速度外, Join的快取決於Bloom Filter,Bloom Filter於Oracle Database 10g引入。

bloom filter的原理須要解釋一下:

A bloom filter transforms a join to a filter that can be applied as part of the scan of the fact table. Bloom filters were originally introduced in Oracle Database 10g to enhance hash join performance and are not specific to Oracle Database In-Memory. However, they are very efficiently applied to columnar data via SIMD vector processing.

Here is a brief description of how they work: When two tables are joined via a hash join, the first table (typically the smaller table) is scanned and the rows that satisfy the ‘where’ clause predicates (for that table) are used to create a hash table. During the hash table creation a bit vector or bloom filter is also created based on the join column. The bit vector is then sent as an additional predicate to the second table scan. After the where clause predicates have been applied to the second table scan, the resulting rows will have their join column hashed and it will be compared to values in the bit vector. If a match is found in the bit vector that row will be sent to the hash join. If no match is found then the row will be discarded. On Exadata the bloom filter or bit vector is passed as an additional predicate so it will be offloaded to the storage cells making bloom filtering even more efficient.

這裏的關鍵是vector table是根據join的column計算的,若是有多個join則有多個vector table。能夠參考Bloom Filters by Example

內存中 Aggregation

分析式查詢一般須要的不只僅是簡單篩選和聯接。它們須要複雜的聚合和彙總。Oracle Database 12.1.0.2 中引入了一個新優化器轉換(稱爲 Vector Group By),可以確保可以使用有效利用 CPU 的新算法處理更復雜的分析查詢。

典型的Aggregation指相似於Group By之類的語句,其它還包括SUM, AVG, MIN, MAX等。

DML 和內存中列存儲

分析的數據不多會改動,但在混合負載的環境下,若是數據修改了,對於DBIM會有何影響?

對於批量數據加載,DBIM建議和分區之前使用,從而能夠提供最佳性能。

對於DML修改,數據變化在行式緩存中修改,這和之前同樣,而後在SCU(前面提到過)中會標記DBIM中的哪些數據是陳舊的,當訪問到這些數據時就會結合日誌返回最新的數據,後續在合適的時候會更新DBIM中的數據。

IMCU 中的陳舊條目越多,IMCU 的掃描速度就越慢。所以,當 IMCU 中的陳舊條目數達到陳舊程度閾值時,Oracle 數據庫將從新填充 IMCU。

IMCO (內存中協調器)每隔兩分鐘就喚醒一次,檢查是否有任何填充任務須要完成。

IM 列存儲保持事務一致性帶來的開銷隨應用程序而異,具體取決於多種因素,其中包括:更改速度、爲表選擇的內存中壓縮級別、更改行的位置以及執行的操做類型。具備較高壓縮級別的表將比具備較低壓縮級別的表產生的開銷要多。

對於具備高 DML 速率的表,建議使用 MEMCOMPRESS FOR DML,此外,若是可能,還建議使用分區在表內定位更改。

總之對應用是透明的,數據也是一致的。原理看如下兩張圖就足夠了。

RAC 上的內存中列存儲

RAC 環境中的每一個節點均可以有其本身獨立的 IM 列存儲。對於不須要 IM 列存儲的任何 RAC 節點,應將 INMEMORY_SIZE 參數設爲 0。

強烈建議將每一個 RAC 節點的 IM 列存儲設置爲相同的大小。

能夠在每一個節點上填充徹底不一樣的對象,也能夠在集羣的全部 IM 列存儲間分佈(DISTRIBUTE)較大的對象。
還能夠在每一個節點的 IM 列存儲中存儲相同的對象(DUPLICATE,僅限工程化系統)。
對象在集羣中各個 IM 列存儲間的分佈經過 INMEMORY 屬性的兩個附加分子句進行控制:DISTRIBUTE 和 DUPLICATE。

默認狀況下,Oracle 基於使用的分區類型(若是有)決定在集羣中分佈對象的最佳方式。或者,能夠指定 DISTRIBUTE BY ROWID RANGE 按 rowid 範圍分佈,指定 DISTRIBUTE BY PARTITION 將分區分佈給不一樣的節點,或指定 DISTRIBUTE BY SUBPARTITION 將子分區分佈給不一樣的節點。

RAC可使用DISTRIBUTE來實現分佈和並行處理,Exadata上的RAC能夠再加上DUPLICATE實現容錯和增長並行度。

DUPLICATE能夠只複製到另外一個RAC節點,或經過DUPLICATE ALL複製到全部的節點,不過複製和爲維護一致性帶來的開銷應較大。

多租戶環境中的內存中列存儲

Oracle Multitenant 是一個新的數據庫整合模型,在該模型中,多個可插拔數據庫 (PDB) 整合在一個容器數據庫 (CDB) 中。在保持單一數據庫的多個隔離特性的同時,它還支持多個 PDB 共享一個通用 CDB 的系統全局區域 (SGA) 和後臺進程。所以,多個 PDB 也共享一個 IM 列存儲。

IM 列存儲的總大小經過在 CDB 中設置 INMEMORY_SIZE 參數進行控制。經過設置每一個 PDB 的 INMEMORY_SIZE 參數,來指定其可以使用的共享 IM 列存儲的大小。並不是給定 CDB 中的全部 PDB 都須要使用內存中列存儲。一些 PDB 能夠將 INMEMORY_SIZE 參數設爲 0,這意味着它們根本不使用內存中列存儲。

PDB 的 INMEMORY_SIZE 參數的總和無需小於或等於 CDB 的 INMEMORY_SIZE 參數的大小。PDB 能夠過分使用 IM 列存儲。容許過分使用可確保某個可插拔數據庫關閉或拔出的狀況下不浪費 IM 列存儲的寶貴空間。因爲 INMEMORY_SIZE 參數是靜態的(須要數據庫實例重啓才能反映更改),最好容許 PDB 過分使用,以即可以使用 IM 列存儲的全部空間。

可是,因爲這種過分使用,一個 PDB 可能會搶佔另外一個 PDB 在 IM 列存儲中的空間。若是不但願任何 PDB 長時間關閉或拔出,建議不採用過分使用。

控制 Oracle Database In-Memory 的使用

核心初始化參數

  • INMEMORY_SIZE - 大於0時啓用DBIM.該參數只能在系統級進行修改,且須要數據庫重啓才能生效
  • INMEMORY_QUERY - 能夠在會話級或系統級將 INMEMORY_QUERY 設置爲 DISABLE,來禁用 IM 列存儲。默認值爲 ENABLE。
  • INMEMORY_MAX_POPULATE_SERVERS - 能夠啓動的最大工做進程數經過 INMEMORY_MAX_POPULATE_SERVERS 進行控制,該參數默認設置爲 0.5 X CPU_COUNT。減小工做進程數將減小填充過程當中佔用的 CPU 資源,但可能會延長填充 IM 列存儲所花費的時間。

優化器提示

如 SELECT /+ NO_INMEMORY /

監視和管理 Oracle Database In-Memory

哪些對象位於內存中列存儲中

存在兩個新的 vv

IM_SEGMENTS 和 v$IM_USER_SEGMENTS,這兩個視圖可指示目前填充到 IM 列存儲的對象。

SQL> SELECT v.owner, v.segment_name name, v.populate_status status, v.bytes_not_populated FROM v$im_segments v; OWNER NAME STATUS BYTES_NOT_POPULATED ---------- --------------- --------- ------------------- SSB DATE_DIM COMPLETED 0 SSB PART COMPLETED 0 SSB SUPPLIER COMPLETED 0 SSB LINEORDER STARTED 835780608 SSB CUSTOMER COMPLETED 0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

USER_TABLES

向 *_TABLES 字典表中添加了一個新的布爾型列(稱爲 INMEMORY),以指示對哪些表指定了 INMEMORY 屬性。

SQL> SELECT table_name, cache, inmemory, inmemory_priority, inmemory_distribute,inmemory_compression FROM user_tables; TABLE_NAME CACHE INMEMORY INMEMORY INMEMORY_DISTRI INMEMORY_COMPRESS ---------- -------------------- -------- -------- --------------- ----------------- DATE_DIM Y ENABLED NONE AUTO FOR QUERY LOW LINEORDER Y ENABLED NONE AUTO FOR QUERY LOW SUPPLIER Y ENABLED NONE AUTO FOR QUERY LOW CUSTOMER Y ENABLED NONE AUTO FOR QUERY LOW PART Y ENABLED NONE AUTO FOR QUERY LOW
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

管理 IM 列存儲填充的 CPU 佔用

IM 列存儲的初始填充是 CPU 密集型操做,可能會影響同時運行的其餘負載的性能。可使用 Resource Manager2 控制 IM 列存儲填充操做的 CPU 使用,並根據須要更改操做的優先級。

參考

相關文章
相關標籤/搜索