Oracle数据库SCNG值,oracle数据库SCN概念

oracle数据库SCN概念

首先这里我们先介绍四个SCN概念。

1,系统检查点scn

当一个检查点动作完成后,Oracle就把系统检查点的SCN存储到控制文件中。

select checkpoint_change#

from v$database;

2,数据文件检查点scn

当一个检查点动作完成后,Oracle就把每个数据文件的scn单独存放在控制文件中。

select

name,checkpoint_change# from v$datafile;

3,启动scn

Oracle把这个检查点的scn存储在每个数据文件的文件头中,这个值称为启动scn,因为它用于在数据库实例启动时,

检查是否需要执行数据库恢复。

select

name,checkpoint_change# from v$datafile_header

4,终止scn

每个数据文件的终止scn都存储在控制文件中。

select name,last_change#

from v$datafile

以下条件需要使用using

backup controlfile

1)、使用备份控制文件

2)、重建resetlogs控制文件,如果重建立noresetlogs不必要使用using backup controlfile

2、alter database openresetlog

指定RESETLOGS将重设当前LOGsequencenumber为1,抛弃所有日志信息。

以下条件需要使用resetlog

1)在不完全恢复(介质恢复)

2)使用备份控制文件

使用resetlogs打开数据库后无必完整地备份一次数据库。

3、create controlfile resetlogs/noresetlogs

1).用Noresetlogs重建控制文件时,控制文件中datafile Checkpoint来自Online logs中的Current log头

2).用Resetlogs重建控制文件时,控制文件中datafile Checkpoint来自各数据文件头。

当system

scn,datafile scn,start scn不全相等,需要介质恢复,如果stopscn

null需要实例恢复resetlogs抛弃所有在上一次恢复没有用到的日志信息,确保不被重新用与恢复。

1、系统正常关闭:

system scn=datafile

scn=start scn=stop scn

1)system scn=datafile

scn=start scn,不需要介质恢复

2)stopscn not null,不需要实例恢复

2、系统异常关闭:

system scn=datafile

scn=start scn,stop scn null

1)system scn=datafile

scn=start scn,不需要介质恢复

2)stopscn null,需要实例恢复

3、旧数据文件

system scn=datafile

scn>start scn,stop scn null/notnull

1)system scn=datafile

scn>start scn,需要介质恢复成system scn=datafile

scn=start scn

2)stopscn null,需要实例恢复,not null不需要实例恢复

4、备份控制文件

system scn=datafile

scn<=start scn(当数据文件为旧的相等),stop scn notnull/null

1)system scn=datafile

scn<=start scn,需要使用using backup controlfile介质恢复成system scn=datafile scn=start scn=current log

scn(当前日志最大SCN)

2)为保证上一次恢复没有用到log日志不被使用,必须resetlogs

5、重建noresetlogs控制文件

控制文件中datafile Checkpoint来自Online

logs中的Current log头

current log scn=system

scn=datafile scn>=start scn,stop scn not null/null

1)current log scn=system

scn=datafile scn>=start scn,需要介质恢复成system

scn=datafile scn=start scn=redolog scn(当前日志最大SCN),stop scn not null

2)stopscn not null不需要实例恢复

6、重建resetlogs控制文件

控制文件中datafile

Checkpoint来自各数据文件头。

system scn>=datafile

scn=start scn,stop scn not null/null

1)system scn>=datafile

scn=start scn,需要使用using backup controlfile介质恢复成system scn=datafile scn=start scn(当前日志最大SCN),stop scn not null

2)stop notnull,因为SCN已经为redolog scn,log已经不能使用,必须resetlogs

=========================================

Oracle SCN机制解析

SCN(System Chang Number)作为oracle中的一个重要机制,在数据恢复、Data Guard、Streams复制、RAC节点间的同步等各个功能中起着重要作用。理解SCN的运作机制,可以帮助你更加深入地了解上述功能。

在理解SCN之前,我们先看下oracle事务中的数据变化是如何写入数据文件的:

1、事务开始;

2、在buffer cache中找到需要的数据块,如果没有找到,则从数据文件中载入buffer

cache中;

3、事务修改buffer cache的数据块,该数据被标识为“脏数据”,并被写入log buffer中;

4、事务提交,LGWR进程将log buffer中的“脏数据”写入redo log file中;

