Redgate Hub

för många som arbetar med Oracle database är SCN (System Change Number) ett ämne som intresserar dem mycket – men trots att det är ett fascinerande ämne är det också förvirrande. I den här artikeln kommer vi att lära oss SCN: s nitty-gritty: vad det är, var det används och hur det fungerar.

det är värt att nämna att detta inte är och inte kan vara fullständig täckning av varje detalj om SCN. Med det sagt, låt oss börja.

SCN – varför behöver vi det?

Antag att det är slutet på månaden och dess lönedag. Du är i Lönegruppen och har med lämplig myndighet utfärdat en fråga för att dra den nuvarande löneberäkningen för alla anställda. Siffror flyter över skärmen, allt går bra.

Antag att en kollega startar en ny lönekörning medan du tittar på utgången och det batchjobbet rensar den aktuella beräkningsöversikten. Saker skulle säkert bli förvirrande om din produktion plötsligt visade ’0’ för de nya raderna som kommer ut.

för det här scenariot skulle du förmodligen förvänta dig att utmatningen återspeglar databasens tillstånd – innehållet i varje rad – hur det fanns när du utfärdade din fråga.

en av garantierna för Oracle-databasen är att”det finns inga smutsiga läsningar av användardata”. Om det behövs kommer Oracle att bygga om varje rad till det stabila tillståndet omedelbart när frågan utfärdades.

Oracle gör det snyggt och mycket exakt genom en egen ”timer”, känd som System Change Number, AKA SCN.

vi kommer att diskutera dessa aspekter av SCN:

  • själva numret
  • nummergeneratorn
  • platser där numret lagras

så låt oss börja!

byggstenar för att förstå SCN

för att undersöka SCN måste flera termer förstås. Även om dessa definitioner är väl dokumenterade är det värt att upprepa dem här:

transaktion

från Konceptguiden för Oracle online Documentation:

”en transaktion är en logisk, atomisk arbetsenhet som innehåller en eller flera SQL-satser. En transaktion grupperar SQL-satser så att de antingen är alla engagerade, vilket innebär att de tillämpas på databasen eller alla rullas tillbaka, vilket innebär att de ångras från databasen. Oracle Database tilldelar varje transaktion en unik identifierare som kallas ett transaktions-ID”.

enklare: när vi startar en transaktion initierar vi en uppsättning ändringar. Dessa måste antingen fyllas i i sin helhet eller får inte slutföras alls. Eftersom transaktionerna sker i databasen får användarna som läser något område som har ändrats inte påverkas av några biverkningar som kan ändra deras resultat.

för att transaktionerna ska fungera korrekt i en databas måste fyra ACID-regler följas av databasen. Dessa är:

  • Atomicitet;
  • konsistens;
  • isolering;
  • hållbarhet.

så var passar SCN i allt detta? Och svaret på den frågan är att använda SCN endast Oracle upprätthåller datakonsistens. Detta görs för att säkerställa att någon tidpunkt, det finns ingen skillnad i de resultat som visas för de andra när en användare ändrar något, och vice versa.

för att sammanfatta, i Oracle, principen om” läsare väntar inte på författare och författare behöver inte läsare ” är helt och verkligen följt. För att göra det är det av yttersta vikt att uppgifterna, som för närvarande genomgår någon form av förändring, inte får vara tillgängliga för någon annan än den person som gör dessa ändringar. För transaktioner krävs detta för att upprätthålla dataens integritet. Tre saker kan inträffa som kan störa denna integritet-Dirty Read, Fuzzy Read och Phantom Read. För att säkerställa att det inte kommer att finnas någon form av integritetsfrågor i dessa transaktioner, olika nivåer av isoleringar finns tillgängliga. Dessa är:

  • Läs Uncommitted
  • Read Committed
  • repeterbar Read
  • Serializable

Transaktionsisoleringsnivåer

från dessa erbjuder Oracle Read Committed som standardisoleringsnivå, och ser till att det inte finns någon möjlighet för en användare att se de ändringar som gjorts av en annan användare som ännu inte är engagerade. Det får inte finnas någon läsning över den data som är markerad som ”smutsig” och det måste finnas en mekanism som är tillräckligt robust för att göra allt detta möjligt.

för att göra detta möjligt spelar SCN en viktig roll.

SCN, en introduktion

System Commit Number kan förstås som Oracles representation av tid. Oracle använder SCN för att kontrollera konsistens, för att utföra återhämtning och för att beställa förändringsvektorerna i redo.

SCN finns på många platser-både i minnet och på disken. Olika platser används för att hjälpa databassystemet att identifiera olika tillstånd i databasen. På vissa platser används det till exempel för att ange transaktionens slutförandestatus och om den är aktiv eller engagerad.

