Redgate Hub

for mange mennesker, der arbejder med Oracle database, er SCN (System Change Number) et emne, der interesserer dem meget – men på trods af at det er et fascinerende emne, er det også forvirrende. I denne artikel lærer vi SCN ‘ s nitty-gritty: hvad det er, hvor det bruges, og hvordan det virker.

det er værd at nævne, at dette ikke er og ikke kan være fuldstændig dækning af alle detaljer om SCN. Med det sagt, lad os starte.

SCN – hvorfor har vi brug for det?

Antag, at det er slutningen af måneden og dens lønningsdag. Du er i Lønningsgruppen og har med passende myndighed udsendt en forespørgsel om at trække den aktuelle lønberegning for alle medarbejdere. Tal flyder over skærmen, alt går godt.

Antag, at mens du kigger på output, starter en kollega en ny lønkørsel, og det batchjob rydder den aktuelle beregningsoversigt. Ting ville helt sikkert blive forvirrende, hvis din output pludselig viste ‘0’ for de nye rækker, der kommer ud.

for dette scenarie ville du sandsynligvis forvente, at output afspejler ‘databasens tilstand’ – indholdet i hver række – den måde, den eksisterede på det øjeblik, du udstedte din forespørgsel.

en af garantierne for Oracle-databasen er, at “der ikke er nogen beskidte læsninger af brugerdata”. Om nødvendigt genopbygger Oracle hver række til stabil tilstand på det tidspunkt, hvor forespørgslen blev udstedt.

Oracle gør det pænt og meget præcist gennem en “timer” af sig selv, kendt som Systemændringsnummeret, AKA SCN.

vi vil diskutere disse aspekter af SCN:

  • selve nummeret
  • nummergeneratoren
  • steder, hvor nummeret er gemt

så lad os begynde!

byggesten til forståelse af SCN

for at undersøge SCN skal flere udtryk forstås. Selvom disse definitioner er veldokumenterede, er det værd at gentage dem her:

transaktion

fra Concepts guide of Oracle online Documentation:

“en transaktion er en logisk, atomisk arbejdsenhed, der indeholder en eller flere KVL-udsagn. En transaktion grupperer udsagn, så de enten er begået, hvilket betyder, at de anvendes på databasen, eller alle rulles tilbage, hvilket betyder, at de fortrydes fra databasen. Oracle Database tildeler hver transaktion en unik identifikator kaldet et transaktions-ID”.

mere enkelt: når vi starter en transaktion, starter vi et sæt ændringer. Disse skal enten udfyldes i sin helhed eller slet ikke udfyldes. Da transaktionerne forekommer i databasen, må brugerne, der læser ethvert område, der er ændret, ikke påvirkes af bivirkninger, der kan ændre deres resultater.

for at transaktionerne skal fungere korrekt i en database, skal fire syre regler følges af databasen. Disse er:

  • Atomicitet;
  • konsistens;
  • isolering;
  • holdbarhed.

så hvor passer SCN ind i alt dette? Og svaret på dette spørgsmål er, at brug af SCN kun Oracle opretholder datakonsistens. Dette gøres for at sikre, at ethvert tidspunkt, er der ingen uoverensstemmelse i de resultater, der vises til de andre, når en bruger ændrer noget, og omvendt.

for at opsummere, i Oracle, følges princippet om “læsere ikke venter på forfattere og forfattere ikke har brug for læsere” fuldstændigt og virkelig. For at gøre det er det yderst vigtigt, at dataene, som i øjeblikket gennemgår nogen form for ændring, ikke må være tilgængelige for nogen undtagen den person, der foretager disse ændringer. For transaktioner er dette nødvendigt for at opretholde dataens integritet. Tre ting kan forekomme, som kan forstyrre denne integritet – beskidt læsning, uklar læsning og Fantomlæsning. For at sikre, at der ikke vil være nogen form for integritetsproblemer i disse transaktioner, er forskellige niveauer af isolationer tilgængelige. Disse er:

  • Read Uncommitted
  • Read Committed
  • Repeatable Read
  • Serialisable

Transaktionsisolationsniveauer

