pentru mulți oameni care lucrează cu Oracle database, SCN (System Change Number) este un subiect care îi interesează foarte mult – dar, în ciuda faptului că este un subiect fascinant, este și confuz. În acest articol vom învăța nitty-gritty de SCN: ce este, unde este folosit și cum funcționează.
merită menționat faptul că aceasta nu este și nu poate fi o acoperire completă a fiecărui detaliu despre SCN. Acestea fiind spuse, să începem.
SCN – de ce avem nevoie de ea?
să presupunem că este sfârșitul lunii și ziua de plată. Sunteți în grupul de salarizare și, cu autoritatea corespunzătoare, ați emis o interogare pentru a trage calculul salariului actual al tuturor angajaților. Numerele curg pe ecran, totul merge grozav.
să presupunem că, în timp ce vă uitați la ieșire, un coleg începe o nouă rulare de plată și că lucrarea de lot șterge rezumatul de calcul curent. Lucrurile ar deveni cu siguranță confuze dacă rezultatul dvs. a arătat brusc ‘0’ pentru noile rânduri care ies.
într – adevăr, pentru acest scenariu, probabil că v – ați aștepta ca rezultatul să reflecte ‘starea bazei de date’ – conținutul fiecărui rând-modul în care a existat în momentul emiterii interogării.
una dintre garanțiile bazei de date Oracle este că „nu există citiri murdare ale datelor Utilizatorului”. Dacă este necesar, Oracle va reconstrui fiecare rând la starea stabilă în momentul în care interogarea a fost emisă.
Oracle o face frumos și foarte precis printr-un „cronometru” propriu, cunoscut sub numele de numărul de schimbare a sistemului, numit SCN.
vom discuta aceste aspecte ale SCN:
- numărul în sine
- generatorul de numere
- locurile în care este stocat numărul
deci, să începem!
blocuri de construcție pentru înțelegerea SCN
pentru a investiga SCN, trebuie înțeleși mai mulți termeni. Deși aceste definiții sunt bine documentate, merită să le repetăm aici:
tranzacție
din Ghidul de concepte al documentației online Oracle:
„o tranzacție este o unitate logică, atomică de lucru care conține una sau mai multe instrucțiuni SQL. O tranzacție grupează instrucțiunile SQL astfel încât să fie toate angajate, ceea ce înseamnă că sunt aplicate bazei de date sau toate derulate înapoi, ceea ce înseamnă că sunt anulate din Baza de date. Oracle Database atribuie fiecărei tranzacții un identificator unic numit ID de tranzacție”.
mai simplu: când începem o tranzacție, inițiem un set de modificări. Acestea trebuie fie completate în totalitate, fie nu trebuie completate deloc. Pe măsură ce tranzacțiile apar în baza de date, Utilizatorii care citesc orice zonă care s-a schimbat nu trebuie să fie afectați de efecte secundare care le pot modifica rezultatele.
pentru ca tranzacțiile să funcționeze corect în orice bază de date, Baza de date trebuie să respecte patru reguli acide. Acestea sunt:
- Atomicitate;
- consistență;
- izolare;
- durabilitate.
deci, unde se potrivește SCN în toate acestea? Și răspunsul la această întrebare este că utilizarea SCN numai Oracle menține coerența datelor. Acest lucru se face pentru a se asigura că orice moment de timp, nu există nici o discrepanță în rezultatele care sunt arătate celorlalți atunci când un utilizator se schimbă ceva, și vice-versa.
pentru a rezuma, în Oracle, principiul „cititorii nu așteaptă scriitorii și scriitorii nu au nevoie de cititori” este urmat complet și cu adevărat. Pentru a face acest lucru, este extrem de important ca datele, care suferă în prezent orice fel de modificare, să nu fie disponibile nimănui, cu excepția persoanei care face aceste modificări. Pentru tranzacții, acest lucru este necesar pentru a menține integritatea datelor. Pot apărea trei lucruri care pot perturba această integritate – citire murdară, citire Fuzzy și citire fantomă. Pentru a ne asigura că nu vor exista probleme de integritate în aceste tranzacții, sunt disponibile diferite niveluri de izolare. Acestea sunt:
- Read Uncomitted
- read Committed
- read Repetable
- Serializable
Transaction Isolation levels
dintre acestea, Oracle oferă read Committed ca nivel de izolare implicit, asigurându-se că nu există posibilitatea ca un utilizator să vadă modificările făcute de un alt utilizator care nu sunt încă angajate. Nu trebuie să se citească acele date care sunt marcate ca” murdare ” și trebuie să existe un mecanism suficient de robust pentru a face toate acestea posibile.
pentru a face acest lucru posibil, SCN joacă un rol vital.
SCN, o introducere
Numărul de comitere a sistemului poate fi înțeles ca reprezentarea timpului de către Oracle. Oracle utilizează SCN pentru controlul consistenței, pentru efectuarea recuperării și pentru a ordona vectorii de schimbare în refacere.
SCN se găsește în multe locații – atât în memorie, cât și pe disc. Diferite locații sunt utilizate pentru a ajuta sistemul de baze de date să identifice diferite stări ale bazei de date. De exemplu, în unele locații este utilizat pentru a indica starea de finalizare a tranzacției și dacă este activă sau angajată.
contrar credinței populare, nu se generează doar în momentul comiterii, deși asta sugerează numele în sine. SCN este acolo tot timpul în baza de date, reprezentând o porțiune de timp pentru operațiunea care se întâmplă în acel moment de timp. Nu este complet inexact să spunem că SCN nu este generat cu o comitere, dar nu este singurul mod în care SCN este generat.
SCN este un număr din două părți care este generat la cerere, ca răspuns la un eveniment. Este oarecum ca data și ora derivate dintr – o combinație de calendar și ceas; ceasul se schimbă rapid și numai atunci când a trecut prin ciclul complet de 24 de ore este preaplinul – calendarul-schimbat. Cu toate acestea, evenimentul care schimbă ceasul este ‘pendulul’ și este regulat, în timp ce evenimentul care schimbă SCN este un apel către o funcție internă specifică.
Similar cu un calendar/ceas timestamp, valoarea poate fi înregistrată într-o varietate de locuri diferite, fiecare pentru o utilizare diferită.
un exemplu din lumea reală similar cu un SCN este un ceas de aeroport. Două persoane intră într-un aeroport în același timp și pot nota ora ceasului. Acel moment ne dă ‘o intrare SCN’ care se întâmplă să fie aceeași pentru ambele persoane. O persoană primește un cărucior pentru bagaje înainte de check-in, în timp ce cealaltă merge direct la ghișeul de check-in. Când locurile sunt alocate, fiecare persoană poate primi un alt’ Check-in SCN’, deoarece orele sunt ușor diferite. Un ‘ SCN de îmbarcare ‘poate fi atribuit pentru a indica momentul în care fiecare s-a îmbarcat, dar ambele primesc același’SCN de decolare’.
ca și combinația de calendar și ceas, SCN este garantat să crească în timpul funcționării normale. Nu există nicio garanție că numărul va fi secvențial (numere lipsă).
deci, unde sunt utilizate aceste informații despre SCN în baza de date Oracle? Ei bine, aproape peste tot. La fel cum asociem timpul cu fiecare activitate a noastră, SCN este, de asemenea, asociat cu fiecare parte a funcționalității bazei de date. De exemplu, atunci când încercați să selectați date dintr-un tabel, SCN este utilizat pentru a confirma dacă aceste date sunt consecvente sau nu. SCN se găsește și în anteturile tranzacțiilor blocului de date. Acest SCN ar reprezenta momentul în care tranzacția a început și când a fost comisă. În mod similar, pentru fiecare modificare efectuată, se menține o intrare în Jurnalul de refacere și pentru fiecare dintre aceste intrări, SCN este utilizat pentru a reprezenta momentul apariției tranzacției.
read consistence utilizează SCN pentru a decide cât timp trebuie să aplice Undo peste tamponul murdar, astfel încât cererea de date consistente citite pentru o sesiune să poată fi finalizată. Și, după cum se știe, SCN este incrementat cu fiecare operațiune de comitere.
formatul și structura SCN
SCN este un număr imens cu două componente: baza SCN & SCB Wrap.
SCN este un număr de 6 octeți (48 biți). Din acești 48 de biți, SCN_WRAP este un număr de 16 biți (2 octeți), iar SCN_BASE este un număr de 32 biți (4 octeți). Ambele bază & WRAP sunt folosite pentru a controla increment SCN și pentru a se asigura că baza de date nu va alerga afară de ea. SCN_WRAP este incrementat cu 1 când SCN_BASE atinge valoarea de 4 miliarde și SCN_BASE devine 0.
din versiunea Oracle 12c, numărul SCN este un număr de 8 octeți.
Deci, cum vedem valoarea SCN curentă? Cel mai simplu mod este de a interoga baza de date view v$. Arunca o privire:
1
2
3
4
5
|
SQL > selectați current_scn din baza de date v$;
CURRENT_SCN
———–
1123790
|
după cum putem vedea, acel SCN este afișat ca număr. Acest lucru este bun, deoarece face ca utilizarea SCN să fie ușoară pentru noi în declarațiile noastre care efectuează recuperare, flashback etc. Dacă dorim, putem converti SCN și la o valoare hexazecimală:
1
2
3
4
5
|
SQL > selectați to_char (‘1123790’, ‘xxxxxxxx’) scn_hex din dual;
SCN_HEX
———
1125ce
|
Iată un exemplu de ieșire din aceeași vizualizare accesată de câteva ori:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
SQL > selectați current_scn din baza de date v$;
CURENT_SCN
———–
1178883
SQL> /
CURENT_SCN
———–
1178885
SQL> /
CURENT_SCN
———–
1178886
|
interesant este că această creștere a valorii SCN arată un aspect important al SCN. Putem vedea că, cu fiecare execuție, există o creștere a numărului de SCN. Interogând baza de date view v$, provocăm de fapt saltul numărului SCN.
Smon_scn_time Table
cel mai simplu mod de a vedea ambele valori este dintr – un tabel intern deținut de SYS user-SMON_SCN_TIME. Următoarea este o ieșire din aceeași (11204).
1
2
3
4
5
6
|
SQL > selectați SCN_wrp, SCN_bas, SCN din smon_SCN_time unde rownum < 3;
SCN_WRP SCN_BAS SCN
———- ———- ———-
0 998222 998222
0 998406 998406
|
acest tabel conține intrările SCN-urilor generate. Stochează datele în trepte de aproximativ 5 minute și deține date în valoare de 5 zile. Aceasta înseamnă că tabelul conține aproximativ 1440 de înregistrări. Numărul exact de înregistrări va varia ușor, deoarece creșterea de stocare nu este exact 5 minute.
1
2
3
4
5
|
SQL > selectați count (*) din SMON_SCN_TIME;
COUNT(*)
———-
1494
|
în versiunile Oracle înainte de 10g, maparea timpului SCN cu timpul a fost de +/- 5 minute, dar de la 10g încoace, aceasta este schimbată în +/- 3 secunde. Deoarece acesta este stocat într-un tabel intern, Oracle nu permite accesul direct la informațiile din acest tabel. Pentru a-l accesa, sunt furnizate API-uri. Un astfel de API este din pachetul dbms_flashback.GET_SYSTEM_CHANGE_NUMBER, care poate fi folosit pentru a accesa numărul de ordine din acest tabel. Un exemplu în acest sens este prezentat mai jos (datorită lui Tom Kyte pentru interogare):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
SQL > l
selectați SCN_to_timestamp (SCN) ts, min(SCN), max (SCN)
din (
selectați dbms_flashback.get_system_change_number () – nivel SCN
de la dual
conectați la nivel <= 100
)
grup de SCN_to_timestamp (SCN)
* comanda de SCN_to_timestamp (SCN)
SQL> /
TS MIN (SCN) MAX (SCN)
————————————————————————— ———- ———-
06-Mai-16 05.22.04.000000000 PM 1245323 1245323
06-Mai-16 05.22.07.000000000 PM 1245324 1245324
06-Mai-16 05.22.10.000000000 PM 1245325 1245325
06-MAI-16 05.22.13.000000000 PM 1245326 1245326
06-MAI-16 05.22.16.000000000 PM 1245327 1245327
06-MAI-16 05.22.19.000000000 PM 1245328 1245328
06-MAI-16 05.22.22.000000000 PM 1245329 1245329
06-MAI-16 05.22.25.000000000 PM 1245330 1245330
06-MAI-16 05.22.28.000000000 PM 1245331 1245331
06-MAI-16 05.22.31.000000000 PM 1245332 1245332
06-MAI-16 05.22.34.000000000 PM 1245333 1245333
06-MAI-16 05.22.37.000000000 PM 1245334 1245334
06-Mai-16 05.22.40.000000000 PM 1245335 1245335
06-Mai-16 05.22.43.000000000 PM 1245336 1245336
06-Mai-16 05.22.46.000000000 PM 1245337 1245337
06-Mai-16 05.22.49.000000000 PM 1245338 1245338
06-Mai-16 05.22.52.000000000 PM 1245339 1245339
|
cum putem mapa SCN cu Timestamp în versiunile anterioare 10g?
este important să ne amintim că acest tabel nu arată de ce ar exista o creștere a ratei de creștere a numerelor SCN. Cu puțină formatare, este posibil să aveți o idee despre numerele SCN generate, dar sursa creșterii lor nu va fi evidentă din acest tabel.
o altă modalitate de a verifica acest lucru este din vizualizarea V$LOG_HISTORY. Vizualizarea conține SCN sub forma coloanelor FIRST_CHANGE # și NEXT_CHANGE# și putem vedea prin aceste două coloane cantitatea de SCN-uri generate în baza de date pe o perioadă de timp. „First_change# este cel mai mic SCN care apare în fișierul jurnal arhivat la un număr de secvență dat al acestui thread. „Next_change#” este cel mai mic SCN care apare în următorul fișier jurnal arhivat.
1
2
3
4
5
6
7
8
9
10
11
12
|
SQL > selectați thread#, first_change#, next_change# din v $ log_history;
THREAD # FIRST_CHANGE # NEXT_CHANGE#
———- ————- ————
1 925702 958823
1 958823 959634
1 959634 972579
1 972579 993714
1 993714 1020785
1 1020785 1023738
1 1023738 1023873
1 1023873 1023995
|
ca și în cazul SMON_SCN_TABLE, nu este posibil să găsiți sursa creșterii generării numerelor SCN din această vizualizare tabel. Totuși, puteți utiliza această vizualizare în instanță unică, precum și într-un mediu RAC.
SCN crește folosind o secvență?
până acum ar trebui să fie destul de evident că SCN pare a fi un număr care este în continuă creștere. Interesant este că, deși este un număr, Oracle nu folosește nicio secvență pentru a-l mări, ci folosește în schimb funcții interne. De exemplu, pentru a crește SCN_BASE, funcția utilizată intern este KCMGAS(Get and Advance SCN). Această funcție este apelată de fiecare dată când este solicitat un nou SCN și apelul pentru această funcție este mărit. În mod similar cu această funcție, KCMGCS (Get Current SCN) este utilizat pentru a obține SCN curent și apelul utilizat pentru acesta. Aceste apeluri de funcții pot fi văzute din vizualizarea v$sysstat. O descriere a acestor statistici poate fi găsită în ghidul de referință 12.1.
să vedem cum aceste apeluri se leagă de generația SCN. Folosim două sesiuni aici – una pentru a vedea apelurile în vizualizarea v$sysstat, iar cealaltă sesiune pentru a trage SCN.
1
2
3
4
5
6
7
8
9
10
|
sesiune -1
SQL> l
1 * Selectați current_SCN din baza de date v$
SQL> /
CURENT_SCN
———–
698815
SQL>
|
pentru acest SCN, acestea au fost valorile pentru v$sysstat:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
SQL> l
1 Selectați nume, valoare de la v$sysstat
2 * Unde nume ca ‘%apelează la%’
SQL> /
valoarea numelui
—————————————————————- ———-
apeluri către kcmgcs 427
apeluri către kcmgrs 0
apeluri către kcmgas 7272
apeluri pentru a obține instantaneu SCN: KCMGSS 159790
SQL>
|
să emitem o interogare pentru a vedea SCN curent în sesiunea 1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
SQL> l
1* select current_SCN from V$database
SQL> /
CURRENT_SCN
———–
698815
SQL> /
CURRENT_SCN
———–
698889
SQL>
|
And iată rezultatul celei de-a doua sesiuni 2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
SQL> /
valoarea numelui
—————————————————————- ———-
apeluri către kcmgcs 427
apeluri către kcmgrs 0
apeluri către kcmgas 7272
apeluri pentru a obține instantaneu SCN: kcmgss 159790
SQL> /
valoarea numelui
—————————————————————- ———-
apeluri către kcmgcs 427
apeluri către kcmgrs 0
apeluri către kcmgas 7278
apeluri pentru a obține instantaneu SCN: kcmgss 159905
SQL>
|
putem vedea că apelurile către KCMGA au crescut la 7278 de la ultima valoare, 7272. Deoarece Oracle nu utilizează o secvență pentru a crește numărul, nu există nicio garanție că numărul SCN va fi întotdeauna mărit în aceeași ordine.
concluzie
în acest articol, am analizat ce este SCN, cum să îl vizualizați și care sunt cerințele pentru acesta. În articolul următor, vom vedea ce tipuri diferite de SCN-uri sunt disponibile și cum sunt utilizate în baza de date. Stay tuned!