5、当发生checkpoint,CKPT进程更新所有数据文件的文件头中的信息,DBWn进程则负责将Buffer Cache中的脏数据写入到数据文件中。

经过上述5个步骤,事务中的数据变化最终被写入到数据文件中。但是,一旦在上述中间环节时,数据库意外宕机了,在重新启动时如何知道哪些数据已经写入数据文件、哪些没有写呢(同样,在DG、streams中也存在类似疑问:redo log中哪些是上一次同步已经复制过的数据、哪些没有)?SCN机制就能比较完善的解决上述问题。

SCN是一个数字,确切的说是一个只会增加、不会减少的数字。正是它这种只会增加的特性确保了Oracle知道哪些应该被恢复、哪些应该被复制。

总共有4中SCN:系统检查点(System Checkpoint)SCN、数据文件检查点(Datafile Checkpoint)SCN、结束SCN(Stop SCN)、开始SCN(Start SCN)。其中其面3中SCN存在于控制文件中,最后一种则存在于数据文件的文件头中。

在控制文件中,System

Checkpoint SCN是针对整个数据库全局的,因而只存在一个,而Datafile

Checkpoint SCN和Stop SCN是针对每个数据文件的,因而一个数据文件就对应在控制文件中存在一份Datafile Checkpoint SCN和Stop

