在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条数据库设计最佳实践
