Oracle SCN概念和说明

Oracle scn

Oracle SCN: oracle system change number 记录数据库变更的时间号
The system change number (SCN) is a database ordering primitive. The value of an SCN is the logical point in time at which changes are made to a database. The database uses these SCNs to query and track the changes. For example, if a transaction updates a row, then the database records the SCN at which this update occurred.
记录的为数据库系统的逻辑上变更时间,可以 使用scn进行对数据库的查询或变更的追踪。
SCN是数据库内部的时钟机制,数据库内部的事务是按照SCN排序生成。
SCN在数据库中是唯一的,随时间的增加而增加。

SCN和系统时间

oralce中维护一张scn值 和 timestamp及系统时间对应的表
sys.smon_scn_time

查看最新的对应关系:
select time_mp,time_dp,scn from sys.smon_scn_time t where rownum < 10 order by scn desc ;

SQL> select time_mp,time_dp,scn from sys.smon_scn_time t  where rownum < 10 order by scn desc ;

        TIME_MP TIME_DP                           SCN
  - -------------- ------------------- -----------------
     1564632734 2019-08-01 04:12:14    16010028042706
     1564456246 2019-07-30 03:10:46    16010026847230
     1564455646 2019-07-30 03:00:46    16010026844711
     1564455328 2019-07-30 02:55:28    16010026843162
     1564454123 2019-07-30 02:35:23    16010026839268
     1564399969 2019-07-29 11:32:49    16010026413692
     1564398826 2019-07-29 11:13:46    16010026410912
     1564349417 2019-07-28 21:30:17    16010026136582
     1564163289 2019-07-26 17:48:09    16010024835630

9 rows selected.

oracle所支持的最大scn值为:
2^28=281,474,976,710,656
理论上scn是用不完的,当scn用完,则数据库会不可访问 。

查看当前系统的SCN
select dbms_flashback.get_system_change_number from dual;
select current_scn from v$database;

SCN和系统恢复

checkpoint scn
这里说的是不准确,应该是redo log记录的事务变更的scn
redo log中的有一个FIRST_CHANGE#和NEXT_CHANGE#字段,这两个字段分为记录了一个redo log文件中数据库事务变更的区间

当v$log.status为CURRENT当前应用状态时,则记录区间为FIRST_CHANGE#到当着系统的SCN(v$database.current_scn)。 此时 ,如果查看NEXT_CHANGE#值,则是SCN所支行的最大值,281474976710655,也就是2^28 -1=281,474,976,710,656 -1 =281474976710655。


SQL> select group#,status,first_change#,next_change# from v$log;

         GROUP# STATUS             FIRST_CHANGE#    NEXT_CHANGE#
--------------- ---------------- --------------- ---------------
              1 INACTIVE          16010028041190  16010028041287
              2 INACTIVE          16010028041287  16010028041386
              3 CURRENT           16010028041386 281474976710655

SQL> select current_scn from v$database;

    CURRENT_SCN
---------------
 16010028046672

当数据库损坏(instance crash)时,oracle进行实例的recovery时,则恢复的数据库CURRENT状态log组的FIRST_CHANGE#至v$database.current_scn之间的数据值。

从当前内存查看scn,并进行相应的转换:

SQL> oradebug setmypid
Statement processed.
SQL> oradebug DUMPvar SGA kcsgscn_
kcslf kcsgscn_ [06001AE70, 06001AEA0) = A0090B26 00000E8F 00000000 00000000 0011E2E1 00000000 00000000 00000000 00000000 00000000 6001AB50 00000000
SQL> select current_scn from v$database;

    CURRENT_SCN
---------------
 16010028059450

SQL> 
SQL> select to_char('16010028059450','xxxxxxxxxxxx') from dual;

