25、SCN_1
SCN(system change number)系统改变号
对于oracle数据库来讲,在很多地方都需要用先后顺序来进行比较,比如时间(年月日、时分秒),计算机将时间转为数字来进行比较
在计算机里面,有很多地方需要知道先后顺序,它就用一个数字(SCN号)来进行比较;但是我们已经习惯用时间来进行比较,所以我们可以把SCN号转换为时间,也可以将时间转换为SCN号来进行比较
SCN号的几个特征
1、SCN确实与时间有关系,可以互相转换;
2、SCN只能增加,从来不会减少,即使把系统的时间调了,它也是往后增长的;
3、SCN号和时间的对应关系是和某个数据库关联起来的(比如同一个SCN号,对于A数据库来说,转换为时间是:2016.01.14;而对于B数据库来说,转换为时间可能就是:2013.02.15);
SCN号的作用:是用来表示新旧的
对于数据来讲,默认的SCN号,可以用500年,但是,有一些情况:就是SCN在某些情况下会暴涨,暴涨以后,SCN号用尽了(SCN号有一个最大值),没有SCN号了,这时候,这个数据库就只能重建了
oracle数据库哪些地方有SCN号?
在控制文件里面的SCN号:
1、系统SCN号
2、文件SCN号
3、终止SCN号
控制文件(controlfile):
1、数据库的物理结构
2、系统的SCN号(整个数据库里有的一个SCN):可以记录数据库当前的系统时间
图解:
一个控制文件,有一个系统SCN号,然后控制文件有一个数据库的物理结构,物理结构有一些数据文件(1、2、3、4号文件),对于每一个数据文件在控制文件里面都有一行信息,然后对于每一个数据文件的右侧,有一个文件的SCN号,后面还有一个终止SCN号;
控制文件中的4个文件SCN号一样的话,说明4个文件一样新;然后数据文件中的起始SCN号和控制文件中文件SCN号一样的话,说明数据文件里面记录的数据和控制文件中的数据是一样的(一样新)
对于终止SCN号有两种情况:
1、数据库正常关闭的情况下,系统SCN号、文件SCN号、起始SCN号、终止SCN号,这四个SCN号是一样的;
2、数据库正常打开的情况下,统统SCN号 = 文件SCN号 = 起始SCN号,终止SCN号 = null
终止SCN号的作用:可以用来判断数据库是否是正常关闭
在数据文件(datafile)里面的SCN号:
1、起始SCN号
图解:
在每一个数据文件的头部有一个起始SCN号
正常情况下(数据库正常运行的情况下):控制文件里面的系统SCN号等于文件SCN号等于数据文件里面的起始SCN,控制文件中的终止SCN等于NULL(空)
在数据库里面SCN号的作用:
1、非正常关闭:数据库突然崩了,突然把服务器的电源拔了,然后很多信息还没来得及写到控制文件中去,这时候,终止SCN号都是null;数据库再重启启动的时候,smonitor会去检查,发现在控制文件中终止SCN号是null,smonitor就知道上一次数据库没有正常关闭,smonitor就需要对数据库做崩溃恢复;
2、现在把数据库关了,关了以后,把以前备份的数据文件(以前备份的数据文件的SCN号小于现在数据文件的SCN号)覆盖了新的数据文件1,数据库再次打开的时候,smonitor就会发现控制文件中的文件SCN号大于数据文件中的SCN号,smonitor就知道在数据库关闭期间,用旧的文件替换了新的文件,这时候smonitor就会利用日志做一下前滚,把文件更新过来;
3、假设当前4个数据文件,把3、4号文件做成read only(只读文件),就表示这两个文件永远不会更新了,3、4号文件的SCN号就永远都是小的,旧的,这时候就需要使用系统SCN号来判断另外的数据文件是不是最新的,因为里面的数据文件,有的是新的,有的是旧的,系统SCN号永远是最新的
redo log日志文件中的SCN号:
1、每条日志有一个日志条目SCN号
2、first SCN号
3、next SCN号
图解(日志条目SCN号):
每一条redo log后面都会记录着SCN号,比如server process1在buffer里面修改了一个数据,就会在redo log里面记录下来,相对应的也要记录下对应的SCN号(说明是server process1修改的),server process2也在buffer里面修改了一个数据,也要相对应的记录下对应的SCN号,server process3也在buffer里面修改了一个数据,也记录下来对应的SCN号;如果要恢复数据了,就根据这个SCN号去找到相对应的日志记录进行恢复;日志的记录有一个先后顺序,所以在恢复数据的时候,也要按照这个日志的先后顺序进行恢复,先记录的日志先恢复,后记录的日志后恢复;
还有一种情况:就是两个进程同时进行数据的修改,日志是在各自的PGA里面生成的,有可能就是日志的SCN号:SCN号=1在server process1,SCN号=2在server process2,SCN号=3在server process1,SCN号=4在server process2......然后产生的日志不是按照时间的先后顺序排列的,往redo log里面存日志的时候,server process1存它自己的,server process2存它自己的,;所以在读日志的时候,需要先按照SCN号排好序,然后再去恢复
图解:
redo log里面,有一个first SCN号和一个lost SCN号,first SCN号是redo log里面的第一条日志的SCN号,然后往里面写日志,这个redo log用完了,就用下一个redo log;正在使用期间的redo log的状态叫做current(当前状态),对于当前正在使用的redo log里面的next SCN号是null(空的),因为还没写到最后一条日志,然后写写写,写完以后,开始用下一个日志文件,上一个日志文件的next SCN号就等于下一个日志文件的first SCN号,那么这两个日志是连续的;然后以后通过first SCN号和next SCN号就可以知道日志文件里面,SCN的一个范围
这里,controlfile(控制文件)里面同时会记录着当前(current)的redo log文件是谁
提交SCN号
在每一个事务提交的时候,在事物的后面也会有一个SCN号,会在redo log里面记录下(比如sp1对t1做的一个事务),记录事务的提交时间
归档日志的SCN号
图解:
假设现在把数据库关了,关了以后,把以前备份的一个非常老的数据文件(以前备份的数据文件的SCN号小于现在数据文件的SCN号)替换了新的数据文件,数据库再次打开的时候,smonitor就会发现控制文件中的文件SCN号大于数据文件中的SCN号,这时候就需要恢复;
恢复有两种情况:第一种情况,是在redo log里面能找到,现在有三个redo log,3号是current日志文件;假设替换掉的数据文件的SCN号是100,然后2号redo log的first SCN是80,next SCN是130,3号redo log的first SCN是130,所以我们知道,对于替换掉的数据文件,只需要2号redo log和3号redo log就可以将数据文件恢复到最新的;
然后假设替换掉的数据文件的SCN号是10,1号redo log的first SCN是60,next SCN是80,2号redo log的first SCN是80,next SCN是130,3号redo log的first SCN是130,那么一看,使用redo log就不能让它变成最新的,然后就找arch(归档日志文件),找到2号归档日志文件的first SCN是6,next SCN是30,然后就从2号归档日志开始恢复,恢复到60,然后又使用redo log里60开始的恢复,一直恢复到最新的数据
图解:
现在3号redo log用完了,next SCN是180,就要返回1号redo log使用,然后将1号redo log的first SCN和next SCN替换掉,first SCN替换成180,next SCN替换为null;然后系统SCN和文件SCN原来是60,现在也要被替换成180,换成最新的SCN号,数据文件的头部SCN也替换成180;然后接着覆盖2号redo log文件,有覆盖3号redo log文件,在覆盖使用的这个过程中,系统和文件的SCN就保持为180,不替换,然后再下次3号redo log覆盖1号redo log的时候,再替换为最新的;这些SCN号其实就是为了保持系统、控制文件、数据文件、redo log里面的这些SCN号是一样的,但不一定是最新的