oracle026
系统改变号(SCN)的详解
SCN 系统改变号,是通过某些函数把时间产生某个数;确保数据文件的一致性,比较先后,新旧;
为什么使用时间产生数字,因为在比较时间的比较慢,而用数字就相对的块点,就像shared pool 比较sql的
使用算出的hash值进行比较。
select dbms_flashback.get_system_change_number,
SCN_TO_TIMESTAMP(dbms_flashback.get_system_change_number) from dual;
//获取当前时间的SCN的值,dual是一张临时表类似于MYSQL的temp表的用处。
1153633 22-12月-14 03.04.02.000000000 上午
控制文件中有三个SCN:开始SCN 结束SCN 和文件SCN
文件SCN是针对于每个数据文件产生的文件SCN号
文件SCN是针对于每个数据文件产生的结束SCN号
在每个数据文件前有一个开始SCN
在数据库正常的时候结束SCN时NULL的 ,而文件的开始SCN、文件SCN、和系统SCN号是相同的
当数据库关闭的时候,系统、文件、结束、开始都是一样的,
当非正常关闭,结束SCN为空,由于没有及时保存信息;当下一次数据开启的时候。就会
检查到数据时非正常关闭,就会做数据实例的恢复工作:需要redo log部分日志、控制文件LRBA、HRBA、ON DISK RBA
当我们把数据文件换了旧的文件,当系统检测到了旧文件的开始SCN和和结束SCN不一样就需要进行数据恢复做:
跑日志:把SCN跑成新的
提升SCN
查看几个SCN:
select checkpoint_change# from v$database; //系统SCN,存在于每个控制文件
1148314
select name,checkpoint_change# from v$datafile;//文件SCN,存在于每个控制文件
/u01/app/oracle/oradata/jiagulun/system01.dbf 1148314
/u01/app/oracle/oradata/jiagulun/sysaux01.dbf 1148314
/u01/app/oracle/oradata/jiagulun/undotbs01.dbf 1148314
/u01/app/oracle/oradata/jiagulun/users01.dbf 1148314
/u01/app/oracle/oradata/jiagulun/example01.dbf 1148314
select name,last_change# from v$datafile;//结束SCN,存在于每个控制文件
/u01/app/oracle/oradata/jiagulun/system01.dbf
/u01/app/oracle/oradata/jiagulun/sysaux01.dbf
/u01/app/oracle/oradata/jiagulun/undotbs01.dbf
/u01/app/oracle/oradata/jiagulun/users01.dbf
/u01/app/oracle/oradata/jiagulun/example01.dbf
select name ,checkpoint_change# from v$datafile_header//文件头SCN,存在于每个数据文件的头部
/u01/app/oracle/oradata/jiagulun/system01.dbf 1148314
/u01/app/oracle/oradata/jiagulun/sysaux01.dbf 1148314
/u01/app/oracle/oradata/jiagulun/undotbs01.dbf 1148314
/u01/app/oracle/oradata/jiagulun/users01.dbf 1148314
/u01/app/oracle/oradata/jiagulun/example01.dbf 1148314
redo日志文件有一个first SCN 和一个next SCN
first、next 是这个文件中日志记录的范围
每个日志的条目都有一个SCN;可以把frist SCN号当做这个文件第一条记录的SCN号,把next SCN号当做下一个文件日志中记录的开始SCN号
select * from v$log;
名称 空值 类型
------------- -- ------------
GROUP# NUMBER //日志组
THREAD# NUMBER
SEQUENCE# NUMBER //唯一标识
BYTES NUMBER
BLOCKSIZE NUMBER
MEMBERS NUMBER
ARCHIVED VARCHAR2(3)
STATUS VARCHAR2(16) //状态:active,inactive,current
FIRST_CHANGE# NUMBER //first SCN,而下一个日志的开始就是上一个日志的next SCN (在10g的时候是这么认为的)
FIRST_TIME DATE
NEXT_CHANGE# NUMBER //next SCN(10g不一样)
NEXT_TIME DATE
1 1 10 52428800 512 1 NO INACTIVE 1108520 21-12月-14 1148313 22-12月-14
2 1 11 52428800 512 1 NO CURRENT 1148313 22-12月-14 281474976710655
3 1 9 52428800 512 1 NO INACTIVE 1087024 21-12月-14 1108520 21-12月-14
做一个实验:
1. select * from v$log;
1 1 10 52428800 512 1 NO INACTIVE 1108520 21-12月-14 1148313 22-12月-14
2 1 11 52428800 512 1 NO ACTIVE 1148313 22-12月-14 1156305 22-12月-14
3 1 12 52428800 512 1 NO CURRENT 1156305 22-12月-14 281474976710655
2. alter system switch logfile;
3. alter system switch logfile;
4. select * from v$log;
1 1 13 52428800 512 1 NO ACTIVE 1157154 22-12月-14 1157173 22-12月-14
2 1 14 52428800 512 1 NO CURRENT 1157173 22-12月-14 281474976710655
3 1 12 52428800 512 1 NO ACTIVE 1156305 22-12月-14 1157154 22-12月-14
5. select name , last_change# from v$datafile;
/u01/app/oracle/oradata/jiagulun/system01.dbf 1157173
/u01/app/oracle/oradata/jiagulun/sysaux01.dbf 1157173
/u01/app/oracle/oradata/jiagulun/undotbs01.dbf 1157173
/u01/app/oracle/oradata/jiagulun/users01.dbf 1157173
/u01/app/oracle/oradata/jiagulun/example01.dbf 1157173
会发现数据文件中、数据文件头的SCN没有变化,而日志中的SCN的值发生了变化。由于在控制文件中、数据文件头的SCN的主要目的是控制
数据文件的一致性
active表示日志文件中对应脏缓冲区还未写入数据库,不能被覆盖,也就说明需要进行实例恢复。
再做个试验:
1. alter system flush buffer_cache;//冲刷缓冲区数据
2. select name , checkpoint__change# from v$datafile;
/u01/app/oracle/oradata/jiagulun/system01.dbf 1157173
/u01/app/oracle/oradata/jiagulun/sysaux01.dbf 1157173
/u01/app/oracle/oradata/jiagulun/undotbs01.dbf 1157173
/u01/app/oracle/oradata/jiagulun/users01.dbf 1157173
/u01/app/oracle/oradata/jiagulun/example01.dbf 1157173
3. select * from v$log;
1 1 13 52428800 512 1 NO INACTIVE 1157154 22-12月-14 1157173 22-12月-14
2 1 14 52428800 512 1 NO CURRENT 1157173 22-12月-14 281474976710655
3 1 12 52428800 512 1 NO INACTIVE 1156305 22-12月-14 1157154 22-12月-14
上面的数据你会发现当把buffer cache中数据flush掉以后,控制文件、数据文件中的SCN都没有变化,只有日志文件中的状态变了
是由于原本缓冲区的脏数据被清空了,那么它所对应的日志可以变成可以覆盖的了,也就是inactive了
而且在文件头部、控制文件中的SCN的值是记录着日志文件中的ACTIVIE/CURRENT的SCN的值等于最老的redo log中的active的日志
其实控制文件中的SCN是用来定位哪个文件跑日志,而在控制文件中的LRBA是确定从哪里开始跑日志
注意:增量检查点并不会去更新数据文件头,以及控制文件中数据库SCN以及数据文件条目的SCN信息,而只是每3秒由CKPT进程去 更新控制文件中的low cache rba信息,也就是检查点的位置。
那么他们是在什么时候会进行更新呢?
结束SCN时在数据库正常关闭的时候进行更新
其他的SCN是在日志文件的状态从active变成inactive的时候才进行更新的,上面的测试可以证明
fast_start_mttr_target:这个参数是用来设置实例在恢复的时间,因为在个值将会影响DBWR的写数据库频率,
把恢复的时间缩短,说明脏数据少了,那是因为写的频率大。
1、SCN的意义?system change number
时间 先后、新旧 select dbms_flashback.get_system_change_number, SCN_TO_TIMESTAMP(dbms_flashback.get_system_change_number) from dual; 2、常见的SCN 控制文件 系统SCN select checkpoint_change# from v$database; 文件SCN select name,checkpoint_change# from v$datafile; 结束SCN select name,last_change# from v$datafile; 检查点信息 增量检查点并不会去更新数据文件头,以及控制文件中数据库SCN以及数据文件条目的SCN信息,而只是每3秒由CKPT进程去 更新控制文件中的low cache rba信息,也就是检查点的位置。 select CPDRT,CPLRBA_SEQ||‘.‘||CPLRBA_BNO||‘.‘||CPLRBA_BOF "Low RBA",CPODR_SEQ||‘.‘||CPODR_BNO||‘.‘||CPODR_BOF "On disk RBA",CPODS,CPODT,CPHBT from x$kcccp; CPDRT列是检查点队列中的脏块数目. CPODS列是on disk rba的scn CPODT列是on disk rba的时间戳 CPHBT列是心跳 数据文件头部 开始SCN select name,checkpoint_change# from v$datafile_header; 数据块头部ITL事务槽 日志change vector中 跑日志、空跑日志 回滚段事务表中 日志文件头部 first、next select recid,sequence#,first_change#,next_change# from v$log_history where rownum<6; select * from v$log; select * from v$archived_log 3、实例恢复 只是需要redo log:active、current 实例恢复判断依据 演示SCN变化 如果发生了实例崩溃,只需要在日志文件中找到检查点位置(low cache rba),从此处开始应用所有的重做日志文件,就完成了前滚操作。实例崩溃后,再次启动数据库,oracle会到控制文件中读取low cache rba,这就是检查点位置。从此处开始应用重做日志,应用到on disk rba的位置。on disk rba是磁盘中重做日志文件的最后一条重做记录的rba。 4、fast_start_mttr_target 相关操作 select checkpoint_change# from v$database alter system checkpoint alter system switch logfile select name,checkpoint_change# from v$datafile select name,checkpoint_change# from v$datafile_header select * from v$log; begin for i in 1..10000 loop insert into t2 values(1,‘xkj‘); commit; end loop; end; select * from t2 alter system flush buffer_cache |