fra disse tilbyder Oracle Read Committed som standardisolationsniveau, hvilket sikrer, at der ikke er nogen mulighed for, at en bruger ser ændringer foretaget af en anden bruger, som endnu ikke er forpligtet. Der må ikke læses over de data, der er markeret som “beskidte”, og der skal være en mekanisme, der er robust nok til at gøre alt dette muligt.

for at gøre dette muligt spiller SCN en afgørende rolle.

SCN, en introduktion

Systemforpligtelsesnummer kan forstås som Orakels repræsentation af tid. Oracle bruger SCN til at kontrollere konsistens, til at udføre opsving og til at bestille ændringsvektorerne i redo.

SCN findes mange steder – både i hukommelsen og på disken. Forskellige placeringer bruges til at hjælpe databasesystemet med at identificere forskellige tilstande i databasen. For eksempel bruges det nogle steder til at angive transaktionens færdiggørelsesstatus, og om den er aktiv eller engageret.

i modsætning til hvad man tror, genereres det ikke kun på tidspunktet for commit, selvom det er, hvad navnet selv antyder. SCN er der hele tiden i databasen, der repræsenterer en tidsdel for operationen, der sker på det øjeblik. Det er ikke helt unøjagtigt at sige, at SCN ikke bliver genereret med en forpligtelse, det gør det – men det er ikke den eneste måde, SCN genereres på.

SCN er et todelt nummer, der genereres efter anmodning som svar på en begivenhed. Det er lidt som dato og klokkeslæt afledt af en kalender – og urkombination; uret skifter hurtigt, og kun når det har gennemgået det komplette 24 timers cyklus ændres overløbet – kalenderen -. Begivenheden, der ændrer uret, er imidlertid ‘pendulet’ og er regelmæssigt, mens begivenheden, der ændrer SCN, er et opkald til en bestemt intern funktion.

svarende til en kalender/ur tidsstempel, kan værdien registreres i en række forskellige steder, hver til en anden brug.

et eksempel i den virkelige verden, der ligner et SCN, er et lufthavnsur. To personer kommer ind i en lufthavn på samme tid og bemærker muligvis uret. Det øjeblik giver os’ en post SCN’, som tilfældigvis er den samme for begge mennesker. En person får en vogn til bagage, før han tjekker ind, mens den anden fortsætter direkte til check-in tælleren. Når sæderne er tildelt, kan hver person få en anden ‘check-in SCN’, da tiderne er lidt forskellige. Et ‘ boarding SCN ‘kan tildeles for at angive, hvornår hver er gået ombord, men begge får det samme’take-off SCN’.

ligesom kombinationen af kalender og ur er SCN garanteret at stige under normal drift. Der er ingen garanti for, at nummeret vil være sekventielt (manglende tal).

så hvor bruges disse oplysninger om SCN i Oracle-databasen? Nå, næsten overalt. Ligesom vi forbinder tid med alle vores aktiviteter, er SCN også forbundet med alle dele af databasens funktionalitet. Når du f.eks. forsøger at vælge data fra en tabel, bruges SCN til at bekræfte, om disse data er konsistente eller ej. SCN findes også i datablokkens Transaktionsoverskrifter. Denne SCN ville repræsentere det tidspunkt, hvor transaktionen startede, og da den blev begået. Tilsvarende for hver udført ændring opretholdes en post i gentagelsesloggen, og for hver af disse poster bruges SCN til at repræsentere tidspunktet for transaktionens forekomst.

Læsekonsistens bruger SCN til at bestemme, hvor længe den skal anvende Fortryd over den beskidte buffer, så anmodningen om læsekonsistente data for en session kan afsluttes. Og som det er velkendt, øges SCN med hver commit-operation.

SCN Format og struktur

SCN er et stort antal med to komponenter til det: SCN Base & SCB indpakning.

SCN er et 6 byte (48 bit) nummer. Ud af disse 48 bits er SCN_PACK et 16 bit (2 Bytes) nummer, og SCN_BASE er et 32 bit (4 Bytes) nummer. Begge base & indpakning bruges til at kontrollere SCN ‘ s stigning og for at sikre, at databasen ikke løber tør for den. SCN_BASE øges med 1, når SCN_BASE når værdien på 4 milliarder, og SCN_BASE bliver 0.

fra Oracle Version 12C er SCN-nummeret et 8 byte-nummer.

