SCN(System Change Number),也就是通常所说的系统改变号,是数据库中非常重要的一个数据结构。
SCN用以标识数据库在某个确切时刻提交的版本。在事务提交时,它被赋予一个唯一的标识事务的SCN。SCN同时被作为Oracle数据库的内部时钟机制,可被看做逻辑时钟,每个数据库都有一个全局的SCN生成器。
作为数据库内部的逻辑时钟,数据库事务依SCN而排序,Oracle也依据SCN来实现一致性读(Read Consistency)等重要数据库功能。另外对于分布式事务(Distributed Transactions),SCN也极为重要,这里不做更多介绍。
SCN在数据库中是唯一的,并随时间而增加,但是可能并不连贯。除非重建数据库,SCN的值永远不会被重置为0.
一直以来,对于SCN有很多争议,很多人认为SCN是指System Commit Number,而通常SCN在提交时才变化,所以很多时候,这两个名词经常在文档中反复出现。即使在Oracle的官方文档中,SCN也常以System Change/Commit Number两种形式出现。
到底是哪个词其实不是很重要,重要的是需要知道SCN是Oracle内部的时钟机制,Oracle通过SCN来维护数据库的一致性,并通过SCN实施Oracle至关重要的恢复机制。
SCN在数据库中是无处不在,常见的事务表、控制文件、数据文件头、日志文件、数据块头等都记录有SCN值。
冠以不同前缀,SCN也有了不同的名称,如检查点SCN(Checkpint SCN)、Resetlogs SCN等。
~~~~~~~~~~~~~~~~~~~~~
- 控制文件中记录的SCN:
系统检查点SCN(v$database.checkpoint_change#)
数据文件检查点SCN(v$datafile.checkpoint_change#)
数据文件结束SCN(v$datafile.last_change#)
日志文件low scn和next scn - 数据文件中存在的SCN
数据文件头SCN,启动SCN(v$datafile_header.checkpoint_change#)
数据块SCN(块头,块尾) - 日志文件中记录的SCN
日志文件头记录low scn和next scn
日志文件change vector中有每个操作的SCN
1.系统SCN
当一个checkpoint完成时,由CKPT后台进程将这个CHECKPOINT SCN更新到控制文件中
1: select checkpoint_change# from v$database;
2.数据文件SCN
当一个检查点完成时,CKPT进程会将每个数据文件的CHECKPOINT SCN分别更新到控制文件中,每个数据文件对应一条记录.这个值与系统检查点SCN一致.
1: select name,checkpoint_change# from v$datafile;
3.启动SCN(数据文件头SCN)
Oracle把这个检查点的scn存储在每个数据文件的文件头中,这个值也称为启动scn,因为在数据库实例启动时,检查是否需要执行数据库恢复。
1: select name,checkpoint_change# from v$datafile_header;
4.结束SCN
在数据库正常运行过程中,这个SCN值为NULL,也可以理解为无穷大.
当数据库关闭时,会发生一次完全CHECKPOIN,这次检查点除了会更新上面三个SCN外,还会更新控制文件中记录的数据文件的结束SCN.
下一次启动时,会检查datafile header SCN ?= stop scn以确定是否需要恢复
1: select name,last_change# from v$datafile;
数据库正常运行过程中
系统SCN、数据文件SCN、数据文件头SCN 这三个SCN值都是相同的,
当系统发生checkpoint时,
1.触发DBWR进程将DB CACHE中的dirty block写入到数据文件;
2.而DBWR进程在写数据文件之前,会查看这些dirty block相关的redo entris是否已经写入到日志文件;
3.如果相关redo还没有写入到日志文件,则通知LGWR进程将redo entris写入到日志文件;
4.当LGWR与DBWR进程都写完之后,CKPT进程将这个CHECKPOINT SCN值更新到控制文件中的系统SCN、数据文件SCN、还有更新这个CHECKPOINT SCN到各个数据文件头
5.至此,CHECKPOINT完成,此次CHECKPOIN之前的数据与redo信息都已经写入到物理文件中,instance recovery时就不需要恢复在此之前的redo信息。
数据库正常关闭时
发生一次完全CHECKPOIN
这次CHECKPOIN除了会完成上面动作之外,还会更新控制文件中各个数据文件相关的STOP SCN,这样,下次启动时,系统SCN、数据文件SCN、数据文件头SCN、数据文件STOP SCN都是一致的,也就是说不存在数据丢失,就不需要恢复。
数据库非正常关闭时
比如shutdown abort
这时,并不会产生CHECKPOIN,而是直接关掉instance
因为没有发生CHECKPOIN,所以,控制文件,数据文件头中记录的信息还是关闭操作前最近一次CHECKPOINT更新的记录。
这时,系统SCN、DATAFILE SCN、DATAFILE_HEADER SCN是相同的(关闭前最后一次CHECKPOIN更新操作),
而,数据文件的STOP SCN为NULL,
下次打开数据库时,就需要完成恢复操作
数据库打开时
ORACLE会比对数据文件头SCN(启动SCN)与控制文件中记录的数据文件SCN
如果这两个值相同,则比较数据文件头SCN(启动SCN)与控制文件中记录的数据文件STOP SCN
如果这两个值也相同,则证明上次关闭是正常关闭,所有已经提交的操作都已经写入到数据文件,不需要恢复操作
这时,数据库正常打开
当所有的数据文件都正常打开,ORACLE会更新控制文件中记录的数据文件STOP SCN为NULL
完成上次操作之后,数据库才算完全打开,完成了整个OPEN动作,为用户提供服务
一般情况下,发生实例失败时
datafile_header SCN (in datafile header) = datafile SCN(in controlfile) = system SCN (in controlfile)
datafile_header SCN (in datafile header)!= stop SCN(in controlfile)
因为发生instance failur,关闭时没有发生CHECKPOINT,所以stop SCN为NULL(也可以说无穷大),这时,就需要实例恢复,
在datafile header中有RBA的记录,RBA 包含了日志序号、block number 、slot number , 这样ORACLE就可以直接定位到日志文件(归档日志文件)和具体的位置
之后,会比对datafile_header SCN与change vector中记录的SCN,
如果datafile_header SCN < 日志的change vector SCN,则恢复这些redo.
完成redo操作(这个过程中,undo表空间也在完成redo操作)
redo操作完成之后,会根据undo中的记录完成undo操作。
需要介质恢复情况下
datafile_header SCN (START SCN ) != datafile SCN (record in controlfile)
判断是否需要恢复,需要实例恢复还是介质恢复:
datafile_header SCN ?= datafile SCN (record in controlfile)
datafile_header SCN ?= datafile STOP SCN (record in controlfile)
2.SCN的获取方式
可以通过如下几种方式获得数据库的当前或近似SCN。
(1) 从Oracle 9i开始。
可以使用dbms_flashback.get_system_change_number来获得:
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
888266
(2) Oracle 9i前。
可以通过查询x$ktuxe获得系统最接近当前值的SCN:
X$ktuxe的含义是[k]ernel [T]ransaction [U]ndo Transa[x]tion [E]ntry(table)
SQL>select max(ktuxecnw*power(2,32)+ktuxescnb) from x$ktuxe;
MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------
28848232
3.SCN的进一步说明
系统当前SCN并不是在任何的数据库操作时都会改变,SCN通常在事务提交或回滚时改变。在控制文件、数据文件头、数据库、日志文件头、日志文件change vector中都有SCN,但其作用各不相同。
(1) 数据文件头中包含了该数据文件的Checkpoint SCN,表示该数据文件最近一次执行检查点操作时的SCN。
从控制文件的dump文件中,可以得到一下内容:
DATA FILE #1:
(name #7) /opt/ora10g/oradata/ORCL/system01.dbf
creation size=0 block size=8192 status=0xe head=7 tail=7 dup=1
tablespace 0, index=1 krfil=1 prev_file=0
unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
Checkpoint cnt:106 scn: 0x0000.000d845f 11/14/2011 15:24:50
Stop scn: 0xffff.ffffffff 11/14/2011 14:31:00
Creation Checkpointed at scn: 0x0000.00000009 06/30/2005 19:10:11
……
对于每一个数据文件都包含一个这样的条目,记录该文件的检查点SCN的值以及检查点发生的时间,这里的Checkpint SCN、Stop SCN以及Checkpoint CNT都是非常重要的数据结构,我们将会在下面检查点部分详细介绍。
同样可以通过命令转储数据文件头,观察其具体信息及检查点记录等,从跟踪文件中摘取system表空间的记录作为参考:
***************************************************************************
DATA FILE RECORDS
***************************************************************************
(size = 428, compat size = 428, section max = 100, section in-use = 4,
last-recid= 53, old-recno = 0, last-recno = 0)
(extent = 1, blkno = 11, numrecs = 100)
DATA FILE #1:
(name #7) /opt/ora10g/oradata/ORCL/system01.dbf
creation size=0 block size=8192 status=0xe head=7 tail=7 dup=1
tablespace 0, index=1 krfil=1 prev_file=0
unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
Checkpoint cnt:106 scn: 0x0000.000d845f 11/14/2011 15:24:50
Stop scn: 0xffff.ffffffff 11/14/2011 14:31:00
Creation Checkpointed at scn: 0x0000.00000009 06/30/2005 19:10:11
thread:0 rba:(0x0.0.0)
enabled threads: 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Offline scn: 0x0000.0006ce7a prev_range: 0
Online Checkpointed at scn: 0x0000.0006ce7b 11/10/2011 22:40:23
thread:1 rba:(0x1.2.0)
enabled threads: 01000000 00000000 00000000 00000000 00000000 00000000
Hot Backup end marker scn: 0x0000.00000000
aux_file is NOT DEFINED
(2) 日志文件头包含了Low SCN 和Next SCN。
Low SCN和 Next SCN这两个SCN表示该日志文件包含介于Low SCN到Next SCN的重做信息,对于Current的日志文件(当前正在被使用的Redo Logfile),其最终SCN不可知,所以Next SCN被置为无穷大,也就是ffffffff。
来看一下日志文件的情况:
SQL> select * from v$log;
GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM
---------- ---------- ---------- ---------- ---------- --- ----------------------------- ---------
1 1 35 52428800 1 NO CURRENT 881890 14-NOV-11
2 1 33 52428800 1 YES INACTIVE 836815 12-NOV-11
3 1 34 52428800 1 YES INACTIVE 858362 12-NOV-11
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
889346
SQL> alter system switch logfile;
System altered.
SQL> select * from v$log;
GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM
---------- ---------- ---------- ---------- ---------- --- ----------------------------- ---------
1 1 35 52428800 1 YES ACTIVE 881890 14-NOV-11
2 1 36 52428800 1 NO CURRENT 889353 14-NOV-11
3 1 34 52428800 1 YES INACTIVE 858362 12-NOV-11
可以看到,SCN 889346显然位于Log Group#为1的日志文件中,该日志文件包含了SCN自881890 至889353 的Redo信息。Oracle在进行恢复时,就需要根据低SCN和高SCN来确定需要的恢复信息位于哪一个日志或归档文件中。
如果通过控制文件转储,可以在控制文件中找到关于日志文件的信息:
SQL> alter session set events 'immediate trace name redohdr level 10';
Session altered.
LOG FILE #1:
(name #3) /opt/ora10g/oradata/ORCL/redo01.log
Thread 1 redo log links: forward: 2 backward: 0
siz: 0x19000 seq: 0x00000026 hws: 0x1 bsz: 512 nab: 0xffffffff flg: 0x8 dup: 1
Archive links: fwrd: 0 back: 0 Prev scn: 0x0000.000de15c
Low scn: 0x0000.000def9a 11/16/2011 16:06:06
Next scn: 0xffff.ffffffff 01/01/1988 00:00:00
LOG FILE #2:
(name #2) /opt/ora10g/oradata/ORCL/redo02.log
Thread 1 redo log links: forward: 3 backward: 1
siz: 0x19000 seq: 0x00000024 hws: 0x4 bsz: 512 nab: 0x5c6 flg: 0x1 dup: 1
Archive links: fwrd: 0 back: 0 Prev scn: 0x0000.000d74e2
Low scn: 0x0000.000d9209 11/14/2011 16:57:08
Next scn: 0x0000.000de15c 11/16/2011 15:01:07
LOG FILE #3:
(name #1) /opt/ora10g/oradata/ORCL/redo03.log
Thread 1 redo log links: forward: 0 backward: 2
siz: 0x19000 seq: 0x00000025 hws: 0x3 bsz: 512 nab: 0x37e3 flg: 0x1 dup: 1
Archive links: fwrd: 0 back: 0 Prev scn: 0x0000.000d9209
Low scn: 0x0000.000de15c 11/16/2011 15:01:07
Next scn: 0x0000.000def9a 11/16/2011 16:06:06
可以注意到,Log File 1是当前的日志文件,该文件拥有的Next SCN是无穷大。
同样,可以通过直接dump日志文件的方式来进行转储;
SQL> select * from v$logfile;
GROUP# STATUS TYPE MEMBER
---------- ------- ---------------------------------------------------------------------------
3 ONLINE /opt/ora10g/oradata/ORCL/redo03.log
2 ONLINE /opt/ora10g/oradata/ORCL/redo02.log
1 ONLINE /opt/ora10g/oradata/ORCL/redo01.log
SQL> alter system dump logfile '/opt/ora10g/oradata/ORCL/redo01.log';
System altered.
DUMP OF REDO FROM FILE '/opt/ora10g/oradata/ORCL/redo01.log'
Opcodes *.*
RBAs: 0x000000.00000000.0000 thru 0xffffffff.ffffffff.ffff
SCNs: scn: 0x0000.00000000 thru scn: 0xffff.ffffffff
Times: creation thru eternity
FILE HEADER:
Compatibility Vsn = 169869568=0xa200100
Db ID=1294662348=0x4d2afacc, Db Name='ORCL'
Activation ID=1294635980=0x4d2a93cc
Control Seq=953=0x3b9, File size=102400=0x19000
File Number=1, Blksiz=512, File Type=2 LOG
descrip:"Thread 0001, Seq# 0000000038, SCN 0x0000000def9a-0xffffffffffff"
thread: 1 nab: 0xffffffff seq: 0x00000026 hws: 0x1 eot: 1 dis: 0
resetlogs count: 0x2db5af57 scn: 0x0000.0006ce7b (446075)
resetlogs terminal rcv count: 0x0 scn: 0x0000.00000000
prev resetlogs count: 0x2184ef74 scn: 0x0000.00000001 (1)
prev resetlogs terminal rcv count: 0x0 scn: 0x0000.00000000
Low scn: 0x0000.000def9a (913306) 11/16/2011 16:06:06
Next scn: 0xffff.ffffffff 01/01/1988 00:00:00
Enabled scn: 0x0000.0006ce7b (446075) 11/10/2011 22:40:23
Thread closed scn: 0x0000.000def9a (913306) 11/16/2011 16:06:06
Disk cksum: 0x5987 Calc cksum: 0x5987
Terminal recovery stop scn: 0x0000.00000000
Terminal recovery 01/01/1988 00:00:00
Most recent redo scn: 0x0000.00000000
Largest LWN: 0 blocks
End-of-redo stream : No
Unprotected mode
Miscellaneous flags: 0x0
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/16920491/viewspace-744757/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/16920491/viewspace-744757/
396

被折叠的 条评论
为什么被折叠?



