Parallel Execution
Parallel Execution Oracle 7.1 ile gelmiş Standart Edition da olamayıp Enterprise Edition’a ait bir özelliktir. Parallel Execution’u aklınız da canlandırmak için bir ev yaptırdğınızı düşünün evin yapımında birden çok takım çalışacaktır. Evin yapımında herkesin aynı anda aynı iii yapması yerine binanın dikilmesi ve elektirik tesisatı gibi farklı görevlerin aynı anda yapıldığını düşünün şüphesiz evinize erken oturacaksındır.
Oracle da Paralel Execution da aslında aynı mantığı uygular büyük jobları küçük parçalara bölerek concurrent olarak gerçekleştirir. Mesela bir tablo full scan yapılıcaksa 4 processin tablonun farklı yerlerini okuması ve sonucu process koordinatöre getirerek client a sonuc döndürülür ve bu response time ‘ı düşürecektir. En kaba tabirle Oracle ‘ın bir processle yapacağı bir işi birden çok küçük iş parçacıklarına bölüp bunların aynı anda çalışmasıdır.
Seri işlemlerde mesela tablolarmuz full scan edilsin dedicated server process sonucu user processe döndürürür. Paralel query de ise mesela server ikinci derecen paralel hinti görünce Query coordinator tarafından iki dedicated server process yaratılır ve scanlenecek bloklar ikiye ayrılıp slave processler gönderilir.
Parallel Execution uygulamadan önce iki şeyden emin olmalısınız.
1-) Büyük bir taskınız olmalı (Mesela 50 gb full scan data)
2-) Yeterli kaynağınız oldugundan emin olmalısınız yeterli cpu ve I/O gibi (Paralel Processlerin çalışması için).50 gb verininde bieden çok diske dagılması ve disklerden datayı getirmek için I/O kanallarının yeterli olması beklenir.
A Paralel Analogy
Şimdi neden fazla veri ve yeterli kaynak istediğimizi örneklerle açıklayalım. İki task olduğunu düşünün birincisi bir sayfanın özetini alacak ikincisi ise 10 chapter’ın kısa bir özetini alacak ve her bir chapter birbirinden bağımsız halde farklı konular içeriyor.
Birinci görev de sayfada 12 paragraf var ve paragraflar birbirinden bağımsız değiller. Siz bir paralel process kordinatör oldugunuzu düşünün ve 12 kişilik bir takım tuttunuz ve her bir paragrafı bir kişiye verip problemi anlattınız. Sonra her paragraf özetini alıp dogru yazılıp yazılmadığını kontrol edip sıraya koyup yazdırdınız. Bütün bu işlemler sizin serial olarak sayfanın özetini yazmanızdan daha çok zaman alacaktır. İkinci göreve gelince her üniteyi bir kişi verip onlardan gelen sonuçları direk yazdırmanız çok daha performanslı olacaktır.Kaynak yeterliliği konusundan ise bir yine manager olun ve bir işi takımdaki bireylere dağıtmak istediğinizi düşünün eger takım arkadaşlarınıza yapabileceklerinden fazla iş veremezsiniz ve kaynağınız yani çalışanlarınız üstlendikleri işleri yerine getiremiyeceklerdir.
Parallel Execution büyük tablo scanlerken,joinlerken, büyük indeksler yaratırken,tablolar,materialized view yaratırken,bulk insert,merge,update ve delete lerde performansı artırması beklenir.Ayrıca LOB gibi database objelerine de paralel ulaşabilirsiniz.Multiprocessor, yeterli I/O bandwith,yeterli olarak kullanılmayan CPU (mesela %30 un altı) paralel execution performansı için olumlu koşullar olacaktır. Data Warehouse ,OLTP batch processler için paralel execution uygun koşullarda performansı artıracaktır. 1-2 saniye süren kısa tipik OLTP işlemlerde paralel execution yararlı olmayacaktır çünkü slave processlerin koordine edilmesi de bir cost yarattığından bu tip uygulamalarda paralel execution kullanmak performansı düşürecektir. Ayrıca I/O ve CPU yeterince kullanılan sistemlerde kullanmak da yine performansı düşürecektir.
Paralel Query
Paralel query de bir sql ‘in birden çok işparçacıklarına bölünüp bunların eşzamanlı çalışmasıdır. Paralel query de tablo birbiriyle kesişmeyen parçalara bölünür ve her bir slave process tablonun ilgili kısmını okuyup sayar ve asıl kullanıcıya sonucu döndürecek olan server process olan kordinatöre sonuç döner.
Select count(status) from big tables;
Id | Operation | Name | Rows |Bytes | Costs (%CPU) | Time
1 SELECT STATEMENT 2 00:06:29
2 SORT AGGREGATE
3 TABLE ACCES FULL 2 00:06:29
Yukarıda beklediğimiz gibi seri planla karşılaştık Parallelism uygulamak için sql ‘e hint koyabilir ya da objeye paralleliğin derecesi dikte edebiliriz.
>> alter table big_table parallel 4 ;
Ya da
>> alter table big_table paralel ;
Şeklinde yazıp parallelism derecesini Oracle ‘a bırakıyor ve Oracle kaynaklarını uygunsa dinamik olarak parallelik derecesini artıracaktır ya da kaynaklar yogunsa paralellik derecesini düşürecektir.
>>explain plan for
2 select count (status) from big_table ;
Id | Operation | Name | Rows |Bytes | Costs (%CPU) | Time
0 SELECT STATEMENT 1 00:00:54
1 SORT AGGREGATE
2 PX COORDINATOR
3 PX SEND QC (RANDOM)
4 SORT AGGREGATE
5 PX BLOCK ITERATOR
6 TABLE ACCES FULL 1
7
Genel anlamda paralel execution çalıştırırken datayı oldukça fazla diskte tutmak ,raid diskler arasında strinping için ve partitioning datayı fiziksel olarak datalara dagıtmak için kullanılmalıdır ve tablespace de birden çok datafile oluşturmak Oracle ‘ın tablo segmentleri extent etmesi için performanslı olacaktır. Bütün bunlar datayı tek diskte tutulursa paralel execution kullanmak işe yaramayacaktır anlamına gelmiyor fakat ideal olan tablo yukarda bahsettiklerimden oluşuyor.
Parallel DML(PMDL)
Insert,update,delete,merge gibi dml cümlecikleri paralelleştirilebilinir.PMDL de yine parallel execution servers lar tek process yerine DML işlemlerini gercekleştirir.PDML ler yine direk OLTP işlemlerin performansını artırmak için düşünülen bir yol değildir. Genel de tek kullanıcın kaynakları(CPU,disk,memory) en fazla kullanılmasına yönelik bir özelliktir. Paralel execution datawarehouse(çok data,az kullanıcı) işlemlerde uzun süren table summary alırken performans sağlar ve OLTP de long batch job işlemler de yine performansı artırır. OLTP işlemlerde haliyle kısa transaction ve çok kullanıcılı ortamlarda makine kaynaklarını tamamen kullanıcın kullanmasını haliyle istemeyeceksinizdir.DML işlemleri paralelleştirilirken oracle belli kurallar uygular. UPDATE ve DELETE işlemleri için ayrı İNSERT işlemleri için ayrı kuralları vardır.
• Trigerlar PDML operasyonları süresince desteklenmez çünkü ilk update ler sırasında tigerlar sisteme yük olabilir ve sizde PDML hızlı olması için kullandıgınız için iki özellik aynı anda çalışmaz.
• PDML ile değişikliğe uğrayan tabloya commit ya da rollback denilmeden ulaşamazsınız.
• Clustured table desteklenmez.
• Bitmap indeks ve lob kolonlarında eger tablo partitioned ise çalışır ve slave process sayısı partition sayısı ile aynı olmalıdır.
• Insert values desteklenmez .
Oracle UPDATE ve DELETE statementları sadece partitioned tablolarda gecerlidir. Nonpartitioned table da DML ifadeleri paralelleştirlemez. Standart INSERT ifadeleri paralelleştirlemez .INSERT SELECT FROM statemenları paralelleştirilebilinir.Örnek vermek gerekirse:
alter session enable parallel dml;
insert /*+ parallel (emp_big,4,1) */
into emp_big select * from emp;
commit;
alter session disable parallel dml;
How Parallel Execution Works
Oracle taskları alıştıran SQL statementları küçük birimlere ayırarak bagımsız process (threads wndows enirement )olarak çalıştırır. Query coordinator parallelleştirmek için işi küçük parçacıklara böler.Bu processler parallel execution server processes, parallel slave processes gibi adlandırılabilinir. Her bir processe bir gorev atar. Sonra her slave processeden dönen sonucu toplayıp statement’ın sahip oldugu user process’e döner. İş bitiminden sonra her slave process bırakılır ve server pool’a döner.
How Parallel Execution Servers Communicate
Sorgunuzun parallel çalışması için Oracle producer queue server ve consumer server yaratır.Producer queue server tablodan datayı getirir ve consumer server join,dml ve ddl işlemlerini yapar. Her producer bir consumer’a connection ile bağlıdır. Bu da virtual bağlantı sayısı paralleliğin derecesini vermekte olduğunu gösterir.
The Pool of Parallel Slave Processes
Oracle instance’ı başladığında açılışında sayısı PARALLEL_MIN_SERVERS ile belirtilen parametre ile parallel execution servers için pool yaratır. Parallel Operasyon çalıştırıldıgında coordinator parallel execution servers ları pooldan alır ve göreve atar.Statment bittikten sonra processler poola döner. Sql statement alıştırıldıgında optimizer parallel olup olmayacağına ve paralleligin derecesine DOP(degree of parallelism) ‘a gore karar verir.
Slave processlerin sayısı paralleligin derecesiyle belirlenir. Oracle paralleligi iki component den oluşur. Birincisi kullanılacak instance sayısı ikincis her instance daki slave process sayısı. Parallelik derecesi Statement level , Object level, Instance level gibi 3 level da belirlenir. Oracle hint ya da parallel clause kullanan statement level’a bakar birşey bulamazsa objct level da tablo ya da indekse bakar orda da dışardan değer verilmemişse instance için verilmiş default değeri uygular. SELECT /*+ PARALLEL(orders,4,1) */ COUNT(*) FROM orders; gibi hintle statement level bazında belirlemiş oluruz. ALTER TABLE order_items PARALLEL (DEGREE 4); dersek object level bazında belirlemiş oluruz.
Parallel DDL
Parallel DDL partitioned ve nonpartitioned tablo ve indekslerde çalışır. CREATE TABLE…AS SELECT, CREATE INDEX, ALTER INDEX…REBUILD gibi nonpartitioned ya da ALTER TABLE…MOVE PARTITION, ALTER INDEX…REBUILD PARTITION partitioned tablo ya da indekslerde paralelleştirilebilinir. Kısıtlama olarak Object kolonları ya da LOB kolonları paralelleştirilemez.
Parallel Data Loading
Oracle’s SQL*Loader parallel olarak belli kısıtlamlar dahilinde harici dosyalardan data load etmemize izin verir. Eger çok fazla data load edecekseniz sql loaderın parallel gerçekleştirmesi elapsed time’ı düşürecektir. Paralel loading de birden çok path tanımlayarak aynı tabloya ya da tablonun aynı bölümüme data load edebilirsiniz.
Bunun için birden fazla input datafile, her datafile için control file ve her control file ve datafile için bir sqlloader oturumu açmanız yeterli olacaktır. Örnekleycek olursak:
SQLLOAD scott/tiger CONTROL=con1.ctl DIRECT=TRUE PARALLEL=TRUE
SQLLOAD scott/tiger CONTROL=con2.ctl DIRECT=TRUE PARALLEL=TRUE
SQLLOAD scott/tiger CONTROL=con3.ctl DIRECT=TRUE PARALLEL=TRUE
SQLLOAD scott/tiger CONTROL=con4.ctl DIRECT=TRUE PARALLEL=TRUE
Parallel Recovery
Seri recovery de SMON backgroung process’i hem redologları okur ve değişiklikleri datafile ‘a yazar .Recovery için birden fazla datafile gerektiğini düşünürsek seri işlem oldukça zaman alacaktır. Parallel Recovery de SMON redo logları okur ve multiple parallel slave processes ler datafile lara yazar ve böylece recovery zamanı düşer.
RECOVER TABLESPACE tab PARALLEL (DEGREE 4);
Procedural Parallelism
İki türlü procedural parallelism bunlar parallel pipelined functions ve do-it-yourself parallelism DIY .Bunlardan pipelined fonksiyonları örneklendirelim.. Bir seri çalışan batch process prosedürmüz var.
Create procedure process_data
As
Begin
For x in(select * from some_table)
Perform complex process on X
Update some other table ,insert into somewhere else
End loop
End;
Bu prosedür sistem kaynaklarını çok kullanmadığını düşünün ve çalışması saatlerce sürüyor . Runtime da zamanı düşürmek istiyoz bunu yukarda bahsettiğim iki yaklaşımla çözmeye çalışalım.
Parallel Pipelined Functions
Data önceden çalışan process_data prosedürünü parallelleştirelim.Bunu gerçekleştimek için bir tablodan seçip onu işleyip başka tabloya insert etmek yerine loopdaki insert yerine PIPE ROW koyup,sonucu başka tabloya koyup orda işlemeye çalışalım.İki tablo kullanacağız birincisi t1 daha önceden okudugmuz tablo ikincisi ise taşıyacağımız tablo t2 olsun.
Create table t1
As select object id ,object_name text
From all_objects;
Create table t2 as
Select t1.*,0 session_id
From t1
Where 1=0;
T2 tablosunu t1 ile aynı yapıda yarattık. Session_id ile parallelismi görmek için ekledik. Sonra pipelined fonksiyonun döndüreceği output type’ı yarattık.
Create or replace type t2_type
As object
(
Id number ,
Text varchar2(30),
Session_id number
)
Create or replace type t2_tab_type
As table of t2_type
Yazacağımız fonksiyonda refcursor ile input alıp t2_tab_type ‘a değer döneceğiz. Pipelined fonksiyonda parallel_enable durumda ve partition clause ile datayı en ideal biçimde bölümleyerek getir diyoruz. Fonksiyonu yazıyoruz.
Create or replace function parallel pipelined (l_cursor in sys_refcursor)
Return t2_tab_type
Pipelined parallel_enable (partition l_cursor by any)
Is
L_session_id number;
l_rec t1%rowtype;
begin
select sid into l_session_id
from v$mystat
where rownum=1;
loop
fetch l_cursor into l_rec;
exit when l_cursor¬found;
—complex process here
Pipe row(t2_type(l_rec.id,l_rec.text,l_session_id));
End loop;
Close l_cursor;
Return;
End;
Datayı parallel işlemek için artık hazırız parallelik derecesini Oracle kaynak durumuna gore otomatik ayarlayacaktır.
Alter session enable parallel dml;
>>insert /* +append */
into t2(id,text,session_id)
Select * from table (parallel_pipelined(CURSOR (select /*+parallel(t1)*/* from t1)))
>> select session_id,count(*)
From t2
Group by session_id;
Session_id count(*)
241 8040
246 8045
253 8042
254 8042
258 8040
259 8041
Yukarda gördüğümüz gibi Oracle dereceyi 6 olarak belirledi ve her bir slave process yaklaşık 8000 satır işledi.
Instance Configuration
Parallel Execution’un size performans sağlayacağını düşündüğünüz durumlarda konfirigasyon çok da zor olmamaktadır. Eger session ALTER SESSION FORCE PARALLEL … çalıştırılmışsan sql ler için derece CPU_COUNT ile belirtilen ve defaultda system cpu sayısı olan parallelikte çalışır.
parallel_adaptive_multi_user
Parallel execution da çok önemli parametrelerden biridir. Default olarak false gelir ve true olması tavsiye edilir. Bu parametreyi bir örnekle açıklayalım. Çok datadan rapor elde ediyorsunuz ve rapor almak yaklaşık 8 dk sürüyor ve siz dördüncü dereceden parallellikle çalıştırıp süreyi 2 dk ya düşürüyorsunuz. Sonra dereceyi biraz daha artırıp süreyi daha fazla düşürmek istiyorsunuz ama server kaynakları yeterli olmadıgından rapor işlemini gerçekleştiremeyebilirsiniz işte Oracle bunun çözümü için bu adaptive_multi_user ‘I getirdi. Eger server meşgulse talep ettiğinizden daha düşük derecede çalışır parallel sorgularınız ve böylece overheadden kurtulmuş olursunuz.
parallel_max_servers and parallel_min_servers
User process ile PX ler pooldan çağırılır bu iki parametre ile pool’un size’ını ayarlayabilirsiniz. Yine kritik olacak maksimum değeri olacaktır. Bu değeri yüksek verip bir cpu da yüzlerce process çalıştırmanın anlamı yoktur. Maksimum değeri cpu sayısının iki ya da dört katı verilebilinir ama sürekli üstünde durduğumuz gibi tüm etkenler üstünde düşünülmelidir.
parallel_execution_message_size
Bu parametre ile slave processler ile coordinator arasındaki mesajların geçmesindeki buffer miktarı ayarlanır. Defaultda 2 KB gelir. Eger mesajlar değerden büyükse parçalara ayrılır bu az da olsa etkiler performansı. parallel_automatic_tuning tarafında mesajlar 2kb dan 8kb ye kadar çıkarılabilinir.
Bu parametreler ayarlamak dışında dışında data dictionary viewden de processler hakkında kolayca bilgi alabiliriz. Aslında birçok uzmanda bu parametrelerin farkında değildir. Şimdi bazılarına göz atalım.
V$PQ_SESSTAT
Sorgumuzun parallelliğini görmmemiz açısından faydalı olacaktır ayrıca mesaj aktivitelerini de görebiliriz.
SELECT * FROM v$pq_sesstat;
STATISTIC LAST_QUERY SESSION_TOTAL
—————————— ———- ————-
Queries Parallelized 1 2
DML Parallelized 0 0
DDL Parallelized 0 0
DFO Trees 1 2
Server Threads 7 0
Allocation Height 7 0
Allocation Width 1 0
Local Msgs Sent 491 983
Distr Msgs Sent 0 0
Local Msgs Recv’d 491 983
Distr Msgs Recv’d 0 0
Kullanılan px processlerin sayısını ve durumunu görmemiz açısında faydalı olacaktır. Aynı zamanda parallel_max_servers ve parallel_min_servers parametrelerini ayarlamak açısıdan yararlı olacaktır.Unix de |ps -ef|grep “ora_p” da aynı sonucu döndürecektir.
select
statistic,
value
from
v$pq_sysstat
where
statistic = ‘Servers Busy’;
STATISTIC VALUE
——— —–
Servers Busy 30
Monitoring the SQL being executed by slaves
Slave processlerin hangi sql li çalıştırdığını da viewleri joinleyerek bakabiliriz. Burda processler aktif olmak zorundadır.
select p.server_name,
sql.sql_text
from v$px_process p, v$sql sql, v$session s
WHERE p.sid = s.sid
and p.serial# = s.serial#
and s.sql_address = sql.address
and s.sql_hash_value = sql.hash_value
P000 SELECT /*+ PARALLEL (attendance, 2) */ * FROM attendance ORD
ER BY amount_paid
P003 SELECT /*+ PARALLEL (attendance, 2) */ * FROM attendance ORD
ER BY amount_paid
P002 SELECT /*+ PARALLEL (attendance, 2) */ * FROM attendance ORD
ER BY amount_paid
P001 SELECT /*+ PARALLEL (attendance, 2) */ * FROM attendance ORD
ER BY amount_paid
Session Tracing and Wait Events
Parallel execution kullanan bir uygulamayı trace etmek kullanmayana gore daha birkaç yönüyle daha karmaşıktır. Trace file her slave process için üretilir. Versiyona gore değişse de slave processlerin trace dosyaları background_dump_dest de query coordinator trace leri ise user_dump_dest de oluşur. Processler arasında mesaj alışverişleri beklemelere yol açar. En büyük zorluklardan biri de çok sayıda analiz etmeniz gereken trace dosyası olmasıdır.
Parallel-specific Wait Events
Px leri monitor ederken high level da statspack (istatistik görebileceğiniz bir tool) low level da ise event trace kullanabilirsiniz.
Events indicating Consumers are waiting for data from Producers
Daha once bahsettiğimiz consumer’ın producer’i beklemesinden dolayı beklemeler aslında herhangi bir process’in çalışması için diğer processi beklemesinden farklı değildir. Ama bu beklemler çok fazla sürüyorsa bu bir problem göstergesidir. Aşağıda statpacks ile alınmış topten events var ona bakıp yorumlarda bulunalım.
Event Waits Timeouts Time (s) (ms) /txn
direct Path read 2,249,666 0 115,813 51 25.5
PX Deq: Execute Reply553,797 22,006 75,910 137 6.3
PX qref latch 77,461 39,676 42,257 546 0.9
library cache pin 27,877 10,404 31,422 1127 0.3
db file scattered read 1,048,135 0 25,144 24 11.9
Yukardaki değerlere yorumlarsak direk Path read slave processlerin fullscan ya da index full scan yaparken okuma şeklidir. Yukardaki istatistiğin datawarehouse da uzun sure alan bir select oldugu düşünülürse 51 ms çok uzun sure değildir. Execute Reply bir idle process olarak algılanır ve bize çok fakir vermez. PX qref latch değeri bize consumer’ın producer’I beklediğini ve consumerın işleyemeyeceği kadar data getirdiği fikrini verir. Bu işlem çok fazla süren batch işlemioldugu için büyük miktarda mesaj transferinin oldugu görülmektedir. Wait events’I düşürmek için parallel_execution_message_size ‘ düşürmek ya da DOP derecesini düşürmek çözüm olabilir. Bu durum bilinçsizce DOP u artırarak her zaman hızlanacağını düşünenler tarafında karşılaşılabilinir bir durumdur. Ama asıl yukardaki sorun
library cache pin daki değerdeki sorundur. Bu parametre kodun library cache load edilirken göterdiği bekleme değeridir ya da bir başka deyişle library cache concurrency ‘i yöneten değerdir ve shared pool’un yogun kullanıldığı durumlarda yüksek değerde bir değer alacağınız kesindir.
Events indicating producers are quicker than consumers (or QC)
PX qref latch Consumer processin data beklemesinden oluşan beklelerdir. Bu durumda ise parallel_execution_message_size ‘ı artırmak iletişim overhead’ı azaltıp consemer’ın data beklemesini azaltıp haliyle toplam beklemyi de azaltacaktır.
Synchronisation Message Events
• PX Deq Credit: need buffer
• PX Deq: Signal Ack
• PX Deq: Join Ack
Yukardaki gibi QC nin ve slave processlerin haberleşmesinden kaynaklanan beklemelerle karşılaşabilirsiniz bu durumda DOP ve parallel_max_servers değerlerini düşürmeniz yararlı olacaktır.
Query Coordinator waiting for the slaves to parse their SQL statements
• PX Deq: Parse Reply SQL lin parse etmesinde gerçekleşen beklemerdir. Bu beklemeler library cache pin değerlerine de yansır.
Partial Message Event
• PX Deq: Msg Fragment bu event parallel_execution_message_size ‘ın düşük olmasından kaynaklanır. Mesajların processler arasında taşınırken büyük gelip bölümlere ayrılmasından kaynaklanabilir mesaj size’ı dşürüp tecrübe edilmesinde yarar vardır.
Şimdi de teknik alandan çıkıp genel resmi özetleyelim.
• Parallel execution kullanmadan once araştırmalı eger imkan varsa initial testler yapılmalıdır aksi halde büyük problemlerle karşılaşabilinir.
• Parallel Execution donanımı en yoğun kullanmak için tasarlanmıştır. Tek cpu, iki 512 MB lik disk le çok büyük performans artışı beklemek yanlış olacaktır.
• Parallel Execution kullanırken once sql tune edin edin kötü yazılmış ve tasarlanmış uygulamaya parallel execution uygulamaya kalkmayın.
• Kısa süren transactionlarda PX kullanmanız çok az iyileşmeye hatta daha yavaş çalışmaya mahkum olabilir. Kısa sorgu için tüm kaynakları kullanmış olursunuz.
• Parallel Executions geceyarıları batch operasyonları için ya da multiple streams joblarında genelde performans gösterir ama yine de bu uygulamanın türüne bağlıdır.
• Create as Select ya da büyük bulk insert into parallel olarak gerçekleştiriliyorsa NOLOGING modunda çalışırsa performans artar çünkü redo log’a yazdıgınız herşey extra I/O dur aslında ama recovery durumunda logları manuel olarak oluşturmanız gerekecektir.
• PARALLEL_AUTOMATIC_TUNING parametresini true yapın