1. 程式人生 > 其它 >記憶體為王:DBIM RAC Share Nothing架構的挑戰和解決方案

記憶體為王:DBIM RAC Share Nothing架構的挑戰和解決方案

陳煥生

Oracle Real-World Performance Group 成員,senior performance engineer,專注於 OLTP、OLAP 系統 在 Exadata 平臺和 In-Memory 特性上的最佳實踐。個人部落格 http://dbsid.com 。

DBIM 概述

Database In-Memory (DBIM) 是 Oracle 在 12.1.0.2 中引入的新特性,旨在加速分析型 SQL 的速度。In-Memory Columnar Store(IM列式儲存)是位於 SGA 中獨立於 Buffer Cache 的記憶體區域。只要設定表的 inmemory 屬性,就可以把表的資料載入到 IM 列式儲存。資料可以同時存在於 buffer cache 和 IM 列式儲存,傳統資料按行組織,以資料塊為單位存於 buffer cache 和磁碟上,資料在 IM 列式儲存中按照列式組織的。傳統的 OLTP 應用依然通過 buffer cache 修改資料,Oracle 通過內部機制保證行式儲存和列式儲存的事務一致性。分析性的 SQL 從 IM 列式儲存中掃描資料,避免物理讀成為效能瓶頸。

與表空間類似,表空間中包含表或者索引等 segment,segment 由 extent 組成;IMCS 包含多個 In-memory segments,每個 IM segment 以 In-Memory Compress Unit (IMCU) 為儲存單元。對於大部分 In-memory 壓縮格式,每個 IMCU 預設包含 512k 行記錄。