så hvordan ser vi den aktuelle SCN-værdi? Den nemmeste måde er at forespørge Vis V$ – databasen. Tag et kig:

1
2
3
4
5

> vælg current_scn fra V$database;
CURRENT_SCN
———–
1123790

som vi kan se, at SCN vises som et tal. Dette er godt, fordi det gør brugen af SCN let for os i vores udsagn, der udfører gendannelse, flashback osv. Hvis vi vil, kan vi også konvertere SCN til en Seksadecimal værdi:

1
2
3
4
5

> vælg to_char (‘1123790′,’) scn_heks fra dual;
SCN_HEKS
———
1125ce

her er et eksempel på output fra den samme visning, der er adgang til et par gange:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

CURRENT_SCN
———–
1178883
KKL> /
CURRENT_SCN
———–
1178885
KKL> /
CURRENT_SCN
———–
1178886

interessant nok viser denne stigning i SCN-værdien et vigtigt aspekt af SCN. Vi kan se, at der med hver udførelse er en stigning i antallet af SCN. Ved at forespørge Vis V$ – databasen forårsager vi faktisk springet i SCN-nummeret.

SMON_SCN_TIME Table

den nemmeste måde at se begge disse værdier på er fra en intern tabel, der ejes af SYS – bruger-SMON_SCN_TIME. Følgende er et output fra det samme (11204).

1
2
3
4
5
6

> vælg SCN, SCN_bas, SCN fra smon_SCN_time hvor røn < 3;
SCN
———- ———- ———-
0 998222 998222
0 998406 998406

denne tabel indeholder posterne for de genererede SCNs. Den gemmer dataene i cirka 5 minutters intervaller og rummer 5 dages værdi af data. Dette betyder, at tabellen indeholder cirka 1440 poster. Det nøjagtige antal poster varierer lidt, da lagringsforøgelsen ikke er nøjagtigt 5 minutter.

1
2
3
4
5

antal(*)
———-
1494

i versioner af Oracle før 10g var tidskortlægningen af SCN med tiden + / – 5 minutter, men fra 10g og fremefter ændres dette til +/- 3 sekunder. Da dette er butikker i en intern tabel, tillader Oracle ikke adgang til oplysningerne fra denne tabel direkte. For at få adgang til det leveres API ‘ er. En sådan API er fra pakken DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER, som kan bruges til at få adgang til sekvensnummeret fra denne tabel. Et eksempel på dette er angivet nedenfor (tak til Tom Kyte for forespørgslen):

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

> l
vælg SCN_to_timestamp (SCN) ts, min (SCN), maks (SCN)
fra (
vælg dbms_flashback.get_system_change_number ()-niveau SCN
fra dual
Forbind efter niveau <= 100
)
gruppe efter SCN_to_timestamp (SCN)
* Bestil efter SCN_to_timestamp (SCN)
> /
TS MIN (SCN) maks (SCN)
————————————————————————— ———- ———-
06-maj-16 05.22.04.000000000 PM 1245323 1245323
06-maj-16 05.22.07.000000000 PM 1245324 1245324
06-maj-16 05.22.10.000000000 PM 1245325 1245325
06-MAJ-16 05.22.13.000000000 PM 1245326 1245326
06-MAJ-16 05.22.16.000000000 PM 1245327 1245327
06-MAJ-16 05.22.19.000000000 PM 1245328 1245328
06-MAJ-16 05.22.22.000000000 PM 1245329 1245329
06-MAJ-16 05.22.25.000000000 PM 1245330 1245330
06-MAJ-16 05.22.28.000000000 PM 1245331 1245331
06-MAJ-16 05.22.31.000000000 PM 1245332 1245332
06-MAJ-16 05.22.34.000000000 PM 1245333 1245333
06-MAJ-16 05.22.37.000000000 PM 1245334 1245334
06-maj-16 05.22.40.000000000 PM 1245335 1245335
06-maj-16 05.22.43.000000000 PM 1245336 1245336
06-maj-16 05.22.46.000000000 PM 1245337 1245337
06-maj-16 05.22.49.000000000 PM 1245338 1245338
06-maj-16 05.22.52.000000000 PM 1245339 1245339