tvärtemot vad många tror, det inte får genereras endast vid tidpunkten för begå, men det är vad namnet själv antyder. SCN finns där hela tiden i databasen, vilket representerar en tidsdel för operationen som händer vid det ögonblicket. Det är inte helt felaktigt att säga att SCN inte genereras med ett åtagande, det gör det – men det är inte det enda sättet som SCN genereras.

SCN är ett tvådelat nummer som genereras på begäran, som svar på en händelse. Det är ungefär som datum och tid som härrör från en kalender – och klockkombination; klockan ändras snabbt och först när den har gått igenom hela 24 – timmarscykeln ändras överflödet-kalendern. Händelsen som ändrar klockan är dock ’pendeln’ och är regelbunden, medan händelsen som ändrar SCN är ett samtal till en specifik intern funktion.

i likhet med en kalender/klocktidsstämpel kan värdet registreras på en mängd olika platser, var och en för en annan användning.

ett verkligt exempel som liknar en SCN är en flygplatsklocka. Två personer går in på en flygplats samtidigt och kan notera klocktiden. Det ögonblicket ger oss ’en post SCN’ som råkar vara densamma för både människor. En person får en vagn för bagage innan du checkar in, medan den andra fortsätter direkt till incheckningsdisken. När platserna tilldelas, varje person kan få en annan ’check-in SCN’ eftersom tiderna är något annorlunda. En ’boarding SCN’ kan tilldelas för att ange när var och en har gått ombord, men båda får samma ’start SCN’.

liksom kombinationen av kalender och klocka garanteras SCN att öka under normal drift. Det finns ingen garanti för att numret kommer att vara sekventiellt (saknade nummer).

så var används denna information om SCN i Oracle-databasen? Tja, nästan överallt. Precis som vi associerar tid med alla våra aktiviteter, är SCN också associerat med alla delar av databasens funktionalitet. När du till exempel försöker välja data från en tabell används SCN för att bekräfta om dessa data är konsekventa eller inte. SCN finns också i Datablockets Transaktionsrubriker. Denna SCN skulle representera den tid då transaktionen startade och när den begicks. På samma sätt upprätthålls en post i redo-loggen för varje utförd ändring och för var och en av dessa poster används SCN för att representera tidpunkten för transaktionens förekomst.

Läs konsistens använder SCN för att bestämma hur länge den måste tillämpa ångra över den smutsiga bufferten så att Read consistent data request för en session kan slutföras. Och som är välkänt ökas SCN med varje commit-operation.

SCN-Format och struktur

SCN är ett stort antal med två komponenter till det: SCN Base & SCB Wrap.

SCN är ett 6 byte (48 bitar) nummer. Av dessa 48 bitar är SCN_WRAP ett 16 bit (2 Byte) nummer och SCN_BASE är ett 32 bit (4 byte) nummer. Båda bas & WRAP används för att styra SCN: s inkrement och för att säkerställa att databasen inte tar slut. SCN_WRAP ökas med 1 när SCN_BASE når värdet 4 miljarder och SCN_BASE blir 0.

från Oracle Version 12c är SCN-numret ett 8 byte-nummer.

så hur ser vi det aktuella SCN-värdet? Det enklaste sättet är att fråga i view V$ – databasen. Ta en titt:

1
2
3
4
5

SQL> välj current_scn från V$database;
CURRENT_SCN
———–
1123790

som vi kan se visas den SCN som ett nummer. Det här är bra eftersom det gör användningen av SCN lätt för oss i våra uttalanden som utför återhämtning, flashback etc. Om vi vill kan vi också konvertera SCN till ett hexadecimalt värde:

1
2
3
4
5

SQL> välj to_char (’1123790’, ’xxxxxxxx’) scn_hex från dual;
SCN_HEX
———
1125ce

här är ett exempel på utgången från samma vy som nås några gånger:

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

SQL> välj current_scn från V$database;
CURRENT_SCN
———–
1178883
SQL> /
CURRENT_SCN
———–
1178885
SQL> /
CURRENT_SCN
———–
1178886

intressant nog visar denna ökning av SCN-värdet en viktig aspekt av SCN. Vi kan se att med varje utförande är det en ökning av SCN: s räkning. Genom att fråga view V$ – databasen orsakar vi faktiskt hoppet i SCN-numret.

Smon_scn_time Table

det enklaste sättet att se båda dessa värden är från en intern tabell som ägs av SYS – användaren-SMON_SCN_TIME. Följande är en utgång från samma (11204).

1
2
3
4
5
6

SQL> välj SCN_wrp, SCN_bas, SCN från smon_SCN_time där rownum < 3;
SCN_WRP SCN_BAS SCN
———- ———- ———-
0 998222 998222
0 998406 998406

den här tabellen innehåller posterna för de genererade SCN: erna. Den lagrar data i ungefär 5-minuters steg och innehar 5 dagars värde av data. Detta innebär att tabellen innehåller cirka 1440 poster. Det exakta antalet poster varierar något eftersom lagringsökningen inte är exakt 5 minuter.

