什么是SCN?
SCN即system change number,是一个用来维护数据改变版本的数字。其实可以等同于我们所认知的时间,但是若使用我们习惯的时间格式来做比较,数据库的工作量会很大。基于这一点,Oracle将每个时间转换成一个SCN号,使用SCN比较时间先后。SCN号可以和时间互相转换。
SCN的特征
1.SCN和时间相关联,可互相转换
2.SCN只会增加,而不会减少。即使调整数据库服务器的时间,SCN依旧增长
3.SCN号与时间的对应关系,同数据库关联。即不同的数据库服务器,同样的SCN号,对应的时间不一定相同
SCN号的作用是用来表示时间新旧。SCN号有个最大值,一个正常的数据库预备的SCN号可以使用500年,然而有些事故的发生会触发Oracle的某些bug,仍然可能导致SCN号猛增而到达上限,一旦出现这种事故,只能重建数据库。
SCN的类型
1.系统SCN号(检查点SCN)
控制文件记录系统SCN号,标识数据库当前的系统时间
2.文件SCN号、起始SCN
每个数据文件头部记录着一个SCN,叫做起始SCN
控制文件记录数据文件的结构,以及数据文件的文件SCN及终止SCN
正常运行期间,系统SCN=文件SCN=起始SCN
3.终止SCN号
数据库正常关闭,系统SCN=文件SCN=起始SCN=终止SCN
数据库正常打开,系统SCN、文件SCN、起始SCN相同,而终止SCN为NULL。终止SCN可用来判断数据库是否正常关闭。
当数据库非正常关闭时,很多数据不能及时写入磁盘,包括应写入控制文件的信息,终止SCN为NULL,数据库再次启动时,SMON进程检查控制文件记录的SCN号,发现终止SCN为NULL后,知道数据库上次未进行正常关闭,SMON马上对数据库进行崩溃恢复;对于文件SCN,若数据库关闭期间进行了一个数据文件的restore,那么控制文件记录的数据文件的文件SCN肯定要新于restore的数据文件中的起始SCN,在数据库打开的时候,Oracle检测到数据文件是旧的,那么我们需要对数据文件进行recover,恢复到控制文件中与其它数据文件相同的状态;系统SCN号代表数据库的最新状态,用来判断文件是否是最新的。
4.日志条目SCN
数据库server process对表的buffe进行DML操作时会产生日志,对每一行数据进行的每一次修改都会产生一条redo log,每条redo log记录着产生日志的时间,即操作发生的时间。数据库进行恢复的时候,根据redo log的SCN按操作发生的先后顺序进行恢复,即先将日志条目按SCN排好序,再进行恢复
5.first SCN、next SCN
对于current redo日志文件,first SCN记录着该文件中最早的日志的SCN,而next SCN为NULL,当日志写满该文件后,切换到下一组,这时,下一组文件成为current,之前的current成为active,写入新的current文件的最早的日志的SCN记入current文件的first SCN,同时记入上一组日志的next SCN。通过first SCN和next SCN可以将日志串联起来,同时记录着一组日志文件中日志产生的SCN的范围
6.提交SCN
每个事物提交时,log buffer写入事务提交时的系统SCN
检查更新数据库中的SCN由检查点进程CKPT完成,一般来讲,redolog中的SCN要大于数据库中的SCN,虽然redolog记录的SCN新于数据库,但是对于一个正常运行的数据库,系统SCN,文件SCN以及数据文件中的起始SCN仍然一致,SCN号存在的意义就是为了保证数据库的一致性,因此没必要实时更新,并且实时更新对CKPT会产生相当大的工作负载。正常运行期间,系统SCN与控制文件及数据文件中记录的SCN均为redolog file中最早的组(ACTIVE)的first SCN,当redolog file全部用完,需要覆盖使用时,CKPT会将数据库中一切的SCN号更新为覆盖之后的文件的first SCN,将数据库全部刷新,而数据库下次刷新则是在这个文件再次被覆盖的时候。另外,redolog file被归档也会触发CKPT。
查看SCN
1.查看系统SCN号
select a.CHECKPOINT_CHANGE# from v$database a;
2.查看控制文件记录的数据文件的文件SCN和终止SCN
select CHECKPOINT_CHANGE#,LAST_CHANGE# from v$datafile ;
3.查看数据文件头部记录的起始SCN
select CHECKPOINT_CHANGE# from v$datafile_header;
我们可以看出,数据库中的SCN号一致,由于数据库处于运行期间,故控制文件中的last_change#并未记录信息,为NULL
4.查看redolog file的SCN
select group#,status,first_change#,next_change# from v$log;
第二组文件为current,故next_change#标识为无穷大
由于数据库自开启自现在,一直在使用2号redolog file,故系统SCN及数据库SCN保持着current redo的first_change#
接下来我们切换两次日志
SQL> alter system switch logfile;
System altered.
SQL> /
System altered.
现在2号文件状态为ACTIVE,而CURRENT 文件变成了1号,数据库SCN此时并未改变。一段时间后,ACTIVE被归档,如下图,
此时,再查看数据库的SCN,统一更新为6940929
5.查看归档日志的SCN
select a.SEQUENCE#,a.FIRST_CHANGE#,a.NEXT_CHANGE# from v$archived_log a;
使用LogMiner挖掘日志中的SCN
SCN与时间的相互转换
1.查询当前系统的SCN,即使用timestamp_to_scn将system转换成SCN
select dbms_flashback.get_system_change_number SCN1,timestamp_to_scn(sysdate) SCN2 from dual;
2.使用scn_to_timestamp将SCN转换成时间
select to_char(scn_to_timestamp(6940259),'YYYY-MM-DD HH24:MI:SS') from dual;