標籤:multi int parameter 過程 並且 增加 一個 調度 限制
引子:以前一直沒太關注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
PARALLEL_MAX_SERVERS參數用於設定系統中允許的最大並行進程數。Oracle的文檔對於這個參數的描述如下:
PARALLEL_MAX_SERVERS specifies the maximum number of parallel execution processes and parallel recovery processes for an instance. As demand increases, Oracle increases the number of processes from the number created at instance startup up to this value.
If you set this parameter too low, some queries may not have a parallel execution process available to them during query processing. If you set it too high, memory resource shortages may occur during peak periods, which can degrade performance.
這個參數在9i及更老的版本中是靜態參數,修改需要重啟。10g以後可以動態修改生效。如果是RAC環境,則各節點應當設定成同樣的值。
對於9i
1.如果PARALLEL_AUTOMATIC_TUNING=FALSE
PARALLEL_MAX_SERVERS=5
2.如果PARALLEL_AUTOMATIC_TUNING=TRUE
PARALLEL_MAX_SERVERS=CPU_COUNT x 10
9i中PARALLEL_AUTOMATIC_TUNING預設為FALSE,所以PARALLEL_MAX_SERVERS預設為5
對於10g
1.如果PGA_AGGREGATE_TARGET >0
PARALLEL_MAX_SERVERS=CPU_COUNT x PARALLEL_THREADS_PER_CPU x 10
2.如果PGA_AGGREGATE_TARGET=0
PARALLEL_MAX_SERVERS=CPU_COUNT x PARALLEL_THREADS_PER_CPU x 5
假如一台機器有50顆CPU,安裝的是Oracle9i,則PARALLEL_MAX_SERVERS預設值為5,升級到Oracle10g以後,則PARALLEL_MAX_SERVERS預設值會變為1000,這是值得注意的變化,通常需要根據需要來重新設定該參數。
對於OLTP庫,不宜設定過大的PARALLEL_MAX_SERVERS,因為並行操作在OLTP中可用的情境不多,一般也就是在建立和調整索引的時候會用到,並行掃描使用direct path read,會導致掃描對象的segment checkpoint,如果當時系統非常繁忙,後果可能非常嚴重。
oracle parallel 並行 設定 理解