SCN。在数据库正常运行期间,Stop SCN(通过视图v$datafile的字段last_change#可以查询)是一个无穷大的数字或者说是NULL。

在一个事务提交后(上述第四个步骤),会在redo log中存在一条redo记录,同时,系统为其提供一个最新的SCN(通过函数dbms_flashback.get_system_change_number可以知道当前的最新SCN),记录在该条记录中。如果该条记录是在redo

log被清空(日志满做切换时或发生checkpoint时,所有变化日志已经被写入数据文件中),则其SCN被记录为redo log的low SCN。以后在日志再次被清空前写入的redo记录中SCN则成为Next SCN。

当日志切换或发生checkpoint(上述第五个步骤)时,从Low SCN到Next SCN之间的所有redo记录的数据就被DBWn进程写入数据文件中,而CKPT进程则将所有数据文件(无论redo log中的数据是否影响到该数据文件)的文件头上记录的Start SCN(通过视图v$datafile_header的字段checkpoint_change#可以查询)更新为Next SCN,同时将控制文件中的System Checkpoint SCN(通过视图v$database的字段checkpoint_change#可以查询)、每个数据文件对应的Datafile Checkpoint(通过视图v$datafile的字段checkpoint_change#可以查询)也更新为Next

SCN。但是,如果该数据文件所在的表空间被设置为read-only时,数据文件的Start SCN和控制文件中Datafile Checkpoint SCN都不会被更新。

那系统是如何产生一个最新的SCN的?实际上,这个数字是由当时的timestamp转换过来的。每当需要产生一个最新的SCN到redo记录时,系统获取当时的timestamp,将其转换为数字作为SCN。我们可以通过函数SCN_TO_TIMESTAMP(10g以后)将其转换回timestamp:

SQL> select

dbms_flashback.get_system_change_number,

SCN_TO_TIMESTAMP(dbms_flashback.get_system_change_number) from dual;

GET_SYSTEM_CHANGE_NUMBER SCN_TO_TIMESTAMP(DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER)

---------------------------------------------------------------------------------------------------

2877076756       17-AUG-07 02.15.26.000000000 PM

也可以用函数timestamp_to_scn将一个timestamp转换为SCN:

SQL> select

timestamp_to_scn(SYSTIMESTAMP) as scn from dual;

SCN

----------

2877078439

最后,SCN除了作为反映事务数据变化并保持同步外,它还起到系统的“心跳”作用——每隔3秒左右系统会刷新一次系统SCN。

下面,在简单介绍一下SCN如何在数据库恢复中起作用。

数据库在正常关闭(shutdown

immediate/normal)时,会先做一次checkpoint,将log file中的数据写入数据文件中,将控制文件、数据文件中的SCN(包括控制文件中的Stop SCN)都更新为最新的SCN。

数据库异常/意外关闭不会或者只更新部分Stop SCN。

当数据库启动时,Oracle先检查控制文件中的每个Datafile Checkpoint SCN和数据文件中的Start

SCN是否相同,再检查每个Datafile Checkpoint SCN和Stop SCN是否相同。如果发现有不同,就从Redo Log中找到丢失的SCN,重新写入数据文件中进行恢复。具体的数据恢复过程这里就不再赘述。

SCN作为Oracle中的一个重要机制,在多个重要功能中起着“控制器”的作用。了解SCN的产生和实现方式,帮助DBA理解和处理恢复、DG、Streams复制的问题。

最后提一句,利用SCN机制,在Oracle10g、11g中又增加了一些很实用的功能——数据库闪回、数据库负载重现等。

=========================================

SCN: System Change Number

SCN是顺序递增的一个数字,在Oracle中用来标识数据库的每一次改动,及其先后顺序。SCN的最大值是0xffff.ffffffff。

Oracle对SCN的管理

单节点的Instance中

单节点的instance中,SCN值存在SGA区,由system commit number latch保护。任何进程要得到当前的SCN值,都要先得到这个latch。

RAC/OPS环境中

Oracle通过排队机制(Enqueue)实现SCN在各并行节点之间的顺序增长。具体有两种方法:

Lamport算法:又称面包房算法,先来先服务算法。跟很多银行采用的排队机制一样。客户到了银行,先领取一个服务号。一旦某个窗口出现空闲,拥有最小服务号的客户就可以去空闲窗口办理业务。

Commit广播算法:一有commit完成,最新的SCN就广播到所有节点中。

上述两种算法可以通过调整初始化参数max_commit_propagation_delay来切换。在多数系统(除了Compaq Tur64 Unix)中,该参数的默认值都是700厘秒(centisecond),采用Lamport算法。如果该值小于100厘秒,Oracle就采用广播算法,并且记录在alert.log文件中。

几种重要的SCN

Commit SCN

当用户提交commit命令后,系统将当前scn赋给该transaction。这些信息都反映在redo buffer中,并马上更新到redo log文件里。

Offline SCN

除了System

tablespace以外的任何表空间,当我们执行SQL>alter

tablespace … offline normal命令时,就会触发一个checkpoint,将内存中的dirty buffer写入磁盘文件中。Checkpoint完成后,数据文件头会更新checkpoint scn和offline

normal scn值。其中数据库文件头的checkpoint scn值可通过查询列x$kccfe.fecps得到。

如果执行SQL>alter

tablespace …offline命令时采用temporary或immediate选项,而不用normal选项时,offline normal scn会被设成0。

这样当数据库重启后通过resetlog方式打开时,该表空间就无法再改回在线状态。

Checkpoint SCN

当数据库内存的脏数据块(dirty

blocks)写到各数据文件中时,就发生一次checkpoint。数据库的当前checkpoint scn值存在x$kccdi.discn中。Checkpoint scn在数据库恢复中起着至关重要的作用。无论你用何种办法恢复数据库,只有当各个数据库文件的checkpoint scn都相同时,数据库才能打开。

虽然参数“_allow_resetlogs_corruption”可以在checkpoint scn不一致时强制打开数据库,但是这样的数据库在open后必须马上作全库的export,然后重建数据库并import数据。

ResetlogSCN

数据库不完全恢复时,在指定时间点后的scn都无法再应用到数据库中。Resetlog时的scn就被设成当前数据库scn,redo log也会被重新设置。

Stop SCN

Stop scn记录在数据文件头上。当数据库处在打开状态时,stop scn被设成最大值0xffff.ffffffff。在数据库正常关闭过程中,stop scn被设置成当前系统的最大scn值。在数据库打开过程中,Oracle会比较各文件的stop scn和checkpoint scn,如果值不一致,表明数据库先前没有正常关闭,需要做恢复。

High and Low SCN

Oracle的Redo log会顺序纪录数据库的各个变化。一组redo log文件写满后,会自动切换到下一组redo log文件。则上一组redo log的high scn就是下一组redo log的low scn。

在视图v$log_history中,sequence#代表redo log的序列号,first_change#表示当前redo log的low scn,列next_change#表示当前redo log的high scn。

SQL> col recid format

9999

SQL> col requence#

format 9999

SQL> col first_change#

format 9,999,999,999,999

SQL> col next_change#

format 9,999,999,999,999

SQL> select recid,sequence#,first_change#,next_change#

from v$log_history where rownum<6;

RECIDSEQUENCE#

FIRST_CHANGE# NEXT_CHANGE#

----- ----------

------------------ ------------------

484 484 1,928,645,840,091

1,928,645,840,436

485 485 1,928,645,840,436

1,928,645,840,636

486 486 1,928,645,840,636

1,928,778,045,209

487 487 1,928,778,045,209

1,929,255,480,725

488 488 1,929,255,480,725

1,930,752,214,033

关于如何使用参数_allow_resetlogs_corruption,可参见文档

=========================

SCN

SCN -

System Change Number - A number, internal to Oracle that is incremented over

time as change vectors are generated, applied, and written to the Redo log.

SCN -

System Commit Number - A number, internal to Oracle that is incremented with

each database COMMIT.

System

Commit Numbers and System Change Numbers share the same internalsequencegenerator.

eg:

SQL> select

dbms_flashback.get_system_change_number a from dual;

A

----------

15503052

SQL> select

CHECKPOINT_CHANGE# a from v$datafile;

A

----------

15496179

15496179

=======================

问题的提出:

在并发的环境下,每个sql先执行的不一定先提交,因此想如何才能按照事务提交的顺序来对记录进行排序而不是按照sql执行的时间。

先来说说sysdate或者systimestamp,如果系统中使用这样的列来记录每个记录最后提交的时间,那是错误的。而且很多人认为这个时间如果设置为default值,那么记录的就是sql执行的时间,其实也是错误的。oracle 10.2版本的concept第388页有这样一句话“Default values are

included as part of an INSERT statement before the statement is parsed.”因此可以看到,把列的default值设置为缺省值,或者insert into table(col1...)

values (sysdate,...)的方式最后得到的时间都是sql解析的时间而不是sql执行的时间。

ORA_ROWSCN是oracle 10G版本中提出的概念,是一个伪列,用来记录数据提交时候的scn,而scn是唯一的,而且scn的先后就是commit的时间的先后(虽然事务commit不是导致scn增长的唯一因素)。因此可以按照这个伪列进行排序,得到的结果就是事务提交的先后进行的排序。

默认的建表方式的ORA_ROWSCN记录的scn是精确到每个block而不是精确到block中的每个row的,因为ORA_ROWSCN取自data block header的scn。要使用此特性需要使用以下方式建表:create table tab(col1 number) rowdependencies。这样就可以为每个列保存自己的scn,需要增加每行数据6个字节的空间的开销。

另外,oracle还提供了ORA_ROWSCN到TIMESTAMP的转换,可以得到每个记录最后的修改时间,但这个时间和真正的数据发生变化的时间有误差,误差在正负3秒(引用自TOM,是否是因为每3秒SCN会刷一次有关呢?有待验证)

=============================================

Oracle 10g中SCN与TimeStamp的斗转星移

在Oracle数据库10g中,提供了函数对于SCN和时间戳进行相互转换(作为对于闪回操作的一个增强),本文将通过一个示例进行具体分析:

具体示例如下:

第一步,我们可以通过dbms_flashback.get_system_change_number获得系统当前的SCN值:

SQL>

col scn for 9999999999999

SQL>

select dbms_flashback.get_system_change_number scn from dual;

SCN

--------------

8908390522972

然后,通过scn_to_timestamp函数可以将SCN转换为时间戳:

SQL>

select scn_to_timestamp(8908390522972) scn from dual;

SCN

-----------------------------------------------------------

05-JAN-07

10.56.30.000000000 AM

此处,可以通过timestamp_to_scn可以将时间戳转换为SCN:

SQL>

select timestamp_to_scn(scn_to_timestamp(8908390522972)) scn from dual;

SCN

--------------

8908390522972

通过以上这两个函数,Oracle得以将SCN和时间的关系建立起来,而在Oracle数据库10g之前的版本,却无法通过函数转换得到SCN和时间的对应关系,一般情况下只能通过logmnr分析日志获得。

注:此类转换需要依赖于数据库内部的数据记录,对于持久的SCN则不能转换,示例如下:

SQL>

select min(FIRST_CHANGE#) scn,max(FIRST_CHANGE#) scn from v$archived_log;

SCN

SCN

------------------

------------------

8907349093953

8908393582271

SQL>

select scn_to_timestamp(8907349093953) scn from dual;

select

scn_to_timestamp(8907349093953) scn from dual

*

ERROR

at line 1:

ORA-08181:

specified number is not a valid system change number

ORA-06512:

at "SYS.SCN_TO_TIMESTAMP", line 1

ORA-06512:

at line 1

SQL>

select scn_to_timestamp(8908393582271) scn from dual;

SCN

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值