当前位置: 首页 > 科技观察

Oracle安全:SCN的可能最大值和耗尽问题_0

时间:2023-03-22 16:22:33 科技观察

在2012年第一季度的CPU补丁中,包含了一个关于SCN修正的重要变化。增长导致数据库中的所有事务停止。由于SCN无法回滚,因此必须重建数据库才能重新使用。我在下面的链接中描述了这个问题:  http://www.eygle.com/archives/2012/03/oracle_scn_bug_exhaused.html  Oracle使用6Bytes记录SCN,也就是48位,它的最大值为:  SQL>colscnfor999,999,999,999,999,999  SQL>selectpower(2,48)scnfromdual;  SCN  ---------------------  281,474,976,710,656  Oracle内部控制SCN每秒的增加或减少以不超过16K。根据这个计算,这个值可以使用大约544年:  SQL>selectpower(2,48)/16/1024/3600/24/365fromdual;  POWER(2,48)/16/1024/3600/24/365  -------------------------------  544.770078  但是,当出现异常时,尤其是使用DBLink跨库查询时,SCN会同步,如下链接中,我曾经描述过这个问题:  http://www.eygle.com/archives/2006/11/db_link_checkpoint_scn.html  一个数据库当前最大可能的SCN称为“最大合理SCN”,其值可以这样计算:'YYYY')-1988  )*12+  to_char(sysdate,'mm')-1  )*31+to_char(sysdate,'dd')-1  )*24+to_char(sysdate,'hh24')  )*60+to_char(sysdate,'mi')  )*60+to_char(sysdate,'ss')  )*to_number('ffff','XXXXXXXX')/4scn  fromdual  /  这个算法就是SCN算法。它从1988年1月1日00:00:00开始,每秒计算1点。SCN最大为16K。  此内容可参考以下链接:  http://www.eygle.com/archives/2006/01/how_big_scn_can_be.html  在CPU补丁中,Oracle提供了脚本scnhealthcheck.sql用于查看数据库当前SCN的剩余状态。  脚本的算法和上面描述的一样,最后用最大合理SCN减去当前数据库SCN,计算出一个指标:HeadRoom。也就是SCN剩余的头部空间,最后换算成天数:下面是这个脚本的内容:  Rem  Rem$Header:rdbms/admin/scnhealthcheck.sqlst_server_tbhukya_bug-13498243/82012/01/1703:37:18tbhukyaExp$  Rem  Remscnhealthcheck.sql  Rem  RemCopyright(c)2012,Oracleand/oritsaffiliates.Allrightsreserved.  Rem  RemDESCRIPTION  RemChecksscnhealthofaDB  Rem  RemNOTES  Rem。  Rem  Rem  defineLOWTHRESHOLD=10  defineMIDTHRESHOLD=62  defineVERBOSE=FALSE  setverioff;  设置反馈关闭;  setserverouton  DECLARE  verboseboolean:=&&VERBOSE;  Begin  forcin(  select  version,  Date_time, DBMS_FLASHBACK.GEG_SYSTEM_CHANGE_NUMBERCURRENT_SCN,  INDICATOR  from  ,  to_char(SYSDATE,'YYYY/MM/DDHH24:MI:SS')DATE_TIME,  ((((  ((to_number(to_char(sysdate,'YYYY'))-1988)*12*31*24*60*60)+  ((to_number(to_char(sysdate,'MM'))-1)*31*24*60*60)+  (((to_number(to_char(sysdate,'DD'))-1))*24*60*60)+  (to_number(to_char(sysdate,'HH24'))*60*60)+  (to_number(to_char(sysdate,'MI'))*60)+  (to_number(to_char(sysdate,'SS')))  )*(16*1024))-dbms_flashback.get_system_change_number)  /(16*1024*60*60*24)  )指标  fromv$instance  )  )LOOP  dbms_output.put_line('--------------------------------------------------'  ||'--------');  dbms_output.put_line('ScnHealthCheck');  dbms_output.put_line('--------------------------------------------------'  ||'---------');  dbms_output.put_line('CurrentDate:'||C.date_time);  dbms_output.put_line('CurrentSCN:'||C.current_scn);  if(详细)then  dbms_output.put_line('SCNHeadroom:'||round(C.indicator,2));  结束;  dbms_output.put_line('版本:'||C.version);  dbms_output.put_line('--------------------------------------------------'  ||'--------');  IFC.version>'10.2.0.5.0'and  C.versionNOTLIKE'9.2%'THEN  IFC.indicator>&MIDTHRESHOLDTHEN  dbms_output.put_line('Result:A-SCNHeadroomisgood');  dbms_output.put_line('Applythelatestrecommendedpatches');  dbms_output.put_line('basedonyourmaintenanceschedule');  IF(C.version<'11.2.0.2')THEN  dbms_output.put_line('ANDset_external_scn_rejection_threshold_hours='  ||'24afterapply.');  结束;  ELSIFC.indicator<=&LOWTHRESHOLDTHEN  dbms_output.put_line('Result:C-SCNHeadroomislow');  dbms_output.put_line('Ifyouhavenotalreadydonesoapply');  dbms_output.put_line('thelatestrecommendedpatchesrightnow');  IF(C.version<'11.2.0.2')THEN  dbms_output.put_line('set_external_scn_rejection_threshold_hours=24'  ||'afterapply');  结束;  dbms_output.put_line('ANDcontactOraclesupportimmediately.'); ELSE  dbms_output.put_line('Result:B-SCNHeadroomislow');  dbms_output.put_line('Ifyouhavenotalreadydonesoapply');  dbms_output.put_line('thelatestrecommendedpatchesrightnow');  IF(C.version<'11.2.0.2')THEN  dbms_output.put_line('ANDset_external_scn_rejection_threshold_hours='  ||'24afterapply.');  结束;  结束;  ELSE  IFC.indicator<=&MIDTHRESHOLDTHEN  dbms_output.put_line('Result:C-SCNHeadroomislow');  dbms_output.put_line('Ifyouhavenotalreadydonesoapply');  dbms_output.put_line('thelatestrecommendedpatchesrightnow');  IF(C.version>='10.1.0.5.0'and  C.version<='10.2.0.5.0'and  C.versionNOTLIKE'9.2%')THEN  dbms_output.put_line(',set_external_scn_rejection_threshold_hours=24'  ||'afterapply');  结束;  dbms_output.put_line('ANDcontactOraclesupportimmediately.');ELSE  dbms_output.put_line('Result:A-SCNHeadroomisgood');  dbms_output.put_line('Applythelatestrecommendedpatches');  dbms_output.put_line('basedonyourmaintenanceschedule');  IF(C.version>='10.1.0.5.0'and  C.version<='10.2.0.5.0'and  C.versionNOTLIKE'9.2%')THEN  dbms_output.put_line('ANDset_external_scn_rejection_threshold_hours=24'  ||'申请后。');  结束;  结束;  结束;  dbms_output.put_line(  'ForfurtherinformationreviewMOSdocumentid1393363.1');  dbms_output.put_line('----------------------------------------------------'  ||'--------');  结束循环;  结束;  /  应用补丁后,引入一个新的隐式参数_external_scn_rejection_threshold_hours,通常设置为24小时:  _external_scn_rejection_threshold_hours=24  此设置减少了SCNHeadroom的余量。之前默认设置的容量至少是31天,现在减少到24小时,可以增加SCN允许增长的合理空间。  但如果放任不管,SCN还是有可能超出最大合理范围,导致数据库出现问题。  这个问题的影响会非常严重。建议用户查看当前数据库的SCN使用情况。以下是检查脚本的输出示例:  ------------------------------------  ScnHealthCheck  --------------------------------  CurrentDate:2012/01/1514:17:49 CurrentSCN:13194140054241  版本:11.2.0.2.0  ----------------------------------------  结果:C-SCNHeadroomislow  如果您还没有准备好,那么立即应用  最新推荐的补丁  并立即联系Oracle支持。  有关更多信息,请查看MOS文档id1393363。----  这个问题在客户环境中已经出现,需要引起足够的重视。【编者推荐】如何在Oracle中使用Java存储过程(详解)Longwaygo从DB2迁移到Oracle11条重要的数据库设计规则10条让数据库更快的建议20条数据库设计最佳实践