Professional Documents
Culture Documents
LUCRARE DE DISERTAŢIE
Coordonator ştiinţific
Prof.Univ.Dr. Ion LUNGU
Absolvent
Maria Rus
Februarie, 2010
1
ACADEMIA DE STUDII ECONOMICE DIN BUCUREŞTI
FACULTATEA DE CIBERNETICĂ, STATISTICĂ ŞI
INFORMATICA ECONOMICĂ
TEHNICI DE DIAGNOSTICARE ŞI
TUNING A PERFORMANŢELOR
BAZELOR DE DATE ORACLE
Coordonator ştiinţific
Prof.Univ.Dr. Ion LUNGU
Absolvent
Maria Rus
2
Februarie, 2010
Cuprins
Introducere..................................................................................................................................................4
1. Scopul lucrării.......................................................................................................................................4
2. Ce presupun problemele de performanţă, definirea unei probleme, de ce apar acestea (cele mai
frecvente cauze).......................................................................................................................................4
Capitolul 1 - Metodologia problemelor legate de performaţa bazei de date.................................................7
1. Metodologia de Diagnosticare Oracle (ODM = Oracle Diagnostic Methodology).................................7
2. Paşii diagnosticării unei probleme de performanţă a bazelor de date................................................10
Capitolul 2 - Functionarea lentă a bazei de date........................................................................................12
Faza 1 - Identificarea problemei.............................................................................................................12
Faza 2 - Determinarea cauzei................................................................................................................32
Faza 3 - Alegerea strategiei de tuning...................................................................................................37
Capitolul 3 - Baza de date este blocata (locking) sau se agaţă (hang).....................................................49
Faza 1 - Identificarea problemei.............................................................................................................49
Faza 2 - Determinarea cauzei................................................................................................................62
Faza 3 – Alegerea strategiei de tuning...................................................................................................70
Capitolul 4 - Optimizarea interogarilor.......................................................................................................74
Faza 1 - Identificarea problemei.............................................................................................................74
Faza 2 - Determinarea cauzei ...............................................................................................................87
Faza 3 - Alegerea strategiei de tuning.................................................................................................101
Studiu de caz...........................................................................................................................................122
Concluzii..................................................................................................................................................137
Anexa 1...................................................................................................................................................139
Anexa 2...................................................................................................................................................143
Anexa 3...................................................................................................................................................147
Anexa 4...................................................................................................................................................149
Anexa 5...................................................................................................................................................151
................................................................................................................................................................152
Bibliografie...............................................................................................................................................153
3
Introducere
1. Scopul lucrării
Problemele de performanţă sunt în general dificil de soluţionat, dar acestea devin şi mai dificile dacă nu
ştim unde să căutăm informaţia necesară.
Colectarea datelor de diagnosticare corecte este cel mai important prim pas în soluţionarea problemelor
de performanţă.
Diferite tipuri de probleme de performanţă necesită colectarea de informaţii diferite. Această lucrare va
acoperi cele mai întâlnite tipuri de probleme de performanţă , şi va sugera ce tipuri de informaţii ar trebui
colectate pentru fiecare categorie de probleme în parte, o analiză a lor, determinarea posibilelor cauze de
apariţie a acestora şi modele de soluţionare/tuning.
Ce este performanţa?
Performanţa unei baze de date poate să aibă standarde diferite pentru diferiţi utilizatori, de exemplu un
utilizator ce accesează o pagina web va fi interesat să vadă prima pagină de rezultate cât mai curând
posibil (timp de răspuns) iar procesarea altor pagini poate continua în pe fundal. Un utilizator care
lansează un proces, va fi interesat de finalizarea cât mai rapidă a acestuia. El nu este interesat să vadă o
pagină de rezultate, dar baza de date ar trebui să asigure cel mai bun rezultat al procesării (nu timpul de
răspuns). Alte aplicaţii s-ar putea să aibă alte definiţii pentru ceea ce consideră ei performanţe optime.
1. Definirea problemei
Din exemplul prezentat reiese cât de important este să ştim cât expectanţele utilizatorilor înainte de a
începe diagnosticarea propriu-zisă.
Întrebările simple pot fi întotdeauna utile:
• Care este exact problema?
• Care sunt aşteptarile utilizatorilor?
• Rezultatele aşteptate au fost vreodată obţinute?
Lista continuă (detaliată ierarhic pe tipul de problemă descoperit), dar ideea este să obţinem o înţelegere
exactă a problemei. Este foarte important ca problema să poată fii cuantificabilă, pentru a ştii când
rezultatele dorite au fost atinse.
4
2. De ce apar problemele de performanţă?
Această întrebare este cea mai relevantă pentru bazele de date din producţie care au funcţionat bine
pentru o vreme. Aceasta s-ar putea să nu se aplice unei baze de date din dezvoltare sau pre-producţie
unde definim valorile de referinţă.
Dar uneori devine un mister de ce au scăzut performanţele. În aceste cazuri utilizatorii trebuiesc întrebaţi
ce acţiuni au întreprins în trecut, de mai multe ori, pentru a evita emiterea de informaţii irelevante pentru
utilizatori, dar deţinatoare a soluţiei.
3. Colectarea de informaţii
Când se începe diagnosticare unei probleme, adesea afirmaţiile utilizatorilor sună de forma: "aplicaţia
merge încet.", "ceva s-a agaţat", "interogarea nu returnează rezultatele dorite". Este foarte important sa
întelegem ce merge “greu” sau s-a “agăţat”. Ar putea fi aplicatia, o sesiune utilizator, câteva interogări
sau insaşi baza de date.
Trebuie determinat dacă performanţa slabă a sistemului se observă în mod egal dacă volumul de date
rulat este mare sau mic. Dacă ar opera un singur utilizator activ? Performanţele sunt la fel de slabe?
Documentarea faptului cum performanţa sistemului este influenţată sau nu de volumul de date.
Problema poate fi reprodusă sistematic? Documentarea replicarii. dacă problema nu se poate replica,
trebuisc documentate cauzele.
5
A fost efectuat un upgrade sau a fost instalat un program nou pe server de când s-a constatat problema?
Au fost aplicate recent pachete noi sau service-pack-uri pentru sistemul de operare, aplicaţie sau baza de
date, care ar putea afecta performanţa sistemului?
Din răspunsurile la aceste întrebari, putem deja deduce tipul de problemă de performanţă.
Seturile de întrebări specifice per tipul de problemă vor fi detaliate în capitolele dedicate acestora.
6
Capitolul 1 - Metodologia problemelor legate de performaţa
bazei de date
ODM introduce o modalitate definită clar, o abordare standard în rezolvarea problemelor, dar şi o
documentare riguroasă a problemelor şi modalitaţilor de rezolvare a acestora. În acest mod, o nouă
apariţie a aceluiaşi tip de problemă, ar putea să nu mai necesite intervenţia unui specialist.
Utilizând acest principiu ca fundament, ODM rezolvă problemele utilizând următoarele faze:
Această etapă se axează pe identificarea şi verificarea problemei corecte pentru a fi soluţionate în cadrul
situaţiei curente. Problema trebuie enunţata în mod obiectiv fără înclinaţii către nici una din posibilele sale
cauze sau soluţii. Trebuie să fie cu scop restrâns, şi ar trebui să nu conţină sub-probleme sau probleme
fară legatură directă.
1
What is the Oracle Diagnostic Methodology (ODM)? [ID 553866.1]
https://support.oracle.com/CSP/main/article?cmd=show&id=553866.1&type=NOT, accesat la data 23.01.2010
7
Problema, de asemenea, trebuie să fie verificată pentru a ne asigura că există asa cum a fost descrisă.
Acest lucru se realizează prin colectarea de informaţii şi de date de diagnosticare. Pe parcursul colectarii
datelor, se poate întâmpla ca problema descrisă să nu fie cea ce reiese din informaţiile adunate, în acest
caz este necesară re-definirea problemei presupusă iniţial.
Verificarea problemei evită investigarea unei piste greşite şi pierderea timpului în soluţionarea unei
probleme greşit presupusă. Deasemenea acest pas asigură specialistul că investighează problema
corectă din ceea ce i-a fost raportat.
Aceasta faza identifica una sau mai multe cauze posibile pentru problema identificată anterior.
Cei trei paşi în determinarea cauzelor sunt:
Căutarea cauzei în termeni de condiţii şi acţiuni – O condiţie este o cauză care există în timp. O acţiune
este o cauză de moment ce cumulează condiţiile, pentru a determină un efect. Încercarea determinării
dacă o anumită cauză este o acţiune sau un efect, de obicei evidenţiază cauze adiţionale.
Justificarea cauzei – Pentru fiecare cauză identificată, ar trebui colectate date pentru a evidenţia că acea
cauză există în mediul examinat. Justificarea trebuie să se bazeze pe date exacte şi documentată clar.
De obicei, când se adună dovezi, o cauză poate fi exclusă sau înlocuită cu altele, datorită dovezilor ce
indică altceva. Dacă datele colectate nu pot proba cauza, aceasta nu ar trebui luată în considerare ca
fiind una validă.
În cazul în care o cauză concretă nu poate fi identificată, există posibilitatea unui bug, şi ar trebui
înregistrat corespunzător.
Scopul acestei faze este de a asigura una sau mai multe soluţii eficiente ce vor crea o stare dezirabilă
(problema nu mai există). Soluţiile ar trebui identificate pentru cauzele determinate, dând posibilitatea
posesorului sistemului sa aleagă una dintre ele pe baza criteriilor de mai jos.
8
În timpul acestei faze, se cercetează, încercând să recreem problema şi testând soluţiile posibile. În
timpul identificării soluţiilor posibile, date de diagnostic adiţionale ar putea fi necesare, pentru că soluţiile
corecte să fie identificate.
Se poate implementa şi o soluţie care nu întruneşte toate criteriile de mai sus. Trebuie identificate soluţii
pentru TOATE cauzele determinate, deşi unele soluţii se pot adresa unor cauze multiple.
Odata ce soluţiile au fost identificate, ele trebuie verificate să se adreseze cauzelor determinate. Prin
adresarea cauzei şi problemei direct, se poate ca problema să fi fost imparţită în bucăti mai mici, mai uşor
de adresat. În plus, dacă soluţia verifică rezolvarea cauzei, şi totuşi problema persistă, trebuie identificat
un nou set de cauze.
Verificarea soluţiei este o modalitate de a documenta de ce şi cum acea soluţie se adresează unei cauze.
Dacă soluţia nu poate fi verificată, atunci nu poate fi considerată validă. Acest proces reduce posibilitatea
implementării de soluţii care cel mai probabil nu vor rezolva problema iniţială.
Un plan de acţiune trebuie definit cuprinzând un numar de acţiuni cu o ordine pre-definită. Pentru fiecare
sarcină de efectuat din implementarea soluţiei, trebuie identificate eventualele probleme şi riscuri, cum se
pot preveni acestea şi cum li se vor face faţă în caz ca vor fi întâlnite.
9
2. Paşii diagnosticării unei probleme de performanţă a bazelor de date
Aceste date trebuie stabilite/ştiute din primele faze ale investigării deoarece vor determina modalitatea de
abordare ulterioară.
Ce încercăm să aflăm în urma diagnosticării este ce fel de problemă de performanţă este. Acest pas este
definitoriu pentru soluţionarea problemei.
Pentru facilitarea diagnosticării este important sa tratăm sistemul ca un tot unitar, şi să ştim detalii de
bună funcţionare (sau nu) a tuturor parăţilor sale componente.
Sistemului de operare ar trebui urmărit folosind utilitare precum Oracle OS Watcher, ce colectează
informaţii despre SO ca utilizarea procesorului şi informaţii despre memorie. Dacă instalarea de utilitare
adiniţionale nu este permisă, se poate folosi cel built-in ca vmstat.
În analiza informaţiilor despre sistemul de operare, trebuie să avem în vedere dacă nu cumva resursele
SO sunt deficitare. Se utilizează prea mult din capacitatea disponibilă a procesorului? Este memoria
suprasolicitată?
Dacă în urmă analizei datelor colectate despre SO, se concluzionează o bună funcţionare a acestuia, cel
mai probabil cauza problemei de performanţă cade în vina bazei de date.
În caz contrar, o funcţionare deficitară, înca nu putem fi siguri dacă nu este Oracle cel mai mare
consumator de resurse. Alte produse ar putea rula pe server-ul investigat.
10
a). ->DA -> Oracle consumă cel mai mult? -> DA -> investigarea proceselor
Dacă rezultatele investigării concluzionează ca Oracle database este cel mai mare consumator de
resurse, trebuie văzut care din procesele Oracle vizibile în logurile sistemului consumă resursele
procesorului. Şi de aici este un drum foarte scurt pană la obţinerea unui trace file pentru procesele în
cauză. Rezultatele investigării ar putea fi „în favoarea” Oracle, codul funcţional optim, interogări
performante, iar soluţia să fie adăugarea de memorie fizică.
Cel mai simplu ar fi să fie doar vorba de o sesiune singulară lentă, uşor de diagnosticat cu ajutorul unei
trace 10046 şi rezultatele tkprof, ca fiind problema de configurare a bazei de date, un posibil bug, o
problemă de interogări sau de conectivitate/networking.
În unele cazuri, este chiar baza de date în totatlitate care funcţionează lent.
În acest moment avem nevoie de o listă cu sesiunile cheie cu cel mai mare dbtime. Dintre sutele de
sesiuni ce pot fi afişate este imposibil să le analizăm pe toate. Nu le putem urmări pe toate. Trebuie
identificaţi candidaţii optimi de inregistrat şi intocmită o listă cu procesele cele mai afectate de problema
de performanţă. Odată acest lucru realizat le putem analiza corespunzător.
Colectarea de date utilizând rapoartele statspack, AWR, ASH este foarte utilă în identificarea proceselor
problematice.
Alte daţi, utilizatorii raportează blocări. Se pot referi la blocarea întregii baze de date, sau blocare la
realizarea unor operaţiuni.
„Blocare” are în consensul Oracle un inţeles concret, o resursa ce a fost cerută şi nu raspunde la
comenzi. Această problemă va fi adreasată cu intrumente specifice, de genul HangAnalyze, Systemstate,
Errorstack, Pstack, Transient, LTOM, etc.
Tipul de blocare, cel real, este adeasea confundat de către utilizatori cu interogări care durează foarte
mult până să returneze rezultate. Acesta nu este o blocare în sensul Oracle, şi se va incadra în categoria
interogărilor problematice sau chiar în cea a funcţionarii lente a bazei de date.
11
Capitolul 2 - Functionarea lentă a bazei de date
A. Generalităţi2
Pentru a identifica problema pe care dorim să o rezolvam, trebuie să indeplinim următoarele sarcini:
• Să recunoaştem problema.
• Să clarificăm detaliile din jurul problemei
• Să verificăm dacă problema identificată este acceaşi cu cea raportată.
12
b. Clarificarea problemei
O specificare clară a problemei este foarte importantă. Trebuie declarat exact care este problema. Se
poate întâmpla ca în faze ulterioare, sau în timp ce se lucrează la problema, adevărata problemă să iasă
la iveală, şi să fie necesar o redefinire a acesteia.
Pentru a clarifica problema, este necesar să se ştie cât mai multe dintre următoarele:
• Când sistemul a funcţionat lent şi când nu.
• Orice schimbari ce coincid cu performanţele slabe ale sistemului.
• Secvenţa de evenimente ce conduc la problema raportată
• Când/cum a fost observată problema?
• Importanţa problemei
• Ce funcţionează bine?
• Care este rezultatul aşteptat sau acceptat?
• Ce s-a încercat deja pentru rezolvarea problemei?
Exemple practice:
• Un sistem funcţionează deficitar în fiecare dimineaţă intre 10am şi 12pm, în rest funcţionează
bine.
• Problema apare după ce a fost instalată ultima versiune a aplicaţiei.
• Aplicaţia funcţionează lent şi împiedică sistemul să înregistreze comenzile.
• Sistemul funcţionează bine, cu excepţia intervalului 10am-12pm
• Cererile sunt procesate de obicei de către baza de date în 200ms, de când a apărut problema,
procesarea durează 10s.
• S-a încercat re-colectarea de statistici, dar situaţia nu s-a îmbunătăţit.
Obiectivul acestui pas din procesul de diagnosticare este să ne asigurăm că baza de date are
simptomele unei probleme de performanţă. În acest moment trebuie să colectăm date ce verifică
existenţă problemei.
13
• Dovezi specifice ale performanţelor deficitare pentru o sesiune sau diferite interogări.
• Trace-uri extinse ale interogărilor pentru una sau mai multe sesiuni în perioadele cu performanţe
bune şi în cele deficitare.6
Exemple şi sugestii despre ce informaţii de diagnosticare sunt necesare pentru rezolvarea problemei se
vor discuta în secţiunea dedicată colectării de date.
Odată ce datele au fost adunate, ele vor fi analizate pentru a verifica dacă intr-adevar este o problemă de
latentă, sau dacă este vorba de alt tip de problemă.
6
Oracle® Database Performance Tuning Guide 10g Release 1 (10.1), Using the SQL Trace Facility and TKPROF,
http://download.oracle.com/docs/cd/B14117_01/server.101/b10752/sqltrace.htm#8723 , accesat la data 24.01.2010
7
Oracle® Database Performance Tuning Guide 10g Release 1 (10.1),
http://download.oracle.com/docs/cd/B14117_01/server.101/b10752/sqltrace.htm#8723 , accesat la data 24.01.2010
8
FAQ- Statspack Complete Reference [ID 94224.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=94224.1&type=NOT , accesat la data 24.01.2010
9
Recommended Method for Obtaining 10046 trace for Tuning [ID 376442.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=376442.1&type=NOT , accesat la data 24.01.2010
14
Exemple:
Event 10046 va produce un fişier de trace în <<Parameter user_dump_dest>> pentru procesele utilizator,
iar pentru procesele background, în <<Parameter background_dump_dest>>.
Odată ce identificatorul procesului a fost determinat, urmărirea sa poate fi iniţializată după cum urmează:
Presupunem că acesta are oracle pid 9834.
Dezactivarea
15
Setarea va fi dezactivată prin eliminarea parametrului şi repornirea instanţei
Trace-urile SQL sunt foarte utile pentru diagnosticarea problemelor de performantă deoarece ele vor
evidenţia exact ce interogări sunt cel mai afectate, şi cum au fost afectate acestea ( procesor, timpi de
aşteptare, idle time). Secretul constă în obţinerea trace-ului pentru cea mai importantă şi mai afectată
sesiune cât mai complet posibil.
Exemplu real:
Următorul proces ne va ajuta sa obţinem datele dintr-un SQL trace în mod corect:
Alegerea sesiunii
În acest exemplu vom identifica care sunt sesiunile active care au acumulat cel mai mult timp din
procesor.
Următoarea interogare filtrează sesiunile pe baza timpului de logare, mai mic de 4 ore, şi ultima accesare
în ultimele 30 de minute. Aceste restricţii sunt pentru a găsi sesiuni curente mai relevante, decât cele
care rulează de mult şi care au acumulat mult CPU time, dar nu au probleme de performanţă. Valorile
prezentate sunt orientative.
16
ORDER BY st.value;
17
FROM v$sesstat st, v$statname sn, v$session s, v$sesstat stcpu, v$statname sncpu, v$process p
WHERE sn.name = 'DB time' -- CPU
AND st.statistic# = sn.statistic#
AND st.sid = s.sid
AND sncpu.name = 'CPU used by this session' -- CPU
AND stcpu.statistic# = sncpu.statistic#
AND stcpu.sid = st.sid
AND s.paddr = p.addr
AND s.last_call_et < 1800 -- active în ultima jumatate de ora
AND s.logon_time > (SYSDATE - 240/1440) -- sesiuni logate în ultimele 4 ore
AND st.value > 0;
SID SERIAL# OS PID USERNAME MODULE DB Time(sec) CPU Time (sec) % CPU
---------- ---------- ------------ -------- ----------------------------------------------------- -------------- -----------
141 1125 15315 SYS sqlplus@coehq2 (TNS V1-V3) 12.92 9.34 72.29
Ideal ar fi să putem porni un trace imediat ce utilizatorul s-a logat şi începe operaţilunile sale sau
tranzacţiile. Trigger-ul menţionat anterion poate fi folosit în aceste situatii.
Fişier de trace pentru on proces ce rulează mult, care a fost urmarit intermitent în ultimele zile
. . .
*** 2009-07-24 13:35:05.642 <== Timestamp de la o urmarire anterioara
WAIT #8: nam='SQL*Net message from client' ela= 20479935 p1=1650815232 p2=1 p3=0
=====================
PARSING IN CURSOR #9 len=43 dep=0 uid=57 oct=3 lid=57 tim=1007742062095 hv=4018512766
ad='97039a58'
select e.empno, d.deptno<== cursor precedent ce a fost urmarit
from emp e, dept d
18
END OF STMT
PARSE #9:c=630000,e=864645,p=10,cr=174,cu=0,mis=1,r=0,dep=0,og=4,tim=1007742062058
BINDS #9:
EXEC #9:c=0,e=329,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=1007742062997
WAIT #9: nam='SQL*Net message to client' ela= 18 p1=1650815232 p2=1 p3=0
. . .
FETCH #9:c=10000,e=513,p=0,cr=1,cu=0,mis=0,r=15,dep=0,og=4,tim=1007742148898
WAIT #9: nam='SQL*Net message from client' ela= 2450 p1=1650815232 p2=1 p3=0
WAIT #9: nam='SQL*Net message to client' ela= 7 p1=1650815232 p2=1 p3=0
FETCH #9:c=0,e=233,p=0,cr=0,cu=0,mis=0,r=10,dep=0,og=4,tim=1007742152065
. . .
====> ACESTE LINII NU FAC PARTE DIN TEST <====
*** 2006-07-24 18:35:48.850
<== Timestamp oentru trace-urile pe care le urmarim (aprox 5 ore mai tarziu)
=====================
PARSING IN CURSOR #10 len=69 dep=0 uid=57 oct=42 lid=57 tim=1007783391548 hv=3164292706
ad='9915de10'
alter session set events '10046 trace name context forever, level 12'
END OF STMT
. . .
=====================
PARSING IN CURSOR #3 len=68 dep=0 uid=57 oct=3 lid=57 tim=1007831212596 hv=1036028368
ad='9306bee0'
select e.empno, d.dname<== Cursorul ce a fost urmarit
from emp e, dept d
where e.deptno = d.deptno
END OF STMT
PARSE #3:c=20000,e=17200,p=0,cr=6,cu=0,mis=1,r=0,dep=0,og=4,tim=1007831212566
BINDS #3:
EXEC #3:c=0,e=321,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=1007831213512
WAIT #3: nam='SQL*Net message to client' ela= 15 p1=1650815232 p2=1 p3=0
WAIT #3: nam='db file sequential read' ela= 7126 p1=4 p2=11 p3=1
. . .
FETCH #3:c=10000,e=39451,p=12,cr=14,cu=0,mis=0,r=1,dep=0,og=4,tim=1007831253359
WAIT #3: nam='SQL*Net message from client' ela= 2009 p1=1650815232 p2=1 p3=0
WAIT #3: nam='SQL*Net message to client' ela= 10 p1=1650815232 p2=1 p3=0
FETCH #3:c=0,e=654,p=0,cr=1,cu=0,mis=0,r=13,dep=0,og=4,tim=1007831256674
WAIT #3: nam='SQL*Net message from client' ela= 13030644 p1=1650815232 p2=1 p3=0
STAT #3 id=1 cnt=14 pid=0 pos=1 obj=0 op='HASH JOIN (cr=15 pr=12 pw=0 time=39402 us)'
=====================
PARSING IN CURSOR #7 len=55 dep=0 uid=57 oct=42 lid=57 tim=1007844294588 hv=2217940283
ad='95037918'
alter session set events '10046 trace name context off' <== tracing-ul a fost oprit
END OF STMT
Dacă urmărirea a început sau s-a sfarşit în timpul unei apelări, este bine să regândim procesul ca acest
lucru să nu se întâmple din nou.
19
*** 2006-07-24 15:00:45.538 <== Timpul când s-a inceput urmarirea asteptarea
WAIT #3: nam='db file scattered read' ela= 18598 p1=4 p2=69417 p3=8 <== Wait
*** 2006-07-24 15:01:16.849 <== 10g va scrie mesaje dacă în trace nu s-a scris nimic de
ceva vreme
WAIT #3: nam='db file scattered read' ela= 20793 p1=4 p2=126722 p3=7
. . .
*** 2006-07-24 15:27:46.076
WAIT #3: nam='db file sequential read' ela= 226 p1=4 p2=127625 p3=1 <== Yet more waits
WAIT #3: nam='db file sequential read' ela= 102 p1=4 p2=45346 p3=1
WAIT #3: nam='db file sequential read' ela= 127 p1=4 p2=127626 p3=1
WAIT #3: nam='db file scattered read' ela= 2084 p1=4 p2=127627 p3=16
. . .
*** 2006-07-24 15:30:28.536 <== Timestamp final inainte şi după apelarea FETCH
WAIT #3: nam='db file scattered read' ela= 5218 p1=4 p2=127705 p3=16 <== Final wait
WAIT #3: nam='SQL*Net message from client' ela= 1100 p1=1650815232 p2=1 p3=0
=====================
PARSING IN CURSOR #3 len=39 dep=0 uid=57 oct=0 lid=57 tim=1014506207489 hv=1173176699
ad='931230c8'
select count(*) from big_tab1, big_tab2 <== Aceasta nu este parsarea unui apel real
END OF STMT
FETCH #3:c=0,e=11,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=0,tim=1014506207466 <== Terminarea
apelului de FETCH
FETCH raportează 11 microSec.Acest rezultat este greşit după cum se poate observa din
timestamps. Ar trebui să fie aprox. 30 min.
Datele despre sistemul de operare sunt necesare pentru a vedea performanţele maşinii pe care rulează
Oracle.
Începând cu versiunea 10g, rapoartele statspack conţin şi date despre sistemul de operare.
Ca aletrnativă se poate folosi una dintre următoarele:
• OS Watcher (de preferat) – este o colecţie de scripturi shell UNIX ce colectează şi arhivează
metrice ale sistemului de operare şi ale reţelei pentru a susţine soluţionarea problemelor de
performanţă. OSW funcţionează ca un set de procese background pe server şi colectează date
despre SO la intervale constante, apelând utilitare UNIX ca vmstat, netstat sau iostat.10
• LTOM – Lite Onboard Monitor, este un program java, dezvoltat ca o platformă de diagnosticare
în timp real. Diferenţierea acestui utilitar de altele de acest gen, constă în faptul ca funţionarea sa
este mai mult pro-activă decât reactivă. LTOM asigură detectarea problemelor în timp real şi
colectarea de date, fiind foarte util în cazul problemelor neprevăzute.11
10
OS Watcher User Guide [ID 301137.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=301137.1&type=NOT, accesat la data 25.01.2010
11
LTOM - The On-Board Monitor User Guide [ID 352363.1],
20
• Enterprise Manager – pagina de performance management include grafice ce arată date despre
performanţele procesorului şi a memoriei, cât şi informaţii detaliate despre procese. Este tot un
uitlitar în timp real, din aceasta cauza vor fi necesare capturi de ecran pentru analizele
ulterioare.12
Raport RDA
Rapoartele RDA colectează multe tipuri de date diferite despre sistemul investigat, ce vor fi utilizate la un
moment dat în procesul de diagnosticare.13
21
Utilizarea procesorului diferă în funcţie de cum colectăm datele despre SO:
Statistic Total
------------------------- -------------------------------------------------------
BUSY_TIME 14,257
IDLE_TIME 53
IOWAIT_TIME 34
SYS_TIME 2,302
USER_TIME 11,955
LOAD 10
OS_CPU_WAIT_TIME 156,500
VM_IN_BYTES 0
PHYSICAL_MEMORY_BYTES 2,081,890,304
NUM_CPUS 1
22
%DB time waiting for CPU - Resource Mgr:
Procentul ocupat din instanţa ne spune cât din procesorul gazda este utilizat de instanţa investigată, în
acest caz, 74.55%, iar răspunsul este afirmativ, această instanţă consumă cel mai mult din capacitatea
procesorului.
OSWatcher
Memory: 2048M real, 29M free, 4316M swap in use, 1847M swap free
PID USERNAME THR PRI NICE SIZE RES STATE TIME CPU COMMAND
19003 oracle 1 32 0 0K 0K run 6:37 25.13% oracle
6446 oracle 1 0 0 0K 0K run 0:05 21.31% oracle
1980 oracle 30 29 10 200M 53M sleep 1:23 4.83% java
6408 oracle 1 59 0 26M 12M sleep 0:01 2.68% perl
26471 oracle 1 59 0 0K 0K sleep 0:01 1.48% oracle
6424 oracle 1 59 0 0K 0K sleep 0:00 0.81% oracle
697 oracle 14 59 -5 0K 0K sleep 340:59 0.67% ocssd.bin
6455 oracle 1 59 0 0K 0K sleep 0:00 0.56% oracle
28744 oracle 1 59 0 0K 0K sleep 3:50 0.25% oracle
Primele două procese Oracle folosesc aprox 46% din capacitatea procesorului
1. Deficit de memorie?
Memory Page Scan Rate (pagini/s) – măsoară cât de mult page-scanner-ul se străduie să revendice
memorie. Când aceasta este de sute/s, cel mai probabil avem un deficit fizic de memorie.
23
Utilizarea Swap (% sau KB liberi) - cât din partiţia de swap este utilizată. Dacă memoria fizică devine
deficitară, acest procent creşte. Dacă acesta se apropie de 100%, nevoia de memorie devine tot mai
mare, iar sistemul devine inutilizabil (şi va pica).
10gR2 Statspack
Dacă valoarea % Host Mem used for SGA+PGA este ridicată , atunci se verifică utilizarea de către
această instanţă a majoritaţii memoriei.
OSWatcher
Dacă la această întrebare se răspunde afirmativ în urma analizei, atunci s-a verificat existenţa unei
probleme de performanţă Oracle, iar următorul pas este identificarea cauzelor de apariţie.
Idea principală în această comparaţie este să confruntăm DB Time total din rapoartele “bune” şi cele
“rele”. DB Time este timpul total petrecut de baza de date fie procesând (CPU) sau aşteptând după un
24
eveniment non-idle. Când există o problemă de performanţă, DB Time creşte (de obicei deoarece există
multe sesiuni care aşteaptă după evenimente non-idle).
1. 10.2.x: Comparaţie între două rapoarte ASH dintr-o perioadă cu funcţionare optimă şi una
deficitară
Vom compara media sesiunilor active în cele două rapoarte. Media sesiunilor active va arăta câte sesiuni
erau fie în procesor sau aşteptând după un eveniment non-idle. Când performanţa este deficitară din
cauza bazei de date, numărul de sesiuni active va fi mai mare decât în cea cu performanţa optimă. Acest
lucru se datorează faptului ca atunci când există un deficit de resurse, mai multe sesiuni vor fi nevoite să
aştepte activ pentru o anumită resursă şi din această cauză numărul de sesiuni active va fi mai mare.
25
Se observă creşterea numărului mediu de sesiuni active când performanţa nu este optimă, este vorba de
o creştere de 500% (de la 2.65 la 10.11). De asemenea, se observă o schimbare la Top User Events,
timpul de aşteptare a trecut de la “db file sequential read” la “read by other session” şi “CPU+Wait for
CPU”, împreună cu “db file scattered read”. Acest fapt se datorează unui index şters într-o tabelă
importantă. O interogare care în mod normal folosea indexul, acum efectuează un scan complet al tabelei
în perioada cu performanţă deficitară.
Utilizarea unui singur raport statspack nu este relevantă pentru verificarea problemei. Totuşi, putem să ne
uităm la Top 5 evenimente, şi să vedem dacă acestea sunt bune.
26
Evenimente “sănătoase”:
• CPU
• db file sequential read
• db file scattered read
• direct path read
• direct path write
Prezenţa acestor evenimente înseamnă fie o necesitate de a adăuga capacitate procesorului, sau poate
ceva tuning al interogărilor. În orice caz, soluţiile sunt uşor de obţinut prin rezolvări comune.
Se vor analiza datele din trace-ul interogării pentru a verifica dacă baza de date are o problemă de
performanţă.
Variante:
Putem vedea dacă există o problemă de performanţă prin compararea trace-urilor de execuţie ale
aceleiaşi operaţii în cele doua perioade.
- în varianta optimă, la sfarşitul TKProf-ului se vor observa următoarele valori (atat cele recursive cât şi
cele non-recursive):
total elapsed time
total calls
idle time, i.e., SQL*Net Message from client wait, total waited
total number of rows returned
- se vor calcula următoarele metrice:
elapsed time / call = (total elapsed recursive + total elapsed non-rec) / total calls
rows / call = total rows / total calls
total idle time / call =[ idle time (non-recursive) + idle time (recursive)] / total calls
- se vor repeta operaţiunile anterioare şi pentru performanţa deficitară
- se vor compara metricile calculate între cele doua perioade
Concluzii
27
• Nici o problemă – fişierele de trace sunt similare. Acest lucru arată ca nici baza de date, nici
clientul nu au latenţă. Problema ar putea fi inaintea clientului / mid-tier, ex. browser-ul sau
reţeaua ar putea avea latenţă. În acest moment investigarea bazei de date va înceta, iar
eforturile se vor concentra pe clienţi.
• Problemă a bazei de date – comparaţia între fişierele de trace arată Elapsed Time/call mai mari,
ceea ce înseamnă că bazei de date îi ia mai mult timp să execute aceleaşi procesări. Se
confirmă o problemă de performanţă a bazei de date. Pasul următor ar fi identificarea cauzei.
• Problema de client (generală) – comparaţia între fişierele de trace arată că baza de date este mai
mult idle şi nu îi trebuie mulţi timpi de procesare/actiune. De obicei, acest lucru spune despre
clientul bazei de date sau despre reţea că trimit cereri către baza de date, ce pare mai lentă din
punctul de vedere al utilizatorului. În acest moment investigarea bazei de date va înceta, iar
eforturile se vor concentra pe clienţi.
• Problema de client (arraySize) – clientul procesează mai puţine cereri/acţiuni de la baza de date.
Acest comportament este ineficient şi stresează baza de date (mai multe citiri logice, block pins,
context switches, etc.). Pentru a rezolva această problemă, clinetul va trebui să ceară mai multe
procesări. În acest moment investigarea bazei de date va înceta, iar eforturile se vor concentra
pe clienţi.
Exemplu de analiza
28
29
30
Metricele calculate pentru datele adunate sunt:
31
Dacă în cadrul analizei de mai sus s-a concluzionat că este vorba de o problemă a bazei de date, trebuie
să trecem la pasul următor când vom încerca să identificăm care este cauza apariţiei acestor probleme.
Utilizănd datele colectate anterior trebuie să identificăm ariile problematice ale bazei de date. Tuningul
unei baze de date este adesea un proces iterativ, unde sunt identificate blocajele şi rezolvate cu fiecare
iteraţie.
Wait bottleneck
TKPROF
Vom compara durata totală cât procesorul a lucrat concret cu durata procesului. Dacă timpii non-idle sunt
mai mari decât cei procesaţi din durata totală, atunci avem o problemă “wait bottleneck”, în caz contrar o
problemă legată de cunsumul procesorului.
Exemplu
În acest caz vom observa o problemă la timpii de aşteptare “read by other session”. Deasemnea, mai
sunt timpi de aşteptare pentru procesor (ex. o coadă de procese semnificativă datorată supraîncărcării)
ce contează la diferenţa dintre timpul total şi suma timpilor de procesare şi cei de aşteptare.
32
Total CPU time = 24.58 sec
Total DB Time = 284.16 sec
33
Wait: "db file scattered read" = 7.11 / 284.16 = 2.5%
Exemplu
În acest caz se observă un bottleneck mare pentru read by session (79.6% din timpul total al procesării):
Rapoarte ASH
Se va examina secţiunea Top user events, %Activity.
Exemplu
În acest caz, se observă un bottleneck mare pentru read by session (53.4% din sesiunile active).
34
Client bottleneck
Acest tip de blocaj este detectat prin observare faptului că sesiunile petrec majoritatea timpului aşteptând
după un eveniment dinafara Oracle.
Timpii de aşteptare ai clientului pot fi văzuti, agregaţi într-un fişier TKProf, uitându-ne la secţiunea
OVERALL TOTALS:
În acest exemplu putem observa că timpii bazei de date reprezintă doar un mic procent din timpul total
(atât timpii recursivi cât şi cei non-recursivi):
35
Total Time = Database elapsed time + Client Idle time = 2.12 + 187.32 = 189.44 sec
% Client Idle Time = Client Idle Time / Total Time = 187.32 / 189.44 * 100% = 98.9%
Din moment ce aproape 99% din timp este folosit aşteptând clientul, confirmă ipoteza iniţială.
Ca modalitate de rezolvare se poate reduce numărul de apeluri fetch sau tuning-ul clinetului.
Investigarea continuă prin verificarea dacă timpii de aşteptare sunt mari prentru Orice tip de procesare,
prin examinarea unui fişier brut de trace 10046 şi observând timpii de aşteptare pentru mesajele SQL*Net
pentru evenimentele clientului, ce apar în liniile începând ce “WAIT 80”:
În acest exemplu se pot observa două feluri de WAIT: WAIT#0 şi WAIT#1. simbolul # este asociat unui
cursor când este mai mare de 0. Linia "WAIT #0, SQL*Net message from client" este o aşteptare
după ce ultimul fetch s-a terminat şi baza de date aşteaptă un nou apel. Linia "WAIT #1, SQL*Net
message from client" este pentru client, dar pentru un cursor deschis din care tocmai s-a extras. Dacă
ar fi fost executate mai puţine extrageri, numarul aşteptărilor WAIT#1 ar fi putut fi reduse. WAIT#0 pot fi
reduse doar prin folosirea unui client mai rapid.
Acum trebuie să verificăm dacă majoritatea timpului de aşteptare este petrecut aşteptând între două
apeluri de fetch. În raportul TKProf, se poate observa că timpul total al bazei de date este mic în
comparaţie cu cel aşteptat de către client. Deasemenea se poate observa timpul petrecut în mesaje
SQL*Net pentru client:
36
Observatii: 8 apeluri fetch pentru a returna 14 randuri. 78.39 secunde aşteptând SQL*Net message from
client pentru 8 aşteptări. Fiecare aşteptare corespunde fiecărui apel fetch. Timpul total al bazei de date a
fost de 377 microsecunde, dar timpul total pentru returnarea celor 14 rânduri a fost de 78.39 secunde
datorită latenţei clientului. Dacă s-ar reduce numărul de apeluri fetch, se va reduce timpul total.
În orice caz, starea bazei de date este bună, problema fiind una externă.
Se va alege una dintre strategiile de ma jos, în funcţie de tipul de problemă de performanţă identificat.
Pentru Oracle 10g şi versiunile ulterioare, se recomandă utilizarea ADDM pentru tuning-ul bazei de date.
Oracle 10g poate să îndeplinească analize de tuning utilizând ADDM. Se consideră a fi metoda preferată,
tuning-ul manual fiind ultima variantă. Pentru a putea folosi utilitarul ADDM, este necesară o licenţă
pentru Tuning Pack.
În ceea ce priveşte bazele de date, procesorul poate avea două tipuri de consum diferite:
• Parse CPU – capacitatea procesorului utlizată când Oracle procesează (şi optimizează) o
comandă
37
• Non-Parse CPU – capacitatea CPU folosită de Oracle când este angajat în procesări, ca de ex.
când citeşte blocuri în buffer cache, când execută o sortare sau un join, citirea unui fişier, etc.
Acest consum mai este referit cu ajutorul sintagmei “Other CPU”.
Procesorul este urmărit sub sigla “Recursive CPU”. Aceasta reprezintă capacitatea procesorului folosită
de comenzile ce sunt apelate de alte comenzi. Deoarece Recursive CPU se referă la ambele tipuri de
comsum precizate anterior, nu prezintă interes pentru tuning.
a. Cel mai mult timp de procesare se datorează unei (sau mai multor) interogări SAU agregării lor?
• Pentru a raspunde la această întrebare se va genera un nou raport TKProf ordonat după timpul
de parse CPU :
• tkpof trace_file_name output_file sort=prscpu
Probleme posibile:
Una sau mai multe interogări ce consumă mult din capacitatea procesorului în timpul HARD parse. Este
adesea observată când comenzi de dimensiuni mari invocă multe obiecte.
38
Ce să căutăm:
Comanda a fost parsată hard?
Sa comparăm parse cpu time cu parse elapsed time şi să vedem dacă parse cpu time>50%
Cauze identificate:
• S-a folosit dynamic sampling pentru interogare
• Interogarea foloseşte operatori IN / OR
• Tabelele partiţionate au multe partiţii
Model de tuning
Problema identificată: Una sau mai multe interogări ce prezintă consum mare de procesor în timpul unei
HARD parse
Acest compertament este adesea întâlnit când comenzi voluminoase invocă multe obiecte sau obiecte
partiţionate.
Ce să căutăm:
1. Trebuie să verificăm dacă instructiunea/comanda a fost parsată HARD
2. Trebuie sa comparăm “parse CUP time” cu “parse elapsed time” şi să vedem dacă “parse cpu time” este
mai mult de 50%
Cauza identificată: Interogarea foloseşte mostre dinamice şi influenţează în mod negativ timpul de procesare
Justificarea cauzei:
- timpul de procesare este responsabil pentru timpul total de execuţie al interogării
- rezultatul planului de execuţie SQLTXPLAIN, scriptul UTLXPLS, trace-ul 10053 vor arăta ca pentru
optimizarea interogării s-au folosit mostre dinamice.
Efort -mediu
Unele alternative sunt mai uşor de implementat (adaugarea unui hint), iar altele sunt mai dificile (determinarea
hint-ului necesar prin comparaţia planurilor de execuţie).
Risc – scăzut
În general, această soluţie va afecta doar interogarea în cauză.
Implementarea soluţiei
Câteva alternative la mostrele dinamice sunt:
39
1. În 10g sau versiuni ulterioare, se va folosi SQL Tuning Advisor (STA) pentru a genera un profil pentru
interogarea vizată.
2. Se vor gasi hint-urile necesare pentru implementarea planului generat normal prin utilizarea mostrelor
dinamice şi se va modifica interogarea cu hint-ul identificat.
3. Se va folosi outline-ul salvat pentru a capta un plan generat cu mostre dinamice. Pentru date foarte volatile
(pentru care mostrele dinamice ajutau la obţinerea unui plan de execuţie bun), se poate folosi
abordarea ca aplicaţia va alege una dintre interogările cu hint-uri în funcţie de starea datelor (ex.
pentru date şterse recent foloseşte interogarea#!, altfel interogarea#2).
Verificarea implementării
Se va implementa soluţia şi se va verifica dacă performanţele bazei de date se îmbunătăţesc. În caz contrar
trebuie să examinăm următoarele:
- să luăm în considerare alte posibile cauze
- să verificăm dacă datele au fost colectate corect
- să verificăm dacă problema iniţială.
O alternativă ar fi înregistrarea unui Service Request cu Oracle Support pentru asistenţă în rezolvarea
acestei probleme.
14
Oracle® Database Performance Tuning Guide 10g, Release 2 (10.2) – Chapter 16 Using Optimizer Hints
http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14211/hintsref.htm#sthref1602 , accesat la data 25.01.2010
15
Forcing a Known Plan Using Hints [ID 221970.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=221970.1&type=NOT , accesat la data 25.01.2010
16
How to specify an INDEX Hint [ID 50607.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=50607.1&type=NOT , accesat la data 25.01.2010
17
QREF: SQL Statement HINTS [ID 29236.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=29236.1&type=NOT , accesat la data 25.01.2010
18
Oracle® Database Performance Tuning Guide 10g, Release 2 (10.2) – Chapter 18 Using Plan Stability,
http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14211/outlines.htm#sthref1787 , accesat la data 25.01.2010
19
Stored Outline Quick Reference [ID 67536.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=67536.1&type=NOT , accesat la data 25.01.2010
20
How to Tune a Query that Cannot be Modified [ID 122812.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=122812.1&type=NOT , accesat la data 25.01.2010
40
Consumul procesorului pentru activităţi non-parse
Acest tip de consum se datorează, de obicei, interogărilor SQL cu performanţe slabe, sau procedurilor
PL/SQL.
Probleme posibile:
Una sau mai multe interogări folosesc cel mai mult din non-parse CPU
Ce să căutam:
TKProf – doar câteva interogări folosesc cel mai mult din totatul consumul procesorului (top statements
când TKProf este sortat după timpul de fetch şi execute)
Rapoarte AWR sau statspack – doar acteva interogări sunt raportate cu un consum mare de procesor
(secţiunea Top 5 events).
Cauze identificate:
Sunt necesare optimizări ale interogărilor (capitolul V)
41
latch: library cache Concurrency - Latches and Mutexes
latch: shared pool Concurrency - Latches and Mutexes
library cache lock Concurrency - Enqueues / Locks / Pins
library cache pin Concurrency - Enqueues / Locks / Pins
log buffer space Configuration
log file sync Commit
read by other session Concurrency - Buffer Busy Waits
Buffer busy waits indică existenţa unor buffer-e în buffer cache pe care multiple procese încearcă ori să le
acceseze concurent în timp ce sunt citite de pe disc, ori aşteaptă după altă sesiune să termine
modificarile în blocuri.
Unde să căutăm
• TKProf – Overall wait event summary pentru comenzile recursive şi non-recursive arată timpi
semnificativi pentru buffer busy waits
• AWR/statspack – buffer busy waits este în topul evenimentelor cele mai mari consumatoare de
timp.
Cauze identificate:
• O activitate de inserare masivă ce afectează segmentul de index
• Multe interogări concurente ce efectuează citiri fizice
• Multe interogări concurente ce efectuează citiri fizice şi performanţa I/O este scăzută
Problema identificată:
• Read by other session
Cauze identificate:
• Sunt necesare optimizări ale interogărilor, nu sunt prezente şi probleme de I/O
• Probleme de performanţă ale I/O
• Buffer cache este de dimensiune mică
Problema identificată:
• Cozi de aşteptare
Cauze identificate:
• Coloanele chei străine au lipsă un index21
21
Anexa 4
42
• ANALYZE INDEX blochează comenzile DML
• Pe acelaşi obiect se utilizează un DML în timp ce deja rulează un parallel DML
select o.object_name,l.oracle_username,l.os_user_name,l.session_id
,decode(l.locked_mode,2,'Row-S',3,'Row-X',4,'Share',5,'S/Row-X',6 ,'Exclusive','NULL')
from user_objects o , v$locked_object l
where o.object_id = l.object_id;
• Aşteptări ale unei rezervări la nivel de înregistrare datorate unei proiectări defectuase a aplicaţiei
• Obiecte ce sunt compilate în timpul sesiunii
• Procesul de auditare este pornit
• Folosirea excesiva a declanşatoarelor la nivel de înregistrare
Model de tuning
Verificarea problemei:
TKProf – Overall wait event summary pentru comenzile recursive şi non-recursive arată timpii
semnificativi pentru buffer busy waits
AWR/statspack – buffer busy waits este în topul evenimentelor cele mai mari consumatoare de timp.
Cauza identificată: Multe comenzi SQL concurente execută citiri fizice. Acest fapt conduce la timpi mari
de aşteptare pentru buffer-e, deoarece o sesiune va fi cea care scrie fizic, iar celelate vor fi blocate de
către evenimentul buffer busy wait până când citirea s-a terminat. De obicei, acest fapt este un indiciu că
interogarea ar trebui optimizată.
Justificarea cauzei:
TKProf
- rapoarte TKProf ordonate după elapsed execute time
- trebuie să ne uităm la topul comenzilor şi să determinăm dacă acestea “vad” buffer busy waits şi dacă
sunt interogări sau comenzi DDL ce conţin sub-interogări.
Efort – scăzut
43
Risc - scăzut
Acţiunea de optimizare va fi, în general, de creare a unui profil de comandă. Profilul afectează doar o
singura comandă. Orice altă recomandare ar trebui testată cu prudenţă.
Implementarea soluţiei
Detalii despre SQL Tuning Advisor se pot găsi în următoarele documente:
How-To
How to use the Sql Tuning Advisor22
Documentaţie
Automatic SQL Tuning23
Using Advisors to Optimize Database Performance24
Using SQL Tuning Advisor with Oracle Enterprise Manager25
Referinţe
SQL Tuning Advisor Subprograms26
Using SQL Tuning Advisor APIs27
Automatic SQL Tuning - SQL Profiles28
Anexa 5
Verificarea implementării
Se va implementa soluţia şi se va verifica dacă performanţele bazei de date se îmbunătăţesc. În caz contrar
trebuie să examinăm următoarele:
- să luăm în considerare alte posibile cauze
- să verificăm dacă datele au fost colectate corect
- să verificăm dacă problema iniţială.
22
How to use the Sql Tuning Advisor. [ID 262687.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=262687.1&type=NOT , accesat la data 25.01.2010
23
Oracle® Database Performance Tuning Guide - 10g Release 2 (10.2), Chapter 12 Automatic SQL Tuning,
http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/sql_tune.htm#PFGRF028 , accesat la data 25.01.2010
24
Oracle® Database 2 Day DBA 10g Release 2 (10.2) - Using the SQL Tuning Advisor,
http://download.oracle.com/docs/cd/B19306_01/server.102/b14196/montune003.htm#sthref784 , accesat la data 25.01.2010
25
Oracle® Database Performance Tuning Guide 10g Release 2 (10.2) – Chapter 12 Automatic SQL Tuning
http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/sql_tune.htm#PFGRF028 , accesat la data 25.01.2010
26
Oracle® Database PL/SQL Packages and Types Reference 10g Release 2 (10.2) – Chapter 101 DBMS_SQLTUNE,
http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_sqltun.htm#sthref7584 , accesat la data 25.01.2010
27
Oracle® Database Performance Tuning Guide - 10g Release 2 (10.2), Chapter 12.2.4 Using SQL Tuning Advisor APIs,
http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14211/sql_tune.htm#i34827 , accesat la data 25.01.2010
28
Automatic SQL Tuning - SQL Profiles [ID 271196.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=271196.1&type=NOT , accesat la data 25.01.2010
44
O alternativă ar fi înregistrarea unui Service Request cu Oracle Support pentru asistenţă în rezolvarea
acestei probleme.
Un clinet bottleneck în contextul unei baze de date lente reprezinta faptul ca sesiunile consumă cel mai
mult timp înafara bazei de date, cauzate, în principiu de latenţa clientului sau a reţelei.
Timpii de aşteptare mari datoraţi eventurilor de tip client inaintea oricarui apel de comandă sau
procedură.
Oracle shadow petrece mult timp aşteptând mesajele de la clienţi. Timpii de aşteptare apar între apelurile
de FETCH şi cele de PARSE sau înaintea celor de EXECUTE. Există puţine apeluri FETCH pentru
acelaşi cursor.
După ce să ne uităm:
TKProf:
• Overall wait event summary pentru comenzile recursive şi non-recursive arată timpii semnificativi
pentru mesajele SQL*Net de la timpii de aşteptare a clientului comparativ cu „total elapsed time” al
bazei de date.
• Fiecare apel FETCH returnează tipic 5 sau mai multe înregistrări (ceea ce indică existenţa array-
fetch-urilor).
45
Model de tuning
Cauza identificată: Latenţa reţelei ce limitează răspunsurile dintre client şi baza de date. Reţeaua este
saturată şi acest fapt limitează abilitatea clientului şi a bazei de date de a comunica între ei.
Justificarea cauzei:
TKProf:
1. Mesajele SQL*Net pentru timpii de aşteptare client reprezintă o parte mare din timpul total (secţiunea
overall summary)
2. Sunt utilizate operaţii cu array-uri. Acest fapt se observă când există mai mult de 5 înregistrări în medie
per execuţie.
3. Timpul mediu de răspuns la un apel ping este de doua ori cât tipul mediu pentru un mesaj SQL*Net de
la client wait, şi acest timp este mai mare decât câteva milisecunde. Acest lucru indică faptul că cei mai
mulţi timpi sunt petrecuţi înafara reţelei.
De asesemenea, se poate observa o performanţa buna a aceloraşi interogări cerute de un alt client sau
subnet (de obicei,aflate mai aproape de serverul de baze de date).
Soluţia identificată: Investigarea reţelei. Se vor verifica timpii de răspuns ai reţelei la subnet-uri şi
interface card-uri diferite. Netstat ping şi unelte de tracerout pot fi deasemenea utilizate pentru a verifica
performanţele reţelei.
Effor - mediu. Problemele de reţea sunt adesea uşor de verificat, dar dificil de soluţionat.
Risc - scăzut
Implementarea soluţiei
Consultarea documentaţiei sistemului pentru folosirea utilitarelor gen ping, netstat şi tracerout.
Verificarea implementării
Se va implementa soluţia şi se va verifica dacă performanţele bazei de date se îmbunătăţesc. În caz contrar
trebuie să examinăm următoarele:
- să luăm în considerare alte posibile cauze
- să verificăm dacă datele au fost colectate corect
- să verificăm problema iniţială.
O alternativă ar fi înregistrarea unui Service Request cu Oracle Support pentru asistenţă în rezolvarea
acestei probleme.
46
4. Reducerea consumului de memorie de către Oracle
Oracle foloseşte memorie pentru SGA şi PGA. Trebuie examinată dimensiunea SGA şi PGA pentru a
determina ce utilizează memoria sistemului.
După ce să ne uităm:
RDA:
porţinune mare din memoria maşinii este utilizată de una sau mai multe SGA (se vor verifica mărimea
totală a buffer cache-ului şi a shared-pool):
Overview->System information->Total Physical Memory
RDBMS->SGA Information, se vor aduna toate componentele.
Se va repeta pentru toate instantele de pe maşină
Se va compara mărimea totală a SGA cu memoria fizică.
Cauza identificată: Buffer cache supradimensionat. Buffer cache este foarte mare şi utilizează mai multă
memorie decât este necesar.
Justificarea cauzei:
Rapoarte AWR sau statspack:
- nu se foloseşte automatic shared memory management (ASMM), ex. SGA_TARGET=0
- buffer cache hit ratio este în jur de 99%
Soluţia identificată: pentru 10g+ se va folosi automatic shared memory management (ASMM)
ASMM va cauta să optimizeze mărimea buffer cache-ului fără intervenţia utilizatorului.
Effort: scăzut. Schimbarea parametrului de iniţializare.
Risc: scăzut. Se va seta pentru SGA_TARGET o valoare rezonabila.
Implementarea soluţiei:
Documentatie
Concepts: Memory Architecture29
Concepts: Automatic Shared Memory Management30
29
Oracle® Database Performance Tuning Guide - 10g Release 2 (10.2), Chapter 8 – Memory Architecture, http://download-
west.oracle.com/docs/cd/B19306_01/server.102/b14220/memory.htm , accesat la data 25.01.2010
47
Admin: Using Automatic Shared Memory Management31
Performance Tuning: Configuring and Using the Shared Pool and Large Pool32
Articole
Understanding and Tuning the Shared Pool33
Oracle Database 10g Automated SGA Memory Tuning34
How To
How To Use Automatic Shared Memory Management (ASMM) În Oracle10g35
Shared pool sizing în 10g36
Verificarea implementării
Se va implementa soluţia şi se va verifica dacă performanţele bazei de date se îmbunătăţesc. În caz contrar
trebuie sa examinăm următoarele:
- sa luăm în considerare alte posibile cauze
- sa verificăm dacă datele au fost colectate corect
- să verificăm problema iniţială.
O alternativă ar fi înregistrarea unui Service Request cu Oracle Support pentru asistenţă în rezolvarea
acestei probleme.
30
Oracle® Database Performance Tuning Guide - 10g Release 2 (10.2), Chapter 8 – Memory Architecture, Automatic Shared
Memory Management,
http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14220/memory.htm#CNCPT810 , accesat la data 25.01.2010
31
Oracle® Database Performance Tuning Guide - 10g Release 2 (10.2), Chapter 8 – Memory Architecture, Using Automatic
Shared Memory Management,
http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14231/create.htm#BABGCBHI , accesat la data 25.01.2010
32
Oracle® Database Performance Tuning Guide - 10g Release 2 (10.2), Chapter 7 – Memory Confiiguration and Use, 7.3 –
Configuring and Using the Shared Pool and Large Pool,
http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14211/memory.htm#i30970 , accesat la data 25.01.2010
33
Understanding and Tuning the Shared Pool [ID 62143.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=62143.1&type=NOT , accesat la data 25.01.2010
34
Oracle Database 10g Automated SGA Memory Tuning [ID 257643.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=257643.1&type=NOT, accesat la data 25.01.2010
35
How To Use Automatic Shared Memory Management (ASMM) În Oracle10g [ID 295626.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=295626.1&type=NOT , accesat la data 25.01.2010
36
Shared pool sizing in 10g [ID 270935.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=270935.1&type=NOT , accesat la data 25.01.2010
48
Capitolul 3 - Baza de date este blocata (locking) sau se agaţă
(hang)
A. Generalităţi
Pentru o identificare corectă a problemei ce se doreşte a fi rezolvată, sunt necesare trei lucuri:
recunoaşterea unei interogări agăţate
clarificarea detaliilor problemei
verificarea ca problema raportată este cea reală
49
b. Clarificarea problemei
O specificare clară a problemei este foarte importantă. Trebuie declarat exact care este problema. Se
poate întâmpla ca în faze ulterioare, sau în timp ce se lucrează la problemă, adevărata problemă să iasă
la iveală, şi să fie necesară o redefinire a acesteia.
Pentru a clarifica problema, este necesar să se ştie cât mai multe dintre următoarele:
• Utilizatorii afectaţi
• Secvenţa de evenimente care a condus la problema respectivă
• Unde/cum a fost observată
• Importanţa problemei
• Ce funcţionează
• Care este rezultatul acceptat sau aşteptat
• Ce s-a făcut pentru a se încerca rezolvarea problemei
Exemple practice:
• Multe sesiuni par să nu finalizeze cererile adresate
• A fost observată de către utilizatorii finali
• Nu se pot face noi conectări la baza de date
• Nimic nu pare să mai funcţioneze
• În mod normal solicitarile utilizatorilor se finalizează în mai putin de 2 secunde.37
• S-a verificat alert log-ul pentru erori ORA-60.
c. Verificarea problemei
Obiectivul acestui pas din procesul de diagnosticare este să ne asigurăm ca baza de date are
simptomele unei probleme de blocare sau agăţare. În acest moment trebuie sa colectăm date ce verifica
existenta problemei.
Pentru aceasta verificare trebuie sa colectăm dovezi ale agăţării sau blocării.
37
How to Identify Resource Intensive SQL for Tuning [ID 232443.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=232443.1&type=NOT
50
Exemple:
Dacă interogarea nu returnează rezultate, există sansele unei probleme de agăţare reale.
Datele despre sistemul de operare sunt necesare pentru a vedea performanţele maşinii pe care rulează
Oracle.
Începând cu versiunea 10g, rapoartele statspack conţin şi date despre sistemul de operare.
Ca aletrnativă se poate folosi una dintre următoarele:
• OS Watcher (de preferat) – este o colecţie de scripturi shell UNIX ce colectează şi arhivează
metrice ale sistemului de operare şi ale reţelei pentru a susţine soluţionarea problemelor de
performanţă. OSW funcţionează ca un set de procese background pe server şi colectează date
despre SO la intervale constante, apelând utilitare UNIX ca vmstat, netstat sau iostat.38
• LTOM – Lite Onboard Monitor, este un program java, dezvoltat ca o platformă de diagnosticare
în timp real. Diferenţierea acestui utilitar de altele de acest gen, consta în faptul ca funtionarea sa
este mai mult pro-activă decât reactivă. LTOM asigură detectarea problemelor în timp real şi
colectarea de date, fiind foarte util în cazul problemelor neprevăzute.39
• Enterprise Manager – pagina de performance management include grafice ce arată date despre
performanţele procesorului şi a memoriei, cât şi informaţii detaliate despre procese. Este tot un
uitlitar în timp real, din această cauză vor fi necesare capturi de ecran pentru analizele
ulterioare.40
38
OS Watcher User Guide [ID 301137.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=301137.1&type=NOT, accesat la data 25.01.2010
39
LTOM - The On-Board Monitor User Guide [ID 352363.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=352363.1&type=NOT , accesat la data 25.01.2010
40
Oracle® Enterprise Manager Concepts 10g Release 5 (10.2.0.5),
http://download-west.oracle.com/docs/cd/B19306_01/em.102/b31949/host_3rdparty_management.htm#sthref1530 , accesat la data
25.01.2010
51
Hanganalyze şi SystemState
1. Despre Hanganalyze
Hanganalyze utilizează apelări interne ale kernelului pentru a determina dacă sesiune aşteaptă o resursă
şi raportează relaţiile dintre procesele ce blochează şi cele care aşteaptă. Adiţional, determină la ce
procese se poate renunţa şi poate realiza transcrieri ale memoriei (dumps) de tip PROCESSSTATE sau
ERRORSTACK pe acele procese, în funcţie de nivelul ales la execuţia HANGANALYZE-ului.41
Comanada HANGANALYZE este disponibilă încă din versiunea ORACLE 8.1.6. Începând cu versiunea 9i
ofera facilităţi pentru medii RAC într-o singură “fotografiere”.
Sintaxa HANGANALYZE:
ALTER SESSION SET EVENTS 'immediate trace name HANGANALYZE level <nivel>';
ORADEBUG hanganalyze <nivel>
ORADEBUG -g def hanganalyze <nivel> (pentru clustere)
Nivelele sunt:
10 - toate procesele (starea IGN)
5 – Nivelul 4 + conţinutul de memorie pentru toate procesele implicate în lanţuri de aşteptări (starea
NLEAF)
4 – Nivelul 3 + conţinutul de memorie pentru toate nodurile frunză (procesele care blochează) din
lanţurile de aşteptări (starile LEAF, LEAF_NW şi IGN_DMP)
3 – Nivelul 2 + conţinutul de memorie pentru toate procesele ce par a fi agăţate (starea IN_HANG)
1-2 – Doar rezultatul HANGANALYZE, nici un continut de memorie pentru nici un proces.
Se recomandă a nu se utiliza nivel mai mare de 3 datorită numarului potenţial mare de fişiere de trace
care se pot produce (şi ar putea copleşi sistemul de intrări/ieşiri). Deoarece HANGANALYZE se va utiliza
în principal pentru a diagnostica “adevaratele” agaţări, nivelul 3 va scrie conţinutul memoriei doar pentru
procesele care sunt implicate în condiţia de agăţare – de obicei mai putin de 4 procese.
41
Interpreting HANGANALYZE trace files to diagnose hanging and performance problems [ID 215858.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=215858.1&type=NOT , accesat la data 25.01.2010
52
2. Despre SystemState
Starea unui sistem este un set de stări ale proceselor instentei pentru care se scrie conţinutul memoriei
(dump). Un conţinut de memorie al stării unui sistem este util pentru determinarea interacţiunilor dintre
procese. Acest dump va raporta ce resurse sunt reţinute de către fiecare proces în parte.
Sintaxa SYSTEMSTATE
ALTER SESSION SET EVENTS 'immediate trace name SYSTEMSTATE level <nivel>';
ORADEBUG dump systemstate <nivel>
ORADEBUG -g all dump systemstate <nivel>
Nivele sunt:
1 - doar informaţii de bază despre procesele implicate
2 - obiectele de stare ale procesului şi ale sesiunii
10 - cel mai uzual nivel - include structurile arborescente ale obiectelor de stare pentru toate procesele.
256 - adăugând 256 la nivelul ales, se va încerca să se adauge în dump şi stiva de informaţii pentru
fiecare proces.
LTOM – Lite Onboard Monitor, este un program java, dezvoltat ca o platformă de diagnosticare în timp
real. Diferenţierea acestui utilitar de altele de acest gen, constă în faptul că funtionarea să este mai mult
pro-activă decât reactivă. LTOM asigură detectarea problemelor în timp real şi colectarea de date, fiind
foarte util în cazul problemelor neprevăzute .42
Una dintre trăsăturile utilitarului LTOM este detectarea automată a agaţărilor (Automatic Hang
Detection). Totuşi, în sistemele din producţie, nu este recomandată activarea acestei trăsături ca practică
uzuală. Se va utiliza doar dacă se suspectează situaţii de hang în bază de date. Volumul înregistrărilor
colectate pentru problemele de hang ar putea afecta negativ sistemul şi ar trebui monitorizate.
42
LTOM - The On-Board Monitor User Guide [ID 352363.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=352363.1&type=NOT , accesat la data 25.01.2010
53
Colectarea standard cuprinde:
HangAnalyze Level 3
Systemstate Level 266
Wait 60 seconds
HangAnalyze Level 3
Systemstate Level 266
HANGFG (Hang File Generator) - este o serie de scripturi shell utilizate pentru automatizarea procesului
de generare şi colectare a fişierelor cu înregistrări hanganalyze şi systemstate. HANGFG generează şi
colectează fişiere cu înregistrări ale agăţărilor pe baza impactului obţinerii de înregistrări pentru
diagnosticare într-un sistem cu o stare deja degradată. La ce nivel se va realiza colectarea este lăsat la
alegerea utilizatorului. Nivelul poate fi furnizat utilitarului ca argument. Utilitarul poate şi să ia el această
decizie , dacă utilizatorul alege impact uşor (light impact) - opţiunea 1 ca argument.
Pentru mediile non-clusterizate se va verifica dacă fişierele de trace sunt scrise în user_dump_destination
Modul ideal de colectare a vizualizărilor hanganalyze şi systemstate este de a colecta 2 seturi. Totuşi, cel
mai bine ar fi să se deţină 2 vizualizări (dump) hanganalyze într-un singur fişier şi 2 vizualizări (dump)
systemstate în 2 fişiere de înregistrare separate. Pentru aceasta vom avea nevoie de 3 sesiuni sqlplus
separate (SQL1, SQL2 şi SQL3).
43
HANGFG User Guide [ID 362094.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=362094.1&type=NOT , accesat la data 25.01.2010
44
Steps to generate HANGANALYZE trace files [ID 175006.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=175006.1&type=NOT , accesat la data 25.01.2010
54
Se va executa de 3 ori, în 3 ferestre diferite, creâind 3 sesiuni de sqlplus (SQL1, SQL2, şi SQL3)
E. Se va aştepta min 2 minute pentru a acorda timp pentru identificarea modificărilor stării procesului
SPOOL v_views.log;
55
order by 1;
SELECT *
FROM v$session_wait
ORDER BY sid;
/* se va repeta ultima interogarede 3 ori pentru a vedea ce procese aşteaptă în mod repetat */
SPOOL OFF;
56
O baza de date poate parea ca este “agatata” (hung), dar în realitate poate doar functiona lent. În acest
caz, se vor aplica modelele de tuning corespunzatoare. În alte cazuri, baza de date pare agatata, când în
realitate doar câteva sesiuni sunt în aceasta situatie.
Agatare “reală”
O agăţare “reală” într-o baza de date Oracle poate fi definita ca blocare definitiva, o imbratisare “mortala”
denumita în documentatiile de specialitate “deadlock”. Aceasta este o dependenta ciclica intre doua sau
mai multe procese. Cand avem deaface cu blocari DML (de ex. TM), Oracle este capabil sa detecteze
aceasta dependenta şi sa aduca la starea iniţială (rollback) unul dintre procese, pentru a intrerupe
condiţia ciclica. Pe de alta parte, când aceasta situatie apare la nivelul resurselor kernelului (latche-uri
sau pin-uri), Oracle nu le poate detecta şi rezolva automat.
Dacă hangAnalyze a fost colectat asa cum s-a precizat anterior, ar trebui sa existe 2 rezultate intr-un
singur fisier de trace.
În fisierul de trace hanganalyze, secţiunea “CYCLE” raportează dependentele proceselor intre sesiunile
ce sunt într-o conditie de deadlock. Aceste dependente ciclice sunt considerate adevaratele “agaţări” ale
bazei de date.
Exemplu:
Dacă rezultatul colectat prezinta o sectiune “CYCLE”, baza de date este “agatata”.
Se va retine SID-ul şi OSPID-ul procesului ce blochează şi a celui care aşteaptă pentru a putea
determina cauza acestei probleme.
Dacă rezultatul nu contine o sectiune “CYCLE”, se va investiga posibilitatea existentei unor sesiuni
blocate.
2. Date aditionale
Date aditionale sunt colectate în mod automat de comanda hanganalyze dacă o agăţare “reală” a fost
detectata. Vor fi colectate continuturile de memorie pentru systemstate şi processtate pentru sesiunea ce
blochează şi processtate pentru cea care aşteaptă.
57
Exemplu:
Se va retine SID-ul şi OSPID-ul procesului ce blochează şi a celui care aşteaptă pentru a putea
determina cauza acestei probleme.
Oracle foloseşte cozile de aşteptare ca mecanism de blocare pentru administrarea accesului la resursele
partajate. O resursa partajata poate fi definitia unei tabele, o tranzactie sau orice tip de structura ce
reprezinta ceva partajat intre sesiuni. Fiecare tip de actiune intreprinsa de către sesiunile Oracle va
necesita un tip diferit de blocare (ex. “select from <tabel>” va necesita ca sesiunea ce o executa sa aiba o
blocare partajata pe definitia tabelei selectate). Cand apar actiuni conflictuale, Oracle va serializa
procesarea prin punerea unor sesiuni în mod aşteptare pana când actiunile ce blochează resursa din
sesiunea curenta ca fi terminata.
Dacă hangAnalyze a fost colectat asa cum s-a precizat anterior, ar trebui sa existe 2 rezultate intr-un
singur fisier de trace.
În fisierul de trace hanganalyze, secţiunea “OPEN CHAIN” raportează sesiunile implicate în lantul de
aşteptare. Un lant de aşteptare inseamna ca o sesiune bloceaza una sau mai multe alte sesiuni. “Open
chain” reprezinta siseiunile intepenite sau blocate.
Exemplu:
Hanganalyze #1
Open chains found:
Chain 1 : <sid/sess_srno/proc_ptr/ospid/wait_event> :
<16/44773/0x265f15c/1948/SQL*Net message from client> <--sid 16, ospid 1948:blochează
-- <12/5/0x265fad4/2112/enqueue> <--sid 12, ospid 2112: aşteaptă
-- <13/14/0x265fdfc/2076/enqueue> <--sid 13, ospid 2076:aşteaptă
Chain 2 : <sid/sess_srno/proc_ptr/ospid/wait_event> : <19/3/0x2660124/2392/No Wait>
Hanganalyze #2
Open chains found:
Chain 1 : <sid/sess_srno/proc_ptr/ospid/wait_event> :
45
Anexa 1
58
<16/44773/0x265f15c/1948/SQL*Net message from client> <--sid 16, ospid 1948: blochează
-- <12/5/0x265fad4/2112/enqueue> <--sid 12, ospid 2112: aşteaptă
-- <13/14/0x265fdfc/2076/enqueue> <--sid 13, ospid 2076: aşteaptă
Chain 2 : <sid/sess_srno/proc_ptr/ospid/wait_event> : <19/3/0x2660124/2392/No Wait>
Hanganalyze #3
Open chains found:
Chain 1 : <sid/sess_srno/proc_ptr/ospid/wait_event> :
<16/44773/0x265f15c/1948/SQL*Net message from client> <--sid 16, ospid 1948: aşteaptă
-- <12/5/0x265fad4/2112/enqueue> <--sid 12, ospid 2112: aşteaptă
-- <13/14/0x265fdfc/2076/enqueue> <--sid 13, ospid 2076: aşteaptă
-- <19/3/0x2660124/2392/enqueue> <--sid 19, ospid 2392: aşteaptă
La orice moment, există mari sanse sa existe procese (denumite generic procese) ce blochează sau
aşteaptă, dacă se executa ceva în baza de date. Cheia este sa se determine dacă aceste procese sunut
intepenite pentru o perioada de timp inacceptabila.
Se vor compara lanţurile de aşteptare din sectiunile “OPEN CHAIN” din rapoartele generate anterior.
dacă există un numar mare de lanţuri în secţiunea “OPNE CHAIN”, ar trebui sa ne conectram, pentru
inceput, pe primele 3 sau 4 lanţuri.
O baza de date este într-o stare de blocare care ambele conditii sunt adevarate:
A. Unul sau mai multe lanţuri din secţiunea “OPEN CHAIN” au mai mult decât o sesiune. Sunt
necesari cel putin un agent de blocare şi unul de aşteptare.
Exemplu: “Chain 1” din toate cele 3 exemple de hanganalyze intrunsesc acest criteriu.
B. Sesiunea ce blochează ramane acceasi în toate rapoartele hanganalyze în unul sau mai multe
lanţuri ce indeplinesc condiţia A. Un nou proces de aşteptare poate sa se adauge celor deja
existente, observabil în rapoarte hanganalyze ulterioare, în continuare lantul va fi luat în
considerat ca avand o problema de aşteptare.
Exemplu: “Chain 1” din cele 3 exemple de hanganalyze intrunsesc acest criteriu. Sesiunea ce blochează
din “Chain 1” din Hanganalyze #1 şi Hanganalyze #2 nu se schimba. În “Chain 1”, sid 16 este agentul de
blocare şi sid 12, 13 şi 19 aşteaptă. Lantul este acelaşi în toate rapoartele hanganalyze, cu exceptia lui
sid 19. Sid 19 a fost adaugat în lant în Hanganalyze #3.
În continuare, se va retine SID-ul şi OSPID-ul procesului ce blochează şi a celui care aşteaptă pentru a
putea determina cauza acestei probleme.
2. Date aditionale
59
Se vor colecta continuturile de memorie cu stiva de erori pentru sesiunile din secţiunea “OPEN CHAIN”.
Se va utiliza ospis pentru colectarea continutului de memorie al stivei de erori (ErrorStack) după cum
urmeaza:
Inaintea colectarii stivei de erori, trebuie sa determina asupa carui lant ne vom concentra. Primele 3-4
cele mai lungi lanţuri din sectiune “OPEN_CHAIN” sunt cei mai buni candidati.
Se va genera stiva de erori pentru sesiunea ce blochează şi prima care aşteaptă pentru fiecare lant. În
exemplul prezentat, ospid 1948 blochează şi ospid 2112 este primul care aşteaptă. Stivele vor fi deci
generate pentru 1948 şi 2112.
Dacă un proces blochează multe alte sesiuni (mai mult de 10), în fisierul de trace hanganalyzer apare o
sectiune “FOUND” inaintea sectiunii “OPEN_CHAIN”. dacă aceasta sectiune apare în raport, se va
compara fiecare sesiune din rapoartele hanganalyze. dacă un proces ce blochează ramane în secţiunea
“FOUND” în toate rapoartele, se va genera stiva de erori corespunzatoare lui folosind ospid.
60
• O data pentru prima sesiune ce aşteaptă pentru fiecare lant din secţiunea “OPEN CHAIN” pe
care am decis sa il urmarim
• O data pentru fiecare proces ce blockeaza din secţiunea “FOUND” care ramane constant în
toate rapoartele
Mai multe fişiere de trace vor fi generate în user_dump_destination. Va există cate un fisier de trace
pentru fiecare sesiune pentru care s-a generat o stiva de erori.
O problema grava de performanta poate fi interpetata gresit ca fiind o agăţare. Acest fapt se întâmpla, de
obicei, când disputa pentru resurse este atat de “inversunata”, în cât baza de date este complet blocata.
Exemplu:
Hanganalyze #1
Open chains found:
Chain 1 : <sid/sess_srno/proc_ptr/ospid/wait_event> :
<13/23/0x2660124/1776/No Wait>
Chain 2 : <sid/sess_srno/proc_ptr/ospid/wait_event> :
<16/8/0x265f7ac/1888/SQL*Net message from client>
-- <15/20/0x265fad4/296/enqueue>
-- <12/5/0x265fdfc/1804/enqueue>
Hanganalyze #2
Open chains found:
Chain 1 : <sid/sess_srno/proc_ptr/ospid/wait_event> :
<18/3839/0x265ee34/2004/SQL*Net message from client>
-- <19/23/0x265f15c/1876/enqueue>
Chain 2 : <sid/sess_srno/proc_ptr/ospid/wait_event> :
<12/5/0x265fdfc/1804/No Wait>
O baza de date este lenta dacă nu există lanţuri de blocari în secţiunea “OPEN CHAIN”. Un lant nu este
blocat dacă sesiunea ce blockeaza se schimba de la un raport hanganalyze la altul.
61
Faza 2 - Determinarea cauzei
În acest moment ar trebui sa avem verificata o problema de blocare sau agăţare a bazei de date.
Procesul de determinare a cauzei are doua etape:
Colectarea de date – de obicei se folosesc datele colectate în etapa de verificare a problemei.
• Analiza
În acest moment ar trebui sa avem:
Un nou fisier de trace ce a fost scris în user_dump_destination continand 2 viziuni hanganalyze şi una
pentru processtate.
Unul sau mai multe fişiere de trace ce sa contina stiva de erori
v_views.log
62
Sesiuni intepenite sau blocate
Utilizarea OEM
Depanarea sesiunilor intepenite se poate face utilizand câteva dintre caracteristicile OEM. Sesiunile
intepenite trebuie sa fie încă în aceasta stare pana când depanarea s’a finalizat sau imagini ale acestora
sa fie salvate pentru referinte ulterioare.
Pagina Blocking Sessions arata lista tuturor sesiunilor ce în mod curent blochează alte sesiuni.
Acest script afiseaza, într-o structura arborescenta, sesiunile din sistem care aşteaptă după blocari, şi
după ce blocare anume aşteaptă fiecare. Locatia acestui script difera în funcţie de sistemul de operare
utilizat.
Exemplu:
WAITING_SESSION LOCK_TYPE MODE_REQUESTED MODE_HELD LOCK_ID1 LOCK_ID2
---------------- ---------- -------------- ---------- --------- --------
blochează-> 100 None
aşteaptă ---> 118 DML Exclusive Exclusive 51148 0
aşteaptă ---> 125 DML Row-X (SX) Exclusive 51148 0
O data identificate procesele, se vor rula interogarile asupra viziunilor V$ prezentate anterior.
46
Resolving locking issues using utllockt.sql script [ID 166534.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=166534.1&type=NOT , accesat la data 25.01.2010
47
Anexa 2
63
Analiza
Datele coectate anterior vor fi analyzate în aceasta etapa pentru determinarea cauzei problemei de
agăţare sau blocare.
Pana în acest punct ar trebui sa se cunoasca dacă se depaneaza o agăţare “reală” a bazei de date sau o
sesiune intepenita sau blocata.
Datele ce trebuie identificate pentru a ne ajuta sa analizam aceste tipuri de probleme de performanta
sunt:
• OSPID – Identificatorul procesului în cadrul sistemului de operare este necesar pentru a elimina
(kill session) sesiunile de indata ce depanarea este finalizata.
• Evenimentele de aşteptare – este resursa sau evenimentul pe care il aşteaptă sesiunea. Acesta
va fi utilizat pentru a restrange problema de agăţare sau blocare la un subtip specific.
Nu sunt necesare toate aceste date pentry fiecare tip de problema. Inainte de a utiliza oricare din
metodele prezentate mai jos, trebuie sa identificam sesiunile care blochează şi cele care aşteaptă.
Acestea ar trebui deja stiute din etapa Verificarea problemei.
Aceste date vor fi utile în determinarea subtipului de problemele de blocaj şi agăţare. Informatiile
suplimentare necesitate vor depinde de tipul evenimentului de aşteptare.
Se pot utiliza pasii urmatori dacă a fost colectat un ErrorStack pentru sesiunea care blochează şi cel putin
unul pentru una care aşteaptă, sesiuni identificate la Date aditionale.
Un dump Errorstack contine o stiva de apeluri şi dump al starii proceselor. În acest pas vom analiza
informatiile despre starea proceselor. Aceste informaţii sunt impartite în sesctiuni numite obiecte de stare
64
(state objects) ce sunt identificate prin “SO”. Tipul obiectului de stare se afla la inceputul celei de’a 2 linii
din starea obiectului, sub “SO”.
1. OSPID
OSPID poate fi gasit în obiectul stare al “procesului”. Acest identificator va fi necesar la terminarea
sesiunilor la finalizarea depanarii.
Exemplu:
2. Evenimentul de aşteptare
Evenimentul de aşteptare poate fi gasit în obiectul de stare “sesiunie”. Alte informaţii utile ce se afla în
aceasta sectiune sunt SID-ul şi adresa SQL.
În exemplul de mai jos, cu albastru s-au evidentiat datele de identificat:
sid: 118 arata ca Sid-ul sesiunii este 118. Acesta este specificat pentru a
fi asigurati ca urmarim sesiunea care trebuie.
sql: 0x3076f3f8 arata ca adresa pt SQL a acestei sesiuni este 3076f3f8. aceasta
va fi folosita pentru a identifica Interogarile active în pasul urmator.
waiting for 'enq: TM - contention' arata ca evenimentul de aşteptare pentru aceasta sesiune este
enq: TM – contention. Aceasta informaţie se va folosi când vom determina ce tip de blocare este asociata
cu situatia curenta ce este depanata.
65
name|mode=544d0006 arata valoarea pentru P1 dacă evenimentul de aşteptare este o
coada de aşteptare. P1 este o valoare hexa-zecimala ce reprezinta tipul şi modul de blocare (Imode).48
Exemplu:
3. Interogarile active
Interogarile active se gasesc în obiectul de stare “Library Object Lock”. Interogarile active sunt utile
pentru a iidentifica obiectul implicat în agăţare sau blocare.
LIBRARY OBJECT LOCK arata ca obiectul de stare este Library Object Lock
66
name=lock table emp in
exclusive mode arata ca interogarea activă este o blocare pe tabela emp in mod
exclusiv.
Exemplu:
Exemplu: Vezi Anexa 3 – script ce arata blocarile DML, inclusiv numele tabelei.
Exemplu:
67
Identificarea datelor despre agentii de blocare şi cei care aşteaptă utilizand
interogarea viziunilor V$
1. Evenimentul de aşteptare
Evenimentul de aşteptare poate fi identificat din raportul v$lock.log. Vom cauta datele generate de
v$session_wait_querry.
Exemplu:
2. Interogarile active
68
Identificarea datelor despre agentii de blocare şi cei care aşteaptă utilizand
OEM (10gR2)
Indiferent de facilităţile utilizate în OEM pentru a viziona sesiunile blocate, informaţiile cele mai valoroase
pentru depanarea sesiunii inţepenite se vor găsi pe pagina “Session Detail” pentru sesiunea factorului de
blocare şi pentru sesiunea factorului de aşteptare.
1. OSPID
2. Evenimentul de aşteptare
Poate fi găsit în secţiunea “Application” din pagina “Session Detail”. Current SQL reprezintă interogarea
activă. Din pagina “Session Detail”, selectarea “SQL Hash Value” ne va direcţiona către pagina “SQL
Details”.
69
Sectiunea “Text” din pagina “SQL Details” contine interogarea activă:
În cele ce urmeaza voi prezenta cele mai des intalnite cauze asociate cu agatarea bazei de date.
Library cache pin sunt utilizate pentru a administra concurenta library cache-ului.
Fixarea unui obiect cauzează încărcarea heap-urilor în memorie (dacă nu sunt încărcate deja). Fixările
pot fi în mod NULL, SHARE sau EXCLUSIVE şi pot fi considerate o formă specială de blocare/rezervare.
O aşteptare pentru un “library cache pin” implica faptul că alte sesiuni reţin acel PIN într-un mod
incompatibil.
Model de tuning:
Cauza identificată: O sesiune este blocată din cazuza ununi deadlock ce aşteaptă un library cache pin
Justificarea cauzei:
1. Interogam v$session_wait sa aflam sesiunile ce aşteaptă library cach pin:
SID SUBSTR(EVENT,1,25) P1 P2 P3
---------- ------------------------- ---------- ---------- --------------
9 library cache pin 15417016 10090832 20
70
154 library cache pin 15417016 11224168 20
341 library cache pin 15417016 11449936 20
349 library cache pin 15417016 16489792 20
390 library cache pin 15417016 11992536 20
160 library cache pin 15417016 6166600 20
20 library cache pin 15417016 10868760 20
2. Convertim P1(15417016) to HEX --> EB3EB8 şi o cautam în X$KGLPN (Library Cache Object Pin)
71
05B0CD98 8 004001E8 00103A90 00103A90 00EB3EB8 004CA428 3 0
Vom cauta în V$SESSION.SADDR după KGLPNUSE pentru a determina SID-ul sesiunii: 263.
În urma verificarii sesiunea corespunde unui mesaj Client.
Efort - mediu..
Risc - scăzut
Implementarea soluţiei
Verificarea implementării
Se va implementa soluţia şi se va verifica dacă performanţele bazei de date se îmbunătăţesc. În caz contrar
trebuie sa examinăm următoarele:
- sa luăm în considerare alte posibile cauze
- sa verificăm dacă datele au fost colectate corect
- să verificăm problema iniţială.
O alternativă ar fi înregistrarea unui Service Request cu Oracle Support pentru asistenţă în rezolvarea
acestei probleme.
72
2. Blocare library cache-ului
Rezervarea library cache-ului controleaza concurenta clientilor library cache-ului prin asigurarea
rezervarii obiectului pentru ca un client sa impiedice pe altii sa acceseze acelaşi obiect, sau clientul poate
mentine o dependenta pentru un timp indelungat (nici un alt client nu poate modifica obiectul).
Acest eveniment este utilizat pentru asteptarea unei blocari pe data dictionary cache, specificat prin
“cache id.
1. Cozile de aşteptare
Cozile de aşteptare sunt rezervari locale, ce serializeaza accesul la resurse variate. Acest eveniment de
aşteptare indica asteptarea pentru o rezervare ce este retinuta de alta sesiune (sau sesiuni) intr-un mod
incompatibil fără ce modul cerut.
Acest eveniment este utilizat când un obiect din baza de date este incarcat. Rezervarea incarcarii este
obtinuta intotdeauna în mod Exclusiv, în asa fel incat nici un alt proces sa nu poata incarca obiectul în
acelaşi timp. dacă rezervarea incarcarii obiectului este ocupata, sesiunea va astepta acest eveniment,
pana când rezervarea devine disponibilă.
73
Capitolul 4 - Optimizarea interogarilor
A. Generalităţi
Pentru o identificare corectă a problemei ce se doreşte a fi rezolvată, sunt necesare trei lucuri:
Să recunoaştem o problemă de optimizare a interogărilor
Să clarificăm detaliile acestei probleme
Să verificăm dacă problema raportată este cea reală.
74
b. Clarificarea problemei
O specificare clară a problemei este foarte importantă. Trebuie declarat exact care este problema. Se
poate întâmpla ca în faze ulterioare, sau în timp ce se lucrează la problema, adevărata problemă să iasă
la iveală, şi să fie necesar o redefinire a acesteia.
Pentru a clarifica problema, este necesar să se ştie cât mai multe dintre următoarele:
• Interogările afectate
• Secvenţa de evenimente ce au condus la apariţia problemei
• Unde/cum a fost observată
• Importanţa problemei
• Ce funcţionează
• Care este rezultatil acceptat sau aşteptat
• Ce s-a făcut pentru a se încerca rezolvarea problemei
Exemplu:
• frază SQL are performante slabe după re-colectarea de statistici
• A fost observată de utlizatorii finali.
• Face ca aplicaţia să ruleze lent şi împiedica sistemul nostru să preia comenzi
• În rest totul este în regulă şi problema nu s-a manifestat în mediul nostru de testare.
• În mod normal propoziţia se execută în mai puţin de 2 secunde.
• Am încercat să re-colectăm statistici, dar fără niciun efect
c. Verificarea problemei
În acest pas al diagnosticării problemei, obiectivul este de a ne asigura că interogarea despre care se
crede că are nevoie de optimizare este cu adevărat cauza problemei. În acest punct trebuie să
colectatam datele care verifica existenţa problemei.
75
Informaţia despre timpii interogării a fost colectata folosind SQLPlus astfel:
SQL> set timing on
SQL> SELECT order_id
FROM po_orders
WHERE branch_id = 6
ORDER_ID
----------------
232
Elapsed: 00:00:13.26
Consideraţii speciale
Dace se foloseşte Oracle 10g sau versiuni ulterioare, şi se poseda licenţa pentru tuning Pack al
Enterprise Manager-ului, cea mai bună abordare ar fi ca depanarea acestui tip de probleme să fie lăsat în
seama SQL Tuning Advisor-ului.49
Optimizarea interogărilor în bazele de date şi în aplicaţii este un proces interactiv ce necesită o înţelegere
completă a mediului unde rezida baza de date (baza de date, sistemul de operare, aplicaţia, firewall,
etc.).
În aceasta etapa vom aduna date ce ne vor ajuta sa verificăm dacă interogarea suspectata este intr-
adevar cea care va trebui optimizata. Ar trebui sa fim pregatiti sa identificam pasii specifici din aplicaţie ce
au cauzat execuţia lenta a interogarii. Vom urmari sesiunea bazei de date, în timp ce aplicatia executa
interogarea.
Fisierul de trace Extended SQL (10046 trace la nivelul 12) va surprinde statisticile executiei tuturor
interogarilor sesiunii rulate în timpul inregistrarii. Ne va arata cât timp este alocat fiecarei interogări, cât
timp este datorat prcesorului sau evenimentelor de aşteptare, şi legaturile dintre acestia. Va trebui sa
verificăm dacă interogarea sql “candidata” se afla printre acestea.
49
Oracle® Database Performance Tuning Guide, 10g Release 2 (10.2) – Chapter 12 – Automatic SQL tuning,
http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14211/sql_tune.htm#i22019
50
Recommended Method for Obtaining 10046 trace for Tuning [ID 376442.1], , accesat la data 25.01.2010
https://support.oracle.com/CSP/main/article?cmd=show&id=376442.1&type=NOT , accesat la data 25.01.2010
76
Alegerea sesiunii
Următoarele interogări ne ajuta să descoperim sesiunile curente din baza de date ce au acumulat cel mai
mult timp de procesare pentru anumite evenimente de aşteptare. Aceste sesiuni vor fi folosite pentru
identificarea sesiunilor portentiale de urmărit cu ajutorul 10046.
Următoarea interogare filtrează sesiunile pe baza timpului de logare, mai mic de 4 ore, şi ultima accesare
în ultimele 30 de minute. Aceste restricţii sunt pentru a găsi sesiuni curente mai relevante, decât cele
care rulează de mult şi care au acumulat mult CPU time, dar nu au probleme de performanţă. Valorile
prezentate sunt orientative.
77
Gasirea sesiunilor cu cel mai mari timpi de aşteptare
-- sesiunile cu cei mai mari timpi de aşteptare
SELECT s.sid, s.serial#, p.spid as "OS PID", s.username, s.module, se.time_waited
FROM v$session_event se, v$session s, v$process p
WHERE se.event = '&event_name'
AND s.last_call_et < 1800 -- active în ultima jumatate de ora
AND s.logon_time > (SYSDATE - 240/1440) -- sesiuni logate în ultimele 4 ore
AND se.sid = s.sid
AND s.paddr = p.addr
ORDER BY se.time_waited;
SQL> /
SID SERIAL# OS PID USERNAME MODULE DB Time(sec) CPU Time (sec) % CPU
---------- ---------- ------------ -------- ----------------------------------------------------- -------------- -----------
141 1125 15315 SYS sqlplus@coehq2 (TNS V1-V3) 12.92 9.34 72.29
78
Obtinerea unui trace complet
Ideal ar fi sa putem porni un trace imediat ce utilizatorul s-a logat şi incepe operatilunile sale sau
tranzactiile. Trigger-ul mentionat anterion poate fi folosit în aceste situatii.
Paşi de urmat:
O sesiune conectată
• Se începe urmărirea unei sesiuni conectate
• Ne vom coordona cu utilizatorul să înceapă operaţiunea
• Vom măsura timpii de răspuns ai clientului pentru operaţia în cauză. Ideea este de a compara
timpul cât îi ia unei funcţii să ruleze în aplicaţie din perspectiva utilizatorului cu cel cât îi ia
respectivei interogări să ruleze în baza de date. dacă aceşti timpi sunt apropiaţi, atunci problema
de performanţă tine de bază de date, în caz contrar este alt tip de problemă.
• Se va opri înregistrarea.
• Se va colecta fişierul de trace din locaţia user_dump_dest.
Se va generara un raport TKProf şi sortarea interogărilor cele mai lungi se face utilizând următoarea
comanda:
Fişier de trace pentru on proces ce rulează mult care a fost urmarit intermitent în ultimele zile
. . .
*** 2009-07-24 13:35:05.642 <== Timestamp de la o urmarire anterioara
WAIT #8: nam='SQL*Net message from client' ela= 20479935 p1=1650815232 p2=1 p3=0
=====================
PARSING IN CURSOR #9 len=43 dep=0 uid=57 oct=3 lid=57 tim=1007742062095 hv=4018512766
ad='97039a58'
select e.empno, d.deptno<== cursor precedent ce a fost urmarit
79
from emp e, dept d
END OF STMT
PARSE #9:c=630000,e=864645,p=10,cr=174,cu=0,mis=1,r=0,dep=0,og=4,tim=1007742062058
BINDS #9:
EXEC #9:c=0,e=329,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=1007742062997
WAIT #9: nam='SQL*Net message to client' ela= 18 p1=1650815232 p2=1 p3=0
. . .
FETCH #9:c=10000,e=513,p=0,cr=1,cu=0,mis=0,r=15,dep=0,og=4,tim=1007742148898
WAIT #9: nam='SQL*Net message from client' ela= 2450 p1=1650815232 p2=1 p3=0
WAIT #9: nam='SQL*Net message to client' ela= 7 p1=1650815232 p2=1 p3=0
FETCH #9:c=0,e=233,p=0,cr=0,cu=0,mis=0,r=10,dep=0,og=4,tim=1007742152065
. . .
====> ACESTE LINII NU FAC PARTE DIN TEST <====
*** 2006-07-24 18:35:48.850
<== Timestamp oentru trace-urile pe care le urmarim (aprox 5 ore mai tarziu)
=====================
PARSING IN CURSOR #10 len=69 dep=0 uid=57 oct=42 lid=57 tim=1007783391548 hv=3164292706
ad='9915de10'
alter session set events '10046 trace name context forever, level 12'
END OF STMT
. . .
=====================
PARSING IN CURSOR #3 len=68 dep=0 uid=57 oct=3 lid=57 tim=1007831212596 hv=1036028368
ad='9306bee0'
select e.empno, d.dname<== Cursorul ce a fost urmarit
from emp e, dept d
where e.deptno = d.deptno
END OF STMT
PARSE #3:c=20000,e=17200,p=0,cr=6,cu=0,mis=1,r=0,dep=0,og=4,tim=1007831212566
BINDS #3:
EXEC #3:c=0,e=321,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=1007831213512
WAIT #3: nam='SQL*Net message to client' ela= 15 p1=1650815232 p2=1 p3=0
WAIT #3: nam='db file sequential read' ela= 7126 p1=4 p2=11 p3=1
. . .
FETCH #3:c=10000,e=39451,p=12,cr=14,cu=0,mis=0,r=1,dep=0,og=4,tim=1007831253359
WAIT #3: nam='SQL*Net message from client' ela= 2009 p1=1650815232 p2=1 p3=0
WAIT #3: nam='SQL*Net message to client' ela= 10 p1=1650815232 p2=1 p3=0
FETCH #3:c=0,e=654,p=0,cr=1,cu=0,mis=0,r=13,dep=0,og=4,tim=1007831256674
WAIT #3: nam='SQL*Net message from client' ela= 13030644 p1=1650815232 p2=1 p3=0
STAT #3 id=1 cnt=14 pid=0 pos=1 obj=0 op='HASH JOIN (cr=15 pr=12 pw=0 time=39402 us)'
=====================
PARSING IN CURSOR #7 len=55 dep=0 uid=57 oct=42 lid=57 tim=1007844294588 hv=2217940283
ad='95037918'
alter session set events '10046 trace name context off' <== tracing-ul a fost oprit
END OF STMT
80
Asigurarea ca fiserul de trace este complet
Dacă urmarirea a inceput sau s-a sfarsit în timpul unei apelări, este bine sa regandim procesul ca ascest
lucru sa nu se intample din nou.
*** 2006-07-24 15:00:45.538 <== Timpul când s-a inceput urmărirea aşteptarii
WAIT #3: nam='db file scattered read' ela= 18598 p1=4 p2=69417 p3=8 <== Wait
*** 2006-07-24 15:01:16.849 <== 10g va scrie mesaje dacă în trace nu s-a scris nimic de
ceva vreme
WAIT #3: nam='db file scattered read' ela= 20793 p1=4 p2=126722 p3=7
. . .
*** 2006-07-24 15:27:46.076
WAIT #3: nam='db file sequential read' ela= 226 p1=4 p2=127625 p3=1 <== Yet more waits
WAIT #3: nam='db file sequential read' ela= 102 p1=4 p2=45346 p3=1
WAIT #3: nam='db file sequential read' ela= 127 p1=4 p2=127626 p3=1
WAIT #3: nam='db file scattered read' ela= 2084 p1=4 p2=127627 p3=16
. . .
*** 2006-07-24 15:30:28.536 <== Timestamp final inainte şi după apelarea FETCH
WAIT #3: nam='db file scattered read' ela= 5218 p1=4 p2=127705 p3=16 <== Final wait
WAIT #3: nam='SQL*Net message from client' ela= 1100 p1=1650815232 p2=1 p3=0
=====================
PARSING IN CURSOR #3 len=39 dep=0 uid=57 oct=0 lid=57 tim=1014506207489 hv=1173176699
ad='931230c8'
select count(*) from big_tab1, big_tab2 <== Aceasta nu este parsarea unui apel real
END OF STMT
FETCH #3:c=0,e=11,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=0,tim=1014506207466 <== Terminarea
apelului de FETCH
FETCH raportează 11 microSec.Acest rezultat este gresit după cum se poate observa din
timestamps. Ar trebui sa fie aprox. 30 min.
Dacă urmărirea a început sau s-a sfârşit în timpul unei apelări, este bine să regândim procesul ca ascest
lucru să nu se întâmple din nou.
*** 2006-07-24 15:00:45.538 <== Timpul când s-a început urmărirea aşteptarii
WAIT #3: nam='db file scattered read' ela= 18598 p1=4 p2=69417 p3=8 <== Wait
*** 2006-07-24 15:01:16.849 <== 10g va scrie mesaje dacă în trace nu s-a scris nimic de ceva
vreme
WAIT #3: nam='db file scattered read' ela= 20793 p1=4 p2=126722 p3=7
. . .
*** 2006-07-24 15:27:46.076
WAIT #3: nam='db file sequential read' ela= 226 p1=4 p2=127625 p3=1 <== Yet more waits
WAIT #3: nam='db file sequential read' ela= 102 p1=4 p2=45346 p3=1
WAIT #3: nam='db file sequential read' ela= 127 p1=4 p2=127626 p3=1
WAIT #3: nam='db file scattered read' ela= 2084 p1=4 p2=127627 p3=16
. . .
*** 2006-07-24 15:30:28.536 <== Timestamp final înainte şi după apelarea FETCH
81
WAIT #3: nam='db file scattered read' ela= 5218 p1=4 p2=127705 p3=16 <== Final wait
WAIT #3: nam='SQL*Net message from client' ela= 1100 p1=1650815232 p2=1 p3=0
=====================
PARSING ÎN CURSOR #3 len=39 dep=0 uid=57 oct=0 lid=57 tim=1014506207489 hv=1173176699
ad='931230c8'
select count(*) from big_tab1, big_tab2 <== Aceasta nu este parsarea unui apel real
END OF STMT
FETCH #3:c=0,e=11,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=0,tim=1014506207466 <== Terminarea apelului de
FETCH
FETCH raportează 11 microSec.Acest rezultat este greşit după cum se poate observa din timestamps.
Ar trebui să fie aprox. 30 min.
Verificarea dacă cel mai mare timp este cel petrecut aşteptând intre apeluri
Aşteptările pentru mesajele SQL*Net de la client între două apeluri (de obicei apeluri FETCH) indica o
problemă de performanţă a clientului (client lent sau care nu utilizează operaţiile cu array-uri) sau a reţelei
(latenta mare, banda de transfer mică, timeouts). Optimizarea interogărilor nu rezolva acest tip de
probleme.
Dovezi ale timpilor de aşteptare dintre apeluri pot fi identificate uitându-ne după:
1 În TKProf, vom observa că timpul total petrecut în baza de date este mic în comparaţie cu timpul
aşteptat de către client.
Exemplu:
Sesiune TKProf a unei sesiuni unde clientul utilizează un array de 2 şi cauzează multe apeluri FETCH
82
Elapsed times include waiting on following events:
2 Pentru a confirma că aşteptările se datporeaza unui client lent, se va examina trace-ul 10046
pentru interogarea SQL în cauza şi vom analiza timpii de aşteptare între apelurile FETCH:
PARSING ÎN CURSOR #2 len=29 dep=0 uid=57 oct=3 lid=57 tim=1016349402066 hv=3058029015 ad='94239ec0'
Între două apeluri FETCH, există aşteptare pentru client. Acesta este lent şi răspunde la 1-2 sec.
83
C. Verificarea problemei - analiza datelor
În acest pas vorm analiza fişierele de trace şi datele TKProf colectate în etapa anterioară pentru a verifca
dacă interogarea suspectată este cu adevărat cea cu probleme.
TKProf va sumariza rezultatul fişierului de trace SQL pentru a ne arăta cât timp I-a luat fiecărei interogări
SQL saruleze, planul de execuţie la rulare şi timpii de aşteptare asociaţie fiecărei fraze SQL. În acest
mod, putem vedea uşor interogările ce sunt responsabile pentru cei mai mulţi timpi şi ar trebui luate în
considerare pentru optimizare.
dacă observam că interogările prezentate în TOP SQL statements din TKProf sunt aceleaşi pe care le
sustectam şi noi, atunci problema este verificată.
Paşii verificării
2
3 Este timpul total prezentat în TKProf timpul de răspuns al aplicaţiei ce este măsurată când
aceasta
rulează?
Exemplu:
Dacă aplicaţia a rulat în 410s, uitându-ne în secţiunea “Overall Totals” de la sfârşitul raportului TKProf
vom observa că timpul total de urmărire a fost de (presupunând că înregistrarea a început înainte ca
aplicaţia să ruleze şi a fost oprită imediat ce rularea s-a finalizat):
84
Parse 1165 0.66 2.15 0 45 0 0
Execute 2926 1.23 2.92 0 0 0 0
Fetch 2945 117.03 398.23 5548 1699259 16 39654
------- ------ -------- -------- ----- -------- -------- -------------------------------------------------------------------------
total 7036 118.92 403.31 5548 1699304 16 39654
În acest caz, 403s din 410s, văzute din punctul de vedere al utilizatorului au fost petrecute în baza de
date. Este necesară o optimizare a interogărilor.
Timpul petrecut parsând, executând şi obţinând înregistrări este cel mai mare din totalul timpului
din fişierul de trace?
Explicaţii
Scopul optimizării interogărilor este să reducă timpul petrecut de o interogare parsând, executând şi/sau
obţinând date. dacă fişierul de trace arata ca aceste operaţiuni decurg rapid în comparaţie cu timpul total,
trebuie să optimizăm clientul sau reţeaua.
85
Când baza de date petrece cel mai mult timp aşteptând intre execuţiile cursoarelor, suspectăm că
reţeaua sau clientul au latentă.
Pe de lat parte, când cel mai mult din timpul unei interogări este petrcut aşteptând intre apeluri FETCH
ale aceluiaşi cursor, ar trebui să suspectăm un client ce nu utilizează preluări pe loturi (bulk/array).
Interogarea petrece cel mai mult timp în faza de execuţie/fetch (nu în faza de parsare)?
dacă da, verificarea s-a încheiat şi suntem siguri că aceasta este interogarea ce necesită optimizare.
dacă nu este posibilă existenţa unei probleme de parsare. Tehnicile de optimizare obişnuite ce modifică
planul de execuţie al unei interogări, nu vor ajuta în acest caz. Trebuie să modificăm definirea problemei
şi să adăugăm că avem în vedere o îmbunătăţire a timpului de parsare.
Exemplu:
86
Faza 2 - Determinarea cauzei
Verificări de bază
• Ne asigurăm că folosim optimizarea corectă.
• Statistici actuale sunt colectate pentru toate obiectele.
• Setările parametrilor de bază sunt corecte.
Urmărirea paşilor strategiei de optimizare alese pentru identificarea cauzei şi a potenţialelor soluţii.
Se va alege o soluţie şi se va implementa.
Verificarea ca soluţia implementată a rezolvat problema sau sunt necesare acţiuni ulterioare.
Un plan de execuţie corect şi precis este cheia începerii procesului de optimizare. Procesul de obţinere a
unui plan de execuţie variază în funcţie de versiunea bazei de date.
Premise:
87
SQL> @?/rdbms/admin/utlxplan
Oracle 10.2.x51
Valoarea actuală a variabilelor constrânse (bând variables) va influenţa planul de execuţie ce va fi
generat este foarte importantă pentru a obţine planul de execuţie actual pentru interogarea ce întâmpina
probleme de performanţă.
Varianta 1 – de preferat
Această abordare utilizează DBMS_XPLAN pentru a colecta planul de execuţie actual (nu cel
EXPLAINed) şi va asigura informaţii utile despre numărul actual şi estimat de înregistrări returnate.
dacă sunt utilizate variabile constrânse, pentru obţinerea planului de execuţie actual se va utiliza o
metodă dintre următoarele:52
Exemplu:
51
Oracle® Database PL/SQL Packages and Types Reference, 10g Release 2 (10.2) – Chapter 132 – DBMS_XPLAIN – Summary
of DBMS_XPLAIN Subprorams
http://download-west.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_xplan.htm#i996786 , accesat la data 25.01.2010
52
Methods for Obtaining a Formatted Explain Plan [ID 235530.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=235530.1&type=NOT
88
SQL> set linesize 150
SQL> set pagesize 2000
SQL> select * from table(dbms_xplan.display_cursor(null,null, 'ALL'));
• dacă interogarea a fost executată, şi ştim valoarea SQL_ID-ului, putem extrage planul din library
cache:
SQL> set linesize 150
SQL> set pagesize 2000
SQL> select * from TABLE(dbms_xplan.display_cursor('&SQL_ID', &CHILD,'ALL'));
Dacă a fost executat cursorul când se colectau statisticile, atunci se va utiliza ALLSTATS în loc de ALL.
2 Varianta 2
Se vă va utiliza doar dacă prima variantă nu se poate folosi. Această abordare poate fi utilizată pentru a
colecta planul de execuţie pentru interogări ce nu au variabile constrânse.
Important: Se va obţine planul de execuţie al interogării şi când rulează optim şi când întâmpina eficiente
de performanţă.
În cazul în care sistemul cu o performanţă bună nu mai este accesibil, pentru a obţine un plan de
execuţie bun, se poate folosi parametrul optimizer_features_enable, pentru a readuce comportamentul
optimizer-ului la cel vechi. Se vor importa statisticile vechi în sistem. Vom verifica dacă modul optimizer-
ului este setat pe cel vechi.
89
Colectarea de informaţii cuprinzătoare despre interogare
SQLTXPLAIN.SQL colectează date comprehensive despre o anumită interogare. Aceste date pot fi
utilizate pentru a examina obiectele din spatele interogării, pentru a vizualiza planul de execuţie a
interogării şi a intege mai profund cauzele deciziilor optimizatorului privind planul de execuţie.
• Această operaţiune va aduna informaţii despre fiecare tabel sau viziune din interogare, incluzând
şi statistice/histograme, coloane şi dependentele viziunilor.
• Planul de execuţie şi informaţia predicat obţinută din comandă EXPLAIN PLAN, vor fi colectate
deasemena.
• Va fi colectat un fişier de trace CBO (event 10053)
• Un raport final va fi generat în format HTML
Exemplu:
sqlplus <usr>/<pwd>
start sqltxplain.sql <nume fişier text ce conţine interogarea>;
sqlplus apps/apps;
start sqltxplain.sql sql5.txt;
53
SQLT (SQLTXPLAIN) - Tool that helps to diagnose SQL statements performing poorly [ID 215187.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=215187.1&type=NOT
90
Colectarea de informaţii istorice despre interogare
• cale a de află ambii indicatori este să căutăm interogarea în raportul statspack sau AWR în
secţiunea “Top SQL”.
• Altă cale ar fi să ne uităm în fişierul trace brut 10046 colectat dintr-o sesiune din timpul verificării
problemei, identificăm interigarea SQL şi căutam linia asociată cu aceasta interogare ce conţine
“hv=”.
Exemplu:
Rularea scriptului sqrepsql.sql sau awrsqlrpt.sql pentru a căuta un reper în timp când interogarea
se execută oprim.
Când suntem anunţaţi să introduce perioada de început şi de sfârşit a unui snapshot, să introducem o
dată când ştim că interogarea se execută deficitar; un raport similar dintr-o perioadă optimă, ar fi
deasemenea util.
Exemplu:
54
Using Statspack to Record Explain Plan Details [ID 209197.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=209197.1&type=NOT
91
sqlplus perfstat/pwd;
@?/rdbms/admin/sprepsql.sql
Completed Snapshots Snap Snap
Instance DB Name Id Snap Started Level Comment
--------- --------- ----- ----------------- ----- --------------
DB9iR2 DB9IR2 125 18 Aug 2005 21:49 5
...
150 03 Apr 2006 16:51 7
151 03 Apr 2006 16:51 7
Specify the Begin and End Snapshot Ids
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Enter value for begin_snap: 150
Begin Snapshot Id specified: 150
Enter value for end_snap: 151
End Snapshot Id specified: 151
Specify the Hash Value
~~~~~~~~~~~~~~~~~~~~~~
Enter value for hash_value: 710622186
Hash Value specified is: 710622186
Specify the Report Name
~~~~~~~~~~~~~~~~~~~~~~~
The default report file name is sp_150_151_710622186. To use this name,
press <return> to continue, otherwise enter an alternative.
Enter value for report_name:
Se poate utiliza un script de test pentru a rula interogarea cu orice variable de constrângere necesare şi
evenimente de diagnostic pornite sau oprite. Acest script este util ca valoare de referinţă (benchmark) în
timp ce facem modificări asupra interogării.
Acest script va reprezenta aceeaşi performanţă a interogării şi planul de execuţie ca cea originală din
aplicaţie.
Extragerea cazului de test din fişierul de trace extins SQL colectat în etapa verificării problemei
(când interogarea a fost verificată ca fiind un blocaj).
92
• Identificăm variabilele constrânse pentru acesta interogare.
Exemplu
93
set time on
set timing on
spool test_script
-- pornirea trace-ul
alter session set events '10046 trace name context forever, level 12';
-- rularea interogării
select TO_CHAR(hiredate,:dfmt)
from emp
where sal > :salary
and deptno = :b3;
select 'end of script' from dual;
-- oprim trace-ul
alter session set events '10046 trace name context off';
spool off
94
Rularea scriptului de test şi colectarea fişierului de trace extins SQL ce a fost produs în directorul
user_dump_deşt.
Exemplu
Se va genera un raport TKPROf şi se vor ordona interogările SQL după ordinea celui mai mare timp,
folosind comanda:
Se va compara planul de execuţie şi alte statistici de execuţie (physical reads, logical reads, rows
returned per execution) pentru interogarea din scriptul de test cu cele colectate în etapa verificării
problemei. dacă aceste rezultate sunt comparabile, atunci sciptul de test este valid.
Analiza
Datele colectate în paşii anteriori vor fi acum analizate pentru a determina cauza problemei. Este
important să ne asigurăm că datele au fost colectate complet, atât pentru planuri bune, cât şi cele rele.
Acest proces începe întotdeauna prin verificarea validităţii statisticilor, a modului de optimizare, şi a
parametrilor importanţi de iniţializare; apoi, continuă cu alegerea unei strategii de optimizare care să fie
aplicabilă problemei şi obiectivelor tale.
95
Trebuie să ne asigurăm că este utilizată optimizarea bazată pe cost (CBO)., statisticile au fost colectate
în mod corect şi că parametri de iniţializare sunt setaţi cum trebuie, înainte de a analiza detaliile planului
de execuţie şi modul în care acesta va fi îmbunătăţit.
CBO-ul este esenţial pentru a optimiza o interogare, fiindcă RBO-ul nu mai este suportat.
Model de tuning
Justificarea cauzei: Planul de execuţie nu va afişa cardinalitatea estimată sau costul, dacă se utilizează
RBO.
Efort – scăzut
Risc – mediu. Adunarea de statistici noi ar putea modifica unele planuri de execuţie în rău, dar este mai
mult probabil că planurile se vor îmbunătăţi. Colectarea statisticilor vor invalida cursoarele
din shared pool – de aceea se recomanda aceasta operatiunie în perioadele cu activitate
redusă a bazei de date.
Oracle 10g:
exec DBMS_STATS.GATHER_TABLE_STATS(
tabname => ' Table_name '
96
ownname => NULL,
cascade => 'TRUE',
method_opt => 'FOR ALL COLUMNS SIZE AUTO');
exec dbms_stats.gather_table_stats(ownname=>'user_name',-
tabname=>'table_name',-
estimate_percent => 100,-
cascade=>true,-
method_opt=>'for all columns size skewonly');
55
Recommendations for Gathering Optimizer Statistics on 10g [ID 605439.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=605439.1&type=NOT , accesat la data 25.01.2010
56
Histograms: An Overview [ID 1031826.6],
https://support.oracle.com/CSP/main/article?cmd=show&id=1031826.6&type=NOT , accesat la data 25.01.2010
57
Best Practices for automatic statistics collection on Oracle 10g [ID 377152.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=377152.1&type=NOT , accesat la data 25.01.2010
58
How to check what automatic statistics collection is scheduled on 10g [ID 377143.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=377143.1&type=NOT , accesat la data 25.01.2010
59
Statistics Gathering: Frequency and Strategy Guidelines [ID 44961.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=44961.1&type=NOT , accesat la data 25.01.2010
97
Verificarea implementării: Rularea din nou a interogării şi observarea dacă performnta s-a îmbunătăţit. În
caz contrar trebuie să examinăm următoarele:
- să luăm în considerare alte posibile cauze
- să verificăm dacă datele au fost colectate corect
- să verificăm problema iniţială.
O alternativă ar fi înregistrarea unui Service Request cu Oracle Support pentru asistenţă în rezolvarea
acestei probleme.
Statisticile exacte asupra tuturor tabelelor şi indexurilor din căutare sunt esenţiale pentru că CBO-ul să
creeze planuri de execuţie bune.
• Numărul exact de rânduri obţinute în urma unei căutări sau un plan de execuţie care arată
numărul exact, şi cel estimat, de rânduri/pas al planului.
• Numărul de rânduri estimat obţinut în urma unei căutări („Estim Card” sau similar) din planul
de execuţie.
• Determină dacă există o discrepanţă majoră între numărul efectiv şi numărul estimat de
rânduri.
• Examinarea secţiunilor „Tabele” şi „Index”, coloana „Last Analyzed”, pentru a determina dacă
tabelele şi indecşii au fost analizaţi.
• Compararea coloanele „Num Rows” şi „Sample Size” în secţiunea „Tabele”, pentru a vedea
cât anume din tabel a fost folosit drept mostră pentru strângerea de date.
• Examinarea secţiunilor „Tabele” şi „Index”, coloana „User Status” pentru a determina dacă
statisticile au fost introduse direct sau analizate.
• Examinarea „Column Statistics”, „Num Buckets”, iar dacă aici apare 1, înseamnă că nu s-au
colectat histograme.
98
Model de tuning
Identificarea problemei: CBO a estimat un număr de înregistrări returnate semnificativ diferit faţă de
numărul real de înregistrări returnate.
Verificarea problemei:
- folosind raportul SQLTXPLAIN, vom căuta numărul estimat de înregistrări returnate pe interogare
(“Estim card” pentru) pentru prima linie a planului de execuţie.
- compararea numărului estimat de înregistrări cu cel real. dacă acestea idfera după un ordin de
magnitudine sau mai mult, CBO este afectat de statisticle inadecvate.
Statisctici lipsă:
- statisticile au fost colectate pentru tabelele din interogare
- colectarea statisticilor nu a fost defalcata până la indecşi (cascade)
Justificarea cauzei:
- statisticile tabelelor lipsesc: DBA_TABLES.LAST_ANALYZED este NULL
- lipsesc statisticile indecsilo: DBA_INDEX.LAST_ANALYZED este NULL
- mostra inadecvată pentru tabele: DBA_TABLES.SAMPLE_SIZE /# de înregistrări din tabela<5%
- mostra inadecvată pentru indecşi: DBA_INDEXE.SAMPLE_SIZE/# de înregistrări din tabela <30%
- histogramele nu au fost colectate: nu sunt înregistrări în DBA_TAB_HISTOGRAMS pentru coloanele ce
au date modificate.
Efort – scăzut
Risc – mediu
99
CBO foloseşte valorile diferiţilor parametri de iniţializare pentru a estima costul variatelor operaţiuni ale
planului de execuţie. Când anumiţi parametri nu au fost setaţi corespunzător, poate cauza estimarea
costului să fie inadecvată, iar planurile să devină sub-optime.60
Sursă: raportul SQLTXPLAIN, secţiunea de trace a optimizer-ului, “Parameters used by the Optimizer”
Cauza identificată: Parametri de iniţializare ce cauzează scanări complete ale tabelelor şi merge/hash
join-uri
Următorii parametri sunt conoscuti că afectează estimarea costului CBO
- optimizer_index_cost_adj setat mult mai mare de 100
- bd_file_multilock_read_count setat mult prea mare (>1MB/db_block_size)
- optimizer_mode=all_rows
Justificarea cauzei: Scanări complete ale tabelelor, merge/hash join-urile ce apar şi parametrii de mai
sus ce nu sunt setaţi cu valorile iniţiale.
Soluţia identificată: re-setarea parametrilor la valorile iniţiale. Totuşi, schimbarea valorilor iniţiale ale
acestor parametri ar putea îmbunătăţi performanţele unei interogări. Această modificare ar trebui
realizată întâi pentru o sesiune (şi nu la nivelul bazei de date în init.oră sau spfile) şi trebuie luat în
considerare şi impactul asupra altor interogări.
60
Oracle® Database Reference 10g Release 2 (10.2), Initialization Parameter Description, pagina 97,
http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14237.pdf
100
Implementarea soluţiei: detalii pe fiecare versiune61
Verificarea implementării: Rularea din nou a interogării şi observarea dacă performnta s-a îmbunătăţit.
În caz contrar trebuie să examinăm următoarele:
- să luăm în considerare alte posibile cauze
- să verificăm dacă datele au fost colectate corect
- să verificăm problema iniţială.
Răspunsurile la următoarele întrebări ne vor îndruma spre alegerea strategiei de tuning corecte.
2. Suntem mai degrabă interesaţi să rezolvăm cât mai repede problema, şi nu să identificăm cauza
aparititiei acesteia.
dacă este urgent să optimizăm o interogare şi nu suntem interesaţi să descoprim cauza deficiientelor de
performanţă, putem utiliza strategia soluţiei rapide de livra CBO-ului mai multe informaţii şi este posibil să
obţinem un plan de execuţie mai bun.
3. Interogarea petrece cel mai mult timp în faza de execuţie/fetch (şi nu în faza de parsare)?
dacă interogarea petrece cel mai mult timp parsând, tehnicile obişnuite de optimizare modofica planul de
execuţie pentru reducerea I/O (intrări/ieşiri) în timpul execuţiei sau apelurilor fetch, probabil nu vor fi de
mare ajutor. Atenţia optimizării ar trebui inderptata spre strategia de reducere a parsarilor.
Exemplu:
61
Database Initialization Parameters for Oracle Applications Release 12 [ID 396009.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=396009.1&type=NOT , accesat la data 25.01.2010
62
Oracle® Database Performance Tuning Guide 10g Release 2 (10.2), Chapert 11 – SQL Tuning Overview,
http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14211/sql_1016.htm#sthref1060 , accesat la data 25.01.2010
101
Timpul petrecut parsând este 300.83s, comparativ cu doar 85.03s pentru fetching. Interogarea are
probleme de parsare.
Reducerea timpilor de parsare mari necesita o abordare diferită a optimizării, faţă de scopul tipic de a
reduce intrările/ieşirile logice sau un plan de execuţie ineficient.
Se utilizează când s-a identificat ca iterogarea petrece cel mai mult timp în faza de parsare (de obicei
identificată în etapa verificării problemei).
a. Sursa: TKProf
- parse elapsed time, overall elapsed time
- parse time spent on CPU
Exemplu:
63
How to use the Sql Tuning Advisor. [ID 262687.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=262687.1&type=NOT , accesat la data 25.01.2010
_
Oracle® Database Performance Tuning Guide - 10g Release 2 (10.2), Chapter 12 Automatic SQL Tuning,
http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/sql_tune.htm#PFGRF028 , accesat la data 25.01.2010
_
Oracle® Database 2 Day DBA 10g Release 2 (10.2) - Using the SQL Tuning Advisor,
http://download.oracle.com/docs/cd/B19306_01/server.102/b14196/montune003.htm#sthref784 , accesat la data 25.01.2010
_
Oracle® Database Performance Tuning Guide 10g Release 2 (10.2) – Chapter 12 Automatic SQL Tuning
http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/sql_tune.htm#PFGRF028, accesat la data 25.01.2010
102
• total elapsed time of 21.45 sec
• parse elapsed time of 20.12 sec
• total parse CPU time of 20.02 sec
• parse wait time = parse elapsed time - parse cpu time = 20.12 - 20.02 = 0.10 sec
Exemplu:
Timpul petrecut aşteptând a fost parse elapsed - parse CPU = 20.12 - 0.02 = 20.10 secs.
b. dacă timpul petrecut de procesor parsând este mai mult de 50% din timpul total, timpul de parsare este
dominat de procesor, în caz contrar de evenimentele de aşteptare.
103
Model de tuning
Problema identificată: Una sau mai multe interogări ce prezintă consum mare de procesor în timpul
unei HARD parse
Acest compertament este adesea întâlnit când comenzi voluminoase invoca multe obiecte sau obiecte
partiţionate.
Ce să căutăm:
1. Trebuie să verificăm dacă instrucţiunea/comanda a fost parsata HARD
2. Trebuie să comparăm “parse CUP time” cu “parse elapsed time” şi să vedem dacă “parse cpu time”
este mai mult de 50%
Cauza identificată: Interogarea foloseşte mostre dinamice şi influenţează în mod negativ timpul de
procesare
Justificarea cauzei:
- timpul de procesare este responsabil pentru timpul total de execuţie al interogării
- rezultatul planului de execuţie SQLTXPLAIN, scriptul UTLXPLS, trace-ul 10053 vor arăta ca pentru
optimizarea interogării s-au folosit mostre dinamice.
Efort -mediu
Unele alternative sunt mai uşor de implementat (adăugarea unui hint), iar altele sunt mai dificile
(determinarea hint-ului necesar prin comparaţia planurilor de execuţie).
Risc – scăzut
În general, această soluţie va afecta doar interogarea în cauză.
Implementarea soluţiei
Câteva alternative la mostrele dinamice sunt:
1. În 10g sau versiuni ulterioage, se va folosi SQL Tuning Advisor (STA) pentru a genera un profil pentru
interogarea vizată.
2. Se vor găsi hint-urile necesare pentru implementarea planului generat normal prin utilizarea mostrelor
dinamice şi se va modifica interogarea cu hint-ul identificat.
3. Se va folosi outline-ul salvat pentru a capta un plan generat cu mostre dinamice. Pentru date foarte
volatile (pentru care mostrele dinamice ajutau la obţinerea unui plan de execuţie bun), se poate folosi
104
abordarea ca aplicaţia va alege una dintre interogările cu hint-uri în funcţie de starea datelor (ex. pentru
date şterse recent foloseşte interogarea#!, altfel interogarea#2).
Verificarea implementării
Se va implementa soluţia şi se va verifica dacă performanţele bazei de date se îmbunătăţesc. În caz
contrar trebuie să examinăm următoarele:
- să luăm în considerare alte posibile cauze
- să verificăm dacă datele au fost colectate corect
- să verificăm problema iniţială.
64
Oracle® Database Performance Tuning Guide 10g, Release 2 (10.2) – Chapter 16 Using Optimizer Hints
http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14211/hintsref.htm#sthref1602 , accesat la data 25.01.2010
65
Forcing a Known Plan Using Hints [ID 221970.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=221970.1&type=NOT , accesat la data 25.01.2010
66
How to specify an INDEX Hint [ID 50607.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=50607.1&type=NOT , accesat la data 25.01.2010
67
QREF: SQL Statement HINTS [ID 29236.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=29236.1&type=NOT , accesat la data 25.01.2010
68 Oracle® Database Performance Tuning Guide 10g, Release 2 (10.2) – Chapter 18 Using Plan Stability,
105
Doar planul de execuţie deficitar este disponibil şi se doreşte o soluţie
rapidă Strategia soluţiei rapide
Obiectivul acestei strategii este să modifice câteva setări de nivel înalt ale optimizer-ului şi observarea
dacă apar îmbunătăţiri în plnul de execuţie (de ex. se va schimba optimizer_mode sau se va folosi
dynamic sampling). Apoi, se vor folosi hint-uri sau alte mijloace ce vor determina CBO să genereze un
plan de execuţie mai bun. Un plan mai bun poate fi folosit în identificarea ulterioară a cauzei problemei.
Presupuneri
- deja am încercat să folosim SQL Tuning Advisor.
- au fost verificaţi optimizer_mode, statisticile şi parametrii de iniţializare pentru:
o se utilizează CBO
o statisticile au fost colectate pentru toate obiectele, tabelele şi toţi indecşii
o dimensiunea mostrei de analiza este cât mai mare posibilă
o au fost colectate histogramele pentru toate coloanele din predicatul interogării ce au date
modificate
Pregătiri
Vom avea nevoie de textul interogării şi variabilele de constrângere (dacă sunt disponibile) să ruleze pe
sistemul unde interogarea este lentă.
Întâi, ar trebui să încercăm următoarele modificări, ce ar putea, cel mai probabil, să aducă rezultate
pozitive în cel mai scurt timp.
o Hint:
o Parametru:
106
ALTER SESSION SET optimizer_mode = first_rows_1;
SELECT col1, col2, ...
FROM table1...
WHERE col1 = 1 AND ...
o Hint:
o Parametru:
Este important să rulăm interogarea de două ori pentru a determina dacă performanta
acesteia s-a îmbunătăţit, deoarece, prima dată, interogarea este parsata, efortul pentru
construirea mostrei dinamice ar putea fi semnificativ, şi nu se va reflecta în performanţa
planului de execuţie. A doua rulare va indica dacă planul de execuţie s-a îmbunătăţit şi
dacă performanta este mai bună.
107
o ALTER SESSION SET OPTIMIZER_INDEX_COST_ADJ = 1000 (sau mai mare)
o ALTER SESSION SET OPTIMIZER_INDEX_CACHING = 0
o PARALLEL hint
dacă înregistrarea are viziuni, se pot încerca următoarele hint-uri:
o PUSH_PRED, NO_MERGE
o MERGE
dacă interogarea are sub-interogări, se pot încerca următoarele hint-uri:
o PUSH_SUBQ
o NNEST
Obiectivul acestei strategii este de a compara cele două planuri de execuţie, bun şi rău, identificarea
diferenţelor şi a modalităţilor de a determina planul deficitar să funcţioneze ca cel optim.
108
o se utilizează CBO
o statisticile au fost colectate pentru toate obiectele, tabelele şi toţi indecşii
o dimensiunea mostrei de analiza este cât mai mare posibilă
o au fost colectate histogramele pentru toate coloanele din predicatul interogării ce au date
modificate
Exemplu:
În acest caz, execuţia va începe cu pasul ce are “Explain Plan Operatio” “INDEX FAST
FULL SCAN TOWNER.TEAMS_LINKS_IDX_001”, urmat de “INDEX FAST FULL SCAN
TOWNER.UOIS_IDX_003”.
Compararea
Ordinea join-urilor este unul dintre cei mai importanţi factori ce influenţează performanţă
pentru interogările ce implică multe tabele. Puteam obţine ceasta ordine pentru planul bun
astfel:
109
§ Fişierul de trace 10053. În acest fişier vom identifica ultima ordine a join-urilor
aleasă de CBO. Aceasta este citită de sus în jos (de la Table #0 la Table #N).
Exemplu:
Best so far: TABLE#: 0 CST: 8502 CDN: 806162 BYTES: 72554580
Best so far: TABLE#: 1 CST: 40642 CDN: 806162 BYTES: 112056518
Table #0 este tabelul cel mai din stânga, Table #1 este cel din dreapta, şi tot aşa.
În acest exemplu, ordinea este EMP, DEPT.
Exemplu:
110
Comparând ordinea planului bun cu a celui deficitar, dacă acestea diferă, se va
folosi hint-ul ORDERED sau LEADING pentru a direcţiona CBO-ul.
Odată ce au fost identificate diferenţele între cele două planuri, este necesară modificarea interogării cu
un hint pentru a asigura generarea unui plan bun.
Se va revedea textul interogării, căile de acces, ordinea şi metodele join-urilor, se vor implementa soluţii
pentru aceste probleme. Aceasta este abordarea standard a optimizării interogărilor şi este subiectul
principal al acestei strategii.
71
How to Tune a Query that Cannot be Modified [ID 122812.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=122812.1&type=NOT , accesat la data 25.01.2010
111
Examinarea interogării
Vom examina interogarea să identificăm eventualele greşeli şi trebuie să luăm în considerare volumul de
date căruia I se adresează această.
Lipsa predicatelor din join-uri cauzează produsuri carteziene ce sunt foarte ineficiente şi ar trebui evitate.
Exemplu:
SELECT e.ename, d.dname FROM scott.emp e, scott.dept d WHERE e.empno < 1000
Ar trebui scrisă:
SELECT e.ename, d.dname FROM scott.emp e, scott.dept d WHERE e.empno < 1000 AND
e.deptno = d.deptno
Predicate neobişnuite
Exemple:
- predicate identice repetate: WHERE col1 =1 and col1 =1 and col1 =1 and … ce va
determina CBO să subestimeze selectivitatea interogării. Presupunând că selectivitatea
col1=1 este 0.2, această clauză va avea selectivitate=0.2*0.2*0.2=0.008. Aceasta va
determina o cardinalitate estimată mult mai mică decât cea reală şi ar putea bloca calea unui
index, în timp ce o scanare completă a tebelei ar fi fost o variantă mai bună.
- Predicate identice în ambii membri: WHERE d.deptno = d.deptno, ce are ca efecte
eliminarea valorilor NULL din interogare (chiar şi pentru coloanele NULL) şi subestimarea
cardinalitatii.
Predicatele neobişnuite ar trebui eliminaye dacă generează rezultate neaşteptate (ex. eliminarea valorior
nule) sau execuţii deficitare ale planului datorate cardinalitatii estimate greşit.
112
Constructori ce cauzează probleme
Model de tuning
Cauza identificată: Pentru CBO costul unei scanări complete a tabelei este mai mic decât o serie de
scanări pe serii de indecşi. Când sunt utilizaţi operatorii În şi OR, CBO împarte interogarea în blocuri
separate şi fiecare dintre ele va utiliza un index.
Justificarea cauzei: scanări complete ale tabelei în planul de execuţie în locul scanărilor după intervale
de indecşi utilizând operaţia de CONCATENARE.
Implementarea soluţiei:
SELECT /*+ USE_CONCAT */ * FROM table1 WHERE col1 ÎN (1,2,3,4,…);
113
Examinarea căilor de acces la date
Alegerea căilor de acces are un impact deosebit asupra performantei interogărilor. dacă interogarea are
un predicat ce reduce numărul de înregistrări dintr-o tabelă, este de preferat folosirea unui index (în
eventualitatea existenţei unui index pe coloana predicat). Pe de altă parte, dacă nu există un predicat
care să filtreze înregistrările din tabela sau predicatul nu este foarte selectiv şi sunt returnate multe
rânduri, o scanare completă ar putea fi mai eficientă decât o scanare pe bază de index.
Este important să înţelegem care este numărul aşteptat de înregistrări pentru fiecare pas al planului şi să
îl comparăm cu cel estimat de CBO, în acest mod putem determina dacă o scanare completă este
justificată sau nu.
Probleme posibile:
• Interogarea nu foloseşte un index, sau foloseşte indexul greşit. Fie un index nu este disponibil
pentru una sau mai multe coloane din predicatul interogării, sau este disponibil dar nu a fost ales
de către CBO.
Ce să căutăm:
• Planul de execuţie ne arată că indexul nu a fost folosit (şi se utilizează scanarea completă a
tabelei) pentru accesarea înregistrărilor tabelei şi coloanele nu au indecşi sau indexul existent pe
coloana nu este folosit.
Cauze identificate:
• Nu este definit un index pentru coloane sau predicate
• Selectivitatea estimată este incorectă
• Indecşii disponibili sunt prea neselectivi
• Conversia implicită a tipurilor de date din interogare
• Este utilizată o funcţie pe o colană din predicatul interogării ce împiedica utilizarea acelui index
• Interogarea are un hint ce împiedica utilizarea index-ului
• Utilizarea unui optimizer_mode greşit
• Apariţia unui produc cartezian datorat lipsei unui predicat
114
Interogarea ar trebui să returneze multe înregistrări (specific aplicaţiilor de
suport a deciziilor)
Când sunt aşteptate multe înregistrări, scanările complete ale tabelei sau complete indecşilor sunt de
preferat scanărilor parţiale ale indecşilor (unique sau tange). dacă ne aşteptam la un număr mare de
înregistrări, iar performanta interogării lasă de dorit, ar trebui să verificăm dacă indecşii sunt folosiţi
inadecvat.
Probbleme posibile:
• Utilizarea full index scan pentru o tabelă de dimensiuni mari. Interogarea este executată utilizând
metoda de acces a acestui index, în loc de INDEX FAST FULL SCAN.
Ce să căutăm:
• Planul de execuţie arata INDEX SCAN pe tabela
• Tabela are dimensiuni mari (verificarea valorilor NUM_ROWS şi BLOCKS din raportul
SQLTXPLAIN)
Cauze identificate:
• Optimizer_mode sau hint este setat pentru FIRST_ROWS sau FIRST_ROWS_K
• S-a utilizat INDEX FULL SCAN pentru a evita o sortare
• Lipseşte un predicat filtru
• Un număr mare de înregistrări trebuiesc procesate de către interogare
1 Model de tuning
Definirea problemei: Utilizarea full index scan pentru o tabelă de dimensiuni mari. Interogarea este
executată utilizând metoda de acces a acestui index, în loc de INDEX FAST FULL SCAN.
Cauza identificată: Optimizer_mode sau hint este setat pentru FIRST_ROWS sau FIRST_ROWS_K.
Când modul optimizer-ului este setat pe FIRSTT_ROWS sau FIRST_ROWS_K, optimizatorul va favoriza
utilizarea indecşilor pentru a returna înregistrările mai rapid. Acest mod va rezulta într-un plan foarte
infeicient dacă sunt aşteptate multe înregistrări din interogare.
Justificarea cauzei:
- optimizer_ mode este setat printr-un hint ca “/*+FIRST_ROWS_1*/”
115
- optimizer_ mode este setat printr-un parametru de iniţializare ca
OPTIMISER_MODE=FIRST_ROWS_1. Uneori o sesiune poate avea acesta setare printr-un declanşator
la autentificare – trace-ul 10053 poate arăta dacă acest parametru este setat sau nu.
- TKProf arata modul optimizer-ului
Soluţia identificată: Se va încerca utilizarea hint-ului ALL_ROWS. dacă sunt dorite majoritatea
înregistrărilor din interogare (şi nu doar primele care sunt returnate), atunci ALL_ROWS va permite CBO-
ului să identifice planuri de execuţie mai bune decât modul FIRST_ROWS_N, ce produce planuri ce
returnează înregistrările prompt, dar nu este eficient în returnarea tuturor rândurilor.
Ordinea join-urilor poate avea un impact foarte mare asupra performantei interogărilor. O ordine optimă
este, de obicei, cea în care sunt returnate cel mai devreme în plan cele mai puţine înregistrări. CBO
încearcă să înceapă ordinea join-urilor cu tabelele pe care le considera că vor returna doar o
înregistrare. dacă acesta estimare este greşită, este ales tabelul greşit şi performanţă interogării este
afectată.
Alegerea tipului de join este deasemenea importantă. Jon-urile imbricate sunt de dorit doar când câteva
înregistrări sunt necesare rapid şi coloanele de join sunt indexate. Hash join-urile sunt de dorit când sunt
implicate tabele de dimensiuni mari, şi se returnează multe înregistrări, sau coloanele de join nu au
indecşi.
72
Oracle® Database Performance Tuning Guide 10g Release 2 (10.2) – Chapter 16 – Using Optimizer Hintes, 16.1.2.1 Hints for
Optimization Approaches and Gols,
http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14211/hintsref.htm#CHDFIAJD , accesat la data 25.01.2010
116
• Sursa : planul de execuţie
o Numărul real de înregistrări returnate de către interogare sau un plan de execuţie ce
arata numărul de înregistrări real şi estimat la fiecare pas.
o Numărul estimat de înregistrări returnate (Estim Card) din planul de execuţie
o Determinarea existenţei unei mari discrepante intre numărul de înregistrări real şi cel
estimat
• Sursa: raportul SQLTXPLAIN
o Execuţia planului arata ordinea execuţiei în coloana Exec Order
• Sursa: raportul SQLTXPLAIN, secţiunea Optimizer trace, Parameters Used by the Optimizer
Ordinea join-urilor
Probbleme posibile:
• Ordine incorectă – primele tabele intersectate returnează mai puţine interogări decât ultimele.
Numărul înregistrările actuale returnate din primele tabele intersectate este mult mai mare decât
cel rezultat din ultimele tabele intersectate. Este critic să începem ordinea intersectării cu tabelul
ce va returna cele mai puţine rânduri şi să îl intersectăm cu următorul cu cele mai puţine
intersectări, şi tot aşa. Tabelul ce returnează cele mai puţine înregistrări nu este neapărat cel cu
dimensiunea cea mai mică, deoarece şi un tabel de dimensiune foarte mare poate returna o
singură înregistrare când îi sunt aplicate anumite condiţii. În concordanţă, un tabel mic poate să
nu aibă nici o condiţie.
Ce să căutăm:
• Cardinalitatea reală faţă de cea estimată pentru unul sau mai multe tabele din ordinea
intersectării diferă semnificativ.
• Cardinalitatea estimată – poate fi găsită în planul de execuţie (în SQLTXPLAIN), în coloana
“Estim Cardinality” corespunzătoare fiecărei tabele din ordinea intersectării.
• Cardinalitatea reală – se va verifica rularea planului de execuţie în TKProf pentru interogarea în
cauză.
Cauze identificate:
• Selectivitate/cardinalitate estimată greşit pentru primul tabel din join
• Parametrul de iniţializare “OPTIMIZER_MAX_PERMUTATIONS”73 are o valoare prea mică
pentru numărul de tabele din join
73
Initialization Parameters, http://www.adp-gmbh.ch/ora/misc/init_params.html , accesat la data 25.01.2010
117
Model de tuning
Verificarea problemei:
Numărul real de înregistrări returnate de către interogare sau un plan de execuţie ce arata numărul de
înregistrări real şi estimat la fiecare pas.
Numărul estimat de înregistrări returnate (Estim Card) din planul de execuţie
Determinarea existenţei unei mari discrepante intre numărul de înregistrări real şi cel estimat
Cauza identificată: Primul tabel din join are selectivitatea/cardinalitatea estimată greşit.
Justificarea cauzei:
Cardinalitatea reală faţă de cea estimată pentru unul sau mai multe tabele din ordinea intersectării diferă
semnificativ.
Cardinalitatea estimată – poate fi găsită în planul de execuţie (în SQLTXPLAIN), în coloana “Estim
Cardinality” corespunzătoare fiecărei tabele din ordinea intersectării.
Cardinalitatea reală – se va verifica rularea planului de execuţie în TKProf pentru interogarea în cauză.
Efort – scăzut
Risc – mediu. Adunarea de statistici noi ar putea modifica unele planuri de execuţie în rău, dar este mai
mult probabil că planurile se vor îmbunătăţi. Colectarea statisticilor vor invalida cursoarele din shared
pool – de aceea se recomanda aceasta operatiunie în perioadele cu activitate redusă a bazei de date.
Oracle 10g:
exec DBMS_STATS.GATHER_TABLE_STATS(
tabname => ' Table_name '
ownname => NULL,
cascade => 'TRUE',
method_opt => 'FOR ALL COLUMNS SIZE AUTO');
118
Pentru a şterge şi re-crea statisticile pentru un tabel individual şi indecşii săi:
exec dbms_stats.delete_table_stats(ownname=>'user_name',-
tabname=>'table_name',cascade_indexes=>true);
exec dbms_stats.gather_table_stats(ownname=>'user_name',-
tabname=>'table_name',-
estimate_percent => 100,-
cascade=>true,-
method_opt=>'for all columns size skewonly');
74
Recommendations for Gathering Optimizer Statistics on 10g [ID 605439.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=605439.1&type=NOT , accesat la data 25.01.2010
75
Histograms: An Overview [ID 1031826.6],
https://support.oracle.com/CSP/main/article?cmd=show&id=1031826.6&type=NOT , accesat la data 25.01.2010
76
Best Practices for automatic statistics collection on Oracle 10g [ID 377152.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=377152.1&type=NOT , accesat la data 25.01.2010
77
How to check what automatic statistics collection is scheduled on 10g [ID 377143.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=377143.1&type=NOT , accesat la data 25.01.2010
78
Statistics Gathering: Frequency and Strategy Guidelines [ID 44961.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=44961.1&type=NOT , accesat la data 25.01.2010
119
- să verificăm problema iniţială.
Tipul intersectării
Model de tuning
Definirea problemei: Interogarea returnează multe înregistrări, dar a fost aleasă intersectarea imbricată.
Nested loop join permite returnarea radida a unui număr mic de înregistrări. Acestea nu sunt optime când
sunt returnate multe înregistrări.
Verificarea problemei: Execuţia planului arata ordinea execuţiei în coloana Exec Order.
Justificarea cauzei: interogarea foloseşte hint-ul USE_NL şi ar rula mai bine fără acesta sau utilizând
hint-ul USE_HASH sau USE_MERGE.
79
Oracle® Database Performance Tuning Guide 10g Release 2 (10.2) – Chapter 16 – Using Optimizer Hintes, 16.1.2.2 Hints for
Access Paths,
http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14211/hintsref.htm#CHDJDIAH , accesat la data 25.01.2010
120
Examinarea altor operaţii (paralelism, etc.)
Execuţia paralelă
Date necesare pentru analiza: Sursa: planul de execuţie arata informaţii despre o execuţie paralelă
Probblema posibilă:
- Gradul de paralelism este eronat sau neaşteptat. Această problemă apare când gradul efectiv de
paralelism este diferit de cel pe care Oracle îl utilizează în mod obişnuit.
Ce să căutăm:
- Planul de execuţie arata mai puţine fire de execuţie alocate decât sunt necesare
- _px_trace raportează un grad de paralelism mai mic decât cel necesar
Cauze identificate:
- nu sunt disponibile fire de execuţie, iar interogarea a fost executată serial.80
Problema posibilă:
Este întâlnit paralelismul, dar nu este de dorit
Ce să căutăm:
Planul de execuţie arata operaţii paralele.
Fire de execuţie paralele sunt asociate cu sesiune curentă
Cauze identificate:
Setări de configurare sau hint-uri determina planuri paralele. CBO va încerca să utilizeze operaţii paralele
dacă sunt utilizate:
- Hint-ul parallel(t1, 4)
- ALTER SESSION FORCE PARALLEL
- Setarea gradului de paralelism şi/sau numărul de instante pe o tabelă, index sau interogare
Probbleme posibile:
Interogarea se execută seria, dar ar fi de dorit o execuţie paralelă.
Ce să căutăm:
după ce s-a executat interogarea, vom verifica V$PQ_SESSTAT.LAST_QUERY pentru statistica “queries
parallelized”. dacă acesta este 0, atunci interogarea nu a rulat în mod paralel.
Cauze identificate:
Nu erau disponibile fire de execuţie, iar interogarea a rulat serial.
80
Why didn't my parallel query use the expected number of slaves? [ID 199272.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=199272.1&type=NOT , accesat la data 25.01.2010
121
Studiu de caz
Acest studiu se bazează pe un caz real. Distribuţia datelor, analizei sau concluziei este strict interzisă
fară acordul meu scris.
Descrierea problemei
Un client a raportat o problemă de performanţă cu aplicaţia lor externa în timpul execuţiei unor interogări.
Clientul rulează aplicaţia folosind Oracle 9.2.0.4 pe o maşina AIX.
Problema identificată
• Aplicaţia externă a clientului rulează mult mai încet decât ar fi de dorit.
• Problema a fost izolată la o interogare specifică.
• Interogarea rulează 10 ore în sistemul clientului, faţă de 9 ore în sistemul vânzătorului, având
aceleaşi date.
• Nu au fost efectuate modificări în interogare (nu au fost folosite hint-uri) - şi nici nu sunt de
preferat modificări ale interogării.
• Clientul doreşte ca interogarea să ruleze aprox 9 min şi în sistemul lui, la fel ca în cel al
vânzătorului.
Clientul a asigurat rapoarte statspack, 10046/TKProf şi 10053 din ambele sisteme, al său şi al
vânzătorului, rapoarte ce au fost colectate în timpul rulării interogării. Din aceste fişiere a fost posibil să
identific că există diferenţe semnificative intre comportamentul interogării în sistemul clientului şi cel al
văzătorului.
Verificarea problemei
• Interogarea clientului utiliza un index, cea a vânzătorului utiliză o scanare completă a tabelului.
• Când indexul clientului a fost eliminat, performanţa s-a îmbunătăţit din moment ce se utiliza
scanarea completă a tabelului.
Analiza preliminară
Clientul a asigurat rapoarte statspack, 10046/TKProf şi 10053 din ambele sisteme, al său şi al
vânzătorului, rapoarte ce au fost colectate în timpul rulării interogării.
Comenzile pe care le-a utilizat clientul pentru generarea fişierelor de trace au fost următoarele:
Notă: înainte de colectarea fişierelor de trace 10046 şi 10053, am determinat identificatorul procesului din
sistemul de operare, proces ce rulează interogarea.
Statspack:
122
exec statspack.snap;
Analiza
Am utilizat fişierele de trace provenite de la client pentru a verifica problema. S-au comparat cele două
seturi vizând următoarele:
Analiza 10046/TKProf
• Timpul de rulare pentru a verifica afirmaţia clientului
• Evenimentele de aşteptare şi timpul mediu de aşteptare
• Numărul final de înregistrări returnate
• Şi dacă se potriveşte cu ce afişează statspack
Analiza 19953
• Dimensiunea obiectelor
• Statisticile colectate
• Costurile CBO-ului
Clientul a identificat interogarea problematică şi a fost folosită drept referinţă pentru testare:
123
Interogarea problematică este un INSERT… SELECT…¦. Partea de SELCET este cea lentă.
Această interogare a fost utilizată în cazul de test. S-a identificat că şi alte interogări sunt lente, dar
eforturile au fost concentrate pe această.
Analiza detaliată
124
Raportul statspack al clientului: Timed Events
Evenimentul de aşteptare principal al vânzătorului este db file scattered read. Acesta implică utilizarea
scanării complete a tabelei (FTS), ce corespunde observaţiei că performanţa interogării s-a îmbunătăţit
după ce s-a renunţat la index.
Timpul pentru intrări/ieşiri (I/O) este de 5ms, foarte bun dealtfel, şi indică faptul că nu există nici o
problemă în această arie.
125
Evenimentul principal din statspack-ul clientului este db file squential read, acesta indicând utilizarea
indecs-ilor şi nu a FTS.
Interogarea problematică nu este listat în raportul statspack generat în sistemul vânzătorului. Cea mai
apropiată interogare este “insert into E0 select distinct PATT_ID, AGE, NULL, 0, NULL from E
DF_PAŢIENT where AGE>=6574’, probabil nerelevat.
C. Concluziile analizei
• Nu sunt probleme de I/O
• Aparent, vânzătorul utilizează FTS şi nu indecşi.
126
• Datele rezultate corepund celor din raportul statspack? Dacă nu, de ce nu?
Observaţii:
• Timpul de rulare al interogării este de 2651.82 secunde = 44,1 minute, şi nu 9 minute cum s-a
susţinut la raportarea problemei.
• Au fost returnate 12844 de înregistrări. Acest număr trebuie comparat cu cel din sistemul
clientului.
• Planul utilizează o scanare pe baze de indecşi. De ce în statspack văzusem scanare completă a
tabelei?
Observaţii:
127
• Problema de performanţă poate fi atribuită în totalitate performanţei superioare a I/O din sistemul
vânzătorului
• Totuşi aceste date pot proveni dintr-un test neconcludent (ne-reprezentativ) deoarece este
diferită de FTS observat în statspack. Aceste discrepanţe arată că acest test nu este
reprezentativ.
Observaţii:
• Pentru test vânzătorul a utilizat variabile literale şi nu bând
• Acest lucru a condus la faptul că CBO a ales scanarea completă
• Când CBO avea cea mai bună informaţie a ales FTS, variabilele bând au derutat CBO-ul
• Citirile scanării complete/dispersate din statspack erau datorită variabilelor literale?
• CBO nu utilizează oricum variabile bind?
• N-ar trebui că rezultatele să fie aceleaşi?
• Constatăm existenţa unui bug sau aşa ar trebui să funcţioneze?
128
În acesta porţiune din 10053 putem efectua calculele costului pentru când sunt implicate variabilele
literale:
• FTS: #Blocks / MBDivisor = 548958 / 16.404 = 33,465 (minus 1)
• Index: LVL + (Sel * LB) + (Sel * CLUF) = 3 + (.495*283514)+(.495*39975474) = 19,928,202 ~
19,914,925
CBO a ales calea a 2-a, mai convenabilă, ceea ce indică faptul că s-a utilizat FTS.
Observaţii:
129
În mod surprinzător acţiunile CBO au fost:
1. A ales “path 4” ce este o scanare pe bază de index deşi FTS ar for fost mai avantajoasă
2. A înlocuit costul pentru “path 4” cu cel al FTS minus 1.
Când CBO estimează greşit cardinalitatea predicatului, de obicei rezulta un plan de execuţie
inconvenabil. Pentru a determina dacă CBO a estimat greşit cardinalitatea, trebuie să comparăm
cardinalitatea calculată în 10053 cu cea actuală din raportul TKProf de când interogarea a fost executată.
• Utilizarea variabilelor literale, cardinalitatea calculată este mai mică cu 16% decât cea actuală
• Folosind variabilele legate, cardinalitatea calculată este mai mică de 235 de ori!
Mutând atenţia pe sistemul clientului, am comparat datele acestuia cu cele ale vânzătorului.
130
Această secţiune din raportul TKProf arata:
• Timpul scurs a fost de 4793.62 sec = 79.8 min, ce este diferit de valoarea iniţială raportată, de 10
ore. De ce această discrepanţă?
• Nu am fost returnată nici o înregistrare, vs. 12844 de înregistrări în sistemul vânzătorului. De ce?
• 23 mil de înregistrări vizitate fata de 62 mil în testul vânzătorului. De ce?
• Aceste discrepante s-ar putea justifica, prin întreruperea rulării interogării de către client înainte
ca acesta să se fi finalizat.
• Acelaşi plan de execuţie cu cel raportat în 10046 la vânzător: scanarea tabelului pe bază de
index.
131
H. Analiza raportului 10053 provenit de la client
Aceasta porţiune din fişierul de trace 10053 arată aceleaşi rezultate observate în 10053 al vânzătorului,
când interogarea nu utiliza FTS:
• CBO alega o cale estimată ca fiind mai scumpă decât FTS.
• CBO setează costul caii de acces la aceeaşi valoare că utilizând FTS. De ce?
o Utilizând variabile legate, TKProf arată că numărul real de înregistrări vizitate este:
132
arhivate chiar şi după abandonarea interogării.
• Raportul 10046 al ambelor părţi ce a utilizat un index, a avut cardinalitati estimate foarte
inadecvate
• Raportul 10046/Tkprof al clientului a arătat că utilizarea caii de acces bazată pe index nu este
optimă, în timp ce FTS da.
• Rapoartele statspack şi 10053 ale vânzătorului arată că utilizau un plan FTS când performanţa
era bună.
• Concluzie: uneori, vânzătorul a utilizat un plan bazat pe index, alteori bazat pe FTS
o Probabil FTS când s-au utilizat variabilele literale
o Este necesară o analiză ulterioară.
133
Ce trebuie să facem de acum încolo?
Acum vom încerca să eliminăm posibilitatea existenţei unor bug-uri în această versiune de Oracle prin
căutări în baza de date cu bug-uri. Criteriile căutări ar putea fi:
• Cuvinte cheie: cbo bând peek
• Produs: Oracle Server Enterprise Edition
• Versiunea produsului: 9.2.0.3
• Impact: query performance
• Fixat în versiunea: 10
Concluzii
În urma căutării, bug-ul 3668224 pare asemănător cu problemele identificate în acest caz. Simptomele
bug-ului se referă tot la o performanţa slabă a interogării.
134
• Bug-ul determina CBO să intuiască calcularea selectivităţii, din moment ce bând peeking nu
funcţionează
• Intuirea calculării poate produce estimări eronate ale selectivităţii.
• Calcularea selectivităţii este foarte inadecvata pentru aceasta interogare
o Utilizând variabile literale, CBO a estimat 52mil de înregistrări.. valoare apropiată de cea
reală
o Utilizând variabilele legate, CBO a estimat 267000 de înregistrări.. foarte greşit
o Concluzia: CBO intuieşte estimarea din cauza acestui bug.
• Aplicarea patch-ului 3668224 şi activarea acestuia prin setarea evenimentelor 38056 şi 38044.
o Aceasta determina ca variabilele bând din funcţii să utilizeze funcţionalitatea de peeking
o Pro: ar putea rezolva şi alte probleme potenţiale cu alte interogări
o Contra: trebuie aplicat un pach (pachet reparator).
S-a ales optinea instalării pachetului reparator. Cu pachetul instalat şi evenimentele setate, a fost ales
planul de execuţie favorabil (utilizând FTS).
Dar care este explicaţia pentru costul utilizării inex-ului fiind identic cu cel al utilizării FTS pentru situaţia
când variabilele de legătură nu foloseau funcţionalitatea de peeking?
Pentru acesta întrebarea, soluţia este bug-ul 4341508 ce prezentă următoarele simptome:
• CBO favorizează accesul pe bază de index atunci când “intuieşte” valorile (variabilele de legătură
ce nu utilizează funcţionalitatea de peeking determina CBO-ul să intuiască valori).
• Când predicatul implica o valoare intuită şi CBO nu utilizează primele K înregistrări, atunci:
o CBO calculează costul utilizării metodei FTS
o În cazul în care costul accesului este mai mare decât cel utilizând FTS, valoarea acestuia
va deveni egală cu costul FTS. Acesta este motivul pentru care observasem valorile
similare, minus 1.
• Din moment ce _TABLE_SCAN_COST_PLUS_ONE=true, costul FTS era întotdeauna cu doar 1
mai mare decât costul estimat. Aceasta setare, cumulata cu explicaţia anterioară, determina
135
costul FTS să fie întotdeauna cu 1 mai mare decât valoarea pentru index. Acest fapt a determinat
alegerea caii de acces pe bază de index şi nu a FTS-ului.
Aplicaţia acestui client, era puţin neobişnuită, deoarece utiliza variabile bând pentru o interogare de
returna multe înregistrări (>1800).
Bând peeking a rezolvat această problemă.
În cazul acestui client, aplicarea pachetului reparator, a determinat activarea funcţionalităţii de peeking a
variabilelor de legătura utilizate în funcţii, ce a ce a produs o estimare adecvată şi un plan de execuţie
bun.
136
Concluzii
Tendinţa actuală pune mare accent pe capacitatea de reacţie la apariţia unor probleme de performanţă,
având drept coordonată principală timpul de rezolvare.
Se impune existenţa unei metode de investigare / diagnosticare, nu doar a unei analize rapide a
problemelor, şi, in plus, identificarea sursei acestora la momentul apariţie.
Diversificarea aplicaţiilor şi a tehnologiilor utilizate în dezvoltarea lor are implicaţii tot mai mari în
abordarea globală a problemelor de performanţă, adresându-se tuturor componentelor unui sistem.
Calific această abordare ca fiind completă, deoarece este singura modalitate de a investiga probleme de
performanţă complexe ce pot avea implicaţi factori din componente diferite ale sistemului.
Pentru a scurta procesul investigării trebuie să utilizăm o abordare ce evalueaza rapid performanţele
fiecarei componente din sistem (sistemul de operare, reţeaua, aplicaţia, baza de date, library cache, o
interogare particulară, etc, pâna la nivele fine de granularitate). Cu alte cuvinte, fiind o abordare ce
consideră sistemul ca un tot unitar.
Ce metodologie se alege pentru diagnosticarea unei probleme de performanţă, este o decizie personală,
dar metodologia prezentată în acesta lucrare este una verificată şi utilizată cu succes în ultimii ani de
Oracle Corporation.
Această metodologie documentează o abordare bazată pe experienţa reala, ce a evoluat prin rezolvarea
numeroaselor situaţii complexe, dintre care multe critice sau disperate.
Statistic, s-a demostrat că utilizarea acestei metodologii bazate pe principiul cauzalităţii al lui Einstein,
reduce eforturile şi timpul de urmărire şi identificare a problemelor de performanţă din sistem.
Acestă metodologie nu doar formalizeaza procesul de definire a problemei, ci oferă şi avantajul corelării
efectelor cu posibilele consecinţe ale unei performante indezirabile şi pentru alte componente din sistem.
137
Alocarea de resurse fizice sumplimentare este eficientă în prea puţine cazuri de probleme de
performanţă.
O astfel de metodologie este şi un bun mediator între diferitele echipe implicate în funcţionarea sistemului
(dezvoltatorii aplicaţiei, administratorii bazei de date, administratorii de sistem, asistenţa tehnică,
personalul de la vânzări, etc.), acesta metoda oferind dovezi şi o documentare exacta a identificării ariei
de apariţie a problemei şi verificarea acesteia.
O abordare standard a unei probleme de performanţă are doua strategii. Prima, ar fi plasarea problemei
în grija unui expert în tuning/optimizare ce are cunostinţe solide despre utilitarele pentru optimizare
Oracle, iar a doua ar fi suplimentarea resurselor hardware.
Totuşi, nici una dintre aceste două strategii nu este o soluţie pe termen lung, deoarece ele se adresează
simptomelor şi nu cauzelor ce au generat aceste probleme.
Problemele de performanţă pot fi localizate şi identificate relativ usor. Valoarea metodei descrise în
aceasta lucrare este data de faptul că în timp ce este nevoie de un expert într-o anumită tehnologie
pentru rezolvarea problemei, nu trebuie sa fii un expert pentru a identifica o problemă. Obiectivul este de
a orienta scopul investigaţiei spre proceduri cat mai rapide şi eficiente, şi identificarea timpurie a
resurselor necesare pentru rezolvarea problemei (personal: expertul în probleme ale sistemului de
operare, expertul în optimizare SQL, servere de test, timp înafara producţiei pentru testarea soluţiilor
finale, etc.).
Deşi optimizarea unui sistem este o stiinţă, multe din aspectele acestei activităţi ţin de bunul simţ.
Concluzia finală este că o problema definită precis şi complet este cheia identificării problemelor de
performanţă şi va ajuta orientarea eforturilor de optimizare spre atingerea rezultatelor dorite. Cele mai
bune rezultate se obţin prin optimizarea iniţiala a clientului, apoi a bazei de date şi a serverului, în acesta
ordine. Prelucrşrile pe loturi şi rapoartele ar trebui reprogramate pentru minimizarea efectului asupra
utilizatorilon on-line înaintea optimizării interogărilor şi a cailor de acces la date.
Pe parcursul operaţiei de optimizare se vor efectua modificări şi se vor măsura efectele. Când întregul
sistem este optimizat, se vor seta din nou valorile de referinţă (benchmark). Dacă rezultatele dorite încă
nu au fost atinse, se vor re-evalua complet înainte de a propune adăugarea de resurse fizice
sulplimentare. Intotdeauna trebuie să investigăm toate ariile sistemului, adăugarea de resurse
sumplimentare fiind ultima soluţie.
138
Anexa 1
show_blocking_sessions.sql – arata utilizatorii ce aşteaptă o rezervare (lock), agentul de blocare şi
comanda SQL aşteptată, schema şi PID-urile.81
rem -------------------------------------------------------------------------
rem Show users waiting for a lock, the locker and the
rem SQL-Command they are waiting for a lock
rem osuser, schema and PIDs are shown
rem -----------------------------------------------------------------------
rem
--
SET PAGES 24 LINES 100 FEED ON ECHO OFF TERMOUT ON HEAD ON
COLUMN OS_LOCKER FORMAT A15 TRUNC
COLUMN OS_WAITER FORMAT A15 TRUNC
COLUMN LOCKER_SCHEMA FORMAT A15 TRUNC
COLUMN WAITER_SCHEMA FORMAT A15 TRUNC
COLUMN WAITER_PID FORMAT A10
COLUMN LOCKER_PID FORMAT A10
COLUMN SQL_TEXT_WAITER FORMAT A100 WRAP
COLUMN DATABASE NOPRINT NEW_VALUE DATABASE
COLUMN DATUM_ZEIT NOPRINT NEW_VALUE DATUM_ZEIT
SET TERMOUT OFF ECHO OFF FEED OFF
SET TERMOUT ON
TTITLE CENTER 'Current Lock-Waits' SKIP 2
--
select /*+ ordered
no_merge(L_WAITER)
no_merge(L_LOCKER) use_hash(L_LOCKER)
no_merge(S_WAITER) use_hash(S_WAITER)
no_merge(S_LOCKER) use_hash(S_LOCKER)
use_nl(O)
use_nl(U)
*/
/* first the table-level locks (TM) and mixed TM/TX TX/TM */
S_LOCKER.OSUSER OS_LOCKER,
S_LOCKER.USERNAME LOCKER_SCHEMĂ,
S_LOCKER.PROCESS LOCKER_PID,
S_WAITER.OSUSER OS_WAITER,
S_WAITER.USERNAME WAITER_SCHEMĂ,
81
http://www.akadia.com/download/documents/show_blocking_sessions.sql , accesat la data 25.01.2010
139
S_WAITER.PROCESS WAITER_PID,
'Table lock (TM): '||U.NAME||'.'||O.NAME||
' - Mode held: '||
decode(L_LOCKER.LMODE,
0, 'None', /* same aş Monitor */
1, 'Null', /* N */
2, 'Row-S (SS)', /* L */
3, 'Row-X (SX)', /* R */
4, 'Share', /* S */
5, 'S/Row-X (SSX)', /* C */
6, 'Exclusive', /* X */
'???: '||to_char(L_LOCKER.LMODE))||
' / Mode requested: '||
decode(L_WAITER.REQUEST,
0, 'None', /* same aş Monitor */
1, 'Null', /* N */
2, 'Row-S (SS)', /* L */
3, 'Row-X (SX)', /* R */
4, 'Share', /* S */
5, 'S/Row-X (SSX)', /* C */
6, 'Exclusive', /* X */
'???: '||to_char(L_WAITER.REQUEST))
SQL_TEXT_WAITER
from
V$LOCK L_WAITER,
V$LOCK L_LOCKER,
V$SESSION S_WAITER,
V$SESSION S_LOCKER,
OBJ$ O,
USER$ U
where S_WAITER.SID = L_WAITER.SID
and L_WAITER.TYPE ÎN ('TM')
and S_LOCKER.sid = L_LOCKER.sid
and L_LOCKER.ID1 = L_WAITER.ID1
and L_WAITER.REQUEST > 0
and L_LOCKER.LMODE > 0
and L_WAITER.ADDR != L_LOCKER.ADDR
and L_WAITER.ID1 = O.OBJ#
and U.USER# = O.OWNER#
union
select /*+ ordered
no_merge(L_WAITER)
140
no_merge(L_LOCKER) use_hash(L_LOCKER)
no_merge(S_WAITER) use_hash(S_WAITER)
no_merge(S_LOCKER) use_hash(S_LOCKER)
no_merge(L1_WAITER) use_hash(L1_WAITER)
no_merge(O) use_hash(O)
*/
/* now the (usual) row-locks TX */
S_LOCKER.OSUSER OS_LOCKER,
S_LOCKER.USERNAME LOCKER_SCHEMĂ,
S_LOCKER.PROCESS LOCK_PID,
S_WAITER.OSUSER OS_WAITER,
S_WAITER.USERNAME WAITER_SCHEMĂ,
S_WAITER.PROCESS WAITER_PID,
'TX: '||O.SQL_TEXT SQL_TEXT_WAITER
from
V$LOCK L_WAITER,
V$LOCK L_LOCKER,
V$SESSION S_WAITER,
V$SESSION S_LOCKER,
V$_LOCK1 L1_WAITER,
V$OPEN_CURSOR O
where S_WAITER.SID = L_WAITER.SID
and L_WAITER.TYPE ÎN ('TX')
and S_LOCKER.sid = L_LOCKER.sid
and L_LOCKER.ID1 = L_WAITER.ID1
and L_WAITER.REQUEST > 0
and L_LOCKER.LMODE > 0
and L_WAITER.ADDR != L_LOCKER.ADDR
and L1_WAITER.LADDR = L_WAITER.ADDR
and L1_WAITER.KADDR = L_WAITER.KADDR
and L1_WAITER.SADDR = O.SADDR
and O.HASH_VALUE = S_WAITER.SQL_HASH_VALUE
/
TTITLE OFF
COLUMN OS_LOCKER CLEAR
COLUMN OS_WAITER CLEAR
COLUMN LOCKER_SCHEMA CLEAR
COLUMN WAITER_SCHEMA CLEAR
COLUMN WAITER_PID CLEAR
COLUMN LOCKER_PID CLEAR
COLUMN SQL_TEXT_WAITER CLEAR
COLUMN DATABASE CLEAR
141
COLUMN DATUM_ZEIT CLEAR
142
Anexa 2
Utllockt.sql82
rem
rem $Header: utllockt.sql 21-jan-2003.16:21:56 bnnguyen Exp $ locktree.sql
rem
Rem Copyright (c) 1989, 2003, Oracle Corporation. All rights reserved.
Rem NAME
REM UTLLOCKT.SQL
Rem FUNCTION - Prinţ out the lock wait-for graph în tree structured fashion.
Rem This is useful for diagnosing systems that are hung on locks.
Rem NOTES
Rem MODIFIED
Rem bnnguyen 01/21/03 - bug2166717
Rem pgreenwa 04/27/95 - fix column definitions for LOCK_HOLDERS
Rem pgreenwa 04/26/95 - modify lock_holders query to use new dba_locks f
Rem glumpkin 10/20/92 - Renamed from LOCKTREE.SQL
Rem jloaiza 05/24/91 - update for v7
Rem rlim 04/29/91 - change char to varchar2
Rem Loaiza 11/01/89 - Creation
Rem
82
http://www.akadia.com/services/scripts/utllockt.txt , accesat la data 25.01.2010
143
* 9 TX Share (S) Exclusive (X) 65547 16
* 7 RW Exclusive (X) S/Row-X (SSX) 33554440 2
* 10 RW Exclusive (X) S/Row-X (SSX) 33554440 2
*
* The lock information to the right of the session id describes the lock
* that the session is waiting for (not the lock it is holding).
*
* Note that this is a script and not a set of view definitions because
* connect-by is used în the implementation and therefore a temporary table
* is created and dropped since you cannot do a join în a connect-by.
*
* This script has two small disadvantages. One, a table is created when
* this script is run. To create a table a number of locks must be
* acquired. This might cause the session running the script to get caught
* în the lock problem it is trying to diagnose. Two, if a session waits on
* a lock held by more than one session (share lock) then the wait-for graph
* is no longer a tree and the conenct-by will show the session (and any
* sessions waiting on it) several times.
*/
/* Select all sids waiting for a lock, the lock they are waiting on, and the
* sid of the session that holds the lock.
* UNION
* The sids of all session holding locks that someone is waiting on that
* are not themselves waiting for locks. These are included so that the roots
* of the wait for graph (the sessions holding things up) will be displayed.
*/
drop table lock_holders;
144
create table dba_locks_temp aş select * from dba_locks;
/* This is essentially a copy of the dba_waiters view but runs faster since
* it caches the result of selecting from dba_locks.
*/
insert into lock_holders
select w.session_id,
h.session_id,
w.lock_type,
h.mode_held,
w.mode_requested,
w.lock_id1,
w.lock_id2
from dba_locks_temp w, dba_locks_temp h
where h.blocking_others = 'Blocking'
and h.mode_held != 'None'
and h.mode_held != 'Null'
and w.mode_requested != 'None'
and w.lock_type = h.lock_type
and w.lock_id1 = h.lock_id1
and w.lock_id2 = h.lock_id2;
commit;
145
mode_requested,
mode_held,
lock_id1,
lock_id2
from lock_holders
connect by prior waiting_session = holding_session
start with holding_session is null;
146
Anexa 3
show_dml_locks.sql83
rem -------------------------------------------------------------------------
rem Shows actual DML-Locks (incl. Table-Name)
rem WAIT = YES are users waiting for a lock
rem -----------------------------------------------------------------------
rem
--
SET PAGES 24 LINES 80 FEED ON ECHO OFF TERMOUT ON HEAD ON
COLUMN PROGRAM FORMAT A80 TRUNC
COLUMN LOCKER FORMAT A10 TRUNC
COLUMN T_OWNER FORMAT A10 TRUNC
COLUMN OBJECT_NAME FORMAT A25 TRUNC
COLUMN WAIT FORMAT A4
TTITLE "Actual DML-Locks (TM+TX)"
--
select /*+ rule */
decode(L.REQUEST,0,'NO','YES') WAIT,
S.OSUSER,
S.PROCESS,
S.USERNAME LOCKER,
U.NAME T_OWNER,
O.NAME OBJECT_NAME,
' '||S.PROGRAM PROGRAM
from V$LOCK L,
V$SESSION S,
OBJ$ O,
USER$ U
where U.USER# = O.OWNER#
and S.SID = L.SID
and L.ID1 = O.OBJ#
and L.TYPE = 'TM'
union
select decode(L.REQUEST,0,'NO','YES') WAIT,
S.OSUSER,
S.PROCESS,
S.USERNAME LOCKER,
'-',
83
http://www.akadia.com/download/documents/show_dml_locks.sql , accesat la data 25.01.2010
147
'Record(s)',
' '||S.PROGRAM PROGRAM
from V$LOCK L,
V$SESSION S
where S.SID = L.SID
and L.TYPE = 'TX'
order by 7,5,1,2,6
/
ttitle off
col program clear
col locker clear
col t_owner clear
col object_name clear
col wait clear
148
Anexa 4
Show_missing_fk_index.sql84
rem -------------------------------------------------------------------------
rem Shows actual DML-Locks (incl. Table-Name)
rem WAIT = YES are users waiting for a lock
rem -----------------------------------------------------------------------
rem
--
SET PAGES 24 LINES 80 FEED ON ECHO OFF TERMOUT ON HEAD ON
COLUMN PROGRAM FORMAT A80 TRUNC
COLUMN LOCKER FORMAT A10 TRUNC
COLUMN T_OWNER FORMAT A10 TRUNC
COLUMN OBJECT_NAME FORMAT A25 TRUNC
COLUMN WAIT FORMAT A4
TTITLE "Actual DML-Locks (TM+TX)"
--
select /*+ rule */
decode(L.REQUEST,0,'NO','YES') WAIT,
S.OSUSER,
S.PROCESS,
S.USERNAME LOCKER,
U.NAME T_OWNER,
O.NAME OBJECT_NAME,
' '||S.PROGRAM PROGRAM
from V$LOCK L,
V$SESSION S,
OBJ$ O,
USER$ U
where U.USER# = O.OWNER#
and S.SID = L.SID
and L.ID1 = O.OBJ#
and L.TYPE = 'TM'
union
select decode(L.REQUEST,0,'NO','YES') WAIT,
S.OSUSER,
S.PROCESS,
S.USERNAME LOCKER,
84
http://www.akadia.com/download/documents/show_dml_locks.sql , accesat la data 25.01.2010
149
'-',
'Record(s)',
' '||S.PROGRAM PROGRAM
from V$LOCK L,
V$SESSION S
where S.SID = L.SID
and L.TYPE = 'TX'
order by 7,5,1,2,6
/
ttitle off
col program clear
col locker clear
col t_owner clear
col object_name clear
col wait clear
150
Anexa 5
bhla.sql85
----------------------------------------------------------------------------------------------------------
--
-- File name: bhla.sql (Buffer Headers by Latch Address)
-- Purpose: Report which blocks are în buffer cache, protected by a cache
-- buffers chains child latch
--
-- Author: Tanel Poder
-- Copyright: (c) http://www.tanelpoder.com
--
-- Usage: @bhla <child latch address>
-- @bhla 27E5A780
--
--
-- Other: This script reports all buffers "under" the given cache buffers
-- chains child latch, their corresponding segment names and
-- touch counts (TCH).
--
-------------------------------------------------------------------------------------------------------
85
http://www.tanelpoder.com/files/scripts/bhla.sql , accesat la data 25.01.2010
151
where
bh.obj = o.data_object_id
and hladdr = hextoraw(lpad('&1', vsize(hladdr)*2 , '0'))
order by
tch asc
/
152
Bibliografie
153
24. https://support.oracle.com/CSP/main/article?cmd=show&id=175006.1&type=NOT , accesat la
data 25.01.2010
25. https://support.oracle.com/CSP/main/article?cmd=show&id=396009.1&type=NOT , accesat la
data 25.01.2010 Oracle® Database Performance Tuning Guide 10g Release 2 (10.2), Chapert 11
– SQL Tuning Overview,
26. Initialization Parameters, http://www.adp-gmbh.ch/ora/misc/init_params.html , accesat la data
25.01.2010
27. Interpreting HANGANALYZE trace files to diagnose hanging and performance problems [ID
215858.1], https://support.oracle.com/CSP/main/article?cmd=show&id=215858.1&type=NOT ,
accesat la data 25.01.2010
28. LTOM - The On-Board Monitor User Guide [ID 352363.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=352363.1&type=NOT , accesat la
data 25.01.2010
29. LTOM - The On-Board Monitor User Guide [ID 352363.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=352363.1&type=NOT , accesat la
data 25.01.2010
30. LTOM - The On-Board Monitor User Guide [ID 352363.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=352363.1&type=NOT , accesat la
data 25.01.2010
31. Methods for Obtaining a Formatted Explain Plan [ID 235530.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=235530.1&type=NOT
32. Oracle Database 10g Automated SGA Memory Tuning [ID 257643.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=257643.1&type=NOT, accesat la
data 25.01.2010
33. Oracle® Database 2 Day DBA 10g Release 2 (10.2) - Using the SQL Tuning Advisor,
http://download.oracle.com/docs/cd/B19306_01/server.102/b14196/montune003.htm#sthref784 ,
accesat la data 25.01.2010
34. Oracle® Database 2 Day DBA 10g Release 2 (10.2) - Using the SQL Tuning Advisor,
http://download.oracle.com/docs/cd/B19306_01/server.102/b14196/montune003.htm#sthref784 ,
accesat la data 25.01.2010
35. Oracle® Database Performance Tuning Guide - 10g Release 2 (10.2), Chapter 12 Automatic
SQL Tuning,
http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/sql_tune.htm#PFGRF028 ,
accesat la data 25.01.2010
36. Oracle® Database Performance Tuning Guide - 10g Release 2 (10.2), Chapter 12 Automatic
SQL Tuning,
http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/sql_tune.htm#PFGRF028 ,
accesat la data 25.01.2010
37. Oracle® Database Performance Tuning Guide - 10g Release 2 (10.2), Chapter 12.2.4 Using SQL
Tuning Advisor APIs, http://download-
west.oracle.com/docs/cd/B19306_01/server.102/b14211/sql_tune.htm#i34827 , accesat la data
25.01.2010
38. Oracle® Database Performance Tuning Guide - 10g Release 2 (10.2), Chapter 8 – Memory
Architecture, http://download-
west.oracle.com/docs/cd/B19306_01/server.102/b14220/memory.htm , accesat la data
25.01.2010
39. Oracle® Database Performance Tuning Guide - 10g Release 2 (10.2), Chapter 8 – Memory
Architecture, Automatic Shared Memory Management, http://download-
west.oracle.com/docs/cd/B19306_01/server.102/b14220/memory.htm#CNCPT810 , accesat la
data 25.01.2010
40. Oracle® Database Performance Tuning Guide - 10g Release 2 (10.2), Chapter 8 – Memory
Architecture, Using Automatic Shared Memory Management, http://download-
west.oracle.com/docs/cd/B19306_01/server.102/b14231/create.htm#BABGCBHI , accesat la
data 25.01.2010
41. Oracle® Database Performance Tuning Guide - 10g Release 2 (10.2), Chapter 7 – Memory
Confiiguration and Use, 7.3 – Configuring and Using the Shared Pool and Large Pool,
http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14211/memory.htm#i30970 ,
accesat la data 25.01.2010
42. Oracle® Database Performance Tuning Guide 10g Release 1 (10.1),
http://download.oracle.com/docs/cd/B14117_01/server.101/b10752/sqltrace.htm#8723 , accesat
la data 24.01.2010
43. Oracle® Database Performance Tuning Guide 10g Release 1 (10.1), Using the SQL Trace
Facility and TKPROF,
154
http://download.oracle.com/docs/cd/B14117_01/server.101/b10752/sqltrace.htm#8723 , accesat
la data 24.01.2010
44. Oracle® Database Performance Tuning Guide 10g Release 2 (10.2) – Chapter 12 Automatic
SQL Tuning
http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/sql_tune.htm#PFGRF028,
accesat la data 25.01.2010
45. Oracle® Database Performance Tuning Guide 10g Release 2 (10.2) – Chapter 12 Automatic
SQL Tuning,
http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/sql_tune.htm#PFGRF028 ,
accesat la data 25.01.2010
46. Oracle® Database Performance Tuning Guide 10g Release 2 (10.2) – Chapter 16 – Using
Optimizer Hintes, 16.1.2.1 Hints for Optimization Approaches and Gols, http://download-
west.oracle.com/docs/cd/B19306_01/server.102/b14211/hintsref.htm#CHDFIAJD , accesat la
data 25.01.2010
47. Oracle® Database Performance Tuning Guide 10g Release 2 (10.2) – Chapter 16 – Using
Optimizer Hintes, 16.1.2.2 Hints for Access Paths, http://download-
west.oracle.com/docs/cd/B19306_01/server.102/b14211/hintsref.htm#CHDJDIAH , accesat la
data 25.01.2010
48. Oracle® Database Performance Tuning Guide 10g Release 2 (10.2), http://download-
west.oracle.com/docs/cd/B19306_01/server.102/b14211/perf_overview.htm#i1006218, accesat la
data 23.01.2010
49. Oracle® Database Performance Tuning Guide 10g, Release 2 (10.2) – Chapter 16 Using
Optimizer Hints http://download-
west.oracle.com/docs/cd/B19306_01/server.102/b14211/hintsref.htm#sthref1602 , accesat la
data 25.01.2010
Oracle® Database Performance Tuning Guide 10g, Release 2 (10.2) – Chapter 18 Using Plan Stability,
50. http://download-
west.oracle.com/docs/cd/B19306_01/server.102/b14211/outlines.htm#sthref1787 , accesat la
data 25.01.2010
51. Oracle® Database Performance Tuning Guide 10g, Release 2 (10.2) – Chapter 16 Using
Optimizer Hints, http://download-
west.oracle.com/docs/cd/B19306_01/server.102/b14211/hintsref.htm#sthref1602 , accesat la
data 25.01.2010
52. Oracle® Database Performance Tuning Guide 10g, Release 2 (10.2) – Chapter 18 Using Plan
Stability, http://download-
west.oracle.com/docs/cd/B19306_01/server.102/b14211/outlines.htm#sthref1787 , accesat la
data 25.01.2010
53. Oracle® Database Performance Tuning Guide, 10g Release 2 (10.2) – Chapter 12 – Automatic
SQL tuning, http://download-
west.oracle.com/docs/cd/B19306_01/server.102/b14211/sql_tune.htm#i22019
54. Oracle® Database PL/SQL Packages and Types Reference 10g Release 2 (10.2) – Chapter 101
DBMS_SQLTUNE,
http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_sqltun.htm#sthref7584 ,
accesat la data 25.01.2010
55. Oracle® Database PL/SQL Packages and Types Reference, 10g Release 2 (10.2) – Chapter 132
– DBMS_XPLAIN – Summary of DBMS_XPLAIN Subprorams http://download-
west.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_xplan.htm#i996786 , accesat la data
25.01.2010
56. Oracle® Database Reference 10g Release 2 (10.2), Initialization Parameter Description, pagina
97, http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14237.pdf
57. Oracle® Enterprise Manager Concepts 10g Release 5 (10.2.0.5), http://download-
west.oracle.com/docs/cd/B19306_01/em.102/b31949/host_3rdparty_management.htm#sthref153
0 , accesat la data 25.01.2010
58. Oracle® Enterprise Manager Concepts 10g Release 5 (10.2.0.5), http://download-
west.oracle.com/docs/cd/B19306_01/em.102/b31949/host_3rdparty_management.htm#sthref153
0 , accesat la data 25.01.2010
59. OS Watcher User Guide [ID 301137.1], https://support.oracle.com/CSP/main/article?
cmd=show&id=301137.1&type=NOT, accesat la data 25.01.2010
60. OS Watcher User Guide [ID 301137.1], https://support.oracle.com/CSP/main/article?
cmd=show&id=301137.1&type=NOT, accesat la data 25.01.2010
61. QREF: SQL Statement HINTS [ID 29236.1], https://support.oracle.com/CSP/main/article?
cmd=show&id=29236.1&type=NOT , accesat la data 25.01.2010
62. QREF: SQL Statement HINTS [ID 29236.1], https://support.oracle.com/CSP/main/article?
cmd=show&id=29236.1&type=NOT , accesat la data 25.01.2010
155
63. Recommendations for Gathering Optimizer Statistics on 10g [ID 605439.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=605439.1&type=NOT , accesat la
data 25.01.2010
64. Recommendations for Gathering Optimizer Statistics on 10g [ID 605439.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=605439.1&type=NOT , accesat la
data 25.01.2010
65. Recommended Method for Obtaining 10046 trace for Tuning [ID 376442.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=376442.1&type=NOT , accesat la
data 24.01.2010
66. Recommended Method for Obtaining 10046 trace for Tuning [ID 376442.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=376442.1&type=NOT , accesat la
data 25.01.2010
67. Remote Diagnostic Agent (RDA) 4 - Main Man Page [ID 330364.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=330364.1&type=NOT , accesat la
data 25.01.2010
68. Resolving locking issues using utllockt.sql script [ID 166534.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=166534.1&type=NOT , accesat la
data 25.01.2010
69. Shared pool sizing in 10g [ID 270935.1], https://support.oracle.com/CSP/main/article?
cmd=show&id=270935.1&type=NOT , accesat la data 25.01.2010
70. SQLT (SQLTXPLAIN) - Tool that helps to diagnose SQL statements performing poorly [ID
215187.1], https://support.oracle.com/CSP/main/article?cmd=show&id=215187.1&type=NOT
71. Statistics Gathering: Frequency and Strategy Guidelines [ID 44961.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=44961.1&type=NOT , accesat la data
25.01.2010
72. Statistics Gathering: Frequency and Strategy Guidelines [ID 44961.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=44961.1&type=NOT , accesat la data
25.01.2010
73. Steps to generate HANGANALYZE trace files [ID 175006.1],
74. Stored Outline Quick Reference [ID 67536.1], https://support.oracle.com/CSP/main/article?
cmd=show&id=67536.1&type=NOT , accesat la data 25.01.2010
75. Stored Outline Quick Reference [ID 67536.1], https://support.oracle.com/CSP/main/article?
cmd=show&id=67536.1&type=NOT , accesat la data 25.01.2010
76. THE COE PERFORMANCE METHOD [ID 190124.1] , Roger Snowden
https://support.oracle.com/CSP/main/article?cmd=show&id=190124.1&type=NOT, accesat la
data 23.01.2010
77. Understanding and Tuning the Shared Pool [ID 62143.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=62143.1&type=NOT , accesat la data
25.01.2010
78. Using Statspack to Record Explain Plan Details [ID 209197.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=209197.1&type=NOT
79. VIEW: "V$LOCK" Reference Note [ID 29787.1], https://support.oracle.com/CSP/main/article?
cmd=show&type=NOT&id=29787.1
80. WAITEVENT: "enqueue" Reference Note (Doc ID 34566.1),
https://support.oracle.com/CSP/main/article?cmd=show&type=NOT&id=34566.1 , accesat la data
25.01.2010
81. What is the Oracle Diagnostic Methodology (ODM)? [ID 553866.1]
https://support.oracle.com/CSP/main/article?cmd=show&id=553866.1&type=NOT, accesat la
data 23.01.2010
82. Why didn't my parallel query use the expected number of slaves? [ID 199272.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=199272.1&type=NOT , accesat la
data 25.01.2010
83. Yet Another Performance Profiling Method (Or YAPP-Method) [ID 148518.1],
https://support.oracle.com/CSP/main/article?cmd=show&id=148518.1&type=NOT, accesat la
data 25.01.2010
156