本文主要对Oracle scn 结构进行学习,以便掌握相关知识 – by firsouler
SCN介绍
SCN的最大值是0xffff.ffffffff,从Oracle 12c开始,SCN编号是一个8字节的编号。
SCN是一个6字节(48bit)的数字,其值为281,474,976,710,656(2^48),分为2个部分
-
- SCN_BASE :
是一个4字节(32bit)的数字
- SCN_BASE :
-
- SCN_WRAP :
是一个2字节(16bit)的数字
每当SCN_BASE达到其最大值(2^32 = 4294967296)时,SCN_WRAP增加1,SCN_BASE将被重置为0,一直持续到SCN_WRAP达到其最大值,即2^16 = 65536。
SCN =(SCN_WRAP * 4294967296)+ SCN_BASE
SCN随着每个事务的完成而增加。
提交不会写入数据文件,也不更新控制文件。
当发生checkpoint时,控制文件更新,SCN被写入到控制文件。
当前的SCN可以通过以下查询获得:
- SCN_WRAP :
select dbms_flashback.get_system_change_number scn from dual;
--or
select current_scn from v$database;
四种重要的SCN
数据变化如何写入
- 第一步:事务开始;
- 第二步:在buffer cache中找到需要的数据块,如果没找到,从数据文件中载入buffer cache- 中;
- 第三步:事务修改buffer cache的数据块,该数据被标识为“脏数据”,并被写入log buffer中;
- 第四步:事务提交,LGWR进程将log buffer中的“脏数据”的日志条目写入redo log file中;
- 第五步:当发生checkpoint,CKPT进程更新所有数据文件的文件头中的信息,DBWn进程则负责将Buffer Cache中的脏数据写入到数据文件中。
系统检查点(System Checkpoint)SCN
当checkpoint完成后,ORACLE将System Checkpoint SCN号存放在控制文件中。
select checkpoint_change# from v$database;
Datafile Checkpoint SCN
当checkpoint完成后,Oracle将Datafile Checkpoint SCN存放在控制文件中。
select name,checkpoint_change# from v$datafile;
Start SCN
Oracle将Start SCN存放在数据文件头中。这个SCN用于检查数据库启动过程是否需要做media recovery。
select name,checkpoint_change# from v$datafile_header;
Stop SCN
ORACLE将StopS CN存放在控制文件中。当数据库处在打开状态时,stop scn被设成最大值0xffff.ffffffff。在数据库正常关闭过程中,stop scn被设置成当前系统的最大scn值。在数据库打开过程中,Oracle会比较各文件的stop scn和checkpoint scn,如果值不一致,表明数据库先前没有正常关闭,需要做instance recovery.
select name,last_change# from v$datafile;
如果有表空间read only,那么该表空间的所有datafile的start SCN和stop SCN将被冻结,这个时候就跟System Checkpoint SCN不一致.
如果控制文件不是当前的控制文件,则System checkpoint会小于Start SCN或END SCN号。记录这些SCN号,可以区分控制文件是否是当前的控制文件.
查看不同系统 scn信息
--查看系统大小端
select * from v$transportable_platform;
--linux 前4个字节是scn base,后四个是scn WRAP
SQL> oradebug setmypid
Statement processed.
SQL> oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [060017008, 060017038) = 000B49DD 00000000 00000000 00000000 000169BF 00000000 00000000 00000000 00000000 00000000 60016CE8 00000000
--windows 和大端 前4个是scn wrap,后四个字节是scn base
SQL> oradebug setmypid
已处理的语句
SQL> oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [59852C8, 59852E8) = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 059850C0
关于字节
16进制 一个字节是2位, 4个字节正好是8位 也就是我们能看到8个0。1个字节对应两个16进制数位,16进制是0-F。一个字节可以存8个二进制数位,数据库存储以字节Bytes为单位,传输以位(bit)为单位,一个位代表0或1,每8个位组成一个字节。
参考
- https://www.cnblogs.com/muzisanshi/p/11940266.html
- https://blog.csdn.net/u013820054/article/details/39899111