DBIM 帶來的效能飛躍主要來自兩方面,更詳細的介紹請參考官方白皮書 (http://www.oracle.com/technetwork/database/in-memory/overview/twp-oracle-database-in-memory-2245633.html):

硬體方面:

  1. 列式儲存方便利用 CPU 的單指令多資料 (SIMD) 實現加速。對於英特爾 CPU,當前版本使用高階向量擴充套件指令集 AVX (Advanced Vector Extensions)。
  2. 消除了掃描資料的物理 IO,避免掃描大量資料成為瓶頸。注意 DBIM 特性對於 join 過程所需的臨時表空間 IO 沒有影響。

軟體特性方面:

  1. In-memory 列壓縮,有六種壓縮級別可以選擇,需要對記憶體空間和解壓縮增加的CPU做權衡。對於預設的 query low 級別,常見的壓縮比為 2 ~ 10 之間。
  2. In-memory storage index,與 Exadata 的特性類似,會維護 IMCU 中每列的最小值和最大值。如果過濾條件中的值不在最小值和最大值之間,當前 IMCU 會被直接跳過,提高掃描的速度。
  3. Bloom filter,DBIM 支援 bloom filter,掃描 IMCU 時第一時間過濾不符合 join 條件的資料。
  4. In-memory Aggregation,即 Vector group by transformation,可視為 Bloom filter 的增強版。對於小表 join 大表並且帶 group by 的語句,這個新特性會對效能帶來巨大的提升。

DBIM RAC share nothing 的分佈架構

當前版本中,Oracle 只在 Engineered system(如 Exadata、SupperCluster)上支援 RAC 多例項實現 IMCU 映象,由 duplicate 或者 duplicate all 屬性控制 IMCU 分佈到兩個例項或者全部的例項。對於非 Engineered system,在 RAC 系統使用 DBIM 時,duplicate 屬性不起作用,所有載入到 IM 列式儲存的表或者分割槽,IMCU 會分佈到所有例項。分佈方式通過 distribute 屬性控制,有三種方法:

  1. By PARTITION
  2. By SUBPARTITION
  3. By ROWID RANGE

預設為 distribute auto。自動選擇以上三種分佈方式的一種。對於分割槽表,會選擇 by partition 或者 by subpartition 的方式,取決於哪個分割槽維度的 cardinality 更大。比如表有 64 個分割槽,每個分割槽有 32 個子分割槽,分割槽維度的 cardinality 更大,那麼選擇 by partition 的分佈,每個分割槽的所有資料都分佈在一個例項上。如果表有 32 個分割槽,每個分割槽包含 64 個子分割槽,會選擇 by subpartition 分佈,子分割槽迴圈分佈在各個節點。為了利用 Partition Wise Join,在連線鍵上所做的 hash 分割槽,匹配的 hash 分割槽會分佈在相同節點上。對於非分割槽表,只能為 by rowid range 分佈方式,資料以地址區間為單位分佈到每個例項。

RAC 是 share everything 架構,通過 Cache Fusion 機制,資料塊可以通過 interconnect 在例項間傳輸。DBIM 在 RAC 上採用 share nothing 架構,IMCU 不能在例項間傳輸,每個例項上 IMCU 只能由當前例項的程序掃描。這帶來兩個問題:

  1. 查詢 IMC 表時,必須使用並行查詢,而且並行度不能小於例項的個數,每個例項都至少一組並行程序,保證所有的資料都從 IMCU 中獲得。
  2. IMCU 分佈在每個例項,不能共享,資料分佈架構上的不同可能會對效能帶來戲劇性的影響。

本文我們通過一個星型模式上的測試,闡述 DBIMRAC share nothing 的分佈架構帶來的挑戰和解決方法,以及如何合理使用 DBIM 特性,獲得最佳的效能。

術語說明:

  1. IMC 表:全表或者部分分割槽載入到 In-memory 列式儲存的表。
  2. IMC 查詢:inmemory_query=enable,並且查詢至少涉及一個 IMC 表。
  3. DoP:Degree of Parallelism,查詢的並行度。
  4. AutoDoP:當引數 parallel_degree_policy 設為 auto,查詢由優化器自行決定並行度。執行計劃的 Note 部分會顯示 AutoDoP 的資訊。比如:
  1. QC:並行查詢的 Query Coordinator

測試的 schema

這是一個典型的星型模型,事實表 lineorder 有 3 億條記錄,維度表 part/customer/supplier 的資料在 1 百萬左右,三個維度表沒有進行分割槽。為了說明使用 DBIM 時,分割槽資料傾斜可能造成並行執行傾斜的問題,我使用事實表 lineorder 的 LO_STATUS 欄位做列表分割槽,使每個分割槽的資料量和大小都嚴重傾斜。

表名

行數

lineorder

300005811

part

1200000

customer

1500000

supplier

100000

通過以下指令碼載入到把 4 個表載入到 IM 列式儲存,首先我們選擇 distribute auto 的分佈方式,因為測試環境為 Exadata 兩個節點的 RAC,為了模擬非 Engineered system 平臺的 RAC,我需要指定 No Duplicate 屬性,優先順序 critical 使得 IMC 表在後臺可以被自動載入,壓縮級別為預設的 query low。

從 gv$im_segments 可以看到,表 customer 通過 by rowid range 分佈載入到節點 1 和 2;bytes_not_populated 表明多少資料沒有被載入到當前例項。表 part 和 supplier 較小沒有分佈到兩個節點,part 被載入到節點 1,supplier 被載入到節點 2。對於事實表lineorder,實際是按 by partition 被載入到兩個節點的,因為每個分割槽的 IMCU 都只存在於一個節點。而且在 by partition 的分佈模式下,分割槽資料的傾斜會造成 IMCU 分佈的傾斜。其中最大的分割槽 P_STATUS_COM 大小為 28.6G,全部分佈示例 2,在例項 2 所佔 IM 列式儲存大小為 14.3G,壓縮比大概為2。

DBIM RAC 與並行查詢以及 AutoDoP 的關係

並行查詢

因為 IMCU 被分佈兩個例項上,為了從 IMCU 獲得所有的資料,而不是從 buffer cahce、global cache 或者通過直接路徑讀得到,我們必須使用並行查詢,而且查詢的並行度必須至少為例項的個數,才能保證每個例項都有一組並行程序掃描 IMCU。

AutoDoP

並行查詢時,為了使 QC 意識到到 IM Segment 的分佈方式和每個 IMCU 位置,並分配相應的並行程序從 IMCU 中掃描資料,必須使用 AutoDoP (parallel_degree_policy=auto)。這是強制的要求,設定 parallel_degree_policy=limited 也不行。如果不使用 AutoDoP,而且非 engineered system 平臺,IMCU 不能在每個例項複製 (duplicate all),sql 執行的過程中將很可能出現物理讀。

下面是一個例子:

  1. 當 parallel_degree_policy=manual 時,執行時間為 3s,db time 為 9s。執行需要出現 1.9M 的 buffer gets,15GB 的物理讀,為表大小的一半。並行掃描的工作方式為“PX BLOCK ITERATOR”,px granule 為 rowid range,例項 1 和 2 上的並行程序平均掃描lineorder。QC 此時並沒有意識到大部分 IMCU 都分佈在例項 2 上,例項 1 需要通過物理讀獲取資料,大部分物理讀出現在例項 1。Cell Offload Efficiency=88%,通過 Smart Scan 把資料掃描過濾工作解除安裝到儲存節點,15GB 的物理 IO 請求,解除安裝到儲存節點掃描處理之後,只需返回 2GB 給例項 1,大大節省了計算節點的 CPU。 parallel_degree_policy=manual
  1. 當 parallel_degree_policy=auto 時,執行時間為 2s,db time 為 3.6s。Buffer gets 為 1914,所有資料從 IMCU 從掃描獲得,物理讀被消除了。因為大部分 IMCU 都分佈在例項 2 上,例項 2 的並行進行承擔了大部分的工作。 parallel_degree_policy=auto

IMCU 和例項的關聯性,並行執行傾斜

DBIM 是 share nothing 的架構,IMCU 不能在例項之間傳輸。下圖為使用 AutoDoP 全表掃描 lineorder 時各個並行程序消耗的 CPU 資源。因為分割槽 P_STATUS_COM 只分布在例項 2 上,例項 2 上兩組並行程序完成了絕大部分掃描工作,例項 1 的並行程序基本處於空閒的狀態。下圖直觀顯示了 IMCU 分佈傾斜會造成並行執行傾斜,無法同時利用兩個節點的 CPU 能力。這就是為什麼 db time=3.6s,DoP=4,執行時間還需要 2s。理想情況 4 個並行程序平均工作的話應該執行時間應該在 1s 之內。

parallel_degree_policy=auto

並行執行傾斜的另一個例子

對於星型模型的並行查詢時的執行計劃,一般都是一顆右深樹。對維度表的並行分發 (distribution) 都是 PX SEND BROADCAST,事實表因為資料量大不用進行分發。因為 Lineorder 大部分 IMCU 都分佈在例項 2,資料通過例項 2 上的並行程序掃描過濾之後,在之後整個的執行路徑中,lineorder 的資料不會再分發給例項 1 的並行程序,後序大部分資料的 hash join 和 hash group by 操作,都由例項 2 上的負責掃描 IMCU 的並行程序完成的,這時並行執行傾斜的情況會更嚴重。我將在這一小節通過一個典型查詢闡述這種情況。

測試之前的準備:

設定 _px_replication_enabled=false,使每個維度表都使用 PX SEND BROADCAST 的方式分發,12c 中,維度表可以由每組掃描事實表的並行程序重複掃描,避免使用 BROADCAST 分發,為了方便讀者熟悉執行計劃,使每個維度表都進行 broadcast 分發,我在這個測試中特意關掉這個特性。實際使用中,不建議修改這個引數。

設定 optimizer_adaptive_features=false 和 optimizer_dynamic_sampling=4 是為了避免使用 in-memory 查詢時出現硬解析過長的情況。

我們執行三次查詢,對比不使用 Smart Scan、使用 Smart Scan 和使用 IMC 查詢時的效能。

查詢的 sql 如下:

為了閱讀的方便,在下面的輸出中,三次以上查詢的 sql 和 125 條結果集被省略。

以上輸出看到,不使用 Exadata 的殺手鐗 Smart Scan,sql 執行需要 28s;使用 Smart Scan 執行時間為 5s;啟用 IMC 查詢時,執行時間為 14s。下面我們通過 sql monitor report 來分析三次執行的效能差別,尤其是 IMC 查詢為什麼比使用 Smart Scan 的版本慢。(P.S. 我常常覺得驚訝:DBA/開發並不習慣使用 sql monitor report 除錯問題。從 11g 開始,sql monitor report 無疑是研究 Oracle 效能問題最重要的利器,大部分的效能問題都可以從 sql monitor report 中找到原因或者線索,推薦讀者在實際工作中使用 active 格式的 sql monitor report 分析問題)

  1. 三次執行的執行計劃是一樣的,Plan Hash Value=1915476107,這是一個典型的右深樹,三個維表的分發方式都為 broadcast。執行計劃 18 行為 JOIN FILTER CREATE,為掃描維度表 part 分發之後建立的 bloom filter(:BF0000);25 行在掃描 lineorder 的時候使用 bloom filter(:BF0000) 作為過濾條件,predicate information 部分顯示 25 行的條件為: storage(SYS_OP_BLOOM_FILTER(:BF0000,"LINEORDER"."LO_PARTKEY"))。其中 storage 說明這個條件可以被解除安裝到儲存節點,函式 SYS_OP_BLOOM_FILTER 在連線鍵 LO_PARTKEY 列上通過 :BF0000 做過濾,在第一時間把資料量從 300M 過濾為 16M(參見後面的 sql monitor report 的 Actual Rows 列)。
  1. 不使用 Smart Scan,sql 執行時間為 28s;db time(QC 加上所有並行程序使用的 db time 之和)為 1.4 分鐘,其中對 Lineorder 表的掃描過濾花了 65% 的 db time,為 54.6s,因為計算節點的並行程序需要通過直接路徑讀,掃描 Lineorder 全部 30GB 的資料,同時使用 bloom filter 進行過濾。SQL 執行需要花費大量 IO 和 CPU 資源進行物理讀和過濾,這是非 Exadata 平臺分析型應用的典型瓶頸。 inmemory_query=disable cell_offload_processing=false
  1. 使用 Smart Scan,sql 執行時間為 5s;db time 為 18.3s。其中 db cpu 為 15.3s,user I/O 為 3s。對於 Lineorder 的全表掃描佔總 db time 的 39%,為 7.1 秒,其他操作佔總 db time 的 61%,約為 11.2s。 Cell Offload Efficiency 為 98%,意味著當掃描 Lineorder 時,通過 Smart Scan 的 column projection 和 bloom filter 特性,資料掃描和過濾過程被解除安裝到儲存節點,從儲存節點返回的實際資料量大小隻有 30GB 的 2%=630MB,說明這個 sql 本身非常適合發揮 Exadata 的威力。 從 sql monitor report 中的 parallel 標籤中可以看到,例項 1 和例項 2 的 parallel set 2 的工作量的平均的。sql 執行的 AAS (average active sessions)=4,兩個例項的 4 個並行平均分擔了工作。 inmemory_query=disable cell_offload_processing=true
  1. 使用 IMC 查詢時,sql 執行時間為 14s,db time 為 28.3 秒。對 Lineorder 所有 IMCU 的掃描操作佔總 db time 的 44%,為12.5s,其他操作佔總 db time 為 56%,為 15.8s。因為大部分的 IMCU 都分佈在例項 2,db time 的消耗都在例項 2 上。從 parallel 標籤可以看到,DB time 只分布在例項 2 的 paralle set 2。SQL 執行時 AAS=2。例項 1 的 parallel set 2 基本處於空轉的狀態。例項 2 parallel set2 中的並行程序 p002 和 p003 負責大部分的資料的處理,包括掃描分割槽 P_STATUS_COM,後序 hash join 和 hash group by 操作。如果我們可以把 IMCU 平均分配到兩個例項,就可以消除 IMCU 的分佈傾斜以及帶來的並行執行傾斜。 inmemory_query=enable parallel_degree_policy=auto

使用 by rowid range 重新分佈

By rowed range 重新分佈之後,P_STATUS_FKC/P_STATUS_PRP/P_STATUS_COM 三個分割槽的 IMCU 分佈在兩個例項上。Bytes_not_populated 列不為 0,說明這個 segment 有多少資料不在本例項載入。對於最大的分割槽,P_STATUS_COM 平均分佈在兩個例項上。

重新執行查詢,sql 的執行時間為 8s,相對之前 by partition 的分佈方式,減少了 6s 的執行時間。db time 依然為 28.3s。此時 AAS=4,例項 1 和 2 上 parallel set 2 的並行程序平均分擔了工作。By rowid range 的分佈方式消除了 IMCU 在兩個節點分佈傾斜和並行執行傾斜。

對於 RAC,無論是傳統的 cache fusion 機制或者集中式儲存,都是 share everything 的,資料可以通過 interconnect 或者 IO 在每個例項共享。但是 RAC 上使用 DBIM 特性時,IMCU 是不能在例項之間傳輸的。這就是促使我最初寫這篇文章的原因,從 RAC share everything 的架構切換到 DBIM share nothing 的架構,原來一些不合理的設計,可能會開始影響 DBIM 的使用效果。對於原來 share everything 的架構,這些問題可能並沒有暴露出來。比如這個例子中的 Lineorder 列表分割槽策略導致分割槽資料傾斜,這種分割槽傾斜在不使用 DBIM 的時候並沒有造成效能問題,因為並行查詢的操作為“PX BLOCK ITERATOR”,granule 為 dba (data block address) range,可以確保分配給每個並行程序掃描的資料量是大致相當的。當載入到 IM 列式儲存時,如果選擇 by partition 的方式,分割槽的傾斜就會導致 IMCU 分佈傾斜,每個例項的 IMCU 只能由當前例項的並行程序掃描,造成並行執行傾斜,影響 sql 的響應時間;如果對錶 Lineorder 有大量的類似查詢,就會導致例項 1CPU 空閒, 例項 2 CPU 繁忙的情況,影響系統的擴充套件性。

對於這種方式,如果不能更改分割槽策略消除分割槽資料傾斜,那就需要使用 by rowid range 的分佈方式,確保沒有 IMCU 分佈傾斜。

至於 by rowid range 分佈之後,IMC 查詢 (8s) 為什麼依然比使用 Smart Scan 的版本 (5s) 慢呢?首先,對 lineorder 的 IMCU 掃描的時間“In Memory CPU”佔總 db time 的 44%,為 11.32s,而使用 Smart Scan 時,IO 的等待只有 3s;更重要的是,in-memory 查詢時,每個 parallel set 2 的並行程序的執行路徑更長:1,掃描 IMCU 使用 bloom filter 過濾資料; 2,過濾完的資料需要通過 3 次 hash join;3,hash group by。而 Smart Scan 的版本中,並行程序不需要花費 CPU 掃描過濾資料,這部分的工作解除安裝到 Cell 節點完成,執行路徑更短,效率更高。Cell Offload Efficiency 達到 98% 是非常理想的情況,實際中,Exadata 平臺使用 DBIM 特性時,IMC 查詢一般會比 Smart Scan 快一些。

進一步優化,In-Memory Aggregation

為了嘗試 Vector Group By Transformation,加上 vector_transform hint,重新執行 sql,只需 3.71s。

使用 In-memory aggregation,sql 執行接近 4s,db time 為 12.3s,說明整個執行計劃效率更高,消耗的資源更少,並行執行有 4 個 parallel group,AAS 最高的時候為 16。在設計中,優化器對於 Vector group by transformation 的代價估算趨於保守,雖然有些場景使用 vector group by transformation 執行時間更短,但是優化器對 vector group by transformation 執行計劃的 cost 估算更高,所以預設沒有選擇進行 vector group by transformation。實際使用可能需要使用 VECTOR_TRANSFORMhint 手動開啟這個特性。

DBIM 和 RAC 的常見問題

我會對 RAC 上使用 DBIM 的常見問題做一些解釋。

1. 使用 AutoDoP 如何控制並行度?

12c 對 AutoDoP 做了增強,可以使用以下引數對 AutoDoP 做一定的控制:

  1. Parallel_degree_level=n,設定 sql 實際 DoP=computed DoP(優化器計算出來的並行度)乘以一個係數 n/100;比如 n=50,實際 DoP=computed DoP * 0.5;n=400, 實際 DoP=computed DoP * 4。預設值為100。
  2. Parallel_degree_limit=n,限制單個 sql DoP 的最大並行度為 n。
  3. Parallel_servers_target=n,設定例項最多可分配 n 個活躍的並行程序,達到限制之後會觸發 parallel statement queuing,後續的並行查詢進行排隊,等待正在執行的 sql 完成釋放並行程序。這個引數可以對使用 AutoDoP 的應用做簡單的資源控制。

2. AutoDoP 並行度不足的已知問題。❶

AutoDoP 模式下,一條 sql 啟用並行執行之前,優化器會檢查兩個條件:

  1. SQL 的估算的執行時間超過 parallel_min_time_threshhold。(如果查詢所有的表都已經載入到 DBIM 列式儲存中,則 threshhold 為 _parallel_inmemory_min_time_threshold)。
  1. 執行計劃至少包含一個 expensive 的操作,表或者分割槽需要足夠大,才會被優化器認識是 expensive,然後啟用並行。

Bug 18960760(已經在 12.1.0.2.0 包含這個 fix)中對於 IMC 查詢跳過了條件 1,如果查詢中存在一個 IMC 表被分佈到多個例項。但是查詢相對較小的 IMC 表時,DoP 可以依然可能為 1 或者不足例項的個數,Bug 19913129 會繞過第 2 個條件(目前這個 fix 還沒釋出)。

解決方法:

在 AutoDoP 模式下通過 hint 或者在 session 級別指定並行度,就像之前的例子中在 sql 中使用 parallel(4):

  1. alter session force parallel [parallel n],對於現有的應用,可以考慮在 logon 觸發器中設定。
  2. parallel hint

3. 把 IMC 表完全載入到 IM 列式儲存之後,查詢時為什麼還有大量的物理讀?

以下是常見的原因:

  1. 沒有使用 AutoDoP (parallel_degree_policy !=auto),QC 沒有意識到 IMC 表的分佈方式和 IMCU 的位置,導致物理讀。
  2. 由於 IMC 表分佈到每個例項,必須保證 SQL 的並行度至少等於例項的個數,而且可以在所有例項上執行。如果並行度不足例項的個數,或者 SQL 沒有所有的例項中執行,不是所有的資料都能從 IMCU 中獲取,造成物理讀。 a. AutoDoP 的 bug,導致並行度為 1 或者不足例項的個數。 b. 設定 parallel_force_local=true,限制只在本例項分配並行程序。 c. 使用只跑在部分例項的 service 連線,並行執行被限制在 service 正在 running 的例項上。

4. 在當前的 RAC 上,使用 service 做應用分割槽,負載隔離。啟用 DBIM 時,一定需要把 IMC 表分佈到每個例項嗎? 可以指定載入到其中幾個例項嗎?❷

DBIM 支援在系統級別設定可以 parallel_instance_group 為某個 service,通知後臺的載入程序 (w00) 把 IMC 表分佈到支援此 service 的一個或者多個例項。為了從 IMCU 中獲取全部的資料,應用也需要使用同一個 service 連線。這裡舉例說明。

Service IM12C_SINGLETON 跑在例項 1。

通過設定 parallel_instance_group引數,重新載入 Lineorder 之後,Lineorder 會被全部載入到例項 1。(注意 service 名字是區分大小寫的)

對於 DBIM 和 Service 更詳細的說明,可以參見 Oracle product management team 的部落格 (https://blogs.oracle.com/In-Memory/entry/oracle_database_in_memory_on1)。

按 service 分佈時,DBA 需要小心維護 parallel_instance_group 這個引數,在系統級別修改這個引數會導致所有 priority 不為 none 的 IMC 表動態重新分佈。

5. DBIM 和 failover,當一個例項 down 掉之後,這個例項的 IMCU 會分佈到剩餘的例項嗎?

因為把資料從磁碟載入到 IM 列式儲存,生成 IMCU 是一個昂貴的過程(通常是一個 CPU intensive 的過程),某個例項 down 掉之後,這個例項上的 IMCU 並不會立即分佈到其他例項,而是等一段時間,如果這個例項短時間復活了,那麼只需要重新載入屬於自己的 IMCU 即可。如果 down 掉的例項沒有及時啟動,這個 IMCU 就會在後臺自動載入到其他例項 (priority != none),或者在之後首次掃描的時候觸發重新分佈 (priority = none),假設其他例項 IM 列式儲存還有空閒的空間。

不同的分佈方式重新載入的過程有些不同:

  1. by rowid range 分佈方式,只有受影響的例項上 IMCU 後重新分佈,保證只有最少的 IMCU 需要重新載入。
  2. by partition/subpartition 分佈方式,整個 in-memory 表會被清除,然後重新載入。這種方式會浪費大量的 IO 和 CPU,不受影響的 IMCU 都需要重新載入。這會在 Bug 20097849 中修復,實現和 by rowid range 一樣,只有受影響的 IMCU 才重新分佈。

Bug 20097849 - ON IMC RAC WHEN ONE OR MORE INSTANCE DOWN WHOLE IMC TABLE MAY BE REDISTRIBUTED

當 down 掉的例項復活之後,所有屬於這個例項的 IMCU 都會載入回來。

6. IMC 表分佈方式的選擇。

選擇何種 IMCU 分佈方式需要結合分割槽方式和典型的查詢如何掃描資料綜合決定。如果當前系統的分割槽策略合理,那麼可以使用預設 distribute auto 的方式,這裡舉兩個例子:

  1. 為了使用 partition wise join,維度表和事實表已經在連線鍵上做 Hash 分割槽,那麼使用 distribute auto 時,匹配的 HASH 分割槽會被分佈在同一個例項,partition wise join 依然會生效。
  2. 如果查詢跨越多個分割槽,總體而言,IMCU 分佈在所有例項上,並行查詢依然可以相對平均在所有例項上執行。

Distribute auto 不合適的情況:

  1. 就像之前例子說明的,當分割槽資料出現傾斜時,預設的 distribution auto 方式會造成 IMCU 分佈傾斜。需要使用 by rowid range 的分佈方式,使 IMCU 在每個例項均勻分佈。
  2. 如果 distribute auto 實際是按照 by partition 分佈的,每個分割槽的資料只存在一個例項上。如果 SQL 經過分割槽裁剪之後只查詢一個分割槽的資料,那麼所有的 IMCU 只能從一個例項獲得,依然會有並行執行傾斜的情況。此時,需要使用 by subpartition 或者 by rowid range 的方式把一個分割槽的 IMCU 分佈到所有例項,避免並行執行傾斜。

7. 為了更穩定 DBIM 版本,我是否應該等到 12.2 再考慮升級?

根據 Note 742060.1,12.2.0.1 計劃在 2016 上半年釋出,DBIM 這麼酷炫的特性你真的要等到一年半之後再考慮升級嗎?

12.1.0.2 已經是 12.1 的最終版本,之後不會再有 12.1.0.3。BP1 12.1.0.2.1目前已經發布,建議測試的時候打上這個 Bundle patch,patch號為:19189240。

總結

本文介紹了 DBIM RAC share nothing 的架構在對IMCU分佈,並行執行和執行計劃方面帶來的挑戰,以及相應的應對方法。希望讀者通過本文能夠更好的瞭解 DBIM 特性,在測試或者實施 DBIM 特性時,能夠獲得最佳的效能。

在我看來,DBIM 是 Oracle 繼 Exadata 一體機之後,最激動人心的特性。基於 DBIM,非 Exadata 平臺的分析性應用,可以享受媲美甚至比 Exadata Smart Scan 更快的速度。DBIM 的精彩不容錯過!