有一些數據庫性能問題可能是因為同時啟動的并行進程過多造成的,特別常見于RAC節點重啟,很多時候是因為瞬間啟動了幾百個并行進程,導致OS各項指標“彪高”,后臺進程失去響應。最近遇到的一個,是因為SQL語句中寫了/*+ parallel a,8*/? ,但是在RAC的兩個節點上各啟動了512個并行進程,一共啟動了1024個并行進程,導致網絡心跳丟失。因為問題可以通過執行這個語句重現,而使用parallel_force_local=true可以workaround這個問題,所以基本可以確定是跨節點并行導致的。
拋開這個問題背后的其他因素不談,我們單來討論一下:一條SQL語句究竟會產生多少個并行進程
一條SQL語句使用的并行度受3個層面的數值影響:
1)hint中指定的并行度
select /*+ parallel(a,8) */ * from scott.emp a order by ename;
2)表的并行度,也就是表的degree:
select owner,table_name,degree from dba_tables where table_name='EMP';
OWNER????????????????????????? TABLE_NAME???????????????????? DEGREE? ?
------------------------------ ------------------------------ ----------
SCOTT????????????????????????? EMP???????????????????????????????????? 2?
3)auto DOP
單節點:auto DOP = PARALLEL_THREADS_PER_CPU x CPU_COUNT
RAC:auto DOP = PARALLEL_THREADS_PER_CPU x CPU_COUNT x INSTANCE_COUNT
他們的優先級是hint>degree>auto DOP,也就是說:
1)如果hint指定了并行度,會忽略表的degree。
2)如果hint只指定parallel,不寫具體的數字,或者表上DEGREE顯示為DEFAULT,沒有具體數值(alter table scott.emp parallel不指定具體degree數值),則會使用auto DOP。
除此之外,還有以下一些規則:
1)如果表中有group by或者其他排序操作,以上并行度×2。
2)RAC中,并行度會自動平均分配到各個節點上,比如并行度256,2個節點,則每個節點上各起128個并行進程。
“并行度>parallel_max_servers”的判斷在各個節點上進行。
3)在PARALLEL_ADAPTIVE_MULTI_USER = TRUE 的情況下,會根據系統load(當前正在使用并行的用戶數),將并行度乘以一個衰減因子。
4)如果以上并行度>parallel_max_servers能夠提供的空閑并行進程數,則最終并行度=0,也就是不并行(不使用Pnnn的進程)。
舉一些例子來更詳細的說明它:
1)如果SQL中沒有使用hint,而表上degree=1則并行度=0;
2)如果SQL中沒有使用hint,而表上degree=DEFAULT 則并行度=PARALLEL_THREADS_PER_CPU x CPU_COUNT x INSTANCE_COUNT;
3)如果SQL中沒有使用hint,而表上degree>1 則并行度=表上degree;
4)如果SQL中使用沒有數值的hint(/*+ parallel */ ),無論表上degree的值是多少,并行度= PARALLEL_THREADS_PER_CPU x CPU_COUNT x INSTANCE_COUNT;
5)如果SQL中使用帶數值的hint(/*+ parallel (a,8)*/ or /*+ parallel (a 8)*/ ),無論表上degree的值是多少,并行度= hint中的數值(8);
6)如果有排序操作,以上并行度×2;
7)并行度分配到各個RAC節點,乘以衰減因子,如果最終并行度>parallel_max_servers能夠提供的空閑并行進程數,則并行度=0;