1
2
3
4
5

SQL > välj räkna ( * ) från SMON_SCN_TIME;
räkna(*)
———-
1494

I versioner av Oracle före 10g var tidskartläggningen av SCN med tiden + / – 5 minuter men från 10g och framåt ändras detta till + / – 3 sekunder. Eftersom det här lagras i en intern tabell tillåter Oracle inte åtkomst till informationen från den här tabellen direkt. För att komma åt det tillhandahålls API: er. Ett sådant API är från paketet DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER, som kan användas för att komma åt sekvensnumret från den här tabellen. Ett exempel på detta ges nedan (tack vare Tom Kyte för frågan):

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
välj SCN_to_timestamp (SCN) ts, min (SCN), max (SCN)
från (
välj dbms_flashback.get_system_change_number () – nivå SCN
från dubbla
Anslut efter nivå <= 100
)
Gruppera efter SCN_to_timestamp (SCN)
* Beställ efter SCN_to_timestamp (SCN)
SQL> /
TS MIN (SCN) MAX (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

hur kan vi kartlägga SCN med tidsstämpel i versioner före 10g?

det är viktigt att komma ihåg att denna tabell inte visar varför det skulle finnas någon ökning av ökningstakten i SCN-siffrorna. Med lite formatering är det möjligt att få en uppfattning om de genererade SCN-numren men källan till deras tillväxt kommer inte att framgå av denna tabell.

ett annat sätt att kontrollera detta är från vyn V$LOG_HISTORY. Vyn innehåller SCN i form av kolumnerna FIRST_CHANGE# och NEXT_CHANGE# och vi kan se genom dessa två kolumner mängden SCN som genereras i databasen under en tidsperiod. ”First_change# är den lägsta SCN som visas i den arkiverade loggfilen vid ett givet sekvensnummer för denna tråd. ”Next_change#” är den lägsta SCN som visas i nästa arkiverade loggfil.

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

SQL > välj tråd#, first_change#, next_change # från V$log_history;
tråd # 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

som med SMON_SCN_TABLE är det inte möjligt att hitta källan till ökningen av genereringen av SCN-siffrorna från den här tabellvyn. Ändå kan du använda den här vyn i den enskilda instansen såväl som i en RAC-miljö.

SCN ökar med en sekvens?

vid det här laget borde det vara ganska uppenbart att SCN verkar vara ett tal som ständigt ökar. Intressant, även om det är ett tal, använder Oracle ingen sekvens för att öka den utan använder interna funktioner istället. Till exempel, för att öka SCN_BASE, är funktionen som används internt KCMGAS(Get och Advance SCN). Denna funktion anropas varje gång en ny SCN begärs och uppmaningen till denna funktion ökas. På samma sätt som den här funktionen används KCMGCS (Get Current SCN) för att få den aktuella SCN och samtalet som används för det. Dessa funktionsanrop kan ses från V$sysstat-vyn. En beskrivning av denna statistik finns i referensguiden 12.1.

Låt oss se hur dessa samtal länkar till SCN-generationen. Vi använder två sessioner här-en för att se samtalen i vyn v$SYSSTAT-vy och den andra sessionen för att dra SCN.

1
2
3
4
5
6
7
8
9
10

Session -1
SQL> l
1 * Välj current_SCN från V$databas
SQL> /
CURRENT_SCN
———–
698815
SQL>

för denna SCN var dessa värdena för V$sysstat:

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

SQL> l
1 Välj namn, värde från V$sysstat
2 * där namn som ’% samtal till% ’
SQL> /
namn värde
—————————————————————- ———-
samtal till kcmgcs 427
samtal till kcmgrs 0
samtal till kcmgas 7272
samtal för att få ögonblicksbild SCN: kcmgss 159790
SQL>

låt oss utfärda en fråga för att se den aktuella 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 här är resultatet av den andra sessionen 2:

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

SQL> /
namn värde
—————————————————————- ———-
samtal till kcmgcs 427
samtal till kcmgrs 0
samtal till kcmgas 7272
samtal för att få ögonblicksbild SCN: KCMGSS 159790
SQL> /
namn värde
—————————————————————- ———-
samtal till kcmgcs 427
samtal till kcmgrs 0
samtal till kcmgas 7278
samtal för att få ögonblicksbild SCN: kcmgss 159905
SQL>

vi kan se att samtalen till KCMGAS har ökat till 7278 från det sista värdet, 7272. Eftersom Oracle inte använder en sekvens för att öka antalet, finns det ingen garanti för att SCN-numret alltid kommer att ökas i samma ordning.

slutsats

i den här artikeln har vi tittat på vad SCN är, hur man ser det och vad kraven för det är. I nästa artikel kommer vi att se vilka olika typer av SCN som finns tillgängliga och hur de används i databasen. Håll ögonen öppna!

Write a Comment

Din e-postadress kommer inte publiceras.