TO_CHAR('1601
-------------
  e8fa0090b3a

此处补充:oracle十进制和16进制之间的转换

十进制 到 16进制
select to_char('12','xx') from dual;
16进制 到 十进制
select to_number('7D','xxxx') from dual;

记录SCN位置和类型

数据库在不同的位置和物理文件都会记录SCN
当前SCN
v$database.current_scn

另外在控制文件 、数据文件 、redo log 、及SGA中都会记录SCN,其中SGA中的也就是current_scn。 在不同位置记录的SCN可以采用不同的标签来区分 。

此处补充:SCN TIMESTAMP DATE之间的转换

scn转换为时间戳:
SQL> select file#,scn_to_timestamp(checkpoint_change#) from v$datafile_header;

          FILE# SCN_TO_TIMESTAMP(CHECKPOINT_CHANGE#)
--------------- ---------------------------------------------------------------------------
              1 01-AUG-19 03.00.59.000000000 PM
              2 01-AUG-19 03.00.59.000000000 PM
              3 01-AUG-19 03.00.59.000000000 PM
              4 01-AUG-19 03.00.59.000000000 PM
              5 01-AUG-19 03.00.59.000000000 PM
              6 01-AUG-19 03.00.59.000000000 PM

6 rows selected.

时间戳转换为scn:
SQL> select timestamp_to_scn(scn_to_timestamp(checkpoint_change#)) from v$datafile_header;

TIMESTAMP_TO_SCN(SCN_TO_TIMESTAMP(CHECKPOINT_CHANGE#))
------------------------------------------------------
                                        16010028064443
                                        16010028064443
                                        16010028064443
                                        16010028064443
                                        16010028064443
                                        16010028064443
转换为日期格式 :

时间戳转换为日期格式

SQL> select to_char((scn_to_timestamp(checkpoint_change#)),'yyyy-mm-dd hh24:mi:ss') from v$datafile_header;

TO_CHAR((SCN_TO_TIM
-------------------
2019-08-01 15:00:59
2019-08-01 15:00:59
2019-08-01 15:00:59
2019-08-01 15:00:59
2019-08-01 15:00:59
2019-08-01 15:00:59
                                      

SCN组成:
SCN是由6个字节构成 , 为48位二进制数来记录
其中高位字节 2bytes (scn wrap) ,低位字节4bytes (scn base)

另外在控制文件 、数据文件 、redo log 、及SGA中都会记录SCN,其中SGA中的也就是current_scn。 在不同位置记录的SCN可以采用不同的标签来区分 。

控制文件的SCN
使用dump控制文件来查看控制文件记录的SCN

oradebug dump controlf 2
也可以使用命令:
alter session set events ‘immediate trace name controlf level 2’

select * from v$diag_info;

***************************************************************************
DATABASE ENTRY
***************************************************************************
 (size = 316, compat size = 316, section max = 1, section in-use = 1,
  last-recid= 0, old-recno = 0, last-recno = 0)
 (extent = 1, blkno = 1, numrecs = 1)
 05/17/2018 10:53:37
 DB Name "HSTEST"
 Database flags = 0x00404001 0x00001200
 Controlfile Creation Timestamp  05/17/2018 10:53:38
 Incmplt recovery scn: 0x0000.00000000
 Resetlogs scn: 0x0000.000e2006 Resetlogs Timestamp  05/17/2018 10:53:38
 Prior resetlogs scn: 0x0000.00000001 Prior resetlogs Timestamp  08/24/2013 11:37:30
 Redo Version: compatible=0xb200400
 #Data files = 6, #Online files = 6
 Database checkpoint: Thread=1 scn: 0x0e8f.a0095d7e
 Threads: #Enabled=1, #Open=1, Head=1, Tail=1

数据文件的SCN:
oradebug dump file_hdrs 10
alter session set events ‘immediate trace name file_hdrs level 10’;


*** 2019-08-01 17:30:57.271
DUMP OF DATA FILES: 6 files in database

DATA FILE #1:
  name #7: /app/oracle/oradata/HSTEST/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:11774 scn: 0x0e8f.a0095d7e 08/01/2019 17:01:33
 Stop scn: 0xffff.ffffffff 07/26/2019 22:40:13
 Creation Checkpointed at scn:  0x0000.00000007 08/24/2013 11:37:33
 thread:0 rba:(0x0.0.0)
 enabled  threads:  00000000 00000000 00000000 00000000 00000000 00000000
  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

数据文件的scn:
 Checkpoint cnt:11774 scn: 0x0e8f.a0095d7e 08/01/2019 17:01:33
 0x0e8f.a0095d7e

system01.dbf数据文件的checkpoint scn。
而此时:当前系统的scn为:
SQL> select to_char(current_scn,'xxxxxxxxxxxx') from v$database;
TO_CHAR(CURRE
-------------
   e8fa0096d63
### 控制文件的scn: 0x0e8f.a0095d7e
 Resetlogs scn: 0x0000.000e2006 Resetlogs Timestamp  05/17/2018 10:53:38
 Prior resetlogs scn: 0x0000.00000001 Prior resetlogs Timestamp  08/24/2013 11:37:30
 Redo Version: compatible=0xb200400
 #Data files = 6, #Online files = 6
 Database checkpoint: Thread=1 scn: 0x0e8f.a0095d7e
 Threads: #Enabled=1, #Open=1, Head=1, Tail=1
 
#####
 

redo log的scn
alter session set events ‘immediate trace name controlf level 8’;

通过dump控制文件来查看redo log的信息:
***************************************************************************
 
 
***************************************************************************
LOG FILE RECORDS
***************************************************************************
 (size = 72, compat size = 72, section max = 16, section in-use = 3,
  last-recid= 3, old-recno = 0, last-recno = 0)
 (extent = 1, blkno = 10, numrecs = 16)
LOG FILE #1: 
  name #3: /app/oracle/oradata/HSTEST/redo01.log
 Thread 1 redo log links: forward: 2 backward: 0
 siz: 0x19000 seq: 0x00002df7 hws: 0x1 bsz: 512 nab: 0xffffffff flg: 0x8 dup: 1
 Archive links: fwrd: 0 back: 0 Prev scn: 0x0e8f.a0095d2b
 Low scn: 0x0e8f.a0095d7e 08/01/2019 17:01:33
 Next scn: 0xffff.ffffffff 01/01/1988 00:00:00
LOG FILE #2: 
  name #2: /app/oracle/oradata/HSTEST/redo02.log
 Thread 1 redo log links: forward: 3 backward: 1
 siz: 0x19000 seq: 0x00002df5 hws: 0x2 bsz: 512 nab: 0x13dcb flg: 0x1 dup: 1
 Archive links: fwrd: 0 back: 0 Prev scn: 0x0e8f.a0095cc5
 Low scn: 0x0e8f.a0095cfd 08/01/2019 17:01:02
 Next scn: 0x0e8f.a0095d2b 08/01/2019 17:01:06
LOG FILE #3: 
  name #1: /app/oracle/oradata/HSTEST/redo03.log
 Thread 1 redo log links: forward: 0 backward: 2
 siz: 0x19000 seq: 0x00002df6 hws: 0x2 bsz: 512 nab: 0x15c5d flg: 0x1 dup: 1
 Archive links: fwrd: 0 back: 0 Prev scn: 0x0e8f.a0095cfd
 Low scn: 0x0e8f.a0095d2b 08/01/2019 17:01:06
 Next scn: 0x0e8f.a0095d7e 08/01/2019 17:01:33
  
  ### 分析:
  当前使用的redo log 1:
  最低的scn为0x0e8f.a0095d7e
  日志组1为 CURRENT状态
  ###

使用命令直接dump redo log的头,进行相应的分析:
alter session set events ‘immediate trace name redohdr level 2’;

*** 


####
分析 当前CURRENT状态的checkpoint SCN:
*** 2019-08-01 17:31:03.939
DUMP OF LOG FILES: 3 logs in database
LOG FILE #1:
  name #3: /app/oracle/oradata/HSTEST/redo01.log
 Thread 1 redo log links: forward: 2 backward: 0
 siz: 0x19000 seq: 0x00002df7 hws: 0x1 bsz: 512 nab: 0xffffffff flg: 0x8 dup: 1
 Archive links: fwrd: 0 back: 0 Prev scn: 0x0e8f.a0095d2b
 Low scn: 0x0e8f.a0095d7e 08/01/2019 17:01:33
 Next scn: 0xffff.ffffffff 01/01/1988 00:00:00
 FILE HEADER:
        Compatibility Vsn = 186647552=0xb200400
        Db ID=181983153=0xad8d7b1, Db Name='HSTEST'
        Activation ID=182011057=0xad944b1
        Control Seq=375602=0x5bb32, File size=102400=0x19000
        File Number=1, Blksiz=512, File Type=2 LOG
 Format ID is 2
 redo log key is 3813c65432510bcb52912b2af64a26
 redo log key flag is 5
LOG FILE #2:
  name #2: /app/oracle/oradata/HSTEST/redo02.log
 Thread 1 redo log links: forward: 3 backward: 1
 siz: 0x19000 seq: 0x00002df5 hws: 0x2 bsz: 512 nab: 0x13dcb flg: 0x1 dup: 1
 Archive links: fwrd: 0 back: 0 Prev scn: 0x0e8f.a0095cc5
 Low scn: 0x0e8f.a0095cfd 08/01/2019 17:01:02
 Next scn: 0x0e8f.a0095d2b 08/01/2019 17:01:06
 FILE HEADER:
        Compatibility Vsn = 186647552=0xb200400
        Db ID=181983153=0xad8d7b1, Db Name='HSTEST'
        Activation ID=182011057=0xad944b1
        Control Seq=375596=0x5bb2c, File size=102400=0x19000
        File Number=2, Blksiz=512, File Type=2 LOG
 Format ID is 2
 redo log key is 44314cb08b0f711f144cb9a33182d3
 redo log key flag is 5
 LOG FILE #3:
  name #1: /app/oracle/oradata/HSTEST/redo03.log
 Thread 1 redo log links: forward: 0 backward: 2
 siz: 0x19000 seq: 0x00002df6 hws: 0x2 bsz: 512 nab: 0x15c5d flg: 0x1 dup: 1
 Archive links: fwrd: 0 back: 0 Prev scn: 0x0e8f.a0095cfd
 Low scn: 0x0e8f.a0095d2b 08/01/2019 17:01:06
 Next scn: 0x0e8f.a0095d7e 08/01/2019 17:01:33
 FILE HEADER:
        Compatibility Vsn = 186647552=0xb200400
        Db ID=181983153=0xad8d7b1, Db Name='HSTEST'
        Activation ID=182011057=0xad944b1
        Control Seq=375602=0x5bb32, File size=102400=0x19000
        File Number=3, Blksiz=512, File Type=2 LOG
 Format ID is 2
 redo log key is 38397e59f45fc4eb72b6a28baa2d3949
 redo log key flag is 5
 
####

总结分析:
redo log :
low_scn 0x0e8f.a0095d7e
控制文件checkpoint scn:
0x0e8f.a0095d7e
Database checkpoint: Thread=1 scn: 0x0e8f.a0095d7e
#此处为checkpoint scn,这里的值的我们从v$datafile_header中查看到的checkpoint_change#字段的值是相同的。
数据文件 scn:
0x0e8f.a0095d7e
数据库当前的scn:
e8fa0097500

而0x0e8f.a0095d7e这个值是redo group1的low_scn,
所以控制文件和数据文件中记录到的checkpoint_scn为,redo group 2切换的scn信息,也就是redo2和redo3的信息,完成写入到控制文件和数据文件中了。

我们查看v$log中的记录:

SQL> select group# ,to_char(first_change#,'xxxxxxxxxxxx'),to_char(next_change#,'xxxxxxxxxxxx'),status from v$log
  2  ;

         GROUP# TO_CHAR(FIRST TO_CHAR(NEXT_ STATUS
--------------- ------------- ------------- ----------------
              1   e8fa0095d7e  ffffffffffff CURRENT
              2   e8fa0095cfd   e8fa0095d2b INACTIVE
              3   e8fa0095d2b   e8fa0095d7e INACTIVE

此时CURRENT状态的start_scn为:e8fa0095d7e

数据库当前的scn:

SQL> select to_char(current_scn,'xxxxxxxxxxxx') from v$database;

TO_CHAR(CURRE
-------------
  e8fa0097500

查看数据文件头中的start scn:
(存于数据文件头中)执行checkpoint时,Oracle会更新存放在各个实际的数据文件头的Start SCN(注意绝对不会是控制文件中),这个SCN存在的目的是用于检查数据库启动过程中是否需要做media recovery(介质恢复)
start_scn: 检查是否要做media_recovery
select checkpoint_change# from v$datafile_header;
当这个值小于控制文件中的值,则需要进行media recovery,执行数据文件的恢复。

查看控制文件中数据文件的end scn:
(存于控制文件中)每一个所记录的数据文件头都有一个对应的End SCN,这个End SCN一定是存在于控制文件当中。这个SCN存在的绝对意义主要是用来去验证数据库启动过程中是否需要做instance recovery(实例恢复)。
end_scn: 检查是否要做instance recovery(实例恢复)
select name,last_change# from v$datafile
当为空时,则不需要进行instance_recovery

数据文件的checkpoint scn,则表示在此之前的数据已经全部写入到磁盘中0x0e8f.a0091feb, 如果发生instacne crash,则只需要进行此检查点之后的数据即可。
也就是说:redo group2和3记录事务,产生的buffer cache中的数据已全部写入到数据文件当中,如果发生 instance_crash,数据库先使用redo group1和来进行前滚,之后再撤销uncommitted的事务,进行回滚。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值