oracle 並行引數設定
引子:以前一直沒太關注oracle並行這個特性。前幾天一個兄弟碰到的一個問題,才讓我覺得這個東西還是有很多需要注意的地方,有必要仔細熟悉下。其實碰到的問題不復雜:
類似如下的一條語句:insert into xxxx select /*+parallel(a) */ * from xxx a;資料量大約在75G左右,這位兄弟從上午跑到下午還沒跑完,過來問我咋回事,說平常2hrs能跑完的東西跑了好幾個小時還撒動靜。檢視系統性能也比較 正常,cpu,io都不繁忙,平均READ速度在80M/s左右(勉強湊合),但平均寫速度只有10M不到。等待事件裡面大量的‘ ‘PX Deq Credit: send blkd’,這裡能看出並行出了問題,從而最後得知是並行用法有問題,修改之後20分鐘完成了該操作。正確的做法應該是:
alter session enable dml parallel;
insert /*+parallel(xxxx,4) */ into xxxx select /*+parallel(a) */ * from xxx a;
因為oracle預設並不會開啟PDML,對DML語句必須手工啟用。 另外不得不說的是,並行不是一個可擴充套件的特性,只有在資料倉庫或作為DBA等少數人的工具在批量資料操作時利於充分利用資源,而在OLTP環境下使用並行 需要非常謹慎。事實上PDML還是有比較多的限制的,例如不支援觸發器,引用約束,高階複製和分散式事務等特性,同時也會帶來額外的空間佔用,PDDL同 樣是如此。有關Parallel excution可參考官方文件,在Thomas Kyte的新書《Expert Oracle Database architecture》也有精闢的講述。
………………………………………………………………………………………………………………
………………………………………………………………………………………………………………
我在其中一個SESSION 執行
SQL> create table test3 parallel 4 as select * from test1;
表已建立。
SQL> select * from v$mystat where rownum=1;
SID STATISTIC# VALUE
---------- ---------- ----------
151 0 1
SQL>
然後立刻在另一SESSION 乘上一個執行沒結束,看下面,這麼說是有4個並行的程序在處理了
SQL> select * from v$px_session;
SADDR SID SERIAL# QCSID QCSERIAL# QCINST_ID SERVER_GROUP SERVER_SET SERVER# DEGREE REQ_DEGREE
-------- ---------- ---------- ---------- ---------- ---------- ------------ ---------- ---------- ---------- ----------
6D31E434 131 16 151 107 1 1 1 1 4 4
6D32421C 136 11 151 107 1 1 1 2 4 4
6D3267AC 138 18 151 107 1 1 1 3 4 4
6D31F6FC 132 11 151 107 1 1 1 4 4 4
6D335BD4 151 107 151
SQL> select * from v$mystat where rownum=1;
SID STATISTIC# VALUE
---------- ---------- ----------
137 0 1
SQL>
我加大後
SQL> /
SADDR SID SERIAL# QCSID QCSERIAL# QCINST_ID SERVER_GROUP SERVER_SET SERVER# DEGREE REQ_DEGREE
-------- ---------- ---------- ---------- ---------- ---------- ------------ ---------- ---------- ---------- ----------
6D31864C 126 10 151 107 1 1 1 1 7 10
6D31F6FC 132 17 151 107 1 1 1 2 7 10
6D32421C 136 15 151 107 1 1 1 3 7 10
6D3267AC 138 22 151 107 1 1 1 4 7 10
6D322F54 135 11 151 107 1 1 1 5 7 10
6D31E434 131 18 151 107 1 1 1 6 7 10
6D327A74 139 5 151 107 1 1 1 7 7 10
6D335BD4 151 107 151
已選擇8行。
SQL>
奇怪,怎麼看只有7個,我那裡可是寫成
SQL> create table test4 parallel 10 as select * from test1;
表已建立。
怎麼少了3個?
不過我實際只有一個CPU的機器,這些說明什麼問題呢?
BTW
SQL> SHOW Parameter parallel_max
NAME TYPE VALUE
------------------------------------ ---------------------- -------------------
parallel_max_servers integer 20
SQL>
……………………………………………………………………………………………………………………
……………………………………………………………………………………………………………………
開多少個parallel server也要看當時系統的負載,並行是很耗系統資源的,
這個並行度和你初始化引數有關。CPU_COUNT 、PARALLEL_THREADS_PER_CPU 等等都有關係。如果你建表的時候沒有明確指定並行度,那麼oracle會自動的根據需要設定並行度。
用Oracle並行查詢發揮多CPU的威力
在一個單獨的伺服器中安裝更多的CPU成為目前的一個趨勢。使用對稱多處理伺服器(SMP)的情況下,一個Oracle伺服器擁有8個、16個或32個CPU以及幾吉位元RAM的SGA都不足為奇。
Oracle跟上了硬體發展的步伐,提供了很多面向多CPU的功能。從Oracle8i開始,Oracle在每個資料庫函式中都實現了並行性,包括SQL訪問(全表檢索)、並行資料操作和並行恢復。對於Oracle專業版的挑戰是為使用者的資料庫配置儘可能多的CPU。
在Oracle環境中實現並行性最好的方法之一是使用Oracle並行查詢(OPQ)。我將討論OPQ是如何工作的和怎樣用它來提升大的全表檢索的響應時間以及呼叫並行事務回滾等等。
使用OPQ
當在Oracle中進行一次合法的、大型的全表檢索時,OPQ能夠極大地提高響應時間。通過OPQ,Oracle將表劃分成如圖A所示的邏輯塊。
圖 A
由OPQ劃分的表
一旦表被劃分成塊,Oracle啟用並行的子查詢(有時稱為雜務程序),每個子查詢同時讀取一個大型表中的一塊。所有子查詢完畢以後,Oracle將結果會傳給並行查詢排程器,它會重新安排資料,如果需要則進行排序,並且將結果傳遞給終端使用者。OPQ具有無限的伸縮性,因此,以前需要花費幾分鐘的全表檢索現在的響應時間卻不到1秒。
OPQ嚴重依賴於處理器的數量,通過並行執行之所以可以極大地提升全表檢索的效能,其前提就是使用了N-1個並行程序(N=Oracle伺服器上CPU的數量)。
必須注意非常重要的一點,即Oracle9i能夠自動檢測外部環境,包括伺服器上CPU的數量。在安裝時,Oracle9i會檢查伺服器上CPU的數量,設定一個名為cpu_count的引數,並使用cpu_count作為預設的初始化輸入引數。這些初始化引數會影響到Oracle對內部查詢的處理。
下面就是Orale在安裝時根據cpu_count而設定的一些引數:
fast_start_parallel_rollback
parallel_max_servers
log_buffer
db_block_lru_latches
引數
讓我們進一步看看CPU的數量是如何影響這些引數的。
引數fast_start_parallel_rollback
Oracle並行機制中一個令人興奮之處是在系統崩潰時呼叫並行回滾得能力。當Oracle資料庫發生少有的崩潰時,Oracle能自動檢測未完成的事務並回滾到起始狀態。這被稱為並行熱啟動,而Oracle使用基於cpu_count的fast_start_parallel_rollback引數來決定未完成事務的秉性程度。
並行資料操縱語言(DML)恢復能夠在Oracle資料庫崩潰後極大地加快其重新啟動的速度。此引數的預設值是系統CPU數量的兩倍,但是一些DBA們認為應該將這個值設定為cpu_count的四倍。
引數parallel_max_servers_parameter
Oracle一個顯著的加強是自動決定OPQ並行的程度。由於Oracle清楚伺服器中CPU的數量,它會自動分配合適的子程序的數量來提升並行查詢的響應時間。當然,會有其它的外部因素,比如表的劃分以及磁碟輸入/輸出子系統的佈局等,但是根據cpu_count來設定parallel_max_servers引數將給Oracle一個合理的依據來選擇並行的程度。
由於Oracle的並行操作嚴重依賴伺服器上CPU的數量,parallel_max_servers會被設定成伺服器上CPU的數量。如果在一臺伺服器上執行多個例項,則預設值太大了,會導致過度的頁面交換和嚴重的CPU負擔。並行的程度還依賴於目標表中分割槽的數量,因此parallel_max_servers應該設定成足夠大以允許Oracle為每個查詢選擇最佳數量的並行子查詢。
引數log_buffer
引數log_buffer定義了供即刻寫入redo日誌資訊的保留RAM的數量,這個引數受cpu_count的影響。Oracle推薦log_buffer最大為cpu_count乘以500KB或128KB。CPU的數量對於log_buffer來說非常重要,因為Oracle會生成多日誌寫入(LGWR)程序來非同步釋放redo資訊。
log_buffer是Oracle中最易誤解的的RAM引數之一,通常存在下面幾個配置錯誤:
log_buffer被設定得太高(例如,大於1MB),這回引起效能問題,因為大容量的結果會使得寫入同步進行(例如,日誌同步等待事件非常高)。
log_buffer不是db_block_size的倍數。在的Oracle9i中,log_buffer應該是2048位元組的倍數。
引數db_block_lru_latches
LRU鎖的數量是在Oracle資料庫內部用來管理資料庫緩衝的,這嚴重依賴於伺服器上CPU的數量。
很多聰明的Oracle9i的DBA使用多衝資料緩衝(例如db_32k_cache_size),他們推薦將這個未公開宣告的引數重設定為預設的最大值。db_block_lru_latches引數在Oracle8i中使用得很多,但是在Oracle9i中變成了一個未公開宣告的引數,因為Oracle現在根據資料庫擁有的CPU數量設定了一個合理的預設值。
db_block_lru_latches預設被設定為伺服器上cpu_count的一半(例如伺服器上只有一個Oracle資料庫)。Oracle推薦db_block_lru_latches千萬不要超過cpu_count的兩倍或三倍,或db_block_buffers的五十分之一。
如果使用多緩衝池則這種計算方法有一個問題,因為不能控制分配給每個資料緩衝池的鎖的數量。如果db_writers引數大於1,則預設值或許顯得太小。
加強伺服器
Oracle資料庫總是在提升效能,根據外部伺服器環境檢測cpu_count和基本引數設定的能力對於Oracle軟體來說是一個重要的加強。
隨著更多的Oracle系統轉移到SMP上來,當客戶要採取增強措施並將眾多的資料庫轉移到擁有32個或64個CPU的巨大伺服器上來的時候,這些引數顯得愈發重要。
關於10G的parallel引數的說明
parallel_adaptive_multi_user boolean TRUE
說明: 啟用或禁用一個自適應演算法, 旨在提高使用並行執行方式的多使用者環境的效能。通過按系統負荷自動降低請求的並行度,
在啟動查詢時實現此功能。當 PARALLEL_AUTOMATIC_TUNING = TRUE 時, 其效果最佳。
值範圍: TRUE | FALSE
預設值: 如果 PARALLEL_AUTOMATIC_TUNING = TRUE, 則該值為 TRUE; 否則為 FALSE
parallel_automatic_tuning boolean TRUE
說明: 如果設定為 TRUE, Oracle 將為控制並行執行的引數確定預設值。除了設定該引數外,
你還必須為系統中的表設定並行性。
值範圍: TRUE | FALSE
預設值: FALSE
parallel_execution_message_size integer 4096
說明: 指定並行執行 (並行查詢, PDML, 並行恢復和複製) 訊息的大小。如果值大於 2048 或 4096,
就需要更大的共享池。如果 PARALLEL_AUTOMATIC_TUNING = TRUE,
將在大儲存池之外指定訊息緩衝區。
值範圍: 2148 - 無窮大。
預設值: 如果 PARALLEL_AUTOMATIC_TUNING 為 FALSE, 通常值為 2148; 如果 PARALLEL_AUTOMATIC_TUNING 為 TRUE, 則值為 4096 (根據作業系統而定)。
parallel_instance_group string
說明 : 一個群集資料庫引數, 標識用來大量產生並行執行從屬的並行例程組。並行操作只對在其 INSTANCE_GROUPS
引數中指定一個匹配組的例程大量產生並行執行從屬。
值範圍: 一個代表組名的字串。
預設值 : 由所有當前活動例程構成的組
parallel_max_servers integer 160
說明: 指定一個例程的並行執行伺服器或並行恢復程序的最大數量。如果需要, 例程啟動時分配的查詢伺服器的數量將增加到該數量。
值範圍: 0 -256
預設值: 由 CPU_COUNT, PARALLEL_AUTOMATIC_TUNING 和 PARALLEL_ADAPTIVE_MULTI_USER 確定
parallel_min_percent integer 0
說明: 指定並行執行要求的執行緒的最小百分比。設定該引數, 可以確保並行執行在沒有可用的恰當查詢從屬程序時, 會顯示一個錯誤訊息,
並且該查詢會因此而不予執行。
值範圍: 0 -100
預設值: 0, 表示不使用該引數。
parallel_min_servers integer 0
說明: 指定為並行執行啟動例程後, Oracle 建立的查詢伺服器程序的最小數量。
值範圍: 0 - PARALLEL_MAX_SERVERS。
預設值: 0
parallel_server boolean TRUE
說明 : 將 PARALLEL_SERVER 設定為 TRUE, 可以啟用群集資料庫選項。
值範圍: TRUE | FALSE
預設值 : FALSE
parallel_server_instances integer 2
說明: 當前已配置的例程的數量。它用於確定 SGA 結構的大小, 該結構由已配置的例程數量來確定。正確設定該引數將改善 SGA
的記憶體使用情況。 有幾個引數是用該數量計算得到的。
值範圍: 任何非零值。
預設值: 1
parallel_threads_per_cpu integer 2
說明: 說明一個 CPU 在並行執行過程中可處理的程序或執行緒的數量,
並優化並行自適應演算法和負載均衡演算法。如果計算機在執行一個典型查詢時有超負荷的跡象, 應減小該數值。
值範圍: 任何非零值。
預設值: 根據作業系統而定 (通常為 2)
舉例:Parallel Execution for a Session
並行執行會話,有時候為了加快執行速度,充分利用多CPU資源,進行比如並行建立索引的操作.
要使用並行執行某些操作可以使用alter session 語句
ALTER SESSION ENABLE PARALLEL DML|DDL|QUERY
關閉用如下語句
alter session disable parallel DDL|DML|QUERY
強制並行執行:
ALTER SESSION FORCE PARALLEL DML|DDL|QUERY