【SCN】Oracle SCN 详细介绍时间:2022-09-30 16:07:25> 本文主要对Oracle scn 结构进行学习,以便掌握相关知识 -- by firsouler 2022/3/9 #### SCN介绍 SCN的最大值是0xffff.ffffffff,从Oracle 12c开始,SCN编号是一个8字节的编号。 SCN是一个6字节(48bit)的数字,其值为281,474,976,710,656(2^48),分为2个部分 - 1. SCN_BASE : 是一个4字节(32bit)的数字 - 2. 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可以通过以下查询获得: ``` sql 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号存放在控制文件中。 ``` sql select checkpoint_change# from v$database; ``` ##### Datafile Checkpoint SCN 当checkpoint完成后,Oracle将Datafile Checkpoint SCN存放在控制文件中。 ``` sql select name,checkpoint_change# from v$datafile; ``` ##### Start SCN Oracle将Start SCN存放在数据文件头中。这个SCN用于检查数据库启动过程是否需要做media recovery。 ``` sql 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. ``` sql 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信息 ``` sql --查看系统大小端 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