Hvordan kan vi kortlægge SCN med tidsstempel i versioner før 10g?

det er vigtigt at huske, at denne tabel ikke viser, hvorfor der ville være nogen stigning i stigningen i SCN-tallene. Med lidt formatering er det muligt at få en ide om de genererede SCN-tal, men kilden til deres vækst vil ikke fremgå af denne tabel.

en anden måde at kontrollere dette på er fra visningen V$LOG_HISTORY. Visningen indeholder SCN i form af kolonnerne FIRST_CHANGE# og NÆSTE_CHANGE#, og vi kan gennem disse to kolonner se mængden af SCN ‘ er, der genereres i databasen over en periode. “First_change# er den laveste SCN, der vises i den arkiverede logfil ved et givet sekvensnummer i denne tråd. “Næste ændring#” er den laveste SCN, der vises i den næste arkiverede logfil.

1
2
3
4
5
6
7
8
9
10
11
12

> vælg tråd#, first_change#, næste skift # fra V$log_history;
tråd # FIRST_CHANGE# næste#
———- ————- ————
1 925702 958823
1 958823 959634
1 959634 972579
1 972579 993714
1 993714 1020785
1 1020785 1023738
1 1023738 1023873
1 1023873 1023995

som med SMON_SCN_TABLE er det ikke muligt at finde kilden til stigningen i genereringen af SCN-numrene fra denne tabelvisning. Du kan stadig bruge denne visning i den enkelte forekomst såvel som i et RAC-miljø.

SCN øges ved hjælp af en sekvens?

nu skal det være ret tydeligt, at SCN ser ud til at være et tal, der konstant stiger. Interessant nok, selvom det er et tal, bruger Oracle ikke nogen sekvens til at øge den, men bruger interne funktioner i stedet. For eksempel for at øge SCN_BASE er den interne funktion kcmgas (Get and Advance SCN). Denne funktion kaldes hver gang der anmodes om en ny SCN, og opkaldet til denne funktion øges. På samme måde som denne funktion bruges KCMGCS (Get Current SCN) til at få den aktuelle SCN og det opkald, der bruges til det. Disse funktionsopkald kan ses fra V$sysstat-visningen. En beskrivelse af disse statistikker findes i Referencevejledningen 12.1.

lad os se, hvordan disse opkald linker til SCN-generationen. Vi bruger to sessioner her-en til at se opkaldene i visningen V$SYSSTAT-visning, og den anden session til at trække SCN.

1
2
3
4
5
6
7
8
9
10

Session -1
kvm > l
1* Vælg current_SCN fra V $ database
kvm> /
CURRENT_SCN
———–
698815
KKL>

for denne SCN var disse værdierne for V$sysstat:

1
2
3
4
5
6
7
8
9
10
11
12
13

> l
1 Vælg navn, værdi fra V $ sysstat
2 * Hvor navn som ‘% opkald til% ‘
> /
navn værdi
—————————————————————- ———-
opkald til kcmgcs 427
opkald til kcmgrs 0
opkald til kcmgas 7272
opkald for at få snapshot SCN: kcmgss 159790
>

lad os udstede en forespørgsel for at se den aktuelle SCN i session 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 her er resultatet af den anden session 2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

KKL> /
navn værdi
—————————————————————- ———-
opkald til kcmgcs 427
opkald til kcmgrs 0
opkald til kcmgas 7272
opkald til få snapshot SCN: kcmgss 159790
> /
navn værdi
—————————————————————- ———-
opkald til kcmgcs 427
opkald til kcmgrs 0
opkald til kcmgas 7278
opkald for at få snapshot SCN: kcmgss 159905
>

vi kan se, at opkaldene til KCMGAS er steget til 7278 fra den sidste værdi, 7272. Da Oracle ikke bruger en sekvens til at øge antallet, er der ingen garanti for, at SCN-nummeret altid øges i samme rækkefølge.

konklusion

i denne artikel har vi kigget på, hvad SCN er, hvordan man ser det og hvad kravene til det er. I den næste artikel vil vi se, hvilke forskellige typer SCN ‘ er der er tilgængelige, og hvordan de bruges i databasen. Stay tuned!

Write a Comment

Din e-mailadresse vil ikke blive publiceret.