# Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. # ## **************************************************************************** ## * RECOVER.BSQ is now a DERIVED OBJECT. If you are editing * ## * .../rdbms/admin/recover.bsq, STOP and edit * ## * .../rdbms/src/client/tools/rcvman/recover.txt instead. recover.bsq is * ## * derived from recover.txt, and any changes made directly to recover.bsq * ## * will be lost. * ## **************************************************************************** # # If you don't want comments to be removed i.e, lines starting with # or -- # enclose them within STOP_SED and START_SED (where is #) # as is done for this line in recover.txt. Also make sure they are not on the # same line. To keep memory scripts as such use this facility. library '12.2.0.1' raschemaversion 1 define 'x$rman_constant' <<< package rman_constant is &const& end; >>> define 'x$debl' <<< procedure debl(func varchar2, str varchar2, dtype number , level number) is chid varchar2(2000) := krmicd.getChid; begin if (chid is null) then krmicd.writeTrc(func, rman_constant.TRACE_MSG, str, dtype, level); else krmicd.writeTrc(func, rman_constant.TRACE_MSG, 'channel '||chid||': '||str, dtype, level); end if; end; >>> define 'x$deb' <<< procedure deb(func varchar2, str varchar2, dtype number DEFAULT rman_constant.DEBUG_PLSQL, level number DEFAULT rman_constant.LEVEL_DEFAULT) is begin debl(func, str, dtype, level); end; >>> define 'x$beginBackupJobStep' <<< function beginBackupJobStep return boolean is dur_usr_endtime binary_integer; dur_softendtime binary_integer; dur_est_secs binary_integer; partial boolean; backup_cancelled exception; pragma exception_init(backup_cancelled, -19591); begin -- if (NOT krmicd.beginJobStep(dur_usr_endtime, dur_softendtime, dur_est_secs, partial)) then if (NOT partial) then raise backup_cancelled; end if; return FALSE; end if; sys.dbms_backup_restore.setLimit(sys.dbms_backup_restore.dur_endtime, dur_usr_endtime); sys.dbms_backup_restore.setLimit(sys.dbms_backup_restore.dur_est_secs, dur_est_secs); sys.dbms_backup_restore.setLimit(sys.dbms_backup_restore.dur_softendtime, dur_softendtime); return TRUE; end; >>> define 'x$endBackupJobStep' <<< function endBackupJobStep (failed IN boolean, errcode IN binary_integer) return boolean is ignore_errs boolean; sleep_secs number; begin ignore_errs := krmicd.endJobStep(failed, errcode); sys.dbms_backup_restore.getlimit (sys.dbms_backup_restore.sleep_secs, sleep_secs); -- -- if (sleep_secs > 0) then krmicd.writeMsg(8599, krmicd.getChid, to_char(floor(sleep_secs/3600)) || ':' || to_char(floor(mod(sleep_secs, 3600)/60), 'FM09') || ':' || to_char(mod(sleep_secs,60), 'FM09')); end if; -- if (failed and ignore_errs) then krmicd.clearErrors; return TRUE; end if; -- if (not failed) then return TRUE; end if; return FALSE; end; >>> define 'x$setBackupParams' <<< procedure setBackupParams(docopy in boolean) is p1 number; p2 number; p3 number; p4 number; t1 varchar2(1025); t2 varchar2(1); t3 varchar2(1); begin if (not docopy and krmicd.getParams(1, p1, p2, p3, p4, t1, t2, t3)) then sys.dbms_backup_restore.setparms(p0=>1, p1=>1, p2=>p1, p3=>p2, p5=>t1); end if; return; end; >>> define 'x$setRestoreParams' <<< procedure setRestoreParams is p1 number; p2 number; p3 number; p4 number; t1 varchar2(1025); t2 varchar2(1); t3 varchar2(1); begin if (krmicd.getParams(2, p1, p2, p3, p4, t1, t2, t3)) then sys.dbms_backup_restore.setparms(p0=>2, p5=>t1); loop exit when not krmicd.getParams(3, p1, p2, p3, p4, t1, t2, t3); sys.dbms_backup_restore.setparms(p0=>2, p5=>t1); end loop; end if; return; end; >>> define 'x$setNetworkRestoreParams' <<< function setNetworkRestoreParams return boolean is p1 number; p2 number; p3 number; p4 number; t1 varchar2(1025); t2 varchar2(1); t3 varchar2(1); docompress boolean := FALSE; begin setRestoreParams; -- if (krmicd.getParams(1, p1, p2, p3, p4, t1, t2, t3)) then sys.dbms_backup_restore.setParms( p0 => 10, p1 => 1, -- encrypt p2 => p1, -- algorithm p3 => p2, -- transparent p5 => t1); -- password -- sys.dbms_backup_restore.setparms(p0=>2, p5=>t1); end if; -- if (krmicd.getParams(4, p1, p2, p3, p4, t1, t2, t3)) then if (p2 = 1) then p2 := sys.dbms_backup_restore.lopt_false; elsif (p2 = 2) then p2 := sys.dbms_backup_restore.lopt_true; end if; sys.dbms_backup_restore.setParms( p0 => 11, p1 => 1, -- compress p2 => p1, -- asofrel p3 => p2, -- loadopt p5 => t1); -- schema docompress := TRUE; end if; return docompress; end; >>> define 'v$controlfile_record_section' <<< define table v$controlfile_record_section ( TYPE VARCHAR2(128), RECORD_SIZE NUMBER, RECORDS_TOTAL NUMBER, RECORDS_USED NUMBER, FIRST_INDEX NUMBER, LAST_INDEX NUMBER, LAST_RECID NUMBER ); >>> define 'v$controlfile' <<< define table v$controlfile ( STATUS VARCHAR2(7), NAME VARCHAR2(513), IS_RECOVERY_DEST_FILE VARCHAR2(3), BLOCK_SIZE NUMBER, FILE_SIZE_BLKS NUMBER ); >>> define 'v$database' <<< define table v$database ( DBID NUMBER, NAME VARCHAR2(9), CREATED DATE, RESETLOGS_CHANGE# NUMBER, RESETLOGS_TIME DATE, PRIOR_RESETLOGS_CHANGE# NUMBER, PRIOR_RESETLOGS_TIME DATE, LOG_MODE VARCHAR2(12), CHECKPOINT_CHANGE# NUMBER, ARCHIVE_CHANGE# NUMBER, CONTROLFILE_TYPE VARCHAR2(7), CONTROLFILE_CREATED DATE, CONTROLFILE_SEQUENCE# NUMBER, CONTROLFILE_CHANGE# NUMBER, CONTROLFILE_TIME DATE, OPEN_RESETLOGS VARCHAR2(11), VERSION_TIME DATE, RECOVERY_TARGET_INCARNATION# NUMBER, LAST_OPEN_INCARNATION# NUMBER, FLASHBACK_ON VARCHAR2(3), DB_UNIQUE_NAME VARCHAR2(30), DATABASE_ROLE VARCHAR2(16), CONTROLFILE_CONVERTED VARCHAR2(3), PRIMARY_DB_UNIQUE_NAME VARCHAR2(30), CDB VARCHAR2(3) ); >>> define 'v$tablespace' <<< define table v$tablespace ( TS# NUMBER, CON_ID NUMBER, NAME VARCHAR2(30), INCLUDED_IN_DATABASE_BACKUP VARCHAR2(3), BIGFILE VARCHAR2(3), ENCRYPT_IN_BACKUP VARCHAR2(3) ); >>> define 'v$datafile' <<< define table v$datafile ( BLABLA NUMBER ); >>> define 'v$tempfile' <<< define table v$tempfile ( CON_ID NUMBER, FILE# NUMBER, CREATION_CHANGE# NUMBER, NAME VARCHAR2(513) ); >>> define 'x$kccrt' <<< define table x$kccrt ( INST_ID NUMBER, CON_ID NUMBER, RTNUM NUMBER, RTSTA NUMBER, RTNLF NUMBER, RTSEQ NUMBER, RTENB VARCHAR2(20), RTETS VARCHAR2(20), RTDIS VARCHAR2(20), RTDIT VARCHAR2(20) ); >>> define 'x$kcctir' <<< define table x$kcctir ( INST_ID NUMBER, CON_ID NUMBER, TIRNUM NUMBER ); >>> define 'v$log' <<< define table v$log ( CON_ID NUMBER, GROUP# NUMBER, THREAD# NUMBER, SEQUENCE# NUMBER, BYTES NUMBER, MEMBERS NUMBER, ARCHIVED VARCHAR2(3), STATUS VARCHAR2(16), FIRST_CHANGE# NUMBER, FIRST_TIME DATE ); >>> define 'v$standby_log' <<< define table v$standby_log ( CON_ID NUMBER, GROUP# NUMBER, THREAD# NUMBER, SEQUENCE# NUMBER, BYTES NUMBER, MEMBERS NUMBER, ARCHIVED VARCHAR2(3), STATUS VARCHAR2(16), FIRST_CHANGE# NUMBER, FIRST_TIME DATE ); >>> define 'v$logfile' <<< define table v$logfile ( CON_ID NUMBER, GROUP# NUMBER, STATUS VARCHAR2(7), MEMBER VARCHAR2(513), STATUS VARCHAR2(7) ); >>> define 'v$rman_configuration' <<< DEFINE TABLE v$rman_configuration ( CON_ID NUMBER, CONF# NUMBER, NAME VARCHAR2(65), VALUE VARCHAR2(1025) ); >>> define 'v$log_history' <<< define table v$log_history ( CON_ID NUMBER, RECID NUMBER, STAMP NUMBER, THREAD# NUMBER, SEQUENCE# NUMBER, FIRST_CHANGE# NUMBER, FIRST_TIME DATE, NEXT_CHANGE# NUMBER, RESETLOGS_CHANGE# NUMBER, RESETLOGS_TIME DATE ); >>> define 'v$archived_log' <<< define table v$archived_log ( CON_ID NUMBER, RECID NUMBER, STAMP NUMBER, NAME VARCHAR2(513), DEST_ID NUMBER, THREAD# NUMBER, SEQUENCE# NUMBER, RESETLOGS_CHANGE# NUMBER, RESETLOGS_TIME DATE, FIRST_CHANGE# NUMBER, FIRST_TIME DATE, NEXT_CHANGE# NUMBER, NEXT_TIME DATE, BLOCKS NUMBER, BLOCK_SIZE NUMBER, CREATOR VARCHAR2(7), REGISTRAR VARCHAR2(7), STANDBY_DEST VARCHAR2(3), ARCHIVED VARCHAR2(3), APPLIED VARCHAR2(3), DELETED VARCHAR2(3), STATUS VARCHAR2(1), COMPLETION_TIME DATE, DICTIONARY_BEGIN VARCHAR2(3), DICTIONARY_END VARCHAR2(3), IS_RECOVERY_DEST_FILE VARCHAR2(3), COMPRESSED VARCHAR2(3), END_OF_REDO_TYPE VARCHAR2(10) ); >>> define 'v$recovery_status' <<< define table v$recovery_status ( CON_ID NUMBER, RECOVERY_CHECKPOINT DATE, THREAD NUMBER, SEQUENCE_NEEDED NUMBER, SCN_NEEDED VARCHAR2(20), TIME_NEEDED DATE, PREVIOUS_LOG_NAME VARCHAR2(513), PREVIOUS_LOG_STATUS VARCHAR2(13), REASON VARCHAR2(13) ); >>> define 'v$offline_range' <<< define table v$offline_range ( CON_ID NUMBER, RECID NUMBER, STAMP NUMBER, FILE# NUMBER, OFFLINE_CHANGE# NUMBER, ONLINE_CHANGE# NUMBER, ONLINE_TIME DATE, RESETLOGS_CHANGE# NUMBER, RESETLOGS_TIME DATE ); >>> define 'v$backup_set' <<< define table v$backup_set ( CON_ID NUMBER, RECID NUMBER, STAMP NUMBER, SET_STAMP NUMBER, SET_COUNT NUMBER, BACKUP_TYPE VARCHAR2(1), CONTROLFILE_INCLUDED VARCHAR2(3), INCREMENTAL_LEVEL NUMBER, PIECES NUMBER, START_TIME DATE, COMPLETION_TIME DATE, ELAPSED_SECONDS NUMBER, BLOCK_SIZE NUMBER, STATUS VARCHAR2(1), INPUT_FILE_SCAN_ONLY VARCHAR2(3), KEEP VARCHAR2(3), KEEP_UNTIL DATE, KEEP_OPTIONS VARCHAR2(13), MULTI_SECTION VARCHAR2(3), FOR_XTTS VARCHAR2(3), GUID RAW(16) ); >>> define 'v$backup_piece' <<< define table v$backup_piece ( CON_ID NUMBER, RECID NUMBER, STAMP NUMBER, SET_STAMP NUMBER, SET_COUNT NUMBER, PIECE# NUMBER, COPY# NUMBER, DEVICE_TYPE VARCHAR2(17), HANDLE VARCHAR2(513), COMMENTS VARCHAR2(81), MEDIA VARCHAR2(65), MEDIA_POOL NUMBER, CONCUR VARCHAR2(3), TAG VARCHAR2(32), STATUS VARCHAR2(1), START_TIME DATE, COMPLETION_TIME DATE, ELAPSED_SECONDS NUMBER, DELETED VARCHAR2(3), BYTES NUMBER, IS_RECOVERY_DEST_FILE VARCHAR2(3), RMAN_STATUS_RECID NUMBER, RMAN_STATUS_STAMP NUMBER, COMPRESSED VARCHAR2(3), ENCRYPTED VARCHAR2(3), BACKED_BY_OSB VARCHAR2(3), FOR_XTTS VARCHAR2(3), GUID RAW(16) ); >>> define 'v$backup_datafile' <<< define table v$backup_datafile ( CON_ID NUMBER, RECID NUMBER, STAMP NUMBER, SET_STAMP NUMBER, SET_COUNT NUMBER, FILE# NUMBER, CREATION_CHANGE# NUMBER, CREATION_TIME DATE, RESETLOGS_CHANGE# NUMBER, RESETLOGS_TIME DATE, INCREMENTAL_LEVEL NUMBER, INCREMENTAL_CHANGE# NUMBER, CHECKPOINT_CHANGE# NUMBER, CHECKPOINT_TIME DATE, ABSOLUTE_FUZZY_CHANGE# NUMBER, MARKED_CORRUPT NUMBER, MEDIA_CORRUPT NUMBER, LOGICALLY_CORRUPT NUMBER, DATAFILE_BLOCKS NUMBER, BLOCKS NUMBER, BLOCK_SIZE NUMBER, OLDEST_OFFLINE_RANGE NUMBER, COMPLETION_TIME DATE, CONTROLFILE_TYPE VARCHAR2(1), USED_CHANGE_TRACKING VARCHAR2(3), BLOCKS_READ NUMBER, USED_OPTIMIZATION VARCHAR2(3), FOREIGN_DBID NUMBER, PLUGGED_READONLY VARCHAR2(3), PLUGIN_CHANGE# NUMBER, PLUGIN_RESETLOGS_CHANGE# NUMBER, PLUGIN_RESETLOGS_TIME DATE, SECTION_SIZE NUMBER, SPARSE_BACKUP VARCHAR2(3), GUID RAW(16) ); >>> define 'v$backup_corruption' <<< define table v$backup_corruption ( CON_ID NUMBER, RECID NUMBER, STAMP NUMBER, SET_STAMP NUMBER, SET_COUNT NUMBER, PIECE# NUMBER, FILE# NUMBER, BLOCK# NUMBER, BLOCKS NUMBER, CORRUPTION_CHANGE# NUMBER, MARKED_CORRUPT VARCHAR2(3), CORRUPTION_TYPE VARCHAR2(9) ); >>> define 'v$backup_redolog' <<< define table v$backup_redolog ( CON_ID NUMBER, RECID NUMBER, STAMP NUMBER, SET_STAMP NUMBER, SET_COUNT NUMBER, THREAD# NUMBER, SEQUENCE# NUMBER, RESETLOGS_CHANGE# NUMBER, RESETLOGS_TIME DATE, FIRST_CHANGE# NUMBER, FIRST_TIME DATE, NEXT_CHANGE# NUMBER, NEXT_TIME DATE, BLOCKS NUMBER, BLOCK_SIZE NUMBER, TERMINAL VARCHAR2(3) ); >>> define 'v$datafile_copy' <<< define table v$datafile_copy ( CON_ID NUMBER, RECID NUMBER, STAMP NUMBER, NAME VARCHAR2(513), TAG VARCHAR2(32), FILE# NUMBER, RFILE# NUMBER, CREATION_CHANGE# NUMBER, CREATION_TIME DATE, RESETLOGS_CHANGE# NUMBER, RESETLOGS_TIME DATE, INCREMENTAL_LEVEL NUMBER, CHECKPOINT_CHANGE# NUMBER, CHECKPOINT_TIME DATE, ABSOLUTE_FUZZY_CHANGE# NUMBER, RECOVERY_FUZZY_CHANGE# NUMBER, RECOVERY_FUZZY_TIME DATE, ONLINE_FUZZY VARCHAR2(3), BACKUP_FUZZY VARCHAR2(3), MARKED_CORRUPT NUMBER, MEDIA_CORRUPT NUMBER, LOGICALLY_CORRUPT NUMBER, BLOCKS NUMBER, BLOCK_SIZE NUMBER, OLDEST_OFFLINE_RANGE NUMBER, DELETED VARCHAR2(3), STATUS VARCHAR2(1), COMPLETION_TIME DATE, CONTROLFILE_TYPE VARCHAR2(1), KEEP VARCHAR2(3), KEEP_UNTIL DATE, KEEP_OPTIONS VARCHAR2(13), SCANNED VARCHAR2(3), IS_RECOVERY_DEST_FILE VARCHAR2(3), RMAN_STATUS_RECID NUMBER, RMAN_STATUS_STAMP NUMBER, FOREIGN_DBID NUMBER, PLUGGED_READONLY VARCHAR2(3), PLUGIN_CHANGE# NUMBER, PLUGIN_RESETLOGS_CHANGE# NUMBER, PLUGIN_RESETLOGS_TIME DATE, CONVERTED_FILE VARCHAR2(3), SPARSE_BACKUP VARCHAR2(3), GUID RAW(16) ); >>> define 'v$copy_corruption' <<< define table v$copy_corruption ( CON_ID NUMBER, RECID NUMBER, STAMP NUMBER, COPY_RECID NUMBER, COPY_STAMP NUMBER, FILE# NUMBER, BLOCK# NUMBER, BLOCKS NUMBER, CORRUPTION_CHANGE# NUMBER, MARKED_CORRUPT VARCHAR2(3), CORRUPTION_TYPE VARCHAR2(9) ); >>> define 'x$kccblkcor' <<< define table x$kccblkcor ( CON_ID NUMBER, BLKRID NUMBER, BLKSTM NUMBER, BLKTYPE NUMBER, BLKFNO NUMBER, BLKCRS NUMBER, BLKCRT DATE, BLKTOT NUMBER, BLKSBLK NUMBER, BLKSCN NUMBER ); >>> define 'v$deleted_object' <<< define table v$deleted_object ( CON_ID NUMBER, RECID NUMBER, STAMP NUMBER, TYPE VARCHAR2(30), OBJECT_RECID NUMBER, OBJECT_STAMP NUMBER, OBJECT_DATA NUMBER, SET_STAMP NUMBER, SET_COUNT NUMBER ); >>> define 'v$backup_spfile' <<< define table v$backup_spfile ( CON_ID NUMBER, RECID NUMBER, STAMP NUMBER, SET_STAMP NUMBER, SET_COUNT NUMBER, MODIFICATION_TIME DATE, BYTES NUMBER, COMPLETION_TIME DATE, DB_UNIQUE_NAME VARCHAR2(30), GUID RAW(16) ); >>> define 'v$transportable_platform' <<< define table v$transportable_platform ( CON_ID NUMBER, PLATFORM_ID NUMBER, PLATFORM_NAME VARCHAR2(101) ); >>> define 'x$kccdi' <<< define table x$kccdi ( ADDR RAW(4), INDX NUMBER, INST_ID NUMBER, CON_ID NUMBER, DIDFV NUMBER, DIDFC NUMBER, DICTS VARCHAR2(20), DIDBN VARCHAR2(9), DIRDB NUMBER, DICCT VARCHAR2(20), DIFLG NUMBER, DIIRS VARCHAR2(20), DIRLS VARCHAR2(20), DIRLC VARCHAR2(20), DIRLC_I NUMBER, DIPRS VARCHAR2(20), DIPRC VARCHAR2(20), DIPRC_I NUMBER, DIRDV NUMBER, DIRDC NUMBER, DINDF NUMBER, DINOF NUMBER, DICPT NUMBER, DISCN VARCHAR2(20), DINET NUMBER, DINOT NUMBER, DIOTH NUMBER, DIOTT NUMBER, DIETB RAW(8), DIMLM NUMBER, DIMDM NUMBER, DIARH NUMBER, DIART NUMBER, DIFAS VARCHAR2(20), DICKP_SCN VARCHAR2(20), DICKP_TIM VARCHAR2(20), DICSQ NUMBER, DIDBI NUMBER, DISSC_SCN VARCHAR2(20), DISSC_TIM VARCHAR2(20), DISFP NUMBER, DIBSC NUMBER, DIPOFB NUMBER, DIPNFB NUMBER, DICOFB NUMBER, DICNFB NUMBER, DIFL2 NUMBER ); >>> define 'x$kccdi2' <<< define table x$kccdi2 ( CON_ID NUMBER, DI2IRT VARCHAR2(20), DI2FBRET NUMBER ); >>> define 'x$kccfe' <<< define table x$kccfe ( ADDR RAW(4), INDX NUMBER, INST_ID NUMBER, CON_ID NUMBER, FENUM NUMBER, FECSZ NUMBER, FEBSZ NUMBER, FESTA NUMBER, FECRC_SCN VARCHAR2(20), FECRC_TIM VARCHAR2(20), FECRC_THR NUMBER, FECRC_RBA_SEQ NUMBER, FECRC_RBA_BNO NUMBER, FECRC_RBA_BOF NUMBER, FECRC_ETB RAW(8), FECPS VARCHAR2(20), FECPT VARCHAR2(20), FECPC NUMBER, FESTS VARCHAR2(20), FESTT VARCHAR2(20), FEBSC VARCHAR2(20), FEFNH NUMBER, FEFNT NUMBER, FEDUP NUMBER, FEURS VARCHAR2(20), FEURT VARCHAR2(20), FEOFS VARCHAR2(20), FEONC_SCN VARCHAR2(20), FEONC_TIM VARCHAR2(20), FEONC_THR NUMBER, FEONC_RBA_SEQ NUMBER, FEONC_RBA_BNO NUMBER, FEONC_RBA_BOF NUMBER, FEONC_ETB RAW(8), FEPOR NUMBER, FETSN NUMBER, FETSI NUMBER, FERFN NUMBER, FEPFT NUMBER, FEDOR NUMBER, FEPDI NUMBER, FEFDB NUMBER, FEPLG_SCN VARCHAR2(20), FEPAX NUMBER, FEPLUS NUMBER, FEPRLS NUMBER, FEPRLT DATE, FEFCRS NUMBER, FEFCRT DATE, FEFCPS NUMBER, FEFCPT DATE, FEPFDI NUMBER ); >>> define 'x$kcctf' <<< define table x$kcctf ( ADDR RAW(4), INDX NUMBER, INST_ID NUMBER, CON_ID NUMBER, TFNUM NUMBER, TFAFN NUMBER, TFCSZ NUMBER, TFBSZ NUMBER, TFSTA NUMBER, TFCRC_SCN VARCHAR2(20), TFCRC_TIM VARCHAR2(20), TFFNH NUMBER, TFFNT NUMBER, TFDUP NUMBER, TFTSN NUMBER, TFTSI NUMBER, TFRFN NUMBER, TFPFT NUMBER, TFMSZ NUMBER, TFNSZ NUMBER ); >>> define 'x$kccfle' <<< define table x$kccfle ( ADDR RAW(4), INDX NUMBER, INST_ID NUMBER, CON_ID NUMBER, FLELTIM VARCHAR2(20) ); >>> define 'x$kccfn' <<< define table x$kccfn ( ADDR RAW(4), INDX NUMBER, INST_ID NUMBER, CON_ID NUMBER, FNNUM NUMBER, FNTYP NUMBER, FNFNO NUMBER, FNFWD NUMBER, FNBWD NUMBER, FNFLG NUMBER, FNNAM VARCHAR2(513), FNONM VARCHAR2(513), FNUNN NUMBER ); >>> define 'v$mystat' <<< define table v$mystat ( CON_ID NUMBER, SID NUMBER, STATISTIC# NUMBER, VALUE NUMBER ); >>> define 'v$instance' <<< define table v$instance ( CON_ID NUMBER, INSTANCE_NUMBER NUMBER, INSTANCE_NAME VARCHAR2(16), HOST_NAME VARCHAR2(64), VERSION VARCHAR2(17), STARTUP_TIME DATE, STATUS VARCHAR2(7), PARALLEL VARCHAR2(3), THREAD# NUMBER, ARCHIVER VARCHAR2(7), LOG_SWITCH_WAIT VARCHAR2(11), LOGINS VARCHAR2(10), SHUTDOWN_PENDING VARCHAR2(3) ); >>> define 'gv$instance' <<< define table gv$instance ( INST_ID NUMBER, CON_ID NUMBER, INSTANCE_NUMBER NUMBER, INSTANCE_NAME VARCHAR2(16), HOST_NAME VARCHAR2(64), VERSION VARCHAR2(17), STARTUP_TIME DATE, STATUS VARCHAR2(7), PARALLEL VARCHAR2(3), THREAD# NUMBER, ARCHIVER VARCHAR2(7), LOG_SWITCH_WAIT VARCHAR2(11), LOGINS VARCHAR2(10), SHUTDOWN_PENDING VARCHAR2(3) ); >>> define 'v$parameter' <<< define table v$parameter ( CON_ID NUMBER, NUM NUMBER, NAME VARCHAR2(64), TYPE NUMBER, VALUE VARCHAR2(512), ISDEFAULT VARCHAR2(9), ISSES_MODIFIABLE VARCHAR2(5), ISSYS_MODIFIABLE VARCHAR2(9), ISMODIFIED VARCHAR2(10), ISADJUSTED VARCHAR2(5), DESCRIPTION VARCHAR2(64) ); >>> define 'v$parameter2' <<< define table v$parameter2 ( CON_ID NUMBER, NUM NUMBER, NAME VARCHAR2(80), TYPE NUMBER, VALUE VARCHAR2(512), DISPLAY_VALUE VARCHAR2(512), ISDEFAULT VARCHAR2(6), ISSES_MODIFIABLE VARCHAR2(5), ISSYS_MODIFIABLE VARCHAR2(9), ISINSTANCE_MODIFIABLE VARCHAR2(5), ISMODIFIED VARCHAR2(10), ISADJUSTED VARCHAR2(5), ISDEPRECATED VARCHAR2(5), DESCRIPTION VARCHAR2(255), ORDINAL NUMBER, UPDATE_COMMENT VARCHAR2(255) ); >>> define 'v$memory_dynamic_components' <<< define table v$memory_dynamic_components ( CON_ID NUMBER, COMPONENT VARCHAR2(64), CURRENT_SIZE NUMBER, MIN_SIZE NUMBER, MAX_SIZE NUMBER, USER_SPECIFIED_SIZE NUMBER, OPER_COUNT NUMBER, LAST_OPER_TYPE VARCHAR2(13), LAST_OPER_MODE VARCHAR2(9), LAST_OPER_TIME DATE, GRANULE_SIZE NUMBER ); >>> define 'x$kcrmx' <<< define table x$kcrmx ( ADDR RAW(4), INDX NUMBER, INST_ID NUMBER, CON_ID NUMBER, BCF NUMBER, CBR NUMBER, TBR NUMBER, SBR NUMBER, IRS VARCHAR2(20), INS VARCHAR2(20), STM VARCHAR2(20), CKPSCN VARCHAR2(20), CKPTIM VARCHAR2(20), CKPETB RAW(8), EOK NUMBER, NAM VARCHAR2(513), THR NUMBER, SCN VARCHAR2(20), TIM VARCHAR2(20), SEQ NUMBER, LOS VARCHAR2(20), FAM NUMBER, UIS NUMBER, ORT VARCHAR2(20), NRT VARCHAR2(20), FLG NUMBER, MRS NUMBER, NTX NUMBER, CTC NUMBER, RLS NUMBER, RLC NUMBER ); >>> define 'x$undo$' <<< define table undo$ ( US# NUMBER, NAME VARCHAR2(30), USER# NUMBER, FILE# NUMBER, BLOCK# NUMBER, SCNBAS NUMBER, SCNWRP NUMBER, XACTSQN NUMBER, UNDOSQN NUMBER, INST# NUMBER, STATUS$ NUMBER, TS# NUMBER, UGRP# NUMBER, KEEP NUMBER, OPTIMAL NUMBER, FLAGS NUMBER, SPARE1 NUMBER, SPARE2 NUMBER, SPARE3 NUMBER, SPARE4 VARCHAR2(1000), SPARE5 VARCHAR2(1000), SPARE6 DATE ); >>> define 'x$cdb_rollback_segs' <<< define table cdb_rollback_segs ( SEGMENT_NAME VARCHAR2(30), OWNER VARCHAR2(6), TABLESPACE_NAME VARCHAR2(30), SEGMENT_ID NUMBER, FILE_ID NUMBER, BLOCK_ID NUMBER, INITIAL_EXTENT NUMBER, NEXT_EXTENT NUMBER, MIN_EXTENTS NUMBER, MAX_EXTENTS NUMBER, PCT_INCREASE NUMBER, STATUS VARCHAR2(16), INSTANCE_NUM VARCHAR2(40), RELATIVE_FNO NUMBER, CON_ID NUMBER ); >>> define 'v$database_incarnation' <<< define table v$database_incarnation ( CON_ID NUMBER, INCARNATION# NUMBER, RESETLOGS_CHANGE# NUMBER, RESETLOGS_TIME DATE, PRIOR_RESETLOGS_CHANGE# NUMBER, PRIOR_RESETLOGS_TIME DATE, STATUS VARCHAR2(7), RESETLOGS_ID NUMBER, PRIOR_INCARNATION# NUMBER ); >>> define 'x$kcpdbinc' <<< define table x$kcpdbinc ( ADDR RAW(8), INDX NUMBER, INST_ID NUMBER, CON_ID NUMBER, DBINC NUMBER, DBRLS NUMBER, DBRLC DATE, PDBINC NUMBER, STATUS NUMBER, INCSCN NUMBER, BRSCN NUMBER, BRTIME DATE, ERSCN NUMBER, PR_DBINC NUMBER, PR_DBRLS NUMBER, PR_DBRLC DATE, PR_PDBINC NUMBER, PR_PDBINC_NULL NUMBER, PR_INCSCN NUMBER, PR_ERSCN NUMBER, FB_ALLOWED NUMBER ); >>> define 'v$rman_status' <<< define table v$rman_status ( CON_ID NUMBER, SID NUMBER, RECID NUMBER, STAMP NUMBER, PARENT_RECID NUMBER, PARENT_STAMP NUMBER, SESSION_RECID NUMBER, SESSION_STAMP NUMBER, ROW_LEVEL NUMBER, ROW_TYPE VARCHAR2(20), COMMAND_ID VARCHAR2(33), OPERATION VARCHAR2(33), STATUS VARCHAR2(23), MBYTES_PROCESSED NUMBER, START_TIME DATE, END_TIME DATE, INPUT_BYTES NUMBER, OUTPUT_BYTES NUMBER, OPTIMIZED VARCHAR2(3), OBJECT_TYPE VARCHAR2(80), OUTPUT_DEVICE_TYPE VARCHAR2(17), OSB_ALLOCATED VARCHAR2(3) ); >>> define 'v$rman_output' <<< define table v$rman_output ( CON_ID NUMBER, SID NUMBER, RECID NUMBER, STAMP NUMBER, RMAN_STATUS_RECID NUMBER, RMAN_STATUS_STAMP NUMBER, SESSION_RECID NUMBER, SESSION_STAMP NUMBER, OUTPUT VARCHAR2(129) ); >>> define 'x$kccrdi' <<< define table x$kccrdi ( ADDR RAW(4), INDX NUMBER, INST_ID NUMBER, CON_ID NUMBER, LOCATION VARCHAR2(513), SLIMIT NUMBER, SUSED NUMBER, SDATAFILE NUMBER, FCNT NUMBER, SRECL NUMBER, SYSAVAIL NUMBER, OMRTIME DATE, FLAGS NUMBER ); >>> define 'x$kccrsp' <<< define table x$kccrsp ( ADDR RAW(4), INDX NUMBER, INST_ID NUMBER, CON_ID NUMBER, RSPNAME VARCHAR2(128), RSPINCARN NUMBER, RSPSCN VARCHAR2(20), RSPTIME VARCHAR2(20), RSPRSPTIME VARCHAR2(20), RSPLGSZ VARCHAR2(23), RSPFLAGS NUMBER, RSPFSCN VARCHAR2(20), RSPCLEAN NUMBER ); >>> define 'x$kccnrs' <<< define table x$kccnrs ( ADDR RAW(4), INDX NUMBER, INST_ID NUMBER, CON_ID NUMBER, NRSNAME VARCHAR2(128), NRSINCARN NUMBER, NRSSCN VARCHAR2(20), NRSTIME VARCHAR2(20), NRSFLAGS NUMBER, NRSRSPTIME VARCHAR2(20), NRSRID NUMBER, NRSSTM NUMBER, RSPCLEAN NUMBER ); >>> define 'v$containers' <<< define table v$containers ( CON_ID NUMBER, DBID NUMBER, NAME VARCHAR2(128), OPEN_MODE VARCHAR2(10), CREATE_SCN NUMBER, GUID RAW(16), LOCAL_UNDO NUMBER ); >>> define 'x$kccpdb' <<< define table x$kccpdb ( CON_ID NUMBER, PDBRNO NUMBER, PDBDBID NUMBER, PDBDBN VARCHAR2(128), PDBNLN NUMBER, PDBINC NUMBER, PDBSTA NUMBER, PDBFLG NUMBER, PDBINS VARCHAR2(20), PDBRDI NUMBER, PDBCCKP_SCN VARCHAR2(20), PDBCCKP_TIME VARCHAR2(20), PDBADCNE NUMBER, PDBADCNR NUMBER, PDBDFP NUMBER, PDBTFP NUMBER, PDBNDF NUMBER, PDBNTF NUMBER, PDBCRS VARCHAR2(20), PDBOTB RAW(132), PDBCSS VARCHAR2(20), PDBMKID RAW(16), PDBUID NUMBER, PDBGUID RAW(16) ); >>> define 'x$delete_logs' <<< procedure delete_logs(keep_for_rcv IN boolean, del_all IN boolean, del_target IN boolean, preplugin IN boolean) IS alfrec v$archived_log%ROWTYPE; scn_needed_num number; pdbid number; pplcdbdbid number; ppltrans number; begin -- if (keep_for_rcv) then select to_number(scn_needed) into scn_needed_num from v$recovery_status; else scn_needed_num := 9e125; end if; if (preplugin) then krmicd.getPrePluginTranslation(pdbid, pplcdbdbid); ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation( pdbid => pdbid, pplcdbdbid => pplcdbdbid); end if; -- -- loop <> -- -- -- alfrec.name := krmicd.getLog(scn_needed_num, alfrec.thread#, alfrec.sequence#, alfrec.recid, alfrec.stamp, alfrec.resetlogs_change#, alfrec.first_change#, alfrec.next_change#, alfrec.block_size, alfrec.is_recovery_dest_file, preplugin); exit when (alfrec.name is NULL); if (not del_all and alfrec.is_recovery_dest_file != 'YES') then goto getnext; end if; begin if del_target then krmicd.deleteArchivedLog( use_target => 1, recid => alfrec.recid, stamp => alfrec.stamp, fname => alfrec.name, thread => alfrec.thread#, sequence => alfrec.sequence#, resetlogs_change => alfrec.resetlogs_change#, first_change => alfrec.first_change#, blksize => alfrec.block_size, preplugin => preplugin); else sys.dbms_backup_restore.deleteArchivedLog( recid => alfrec.recid, stamp => alfrec.stamp, fname => alfrec.name, thread => alfrec.thread#, sequence => alfrec.sequence#, resetlogs_change => alfrec.resetlogs_change#, first_change => alfrec.first_change#, blksize => alfrec.block_size); end if; exception when others then krmicd.writeMsg(8510, to_char(alfrec.thread#), to_char(alfrec.sequence#)); raise; end; krmicd.writeMsg(8071, krmicd.getChid); krmicd.writeMsg(8514, alfrec.name, to_char(alfrec.recid), to_char(alfrec.stamp)); end loop; if (ppltrans > 0) then sys.dbms_backup_restore.endPrePluginTranslation; end if; end; >>> define 'x$name_log' <<< procedure name_log(memnum IN number ,arch_recid IN number ,arch_stamp IN number ,thread IN number ,sequence IN number ,fname IN varchar2 ,blocks IN number ,blksize IN number ,files IN OUT binary_integer ,first_time IN OUT boolean ,docopies IN boolean ,validatecmd IN boolean) IS duplicate boolean; in_use exception; del_for_space exception; pragma exception_init(in_use, -19584); pragma exception_init(del_for_space, -19805); begin sys.dbms_backup_restore.backupArchivedLog(arch_recid => arch_recid, arch_stamp => arch_stamp, duplicate => duplicate); if first_time then if validatecmd then krmicd.writeMsg(8146, krmicd.getChid); elsif not docopies then krmicd.writeMsg(8014, krmicd.getChid); end if; first_time := FALSE; end if; if not duplicate then files := files + 1; krmicd.writeMsg(8504, to_char(thread), to_char(sequence), to_char(arch_recid), to_char(arch_stamp)); end if; deb('name_log', 'blocks=' || blocks || ' block_size=' || blksize, rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN); exception when in_use then krmicd.writeMsg(8603, fname); krmicd.clearErrors; when del_for_space then krmicd.writeMsg(8604, fname); krmicd.clearErrors; end; >>> define 'x$name_datafilecopy' <<< procedure name_datafilecopy(memnum IN number ,copy_recid IN number ,copy_stamp IN number ,fname IN varchar2 ,dfnumber IN number ,blocks IN number ,blksize IN number ,tsname IN OUT varchar2 ,files IN OUT binary_integer ,docopies IN boolean ,max_corrupt IN number default 0 ,since_change IN number default 0) IS in_use exception; del_for_space exception; dropped_pdb_file exception; pragma exception_init(in_use, -19584); pragma exception_init(del_for_space, -19805); pragma exception_init(dropped_pdb_file, -45913); begin if files < memnum then sys.dbms_backup_restore.backupDataFileCopy( copy_recid => copy_recid, copy_stamp => copy_stamp, max_corrupt => max_corrupt, since_change => since_change); if docopies and dfnumber != 0 then tsname := sys.dbms_backup_restore.getTsNameFromDataFileCopy(fname, dfnumber); end if; files := files + 1; if not docopies then krmicd.writeMsg(8033, krmicd.getChid, to_char(dfnumber, 'FM09999')); krmicd.writeMsg(8506, fname); else krmicd.writeMsg(8587, to_char(dfnumber, 'FM09999'), fname); end if; deb('budc_name', 'blocks=' || blocks || ' block_size=' || blksize, rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN); end if; exception when in_use then krmicd.writeMsg(8603, fname); krmicd.clearErrors; when del_for_space then krmicd.writeMsg(8604, fname); krmicd.clearErrors; when dropped_pdb_file then krmicd.writeMsg(6825, fname); krmicd.clearErrors; end; >>> define 'x$getFileRestored' <<< procedure getFileRestored(proxy IN boolean) IS firstcall boolean := TRUE; ftype binary_integer; thread binary_integer; sequence number; resetscn number; resetstamp number; fno binary_integer; callagain binary_integer; fname varchar2(1024); begin loop callagain := sys.dbms_backup_restore.fetchFileRestored( firstcall => firstcall, proxy => proxy, ftype => ftype, fno => fno, thread => thread, sequence => sequence, resetscn => resetscn, resetstamp => resetstamp, fname => fname ); exit when callagain = 0; firstcall := FALSE; krmicd.fileRestored(ftype => ftype, fno => fno, thread => thread, sequence => sequence, resetscn => resetscn, resetstamp => resetstamp, fname => fname); end loop; end; >>> define 'x$stamp2date' <<< function stamp2date(stamp IN number) return date IS x number; dt varchar2(19); begin x := stamp; dt := to_char(mod(x,60), 'FM09'); -- seconds x := floor(x/60); dt := to_char(mod(x,60), 'FM09') || ':' || dt; -- minutes x := floor(x/60); dt := to_char(mod(x,24), 'FM09') || ':' || dt; -- hours x := floor(x/24); dt := to_char(mod(x,31)+1, 'FM09') || ' ' || dt; -- days x := floor(x/31); dt := to_char(mod(x,12)+1, 'FM09') || '/' || dt; -- months dt := to_char(floor(x/12)+1988) || '/' || dt; return to_date(dt, 'YYYY/MM/DD HH24:MI:SS'); end; >>> define 'x$date2stamp' <<< function date2stamp(dt IN date) return number is stamp number; begin stamp := (((((to_number(to_char(dt, 'YYYY'))-1988)*12 + (to_number(to_char(dt, 'MM'))-1))*31 + (to_number(to_char(dt, 'DD'))-1))*24 + (to_number(to_char(dt, 'HH24'))))*60 + (to_number(to_char(dt, 'MI'))))*60 + (to_number(to_char(dt, 'SS'))); return stamp; end; >>> define 'x$dur2time' <<< procedure dur2time(dur IN OUT number, hours IN OUT number, mins IN OUT number, secs IN OUT number) is begin hours := floor(dur*24); dur := dur - hours/24; mins := floor(dur*24*60); dur := dur - mins/(24*60); secs := dur*24*60*60; end; >>> define 'x$entered' <<< procedure entered(func varchar2) is begin krmicd.writeTrc(func, rman_constant.TRACE_ENTER, '', rman_constant.DEBUG_PLSQL, 1); end; >>> define 'x$exited' <<< procedure exited(func varchar2, str varchar2) is begin krmicd.writeTrc(func, rman_constant.TRACE_EXIT, str, rman_constant.DEBUG_PLSQL, 1); end; >>> define 'x$bool2char' <<< function bool2char(b boolean) return varchar2 is begin if (b) then return 'TRUE'; else return 'FALSE'; end if; end; >>> define 'x$kcvfh' <<< DEFINE TABLE x$kcvfh ( ADDR RAW(4), INDX NUMBER, INST_ID NUMBER, HXFIL NUMBER, HXONS NUMBER, HXSTS VARCHAR2(20), HXERR NUMBER, HXVER NUMBER, FHSWV NUMBER, FHCVN NUMBER, FHDBI NUMBER, FHDBN VARCHAR2(9), FHCSQ NUMBER, FHFSZ NUMBER, FHBSZ NUMBER, FHFNO NUMBER, FHTYP NUMBER, FHRDB NUMBER, FHCRS VARCHAR2(20), FHCRT VARCHAR2(20), FHRLC VARCHAR2(20), FHRLC_I NUMBER, FHRLS VARCHAR2(20), FHPRC VARCHAR2(20), FHPRC_I NUMBER, FHPRS VARCHAR2(20), FHBTI VARCHAR2(20), FHBSC VARCHAR2(20), FHBTH NUMBER, FHSTA NUMBER, FHSCN VARCHAR2(20), FHTIM VARCHAR2(20), FHTHR NUMBER, FHRBA_SEQ NUMBER, FHRBA_BNO NUMBER, FHRBA_BOF NUMBER, FHETB RAW(8), FHCPC NUMBER, FHRTS VARCHAR2(20), FHCCC NUMBER, FHBCP_SCN VARCHAR2(20), FHBCP_TIM VARCHAR2(20), FHBCP_THR NUMBER, FHBCP_RBA_SEQ NUMBER, FHBCP_RBA_BNO NUMBER, FHBCP_RBA_BOF NUMBER, FHBCP_ETB RAW(8), FHBHZ NUMBER, FHXCD RAW(16), FHTSN NUMBER, FHTNM VARCHAR2(30), FHRFN NUMBER, FHAFS VARCHAR2(20), FHRFS VARCHAR2(20), FHRFT VARCHAR2(20), HXIFZ NUMBER, HXNRCV NUMBER, HXFNM VARCHAR2(513), FHPOFB NUMBER, FHPNFB NUMBER ); >>> define 'x$kcvfhtmp' <<< define table x$kcvfhtmp ( ADDR RAW(4), INDX NUMBER, INST_ID NUMBER, HTMPXFIL NUMBER, HTMPXONS NUMBER, HTMPXERR NUMBER, HTMPXVER NUMBER, FHTMPSWV NUMBER, FHTMPCVN NUMBER, FHTMPDBI NUMBER, FHTMPDBN VARCHAR2(9), FHTMPCSQ NUMBER, FHTMPFSZ NUMBER, FHTMPBSZ NUMBER, FHTMPFNO NUMBER, FHTMPTYP NUMBER, FHTMPCRS VARCHAR2(20), FHTMPCRT VARCHAR2(20), FHTMPSTA NUMBER, FHTMPCCC NUMBER, FHTMPXCD RAW(16), FHTMPTSN NUMBER, FHTMPTNM VARCHAR2(30), FHTMPRFN NUMBER, HTMPXFNM VARCHAR2(513) ); >>> define 'x$dual' <<< DEFINE TABLE x$dual ( ADDR RAW(4), INDX NUMBER, INST_ID NUMBER, DUMMY VARCHAR2(1) ); >>> define 'v$proxy_datafile' <<< DEFINE TABLE v$proxy_datafile ( CON_ID NUMBER, RECID NUMBER, STAMP NUMBER, DEVICE_TYPE VARCHAR2(17), HANDLE VARCHAR2(513), COMMENTS VARCHAR2(81), MEDIA VARCHAR2(65), MEDIA_POOL NUMBER, TAG VARCHAR2(32), STATUS VARCHAR2(1), DELETED VARCHAR2(3), FILE# NUMBER, CREATION_CHANGE# NUMBER, CREATION_TIME DATE, RESETLOGS_CHANGE# NUMBER, RESETLOGS_TIME DATE, CHECKPOINT_CHANGE# NUMBER, CHECKPOINT_TIME DATE, ABSOLUTE_FUZZY_CHANGE# NUMBER, RECOVERY_FUZZY_CHANGE# NUMBER, RECOVERY_FUZZY_TIME DATE, INCREMENTAL_LEVEL NUMBER, ONLINE_FUZZY VARCHAR2(3), BACKUP_FUZZY VARCHAR2(3), BLOCKS NUMBER, BLOCK_SIZE NUMBER, OLDEST_OFFLINE_RANGE NUMBER, START_TIME DATE, COMPLETION_TIME DATE, ELAPSED_SECONDS NUMBER, CONTROLFILE_TYPE VARCHAR2(1), KEEP VARCHAR2(3), KEEP_UNTIL DATE, KEEP_OPTIONS VARCHAR2(13), RMAN_STATUS_RECID NUMBER, RMAN_STATUS_STAMP NUMBER, FOREIGN_DBID NUMBER, PLUGGED_READONLY VARCHAR2(3), PLUGIN_CHANGE# NUMBER, PLUGIN_RESETLOGS_CHANGE# NUMBER, PLUGIN_RESETLOGS_TIME DATE, GUID RAW(16) ); >>> define 'v$proxy_archivedlog' <<< DEFINE TABLE v$proxy_archivedlog ( RECID NUMBER, STAMP NUMBER, DEVICE_TYPE VARCHAR2(17), HANDLE VARCHAR2(513), COMMENTS VARCHAR2(81), MEDIA VARCHAR2(65), MEDIA_POOL NUMBER, TAG VARCHAR2(32), STATUS VARCHAR2(1), DELETED VARCHAR2(3), THREAD# NUMBER, SEQUENCE# NUMBER, RESETLOGS_CHANGE# NUMBER, RESETLOGS_TIME DATE, FIRST_CHANGE# NUMBER, FIRST_TIME DATE, NEXT_CHANGE# NUMBER, NEXT_TIME DATE, BLOCKS NUMBER, BLOCK_SIZE NUMBER, START_TIME DATE, COMPLETION_TIME DATE, ELAPSED_SECONDS NUMBER, RMAN_STATUS_RECID NUMBER, RMAN_STATUS_STAMP NUMBER, TERMINAL VARCHAR2(3), KEEP VARCHAR2(3), KEEP_UNTIL DATE, KEEP_OPTIONS VARCHAR2(13) ); >>> define 'x$is_recovery_area_enabled' <<< function is_recovery_area_enabled return boolean IS dbstate number := 0; begin select count(*) into dbstate from x$kccrdi where location is not null; if (dbstate = 0) then return FALSE; end if; return TRUE; end; >>> define 'x$aged_files' <<< procedure refreshAgedFiles is busy_retries number := 0; -- retry counter for ss enqueue busy err_msg varchar2(2048); begin if (NOT krmicd.valRedoLogDeletionPolicy) then krmicd.writeMsg(8591); end if; if (NOT is_recovery_area_enabled()) then deb('refreshAgedFiles', 'recovery area is not enabled'); return; end if; deb('refreshAgedFiles', 'Starting refreshAgedFiles at ' || to_char(sysdate)); <> begin sys.dbms_backup_restore.refreshAgedFiles; exception when sys.dbms_backup_restore.snapshot_enqueue_busy then -- -- -- -- if busy_retries = 180 then err_msg := sqlerrm; krmicd.writeErrMsg(6764, err_msg); krmicd.writeMsg(8132); -- unable to refresh aged files krmicd.clearErrors; else busy_retries := busy_retries + 1; -- if (mod(busy_retries, 15) = 0) then krmicd.writeMsg(8512); end if; krmicd.sleep(20); krmicd.clearErrors; goto retry; end if; when others then err_msg := sqlerrm; krmicd.writeErrMsg(6764, err_msg); krmicd.writeMsg(8132); -- unable to refresh aged files krmicd.clearErrors; end; deb('refreshAgedFiles', 'Finished refreshAgedFiles at ' || to_char(sysdate)); end; >>> define 'x$applied_al' <<< function isalnotapplied(recid IN number, stamp IN number, next_change IN number, resetlogs_change IN number, resetlogs_time IN varchar2) return boolean IS applied_change number; isnotapplied binary_integer := 1; begin -- select decode(al.applied, 'YES', 0, 1) into isnotapplied from v$archived_log al where al.recid = isalnotapplied.recid and al.stamp = isalnotapplied.stamp and al.resetlogs_change# = isalnotapplied.resetlogs_change and al.resetlogs_time = to_date(isalnotapplied.resetlogs_time, 'YYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=Gregorian'); if (isnotapplied = 1) then -- -- select nvl(max(al.first_change#), 0) into applied_change from v$archived_log al where al.applied = 'YES' and al.standby_dest = 'NO' and al.resetlogs_change# = isalnotapplied.resetlogs_change and al.resetlogs_time = to_date(isalnotapplied.resetlogs_time, 'YYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=Gregorian'); if (next_change <= applied_change) then isnotapplied := 0; end if; end if; if (isnotapplied > 0) then return TRUE; else return FALSE; end if; end; >>> define 'x$isalforgrsp' <<< function isalforgrsp(first_change IN number, next_change IN number, resetlogs_change IN number, resetlogs_time IN varchar2) return boolean is count_grsp number; begin select count(*) into count_grsp from x$kccrsp grsp, v$database_incarnation dbinc where grsp.rspincarn = dbinc.incarnation# and bitand(grsp.rspflags, 2) != 0 and bitand(grsp.rspflags, 1) = 1 -- Guaranteed and grsp.rspfscn <= grsp.rspscn -- filter archived log for clean grsp and grsp.rspfscn != 0 and dbinc.resetlogs_change# = isalforgrsp.resetlogs_change and dbinc.resetlogs_time = to_date(isalforgrsp.resetlogs_time, 'YYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=Gregorian') -- and isalforgrsp.first_change <= (grsp.rspscn + 1) and isalforgrsp.next_change >= grsp.rspfscn; if (count_grsp > 0) then return TRUE; end if; return FALSE; end; >>> define 'x$del_copy' <<< procedure del_copy(copy_recid IN number ,copy_stamp IN number ,fname IN varchar2 ,dfnumber IN binary_integer ,resetlogs_change IN number ,creation_change IN number ,checkpoint_change IN number ,blksize IN number ,no_delete IN binary_integer) IS begin sys.dbms_backup_restore.deleteDataFileCopy( recid => copy_recid, stamp => copy_stamp, fname => fname, dfnumber => dfnumber, resetlogs_change => resetlogs_change, creation_change => creation_change, checkpoint_change => checkpoint_change, blksize => blksize, no_delete => no_delete); if (dfnumber = 0) then krmicd.writeMsg(8072); krmicd.writeMsg(8516, fname, to_char(copy_recid), to_char(copy_stamp)); else krmicd.writeMsg(8070); krmicd.writeMsg(8513, fname, to_char(copy_recid), to_char(copy_stamp)); end if; end; >>> define 'x$del_log' <<< procedure del_log(cfisstby IN boolean ,arch_recid IN number ,arch_stamp IN number ,fname IN varchar2 ,thread IN number ,sequence IN number ,resetlogs_change IN number ,resetlogs_time IN varchar2 ,first_change IN number ,blksize IN number ,next_change IN number ,first_time IN OUT boolean ,docopies IN boolean ,reqscn IN OUT number -- required scn ,rlgscn IN OUT number ,appscn IN OUT number -- applied scn ,apprlgscn IN OUT number ,alldest IN number ,reqbackups IN number ,nbackups IN number) IS skiparch_lal boolean := FALSE; -- TRUE if log is required locally skiparch_ral boolean := FALSE; -- TRUE is log is required remotely skiparch_nbck boolean := FALSE; -- TRUE if log is required for backups skiparch_grsp boolean := FALSE; err_msg varchar2(2048); begin -- -- if (not docopies) then -- -- -- -- if (first_time) then krmicd.getArchiveLogDeletionSCN(alldest, reqscn, rlgscn, appscn, apprlgscn); deb('del_log', 'reqscn='||reqscn||',rlgscn='||rlgscn); deb('del_log', 'appscn='||appscn||',apprlgscn='||apprlgscn); end if; if ((next_change > appscn and resetlogs_change = apprlgscn) OR (resetlogs_change > apprlgscn)) then skiparch_lal := TRUE; deb('del_log', 'next_change='||next_change|| ',rlgscn='||resetlogs_change); -- -- -- -- elsif ((next_change > reqscn and resetlogs_change = rlgscn) OR (resetlogs_change > reqscn)) then skiparch_ral := TRUE; deb('del_log', 'next_change='||next_change|| ',rlgscn='||resetlogs_change); elsif (reqbackups > nbackups) then -- skiparch_nbck := TRUE; else skiparch_grsp := isalforgrsp(first_change, next_change, resetlogs_change, resetlogs_time); end if; end if; -- -- if (first_time) then krmicd.writeMsg(8071, krmicd.getChid); end if; first_time := FALSE; if skiparch_lal then krmicd.writeMsg(8120); krmicd.writeMsg(8515, fname, to_char(thread), to_char(sequence)); elsif skiparch_ral then krmicd.writeMsg(8137); krmicd.writeMsg(8515, fname, to_char(thread), to_char(sequence)); elsif skiparch_nbck then krmicd.writeMsg(8138); krmicd.writeMsg(8515, fname, to_char(thread), to_char(sequence)); elsif skiparch_grsp then krmicd.writeMsg(8139); krmicd.writeMsg(8515, fname, to_char(thread), to_char(sequence)); else -- -- krmicd.writeMsg(8514, fname, to_char(arch_recid), to_char(arch_stamp)); begin sys.dbms_backup_restore.deleteArchivedLog( recid => arch_recid, stamp => arch_stamp, fname => fname, thread => thread, sequence => sequence, resetlogs_change => resetlogs_change, first_change => first_change, blksize => blksize); -- -- exception when others then err_msg := sqlerrm; krmicd.writeMsg(8118); krmicd.writeMsg(8515, fname, to_char(thread), to_char(sequence)); krmicd.writeErrMsg(4005, err_msg); krmicd.clearErrors; end; end if; end; >>> define 'x$is_db_in_noarchivelog' <<< function is_db_in_noarchivelog return boolean is noarchivelog binary_integer; begin select count(*) into noarchivelog from v$database where log_mode = 'NOARCHIVELOG'; if (noarchivelog = 0) then return FALSE; else return TRUE; end if; end; >>> define 'x$listNbrBlockStat' <<< procedure listNbrBlockStat(blkstat IN sys.dbms_backup_restore.blockStatTable_t) IS firstcall boolean := TRUE; lastcall boolean := FALSE; begin for i in 1..blkstat.count loop if (i = blkstat.count) then lastcall := TRUE; end if; if firstcall then krmicd.writeMsg(7225); krmicd.writeMsg(7226); krmicd.writeMsg(7267); krmicd.writeMsg(7268); end if; if blkstat(i).status then krmicd.writeMsg(7269, to_char(blkstat(i).dfnumber), to_char(blkstat(i).corrupt), to_char(blkstat(i).examined), to_char(blkstat(i).empty)); else krmicd.writeMsg(7270, to_char(blkstat(i).dfnumber)); end if; if lastcall then krmicd.writeMsg(0); krmicd.writeMsg(7271); krmicd.writeMsg(0); end if; firstcall := FALSE; end loop; end; >>> define regdb <<< -- declare db_name varchar2(8); reg_dbuname varchar2(30); reset_scn number; reset_time date; db_id number; cf_type binary_integer; cf_sequence binary_integer; l_con_id number := sys_context('userenv', 'con_id'); l_guid v$containers.guid%type; begin select dbid, name, resetlogs_change#, resetlogs_time, db_unique_name into db_id, db_name, reset_scn, reset_time, reg_dbuname from v$database; select c.guid into l_guid from v$containers c where c.con_id = l_con_id; dbms_rcvcat.registerDatabase (db_id, db_name, reset_scn, reset_time, reg_dbuname, l_con_id, l_guid); krmicd.writeMsg(8006, db_name); end; >>> define resetdb <<< -- declare db_name varchar2(8); reset_scn number; reset_time date; parent_reset_scn number; parent_reset_time date; db_id number; cf_type binary_integer; cf_sequence binary_integer; dbinc_key number; cfdbinc_key number; db_not_mounted EXCEPTION; PRAGMA EXCEPTION_INIT(db_not_mounted, -1507); incarnation_key_missing EXCEPTION; PRAGMA EXCEPTION_INIT(incarnation_key_missing, -20008); incarnation_already_registered EXCEPTION; PRAGMA EXCEPTION_INIT(incarnation_already_registered, -20009); begin &object& %IF% target if (dbinc_key is not NULL) then sys.dbms_backup_restore.resetdatabase(dbinc_key); krmicd.writeMsg(8066, dbinc_key); else raise incarnation_key_missing; end if; %ENDIF% target %IF% catalog if (dbinc_key is NULL) then select dbid, name, resetlogs_change#, resetlogs_time into db_id, db_name, reset_scn, reset_time from v$database; select diprs, to_date(diprc, 'MM/DD/RR HH24:MI:SS', 'NLS_CALENDAR=Gregorian') into parent_reset_scn, parent_reset_time from x$kccdi; begin dbms_rcvcat.resetDatabase(db_id => db_id, db_name => db_name, reset_scn => reset_scn, reset_time => reset_time, parent_reset_scn => parent_reset_scn, parent_reset_time => parent_reset_time); dbms_rcvcat.setReason(dbms_rcvcat.RESYNC_REASON_RESET); krmicd.writeMsg(8005, db_name); exception when incarnation_already_registered then krmicd.writeMsg(20009); when others then raise; end; else select upper(value) into db_name from v$parameter where name = 'db_name'; dbms_rcvcat.resetDatabase(dbinc_key, db_name, reset_scn, reset_time, db_id); krmicd.writeMsg(8066, dbinc_key); begin select incarnation# into cfdbinc_key from v$database_incarnation where resetlogs_change#=reset_scn and resetlogs_time =reset_time; sys.dbms_backup_restore.resetDatabase(cfdbinc_key); -- exception when db_not_mounted then krmicd.clearErrors; when no_data_found then krmicd.writeMsg(6566); when others then krmicd.writeErrMsg(1005, sqlerrm); end; end if; %ENDIF% catalog end; >>> define 'resync' <<< -- declare &constants& CONFIGRESYNC_NO CONSTANT number := 0; CONFIGRESYNC_TORC CONSTANT number := 1; CONFIGRESYNC_TOCF CONSTANT number := 2; CONFIGRESYNC_TORC_TOCF CONSTANT number := 3; mount_status varchar2(7); cf_type varchar2(7) := NULL; tmzone varchar2(256); -- timezone of primary db_id number; db_name varchar2(8); ldb_unique_name varchar2(30); -- parameter db_unique_name reset_scn number; -- db current reset scn reset_time date; -- db current reset time err_msg varchar2(2048); parent_reset_scn number; parent_reset_time date; -- flashback_time date := to_date(NULL); prior_reset_scn number; -- db prior reset scn prior_reset_time date; -- db prior reset time snapcf varchar2(512); -- snapshot controlfile name name varchar2(512); -- default snapshot cf name cfname varchar2(512) := NULL; -- backup cf name ckp_scn number; ckp_time date; ckp_cf_seq number; cf_create_time date; getckptscn number; cf_version date; -- v$database.version_time kccdivts number; -- date2stamp(cf_version) recid number; high_cp_recid number; -- 1 high_rt_recid number; -- 2 high_le_recid number; -- 3 high_fe_recid number; -- 4 high_fn_recid number; -- 5 high_ts_recid number; -- 6 high_r1_recid number; -- 7 high_rm_recid number; -- 8 high_lh_recid number; -- 9 high_or_recid number; -- 10 high_al_recid number; -- 11 high_bs_recid number; -- 12 high_bp_recid number; -- 13 high_bf_recid number; -- 14 high_bl_recid number; -- 15 high_dc_recid number; -- 16 high_fc_recid number; -- 17 high_cc_recid number; -- 18 high_dl_recid number; -- 19 high_pc_recid number; -- 20 high_bi_recid number; -- 21 -- -- -- high_ic_recid number; -- 22 'DATABASE INCARNATION' high_rsr_recid number; -- 24 'RMAN STATUS RECORDS' high_tf_recid number; high_grsp_recid number := 0; high_nrsp_recid number := 0; shigh_rsr_recid number; high_rout_stamp number; -- in-memory 'RMAN OUTPUT records' high record stamp inst_startup_time DATE; inst_startup_stamp number; high_bcr_recid number; -- 'DATABASE BLOCK CORRUPTION' low_bcr_recid number; high_pdb_recid number; high_pic_recid number; doRoutMining boolean; full_resync boolean; -- set by rman compiler implicit boolean; -- set by rman compiler debug_resync boolean; -- set by rman compiler converted_cf boolean; -- set by rman compiler read_retries number := 0; -- retry counter for inconsistant_read busy_retries number := 0; -- retry counter for ss enqueue busy sort_retries number := 0; -- retry counter for sort_area_size sync_retries number := 0; -- retry counter for automatic resync conf_toCF boolean := FALSE; -- flags that tells how resync conf first boolean; force boolean; -- flag that tells do we force resync rc_aux_fname varchar2(1025); -- aux_name from recovery catalog rbs_count number := NULL; b boolean; read_only number; ret number; sort_area_size number; -- sort_area_size from v$parameter sort_area_size_init CONSTANT number := 10485760; sort_area_size_incr CONSTANT number := 10485760; rec_size number; -- record_size from v$controlfile_record_section total_recs number; high_recno number; rec_per_chunk integer; high number; low number; found number; releasecf boolean := FALSE; -- flag tells to release cfile enqueue parent_dbinc_key number; low_bs_recid number; low_bdf_recid number; low_bsf_recid number; low_brl_recid number; local_low number; local_high number; dbtype number := rman_constant.DEBUG_RESYNC; low_run_recid number := 0; -- Lowest remote runnig rman row running_found boolean; -- flag used in resync of V$RMAN_STATUS resyncstamp number := 0; -- resync above this timestamp min_stamp number; -- minimum timestamp max_stamp number; -- maximum timestamp high_stamp number; -- to move high timestamp new_min_stamp number; -- retry using this minimum timestamp until_stamp number; -- check until this timestamp wasresyncstamp number; -- was resynced timestamp middle number; -- for binary search no_units number; -- number of units between min-max stamp maxdups number := 16; -- look for these many duplicates lh_lowscn number; -- low_scn of log history resynced -- -- -- -- -- -- -- unit number := 2; -- 12 hours granularity least_stamp CONSTANT number := 0; greatest_stamp CONSTANT number := 2**32; resync_reason number; fullResyncBaseMsg number; resync_active boolean; resync_valid boolean; resync_added number; resync_dropped number; resync_changed number; resync_recreated number; resync_renamed number; resync_resized number; type rspname_t is table of x$kccrsp.rspname%type index by binary_integer; type numTab_t is table of number index by binary_integer; type timeTab_t is table of date index by binary_integer; type boolTab_t is table of varchar2(3) index by binary_integer; for_dbuname varchar2(30); curr_dbuname varchar2(30); source_cs varchar2(512); dest_cs varchar2(512); for_db_id number; ub4_cf_type binary_integer := 0; null_retVal varchar2(1); auto_prim_resync boolean := FALSE; callSetDatabase boolean := FALSE; pdb_dict_check numTab_t; ignore_resync_err boolean := FALSE; lrecid number; lstamp number; lrec_type number; lfname varchar2(1024); oam_tst_level number; resync_2_AMSchema number := 0; rsid number; rsts number; curr_set_stamp number := 0; curr_set_count number := 0; invalid_pdbid number := sys.dbms_backup_restore.getParm(16); need_primary_resync exception; pragma exception_init(need_primary_resync, -20079); db_id_mismatch exception; pragma exception_init(db_id_mismatch, -20109); sort_area_too_small EXCEPTION; PRAGMA EXCEPTION_INIT(sort_area_too_small, -1220); resync_not_needed exception; pragma exception_init(resync_not_needed, -20034); DATABASE_INCARNATION_NOT_FOUND exception; pragma exception_init(DATABASE_INCARNATION_NOT_FOUND, -20003); change_record_stamp exception; pragma exception_init(change_record_stamp, -20081); dbuname_mismatch exception; pragma exception_init(dbuname_mismatch, -20223); setstamp_setcount_conflict exception; pragma exception_init(setstamp_setcount_conflict, -20110); invalid_setstamp_setcount_conf exception; pragma exception_init(invalid_setstamp_setcount_conf, -20111); incarnation_already_registered exception; pragma exception_init(incarnation_already_registered, -20009); -- -- -- -- -- -- -- -- -- -- cursor rs is select type, last_recid from v$controlfile_record_section; cursor pdb is select name, con_id, dbid, create_scn, guid, 'N' noBackup from v$containers where con_id = 0 -- applicable only for non-cdb union all select substr(pdb.pdbdbn, 1, pdb.pdbnln) name, pdb.con_id, pdb.pdbdbid dbid, to_number(pdb.pdbcrs) create_scn, pdb.pdbguid guid, decode(bitand(pdb.pdbflg, 4096), 4096, 'Y', 'N') noBackup from x$kccpdb pdb where (pdb.pdbcrs > 0 or con_id = 1) -- -- and (pdb.pdbsta != 3 OR bitand(pdb.pdbflg, 8192)=8192) and pdb.con_id > 0 order by guid; cursor pdb_dict_check_c is select con_id from x$kccpdb pdb where pdb.con_id > 1 and (pdb.pdbsta != 3 OR bitand(pdb.pdbflg, 8192)=8192) and bitand(pdb.pdbflg, 8192) !=8192 -- skip refresh PDBs and bitand(pdb.pdbflg, 1) = 1; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- cursor ts is select ts2.ts#, ts2.name, ts2.included_in_database_backup, to_number(fe2.fecrc_scn) create_scn, to_date(fe2.fecrc_tim,'MM/DD/RR HH24:MI:SS', 'NLS_CALENDAR=Gregorian') create_time, ts2.bigfile bigfile, 'NO' temporary, ts2.encrypt_in_backup, fe2.feplus plugin_scn, ts2.con_id con_id from x$kccfe fe2, (select ts1.ts#, ts1.name, ts1.included_in_database_backup, min(fe1.fenum) fenum, ts1.bigfile bigfile, ts1.encrypt_in_backup, ts1.con_id from x$kccfe fe1, (select ts.ts#, ts.name, ts.included_in_database_backup, min(to_number(fe.fecrc_scn)) create_scn, ts.bigfile bigfile, ts.encrypt_in_backup, ts.con_id from x$kccfe fe, v$tablespace ts where fe.fetsn=ts.ts# and fe.con_id = ts.con_id and fe.fedup<>0 group by ts.con_id, ts.ts#, ts.name, ts.included_in_database_backup, ts.bigfile, ts.encrypt_in_backup ) ts1 where ts1.ts#=fe1.fetsn and ts1.con_id= fe1.con_id and to_number(fe1.fecrc_scn) = ts1.create_scn group by ts1.con_id, ts1.ts#, ts1.name, ts1.included_in_database_backup, ts1.bigfile, ts1.encrypt_in_backup ) ts2 where ts2.fenum=fe2.fenum and (fe2.fefdb = 0 or fe2.feplus != 0) union all select ts2.ts#, ts2.name, ts2.included_in_database_backup, to_number(tf2.tfcrc_scn) create_scn, to_date(tf2.tfcrc_tim,'MM/DD/RR HH24:MI:SS', 'NLS_CALENDAR=Gregorian') create_time, ts2.bigfile bigfile, 'YES' temporary, ts2.encrypt_in_backup, 0 plugin_scn, ts2.con_id con_id from x$kcctf tf2, (select ts1.ts#, ts1.name, ts1.included_in_database_backup, min(tf1.tfnum) tfnum, ts1.bigfile bigfile, ts1.encrypt_in_backup, ts1.con_id from x$kcctf tf1, (select ts.ts#, ts.name, ts.included_in_database_backup, min(to_number(tf.tfcrc_scn)) create_scn, ts.bigfile bigfile, ts.encrypt_in_backup, ts.con_id from x$kcctf tf, v$tablespace ts where tf.tftsn = ts.ts# and tf.con_id = ts.con_id and tf.tfdup != 0 and bitand(tf.tfsta, 32) != 32 group by ts.con_id, ts.ts#, ts.name, ts.included_in_database_backup, ts.bigfile, ts.encrypt_in_backup ) ts1 where ts1.ts#=tf1.tftsn and ts1.con_id = tf1.con_id and to_number(tf1.tfcrc_scn) = ts1.create_scn group by ts1.con_id, ts1.ts#, ts1.name, ts1.included_in_database_backup, ts1.bigfile, ts1.encrypt_in_backup ) ts2 where ts2.tfnum=tf2.tfnum order by 10, 1; -- con_id, ts# -- -- -- -- -- -- -- -- -- -- -- -- -- cursor df(low_fno number, high_fno number) IS SELECT fenum fileno, to_number(fe.fecrc_scn) create_scn, to_date(fe.fecrc_tim,'MM/DD/RR HH24:MI:SS', 'NLS_CALENDAR=Gregorian') create_time, fe.fecrc_thr create_thread, fe.fecsz create_size, fe.fetsn tsnum, fn.fnnam fname, fh.fhfsz fsize, fe.febsz block_size, to_number(fe.feofs) offline_scn, to_number(fe.feonc_scn) online_scn, to_date(fe.feonc_tim,'MM/DD/RR HH24:MI:SS', 'NLS_CALENDAR=Gregorian') online_time, to_number(fe.fecps) stop_scn, to_date(fe.festt, 'MM/DD/RR HH24:MI:SS', 'NLS_CALENDAR=Gregorian') stop_time, to_number(bitand(fe.festa, 4096+128)) clean_flag, -- This WCC or SOR to_number(bitand(fe.festa, 4)) read_enabled_flag, to_number(bitand(fe.festa, 64)) missing_file_flag, -- this is KCCFECKD fe.ferfn rfileno, -- this is relative file number decode(fe.fepax, 0 , 'UNKNOWN' , 65535, 'NONE' , fnaux.fnnam) aux_fname, fe.fepdi foreign_dbid, fe.fefcrs foreign_create_scn, fe.fefcrt foreign_create_time, decode(fe.fefdb, 1, 'YES', 'NO') plugged_readonly, fe.feplus plugin_scn, fe.feprls plugin_reset_scn, fe.feprlt plugin_reset_time, fe.con_id con_id, CASE WHEN fe.con_id > 1 THEN decode(bitand(fe.festa, (4096+128)), 0, 0, decode(fe.fecps, fe1.pdbStopScn, 1, 0)) ELSE 0 END pdb_closed, fe.fepfdi pdb_foreign_dbid FROM x$kccfe fe, x$kccfn fn, x$kccfn fnaux, x$kcvfh fh, (SELECT fe.con_id, MIN(decode(bitand(fe.festa, (4096+128)), 0, 0, fe.fecps)) pdbStopScn FROM x$kccfe fe WHERE fe.fetsn = 0 AND fe.fedup != 0 AND (fe.fefdb = 0 OR fe.feprls != 0) GROUP BY fe.con_id) fe1 WHERE fe.fepax = fnaux.fnnum(+) AND fn.fnfno=fe.fenum AND fn.fnfno=fh.hxfil AND fe.fefnh=fn.fnnum AND fe.fedup<>0 AND fnaux.fntyp(+)=22 AND fn.fntyp=4 AND fn.fnnam IS NOT NULL AND fe.fenum between low_fno and high_fno AND fe.con_id = fe1.con_id ORDER BY fe.fenum; cursor tf(low_fno number, high_fno number) IS SELECT tfnum fileno, to_number(tf.tfcrc_scn) create_scn, to_date(tf.tfcrc_tim,'MM/DD/RR HH24:MI:SS', 'NLS_CALENDAR=Gregorian') create_time, tf.tftsn tsnum, fn.fnnam fname, decode(nvl(fh.fhtmpfsz, 0), 0, tf.tfcsz, fh.fhtmpfsz) fsize, tf.tfbsz block_size, tf.tfrfn rfileno, -- this is relative file number decode(bitand(tf.tfsta, 16), 0, 'OFF', 'ON') autoextend, tf.tfmsz max_size, tf.tfnsz next_size, tf.con_id con_id FROM x$kcctf tf, x$kccfn fn, x$kcvfhtmp fh WHERE fn.fnfno=tf.tfnum AND fn.fnfno=fh.htmpxfil AND tf.tffnh=fn.fnnum AND tf.tfdup!=0 AND fn.fntyp=7 AND bitand(tf.tfsta, 32)!=32 AND fn.fnnam IS NOT NULL AND tf.tfnum between low_fno and high_fno ORDER BY tf.tfnum; cursor rt is select rtnum thread#, rtseq last_sequence#, to_number(rtenb) enable_scn, to_date(rtets,'MM/DD/RR HH24:MI:SS', 'NLS_CALENDAR=Gregorian') enable_time, to_number(rtdis) disable_scn, to_date(rtdit,'MM/DD/RR HH24:MI:SS', 'NLS_CALENDAR=Gregorian') disable_time, decode(bitand(rtsta,67), 0, 'D', 2, 'E', 3, 'E', 66, 'I') status from x$kccrt rt, x$kcctir tr where rtnlf != 0 -- groups is not zero and tr.inst_id = rt.inst_id -- join with x$kcctir and tirnum = rtnum and rt.inst_id = USERENV('Instance') -- belongs to this instance order by rtnum; -- -- -- -- cursor orl is select thread#, group#, member fname, bytes, type from (select l.thread#, lf.group#, lf.member, l.bytes, 'ONLINE' type from v$log l, v$logfile lf where l.group# = lf.group# and l.thread# != 0 -- skip unassigned threads and nvl(lf.status, 'FOO') not in ('INVALID', 'DELETED', 'UNKNOWN') union all select l.thread#, lf.group#, lf.member, l.bytes, 'STANDBY' type from v$standby_log l, v$logfile lf where l.group# = lf.group# and l.thread# != 0 -- skip unassigned threads and nvl(lf.status, 'FOO') not in ('INVALID', 'DELETED', 'UNKNOWN')) order by nlssort(member, 'NLS_COMP=ANSI NLS_SORT=ASCII7'); -- bug 2107554 -- cursor grsp is select rspname, rspfscn from_scn, rspscn to_scn, to_date(rsprsptime, 'MM/DD/YYYY HH24:MI:SS', 'NLS_CALENDAR=Gregorian') rsprsptime, to_date(rsptime, 'MM/DD/YYYY HH24:MI:SS', 'NLS_CALENDAR=Gregorian') rsptime, decode(bitand(rspflags, 1), 1, 'YES', 'NO') guaranteed, resetlogs_change#, resetlogs_time, r.con_id con_id, decode(bitand(rspflags, 16), 16, 'YES', 'NO') clean from x$kccrsp r, v$database_incarnation where rspincarn = incarnation# and bitand(rspflags, 2) != 0 order by r.con_id, nlssort(rspname, 'NLS_COMP=ANSI NLS_SORT=ASCII7'); cursor nrsp(low number, high number) is select nrsname, nrsrid recid, nrsstm stamp, nrsincarn, nrsscn, to_date(nrsrsptime, 'MM/DD/YYYY HH24:MI:SS', 'NLS_CALENDAR=Gregorian') nrsrsptime, to_date(nrstime, 'MM/DD/YYYY HH24:MI:SS', 'NLS_CALENDAR=Gregorian') nrstime, decode(bitand(nrsflags, 2), 2, 0, 1) deleted, resetlogs_change# reset_scn, resetlogs_time reset_time, r.con_id con_id, decode(bitand(nrsflags, 16), 16, 'YES', 'NO') clean from x$kccnrs r, v$database_incarnation d where r.nrsincarn = d.incarnation# and nrsrid between low and high and (nrsstm >= kccdivts OR nrsrid = high) and nrsstm >= resyncstamp order by nrsrid; -- -- -- -- cursor rlh(low_recid number, high_recid number) is select recid, stamp, thread#, sequence#, first_change# low_scn, first_time low_time, next_change# next_scn, resetlogs_change#, resetlogs_time from v$log_history where recid between low_recid and high_recid and resetlogs_time is not null -- bug 3125145 and stamp >= resyncstamp order by recid; -- -- -- -- -- -- cursor al(low_recid number, high_recid number, cf_type varchar2) is select recid, stamp, name, thread#, sequence#, resetlogs_change#, resetlogs_time, first_change#, first_time, next_change#, next_time, blocks, block_size, decode(archived, 'YES', 'Y', 'NO', 'N', 'UNKNOWN') archived, status, completion_time, decode(registrar, 'RFS', 'Y', 'SRMN', 'Y', 'RMAN', 'N', 'N') is_standby, dictionary_begin, dictionary_end, is_recovery_dest_file, compressed, creator, decode(end_of_redo_type, 'TERMINAL', 'YES', 'NO') terminal from v$archived_log where recid between low_recid and high_recid and (stamp >= kccdivts OR recid = high_recid) and standby_dest = 'NO' and stamp >= resyncstamp order by recid; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- cursor offr(low_recid number, high_recid number) is select /*+ first_rows */ offr.recid, offr.stamp, offr.file#, to_number(fe.fecrc_scn) creation_change#, offr.offline_change#,offr.online_change#,offr.online_time, offr.resetlogs_change#, offr.resetlogs_time from v$offline_range offr, x$kccfe fe where offr.file# = fe.fenum(+) and offr.online_change# > to_number(fe.fecrc_scn(+)) and (offr.recid between low_recid and high_recid or fe.fecrc_scn is null) -- bug 3408643 and offr.resetlogs_time is not null -- bug 3125145 and fe.fedup != 0 -- we are not interested in dropped files and stamp >= resyncstamp order by offr.recid; cursor bs(low_recid number, high_recid number) is select bs.recid, bs.stamp, bs.set_stamp, bs.set_count, bs.backup_type, bs.incremental_level, bs.pieces, start_time, completion_time, controlfile_included, bs.input_file_scan_only, keep_until, decode (bs.keep_options, 'LOGS' , KEEP_LOGS , 'NOLOGS' , KEEP_NOLOGS , 'BACKUP_LOGS' , KEEP_CONSIST , 0) keep_options, bs.block_size, bs.multi_section, bs.guid, decode(bs.con_id, invalid_pdbid, 1, 0) dropped_pdb from v$backup_set bs where bs.recid between low_recid and high_recid and (bs.stamp >= kccdivts OR bs.recid = high_recid) and bs.stamp >= resyncstamp and bs.for_xtts != 'YES' order by bs.recid; cursor bp(low_recid number, high_recid number) is select bp.recid, bp.stamp, bp.set_stamp, bp.set_count, bp.piece#, bp.copy#, bp.tag, bp.device_type, bp.handle, bp.comments, bp.media, bp.media_pool, bp.concur, bp.start_time, bp.completion_time, bp.status, bp.bytes, bp.is_recovery_dest_file, bp.rman_status_recid, bp.rman_status_stamp, bp.compressed, bp.encrypted, bp.backed_by_osb, bp.guid, decode(bp.con_id, invalid_pdbid, 1, 0) dropped_pdb from v$backup_piece bp where bp.recid between low_recid and high_recid and (bp.stamp >= kccdivts OR bp.recid = high_recid) and bp.stamp >= resyncstamp and bp.for_xtts != 'YES' order by bp.recid; cursor bdf(low_recid number, high_recid number) is select bdf.recid, bdf.stamp, bdf.set_stamp, bdf.set_count, bdf.file#, bdf.creation_change#, bdf.creation_time, bdf.resetlogs_change#, bdf.resetlogs_time, bdf.incremental_level, bdf.incremental_change#, bdf.checkpoint_change#, bdf.checkpoint_time, bdf.absolute_fuzzy_change#, bdf.datafile_blocks, bdf.blocks, bdf.block_size, bdf.oldest_offline_range, bdf.completion_time, bdf.controlfile_type, bdf.marked_corrupt, bdf.media_corrupt, bdf.logically_corrupt, bdf.blocks_read, bdf.used_change_tracking, bdf.used_optimization, bdf.foreign_dbid, bdf.plugged_readonly, bdf.plugin_change#, bdf.plugin_resetlogs_change#, bdf.plugin_resetlogs_time, bdf.section_size, bdf.guid, bdf.sparse_backup, decode(bdf.con_id, invalid_pdbid, 1, 0) dropped_pdb from v$backup_datafile bdf where bdf.recid between low_recid and high_recid and (bdf.stamp >= kccdivts OR bdf.recid = high_recid) and bdf.stamp >= resyncstamp order by bdf.recid; -- cursor bdfbs(low_recid number, high_recid number, low_bs_recid number, high_bs_recid number) is select bdf.recid, bdf.stamp, bdf.set_stamp, bdf.set_count, bdf.file#, bdf.creation_change#, bdf.creation_time, bdf.resetlogs_change#, bdf.resetlogs_time, bdf.incremental_level, bdf.incremental_change#, bdf.checkpoint_change#, bdf.checkpoint_time, bdf.absolute_fuzzy_change#, bdf.datafile_blocks, bdf.blocks, bdf.block_size, bdf.oldest_offline_range, bdf.completion_time, bdf.controlfile_type, bdf.marked_corrupt, bdf.media_corrupt, bdf.logically_corrupt, bdf.blocks_read, bdf.used_change_tracking, bdf.used_optimization, bdf.foreign_dbid, bdf.plugged_readonly, bdf.plugin_change#, bdf.plugin_resetlogs_change#, bdf.plugin_resetlogs_time, bdf.section_size, bdf.guid, bdf.sparse_backup, decode(bdf.con_id, invalid_pdbid, 1, 0) dropped_pdb from v$backup_datafile bdf, v$backup_set bs where bs.recid between low_bs_recid and high_bs_recid and (bs.stamp >= kccdivts OR bs.recid = high_bs_recid) and bs.stamp >= resyncstamp and bdf.set_stamp = bs.set_stamp and bdf.set_count = bs.set_count and bs.backup_type != 'L' -- ignore archivelog backups and bdf.recid between low_recid and high_recid order by bdf.recid; cursor bsf(low_recid number, high_recid number) is select bsf.recid, bsf.stamp, bsf.set_stamp, bsf.set_count, bsf.modification_time, bsf.bytes, bsf.completion_time, bsf.db_unique_name, bsf.guid, decode(bsf.con_id, invalid_pdbid, 1, 0) dropped_pdb from v$backup_spfile bsf where bsf.recid between low_recid and high_recid and (bsf.stamp >= kccdivts OR bsf.recid = high_recid) and bsf.stamp >= resyncstamp and bsf.modification_time is not null and bsf.completion_time is not null and bsf.bytes is not null order by bsf.recid; -- cursor bsfbs(low_recid number, high_recid number, low_bs_recid number, high_bs_recid number) is select bsf.recid, bsf.stamp, bsf.set_stamp, bsf.set_count, bsf.modification_time, bsf.bytes, bsf.completion_time, bsf.db_unique_name, bsf.guid, decode(bsf.con_id, invalid_pdbid, 1, 0) dropped_pdb from v$backup_spfile bsf, v$backup_set bs where bs.recid between low_bs_recid and high_bs_recid and (bs.stamp >= kccdivts OR bs.recid = high_bs_recid) and bs.stamp >= resyncstamp and bsf.set_stamp = bs.set_stamp and bsf.set_count = bs.set_count and bsf.modification_time is not null and bsf.completion_time is not null and bsf.bytes is not null and bs.backup_type != 'L' -- ignore archivelog backups and bsf.recid between low_recid and high_recid order by bsf.recid; cursor bcb(low_recid number, high_recid number) is select recid, stamp, set_stamp, set_count, piece#, file#, block#, blocks, corruption_change#, marked_corrupt, corruption_type from v$backup_corruption where recid between low_recid and high_recid and (stamp >= kccdivts OR recid = high_recid) and stamp >= resyncstamp order by recid; cursor brl(low_recid number, high_recid number) is select recid, stamp, set_stamp, set_count, thread#, sequence#, resetlogs_change#, resetlogs_time, first_change#, first_time, next_change#, next_time, blocks, block_size, terminal from v$backup_redolog where recid between low_recid and high_recid and (stamp >= kccdivts OR recid = high_recid) and stamp >= resyncstamp order by recid; -- cursor brlbs(low_recid number, high_recid number, low_bs_recid number, high_bs_recid number) is select brl.recid, brl.stamp, brl.set_stamp, brl.set_count, brl.thread#, brl.sequence#, brl.resetlogs_change#, brl.resetlogs_time, brl.first_change#, brl.first_time, brl.next_change#, brl.next_time, brl.blocks, brl.block_size, brl.terminal from v$backup_redolog brl, v$backup_set bs where bs.recid between low_bs_recid and high_bs_recid and (bs.stamp >= kccdivts OR bs.recid = high_bs_recid) and bs.stamp >= resyncstamp and brl.set_stamp = bs.set_stamp and brl.set_count = bs.set_count and bs.backup_type = 'L' -- only archivelog backups and brl.recid between low_recid and high_recid order by brl.recid; cursor cdf(low_recid number, high_recid number) is select dc.recid, dc.stamp, dc.name fname, dc.tag, dc.file#, dc.creation_change# create_scn, dc.creation_time create_time, dc.resetlogs_change# reset_scn, dc.resetlogs_time reset_time, dc.incremental_level incr_level, dc.checkpoint_change# ckp_scn, dc.checkpoint_time ckp_time, dc.absolute_fuzzy_change# abs_fuzzy_scn, dc.online_fuzzy, dc.backup_fuzzy, dc.recovery_fuzzy_change# rcv_fuzzy_scn, dc.recovery_fuzzy_time rcv_fuzzy_time, dc.blocks, dc.block_size, dc.oldest_offline_range, dc.status, dc.completion_time, dc.controlfile_type, dc.keep_until, decode (dc.keep_options, 'LOGS' , KEEP_LOGS , 'NOLOGS' , KEEP_NOLOGS , 'BACKUP_LOGS' , KEEP_CONSIST , 0) keep_options, dc.scanned, dc.is_recovery_dest_file, dc.rman_status_recid, dc.rman_status_stamp, dc.marked_corrupt, dc.foreign_dbid, dc.plugged_readonly, dc.plugin_change#, dc.plugin_resetlogs_change#, dc.plugin_resetlogs_time, dc.guid, dc.sparse_backup, decode(dc.con_id, invalid_pdbid, 1, 0) dropped_pdb from v$datafile_copy dc where dc.recid between low_recid and high_recid and (dc.stamp >= kccdivts OR dc.recid = high_recid) and dc.stamp >= resyncstamp and dc.converted_file != 'YES' order by dc.recid; cursor xdf(low_recid number, high_recid number) is select pdf.recid, pdf.stamp, pdf.tag, pdf.file#, pdf.creation_change# create_scn, pdf.creation_time create_time, pdf.resetlogs_change# reset_scn, pdf.resetlogs_time reset_time, pdf.incremental_level incr_level, pdf.checkpoint_change# ckp_scn, pdf.checkpoint_time ckp_time, pdf.absolute_fuzzy_change# abs_fuzzy_scn, pdf.online_fuzzy, pdf.backup_fuzzy, pdf.recovery_fuzzy_change# rcv_fuzzy_scn, pdf.recovery_fuzzy_time rcv_fuzzy_time, pdf.blocks, pdf.block_size, pdf.oldest_offline_range, pdf.device_type, pdf.handle, pdf.comments, pdf.media, pdf.media_pool, pdf.status, pdf.start_time, pdf.completion_time, pdf.controlfile_type, pdf.keep_until, decode (pdf.keep_options, 'LOGS' , KEEP_LOGS , 'NOLOGS' , KEEP_NOLOGS , 'BACKUP_LOGS' , KEEP_CONSIST , 0) keep_options, pdf.rman_status_recid, pdf.rman_status_stamp, pdf.foreign_dbid, pdf.plugged_readonly, pdf.plugin_change#, pdf.plugin_resetlogs_change#, pdf.plugin_resetlogs_time, pdf.guid, decode(pdf.con_id, invalid_pdbid, 1, 0) dropped_pdb from v$proxy_datafile pdf where pdf.recid between low_recid and high_recid and (pdf.stamp >= kccdivts OR pdf.recid = high_recid) and pdf.stamp >= resyncstamp order by pdf.recid; cursor xal(low_recid number, high_recid number) is select recid, stamp, tag, thread#, sequence#, resetlogs_change#, resetlogs_time, first_change#, first_time, next_change#, next_time, blocks, block_size, device_type, handle, comments, media, media_pool, status, start_time, completion_time, rman_status_recid, rman_status_stamp, terminal, keep_until, decode (keep_options, 'LOGS' , KEEP_LOGS , 'NOLOGS' , KEEP_NOLOGS , 'BACKUP_LOGS' , KEEP_CONSIST , 0) keep_options from v$proxy_archivedlog where recid between low_recid and high_recid and (stamp >= kccdivts OR recid = high_recid) and stamp >= resyncstamp order by recid; cursor ccb(low_recid number, high_recid number) is select recid, stamp, copy_recid, copy_stamp, file#, block#, blocks, corruption_change#, marked_corrupt, corruption_type from v$copy_corruption where recid between low_recid and high_recid and (stamp >= kccdivts OR recid = high_recid) and stamp >= resyncstamp order by recid; cursor bcr(low_recid number, high_recid number) is select blkrid recid, blkstm stamp, blkfno file#, blkcrs create_scn, blkcrt create_time, blksblk block#, blktot blocks, blkscn corrupt_scn, decode(bitand(blktype, 255), 2, 'ALL ZERO', 3, 'FRACTURED', 4, 'CHECKSUM', 5, 'CORRUPT', 6, 'NOLOGGING', 7, 'LOGICAL', 'UNKNOWN') corruption_type from x$kccblkcor where blkrid between low_recid and high_recid and blkstm >= resyncstamp and bitand(blktype, 255) != 1 -- skip deleted records and bitand(blktype, 255) != 6 -- skip nologging records order by blkrid; -- -- -- -- cursor dl(low_recid number, high_recid number) is select /*+ LEADING(x$kccdl@sel$3 df tf) USE_HASH(df) USE_HASH(tf) FULL(x$kccdl@sel$3) NO_SWAP_JOIN_INPUTS(df) NO_SWAP_JOIN_INPUTS(tf) */ recid, stamp, type object_type, object_recid, object_stamp, object_data, type, (case when type = 'DATAFILE RENAME ON RESTORE' OR type = 'PLUGGED READONLY RENAME' then df.name when type = 'TEMPFILE RENAME' then tf.name else to_char(null) end) object_fname, (case when type = 'DATAFILE RENAME ON RESTORE' then df.creation_change# when type = 'PLUGGED READONLY RENAME' then df.plugin_change# when type = 'TEMPFILE RENAME' then tf.creation_change# else to_number(null) end) object_create_scn, set_stamp, set_count from v$deleted_object, (select /*+ LEADING(fe) FULL(fe) FULL(fn) USE_HASH(fn) */ fe.fenum file#, to_number(fe.fecrc_scn) creation_change#, fe.feplus plugin_change#, fn.fnnam name from x$kccfe fe, x$kccfn fn where fe.fenum = fn.fnfno and fe.fefnh = fn.fnnum and fe.fedup != 0 and fn.fntyp = 4 and fn.fnnam is not null and bitand(fn.fnflg, 4) != 4) df, (select /*+ LEADING(tf) FULL(tf) FULL(fn) USE_HASH(fn) */ tf.tfnum file#, to_number(tf.tfcrc_scn) creation_change#, fn.fnnam name from x$kcctf tf, x$kccfn fn where tf.tfnum = fn.fnfno and tf.tffnh = fn.fnnum and tf.tfdup != 0 and bitand(tf.tfsta, 32) != 32 and fn.fntyp = 7 and fn.fnnam is not null) tf where object_data = df.file#(+) and object_data = tf.file#(+) and recid between low_recid and high_recid and (stamp >= kccdivts OR recid = high_recid) and stamp >= resyncstamp and type != 'BACKUP RECORD CLEANUP' and type != 'PREVIOUS PIECE BACKUP SET' order by recid; cursor ic(low_recid number, high_recid number) is select resetlogs_change#, resetlogs_time, prior_resetlogs_change#, prior_resetlogs_time from v$database_incarnation where incarnation# between low_recid and high_recid order by resetlogs_change#; -- resync parent first cursor pic(low_recid number, high_recid number, special_rec number) is select substr(pdb.pdbdbn, 1, pdb.pdbnln) name, pdb.pdbguid guid, pdb.con_id, to_number(pdb.pdbcrs) create_scn, pdbinc.pdbinc recid, decode(pdbinc.status, 1, 'YES', 'NO') curr_pdbinc, pdbinc.incscn inc_scn, pdbinc.brscn begin_reset_scn, pdbinc.brtime begin_reset_time, pdbinc.erscn end_reset_scn, pdbinc.dbrls db_reset_scn, pdbinc.dbrlc db_reset_time, pdbinc.pr_incscn pr_inc_scn, pdbinc.pr_erscn pr_end_reset_scn, pdbinc.pr_dbrls pr_db_reset_scn, pdbinc.pr_dbrlc pr_db_reset_time from x$kcpdbinc pdbinc, x$kccpdb pdb where pdbinc.con_id = pdb.con_id and (pdb.pdbsta != 3 OR bitand(pdb.pdbflg, 8192)=8192) and pdb.pdbcrs > 0 and pdb.con_id > 1 and ((pdbinc.pdbinc between low_recid and high_recid) OR (special_rec = 1 AND pdbinc.pdbinc = pdb.pdbinc)) order by guid, begin_reset_scn, begin_reset_time, end_reset_scn, recid; -- -- cursor rsr(low_recid number, high_recid number) is select /*+ rule */ recid, stamp, parent_recid, parent_stamp, session_recid, session_stamp, row_level, row_type, command_id, operation, status, mbytes_processed, start_time, end_time, input_bytes, output_bytes, optimized, object_type, output_device_type, osb_allocated from v$rman_status where recid between low_recid and high_recid and (stamp >= kccdivts OR recid = high_recid) and (stamp >= resyncstamp OR stamp >= rsts) -- -- and ((resync_2_AMSchema = 0) or (resync_2_AMSchema = 1 and oam_tst_level = 0) or (resync_2_AMSchema = 1 and oam_tst_level >= 1 and session_recid = rsid and session_stamp = rsts)) order by recid; cursor rout(low_stamp number) is select recid, stamp, session_recid, session_stamp, rman_status_recid, rman_status_stamp, output from v$rman_output where stamp >= low_stamp and stamp >= resyncstamp -- -- and ((resync_2_AMSchema = 0) or (resync_2_AMSchema = 1 and oam_tst_level = 0) or (resync_2_AMSchema = 1 and oam_tst_level >= 1 and session_recid = rsid and session_stamp = rsts)) order by session_recid, rman_status_recid; -- cursor duprec_c(low_stamp number, high_stamp number) is select recid, stamp, 'AL' type from v$archived_log where status != 'D' and standby_dest = 'NO' and archived = 'YES' and stamp > low_stamp and stamp <= high_stamp union all select recid, stamp, 'BP' type from v$backup_piece where status != 'D' and stamp > low_stamp and stamp <= high_stamp union all select recid, stamp, 'DC' type from v$datafile_copy where status != 'D' and stamp > low_stamp and stamp <= high_stamp order by stamp desc; cursor duprout_c(low_stamp number, high_stamp number) is select recid, stamp, session_recid, session_stamp, rman_status_recid, rman_status_stamp from v$rman_output where stamp > low_stamp and stamp <= high_stamp order by stamp desc; procedure deb_sort_area(max_high IN number) is begin -- if debug_resync then deb('resync', 'sort_area_size='||sort_area_size, dbtype, rman_constant.LEVEL_HI); deb('resync', 'rec_size='||rec_size, dbtype, rman_constant.LEVEL_HI); deb('resync', 'rec_per_chunk='||rec_per_chunk, dbtype, rman_constant.LEVEL_HI); deb('resync', 'low= '||low||' max_high='||max_high, dbtype, rman_constant.LEVEL_HI); deb('resync', 'total_recs='||total_recs, dbtype, rman_constant.LEVEL_HI); end if; end; function set_sort_area_size(newsize in number) return number is s number; memmgmt number; maxrecsize number; inststatus varchar2(12); begin select count(*) into memmgmt from v$parameter where name='workarea_size_policy' and upper(value)='AUTO'; krmicd.clearErrors; if memmgmt = 0 then -- manual memory management deb('resync', 'manual memory management', dbtype); if newsize is not null then krmicd.execSql('alter session set sort_area_size=' || to_char(newsize)); krmicd.clearErrors; end if; select to_number(value) into s from v$parameter where name='sort_area_size'; if s < newsize then krmicd.writeMsg(1005, 'could not set sort_area_size to '|| to_char(newsize) || ', using ' || to_char(s) || ' instead.'); end if; else -- automatic memory management -- -- select current_size into s from v$memory_dynamic_components where component='PGA Target' AND (CON_ID = 0 OR CON_ID = sys_context('userenv', 'con_id')); deb('resync', 'Instance using automatic memory management, PGA Target size ' || s, dbtype); -- -- select status into inststatus from v$instance; if inststatus in ('MOUNTED', 'OPEN') then select max(record_size) into maxrecsize from v$controlfile_record_section; else -- maxrecsize := 12288; end if; if s < maxrecsize then krmicd.writeMsg(1005, 'Cannot use PGA Target dynamic memory current_size ' || to_char(s) || ', using ' || to_char(maxrecsize) || ' instead.'); s := maxrecsize; end if; end if; return s; end set_sort_area_size; procedure display_uncatalog_bp(set_stamp IN number, set_count IN number) is cursor gethandle(setstamp number, setcount number) is select bp.handle from v$backup_piece bp where bp.set_stamp = setstamp and bp.set_count = setcount and bp.status = 'A'; begin for hdle in gethandle(set_stamp, set_count) loop krmicd.writeMsg(8192, hdle.handle); end loop; end display_uncatalog_bp; -- -- procedure resyncConf2Catalog(cf_type IN varchar2, current_cf IN boolean) IS -- cursor conf_c is select conf#, name, value from v$rman_configuration; begin high_rm_recid := null; if current_cf then sys.dbms_backup_restore.getCkpt(getckptscn ,high_cp_recid ,high_rt_recid ,high_le_recid ,high_fe_recid ,high_fn_recid ,high_ts_recid ,high_r1_recid ,high_rm_recid ,high_lh_recid ,high_or_recid ,high_al_recid ,high_bs_recid ,high_bp_recid ,high_bf_recid ,high_bl_recid ,high_dc_recid ,high_fc_recid ,high_cc_recid ,high_dl_recid ,high_pc_recid ,high_bi_recid ); end if; -- -- dbms_rcvcat.resetConfig2(TRUE, high_rm_recid); -- wipe out nodespecific if cf_type in ('CURRENT', 'CREATED') then dbms_rcvcat.resetConfig2(FALSE); -- wipe out generic end if; -- for confrec in conf_c loop deb('resync', 'Resyncing configuration cf_type '|| cf_type, dbtype); deb('resync', 'Resyncing configuration '|| confrec.conf#, dbtype); deb('resync', ' Name: ' || confrec.name || ' Value: '|| confrec.value, dbtype); -- if krmicd.isNodeSpecific(confrec.name, confrec.value) then dbms_rcvcat.setConfig2(confrec.conf#, confrec.name, confrec.value, TRUE); -- node specific elsif cf_type in ('CURRENT', 'CREATED') then dbms_rcvcat.setConfig2(confrec.conf#, confrec.name, confrec.value, FALSE); -- generic -- -- -- -- if confrec.name = 'DB_UNIQUE_NAME' then dbms_rcvcat.resyncAddDBUname(confrec.value); end if; end if; end loop; end resyncConf2Catalog; -- -- procedure resyncConf2ControlFile(for_dbuname in varchar2, source_cs in varchar2) IS first boolean; conf_name varchar2(65); conf_value varchar2(1025); recid number; null_retVal varchar2(1); begin -- if for_dbuname is not null then null_retVal := sys.dbms_backup_restore.remoteSQLExecute( source_dbuname => for_dbuname, source_cs => source_cs, stmt => 'begin ' || ' sys.dbms_backup_restore.resetConfig;' || 'end;'); else sys.dbms_backup_restore.resetConfig; end if; first := TRUE; deb('resync', 'Pushing configuration to controlfile'); -- loop begin conf_name := NULL; conf_value := NULL; dbms_rcvcat.getConfig(recid, conf_name, conf_value, first); if for_dbuname is not null then null_retVal := sys.dbms_backup_restore.remoteSQLExecute( source_dbuname => for_dbuname, source_cs => source_cs, stmt => 'declare ' || ' recid number; ' || 'begin ' || ' recid := sys.dbms_backup_restore.setConfig (' || '''' || replace(conf_name,'''','''''') || ''',''' || replace(conf_value,'''','''''') || '''); '|| 'end;'); else recid := sys.dbms_backup_restore.setConfig (conf_name, conf_value); end if; deb('resync', 'Pushing conf name=' || conf_name || ';value=' || conf_value); first := FALSE; exception when no_data_found then krmicd.clearErrors; exit; end; end loop; end resyncConf2ControlFile; function getFlashbackTime(cftype varchar2) return date is flashback_on number; fb_retention_target number; fb_until_time date := to_date(null); recovery_time date; begin -- select decode(flashback_on, 'YES', 1, 0) into flashback_on from v$database; if (flashback_on = 0) then return to_date(null); -- flashback off end if; -- select di2fbret into fb_retention_target from x$kccdi2; if (nvl(fb_retention_target, 0) = 0) then return to_date(null); -- no retention target set end if; deb('resync', 'fb_retention_target= ' || to_char(fb_retention_target), dbtype); -- -- if (fb_retention_target > 14 * 60 * 24) then select min(to_date(fleltim, 'MM DD YYYY HH24:MI:SS', 'NLS_CALENDAR=Gregorian')) into fb_until_time from x$kccfle; deb('resync', 'fb_until_time= ' || nvl(to_char(fb_until_time), 'NULL'), dbtype); -- -- -- -- fb_retention_target := 14 * 60 * 24; end if; -- if (fb_until_time IS NULL) then -- select decode(cftype, 'STANDBY', nvl(to_date(di2irt, 'MM DD YYYY HH24:MI:SS', 'NLS_CALENDAR=Gregorian'), sysdate), sysdate) into recovery_time from x$kccdi2; deb('resync', 'recovery_time= ' || to_char(recovery_time), dbtype); -- fb_until_time := recovery_time - fb_retention_target/(60 * 24); deb('resync', 'fb_until_time= ' || nvl(to_char(fb_until_time), 'NULL'), dbtype); end if; return fb_until_time; exception when no_data_found then return to_date(null); when others then raise; end; -- function is19871set return boolean is isset number; begin select count(*) into isset from v$parameter2 where name = 'event' and lower(value) = '19871 trace name context forever, level 1'; if isset > 0 then return true; else return false; end if; exception when others then return false; end; -- function is_19871_L0_set return boolean is isset number; begin select count(*) into isset from v$parameter2 where name = 'event' and lower(value) = '19871 trace name context forever, level 0'; if isset > 0 then return true; else return false; end if; exception when others then return false; end; -- -- -- -- -- -- -- function wasresynced(until_stamp IN number ,high_stamp IN number) return number is nodups number; -- number of duplicates high number; low number; resyncstamp number; begin high := high_stamp; low := until_stamp; nodups := 0; resyncstamp := 0; deb('resync', 'wasresynced high_stamp=' || high_stamp || ' high_date=' || stamp2date(high_stamp), dbtype); for duprec in duprec_c(low, high) loop if (dbms_rcvcat.isDuplicateRecord(recid => duprec.recid ,stamp => duprec.stamp ,type => duprec.type)) then if (resyncstamp = 0) then resyncstamp := duprec.stamp; end if; nodups := nodups + 1; if (nodups >= maxdups) then deb('resync', 'wasresynced resyncstamp=' || resyncstamp || ' resyncdate=' || stamp2date(resyncstamp), dbtype); return resyncstamp; end if; else -- couldn't find 16 consecutive duplicate records. deb('resync', 'wasresynced could not find record recid=' || duprec.recid || ' stamp=' || duprec.stamp || ' type=' || duprec.type || ' maxdups=' || nodups, dbtype); return 0; end if; end loop; -- -- deb('resync', 'timestamp range not enough - nodups=' || nodups, dbtype); return -1; end; function routresynced(until_stamp IN number ,high_stamp IN number) return number is nodups number; -- number of duplicates high number; low number; resyncstamp number; begin high := high_stamp; low := until_stamp; nodups := 0; resyncstamp := 0; deb('resync', 'routresynced high_stamp=' || high_stamp || ' high_date=' || stamp2date(high_stamp), dbtype); for duprec in duprout_c(low, high) loop if (dbms_rcvcat.isRoutDuplicateRecord( recid => duprec.recid ,stamp => duprec.stamp ,session_recid => duprec.session_recid ,session_stamp => duprec.session_stamp ,rman_status_recid => duprec.rman_status_recid ,rman_status_stamp => duprec.rman_status_stamp)) then if (resyncstamp = 0) then resyncstamp := duprec.stamp; end if; nodups := nodups + 1; if (nodups >= maxdups) then deb('resync', 'routresynced resyncstamp=' || resyncstamp || ' resyncdate=' || stamp2date(resyncstamp), dbtype); return resyncstamp; end if; else -- couldn't find 16 consecutive duplicate records. deb('resync', 'routresynced could not find record recid=' || duprec.recid || ' stamp=' || duprec.stamp || ' maxdups=' || nodups, dbtype); return 0; end if; end loop; -- -- deb('resync', 'timestamp range not enough - nodups=' || nodups, dbtype); return -1; end; procedure resyncTempfiles is begin select record_size, last_recid into rec_size, high_tf_recid from v$controlfile_record_section where type = 'TEMPORARY FILENAME'; deb('resync', 'high_tf_recid= '|| high_tf_recid, dbtype); if dbms_rcvcat.beginTempFileResync(high_tf_recid) THEN rec_size := 1024 + rec_size; -- kccfn + kcctf rec_per_chunk := floor(sort_area_size / rec_size); -- select nvl(max(tfnum), 0) into high_recno from x$kcctf where tfdup != 0; found := 0; low := 1; deb_sort_area(0); loop high := low + rec_per_chunk - 1; for tfrec in tf(low, high) LOOP deb('resync', 'Resyncing tempfile '|| tfrec.fname, dbtype); IF tfrec.fsize = 0 THEN -- -- tfrec.fsize := NULL; END IF; deb('resync', 'Calling checkTempFile for fileno '|| tfrec.fileno||' size '||tfrec.fsize, dbtype); dbms_rcvcat.checkTempFile( tfrec.fileno, tfrec.fname, tfrec.create_scn, tfrec.create_time, tfrec.fsize, tfrec.block_size, tfrec.tsnum, tfrec.rfileno, tfrec.autoextend, tfrec.max_size, tfrec.next_size, tfrec.con_id, pdb_dict_check.exists(tfrec.con_id)); found := found + 1; end loop; IF (high >= high_recno) THEN deb('resync', 'Processed '||found|| ' tempfiles. Done', dbtype); goto all_tf_found; ELSE low := high + 1; END IF; end loop; <> dbms_rcvcat.endTempFileResync; end if; end; procedure resyncPdbInc is is_cdb number; -- is a CDB? begin select decode(cdb, 'YES', 1, 0) into is_cdb from v$database; if (is_cdb = 0) then return; end if; recid := dbms_rcvcat.beginPluggableDbincResync; -- for picrec in pic(0, 0, 1) loop deb('resync', 'Calling checkPluggableDbinc for fab/special record'|| ' pdbname= ' || picrec.name || ' guid=' || picrec.guid || ' con_id=' || picrec.con_id|| ' recid=' || picrec.recid || ' curr=' || picrec.curr_pdbinc || ' inc_scn=' || picrec.inc_scn || ' end_reset_scn=' || picrec.end_reset_scn || ' db_reset_scn=' || picrec.db_reset_scn || ' pr_inc_scn=' || nvl(picrec.pr_inc_scn, '') || ' pr_end_reset_scn=' || nvl(picrec.pr_end_reset_scn, '') || ' pr_db_reset_scn=' || picrec.pr_db_reset_scn, dbtype); dbms_rcvcat.checkPluggableDbinc( picrec.recid, picrec.guid, picrec.curr_pdbinc, picrec.inc_scn, picrec.begin_reset_scn, picrec.begin_reset_time, picrec.end_reset_scn, picrec.db_reset_scn, picrec.db_reset_time, picrec.pr_inc_scn, picrec.pr_end_reset_scn, picrec.pr_db_reset_scn, picrec.pr_db_reset_time, FALSE); end loop; select record_size, last_recid into rec_size, high_pic_recid from v$controlfile_record_section where type='PDBINC RECORD'; deb('resync', 'Plugggable inc last recid ' || recid || '; high ' || high_pic_recid); -- recid := dbms_rcvcat.beginPluggableDbincResync; if (high_pic_recid > recid) then high := recid; low := recid + 1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := high_pic_recid - low + 1; deb_sort_area(high_pic_recid); while (high < high_pic_recid) loop high := least(low + rec_per_chunk - 1, high_pic_recid); for picrec in pic(low, high, 0) loop deb('resync', 'Calling checkPluggableDbinc for' || ' pdbname= ' || picrec.name || ' guid=' || picrec.guid || ' con_id=' || picrec.con_id || ' recid=' || picrec.recid || ' curr=' || picrec.curr_pdbinc || ' inc_scn=' || picrec.inc_scn || ' end_reset_scn=' || picrec.end_reset_scn || ' db_reset_scn=' || picrec.db_reset_scn || ' pr_inc_scn=' || nvl(picrec.pr_inc_scn, '') || ' pr_end_reset_scn=' || nvl(picrec.pr_end_reset_scn, '') || ' pr_db_reset_scn=' || picrec.pr_db_reset_scn, dbtype); dbms_rcvcat.checkPluggableDbinc( picrec.recid, picrec.guid, picrec.curr_pdbinc, picrec.inc_scn, picrec.begin_reset_scn, picrec.begin_reset_time, picrec.end_reset_scn, picrec.db_reset_scn, picrec.db_reset_time, picrec.pr_inc_scn, picrec.pr_end_reset_scn, picrec.pr_db_reset_scn, picrec.pr_db_reset_time, TRUE); end loop; low := high + 1; end loop; end if; dbms_rcvcat.endPluggableDbincResync(high_pic_recid); end; begin entered('resync'); debug_resync := FALSE; &resync_flag& deb('resync', 'resyncing to AM is =' || resync_2_AMSchema, dbtype); -- -- -- -- -- -- if not implicit then dbms_rcvcat.lockForCkpt; end if; <> -- come back here for automatic resync from primary -- -- if (releasecf) then deb('resync', 'Release earlier held snapshot enqueue', dbtype); sys.dbms_backup_restore.cfileUseCurrent; releasecf := FALSE; end if; if auto_prim_resync then select primary_db_unique_name into for_dbuname from v$database; end if; if callSetDatabase then select dbid, name, dbinc.resetlogs_change#, dbinc.resetlogs_time, controlfile_type, upper(db_unique_name) into for_db_id, db_name, reset_scn, reset_time, cf_type, curr_dbuname from v$database, v$database_incarnation dbinc where dbinc.status = 'CURRENT'; if cf_type = 'BACKUP' then deb('resync', 'remote site is primary', dbtype); cf_type := 'CURRENT'; -- -- ub4_cf_type := 1; else deb('resync', 'remote site is standby', dbtype); -- -- ub4_cf_type := 4; end if; <> -- come here after registering new incarnation begin dbms_rcvcat.setDatabase(db_name => db_name, reset_scn => reset_scn, reset_time => reset_time, db_id => db_id, db_unique_name => curr_dbuname, dummy_instance => FALSE, cf_type => ub4_cf_type, site_aware => TRUE); -- -- -- krmicd.checksetDatabase; callSetDatabase := FALSE; exception -- -- when DATABASE_INCARNATION_NOT_FOUND then select dbid, name, resetlogs_change#, resetlogs_time into db_id, db_name, reset_scn, reset_time from v$database; select diprs, to_date(diprc, 'MM/DD/RR HH24:MI:SS', 'NLS_CALENDAR=Gregorian') into parent_reset_scn, parent_reset_time from x$kccdi; begin dbms_rcvcat.resetDatabase(db_id => db_id, db_name => db_name, reset_scn => reset_scn, reset_time => reset_time, parent_reset_scn => parent_reset_scn, parent_reset_time => parent_reset_time); krmicd.writeMsg(8005); goto resync_after_incarnation; exception when incarnation_already_registered then deb('resync', 'database incarnation already known',dbtype); goto resync_after_incarnation; end; when others then raise; end; end if; sort_area_size := set_sort_area_size(null); if sort_area_size < sort_area_size_init then sort_area_size := set_sort_area_size(sort_area_size_init); end if; deb('resync', 'Starting resync', dbtype); -- if for_dbuname is not null then krmicd.writeMsg(6615, for_dbuname); end if; deb('resync', 'cfname is '|| cfname, dbtype); if cfname is null then select status into mount_status from v$instance; if mount_status not in ('MOUNTED', 'OPEN') then if full_resync then krmicd.writeMsg(8034); else krmicd.writeMsg(8035); end if; return; end if; else mount_status := 'BACKUP'; -- resync from backup cf end if; -- -- -- if for_dbuname is null then select startup_time into inst_startup_time from v$instance; inst_startup_stamp := date2stamp(inst_startup_time); end if; <> -- retry on makeAndUseSnapshot failure begin -- -- if (full_resync) then deb('resync', 'full_resync value is true', dbtype); else deb('resync', 'full_resync value is false', dbtype); end if; if (full_resync or for_dbuname is not null) then if (cfname is null) then -- -- select controlfile_type, db_id into cf_type, db_id from v$database; -- -- -- -- -- -- if for_dbuname is null then sys.dbms_backup_restore.cfileMakeAndUseSnapshot( isstby => FALSE, source_dbuname => NULL, source_cs => NULL, dest_cs => NULL, for_resync => TRUE); else -- -- deb('resync', 'creating remote cf snapshot for '|| for_dbuname,dbtype); deb('resync', 'source connid '|| source_cs, dbtype); deb('resync', 'dest connid '|| dest_cs, dbtype); -- -- -- -- low_run_recid := sys.dbms_backup_restore.remoteSQLExecute( source_dbuname => for_dbuname, source_cs => source_cs, stmt => 'select nvl(min(recid), -1) ' || 'from gv$rman_status_current ' || 'where status like ''%RUNNING%'''); deb('resync', 'lowest recid for running job at primary ' || low_run_recid, dbtype ); if source_cs is null then source_cs := sys.dbms_backup_restore.get_connect_identifier (dbuname => for_dbuname); if source_cs is null then krmicd.SignalErrMsg(6613, for_dbuname); return; end if; deb('resync', 'got source connid '|| source_cs, dbtype); end if; if dest_cs is null then select db_unique_name into ldb_unique_name from v$database; -- -- null_retVal := sys.dbms_backup_restore.remoteSQLExecute( source_dbuname => for_dbuname, source_cs => source_cs, stmt => 'declare ' || ' n varchar2(200);' || 'begin ' || ' n := sys.dbms_backup_restore.getCkptSCN;' || 'end;'); dest_cs := sys.dbms_backup_restore.remoteSQLExecute( source_dbuname => for_dbuname, source_cs => source_cs, stmt => 'select ' || ' sys.dbms_backup_restore.get_connect_identifier('|| ' dbuname=>''' || ldb_unique_name || ''')' || ' from dual'); if dest_cs is null then krmicd.SignalErrMsg(6613, ldb_unique_name); return; end if; deb('resync', 'got dest connid '|| dest_cs, dbtype); end if; sys.dbms_backup_restore.cfileMakeAndUseSnapshot( isstby => FALSE, source_dbuname => for_dbuname, source_cs => source_cs, dest_cs => dest_cs, for_resync => TRUE); -- -- select dbid, name, dbinc.resetlogs_change#, dbinc.resetlogs_time, controlfile_type, upper(db_unique_name) into for_db_id, db_name, reset_scn, reset_time, cf_type, ldb_unique_name from v$database db, v$database_incarnation dbinc where dbinc.status = 'CURRENT'; -- if db_id <> for_db_id then raise db_id_mismatch; end if; -- -- -- -- -- -- -- if lower(ldb_unique_name) <> lower(for_dbuname) then krmicd.writeMsg(6538, for_dbuname, ldb_unique_name); raise dbuname_mismatch; end if; mount_status := sys.dbms_backup_restore.remoteSQLExecute( source_dbuname => for_dbuname, source_cs => source_cs, stmt => 'select status from v$instance'); deb('resync', 'remote site mount_status=' || mount_status, dbtype); -- -- if cf_type = 'BACKUP' then deb('resync', 'remote site is primary', dbtype); cf_type := 'CURRENT'; -- -- ub4_cf_type := 1; else deb('resync', 'remote site is standby', dbtype); -- -- ub4_cf_type := 4; end if; -- -- begin dbms_rcvcat.setDatabase(db_name => db_name, reset_scn => reset_scn, reset_time => reset_time, db_id => db_id, db_unique_name => for_dbuname, dummy_instance => FALSE, cf_type => ub4_cf_type, site_aware => TRUE); -- -- -- krmicd.checksetDatabase; exception -- -- when others then raise; end; end if; else -- sys.dbms_backup_restore.cfileUseCopy(cfname); end if; releasecf := TRUE; end if; exception when sys.dbms_backup_restore.snapshot_enqueue_busy then -- -- -- -- if busy_retries = 180 then krmicd.writeMsg(20029, 'cannot make a snapshot controlfile'); raise; end if; busy_retries := busy_retries + 1; -- if (mod(busy_retries, 15) = 0) then krmicd.writeMsg(8512); end if; krmicd.sleep(20); krmicd.clearErrors; goto snapshot; end; -- snapshot controlfile stuff -- -- -- pdb_dict_check.delete; for pdbrec in pdb_dict_check_c loop pdb_dict_check(pdbrec.con_id) := 1; deb('resync', 'con_id=' || pdbrec.con_id || ' needs dictionary check', dbtype); end loop; -- -- -- if (cf_type is null) then -- cf_type not filled up yet select controlfile_type into cf_type from v$database; deb('resync', 'set cf_type to '|| cf_type); end if; if cf_type = 'STANDBY' then -- -- -- -- deb('resync', 'Resyncing from a standby controlfile', dbtype); full_resync := FALSE; elsif cf_type = 'CURRENT' then deb('resync', 'Resyncing from a current controlfile', dbtype); elsif cf_type = 'BACKUP' then deb('resync', 'Resyncing from a backup controlfile', dbtype); full_resync := FALSE; elsif cf_type = 'FARSYNC' then deb('resync', 'Resyncing from a farsync controlfile', dbtype); full_resync := FALSE; elsif cf_type = 'CREATED' then deb('resync', 'Resyncing from a created controlfile', dbtype); full_resync := FALSE; else if full_resync then krmicd.writeMsg(8040); else krmicd.writeMsg(8041); end if; ignore_resync_err := TRUE; raise resync_not_needed; end if; <> -- retry on inconsistent read or sort_area_size overflow begin -- -- -- -- -- if (sort_retries = 0 AND read_retries = 0) then select dbid, name, dbinc.resetlogs_change#, dbinc.prior_resetlogs_change#, dbinc.resetlogs_time, dbinc.prior_resetlogs_time, controlfile_created, controlfile_sequence#, controlfile_change#, controlfile_time, version_time into db_id, db_name, reset_scn, prior_reset_scn, reset_time, prior_reset_time, cf_create_time, ckp_cf_seq, ckp_scn, ckp_time, cf_version from v$database db, v$database_incarnation dbinc where dbinc.incarnation# = db.recovery_target_incarnation#; -- select db_unique_name into ldb_unique_name from v$database; kccdivts := date2stamp(cf_version); -- used by circular record queries deb('resync', 'kccdivts= '||to_char(kccdivts), dbtype); if for_dbuname is not null then -- -- null_retVal := sys.dbms_backup_restore.remoteSQLExecute( source_dbuname => for_dbuname, source_cs => source_cs, stmt => 'declare ' || ' n varchar2(200);' || 'begin ' || ' n := sys.dbms_backup_restore.getCkptSCN;' || 'end;'); getckptscn := to_number( sys.dbms_backup_restore.remoteSQLExecute( source_dbuname => for_dbuname, source_cs => source_cs, stmt => 'select sys.dbms_backup_restore.getCkptSCN from dual')); else getckptscn := sys.dbms_backup_restore.getCkptSCN; end if; -- -- select last_recid into high_cp_recid from v$controlfile_record_section where type = 'CKPT PROGRESS'; select last_recid into high_rt_recid from v$controlfile_record_section where type = 'REDO THREAD'; select last_recid into high_le_recid from v$controlfile_record_section where type = 'REDO LOG'; select last_recid into high_fe_recid from v$controlfile_record_section where type = 'DATAFILE'; select last_recid into high_fn_recid from v$controlfile_record_section where type = 'FILENAME'; select last_recid into high_ts_recid from v$controlfile_record_section where type = 'TABLESPACE'; select last_recid into high_r1_recid from v$controlfile_record_section where type = 'TEMPORARY FILENAME'; select last_recid into high_rm_recid from v$controlfile_record_section where type = 'RMAN CONFIGURATION'; select last_recid into high_lh_recid from v$controlfile_record_section where type = 'LOG HISTORY'; select last_recid into high_or_recid from v$controlfile_record_section where type = 'OFFLINE RANGE'; select last_recid into high_al_recid from v$controlfile_record_section where type = 'ARCHIVED LOG'; select last_recid into high_bs_recid from v$controlfile_record_section where type = 'BACKUP SET'; select last_recid into high_bp_recid from v$controlfile_record_section where type = 'BACKUP PIECE'; select last_recid into high_bf_recid from v$controlfile_record_section where type = 'BACKUP DATAFILE'; select last_recid into high_bl_recid from v$controlfile_record_section where type = 'BACKUP REDOLOG'; select last_recid into high_dc_recid from v$controlfile_record_section where type = 'DATAFILE COPY'; select last_recid into high_fc_recid from v$controlfile_record_section where type = 'BACKUP CORRUPTION'; select last_recid into high_cc_recid from v$controlfile_record_section where type = 'COPY CORRUPTION'; select last_recid into high_dl_recid from v$controlfile_record_section where type = 'DELETED OBJECT'; select last_recid into high_pc_recid from v$controlfile_record_section where type = 'PROXY COPY'; select last_recid into high_bi_recid from v$controlfile_record_section where type = 'BACKUP SPFILE'; if debug_resync then deb('resync', 'high_cp_recid= '||high_cp_recid, dbtype); deb('resync', 'high_rt_recid= '||high_rt_recid, dbtype); deb('resync', 'high_le_recid= '||high_le_recid, dbtype); deb('resync', 'high_fe_recid= '||high_fe_recid, dbtype); deb('resync', 'high_fn_recid= '||high_fn_recid, dbtype); deb('resync', 'high_ts_recid= '||high_ts_recid, dbtype); deb('resync', 'high_r1_recid= '||high_r1_recid, dbtype); deb('resync', 'high_rm_recid= '||high_rm_recid, dbtype); deb('resync', 'high_lh_recid= '||high_lh_recid, dbtype); deb('resync', 'high_or_recid= '||high_or_recid, dbtype); deb('resync', 'high_al_recid= '||high_al_recid, dbtype); deb('resync', 'high_bs_recid= '||high_bs_recid, dbtype); deb('resync', 'high_bp_recid= '||high_bp_recid, dbtype); deb('resync', 'high_bf_recid= '||high_bf_recid, dbtype); deb('resync', 'high_bl_recid= '||high_bl_recid, dbtype); deb('resync', 'high_dc_recid= '||high_dc_recid, dbtype); deb('resync', 'high_fc_recid= '||high_fc_recid, dbtype); deb('resync', 'high_cc_recid= '||high_cc_recid, dbtype); deb('resync', 'high_dl_recid= '||high_dl_recid, dbtype); deb('resync', 'high_pc_recid= '||high_pc_recid, dbtype); deb('resync', 'high_bi_recid= '||high_bi_recid, dbtype); end if; if (not full_resync) then ckp_scn := getckptscn; ckp_time := NULL; end if; begin if (full_resync or auto_prim_resync) then dbms_rcvcat.beginCkpt (ckp_scn, ckp_cf_seq, cf_version, ckp_time, 'FULL', mount_status, high_fe_recid, cf_type); else dbms_rcvcat.beginCkpt (ckp_scn, ckp_cf_seq, cf_version, ckp_time, 'PARTIAL', mount_status, high_fe_recid, cf_type); end if; exception when resync_not_needed then ignore_resync_err := implicit; raise; end; -- -- -- -- -- if (dbms_rcvcat.lastFullCkpt is null) then deb('resync', 'first resync after open resetlogs of root', dbtype); deb('resync', 'ignore pdb dictionary check bit', dbtype); pdb_dict_check.delete; end if; if (full_resync) then if implicit then resync_reason := dbms_rcvcat.getReason; if resync_reason = dbms_rcvcat.RESYNC_REASON_NOACTION then fullResyncBaseMsg := 8002; elsif resync_reason = dbms_rcvcat.RESYNC_REASON_TS then fullResyncBaseMsg := 8200; elsif resync_reason = dbms_rcvcat.RESYNC_REASON_DF then fullResyncBaseMsg := 8205; elsif resync_reason = dbms_rcvcat.RESYNC_REASON_TF then fullResyncBaseMsg := 8210; elsif resync_reason = dbms_rcvcat.RESYNC_REASON_THR then fullResyncBaseMsg := 8215; elsif resync_reason = dbms_rcvcat.RESYNC_REASON_ORL then fullResyncBaseMsg := 8220; elsif resync_reason = dbms_rcvcat.RESYNC_REASON_RESET then fullResyncBaseMsg := 8224; elsif resync_reason = dbms_rcvcat.RESYNC_REASON_CONF then fullResyncBaseMsg := 8225; elsif resync_reason = dbms_rcvcat.RESYNC_REASON_RSL then fullResyncBaseMsg := 8226; elsif resync_reason = dbms_rcvcat.RESYNC_REASON_CF then fullResyncBaseMsg := 8227; elsif resync_reason = dbms_rcvcat.RESYNC_REASON_INC then fullResyncBaseMsg := 8228; elsif resync_reason = dbms_rcvcat.RESYNC_REASON_PDB then fullResyncBaseMsg := 8237; else fullResyncBaseMsg := 8229; end if; if not auto_prim_resync then krmicd.writeMsg(fullResyncBaseMsg); end if; else if not auto_prim_resync then krmicd.writeMsg(8002); -- full resync end if; end if; else if not implicit and not auto_prim_resync then krmicd.writeMsg(8243); end if; end if; end if; -- if (for_dbuname IS NOT NULL) then tmzone := sys.dbms_backup_restore.remoteSQLExecute( source_dbuname => for_dbuname, source_cs => source_cs, stmt => 'select TO_CHAR(systimestamp, ''TZR'') from dual'); else select TO_CHAR(systimestamp, 'TZR') into tmzone from x$dual; end if; select db_unique_name into ldb_unique_name from v$database; deb('resync','Instance '||ldb_unique_name|| ' has timezone' || tmzone, dbtype); dbms_rcvcat.addTimeZone(ldb_unique_name, tmzone, 'R'); if (full_resync or auto_prim_resync) then select last_recid into high_pdb_recid from v$controlfile_record_section where type = 'PDB RECORD'; deb('resync', 'high_pdb_recid = ' || high_pdb_recid, dbtype); if dbms_rcvcat.beginPluggableDBResync(high_pdb_recid) then for pdbrec in pdb loop deb('resync', 'Calling checkPluggableDB name=' || pdbrec.name || ' dbid=' || pdbrec.dbid || ' con_id=' || pdbrec.con_id, dbtype); dbms_rcvcat.checkPluggableDB( pdbrec.name, pdbrec.con_id, pdbrec.dbid, pdbrec.create_scn, pdbrec.guid, pdbrec.noBackup); end loop; dbms_rcvcat.endPluggableDBResync; end if; -- -- -- -- resyncPdbInc; select last_recid into high_tf_recid from v$controlfile_record_section where type = 'TEMPORARY FILENAME'; -- -- -- -- -- -- -- -- -- if (mount_status = 'OPEN' OR dbms_rcvcat.tempFileToResync(high_tf_recid)) then force := TRUE; -- force tablespace resync deb('resync', 'Forcing tablespace resync, for '|| nvl(high_ts_recid, 0)||' tablespaces', dbtype); else force := FALSE; deb('resync', 'Checking if tablespace resync is needed, have '|| nvl(high_ts_recid, 0)||' tablespaces', dbtype); end if; krmicd.clearErrors; if dbms_rcvcat.beginTableSpaceResync(high_ts_recid, force) then for tsrec in ts loop if (mount_status = 'OPEN') then begin rbs_count := 0; if tsrec.con_id = 0 then -- non-cdb if for_dbuname is not null then rbs_count := to_number( sys.dbms_backup_restore.remoteSQLExecute( source_dbuname => for_dbuname, source_cs => source_cs, stmt => 'select count(us#) from undo$ u ' || ' where u.ts# = ' || tsrec.ts# || ' and u.status$ != 1')); else select count(us#) into rbs_count from undo$ u where u.ts# = tsrec.ts# and u.status$ != 1; end if; else -- cdb if for_dbuname is not null then rbs_count := to_number( sys.dbms_backup_restore.remoteSQLExecute( source_dbuname => for_dbuname, source_cs => source_cs, stmt => 'select count(*) from cdb_rollback_segs u ' || ' where u.tablespace_name = ''' || tsrec.name || ''' and u.con_id = ' || tsrec.con_id || ' and (u.con_id = 1 or ' || ' exists ( ' || ' select 1 from v$containers ' || ' where con_id = ' || tsrec.con_id || ' and local_undo = 1 ' || ' ) ' || ' )')); else select count(*) into rbs_count from cdb_rollback_segs u where tsrec.name = u.tablespace_name and tsrec.con_id = u.con_id and (u.con_id = 1 or exists (select 1 from v$containers where con_id = tsrec.con_id and local_undo = 1)); end if; end if; exception when others then err_msg := sqlerrm; krmicd.writeErrMsg(4005, err_msg); rbs_count := 0; raise; end; end if; deb('resync', 'Calling checkTableSpace', dbtype); deb('resync', ' for ts: '||tsrec.name||' ('||to_char(tsrec.ts#)|| '), cscn: '||to_char(tsrec.create_scn)|| ', plugin_scn: '||to_char(tsrec.plugin_scn)||' with '|| rbs_count||' rollback segments', dbtype); dbms_rcvcat.checkTableSpace (tsrec.name, tsrec.ts#, tsrec.create_scn, tsrec.create_time, rbs_count, tsrec.included_in_database_backup, tsrec.bigfile, tsrec.temporary, tsrec.encrypt_in_backup, tsrec.plugin_scn, tsrec.con_id, pdb_dict_check.exists(tsrec.con_id)); end loop; deb('resync', 'Calling endTableSpaceResync', dbtype); dbms_rcvcat.endTableSpaceResync; end if; IF dbms_rcvcat.beginDataFileResync(high_fe_recid) THEN select record_size into rec_size from v$controlfile_record_section where type='DATAFILE'; rec_size := 1024 + rec_size; -- kccfn + kccfe rec_per_chunk := floor(sort_area_size / rec_size); select max(fenum) into high_recno from x$kccfe fe where fe.fedup != 0; deb('resync', 'total files= '|| total_recs, dbtype); found := 0; low := 1; deb_sort_area(0); loop high := low + rec_per_chunk - 1; for dfrec in df(low, high) LOOP deb('resync', 'Resyncing datafile '|| dfrec.fname, dbtype); IF (dfrec.plugged_readonly = 'NO' OR dfrec.plugin_scn != 0) THEN IF (dfrec.clean_flag <> 0 OR -- the clean bit is on dfrec.plugged_readonly = 'YES') THEN IF (dfrec.read_enabled_flag <> 0 AND dfrec.pdb_closed = 0) THEN read_only := 1; ELSE read_only := 0; -- offline clean or pdb_closed END IF; ELSE -- the file is not clean dfrec.stop_scn := NULL; dfrec.stop_time := NULL; dfrec.pdb_closed := 0; read_only := 0; END IF; IF dfrec.fsize = 0 THEN -- -- dfrec.fsize := NULL; END IF; IF dfrec.missing_file_flag <> 0 THEN -- -- -- dfrec.fname := NULL; END IF; deb('resync', 'Calling checkDataFile for fileno '|| dfrec.fileno||' size '||dfrec.fsize, dbtype); dbms_rcvcat.checkDataFile( dfrec.fileno, dfrec.fname, dfrec.create_scn, dfrec.create_time, dfrec.fsize, dfrec.block_size, dfrec.tsnum, dfrec.stop_scn, read_only, dfrec.stop_time, dfrec.rfileno, dfrec.aux_fname, dfrec.foreign_dbid, dfrec.foreign_create_scn, dfrec.foreign_create_time, dfrec.plugged_readonly, dfrec.plugin_scn, dfrec.plugin_reset_scn, dfrec.plugin_reset_time, dfrec.create_thread, dfrec.create_size, dfrec.con_id, dfrec.pdb_closed, pdb_dict_check.exists(dfrec.con_id), dfrec.pdb_foreign_dbid); -- -- -- IF (dfrec.aux_fname = 'UNKNOWN') THEN IF debug_resync THEN deb('resync', 'Calling getCloneName', dbtype); END IF; rc_aux_fname := dbms_rcvcat.getCloneName(dfrec.fileno, dfrec.create_scn, dfrec.plugin_scn); IF for_dbuname is not null THEN null_retVal := sys.dbms_backup_restore.remoteSQLExecute( source_dbuname => for_dbuname, source_cs => source_cs, stmt => 'begin ' || ' sys.dbms_backup_restore.setDatafileAux(' || dfrec.fileno || ',''' || replace(rc_aux_fname,'''','''''') || '''); '|| 'end;'); ELSE sys.dbms_backup_restore.setDatafileAux(dfrec.fileno, rc_aux_fname); END IF; END IF; IF dfrec.offline_scn <> 0 then deb('resync', 'Calling checkOfflineRange: offline '|| dfrec.offline_scn||' online '|| dfrec.online_scn, dbtype); dbms_rcvcat.checkOfflineRange( null, null, dfrec.fileno, dfrec.create_scn, dfrec.offline_scn, dfrec.online_scn, dfrec.online_time, cf_create_time); END IF; END IF; found := found + 1; end loop; IF (high >= high_recno) THEN deb('resync', 'Processed '||found|| ' datafiles. Done', dbtype); goto all_df_found; END IF; low := high + 1; end loop; <> dbms_rcvcat.endDataFileResync; end if; resyncTempfiles; deb('resync', 'high_rt_recid= '|| high_rt_recid, dbtype); if dbms_rcvcat.beginThreadResync(high_rt_recid) then for rtrec in rt loop deb('resync', 'Calling checkThread for thread '|| rtrec.thread#||' with sequence '|| rtrec.last_sequence#, dbtype); dbms_rcvcat.checkThread (rtrec.thread#, rtrec.last_sequence#, rtrec.enable_scn, rtrec.enable_time, rtrec.disable_scn, rtrec.disable_time, rtrec.status); end loop; dbms_rcvcat.endThreadResync; end if; deb('resync', 'high_le_recid= '|| high_le_recid, dbtype); if dbms_rcvcat.beginOnlineRedoLogResync(high_le_recid) then for orlrec in orl loop deb('resync','Calling checkOnlineRedoLog '|| orlrec.fname, dbtype); dbms_rcvcat.checkOnlineRedoLog (orlrec.thread#, orlrec.group#, orlrec.fname, orlrec.bytes, orlrec.type); end loop; dbms_rcvcat.endOnlineRedoLogResync; end if; if resync_reason != dbms_rcvcat.RESYNC_REASON_NOACTION then deb('resync', 'Checking for fullResyncAction', dbtype); dbms_rcvcat.getResyncActions(resync_valid, resync_added, resync_dropped, resync_changed, resync_recreated, resync_renamed, resync_resized); deb('resync', 'fullResyncAction.added: '||nvl(resync_added, -1), dbtype); deb('resync', 'fullResyncAction.dropped: '||nvl(resync_dropped, -1), dbtype); deb('resync', 'fullResyncAction.changed: '||nvl(resync_changed, -1), dbtype); deb('resync', 'fullResyncAction.recreated: '||nvl(resync_recreated, -1), dbtype); deb('resync', 'fullResyncAction.renamed: '||nvl(resync_renamed, -1), dbtype); deb('resync', 'fullResyncAction.resized: '||nvl(resync_resized, -1), dbtype); if resync_valid then deb('resync', 'Got a valid fullResyncAction', dbtype); krmicd.msgResyncActions(fullResyncBaseMsg, resync_added, resync_dropped, resync_changed, resync_recreated, resync_renamed, resync_resized); end if; end if; dbms_rcvcat.setReason(dbms_rcvcat.RESYNC_REASON_NONE, TRUE); end if; -- full_resync or auto_prim_resync IF not auto_prim_resync AND cf_type = 'STANDBY' AND not converted_cf THEN IF dbms_rcvcat.beginOnlineRedoLogResync(high_le_recid) THEN for orlrec in orl loop deb('resync','Calling checkOnlineRedoLog '|| orlrec.fname, dbtype); dbms_rcvcat.checkOnlineRedoLog (orlrec.thread#, orlrec.group#, orlrec.fname, orlrec.bytes, orlrec.type); end loop; dbms_rcvcat.endOnlineRedoLogResync; END IF; IF dbms_rcvcat.beginDataFileResyncForStandby(high_fe_recid) THEN rec_size := 758 + 75; rec_per_chunk := floor(sort_area_size / rec_size); select max(fenum) into high_recno from x$kccfe fe where fe.fedup != 0; found := 0; low := 1; deb_sort_area(0); loop high := low + rec_per_chunk - 1; for dfrec in df(low, high) LOOP deb('resync', 'Resyncing datafile for standby '|| dfrec.fname); IF (dfrec.plugged_readonly = 'NO' OR dfrec.plugin_scn != 0) THEN IF (dfrec.clean_flag <> 0 OR -- the clean bit is on dfrec.plugged_readonly = 'YES') THEN IF (dfrec.read_enabled_flag <> 0 AND dfrec.pdb_closed = 0) THEN read_only := 1; ELSE read_only := 0; -- offline clean END IF; ELSE -- the file is not clean dfrec.stop_scn := NULL; dfrec.stop_time := NULL; read_only := 0; END IF; IF dfrec.fsize = 0 THEN -- -- dfrec.fsize := NULL; END IF; IF dfrec.missing_file_flag <> 0 THEN -- -- -- dfrec.fname := NULL; END IF; deb('resync', 'Calling checkDataFileForStandby for fileno '|| dfrec.fileno||' size '||dfrec.fsize); dbms_rcvcat.checkDataFileForStandby( dfrec.fileno, dfrec.fname, dfrec.create_scn, dfrec.create_time, dfrec.fsize, dfrec.block_size, dfrec.tsnum, dfrec.rfileno, dfrec.stop_scn, read_only, dfrec.foreign_dbid, dfrec.plugin_scn); END IF; found := found + 1; end loop; IF (high >= high_recno) THEN deb('resync', 'Processed '||found|| ' datafiles. Done'); goto all_df_found_for_standby; END IF; low := high + 1; end loop; <> dbms_rcvcat.endDataFileResyncForStandby; end if; select record_size, last_recid into rec_size, high_tf_recid from v$controlfile_record_section where type = 'TEMPORARY FILENAME'; if dbms_rcvcat.beginTempFileResyncForStandby(high_tf_recid) THEN rec_size := 1024 + rec_size; -- kccfn + kcctf rec_per_chunk := floor(sort_area_size / rec_size); -- select nvl(max(tfnum), 0) into high_recno from x$kcctf where tfdup != 0; found := 0; low := 1; deb_sort_area(0); loop high := low + rec_per_chunk - 1; for tfrec in tf(low, high) LOOP deb('resync', 'Resyncing tempfile '|| tfrec.fname, dbtype); IF tfrec.fsize = 0 THEN -- -- tfrec.fsize := NULL; END IF; deb('resync', 'Calling checkTempFile for fileno '|| tfrec.fileno||' size '||tfrec.fsize, dbtype); dbms_rcvcat.checkTempFileForStandby( tfrec.fileno, tfrec.fname, tfrec.create_scn, tfrec.create_time, tfrec.fsize, tfrec.block_size, tfrec.tsnum, tfrec.rfileno, tfrec.autoextend, tfrec.max_size, tfrec.next_size, tfrec.con_id); found := found + 1; end loop; IF (high >= high_recno) THEN deb('resync', 'Processed '||found|| ' tempfiles. Done', dbtype); goto all_stby_tf_found; ELSE low := high + 1; END IF; end loop; <> dbms_rcvcat.endTempFileResyncForStandby; end if; END IF; if (not auto_prim_resync and dbms_rcvcat.doDuplicateMining) then -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- deb('resync', 'Begin mining previous resyncstamp', dbtype); select max(stamp1), min(stamp2) into max_stamp, until_stamp from (select nvl(max(al.stamp), least_stamp) stamp1, nvl(min(al.stamp), greatest_stamp) stamp2 from v$archived_log al where standby_dest = 'NO' and status != 'D' and archived = 'YES' and al.stamp >= kccdivts union all select nvl(max(bp.stamp), least_stamp) stamp1, nvl(min(bp.stamp), greatest_stamp) stamp2 from v$backup_piece bp where status != 'D' and bp.stamp >= kccdivts union all select nvl(max(dc.stamp), least_stamp) stamp1, nvl(min(dc.stamp), greatest_stamp) stamp2 from v$datafile_copy dc where status != 'D' and dc.stamp >= kccdivts); deb('resync', '(until_stamp, max_stamp)=(' || until_stamp || ',' || max_stamp || ')', dbtype); if (max_stamp >= until_stamp) then if is19871set then -- testing binary search unit := 24 * 60 * 60; -- second granularity maxdups := 2; -- look for two duplicates end if; min_stamp := until_stamp; <> no_units := stamp2date(max_stamp) - stamp2date(min_stamp); deb('resync', 'number of days apart=' || no_units || ' unit=' || unit, dbtype); no_units := ceil(no_units * unit); deb('resync', 'number of units apart=' || no_units, dbtype); high := no_units; low := 0; middle := 0; -- while (low <= high) loop middle := floor((low + high) / 2); deb('resync', 'high=' || high || ' low=' || low, dbtype); high_stamp := date2stamp(stamp2date(min_stamp) + middle/unit); wasresyncstamp := wasresynced(until_stamp, high_stamp); if (wasresyncstamp != 0) then resyncstamp := wasresyncstamp; low := middle + 1; if (wasresyncstamp = -1) then new_min_stamp := high_stamp; end if; else high := middle - 1; end if; end loop; -- -- if (resyncstamp = -1 and unit < 1440 and new_min_stamp > 0) then deb('resync', 'retry using new min_stamp ' || new_min_stamp, dbtype); unit := 1440; -- minute granularity min_stamp := new_min_stamp; goto retry_mining; end if; deb('resync', 'previous resyncstamp=' || resyncstamp, dbtype); end if; deb('resync', 'End mining previous resyncstamp', dbtype); end if; -- -- -- select record_size, last_recid into rec_size, high_ic_recid from v$controlfile_record_section where type='DATABASE INCARNATION'; recid := dbms_rcvcat.beginIncarnationResync(return_Recid=>TRUE); deb('resync', 'Incarnation last recid ' ||recid||'; high '||high_ic_recid, dbtype); if (high_ic_recid > recid) then high := recid; low := recid+1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := high_ic_recid - low + 1; deb_sort_area(high_ic_recid); while (high < high_ic_recid) loop high := least(low + rec_per_chunk -1, high_ic_recid); for icrec in ic(low, high) loop deb('resync', 'Calling checkIncarnation with reset_scn: '|| icrec.resetlogs_change#||' reset_time: ' || icrec.prior_resetlogs_time, dbtype); parent_dbinc_key := dbms_rcvcat.checkIncarnation(icrec.resetlogs_change#, icrec.resetlogs_time, icrec.prior_resetlogs_change#, icrec.prior_resetlogs_time, db_name); end loop; low := high + 1; end loop; -- deb('resync', 'Calling checkIncarnation for current reset_scn: '|| reset_scn||' reset_time: '||reset_time, dbtype); parent_dbinc_key := dbms_rcvcat.checkIncarnation(reset_scn, reset_time, prior_reset_scn, prior_reset_time, db_name); end if; dbms_rcvcat.endIncarnationResync(kccdivts, high_ic_recid); -- -- -- ret := dbms_rcvcat.beginConfigResync2(high_conf_recid => high_rm_recid); deb('resync', 'Configuration last recid '||high_rm_recid|| '; ret '|| ret, dbtype); -- -- -- -- if (ret = CONFIGRESYNC_TORC OR ret = CONFIGRESYNC_TORC_TOCF) then resyncConf2Catalog(cf_type, FALSE); end if; if auto_prim_resync then goto skip_circular_section_resync; end if; if (cfname is null and -- not a resync from controlfile copy cf_type != 'BACKUP') then -- not a backup controlfile flashback_time := getFlashbackTime(cf_type); select last_recid into high_grsp_recid from v$controlfile_record_section where type = 'GUARANTEED RESTORE POINT'; dbms_rcvcat.updateOldestFlashbackSCN( oldest_flashback_scn => NULL, -- obsolete argument oldest_flashback_time => flashback_time); deb('resync', 'high_grsp_recid = ' || high_grsp_recid, dbtype); if dbms_rcvcat.beginGuaranteedRPResync(high_grsp_recid) then for grsprec in grsp loop deb('resync', 'Calling checkGuaranteedRP ' || grsprec.rspname, dbtype); dbms_rcvcat.checkGuaranteedRP (grsprec.rspname, grsprec.from_scn, grsprec.to_scn, grsprec.resetlogs_change#, grsprec.resetlogs_time, grsprec.rsptime, grsprec.rsprsptime, grsprec.guaranteed, grsprec.con_id, grsprec.clean); end loop; dbms_rcvcat.endGuaranteedRPResync; end if; end if; -- -- -- -- -- -- -- -- -- -- -- -- recid := dbms_rcvcat.beginRmanStatusResync; -- -- -- -- select record_size, last_recid into rec_size, high_rsr_recid from v$controlfile_record_section where type='RMAN STATUS'; running_found := FALSE; deb('resync', 'RmanStatusResync last recid '||recid|| '; high '||high_rsr_recid, dbtype); -- if (low_run_recid > 0 and low_run_recid < high_rsr_recid) then deb('resync', 'using low_run_recid ' || low_run_recid, dbtype); shigh_rsr_recid := low_run_recid - 1; else shigh_rsr_recid := high_rsr_recid; end if; if (high_rsr_recid > recid) then high := recid; low := recid + 1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := high_rsr_recid - low + 1; deb_sort_area(high_rsr_recid); while (high < high_rsr_recid) loop high := least(low + rec_per_chunk - 1, high_rsr_recid); deb('resync', 'Calling rsr cursor from: '|| low||' to: '||high, dbtype); for rsrrec in rsr(low, high) loop -- -- -- -- -- -- if (rsrrec.status like '%RUNNING%' and sysdate - rsrrec.start_time < 4 and not running_found ) then deb('resync', 'row '||low||' belongs to job still running: ' || rsrrec.status, dbtype); shigh_rsr_recid := rsrrec.recid - 1; running_found := TRUE; else deb('resync', 'row '||low||' belongs to finished job: ' || rsrrec.status, dbtype, rman_constant.LEVEL_HI); end if; deb('resync', 'Calling checkRmanStatus for '|| rsrrec.recid || ' with status '||rsrrec.status, dbtype); dbms_rcvcat.checkRmanStatus(rsrrec.recid, rsrrec.stamp, rsrrec.parent_recid, rsrrec.parent_stamp, rsrrec.row_level, rsrrec.row_type, rsrrec.command_id, rsrrec.operation, rsrrec.status, rsrrec.mbytes_processed, rsrrec.start_time, rsrrec.end_time, rsrrec.input_bytes, rsrrec.output_bytes, rsrrec.optimized, rsrrec.object_type, rsrrec.session_recid, rsrrec.session_stamp, rsrrec.output_device_type, rsrrec.osb_allocated); end loop; low := high + 1; end loop; end if; dbms_rcvcat.endRmanStatusResync(shigh_rsr_recid); if for_dbuname is not null then -- -- -- -- deb('resync', 'we can not resync rman output for remote instance'); else low := dbms_rcvcat.beginRmanOutputResync(inst_startup_stamp, doRoutMining); -- -- -- -- if (doRoutMining = true) then deb('resync', 'Begin duplicate rout mining'); select max(stamp1), min(stamp2) into max_stamp, until_stamp from (select nvl(max(rout.stamp), least_stamp) stamp1, nvl(min(rout.stamp), greatest_stamp) stamp2 from v$rman_output rout); deb('resync', '(until_stamp, max_stamp)=(' || until_stamp || ',' || max_stamp || ')', dbtype); if (max_stamp >= until_stamp) then unit := 24 * 60 * 60; -- second granularity maxdups := 16; -- look for 16 duplicates min_stamp := until_stamp; <> no_units := stamp2date(max_stamp) - stamp2date(min_stamp); deb('resync', 'number of days apart=' || no_units || ' unit=' || unit, dbtype); no_units := ceil(no_units * unit); deb('resync', 'number of units apart=' || no_units, dbtype); high := no_units; low := 0; middle := 0; -- while (low <= high) loop middle := floor((low + high) / 2); deb('resync', 'high=' || high || ' low=' || low, dbtype); high_stamp := date2stamp(stamp2date(min_stamp) + middle/unit); wasresyncstamp := routresynced(until_stamp, high_stamp); if (wasresyncstamp != 0) then resyncstamp := wasresyncstamp; low := middle + 1; if (wasresyncstamp = -1) then new_min_stamp := high_stamp; end if; else high := middle - 1; end if; end loop; deb('resync', 'previous resyncstamp=' || resyncstamp, dbtype); end if; deb('resync', 'End mining previous resyncstamp', dbtype); if (resyncstamp > 0) then low := resyncstamp; end if; end if; if low = (greatest_stamp - 1) then deb('resync', 'RMAN output disabled'); else deb('resync', 'RMAN output last RMAN output '||low); for routrec in rout(low) loop deb('resync', 'Calling checkRmanOutput with recid '||routrec.recid ||' stamp '|| routrec.stamp||' session '|| routrec.session_recid ||' session stamp '|| routrec.session_stamp, dbtype, rman_constant.LEVEL_HI); deb('resync', 'rman_status_recid '||routrec.rman_status_recid || ' rman_status_stamp '|| routrec.rman_status_stamp, dbtype, rman_constant.LEVEL_HI); deb('resync', 'Calling checkRmanOutput with output '|| routrec.output, dbtype, rman_constant.LEVEL_HI); dbms_rcvcat.checkRmanOutput(routrec.recid, routrec.stamp, routrec.session_recid, routrec.session_stamp, routrec.rman_status_recid, routrec.rman_status_stamp, routrec.output); end loop; dbms_rcvcat.endRmanOutputResync; end if; end if; recid := dbms_rcvcat.beginLogHistoryResync; if (recid = 0) then lh_lowscn := dbms_rcvcat.getLogHistoryLowSCN; if (lh_lowscn > 0) then select nvl(max(recid), 0) into recid from v$log_history where first_change# <= lh_lowscn; end if; end if; deb('resync', 'Log History last recid '||recid|| '; high '||high_lh_recid, dbtype); if (high_lh_recid > recid) then select record_size into rec_size from v$controlfile_record_section where type='LOG HISTORY'; high := recid; low := recid + 1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := high_lh_recid - low + 1; deb_sort_area(high_lh_recid); while (high < high_lh_recid) loop high := least(low + rec_per_chunk -1, high_lh_recid); for rlhrec in rlh(low, high) loop deb('resync', 'Calling checkLogHistory with recid '||rlhrec.recid || ' thread '|| rlhrec.thread#||' sequence '||rlhrec.sequence# || ' reset_scn '|| rlhrec.resetlogs_change#, dbtype); dbms_rcvcat.checkLogHistory( rlhrec.recid, rlhrec.stamp, rlhrec.thread#, rlhrec.sequence#, rlhrec.low_scn, rlhrec.low_time, rlhrec.next_scn, rlhrec.resetlogs_change#, rlhrec.resetlogs_time); end loop; low := high + 1; end loop; end if; dbms_rcvcat.endLogHistoryResync; recid := dbms_rcvcat.beginArchivedLogResync; deb('resync', 'Archive log last recid '||recid|| '; high '||high_al_recid, dbtype); if (high_al_recid > recid) then select record_size into rec_size from v$controlfile_record_section where type='ARCHIVED LOG'; high := recid; low := recid + 1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := high_al_recid - low + 1; deb_sort_area(high_al_recid); while (high < high_al_recid) loop high := least(low + rec_per_chunk -1, high_al_recid); for alrec in al(low, high, cf_type) loop <> begin deb('resync', 'Calling checkArchivedLog for '|| alrec.name, dbtype); deb('resync', ' with sequence '||alrec.sequence#|| ' archived '||alrec.archived|| ' status '||alrec.status|| ' recid '||alrec.recid|| ' is_standby '||alrec.is_standby, dbtype); dbms_rcvcat.checkArchivedLog( alrec.recid, alrec.stamp, alrec.thread#, alrec.sequence#, alrec.resetlogs_change#, alrec.resetlogs_time, alrec.first_change#, alrec.first_time, alrec.next_change#, alrec.next_time, alrec.blocks, alrec.block_size, alrec.name, alrec.archived, alrec.completion_time, alrec.status, alrec.is_standby, alrec.dictionary_begin, alrec.dictionary_end, alrec.is_recovery_dest_file, alrec.compressed, alrec.creator, alrec.terminal); exception when change_record_stamp then deb('resync', 'got exception: Changing stamp for this record'); if for_dbuname is not null then null_retVal := sys.dbms_backup_restore.remoteSQLExecute( source_dbuname => for_dbuname, source_cs => source_cs, stmt => 'begin ' || ' sys.dbms_backup_restore.IncrementRecordStamp(' || ' rectype => ' || ' sys.dbms_backup_restore.RTYP_ARCHIVED_LOG ' || ' , recid => ' || alrec.recid || ' , stamp => ' || alrec.stamp || ' ); ' || 'end;'); else sys.dbms_backup_restore.IncrementRecordStamp( rectype => sys.dbms_backup_restore.RTYP_ARCHIVED_LOG, recid => alrec.recid, stamp => alrec.stamp); end if; alrec.stamp := alrec.stamp + 1; krmicd.clearErrors; goto al_resync_again; end; end loop; low := high + 1; end loop; end if; dbms_rcvcat.endArchivedLogResync; recid := dbms_rcvcat.beginOfflineRangeResync; deb('resync', 'Offline range last recid '||recid|| '; high '||high_or_recid, dbtype); if (high_or_recid > recid) then select record_size into rec_size from v$controlfile_record_section where type='OFFLINE RANGE'; high := recid; low := recid + 1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := high_or_recid - low + 1; deb_sort_area(high_or_recid); while (high < high_or_recid) loop high := least(low + rec_per_chunk -1, high_or_recid); for offrrec in offr(low, high) LOOP deb('resync', 'Calling checkOfflineRange'|| ' recid: '||nvl(offrrec.recid,-1)|| ' file#: '||offrrec.file#|| ' creation_scn: '||nvl(offrrec.creation_change#, -1)|| ' offline_scn: '||offrrec.offline_change#|| ' online_scn: '||offrrec.online_change#, dbtype); dbms_rcvcat.checkOfflineRange( offrrec.recid, offrrec.stamp, offrrec.file#, offrrec.creation_change#, offrrec.offline_change#, offrrec.online_change#, offrrec.online_time, cf_create_time, offrrec.resetlogs_change#, offrrec.resetlogs_time); end loop; low := high + 1; end loop; end if; dbms_rcvcat.endOfflineRangeResync; -- -- -- -- select last_recid, record_size into high_nrsp_recid, rec_size from v$controlfile_record_section where type = 'RESTORE POINT'; deb('resync', 'high_nrsp_recid= '||high_nrsp_recid, dbtype); -- -- recid := dbms_rcvcat.beginRestorePointResync; deb('resync', 'Restore Point last recid '||recid|| '; high '|| high_nrsp_recid,dbtype); if (high_nrsp_recid > recid) then high := recid; low := recid + 1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := high_nrsp_recid - low + 1; deb_sort_area(high_nrsp_recid); while (high < high_nrsp_recid) loop high := least(low + rec_per_chunk -1, high_nrsp_recid); for nrsprec in nrsp(low, high) loop deb('resync', 'Calling checkRestorePoint for recid '|| nrsprec.recid||' name '||nrsprec.nrsname || ' con_id ' || nrsprec.con_id, dbtype); dbms_rcvcat.checkRestorePoint( nrsprec.recid, nrsprec.stamp, nrsprec.nrsname, nrsprec.reset_scn, nrsprec.reset_time, nrsprec.nrsscn, nrsprec.nrsrsptime, nrsprec.nrstime, nrsprec.deleted, nrsprec.con_id, nrsprec.clean); end loop; low := high + 1; end loop; end if; select min(nrsrid) into low from x$kccnrs; -- Purge catalog below cf recid dbms_rcvcat.endRestorePointResync(low); deb('resync', 'oam_tst_level = ' || oam_tst_level, dbtype); deb('resync', 'resync_2_AMSchema = ' || resync_2_AMSchema, dbtype); if resync_2_AMSchema = 1 and oam_tst_level >= 2 then deb('resync', 'oam_tst_level:Skipping resync of all backup set records', dbtype); goto skip_all_backupset_resync; end if; recid := dbms_rcvcat.beginBackupSetResync; low_bs_recid := recid; -- store this recid for bdf, brl resync deb('resync', 'Backup set last recid '||recid|| '; high '||high_bs_recid, dbtype); if (high_bs_recid > recid) then select record_size into rec_size from v$controlfile_record_section where type='BACKUP SET'; high := recid; low := recid + 1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := high_bs_recid - low + 1; deb_sort_area(high_bs_recid); while (high < high_bs_recid) loop high := least(low + rec_per_chunk -1, high_bs_recid); for bsrec in bs(low, high) loop deb('resync', 'Calling checkBackupSet for set_stamp '|| bsrec.set_stamp||' set_count '||bsrec.set_count|| ' pieces: '||bsrec.pieces||' recid: '||bsrec.recid, dbtype); dbms_rcvcat.checkBackupSet( bsrec.recid, bsrec.stamp, bsrec.set_stamp, bsrec.set_count, bsrec.backup_type, bsrec.incremental_level, bsrec.pieces, bsrec.start_time, bsrec.completion_time, bsrec.controlfile_included, bsrec.input_file_scan_only, bsrec.keep_options, bsrec.keep_until, bsrec.block_size, bsrec.multi_section, TRUE, bsrec.guid, bsrec.dropped_pdb); end loop; low := high + 1; end loop; deb('resync', 'Backupset -> Backup DataFile', dbtype); low_bdf_recid := dbms_rcvcat.beginBackupDataFileResync; select nvl(min(bdf.recid) - 1, 0), nvl(max(bdf.recid), 0) into local_low, local_high from v$backup_set bs, v$backup_datafile bdf where ((bdf.recid <= low_bdf_recid and low_bdf_recid != 0) OR (bdf.stamp <= kccdivts and low_bdf_recid = 0)) and bs.recid between low_bs_recid and high_bs_recid and (bs.stamp >= kccdivts OR bs.recid = high_bs_recid) and bs.stamp >= resyncstamp and bs.set_stamp = bdf.set_stamp and bs.set_count = bdf.set_count and bs.backup_type != 'L'; -- ignore archivelog backups select record_size into rec_size from v$controlfile_record_section where type='BACKUP DATAFILE'; high := local_low; low := local_low + 1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := local_high - low + 1; deb_sort_area(local_high); while (high < local_high) loop high := least(low + rec_per_chunk -1, local_high); for bdfbsrec in bdfbs(low, high, low_bs_recid, high_bs_recid) loop curr_set_stamp := bdfbsrec.set_stamp; curr_set_count := bdfbsrec.set_count; deb('resync', 'Calling checkBackupDataFile for set_stamp '|| bdfbsrec.set_stamp||' set_count '||bdfbsrec.set_count, dbtype); deb('resync', ' file# '||bdfbsrec.file#||' recid '||bdfbsrec.recid, dbtype); dbms_rcvcat.checkBackupDataFile( bdfbsrec.recid, bdfbsrec.stamp, bdfbsrec.set_stamp, bdfbsrec.set_count, bdfbsrec.file#, bdfbsrec.creation_change#, bdfbsrec.creation_time, bdfbsrec.resetlogs_change#, bdfbsrec.resetlogs_time, bdfbsrec.incremental_level, bdfbsrec.incremental_change#, bdfbsrec.checkpoint_change#, bdfbsrec.checkpoint_time, bdfbsrec.absolute_fuzzy_change#, bdfbsrec.datafile_blocks, bdfbsrec.blocks, bdfbsrec.block_size, bdfbsrec.oldest_offline_range, bdfbsrec.completion_time, bdfbsrec.controlfile_type, bdfbsrec.marked_corrupt, bdfbsrec.media_corrupt, bdfbsrec.logically_corrupt, FALSE, bdfbsrec.blocks_read, bdfbsrec.used_change_tracking, bdfbsrec.used_optimization, bdfbsrec.foreign_dbid, bdfbsrec.plugged_readonly, bdfbsrec.plugin_change#, bdfbsrec.plugin_resetlogs_change#, bdfbsrec.plugin_resetlogs_time, bdfbsrec.section_size, bdfbsrec.guid, bdfbsrec.sparse_backup, TRUE, FALSE, bdfbsrec.dropped_pdb); curr_set_stamp := 0; curr_set_count := 0; end loop; low := high + 1; end loop; dbms_rcvcat.endBackupDataFileResync; deb('resync', 'Backupset -> Backup Spfile', dbtype); low_bsf_recid := dbms_rcvcat.beginBackupSpFileResync; select nvl(min(bsf.recid) - 1, 0), nvl(max(bsf.recid), 0) into local_low, local_high from v$backup_set bs, v$backup_spfile bsf where ((bsf.recid <= low_bsf_recid and low_bsf_recid != 0) OR (bsf.stamp <= kccdivts and low_bsf_recid = 0)) and bs.recid between low_bs_recid and high_bs_recid and (bs.stamp >= kccdivts OR bs.recid = high_bs_recid) and bs.stamp >= resyncstamp and bs.set_stamp = bsf.set_stamp and bs.set_count = bsf.set_count and bs.backup_type != 'L'; -- ignore archivelog backups select record_size into rec_size from v$controlfile_record_section where type='BACKUP SPFILE'; high := local_low; low := local_low + 1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := local_high - low + 1; deb_sort_area(local_high); while (high < local_high) loop high := least(low + rec_per_chunk -1, local_high); for bsfbsrec in bsfbs(low, high, low_bs_recid, high_bs_recid) loop curr_set_stamp := bsfbsrec.set_stamp; curr_set_count := bsfbsrec.set_count; deb('resync', 'Calling checkBackupSpFile for set_stamp '|| bsfbsrec.set_stamp||' set_count '||bsfbsrec.set_count ||' recid '||bsfbsrec.recid, dbtype); dbms_rcvcat.checkBackupSpFile( bsfbsrec.recid, bsfbsrec.stamp, bsfbsrec.set_stamp, bsfbsrec.set_count, bsfbsrec.modification_time, bsfbsrec.bytes, FALSE, bsfbsrec.db_unique_name, bsfbsrec.guid, bsfbsrec.dropped_pdb); curr_set_stamp := 0; curr_set_count := 0; end loop; low := high + 1; end loop; dbms_rcvcat.endBackupSpFileResync; deb('resync', 'Backupset -> Backup RedoLog', dbtype); low_brl_recid := dbms_rcvcat.beginBackupRedoLogResync; select nvl(min(brl.recid) - 1, 0), nvl(max(brl.recid), 0) into local_low, local_high from v$backup_set bs, v$backup_redolog brl where ((brl.recid <= low_brl_recid and low_brl_recid != 0) OR (brl.stamp <= kccdivts and low_brl_recid = 0)) and bs.recid between low_bs_recid and high_bs_recid and (bs.stamp >= kccdivts OR bs.recid = high_bs_recid) and bs.stamp >= resyncstamp and bs.set_stamp = brl.set_stamp and bs.set_count = brl.set_count and bs.backup_type = 'L'; -- only archivelog backups select record_size into rec_size from v$controlfile_record_section where type='BACKUP REDOLOG'; high := local_low; low := local_low + 1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := local_high - low + 1; deb_sort_area(local_high); while (high < local_high) loop high := least(low + rec_per_chunk -1, local_high); for brlbsrec in brlbs(low, high, low_bs_recid, high_bs_recid) loop curr_set_stamp := brlbsrec.set_stamp; curr_set_count := brlbsrec.set_count; deb('resync', 'Calling checkBackupRedoLog for set_stamp '|| brlbsrec.set_stamp||' set_count '||brlbsrec.set_count|| ' recid '||brlbsrec.recid, dbtype); deb('resync', ' sequence '||brlbsrec.sequence#|| ' first change '||brlbsrec.first_change#|| ' next change '||brlbsrec.next_change#, dbtype); dbms_rcvcat.checkBackupRedoLog( brlbsrec.recid, brlbsrec.stamp, brlbsrec.set_stamp, brlbsrec.set_count, brlbsrec.thread#, brlbsrec.sequence#, brlbsrec.resetlogs_change#, brlbsrec.resetlogs_time, brlbsrec.first_change#, brlbsrec.first_time, brlbsrec.next_change#, brlbsrec.next_time, brlbsrec.blocks, brlbsrec.block_size, FALSE, brlbsrec.terminal); curr_set_stamp := 0; curr_set_count := 0; end loop; low := high + 1; end loop; dbms_rcvcat.endBackupRedoLogResync; end if; dbms_rcvcat.endBackupSetResync; recid := dbms_rcvcat.beginBackupPieceResync; deb('resync', 'Backup piece last recid '||recid|| '; high '||high_bp_recid, dbtype); if (high_bp_recid > recid) then select record_size into rec_size from v$controlfile_record_section where type='BACKUP PIECE'; high := recid; low := recid + 1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := high_bp_recid - low + 1; deb_sort_area(high_bp_recid); while (high < high_bp_recid) loop high := least(low + rec_per_chunk -1, high_bp_recid); for bprec in bp(low, high) loop << bp_resync_again>> begin deb('resync', 'Calling checkBackupPiece for stamp '|| bprec.stamp||' recid '||bprec.recid, dbtype); deb('resync', ' Handle '||bprec.handle||' status '|| bprec.status||' piece# '||bprec.piece#, dbtype); deb('resync', 'set_stamp '||bprec.set_stamp|| ' set_count '||bprec.set_count, dbtype); if resync_2_AMSchema = 1 and (oam_tst_level >= 1 and bprec.device_type = 'SBT_TAPE') then deb('resync', 'oam_tst_level:' || 'Skipping resync of all tape backup piece recs', dbtype); continue; end if; dbms_rcvcat.checkBackupPiece( bprec.recid, bprec.stamp, bprec.set_stamp, bprec.set_count, bprec.piece#, bprec.tag, bprec.device_type, bprec.handle, bprec.comments, bprec.media, bprec.concur, bprec.start_time, bprec.completion_time, bprec.status, bprec.copy#, bprec.media_pool, bprec.bytes, bprec.is_recovery_dest_file, bprec.rman_status_recid, bprec.rman_status_stamp, bprec.compressed, bprec.encrypted, bprec.backed_by_osb, 'U', NULL, TRUE, NULL, bprec.guid, NULL, bprec.dropped_pdb); exception when change_record_stamp then deb('resync', 'got exception: Changing stamp for this record'); if for_dbuname is not null then null_retVal := sys.dbms_backup_restore.remoteSQLExecute( source_dbuname => for_dbuname, source_cs => source_cs, stmt => 'begin ' || ' sys.dbms_backup_restore.IncrementRecordStamp(' || ' rectype => ' || ' sys.dbms_backup_restore.RTYP_BACKUP_PIECE ' || ' , recid => ' || bprec.recid || ' , stamp => ' || bprec.stamp || ' ); ' || 'end;'); else sys.dbms_backup_restore.IncrementRecordStamp( rectype => sys.dbms_backup_restore.RTYP_BACKUP_PIECE, recid => bprec.recid, stamp => bprec.stamp); end if; bprec.stamp := bprec.stamp + 1; krmicd.clearErrors; goto bp_resync_again; end; end loop; low := high + 1; end loop; end if; dbms_rcvcat.endBackupPieceResync; recid := dbms_rcvcat.beginBackupDataFileResync; deb('resync', 'Backup DataFile last recid '||recid|| '; high '||high_bf_recid, dbtype); if (high_bf_recid > recid) then select record_size into rec_size from v$controlfile_record_section where type='BACKUP DATAFILE'; high := recid; low := recid + 1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := high_bf_recid - low + 1; deb_sort_area(high_bf_recid); while (high < high_bf_recid) loop high := least(low + rec_per_chunk -1, high_bf_recid); for bdfrec in bdf(low, high) loop curr_set_stamp := bdfrec.set_stamp; curr_set_count := bdfrec.set_count; deb('resync', 'Calling checkBackupDataFile for set_stamp '|| bdfrec.set_stamp||' set_count '||bdfrec.set_count || ' recid '||bdfrec.recid, dbtype); deb('resync', ' file# '||bdfrec.file#, dbtype); dbms_rcvcat.checkBackupDataFile( bdfrec.recid, bdfrec.stamp, bdfrec.set_stamp, bdfrec.set_count, bdfrec.file#, bdfrec.creation_change#, bdfrec.creation_time, bdfrec.resetlogs_change#, bdfrec.resetlogs_time, bdfrec.incremental_level, bdfrec.incremental_change#, bdfrec.checkpoint_change#, bdfrec.checkpoint_time, bdfrec.absolute_fuzzy_change#, bdfrec.datafile_blocks, bdfrec.blocks, bdfrec.block_size, bdfrec.oldest_offline_range, bdfrec.completion_time, bdfrec.controlfile_type, bdfrec.marked_corrupt, bdfrec.media_corrupt, bdfrec.logically_corrupt, TRUE, bdfrec.blocks_read, bdfrec.used_change_tracking, bdfrec.used_optimization, bdfrec.foreign_dbid, bdfrec.plugged_readonly, bdfrec.plugin_change#, bdfrec.plugin_resetlogs_change#, bdfrec.plugin_resetlogs_time, bdfrec.section_size, bdfrec.guid, bdfrec.sparse_backup, TRUE, FALSE, bdfrec.dropped_pdb); curr_set_stamp := 0; curr_set_count := 0; end loop; low := high + 1; end loop; end if; dbms_rcvcat.endBackupDataFileResync; recid := dbms_rcvcat.beginBackupSpFileResync; deb('resync', 'Backup SPFILE last recid '||recid|| '; high '||high_bi_recid, dbtype); if (high_bi_recid > recid) then select record_size into rec_size from v$controlfile_record_section where type='BACKUP SPFILE'; high := recid; low := recid + 1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := high_bi_recid - low + 1; deb_sort_area(high_bi_recid); while (high < high_bi_recid) loop high := least(low + rec_per_chunk - 1, high_bi_recid); for bsfrec in bsf(low, high) loop curr_set_stamp := bsfrec.set_stamp; curr_set_count := bsfrec.set_count; deb('resync', 'Calling checkBackupSpFile for set_stamp '|| bsfrec.set_stamp||' set_count '||bsfrec.set_count || ' recid '||bsfrec.recid, dbtype); dbms_rcvcat.checkBackupSpFile( bsfrec.recid, bsfrec.stamp, bsfrec.set_stamp, bsfrec.set_count, bsfrec.modification_time, bsfrec.bytes, TRUE, bsfrec.db_unique_name, bsfrec.guid, bsfrec.dropped_pdb); curr_set_stamp := 0; curr_set_count := 0; end loop; low := high + 1; end loop; end if; dbms_rcvcat.endBackupSpFileResync; recid := dbms_rcvcat.beginBackupCorruptionResync; deb('resync', 'Backup Corruption last recid '||recid|| '; high '||high_fc_recid, dbtype); if (high_fc_recid > recid) then select record_size into rec_size from v$controlfile_record_section where type='BACKUP CORRUPTION'; high := recid; low := recid + 1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := high_fc_recid - low + 1; deb_sort_area(high_fc_recid); while (high < high_fc_recid) loop high := least(low + rec_per_chunk -1, high_fc_recid); for bcbrec in bcb(low, high) loop deb('resync', 'Calling checkBackupCorruption for set_stamp '|| bcbrec.set_stamp||' set_count '||bcbrec.set_count, dbtype); deb('resync', ' file# '||bcbrec.file# ||' recid '||bcbrec.recid, dbtype); dbms_rcvcat.checkBackupCorruption( bcbrec.recid, bcbrec.stamp, bcbrec.set_stamp, bcbrec.set_count, bcbrec.piece#, bcbrec.file#, bcbrec.block#, bcbrec.blocks, bcbrec.corruption_change#, bcbrec.marked_corrupt, bcbrec.corruption_type); end loop; low := high + 1; end loop; end if; dbms_rcvcat.endBackupCorruptionResync; recid := dbms_rcvcat.beginBackupRedoLogResync; deb('resync', 'Backup RedoLog last recid '||recid|| '; high '||high_bl_recid, dbtype); if (high_bl_recid > recid) then select record_size into rec_size from v$controlfile_record_section where type='BACKUP REDOLOG'; high := recid; low := recid + 1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := high_bl_recid - low + 1; deb_sort_area(high_bl_recid); while (high < high_bl_recid) loop high := least(low + rec_per_chunk -1, high_bl_recid); for brlrec in brl(low, high) loop curr_set_stamp := brlrec.set_stamp; curr_set_count := brlrec.set_count; deb('resync', 'Calling checkBackupRedoLog for set_stamp '|| brlrec.set_stamp||' set_count '||brlrec.set_count|| ' recid '||brlrec.recid, dbtype); deb('resync', ' sequence '||brlrec.sequence#|| ' first change '||brlrec.first_change#|| ' next change '||brlrec.next_change#, dbtype); dbms_rcvcat.checkBackupRedoLog( brlrec.recid, brlrec.stamp, brlrec.set_stamp, brlrec.set_count, brlrec.thread#, brlrec.sequence#, brlrec.resetlogs_change#, brlrec.resetlogs_time, brlrec.first_change#, brlrec.first_time, brlrec.next_change#, brlrec.next_time, brlrec.blocks, brlrec.block_size, TRUE, brlrec.terminal); curr_set_stamp := 0; curr_set_count := 0; end loop; low := high + 1; end loop; end if; dbms_rcvcat.endBackupRedoLogResync; << skip_all_backupset_resync >> if resync_2_AMSchema = 1 and oam_tst_level >= 2 then deb('resync', 'oam_tst_level:Skipping resync of datafile image copy recs', dbtype); goto skip_all_dfcopy_resync; end if; recid := dbms_rcvcat.beginDataFileCopyResync; deb('resync', 'DataFIleCopy last recid '||recid|| '; high '||high_dc_recid, dbtype); if (high_dc_recid > recid) then select record_size into rec_size from v$controlfile_record_section where type='DATAFILE COPY'; high := recid; low := recid + 1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := high_dc_recid - low + 1; deb_sort_area(high_dc_recid); while (high < high_dc_recid) loop high := least(low + rec_per_chunk -1, high_dc_recid); for cdfrec in cdf(low, high) loop << cdf_resync_again >> begin deb('resync', 'Calling checkDataFileCopy for '|| cdfrec.fname, dbtype); deb('resync', ' file# '||cdfrec.file#|| ' status '||cdfrec.status|| ' recid '||cdfrec.recid, dbtype); dbms_rcvcat.checkDataFileCopy( cdfrec.recid, cdfrec.stamp, cdfrec.fname, cdfrec.tag, cdfrec.file#, cdfrec.create_scn, cdfrec.create_time, cdfrec.reset_scn, cdfrec.reset_time, cdfrec.incr_level, cdfrec.ckp_scn, cdfrec.ckp_time, cdfrec.online_fuzzy, cdfrec.backup_fuzzy, cdfrec.abs_fuzzy_scn, cdfrec.rcv_fuzzy_scn, cdfrec.rcv_fuzzy_time, cdfrec.blocks, cdfrec.block_size, cdfrec.oldest_offline_range, cdfrec.completion_time, cdfrec.status, cdfrec.controlfile_type, cdfrec.keep_options, cdfrec.keep_until, cdfrec.scanned, cdfrec.is_recovery_dest_file, cdfrec.rman_status_recid, cdfrec.rman_status_stamp, cdfrec.marked_corrupt, cdfrec.foreign_dbid, cdfrec.plugged_readonly, cdfrec.plugin_change#, cdfrec.plugin_resetlogs_change#, cdfrec.plugin_resetlogs_time, cdfrec.guid, cdfrec.sparse_backup, cdfrec.dropped_pdb); exception when change_record_stamp then deb('resync', 'got exception: Changing stamp for this record'); if for_dbuname is not null then null_retVal := sys.dbms_backup_restore.remoteSQLExecute( source_dbuname => for_dbuname, source_cs => source_cs, stmt => 'begin ' || ' sys.dbms_backup_restore.IncrementRecordStamp(' || ' rectype => ' || ' sys.dbms_backup_restore.RTYP_DFILE_COPY ' || ' , recid => ' || cdfrec.recid || ' , stamp => ' || cdfrec.stamp || ' ); ' || 'end;'); else sys.dbms_backup_restore.IncrementRecordStamp( rectype => sys.dbms_backup_restore.RTYP_DFILE_COPY, recid => cdfrec.recid, stamp => cdfrec.stamp); end if; cdfrec.stamp := cdfrec.stamp + 1; krmicd.clearErrors; goto cdf_resync_again; end; end loop; low := high + 1; end loop; end if; dbms_rcvcat.endDataFileCopyResync; << skip_all_dfcopy_resync >> recid := dbms_rcvcat.beginCopyCorruptionResync; deb('resync', 'Copy Corruption last recid '||recid|| '; high '||high_cc_recid, dbtype); if (high_cc_recid > recid) then select record_size into rec_size from v$controlfile_record_section where type='COPY CORRUPTION'; high := recid; low := recid + 1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := high_cc_recid - low + 1; deb_sort_area(high_cc_recid); while (high < high_cc_recid) loop high := least(low + rec_per_chunk -1, high_cc_recid); for ccbrec in ccb(low, high) loop deb('resync', 'Calling checkCopyCorruption for file '||ccbrec.file# ||' recid '||ccbrec.copy_recid, dbtype); dbms_rcvcat.checkCopyCorruption(ccbrec.recid, ccbrec.stamp, ccbrec.copy_recid, ccbrec.copy_stamp, ccbrec.file#, ccbrec.block#, ccbrec.blocks, ccbrec.corruption_change#, ccbrec.marked_corrupt, ccbrec.corruption_type); end loop; low := high + 1; end loop; end if; dbms_rcvcat.endCopyCorruptionResync; select record_size, decode(records_used, 0, 0, last_recid + 1 - records_used) old_recid, last_recid into rec_size, low_bcr_recid, high_bcr_recid from v$controlfile_record_section where type='DATABASE BLOCK CORRUPTION'; recid := dbms_rcvcat.beginBlockCorruptionResync(low_bcr_recid); deb('resync', 'Block Corruption last recid '||recid|| '; low ' ||low_bcr_recid || ';high '||high_bcr_recid, dbtype); if (high_bcr_recid > recid) then high := recid; low := recid + 1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := high_bcr_recid - low + 1; deb_sort_area(high_bcr_recid); while (high < high_bcr_recid) loop high := least(low + rec_per_chunk -1, high_bcr_recid); for bcrrec in bcr(low, high) loop deb('resync', 'Calling checkBlockCorruption for' ||' recid ' || bcrrec.recid ||' stamp ' || bcrrec.stamp ||' file# ' || bcrrec.file# ||' block# ' || bcrrec.block# ||' blocks ' || bcrrec.blocks, dbtype); dbms_rcvcat.checkBlockCorruption(bcrrec.recid, bcrrec.stamp, bcrrec.file#, bcrrec.create_scn, bcrrec.create_time, bcrrec.block#, bcrrec.blocks, bcrrec.corrupt_scn, bcrrec.corruption_type); end loop; low := high + 1; end loop; end if; dbms_rcvcat.endBlockCorruptionResync; recid := dbms_rcvcat.beginDeletedObjectResync; deb('resync', 'DeletedObject last recid '||recid|| '; high '||high_dl_recid, dbtype); if (high_dl_recid > recid) then select record_size into rec_size from v$controlfile_record_section where type='DELETED OBJECT'; high := recid; low := recid + 1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := high_dl_recid - low + 1; deb_sort_area(high_dl_recid); while (high < high_dl_recid) loop high := least(low + rec_per_chunk -1, high_dl_recid); for dlrec in dl(low, high) loop if (dlrec.object_type = 'INSTANT RESTORE') then dlrec.object_fname := sys.dbms_backup_restore.getParm( sys.dbms_backup_restore.BACKING_FILENAME, dlrec.object_data); end if; deb('resync', 'Calling checkDeletedObject for recid '|| dlrec.recid ||' object type ' || dlrec.object_type ||' with count ' || dlrec.object_recid ||' and stamp ' || dlrec.object_stamp ||' and data ' || dlrec.object_data ||' and set_stamp ' || nvl(to_char(dlrec.set_stamp), 'NULL') ||' and set_count ' || nvl(to_char(dlrec.set_count), 'NULL') ||' and create_scn ' || nvl(to_char(dlrec.object_create_scn), 'NULL'), dbtype); dbms_rcvcat.checkDeletedObject( dlrec.recid, dlrec.stamp, dlrec.object_type, dlrec.object_recid, dlrec.object_stamp, dlrec.object_data, dlrec.object_fname, dlrec.object_create_scn, dlrec.set_stamp, dlrec.set_count); end loop; low := high + 1; end loop; end if; dbms_rcvcat.endDeletedObjectResync; if resync_2_AMSchema = 1 and oam_tst_level >= 1 then deb('resync', 'oam_tst_level:Skipping resync of all proxy backup records', dbtype); goto skip_all_proxy_resync; end if; recid := dbms_rcvcat.beginProxyResync; deb('resync', 'ProxyResync last recid '||recid|| '; high '||high_pc_recid, dbtype); if (high_pc_recid > recid) then select record_size into rec_size from v$controlfile_record_section where type='PROXY COPY'; high := recid; low := recid + 1; rec_per_chunk := floor(sort_area_size / rec_size); total_recs := high_pc_recid - low + 1; deb_sort_area(high_pc_recid); while (high < high_pc_recid) loop high := least(low + rec_per_chunk - 1, high_pc_recid); for xdfrec in xdf(low, high) loop << xdf_resync_again >> begin deb('resync', 'Calling checkProxyDataFile for '|| xdfrec.handle || ' recid ' || xdfrec.recid, dbtype); deb('resync', ' file# '||xdfrec.file#|| ' status '||xdfrec.status, dbtype); dbms_rcvcat.checkProxyDataFile(xdfrec.recid, xdfrec.stamp, xdfrec.tag, xdfrec.file#, xdfrec.create_scn, xdfrec.create_time, xdfrec.reset_scn, xdfrec.reset_time, xdfrec.incr_level, xdfrec.ckp_scn, xdfrec.ckp_time, xdfrec.online_fuzzy, xdfrec.backup_fuzzy, xdfrec.abs_fuzzy_scn, xdfrec.rcv_fuzzy_scn, xdfrec.rcv_fuzzy_time, xdfrec.blocks, xdfrec.block_size, xdfrec.oldest_offline_range, xdfrec.device_type, xdfrec.handle, xdfrec.comments, xdfrec.media, xdfrec.media_pool, xdfrec.start_time, xdfrec.completion_time, xdfrec.status, xdfrec.controlfile_type, xdfrec.keep_options, xdfrec.keep_until, xdfrec.rman_status_recid, xdfrec.rman_status_stamp, xdfrec.foreign_dbid, xdfrec.plugged_readonly, xdfrec.plugin_change#, xdfrec.plugin_resetlogs_change#, xdfrec.plugin_resetlogs_time, xdfrec.guid, xdfrec.dropped_pdb); exception when change_record_stamp then deb('resync', 'got exception: Changing stamp for this record'); if for_dbuname is not null then null_retVal := sys.dbms_backup_restore.remoteSQLExecute( source_dbuname => for_dbuname, source_cs => source_cs, stmt => 'begin ' || ' sys.dbms_backup_restore.IncrementRecordStamp(' || ' rectype => ' || ' sys.dbms_backup_restore.RTYP_PROXY ' || ' , recid => ' || xdfrec.recid || ' , stamp => ' || xdfrec.stamp || ' ); ' || 'end;'); else sys.dbms_backup_restore.IncrementRecordStamp( rectype => sys.dbms_backup_restore.RTYP_PROXY, recid => xdfrec.recid, stamp => xdfrec.stamp); end if; xdfrec.stamp := xdfrec.stamp + 1; krmicd.clearErrors; goto xdf_resync_again; end; end loop; for xalrec in xal(low, high) loop << xal_resync_again >> begin deb('resync', 'Calling checkProxyArchivedLog for '|| xalrec.handle, dbtype); deb('resync', ' thread# ' || xalrec.thread# || ' sequence# ' || xalrec.sequence# || ' status ' || xalrec.status || ' recid ' || xalrec.recid, dbtype); dbms_rcvcat.checkProxyArchivedLog(xalrec.recid, xalrec.stamp, xalrec.tag, xalrec.thread#, xalrec.sequence#, xalrec.resetlogs_change#, xalrec.resetlogs_time, xalrec.first_change#, xalrec.first_time, xalrec.next_change#, xalrec.next_time, xalrec.blocks, xalrec.block_size, xalrec.device_type, xalrec.handle, xalrec.comments, xalrec.media, xalrec.media_pool, xalrec.start_time, xalrec.completion_time, xalrec.status, xalrec.rman_status_recid, xalrec.rman_status_stamp, xalrec.terminal, xalrec.keep_until, xalrec.keep_options); exception when change_record_stamp then deb('resync', 'got exception: Changing stamp for this record'); if for_dbuname is not null then null_retVal := sys.dbms_backup_restore.remoteSQLExecute( source_dbuname => for_dbuname, source_cs => source_cs, stmt => 'begin ' || ' sys.dbms_backup_restore.IncrementRecordStamp(' || ' rectype => ' || ' sys.dbms_backup_restore.RTYP_PROXY ' || ' , recid => ' || xalrec.recid || ' , stamp => ' || xalrec.stamp || ' ); ' || 'end;'); else sys.dbms_backup_restore.IncrementRecordStamp( rectype => sys.dbms_backup_restore.RTYP_PROXY, recid => xalrec.recid, stamp => xalrec.stamp); end if; xalrec.stamp := xalrec.stamp + 1; krmicd.clearErrors; goto xal_resync_again; end; end loop; low := high + 1; end loop; end if; dbms_rcvcat.endProxyResync; << skip_all_proxy_resync >> << skip_circular_section_resync >> -- -- if (releasecf) then sys.dbms_backup_restore.cfileUseCurrent; releasecf := FALSE; end if; -- if (ret = CONFIGRESYNC_TOCF OR ret = CONFIGRESYNC_TORC_TOCF) then resyncConf2ControlFile(for_dbuname, source_cs); end if; -- -- -- -- -- -- -- if for_dbuname is null and (ret = CONFIGRESYNC_TOCF OR ret = CONFIGRESYNC_TORC_TOCF) then resyncConf2Catalog(cf_type, TRUE); end if; dbms_rcvcat.endConfigResync2; deb('resync', 'Calling getPolledRec', dbtype); while (dbms_rcvcat.getPolledRec(lrec_type, lrecid, lstamp, lfname)) loop deb('resync', 'BA Polled ' || lfname, dbtype); sys.dbms_backup_restore.OAMPolledRecord( rectype => lrec_type, recid => lrecid, stamp => lstamp); end loop; deb('resync', 'Calling sanityCheck', dbtype); dbms_rcvcat.sanityCheck; deb('resync', 'Calling endCkpt', dbtype); dbms_rcvcat.endCkpt; if (auto_prim_resync) then krmicd.writeMsg(8244); auto_prim_resync := FALSE; for_dbuname := null; cf_type := null; -- read_retries := 0; busy_retries := 0; sort_retries := 0; callSetDatabase := TRUE; if (sync_retries < 2 and is_19871_L0_set) then null_retVal := sys.dbms_backup_restore.remoteSQLExecute( source_dbuname => for_dbuname, source_cs => source_cs, stmt => 'alter system archive log current'); sys.dbms_backup_restore.sleep(10); end if; goto restart_resync; elsif (full_resync) then krmicd.writeMsg(8004); else if not implicit then krmicd.writeMsg(8245); end if; end if; exited('resync', 'OK'); exception when need_primary_resync then if sync_retries < 5 then krmicd.writeErrMsg(1005, sqlerrm); krmicd.writeMsg(8246); sync_retries := sync_retries + 1; dbms_rcvcat.cancelCkpt; auto_prim_resync := TRUE; cf_type := null; -- read_retries := 0; busy_retries := 0; sort_retries := 0; krmicd.clearErrors; goto restart_resync; else dbms_rcvcat.cancelCkpt; raise; end if; when sort_area_too_small then if (sort_retries < 5) then sort_retries := sort_retries + 1; krmicd.writeMsg(1005, 'resync got ORA'||to_char(sqlcode)|| ', retrying with sort_area_size = '|| to_char((sort_area_size + sort_area_size_incr) / 1048576)|| 'MB'); sort_area_size := set_sort_area_size(sort_area_size + sort_area_size_incr); goto retry; else dbms_rcvcat.cancelCkpt; krmicd.writeMsg(1005, 'resync got ORA-'||to_char(sqlcode)|| ', giving up'); exited('resync', 'sort_area_too_small'); raise; end if; -- -- -- when sys.dbms_backup_restore.inconsistant_read then -- if (read_retries < 5) then read_retries := read_retries + 1; krmicd.writeMsg(1005, 'resync got ORA-235, retry '||to_char(read_retries)); krmicd.clearErrors; krmicd.sleep(10*read_retries); goto retry; else dbms_rcvcat.cancelCkpt; krmicd.writeMsg(1005, 'resync got ORA-235, giving up'); exited('resync', 'inconsistant_read'); raise; end if; when resync_not_needed then dbms_rcvcat.cancelCkpt; if (releasecf) then sys.dbms_backup_restore.cfileUseCurrent; releasecf := FALSE; end if; if ignore_resync_err then deb('resync', 'Ignoring resync error RMAN-20034'); krmicd.clearErrors; else raise; end if; when setstamp_setcount_conflict then dbms_rcvcat.cancelCkpt; if (releasecf) then sys.dbms_backup_restore.cfileUseCurrent; releasecf := FALSE; end if; if (curr_set_stamp = 0 AND curr_set_count = 0) then exited('resync', 'invalid_set_stamp set_count conflict'); krmicd.SignalErrMsg(20111); else display_uncatalog_bp(curr_set_stamp, curr_set_count); exited('resync', 'set_stamp set_count conflict'); raise; end if; when others then dbms_rcvcat.cancelCkpt; if (releasecf) then sys.dbms_backup_restore.cfileUseCurrent; releasecf := FALSE; end if; exited('resync', 'ORA-'||to_char(sqlcode)); raise; end; end; >>> define devalloc <<< -- declare devtype varchar2(255); chid varchar2(255); debug varchar2(10) := null; options number := null; node varchar2(255); maxsize number; kbytes number := null; parallel binary_integer := null; readrate number := null; rate number := null; sendcmd varchar2(256); vendor varchar2(256); israc boolean; instname varchar2(17); isfirst boolean; wait boolean; wait_msg_dis boolean := false; num_sbt_chns number; error_str varchar2(256); oam_job_id varchar2(256); request_time date; oam_tst_level number; vendortype number := 0; begin &object& if debug is not null then krmicd.execSql( 'alter session set events ''trace[krb.*] disk=' ||debug|| ', memory=' ||debug||''''); end if; if options is not null then krmicd.execSql( 'alter session set events ''immediate trace name krb_options level ' ||options||''''); end if; devtype := sys.dbms_backup_restore.deviceAllocate( ident => chid, node => node, &args& ); if kbytes is null then maxsize := sys.dbms_backup_restore.deviceQuery (sys.dbms_backup_restore.DEVICEQUERY_MAXSIZE); else maxsize := kbytes; end if; if maxsize > 0 then sys.dbms_backup_restore.setlimit (sys.dbms_backup_restore.kbytes, maxsize); end if; if devtype = 'SBT_TAPE' then vendortype := to_number(sys.dbms_backup_restore.deviceQuery (sys.dbms_backup_restore.DEVICEQUERY_VENDORTYPE)); end if; krmicd.setChannelInfo (devtype, node, maxsize, sys.dbms_backup_restore.deviceQuery (sys.dbms_backup_restore.DEVICEQUERY_PROXY), sys.dbms_backup_restore.deviceQuery (sys.dbms_backup_restore.DEVICEQUERY_MAXPROXY), vendortype); if parallel is not null then sys.dbms_backup_restore.setlimit (sys.dbms_backup_restore.parallel, parallel); end if; if readrate is not null then sys.dbms_backup_restore.setlimit (sys.dbms_backup_restore.readrate, readrate); end if; if rate is not null then sys.dbms_backup_restore.setlimit (sys.dbms_backup_restore.max_read_kbytes, rate); end if; if sendcmd is not null then sys.dbms_backup_restore.devicecommand(sendcmd, NULL); end if; krmicd.writeMsg(8030, chid); krmicd.getInstance(instname, israc); if (israc) then krmicd.writeMsg(8605, chid, to_char(krmicd.getSid), to_char(instname), devtype); else krmicd.writeMsg(8500, chid, to_char(krmicd.getSid), devtype); end if; vendor := sys.dbms_backup_restore.deviceQuery (sys.dbms_backup_restore.DEVICEQUERY_VENDOR); if vendor is not null then krmicd.writemsg(8526, chid, vendor); end if; if (oam_tst_level > 0 and (vendortype = sys.dbms_backup_restore.DEVICEQUERY_BA) ) then -- sys.dbms_backup_restore.setParms(p0 => 14, p1 => 1); end if; %IF% catalog if (vendortype = sys.dbms_backup_restore.DEVICEQUERY_BA) then krmicd.getChannelInfo(chid, isfirst); if isfirst then request_time := sysdate; oam_job_id := to_char(krmicd.getSid) || to_char(sysdate, 'hh24mmssddmmyyyy'); wait := true; num_sbt_chns := krmicd.getSBTParallelism; while wait loop dbms_rcvcat.throttle_me(oam_job_id, num_sbt_chns, request_time, wait, error_str); if error_str is not null then krmicd.SignalErrMsg(1004, error_str); elsif wait then krmicd.writeMsg(8629, to_char(num_sbt_chns)); wait_msg_dis := true; krmicd.sleep(60); else if wait_msg_dis then krmicd.writeMsg(8630); end if; end if; end loop; end if; end if; %ENDIF% catalog %IF% target -- -- if (vendortype = sys.dbms_backup_restore.DEVICEQUERY_BA) then krmicd.writeMsg(6918); end if; %ENDIF% target end; >>> define devrel <<< -- begin sys.dbms_backup_restore.deviceDeallocate; sys.dbms_backup_restore.set_client_info(''); krmicd.writeMsg(8031, krmicd.getChid); krmicd.clearChannelInfo; -- tell krmq no device here now end; >>> define setlm <<< begin >>> define 'kbytes' <<< sys.dbms_backup_restore.setLimit( sys.dbms_backup_restore.kbytes,&args&); >>> define 'rate' <<< sys.dbms_backup_restore.setLimit( sys.dbms_backup_restore.max_read_kbytes,&args&); >>> define 'readrate' <<< sys.dbms_backup_restore.setLimit( sys.dbms_backup_restore.readrate,&args&); >>> define 'parallel' <<< sys.dbms_backup_restore.setLimit( sys.dbms_backup_restore.parallel,&args&); >>> define setlmend <<< end; >>> define 'change' <<< -- declare found boolean; mismatch boolean; anymiss boolean := FALSE; runatsite boolean := FALSE; ocount number := 0; mcount number := 0; rscount number := 0; rc number; rc_in_use number; msg number; /* about the object */ new_status varchar2(1); old_status varchar2(1); ba_access varchar2(1); objectType number; handle varchar2(512); recid number; stamp number; obj_key1 number; obj_key2 number; pieceno number; blksize number; rlscn number; rlstime date; crescn number; ckpscn number; new_fname varchar2(512); cmdmsg number; cmdtxt varchar2(32); new_recid number; new_stamp number; obj_typen varchar2(20); devtype varchar2(20); devicetype varchar2(20); writeflag binary_integer; dummy binary_integer; keep_until_d date := NULL; force binary_integer; hdl_isdisk binary_integer; site_key number; this_site_key number := 0; nsite_key number := 0; source_dbid number; vbkey number := 0; foreignal binary_integer; to_db_unique_name varchar2(30); pdbid number; pplcdbdbid number; ppltrans number; -- -- &constants& -- dexpired_exists exception; internal_error exception; pragma exception_init(dexpired_exists, -20502); pragma exception_init(internal_error, -600); begin &1& entered('change'); deb('change', 'started, command:'||cmd); select decode(cmd, krmiAVAIL, 6200, krmiDELETE, 6201, krmiDEXPIRED, 6202, krmiKEEP, 6203, krmiUAVAIL, 6204, krmiUNCAT, 6205, krmiXCHECK, 6206) into cmdmsg from x$dual; select decode(cmd, krmiAVAIL, 'CHANGE AVAILABLE', krmiDELETE, 'DELETE', krmiDEXPIRED, 'DELETE', krmiXCHECK, 'CROSSCHECK', 'UNKNOWN') into cmdtxt from x$dual; devicetype := NULL; %IF% catalog this_site_key := dbms_rcvcat.getThisSiteKey; nsite_key := dbms_rcvcat.getThisSiteKey(to_db_unique_name); deb('change', 'this_site_key=' || this_site_key); deb('change', 'nsite_key=' || nsite_key); %ENDIF% catalog loop found := FALSE; mismatch := FALSE; rc_in_use := 0; vbkey := 0; -- krmicd.changeGetNext(objectType, handle, recid, stamp, obj_key1, obj_key2, pieceno, blksize, ckpscn, rlscn, rlstime, crescn, old_status, devtype, site_key, source_dbid, vbkey, ba_access, pdbid, pplcdbdbid); deb('change', 'File '|| handle || ' belongs to ' ||site_key); deb('change', 'File '|| handle || ' virtual key '||vbkey); deb('change', 'File '|| handle || ' ba_access ' ||ba_access); deb('change', 'Pdbid '|| pdbid || ' pplcdbdbid ' || pplcdbdbid); %IF% catalog -- -- -- -- -- if site_key = 0 and this_site_key <> 0 then site_key := this_site_key; deb('change', 'updated site_key to '|| site_key); end if; %ENDIF% catalog exit when objectType = 0; if old_status != 'X' and cmd = krmiDEXPIRED then krmicd.writeMsg(1005, 'INTERNAL ERROR: Available object during '|| 'DELETE EXPIRED'); raise internal_error; end if; if nforce = 1 or (old_status = 'U' and cmd = krmiDELETE) then force := 1; else force := 0; end if; if devtype = 'DISK' then hdl_isdisk := 1; else hdl_isdisk := 0; end if; if devicetype is NULL and devtype is not NULL then devicetype := devtype; end if; deb('change', ' processing (file/handle='||handle||','|| 'recid='||to_char(recid)||', old_status='||old_status|| ', hdl_isdisk=' || hdl_isdisk || ', devicetype=' || nvl(devicetype, 'NULL') || ', source_dbid=' || source_dbid || ')'); deb('change',' force: '||force); if objectType = krmiBPIECEX then obj_typen := 'Backup Piece'; elsif objectType = krmiPC then obj_typen := 'Proxy Copy'; elsif objectType = krmiDC then if (obj_key1 = 0) then obj_typen := 'Control File Copy'; else obj_typen := 'Datafile Copy'; end if; elsif objectType = krmiRAL then if (source_dbid = 0) then obj_typen := 'Archivelog'; foreignal := 0; else obj_typen := 'Foreign Archivelog'; foreignal := 1; end if; elsif objectType = krmiBS then obj_typen := 'Backup Set'; else krmicd.writeMsg(1005, 'INTERNAL ERROR: unexpected objectType='|| to_char(objectType)); raise internal_error; end if; if cmd in (krmiUAVAIL, krmiUNCAT, krmiKEEP, krmiRESETDBUN) then -- -- -- -- -- -- -- found := TRUE; else -- -- begin ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation( pdbid => pdbid, pplcdbdbid => pplcdbdbid); if objectType = krmiBPIECEX then deb('change', 'Calling ValidateBackupPiece for '||handle); rc := sys.dbms_backup_restore.validateBackupPiece( recid => recid, stamp => stamp, handle => handle, set_stamp => obj_key2, set_count => obj_key1, pieceno => pieceno, hdl_isdisk => hdl_isdisk); elsif objectType = krmiPC then deb('change', 'Calling proxyValOnly for '||handle); rc := sys.dbms_backup_restore.proxyValOnly( recid => recid, stamp => stamp, handle => handle); elsif objectType = krmiDC then deb('change', 'Calling ValidateDataFileCopy for '||handle); rc := sys.dbms_backup_restore.validateDataFileCopy( recid => recid, stamp => stamp, fname => handle, dfnumber => obj_key1, resetlogs_change => rlscn, creation_change => crescn, checkpoint_change => ckpscn, blksize => blksize, signal => 0); elsif objectType = krmiRAL then deb('change', 'Calling ValidateArchivedLog for '||handle); rc := sys.dbms_backup_restore.validateArchivedLog( recid => recid, stamp => stamp, fname => handle, thread => obj_key1, sequence => obj_key2, resetlogs_change => rlscn, first_change => crescn, blksize => blksize, signal => 0, terminal => 0, foreignal => foreignal); end if; if (ppltrans > 0) then sys.dbms_backup_restore.endPrePluginTranslation; end if; exception when others then if implicit != 0 then -- -- rc := sys.dbms_backup_restore.validate_file_different; krmicd.writeErrMsg(1005, sqlerrm); krmicd.clearErrors; elsif force = 0 then raise; else krmicd.clearErrors; end if; end; deb('change', 'file '||handle||', rc='||rc); rc_in_use := bitand(rc, sys.dbms_backup_restore.validate_in_use); rc := bitand(rc, sys.dbms_backup_restore.validate_file_different); deb('change', 'file '||handle||', Modified rc='||rc|| ' rc_in_use='||rc_in_use); if rc = 0 and rc_in_use = 0 then found := TRUE; end if; end if; deb('change', 'file '||handle||', found='||bool2char(found)); if krmicd.changeSetFound(found) then if found then deb('change', 'file '||handle||' in found'); if cmd in (krmiDELETE, krmiDEXPIRED) and old_status = 'X' then deb('change', 'file '||handle||'mismatched due to X'); mismatch := TRUE; -- -- end if; else if rc_in_use != 0 then deb('change', 'cannot validate file:'||handle|| ', in use by another process'); if force = 0 then krmicd.writeMsg(8167, cmdtxt); krmicd.writeMsg(8517, handle, to_char(recid), to_char(stamp)); goto next_object; end if; end if; if cmd = krmiAVAIL then deb('change', 'file '||handle||' not found in AVAIL'); if objectType = krmiBPIECEX then krmicd.writeMsg(6481, handle); elsif objectType = krmiPC then krmicd.writeMsg(6482, handle); elsif objectType = krmiDC then if obj_key1 = 0 then krmicd.writeMsg(6479, handle); else krmicd.writeMsg(6478, handle); end if; elsif objectType = krmiRAL then krmicd.writeMsg(6480, handle); end if; -- -- ocount := ocount - 1; elsif cmd = krmiDELETE then deb('change', 'file '||handle||' not found in DELETE'); if old_status = 'A' then mismatch := TRUE; end if; else deb('change', 'file '||handle||' not found for cmd '||cmd); end if; end if; deb('change', 'file '||handle||' mismatch: '||bool2char(mismatch)|| ' force: '||force|| ' rc_in_use: '||rc_in_use ); if mismatch and force = 0 then -- krmicd.mismatchObj(obj_typen, handle, site_key); anymiss := TRUE; mcount := mcount + 1; goto next_object; end if; -- if cmd in (krmiXCHECK, krmiAVAIL) then if found then new_status := 'A'; else new_status := 'X'; end if; elsif cmd in (krmiDEXPIRED, krmiDELETE) then new_status := 'D'; elsif cmd = krmiUNCAT then new_status := 'R'; elsif cmd = krmiUAVAIL then new_status := 'U'; elsif cmd = krmiRESETDBUN then new_status := old_status; elsif cmd = krmiKEEP then -- new_status := 'K'; keep_until_d := stamp2date(keep_until); else krmicd.writeMsg(1005,'INTERNAL ERROR: unknown cmd='||to_char(cmd)); raise internal_error; end if; -- -- -- if cmd in (krmiXCHECK, krmiAVAIL) then if not found and site_key <> this_site_key then deb('change','file ' || handle || ' must be crosschecked at site ' || site_key); krmicd.runAtSiteObj(obj_typen, handle, site_key); runatsite := TRUE; rscount := rscount + 1; goto next_object; end if; end if; -- -- -- if cmd in (krmiDEXPIRED, krmiDELETE) then if not found and site_key <> this_site_key then deb('change','file ' || handle || ' must be deleted at site ' || site_key); krmicd.runAtSiteObj(obj_typen, handle, site_key); runatsite := TRUE; rscount := rscount + 1; goto next_object; end if; end if; -- -- -- if objectType = krmiBS and cmd = krmiKEEP and vbkey != 0 then krmicd.writeMsg(1005, 'Not Supported on Recovery Appliance '); krmicd.writeMsg(1005, 'Cannot do KEEP on virtual backups'); goto next_object; elsif objectType = krmiBS then %IF% catalog if (cmd = krmiRESETDBUN AND (site_key is null or site_key <> nsite_key)) then dbms_rcvcat.changeBackupSet( recid => recid, stamp => stamp, keep_options => keep_options, keep_until => keep_until_d, osite_key => site_key, nsite_key => nsite_key); end if; %ENDIF% catalog if dbnomount = 0 then ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation( pdbid => pdbid, pplcdbdbid => pplcdbdbid); sys.dbms_backup_restore.changeBackupSet( recid => recid, stamp => stamp, set_count => obj_key1, keep_options => keep_options, keep_until => keep_until); if (ppltrans > 0) then sys.dbms_backup_restore.endPrePluginTranslation; end if; %IF% catalog else dbms_rcvcat.changeBackupSet( recid => recid, stamp => stamp, keep_options => keep_options, keep_until => keep_until_d); %ENDIF% catalog end if; if cmd = krmiKEEP then if keep_options = 0 then -- krmicd.writeMsg(8121); else -- krmicd.writeMsg(8122); if keep_until > 0 then krmicd.writeMsg(6518, to_char(keep_until_d)); else krmicd.writeMsg(6519); end if; if (keep_options = KEEP_LOGS) then -- -- krmicd.writeMsg(6521); elsif (keep_options = KEEP_NOLOGS) then -- -- krmicd.writeMsg(6520); elsif (keep_options != KEEP_CONSIST) then -- krmicd.writeMsg(1005, 'INTERNAL ERROR: ' || 'unexpected keep option for Backup Set'); raise internal_error; end if; end if; else krmicd.writeMsg(1005, 'INTERNAL ERROR: unexpected cmd='|| to_char(cmd)||' for Backup Set'); raise internal_error; end if; krmicd.writeMsg(8539, to_char(obj_key2), -- set key to_char(recid), -- set recid to_char(stamp)); -- set stamp elsif objectType = krmiBPIECEX then %IF% catalog if (cmd = krmiRESETDBUN AND (site_key is null or site_key <> nsite_key)) then dbms_rcvcat.changeBackupPiece( bp_recid => recid, bp_stamp => stamp, status => new_status, set_stamp => obj_key2, set_count => obj_key1, osite_key => site_key, nsite_key => nsite_key); end if; %ENDIF% catalog if (old_status != new_status ) then if (vbkey != 0 or ba_access = 'L') and (cmd = krmiAVAIL or cmd = krmiUAVAIL or cmd = krmiUNCAT) then krmicd.writeMsg(1005, 'Not Supported on ' || 'Recovery Appliance '); krmicd.writeMsg(1005, 'Cannot change availability ' || 'or uncatalog backup ' || handle); goto next_object; elsif dbnomount = 0 then ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation( pdbid => pdbid, pplcdbdbid => pplcdbdbid); sys.dbms_backup_restore.changeBackupPiece( recid => recid, stamp => stamp, handle => handle, set_stamp => obj_key2, set_count => obj_key1, pieceno => pieceno, status => new_status, force => force); if (ppltrans > 0) then sys.dbms_backup_restore.endPrePluginTranslation; end if; %IF% catalog else -- if dbnomount != 0 and new_status = 'D' and force = 0 then ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation( pdbid => pdbid, pplcdbdbid => pplcdbdbid); sys.dbms_backup_restore.changeBackupPiece( recid => recid, stamp => stamp, handle => handle, set_stamp => obj_key2, set_count => obj_key1, pieceno => pieceno, status => new_status, force => 1); if (ppltrans > 0) then sys.dbms_backup_restore.endPrePluginTranslation; end if; end if; dbms_rcvcat.changeBackupPiece( bp_recid => recid, bp_stamp => stamp, status => new_status, set_stamp => obj_key2, set_count => obj_key1); %ENDIF% catalog end if; else deb('change', 'file '||handle|| ' not updated on repository, old_status:'||old_status|| ' same as new_status:'||new_status||',site_key:'||site_key); end if; if cmd = krmiXCHECK then if found then krmicd.writeMsg(8074, 'AVAILABLE'); else krmicd.writeMsg(8074, 'EXPIRED'); end if; elsif cmd in (krmiDEXPIRED, krmiDELETE) then if (rc_in_use = 0 or (rc_in_use != 0 and force != 0)) then krmicd.writeMsg(8073); end if; elsif cmd = krmiAVAIL then if found then krmicd.writeMsg(6115); else krmicd.writeMsg(6486); end if; elsif cmd = krmiUAVAIL then krmicd.writeMsg(6111); elsif cmd = krmiRESETDBUN then if (site_key is null or site_key <> nsite_key) then krmicd.writeMsg(1005, 'change backup piece db_unique_name'); end if; elsif cmd = krmiUNCAT then krmicd.writeMsg(8128); end if; if (rc_in_use = 0 or (rc_in_use != 0 and force != 0)) then krmicd.writeMsg(8517, handle, to_char(recid), to_char(stamp)); ocount := ocount + 1; end if; elsif objectType = krmiPC then %IF% catalog if (cmd = krmiRESETDBUN AND (site_key is null or site_key <> nsite_key)) then dbms_rcvcat.changeProxyCopy( pc_recid => recid, pc_stamp => stamp, status => new_status, keep_options => keep_options, keep_until => keep_until_d, osite_key => site_key, nsite_key => nsite_key); end if; %ENDIF% catalog if (old_status != new_status) then if dbnomount = 0 then ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation( pdbid => pdbid, pplcdbdbid => pplcdbdbid); sys.dbms_backup_restore.proxyChange( recid => recid, stamp => stamp, handle => handle, status => new_status, keep_options => keep_options, keep_until => keep_until, force => force); if (ppltrans > 0) then sys.dbms_backup_restore.endPrePluginTranslation; end if; %IF% catalog else dbms_rcvcat.changeProxyCopy( pc_recid => recid, pc_stamp => stamp, status => new_status, keep_options => keep_options, keep_until => keep_until_d); %ENDIF% catalog end if; else deb('change', 'file '||handle|| ' not updated on repository, old_status:'||old_status|| 'same as new_status:'||new_status||',site_key:'||site_key); end if; if cmd = krmiXCHECK then if found then krmicd.writeMsg(6450, 'AVAILABLE'); else krmicd.writeMsg(6450, 'EXPIRED'); end if; elsif cmd in (krmiDEXPIRED, krmiDELETE) then krmicd.writeMsg(6449); elsif cmd = krmiAVAIL then if found then krmicd.writeMsg(6447); else krmicd.writeMsg(6487); end if; elsif cmd = krmiUAVAIL then krmicd.writeMsg(6446); elsif cmd = krmiRESETDBUN then if (site_key is null or site_key <> nsite_key) then krmicd.writeMsg(1005, 'change proxy copy db_unique_name'); end if; elsif cmd = krmiUNCAT then krmicd.writeMsg(6448); elsif cmd = krmiKEEP then if keep_options = 0 then -- krmicd.writeMsg(8125); else -- krmicd.writeMsg(8126); if keep_until > 0 then krmicd.writeMsg(6518, to_char(keep_until_d)); else krmicd.writeMsg(6519); end if; if keep_options = KEEP_LOGS then -- -- krmicd.writeMsg(6521); elsif keep_options = KEEP_NOLOGS then -- -- krmicd.writeMsg(6520); elsif keep_options = KEEP_CONSIST then krmicd.writeMsg(1005, 'INTERNAL ERROR: ' || 'unexpected keep option for Proxy Copy'); raise internal_error; end if; end if; else krmicd.writeMsg(1005, 'INTERNAL ERROR: unexpected cmd='|| to_char(cmd)||' for Proxy Copy'); raise internal_error; end if; krmicd.writeMsg(6451, handle, to_char(recid), to_char(stamp)); ocount := ocount + 1; elsif objectType = krmiDC then %IF% catalog if (cmd = krmiRESETDBUN AND (site_key is null or site_key <> nsite_key)) then dbms_rcvcat.changeDataFileCopy( cdf_recid => recid, cdf_stamp => stamp, status => new_status, keep_options => keep_options, keep_until => keep_until_d, osite_key => site_key, nsite_key => nsite_key); end if; %ENDIF% catalog if (old_status != new_status) then if dbnomount = 0 then ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation( pdbid => pdbid, pplcdbdbid => pplcdbdbid); sys.dbms_backup_restore.changeDataFileCopy( recid => recid, stamp => stamp, fname => handle, dfnumber => obj_key1, resetlogs_change => rlscn, creation_change => crescn, checkpoint_change => ckpscn, blksize => blksize, new_status => new_status, keep_options => keep_options, keep_until => keep_until, force => force); if (ppltrans > 0) then sys.dbms_backup_restore.endPrePluginTranslation; end if; %IF% catalog else dbms_rcvcat.changeDataFileCopy( cdf_recid => recid, cdf_stamp => stamp, status => new_status, keep_options => keep_options, keep_until => keep_until_d); %ENDIF% catalog end if; else deb('change', 'file '||handle|| ' not updated on repository, old_status:'||old_status|| 'same as new_status:'||new_status||',site_key:'||site_key); end if; if cmd = krmiXCHECK then if found then if obj_key1 = 0 then krmicd.writeMsg(6156); else krmicd.writeMsg(6154); end if; else if obj_key1 = 0 then krmicd.writeMsg(6155); else krmicd.writeMsg(6153); end if; end if; elsif cmd in (krmiDEXPIRED, krmiDELETE) then if obj_key1 = 0 then krmicd.writeMsg(8072); else krmicd.writeMsg(8070); end if; elsif cmd = krmiAVAIL then if obj_key1 = 0 then if found then krmicd.writeMsg(6114); else krmicd.writeMsg(6484); end if; else if found then krmicd.writeMsg(6112); else krmicd.writeMsg(6483); end if; end if; elsif cmd = krmiUAVAIL then if obj_key1 = 0 then krmicd.writeMsg(6110); else krmicd.writeMsg(6108); end if; elsif cmd = krmiRESETDBUN then if (site_key is null or site_key <> nsite_key) then if obj_key1 = 0 then krmicd.writeMsg(1005, 'change control file copy db_unique_name'); else krmicd.writeMsg(1005, 'change datafile copy db_unique_name'); end if; end if; elsif cmd = krmiUNCAT then if obj_key1 = 0 then krmicd.writeMsg(6121); else krmicd.writeMsg(6119); end if; elsif cmd = krmiKEEP then if keep_options = 0 then -- krmicd.writeMsg(8123); else -- krmicd.writeMsg(8124); if keep_until > 0 then krmicd.writeMsg(6512, to_char(keep_until_d)); else krmicd.writeMsg(6513); end if; if keep_options = KEEP_LOGS then -- -- krmicd.writeMsg(6515); elsif keep_options = KEEP_NOLOGS then -- -- krmicd.writeMsg(6514); elsif keep_options != KEEP_CONSIST then -- krmicd.writeMsg(1005, 'INTERNAL ERROR: ' || 'unexpected keep option for Copy'); raise internal_error; end if; end if; else krmicd.writeMsg(1005, 'INTERNAL ERROR: unexpected cmd='|| to_char(cmd)||' for Copy'); raise internal_error; end if; if obj_key1 = 0 then krmicd.writeMsg(8516, handle, to_char(recid), to_char(stamp)); else krmicd.writeMsg(8513, handle, to_char(recid), to_char(stamp)); end if; ocount := ocount + 1; elsif objectType = krmiRAL then %IF% catalog if (cmd = krmiRESETDBUN AND (site_key is null or site_key <> nsite_key)) then dbms_rcvcat.changeArchivedLog( al_recid => recid, al_stamp => stamp, status => new_status, osite_key => site_key, nsite_key => nsite_key); end if; %ENDIF% catalog if (old_status != new_status) then if dbnomount = 0 then ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation( pdbid => pdbid, pplcdbdbid => pplcdbdbid); sys.dbms_backup_restore.changeArchivedLog( recid => recid, stamp => stamp, fname => handle, thread => obj_key1, sequence => obj_key2, resetlogs_change => rlscn, first_change => crescn, blksize => blksize, new_status => new_status, force => force, foreignal => foreignal); if (ppltrans > 0) then sys.dbms_backup_restore.endPrePluginTranslation; end if; %IF% catalog else if (foreignal != 0) then krmicd.writeMsg(1005, 'INTERNAL ERROR: unexpected database status'|| ' for Foreign Archivelog'); raise internal_error; end if; dbms_rcvcat.changeArchivedLog( al_recid => recid, al_stamp => stamp, osite_key => site_key, status => new_status); %ENDIF% catalog end if; else deb('change', 'file '||handle|| ' not updated on repository, old_status:'||old_status|| ',same as new_status:'||new_status||',site_key:'||site_key); end if; if (foreignal = 0) then if cmd = krmiXCHECK then if found then krmicd.writeMsg(6158); else krmicd.writeMsg(6157); end if; elsif cmd in (krmiDEXPIRED, krmiDELETE) then krmicd.writeMsg(6406); elsif cmd = krmiAVAIL then if found then krmicd.writeMsg(6113); else krmicd.writeMsg(6485); end if; elsif cmd = krmiUAVAIL then krmicd.writeMsg(6109); elsif cmd = krmiRESETDBUN then if (site_key is null or site_key <> nsite_key) then krmicd.writeMsg(1005, 'change archived log db_unique_name'); end if; elsif cmd = krmiUNCAT then krmicd.writeMsg(6120); end if; krmicd.writeMsg(8514, handle, to_char(recid), to_char(stamp)); else -- foreign archived log if cmd = krmiXCHECK then if found then krmicd.writeMsg(8618); else krmicd.writeMsg(8617); end if; elsif cmd in (krmiDEXPIRED, krmiDELETE) then krmicd.writeMsg(8621); elsif cmd = krmiAVAIL then if found then krmicd.writeMsg(8622); else krmicd.writeMsg(8623); end if; elsif cmd in (krmiUAVAIL, krmiRESETDBUN) then krmicd.writeMsg(1005, 'INTERNAL ERROR: unexpected cmd='|| to_char(cmd)||' for Foreign Archivelog'); raise internal_error; elsif cmd = krmiUNCAT then krmicd.writeMsg(8620); end if; krmicd.writeMsg(8619, handle, to_char(recid), to_char(stamp)); end if; ocount := ocount + 1; else krmicd.writeMsg(1005, 'INTERNAL ERROR: unexpected objectType='|| to_char(objectType)); raise internal_error; end if; end if; <> null; end loop; if ocount > 0 then if cmd = krmiRESETDBUN then krmicd.writeMsg(1005, 'Changed ' || to_char(ocount) || ' objects db_unique_name'); else krmicd.writeMsg(cmdmsg, to_char(ocount)); end if; if ((not anymiss) and implicit = 0)then krmicd.writeMsg(0); end if; if (cmd in (krmiDELETE, krmiDEXPIRED, krmiUNCAT)) then sys.dbms_backup_restore.cleanupBackupRecords; end if; end if; if anymiss then -- krmicd.writeMsg(0); krmicd.writeMsg(6207, mcount, nvl(devicetype, ' ')); krmicd.writeMsg(6208); krmicd.listMismatch; krmicd.writeMsg(0); end if; if runatsite then -- krmicd.writeMsg(0); krmicd.writeMsg(6216, rscount); krmicd.listRunAtSite; krmicd.writeMsg(0); end if; if (vbkey != 0) then exited('change', 'OK'); else exited('change', 'NOTOK'); end if; end; >>> define change_failure <<< -- declare failureList sys.dbms_ir.ir_failure_list_type; errorList sys.dbms_ir.ir_error_list_type; cmdmsg number; failureId number; firstcall binary_integer; &constants& internal_error exception; pragma exception_init(internal_error, -600); begin entered('change_failure'); deb('change_failure', 'started, command: '|| cmd); select decode(cmd, krmiHIGH, 7207, krmiLOW, 7208, krmiCLOSED, 7209) into cmdmsg from x$dual; firstcall := 1; loop exit when not krmicd.failureGetNext(firstcall, failureId); firstcall := 0; failureList(failureList.count + 1) := failureId; deb('change_failure', 'added failureId = ' || failureId); end loop; if (failureList.count = 0) then raise internal_error; end if; if (cmd = krmiCLOSED) then sys.dbms_ir.closeFailures( failureList => failureList ,errorList => errorList); elsif (cmd = krmiHIGH) then sys.dbms_ir.changePriority( failureList => failureList ,newPriority => sys.dbms_ir.IR_FAILURE_HIGH ,errorList => errorList); elsif (cmd = krmiLOW) then sys.dbms_ir.changePriority( failureList => failureList ,newPriority => sys.dbms_ir.IR_FAILURE_LOW ,errorList => errorList); else raise internal_error; end if; for i in 1..errorList.count loop if (abs(errorList(i).errorCode) = 51102) then krmicd.writeMsg(8062, to_char(errorList(i).failureID)); else krmicd.writeMsg(8061, to_char(errorList(i).failureID), abs(errorList(i).errorCode)); end if; end loop; krmicd.writeMsg(cmdmsg, to_char(failureList.count - errorList.count)); exited('change_failure', 'OK'); end; >>> define catdfc <<< -- declare fname varchar2(512); full_name varchar2(512); recid number; stamp number; rsid number; rsts number; begin &object& sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); sys.dbms_backup_restore.inspectDataFileCopy(fname => fname, full_name => full_name, recid => recid, stamp => stamp, &args&); krmicd.writeMsg(8050); krmicd.writeMsg(8513, full_name, to_char(recid), to_char(stamp)); sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0); end; >>> define catalc <<< -- declare fname varchar2(512); full_name varchar2(512); recid number; stamp number; rsid number; rsts number; begin &object& sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); sys.dbms_backup_restore.inspectArchivedLog(fname => fname, full_name => full_name, recid => recid, stamp => stamp); krmicd.writeMsg(8051); krmicd.writeMsg(8514, full_name, to_char(recid), to_char(stamp)); sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0); end; >>> define catbcf <<< -- declare fname varchar2(512); full_name varchar2(512); recid number; stamp number; rsid number; rsts number; begin &object& sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); sys.dbms_backup_restore.inspectControlFile(fname => fname, full_name => full_name, recid => recid, stamp => stamp); krmicd.writeMsg(8052); krmicd.writeMsg(8516, full_name, to_char(recid), to_char(stamp)); sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0); end; >>> define catbp <<< -- declare handle varchar2(512); full_handle varchar2(512); recid number; stamp number; err_num number := 0; err_msg varchar2(2048); rsid number; rsts number; db_not_mounted exception; pragma exception_init(db_not_mounted, -1507); begin &object& begin sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); sys.dbms_backup_restore.inspectBackupPiece( handle => handle, full_handle => full_handle, recid => recid, stamp => stamp); exception when db_not_mounted then raise; -- -- when others then -- err_num := sqlcode; err_msg := sqlerrm; end; if (err_num = 0) then krmicd.writeMsg(8127); krmicd.writeMsg(8517, full_handle, to_char(recid), to_char(stamp)); else krmicd.writeErrMsg(1005, err_msg); -- krmicd.mismatchObj('Backup Piece', handle, 0); krmicd.setDeferError; end if; sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0); end; >>> define clean <<< -- declare /* device status variables */ state binary_integer; devtype varchar2(512); name varchar2(512); bufsz binary_integer; bufcnt binary_integer; kbytes number; readrate binary_integer; parallel binary_integer; thread number; kcrmx_recs number; autochn number := 0; mr_not_started exception; pragma exception_init(mr_not_started, -1112); db_not_mounted exception; pragma exception_init(db_not_mounted, -1507); begin &object& begin krmicd.execSql('select count(*) from x$dual'); exception when others then krmicd.clearErrors; end; sys.dbms_backup_restore.backupCancel; sys.dbms_backup_restore.restoreCancel(FALSE); begin sys.dbms_backup_restore.proxyCancel; exception when others then krmicd.clearErrors; end; sys.dbms_backup_restore.cfileUseCurrent; -- release enqueue sys.dbms_backup_restore.deviceStatus(state, devtype, name, bufsz, bufcnt, kbytes, readrate, parallel); begin sys.dbms_backup_restore.bmrCancel; exception when others then krmicd.clearErrors; end; begin sys.dbms_backup_restore.flashbackCancel; exception when others then krmicd.clearErrors; end; begin sys.dbms_backup_restore.nbrCancel; exception when others then krmicd.clearErrors; end; begin sys.dbms_backup_restore.prePluginRecoveryCancel; exception when others then krmicd.clearErrors; end; begin sys.dbms_backup_restore.endPrePluginTranslation; exception when others then krmicd.clearErrors; end; begin sys.dbms_backup_restore.recoverCancel; exception when others then krmicd.clearErrors; end; begin if krmicd.mrCheck > 0 then krmicd.execSql('alter database recover cancel'); end if; exception when others then krmicd.clearErrors; end; begin sys.dbms_backup_restore.cleanupPgaContext; exception when others then krmicd.clearErrors; end; -- -- -- -- -- -- if (autochn = 0) then if (state > sys.dbms_backup_restore.NO_DEVICE) then sys.dbms_backup_restore.deviceDeallocate; krmicd.writeMsg(8031, krmicd.getChid); -- -- -- sys.dbms_backup_restore.set_client_info(''); end if; krmicd.clearChannelInfo; -- tell krmq no device here now end if; sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0); end; >>> define del_start <<< -- declare first_time boolean := TRUE; arch_recid number; arch_stamp number; fname varchar2(512); thread number; sequence number; resetlogs_change number; resetlogs_time varchar2(512); first_change number; next_change number; blksize number; handle varchar2(512); recid number; stamp number; cfisstby boolean := FALSE; chtype varchar2(16); cfauto boolean := FALSE; skipped boolean := FALSE; dfnumber number; copy_recid number; copy_stamp number; creation_change number; checkpoint_change number; no_delete binary_integer; reqscn number; -- streams/standby required scn rlgscn number; -- streams/standby resetlogs scn appscn number; apprlgscn number; alldest number := 0; docopies boolean := FALSE; reqbackups number; nbackups number; begin first_time := TRUE; -- make sure atleast one statement -- chtype := krmicd.getDevType; >>> define budf_start <<< -- /* This must be retriable, which means a backup conversation may already * be in progress when this step (re)executes. */ declare /* backup conversation status variables */ state binary_integer; setid number; stamp number; pieceno binary_integer; files binary_integer; datafiles boolean; incremental boolean; nochecksum boolean; device boolean; hdrupd boolean := TRUE; sparse_option binary_integer := 0; /* default backup type of sparse datafile */ /* piece creation variables */ done boolean; concur boolean; chg_tracking_err number; /* Miscellaneous */ memnum number; dfnumber number; cfname varchar2(512); copy_recid number; copy_stamp number; busy_retries number := 0; resetlogs_change number; creation_change number; checkpoint_change number; blksize number; blocks number; fname varchar2(1024); dpfname varchar2(1024); no_delete binary_integer; copy number; nformat number := 1; handle varchar2(512); comment varchar2(80); media varchar2(80); wrong_format exception; pragma exception_init(wrong_format, -20039); first_time boolean := TRUE; backup_level number; elapsed number; starttime date; hours number; mins number; secs number; ncopies number := 0; docompress boolean := FALSE; compressalg varchar2(80); compressasof number; compresslopt binary_integer; nonlogblk boolean := FALSE; /* backup_type is used to indicate what type of backup is done. This is used * to get configured copies, look at krmkgbac for more comments. */ backup_type number := 2; isstby boolean; larchlog_failover boolean; failoverdone boolean := FALSE; docopies boolean := FALSE; cnvrtto boolean := FALSE; cnvrtfr boolean := FALSE; sameen boolean := FALSE; reusefile boolean := FALSE; tsname varchar2(30) := NULL; thread number := NULL; sequence number := NULL; m number := 8581; cprecid number; cpstamp number; rsid number; rsts number; cptag varchar2(31) := NULL; noct boolean := FALSE; nooptim boolean := FALSE; dontcare varchar2(1); pltfrmto number := NULL; pltfrmfr number := NULL; foreign_dbname varchar2(8) := NULL; foreign_dbid number := NULL; doconvert boolean := FALSE; savepiecename boolean := FALSE; transontarget boolean := FALSE; transonlyundo boolean := FALSE; convertdb boolean := FALSE; bckconvertdb boolean := FALSE; processfile boolean := TRUE; isomf boolean; istmplt boolean; isasm boolean; validatecmd boolean; validateopt boolean; newcorrupt boolean; -- TRUE if new corruption is found updateok boolean; snapshot_cf boolean; file_exists number; crescn number; isfarsync boolean := FALSE; /* Multi-section backup fields */ msb_secbytes number := 0; msb_file_size number; msb_set_stamp number; msb_set_count number; msb_section_size number; msb_first_section number; msb_section_count number; msb_piece_number number; msb_piece_count number; msb_section_copy_fname varchar2(1025); msb_is_first_section boolean := FALSE; dpscn number; cnvrt_need_format exception; bkp_need_format exception; /* Transportable tablespace encryption */ jobname varchar2(512) := null; passphrase varchar2(128) := null; pragma exception_init(cnvrt_need_format, -20038); pragma exception_init(bkp_need_format, -20045); begin &1& -- &2& -- &3& -- &4& -- &5& -- &6& -- &7& -- &msb_secbytes& -- &comp_alg& -- &sparse_option& if pltfrmto is not null or pltfrmfr is not null then doconvert := true; end if; -- if (NOT beginBackupJobStep()) then return; end if; sys.dbms_backup_restore.backupStatus(state, setid, stamp, pieceno, files, datafiles, incremental, nochecksum, device); if state = sys.dbms_backup_restore.BACKUP_NO_CONVERSATION then goto start_convo; elsif state = sys.dbms_backup_restore.BACKUP_NAMING_FILES then goto name_files; else goto create_piece; end if; <> sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); sys.dbms_backup_restore.backupSetDatafile(stamp, setid, &args_start&, &args_tag&, backup_level => backup_level, imagcp => docopies, convertto => cnvrtto, convertfr => cnvrtfr, pltfrmto => pltfrmto, pltfrmfr => pltfrmfr, sameen => sameen, convertdb => convertdb or bckconvertdb, validate => validateopt, hdrupd => hdrupd, sparse_option => sparse_option); if hdrupd then krmicd.writeMsg(6782); krmicd.writeMsg(6785); updateok := sys.dbms_backup_restore.UpdateHeaders(); if not updateok then krmicd.writeMsg(6784); krmicd.writeMsg(8191, sys.dbms_backup_restore.getParm( sys.dbms_backup_restore.TRACE_FILENAME)); end if; krmicd.writeMsg(6783); end if; if (noct) then dontcare := sys.dbms_backup_restore.getParm(sys.dbms_backup_restore.incr_noct); end if; if (nooptim) then dontcare := sys.dbms_backup_restore.getParm(sys.dbms_backup_restore.full_nooptim); end if; -- if docopies then -- if not convertdb then if doconvert then krmicd.writeMsg(8589, krmicd.getChid); else krmicd.writeMsg(8580, krmicd.getChid); end if; end if; else if backup_level is not null then if (docompress) then krmicd.writeMsg(8047, krmicd.getChid, to_char(backup_level)); else krmicd.writeMsg(8048, krmicd.getChid, to_char(backup_level)); end if; else if (docompress) then krmicd.writeMsg(8046, krmicd.getChid); elsif (validatecmd) then krmicd.writeMsg(8140, krmicd.getChid); else krmicd.writeMsg(8008, krmicd.getChid); end if; end if; end if; if pltfrmto is not null and not docopies then krmicd.getExportJobName(jobname, passphrase); -- -- if (jobname is not null) then passphrase := null; sys.dbms_backup_restore.setExportJobName(jobname, passphrase); end if; end if; setBackupParams(docopies); <> deb('budf_start', 'set_stamp=' || stamp || ' set_count=' || setid, rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN); >>> define bual_start <<< -- /* This must be retriable, which means a backup conversation may already * be in progress when this step (re)executes. */ declare /* backup conversation status variables */ state binary_integer; setid number; stamp number; pieceno binary_integer; files binary_integer; datafiles boolean; incremental boolean; backup_level number; nochecksum boolean; device boolean; /* piece creation variables */ done boolean; concur boolean; chg_tracking_err number; /* Miscellaneous */ memnum number; arch_recid number; arch_stamp number; fname varchar2(512); dpfname varchar2(512); thread number; sequence number; resetlogs_change number; resetlogs_time varchar2(512); first_change number; next_change number; blksize number; blocks number; copy number; nformat number := 1; handle varchar2(512); comment varchar2(80); media varchar2(80); wrong_format exception; pragma exception_init(wrong_format, -20039); first_time boolean := TRUE; cfisstby boolean := FALSE; elapsed number; starttime date; hours number; mins number; secs number; ncopies number := 0; -- -- backup_type number := 1; larchlog_failover boolean; failoverdone boolean := FALSE; docopies boolean := FALSE; reusefile boolean := FALSE; dfnumber number := NULL; tsname varchar2(30) := NULL; m number := 8583; cprecid number; cpstamp number; foreign_dbname varchar2(8) := NULL; foreign_dbid number := NULL; rsid number; rsts number; cptag varchar2(31) := NULL; doconvert boolean := FALSE; docompress boolean := FALSE; compressalg varchar2(80); compressasof number; compresslopt binary_integer; savepiecename boolean := FALSE; transontarget boolean := FALSE; transonlyundo boolean := FALSE; convertdb boolean := FALSE; bckconvertdb boolean := FALSE; processfile boolean := TRUE; reqscn number; -- streams/standby required scn rlgscn number; -- streams/standby resetlogs scn appscn number; alldest number := 0; apprlgscn number; reqbackups number; nbackups number; isomf boolean; istmplt boolean; isasm boolean; validatecmd boolean; validateopt boolean; newcorrupt boolean; -- TRUE if new corruption is found msb_secbytes number := 0; msb_is_first_section boolean := FALSE; nonlogblk boolean := FALSE; cnvrt_need_format exception; bkp_need_format exception; pragma exception_init(cnvrt_need_format, -20038); pragma exception_init(bkp_need_format, -20045); begin -- &2& -- &3& -- &4& -- &5& -- &6& -- &7& -- &msb_secbytes& -- &comp_alg& -- if (NOT beginBackupJobStep()) then return; end if; sys.dbms_backup_restore.backupStatus(state, setid, stamp, pieceno, files, datafiles, incremental, nochecksum, device); if state = sys.dbms_backup_restore.BACKUP_NO_CONVERSATION then goto start_convo; elsif state = sys.dbms_backup_restore.BACKUP_NAMING_FILES then goto name_files; else goto create_piece; end if; <> sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); sys.dbms_backup_restore.backupSetArchivedLog(set_stamp => stamp, set_count => setid, &args_start&, &args_tag&, imagcp => docopies, validate => validateopt); if not docopies then if (validatecmd) then krmicd.writeMsg(8145, krmicd.getChid); elsif (docompress) then krmicd.writeMsg(8049, krmicd.getChid); else krmicd.writeMsg(8009, krmicd.getChid); end if; else krmicd.writeMsg(8582, krmicd.getChid); end if; setBackupParams(docopies); <> >>> define bubs_start <<< -- declare set_count number; set_stamp number; recid number; stamp number; copy_recid number; copy_stamp number; isrdf boolean; pieceno number := 0; -- piece number for this step piececnt binary_integer := 0; -- count of distinct piece copies npieces binary_integer := 0; -- number pieces in backup set type names is table of varchar2(512) index by binary_integer; type ctlid is table of number index by binary_integer; type isrdf_tab is table of boolean index by binary_integer; pnames names; precid ctlid; pstamp ctlid; pisrdf isrdf_tab; /* piece creation variables */ concur boolean; /* Miscellaneous */ fname varchar2(1024); copy number; max_copy binary_integer; ncopies number := 0; -- number of output copies to make docompress boolean := FALSE; nformat number := 1; handle varchar2(512); comment varchar2(80); media varchar2(80); elapsed number; stampd date; hours number; mins number; secs number; cfauto boolean := FALSE; skipped boolean := FALSE; -- skipped this backuppiece chtype varchar2(16); start_time date; savepiecename boolean := FALSE; transontarget boolean := FALSE; transonlyundo boolean := FALSE; convertdb boolean := FALSE; bckconvertdb boolean := FALSE; processfile boolean := TRUE; rsid number; rsts number; wrong_format exception; in_use exception; del_for_space exception; dropped_pdb_file exception; isomf boolean; istmplt boolean; isasm boolean; skip_inaccessible boolean; firstscan boolean; pltfrmfr number := NULL; nofrpltfrm boolean := FALSE; pragma exception_init(wrong_format, -20039); pragma exception_init(in_use, -19584); pragma exception_init(del_for_space, -19805); pragma exception_init(dropped_pdb_file, -45913); begin -- &object& -- &3& -- &4& if (skip_inaccessible and krmicd.isBsInaccessible(firstscan)) then if (firstscan) then krmicd.writeMsg(8107, to_char(set_count), to_char(set_stamp)); end if; return; end if; if pltfrmfr is NULL then krmicd.writeMsg(8104, krmicd.getChid, to_char(set_count), to_char(set_stamp), to_char(pieceno)); end if; -- if (NOT beginBackupJobStep()) then return; end if; sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); >>> define copyfil_start <<< -- declare cpfil_unsupported exception; pragma exception_init(cpfil_unsupported, -16524); type names is table of varchar2(512) index by binary_integer; src_name varchar2(512); lformat names; nformat number := 1; netalias varchar2(1000) := NULL; worked boolean; memnum number; begin -- if (NOT beginBackupJobStep()) then return; end if; >>> define budf_name <<< -- &memnum& &object& if (first_time) then if validatecmd then if (nonlogblk = FALSE) then krmicd.writeMsg(8141, krmicd.getChid); end if; elsif not docopies then krmicd.writeMsg(8010, krmicd.getChid); end if; first_time := FALSE; end if; if files < memnum then begin sys.dbms_backup_restore.backupDataFile(dfnumber => dfnumber, &args&); if convertdb then if transonlyundo then processfile := krmicd.isFileUndo(dfnumber); end if; if processfile then if transontarget then krmicd.writeMsg(8305, krmicd.getChid); else krmicd.writeMsg(8589, krmicd.getChid); end if; end if; end if; if (processfile and nonlogblk = FALSE) then krmicd.writeMsg(8522, to_char(dfnumber, 'FM09999'), fname); deb('budf_name', 'blocks=' || blocks || ' block_size=' || blksize, rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN); end if; exception when sys.dbms_backup_restore.inc_scn_matches_df_scn then krmicd.writeMsg(8522, to_char(dfnumber, 'FM09999'), fname); krmicd.writeMsg(8056, to_char(dfnumber, 'FM09999')); krmicd.clearErrors; -- when others then select count(*) into file_exists from x$kccfe fe where fe.fenum = dfnumber and to_number(fe.fecrc_scn) = crescn and fe.fedup != 0; -- if file_exists > 0 then raise; else -- krmicd.writeMsg(8193, to_char(dfnumber, 'FM09999'), fname); deb('budf_fname', sqlerrm); krmicd.clearErrors; end if; end; files := files + 1; end if; >>> define budc_name <<< -- &memnum& &object& name_datafilecopy(memnum, copy_recid, copy_stamp, fname, dfnumber, blocks, blksize, tsname, files, docopies, &args&); >>> define bucv_name <<< -- &memnum& &object& if files < memnum then sys.dbms_backup_restore.convertDataFileCopy(fname, &args&); files := files + 1; krmicd.writeMsg(8506, fname); end if; >>> define busp_name <<< -- &memnum& &object& if (first_time) then if validatecmd then krmicd.writeMsg(8141, krmicd.getChid); elsif not docopies then krmicd.writeMsg(8010, krmicd.getChid); end if; first_time := FALSE; end if; sys.dbms_backup_restore.backupSpFile; krmicd.writeMsg(8113); >>> define bucf_name <<< -- isstby := FALSE; isfarsync := FALSE; dfnumber := 0; &memnum& &object& if (first_time) then if validatecmd then krmicd.writeMsg(8141, krmicd.getChid); elsif not docopies then krmicd.writeMsg(8010, krmicd.getChid); end if; first_time := FALSE; end if; if (cfname is null and not validateopt and not docopies) then snapshot_cf := TRUE; else snapshot_cf := FALSE; -- -- -- -- for r in (select 1 from v$instance where parallel = 'YES') loop snapshot_cf := TRUE; exit; end loop; end if; if files < memnum then -- -- -- -- <> -- retry on failure to get snapshot enqueue begin -- if snapshot_cf then sys.dbms_backup_restore.cfileMakeAndUseSnapshot(isstby); sys.dbms_backup_restore.cfileUseCurrent; end if; sys.dbms_backup_restore.backupControlFile(cfname => cfname, isstby => isstby, snapshot_cf => snapshot_cf, isfarsync => isfarsync); exception when sys.dbms_backup_restore.snapshot_enqueue_busy then -- -- -- -- if busy_retries = 180 then krmicd.writeMsg(20029, 'cannot make a snapshot controlfile'); raise; end if; busy_retries := busy_retries + 1; -- if (mod(busy_retries, 15) = 0) then krmicd.writeMsg(8512); end if; krmicd.sleep(20); krmicd.clearErrors; goto snapshot; end; -- snapshot controlfile stuff files := files + 1; if cfname is null then if validatecmd then if isstby then krmicd.writeMsg(8142); else krmicd.writeMsg(8143); end if; elsif not docopies then if isstby then krmicd.writeMsg(8020); else krmicd.writeMsg(8011); end if; else if isstby then krmicd.writeMsg(8585); else krmicd.writeMsg(8584); end if; end if; else krmicd.writeMsg(8524, cfname); deb('bucf_name', 'blocks=' || blocks || ' block_size=' || blksize, rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN); end if; end if; >>> define bual_name <<< -- name_log(&memnum&, &object&, files=>files, first_time => first_time, docopies => docopies, validatecmd => validatecmd); &1& >>> define bubp_name <<< -- &object& -- pnames(piececnt) := fname; precid(piececnt) := copy_recid; pstamp(piececnt) := copy_stamp; pisrdf(piececnt) := isrdf; piececnt := piececnt + 1; >>> define budp_name <<< -- declare dpckpscn number; dpckptime number; dprlgscn number; dprlgtime number; dpfno number; dpdeflt boolean; begin &memnum& &object& if files < memnum then sys.dbms_backup_restore.backupDmpfile(dmpfile => fname, blksize => blksize, dpckpscn => dpckpscn, dpckptime => dpckptime, dprlgscn => dprlgscn, dprlgtime => dprlgtime, dpfno => dpfno, dbid => foreign_dbid); krmicd.writeMsg(8557, fname); if dpdeflt then dpfname := fname; end if; deb('budp_name', 'dmpfile=' || fname || ' blocksize=' || blksize || ' dprlgtime=' || dprlgtime || ' dprlgscn= ' || dprlgscn || ' dpckpscn= ' || dpckpscn || ' dpckptime= '|| dpckptime || ' dpfno=' || dpfno || ' dbid=' || foreign_dbid); files := files + 1; end if; end; >>> define copyfil_name <<< -- &memnum& &object& >>> define msb <<< -- sys.dbms_backup_restore.backupStatus(state, setid, stamp, pieceno, files, datafiles, incremental, nochecksum, device); if (files = 0 ) then if krmicd.firstMSB then krmicd.exitMSB; goto create_piece; end if; else if krmicd.firstMSB then sys.dbms_backup_restore.initMSB(dfnumber, msb_file_size, msb_set_stamp, msb_set_count); if docopies then msb_is_first_section := TRUE; end if; krmicd.initMSB(msb_file_size, blksize, msb_secbytes, msb_set_stamp, msb_set_count); end if; -- -- -- if (not msb_is_first_section and docopies and not validateopt) then krmicd.getMSC(handle); sys.dbms_backup_restore.setMSC(handle); deb('msb', 'Nextsection: '||handle); end if; krmicd.getMSB(msb_section_size, msb_first_section, msb_section_count, msb_set_stamp, msb_set_count, msb_piece_number, msb_piece_count); sys.dbms_backup_restore.setMSB(dfnumber, msb_section_size, msb_first_section, msb_section_count, msb_set_stamp, msb_set_count, msb_piece_number, msb_piece_count); if (validatecmd) then krmicd.writeMsg(8616, msb_section_size * msb_first_section + 1, least(blocks, (msb_section_size * msb_first_section) + (msb_section_size * msb_section_count))); else krmicd.writeMsg(8525, msb_section_size * msb_first_section + 1, least(blocks, (msb_section_size * msb_first_section) + (msb_section_size * msb_section_count))); end if; end if; >>> define bu_create <<< -- <> sys.dbms_backup_restore.backupStatus(state, setid, stamp, pieceno, files, datafiles, incremental, nochecksum, device); starttime := sysdate; -- -- if (files = 0) then sys.dbms_backup_restore.backupCancel; krmicd.writeMsg(8057, krmicd.getChid); else -- &ncopies& if (ncopies = 0) then ncopies := krmicd.getBackupCopies(backup_type, krmicd.getDevType); end if; sys.dbms_backup_restore.setLimit(sys.dbms_backup_restore.dupcnt, ncopies); loop if not docopies then krmicd.writeMsg(8038, krmicd.getChid, to_char(pieceno+1), to_char(sysdate)); end if; declare type names is table of varchar2(512) index by binary_integer; fnames names; lformat names; lyear varchar2(4); lday varchar2(2); lmonth varchar2(2); copyaux number; chtype varchar2(16); busy_retries number := 0; piecefmt varchar2(512); orig_fname varchar2(512); set_stamp number; set_count number; deffmt binary_integer; dest binary_integer := 0; netalias varchar2(1000) := NULL; new_reusefile boolean := reusefile ; begin <> begin select to_char(sysdate, 'YYYY', 'NLS_CALENDAR=Gregorian'), to_char(sysdate, 'MM', 'NLS_CALENDAR=Gregorian'), to_char(sysdate, 'DD', 'NLS_CALENDAR=Gregorian') into lyear, lmonth, lday from x$dual; -- lformat(0) := NULL; -- -- -- -- &lformat& -- -- -- copy := 0; while copy < ncopies loop begin -- piecefmt := lformat(mod(copy, nformat)); krmicd.getFormat(format => piecefmt, copy => copy+1, deffmt => deffmt, dest => dest); -- -- -- chtype := krmicd.getDevType; if chtype is null then chtype := 'N/A'; elsif (docopies and chtype != 'DISK') then chtype := 'DISK'; end if; &savepiecename& if docopies then orig_fname := fname; else orig_fname := NULL; end if; deb('bu_create_genpiece', 'pieceno: ' || nvl(to_char(pieceno),'-NULL-') || ' setid: ' || nvl(to_char(setid),'-NULL-') || ' stamp: ' || nvl(to_char(stamp),'-NULL-') || ' format: ' || nvl(piecefmt,'-NULL-') || ' copy: ' || nvl(to_char(copy),'-NULL-') || ' chtype: ' || nvl(chtype,'-NULL-') || ' lyear: ' || nvl(lyear,'-NULL-') || ' lmonth: ' || nvl(lmonth,'-NULL-') || ' lday: ' || nvl(lday,'-NULL-') || ' foreign_dbid: ' || nvl(to_char(foreign_dbid),'-NULL-') || ' ndbname: ' || nvl(foreign_dbname,'-NULL-') || ' dfnumber: ' || nvl(to_char(dfnumber),'-NULL-') || ' tsname: ' || nvl(tsname,'-NULL-') || ' logseq: ' || nvl(to_char(sequence),'-NULL-') || ' logthr: ' || nvl(to_char(thread),'-NULL-') ); fnames(copy) := sys.dbms_backup_restore.genPieceName( pno => pieceno+1, set_count => setid, set_stamp => stamp, format => piecefmt, copyno => copy+1, devtype => chtype, year => lyear, month => lmonth, day => lday, dbid => foreign_dbid, ndbname => foreign_dbname, cfseq => NULL, -- not used fileno => dfnumber, tsname => tsname, logseq => to_char(sequence), logthr => thread, imagcp => docopies, savepname => savepiecename, fname => orig_fname, forcnvrt => processfile); -- istmplt := FALSE; if (chtype = 'DISK') then sys.dbms_backup_restore.isfileNameOMF( fname => fnames(copy), isomf => isomf, isasm => isasm, istmplt => istmplt); if deffmt != 0 then if (doconvert and docopies) then raise cnvrt_need_format; elsif (incremental and backup_level is null) then raise bkp_need_format; end if; end if; end if; -- -- copyaux := 0; while (not istmplt and dest = 0 and copyaux < copy) loop if fnames(copy) = fnames(copyaux) then raise wrong_format; end if; copyaux := copyaux + 1; end loop; -- if (copy > 0) then sys.dbms_backup_restore.backupPieceCrtDupSet(copy, fnames(copy)); end if; end; copy := copy + 1; end loop; -- -- copy := 0; -- -- -- if docopies and msb_is_first_section and not validateopt then deb('bu_create ','Msc: Front Loader'); sys.dbms_backup_restore.initMSC(fname => fnames(copy), deffmt => deffmt, dest => dest, handle => handle); deb('bu_create ', 'HANDLE:'||handle); -- -- -- -- krmicd.setMSC(handle); end if; -- -- -- if processfile and not transontarget then if krmicd.checkFailedBP(fnames(copy), pieceno) then new_reusefile := TRUE; deb('bu_create ', 'reusefile '); else deb('bu_create ', 'save file name'); -- -- new_reusefile := reusefile; krmicd.saveBpName(fnames(copy), pieceno); end if; sys.dbms_backup_restore.backupPieceCreate( fname => fnames(copy), pieceno => pieceno, done => done, handle => handle, comment => comment, media => media, concur => concur, &args_create&, reuse => new_reusefile, archlog_failover => larchlog_failover, deffmt => deffmt, recid => cprecid, stamp => cpstamp, tag => cptag, dest => dest, post10_2 => TRUE, netalias => netalias, docompress => docompress, compressalg => compressalg, compressasof => compressasof, compresslopt => compresslopt); -- krmicd.fileRestored(ftype => rman_constant.DATAFILE, fno => nvl(dfnumber, 0), thread => 0, sequence => 0, resetscn => 0, resetstamp => 0, fname => handle); -- -- -- sys.dbms_backup_restore.pieceContextGetNumber( sys.dbms_backup_restore.signal_change_tracking_error, chg_tracking_err); if chg_tracking_err = 1 then krmicd.writeMsg(8606); end if; else done := TRUE; end if; if larchlog_failover then failoverdone := TRUE; end if; if concur then krmicd.writeMsg(8135, fname); end if; if done then sys.dbms_backup_restore.backupCancel(); end if; exception when sys.dbms_backup_restore.snapshot_enqueue_busy then -- -- -- -- -- -- if busy_retries = 180 then krmicd.writeMsg(20029, 'cannot make a snapshot controlfile'); sys.dbms_backup_restore.backupCancel(); raise; end if; busy_retries := busy_retries + 1; -- if (mod(busy_retries, 15) = 0) then krmicd.writeMsg(8512); end if; krmicd.sleep(20); krmicd.clearErrors; goto snapshot; end; krmicd.writeIOs(stamp, setid); end; -- snapshot controlfile stuff if not docopies then if ncopies = 1 then krmicd.writeMsg(8044, krmicd.getChid, to_char(pieceno), to_char(sysdate)); else -- -- if cptag is not null then krmicd.writeMsg(8053, krmicd.getChid, to_char(pieceno), to_char(sysdate), to_char(ncopies), cptag); else krmicd.writeMsg(8045, krmicd.getChid, to_char(pieceno), to_char(sysdate), to_char(ncopies)); end if; end if; end if; copy := 0; -- -- -- if processfile and not transontarget then while copy < ncopies loop if (copy > 0) then -- sys.dbms_backup_restore.backupPieceCrtDupGet(copy, handle, comment, media); end if; if not docopies then if comment is null then comment := 'NONE'; end if; -- -- -- -- if ncopies = 1 and cptag is not null then krmicd.writeMsg(8530, handle, cptag, comment); else krmicd.writeMsg(8503, handle, comment); end if; else if doconvert then krmicd.writeMsg(8588, handle); else if cptag is NOT NULL then if cprecid = 0 and cpstamp = 0 then krmicd.writeMsg(8592, handle, cptag); else krmicd.writeMsg(8586, handle, cptag, to_char(cprecid), to_char(cpstamp)); end if; else krmicd.writeMsg(8501, handle, to_char(cprecid), to_char(cpstamp)); end if; end if; end if; copy := copy + 1; end loop; end if; if done then select sysdate-starttime into elapsed from x$dual; dur2time(elapsed, hours, mins, secs); if failoverdone then krmicd.writemsg(8112, krmicd.getChid); end if; if not docopies then m := 8540; elsif processfile then if transontarget then m := 8306; elsif doconvert then m := 8590; end if; end if; if processfile then krmicd.writemsg(m, krmicd.getChid, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); end if; if dpfname is not null then sys.dbms_backup_restore.deleteFile(dpfname); end if; exit; end if; end loop; end if; first_time := TRUE; -- in case we will be deleting what we backed up >>> define bu_validate <<< -- <> sys.dbms_backup_restore.backupStatus(state, setid, stamp, pieceno, files, datafiles, incremental, nochecksum, device); starttime := sysdate; -- -- if (files = 0) then sys.dbms_backup_restore.backupCancel; krmicd.writeMsg(8057, krmicd.getChid); else declare busy_retries number := 0; m number; blkstat sys.dbms_backup_restore.blockStatTable_t; blkRangeTable sys.dbms_backup_restore.blockRangeTable_t; blkRange sys.dbms_backup_restore.blockRange_t; firstcall boolean := TRUE; begin loop exit when not krmicd.validateBlockGetNext( firstcall => firstcall, dfnumber => blkRange.dfnumber, blknumber => blkRange.blknumber, range => blkRange.range); blkRangeTable(blkRangeTable.count + 1) := blkRange; firstcall := FALSE; deb('bu_validate', 'dfnumber = ' || blkRange.dfnumber || ' blknumber = ' || blkRange.blknumber || ' count = ' || blkRange.range); end loop; sys.dbms_backup_restore.validateBlock(blkRangeTable); <> newcorrupt := FALSE; begin sys.dbms_backup_restore.backupValidate( archlog_failover => larchlog_failover, nocleanup => TRUE, compress_set => docompress, nbr_option => nonlogblk); if larchlog_failover then failoverdone := TRUE; end if; sys.dbms_backup_restore.getBlockStat(blkstat); for i in 1..blkstat.count loop krmicd.copyBlockStat( filetype => blkstat(i).filetype ,dfnumber => blkstat(i).dfnumber ,thread => blkstat(i).thread ,sequence => blkstat(i).sequence ,highscn => blkstat(i).highscn ,examined => blkstat(i).examined ,corrupt => blkstat(i).corrupt ,empty => blkstat(i).empty ,data_proc => blkstat(i).data_proc ,data_fail => blkstat(i).data_fail ,index_proc => blkstat(i).index_proc ,index_fail => blkstat(i).index_fail ,other_proc => blkstat(i).other_proc ,other_fail => blkstat(i).other_fail ,nonlogblk => blkstat(i).nonlogblk ,status => blkstat(i).status); if (blkstat(i).data_fail > 0 or blkstat(i).index_fail > 0 or blkstat(i).other_fail > 0) then newcorrupt := TRUE; end if; end loop; sys.dbms_backup_restore.backupCancel(); exception when sys.dbms_backup_restore.snapshot_enqueue_busy then -- -- -- -- if busy_retries = 180 then krmicd.writeMsg(20029, 'cannot make a snapshot controlfile'); raise; end if; busy_retries := busy_retries + 1; -- if (mod(busy_retries, 15) = 0) then krmicd.writeMsg(8512); end if; krmicd.sleep(20); krmicd.clearErrors; goto snapshot; end; end; -- <> select sysdate-starttime into elapsed from x$dual; dur2time(elapsed, hours, mins, secs); if failoverdone then krmicd.writemsg(8112, krmicd.getChid); end if; if validatecmd then m := 8144; elsif not docopies then m := 8540; else if doconvert then m := 8590; else m := 8581; end if; end if; krmicd.writemsg(m, krmicd.getChid, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); krmicd.listBlockStat; if (newcorrupt) then krmicd.setErrState; krmicd.writeMsg(8190); krmicd.writeMsg(8191, sys.dbms_backup_restore.getParm( sys.dbms_backup_restore.TRACE_FILENAME)); end if; end if; >>> define bu_copy <<< -- select sysdate into start_time from x$dual; max_copy := krmicd.getmaxcopyno(set_stamp => set_stamp, set_count => set_count); if piececnt = 0 then krmicd.writeMsg(8105, krmicd.getChid); else if pltfrmfr is NOT NULL then declare pname varchar2(101); begin if nofrpltfrm THEN krmicd.writeMsg(8559, krmicd.getChid); else select platform_name into pname from v$transportable_platform where platform_id = pltfrmfr; krmicd.writeMsg(8558, krmicd.getChid, pname); end if; end; else krmicd.writeMsg(8038, krmicd.getChid, to_char(pieceno), to_char(sysdate)); end if; declare type names is table of varchar2(512) index by binary_integer; copyaux number; fnames names; busy_retries number := 0; lyear varchar2(4); lday varchar2(2); lmonth varchar2(2); lformat names; piecefmt varchar2(512); piececopy number; lcfaudate varchar2(512); cfaudate date; lsequence number; deffmt binary_integer; dest binary_integer := 0; rc binary_integer; rcva_enabled boolean; dummy number; encrypt number := 0; enc_algorithm number := 0; allowTDE number := 0; password varchar2(1025); p3 number; p4 number; t2 varchar2(1); t3 varchar2(1); begin lformat(0) := NULL; -- initalize the format -- -- -- -- -- &lcfaudate& &lsequence& &ncopies& &lformat& cfaudate := to_date(lcfaudate, 'YYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=Gregorian'); select to_char(nvl(cfaudate, sysdate), 'YYYY', 'NLS_CALENDAR=Gregorian'), to_char(nvl(cfaudate, sysdate), 'MM', 'NLS_CALENDAR=Gregorian'), to_char(nvl(cfaudate, sysdate), 'DD', 'NLS_CALENDAR=Gregorian') into lyear, lmonth, lday from x$dual; if lsequence is not NULL and lsequence >=0 and lsequence <=255 and ncopies = 1 then cfauto := TRUE; -- controlfile autobackup piece end if; chtype := krmicd.getDevType; if chtype is null then chtype := 'N/A'; end if; sys.dbms_backup_restore.setLimit(sys.dbms_backup_restore.dupcnt, ncopies); -- -- -- copy := 0; while copy < ncopies loop begin -- piecefmt := lformat(mod(copy, nformat)); skipped := FALSE; if cfauto then krmicd.getFormat(format => piecefmt, copy => copy+1, cfauto => TRUE, deffmt => deffmt, dest => dest); else krmicd.getFormat(format => piecefmt, copy => copy+1, deffmt => deffmt, dest => dest); end if; fnames(copy) := sys.dbms_backup_restore.genPieceName( pno => pieceno, set_count => set_count, set_stamp => set_stamp, format => piecefmt, copyno => copy+max_copy+1, devtype => chtype, year => lyear, month => lmonth, day => lday, dbid => null, -- computed in server if required ndbname => null, -- computed in server if required pdbname => null, -- computed in server if required cfseq => lsequence); -- istmplt := FALSE; if (chtype = 'DISK') then sys.dbms_backup_restore.isfileNameOMF( fname => fnames(copy), isomf => isomf, isasm => isasm, istmplt => istmplt); end if; -- copyaux := 0; while (not istmplt and dest = 0 and copyaux < copy) loop if fnames(copy) = fnames(copyaux) then raise wrong_format; end if; copyaux := copyaux + 1; end loop; -- if (copy > 0) then sys.dbms_backup_restore.backupPieceCrtDupSet(copy, fnames(copy)); end if; end; copy := copy + 1; end loop; -- piececopy := 0; -- start with first copy; <> begin -- -- -- -- -- -- if cfauto then rcva_enabled := is_recovery_area_enabled(); if chtype != 'DISK' or not rcva_enabled or deffmt = 0 then rc := sys.dbms_backup_restore.validateBackupPiece( recid => 0, stamp => 0, handle => fnames(0), set_stamp => set_stamp, set_count => set_count, pieceno => 0, params => NULL, hdl_isdisk => 0); if bitand(rc, sys.dbms_backup_restore.validate_file_different) = 0 then skipped := TRUE; end if; elsif rcva_enabled and deffmt != 0 then -- -- if pisrdf(piececopy) then skipped := TRUE; end if; end if; end if; if (not skipped) then krmicd.writeMsg(8013, krmicd.getChid, pnames(piececopy)); deb('bu_copy', 'get.Params'); if (krmicd.getParams(1, enc_algorithm, allowTDE, p3, p4, password, t2, t3)) then encrypt := 1; else encrypt := 0; enc_algorithm := 0; allowTDE := 0; password := NULL; end if; sys.dbms_backup_restore.backupBackupPiece( bpname => pnames(piececopy), fname => fnames(0), handle => handle, comment => comment, media => media, concur => concur, recid => recid, stamp => stamp, copyno => max_copy, &args_start&, &args_tag&, &args_create&, &args_reuse&, deffmt => deffmt, copy_recid => precid(piececopy), copy_stamp => pstamp(piececopy), npieces => npieces, dest => dest, pltfrmfr => pltfrmfr, ors => FALSE, bpsize => dummy, template_key => NULL, encrypt => encrypt, enc_algorithm => enc_algorithm, allowTDE => allowTDE, password => password); -- copy := 0; while (copy < ncopies) loop if (copy > 0) then -- sys.dbms_backup_restore.backupPieceCrtDupGet( copy, handle, comment, media); end if; if comment is null then comment := 'NONE'; end if; krmicd.writeMsg(8503, handle, comment); copy := copy + 1; end loop; else krmicd.writeMsg(8119, pnames(piececopy)); end if; exception when sys.dbms_backup_restore.retryable_error_exp then piececopy := piececopy + 1; if (piececopy >= piececnt) then raise; end if; krmicd.writeMsg(8110); krmicd.clearErrors; -- clear failover errors goto failover; when in_use then krmicd.writeMsg(8603, pnames(piececopy)); piececopy := piececopy + 1; if (piececopy < piececnt) then krmicd.writeMsg(8110); krmicd.clearErrors; -- clear failover errors goto failover; else krmicd.clearErrors; end if; when del_for_space then krmicd.writeMsg(8604, pnames(piececopy)); piececopy := piececopy + 1; if (piececopy < piececnt) then krmicd.writeMsg(8110); krmicd.clearErrors; -- clear failover errors goto failover; else krmicd.clearErrors; end if; when dropped_pdb_file then krmicd.writeMsg(6826, pnames(piececopy)); piececopy := piececopy + 1; krmicd.clearErrors; end; if ncopies = 1 then krmicd.writeMsg(8044, krmicd.getChid, to_char(pieceno), to_char(sysdate)); else krmicd.writeMsg(8045, krmicd.getChid, to_char(pieceno), to_char(sysdate), to_char(ncopies)); end if; select sysdate-start_time into elapsed from x$dual; dur2time(elapsed, hours, mins, secs); krmicd.writemsg(8556, krmicd.getChid, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); end; end if; >>> define copyfil_xfer <<< -- lformat(0) := NULL; -- -- -- &lformat& -- -- if (lformat(0) is null) then raise cpfil_unsupported; end if; worked := sys.dbms_backup_restore.networkFileTransfer( dbname => netalias, username => null, passwd => null, srcfile => src_name, destfile => lformat(0), operation => 'read'); >>> define budc_begin_del <<< -- declare copy_recid number; copy_stamp number; fname varchar2(1024); dfnumber number; resetlogs_change number; creation_change number; checkpoint_change number; blksize number; no_delete binary_integer; begin >>> define budc_del <<< -- &object& del_copy(copy_recid, copy_stamp, fname, dfnumber, resetlogs_change, creation_change, checkpoint_change, blksize, no_delete); >>> define budc_end_del <<< -- end; >>> define bual_begin_del <<< -- declare cfisstby boolean := FALSE; arch_recid number; arch_stamp number; fname varchar2(512); thread number; sequence number; resetlogs_change number; resetlogs_time varchar2(512); first_change number; blksize number; next_change number; first_time boolean := TRUE; docopies boolean := FALSE; reqscn number; -- streams/standby required scn rlgscn number; -- streams/standby resetlogs scn appscn number; apprlgscn number; alldest number := 0; reqbackups number; nbackups number; begin >>> define bual_del <<< -- &object& del_log(cfisstby, arch_recid, arch_stamp, fname, thread, sequence, resetlogs_change, resetlogs_time, first_change, blksize, next_change, first_time, docopies, reqscn, rlgscn, appscn, apprlgscn, alldest, reqbackups, nbackups); >>> define bual_end_del <<< -- end; >>> define bubp_begin_del <<< -- declare skipped boolean := FALSE; -- skipped this backuppiece handle varchar2(1024); recid number; stamp number; begin >>> define bubp_del <<< -- &object& -- -- -- -- -- -- if ((not skipped) or (krmicd.getDevType != 'DISK')) then sys.dbms_backup_restore.changeBackupPiece( handle => handle, recid => recid, stamp => stamp, status => 'S', &args& ); krmicd.writeMsg(8073); krmicd.writeMsg(8517, handle, to_char(recid), to_char(stamp)); end if; >>> define bubp_end_del <<< -- end; >>> define bu_end <<< -- if (endBackupJobStep(FALSE, 0)) then null; end if; sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0); exception when others then if (not endBackupJobStep(TRUE, sqlcode)) then raise; end if; sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0); end; >>> define switch_prim_bct <<< begin sys.dbms_backup_restore.switch_primary_bct(); end; >>> define restoredfc <<< -- declare recid number; stamp number; copy_recid number; copy_stamp number; dfnumber number; old_dfnumber number; fname varchar2(512) := null; -- restore dest max_corrupt number := 0; full_name varchar2(512); -- output filename copy varchar2(512); -- input filename check_logical boolean := false; byduplicate boolean := false; preplugin boolean := false; pdbid number; pplcdbdbid number; blksize number := 0; blocks number := 0; rfno number := 0; lowscn varchar2(41) := null; identical boolean := FALSE; force boolean := FALSE; rsid number; rsts number; tsname varchar2(512) := null; found boolean; inst_restore number := 0; sparse_restore number := 0; begin &object& found := krmicd.valGetFound(copy_recid, copy_stamp); sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); krmicd.writeMsg(8019, krmicd.getChid, to_char(dfnumber, 'FM09999')); krmicd.writeMsg(8507, to_char(copy_recid), to_char(copy_stamp), copy); if fname is not null then krmicd.writeMsg(8509, to_char(dfnumber, 'FM09999'), fname); if (identical and force) then -- -- -- krmicd.writeMsg(8552, fname); return; end if; end if; begin if byduplicate and copy is not null and fname is not null then sys.dbms_backup_restore.resDataFileCopy( cname => copy, fname => fname, full_name => full_name, max_corrupt => max_corrupt, check_logical => check_logical, blksize => blksize, blocks => blocks, fno => dfnumber, scnstr => lowscn, rfno => rfno, tsname => tsname, sparse_restore => sparse_restore); krmicd.writeMsg(8007, krmicd.getChid, to_char(dfnumber, 'FM09999')); krmicd.writeMsg(8505, full_name); elsif preplugin then sys.dbms_backup_restore.copyDataFileCopy( full_name => full_name, cname => copy, fno => dfnumber, oldfno => old_dfnumber, rfno => rfno, blksize => blksize, blocks => blocks, fname => fname, max_corrupt => max_corrupt, check_logical => check_logical, inst_restore => inst_restore, preplugin => true, sparse_restore => sparse_restore); krmicd.writeMsg(8007, krmicd.getChid, to_char(dfnumber, 'FM09999')); krmicd.writeMsg(8505, full_name); else sys.dbms_backup_restore.copyDataFileCopy( full_name => full_name, recid => recid, stamp => stamp, fname => fname, copy_recid => copy_recid, copy_stamp => copy_stamp, max_corrupt => max_corrupt, check_logical => check_logical, inst_restore => inst_restore, sparse_restore => sparse_restore); krmicd.writeMsg(8007, krmicd.getChid, to_char(dfnumber, 'FM09999')); krmicd.writeMsg(8501, full_name, to_char(recid),to_char(stamp)); end if; krmicd.fileRestored(ftype => rman_constant.DATAFILE, fno => dfnumber, thread => 0, sequence => 0, resetscn => 0, resetstamp => 0, fname => full_name); exception when sys.dbms_backup_restore.retryable_error_exp then if not krmicd.doRestoreFailover(rman_constant.DATAFILE) then raise; end if; -- krmicd.writeErrMsg(1005, sqlerrm); krmicd.clearErrors; when others then raise; end; end; >>> define restorecfc <<< -- declare src_name varchar2(512); dest_name varchar2(512); full_name varchar2(512); recid number; stamp number; currcf boolean; identical boolean := FALSE; force boolean := FALSE; rsid number; rsts number; isstby boolean := FALSE; nocfconv boolean := FALSE; isfarsync boolean := FALSE; begin &object& sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); krmicd.writeMsg(8021, krmicd.getChid); if (not currcf) then krmicd.writeMsg(8505, dest_name); end if; if (identical and force) then -- -- -- krmicd.writeMsg(8552, dest_name); return; end if; begin sys.dbms_backup_restore.copyControlFile(full_name => full_name, recid => recid, stamp => stamp, src_name => src_name, dest_name => dest_name); krmicd.writeMsg(8025, krmicd.getChid); krmicd.writeMsg(8506, src_name); if (currcf) then print_controlfile; else krmicd.writeMsg(8501, full_name, to_char(recid), to_char(stamp)); end if; krmicd.fileRestored(ftype => rman_constant.CONTROLFILE, fno => 0, thread => 0, sequence => 0, resetscn => 0, resetstamp => 0); exception when sys.dbms_backup_restore.retryable_error_exp then if not krmicd.doRestoreFailover(rman_constant.CONTROLFILE) then raise; end if; -- krmicd.writeErrMsg(1005, sqlerrm); krmicd.clearErrors; when others then raise; end; sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0); end; >>> define rsdf_start <<< -- declare /* restoreStatus */ state binary_integer; pieces_done binary_integer; files binary_integer; datafiles boolean; incremental boolean; device boolean; /* restorebackuppiece */ done boolean; currcf boolean; fhandle varchar2(512); handle varchar2(512); outhandle varchar2(512); params varchar2(512); fromdisk boolean; -- TRUE => backupset on disk /* Miscellaneous */ memnum number; piecenum number; dfnumber number; thread number := null; sequence number := null; toname varchar2(512); tsname varchar2(512); cfname varchar2(512); pfname varchar2(512); sfname varchar2(512); set_count number; set_stamp number; first_time boolean := TRUE; validate boolean := FALSE; -- TRUE => only validate val_bs_only boolean := FALSE; -- TRUE => only bs validation -- max_corrupt binary_integer := 0; check_logical boolean := FALSE; tag varchar2(31); outtag varchar2(31); bmr boolean := FALSE; blocks number; blksize number; failover boolean := FALSE; devtype varchar2(512); rsid number; rsts number; err_msg varchar2(2048); start_time date; recid number; stamp number; preview boolean := FALSE; recall boolean := FALSE; isstby boolean := FALSE; nocfconv boolean := FALSE; msrpno number := 0; msrpct number := 0; isfarsync boolean := FALSE; networkfdf boolean := FALSE; sameend boolean := TRUE; preplugin boolean := FALSE; pdbid number; pplcdbdbid number; ppltrans number; old_dfnumber number; sparse_restore number := 0; encdec_restore number := 0; restore_not_complete exception; begin &1& -- if preview then deb('rsdf_start', 'preview'); return; end if; if (preplugin) then ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation( pdbid => pdbid, pplcdbdbid => pplcdbdbid); end if; sys.dbms_backup_restore.restoreStatus(state, pieces_done, files, datafiles, incremental, device); if (msrpno > 1) then -- -- -- -- pieces_done := msrpno - 1; end if; select sysdate into start_time from x$dual; if state = sys.dbms_backup_restore.restore_no_conversation then goto start_convo; elsif state = sys.dbms_backup_restore.restore_naming_files then goto name_files; else goto restore_piece; end if; <> sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); sys.dbms_backup_restore.restoreSetDataFile( check_logical => check_logical ,cleanup => FALSE ,service => NULL ,chunksize => 0 ,rs_flags => 0 ,preplugin => preplugin ,sparse_restore => sparse_restore ,encdec_restore => encdec_restore); incremental := FALSE; if bmr then krmicd.writeMsg(8106, krmicd.getChid); elsif validate then krmicd.writeMsg(8096, krmicd.getChid); else krmicd.writeMsg(8016, krmicd.getChid); end if; setRestoreParams; <> deb('rsdf_start', 'set_stamp=' || set_stamp || ' set_count=' || set_count, rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN); >>> define ridf_start <<< -- declare /* restoreStatus */ state binary_integer; pieces_done binary_integer; files binary_integer; datafiles boolean; incremental boolean; device boolean; /* restorebackuppiece */ done boolean; currcf boolean; fhandle varchar2(512); handle varchar2(512); outhandle varchar2(512); params varchar2(512); fromdisk boolean; -- TRUE => backupset on disk /* Miscellaneous */ memnum number; piecenum number; dfnumber number; thread number := null; sequence number := null; toname varchar2(512); cfname varchar2(512); fuzzy_hint number; set_count number; set_stamp number; first_time boolean := TRUE; validate boolean := FALSE; val_bs_only boolean := FALSE; -- TRUE => only bs validation -- max_corrupt binary_integer := 0; check_logical boolean := FALSE; tag varchar2(31); outtag varchar2(31); bmr boolean := FALSE; blocks number; blksize number; failover boolean := FALSE; devtype varchar2(512); rcvcopy boolean := FALSE; islevel0 binary_integer := 0; rsid number; rsts number; err_msg varchar2(2048); start_time date; recid number; stamp number; preview boolean := FALSE; recall boolean := FALSE; isstby boolean := FALSE; nocfconv boolean := FALSE; msrpno number := 0; msrpct number := 0; isfarsync boolean := FALSE; preplugin boolean := FALSE; pdbid number := 0; pplcdbdbid number := 0; ppltrans number; old_dfnumber number; restore_not_complete exception; begin &1& -- if preview then deb('ridf_start', 'preview'); return; end if; sys.dbms_backup_restore.restoreStatus(state, pieces_done, files, datafiles, incremental, device); if (msrpno > 1) then -- -- -- -- pieces_done := msrpno - 1; end if; select sysdate into start_time from x$dual; if state = sys.dbms_backup_restore.restore_no_conversation then goto start_convo; elsif state = sys.dbms_backup_restore.restore_naming_files then goto name_files; else goto restore_piece; end if; <> sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); sys.dbms_backup_restore.applySetDatafile( check_logical => check_logical ,cleanup => FALSE ,service => NULL ,chunksize => 0 ,rs_flags => 0 ,preplugin => preplugin); incremental := TRUE; krmicd.writeMsg(8039, krmicd.getChid); setRestoreParams; <> deb('ridf_start', 'set_stamp=' || set_stamp || ' set_count=' || set_count, rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN); >>> define rsdf_name <<< -- toname := null; max_corrupt := 0; &memnum& &object& if msrpno > 1 and not bmr then declare tempfno number; begin krmicd.getMSR(tempfno, toname); end; end if; if files < memnum then sys.dbms_backup_restore.restoreDataFileTo( dfnumber => dfnumber, toname => toname, max_corrupt => max_corrupt, tsname => tsname, old_dfnumber => old_dfnumber); if msrpno = 1 and not bmr then sys.dbms_backup_restore.initMSR(dfnumber, toname); end if; if msrpno > 0 then krmicd.setMSR(dfnumber, toname); end if; if first_time then if bmr then krmicd.writeMsg(8108, krmicd.getChid); else krmicd.writeMsg(8089, krmicd.getChid); end if; first_time := FALSE; end if; if bmr then krmicd.writeMsg(8533, to_char(dfnumber, 'FM09999')); else if toname is not null then krmicd.writeMsg(8610, krmicd.getChid, to_char(dfnumber, 'FM09999'), toname); else krmicd.writeMsg(8610, krmicd.getChid, to_char(dfnumber, 'FM09999'), 'default location'); end if; deb('rsdf_name', 'blocks=' || blocks || ' block_size=' || blksize, rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN); end if; if (msrpno > 0) then krmicd.writeMsg(8555, krmicd.getChid, to_char(msrpno), to_char(msrpct)); end if; end if; >>> define ridf_name <<< -- toname := null; max_corrupt := 0; &memnum& &object& if msrpno > 1 and not bmr then declare tempfno number; begin krmicd.getMSR(tempfno, toname); end; end if; if files < memnum then sys.dbms_backup_restore.applyDataFileTo( dfnumber => dfnumber, toname => toname, fuzziness_hint => fuzzy_hint, max_corrupt => max_corrupt, islevel0 => islevel0, recid => recid, stamp => stamp, old_dfnumber => old_dfnumber); if msrpno = 1 and not bmr then sys.dbms_backup_restore.initMSR(dfnumber, toname); end if; if msrpno > 0 then krmicd.setMSR(dfnumber, toname); end if; if first_time then if bmr then krmicd.writeMsg(8108, krmicd.getChid); elsif rcvcopy then krmicd.writeMsg(8131, krmicd.getChid); else krmicd.writeMsg(8089, krmicd.getChid); end if; first_time := FALSE; end if; if bmr then krmicd.writeMsg(8533, to_char(dfnumber, 'FM09999')); elsif toname is not null then if rcvcopy then krmicd.writeMsg(8551, to_char(dfnumber, 'FM09999'), toname); else krmicd.writeMsg(8509, to_char(dfnumber, 'FM09999'), toname); end if; deb('ridf_name', 'blocks=' || blocks || ' block_size=' || blksize, rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN); end if; if (msrpno > 0) then krmicd.writeMsg(8555, krmicd.getChid, to_char(msrpno), to_char(msrpct)); end if; end if; >>> define rscf_name <<< -- &object& &memnum& if files < memnum then sys.dbms_backup_restore.restoreControlfileTo(cfname => cfname, isstby => isstby, nocfconv => nocfconv, isfarsync => isfarsync); krmicd.writeMsg(8021, krmicd.getChid); if (not currcf) then krmicd.writeMsg(8505, cfname); end if; end if; >>> define rssf_name <<< -- &object& &memnum& if files < memnum then sys.dbms_backup_restore.restoreSpfileTo(pfname => pfname, sfname => sfname); if pfname is not null then krmicd.writeMsg(8114, krmicd.getChid); krmicd.writeMsg(8505, pfname); elsif sfname is not null then krmicd.writeMsg(8115, krmicd.getChid); krmicd.writeMsg(8505, sfname); else krmicd.writeMsg(8115, krmicd.getChid); krmicd.writeMsg(8116); end if; end if; >>> define restore_piece_label <<< -- <> >>> define rspiece_init <<< -- fhandle := NULL; &piecenum& >>> define rspiece_name <<< -- &object& -- handle, tag, fromdisk, recid, stamp if (pieces_done+1) = piecenum then sys.dbms_backup_restore.restoreSetPiece(handle => handle, tag => tag, fromdisk => fromdisk, recid => recid, stamp => stamp); if fhandle is NULL then fhandle := handle; end if; end if; >>> define 'x$print_controlfile' <<< procedure print_controlfile is src_name varchar2(512); dest_name varchar2(512); begin for i in 1..9999 loop dest_name := sys.dbms_backup_restore.getparm( sys.dbms_backup_restore.control_file, i); exit when dest_name is null; krmicd.writeMsg(8505, dest_name); end loop; end; >>> define 'x$restore_piece' <<< function restore_piece_int(pieces_done IN OUT binary_integer ,piecenum IN number ,fhandle IN varchar2 ,done OUT boolean ,params IN varchar2 ,outhandle OUT varchar2 ,outtag OUT varchar2 ,failover OUT boolean ,err_msg OUT varchar2 ,val_bs_only IN boolean ,validate IN boolean ,devtype OUT varchar2 ,bmr IN boolean ,set_stamp IN number ,set_count IN number ,start_time IN date ,incremental IN boolean ,currcf IN boolean ,ppltrans IN number) return boolean is elapsed number; hours number; mins number; secs number; begin -- if (pieces_done+1) = piecenum then begin if (fhandle is not NULL) then krmicd.writeMsg(8003, krmicd.getChid, fhandle); end if; sys.dbms_backup_restore.restoreBackupPiece(done => done, params => params, outhandle => outhandle, outtag => outtag, failover => failover); exception when sys.dbms_backup_restore.retryable_error_exp then err_msg := sqlerrm; if not krmicd.doRestoreFailover(rman_constant.BACKUPPIECE) then raise; end if; -- -- -- if (val_bs_only) then raise; end if; if (not validate) then getFileRestored(FALSE); end if; devtype := krmicd.checkBsFailover; if (incremental and devtype is null) then raise; end if; -- krmicd.writeErrMsg(8615, krmicd.getChid||': '||err_msg); krmicd.clearErrors; if (devtype is not null) then krmicd.writeMsg(8612, krmicd.getChid, devtype); end if; return true; when others then raise; end; if failover then krmicd.writeMsg(8614, krmicd.getChid, fhandle); krmicd.writeMsg(8613, krmicd.getChid, outhandle, nvl(outtag, 'NULL')); else krmicd.writeMsg(8611, krmicd.getChid, outhandle, nvl(outtag, 'NULL')); end if; if bmr then krmicd.writeMsg(8109, krmicd.getChid, to_char(piecenum)); else krmicd.writeMsg(8023, krmicd.getChid, to_char(piecenum)); krmicd.writeIOs(set_stamp, set_count); end if; if done then select abs(sysdate-start_time) into elapsed from x$dual; dur2time(elapsed, hours, mins, secs); if (bmr) then krmicd.writeMsg(8183, krmicd.getChid, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); elsif (validate) then krmicd.writeMsg(8182, krmicd.getChid, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); else krmicd.writeMsg(8180, krmicd.getChid, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); end if; -- if currcf then print_controlfile; end if; if validate then -- validate backupset, restore validate cmds krmicd.fileRestored(ftype => rman_constant.BACKUPPIECE, fno => 0, thread => 0, sequence => 0, resetscn => 0, resetstamp => 0); else getFileRestored(FALSE); end if; if (ppltrans > 0) then sys.dbms_backup_restore.endPrePluginTranslation; end if; sys.dbms_backup_restore.restoreCancel(TRUE); return false; end if; pieces_done := pieces_done + 1; end if; return false; end; >>> define restore_piece <<< if (restore_piece_int(pieces_done, piecenum, fhandle, done, params, outhandle, outtag, failover, err_msg, val_bs_only, validate, devtype, bmr, set_stamp, set_count, start_time, incremental, currcf, ppltrans)) then goto restore_failover; end if; if done then return; end if; >>> define restore_end <<< -- krmicd.writeMsg(8001); if not krmicd.doRestoreFailover(rman_constant.BACKUPPIECE) then begin sys.dbms_backup_restore.restoreCancel(FALSE); exception when others then krmicd.writeMsg(1005, 'a. dbms_backup_restore.restoreCancel() failed'); end; if (ppltrans > 0) then sys.dbms_backup_restore.endPrePluginTranslation; end if; raise restore_not_complete; end if; -- -- -- -- if (not validate) then getFileRestored(FALSE); end if; devtype := krmicd.checkBsFailover; if (incremental and devtype is null) then begin sys.dbms_backup_restore.restoreCancel(TRUE); exception when others then krmicd.writeMsg(1005, 'b. dbms_backup_restore.restoreCancel() failed'); end; if (ppltrans > 0) then sys.dbms_backup_restore.endPrePluginTranslation; end if; end if; if (dfnumber is not null) then krmicd.writeMsg(1005, 'Restore did not complete for some' || ' files from backup piece ' || outhandle || ' (piecenum=' || to_char(piecenum) || ', pieces_done=' || to_char(pieces_done) || ', done=' || bool2char(done) || ', failover=' || bool2char(failover) || ')'); else krmicd.writeMsg(1005, 'Restore did not complete for some' || ' archived logs from backup piece ' || outhandle || ' (piecenum=' || to_char(piecenum) || ', pieces_done=' || to_char(pieces_done) || ', done=' || bool2char(done) || ', failover=' || bool2char(failover) || ')'); end if; krmicd.writeMsg(1005, 'Please check alert log for ' || 'additional information.'); if (devtype is not null) then krmicd.writeMsg(8612, krmicd.getChid, devtype); end if; -- <> begin sys.dbms_backup_restore.restoreCancel(FALSE); exception when others then krmicd.writeMsg(1005, 'c. dbms_backup_restore.restoreCancel() failed'); end; if (ppltrans > 0) then sys.dbms_backup_restore.endPrePluginTranslation; end if; sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0); end; >>> define msr_finish <<< -- declare dfnumber number; msrfname varchar2(1024); begin krmicd.getMSR(dfnumber, msrfname); sys.dbms_backup_restore.setParms(p0 => 5, p1 => dfnumber, p5 => msrfname); end; >>> define msc_finish <<< -- declare mscfname varchar2(1024); begin krmicd.getMSC(mscfname); sys.dbms_backup_restore.setParms(p0 => 9, p5 => mscfname); end; >>> define rsal_start <<< -- declare /* restoreStatus */ state binary_integer; pieces_done binary_integer; files binary_integer; datafiles boolean; incremental boolean; device boolean; /* restorebackuppiece */ done boolean; currcf boolean; -- unused here cfname varchar2(512); fhandle varchar2(512); handle varchar2(512); outhandle varchar2(512); params varchar2(512); fromdisk boolean; -- TRUE => backupset on disk /* Miscellaneous */ memnum number; piecenum number; dfnumber number := null; thread number; sequence number; destination varchar2(512) := null; validate boolean := FALSE; val_bs_only boolean := FALSE; -- TRUE => only bs validation -- tag varchar2(31); outtag varchar2(31); bmr boolean := FALSE; set_count number; set_stamp number; failover boolean := FALSE; devtype varchar2(512); rsid number; rsts number; err_msg varchar2(2048); start_time date; recid number; stamp number; savepiecename boolean := FALSE; transontarget boolean := FALSE; preview boolean := FALSE; recall boolean := FALSE; isstby boolean := FALSE; nocfconv boolean := FALSE; preplugin boolean := FALSE; pdbid number := 0; pplcdbdbid number := 0; ppltrans number; isfarsync boolean := FALSE; restore_not_complete exception; log_included exception; pragma exception_init(log_included, -19636); begin &1& -- if preview then deb('rsal_start', 'preview'); return; end if; if (preplugin) then ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation( pdbid => pdbid, pplcdbdbid => pplcdbdbid); end if; sys.dbms_backup_restore.restoreStatus(state, pieces_done, files, datafiles, incremental, device); select sysdate into start_time from x$dual; if state = sys.dbms_backup_restore.restore_no_conversation then goto start_convo; elsif state = sys.dbms_backup_restore.restore_naming_files then goto name_files; else goto restore_piece; end if; <> &object& sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); sys.dbms_backup_restore.restoreSetArchivedLog( destination => destination ,cleanup => FALSE ,service => NULL ,preplugin => preplugin); incremental := FALSE; if validate then krmicd.writeMsg(8097, krmicd.getChid); elsif destination is null then krmicd.writeMsg(8017, krmicd.getChid); else krmicd.writeMsg(8018, krmicd.getChid); krmicd.writeMsg(8508, destination); end if; setRestoreParams; <> deb('rsal_start', 'set_stamp=' || set_stamp || ' set_count=' || set_count, rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN); >>> define rsal_name <<< -- &memnum& &object& if files < memnum then begin sys.dbms_backup_restore.restoreArchivedLog(thread => thread, sequence => sequence); krmicd.writeMsg(8022, krmicd.getChid); krmicd.writeMsg(8510, to_char(thread), to_char(sequence)); %IF% target exception -- -- -- when log_included then null; %ENDIF% target end; end if; >>> define 'switch' <<< -- declare copy_recid number; copy_stamp number; catalog boolean; dfnumber number; fname varchar2(512); begin &object& sys.dbms_backup_restore.switchToCopy(copy_recid => copy_recid ,copy_stamp => copy_stamp ,catalog => catalog); krmicd.writeMsg(8015, to_char(dfnumber)); krmicd.writeMsg(8507, to_char(copy_recid), to_char(copy_stamp), fname); end; >>> define tdb_gtsc <<< -- /* This is to generate the transport script */ declare tscname varchar2(512); pfformat varchar2(512); rmtscname varchar2(512); pfname varchar2(512); newtscname varchar2(512); newrmtscname varchar2(512); begin &tscname& &pfformat& &rmtscname& sys.dbms_backup_restore.genTransportScript(tscname, pfformat, rmtscname, pfname, newtscname, newrmtscname, &args&); krmicd.writeMsg(8301, pfname); if rmtscname is not null then krmicd.writeMsg(8302, newrmtscname); end if; if tscname is not null then krmicd.writeMsg(8300, newtscname); end if; end; >>> define tdb_lock <<< /* This is to lock transportable db context */ declare newdbname varchar2(10); begin &newdbname& sys.dbms_backup_restore.TransportDBLock(newdbname); end; >>> define tdb_unlock <<< /* This is to unlock transportable db context */ begin sys.dbms_backup_restore.TransportDBUnlock; krmicd.writeMsg(8303); krmicd.writeMsg(8304); end; >>> define 'sql' <<< -- begin krmicd.execSql(&args&); end; >>> define testkrm <<< begin krmicd.writeMsg(1005, null); end; >>> define 'smr1' <<< -- declare mr_cancelled exception; pragma exception_init(mr_cancelled, -283); mr_need_log exception; pragma exception_init(mr_need_log, -279); mr_not_needed exception; pragma exception_init(mr_not_needed, -264); bmr_block_errors exception; pragma exception_init(bmr_block_errors, -19680); thread number; sequence number; scn number; dellog binary_integer; recid binary_integer; stamp binary_integer; seq binary_integer; resetlogs_change number; first_change number; blksize binary_integer; logname varchar2(512); stopthd number; stopseq number; toclause boolean; -- TRUE = TO CLAUSE; FALSE = TO BEFORE CLAUSE bmr boolean := FALSE; rls number; -- resetlogs scn for required log rlc number; -- resetlogs count for required log flash boolean := FALSE; pdbpitr boolean := FALSE; stoprcv boolean; start_time date; elapsed number; hours number; mins number; secs number; nonlogblk boolean := FALSE; con_id number := sys_context('userenv', 'con_id'); app_root varchar2(3) := sys_context('userenv', 'is_application_root'); internal_error exception; preplugin boolean := FALSE; pdbid number; pplpdbid number; pplcdbdbid number; unplugSCN number; file# number; old_file# number; firstcall binary_integer; pragma exception_init(internal_error, -600); begin begin &object& select sysdate into start_time from x$dual; if (nonlogblk) then krmicd.writeMsg(8241); -- starting NBR recovery else krmicd.writeMsg(8054); -- starting media recovery end if; if preplugin then sys.dbms_backup_restore.prePluginRecoveryStart( pdbid => pdbid ,pplpdbid => pplpdbid ,pplcdbdbid => pplcdbdbid ,unplugSCN => unplugSCN); firstcall := 1; loop exit when not krmicd.recoverFileGetNext(firstcall, file#, old_file#); firstcall := 0; deb('smr1', 'file# = ' || file# || ' ,old_file# = ' || old_file#); sys.dbms_backup_restore.prePluginRecoveryAddFile(file#, old_file#); end loop; elsif (not bmr and not flash) then if (con_id <= 1) then krmicd.execSQL('alter database recover datafile list clear'); elsif (app_root = 'YES') then krmicd.execSQL('alter database recover datafile root'); end if; end if; >>> define 'smr2' <<< -- if (con_id > 1) then raise internal_error; end if; krmicd.execSql('alter database recover datafile list' || '&args&'); >>> define 'smr3' <<< -- if bmr then sys.dbms_backup_restore.bmrDoMediaRecovery(NULL); begin sys.dbms_backup_restore.bmrCancel; exception when bmr_block_errors then krmicd.writeMsg(8111); end; elsif flash then begin sys.dbms_backup_restore.flashbackFiles(NULL); krmicd.checkSetDatabase; exception when others then krmicd.checkSetDatabase; raise; end; sys.dbms_backup_restore.flashbackCancel; krmicd.checkSetDatabase; elsif pdbpitr then sys.dbms_backup_restore.recoverDo(NULL); sys.dbms_backup_restore.recoverCancel; elsif nonlogblk then declare blkstat sys.dbms_backup_restore.blockStatTable_t; firstcall boolean := TRUE; lastcall boolean := FALSE; files binary_integer; begin sys.dbms_backup_restore.NbrFileStatus(files); if (files = 0) then sys.dbms_backup_restore.nbrCancel; krmicd.writeMsg(8057, krmicd.getChid); else sys.dbms_backup_restore.nbrDoMediaRecovery(NULL); sys.dbms_backup_restore.getNbrBlockStat(blkstat); listNbrBlockStat(blkstat); end if; end; elsif preplugin then sys.dbms_backup_restore.prePluginDoMediaRecovery(NULL); sys.dbms_backup_restore.prePluginRecoveryCancel; else krmicd.execSql('alter database recover' || '&args&'); end if; select abs(sysdate-start_time) into elapsed from x$dual; dur2time(elapsed, hours, mins, secs); -- if (nonlogblk) then krmicd.writeMsg(8242, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); -- else krmicd.writeMsg(8181, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); end if; return; exception when mr_cancelled then krmicd.writeMsg(8059); raise; when mr_need_log then krmicd.clearErrors; when mr_not_needed then krmicd.clearErrors; select abs(sysdate-start_time) into elapsed from x$dual; dur2time(elapsed, hours, mins, secs); -- if (nonlogblk) then krmicd.writeMsg(8242, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); -- else krmicd.writeMsg(8181, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); end if; return; when others then krmicd.writeMsg(8059); raise; end; toclause := krmicd.checkUntil(stopthd, stopseq); select resetlogs_change# into resetlogs_change from v$database_incarnation where status='CURRENT'; select thr, seq, scn, rls, rlc into thread, sequence, scn, rls, rlc from x$kcrmx; if (resetlogs_change = rls and stopthd = thread and ((sequence >= stopseq and toclause = FALSE) OR (sequence > stopseq and toclause = TRUE))) then if bmr then begin sys.dbms_backup_restore.bmrCancel; exception when bmr_block_errors then krmicd.writeMsg(8111); end; elsif flash then sys.dbms_backup_restore.flashbackCancel; krmicd.checkSetDatabase; elsif pdbpitr then sys.dbms_backup_restore.recoverCancel; elsif nonlogblk then sys.dbms_backup_restore.nbrCancel; elsif preplugin then sys.dbms_backup_restore.prePluginRecoveryCancel; else krmicd.execSql('alter database recover cancel'); end if; select abs(sysdate-start_time) into elapsed from x$dual; dur2time(elapsed, hours, mins, secs); -- if (nonlogblk) then krmicd.writeMsg(8242, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); -- else krmicd.writeMsg(8181, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); end if; return; end if; end; >>> define 'log_apply1' <<< -- declare mr_cancelled exception; pragma exception_init(mr_cancelled, -283); -- mr_cont_rcv exception; pragma exception_init(mr_cont_rcv, -288); mr_need_log exception; pragma exception_init(mr_need_log, -279); mr_aborted exception; pragma exception_init(mr_aborted, -20500); bmr_block_errors exception; pragma exception_init(bmr_block_errors, -19680); mr_createdf exception; pragma exception_init(mr_createdf, -20505); archivelog_missing_exception exception; pragma exception_init(archivelog_missing_exception, -20515); archivelog_backup_not_found exception; pragma exception_init(archivelog_backup_not_found, -20506); alfrec v$archived_log%ROWTYPE; dellog boolean := FALSE; -- set by rman compiler deltarget boolean := FALSE; -- set by rman compiler bmr boolean := FALSE; -- set by rman compiler flash boolean := FALSE; -- set by rman compiler pdbpitr boolean := FALSE; -- set by rman compiler untilcancel boolean := FALSE; -- set by rman compiler preplugin boolean := FALSE; -- set by rman compiler scn number; stopthd number; stopseq number; stoprcv boolean; rlc number; -- resetlogs count resetlogs_change number; -- resetlogs SCN used when untilLog is set start_time date; elapsed number; hours number; mins number; secs number; pstandby number; -- unnamed varchar2(1024); dfname varchar2(1024); newdfname varchar2(1024); fileno number := 0; recovdf boolean := false; filelist varchar2(512):=NULL; tmp number:=0; toclause boolean; tsnum number; tsname varchar2(32); pdbname varchar2(128); bnewomf boolean; dropf boolean; createdf boolean := false; type numTab_t is table of number index by binary_integer; df_offln_list numTab_t; con_id number := sys_context('userenv', 'con_id'); internal_error exception; pragma exception_init(internal_error, -600); function continue_rcv(createdf OUT boolean) return boolean is begin createdf := false; <> begin krmicd.clearErrors; krmicd.execSql('alter database recover continue'); exception when mr_cont_rcv then goto do_cont_again; when mr_need_log then return true; when mr_createdf then createdf := true; return true; end; return false; end; begin &object& toclause := krmicd.checkUntil(stopthd, stopseq); select count(*) into pstandby from V$DATABASE where database_role='PHYSICAL STANDBY'; <> -- recovery is never restarted for bmr begin select sysdate into start_time from x$dual; -- -- -- -- -- if not bmr and not flash and not pdbpitr and recovdf then deb('apply_log', 're-start recovery'); krmicd.execSQL('alter database recover datafile list clear'); if filelist is not null then krmicd.execSql('alter database recover datafile list ' || filelist); end if; >>> define 'log_apply3' <<< krmicd.execSql('alter database recover' || '&args&'); fileno := 0; recovdf := false; end if; exception when mr_need_log then krmicd.clearErrors; end; -- <> if createdf then createdf := false; raise mr_createdf; end if; begin select thr, seq, scn, rls, rlc into alfrec.thread#, alfrec.sequence#, scn, alfrec.resetlogs_change#, rlc from x$kcrmx; exception when no_data_found then if bmr then begin sys.dbms_backup_restore.bmrCancel; exception when bmr_block_errors then krmicd.writeMsg(8111); end; elsif flash then sys.dbms_backup_restore.flashbackCancel; krmicd.checkSetDatabase; elsif pdbpitr then sys.dbms_backup_restore.recoverCancel; elsif preplugin then sys.dbms_backup_restore.prePluginRecoveryCancel; end if; -- -- -- -- -- -- -- -- -- delete_logs(FALSE, dellog, deltarget, preplugin); return; end; select resetlogs_change# into resetlogs_change from v$database_incarnation where status='CURRENT'; if (resetlogs_change=alfrec.resetlogs_change# and stopthd = alfrec.thread# and alfrec.sequence# >= stopseq) then stoprcv := FALSE; if bmr then begin sys.dbms_backup_restore.bmrCancel; exception when bmr_block_errors then krmicd.writeMsg(8111); end; stoprcv := TRUE; elsif flash then -- -- if alfrec.sequence# > stopseq then sys.dbms_backup_restore.flashbackCancel; krmicd.checkSetDatabase; stoprcv := TRUE; end if; elsif pdbpitr then sys.dbms_backup_restore.recoverCancel; stoprcv := TRUE; elsif preplugin then sys.dbms_backup_restore.prePluginRecoveryCancel; stoprcv := TRUE; else krmicd.execSql('alter database recover cancel'); stoprcv := TRUE; end if; if stoprcv then -- -- -- -- -- -- delete_logs(FALSE, dellog, deltarget, preplugin); select abs(sysdate-start_time) into elapsed from x$dual; dur2time(elapsed, hours, mins, secs); -- krmicd.writeMsg(8181, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); return; end if; end if; begin deb('log_apply', 'looking for log with scn ' ||scn||' thread='|| alfrec.thread#||' sequence='||alfrec.sequence# ||' resetlogs scn '|| alfrec.resetlogs_change#||' resetlogs time='|| to_char(stamp2date(rlc))); begin -- alfrec.name := krmicd.checkLog(scn, alfrec.thread#, alfrec.sequence#, alfrec.recid, alfrec.stamp, alfrec.resetlogs_change#, stamp2date(rlc), alfrec.first_change#, alfrec.next_change#, alfrec.block_size, preplugin); exception when archivelog_backup_not_found or archivelog_missing_exception then if (untilcancel) then -- -- -- alfrec.name := NULL; krmicd.writeMsg(8194, to_char(alfrec.thread#), to_char(alfrec.sequence#)); else -- -- -- raise; end if; end; exception when archivelog_backup_not_found then raise; when others then if (is_db_in_noarchivelog) then krmicd.writeMsg(8187, to_char(scn)); else if pstandby = 1 then krmicd.clearErrors; -- delete_logs(FALSE, dellog, deltarget, preplugin); select abs(sysdate-start_time) into elapsed from x$dual; dur2time(elapsed, hours, mins, secs); -- krmicd.writeMsg(8181, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); return; else krmicd.writeMsg(8060); -- unable to find log krmicd.writeMsg(8510, to_char(alfrec.thread#), to_char(alfrec.sequence#)); raise; end if; end if; end; deb('log_apply', 'log file name returned is ' || alfrec.name ); begin if alfrec.name is not NULL then if bmr then sys.dbms_backup_restore.bmrDoMediaRecovery(alfrec.name); elsif flash then sys.dbms_backup_restore.flashbackFiles(alfrec.name); elsif pdbpitr then sys.dbms_backup_restore.recoverDo(alfrec.name); elsif preplugin then sys.dbms_backup_restore.prePluginDoMediaRecovery(alfrec.name); else krmicd.writeMsg(8515, alfrec.name, to_char(alfrec.thread#), to_char(alfrec.sequence#)); -- krmicd.execSql( 'alter database recover logfile ''' || replace(alfrec.name,'''','''''') || ''''); end if; -- -- -- -- -- -- delete_logs(FALSE, dellog, deltarget, preplugin); if bmr then begin sys.dbms_backup_restore.bmrCancel; exception when bmr_block_errors then krmicd.writeMsg(8111); end; elsif flash then sys.dbms_backup_restore.flashbackCancel; krmicd.checkSetDatabase; elsif pdbpitr then sys.dbms_backup_restore.recoverCancel; elsif preplugin then sys.dbms_backup_restore.prePluginRecoveryCancel; end if; select abs(sysdate-start_time) into elapsed from x$dual; dur2time(elapsed, hours, mins, secs); -- krmicd.writeMsg(8181, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); return; else return; end if; exception when mr_cont_rcv then if continue_rcv(createdf) then goto get_log; end if; when mr_need_log then -- -- krmicd.clearErrors; -- -- -- -- -- delete_logs(TRUE, dellog, deltarget, preplugin); goto get_log; when mr_createdf then if (bmr or flash or pdbpitr) then raise; end if; -- for df_rec in (select fnfno, fnnam, fnonm, ts.ts#, ts.name, fepfdi, fepdi, (case when pdb.con_id > 1 then pdb.name else null end) pdbname from x$kccfn fn, x$kccfe fe, v$tablespace ts, v$containers pdb where fn.fnunn = 1 and fn.fnfno=fe.fenum and fe.fefnh=fnnum and fe.fetsn=ts.ts# and fe.con_id = ts.con_id and fe.con_id = pdb.con_id) loop -- -- if (df_rec.fepdi > 0 or df_rec.fepfdi > 0) then raise; end if; fileno := df_rec.fnfno; unnamed := df_rec.fnnam; dfname := df_rec.fnonm; tsnum := df_rec.ts#; tsname := df_rec.name; pdbname := df_rec.pdbname; deb('apply_log', 'tsnum ' || tsnum); deb('apply_log', 'tsname ' || tsname); deb('apply_log', 'fileno ' || fileno); deb('apply_log', 'dfname ' || dfname); deb('apply_log', 'pdbname' || nvl(pdbname, 'NULL')); deb('apply_log', 'file old name is ' || dfname); recovdf := true; if krmicd.getDfInfo(fileno, tsnum, tsname, pdbname, newdfname, bnewomf, dropf) then if (newdfname is not null) then dfname := newdfname; deb('apply_log', 'file new name is ' || newdfname); else deb('apply_log', 'using name at creation ' || dfname); end if; krmicd.writeMsg(6064, fileno, dfname); sys.dbms_backup_restore.createDatafile(fno => fileno, newomf => bnewomf, recovery => TRUE, fname => dfname); -- if filelist is not null then filelist := filelist || ', ' || fileno; else filelist := fileno; end if; else dfname := null; deb('apply_log', 'no filename - ignore creation of file# ' || fileno); deb('apply_log', 'This is recover database skip tablespace cmd'); if (df_offln_list.exists(fileno)) then deb('apply_log', 'file is already offlined ' || fileno); else df_offln_list(fileno) := 1; if (dropf = true) then krmicd.writeMsg(6958, 'alter database datafile ' || fileno || ' offline drop'); krmicd.execSql('alter database datafile ' || fileno || ' offline drop'); else krmicd.writeMsg(6958, 'alter database datafile ' || fileno || ' offline'); krmicd.execSql('alter database datafile ' || fileno || ' offline'); end if; end if; end if; end loop; -- -- krmicd.clearErrors; goto restart_recovery; end; end; >>> define 'scr_cre_rep' <<< -- declare creat boolean; line varchar2(1024); name varchar2(100); scr_com varchar2(255); global boolean; begin &args& if creat then dbms_rcvcat.createScript(name, scr_com, global); else dbms_rcvcat.replaceScript(name, scr_com, global); end if; loop line := krmicd.getLine; if line is null then exit; end if; dbms_rcvcat.putLine(line); end loop; dbms_rcvcat.commitChanges; if creat then if global then krmicd.writeMsg(8150, name); else krmicd.writeMsg(8085, name); end if; else if global then krmicd.writeMsg(8151, name); else krmicd.writeMsg(8086, name); end if; end if; end; >>> define replicate_controlfile <<< declare cfname varchar2(512); begin &object& replicate_controlfile(cfname => cfname); end; >>> define 'x$replicate_controlfile' <<< procedure replicate_controlfile(cfname IN varchar2) IS src_name varchar2(512); dest_name varchar2(512); full_name varchar2(512); recid number; stamp number; firstcall boolean := TRUE; begin src_name := sys.dbms_backup_restore.normalizefilename(cfname); for i in 1..9999 loop dest_name := sys.dbms_backup_restore.getparm( sys.dbms_backup_restore.control_file, i); if dest_name is null then exit; end if; if src_name <> dest_name then if firstcall then krmicd.writeMsg(8058); krmicd.writeMsg(8506, src_name); firstcall := FALSE; end if; krmicd.writeMsg(8505, dest_name); sys.dbms_backup_restore.copyControlFile(src_name => src_name, dest_name => dest_name, recid => recid, stamp => stamp, full_name => full_name); end if; end loop; end; >>> define "rpctest" <<< -- begin sys.dbms_backup_restore.sleep(60); -- 1 minute end; >>> define tspitr_rescf <<< # restore the controlfile restore clone controlfile; # mount the controlfile sql clone 'alter database mount clone database'; # archive current online log sql 'alter system archive log current'; >>> define tspitr_noauto <<< # avoid unnecessary autobackups for structural changes during TSPITR sql 'begin dbms_backup_restore.AutoBackupFlag(FALSE); end;'; >>> define tspitr_resync <<< # resync catalog resync catalog; >>> define tspitr_until <<< { # set requested point in time set until &1&; >>> define tspitr_offrecset <<< plsql &begin& -- declare sqlstatement varchar2(512); pdbname varchar2(128); offline_not_needed exception; pragma exception_init(offline_not_needed, -01539); begin &object& -- pdbname sqlstatement := 'alter tablespace '|| &1& ||' offline immediate'; krmicd.writeMsg(6162, sqlstatement); krmicd.execSql(sqlstatement, 0, pdbname); exception when offline_not_needed then null; end; &end& ; >>> define tspitr_flipcom <<< # switch to valid datafilecopies >>> define tspitr_flip <<< switch clone datafile &1& to datafilecopy &2&; >>> define tspitr_newcom <<< # set destinations for recovery set and auxiliary set datafiles >>> define tspitr_newdf <<< set newname for datafile &1& to &2&; >>> define tspitr_newomfaux <<< set newname for clone datafile &1& to new; >>> define tspitr_newomfrec <<< set newname for datafile &1& to new; >>> define tspitr_newtemp <<< set newname for tempfile &1& to &2&; >>> define tspitr_newomftemp <<< set newname for clone tempfile &1& to new; >>> define tspitr_switchtemp <<< # switch all tempfiles switch clone tempfile all; >>> define tspitr_restore <<< # restore the tablespaces in the recovery set and the auxiliary set restore clone datafile &1&; >>> define tspitr_restore_sparse <<< # sparse restore the tablespaces in the recovery set and the auxiliary set restore clone from &1& datafile &2& ; >>> define tspitr_restore_close <<< switch clone datafile all; } >>> define tspitr_onlinecom <<< # online the datafiles restored or switched >>> define tspitr_onlinedf <<< sql clone&1& "alter database datafile &2& online"; >>> define tspitr_recover_reset <<< # recover and open resetlogs recover clone database tablespace &1& delete archivelog; alter clone database open resetlogs; } >>> define tspitr_open_pdb <<< { sql clone 'alter pluggable database &1& open'; } >>> define tspitr_recover_ro <<< # recover and open database read only recover clone database tablespace &1&; sql clone 'alter database open read only'; } >>> define tspitr_open_pdb_ro <<< { sql clone 'alter pluggable database &1& open read only'; } >>> define tspitr_onlinetscom <<< # online the tablespaces that will be exported >>> define tspitr_onts <<< sql clone&1& 'alter tablespace &2& online'; >>> define tspitr_readonlycom <<< # make read only the tablespace that will be exported >>> define tspitr_rots <<< sql clone&1& 'alter tablespace &2& read only'; >>> define tspitr_mkclonedir <<< # create directory for datapump export sql clone&1& "create or replace directory &2& as ''&3&''"; >>> define tspitr_mktargetdir <<< # create directory for datapump import sql&1& "create or replace directory &2& as ''&3&''"; >>> define tspitr_uncatcom <<< # uncatalog used datafilecopies >>> define tspitr_uncatcopy <<< change datafilecopy &1& uncatalog; >>> define tspitr_dropcom <<< # drop target tablespaces before importing them back >>> define tspitr_dropkeepts <<< sql&1& 'drop tablespace &2& including contents keep datafiles cascade constraints'; >>> define tspitr_dropts <<< sql&1& 'drop tablespace &2& including contents cascade constraints'; >>> define tspitr_shutclone <<< # shutdown clone before import shutdown clone abort >>> define tspitr_readwritecom <<< # make read write and offline the imported tablespaces >>> define tspitr_rwts <<< sql&1& 'alter tablespace &2& read write'; sql&3& 'alter tablespace &4& offline'; >>> define tspitr_yesauto <<< # enable autobackups after TSPITR is finished sql 'begin dbms_backup_restore.AutoBackupFlag(TRUE); end;'; >>> define tspitr_mount_cl <<< # mount database sql clone 'alter database mount clone database'; >>> define impscrpt_0 <<< /* The following command may be used to import the tablespaces. Substitute values for and . impdp directory= dumpfile=&1& transport_datafiles=&2& */ -- -- -- -- >>> define impscrpt_1 <<< CREATE DIRECTORY &1& AS &2&; >>> define impscrpt_2 <<< /* PL/SQL Script to import the exported tablespaces */ DECLARE -- tbs_files dbms_streams_tablespace_adm.file_set; cvt_files dbms_streams_tablespace_adm.file_set; -- dump_file dbms_streams_tablespace_adm.file; dp_job_name VARCHAR2(30) := NULL; -- ts_names dbms_streams_tablespace_adm.tablespace_set; BEGIN -- dump_file.file_name := &1&; dump_file.directory_object := '&2&'; -- >>> define impscrpt_3 <<< tbs_files(&1&).file_name := &2&; tbs_files(&3&).directory_object := &4&; >>> define impscrpt_4 <<< -- dbms_streams_tablespace_adm.attach_tablespaces( datapump_job_name => dp_job_name, dump_file => dump_file, tablespace_files => tbs_files, converted_files => cvt_files, tablespace_names => ts_names); -- IF ts_names IS NOT NULL AND ts_names.first IS NOT NULL THEN FOR i IN ts_names.first .. ts_names.last LOOP dbms_output.put_line('imported tablespace '|| ts_names(i)); END LOOP; END IF; END; / -- >>> define impscrpt_5 <<< DROP DIRECTORY &1&; >>> define impscrpt_6 <<< -------------------------------------------------------------- -- End of sample PL/SQL script -------------------------------------------------------------- >>> define pdbpitr_rescf <<< # restore the controlfile restore clone controlfile; # mount the controlfile sql clone 'alter database mount clone database'; >>> define pdbpitr_recover1 <<< # recover pdb recover clone database tablespace &1& pluggable database &2& delete archivelog; sql clone 'alter database open read only'; >>> define pdbpitr_recover2 <<< # recover pdb recover clone database tablespace &1& datafile &3& pluggable database &2& delete archivelog; sql clone 'alter database open read only'; >>> define pdbpitr_recover3 <<< #recover pdb recover clone database tablespace &1& pluggable database &2& delete archivelog; #open in read write mode sql clone 'alter database open resetlogs'; #unplug dropped pdb into temp file sql clone "alter pluggable database &5& unplug into ''&3&''"; #create pdb using temp file of recovered pdb sql "create pluggable database &6& using ''&4&'' nocopy tempfile reuse"; alter pluggable database &7& open; } >>> define 'x$save_pdb_clean_scn' <<< procedure save_pdb_clean_scn is clnscnwrp number; clnscnbas number; begin krmicd.pdbCleanScn(clnscnwrp => clnscnwrp, clnscnbas => clnscnbas); deb('save_pdb_clean_scn', 'clnscnwrp=' || clnscnwrp || ' clnscnbas=' || clnscnbas); end; >>> define save_pdb_clean_scn <<< plsql &begin& begin save_pdb_clean_scn; end; &end& ; >>> define 'x$add_dropped_ts' <<< procedure add_dropped_ts is firstcall binary_integer := 1; fname varchar2(512); full_name varchar2(512); recid number; stamp number; cant_inspect_curr_file exception; pragma exception_init(cant_inspect_curr_file, -19657); begin loop exit when not krmicd.droppedFileGetNext( firstcall => firstcall, fname => fname); firstcall := 0; deb('add_dropped_ts', 'fname=' || fname); begin sys.dbms_backup_restore.inspectDataFileCopy( fname => fname, full_name => full_name, recid => recid, stamp => stamp, change_rdi => FALSE); sys.dbms_backup_restore.switchToCopy( copy_recid => recid, copy_stamp => stamp, catalog => TRUE); exception when cant_inspect_curr_file then deb('add_dropped_ts ', 'already exists'); krmicd.clearErrors; end; end loop; end; >>> define add_dropped_ts <<< plsql &begin& begin add_dropped_ts; end; &end& ; >>> define 'x$pdbpitr_inspect' <<< procedure pdbpitr_inspect(pdbname in varchar2) is firstcall binary_integer := 1; auxdfcList sys.dbms_backup_restore.register_auxdfc_list; auxdfc sys.dbms_backup_restore.register_auxdfc; i binary_integer := 0; clnscnwrp number; clnscnbas number; begin krmicd.pdbCleanScn(clnscnwrp => clnscnwrp, clnscnbas => clnscnbas); deb('pdbpitr_inspect', 'clnscnwrp=' || clnscnwrp || ' clnscnbas=' || clnscnbas); loop exit when not krmicd.auxFileGetNext( firstcall => firstcall, fname => auxdfc.fname, dfnumber => auxdfc.dfnumber, tsnum => auxdfc.tsnum, blksize => auxdfc.blksize); deb('pdbpitr_inspect', 'fname=' || auxdfc.fname || ' dfnumber=' || auxdfc.dfnumber || ' tsnum=' || auxdfc.tsnum || ' blksize=' || auxdfc.blksize); auxdfcList(i) := auxdfc; i := i+ 1; firstcall := 0; end loop; sys.dbms_backup_restore.registerAuxDfCopy( pdbname => pdbname, auxdfcList => auxdfcList, clnscnwrp => clnscnwrp, clnscnbas => clnscnbas); end; >>> define pdbpitr_inspect <<< plsql &begin& begin pdbpitr_inspect(pdbname => &1&); end; &end& ; } >>> define validateset <<< -- sys.dbms_backup_restore.restorevalidate; >>> define scandfc <<< -- declare recid number; stamp number; fname varchar2(512); dfnumber number; old_dfnumber number; rfno number; blksize number; blocks number; scn number; check_logical boolean := false; found boolean; preplugin boolean := false; pdbid number; pplcdbdbid number; begin &object& found := krmicd.valGetFound(recid, stamp); if dfnumber = 0 then krmicd.writeMsg(8518, krmicd.getChid, fname); else krmicd.writeMsg(8519, krmicd.getChid, fname); end if; if (not preplugin) then scn := sys.dbms_backup_restore.scandatafilecopy( recid => recid, stamp => stamp, update_fuzziness => false, check_logical => check_logical); else scn := sys.dbms_backup_restore.scandatafilecopy( update_fuzziness => false, check_logical => check_logical, fname => fname, fno => dfnumber, oldfno => old_dfnumber, rfno => rfno, blksize => blksize, blocks => blocks, preplugin => true); end if; if dfnumber = 0 then krmicd.fileRestored(ftype => rman_constant.CONTROLFILE, fno => 0, thread => 0, sequence => 0, resetscn => 0, resetstamp => 0); else krmicd.fileRestored(ftype => rman_constant.DATAFILE, fno => dfnumber, thread => 0, sequence => 0, resetscn => 0, resetstamp => 0, fname => fname); end if; exception when sys.dbms_backup_restore.retryable_error_exp then if not krmicd.doRestoreFailover(rman_constant.DATAFILE) then raise; end if; -- krmicd.writeErrMsg(1005, sqlerrm); krmicd.clearErrors; when others then raise; end; >>> define bscandfc <<< -- declare recid number; stamp number; found boolean; fname varchar2(512); begin &object& found := krmicd.valGetFound(recid, stamp); krmicd.writeMsg(8532, krmicd.getChid, fname); sys.dbms_backup_restore.bmrscandatafilecopy(recid, stamp); exception when sys.dbms_backup_restore.retryable_error_exp then if not krmicd.doRestoreFailover(rman_constant.DATAFILE) then raise; end if; -- krmicd.writeErrMsg(1005, sqlerrm); krmicd.clearErrors; when others then raise; end; >>> define scanal <<< -- declare record_not_found exception; pragma exception_init(record_not_found, -19571); recid number; stamp number; fname varchar2(512); full_name varchar2(512); rsid number; rsts number; isstby boolean := FALSE; nocfconv boolean := FALSE; isfarsync boolean := FALSE; begin &object& krmicd.writeMsg(8520, krmicd.getChid, fname); sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); <> -- retry on non-cataloged archived log begin sys.dbms_backup_restore.scanarchivedlog(recid => recid, stamp => stamp); exception when record_not_found then sys.dbms_backup_restore.inspectArchivedLog(fname => fname, full_name => full_name, recid => recid, stamp => stamp); deb('scanal', 'cataloged archive log recid=' || recid || ' stamp=' || stamp); krmicd.clearErrors; goto scan_log; end; sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0); end; >>> define setcmdid <<< -- declare cmdid varchar2(512); begin &object& if krmicd.getDevType is null then return; end if; sys.dbms_backup_restore.set_client_info( 'id='||cmdid||',rman channel='||krmicd.getchid); end; >>> define aor <<< -- declare cfname varchar2(512) := null; recid number; stamp number; copy_recid number := 0; copy_stamp number := 0; fname varchar2(512) := null; dfnumber binary_integer := null; blksize number := null; begin &1& -- set variables sys.dbms_backup_restore.applyOfflineRange(cfname => cfname, dfname => fname, blksize => blksize, recid => recid, stamp => stamp, fno => dfnumber, dfrecid => copy_recid, dfstamp => copy_stamp); if (fname is not null) then krmicd.writeMsg(8088, fname); else krmicd.writeMsg(8088, to_char(dfnumber, 'FM09999')); end if; krmicd.writeMsg(8521, to_char(recid), to_char(stamp)); end; >>> define net_rsdf_start <<< -- declare done boolean; tsname varchar2(512); toname varchar2(512); service varchar2(256); piecenum number; dfnumber number; max_corrupt binary_integer := 0; check_logical boolean := FALSE; err_msg varchar2(2048); start_time date; elapsed number; hours number; mins number; secs number; outhandle varchar2(512); failover boolean := FALSE; outtag varchar2(31); rcvcopy boolean := FALSE; rsid number; rsts number; preview boolean := FALSE; validate boolean := FALSE; isstby boolean; nocfconv boolean; cfname varchar2(512); currcf boolean; pfname varchar2(512); sfname varchar2(512); msrpno number := 0; msrpct number := 0; first_time boolean := TRUE; msb_section_size number; docompress boolean; isfarsync boolean := FALSE; networkfdf boolean := FALSE; sameend boolean := TRUE; transname boolean := FALSE; xfno number := 0; fileckpt_scn number := 0; restore_not_complete exception; sparse_restore number := 0; begin &1& -- set conversation variables -- if preview then deb('net_rsdf_start', 'preview'); return; end if; select sysdate into start_time from x$dual; sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); -- if networkfdf then sys.dbms_backup_restore.restoreSetForeignDF( check_logical => check_logical ,cleanup => FALSE ,service => service ,dfincr => FALSE ,sameend => sameend); else sys.dbms_backup_restore.restoreSetDataFile( check_logical => check_logical ,cleanup => FALSE ,service => service ,sparse_restore => sparse_restore); end if; docompress := setNetworkRestoreParams; if validate then krmicd.writeMsg(8096, krmicd.getChid); else krmicd.writeMsg(8016, krmicd.getChid); end if; if docompress then krmicd.writeMsg(8168, krmicd.getChid, service); else krmicd.writeMsg(8169, krmicd.getChid, service); end if; >>> define net_ridf_start <<< -- declare done boolean; toname varchar2(512); service varchar2(256); piecenum number; dfnumber number; max_corrupt binary_integer := 0; check_logical boolean := FALSE; err_msg varchar2(2048); start_time date; elapsed number; hours number; mins number; secs number; outhandle varchar2(512); failover boolean := FALSE; outtag varchar2(31); recid number; stamp number; fuzzy_hint number; islevel0 binary_integer; rcvcopy boolean := FALSE; rsid number; rsts number; preview boolean := FALSE; validate boolean := FALSE; isstby boolean; nocfconv boolean; msrpno number := 0; msrpct number := 0; first_time boolean := TRUE; msb_section_size number; docompress boolean; currcf boolean; isfarsync boolean := FALSE; networkfdf boolean := FALSE; sameend boolean := TRUE; transname boolean := FALSE; xfno number := 0; fileckpt_scn number := 0; restore_not_complete exception; begin &1& -- set conversation variables -- if preview then deb('net_ridf_start', 'preview'); return; end if; select sysdate into start_time from x$dual; sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); if networkfdf then sys.dbms_backup_restore.restoreSetForeignDF( check_logical => check_logical ,cleanup => FALSE ,service => service ,dfincr => TRUE ,sameend => sameend); else sys.dbms_backup_restore.applySetDatafile( check_logical => check_logical ,cleanup => FALSE ,service => service); end if; docompress := setNetworkRestoreParams; krmicd.writeMsg(8039, krmicd.getChid); if docompress then krmicd.writeMsg(8168, krmicd.getChid, service); else krmicd.writeMsg(8169, krmicd.getChid, service); end if; >>> define net_rsal_start <<< -- declare done boolean; toname varchar2(512); service varchar2(256); piecenum number; thread number; sequence number; arch_recid number; arch_stamp number; destination varchar2(512) := null; err_msg varchar2(2048); start_time date; elapsed number; hours number; mins number; secs number; outhandle varchar2(512); failover boolean := FALSE; outtag varchar2(31); rsid number; rsts number; preview boolean := FALSE; validate boolean := FALSE; currcf boolean; docompress boolean; msrpno number; dfnumber number; networkfdf boolean := FALSE; sameend boolean := TRUE; transname boolean := FALSE; xfno number := 0; fileckpt_scn number := 0; restore_not_complete exception; begin &1& -- if preview then deb('net_rsal_start', 'preview'); return; end if; select sysdate into start_time from x$dual; sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); sys.dbms_backup_restore.restoreSetArchivedLog( destination => destination ,cleanup => FALSE ,service => service); docompress := setNetworkRestoreParams; if validate then krmicd.writeMsg(8097, krmicd.getChid); elsif destination is null then krmicd.writeMsg(8017, krmicd.getChid); else krmicd.writeMsg(8018, krmicd.getChid); krmicd.writeMsg(8508, destination); end if; if docompress then krmicd.writeMsg(8168, krmicd.getChid, service); else krmicd.writeMsg(8169, krmicd.getChid, service); end if; >>> define net_rsdf_name <<< -- toname := null; max_corrupt := 0; &object& -- dfnumber, toname, max_corrupt, tsname sys.dbms_backup_restore.networkBackupDatafile(dfnumber => dfnumber); if msrpno > 0 then sys.dbms_backup_restore.networkSetMSB( dfnumber => dfnumber, section_size => msb_section_size, first_section => piecenum - 1, section_count => 1, pieceno => piecenum, piececnt => msrpct); end if; if msrpno > 1 then declare tempfno number; begin krmicd.getMSR(tempfno, toname); end; end if; if (not validate) then sys.dbms_backup_restore.restoreDataFileTo(dfnumber => dfnumber, toname => toname, max_corrupt => max_corrupt, tsname => tsname); if msrpno = 1 then sys.dbms_backup_restore.initMSR(dfnumber, toname); end if; -- -- if first_time then krmicd.writeMsg(8089, krmicd.getChid); first_time := FALSE; end if; -- if (not networkfdf) then if toname is not null then krmicd.writeMsg(8610, krmicd.getChid, to_char(dfnumber, 'FM09999'), toname); else krmicd.writeMsg(8610, krmicd.getChid, to_char(dfnumber, 'FM09999'), 'default location'); end if; end if; if (msrpno > 0) then krmicd.writeMsg(8555, krmicd.getChid, to_char(msrpno), to_char(msrpct)); end if; end if; >>> define net_ridf_name <<< -- toname := null; max_corrupt := 0; -- &object& sys.dbms_backup_restore.networkBackupDatafile(dfnumber => dfnumber); if msrpno > 0 then sys.dbms_backup_restore.networkSetMSB( dfnumber => dfnumber, section_size => msb_section_size, first_section => piecenum - 1, section_count => 1, pieceno => piecenum, piececnt => msrpct); end if; if msrpno > 1 then declare tempfno number; begin krmicd.getMSR(tempfno, toname); end; end if; if (not validate) then sys.dbms_backup_restore.applyDataFileTo( dfnumber => dfnumber ,toname => toname ,fuzziness_hint => fuzzy_hint ,max_corrupt => max_corrupt ,islevel0 => islevel0 ,recid => recid ,stamp => stamp); if msrpno = 1 then sys.dbms_backup_restore.initMSR(dfnumber, toname); end if; -- -- if toname is not null then if rcvcopy then krmicd.writeMsg(8551, to_char(dfnumber, 'FM09999'), toname); elsif (networkfdf) then krmicd.writeMsg(8626, krmicd.getChid, to_char(dfnumber, 'FM09999'), toname); else krmicd.writeMsg(8509, to_char(dfnumber, 'FM09999'), toname); end if; end if; if (msrpno > 0) then krmicd.writeMsg(8555, krmicd.getChid, to_char(msrpno), to_char(msrpct)); end if; end if; >>> define net_rsal_name <<< -- &object& sys.dbms_backup_restore.networkBackupArchivedLog( arch_recid => arch_recid, arch_stamp => arch_stamp); if (not validate) then sys.dbms_backup_restore.restoreArchivedLog(thread => thread, sequence => sequence); krmicd.writeMsg(8022, krmicd.getChid); krmicd.writeMsg(8510, to_char(thread), to_char(sequence)); end if; >>> define net_rscf_name <<< -- &object& sys.dbms_backup_restore.networkBackupDatafile(dfnumber => 0); if (not validate) then sys.dbms_backup_restore.restoreControlfileTo(cfname => cfname, isstby => isstby, nocfconv => nocfconv, isfarsync => isfarsync); krmicd.writeMsg(8021, krmicd.getChid); if (not currcf) then krmicd.writeMsg(8505, cfname); end if; end if; >>> define net_rssf_name <<< -- &object& sys.dbms_backup_restore.networkBackupSpfile; if (not validate) then sys.dbms_backup_restore.restoreSpfileTo(pfname => pfname, sfname => sfname); if pfname is not null then krmicd.writeMsg(8114, krmicd.getChid); krmicd.writeMsg(8505, pfname); elsif sfname is not null then krmicd.writeMsg(8115, krmicd.getChid); krmicd.writeMsg(8505, sfname); else krmicd.writeMsg(8115, krmicd.getChid); krmicd.writeMsg(8116); end if; end if; >>> define net_restore_piece <<< -- sys.dbms_backup_restore.restoreSetPiece(handle => 'network' ,tag => null ,fromdisk => false ,recid => 0 ,stamp => 0); -- -- if msrpno > 0 then krmicd.setMSR(dfnumber, nvl(toname, 'dummy')); end if; sys.dbms_backup_restore.restoreBackupPiece(done => done ,params => null ,outhandle => outhandle ,outtag => outtag ,failover => failover); if (not done) then krmicd.writeMsg(8001); raise restore_not_complete; end if; select abs(sysdate-start_time) into elapsed from x$dual; dur2time(elapsed, hours, mins, secs); -- -- if (transname) then xfno := sys.dbms_backup_restore.getXttsName(toname); krmicd.writeMsg(8626, krmicd.getChid, xfno, toname); end if; if (validate) then krmicd.writeMsg(8182, krmicd.getChid, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); else krmicd.writeMsg(8180, krmicd.getChid, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); end if; if validate then -- validate backupset, restore validate cmds krmicd.fileRestored(ftype => rman_constant.BACKUPPIECE, fno => 0, thread => 0, sequence => 0, resetscn => 0, resetstamp => 0); else -- if currcf then print_controlfile; end if; getFileRestored(FALSE); end if; sys.dbms_backup_restore.restoreCancel(TRUE); exception when sys.dbms_backup_restore.retryable_error_exp then err_msg := sqlerrm; if not krmicd.doRestoreFailover(rman_constant.DATAFILE) then raise; end if; -- if (not validate) then getFileRestored(FALSE); end if; begin sys.dbms_backup_restore.restoreCancel(TRUE); exception when others then krmicd.writeMsg(1005, 'dbms_backup_restore.restoreCancel() failed'); end; -- raise; when others then sys.dbms_backup_restore.restoreCancel(TRUE); raise; end; >>> define proxy_backup_start <<< -- declare dfnumber number; copy_recid number; copy_stamp number; busy_retries number; resetlogs_change number; resetlogs_time varchar2(512); creation_change number; checkpoint_change number; blksize number; fname varchar2(1024); fmt varchar2(1024); no_delete binary_integer; first_time boolean := TRUE; cfisstby boolean := FALSE; incremental boolean := FALSE; media_pool binary_integer := 0; set_type varchar2(30); tag varchar2(32) := NULL; elapsed number; start_time date; hours number; mins number; secs number; pieceno number := 0; set_stamp number; set_count number; cfname varchar2(1); -- not used for backup currcf boolean := FALSE; -- not used for backup validate boolean := FALSE; -- not used for backup val_bs_only boolean := FALSE; -- TRUE => only bs validation -- keep_options binary_integer := 0; keep_until number := 0; lyear varchar2(4); lmonth varchar2(2); lday varchar2(2); chtype varchar2(16); isstby boolean; handle varchar2(512); arch_recid number; arch_stamp number; thread number; sequence number; first_change number; next_change number; deffmt binary_integer; dest binary_integer := 0; isrestore boolean := FALSE; -- not a proxy restore rsid number; rsts number; reqscn number; -- streams/standby required scn rlgscn number; -- streams/standby resetlogs scn appscn number; apprlgscn number; reqbackups number; nbackups number; alldest number := 0; docopies boolean := FALSE; in_use exception; del_for_space exception; no_files exception; dropped_pdb_file exception; isfarsync boolean := FALSE; ppltrans number; pragma exception_init(in_use, -19584); pragma exception_init(del_for_space, -19805); pragma exception_init(no_files, -19581); pragma exception_init(dropped_pdb_file, -45913); begin &1& if incremental then set_type := 'incremental level 0'; else set_type := 'full'; end if; select to_char(sysdate, 'YYYY', 'NLS_CALENDAR=Gregorian'), to_char(sysdate, 'MM', 'NLS_CALENDAR=Gregorian'), to_char(sysdate, 'DD', 'NLS_CALENDAR=Gregorian') into lyear, lmonth, lday from x$dual; sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); sys.dbms_backup_restore.proxyBeginBackup(tag => tag, incremental => incremental, media_pool => media_pool, set_stamp => set_stamp, set_count => set_count, keep_options => keep_options, keep_until => keep_until); start_time := stamp2date(set_stamp); >>> define proxy_budf <<< -- fmt := NULL; &1& -- fmt chtype := krmicd.getDevType; krmicd.getFormat(format => fmt, copy => 1, deffmt => deffmt, dest => dest); if chtype is null then chtype := 'N/A'; end if; loop exit when not krmicd.proxyBackupDataFile(dfnumber, fname); pieceno := pieceno + 1; if (first_time) then krmicd.writeMsg(8527, krmicd.getChid, set_type, to_char(stamp2date(set_stamp))); krmicd.writeMsg(8091, krmicd.getChid); first_time := FALSE; end if; handle := sys.dbms_backup_restore.genPieceName( pno => pieceno, set_count => set_count, set_stamp => set_stamp, format => fmt, copyno => 1, devtype => chtype, year => lyear, month => lmonth, day => lday, dbid => null, -- computed in server ndbname => null, -- computed in server pdbname => null, -- computed in server cfseq => NULL); -- not used sys.dbms_backup_restore.proxyBackupDataFile(file# => dfnumber, handle => handle); krmicd.writeMsg(8522, to_char(dfnumber, 'FM09999'), fname); krmicd.writeMsg(8529, handle); end loop; >>> define proxy_budc <<< -- fmt := NULL; &1& -- fmt chtype := krmicd.getDevType; krmicd.getFormat(format => fmt, copy => 1, deffmt => deffmt, dest => dest); if chtype is null then chtype := 'N/A'; end if; loop exit when not krmicd.proxyBackupDataFileCopy(dfnumber, fname, copy_recid, copy_stamp); pieceno := pieceno + 1; if (first_time) then krmicd.writeMsg(8527, krmicd.getChid, set_type, to_char(stamp2date(set_stamp))); krmicd.writeMsg(8091, krmicd.getChid); first_time := FALSE; end if; handle := sys.dbms_backup_restore.genPieceName( pno => pieceno, set_count => set_count, set_stamp => set_stamp, format => fmt, copyno => 1, devtype => chtype, year => lyear, month => lmonth, day => lday, dbid => null, -- computed in server ndbname => null, -- computed in server pdbname => null, -- computed in server cfseq => NULL); -- not used begin sys.dbms_backup_restore.proxyBackupDataFileCopy( copy_recid => copy_recid, copy_stamp => copy_stamp, handle => handle); krmicd.writeMsg(8033, krmicd.getChid, to_char(dfnumber, 'FM09999')); krmicd.writeMsg(8506, fname); krmicd.writeMsg(8529, handle); exception when in_use then krmicd.writeMsg(8603, fname); krmicd.clearErrors; when del_for_space then krmicd.writeMsg(8604, fname); krmicd.clearErrors; when dropped_pdb_file then krmicd.writeMsg(6825, fname); krmicd.clearErrors; end; end loop; >>> define proxy_bucf <<< -- fmt := NULL; &1& -- fmt chtype := krmicd.getDevType; krmicd.getFormat(format => fmt, copy => 1, deffmt => deffmt, dest => dest); if chtype is null then chtype := 'N/A'; end if; loop fname := NULL; exit when not krmicd.proxyBackupControlfile(fname); pieceno := pieceno + 1; if (first_time) then krmicd.writeMsg(8527, krmicd.getChid, set_type, to_char(stamp2date(set_stamp))); krmicd.writeMsg(8091, krmicd.getChid); first_time := FALSE; end if; -- -- -- -- busy_retries := 0; <> -- retry on failure to get snapshot enqueue begin if fname is null then -- backup current controlfile sys.dbms_backup_restore.cfileMakeAndUseSnapshot(isstby); sys.dbms_backup_restore.cfileUseCurrent; end if; handle := sys.dbms_backup_restore.genPieceName( pno => pieceno, set_count => set_count, set_stamp => set_stamp, format => fmt, copyno => 1, devtype => chtype, year => lyear, month => lmonth, day => lday, dbid => null, -- computed in server ndbname => null, -- computed in server pdbname => null, -- computed in server cfseq => NULL); -- not used sys.dbms_backup_restore.proxyBackupControlFile(name => fname, handle => handle); exception when sys.dbms_backup_restore.snapshot_enqueue_busy then -- -- -- -- if busy_retries = 180 then krmicd.writeMsg(20029, 'cannot make a snapshot controlfile'); raise; end if; busy_retries := busy_retries + 1; -- if (mod(busy_retries, 15) = 0) then krmicd.writeMsg(8512); end if; krmicd.sleep(20); krmicd.clearErrors; goto snapshot; end; -- snapshot controlfile stuff if fname is null then if isstby then krmicd.writeMsg(8099); else krmicd.writeMsg(8093); end if; else krmicd.writeMsg(8524, fname); end if; krmicd.writeMsg(8529, handle); end loop; >>> define proxy_bual <<< -- fmt := NULL; &1& -- fmt chtype := krmicd.getDevType; krmicd.getFormat(format => fmt, copy => 1, deffmt => deffmt, dest => dest); if chtype is null then chtype := 'N/A'; end if; loop fname := NULL; exit when not krmicd.proxyBackupArchivedLog(thread, sequence, fname, arch_recid, arch_stamp); pieceno := pieceno + 1; if (first_time) then krmicd.writeMsg(8542, krmicd.getChid, to_char(stamp2date(set_stamp))); krmicd.writeMsg(8543, krmicd.getChid); first_time := FALSE; end if; handle := sys.dbms_backup_restore.genPieceName( pno => pieceno, set_count => set_count, set_stamp => set_stamp, format => fmt, copyno => 1, devtype => chtype, year => lyear, month => lmonth, day => lday, dbid => null, -- computed in server ndbname => null, -- computed in server pdbname => null, -- computed in server cfseq => NULL); -- not used begin sys.dbms_backup_restore.proxyBackupArchivedlog( arch_recid => arch_recid, arch_stamp => arch_stamp, handle => handle); krmicd.writeMsg(8504, to_char(thread), to_char(sequence), to_char(arch_recid), to_char(arch_stamp)); krmicd.writeMsg(8529, handle); exception when in_use then krmicd.writeMsg(8603, fname); krmicd.clearErrors; when del_for_space then krmicd.writeMsg(8604, fname); krmicd.clearErrors; end; end loop; >>> define proxy_restore_start <<< -- declare currcf boolean; handle varchar2(512); dfnumber number; toname varchar2(512); cfname varchar2(512); destination varchar2(512) := null; first_time boolean := TRUE; start_time date; elapsed number; hours number; mins number; secs number; recid number; stamp number; validate boolean; val_bs_only boolean := FALSE; -- TRUE => only bs validation -- vrc binary_integer; validation_failure exception; thread number; sequence number; resetlogs_id number; -- ub4 value of resetlogs timestamp, used -- -- isrestore boolean := TRUE; -- is a proxy restore rsid number; rsts number; tsname varchar2(512); blksize number; blocks number; no_files exception; preplugin boolean := FALSE; pdbid number := 0; pplcdbdbid number := 0; ppltrans number; old_dfnumber number; pragma exception_init(no_files, -19581); begin &1& if (preplugin) then ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation( pdbid => pdbid, pplcdbdbid => pplcdbdbid); end if; sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); if not validate then sys.dbms_backup_restore.proxyBeginRestore( destination => destination ,cleanup => FALSE ,preplugin => preplugin); end if; select sysdate into start_time from x$dual; if (validate) then krmicd.writeMsg(8100, krmicd.getChid); else krmicd.writeMsg(8090, krmicd.getChid); end if; >>> define proxy_rsdf <<< -- loop exit when not krmicd.proxyRestoreDatafile( handle, dfnumber, toname, blocks, blksize, tsname, old_dfnumber); sys.dbms_backup_restore.proxyRestoreDatafile( handle => handle, file# => dfnumber, toname => toname, tsname => tsname, blksize => blksize, blocks => blocks, old_file# => old_dfnumber); if first_time then krmicd.writeMsg(8094, krmicd.getChid); first_time := FALSE; end if; krmicd.writeMsg(8610, krmicd.getChid, to_char(dfnumber, 'FM09999'), toname); krmicd.writeMsg(8529, handle); end loop; >>> define proxy_rscf <<< -- loop exit when not krmicd.proxyRestoreControlfile(handle, cfname, currcf, blocks, blksize); sys.dbms_backup_restore.proxyRestoreControlfile(handle => handle, toname => cfname, blksize => blksize, blocks => blocks); if first_time then krmicd.writeMsg(8094, krmicd.getChid); first_time := FALSE; end if; krmicd.writeMsg(8021, krmicd.getChid); if (cfname is not null) then krmicd.writeMsg(8505, cfname); end if; krmicd.writeMsg(8529, handle); end loop; >>> define proxy_rsal <<< -- loop exit when not krmicd.proxyRestoreArchivedLog(handle, thread, sequence, resetlogs_id, blocks, blksize); sys.dbms_backup_restore.proxyRestoreArchivedLog( handle => handle, thread => thread, sequence => sequence, resetlogs_id =>resetlogs_id, blksize => blksize, blocks => blocks); if first_time then krmicd.writeMsg(8544, krmicd.getChid); first_time := FALSE; end if; krmicd.writeMsg(8529, handle); krmicd.writeMsg(8022, krmicd.getChid); krmicd.writeMsg(8510, to_char(thread), to_char(sequence)); end loop; >>> define proxy_val <<< -- loop exit when not krmicd.proxyValOnly(handle, recid, stamp); vrc := sys.dbms_backup_restore.proxyValOnly(recid, stamp, handle); if vrc < sys.dbms_backup_restore.validate_file_different then krmicd.writeMsg(8531, krmicd.getChid, handle, 'FOUND'); krmicd.fileRestored(ftype => rman_constant.PROXYFILE, fno => 0, thread => 0, sequence => 0, resetscn => 0, resetstamp => 0); else krmicd.writeMsg(8531, krmicd.getChid, handle, 'NOT FOUND'); end if; end loop; >>> define proxy_go <<< -- if not validate then begin sys.dbms_backup_restore.proxyGo; if isrestore then getFileRestored(TRUE); end if; sys.dbms_backup_restore.proxyCancel; -- this could also signal error exception when sys.dbms_backup_restore.retryable_error_exp then if (isrestore and krmicd.doRestoreFailover(rman_constant.PROXYFILE)) then -- krmicd.writeErrMsg(1005, sqlerrm); krmicd.clearErrors; else raise; end if; when no_files then if (not isrestore) then krmicd.writeMsg(8057, krmicd.getChid); krmicd.clearErrors; else raise; end if; when others then raise; end; if (ppltrans > 0) then sys.dbms_backup_restore.endPrePluginTranslation; end if; -- if currcf then print_controlfile; end if; select sysdate - start_time into elapsed from x$dual; dur2time(elapsed, hours, mins, secs); krmicd.writemsg(8528, krmicd.getChid, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); end if; first_time := TRUE; -- just in case we delete the backed archivelog >>> define proxy_end <<< if validate then krmicd.writeMsg(8101, krmicd.getChid); end if; sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0); end; >>> define cl_beg <<< { >>> define cl_unt1 <<< set until scn &1&; >>> define cl_unt2 <<< set until time &1&; >>> define cl_unt3 <<< set to restore point &1&; >>> define cl_catb <<< catalog clone datafilecopy &1& >>> define cl_cat <<< , &1& >>> define cl_cate <<< ; >>> define cl_cend <<< ; >>> define cl_end <<< } >>> define res_cl_res <<< restore >>> define res_cl_spf <<< restore clone spfile to &1&; >>> define res_cl_spffb <<< restore clone spfile to &1& from &2&; >>> define res_cl_spffs <<< restore clone from service &2& spfile to &1&; >>> define res_cl_spffs_uscomp <<< restore clone from service &2& using compressed backupset spfile to &1&; >>> define cop_cl_file <<< targetfile &1& auxiliary format &2& >>> define cop_set_spf <<< sql clone "alter system set spfile=&1&"; >>> define set_cl_spfp <<< sql clone "alter system set &1& = &2& comment=&3& scope=spfile"; >>> define set_cl_spfr <<< sql clone "alter system reset &1& scope=spfile"; >>> define cspfile_cl <<< sql clone "create spfile from memory"; >>> define cpfile_cl <<< sql clone "create pfile=&1& from spfile"; >>> define cl_skp <<< skip forever tablespace &1& >>> define cl_skp_ro <<< skip readonly >>> define cl_from_service <<< from service &1& >>> define cl_from_sparse <<< from &1& >>> define cl_section_size <<< section size &1& >>> define cl_using_compress <<< using compressed backupset >>> define cl_db <<< clone database >>> define cl_df <<< clone datafile &1& >>> define cl_stby <<< standby >>> define cop_cl_bck <<< backup as copy reuse >>> define cop_cl_df <<< datafile &1& auxiliary format &2& >>> define copn_cl_df <<< datafile &1& auxiliary format new >>> define cop_cl_al <<< archivelog like &1& auxiliary format &2& >>> define res_cl_alfs <<< restore clone force from service &1& archivelog from scn &2&; >>> define res_cl_alfs_uscomp <<< restore clone force from service &1& using compressed backupset archivelog from scn &2&; >>> define cl_add_srlg <<< sql clone "alter database add standby logfile group &1& &2& size &3& &4&"; >>> define cl_add_srl <<< sql clone "alter database add standby logfile member &1& reuse to group &2&"; >>> define cl_drop_srlg <<< sql clone "alter database drop standby logfile group &1&"; >>> define cat_cl_al1 <<< catalog clone archivelog &1&; >>> define cat_cl_al2 <<< catalog clone recovery area; >>> define cat_cl_al3 <<< catalog clone start with &1&; >>> define arc_cl_log <<< sql 'alter system archive log current'; >>> define res_cl_set <<< set newname for datafile &1& to &2&; >>> define res_cl_setn <<< set newname for clone datafile &1& to new; >>> define res_cl_swi <<< switch clone datafile all; >>> define res_cl_sett <<< set newname for tempfile &1& to &2&; >>> define res_cl_setnt <<< set newname for clone tempfile &1& to new; >>> define res_cl_swit <<< switch clone tempfile all; >>> define rec_cl_rec <<< recover >>> define rec_cl_comma <<< , >>> define rec_cl_noredo <<< noredo >>> define rec_cl_delinp <<< delete archivelog >>> define opn_cl_shi <<< shutdown clone immediate; >>> define opn_cl_stp <<< startup clone nomount pfile=&1&; >>> define opn_cl_stsp <<< startup clone nomount; >>> define opn_cl_swi <<< switch clone datafile &1& to datafilecopy &2&; >>> define opn_cl_end <<< Alter clone database open resetlogs; >>> define opn_cl_pdb_end <<< sql clone "alter pluggable database all open"; >>> define opn_cl_pdb_end_restrict <<< sql clone "alter pluggable database all open restricted"; >>> define en_rest_sess <<< sql clone 'alter system enable restricted session'; >>> define cl_onl_ts <<< #online the readonly tablespace sql clone&1& "alter tablespace &2& online"; >>> define cop_cl_cf <<< shutdown clone immediate; startup clone force nomount backup as copy current controlfile auxiliary format &1&; >>> define cop_cl_scf <<< backup as copy current controlfile for standby auxiliary format &1&; >>> define cop_cl_fcf <<< backup as copy current controlfile for farsync auxiliary format &1&; >>> define cl_flash_off <<< sql clone 'alter database flashback off'; >>> define cop_cl_cf2 <<< restore clone primary controlfile to &1& from &2&; >>> define mnt_cl_cf <<< alter clone database mount; >>> define mnt_cl_scf <<< sql clone 'alter database mount standby database'; >>> define res_cl_scf <<< restore clone standby controlfile; >>> define res_cl_scffb <<< restore clone standby controlfile from &1&; >>> define res_cl_scffs <<< restore clone from service &1& standby controlfile; >>> define res_cl_scffs_uscomp <<< restore clone from service &1& using compressed backupset standby controlfile; >>> define mnt_cl_fcf <<< sql clone 'alter database mount'; >>> define res_cl_fcf <<< restore clone farsync controlfile; >>> define res_cl_fcffb <<< restore clone farsync controlfile from &1&; >>> define res_cl_fcffs <<< restore clone from service &1& farsync controlfile; >>> define res_cl_fcffs_uscomp <<< restore clone from service &1& using compressed backupset farsync controlfile; >>> define res_cl_clcf <<< restore clone controlfile; sql clone 'alter database mount clone database'; >>> define res_cl_cf <<< shutdown clone immediate; startup clone force nomount restore clone primary controlfile; alter clone database mount; >>> define res_cl_cffb <<< shutdown clone immediate; startup clone force nomount restore clone primary controlfile from &1&; alter clone database mount; >>> define res_cl_cffs <<< shutdown clone immediate; startup clone force nomount restore clone from service &1& primary controlfile; >>> define res_cl_cffs_uscomp <<< shutdown clone immediate; startup clone force nomount restore clone from service &1& using compressed backupset primary controlfile; >>> define cl_onl_df <<< sql clone&1& "alter database datafile &2& online"; >>> define cl_uncat <<< change datafilecopy &1& uncatalog; >>> define val_pieces <<< -- declare pieceCnt number := 0; retval binary_integer; handle varchar2(512); recid number; stamp number; setCount number; setStamp number; piece number; valrc binary_integer; hdl_isdisk binary_integer := 0; m1 varchar2(128); m2 varchar2(128); m3 varchar2(128); m4 varchar2(128); m5 varchar2(128); m6 varchar2(128); m7 varchar2(128); m8 varchar2(128); m9 varchar2(128); m10 varchar2(128); m11 varchar2(128); m12 varchar2(128); m13 varchar2(128); m14 varchar2(128); m15 varchar2(128); m16 varchar2(128); m17 varchar2(128); m18 varchar2(128); m19 varchar2(128); m20 varchar2(128); returnCode binary_integer; msca binary_integer; attributes binary_integer; preview boolean := FALSE; recall boolean := FALSE; flags binary_integer := 0; disp_hdr boolean := TRUE; few_remote boolean := FALSE; few_remote_e exception; pragma exception_init(few_remote_e, -20507); function addcomma(media in varchar2) return varchar2 is out_media varchar2(80) := null; begin if media is not null then out_media := ',' ||media; end if; return out_media; end; begin &1& -- sys.dbms_backup_restore.validationStart; -- loop retval := krmicd.getValidatePieceArgs(handle, recid, stamp, setCount, setStamp, piece, hdl_isdisk); deb('val_pieces', 'handle:'||handle||' is disk:'||hdl_isdisk); if (retval = 0) then -- -- sys.dbms_backup_restore.validationAddPiece( recid => recid, stamp => stamp, handle => handle, set_stamp => setStamp, set_count => setCount, pieceno => piece, params => NULL, hdl_isdisk => hdl_isdisk); -- pieceCnt := pieceCnt + 1; else -- exit; end if; end loop; if (pieceCnt = 0) then sys.dbms_backup_restore.validationEnd; return; end if; if recall then flags := sys.dbms_backup_restore.vvflags_recall; end if; -- sys.dbms_backup_restore.validationValidate(flags => flags); -- -- loop sys.dbms_backup_restore.validationNextResult(handle => handle, recid => recid, set_stamp => setStamp, set_count => setCount, pieceno => piece, msca => msca, m1 => m1, m2 => m2, m3 => m3, m4 => m4, m5 => m5, m6 => m6, m7 => m7, m8 => m8, m9 => m9, m10 => m10, m11 => m11, m12 => m12, m13 => m13, m14 => m14, m15 => m15, m16 => m16, m17 => m17, m18 => m18, m19 => m19, m20 => m20, attributes => attributes); exit when handle is NULL; deb('val_pieces', 'validated handle:' || handle||' Media:'||m1|| ' attributes='||attributes||' msca='||msca); if bitand(attributes, sys.dbms_backup_restore.attribute_remote) = 1 then if disp_hdr then if recall then krmicd.writeMsg(8608); krmicd.writeMsg(7524); else krmicd.writeMsg(8607); krmicd.writeMsg(6320); end if; disp_hdr := FALSE; few_remote := TRUE; end if; krmicd.writeMsg(6355, handle, m1 || addcomma(m2) || addcomma(m3) || addcomma(m4) || addcomma(m5) || addcomma(m6) || addcomma(m7) || addcomma(m8) || addcomma(m9) || addcomma(m10) || addcomma(m11) || addcomma(m12) || addcomma(m13) || addcomma(m14) || addcomma(m15) || addcomma(m16) || addcomma(m17) || addcomma(m18) || addcomma(m19) || addcomma(m20)); end if; pieceCnt := pieceCnt - 1; krmicd.setValidateResult(handle, recid, setStamp, setCount, piece, msca, m1 , m2 , m3 , m4 , m5 , m6 , m7 , m8 , m9 , m10, m11, m12, m13, m14, m15, m16, m17, m18, m19, m20); end loop; krmicd.endPieceValidate; sys.dbms_backup_restore.validationEnd; if few_remote and not preview then raise few_remote_e; end if; end; >>> define backup_baut <<< declare ncopies number; copyno number; handle varchar2(512); comment varchar2(80); media varchar2(80); lcfaudate date; lsequence binary_integer; lbautfmt varchar2(512); rsid number; rsts number; p1 binary_integer := 0; p2 binary_integer; p3 binary_integer; p4 binary_integer; p5 binary_integer; t1 varchar2(1025); t2 varchar2(1); t3 varchar2(1); busy_retries number := 0; begin -- -- -- &lsequence& &lcfaudate& &lbautfmt& &object& setBackupParams(FALSE); if (krmicd.getParams(1, p2, p3, p4, p5, t1, t2, t3)) then p1 := 1; end if; sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); <> -- retry on failure to get snapshot enqueue begin sys.dbms_backup_restore.DoAutobackup(ncopies => ncopies, cfaudate => lcfaudate, seq => lsequence, format => lbautfmt, p1 => p1, p2 => p2, p3 => p3, p4 => t1); exception when sys.dbms_backup_restore.snapshot_enqueue_busy then -- -- -- -- if busy_retries = 180 then krmicd.writeMsg(20029, 'cannot make a snapshot controlfile'); raise; end if; busy_retries := busy_retries + 1; -- if (mod(busy_retries, 15) = 0) then krmicd.writeMsg(8512); end if; krmicd.sleep(20); krmicd.clearErrors; goto snapshot; end; -- snapshot controlfile stuff copyno := 0; loop exit when copyno=ncopies; sys.dbms_backup_restore.backupPieceCrtDupGet(copyno, handle, comment, media); if comment is null then comment := 'NONE'; end if; krmicd.writeMsg(8503, handle, comment); copyno := copyno + 1; end loop; sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0); end; >>> define raut_search <<< -- declare ldbid number := 0; trgt_date date; lyear varchar2(4); lmonth varchar2(2); lday varchar2(2); lmon_day varchar2(4); year binary_integer; month binary_integer; day binary_integer; ats number; -- autobackup time stamp days number; sft_seq binary_integer; -- search file table seq and date sft_date number; aut_seq binary_integer; -- used autobackup seq and date aut_date number; tempseq binary_integer; -- temp var tempdate number; old_seq binary_integer := 1; cfname varchar2(512); sfname varchar2(512); pfname varchar2(512); rc number; status number; lformat varchar2(512) := NULL; lsequence binary_integer := 255; lmaxdays number := 7; handle varchar2(512) := NULL; outhandle varchar2(512); sfthandle varchar2(512); lhandle varchar2(512); sdate varchar2(512) := NULL; currcf boolean := FALSE; set_ra varchar2(512) := NULL; -- recovery area specified by user set_ns varchar2(512) := NULL; -- name space specified by user uset_ns varchar2(512) := NULL; -- upper case of db_name given by user done boolean; found boolean; mustspfile boolean; -- must we find autobackup with spfile? abort boolean; dorestore boolean; endstatus boolean; fromcopy boolean := FALSE; begtime date; endtime date; seconds number; retval number; full_name varchar2(512); recid number; stamp number; isstby boolean := FALSE; -- restore standby controlfile? nocfconv boolean := FALSE; csf_retries number := 0; -- retry counter for spfile_not_in_bs -- rsid number; rsts number; start_time date; -- begin_time of restore elapsed number; -- elapsed time for restore hours number; mins number; secs number; dummyscn number; isomf boolean; isasm boolean; istmplt boolean; validate boolean := FALSE; preview boolean := FALSE; vheader boolean := FALSE; isfarsync boolean := FALSE; -- restore farsync controlfile? -- -- dummy_error exception; pragma exception_init(dummy_error, -6512); begin -- -- &1& old_seq := lsequence; aut_seq := lsequence; select decode(sdate, NULL, sysdate, to_date(sdate, 'MON DD YYYY HH24:MI:SS', 'NLS_CALENDAR=Gregorian')) into trgt_date from x$dual; select sysdate into start_time from x$dual; done := FALSE; abort := FALSE; dorestore := FALSE; endstatus := FALSE; isasm := FALSE; isomf := FALSE; istmplt := FALSE; aut_seq := 0; aut_date := 0; sft_date := 0; sft_seq := 0; sfthandle := to_char(NULL); outhandle := to_char(NULL); -- if handle is not null then -- -- -- -- -- -- -- -- status := sys.dbms_backup_restore.validateBackupPiece( recid => 0, stamp => 0, handle => handle, set_stamp => 0, set_count => 0, pieceno => 0, params => NULL, hdl_isdisk => 0); rc := bitand(status, sys.dbms_backup_restore.validate_file_different); if (rc = 0) then outhandle := handle; fromcopy := FALSE; else status := sys.dbms_backup_restore.validateDatafileCopy( recid => 0, stamp => 0, fname => handle, dfnumber => 0, resetlogs_change => 0, creation_change => 0, checkpoint_change => 0, blksize => 0, signal => 0); rc := bitand(status, sys.dbms_backup_restore.validate_file_different); if (rc = 0) then outhandle := handle; fromcopy := TRUE; end if; end if; elsif (krmicd.getDevType = 'DISK') then if (lformat is not NULL and instr(lformat, '%') = 0) then -- sys.dbms_backup_restore.isfileNameOMF(fname => lformat, isomf => isomf, isasm => isasm, istmplt => istmplt); end if; -- if (istmplt and isasm) then deb('raut_search', 'Searching ASM diskgroup ' || lformat); -- sys.dbms_backup_restore.searchFiles(pattern => lformat, ns => set_ns, omf => TRUE, ccf => FALSE, ftype => 'U'); found := sys.dbms_backup_restore.findAutSearchFileTable( mustspfile => mustspfile, until => date2stamp(trgt_date), fname => lhandle, year => year, month => month, day => day, sequence => tempseq, ats => ats); krmicd.writeMsg(8600, lformat); krmicd.writeMsg(8549, set_ns); if (found) then krmicd.writeMsg(8601, krmicd.getChid, lhandle, lformat); sft_date := year*10000+month*100+day; sft_seq := tempseq; sfthandle := lhandle; deb('raut_search', 'sft_date=' || sft_date || ' sft_seq=' || sft_seq); else krmicd.writeMsg(8602, krmicd.getChid, lformat); end if; end if; -- -- -- begin deb('raut_search', 'Searching recovery area ' || set_ra); sys.dbms_backup_restore.searchFiles(pattern => set_ra, ns => set_ns, omf => TRUE, ccf => FALSE, ftype => 'U'); found := sys.dbms_backup_restore.findAutSearchFileTable( mustspfile => mustspfile, until => date2stamp(trgt_date), fname => lhandle, year => year, month => month, day => day, sequence => tempseq, ats => ats); krmicd.writeMsg(8548, set_ra); krmicd.writeMsg(8549, set_ns); if (found) then krmicd.writeMsg(8546, krmicd.getChid, lhandle); tempdate := year*10000+month*100+day; if (sft_date < tempdate OR (sft_date = tempdate AND sft_seq < tempseq)) then if sfthandle is not null then deb('raut_search', 'Skipping autobackup ' || sfthandle || ' ;older than ' || lhandle); end if; sft_date := tempdate; sft_seq := tempseq; sfthandle := lhandle; deb('raut_search', 'sft_date=' || sft_date || ' sft_seq=' || sft_seq); else deb('raut_search', 'Skipping autobackup ' || lhandle || ' ;older than ' || sfthandle); end if; else krmicd.writeMsg(8547, krmicd.getChid); end if; exception when sys.dbms_backup_restore.ra_not_set then krmicd.clearErrors; end; end if; -- if not handle <> -- retry on *_not_in_bs errors from restoreBackupPiece -- -- -- if (sfthandle is not null) then outhandle := sfthandle; end if; -- -- if (istmplt and isasm) then goto raut_search_end; end if; -- -- if (handle is not null) then goto raut_search_end; end if; -- if (ldbid = 0) then krmicd.writeMsg(8550, lformat); goto raut_search_end; end if; -- begin deb('raut_search', 'Searching manually starting with day: ' || trgt_date || ' and sequence: ' || old_seq); found := FALSE; for days in 1..lmaxdays loop select to_char(trgt_date, 'YYYY', 'NLS_CALENDAR=Gregorian'), to_char(trgt_date, 'MM', 'NLS_CALENDAR=Gregorian'), to_char(trgt_date, 'DD', 'NLS_CALENDAR=Gregorian'), upper(set_ns) into lyear, lmonth, lday, uset_ns from x$dual; select sysdate into begtime from x$dual; deb('raut_search', 'Channel '||krmicd.getChid|| ' starting search for day '||lyear||lmonth||lday|| ' at '||begtime); tempdate := to_number(lyear||lmonth||lday); for tempseq in reverse 0..old_seq loop -- -- if (tempdate < sft_date OR (tempdate = sft_date AND tempseq < sft_seq)) then deb('raut_search', 'Skipping autobackup search; day ' || tempdate || ' older than ' || outhandle); found := TRUE; exit; end if; if krmicd.getAut(tempseq, lyear||lmonth||lday) = 1 then if (tempseq = old_seq) then krmicd.writeMsg(8535, krmicd.getChid, tempdate); end if; else abort := TRUE; exit; end if; lhandle := sys.dbms_backup_restore.genPieceName (pno => 0, set_count => 0, set_stamp => 0, format => lformat, copyno => 1, devtype => 'N/A', year => lyear, month => lmonth, day => lday, dbid => ldbid, ndbname => uset_ns, pdbname => NULL, cfseq => tempseq); if (mod(tempseq,10) = 0) then deb('raut_search', 'Channel '|| krmicd.getChid || ' looking for day: '|| lyear || lmonth || lday || ' sequence ' || tempseq || ' handle: '||lhandle); end if; -- status := sys.dbms_backup_restore.validateBackupPiece( recid => 0, stamp => 0, handle => lhandle, set_stamp => 0, set_count => 0, pieceno => 0, params => NULL, hdl_isdisk => 0); deb('raut_search', 'status=' || status); rc := bitand(status, sys.dbms_backup_restore.validate_file_different); deb('raut_search', 'rc=' || rc); if (rc = 0) then found := TRUE; aut_date := tempdate; aut_seq := tempseq; outhandle := lhandle; krmicd.writeMsg(8536, krmicd.getChid, lhandle); if (sfthandle is not null) then deb('raut_search', 'Skipping autobackup ' || sfthandle || ' ;older than ' || outhandle); end if; exit; end if; end loop; exit when (found OR abort); select sysdate, (sysdate-begtime)*60*24*60 into endtime, seconds from x$dual; deb('raut_search', 'Channel ' || krmicd.getChid || ' ending search for day ' || lyear || lmonth || lday || ' at ' || endtime ||' (elapsed: ' || seconds || ' seconds)'); old_seq := 255; trgt_date := trgt_date - 1; end loop; end; <> if outhandle is not null then -- if outhandle = sfthandle then aut_seq := sft_seq; aut_date := sft_date; -- -- sft_date := 0; sft_seq := 0; sfthandle := to_char(null); end if; -- -- -- -- -- -- if (krmicd.foundAut(aut_seq, aut_date) = 0) then abort := TRUE; else retval := krmicd.resAut(aut_seq, aut_date); while (retval = 2) loop sys.dbms_backup_restore.sleep(5); retval := krmicd.resAut(aut_seq, aut_date); end loop; if (retval = 0) then abort := TRUE; end if; if (retval = 1) then dorestore := TRUE; end if; end if; end if; if abort then krmicd.writeMsg(8537, krmicd.getChid); else if outhandle is null then if ldbid <> 0 then krmicd.writeMsg(8538, krmicd.getChid, lmaxdays); end if; krmicd.setNotFeasible; end if; end if; -- -- -- -- -- endstatus := krmicd.endAut; if preview then if not endstatus then krmicd.writeMsg(6172); krmicd.clearErrors; end if; return; end if; if not endstatus then -- -- -- raise dummy_error; end if; if vheader then return; end if; >>> define raut_cf <<< -- -- -- &1& sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); -- -- if aut_seq = 0 then trgt_date := trgt_date - 1; old_seq := 255; else old_seq := aut_seq - 1; end if; if dorestore then if not fromcopy then -- -- if validate then krmicd.writeMsg(8096, krmicd.getChid); elsif handle is null then krmicd.writeMsg(8553, krmicd.getChid, outhandle); else krmicd.writeMsg(8021, krmicd.getChid); end if; if (csf_retries = 0) then sys.dbms_backup_restore.restoreSetDataFile; setRestoreParams; if validate then sys.dbms_backup_restore.restorevalidate; else sys.dbms_backup_restore.restoreControlFileTo(cfname, isstby, nocfconv, isfarsync); end if; end if; begin sys.dbms_backup_restore.restoreBackupPiece(done => done, handle => outhandle, params => NULL); exception -- -- -- -- when sys.dbms_backup_restore.scf_not_in_bs then if (csf_retries = 3) or (handle is not null) then raise; end if; csf_retries := csf_retries + 1; krmicd.writeMsg(8133, krmicd.getChid); krmicd.writeMsg(8134, krmicd.getChid); krmicd.clearErrors; -- -- done := FALSE; abort := FALSE; dorestore := FALSE; endstatus := FALSE; outhandle := to_char(NULL); aut_seq := 0; aut_date := 0; goto retry; end; select abs(sysdate-start_time) into elapsed from x$dual; dur2time(elapsed, hours, mins, secs); if validate then krmicd.writeMsg(8182, krmicd.getChid, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); elsif handle is null then krmicd.writeMsg(8534, krmicd.getChid); else krmicd.writeMsg(8180, krmicd.getChid, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); end if; -- if currcf and not validate then print_controlfile; end if; else -- -- if validate then krmicd.writeMsg(8518, krmicd.getChid, outhandle); dummyscn := sys.dbms_backup_restore.scandatafilecopy( recid => recid, stamp => stamp, update_fuzziness => false, check_logical => false); else sys.dbms_backup_restore.copyControlFile(full_name => full_name, recid => recid, stamp => stamp, src_name => outhandle, dest_name => cfname); krmicd.writeMsg(8025, krmicd.getChid); end if; -- if currcf then print_controlfile; end if; end if; krmicd.fileRestored(ftype => rman_constant.CONTROLFILE, fno => 0, thread => 0, sequence => 0, resetscn => 0, resetstamp => 0); end if; sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0); end; >>> define raut_sf <<< -- -- &1& sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); -- -- if aut_seq = 0 then trgt_date := trgt_date - 1; old_seq := 255; else old_seq := aut_seq - 1; end if; if dorestore then krmicd.writeMsg(8554, krmicd.getChid, outhandle); -- if (csf_retries = 0) then sys.dbms_backup_restore.restoreSetDataFile; setRestoreParams; sys.dbms_backup_restore.restoreSpFileTo(pfname => pfname, sfname => sfname); end if; begin sys.dbms_backup_restore.restoreBackupPiece(done => done, handle => outhandle, params => NULL); exception -- -- -- -- -- when sys.dbms_backup_restore.spfile_not_in_bs then if (csf_retries = 3) or (handle is not null) then raise; end if; csf_retries := csf_retries + 1; krmicd.writeMsg(8117, krmicd.getChid); krmicd.writeMsg(8134, krmicd.getChid); krmicd.clearErrors; -- -- done := FALSE; abort := FALSE; dorestore := FALSE; endstatus := FALSE; outhandle := to_char(NULL); aut_seq := 0; aut_date := 0; goto retry; end; krmicd.fileRestored(ftype => rman_constant.SPFILE, fno => 0, thread => 0, sequence => 0, resetscn => 0, resetstamp => 0); krmicd.writeMsg(8541, krmicd.getChid); end if; sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0); end; >>> define refresh_agf <<< -- begin refreshAgedFiles; end; >>> define switch_tf <<< declare tsnum number; tsname varchar2(32); tfnum number; tfname varchar2(1024); create_time date; create_scn number; blocks number; blocksize binary_integer; rfnum number; exton boolean; isSFT boolean; maxsize number; nextsize number; missing boolean; rename boolean; pdbid number; begin loop exit when not krmicd.switchTempfile(tsnum, tsname, tfnum, tfname, create_time, create_scn, blocks, blocksize, rfnum, exton, isSFT, maxsize, nextsize, missing, rename, pdbid); deb('switch_tf', 'channel: '|| krmicd.getChid || ' tempfile= '|| tfname || ' tsname= ' || tsname || ' blocks= ' || blocks || ' blocksize= ' || blocksize || ' create_scn= ' || to_char(create_scn) || ' maxsize= ' || maxsize || ' nextsize= ' || nextsize || ' pdbid= ' || pdbid); sys.dbms_backup_restore.switchTempfile( tsnum => tsnum, tsname => tsname, tfnum => tfnum, tfname => tfname, create_time => create_time, create_scn => create_scn, blocks => blocks, blocksize => blocksize, rfnum => rfnum, exton => exton, isSFT => isSFT, maxsize => maxsize, nextsize => nextsize, pdbid => pdbid); if (missing) then krmicd.writeMsg(8184, tfname, tsname); elsif (rename) then krmicd.writeMsg(8185, to_char(tfnum), tfname); else krmicd.writeMsg(8186, tfname); end if; end loop; end; >>> define val_copies <<< -- declare objecttype number; handle varchar2(512); newname varchar2(512); recid number; stamp number; objkey1 number; objkey2 number; blksize number; ckpscn number; rlscn number; crescn number; rc number; found boolean; dummy boolean; &constants& internal_error exception; db_not_mounted exception; pragma exception_init(internal_error, -600); pragma exception_init(db_not_mounted, -1507); begin &object& loop found := FALSE; exit when not krmicd.valCopyGetNext( objecttype => objecttype, handle => handle, recid => recid, stamp => stamp, objkey1 => objkey1, objkey2 => objkey2, blksize => blksize, ckpscn => ckpscn, rlscn => rlscn, crescn => crescn, found => dummy); begin if (objecttype = krmiDC) then rc := sys.dbms_backup_restore.validateDataFileCopy( recid => recid, stamp => stamp, fname => handle, dfnumber => objkey1, resetlogs_change => rlscn, creation_change => crescn, checkpoint_change => ckpscn, blksize => blksize, signal => 0); if (bitand(rc, krmkvt_MISSING) != 0 or bitand(rc, krmkvt_MISSOK) != 0) then if (bitand(rc, krmkvt_FILE_DIFF) = 0 and bitand(rc, krmkvt_IN_USE) = 0 and bitand(rc, krmkvt_DEL_FOR_SPACE) = 0) then if (objkey1 = 0) then sys.dbms_backup_restore.inspectControlFile( fname => handle, full_name => newname, recid => recid, stamp => stamp); else sys.dbms_backup_restore.inspectDataFileCopy( fname => handle, full_name => newname, recid => recid, stamp => stamp); end if; deb('val_copies', 'new recid='||recid||' stamp='||stamp); end if; end if; elsif (objecttype = krmiPC) then rc := sys.dbms_backup_restore.proxyValOnly( recid => recid, stamp => stamp, handle => handle); elsif (objecttype = krmiRAL) then rc := sys.dbms_backup_restore.validateArchivedLog( recid => recid, stamp => stamp, fname => handle, thread => objkey1, sequence => objkey2, resetlogs_change => rlscn, first_change => crescn, blksize => blksize, signal => 0); else raise internal_error; end if; exception when internal_error then raise; when db_not_mounted then rc := 0; -- inspect should have failed but successfully validated krmicd.clearErrors; when others then rc := sys.dbms_backup_restore.validate_file_different; krmicd.writeErrMsg(1005, sqlerrm); krmicd.clearErrors; end; if (rc = 0 or rc = sys.dbms_backup_restore.validate_record_notfound) then found := TRUE; end if; if (krmicd.valCopySetFound(found, recid, stamp)) then deb('val_copies', 'chid: ' || krmicd.getChid || ' found ' || handle); end if; end loop; end; >>> define valhdr_copies <<< -- declare objecttype number; handle varchar2(512); recid number; stamp number; objkey1 number; objkey2 number; blksize number; ckpscn number; rlscn number; crescn number; found boolean; allfound boolean := TRUE; &constants& internal_error exception; pragma exception_init(internal_error, -600); begin &object& loop found := FALSE; exit when not krmicd.valCopyGetNext( objecttype => objecttype, handle => handle, recid => recid, stamp => stamp, objkey1 => objkey1, objkey2 => objkey2, blksize => blksize, ckpscn => ckpscn, rlscn => rlscn, crescn => crescn, found => found); if (not found) then allfound := FALSE; if (objecttype = krmiDC) then if (objkey1 != 0) then krmicd.writeMsg(6727, handle); else krmicd.writeMsg(6728, handle); end if; elsif (objecttype = krmiPC) then krmicd.writeMsg(8165, handle); elsif (objecttype = krmiRAL) then krmicd.writeMsg(6726, handle); else raise internal_error; end if; krmicd.setNotFeasible; end if; end loop; if (allfound) then if (objecttype = krmiDC) then krmicd.writeMsg(8166); elsif (objecttype = krmiPC) then krmicd.writeMsg(8164); elsif (objecttype = krmiRAL) then krmicd.writeMsg(6158); else raise internal_error; end if; end if; end; >>> define 'x$valhdr_pieces' <<< procedure valhdr_pieces(bskey in number) is recid number; stamp number; begin if not krmicd.valGetFound(recid, stamp) then krmicd.writeMsg(12017, bskey); krmicd.setNotFeasible; elsif (krmicd.isValAllFound) then krmicd.writeMsg(8163); end if; end; >>> define valhdr_pieces <<< begin valhdr_pieces(&object&); end; >>> define create_working_set <<< -- declare failureList sys.dbms_ir.ir_failure_list_type; firstcall binary_integer; adviseid number; failureId number; start_time date; elapsed number; hours number; mins number; secs number; begin &object& select sysdate into start_time from x$dual; if (adviseid is null) then firstcall := 1; loop exit when not krmicd.failureGetNext(firstcall, failureId); firstcall := 0; failureList(failureList.count + 1) := failureId; deb('create_working_set', 'added failureId = ' || failureId); end loop; sys.dbms_ir.getAdviseId(failureList => failureList, adviseid => adviseid); deb('create_working_set', 'adviseid = ' || adviseid); end if; krmicd.copyAdviseId(adviseid => adviseid); sys.dbms_ir.createWorkingRepairSet(adviseid => adviseid); select sysdate - start_time into elapsed from x$dual; dur2time(elapsed, hours, mins, secs); deb('create_working_set', 'took ' || to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); end; >>> define update_feasibility_check <<< -- declare firstcall binary_integer; adviseid number; feasible_int binary_integer; repairFeasList sys.dbms_ir.ir_repair_feasibility_list; repairFeasRec sys.dbms_ir.ir_repair_feasibility; start_time date; elapsed number; hours number; mins number; secs number; begin &object& select sysdate into start_time from x$dual; firstcall := 1; loop exit when not krmicd.repairGetNext( firstcall => firstcall, failureidx => repairFeasRec.failureidx, repairidx => repairFeasRec.repairidx, feasibility => repairFeasRec.feasibility); firstcall := 0; -- no more first call repairFeasList(repairFeasList.count + 1) := repairFeasRec; if (repairFeasRec.feasibility) then feasible_int := 1; else feasible_int := 0; end if; deb('update_feasibility_check', 'failureidx=' || repairFeasRec.failureidx || ' repairidx=' || repairFeasRec.repairidx || ' feasible=' || feasible_int); end loop; if (repairFeasList.count > 0) then sys.dbms_ir.updateFeasibilityAndImpact( adviseid => adviseid ,repairList => repairFeasList); end if; sys.dbms_ir.consolidateRepair(adviseid => adviseid); select sysdate - start_time into elapsed from x$dual; dur2time(elapsed, hours, mins, secs); deb('update_feasibility_check', 'took: ' || to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); end; >>> define create_repair_script <<< -- declare firstcall binary_integer; filename varchar2(512); fileid number; cmdline varchar2(513); cmdscript sys.dbms_ir.ir_script_file_type; start_time date; elapsed number; hours number; mins number; secs number; begin select sysdate into start_time from x$dual; firstcall := 1; loop exit when not krmicd.scriptLineGetNext(firstcall, cmdline); if (firstcall != 0) then sys.dbms_ir.createScriptFile( fileid => fileid ,fileName => fileName); end if; deb('create_repair_script', 'cmdline=' || cmdline); firstcall := 0; cmdscript(cmdscript.count + 1) := cmdline; end loop; if (fileid is not null) then sys.dbms_ir.writeFile(fileid => fileid ,contents => cmdscript); sys.dbms_ir.closeScriptFile(fileid => fileid); krmicd.copyRepairScriptName(filename); end if; select sysdate - start_time into elapsed from x$dual; dur2time(elapsed, hours, mins, secs); deb('create_repair_script', 'took: ' || to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); end; >>> define update_repair_option <<< -- declare adviseid number; optionidx number; filename varchar2(512); start_time date; elapsed number; hours number; mins number; secs number; begin &object& select sysdate into start_time from x$dual; filename := krmicd.getRepairScriptName; deb('update_repair_option', 'script_name=' || filename); sys.dbms_ir.updateRepairOption( adviseid => adviseid ,optionidx => optionidx ,scriptname => filename); select sysdate - start_time into elapsed from x$dual; dur2time(elapsed, hours, mins, secs); deb('update_repair_option', 'took: ' || to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); end; >>> define advise_done <<< -- declare adviseid number; repairOptionList sys.dbms_ir.ir_repair_option_list; start_time date; elapsed number; hours number; mins number; secs number; begin &object& select sysdate into start_time from x$dual; sys.dbms_ir.advisedone( adviseid => adviseid ,generatedRepairs => repairOptionList); for i in 1..repairOptionList.count loop deb('advise_done', 'optionidx=' || repairOptionList(i).optionidx || ' repairid=' || repairOptionList(i).repairid); krmicd.copyRepairId( optionidx => repairOptionList(i).optionidx ,repairid => repairOptionList(i).repairid); end loop; select sysdate - start_time into elapsed from x$dual; dur2time(elapsed, hours, mins, secs); deb('advise_done', 'took: ' || to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); end; >>> define get_repair_script <<< -- declare repairid number; fileid number; cmdscript sys.dbms_ir.ir_script_file_type; start_time date; elapsed number; hours number; mins number; secs number; opendb boolean := TRUE; begin &object& select sysdate into start_time from x$dual; sys.dbms_ir.openScriptFile( repairid => repairid ,fileid => fileid); sys.dbms_ir.getFile( fileid => fileid ,contents => cmdscript); sys.dbms_ir.closeScriptFile(fileid => fileid); for i in 1..cmdscript.count loop deb('get_repair_script', 'cmdline=' || cmdscript(i)); if (not opendb and cmdscript(i) like '%alter database open resetlogs%') then deb('get_repair_script', 'skipping open resetlogs'); else krmicd.scriptLineCopyNext(cmdscript(i)); end if; end loop; select sysdate - start_time into elapsed from x$dual; dur2time(elapsed, hours, mins, secs); deb('get_repair_script', 'took: ' || to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); end; >>> define repair_desc <<< #&^desc& >>> define repair_spec_end <<< ) >>> define repair_command_end <<< ; >>> define repair_add_fservice <<< from service &^1& >>> define repair_add_df <<< datafile &^1& >>> define repair_add_df_spec <<< ( datafile &^1& >>> define repair_add_block <<< datafile &2& block &^1& >>> define repair_add_arg <<< &^1& >>> define repair_fc_restore_df_only <<< restore validate header >>> define repair_fc_restore_df <<< restore validate header preview >>> define repair_rs_restore_df <<< restore >>> define repair_fc_recover_df <<< recover validate header preview >>> define repair_rs_recover_df <<< recover >>> define repair_fc_offline_df <<< declare open_inst binary_integer; mount_inst binary_integer; total_inst binary_integer; system_tbs binary_integer; noarchivelog binary_integer; online_rw binary_integer; feasibility boolean := TRUE; type numTab_t is table of number index by binary_integer; dfnol numTab_t; begin &1& select count(case when status = 'OPEN' then 1 else 0 end), count(case when status = 'MOUNTED' then 1 else 0 end), count(*) into open_inst, mount_inst, total_inst from gv$instance; deb('fc_offline_df', 'open_inst=' || open_inst || ' mount_inst=' || mount_inst || ' total_inst=' || total_inst); if (open_inst != total_inst OR mount_inst != total_inst) then feasibility := FALSE; end if; select count(*) into noarchivelog from v$database where log_mode = 'NOARCHIVELOG'; deb('fc_offline_df', 'noarchivelog=' || noarchivelog); for i in 1..dfnol.count loop exit when not feasibility; select count(*) into system_tbs from (select fe.fenum file#, fe.fetsn ts#, fe.con_id from x$kccfe fe where fe.fedup != 0) df, v$tablespace ts where ts.name = 'SYSTEM' and ts.ts# = df.ts# and df.con_id = ts.con_id and df.file# = dfnol(i); deb('fc_offline_df', 'dfno=' || dfnol(i)); deb('fc_offline_df', 'system_tbs=' || system_tbs); if (system_tbs > 0) then feasibility := FALSE; else select count(*) into online_rw from (select fe.fenum file#, decode(fe.fetsn, 0, decode(bitand(fe.festa,2), 0, 'SYSOFF', 'SYSTEM'), decode(bitand(fe.festa,18), 0, 'OFFLINE', 2, 'ONLINE', 'RECOVER')) status, decode(fe.fedor, 2,'READ ONLY', decode(bitand(fe.festa, 12), 0, 'DISABLED', 4, 'READ ONLY', 12, 'READ WRITE', 'UNKNOWN')) enabled from x$kccfe fe where fe.fedup != 0) df where df.status = 'ONLINE' and df.enabled = 'READ WRITE' and df.file# = dfnol(i); deb('fc_offline_df', 'online_rw=' || online_rw); if (noarchivelog > 0 and online_rw > 0) then feasibility := FALSE; end if; end if; end loop; if (feasibility) then deb('fc_offline_df', 'feasibility=TRUE'); else deb('fc_offline_df', 'feasibility=FALSE'); krmicd.setNotFeasible; end if; end; >>> define repair_rs_alter_df <<< sql&2& 'alter database datafile &^1& >>> define repair_rs_offline_df <<< offline'; >>> define repair_rs_online_df <<< online'; >>> define repair_fc_restore_db_only <<< restore database validate header; >>> define repair_fc_restore_db_only_fservice <<< restore database validate header from service&^1&; >>> define repair_fc_restore_db <<< restore database validate header preview; >>> define repair_fc_rstore_db_fservice <<< restore database validate header preview from service&^1&; >>> define repair_fc_restore_dbpitr <<< restore database validate header preview until scn &^untscn&; >>> define repair_rs_restore_db <<< restore database; >>> define repair_rs_restore_db_fservice <<< restore database from service&^1&; >>> define repair_rs_reset_incarnation <<< reset database to incarnation &^1&; >>> define repair_rs_restore_dbpitr <<< restore database until scn &^untscn&; >>> define repair_fc_recover_db <<< recover validate header preview database; >>> define repair_fc_recover_dbpitr <<< recover validate header preview database until scn &^untscn&; >>> define repair_rs_recover_db <<< recover database; >>> define repair_rs_recover_dbpitr <<< recover database until scn &^untscn&; >>> define repair_rs_open_resetlogs <<< alter database open resetlogs; >>> define repair_fc_flashback_db <<< flashback validate header preview database to before scn &^1&; >>> define repair_rs_flashback_db <<< flashback database to before scn &^1&; >>> define repair_fc_bmr <<< recover validate header preview >>> define repair_rs_bmr <<< recover >>> define repair_fc_restore_ctl <<< restore validate header preview controlfile&^1&; >>> define repair_fc_restore_ctl_fservice <<< restore validate header preview from service&^1& controlfile; >>> define repair_rs_set_dbid <<< set dbid&^1&; >>> define repair_rs_restore_ctl <<< restore controlfile&^1&; sql 'alter database mount'; >>> define repair_rs_restore_ctl_fservice <<< restore controlfile from service&^1&; sql 'alter database mount'; >>> define repair_rs_restart_db <<< shutdown; startup nomount; >>> define repair_fc_replicate_ctl <<< declare feasibility boolean := FALSE; cfname v$controlfile.name%type; begin for i in 1..9999 loop cfname := sys.dbms_backup_restore.getparm( sys.dbms_backup_restore.control_file, i); exit when cfname is null; feasibility := sys.dbms_ir.controlfilecheck(cfname => cfname); if (feasibility) then deb('repair_fc_replicate_ctl', cfname || ' feasible'); else deb('repair_fc_replicate_ctl', cfname || ' not feasible'); end if; exit when feasibility; end loop; if (feasibility) then krmicd.copyReplicateCtlFrom(cfname => cfname); else krmicd.setNotFeasible; end if; end; >>> define repair_rs_replicate_ctl <<< restore controlfile from&^1&; sql 'alter database mount'; >>> define repair_fc_sqlscript <<< declare repairtype number; feasibility boolean; dataloss number; repairtime number; parameterlist varchar2(2048); impact varchar2(256); begin -- &1& sys.dbms_ir.getFeasibilityAndImpact( repairtype => repairtype ,parameterlist => parameterlist ,feasibility => feasibility ,dataloss => dataloss ,repairtime => repairtime ,impact => impact); if (feasibility) then deb('fc_sqlscript', 'feasibility=TRUE'); else deb('fc_sqlscript', 'feasibility=FALSE'); krmicd.setNotFeasible; end if; end; >>> define repair_rs_sqlscript <<< sql "begin sys.dbms_ir.execsqlscript(filename =>&1&); end;"; >>> define repair_fc_force_openreset <<< declare repairtype number; feasibility boolean; dataloss number; repairtime number; parameterlist varchar2(2048); impact varchar2(256); begin -- &1& sys.dbms_ir.getFeasibilityAndImpact( repairtype => repairtype ,parameterlist => null ,feasibility => feasibility ,dataloss => dataloss ,repairtime => repairtime ,impact => impact); if (feasibility) then deb('fc_force_openreset', 'feasibility=TRUE'); else deb('fc_force_openreset', 'feasibility=FALSE'); krmicd.setNotFeasible; end if; end; >>> define repair_rs_force_openreset <<< sql 'alter database recover database until cancel'; alter database open resetlogs; >>> define res_xtt_start <<< -- declare /* restoreStatus */ state binary_integer; pieces_done binary_integer; files binary_integer; datafiles boolean; incremental boolean; device boolean; typefno boolean := FALSE; typets boolean := FALSE; typefall boolean := FALSE; typedfcopy boolean := FALSE; /* setRmanStatusRowId */ rsid number; rsts number; /* restoreSetXttfile */ pltfrmfr number; /* restoreXttFileTo */ xfno number; xfname varchar2(512) := NULL; xtsname varchar2(30); /* restoreXttSetPiece */ handle varchar2(512); xplugfile varchar2(512) := NULL; doxttplug boolean := FALSE; /* restoreDmpfile */ fulldmpfile varchar2(512) := NULL; dmpfile varchar2(512) := NULL; dpdest varchar2(512) := NULL; /* restoreXttBPiece */ done boolean; /* Statistical variables */ start_time date; elapsed number; hours number; mins number; secs number; piecenum number; memnum number; otag varchar2(31); failo boolean := FALSE; chtype varchar2(16); fromdisk boolean := FALSE; first_time boolean := TRUE; files_named boolean := FALSE; doimport boolean := FALSE; remdmpfile boolean := TRUE; xttsincr boolean := FALSE; doplugfcnv boolean := FALSE; restore_not_complete exception; /* Transportable tablespace encryption */ jobname varchar2(512) := NULL; passphrase varchar2(128) := NULL; begin &1& -- rsid, rsts, platform sys.dbms_backup_restore.restoreStatus(state, pieces_done, files, datafiles, incremental, device); select sysdate into start_time from x$dual; -- -- krmicd.getExportJobName(jobname, passphrase); if state = sys.dbms_backup_restore.restore_no_conversation then goto start_convo; elsif state = sys.dbms_backup_restore.restore_naming_files then goto name_files; else goto restore_piece; end if; <> sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts); sys.dbms_backup_restore.restoreSetXttfile(pltfrmfr, xttsincr); setRestoreParams; krmicd.writeMsg(8016, krmicd.getChid); if (passphrase is not null) then sys.dbms_backup_restore.setExportJobName(jobname, passphrase); passphrase := null; end if; <> >>> define res_xtt_fname <<< -- &1& -- xfno, xtsname, xfname, memnum if files < memnum then if first_time then krmicd.writeMsg(8089, krmicd.getChid); first_time := FALSE; end if; if typefall then sys.dbms_backup_restore.restoreXttFileTo( sys.dbms_backup_restore.xtt_all, NULL, NULL, xfname); krmicd.writeMsg(8622, krmicd.getChid); elsif typets then sys.dbms_backup_restore.restoreXttFileTo( sys.dbms_backup_restore.xtt_tablespace, NULL, xtsname, xfname); krmicd.writeMsg(8623, krmicd.getChid, xtsname); elsif typefno then sys.dbms_backup_restore.restoreXttFileTo( sys.dbms_backup_restore.xtt_fileno, xfno, NULL, xfname); krmicd.writeMsg(8624, krmicd.getChid, to_char(xfno, 'FM09999')); elsif typedfcopy then sys.dbms_backup_restore.applyDataFileTo( dfnumber => 1, toname => xfname, fuzziness_hint => 0, max_corrupt => 0, islevel0 => 1, recid => 0, stamp => 0); krmicd.writeMsg(8624, krmicd.getChid, xfname); end if; end if; >>> define res_name_dmpfile <<< -- &1& -- dmpfile, dpdest, fulldmpfile, memnum, doimport, remdmpfile if files < memnum then if first_time then krmicd.writeMsg(8089, krmicd.getChid); first_time := FALSE; end if; krmicd.writeMsg(8625, krmicd.getChid, fulldmpfile); sys.dbms_backup_restore.restoreDmpfile(dmpfile => fulldmpfile); end if; >>> define res_xtt_do <<< -- &1& -- handle, piecenum, xplugfile, doplugfcnv if (pieces_done + 1) = piecenum then krmicd.writeMsg(8003, krmicd.getChid, handle); begin if xplugfile IS NOT NULL then sys.dbms_backup_restore.parsePlugXmlFile(xplugfile); doxttplug := TRUE; end if; end; loop begin if xttsincr then chtype := krmicd.getDevType; if chtype = 'DISK' then fromdisk := TRUE; end if; sys.dbms_backup_restore.restoreSetPiece( handle => handle, tag => null, fromdisk => fromdisk, recid => null, stamp => null); sys.dbms_backup_restore.restoreBackupPiece( done => done, params => null, outhandle => handle, outtag => otag, failover => failo); files_named := TRUE; else sys.dbms_backup_restore.XttRestore(handle, done); files_named := TRUE; end if; exception when sys.dbms_backup_restore.xtts_name_files then krmicd.clearErrors; loop xfno := sys.dbms_backup_restore.getXttsName(xfname); exit when xfno = 0; krmicd.writeMsg(8626, krmicd.getChid, xfno, xfname); krmicd.addxttfile(xfno, xfname); end loop; when others then raise; end; exit when files_named; end loop; krmicd.writeMsg(8627, krmicd.getChid, handle); krmicd.writeMsg(8023, krmicd.getChid, to_char(piecenum)); if done then select abs(sysdate - start_time) into elapsed from x$dual; dur2time(elapsed, hours, mins, secs); krmicd.writeMsg(8180, krmicd.getChid, to_char(hours, 'FM09') || ':' || to_char(mins, 'FM09') || ':' || to_char(secs, 'FM09')); if doimport then deb('xtt-restore', 'Calling doxttimport'); krmicd.doxttimport(dpdest, dmpfile); end if; if doxttplug then krmicd.isRestorePlugin(true); loop xfno := sys.dbms_backup_restore.getXttsPlugName(xfname); exit when xfno = 0; krmicd.writeMsg(8430, krmicd.getChid, xfno, xfname); krmicd.addxttfile(xfno, xfname); end loop; deb('xtt-restore', 'Calling doxttplug'); krmicd.doxttplug(xplugfile, doplugfcnv); krmicd.isRestorePlugin(false); end if; sys.dbms_backup_restore.restoreCancel(TRUE); deb('xtt-restore', 'Done'); return; end if; pieces_done := pieces_done + 1; end if; >>> define res_xtt_end <<< -- krmicd.writeMsg(8001); begin sys.dbms_backup_restore.restoreCancel(FALSE); exception when others then krmicd.writeMsg(1005, 'a. dbms_backup_restore.restoreCancel() failed'); end; raise restore_not_complete; end; >>> #STOPSTOP <--- This is where krmk.pc stops parsing during initialization define db <<< CREATE TABLE db ( db_key NUMBER NOT NULL, -- sequence generated primary key db_id NUMBER NOT NULL, -- kccfhdbi from controlfile reg_db_unique_name VARCHAR2(30), -- primary db unique name given -- -- curr_dbinc_key NUMBER, -- current incarnation storage_prov VARCHAR(1) DEFAULT 'N', -- 'Y' if storage is provisioned -- CONSTRAINT db_p PRIMARY KEY (db_key), -- db_key is primary key CONSTRAINT db_u1 UNIQUE(db_id) -- ensure that db_id is unique ) &tablespace& >>> define db_insert_trigger <<< create or replace trigger db_insert_trigger before insert on db for each row declare is_owner number; is_auth number; can_add number; begin -- -- -- -- select count(*) into is_owner from user_users where username=user; if is_owner > 0 then return; end if; select count(*) into is_auth from vpc_databases where filter_uid = uid and db_id <> 0 and db_id = :new.db_id; if is_auth > 0 then return; end if; update vpc_databases set db_id = :new.db_id, reg_db_unique_name = null where filter_uid = uid and db_id = 0 and reg_db_unique_name = :new.reg_db_unique_name; if sql%rowcount = 1 then return; end if; select count(*) into can_add from vpc_users where filter_uid = uid and add_new_db = 'Y'; if can_add = 0 then raise_application_error(num => -20012, msg => 'not authorized to add new database'); end if; -- -- -- -- -- insert into vpc_databases(filter_user, filter_uid, db_id) values(user, uid, :new.db_id); end; >>> define rman_seq <<< CREATE SEQUENCE rman_seq MAXVALUE 18446744073709551615 CACHE 100 ORDER NOCYCLE >>> define conf <<< CREATE TABLE conf ( db_key NUMBER NOT NULL, -- db to which this configuration -- conf# NUMBER NOT NULL, -- configuration number -- name VARCHAR2(65) NOT NULL, -- configuration name value VARCHAR2(1025), -- configuration value -- -- -- -- db_unique_name VARCHAR2(512) DEFAULT NULL, site_key NUMBER DEFAULT 0 NOT NULL, -- -- -- -- -- -- cleanup VARCHAR2(3) DEFAULT 'YES', CONSTRAINT conf_f1 FOREIGN KEY(db_key) REFERENCES db ON DELETE CASCADE ) &tablespace& >>> define conf_i_db <<< CREATE INDEX conf_i_db on conf(db_key) &tablespace& >>> define 'node' <<< CREATE TABLE node ( db_unique_name VARCHAR2(512), -- Instance site name db_key NUMBER NOT NULL, high_conf_recid NUMBER DEFAULT 0 NOT NULL, -- last configuration recid seen force_resync2cf VARCHAR2(3) DEFAULT 'NO' NOT NULL, -- high_rout_stamp NUMBER default 0, inst_startup_stamp NUMBER default 0, -- -- -- -- -- database_role VARCHAR2(7) DEFAULT 'PRIMARY' NOT NULL, site_key NUMBER DEFAULT 0 NOT NULL, last_kccdivts NUMBER DEFAULT 0, -- for incarnation resync high_ic_recid NUMBER DEFAULT 0, -- recid based incarnation resync cf_create_time DATE, -- cf version_time at last resync -- -- dbinc_key NUMBER DEFAULT 0 NOT NULL, -- incarnation of ckp_scn ckp_scn NUMBER DEFAULT 0 NOT NULL, -- cf ckp scn at last full resync full_ckp_cf_seq NUMBER DEFAULT 0 NOT NULL, -- cf seq at last full resync job_ckp_cf_seq NUMBER DEFAULT 0 NOT NULL, -- cf seq at last partial resync high_ts_recid NUMBER, -- tablespace recid high_df_recid NUMBER, -- datafile recid high_rt_recid NUMBER, -- redo thread recid high_orl_recid NUMBER, -- online redo log recid high_offr_recid NUMBER DEFAULT 0 NOT NULL, -- offline range (kkor) recid high_rlh_recid NUMBER DEFAULT 0 NOT NULL, -- log history (kcclh) recid high_al_recid NUMBER DEFAULT 0 NOT NULL, -- archived log (kccal) recid high_bs_recid NUMBER DEFAULT 0 NOT NULL, -- backup set (kccbs) recid high_bp_recid NUMBER DEFAULT 0 NOT NULL, -- backup piece (kccbp) recid high_bdf_recid NUMBER DEFAULT 0 NOT NULL, -- backup datafile (kccbf) recid high_cdf_recid NUMBER DEFAULT 0 NOT NULL, -- datafile copy (kccdc) recid high_brl_recid NUMBER DEFAULT 0 NOT NULL, -- backup redo log (kccbl) recid high_bcb_recid NUMBER DEFAULT 0 NOT NULL, -- backup datafile corruption recid high_ccb_recid NUMBER DEFAULT 0 NOT NULL, -- datafile copy corruption recid high_do_recid NUMBER DEFAULT 0 NOT NULL, -- deleted object recid high_pc_recid NUMBER DEFAULT 0 NOT NULL, -- proxy copy (kccpc) recid high_bsf_recid NUMBER DEFAULT 0 NOT NULL, -- backup SPFILE (kccbi) recid high_rsr_recid NUMBER DEFAULT 0 NOT NULL, -- RMAN status (kccrsr) recid high_tf_recid NUMBER DEFAULT 0 NOT NULL, -- tempfile recid high_grsp_recid NUMBER DEFAULT 0 NOT NULL, -- guaranteed restore point recid high_nrsp_recid NUMBER DEFAULT 0 NOT NULL, -- normal restore point recid high_bcr_recid NUMBER DEFAULT 0 NOT NULL, -- high blk crpt (kccblkcor) recid low_bcr_recid NUMBER DEFAULT 0 NOT NULL, -- low blk crpt (kccblkcor) recid high_pdb_recid NUMBER, -- pluggable database recid high_pic_recid NUMBER DEFAULT 0 NOT NULL, -- pluggable dbinc recid bcr_in_use VARCHAR2(3) DEFAULT 'NO' NOT NULL, -- bp_key_poll NUMBER DEFAULT 0 NOT NULL, -- Feedback given to control file -- db_timezone VARCHAR2(64), -- Time Zone of database timezone_src VARCHAR2(1), -- 'A' - from OAM admin -- -- -- CONSTRAINT node_p PRIMARY KEY (site_key), CONSTRAINT check_site_key CHECK (site_key > 0), CONSTRAINT node_f1 FOREIGN KEY(db_key) REFERENCES db ON DELETE CASCADE, CONSTRAINT node_u1 UNIQUE (db_key, db_unique_name), -- -- -- CONSTRAINT check_database_role_c2 CHECK ((substr(db_unique_name,1,1) = '$' AND database_role = 'RA') OR (substr(nvl(db_unique_name, 'A'),1,1) <> '$' AND database_role IN ('PRIMARY', 'STANDBY'))), CONSTRAINT check_timezone_src CHECK (timezone_src IN ('A', 'P','R','S')) ) &tablespace& >>> define dbinc <<< CREATE TABLE dbinc ( dbinc_key NUMBER NOT NULL, -- sequence generated primary key db_key NUMBER NOT NULL, -- database to which this incarnation -- db_name VARCHAR2(8) NOT NULL, -- current db_name reset_scn NUMBER NOT NULL, -- SCN of last resetlogs reset_time DATE NOT NULL, -- timestamp of last resetlogs parent_dbinc_key NUMBER, -- parent incarnation -- dbinc_status VARCHAR2(8) DEFAULT 'ORPHAN' NOT NULL, dbinc_timezone VARCHAR2(64), -- timezone of incarnation -- -- CONSTRAINT dbinc_status CHECK(dbinc_status in ('CURRENT', 'PARENT', 'ORPHAN')), CONSTRAINT dbinc_p PRIMARY KEY(dbinc_key), CONSTRAINT dbinc_u1 UNIQUE (db_key, reset_scn, reset_time), CONSTRAINT dbinc_f1 FOREIGN KEY(db_key) REFERENCES db ON DELETE CASCADE ) &tablespace& >>> define db_f1 <<< ALTER TABLE db ADD CONSTRAINT db_f1 FOREIGN KEY(curr_dbinc_key) REFERENCES dbinc >>> define pdb <<< CREATE TABLE pdb ( pdb_key NUMBER, db_key NUMBER NOT NULL, -- db to which this pdb belongs name VARCHAR2(128), -- PDB name con_id NUMBER NOT NULL, -- container id db_id NUMBER NOT NULL, -- database id of the PDB create_scn NUMBER NOT NULL, guid RAW(16) NOT NULL, -- guid of PDB nobackup VARCHAR2(1) DEFAULT 'N' NOT NULL, -- CONSTRAINT pdb_p PRIMARY KEY (pdb_key), CONSTRAINT pdb_u1 UNIQUE (db_key, guid), CONSTRAINT pdb_f1 FOREIGN KEY(db_key) REFERENCES db ON DELETE CASCADE, CONSTRAINT pdb_c1 CHECK (create_scn > 0), CONSTRAINT pdb_c_nobackup CHECK (nobackup in ('Y','N')) ) &tablespace& >>> define pdb_i_1 <<< CREATE INDEX pdb_i_1 on pdb(db_key) &tablespace& >>> define pdb_i_2 <<< CREATE INDEX pdb_i_2 on pdb(db_key, guid, pdb_key) &tablespace& >>> define pdbinc <<< CREATE TABLE pdbinc ( pdbinc_key NUMBER NOT NULL, -- sequence generated primary key pdb_key NUMBER NOT NULL, -- pdb to which this inc belongs born_dbinc_key NUMBER NOT NULL, -- dbinc at which this pdbinc is born inc_scn NUMBER NOT NULL, -- incarnation scn begin_reset_scn NUMBER NOT NULL, -- begin resetlogs scn begin_reset_time DATE NOT NULL, -- timestamp of begin resetlogs end_reset_scn NUMBER NOT NULL, -- end resetlogs scn parent_pdbinc_key NUMBER, -- parent incarnation -- pdbinc_status VARCHAR2(8) DEFAULT 'ORPHAN' NOT NULL, CONSTRAINT pdbinc_status CHECK( pdbinc_status in ('CURRENT', 'PARENT', 'ORPHAN')), CONSTRAINT pdbinc_p PRIMARY KEY(pdbinc_key), CONSTRAINT pdbinc_u1 UNIQUE (pdb_key, born_dbinc_key, end_reset_scn), CONSTRAINT pdbinc_f1 FOREIGN KEY(pdb_key) REFERENCES pdb ON DELETE CASCADE, CONSTRAINT pdbinc_f2 FOREIGN KEY(born_dbinc_key) REFERENCES dbinc ON DELETE CASCADE, CONSTRAINT pdbinc_c1 CHECK (end_reset_scn >= inc_scn) ) &tablespace& >>> define pdbinc_i_1 <<< CREATE INDEX pdbinc_i_1 on pdbinc(pdbinc_status, pdb_key) &tablespace& >>> define pdb_dbinc <<< CREATE TABLE pdb_dbinc ( dbinc_key NUMBER NOT NULL, pdb_key NUMBER NOT NULL, drop_scn NUMBER, drop_time DATE, -- curr_pdbinc_key NUMBER, -- current incarnation CONSTRAINT pdb_dbinc_p PRIMARY KEY (dbinc_key, pdb_key), CONSTRAINT pdb_dbinc_f1 FOREIGN KEY(pdb_key) REFERENCES pdb ON DELETE CASCADE, CONSTRAINT pdb_dbinc_f2 FOREIGN KEY(dbinc_key) REFERENCES dbinc ON DELETE CASCADE ) &tablespace& >>> define ckp <<< CREATE TABLE ckp ( ckp_key NUMBER NOT NULL, -- primary key ckp_scn NUMBER NOT NULL, -- controlfile checkpoint scn ckp_time DATE, -- controlfile checkpoint timestamp ckp_cf_seq NUMBER NOT NULL, -- controlfile sequence cf_create_time DATE NOT NULL, -- controlfile version_time -- -- dbinc_key NUMBER NOT NULL, -- database incarnation ckp_type VARCHAR2(7) NOT NULL, -- resync type, 'FULL' or 'PARTIAL' ckp_db_status VARCHAR2(7), -- 'OPEN' or 'MOUNTED' or NULL resync_time DATE NOT NULL, -- resync time site_key NUMBER DEFAULT 0 NOT NULL, CONSTRAINT ckp_p PRIMARY KEY (ckp_key), -- -- -- CONSTRAINT ckp_u1 UNIQUE (dbinc_key, ckp_scn, ckp_type, ckp_cf_seq, cf_create_time), CONSTRAINT ckp_f1 FOREIGN KEY (dbinc_key) -- checkpoint belongs to a dbinc REFERENCES dbinc ON DELETE CASCADE, CONSTRAINT ckp_f3 FOREIGN KEY (site_key) -- checkpoint belongs to a site REFERENCES node ON DELETE CASCADE, CONSTRAINT ckp_c_type CHECK (ckp_type in ('FULL', 'PARTIAL')) ) &tablespace& >>> define ts <<< CREATE TABLE ts ( dbinc_key NUMBER NOT NULL, -- database incarnation ts# NUMBER NOT NULL, -- tablespace id in target db ts_name VARCHAR2(30) NOT NULL, -- tablespace name create_scn NUMBER NOT NULL, -- creation SCN (from 1st datafile) create_time DATE, -- creation time plugin_scn NUMBER DEFAULT 0 NOT NULL, -- plugin SCN bigfile VARCHAR2(3) DEFAULT 'NO' NOT NULL, -- -- -- temporary VARCHAR2(3) DEFAULT 'NO' NOT NULL, -- -- -- -- drop_scn NUMBER, -- drop SCN (as calculated) -- drop_time DATE, -- drop time included_in_database_backup VARCHAR2(3) DEFAULT 'YES' NOT NULL, -- -- -- encrypt_in_backup VARCHAR2(3), -- -- -- -- pdbinc_key NUMBER NOT NULL, CONSTRAINT ts_p2 PRIMARY KEY (dbinc_key, pdbinc_key, ts#, create_scn, plugin_scn), CONSTRAINT ts_u5 UNIQUE (dbinc_key, pdbinc_key, ts_name, create_scn, plugin_scn), CONSTRAINT ts_u4 UNIQUE (dbinc_key, pdbinc_key, ts#, drop_scn), CONSTRAINT ts_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE, CONSTRAINT ts_f2 FOREIGN KEY (pdbinc_key) REFERENCES pdbinc ON DELETE CASCADE ) &tablespace& >>> define tsatt <<< CREATE TABLE tsatt ( dbinc_key NUMBER NOT NULL, -- database incarnation ts# NUMBER NOT NULL, -- tablespace id in target db create_scn NUMBER NOT NULL, -- creation SCN plugin_scn NUMBER DEFAULT 0 NOT NULL, -- plugin SCN start_ckp_key NUMBER NOT NULL, -- ckp when first observed end_ckp_key NUMBER, -- ckp when changed; NULL->current rbs_count NUMBER, -- number of rollback segs in this ts -- pdbinc_key NUMBER NOT NULL, CONSTRAINT tsatt_u3 UNIQUE (dbinc_key, pdbinc_key, ts#, create_scn, plugin_scn, end_ckp_key), CONSTRAINT tsatt_f2 FOREIGN KEY (start_ckp_key) REFERENCES ckp, CONSTRAINT tsatt_f3 FOREIGN KEY (end_ckp_key) REFERENCES ckp, CONSTRAINT tsatt_f5 FOREIGN KEY (dbinc_key, pdbinc_key, ts#, create_scn, plugin_scn) REFERENCES ts ON DELETE CASCADE INITIALLY DEFERRED, CONSTRAINT tsatt_f6 FOREIGN KEY (pdbinc_key) REFERENCES pdbinc ON DELETE CASCADE ) &tablespace& >>> define df <<< CREATE TABLE df ( dbinc_key NUMBER NOT NULL, -- database incarnation file# NUMBER NOT NULL, -- database file number create_scn NUMBER NOT NULL, -- creation SCN create_time DATE, -- creation timestamp ts# NUMBER NOT NULL, -- tablespace id in target db ts_create_scn NUMBER NOT NULL, -- tablespace creation SCN block_size NUMBER NOT NULL, -- blocksize -- clone_fname VARCHAR2(1024), -- clone datafile name (alias aux_name) drop_scn NUMBER, -- drop SCN (as calculated) -- drop_time DATE, -- drop time stop_scn NUMBER, -- offline clean or read only scn stop_time DATE, -- timestamp for above SCN read_only NUMBER NOT NULL, -- 1 if stop_scn is read only, else 0 rfile# NUMBER, -- tablespace relative file number df_key NUMBER NOT NULL, blocks NUMBER, -- size of file foreign_dbid NUMBER DEFAULT 0 NOT NULL, foreign_create_scn NUMBER DEFAULT 0 NOT NULL, foreign_create_time DATE, plugged_readonly VARCHAR2(3) DEFAULT 'NO' NOT NULL, plugin_scn NUMBER DEFAULT 0 NOT NULL, plugin_reset_scn NUMBER DEFAULT 0 NOT NULL, plugin_reset_time DATE, create_thread NUMBER, -- null means unknown, 0 not recreatable create_size NUMBER, -- null means unknown, 0 not recreatable pdbinc_key NUMBER NOT NULL, ts_pdbinc_key NUMBER NOT NULL, issft NUMBER, -- null means unknown ts_plugin_scn NUMBER DEFAULT 0 NOT NULL, -- tablespace plugin scn pdb_closed NUMBER DEFAULT 0 NOT NULL, -- 1 if pdb is closed, else 0 pdb_foreign_dbid NUMBER DEFAULT 0 NOT NULL, -- CONSTRAINT df_p1 PRIMARY KEY (dbinc_key, pdbinc_key, file#, create_scn, plugin_scn), CONSTRAINT df_u3 UNIQUE (dbinc_key, pdbinc_key, file#, drop_scn), CONSTRAINT df_u4 UNIQUE (dbinc_key, pdbinc_key, df_key), -- -- -- -- CONSTRAINT df_f6 FOREIGN KEY (dbinc_key, ts_pdbinc_key, ts#, ts_create_scn, ts_plugin_scn) REFERENCES ts ON DELETE CASCADE, CONSTRAINT df_f7 FOREIGN KEY (pdbinc_key) REFERENCES pdbinc ON DELETE CASCADE ) &tablespace& >>> define df_i_1 <<< CREATE INDEX df_i_1 on df(dbinc_key, ts_pdbinc_key, ts#, ts_create_scn, ts_plugin_scn) &tablespace& >>> define site_dfatt <<< CREATE TABLE site_dfatt ( fname VARCHAR2(1024), -- datafile name df_key NUMBER NOT NULL, site_key NUMBER NOT NULL, CONSTRAINT site_dfatt_p PRIMARY KEY (df_key, site_key), -- -- CONSTRAINT site_dfatt_f2 FOREIGN KEY (site_key) REFERENCES node ON DELETE CASCADE ) &tablespace& >>> define offr <<< CREATE TABLE offr ( offr_key NUMBER NOT NULL, dbinc_key NUMBER NOT NULL, -- database incarnation offr_recid NUMBER, -- offline range recid offr_stamp NUMBER, -- offline range stamp file# NUMBER NOT NULL, -- datafile number create_scn NUMBER NOT NULL, -- datafile creation scn offline_scn NUMBER NOT NULL, -- scn at datafile was taken offline online_scn NUMBER NOT NULL, -- online checkpoint SCN online_time DATE NOT NULL, -- online checkpoint time cf_create_time DATE, -- controlfile creation time CONSTRAINT offr_p PRIMARY KEY (offr_key), CONSTRAINT offr_u2 UNIQUE (dbinc_key, file#, create_scn, offline_scn, cf_create_time), CONSTRAINT offr_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE ) &tablespace& >>> define tf <<< CREATE TABLE tf ( dbinc_key NUMBER NOT NULL, -- database incarnation file# NUMBER NOT NULL, -- tempfile number create_scn NUMBER NOT NULL, -- creation SCN create_time DATE, -- creation timestamp ts# NUMBER NOT NULL, -- tablespace id in target db ts_create_scn NUMBER NOT NULL, -- tablespace creation SCN plugin_scn NUMBER DEFAULT 0 NOT NULL, -- always zero for temp files -- block_size NUMBER NOT NULL, -- blocksize rfile# NUMBER, -- tablespace relative file number tf_key NUMBER NOT NULL, pdb_key NUMBER NOT NULL, ts_pdbinc_key NUMBER NOT NULL, CONSTRAINT tf_p PRIMARY KEY (dbinc_key, file#, create_scn), -- -- -- -- -- -- -- -- -- -- CONSTRAINT tf_f4 FOREIGN KEY (pdb_key) REFERENCES pdb ON DELETE CASCADE ) &tablespace& >>> define tf_i_1 <<< CREATE INDEX tf_i_1 on tf(dbinc_key, ts_pdbinc_key, ts#, ts_create_scn, plugin_scn) &tablespace& >>> define site_tfatt <<< CREATE TABLE site_tfatt ( fname VARCHAR2(1024), -- datafile name tf_key NUMBER NOT NULL, site_key NUMBER NOT NULL, drop_scn NUMBER, -- drop SCN (as calculated) -- drop_time DATE, -- drop time blocks NUMBER, -- size of file in blocks autoextend VARCHAR2(3), max_size NUMBER, next_size NUMBER, CONSTRAINT site_tfatt_p PRIMARY KEY (tf_key, site_key), -- -- CONSTRAINT site_tfatt_f2 FOREIGN KEY (site_key) REFERENCES node ON DELETE CASCADE ) &tablespace& >>> define rr <<< CREATE TABLE rr ( rr_key NUMBER NOT NULL, dbinc_key NUMBER NOT NULL, -- database incarnation low_scn NUMBER NOT NULL, -- low SCN of the range high_scn NUMBER NOT NULL, -- high SCN of the range CONSTRAINT rr_p PRIMARY KEY (rr_key), CONSTRAINT rr_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE ) &tablespace& >>> define rt <<< CREATE TABLE rt ( dbinc_key NUMBER NOT NULL, -- database incarnation thread# NUMBER NOT NULL, -- thread number -- sequence# NUMBER NOT NULL, -- last log sequence number allocated enable_scn NUMBER, -- SCN of last enable enable_time DATE, -- timestamp of last enable disable_scn NUMBER, -- SCN of last disable disable_time DATE, -- timestamp of last disable status VARCHAR2(1) NOT NULL, -- 'D' -> disabled -- -- -- CONSTRAINT rt_p PRIMARY KEY (dbinc_key, thread#), CONSTRAINT rt_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE, CONSTRAINT rt_c1_status CHECK (status in ('D','E','O','I')) ) &tablespace& >>> define orl <<< CREATE TABLE orl ( dbinc_key NUMBER NOT NULL, -- database incarnation thread# NUMBER NOT NULL, -- thread number group# NUMBER NOT NULL, -- group number fname VARCHAR2(1024) NOT NULL, -- datafile name bytes NUMBER DEFAULT NULL, -- size of redolog type VARCHAR2(7) DEFAULT 'ONLINE', -- ONLINE or STANDBY site_key NUMBER, -- CONSTRAINT orl_f1 FOREIGN KEY (dbinc_key, thread#) REFERENCES rt ON DELETE CASCADE, CONSTRAINT orl_f2 FOREIGN KEY (site_key) REFERENCES node ON DELETE CASCADE ) &tablespace& >>> define orl_i_1 <<< CREATE INDEX orl_i_1 on orl(dbinc_key, thread#, group#) &tablespace& >>> define rlh <<< CREATE TABLE rlh ( rlh_key NUMBER NOT NULL, dbinc_key NUMBER NOT NULL, -- database incarnation rlh_recid NUMBER NOT NULL, -- log history recid from control file rlh_stamp NUMBER NOT NULL, -- log history stamp from control file thread# NUMBER NOT NULL, -- thread number sequence# NUMBER NOT NULL, -- log sequence number low_scn NUMBER NOT NULL, -- scn generated when switching in low_time DATE NOT NULL, next_scn NUMBER NOT NULL, -- scn generated when switching out status VARCHAR2(1), -- 'C' -> cleared CONSTRAINT rlh_p PRIMARY KEY (rlh_key), CONSTRAINT rlh_u1 UNIQUE (dbinc_key, thread#, sequence#, low_scn), CONSTRAINT rlh_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE, CONSTRAINT rlh_c_status CHECK (status in ('C')) ) &tablespace& >>> define al <<< CREATE TABLE al ( al_key NUMBER NOT NULL, dbinc_key NUMBER NOT NULL, -- database incarnation al_recid NUMBER NOT NULL, -- archive log recid from control file al_stamp NUMBER NOT NULL, -- archive log stamp from control file thread# NUMBER NOT NULL, -- thread number sequence# NUMBER NOT NULL, -- log sequence number low_scn NUMBER NOT NULL, -- scn generated when switching in low_time DATE NOT NULL, -- time low SCN allocated next_scn NUMBER NOT NULL, -- scn generated when switching out next_time DATE, -- time when next SCN allocated fname VARCHAR2(1024), -- archive log file name, -- fname_hashkey VARCHAR2(20), -- hashed fname for indexing archived VARCHAR2(1) NOT NULL, -- 'Y' -> archived log -- blocks NUMBER NOT NULL, -- number of blocks written block_size NUMBER NOT NULL, -- size of a block in bytes completion_time DATE NOT NULL, -- time the log was archived or copied is_standby VARCHAR2(1), -- 'Y' if standby, 'N' if primary status VARCHAR2(1) NOT NULL, dictionary_begin VARCHAR2(3), -- log contains start of logminer dict dictionary_end VARCHAR2(3), -- log contains end of logminer dict is_recovery_dest_file VARCHAR2(3) DEFAULT 'NO' NOT NULL, -- compressed VARCHAR2(3) DEFAULT 'NO', -- compressed creator VARCHAR2(7) DEFAULT NULL, terminal VARCHAR2(3) DEFAULT 'NO', -- 'YES' for terminal rcv log site_key NUMBER, -- Null when log owner is unknown CONSTRAINT al_p PRIMARY KEY (al_key), CONSTRAINT al_u1 UNIQUE (dbinc_key, al_recid, al_stamp, is_standby), CONSTRAINT al_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE, CONSTRAINT al_f2 FOREIGN KEY (site_key) REFERENCES node ON DELETE CASCADE, CONSTRAINT al_c_archived CHECK (archived in ('Y','N')), CONSTRAINT al_c_status CHECK (status in ('A','U','D','X')), CONSTRAINT al_c_is_standby CHECK (is_standby in ('Y','N')) ) &tablespace& >>> define al_i_fname_status <<< CREATE INDEX al_i_fname_status on al(fname_hashkey, status) &tablespace& >>> define al_i_2 <<< CREATE INDEX al_i_2 on al(dbinc_key, thread#, sequence#, low_scn) &tablespace& >>> define bs <<< CREATE TABLE bs ( bs_key NUMBER NOT NULL, -- sequence generated primary key db_key NUMBER NOT NULL, -- database bs_recid NUMBER, -- backup set recid from control file bs_stamp NUMBER, -- backup set stamp from control file set_stamp NUMBER NOT NULL, -- set_stamp from control file set_count NUMBER NOT NULL, -- set_count from control file bck_type VARCHAR2(1), -- 'D' -> full datafile -- -- incr_level NUMBER, -- incremental backup level (0 - 4) -- -- pieces NUMBER NOT NULL, -- number of backup pieces in the set start_time DATE, -- time when this backup started completion_time DATE, -- time when this backup completed status VARCHAR2(1), -- 'A' -> complete set of pieces avail -- -- controlfile_included -- Indicates if this backup set has VARCHAR2(7), -- a controlfile in it -- -- -- -- input_file_scan_only VARCHAR2(3), -- 'NO' -> this is a real backup -- keep_options NUMBER DEFAULT 0 NOT NULL,-- if backup is done with keep option -- -- -- -- keep_until DATE, -- valid only if keep_options != 0 -- block_size NUMBER DEFAULT NULL, -- block size for backup set -- -- site_key NUMBER, -- Null when set owner is unknown -- multi_section VARCHAR2(1), -- 'Y' if backup is multi-section, else -- pdb_key NUMBER NOT NULL, CONSTRAINT bs_p PRIMARY KEY (bs_key), CONSTRAINT bs_u2 UNIQUE (db_key, set_stamp, set_count), CONSTRAINT bs_f1 FOREIGN KEY(db_key) -- backup set belongs to a db REFERENCES db ON DELETE CASCADE, CONSTRAINT bs_f2 FOREIGN KEY (site_key) REFERENCES node, CONSTRAINT bs_f3 FOREIGN KEY (pdb_key) REFERENCES pdb, CONSTRAINT bs_c_bck_type CHECK (bck_type in ('D','I','L')), CONSTRAINT bs_c_incr_level CHECK (incr_level in (0,1,2,3,4)), -- CONSTRAINT bs_c_controlfile_included CHECK (controlfile_included in ('NONE','BACKUP','STANDBY')) ) &tablespace& >>> define bs_i_1 <<< CREATE INDEX bs_i_1 on bs(db_key, bs_recid, bs_stamp) &tablespace& >>> define bs_i_site_db_key <<< CREATE INDEX bs_i_site_db_key on bs(site_key,db_key) &tablespace& >>> define bp <<< CREATE TABLE bp ( bp_key NUMBER NOT NULL, -- sequence generated primary key bs_key NUMBER NOT NULL, -- backup set db_key NUMBER NOT NULL, bp_recid NUMBER NOT NULL, -- backup piece recid from control file bp_stamp NUMBER NOT NULL, -- backup piece stamp from control file piece# NUMBER NOT NULL, -- first piece is 1 copy# NUMBER NOT NULL, -- copy number, 1 if no copies tag VARCHAR2(32), -- user specified tag device_type VARCHAR2(255) NOT NULL, -- 'DISK' -> on disk rather than seq handle VARCHAR2(1024) NOT NULL, --backup piece handle handle_hashkey VARCHAR2(30) NOT NULL, -- indexed hashkey on handle comments VARCHAR2(255), -- media VARCHAR2(80), -- media handle media_pool NUMBER, -- media pool concur VARCHAR2(1) NOT NULL, -- 'Y' media supports concurrent access start_time DATE NOT NULL, -- time when this piece started completion_time DATE NOT NULL, -- time when this piece completed -- status VARCHAR2(1) NOT NULL, bytes NUMBER DEFAULT NULL, is_recovery_dest_file VARCHAR2(3) DEFAULT 'NO' NOT NULL, -- rsr_key NUMBER, -- key of the row in the rsr table compressed VARCHAR2(3) DEFAULT 'NO',-- compressed site_key NUMBER, -- Null when piece owner is unknown encrypted VARCHAR(1) DEFAULT 'N', -- 'Y' means encrypted, otherwise not backed_by_osb VARCHAR(1) DEFAULT 'N', -- 'Y' means backed by OSB ct_key NUMBER, -- sbt_catalog key ba_access VARCHAR(1) DEFAULT 'U', -- Unknown, Local, Tape, Disk, -- -- -- vb_key NUMBER, -- virtual backup ID lib_key NUMBER, -- lib_key (used by ORS only) purged VARCHAR(1) DEFAULT 'U' NOT NULL, -- -- -- pdb_key NUMBER NOT NULL, template_key NUMBER, -- template_key CONSTRAINT bp_p PRIMARY KEY (bp_key), CONSTRAINT bp_u1 UNIQUE (bs_key, bp_recid, bp_stamp), CONSTRAINT bp_u2 UNIQUE (ct_key), CONSTRAINT bp_f2 FOREIGN KEY (site_key) REFERENCES node, CONSTRAINT bp_f3 FOREIGN KEY (bs_key) REFERENCES bs, CONSTRAINT bp_f4 FOREIGN KEY (pdb_key) REFERENCES pdb, CONSTRAINT bp_c_rs CHECK (ba_access IN ('U', 'D', 'L', 'T', 'R')), CONSTRAINT bp_c_lib_key CHECK ((lib_key IS NOT NULL AND vb_key IS NULL AND ba_access IN ('T', 'R')) OR (lib_key IS NULL AND ba_access IN ('D', 'L', 'U'))), CONSTRAINT bp_c_status CHECK (status in ('A','U','D','X')), CONSTRAINT bp_c_concur CHECK (concur in ('Y','N')), CONSTRAINT bp_c_purged CHECK ((purged in ('Y','N') AND status = 'D' AND ba_access != 'U') OR (purged = 'N' AND status != 'D' AND ba_access != 'U') OR (purged = 'U' AND ba_access = 'U')), CONSTRAINT bp_c_copyno CHECK (copy# > 0 AND copy# <= 256) ) &tablespace& >>> define bp_i_device_handle_status <<< CREATE INDEX bp_i_device_handle_status on bp(handle_hashkey, status) &tablespace& >>> define bp_i_2 <<< CREATE INDEX bp_i_2 on bp(db_key, bp_recid, bp_stamp) &tablespace& >>> define bp_i_3 <<< CREATE INDEX bp_i_3 on bp(db_key, bs_key) &tablespace& >>> define bp_i_site_bs_key <<< CREATE INDEX bp_i_site_bs_key on bp(site_key,bs_key) &tablespace& >>> define bcf <<< CREATE TABLE bcf ( bcf_key NUMBER NOT NULL, bs_key NUMBER NOT NULL, -- backup set dbinc_key NUMBER NOT NULL, -- database incarnation bcf_recid NUMBER NOT NULL, -- recid from control file bcf_stamp NUMBER NOT NULL, -- stamp from control file ckp_scn NUMBER NOT NULL, -- controlfile checkpoint SCN ckp_time DATE NOT NULL, -- controlfile checkpoint time create_time DATE NOT NULL, -- controlfile creation time min_offr_recid NUMBER NOT NULL, -- recid of the oldest offline range block_size NUMBER NOT NULL, -- blocksize controlfile_type VARCHAR2(1), -- 'B' -> backup controlfile -- blocks NUMBER, -- # blocks autobackup_date DATE, -- controlfile autobackup date autobackup_sequence NUMBER, -- controlfile autobackup sequence pdb_key NUMBER NOT NULL, CONSTRAINT bcf_p PRIMARY KEY (bcf_key), CONSTRAINT bcf_u2 UNIQUE (bs_key), CONSTRAINT bcf_f1 FOREIGN KEY (bs_key) REFERENCES bs ON DELETE CASCADE, CONSTRAINT bcf_f2 FOREIGN KEY (pdb_key) REFERENCES pdb, CONSTRAINT bcf_f3 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE, CONSTRAINT bcf_c_cf_type CHECK (controlfile_type in ('S','B')) ) &tablespace& >>> define bcf_i_dbinc <<< CREATE INDEX bcf_i_dbinc on bcf(dbinc_key) &tablespace& >>> define ccf <<< CREATE TABLE ccf ( ccf_key NUMBER NOT NULL, dbinc_key NUMBER NOT NULL, -- database incarnation ccf_recid NUMBER NOT NULL, -- recid from control file ccf_stamp NUMBER NOT NULL, -- stamp from control file fname VARCHAR2(1024) NOT NULL, -- cf copy file name fname_hashkey VARCHAR2(20) NOT NULL, -- hashed fname for indexing tag VARCHAR2(32), -- cf copy tag ckp_scn NUMBER NOT NULL, -- controlfile checkpoint SCN ckp_time DATE NOT NULL, -- controlfile checkpoint time create_time DATE NOT NULL, -- controlfile creation time min_offr_recid NUMBER NOT NULL, -- recid of the oldest offline range blocks NUMBER DEFAULT NULL, -- number of blocks block_size NUMBER NOT NULL, -- blocksize completion_time DATE NOT NULL, -- time that the copy was taken controlfile_type VARCHAR2(1), -- 'B' -> backup controlfile -- -- status VARCHAR2(1) NOT NULL, keep_options NUMBER DEFAULT 0 NOT NULL,-- if backup is done with keep option -- -- -- -- keep_until DATE, -- valid only if keep_options != 0 -- is_recovery_dest_file VARCHAR2(3) DEFAULT 'NO' NOT NULL, -- rsr_key NUMBER, -- key of the row in the rsr table site_key NUMBER, -- Null when cfcopy owner is unknown pdb_key NUMBER NOT NULL, CONSTRAINT ccf_p PRIMARY KEY (ccf_key), CONSTRAINT ccf_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE, CONSTRAINT ccf_f2 FOREIGN KEY (site_key) REFERENCES node, CONSTRAINT ccf_f3 FOREIGN KEY (pdb_key) REFERENCES pdb, CONSTRAINT ccf_u1 UNIQUE (dbinc_key, ccf_recid, ccf_stamp), CONSTRAINT ccf_c_status CHECK (status in ('A','U','D','X')), CONSTRAINT ccf_c_cf_type CHECK (controlfile_type in ('S','B')) ) &tablespace& >>> define ccf_i_fname_status <<< CREATE INDEX ccf_i_fname_status on ccf(fname_hashkey, status) &tablespace& >>> define xcf <<< CREATE TABLE xcf ( xcf_key NUMBER NOT NULL, dbinc_key NUMBER NOT NULL, -- database incarnation xcf_recid NUMBER NOT NULL, -- recid from control file xcf_stamp NUMBER NOT NULL, -- stamp from control file tag VARCHAR2(32), -- cf copy tag ckp_scn NUMBER NOT NULL, -- controlfile checkpoint SCN ckp_time DATE NOT NULL, -- controlfile checkpoint time create_time DATE NOT NULL, -- controlfile creation time min_offr_recid NUMBER NOT NULL, -- recid of the oldest offline range blocks NUMBER DEFAULT NULL, -- number of blocks in file block_size NUMBER NOT NULL, -- blocksize device_type VARCHAR2(255) NOT NULL, -- 'DISK' -> on disk rather than seq handle VARCHAR2(1024) NOT NULL, -- backup piece handle handle_hashkey VARCHAR2(30) NOT NULL, -- indexed hashkey on handle comments VARCHAR2(255), -- media VARCHAR2(80), -- media handle media_pool NUMBER, -- media pool start_time DATE NOT NULL, -- time when this piece started completion_time DATE NOT NULL, -- time when this piece completed controlfile_type VARCHAR2(1), -- 'B' -> backup controlfile -- -- status VARCHAR2(1) NOT NULL, keep_options NUMBER DEFAULT 0 NOT NULL,-- if backup is done with keep option -- -- -- -- keep_until DATE, -- valid only if keep_options != 0 -- rsr_key NUMBER, -- key of the row in the rsr table site_key NUMBER, -- Null when proxycopy owner is unknown pdb_key NUMBER NOT NULL, CONSTRAINT xcf_p PRIMARY KEY (xcf_key), CONSTRAINT xcf_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE, CONSTRAINT xcf_f2 FOREIGN KEY (site_key) REFERENCES node, CONSTRAINT xcf_f3 FOREIGN KEY (pdb_key) REFERENCES pdb, CONSTRAINT xcf_u1 UNIQUE (dbinc_key, xcf_recid, xcf_stamp), CONSTRAINT xcf_c_status CHECK (status in ('A','U','D','X')), CONSTRAINT xcf_c_cf_type CHECK (controlfile_type in ('S','B')) ) &tablespace& >>> define xcf_i_handle_status <<< CREATE INDEX xcf_i_handle_status on xcf(handle_hashkey, status) &tablespace& >>> define bsf <<< CREATE TABLE bsf ( bsf_key NUMBER NOT NULL, bs_key NUMBER NOT NULL, -- backup set db_key NUMBER NOT NULL, -- database to which this SPFILE -- db_unique_name VARCHAR2(30), -- Instance site name -- bsf_recid NUMBER NOT NULL, -- recid from control file bsf_stamp NUMBER NOT NULL, -- stamp from control file modification_time DATE NOT NULL, -- SPFILE modification time bytes NUMBER NOT NULL, -- size of SPFILE in bytes pdb_key NUMBER NOT NULL, CONSTRAINT bsf_p PRIMARY KEY (bsf_key), CONSTRAINT bsf_u2 UNIQUE (bs_key), CONSTRAINT bsf_f1 FOREIGN KEY (bs_key) REFERENCES bs ON DELETE CASCADE, CONSTRAINT bsf_f2 FOREIGN KEY (pdb_key) REFERENCES pdb ) &tablespace& >>> define bsf_i_bs_key <<< CREATE INDEX bsf_i_bs_key on bsf(bs_key) &tablespace& >>> define bdf <<< CREATE TABLE bdf ( bdf_key NUMBER NOT NULL, -- primary key dbinc_key NUMBER NOT NULL, -- database incarnation bdf_recid NUMBER NOT NULL, -- bdf recid from control file bdf_stamp NUMBER NOT NULL, -- bdf stamp from control file bs_key NUMBER NOT NULL, -- backup set, null if copy file# NUMBER NOT NULL, -- database file number create_scn NUMBER NOT NULL, -- creation SCN create_time DATE DEFAULT NULL,-- creation time incr_level NUMBER, -- incremental backup level (null,0-4) incr_scn NUMBER NOT NULL, -- scn since backup contains changes ckp_scn NUMBER NOT NULL, -- scn of the last datafile ckpt ckp_time DATE NOT NULL, -- time of the last datafile ckpt abs_fuzzy_scn NUMBER, -- absolute fuzzy scn rcv_fuzzy_scn NUMBER, -- media recovery fuzzy scn rcv_fuzzy_time DATE, -- timestamp for media rcv fuzzy scn datafile_blocks NUMBER NOT NULL, -- number of blocks in datafile blocks NUMBER NOT NULL, -- number of blocks written to backup block_size NUMBER NOT NULL, -- blocksize completion_time DATE, -- completion time (null for 8.0.2) blocks_read NUMBER NOT NULL, -- number of blocks read for backup marked_corrupt NUMBER DEFAULT NULL, -- used_chg_track VARCHAR2(1) DEFAULT 'N', -- used_optim VARCHAR2(1) DEFAULT 'N', -- foreign_dbid NUMBER DEFAULT 0 NOT NULL, plugged_readonly VARCHAR2(3) DEFAULT 'NO' NOT NULL, plugin_scn NUMBER DEFAULT 0 NOT NULL, plugin_reset_scn NUMBER DEFAULT 0 NOT NULL, plugin_reset_time DATE, section_size NUMBER, pdb_key NUMBER NOT NULL, sparse_backup VARCHAR2(3) DEFAULT 'NO' NOT NULL, CONSTRAINT bdf_p PRIMARY KEY (bdf_key), CONSTRAINT bdf_u2 UNIQUE (bs_key, file#), CONSTRAINT bdf_f1 FOREIGN KEY (bs_key) REFERENCES bs ON DELETE CASCADE, CONSTRAINT bdf_f2 FOREIGN KEY (pdb_key) REFERENCES pdb, CONSTRAINT bdf_c_sparse_backup CHECK (sparse_backup in ('YES', 'NO')) ) &tablespace& >>> define bdf_i_bs_key <<< CREATE INDEX bdf_i_bs_key on bdf(bs_key) &tablespace& >>> define bdf_i_df_key <<< CREATE INDEX bdf_i_df_key on bdf(dbinc_key, file#, create_scn) &tablespace& >>> define cdf <<< CREATE TABLE cdf ( cdf_key NUMBER NOT NULL, -- primary key dbinc_key NUMBER NOT NULL, -- database incarnation cdf_recid NUMBER NOT NULL, -- df copy recid from control file cdf_stamp NUMBER NOT NULL, -- df copy stamp from control file file# NUMBER NOT NULL, -- database file number create_scn NUMBER NOT NULL, -- creation SCN create_time DATE DEFAULT NULL,-- timestamp when datafile was created fname VARCHAR2(1024) NOT NULL, -- fname_hashkey VARCHAR2(20) NOT NULL, -- tag VARCHAR2(32), -- df copy tag incr_level NUMBER, -- incremental backup level (null or 0) ckp_scn NUMBER NOT NULL, -- scn of the last datafile ckpt ckp_time DATE NOT NULL, -- time of the last datafile ckpt onl_fuzzy VARCHAR2(1) NOT NULL, -- bck_fuzzy VARCHAR2(1) NOT NULL, -- abs_fuzzy_scn NUMBER, -- absolute fuzzy scn, if known. -- rcv_fuzzy_scn NUMBER, -- media recovery fuzzy scn rcv_fuzzy_time DATE, -- timestamp for media rcv fuzzy scn blocks NUMBER NOT NULL, -- number of blocks block_size NUMBER NOT NULL, -- blocksize completion_time DATE NOT NULL, -- time when this copy completed -- status VARCHAR2(1) NOT NULL, keep_options NUMBER DEFAULT 0 NOT NULL, -- -- -- -- -- keep_until DATE, -- valid only if keep_options != 0 -- scanned VARCHAR2(1) DEFAULT 'N' NOT NULL, -- is_recovery_dest_file VARCHAR2(3) DEFAULT 'NO' NOT NULL, -- rsr_key NUMBER, -- key of the row in the rsr table marked_corrupt NUMBER DEFAULT NULL, -- site_key NUMBER, -- Null when dfcopy owner is unknown foreign_dbid NUMBER DEFAULT 0 NOT NULL, plugged_readonly VARCHAR2(3) DEFAULT 'NO' NOT NULL, plugin_scn NUMBER DEFAULT 0 NOT NULL, plugin_reset_scn NUMBER DEFAULT 0 NOT NULL, plugin_reset_time DATE, pdb_key NUMBER NOT NULL, sparse_backup VARCHAR2(3) DEFAULT 'NO' NOT NULL, CONSTRAINT cdf_p PRIMARY KEY (cdf_key), CONSTRAINT cdf_u1 UNIQUE (dbinc_key, cdf_recid, cdf_stamp), CONSTRAINT cdf_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE, -- -- -- -- CONSTRAINT cdf_f3 FOREIGN KEY (site_key) REFERENCES node, CONSTRAINT cdf_f4 FOREIGN KEY (pdb_key) REFERENCES pdb, CONSTRAINT cdf_c_status CHECK (status in ('A','U','D','X','F')), CONSTRAINT cdf_c_onl_fuzzy CHECK (onl_fuzzy in ('Y','N')), CONSTRAINT cdf_c_bck_fuzzy CHECK (bck_fuzzy in ('Y','N')), CONSTRAINT cdf_c_sparse_backup CHECK (sparse_backup in ('YES', 'NO')) ) &tablespace& >>> define cdf_i_df_key <<< CREATE INDEX cdf_i_df_key on cdf(dbinc_key, file#, create_scn) &tablespace& >>> define cdf_i_fname_status <<< CREATE INDEX cdf_i_fname_status on cdf(fname_hashkey, status) &tablespace& >>> define xdf <<< CREATE TABLE xdf ( xdf_key NUMBER NOT NULL, -- primary key dbinc_key NUMBER NOT NULL, -- database incarnation xdf_recid NUMBER NOT NULL, -- x$kccpd recid from control file xdf_stamp NUMBER NOT NULL, -- x$kccpd stamp from control file file# NUMBER NOT NULL, -- database file number create_scn NUMBER NOT NULL, -- creation SCN create_time DATE DEFAULT NULL,-- creation time tag VARCHAR2(32), -- df copy tag incr_level NUMBER, -- incremental backup level (null or 0) ckp_scn NUMBER NOT NULL, -- scn of the last datafile ckpt ckp_time DATE NOT NULL, -- time of the last datafile ckpt onl_fuzzy VARCHAR2(1) NOT NULL, -- bck_fuzzy VARCHAR2(1) NOT NULL, -- abs_fuzzy_scn NUMBER, -- absolute fuzzy scn, if known. -- rcv_fuzzy_scn NUMBER, -- media recovery fuzzy scn rcv_fuzzy_time DATE, -- timestamp for media rcv fuzzy scn blocks NUMBER NOT NULL, -- number of blocks block_size NUMBER NOT NULL, -- blocksize device_type VARCHAR2(255) NOT NULL, -- handle VARCHAR2(1024) NOT NULL, -- handle_hashkey VARCHAR2(30) NOT NULL, -- comments VARCHAR2(255), -- media VARCHAR2(80), -- media handle media_pool NUMBER, -- media pool start_time DATE NOT NULL, -- time when this piece started completion_time DATE NOT NULL, -- time when this piece completed -- status VARCHAR2(1) NOT NULL, keep_options NUMBER DEFAULT 0 NOT NULL, -- -- -- -- -- keep_until DATE, -- valid only if keep_options != 0 -- rsr_key NUMBER, -- key of the row in the rsr table site_key NUMBER, -- Null when proxycopy owner is unknown foreign_dbid NUMBER DEFAULT 0 NOT NULL, plugged_readonly VARCHAR2(3) DEFAULT 'NO' NOT NULL, plugin_scn NUMBER DEFAULT 0 NOT NULL, plugin_reset_scn NUMBER DEFAULT 0 NOT NULL, plugin_reset_time DATE, pdb_key NUMBER NOT NULL, CONSTRAINT xdf_p PRIMARY KEY (xdf_key), CONSTRAINT xdf_u1 UNIQUE (dbinc_key, xdf_recid, xdf_stamp), CONSTRAINT xdf_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE, -- -- -- -- CONSTRAINT xdf_f3 FOREIGN KEY (site_key) REFERENCES node, CONSTRAINT xdf_f4 FOREIGN KEY (pdb_key) REFERENCES pdb, CONSTRAINT xdf_c_status CHECK (status in ('A','U','D','X')), CONSTRAINT xdf_c_onl_fuzzy CHECK (onl_fuzzy in ('Y','N')), CONSTRAINT xdf_c_bck_fuzzy CHECK (bck_fuzzy in ('Y','N')) ) &tablespace& >>> define xdf_i_df_key <<< CREATE INDEX xdf_i_df_key on xdf(dbinc_key, file#, create_scn) &tablespace& >>> define xdf_i_handle_status <<< CREATE INDEX xdf_i_handle_status on xdf(handle_hashkey, status) &tablespace& >>> define xal <<< CREATE TABLE xal ( xal_key NUMBER NOT NULL, -- primary key dbinc_key NUMBER NOT NULL, -- database incarnation xal_recid NUMBER NOT NULL, -- x$kccpa recid from control file xal_stamp NUMBER NOT NULL, -- x$kccpa stamp from control file tag VARCHAR2(32), -- al copy tag thread# NUMBER NOT NULL, -- thread number sequence# NUMBER NOT NULL, -- log sequence number low_scn NUMBER NOT NULL, -- scn generated when switching in low_time DATE NOT NULL, -- time low SCN allocated next_scn NUMBER NOT NULL, -- scn generated when switching out next_time DATE NOT NULL, -- time when next SCN allocated blocks NUMBER NOT NULL, -- number of blocks written to backup block_size NUMBER NOT NULL, -- size of a block in bytes device_type VARCHAR2(255) NOT NULL, -- 'DISK' -> on disk rather than seq handle VARCHAR2(1024) NOT NULL,-- backup piece handle handle_hashkey VARCHAR2(30) NOT NULL, -- indexed hashkey on handle comments VARCHAR2(255), -- media VARCHAR2(80), -- media handle media_pool NUMBER, -- media pool start_time DATE NOT NULL, -- time when this piece started completion_time DATE NOT NULL, -- time when this piece completed rsr_key NUMBER, -- key of the row in the rsr table terminal VARCHAR2(3) DEFAULT 'NO', -- 'YES' for terminal rcv log keep_options NUMBER DEFAULT 0 NOT NULL, -- -- -- -- -- keep_until DATE, -- valid only if keep_options != 0 -- -- status VARCHAR2(1) NOT NULL, site_key NUMBER, -- Null when proxycopy owner is unknown CONSTRAINT xal_p PRIMARY KEY (xal_key), CONSTRAINT xal_u1 UNIQUE (dbinc_key, xal_recid, xal_stamp), CONSTRAINT xal_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE, CONSTRAINT xal_f2 FOREIGN KEY (site_key) REFERENCES node, CONSTRAINT xal_c_status CHECK (status in ('A','U','D','X')) ) &tablespace& >>> define xal_i_al_key <<< CREATE INDEX xal_i_al_key on xal(dbinc_key, thread#, sequence#) &tablespace& >>> define xal_i_handle_status <<< CREATE INDEX xal_i_handle_status on xal(handle_hashkey, status) &tablespace& >>> define brl <<< CREATE TABLE brl ( brl_key NUMBER NOT NULL, dbinc_key NUMBER NOT NULL, -- database incarnation brl_recid NUMBER NOT NULL, -- recid from control file brl_stamp NUMBER NOT NULL, -- stamp from control file bs_key NUMBER NOT NULL, -- backup set key thread# NUMBER NOT NULL, -- thread number sequence# NUMBER NOT NULL, -- log sequence number low_scn NUMBER NOT NULL, -- scn generated when switching in low_time DATE NOT NULL, -- time low SCN allocated next_scn NUMBER NOT NULL, -- scn generated when switching out next_time DATE NOT NULL, -- time when next SCN allocated blocks NUMBER NOT NULL, -- number of blocks written to backup block_size NUMBER NOT NULL, -- size of a block in bytes terminal VARCHAR2(3) DEFAULT 'NO', -- 'YES' for terminal rcv log activation VARCHAR2(1), -- 'Y' for activation log, NULL = N CONSTRAINT brl_p PRIMARY KEY (brl_key), CONSTRAINT brl_u2 UNIQUE (bs_key, thread#, sequence#), CONSTRAINT brl_f1 FOREIGN KEY (bs_key) REFERENCES bs ON DELETE CASCADE ) &tablespace& >>> define brl_i_bs_key <<< CREATE INDEX brl_i_bs_key on brl(bs_key) &tablespace& >>> define brl_i_dts <<< CREATE INDEX brl_i_dts on brl(dbinc_key, thread#, sequence#) &tablespace& >>> define brl_i_act <<< CREATE INDEX brl_i_act ON brl (NVL2(activation, dbinc_key, NULL)) COMPRESS 1 &tablespace& >>> define bcb <<< CREATE TABLE bcb ( bdf_key NUMBER NOT NULL, -- datafile backup or copy bcb_recid NUMBER NOT NULL, -- recid from control file bcb_stamp NUMBER NOT NULL, -- stamp from control file piece# NUMBER NOT NULL, -- backup piece to which block belongs block# NUMBER NOT NULL, -- starting block number in the file blocks NUMBER NOT NULL, -- block count in corrupt range corrupt_scn NUMBER, -- scn at which corruption was detected marked_corrupt VARCHAR2(1) NOT NULL, -- 'Y' -> could not read from disk corruption_type VARCHAR2(9), CONSTRAINT bcb_u1 UNIQUE (bdf_key, bcb_recid, bcb_stamp), CONSTRAINT bcb_f1 FOREIGN KEY (bdf_key) REFERENCES bdf ON DELETE CASCADE ) &tablespace& >>> define ccb <<< CREATE TABLE ccb ( cdf_key NUMBER NOT NULL, -- datafile copy ccb_recid NUMBER NOT NULL, -- recid from control file ccb_stamp NUMBER NOT NULL, -- stamp from control file block# NUMBER NOT NULL, -- block number in the file blocks NUMBER NOT NULL, -- block count in corrupt range corrupt_scn NUMBER, -- scn at which corruption was detected marked_corrupt VARCHAR2(1) NOT NULL, -- 'Y' -> could not read from disk corruption_type VARCHAR2(9), CONSTRAINT ccb_u1 UNIQUE (cdf_key, ccb_recid, ccb_stamp), CONSTRAINT ccb_f1 FOREIGN KEY (cdf_key) REFERENCES cdf ON DELETE CASCADE ) &tablespace& >>> define rsr <<< CREATE TABLE rsr ( rsr_key NUMBER NOT NULL, dbinc_key NUMBER NOT NULL, -- database incarnation rsr_recid NUMBER NOT NULL, -- recid from control file rsr_stamp NUMBER NOT NULL, -- stamp from control file rsr_pkey NUMBER, -- key of the parent, NULL if no rsr_l0key NUMBER, -- key of the level 0, NULL if no rsr_level NUMBER, -- level rsr_type VARCHAR2(33), -- row type rsr_oper VARCHAR2(33), -- operation rsr_cmdid VARCHAR2(33), -- command id rsr_status VARCHAR2(33), -- status rsr_mbytes NUMBER NOT NULL, -- megabytes rsr_start DATE NOT NULL, -- start time rsr_end DATE, -- end time rsr_ibytes NUMBER, -- input megabytes processed rsr_obytes NUMBER, -- output megabytes produced rsr_optimized VARCHAR2(3), -- was optimization applied rsr_otype VARCHAR2(80), -- input object types involved in oper rsr_srecid NUMBER, -- session recid rsr_sstamp NUMBER, -- session stamp rsr_odevtype VARCHAR2(17), -- output device type site_key NUMBER, -- Null when rman job owner is unknown rsr_osb_allocated VARCHAR2(1), -- 'Y' when OSB is allocated CONSTRAINT rsr_key PRIMARY KEY(rsr_key), CONSTRAINT rsr_u2 UNIQUE (dbinc_key, rsr_recid, rsr_stamp, site_key), CONSTRAINT rsr_f1 FOREIGN KEY(dbinc_key) REFERENCES dbinc ON DELETE CASCADE, CONSTRAINT rsr_f2 FOREIGN KEY (site_key) REFERENCES node ON DELETE CASCADE ) &tablespace& >>> define scr <<< CREATE TABLE scr ( scr_key NUMBER NOT NULL, -- sequence generated primary key db_key NUMBER, -- database that owns this script, -- scr_name VARCHAR2(100) NOT NULL, -- script name scr_comment VARCHAR2(255), -- comment for script CONSTRAINT scr_p PRIMARY KEY(scr_key), CONSTRAINT scr_f1 FOREIGN KEY(db_key) REFERENCES db ON DELETE CASCADE, CONSTRAINT scr_u1 UNIQUE(db_key, scr_name) ) &tablespace& >>> define scr_trigger <<< create or replace trigger scr_trigger before insert or update or delete on scr for each row declare global_script boolean; begin if inserting then global_script := :new.db_key is null; elsif updating then global_script := :old.db_key is null or :new.db_key is null; elsif deleting then global_script := :old.db_key is null; end if; if not global_script or dbms_catowner = user then return; end if; raise_application_error(num=>-20016, msg=>'virtual private catalog user cannot modify global scripts'); end; >>> define scrl <<< CREATE TABLE scrl ( scr_key NUMBER NOT NULL, -- script that owns this line db_key NUMBER, -- database that owns this script linenum NUMBER NOT NULL, -- line number text VARCHAR2(1024) NOT NULL,-- text of the line CONSTRAINT scrl_u1 UNIQUE(scr_key, linenum), CONSTRAINT scrl_f1 FOREIGN KEY(scr_key) REFERENCES scr ON DELETE CASCADE ) &tablespace& >>> define scrl_trigger <<< create or replace trigger scrl_trigger before insert or update or delete on scrl for each row declare dbkey number; begin if inserting then select db_key into dbkey from scr where scr_key = :new.scr_key; :new.db_key := dbkey; end if; if dbms_catowner = user then return; end if; if updating then dbkey := :new.db_key; if :old.db_key <> :new.db_key then raise_application_error(num=>-20017, msg=>'illegal script update operation'); end if; elsif deleting then dbkey := :old.db_key; end if; if dbkey is not null then return; end if; raise_application_error(num=>-20016, msg=>'virtual private catalog user cannot modify global scripts'); end; >>> define rout <<< CREATE TABLE rout ( db_key NUMBER NOT NULL, -- database output belongs to rsr_key NUMBER NOT NULL, -- command that generated the output rout_skey NUMBER NOT NULL, -- session that created the output rout_recid NUMBER NOT NULL, -- record id from server rout_stamp NUMBER NOT NULL, -- timestamp when row was added site_key NUMBER, -- sitekey rout_text VARCHAR2(130) NOT NULL, -- RMAN output CONSTRAINT rout_u1 UNIQUE(db_key, rout_skey, rsr_key, rout_recid, rout_stamp), CONSTRAINT rout_f1 FOREIGN KEY(db_key) REFERENCES db ON DELETE CASCADE, CONSTRAINT rout_f2 FOREIGN KEY(rsr_key) REFERENCES rsr ON DELETE CASCADE, CONSTRAINT rout_f3 FOREIGN KEY(site_key) REFERENCES node ON DELETE CASCADE ) &tablespace& >>> define config <<< CREATE TABLE config ( name VARCHAR2(30), -- name of configuration option value VARCHAR2(100), -- value of configuration option CONSTRAINT config_p PRIMARY KEY (name) ) ORGANIZATION INDEX &tablespace& >>> define fb <<< CREATE TABLE fb ( dbinc_key NUMBER NOT NULL, db_unique_name VARCHAR2(512) NOT NULL, -- Instance site name oldest_flashback_scn NUMBER, -- guaranteed flashback scn oldest_flashback_time DATE DEFAULT NULL, -- flashback target time CONSTRAINT fb_u1 UNIQUE(dbinc_key, db_unique_name), CONSTRAINT fb_f1 FOREIGN KEY(dbinc_key) REFERENCES dbinc ON DELETE CASCADE ) &tablespace& >>> define grsp <<< CREATE TABLE grsp ( dbinc_key NUMBER NOT NULL, site_key NUMBER, rspname VARCHAR2(128) NOT NULL, creation_time DATE DEFAULT NULL, rsptime DATE DEFAULT NULL, from_scn NUMBER, to_scn NUMBER, guaranteed VARCHAR2(3) DEFAULT 'YES', pdb_key NUMBER NOT NULL, clean VARCHAR2(3) DEFAULT 'NO', CONSTRAINT grsp_u2 FOREIGN KEY(dbinc_key) REFERENCES dbinc ON DELETE CASCADE, CONSTRAINT grsp_u3 FOREIGN KEY (site_key) REFERENCES node ON DELETE CASCADE, CONSTRAINT grsp_u4 UNIQUE(site_key, rspname, pdb_key), CONSTRAINT grsp_f1 FOREIGN KEY (pdb_key) REFERENCES pdb ON DELETE CASCADE, CONSTRAINT grsp_c1 CHECK (clean IN ('YES','NO')) ) &tablespace& >>> define nrsp <<< CREATE TABLE nrsp ( nrsp_recid NUMBER NOT NULL, nrsp_stamp NUMBER NOT NULL, dbinc_key NUMBER NOT NULL, site_key NUMBER, rspname VARCHAR2(128) NOT NULL, creation_time DATE DEFAULT NULL, rsptime DATE DEFAULT NULL, to_scn NUMBER, long_term VARCHAR2(3), pdb_key NUMBER NOT NULL, clean VARCHAR2(3) DEFAULT 'NO', CONSTRAINT nrsp_u1 UNIQUE (dbinc_key, nrsp_recid, nrsp_stamp, site_key), CONSTRAINT nrsp_f1 FOREIGN KEY(dbinc_key) REFERENCES dbinc ON DELETE CASCADE, CONSTRAINT nrsp_f2 FOREIGN KEY (site_key) REFERENCES node ON DELETE CASCADE, CONSTRAINT nrsp_u2 UNIQUE(site_key, rspname, pdb_key), CONSTRAINT nrsp_f3 FOREIGN KEY (pdb_key) REFERENCES pdb ON DELETE CASCADE, CONSTRAINT nrsp_c1 CHECK (clean IN ('YES','NO')) ) &tablespace& >>> define bcr <<< CREATE TABLE bcr ( bcr_recid NUMBER NOT NULL, -- recid from control file bcr_stamp NUMBER NOT NULL, -- stamp from control file df_key NUMBER NOT NULL, -- df_key in df table site_key NUMBER NOT NULL, -- which db_unique_name it contains block# NUMBER NOT NULL, -- block number in the file blocks NUMBER NOT NULL, -- block count in corrupt range corrupt_scn NUMBER, -- scn at which corruption was corruption_type VARCHAR2(9), CONSTRAINT bcr_p PRIMARY KEY (bcr_recid, bcr_stamp, site_key), CONSTRAINT bcr_f1 FOREIGN KEY (site_key) REFERENCES node ON DELETE CASCADE, CONSTRAINT bcr_f2 FOREIGN KEY (df_key, site_key) REFERENCES site_dfatt ON DELETE CASCADE, CONSTRAINT bcr_c_blocks CHECK (blocks != 0) ) &tablespace& >>> define vpc_users <<< CREATE TABLE vpc_users ( filter_user VARCHAR2(128) NOT NULL, -- Name of user who has access filter_uid NUMBER constraint vpc_users_uid_nn NOT NULL, -- uid of above add_new_db CHAR(1), -- Y -> user can add new DBs to catalog version VARCHAR2(12), -- Version this user is sync'ed to CONSTRAINT vpc_users_p PRIMARY KEY(filter_user) ) &tablespace& >>> define vpc_databases <<< CREATE TABLE vpc_databases ( filter_user VARCHAR2(128) NOT NULL, -- Name of user who has access filter_uid NUMBER constraint vpc_databases_uid_nn NOT NULL, -- uid of above db_id NUMBER NOT NULL, -- Database to which this user has access reg_db_unique_name VARCHAR2(30), -- Will become null, as soon as db_id is -- CONSTRAINT vpc_databases_f1 FOREIGN KEY(filter_user) REFERENCES vpc_users, CONSTRAINT vpc_databases_u2 UNIQUE(filter_user, db_id, reg_db_unique_name), CONSTRAINT vpc_databases_c1 CHECK ((db_id > 0 and reg_db_unique_name is null) or (db_id = 0 and reg_db_unique_name is not null)) ) &tablespace& >>> define upgcat_vpc_users_add_uid <<< alter table vpc_users add (filter_uid number) >>> define upgcat_vpc_users_populate_uid <<< -- -- -- -- begin update vpc_users set filter_uid = (select user_id from all_users where username = filter_user) where filter_uid is null; commit; end; >>> define upgcat_db_add_reg_db_unique_name <<< alter table db add (reg_db_unique_name varchar2(30)) >>> define upgcat_vpc_databases_add_reg_db_unique_name <<< alter table vpc_databases add (reg_db_unique_name varchar2(30)) >>> define upgcat_db_add_storage_prov <<< alter table db add (storage_prov VARCHAR(1) DEFAULT 'N') >>> define upgcat_vpc_databases_add_vpc_databases_c1 <<< alter table vpc_databases add CONSTRAINT vpc_databases_c1 CHECK ((db_id > 0 and reg_db_unique_name is null) or (db_id = 0 and reg_db_unique_name is not null)) >>> define upgcat_vpc_databases_add_vpc_databases_u2 <<< alter table vpc_databases add CONSTRAINT vpc_databases_u2 UNIQUE(filter_user, db_id, reg_db_unique_name) >>> define upgcat_vpc_databases_drop_vpc_databases_u1 <<< alter table vpc_databases drop constraint vpc_databases_u1 >>> define upgcat_vpc_databases_add_uid <<< alter table vpc_databases add (filter_uid number) >>> define upgcat_vpc_databases_populate_uid <<< -- -- -- begin update vpc_databases set filter_uid = (select filter_uid from vpc_users where vpc_databases.filter_user = vpc_users.filter_user) where filter_uid is null; delete from vpc_databases where filter_uid is null; commit; end; >>> define upgcat_vpc_users_delete_null_uids <<< begin delete from vpc_users where filter_uid is null; commit; end; >>> define upgcat_vpc_users_uid_not_null <<< alter table vpc_users modify(filter_uid constraint vpc_users_uid_nn not null) >>> define upgcat_vpc_databases_uid_not_null <<< alter table vpc_databases modify(filter_uid constraint vpc_databases_uid_nn not null) >>> define cfs <<< CREATE TABLE cfs ( stmt_number NUMBER NOT NULL, -- statement number stmt_type CHAR(1), -- statement type (C=create, D=drop) stmt_sql LONG -- DDL statement to execute ) &tablespace& >>> define xmlstore <<< CREATE TABLE xmlstore ( created_user VARCHAR2(128) NOT NULL, -- User who has created store_key number NOT NULL, name varchar2(1024) NOT NULL, name_tag varchar2(64), version_num number DEFAULT 1 NOT NULL, creation_time timestamp NOT NULL, modified_time timestamp NOT NULL, doctype varchar2(32), schema_ver varchar2(32), xml_comment varchar2(1024), xmldoc sys.xmltype NOT NULL, constraint xmlstore_p primary key(store_key), constraint xmlstore_u1 unique(name, name_tag, version_num) ) &tablespace& xmltype xmldoc store as clob >>> define xmlstore_insert_trigger <<< create or replace trigger xmlstore_insert_trigger before insert or update on xmlstore for each row declare can_add number; begin if dbms_catowner <> user then select count(*) into can_add from vpc_users where filter_user=user; if can_add = 0 then raise_application_error(num => -20012, msg => 'not authorized to add new row to xmlstore'); end if; end if; if inserting then :new.created_user := user; :new.creation_time := sys_extract_utc(systimestamp); :new.modified_time := :new.creation_time; else :new.created_user := :old.created_user; :new.modified_time := sys_extract_utc(systimestamp); :new.creation_time := :old.creation_time; end if; end; >>> define rs_server <<< create table server ( server_key number NOT NULL, filter_user varchar2(128) NOT NULL, -- User who has access to ORS server_host clob NOT NULL, -- comma separated list of host server_port number NOT NULL, -- http port wallet_alias varchar2(512) NOT NULL, wallet_path varchar2(512), proxy_url varchar2(512), -- http proxy host without port proxy_port number, -- port timeout_secs number, rep_server_name varchar2(128) NOT NULL, CONSTRAINT server_p PRIMARY KEY (server_key), CONSTRAINT server_u1 UNIQUE(filter_user, wallet_alias, wallet_path), CONSTRAINT server_u2 UNIQUE(rep_server_name), CONSTRAINT server_c1 CHECK (server_port > 0), CONSTRAINT server_c2 CHECK (proxy_port > 0) ) &tablespace& >>> define deleted_object <<< CREATE TABLE deleted_object ( do_key number NOT NULL, db_key number NOT NULL, create_time date NOT NULL, obj_typ varchar(26) NOT NULL, obj_key number NOT NULL, obj_stamp number NOT NULL, obj_data number, set_stamp number, set_count number, handle varchar2(1024), device_type varchar2(255), CONSTRAINT deleted_object_p1 primary key(do_key, db_key), CONSTRAINT deleted_object_c1 CHECK (obj_typ in ('BACKUP PIECE', 'BACKUP PIECE AVAILABLE', 'BACKUP PIECE UNAVAILABLE', 'BACKUP PIECE EXPIRED', 'BACKUP SET KEEP OPTIONS', 'BACKUP SET KEEP UNTIL')), CONSTRAINT deleted_object_f1 FOREIGN KEY(db_key) REFERENCES DB ON DELETE CASCADE ) &tablespace& >>> define deleted_object_i_1 <<< CREATE INDEX deleted_object_i_1 on deleted_object(db_key,create_time) compress 1 &tablespace& >>> define create_deleted_object_seq <<< DECLARE is_ra VARCHAR2(128); invalid_identifier exception; pragma exception_init(invalid_identifier, -904); BEGIN BEGIN EXECUTE IMMEDIATE 'select sys.rai_schema from dual' INTO is_ra; EXCEPTION WHEN invalid_identifier THEN NULL; END; IF is_ra IS NULL THEN BEGIN FOR do_seq_rec IN (select table_name from user_tables where partitioned='YES' and table_name = 'DO_SEQ') LOOP EXECUTE IMMEDIATE 'drop table do_seq'; END LOOP; END; END IF; EXECUTE IMMEDIATE q'{ CREATE TABLE do_seq ( db_key NUMBER NOT NULL, curr_value NUMBER DEFAULT 0 NOT NULL, CONSTRAINT do_seq_p1 PRIMARY KEY(db_key) USING INDEX ( CREATE UNIQUE INDEX do_seq_p1 ON do_seq(db_key) }' || CASE WHEN is_ra IS NOT NULL THEN ' LOCAL' END || q'{), CONSTRAINT do_seq_f1 FOREIGN KEY(db_key) REFERENCES DB ON DELETE CASCADE )}' || CASE WHEN is_ra IS NOT NULL THEN ' PARTITION BY HASH (db_key) PARTITIONS 16' END || ' &tablespace& '; END; >>> define bp_update_trigger <<< create or replace trigger bp_update_trigger before update on bp for each row when (old.status <> new.status) declare l_set_stamp number; l_set_count number; l_do_seq number; begin update do_seq set curr_value = curr_value + 1 where db_key = :old.db_key returning curr_value into l_do_seq; select set_stamp, set_count into l_set_stamp, l_set_count from bs where bs_key = :old.bs_key; insert into deleted_object(do_key, db_key, create_time, obj_typ, obj_key, obj_stamp, obj_data, set_stamp, set_count, handle, device_type) values (l_do_seq, :old.db_key, sysdate, decode(:new.status, 'A', 'BACKUP PIECE AVAILABLE', 'U', 'BACKUP PIECE UNAVAILABLE', 'D', 'BACKUP PIECE', 'X', 'BACKUP PIECE EXPIRED', 'INVALID VALUE ' || :new.status), :old.bp_recid, :old.bp_stamp, null, l_set_stamp, l_set_count, :old.handle, :old.device_type); end; >>> define watermarks <<< create table watermarks ( db_key number NOT NULL, db_unique_name varchar2(32) NOT NULL, rs_version_stamp date NOT NULL, high_bp_recid number DEFAULT 0 NOT NULL, -- backup piece recid high_do_key number DEFAULT 0 NOT NULL, -- delete object stamp cf_version_stamp date, -- primary cf version time high_df_recid number DEFAULT 0 NOT NULL, -- df mark for last full resync high_ts_recid number DEFAULT 0 NOT NULL, -- ts mark for last full rsync high_tf_recid number DEFAULT 0 NOT NULL, -- tf mark for last full resync high_offr_recid number DEFAULT 0 NOT NULL, -- offline range mark CONSTRAINT watermarks_f1 FOREIGN KEY(db_key) REFERENCES db ON DELETE CASCADE, CONSTRAINT watermarks_u1 UNIQUE (db_key) ) &tablespace& >>> define rcfile <<< CREATE TABLE rcfile ( rcfile_key number, creation_time timestamp NOT NULL, name varchar2(1024) NOT NULL, xmldoc sys.xmltype NOT NULL, constraint rcfile_p primary key(rcfile_key), constraint rcfile_u1 unique(name) ) &tablespace& xmltype xmldoc store as clob >>> define orsevent <<< CREATE TABLE orsevent ( ospid number, stamp number, stat_start_time date, event varchar2(64) NOT NULL, param1 varchar2(512), tag varchar2(64), total_waits number DEFAULT 0 NOT NULL, time_waited number, minimum_elapsed number, minimum_time date, maximum_elapsed number, maximum_time date, start_time timestamp, last_start_time date, last_end_time date, buf_size number, buf_count number, event_type number, newstats number, constraint orsevent_u1 unique (ospid, stamp, event, param1), constraint orsevent_c1_event_type CHECK (event_type in (1,2)), constraint orsevent_c2_newstats CHECK (newstats in (0,1)) ) &tablespace& >>> define avm_restore_range_cache <<< CREATE TABLE rrcache ( db_key number, low_time date, high_time date, low_scn number, high_scn number, low_dbinc_key number, high_dbinc_key number, range_type varchar2(32), max_bp_key number, last_do_key number, last_updated date, constraint restore_range_cache_u1 unique(db_key, range_type, low_scn) ) &tablespace& >>> define db_delete_trigger <<< create or replace trigger db_delete_trigger after delete on db for each row declare begin delete rcfile where name like '%_' || :old.db_id || '%'; end; >>> define rs_rc_get_object_list <<< create or replace view "_RS_RC_GET_OBJECT_LIST_" as select y.rcfile_key, y.prefix, y.istruncated, substr(y.marker, 8) marker, y.maxkeys, substr(z.rcfile_name, 8) rcfile_name, z.lastmodified, z.bytes from (select x.rcfile_key, t.prefix, t.istruncated, t.xmldoc, t.marker, t.maxkeys from rcfile x, xmltable('/ListBucketResult' passing x.xmldoc columns prefix varchar2(1024) path 'Prefix', istruncated varchar2(10) path 'IsTruncated', xmldoc xmltype path 'Contents', marker varchar2(1024) path 'Marker', MaxKeys number path 'MaxKeys') t where name like 'prefix=%') y, xmltable('/Contents' passing y.xmldoc columns rcfile_name varchar2(1024) path 'Key', lastmodified timestamp with time zone path 'LastModified', bytes number path 'Size')z >>> define rc_rcver <<< create or replace view rc_rcver as select version from rcver >>> define rc_deleted_object <<< create or replace view rc_deleted_object as select deleted_object.db_key db_key, deleted_object.do_key do_key, deleted_object.obj_typ object_type, deleted_object.obj_key object_key, deleted_object.obj_stamp object_stamp, deleted_object.obj_data object_data, deleted_object.set_stamp set_stamp, deleted_object.set_count set_count, deleted_object.handle handle, deleted_object.device_type device_type from deleted_object >>> define rc_watermarks <<< create or replace view rc_watermarks as select db_key, db_unique_name, rs_version_stamp, high_bp_recid, high_do_key, cf_version_stamp, high_df_recid, high_ts_recid, high_tf_recid, high_offr_recid from watermarks >>> define xml_table_names_views <<< DECLARE type table_name_type is table of user_tables.table_name%TYPE index by binary_integer; ltable_name table_name_type; PROCEDURE createView(name IN VARCHAR2) IS CURSOR column_c IS SELECT column_name, data_type, data_length FROM user_tab_columns WHERE TABLE_NAME = name ORDER BY column_name; first_row BOOLEAN := TRUE; row_data column_c%ROWTYPE; column_list VARCHAR2(4000); column_defs VARCHAR2(4000); view_stmt VARCHAR2(4000); xml_col_name VARCHAR2(4000); -- -- BEGIN OPEN column_c; LOOP FETCH column_c INTO row_data; EXIT WHEN column_c%NOTFOUND; xml_col_name := REPLACE(row_data.column_name, '#', '_x0023_'); IF row_data.data_type = 'VARCHAR2' OR row_data.data_type = 'RAW' THEN column_defs := column_defs || to_char(case when first_row THEN '' ELSE ',' end) || '"' || row_data.column_name || '" ' || row_data.data_type || '(' || row_data.data_length || ')' || ' path ''' || xml_col_name || ''''; -- -- -- -- ELSIF row_data.data_type = 'DATE' THEN column_defs := column_defs || to_char(case when first_row THEN '' ELSE ',' end) || '"' || row_data.column_name || '" CHAR(24) path ''' || xml_col_name || ''''; ELSE column_defs := column_defs || to_char(case when first_row THEN '' ELSE ',' end) || '"' || row_data.column_name || '" ' || row_data.data_type || ' path ''' || xml_col_name || ''''; END IF; column_list := column_list || to_char(case when first_row THEN '' ELSE ',' end) || 't."' || row_data.column_name || '"'; first_row := FALSE; END LOOP; IF first_row = FALSE THEN view_stmt := 'CREATE OR REPLACE VIEW "_RS_' || name || '_" AS ' || ' select x.rcfile_key rs_rcfile_key, x.creation_time ' || ' rs_rcfile_creation_time, x.name rs_rcfile_name,' || column_list || ' from rcfile x, xmltable(' || '''/ALL_TABLES/TABLE_' || name || '/ROW''' || ' passing x.xmldoc columns ' || column_defs || ') t'; END IF; DBMS_OUTPUT.PUT_LINE(view_stmt); EXECUTE IMMEDIATE view_stmt; END; BEGIN -- -- ltable_name(1) := 'RC_DATABASE'; ltable_name(2) := 'RC_DATABASE_INCARNATION'; ltable_name(3) := 'RC_SITE'; ltable_name(4) := 'RC_RMAN_CONFIGURATION'; ltable_name(5) := 'RC_TABLESPACE'; ltable_name(6) := 'RC_REDO_THREAD'; ltable_name(7) := 'RCI_DATAFILE'; ltable_name(8) := 'RCI_TEMPFILE'; ltable_name(9) := 'RC_REDO_LOG'; ltable_name(10) := 'RC_CHECKPOINT'; ltable_name(11) := 'RC_OFFLINE_RANGE'; ltable_name(12) := 'RCI_PDBS'; ltable_name(13) := 'RC_PLUGGABLE_DATABASE_INC'; -- -- ltable_name(14) := 'RC_RCVER'; ltable_name(15) := 'RC_WATERMARKS'; ltable_name(16) := 'RCI_BACKUP_SET'; ltable_name(17) := 'RCI_BACKUP_PIECE'; ltable_name(18) := 'RCI_BACKUP_CONTROLFILE'; ltable_name(19) := 'RCI_BACKUP_DATAFILE'; ltable_name(20) := 'RC_BACKUP_REDOLOG'; ltable_name(21) := 'RCI_BACKUP_SPFILE'; ltable_name(22) := 'RC_DELETED_OBJECT'; ltable_name(23) := 'RCI_RA_UPSTREAM_DATABASE'; FOR idx in 1..23 LOOP createView(ltable_name(idx)); END LOOP; END; >>> define dbms_catowner <<< CREATE OR REPLACE FUNCTION dbms_catowner RETURN VARCHAR2 AUTHID DEFINER IS u varchar2(128); begin select username into u from user_users; return u; end; >>> define grant_rman_seq <<< grant select on rman_seq to public >>> define grant_dbms_rcvman <<< grant execute on dbms_rcvman to public >>> define grant_dbms_rcvcat <<< grant execute on dbms_rcvcat to public >>> define grant_rc_listBackupPipe <<< grant execute on rc_listBackupPipe to public >>> define grant_rc_listRsRangePipe <<< grant execute on rc_listRsRangePipe to public >>> define grant_dbms_catowner <<< grant execute on dbms_catowner to public >>> define drop_al_v <<< drop view al_v >>> define drop_bcf_v <<< drop view bcf_v >>> define drop_bdf_v <<< drop view bdf_v >>> define drop_brl_v <<< drop view brl_v >>> define drop_ccf_v <<< drop view ccf_v >>> define drop_cdf_v <<< drop view cdf_v >>> define drop_ckp_v <<< drop view ckp_v >>> define drop_site_dfatt_v <<< drop view site_dfatt_v >>> define drop_df_v <<< drop view df_v >>> define drop_fb_v <<< drop view fb_v >>> define drop_grsp_v <<< drop view grsp_v >>> define drop_nrsp_v <<< drop view nrsp_v >>> define drop_offr_v <<< drop view offr_v >>> define drop_orl_v <<< drop view orl_v >>> define drop_rlh_v <<< drop view rlh_v >>> define drop_rr_v <<< drop view rr_v >>> define drop_rsr_v <<< drop view rsr_v >>> define drop_rt_v <<< drop view rt_v >>> define drop_site_tfatt_v <<< drop view site_tfatt_v >>> define drop_tf_v <<< drop view tf_v >>> define drop_tsatt_v <<< drop view tsatt_v >>> define drop_ts_v <<< drop view ts_v >>> define drop_xal_v <<< drop view xal_v >>> define drop_xcf_v <<< drop view xcf_v >>> define drop_xdf_v <<< drop view xdf_v >>> define drop_bp_v <<< drop view bp_v >>> define drop_bsf_v <<< drop view bsf_v >>> define drop_bs_v <<< drop view bs_v >>> define drop_conf_v <<< drop view conf_v >>> define drop_dbinc_v <<< drop view dbinc_v >>> define drop_db_v <<< drop view db_v >>> define drop_pdb_v <<< drop view pdb_v >>> define drop_pdbinc_v <<< drop view pdbinc_v >>> define drop_pdb_dbinc_v <<< drop view pdb_dbinc_v >>> define drop_node_v <<< drop view node_v >>> define drop_rout_v <<< drop view rout_v >>> define drop_scr_v <<< drop view scr_v >>> define drop_bcb_v <<< drop view bcb_v >>> define drop_ccb_v <<< drop view ccb_v >>> define drop_scrl_v <<< drop view scrl_v >>> define drop_config_v <<< drop view config_v >>> define drop_rcver_v <<< drop view rcver_v >>> define drop_vpc_users_v <<< drop view vpc_users_v >>> define drop_vpc_databases_v <<< drop view vpc_databases_v >>> define drop_cfs_v <<< drop view cfs_v >>> define drop_xmlstore_v <<< drop view xmlstore_v >>> define drop_bcr_v <<< drop view bcr_v >>> define drop_server_v <<< drop view server_v >>> define drop_deleted_object_v <<< drop view deleted_object_v >>> define drop_watermarks_v <<< drop view watermarks_v >>> define drop_rcfile_v <<< drop view rcfile_v >>> define drop_orsevent_v <<< drop view orsevent_v >>> define drop_dbms_catowner <<< drop function dbms_catowner >>> define syn_drop_all <<< begin for s in (select * from all_synonyms where owner = sys_context('USERENV', 'CURRENT_SCHEMA')) loop execute immediate 'drop synonym ' || s.synonym_name; end loop; end; >>> define config_update <<< begin insert into config select 'compatible','080004' from dual where not exists (select * from config); commit; end; >>> define tempres <<< CREATE TABLE tempres ( name VARCHAR2(1024) NOT NULL, -- name of the temporary resource data_type VARCHAR2(32) NOT NULL, -- TABLE or DBLINK CONSTRAINT tempres_u1 UNIQUE(name) ) &tablespace& >>> define idb <<< CREATE TABLE &1& ( db_key NUMBER NOT NULL, db_id NUMBER NOT NULL, CONSTRAINT &2&_p PRIMARY KEY (db_key), CONSTRAINT &3&_u1 UNIQUE(db_id) ) >>> define idbinc <<< CREATE TABLE &1& ( dbinc_key NUMBER NOT NULL, CONSTRAINT &2&_p PRIMARY KEY(dbinc_key) ) >>> define dblink <<< -- -- -- -- CREATE DATABASE LINK &1& CONNECT TO &2& IDENTIFIED BY &3& USING &4& >>> define rc_database <<< create or replace view rc_database as select db.db_key, db.curr_dbinc_key dbinc_key, db.db_id dbid, dbinc.db_name name, dbinc.reset_scn resetlogs_change#, dbinc.reset_time resetlogs_time, (CAST(NULL AS NUMBER)) final_change# from db, dbinc where db.curr_dbinc_key = dbinc.dbinc_key >>> define rc_database_ors <<< create or replace view rc_database as select db.db_key, db.curr_dbinc_key dbinc_key, db.db_id dbid, dbinc.db_name name, dbinc.reset_scn resetlogs_change#, dbinc.reset_time resetlogs_time, (case when (select count(*) from task where task_type in (120,130) and state not in (3,8) and db_key = db.db_key and rownum = 1) > 0 then 0 else (select min(max(next_scn)) from brl b1 where nvl2(activation, dbinc_key, null) = db.curr_dbinc_key and db.storage_prov = 'Y' and not exists (select 1 from brl b2 where b1.dbinc_key = b2.dbinc_key and b1.thread# = b2.thread# and b1.sequence# < b2.sequence#) group by thread#) end) as final_change# from db, dbinc where db.curr_dbinc_key = dbinc.dbinc_key >>> define rci_pdbs <<< create or replace view rci_pdbs as select pdb.pdb_key, pdb.db_key, pdb.name, pdb.con_id, pdb.db_id dbid, pdb.create_scn creation_change#, pdb.guid guid, pdb.nobackup from pdb >>> define rc_pdbs <<< create or replace view rc_pdbs as select pdb_key, db_key, name, con_id, dbid, creation_change#, guid from rci_pdbs where con_id > 1 >>> define rc_rman_configuration <<< create or replace view rc_rman_configuration as select conf.db_key, conf.conf# conf#, conf.name name, conf.value value, conf.db_unique_name db_unique_name, conf.site_key from db, conf where db.db_key = conf.db_key >>> define rc_database_incarnation <<< create or replace view rc_database_incarnation as select db.db_key, db.db_id dbid, cur.dbinc_key, cur.db_name name, cur.reset_scn resetlogs_change#, cur.reset_time resetlogs_time, decode(cur.dbinc_key, db.curr_dbinc_key, 'YES', 'NO') current_incarnation, cur.parent_dbinc_key, par.reset_scn prior_resetlogs_change#, par.reset_time prior_resetlogs_time, cur.dbinc_status status, db.reg_db_unique_name, pdb.con_id, pdb.guid from db, dbinc cur, dbinc par, pdb where db.db_key = cur.db_key and (cur.parent_dbinc_key = par.dbinc_key) and db.db_key = pdb.db_key and pdb.con_id in (1, 0) union all select db.db_key, db.db_id dbid, dbinc.dbinc_key, dbinc.db_name name, dbinc.reset_scn resetlogs_change#, dbinc.reset_time resetlogs_time, decode(dbinc.dbinc_key, db.curr_dbinc_key, 'YES', 'NO') current_incarnation, to_number(null), to_number(null), to_date(null), dbinc.dbinc_status status, db.reg_db_unique_name, pdb.con_id, pdb.guid from db, dbinc, pdb where db.db_key=dbinc.db_key and dbinc.parent_dbinc_key IS NULL -- get last incarnation and db.db_key = pdb.db_key and pdb.con_id in (1, 0) >>> define rci_pdbinc_this_dbinc <<< create or replace view rci_pdbinc_this_dbinc as select par.*, cur.inc_scn next_inc_scn, cur.end_reset_scn next_end_reset_scn, pdb.db_key, pdb_dbinc.dbinc_key, pdb.name, pdb.con_id, pdb.db_id, pdb.create_scn, pdb_dbinc.drop_scn, pdb_dbinc.curr_pdbinc_key, pdb.nobackup from pdbinc cur, pdbinc par, pdb, pdb_dbinc where cur.parent_pdbinc_key = par.pdbinc_key and cur.pdbinc_status != 'ORPHAN' and cur.pdb_key = pdb.pdb_key and pdb.pdb_key = pdb_dbinc.pdb_key union all select pdbinc.*, 18446744073709551615 next_inc_scn, 18446744073709551615 next_end_reset_scn, pdb.db_key, pdb_dbinc.dbinc_key, pdb.name, pdb.con_id, pdb.db_id, pdb.create_scn, pdb_dbinc.drop_scn, pdb_dbinc.curr_pdbinc_key, pdb.nobackup from pdbinc, pdb, pdb_dbinc where pdb_dbinc.curr_pdbinc_key = pdbinc.pdbinc_key and pdbinc.pdbinc_status = 'CURRENT' and pdbinc.pdb_key = pdb.pdb_key >>> define rc_pluggable_database_inc <<< create or replace view rc_pluggable_database_inc as select rci_pdbs.pdb_key, rci_pdbs.name, rci_pdbs.con_id, rci_pdbs.dbid, rci_pdbs.guid, rci_pdbs.creation_change# create_scn, cur.pdbinc_key, rci_pdbs.db_key db_key, decode(cur.pdbinc_status, 'CURRENT', 'YES', 'NO') current_incarnation, cur.inc_scn incarnation_scn, cur.begin_reset_scn begin_resetlogs_scn, cur.begin_reset_time begin_resetlogs_time, cur.end_reset_scn end_resetlogs_scn, cur.born_dbinc_key dbinc_key, cur_dbinc.reset_scn db_resetlogs_scn, cur_dbinc.reset_time db_resetlogs_time, cur.parent_pdbinc_key prior_pdbinc_key, par.inc_scn prior_incarnation_scn, par.begin_reset_scn prior_begin_resetlogs_scn, par.begin_reset_time prior_begin_resetlogs_time, par.end_reset_scn prior_end_resetlogs_scn, par.born_dbinc_key prior_dbinc_key, par_dbinc.reset_scn prior_db_resetlogs_scn, par_dbinc.reset_time prior_db_resetlogs_time, cur.pdbinc_status status from rci_pdbs, pdbinc cur, pdbinc par, dbinc cur_dbinc, dbinc par_dbinc where rci_pdbs.pdb_key = cur.pdb_key and rci_pdbs.con_id > 1 and cur.parent_pdbinc_key = par.pdbinc_key(+) and cur_dbinc.dbinc_key = cur.born_dbinc_key and cur_dbinc.parent_dbinc_key = par_dbinc.dbinc_key >>> define rc_resync <<< create or replace view rc_resync as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, ckp.ckp_key resync_key, ckp.ckp_scn controlfile_change#, ckp.ckp_time controlfile_time, ckp.ckp_cf_seq controlfile_sequence#, ckp.cf_create_time controlfile_version, ckp.ckp_type resync_type, ckp.ckp_db_status db_status, ckp.resync_time from ckp, dbinc where ckp.dbinc_key = dbinc.dbinc_key >>> define rc_checkpoint <<< create or replace view rc_checkpoint as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, ckp.ckp_key, ckp.ckp_scn, ckp.ckp_cf_seq, ckp.ckp_time, ckp.ckp_type, ckp.ckp_db_status, ckp.site_key from ckp, dbinc where ckp.dbinc_key = dbinc.dbinc_key >>> define rci_tablespace_this_dbinc <<< create or replace view rci_tablespace_this_dbinc as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, pdbinc.con_id, pdbinc.name pdb_name, pdbinc.pdb_key pdb_key, ts.pdbinc_key, ts.ts#, ts.ts_name name, ts.create_scn creation_change#, ts.create_time creation_time, ts.drop_scn drop_change#, ts.drop_time, ts.included_in_database_backup, ts.bigfile, ts.temporary, ts.encrypt_in_backup, ts.plugin_scn plugin_change# from ts, dbinc, rci_pdbinc_this_dbinc pdbinc where dbinc.dbinc_key = ts.dbinc_key and ts.pdbinc_key = pdbinc.pdbinc_key and ts.dbinc_key = pdbinc.dbinc_key and ts.create_scn < pdbinc.next_inc_scn and ts.plugin_scn < pdbinc.next_inc_scn >>> define rc_tablespace <<< create or replace view rc_tablespace as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, pdb.con_id, decode(pdb.con_id, 0, NULL, pdb.name) pdb_name, pdb.pdb_key pdb_key, ts.pdbinc_key, ts.ts#, ts.ts_name name, ts.create_scn creation_change#, ts.create_time creation_time, ts.drop_scn drop_change#, ts.drop_time, ts.included_in_database_backup, ts.bigfile, ts.temporary, ts.encrypt_in_backup, ts.plugin_scn plugin_change# from ts, dbinc, pdbinc, pdb where dbinc.dbinc_key = ts.dbinc_key and ts.pdbinc_key = pdbinc.pdbinc_key and pdbinc.pdb_key = pdb.pdb_key >>> define rci_tempfile <<< create or replace view rci_tempfile as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, pdb.con_id con_id, decode(pdb.con_id, 0, NULL, pdb.name) pdb_name, pdb.pdb_key pdb_key, ts.ts#, ts.ts_name tablespace_name, tf.file#, tf.create_scn creation_change#, tf.create_time creation_time, site_tfatt.drop_scn drop_change#, site_tfatt.drop_time, site_tfatt.blocks * tf.block_size bytes, site_tfatt.blocks, tf.block_size, site_tfatt.fname name, tf.rfile#, site_tfatt.autoextend, site_tfatt.max_size maxsize, site_tfatt.next_size nextsize, ts.bigfile, node.site_key, node.db_unique_name, ts.create_scn tablespace_creation_change#, ts.create_time tablespace_creation_time, ts.drop_scn tablespace_drop_change#, ts.drop_time tablespace_drop_time from dbinc, ts, tf, node, site_tfatt, pdb where dbinc.dbinc_key = ts.dbinc_key and ts.dbinc_key = tf.dbinc_key and ts.ts# = tf.ts# and ts.create_scn = tf.ts_create_scn and ts.pdbinc_key = tf.ts_pdbinc_key and node.db_key = dbinc.db_key and tf.tf_key = site_tfatt.tf_key and node.site_key = site_tfatt.site_key and tf.pdb_key = pdb.pdb_key >>> define rci_datafile <<< create or replace view rci_datafile as select a.db_key, a.dbinc_key, a.db_name, a.con_id, a.pdb_name, a.pdb_key, a.pdb_closed, a.pdbinc_key, a.ts#, a.tablespace_name, a.file#, a.creation_change#, a.creation_time, a.drop_change#, a.drop_time, a.bytes, a.blocks, a.block_size, site_dfatt.fname name, a.stop_change#, a.stop_time, a.read_only, a.rfile#, a.included_in_database_backup, a.aux_name, a.encrypt_in_backup, a.site_key, a.db_unique_name, a.foreign_dbid, a.foreign_create_scn foreign_creation_change#, a.foreign_create_time foreign_creation_time, a.plugged_readonly, a.plugin_scn plugin_change#, a.plugin_reset_scn plugin_resetlogs_change#, a.plugin_reset_time plugin_resetlogs_time, a.creation_thread, a.creation_size, a.pdb_foreign_dbid, a.pdb_nobackup from (select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, pdb.con_id con_id, pdb.name pdb_name, pdb.pdb_key pdb_key, df.pdbinc_key, df.pdb_closed, ts.ts#, ts.ts_name tablespace_name, df.file#, df.create_scn creation_change#, df.create_time creation_time, df.drop_scn drop_change#, df.drop_time, df.blocks*df.block_size bytes, df.blocks, df.block_size, df.stop_scn stop_change#, df.stop_time, df.read_only read_only, df.rfile#, ts.included_in_database_backup, df.clone_fname aux_name, ts.encrypt_in_backup, df.df_key, node.site_key, node.db_unique_name, df.foreign_dbid, df.foreign_create_scn, df.foreign_create_time, df.plugged_readonly, df.plugin_scn, df.plugin_reset_scn, df.plugin_reset_time, df.create_thread creation_thread, df.create_size creation_size, df.pdb_foreign_dbid, pdb.nobackup pdb_nobackup from dbinc, ts, df, node, pdbinc, pdb where dbinc.dbinc_key = ts.dbinc_key and ts.dbinc_key = df.dbinc_key and ts.ts# = df.ts# and ts.create_scn = df.ts_create_scn and ts.pdbinc_key = df.ts_pdbinc_key and node.db_key = dbinc.db_key and df.pdbinc_key = pdbinc.pdbinc_key and pdb.pdb_key = pdbinc.pdb_key) a, site_dfatt where a.site_key = site_dfatt.site_key(+) and a.df_key = site_dfatt.df_key(+) >>> define rci_datafile_this_dbinc <<< create or replace view rci_datafile_this_dbinc as select a.db_key, a.dbinc_key, a.db_name, a.con_id, a.pdb_name, a.pdb_key, a.pdb_closed, a.pdbinc_key, a.ts#, a.tablespace_name, a.file#, a.creation_change#, a.creation_time, a.drop_change#, a.drop_time, a.bytes, a.blocks, a.block_size, site_dfatt.fname name, a.stop_change#, a.stop_time, a.read_only, a.rfile#, a.included_in_database_backup, a.aux_name, a.encrypt_in_backup, a.site_key, a.db_unique_name, a.foreign_dbid, a.foreign_create_scn foreign_creation_change#, a.foreign_create_time foreign_creation_time, a.plugged_readonly, a.plugin_scn plugin_change#, a.plugin_reset_scn plugin_resetlogs_change#, a.plugin_reset_time plugin_resetlogs_time, a.creation_thread, a.creation_size, a.pdb_foreign_dbid, a.pdb_nobackup from (select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, pdbinc.con_id con_id, pdbinc.name pdb_name, pdbinc.pdb_key pdb_key, df.pdbinc_key, df.pdb_closed, ts.ts#, ts.ts_name tablespace_name, df.file#, df.create_scn creation_change#, df.create_time creation_time, df.drop_scn drop_change#, df.drop_time, df.blocks*df.block_size bytes, df.blocks, df.block_size, df.stop_scn stop_change#, df.stop_time, df.read_only read_only, df.rfile#, ts.included_in_database_backup, df.clone_fname aux_name, ts.encrypt_in_backup, df.df_key, node.site_key, node.db_unique_name, df.foreign_dbid, df.foreign_create_scn, df.foreign_create_time, df.plugged_readonly, df.plugin_scn, df.plugin_reset_scn, df.plugin_reset_time, df.create_thread creation_thread, df.create_size creation_size, df.pdb_foreign_dbid, pdbinc.nobackup pdb_nobackup from dbinc, ts, df, node, rci_pdbinc_this_dbinc pdbinc where dbinc.dbinc_key = ts.dbinc_key and ts.dbinc_key = df.dbinc_key and ts.ts# = df.ts# and ts.create_scn = df.ts_create_scn and ts.pdbinc_key = df.ts_pdbinc_key and node.db_key = dbinc.db_key and df.pdbinc_key = pdbinc.pdbinc_key and df.dbinc_key = pdbinc.dbinc_key and df.create_scn < pdbinc.next_inc_scn and df.plugin_scn < pdbinc.next_inc_scn) a, site_dfatt where a.site_key = site_dfatt.site_key(+) and a.df_key = site_dfatt.df_key(+) >>> define create_rci_avm_upstream_database <<< create or replace view rci_ra_upstream_database as select to_number(null) dbid, 'NOT_RA_SCHEMA' name from dual >>> define create_rci_avm_upstream_database_ors <<< create or replace view rci_ra_upstream_database as select dbid, name from v$database >>> define rc_datafile <<< create or replace view rc_datafile as select db_key, dbinc_key, db_name, con_id, decode(con_id, 0, NULL, pdb_name) pdb_name, pdb_key, pdbinc_key, ts#, tablespace_name, file#, creation_change#, creation_time, drop_change#, drop_time, bytes, blocks, block_size, name, stop_change#, stop_time, read_only, rfile#, included_in_database_backup, aux_name, encrypt_in_backup, site_key, db_unique_name, foreign_dbid, foreign_creation_change#, foreign_creation_time, plugged_readonly, plugin_change#, plugin_resetlogs_change#, plugin_resetlogs_time, creation_thread, creation_size from rci_datafile where substr(nvl(db_unique_name, 'A'),1,1) <> '$' >>> define rc_tempfile <<< create or replace view rc_tempfile as select * from rci_tempfile where substr(nvl(db_unique_name, 'A'),1,1) <> '$' >>> define rc_redo_thread <<< create or replace view rc_redo_thread as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, rt.thread#, rt.status, rt.sequence#, rt.enable_scn enable_change#, rt.enable_time, rt.disable_scn disable_change#, rt.disable_time from dbinc, rt where dbinc.dbinc_key = rt.dbinc_key >>> define rc_redo_log <<< create or replace view rc_redo_log as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, orl.thread#, orl.group#, orl.fname name, orl.site_key, orl.bytes bytes, orl.type type from dbinc, orl where dbinc.dbinc_key = orl.dbinc_key >>> define rc_log_history <<< create or replace view rc_log_history as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, rlh.rlh_recid recid, rlh.rlh_stamp stamp, rlh.thread#, rlh.sequence#, rlh.low_scn first_change#, rlh.low_time first_time, rlh.next_scn next_change#, decode(rlh.status, 'N', 'NO', 'Y', 'YES', NULL, NULL, '?') cleared -- rlh.next_time, -- rlh.blocks from dbinc, rlh where dbinc.dbinc_key = rlh.dbinc_key >>> define rc_archived_log <<< create or replace view rc_archived_log as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, al.al_key, al.al_recid recid, al.al_stamp stamp, al.fname name, al.thread#, al.sequence#, dbinc.reset_scn resetlogs_change#, dbinc.reset_time resetlogs_time, al.low_scn first_change#, al.low_time first_time, al.next_scn next_change#, al.next_time, al.blocks, al.block_size, al.completion_time, decode(al.archived, 'N', 'NO', 'Y', 'YES', '?') archived, al.status, decode(al.is_standby, 'Y', 'YES', 'NO') is_standby, al.dictionary_begin, al.dictionary_end, al.is_recovery_dest_file, al.compressed, al.creator, al.terminal, al.site_key from dbinc, al where dbinc.dbinc_key = al.dbinc_key >>> define rci_backup_set <<< create or replace view rci_backup_set as select db.db_key, db.db_id, bs.bs_key, bs.bs_recid recid, bs.bs_stamp stamp, bs.set_stamp, bs.set_count, bs.bck_type backup_type, bs.incr_level incremental_level, bs.pieces, bs.start_time, bs.completion_time, abs((bs.completion_time - bs.start_time) * 86400) elapsed_seconds, bs.status, bs.controlfile_included, bs.input_file_scan_only, decode(keep_options, 0, 'NO', 'YES') keep, keep_until, decode(keep_options, 256, 'LOGS', 512, 'NOLOGS', 1024, 'BACKUP_LOGS', NULL) keep_options, bs.block_size, bs.site_key, decode(bs.multi_section, 'Y', 'YES', 'NO') multi_section, pdb.guid, pdb.pdb_key from db, bs, pdb where db.db_key = bs.db_key and pdb.pdb_key = bs.pdb_key >>> define rc_backup_set <<< create or replace view rc_backup_set as select db_key, db_id, pdb_key, bs_key, recid, stamp, set_stamp, set_count, backup_type, incremental_level, pieces, start_time, completion_time, elapsed_seconds, status, controlfile_included, input_file_scan_only, keep, keep_until, keep_options, block_size, site_key, multi_section from rci_backup_set >>> define rci_backup_piece <<< create or replace view rci_backup_piece as select db.db_key, db.db_id, bp.bp_key, bp.bp_recid recid, bp.bp_stamp stamp, bs.bs_key, bs.set_stamp, bs.set_count, bs.bck_type backup_type, bs.incr_level incremental_level, bp.piece#, bp.copy#, bp.device_type, bp.handle, bp.comments, bp.media, bp.media_pool, decode(bp.concur, 'N', 'NO', 'Y', 'YES', '?') concur, bp.tag, bp.start_time, bp.completion_time, abs((bp.completion_time - bp.start_time) * 86400) elapsed_seconds, bp.status, bp.bytes, bp.is_recovery_dest_file, bp.rsr_key, bp.compressed, bp.site_key, decode(bp.encrypted, 'N', 'NO', 'Y', 'YES', '?') encrypted, decode(bp.backed_by_osb, 'N', 'NO', 'Y', 'YES', '?') backed_by_osb, decode(bp.ba_access, 'U', 'Unknown', 'T', 'Tape', 'L', 'Local', 'D', 'Disk', 'R', 'Replication') ba_access, -- any changes to this list -- bp.vb_key, decode(bp.vb_key, NULL, 'NO', 'YES') virtual, bp.lib_key, pdb.guid, pdb.pdb_key from db, bs, bp, pdb where db.db_key = bs.db_key and bs.bs_key = bp.bs_key and bp.status != 'D' and bp.pdb_key = pdb.pdb_key >>> define rc_backup_piece <<< create or replace view rc_backup_piece as select db_key, db_id, pdb_key, bp_key, recid, stamp, bs_key, set_stamp, set_count, backup_type, incremental_level, piece#, copy#, device_type, handle, comments, media, media_pool, concur, tag, start_time, completion_time, elapsed_seconds, status, bytes, is_recovery_dest_file, rsr_key, compressed, site_key, encrypted, backed_by_osb, ba_access, vb_key, virtual, lib_key from rci_backup_piece >>> define rci_backup_datafile <<< create or replace view rci_backup_datafile as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, bdf.bdf_key, bdf.bdf_recid recid, bdf.bdf_stamp stamp, bs.bs_key, bs.set_stamp, bs.set_count, bs.bs_recid, bs.bs_stamp, bs.bck_type backup_type, bdf.incr_level incremental_level, bdf.completion_time, bdf.file#, bdf.create_scn creation_change#, bdf.create_time creation_time, dbinc.reset_scn resetlogs_change#, dbinc.reset_time resetlogs_time, bdf.incr_scn incremental_change#, bdf.ckp_scn checkpoint_change#, bdf.ckp_time checkpoint_time, bdf.abs_fuzzy_scn absolute_fuzzy_change#, bdf.datafile_blocks, bdf.blocks, bdf.block_size, bs.status, bs.incr_level bs_level, bs.pieces, bdf.blocks_read, bdf.marked_corrupt, decode(bdf.used_chg_track, 'Y', 'YES', 'NO') used_change_tracking, decode(bdf.used_optim, 'Y', 'YES', 'NO') used_optimization, decode(bdf.used_optim, 'Y',round((100 *(bdf.datafile_blocks - bdf.blocks_read)) / bdf.datafile_blocks), NULL) pct_notread, bdf.foreign_dbid, bdf.plugged_readonly, bdf.plugin_scn plugin_change#, bdf.plugin_reset_scn plugin_resetlogs_change#, bdf.plugin_reset_time plugin_resetlogs_time, bdf.section_size, pdb.guid, bdf.sparse_backup, pdb.pdb_key from dbinc, bs, bdf, pdb where dbinc.dbinc_key = bdf.dbinc_key and bs.bs_key = bdf.bs_key and bs.bck_type != 'L' and bdf.pdb_key = pdb.pdb_key >>> define rc_backup_datafile <<< create or replace view rc_backup_datafile as select db_key, dbinc_key, db_name, pdb_key, bdf_key, recid, stamp, bs_key, set_stamp, set_count, bs_recid, bs_stamp, backup_type, incremental_level, completion_time, file#, creation_change#, creation_time, resetlogs_change#, resetlogs_time, incremental_change#, checkpoint_change#, checkpoint_time, absolute_fuzzy_change#, datafile_blocks, blocks, block_size, status, bs_level, pieces, blocks_read, marked_corrupt, used_change_tracking, used_optimization, pct_notread, foreign_dbid, plugged_readonly, plugin_change#, plugin_resetlogs_change#, plugin_resetlogs_time, section_size, sparse_backup from rci_backup_datafile >>> define rci_backup_controlfile <<< create or replace view rci_backup_controlfile as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, bcf.bcf_key, bcf.bcf_recid recid, bcf.bcf_stamp stamp, bs.bs_key, bs.set_stamp, bs.set_count, dbinc.reset_scn resetlogs_change#, dbinc.reset_time resetlogs_time, bcf.ckp_scn checkpoint_change#, bcf.ckp_time checkpoint_time, bcf.create_time creation_time, bcf.block_size, bcf.min_offr_recid oldest_offline_range, bs.status, bs_recid, bs_stamp, bs.incr_level bs_level, bs.completion_time, bcf.controlfile_type, bcf.blocks, bcf.autobackup_date, bcf.autobackup_sequence, pdb.guid, pdb.pdb_key from dbinc, bs, bcf, pdb where dbinc.dbinc_key = bcf.dbinc_key and bs.bs_key = bcf.bs_key and bs.bck_type != 'L' and bcf.pdb_key = pdb.pdb_key >>> define rc_backup_controlfile <<< create or replace view rc_backup_controlfile as select db_key, dbinc_key, db_name, bcf_key, recid, stamp, bs_key, set_stamp, set_count, resetlogs_change#, resetlogs_time, checkpoint_change#, checkpoint_time, creation_time, block_size, oldest_offline_range, status, bs_recid, bs_stamp, bs_level, completion_time, controlfile_type, blocks, autobackup_date, autobackup_sequence from rci_backup_controlfile >>> define rci_backup_spfile <<< create or replace view rci_backup_spfile as select db.db_key, bsf.bsf_key, bsf.bsf_recid recid, bsf.bsf_stamp stamp, bs.bs_key, bs.set_stamp, bs.set_count, bsf.modification_time, bs.status, bs_recid, bs_stamp, bs.completion_time, bsf.bytes, bsf.db_unique_name, pdb.guid from db, bs, bsf, pdb where db.db_key = bsf.db_key and bs.bs_key = bsf.bs_key and bs.bck_type != 'L' and bsf.pdb_key = pdb.pdb_key >>> define rc_backup_spfile <<< create or replace view rc_backup_spfile as select db_key, bsf_key, recid, stamp, bs_key, set_stamp, set_count, modification_time, status, bs_recid, bs_stamp, completion_time, bytes, db_unique_name from rci_backup_spfile >>> define rc_datafile_copy <<< create or replace view rc_datafile_copy as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, cdf.pdb_key, cdf.cdf_key, cdf.cdf_recid recid, cdf.cdf_stamp stamp, cdf.fname name, cdf.tag, cdf.file#, cdf.create_scn creation_change#, cdf.create_time creation_time, dbinc.reset_scn resetlogs_change#, dbinc.reset_time resetlogs_time, cdf.incr_level incremental_level, cdf.ckp_scn checkpoint_change#, cdf.ckp_time checkpoint_time, cdf.abs_fuzzy_scn absolute_fuzzy_change#, cdf.rcv_fuzzy_scn recovery_fuzzy_change#, cdf.rcv_fuzzy_time recovery_fuzzy_time, decode(cdf.onl_fuzzy,'N', 'NO', 'Y', 'YES', '?') online_fuzzy, decode(cdf.bck_fuzzy,'N', 'NO', 'Y', 'YES', '?') backup_fuzzy, cdf.blocks, cdf.block_size, cdf.completion_time, cdf.status, decode(keep_options, 0, 'NO', 'YES') keep, keep_until, decode(keep_options, 256, 'LOGS', 512, 'NOLOGS', 1024, 'BACKUP_LOGS', NULL) keep_options, decode(cdf.scanned,'N', 'NO', 'Y', 'YES', '?') scanned, cdf.is_recovery_dest_file, cdf.rsr_key, cdf.marked_corrupt, cdf.site_key, cdf.foreign_dbid, cdf.plugged_readonly, cdf.plugin_scn plugin_change#, cdf.plugin_reset_scn plugin_resetlogs_change#, cdf.plugin_reset_time plugin_resetlogs_time, cdf.sparse_backup from dbinc, cdf where dbinc.dbinc_key = cdf.dbinc_key >>> define rc_controlfile_copy <<< create or replace view rc_controlfile_copy as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, ccf.ccf_key, ccf.ccf_recid recid, ccf.ccf_stamp stamp, ccf.fname name, ccf.tag, dbinc.reset_scn resetlogs_change#, dbinc.reset_time resetlogs_time, ccf.ckp_scn checkpoint_change#, ccf.ckp_time checkpoint_time, ccf.create_time creation_time, -- ccf.blocks, ccf.block_size, ccf.min_offr_recid, ccf.min_offr_recid oldest_offline_range, ccf.completion_time, ccf.status, ccf.controlfile_type, decode(keep_options, 0, 'NO', 'YES') keep, keep_until, decode(keep_options, 256, 'LOGS', 512, 'NOLOGS', 1024, 'BACKUP_LOGS', NULL) keep_options, ccf.is_recovery_dest_file, ccf.rsr_key, ccf.site_key from dbinc, ccf where dbinc.dbinc_key = ccf.dbinc_key >>> define rc_backup_redolog <<< create or replace view rc_backup_redolog as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, brl.brl_key, brl.brl_recid recid, brl.brl_stamp stamp, bs.bs_key, bs.set_stamp, bs.set_count, bs.bck_type backup_type, bs.completion_time, brl.thread#, brl.sequence#, dbinc.reset_scn resetlogs_change#, dbinc.reset_time resetlogs_time, brl.low_scn first_change#, brl.low_time first_time, brl.next_scn next_change#, brl.next_time, brl.blocks, brl.block_size, bs.status, bs_recid, bs_stamp, bs.pieces, brl.terminal, decode(activation,'Y','YES','NO') partial from dbinc, bs, brl where dbinc.dbinc_key = brl.dbinc_key and bs.bs_key = brl.bs_key and bs.bck_type = 'L' >>> define rc_backup_corruption <<< create or replace view rc_backup_corruption as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, bcb.bcb_recid recid, bcb.bcb_stamp stamp, bs.bs_key, bs.set_stamp, bs.set_count, bcb.piece#, bdf.bdf_key, bdf.bdf_recid, bdf.bdf_stamp, bdf.file#, bdf.create_scn creation_change#, bcb.block#, bcb.blocks, bcb.corrupt_scn corruption_change#, decode(bcb.marked_corrupt,'N', 'NO', 'Y', 'YES', '?') marked_corrupt, bcb.corruption_type from dbinc, bs, bdf, bcb where dbinc.dbinc_key = bdf.dbinc_key and bs.bs_key = bdf.bs_key and bdf.bdf_key = bcb.bdf_key >>> define rc_copy_corruption <<< create or replace view rc_copy_corruption as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, ccb.ccb_recid recid, ccb.ccb_stamp stamp, cdf.cdf_key, cdf.cdf_recid copy_recid, cdf.cdf_stamp copy_stamp, cdf.file#, cdf.create_scn creation_change#, ccb.block#, ccb.blocks, ccb.corrupt_scn corruption_change#, decode(ccb.marked_corrupt,'N', 'NO', 'Y', 'YES', '?') marked_corrupt, ccb.corruption_type from dbinc, cdf, ccb where dbinc.dbinc_key = cdf.dbinc_key and cdf.cdf_key = ccb.cdf_key and cdf.status = 'A' >>> define rc_offline_range <<< create or replace view rc_offline_range as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, offr.offr_recid recid, offr.offr_stamp stamp, offr.file#, offr.create_scn creation_change#, offr.offline_scn offline_change#, offr.online_scn online_change#, offr.online_time, offr.cf_create_time, dbinc.reset_scn resetlogs_change#, dbinc.reset_time resetlogs_time, offr.offr_key from dbinc, offr where dbinc.dbinc_key = offr.dbinc_key >>> define rc_stored_script <<< create or replace view rc_stored_script as select db.db_key, nvl(dbinc.db_name, 'GLOBAL') db_name, scr.scr_name script_name, scr.scr_comment script_comment from db, dbinc, scr where dbinc.dbinc_key(+) = db.curr_dbinc_key and db.db_key(+) = scr.db_key >>> define rc_stored_script_line <<< create or replace view rc_stored_script_line as select db.db_key, scr.scr_name script_name, scrl.linenum line, scrl.text from db, scr, scrl where db.db_key(+) = scr.db_key and scr.scr_key = scrl.scr_key >>> define rc_proxy_datafile <<< create or replace view rc_proxy_datafile as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, xdf.pdb_key, xdf.xdf_key, xdf.xdf_recid recid, xdf.xdf_stamp stamp, xdf.tag, xdf.file#, xdf.create_scn creation_change#, xdf.create_time creation_time, dbinc.reset_scn resetlogs_change#, dbinc.reset_time resetlogs_time, xdf.incr_level incremental_level, xdf.ckp_scn checkpoint_change#, xdf.ckp_time checkpoint_time, xdf.abs_fuzzy_scn absolute_fuzzy_change#, xdf.rcv_fuzzy_scn recovery_fuzzy_change#, xdf.rcv_fuzzy_time recovery_fuzzy_time, decode(xdf.onl_fuzzy,'N', 'NO', 'Y', 'YES', '?') online_fuzzy, decode(xdf.bck_fuzzy,'N', 'NO', 'Y', 'YES', '?') backup_fuzzy, xdf.blocks, xdf.block_size, xdf.device_type, xdf.handle, xdf.comments, xdf.media, xdf.media_pool, xdf.start_time, xdf.completion_time, abs((xdf.completion_time - xdf.start_time) * 86400) elapsed_seconds, xdf.status, decode(keep_options, 0, 'NO', 'YES') keep, keep_until, decode(keep_options, 256, 'LOGS', 512, 'NOLOGS', 1024, 'BACKUP_LOGS', NULL) keep_options, xdf.rsr_key, xdf.site_key, xdf.foreign_dbid, xdf.plugged_readonly, xdf.plugin_scn plugin_change#, xdf.plugin_reset_scn plugin_resetlogs_change#, xdf.plugin_reset_time plugin_resetlogs_time from dbinc, xdf where dbinc.dbinc_key = xdf.dbinc_key >>> define rc_proxy_controlfile <<< create or replace view rc_proxy_controlfile as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, xcf.xcf_key, xcf.xcf_recid recid, xcf.xcf_stamp stamp, xcf.tag, dbinc.reset_scn resetlogs_change#, dbinc.reset_time resetlogs_time, xcf.ckp_scn checkpoint_change#, xcf.ckp_time checkpoint_time, xcf.create_time creation_time, xcf.block_size, xcf.blocks, xcf.min_offr_recid, xcf.min_offr_recid oldest_offline_range, xcf.device_type, xcf.handle, xcf.comments, xcf.media, xcf.media_pool, xcf.start_time, xcf.completion_time, abs((xcf.completion_time - xcf.start_time) * 86400) elapsed_seconds, xcf.status, xcf.controlfile_type, decode(keep_options, 0, 'NO', 'YES') keep, keep_until, decode(keep_options, 256, 'LOGS', 512, 'NOLOGS', 1024, 'BACKUP_LOGS', NULL) keep_options, xcf.rsr_key, xcf.site_key from dbinc, xcf where dbinc.dbinc_key = xcf.dbinc_key >>> define rc_proxy_archivedlog <<< create or replace view rc_proxy_archivedlog as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, xal.xal_key, xal.xal_recid recid, xal.xal_stamp stamp, xal.tag, xal.device_type, xal.handle, xal.comments, xal.media, xal.media_pool, xal.status, xal.thread#, xal.sequence#, dbinc.reset_scn resetlogs_change#, dbinc.reset_time resetlogs_time, xal.low_scn first_change#, xal.low_time first_time, xal.next_scn next_change#, xal.next_time, xal.blocks, xal.block_size, xal.start_time, xal.completion_time, abs((xal.completion_time - xal.start_time) * 86400) elapsed_seconds, xal.rsr_key, xal.terminal, decode(keep_options, 0, 'NO', 'YES') keep, keep_until, decode(keep_options, 256, 'LOGS', 512, 'NOLOGS', 1024, 'BACKUP_LOGS', NULL) keep_options, xal.site_key from dbinc, xal where dbinc.dbinc_key = xal.dbinc_key >>> define rc_database_block_corruption <<< create or replace view rc_database_block_corruption as select node.db_key db_key, df.dbinc_key dbinc_key, df.file# file#, bcr.block# block#, bcr.blocks blocks, bcr.corrupt_scn corruption_change#, bcr.corruption_type corruption_type from bcr, df, (select dbinc_key from dbinc where dbinc_status = 'CURRENT') dbinc, (select distinct db_key, site_key from node where bcr_in_use = 'YES') node where bcr.df_key = df.df_key and node.site_key = bcr.site_key and df.drop_scn is null and df.dbinc_key = dbinc.dbinc_key union all select distinct outer.db_key db_key, outer.dbinc_key dbinc_key, outer.file# file#, outer.block# block#, outer.blocks blocks, outer.corruption_change# corruption_change#, outer.corruption_type corruption_type from (select db_key, dbinc_key, file#, block#, blocks, corruption_change#, copy_stamp stamp, corruption_type from rc_copy_corruption union select bs.db_key, dbinc_key, file#, block#, blocks, corruption_change#, bs.stamp, corruption_type from rc_backup_corruption bc, rc_backup_set bs where bc.bs_key = bs.bs_key) outer, (select distinct db_key from node where bcr_in_use = 'NO') node where outer.db_key = node.db_key and not exists (select 1 from rc_datafile_copy where outer.db_key = db_key and outer.dbinc_key = dbinc_key and scanned = 'YES' and outer.file# = file# and outer.stamp < stamp union select 1 from rc_backup_datafile bdf, rc_backup_set bs where bdf.bs_key = bs.bs_key and outer.db_key = bdf.db_key and outer.dbinc_key = bdf.dbinc_key and outer.file# = file# and outer.stamp < bs.stamp and (datafile_blocks = blocks_read or (nvl(bdf.incremental_level,0) = 0 and used_optimization='YES'))) >>> define drop_rc_lbRecVar_t <<< drop type rc_lbRecVar_t >>> define drop_rc_lbRecSet_t <<< drop type rc_lbRecSet_t >>> define drop_rc_lbRec_t <<< drop type rc_lbRec_t >>> define rc_lbRec_t <<< create or replace type rc_lbRec_t authid current_user as object ( list_order1 NUMBER, list_order2 NUMBER, pkey NUMBER, backup_type VARCHAR2(32), file_type VARCHAR2(32), keep VARCHAR2(3), keep_until DATE, keep_options VARCHAR2(13), status VARCHAR2(16), fname VARCHAR2(1024), tag VARCHAR2(32), media VARCHAR2(80), recid NUMBER, stamp NUMBER, device_type VARCHAR2(255), block_size NUMBER, completion_time DATE, is_rdf VARCHAR2(3), compressed VARCHAR2(3), obsolete VARCHAR2(3), bytes NUMBER, bs_key NUMBER, bs_count NUMBER, bs_stamp NUMBER, bs_type VARCHAR2(32), bs_incr_type VARCHAR2(32), bs_pieces NUMBER, bs_copies NUMBER, bs_completion_time DATE, bs_status VARCHAR2(16), bs_bytes NUMBER, bs_compressed VARCHAR2(3), bs_tag VARCHAR2(1024), bs_device_type VARCHAR2(255), bp_piece# NUMBER, bp_copy# NUMBER, df_file# NUMBER, df_ts# NUMBER, df_plugin_change# NUMBER, df_foreign_dbid NUMBER, df_tablespace VARCHAR2(30), df_resetlogs_change# NUMBER, df_creation_change# NUMBER, df_checkpoint_change# NUMBER, df_ckp_mod_time DATE, df_incremental_change# NUMBER, rl_thread# NUMBER, rl_sequence# NUMBER, rl_resetlogs_change# NUMBER, rl_first_change# NUMBER, rl_first_time DATE, rl_next_change# NUMBER, rl_next_time DATE ) >>> define rc_lbRecSet_t <<< create or replace type rc_lbRecSet_t as table of rc_lbRec_t >>> define drop_rc_lbRecSetImpl_t <<< drop type rc_lbRecSetImpl_t >>> define rc_lbRecSetImpl_t <<< create or replace type rc_lbRecSetImpl_t authid current_user as object ( curval number, -- current rownum done number, -- done with the query needobsolete number, -- user interested in obsolete col static function ODCITableStart(sctx IN OUT rc_lbRecSetImpl_t) return number, member function ODCITableFetch(self IN OUT rc_lbRecSetImpl_t, nrows IN number, objSet OUT rc_lbRecSet_t) return number, member function ODCITableClose(self IN rc_lbRecSetImpl_t) return number ) >>> define rc_lbRecSetImplbody_t <<< create or replace type body rc_lbRecSetImpl_t is -- -- -- static function ODCITableStart(sctx IN OUT rc_lbRecSetImpl_t) return number is begin -- sctx:=rc_lbRecSetImpl_t(0, 0, 1); return SYS.ODCIConst.Success; end ODCITableStart; -- -- -- -- member function ODCITableFetch(self IN OUT rc_lbRecSetImpl_t, nrows IN number, objSet OUT rc_lbRecSet_t) return number is n number := 0; firstCall boolean := TRUE; ret boolean := TRUE; redundancy number; recovery_window number; untilTime date; lbRec dbms_rcvman.lbrec_t; lbCursor dbms_rcvman.lbCursor_t; lbState dbms_rcvman.lbState_t; begin objSet:=rc_lbRecSet_t(); -- dbms_rcvman.resetAll; redundancy := 1; recovery_window := 0; -- -- -- dbms_rcvman.getRetentionPolicy(recovery_window, redundancy); -- dbms_rcvman.setAllIncarnations(TRUE); -- if (recovery_window > 0) then SELECT (sysdate-recovery_window) INTO untilTime from dual; dbms_rcvman.setUntilTime(untilTime); end if; dbms_rcvman.setDeviceTypeAny; if (recovery_window = 0 and redundancy = 0) then -- dbms_rcvman.setNeedObsoleteData(false); else if self.needobsolete = 1 then dbms_rcvman.setNeedObsoleteData(true); else dbms_rcvman.setNeedObsoleteData(false); end if; end if; while ret and self.done = 0 loop ret := dbms_rcvman.listBackup(lbRec, firstCall, FALSE, redundancy, TRUE, lbCursor, lbState, null); if (lbRec.pkey is not null) then objSet.extend; n := n + 1; objSet(n):= rc_lbRec_t( to_number(null), -- list_order1 to_number(null), -- list_order2 to_number(null), -- pkey to_char(null), -- backup_type to_char(null), -- file_type to_char(null), -- keep to_date(null), -- keep_until to_char(null), -- keep_options to_char(null), -- status to_char(null), -- fname to_char(null), -- tag to_char(null), -- media to_number(null), -- recid to_number(null), -- stamp to_char(null), -- device_type to_number(null), -- block_size to_date(null), -- completion_time to_char(null), -- is_rdf to_char(null), -- compressed to_char(null), -- obsolete to_number(null), -- bytes to_number(null), -- bs_key to_number(null), -- bs_count to_number(null), -- bs_stamp to_char(null), -- bs_type to_char(null), -- bs_incr_type to_number(null), -- bs_pieces to_number(null), -- bs_copies to_date(null), -- bs_completion_time to_char(null), -- bs_status to_number(null), -- bs_bytes to_char(null), -- bs_compressed to_char(null), -- bs_tag to_char(null), -- bs_device_type to_number(null), -- bp_piece# to_number(null), -- bp_copy# to_number(null), -- df_file# to_number(null), -- df_ts# to_number(null), -- df_plugin_change# to_number(null), -- df_foreign_dbid to_char(null), -- df_tablespace to_number(null), -- df_resetlogs_change# to_number(null), -- df_creation_change# to_number(null), -- df_checkpoint_change# to_date(null), -- df_ckp_mod_time to_number(null), -- df_incremental_change# to_number(null), -- rl_thread# to_number(null), -- rl_sequence# to_number(null), -- rl_resetlogs_change# to_number(null), -- rl_first_change# to_date(null), -- rl_first_time to_number(null), -- rl_next_change# to_date(null)); -- rl_next_time objSet(n).list_order1 := lbRec.list_order1; objSet(n).list_order2 := lbRec.list_order2; objSet(n).pkey := lbRec.pkey; objSet(n).backup_type := lbRec.backup_type; objSet(n).file_type := lbRec.file_type; objSet(n).keep := lbRec.keep; objSet(n).keep_until := lbRec.keep_until; objSet(n).keep_options := lbRec.keep_options; objSet(n).status := lbRec.status; objSet(n).fname := lbRec.fname; objSet(n).tag := lbRec.tag; objSet(n).media := lbRec.media; objSet(n).recid := lbRec.stamp; objSet(n).stamp := lbRec.stamp; objSet(n).device_type := lbRec.device_type; objSet(n).block_size := lbRec.block_size; objSet(n).completion_time := lbRec.completion_time; objSet(n).is_rdf := lbRec.is_rdf; objSet(n).compressed := lbRec.compressed; objSet(n).obsolete := lbRec.obsolete; objSet(n).bytes := lbRec.bytes; objSet(n).bs_key := lbRec.bs_key; objSet(n).bs_count := lbRec.bs_count; objSet(n).bs_stamp := lbRec.bs_stamp; objSet(n).bs_type := lbRec.bs_type; objSet(n).bs_incr_type := lbRec.bs_incr_type; objSet(n).bs_pieces := lbRec.bs_pieces; objSet(n).bs_copies := lbRec.bs_copies; objSet(n).bs_completion_time := lbRec.bs_completion_time; objSet(n).bs_status := lbRec.bs_status; objSet(n).bs_bytes := lbRec.bs_bytes; objSet(n).bs_compressed := lbRec.bs_compressed; objSet(n).bs_tag := lbRec.bs_tag; objSet(n).bs_device_type := lbRec.bs_device_type; objSet(n).bp_piece# := lbRec.bp_piece#; objSet(n).bp_copy# := lbRec.bp_copy#; objSet(n).df_file# := lbRec.df_file#; objSet(n).df_ts# := lbRec.df_ts#; objSet(n).df_plugin_change# := lbRec.df_plugin_change#; objSet(n).df_foreign_dbid := lbRec.df_foreign_dbid; objSet(n).df_tablespace := lbRec.df_tablespace; objSet(n).df_resetlogs_change# := lbRec.df_resetlogs_change#; objSet(n).df_creation_change# := lbRec.df_creation_change#; objSet(n).df_checkpoint_change# := lbRec.df_checkpoint_change#; objSet(n).df_ckp_mod_time := lbRec.df_ckp_mod_time; objSet(n).df_incremental_change# := lbRec.df_incremental_change#; objSet(n).rl_thread# := lbRec.rl_thread#; objSet(n).rl_sequence# := lbRec.rl_sequence#; objSet(n).rl_resetlogs_change# := lbRec.rl_resetlogs_change#; objSet(n).rl_first_change# := lbRec.rl_first_change#; objSet(n).rl_first_time := lbRec.rl_first_time; objSet(n).rl_next_change# := lbRec.rl_next_change#; objSet(n).rl_next_time := lbRec.rl_next_time; end if; firstCall := false; self.curval:=self.curval+1; if not ret then self.done := 1; end if; end loop; return SYS.ODCIConst.Success; end ODCITableFetch; member function ODCITableClose(self IN rc_lbRecSetImpl_t) return number is begin return SYS.ODCIConst.Success; end ODCITableClose; end; >>> define drop_rc_listBackupPipe <<< drop function rc_listBackupPipe >>> define rc_listBackupPipe <<< CREATE OR REPLACE FUNCTION rc_listBackupPipe RETURN rc_lbRecSet_t AUTHID DEFINER PIPELINED using rc_lbRecSetImpl_t; >>> define rc_backup_files <<< create or replace view rc_backup_files as select pkey, backup_type, file_type, keep, keep_until, keep_options, status, fname, tag, media, recid, stamp, device_type, block_size, completion_time, compressed, obsolete, bytes, bs_key, bs_count, bs_stamp, bs_type, bs_incr_type, bs_pieces, bs_copies, bs_completion_time, bs_status, bs_bytes, bs_compressed, bs_tag, bs_device_type, bp_piece#, bp_copy#, df_file#, df_tablespace, df_resetlogs_change#, df_creation_change#, df_checkpoint_change#, df_ckp_mod_time, rl_thread#, rl_sequence#, rl_resetlogs_change#, rl_first_change#, rl_first_time, rl_next_change#, rl_next_time from TABLE(rc_listBackupPipe) >>> define drop_rc_RangeRecVar_t <<< drop type rc_RangeRecVar_t >>> define drop_rc_RangeRecSet_t <<< drop type rc_RangeRecSet_t >>> define drop_rc_RangeRec_t <<< drop type rc_RangeRec_t >>> define rc_RangeRec_t <<< create or replace type rc_RangeRec_t authid current_user as object ( db_key NUMBER, site_key NUMBER, high_time DATE, low_time DATE, low_scn NUMBER, high_scn NUMBER, low_dbinc_key NUMBER, high_dbinc_key NUMBER ) >>> define rc_RangeRecSet_t <<< create or replace type rc_RangeRecSet_t as table of rc_RangeRec_t >>> define drop_rc_RangeRecSetImpl_t <<< drop type rc_RangeRecSetImpl_t >>> define rc_RangeRecSetImpl_t <<< create or replace type rc_RangeRecSetImpl_t authid current_user as object ( curval number, -- current rownum done number, -- done with the query opCode varchar2(20), -- backup/log location static function ODCITableStart(sctx IN OUT rc_RangeRecSetImpl_t, opCode IN varchar2) return number, member function ODCITableFetch(self IN OUT rc_RangeRecSetImpl_t, nrows IN number, objSet OUT rc_RangeRecSet_t) return number, member function ODCITableClose(self IN rc_RangeRecSetImpl_t) return number ) >>> define rc_RangeRecSetImplbody_t <<< create or replace type body rc_RangeRecSetImpl_t is static function ODCITableStart(sctx IN OUT rc_RangeRecSetImpl_t, opCode IN varchar2) return number is PRAGMA AUTONOMOUS_TRANSACTION; begin -- sctx:=rc_RangeRecSetImpl_t(0, 0, opCode); return SYS.ODCIConst.Success; end ODCITableStart; member function ODCITableFetch(self IN OUT rc_RangeRecSetImpl_t, nrows IN number, objSet OUT rc_RangeRecSet_t) return number is PRAGMA AUTONOMOUS_TRANSACTION; n number := 0; i number; indx number := 0; ret boolean; isOrs number := 0; site_aware boolean; dbid number := 0; dbkey number := 0; sitekey number := 0; single_site boolean := false; -- true means we are interested in -- hashval_old number; hashval_new number; high_bp_key_new number := 0; last_do_key_new number := 0; valfound boolean; no_of_entries number := 0; no_of_db number := 0; dev_type varchar(32); high_bp_key_old number; last_do_key_old number; max_range_scn number; maxScnExist boolean; maxScn number; maxTime date; maxDbIncKey number; maxRlgScn number; maxRlgTime date; logMissing boolean; logBreakPointScn number; logBreakPointTime date; logBreakDbIncKey number; logBreakRlgScn number; logBreakRlgTime date; restoreRangeTab dbms_rcvman.restoreRangeTab_t; CURSOR getAllDb_c IS SELECT db_key, db_id FROM db; CURSOR getAllSite_c IS SELECT site_key, db.db_key, db_unique_name, db_id FROM node, db WHERE node.db_key = db.db_key order by db_key; CURSOR restore_range_c ( dbkey_p IN number, dev_type_p IN varchar2) IS SELECT * FROM rrcache WHERE db_key = dbkey_p AND range_type=dev_type_p; dbDetail getAllDb_c%rowtype; siteDetail getAllSite_c%rowtype; restore_range_r restore_range_c%rowtype; begin dbkey := dbms_rcvman.getDbKey; -- if dbkey is null then single_site := false; open getAllDb_c; open getAllSite_c; else -- user is interested for a particular db SELECT db_id INTO dbid from db where db_key = dbkey; single_site := true; end if; objSet := rc_RangeRecSet_t(); if (single_site = false) then dbms_rcvman.resetAll; end if; dbms_rcvman.setAllIncarnations(TRUE); -- if (substr(opCode, 1, 2) = 'RA') then isOrs := 1; else isOrs := 0; end if; -- dbms_rcvman.resetDeviceType; -- if (isOrs = 1) then dbms_rcvman.setDeviceType('SBT_TAPE'); if (substr(opCode, 4, 3) = 'ANY') then dev_type := 'RA$ANY'; elsif (substr(opCode, 4, 4) = 'DISK') then dev_type := 'RA$DISK'; elsif (substr(opCode, 4, 3) = 'SBT') then dev_type := 'RA$SBT'; end if; else if (substr(opCode, 4, 3) = 'ANY') then dbms_rcvman.setDeviceTypeAny; dev_type := 'RC$ANY'; elsif (substr(opCode, 4, 4) = 'DISK') then dbms_rcvman.setDeviceType('DISK'); dev_type := 'RC$DISK'; elsif (substr(opCode, 4, 3) = 'SBT') then dbms_rcvman.setDeviceType('SBT_TAPE'); dev_type := 'RC$SBT'; end if; end if; if ((substr(opCode, 8, 10) = 'SITE_AWARE') or (substr(opCode, 9, 10) = 'SITE_AWARE')) then site_aware := TRUE; else site_aware := FALSE; end if; -- WHILE self.done = 0 LOOP n := n + 1; exit when n = 2 and single_site = true; IF (isOrs = 1) THEN if (single_site = false) then fetch getAllDb_c into dbDetail; exit when getAllDb_c%NOTFOUND; dbkey := dbDetail.db_key; dbid := dbDetail.db_id; end if; ELSE if (single_site = false) then fetch getAllSite_c into siteDetail; exit when getAllSite_c%NOTFOUND; dbkey := siteDetail.db_key; dbid := siteDetail.db_id; sitekey := siteDetail.site_key; end if; END IF; -- select max(max_bp_key) into high_bp_key_old from rrcache where db_key = dbkey and range_type = dev_type; select max(last_do_key) into last_do_key_old from rrcache where db_key = dbkey and range_type = dev_type; -- IF (isOrs = 1) THEN SELECT NVL(MAX(bp_key), 0) INTO high_bp_key_new FROM (SELECT bp_key FROM bp WHERE db_key = dbkey ORDER BY 1 DESC) WHERE ROWNUM = 1; ELSE high_bp_key_new := 0; END IF; SELECT NVL(MAX(curr_value), 0) INTO last_do_key_new FROM do_seq WHERE db_key = dbkey; valfound := FALSE; -- -- -- -- IF (isOrs = 0) THEN valfound := FALSE; -- -- -- ELSIF (high_bp_key_old < high_bp_key_new and last_do_key_new = last_do_key_old) THEN dbms_rcvman.setRestoreRangeDevTyp(dev_type); ret := dbms_rcvman.setLocalOrsSiteKey(dbid); -- -- -- IF ret = TRUE THEN maxScnExist := dbms_rcvman.getMaxRedoSCN(maxScn, maxTime, maxDbIncKey, maxRlgScn, maxRlgTime, isOrs); IF (maxScnExist) THEN SELECT nvl(max(high_scn), 0) INTO max_range_scn FROM rrcache WHERE db_key = dbkey AND range_type = dev_type AND high_scn < maxScn; -- -- logMissing := dbms_rcvman.findLogBreakPoint(logBreakPointScn, logBreakPointTime, logBreakDbIncKey, logBreakRlgScn, logBreakRlgTime, max_range_scn, maxScn, isOrs); IF (logMissing = FALSE and max_range_scn > 0) THEN UPDATE rrcache SET high_scn = maxScn, high_time = maxTime, high_dbinc_key = maxDbIncKey, last_updated = sysdate WHERE db_key = dbkey and range_type = dev_type and high_scn = max_range_scn; commit; valfound := TRUE; END IF; END IF; END IF; dbms_rcvman.resetLocalOrsSiteKey; dbms_rcvman.resetRestoreRangeDevTyp; ELSIF (high_bp_key_old = high_bp_key_new and last_do_key_new = last_do_key_old) THEN valfound := true; END IF; if valfound = false then if single_site = false then if (isOrs = 1) then dbms_rcvman.setdatabase(NULL, NULL, NULL, dbDetail.db_id); else dbms_rcvman.setdatabase(db_name => NULL, reset_scn => NULL, reset_time => NULL, db_id => siteDetail.db_id, db_unique_name => siteDetail.db_unique_name, site_aware => site_aware, dummy_instance => FALSE, ors_instance => FALSE); end if; end if; ret := dbms_rcvman.getRestoreRangeSet(restoreRangeTab, opCode, dbid); end if; -- -- IF (valfound = true) then OPEN restore_range_c(dbkey, dev_type); loop FETCH restore_range_c INTO restore_range_r; EXIT WHEN restore_range_c%NOTFOUND; objSet.extend; indx := indx + 1; objSet(indx) := rc_RangeRec_t( to_number(null), to_number(null), to_date(null), to_date(null), to_number(null), to_number(null), to_number(null), to_number(null)); objSet(indx).db_key := dbkey; objSet(indx).site_key := sitekey; objSet(indx).low_time := restore_range_r.low_time; objSet(indx).high_time := restore_range_r.high_time; objSet(indx).low_scn := restore_range_r.low_scn; objSet(indx).high_scn := restore_range_r.high_scn; objSet(indx).low_dbinc_key := restore_range_r.low_dbinc_key; objSet(indx).high_dbinc_key := restore_range_r.high_dbInc_key; end loop; CLOSE restore_range_c; -- -- ELSE no_of_entries := 0; i := null; -- DELETE FROM rrcache where db_key = dbkey and range_type = dev_type; commit; loop if (i is null) then i := restoreRangeTab.first; else i := restoreRangeTab.next(i); end if; exit when i is NULL; if (restoreRangeTab(i).isValidRange = TRUE) then objSet.extend; indx := indx + 1; objSet(indx) := rc_RangeRec_t( to_number(null), to_number(null), to_date(null), to_date(null), to_number(null), to_number(null), to_number(null), to_number(null)); if (ret = TRUE) then no_of_entries := no_of_entries + 1; objSet(indx).db_key := dbkey; objSet(indx).site_key := sitekey; objSet(indx).low_time := restoreRangeTab(i).lowTime; objSet(indx).high_time := restoreRangeTab(i).highTime; objSet(indx).low_scn := restoreRangeTab(i).lowScn; objSet(indx).high_scn := restoreRangeTab(i).highScn; objSet(indx).low_dbinc_key := restoreRangeTab(i).lowDbIncKey; objSet(indx).high_dbinc_key := restoreRangeTab(i).highDbIncKey; end if; end if; -- if restoreRangeTab(i).isValidRange = TRUE and ret = TRUE then INSERT INTO rrcache( db_key, low_time, high_time, low_scn, high_scn, low_dbinc_key, high_dbinc_key, range_type, max_bp_key, last_do_key, last_updated) values (dbkey, restoreRangeTab(i).lowTime, restoreRangeTab(i).highTime, restoreRangeTab(i).lowScn, restoreRangeTab(i).highScn, restoreRangeTab(i).lowDbIncKey, restoreRangeTab(i).highDbIncKey, dev_type, high_bp_key_new, last_do_key_new, sysdate); commit; end if; end loop; -- loop ends for each restore range of a database END IF; -- end of if (valfound = true) -- if (single_site = false) then dbms_rcvman.resetdbkey; end if; self.curval := self.curval + 1; END LOOP; -- loop ends for each database -- if (single_site = false) then dbms_rcvman.resetdbkey; end if; self.done := 1; if (single_site = false) then close getAllDb_c; close getAllSite_c; end if; return SYS.ODCIConst.Success; EXCEPTION WHEN others THEN dbms_rcvman.resetDeviceType; if getAllDb_c%ISOPEN then close getAllDb_c; end if; if getAllSite_c%ISOPEN then close getAllSite_c; end if; return SYS.ODCIConst.Error; end ODCITableFetch; member function ODCITableClose(self IN rc_RangeRecSetImpl_t) return number is begin return SYS.ODCIConst.Success; end ODCITableClose; end; >>> define drop_rc_listRsRangePipe <<< drop function rc_listRsRangePipe >>> define rc_listRsRangePipe <<< CREATE OR REPLACE FUNCTION rc_listRsRangePipe (opCode IN varchar2) RETURN rc_RangeRecSet_t AUTHID DEFINER PIPELINED using rc_RangeRecSetImpl_t; >>> define rc_restore_range <<< create or replace view rc_restore_range as select db_key, site_key, low_time, high_time, low_scn, high_scn, low_dbinc_key, high_dbinc_key from TABLE(rc_listRsRangePipe('RC$ANY$SITE_AWARE')) >>> define rc_disk_restore_range <<< create or replace view rc_disk_restore_range as select db_key, site_key, low_time, high_time, low_scn, high_scn, low_dbinc_key, high_dbinc_key from TABLE(rc_listRsRangePipe('RC$DISK$SITE_AWARE')) >>> define rc_sbt_restore_range <<< create or replace view rc_sbt_restore_range as select db_key, site_key, low_time, high_time, low_scn, high_scn, low_dbinc_key, high_dbinc_key from TABLE(rc_listRsRangePipe('RC$SBT$SITE_AWARE')) >>> define rc_rman_status <<< create or replace view rc_rman_status as select dbinc.db_key, dbinc.dbinc_key, dbinc.db_name, rsr.rsr_recid recid, rsr.rsr_stamp stamp, rsr.rsr_key rsr_key, rsr.rsr_pkey parent_key, nvl(rsr.rsr_l0key, rsr.rsr_key) session_key, rsr.rsr_type row_type, rsr.rsr_level row_level, rsr.rsr_oper operation, rsr.rsr_status status, rsr.rsr_cmdid command_id, rsr.rsr_mbytes mbytes_processed, rsr.rsr_start start_time, rsr.rsr_end end_time, nvl(rsr.rsr_l0key, rsr.rsr_key) job_key, rsr.rsr_ibytes input_bytes, rsr.rsr_obytes output_bytes, rsr.rsr_optimized optimized, rsr.rsr_otype object_type, rsr.rsr_srecid session_recid, rsr.rsr_sstamp session_stamp, rsr.rsr_odevtype output_device_type, rsr.site_key site_key, decode(rsr.rsr_osb_allocated, 'Y', 'YES', 'NO') osb_allocated from dbinc, rsr where dbinc.dbinc_key = rsr.dbinc_key >>> define drop_rc_rout <<< drop table rout >>> define drop_rc_rman_output <<< drop view rc_rman_output >>> define rc_rman_output <<< create or replace view rc_rman_output as select db_key, rsr_key, site_key, rout_skey session_key, rout_recid recid, rout_stamp stamp, rout_text output from rout >>> define rc_rman_backup_subjob_details <<< create or replace view RC_RMAN_BACKUP_SUBJOB_DETAILS as select a.*, decode(nvl(b.autocnt,0), 0, 'NO', 'YES') autobackup_done, decode(status_weight, 2000, 'FAILED', 1900, 'RUNNING WITH ERRORS', 1500, 'RUNNING WITH WARNINGS', 1001, 'RUNNING', 900, 'COMPLETED WITH ERRORS', 500, 'COMPLETED WITH WARNINGS', 001, 'COMPLETED', 'FAILED') status, decode(input_type_weight,9, 'DB FULL', 8, 'RECVR AREA', 7, 'DB INCR', 6, 'DATAFILE FULL', 5, 'DATAFILE INCR', 4, 'ARCHIVELOG', 3, 'CONTROLFILE', 2, 'SPFILE', 1, 'BACKUPSET', null) input_type, decode(optimized_weight, 1, 'YES', 'NO') optimized, nvl(b.autocnt,0) autobackup_count, case when input_bytes/decode(output_bytes,0,null,output_bytes)>1 then input_bytes/decode(output_bytes,0,null,output_bytes) else 1 end compression_ratio, dbms_rcvman.Num2DisplaySize(input_bytes) input_bytes_display, dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display from ( select unique db_key, db_name, session_key, session_recid, session_stamp, operation, command_id, min(start_time) over (partition by session_key, operation) start_time, max(end_time) over (partition by session_key, operation) end_time, sum(input_bytes) over (partition by session_key, operation) input_bytes, sum(output_bytes) over (partition by session_key, operation) output_bytes, max(status_weight) over (partition by session_key, operation)status_weight, max(optimized_weight) over (partition by session_key, operation) optimized_weight, max(input_type_weight) over (partition by session_key, operation) input_type_weight, decode(count(distinct output_device_type) over (partition by session_key, operation),1, first_value(output_device_type) over (partition by session_key, operation),0, null, '*') output_device_type, decode(count(distinct osb_allocated) over (partition by session_key, operation),1, first_value(osb_allocated) over (partition by session_key, operation),0, 'NO', '*') backed_by_osb from (select d.*, decode(status, 'RUNNING', 1001, 'RUNNING WITH WARNINGS', 1500, 'RUNNING WITH ERRORS', 1900, 'COMPLETED', 0001, 'COMPLETED WITH WARNINGS', 500, 'COMPLETED WITH ERRORS', 900, 'FAILED', 2000, 2000) status_weight, decode(optimized,'YES', 1, 0) optimized_weight, decode(object_type, 'DB FULL', 9, 'RECVR AREA', 8, 'DB INCR', 7, 'DATAFILE FULL', 6, 'DATAFILE INCR', 5, 'ARCHIVELOG', 4, 'CONTROLFILE', 3, 'SPFILE', 2, 'BACKUPSET', 1, 0) input_type_weight from rc_rman_status d where operation like 'BACKUP%' and row_level=1)) a, ( select session_key, count(*) autocnt from rc_rman_status where operation like '%AUTOBACKUP%' and row_level > 1 group by session_key ) b where a.session_key=b.session_key (+) >>> define rc_rman_backup_job_details <<< create or replace view RC_RMAN_BACKUP_JOB_DETAILS as select a.*, dbms_rcvman.Num2DisplaySize(input_bytes) input_bytes_display, dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display, dbms_rcvman.Num2DisplaySize(input_bytes_per_sec) input_bytes_per_sec_display, dbms_rcvman.Num2DisplaySize(output_bytes_per_sec) output_bytes_per_sec_display, dbms_rcvman.Sec2DisplayTime(elapsed_seconds) time_taken_display from (select unique a.*, decode(autobackup_count, 0, 'NO', 'YES') autobackup_done, decode(status_weight, 2000, 'FAILED', 1900, 'RUNNING WITH ERRORS', 1500, 'RUNNING WITH WARNINGS', 1001, 'RUNNING', 900, 'COMPLETED WITH ERRORS', 500, 'COMPLETED WITH WARNINGS', 001, 'COMPLETED', 'FAILED') status, decode(input_type_weight,9, 'DB FULL', 8, 'RECVR AREA', 7, 'DB INCR', 6, 'DATAFILE FULL', 5, 'DATAFILE INCR', 4, 'ARCHIVELOG', 3, 'CONTROLFILE', 2, 'SPFILE', 1, 'BACKUPSET', null) input_type, decode(optimized_weight, 1, 'YES', 'NO') optimized, abs(a.end_time-a.start_time)*86400 elapsed_seconds, case when a.input_bytes/decode(a.output_bytes,0,null,a.output_bytes)>1 then a.input_bytes/decode(a.output_bytes,0,null,a.output_bytes) else 1 end compression_ratio, a.input_bytes/(decode(a.end_time-a.start_time, 0, 1, abs(a.end_time-a.start_time))*86400) input_bytes_per_sec, a.output_bytes/(decode(a.end_time-a.start_time, 0, 1, abs(a.end_time-a.start_time))*86400) output_bytes_per_sec from (select db_key, db_name, session_key, session_recid, session_stamp, command_id, min(start_time) over (partition by session_key) start_time, max(end_time) over (partition by session_key) end_time, sum(input_bytes) over (partition by session_key) input_bytes, sum(output_bytes) over (partition by session_key) output_bytes, max(status_weight) over (partition by session_key)status_weight, max(optimized_weight) over (partition by session_key) optimized_weight, max(input_type_weight) over (partition by session_key) input_type_weight, decode(count(distinct output_device_type) over (partition by session_key),1, first_value(output_device_type) over (partition by session_key),0, null, '*') output_device_type, sum(autobackup_count) over (partition by session_key) autobackup_count, backed_by_osb from RC_RMAN_BACKUP_SUBJOB_DETAILS) a) a >>> define rc_backup_set_details <<< create or replace view RC_BACKUP_SET_DETAILS as select unique b.session_key, b.session_recid, b.session_stamp, a.db_key, f.db_name, a.bs_key, a.RECID, a.stamp, a.set_stamp, a.set_count, a.backup_type, a.controlfile_included, a.incremental_level, a.pieces, a.start_time, a.completion_time, a.elapsed_seconds, a.block_size, a.keep, a.keep_until, a.keep_options, a.device_type, a.compressed, a.num_copies, a.output_bytes, a.original_input_bytes, case when a.compression_ratio>1 then a.compression_ratio else 1 end compression_ratio, 'A' status, a.original_inprate_bytes, a.output_rate_bytes, dbms_rcvman.Num2DisplaySize(original_input_bytes) original_input_bytes_display, dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display, dbms_rcvman.Num2DisplaySize(original_inprate_bytes) original_inprate_bytes_display, dbms_rcvman.Num2DisplaySize(output_rate_bytes) output_rate_bytes_display, dbms_rcvman.Sec2DisplayTime(elapsed_seconds) time_taken_display, a.encrypted, a.backed_by_osb from ( select unique a.*, b.rsr_key, decode(b.devcnt, 1, first_value(b.device_type) over (partition by b.bs_key), '*') device_type, b.compressed, count(distinct copy#) over (partition by b.bs_key) num_copies, b.output_bytes output_bytes, c.original_input_bytes, c.original_input_bytes / (decode(b.output_bytes,0,c.original_input_bytes, b.output_bytes)) compression_ratio, c.original_input_bytes/ (decode(a.elapsed_seconds, 0, 1, a.elapsed_seconds)) original_inprate_bytes, b.output_bytes/ (decode(a.elapsed_seconds, 0, 1, a.elapsed_seconds)) output_rate_bytes, b.encrypted, b.backed_by_osb from rc_backup_set a, (select bs_key, device_type, status, count(distinct device_type) over (partition by bs_key)devcnt, compressed, sum(bytes) over (partition by bs_key, copy#) output_bytes, copy#, rsr_key, count(piece#) over (partition by bs_key, copy#) npieces, encrypted, backed_by_osb from rc_backup_piece where status = 'A') b, ( select bs_key, sum(original_input_bytes) original_input_bytes from ( select bs_key, sum((datafile_blocks+1)*block_size) over (partition by bs_key) original_input_bytes from rc_backup_datafile union select bs_key, sum((blocks+1)*block_size) over (partition by bs_key) original_input_bytes from rc_backup_controlfile union select bs_key, sum(bytes) over (partition by bs_key) original_input_bytes from rc_backup_spfile ) group by bs_key union select bs_key, sum((blocks+1)*block_size) over (partition by bs_key) original_input_bytes from rc_backup_redolog ) c where a.bs_key=b.bs_key and a.bs_key=c.bs_key and a.pieces=b.npieces ) a, (select session_key, session_recid, session_stamp, recid, stamp, rsr_key, start_time, end_time, db_key, db_name from rc_rman_status) b, (select db_key, name "DB_NAME" from rc_database) f, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.rsr_key = b.rsr_key (+) and a.db_key = f.db_key and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time) >>> define rc_backup_piece_details <<< create or replace view RC_BACKUP_PIECE_DETAILS as select unique b.session_key,b.session_recid,b.session_stamp, a.*, dbms_rcvman.Num2DisplaySize(bytes) size_bytes_display from (select f.db_name, c.* from rc_backup_set a, (select rc_backup_piece.*, count(piece#) over (partition by bs_key, copy#) pieces_per_set from rc_backup_piece where status = 'A') c, (select db_key, name "DB_NAME" from rc_database) f where a.bs_key = c.bs_key and a.db_key = f.db_key and a.pieces = c.pieces_per_set) a, (select session_key, session_recid, session_stamp, recid, stamp, rsr_key, start_time, end_time, db_key, db_name from rc_rman_status) b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.status = 'A' and a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time) >>> define rc_backup_copy_details <<< create or replace view RC_BACKUP_COPY_DETAILS as select a.*, dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display from (select b.session_key, b.session_recid, b.session_stamp, a.* from ((select db_key, db_name, rsr_key, cdf_key copy_key, file#, name, tag, creation_change#, creation_time, checkpoint_change#, checkpoint_time, marked_corrupt, (blocks+1)*block_size output_bytes, completion_time, null controlfile_type, keep, keep_until, keep_options, is_recovery_dest_file, sparse_backup from rc_datafile_copy where status='A') union (select db_key, db_name, rsr_key, ccf_key copy_key, 0, name, tag, null creation_change#, creation_time, checkpoint_change#, checkpoint_time, null, (blocks +1)*block_size output_bytes, completion_time, controlfile_type, keep, keep_until, keep_options, is_recovery_dest_file, 'NO' sparse_backup from rc_controlfile_copy where status='A')) a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time))a >>> define rc_proxy_copy_details <<< create or replace view RC_PROXY_COPY_DETAILS as select a.*, dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display from (select b.session_recid session_key, b.session_recid, b.session_stamp, a.* from (select db_key, db_name, rsr_key, xdf_key copy_key, file#, handle,comments, media,media_pool, tag, creation_change#, creation_time, checkpoint_change#, checkpoint_time, (blocks+1)*block_size output_bytes, completion_time, null controlfile_type, keep, keep_until, keep_options from rc_proxy_datafile where status = 'A' union select db_key, db_name, rsr_key, xcf_key copy_key, 0, handle,comments, media,media_pool, tag, null creation_change#, creation_time, checkpoint_change#, checkpoint_time, (blocks+1)*block_size output_bytes, completion_time, controlfile_type, keep, keep_until, keep_options from rc_proxy_controlfile where status='A') a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time))a >>> define rc_proxy_archivelog_details <<< create or replace view RC_PROXY_ARCHIVELOG_DETAILS as select a.*, dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display from (select b.rsr_key session_key, b.session_recid, b.session_stamp, a.db_key, a.db_name, a.recid copy_key, a.thread#, a.sequence#, a.resetlogs_change#, a.resetlogs_time, a.handle, a.media, a.media_pool, a.tag, a.first_change#, a.next_change#, a.first_time, a.next_time, (a.blocks+1)*a.block_size output_bytes, a.completion_time from rc_proxy_archivedlog a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.status = 'A' and a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time))a >>> define rc_backup_datafile_details <<< CREATE OR REPLACE VIEW RC_BACKUP_DATAFILE_DETAILS AS select a.*, b.con_id, b.pdb_name, b.pdb_key, b.ts#, b.name tsname, dbms_rcvman.Num2DisplaySize(filesize) filesize_display from (select unique 'BACKUPSET' btype, b.bs_key btype_key, b.session_key, b.session_recid, b.session_stamp, b.db_key, b.db_name, a.set_stamp id1, b.set_count id2, file#, creation_change#, creation_time, resetlogs_change#, resetlogs_time, a.incremental_level, incremental_change#, checkpoint_change#, checkpoint_time, marked_corrupt, (datafile_blocks+1)*a.block_size filesize, (datafile_blocks+1)/(blocks+1) compression_ratio, a.sparse_backup from rc_backup_datafile a, rc_backup_set_details b where a.bs_key = b.bs_key union select unique 'IMAGECOPY' btype, a.cdf_key btype_key, b.session_key, b.session_recid, b.session_stamp, a.db_key, a.db_name, a.recid, a.stamp, file#, creation_change#, creation_time, resetlogs_change#, resetlogs_time, incremental_level, 0 incremental_change#, checkpoint_change#, checkpoint_time, marked_corrupt, (blocks+1)*block_size filesize, 1 compression_ratio, a.sparse_backup from rc_datafile_copy a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.status = 'A' and a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time) union select unique 'PROXYCOPY' btype, a.xdf_key btype_key, b.session_key, b.session_recid, b.session_stamp, a.db_key, a.db_name, a.recid, a.stamp, file#, creation_change#, creation_time, resetlogs_change#, resetlogs_time, incremental_level, 0 incremental_change#, checkpoint_change#, checkpoint_time, null marked_corrupt, (blocks+1)*block_size filesize, 1 compression_ratio, 'NO' sparse_backup from rc_proxy_datafile a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.status = 'A' and a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time)) a, (select distinct df.db_key, df.file#, df.ts#, df.con_id, df.pdb_name, df.pdb_key, ts.name from rci_datafile df, rc_tablespace ts where ts.ts# = df.ts# and ts.pdb_key = df.pdb_key and df.db_key=ts.db_key) b where a.file# = b.file#(+) and a.db_key=b.db_key(+) >>> define rc_backup_controlfile_details <<< CREATE Or REPLACE VIEW RC_BACKUP_CONTROLFILE_DETAILS AS select a.*, dbms_rcvman.Num2DisplaySize(filesize) filesize_display from (select unique 'BACKUPSET' btype, b.bs_key btype_key, b.session_key, b.session_recid, b.session_stamp, a.db_key, a.db_name, a.set_stamp id1, b.set_count id2, creation_time, resetlogs_change#, resetlogs_time, checkpoint_change#, checkpoint_time, (a.blocks+1)*a.block_size filesize, 1 compression_ratio from rc_backup_controlfile a, rc_backup_set_details b where a.bs_key = b.bs_key union select unique 'IMAGECOPY' btype, a.ccf_key btype_key, b.session_key, b.session_recid, b.session_stamp, a.db_key, a.db_name, a.recid, a.stamp, creation_time, resetlogs_change#, resetlogs_time, checkpoint_change#, checkpoint_time, (blocks+1)*block_size filesize, 1 compression_ratio from rc_controlfile_copy a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.status = 'A' and a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time) union select unique 'PROXYCOPY' btype, a.xcf_key btype_key, b.session_key, b.session_recid, b.session_stamp, a.db_key, a.db_name, a.recid, a.stamp, creation_time, resetlogs_change#, resetlogs_time, checkpoint_change#, checkpoint_time, (blocks+1)*block_size filesize, 1 compression_ratio from rc_proxy_controlfile a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.status = 'A' and a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_recid) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time))a >>> define rc_backup_archivelog_details <<< CREATE Or REPLACE VIEW RC_BACKUP_ARCHIVELOG_DETAILS AS select a.*, dbms_rcvman.Num2DisplaySize(filesize) filesize_display from (select unique 'BACKUPSET' btype, b.bs_key btype_key, b.session_key, b.session_recid, b.session_stamp, a.db_key, a.db_name, a.set_stamp id1, b.set_count id2, thread#, sequence#, resetlogs_change#, resetlogs_time, first_change#, first_time, next_change#, next_time, (blocks+1)*a.block_size filesize, b.compression_ratio from rc_backup_redolog a, rc_backup_set_details b where a.bs_key = b.bs_key union select unique 'PROXYCOPY', a.xal_key btype_key, session_key, session_recid, session_stamp, a.db_key, a.db_name, a.recid, a.stamp, thread#, sequence#, resetlogs_change#, resetlogs_time, first_change#, first_time, next_change#, next_time, (blocks+1)*block_size filesize, 1 from rc_proxy_archivedlog a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.status = 'A' and a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time))a >>> define rc_backup_spfile_details <<< CREATE Or REPLACE VIEW RC_BACKUP_SPFILE_DETAILS AS select unique b.session_recid session_key, b.session_recid, b.session_stamp, b.db_key, b.db_name, b.recid bs_key, a.set_stamp, b.set_count, modification_time, a.bytes filesize, dbms_rcvman.Num2DisplaySize(a.bytes) filesize_display from rc_backup_spfile a, rc_backup_set_details b where a.bs_key = b.bs_key >>> define rc_backup_set_summary <<< CREATE Or REPLACE VIEW RC_BACKUP_SET_SUMMARY AS select db.name db_name, a.*, case when original_input_bytes/decode(output_bytes, 0, null, output_bytes) > 1 then original_input_bytes/decode(output_bytes, 0, null, output_bytes) else 1 end compression_ratio, dbms_rcvman.Num2DisplaySize(original_input_bytes) original_input_bytes_display, dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display , dbms_rcvman.Num2DisplaySize(original_inprate_bytes) original_inprate_bytes_display, dbms_rcvman.Num2DisplaySize(output_rate_bytes) output_rate_bytes_display from (select db_key, count(*) num_backupsets, min(start_time) oldest_backup_time, max(start_time) newest_backup_time, sum(output_bytes) output_bytes, sum(original_input_bytes) original_input_bytes, avg(original_inprate_bytes) original_inprate_bytes, avg(output_rate_bytes) output_rate_bytes from (select unique db_key, set_stamp, set_count, start_time, output_bytes, original_input_bytes, original_inprate_bytes, output_rate_bytes, compression_ratio from rc_backup_set_details) group by db_key)a, rc_database db where db.db_key = a.db_key >>> define rc_backup_datafile_summary <<< CREATE OR REPLACE VIEW RC_BACKUP_DATAFILE_SUMMARY AS select db.name db_name, a.*, case when input_bytes/decode(output_bytes, 0, null, output_bytes) > 1 then input_bytes/decode(output_bytes, 0, null, output_bytes) else 1 end compression_ratio, dbms_rcvman.Num2DisplaySize(input_bytes) input_bytes_display, dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display from (select db_key, sum(num_times_backed) num_files_backed, sum(distinct_files_backed) num_distinct_files_backed, count(distinct ts# || '.' || pdb_key) num_distinct_ts_backed, min(min_checkpoint_change#) min_checkpoint_change#, max(max_checkpoint_change#) max_checkpoint_change#, min(min_checkpoint_time) min_checkpoint_time, max(max_checkpoint_time) max_checkpoint_time, sum(input_bytes) input_bytes, sum(output_bytes) output_bytes from ( select a.*, b.ts#, b.pdb_key, count(distinct a.file#) over (partition by a.file#, a.creation_change#) distinct_files_backed from (select unique a.db_key, a.file#, sum(a.num_times_backed) num_times_backed, min(min_checkpoint_change#) min_checkpoint_change#, max(max_checkpoint_change#) max_checkpoint_change#, min(min_checkpoint_time) min_checkpoint_time, max(max_checkpoint_time) max_checkpoint_time, sum(input_bytes) input_bytes, sum(output_bytes) output_bytes, creation_change# from ((select a.db_key, file#,count(*) over (partition by a.db_key,file#, creation_change#) num_times_backed, min(checkpoint_change#) over (partition by a.db_key,file#, creation_change#) min_checkpoint_change#, max(checkpoint_change#) over (partition by a.db_key,file#, creation_change#) max_checkpoint_change#, min(checkpoint_time) over (partition by a.db_key,file#, creation_change#) min_checkpoint_time, max(checkpoint_time) over (partition by a.db_key,file#, creation_change#) max_checkpoint_time, sum((datafile_blocks+1)*a.block_size) over (partition by a.db_key,file#, creation_change#) input_bytes, sum((a.blocks+1)*a.block_size) over (partition by a.db_key,file#, creation_change#) output_bytes, creation_change# from rc_backup_datafile a, (select unique db_key, bs_key from rc_backup_set_details) b where a.bs_key = b.bs_key and a.db_key = b.db_key ) union (select unique a.db_key, file#, count(*) over (partition by a.db_key, file#, creation_change#) num_times_backed, min(checkpoint_change#) over (partition by a.db_key, file#, creation_change#) min_checkpoint_change#, max(checkpoint_change#) over (partition by a.db_key, file#, creation_change#) max_checkpoint_change#, min(checkpoint_time) over (partition by a.db_key, file#, creation_change#) min_checkpoint_time, max(checkpoint_time) over (partition by a.db_key,file#, creation_change#) max_checkpoint_time, sum((blocks+1)*block_size) over (partition by a.db_key,file#, creation_change#) input_bytes, sum((blocks+1)*block_size) over (partition by a.db_key,file#, creation_change#) output_bytes, creation_change# from rc_datafile_copy a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.status = 'A' and a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time) and a.db_key = b.db_key ) union (select unique a.db_key, file#, count(*) over (partition by a.db_key, file#, creation_change#) num_times_backed, min(checkpoint_change#) over (partition by a.db_key, file#, creation_change#) min_checkpoint_change#, max(checkpoint_change#) over (partition by a.db_key, file#, creation_change#) max_checkpoint_change#, min(checkpoint_time) over (partition by a.db_key, file#, creation_change#) min_checkpoint_time, max(checkpoint_time) over (partition by a.db_key, file#, creation_change#) max_checkpoint_time, sum((blocks+1)*block_size) over (partition by a.db_key, file#, creation_change#) input_bytes, sum((blocks+1)*block_size) over (partition by a.db_key, file#, creation_change#) output_bytes, creation_change# from rc_proxy_datafile a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.status = 'A' and a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time) and a.db_key = b.db_key )) a group by a.db_key, a.file#, creation_change#) a, (select distinct df.db_key, df.file#, df.ts#, df.pdb_key, ts.name from rci_datafile df, rc_tablespace ts where ts.ts# = df.ts# and ts.pdb_key = df.pdb_key and ts.db_key = df.db_key) b where a.db_key = b.db_key and a.file# = b.file#(+)) group by db_key)a, rc_database db where a.db_key = db.db_key >>> define rc_backup_controlfile_summary <<< CREATE OR REPLACE VIEW RC_BACKUP_CONTROLFILE_SUMMARY AS select b.name db_name, a.*, case when input_bytes/decode(output_bytes, 0, null, output_bytes) > 1 then input_bytes/decode(output_bytes, 0, null, output_bytes) else 1 end compression_ratio, dbms_rcvman.Num2DisplaySize(input_bytes) input_bytes_display, dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display from (select db_key, sum(num_times_backed) num_files_backed, 1 num_distinct_files_backed, min(min_checkpoint_change#) min_checkpoint_change#, max(max_checkpoint_change#) max_checkpoint_change#, min(min_checkpoint_time) min_checkpoint_time, max(max_checkpoint_time) max_checkpoint_time, sum(input_bytes) input_bytes, sum(output_bytes) output_bytes from ((select a.db_key, count(*) over (partition by creation_time) num_times_backed, min(checkpoint_change#) over (partition by creation_time) min_checkpoint_change#, max(checkpoint_change#) over (partition by creation_time) max_checkpoint_change#, min(checkpoint_time) over (partition by creation_time) min_checkpoint_time, max(checkpoint_time) over (partition by creation_time) max_checkpoint_time, sum((blocks+1)*a.block_size) over (partition by creation_time) input_bytes, sum((blocks+1)*a.block_size) over (partition by creation_time) output_bytes, creation_time from rc_backup_controlfile a, (select unique db_key, bs_key from rc_backup_set_details) b where a.bs_key = b.bs_key and a.db_key = b.db_key ) union (select a.db_key, count(*) over (partition by creation_time) num_times_backed, min(checkpoint_change#) over (partition by creation_time) min_checkpoint_change#, max(checkpoint_change#) over (partition by creation_time) max_checkpoint_change#, min(checkpoint_time) over (partition by creation_time) min_checkpoint_time, max(checkpoint_time) over (partition by creation_time) max_checkpoint_time, sum((blocks+1)*block_size) over (partition by creation_time) input_bytes, sum((blocks+1)*block_size) over (partition by creation_time) output_bytes, creation_time from rc_controlfile_copy a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.status = 'A' and a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time) and a.db_key = b.db_key ) union (select a.db_key, count(*) over (partition by creation_time) num_times_backed, min(checkpoint_change#) over (partition by creation_time) min_checkpoint_change#, max(checkpoint_change#) over (partition by creation_time) max_checkpoint_change#, min(checkpoint_time) over (partition by creation_time) min_checkpoint_time, max(checkpoint_time) over (partition by creation_time) max_checkpoint_time, sum((blocks+1)*block_size) over (partition by creation_time) input_bytes, sum((blocks+1)*block_size) over (partition by creation_time) output_bytes, creation_time from rc_proxy_controlfile a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.status = 'A' and a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time) and a.db_key = b.db_key ))group by db_key)a, rc_database b where a.db_key=b.db_key >>> define rc_backup_archivelog_summary <<< CREATE or REPLACE VIEW RC_BACKUP_ARCHIVELOG_SUMMARY AS select db.name db_name, a.*, case when input_bytes/decode(output_bytes, 0, null, output_bytes) > 1 then input_bytes/decode(output_bytes, 0, null, output_bytes) else 1 end compression_ratio, dbms_rcvman.Num2DisplaySize(input_bytes) input_bytes_display, dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display from (select db_key, sum(num_files_backed) num_files_backed, sum(distinct_files_backed) num_distinct_files_backed, min(min_first_change#) min_first_change#, max(max_next_change#) max_next_change#, min(min_first_time) min_first_time, max(max_next_time) max_next_time, sum(original_input_bytes) input_bytes, sum(output_bytes) output_bytes from ((select a.db_key, num_files_backed, distinct_files_backed, min_first_change#, max_next_change#, min_first_time, max_next_time, original_input_bytes, output_bytes from (select a.db_key, count(*) num_files_backed, min(first_change#)min_first_change#, max(next_change#) max_next_change#, min(first_time)min_first_time, max(next_time) max_next_time from rc_backup_redolog a, rc_backup_set_details b where a.bs_key = b.bs_key and a.db_key = b.db_key group by a.db_key)a, (select db_key, count(*) distinct_files_backed from (select unique a.db_key, thread#, sequence#, resetlogs_change#, resetlogs_time from rc_backup_redolog a, rc_backup_set_details b where a.bs_key = b.bs_key and a.db_key = b.db_key) group by db_key)b, (select db_key, nvl(sum(original_input_bytes),0) original_input_bytes, nvl(sum(output_bytes), 0) output_bytes from (select unique db_key, bs_key, original_input_bytes, output_bytes from rc_backup_set_details where backup_type='L') group by db_key)c where a.db_key = b.db_key and b.db_key = c.db_key) union (select a.db_key, num_files_backed, distinct_files_backed, min_first_change#, max_next_change#, min_first_time, max_next_time, original_input_bytes, output_bytes from (select a.db_key, count(*) num_files_backed, min(first_change#)min_first_change#, max(next_change#) max_next_change#, min(first_time)min_first_time, max(next_time) max_next_time, nvl(sum((blocks+1)*block_size),0) original_input_bytes, nvl(sum((blocks+1)*block_size),0) output_bytes from rc_proxy_archivedlog a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.status = 'A' and a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time) and a.db_key = b.db_key group by a.db_key) a, (select db_key, count(*) distinct_files_backed from (select unique a.db_key, thread#, sequence#, resetlogs_change#, resetlogs_time from rc_proxy_archivedlog a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.status = 'A' and a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time) and a.db_key = b.db_key) group by db_key)b where a.db_key=b.db_key)) group by db_key)a, rc_database db where a.db_key=db.db_key >>> define rc_backup_spfile_summary <<< create or replace view RC_BACKUP_SPFILE_SUMMARY as select db.name db_name, a.*, dbms_rcvman.Num2DisplaySize(input_bytes) input_bytes_display from (select a.db_key, num_files_backed, num_distinct_files_backed, min_modification_time, max_modification_time, input_bytes from (select a.db_key, count(*) num_files_backed, min(modification_time)min_modification_time, max(modification_time) max_modification_time, sum(bytes) input_bytes from rc_backup_spfile a, rc_backup_set_details b where a.bs_key = b.bs_key and a.db_key=b.db_key group by a.db_key)a, (select db_key, count(*) num_distinct_files_backed from (select unique a.db_key, modification_time from rc_backup_spfile a, rc_backup_set_details b where a.bs_key = b.bs_key and a.db_key=b.db_key) group by db_key)b where a.db_key=b.db_key)a, rc_database db where a.db_key=db.db_key >>> define rc_backup_copy_summary <<< CREATE OR REPLACE VIEW RC_BACKUP_COPY_SUMMARY AS select db.name db_name, a.*, dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display from (select db_key, nvl(sum(num_times_backed),0) num_copies, sum(distinct_copies) num_distinct_copies, min(min_checkpoint_change#) min_checkpoint_change#, max(max_checkpoint_change#) max_checkpoint_change#, min(min_checkpoint_time) min_checkpoint_time, max(max_checkpoint_time) max_checkpoint_time, sum(output_bytes) output_bytes from (select unique a.db_key, file#, count(*) over (partition by file#, creation_change#) num_times_backed, count(distinct file#) over (partition by file#, creation_change#, checkpoint_change#) distinct_copies, min(checkpoint_change#) over (partition by file#, creation_change#) min_checkpoint_change#, max(checkpoint_change#) over (partition by file#, creation_change#) max_checkpoint_change#, min(checkpoint_time) over (partition by file#, creation_change#) min_checkpoint_time, max(checkpoint_time) over (partition by file#, creation_change#) max_checkpoint_time, sum((blocks+1)*block_size) over (partition by file#, creation_change#) output_bytes from rc_datafile_copy a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.status = 'A' and a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time) and a.db_key=b.db_key union select unique a.db_key, 0 file#, count(*) over (partition by creation_time) num_times_backed, 1 distinct_copies, min(checkpoint_change#) over (partition by creation_time) min_checkpoint_change#, max(checkpoint_change#) over (partition by creation_time) max_checkpoint_change#, min(checkpoint_time) over (partition by creation_time) min_checkpoint_time, max(checkpoint_time) over (partition by creation_time) max_checkpoint_time, sum((blocks+1)*block_size) over (partition by creation_time) output_bytes from rc_controlfile_copy a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.status = 'A' and a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time) and a.db_key=b.db_key) group by db_key)a, rc_database db where a.db_key=db.db_key >>> define rc_proxy_copy_summary <<< CREATE OR REPLACE VIEW RC_PROXY_COPY_SUMMARY AS select db.name db_name, a.*, dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display from (select db_key, nvl(sum(num_times_backed),0) num_copies, sum(distinct_copies) num_distinct_copies, min(min_checkpoint_change#) min_checkpoint_change#, max(max_checkpoint_change#) max_checkpoint_change#, min(min_checkpoint_time) min_checkpoint_time, max(max_checkpoint_time) max_checkpoint_time, sum(output_bytes) output_bytes from (select unique a.db_key, file#, count(*) over (partition by file#, creation_change#) num_times_backed, count(distinct file#) over (partition by file#, creation_change#, checkpoint_change#) distinct_copies, min(checkpoint_change#) over (partition by file#, creation_change#) min_checkpoint_change#, max(checkpoint_change#) over (partition by file#, creation_change#) max_checkpoint_change#, min(checkpoint_time) over (partition by file#, creation_change#) min_checkpoint_time, max(checkpoint_time) over (partition by file#, creation_change#) max_checkpoint_time, sum((blocks+1)*block_size) over (partition by file#, creation_change#) output_bytes from rc_proxy_datafile a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.status = 'A' and a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time) and a.db_key = b.db_key union select unique a.db_key, 0 file#, count(*) over (partition by creation_time) num_times_backed, 1 distinct_copies, min(checkpoint_change#) over (partition by creation_time) min_checkpoint_change#, max(checkpoint_change#) over (partition by creation_time) max_checkpoint_change#, min(checkpoint_time) over (partition by creation_time) min_checkpoint_time, max(checkpoint_time) over (partition by creation_time) max_checkpoint_time, sum((blocks+1)*block_size) over (partition by creation_time) output_bytes from rc_proxy_controlfile a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.status = 'A' and a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time) and a.db_key = b.db_key) group by db_key) a, rc_database db where a.db_key = db.db_key >>> define rc_proxy_archivelog_summary <<< CREATE or REPLACE VIEW RC_PROXY_ARCHIVELOG_SUMMARY AS select db.name db_name, a.*, dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display from (select a.db_key, nvl(num_files_backed, 0) num_files_backed, num_distinct_files_backed, min_first_change#, max_next_change#, min_first_time, max_next_time, output_bytes from (select a.db_key, count(*) num_files_backed, min(first_change#)min_first_change#, max(next_change#) max_next_change#, min(first_time)min_first_time, max(next_time) max_next_time, sum((blocks+1)*block_size) output_bytes from rc_proxy_archivedlog a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.status = 'A' and a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time) and a.db_key=b.db_key group by a.db_key)a, (select db_key, count(*) num_distinct_files_backed from (select unique a.db_key, thread#, sequence#, resetlogs_change#, resetlogs_time from rc_proxy_archivedlog a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.status = 'A' and a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time) and a.db_key=b.db_key) group by db_key)b where a.db_key=b.db_key)a, rc_database db where a.db_key=db.db_key >>> define rc_unusable_backupfile_details <<< create or replace view RC_UNUSABLE_BACKUPFILE_DETAILS AS select b.session_key, a.* from (select a.db_key, f.db_name, a.rsr_key, 'BACKUPSET' btype, a.bs_key btype_key, a.set_stamp id1, a.set_count id2, 'BACKUPPIECE' filetype, a.bp_key filetype_key, a.status, a.bytes filesize, a.device_type, a.handle filename, a.media, a.media_pool from rc_backup_piece a, (select db_key, name "DB_NAME" from rc_database) f where a.status <> 'A' and a.db_key = f.db_key union select db_key, db_name, rsr_key, 'IMAGECOPY', cdf_key, null, null, 'DATAFILECOPY', cdf_key, status, (blocks+1)*block_size, 'DISK', name, null, null from rc_datafile_copy where status <> 'A' union select db_key, db_name, rsr_key, 'IMAGECOPY', ccf_key, null, null, 'CONTROLFILECOPY', ccf_key, status, (blocks+1)*block_size, 'DISK', name, null, null from rc_controlfile_copy where status <> 'A' union select db_key, db_name, rsr_key, 'PROXYCOPY', xdf_key, null, null, 'DATAFILECOPY', xdf_key, status, (blocks+1)*block_size, device_type, handle, media, media_pool from rc_proxy_datafile where status <> 'A' union select db_key, db_name, rsr_key, 'PROXYCOPY', xcf_key, null, null, 'CONTROLFILECOPY', xcf_key, status, (blocks+1)*block_size, device_type, handle, media, media_pool from rc_proxy_controlfile where status <> 'A' union select db_key, db_name, rsr_key, 'PROXYCOPY', xal_key, null, null, 'ARCHIVELOGCOPY', xal_key, status, (blocks+1)*block_size, device_type, handle, media, media_pool from rc_proxy_archivedlog where status <> 'A') a, rc_rman_status b, (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c, (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime from dual) d, (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime from dual) e where a.rsr_key = b.rsr_key (+) and (c.skey is null or c.skey = b.session_key) and (d.fTime is null or d.fTime <= b.start_time) and (e.uTime is null or e.uTime >= b.end_time) >>> define rc_rman_backup_type <<< create or replace view rc_rman_backup_type as select 9 weight, 'DB FULL' input_type from dual union select 8, 'RECVR AREA' from dual union select 7, 'DB INCR' from dual union select 6, 'DATAFILE FULL' from dual union select 5, 'DATAFILE INCR' from dual union select 4, 'ARCHIVELOG' from dual union select 3, 'CONTROLFILE' from dual union select 2, 'SPFILE' from dual union select 1, 'BACKUPSET' from dual >>> define rc_restore_point <<< create or replace view rc_restore_point as select dbinc_key, null recid, null stamp, site_key, rspname name, rsptime restore_point_time, creation_time creation_time, to_scn scn, 'NO' long_term, 'YES' preserved, /* All guaranteed are also preserved */ guaranteed guarantee_flashback_database, pdb_key, clean from grsp union select dbinc_key, nrsp_recid recid, nrsp_stamp stamp, site_key, rspname name, rsptime restore_point_time, creation_time creation_time, to_scn scn, long_term, 'NO' preserved, 'NO' guarantee_flashback_database, pdb_key, clean from nrsp >>> define rci_site <<< create or replace view rci_site as select site_key, db_key, database_role, cf_create_time, substr(db_unique_name, 1, 30) db_unique_name, high_conf_recid, force_resync2cf, high_rout_stamp, inst_startup_stamp, last_kccdivts, high_ic_recid, dbinc_key, ckp_scn, full_ckp_cf_seq, job_ckp_cf_seq, high_ts_recid, high_df_recid, high_rt_recid, high_orl_recid, high_offr_recid, high_rlh_recid, high_al_recid, high_bs_recid, high_bp_recid, high_bdf_recid, high_cdf_recid, high_brl_recid, high_bcb_recid, high_ccb_recid, high_do_recid, high_pc_recid, high_bsf_recid, high_rsr_recid, high_tf_recid, high_grsp_recid, high_nrsp_recid, high_bcr_recid, low_bcr_recid, bcr_in_use, high_pdb_recid, high_pic_recid from node >>> define rc_site <<< create or replace view rc_site as select * from rci_site where substr(nvl(db_unique_name, 'A'),1,1) <> '$' >>> define rc_current_xmlfiles <<< create or replace view rc_current_xmlfile as select name, name_tag, version_num, schema_ver, xml_comment, creation_time, modified_time from (select name, name_tag, version_num, max(version_num) over (partition by name, name_tag) curr_version_num, creation_time, last_value(modified_time) over (partition by name, name_tag, version_num) modified_time, doctype, last_value(schema_ver) over (partition by name, name_tag, version_num) schema_ver, last_value(xml_comment) over (partition by name, name_tag, version_num) xml_comment from xmlstore) where version_num = curr_version_num >>> define drop_rc_rman_backup_subjob_details <<< drop view rc_rman_backup_subjob_details >>> define drop_rc_rman_backup_job_details <<< drop view rc_rman_backup_job_details >>> define drop_rc_backup_set_details <<< drop view rc_backup_set_details >>> define drop_rc_backup_piece_details <<< drop view rc_backup_piece_details >>> define drop_rc_backup_copy_details <<< drop view rc_backup_copy_details >>> define drop_rc_proxy_copy_details <<< drop view rc_proxy_copy_details >>> define drop_rc_proxy_archivelog_details <<< drop view rc_proxy_archivelog_details >>> define drop_rc_backup_datafile_details <<< drop view rc_backup_datafile_details >>> define drop_rc_backup_controlfile_details <<< drop view rc_backup_controlfile_details >>> define drop_rc_backup_archivelog_details <<< drop view rc_backup_archivelog_details >>> define drop_rc_backup_spfile_details <<< drop view rc_backup_spfile_details >>> define drop_rc_backup_set_summary <<< drop view rc_backup_set_summary >>> define drop_rc_backup_datafile_summary <<< drop view rc_backup_datafile_summary >>> define drop_rc_backup_controlfile_summary <<< drop view rc_backup_controlfile_summary >>> define drop_rc_backup_archivelog_summary <<< drop view rc_backup_archivelog_summary >>> define drop_rc_backup_spfile_summary <<< drop view rc_backup_spfile_summary >>> define drop_rc_backup_copy_summary <<< drop view rc_backup_copy_summary >>> define drop_rc_proxy_copy_summary <<< drop view rc_proxy_copy_summary >>> define drop_rc_proxy_archivelog_summary <<< drop view rc_proxy_archivelog_summary >>> define drop_rc_unusable_backupfile_details <<< drop view rc_unusable_backupfile_details >>> define drop_rc_rman_backup_type <<< drop view rc_rman_backup_type >>> define drop_rc_restore_point <<< drop view rc_restore_point >>> define drop_rc_site <<< drop view rc_site >>> define drop_rci_site <<< drop view rci_site >>> define drop_rc_current_xmlfiles <<< drop view rc_current_xmlfile >>> define drop_rc_pdbs <<< drop view rc_pdbs >>> define drop_rci_pdbs <<< drop view rci_pdbs >>> define drop_rci_pdbinc_this_dbinc <<< drop view rci_pdbinc_this_dbinc >>> define drop_rc_pluggable_database_inc <<< drop view rc_pluggable_database_inc >>> define drop_rc_restore_range <<< drop view rc_restore_range >>> define drop_rc_disk_restore_range <<< drop view rc_disk_restore_range >>> define drop_rc_sbt_restore_range <<< drop view rc_sbt_restore_range >>> define dbmsrvct_sql <<< create or replace package dbms_rcvcat authid current_user is -- TRUE# CONSTANT number := 1; FALSE# CONSTANT number := 0; -- UPGRADE_COMPLETED CONSTANT number := 1; -- RESYNC_FULL CONSTANT number := 1; RESYNC_PARTIAL CONSTANT number := 2; RESYNC_NONE CONSTANT number := 3; CONFIGRESYNC_NO CONSTANT number := 0; CONFIGRESYNC_TORC CONSTANT number := 1; CONFIGRESYNC_TOCF CONSTANT number := 2; CONFIGRESYNC_TORC_TOCF CONSTANT number := 3; -- -- CF_CURRENT CONSTANT number := 1; CF_BACKUP CONSTANT number := 2; CF_CREATED CONSTANT number := 3; CF_STANDBY CONSTANT number := 4; CF_CLONE CONSTANT number := 5; CF_NOMOUNT CONSTANT number := 6; -- -- this_db_key number := NULL; this_dbinc_key number := NULL; type registerDbPending_t is record ( dbid number := null, con_id number := null, guid raw(16) := null ); registerDbPending registerDbPending_t; RESYNC_REASON_NOACTION CONSTANT number := 1; -- do not display reasons RESYNC_REASON_NONE CONSTANT number := 2; -- no reason is yet set RESYNC_REASON_DF CONSTANT number := 3; RESYNC_REASON_TF CONSTANT number := 4; RESYNC_REASON_TS CONSTANT number := 5; RESYNC_REASON_THR CONSTANT number := 6; RESYNC_REASON_ORL CONSTANT number := 7; RESYNC_REASON_CONF CONSTANT number := 8; RESYNC_REASON_CF CONSTANT number := 9; RESYNC_REASON_RSL CONSTANT number := 10; RESYNC_REASON_INC CONSTANT number := 11; RESYNC_REASON_RESET CONSTANT number := 12; RESYNC_REASON_PDB CONSTANT number := 13; resync_reason number := RESYNC_REASON_NONE; doResyncReasons boolean := FALSE; RESYNC_ACTION_ADD CONSTANT number := 1; RESYNC_ACTION_DROP CONSTANT number := 2; RESYNC_ACTION_CHANGE CONSTANT number := 3; RESYNC_ACTION_RECREATE CONSTANT number := 4; RESYNC_ACTION_RENAME CONSTANT number := 5; RESYNC_ACTION_RESIZE CONSTANT number := 6; TYPE resyncActionNames_t IS VARRAY(6) OF varchar2(12); -- RESYNC_ACTION_NAMES CONSTANT resyncActionNames_t := resyncActionNames_t('added', 'dropped', 'changed', 'recreated', 'renamed', 'resized'); TYPE resyncActionTaken_t IS VARRAY(6) OF boolean; TYPE resyncActionCounts_t IS VARRAY(6) OF number; RESYNC_OBJECT_TABLESPACE CONSTANT number := 1; RESYNC_OBJECT_DATAFILE CONSTANT number := 2; RESYNC_OBJECT_TEMPFILE CONSTANT number := 3; RESYNC_OBJECT_REDOTHREAD CONSTANT number := 4; RESYNC_OBJECT_ONLINELOG CONSTANT number := 5; RESYNC_OBJECT_PDB CONSTANT number := 6; TYPE resyncActionObjects_t IS VARRAY(5) OF varchar2(16); -- RESYNC_ACTION_OBJECTS CONSTANT resyncActionObjects_t := resyncActionObjects_t('Tablespace', 'Datafile', 'Tempfile', 'Redo thread', 'Online redo log'); -- RCVCAT_LEVEL_ZERO CONSTANT number := 0; RCVCAT_LEVEL_MIN CONSTANT number := 1; RCVCAT_LEVEL_LOW CONSTANT number := 5; RCVCAT_LEVEL_MID CONSTANT number := 9; RCVCAT_LEVEL_HI CONSTANT number := 12; RCVCAT_LEVEL_MAX CONSTANT number := 15; RCVCAT_LEVEL_DEFAULT CONSTANT number := RCVCAT_LEVEL_MID; TYPE fullResyncActions_t IS RECORD ( active boolean, valid boolean, lastobjno number, objtype number, actTaken resyncActionTaken_t, actCount resyncActionCounts_t ); fullResyncAction fullResyncActions_t; -- := -- -- -- /*-----------------------* * Debugging functions * *-----------------------*/ PROCEDURE setDebugOn(dbglevel IN NUMBER DEFAULT RCVCAT_LEVEL_DEFAULT); PROCEDURE setDebugOff; /*-----------------------* * Database Registration * *-----------------------*/ PROCEDURE registerDatabase( db_id IN number ,db_name IN varchar2 ,reset_scn IN number ,reset_time IN date ,db_unique_name IN varchar2 default null ,con_id IN number default 0 ,guid IN raw default null ); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- procedure resetDatabase( db_id IN number ,db_name IN varchar2 ,reset_scn IN number ,reset_time IN date ,parent_reset_scn IN number ,parent_reset_time IN date ); function resetDatabase( db_id IN number ,db_name IN varchar2 ,reset_scn IN number ,reset_time IN date ,parent_reset_scn IN number ,parent_reset_time IN date ) return number; procedure resetDatabase( dbinc_key IN number ,db_name IN varchar2 ); procedure resetDatabase( dbinc_key IN number ,db_name IN varchar2 ,reset_scn OUT number ,reset_time OUT date ,db_id IN number DEFAULT NULL ); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- procedure unregisterDatabase( db_key IN NUMBER DEFAULT NULL ,db_id IN NUMBER ); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- /*--------------------------* * Set Database Incarnation * *--------------------------*/ procedure setDatabase( db_name IN varchar2 ,reset_scn IN number ,reset_time IN date ,db_id IN number ,db_unique_name IN varchar2 ,dummy_instance IN boolean ,cf_type IN number ,site_aware IN boolean default FALSE ,ors_instance IN boolean default FALSE ); procedure setDatabase( db_name IN varchar2 ,reset_scn IN number ,reset_time IN date ,db_id IN number ,db_unique_name IN varchar2 default NULL); procedure setDatabase(dbinc_key number); procedure setDatabase; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- /*-----------------------------* * Recovery Catalog Checkpoint * *-----------------------------*/ function ckptNeeded( ckp_scn IN number ,ckp_cf_seq IN number ,cf_version IN date ,cf_type IN number ,high_df_recid IN number ,high_orl_recid IN number ,high_cdf_recid IN number ,high_al_recid IN number ,high_bp_recid IN number ,high_do_recid IN number ,high_offr_recid IN number ,high_pc_recid IN number DEFAULT NULL -- for compatibility ,high_conf_recid IN number DEFAULT NULL -- for compatibility ,rltime IN DATE DEFAULT NULL -- for compatibility ,high_ts_recid IN number DEFAULT NULL -- for compatibility ,high_bs_recid IN number DEFAULT NULL -- for compatibility ,lopen_reset_scn IN number DEFAULT NULL -- for compatibility ,lopen_reset_time IN DATE DEFAULT NULL -- for compatibility ,high_ic_recid IN number DEFAULT NULL -- for compatibility ,high_tf_recid IN number DEFAULT NULL -- for compatibility ,high_rt_recid IN number DEFAULT NULL -- for compatibility ,high_grsp_recid IN number DEFAULT NULL -- for compatibility ,high_nrsp_recid IN number DEFAULT NULL -- for compatibility ,high_bcr_recid IN number DEFAULT NULL -- for compatibility ,high_pdb_recid IN number DEFAULT NULL -- for compatibility ,high_pic_recid IN number DEFAULT NULL -- for compatibility ) return number; PROCEDURE lockForCkpt(ors_inspect IN boolean DEFAULT FALSE); procedure beginCkpt( ckp_scn IN number ,ckp_cf_seq IN number ,cf_version IN date ,ckp_time IN date ,ckp_type IN varchar2 ,ckp_db_status IN varchar2 ,high_df_recid IN number ,cf_type IN varchar2 DEFAULT 'CURRENT' -- for compatibility reasons ); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- procedure endCkpt; -- -- -- -- -- -- -- -- -- -- procedure cancelCkpt; -- -- -- -- -- function lastFullCkpt return number; -- -- FUNCTION getPolledRec(rec_type OUT NUMBER, recid OUT NUMBER, stamp OUT NUMBER, fname OUT VARCHAR2) RETURN BOOLEAN; /*-------------------* * Resync * *-------------------*/ -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- /*---------------------* * Pluggable DB Resync * *---------------------*/ FUNCTION beginPluggableDBResync( high_pdb_recid IN NUMBER) RETURN BOOLEAN; -- -- -- PROCEDURE checkPluggableDB( name IN VARCHAR2 ,con_id IN NUMBER ,db_id IN NUMBER ,create_scn IN NUMBER ,guid IN RAW ,noBackup IN VARCHAR2 DEFAULT 'N' ); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE endPluggableDBResync; -- -- /*-------------------* * Tablespace Resync * *-------------------*/ function beginTableSpaceResync( high_ts_recid IN NUMBER, force IN BOOLEAN DEFAULT FALSE ) return boolean; -- -- -- -- -- -- -- procedure checkTableSpace( ts_name IN varchar2 ,ts# IN number ,create_scn IN number ,create_time IN date ,rbs_count IN number DEFAULT NULL ,included_in_database_backup IN varchar2 DEFAULT NULL ,bigfile IN varchar2 DEFAULT NULL ,temporary IN varchar2 DEFAULT NULL ,encrypt_in_backup IN varchar2 DEFAULT NULL ,plugin_scn IN number DEFAULT 0 ,con_id IN number DEFAULT 0 ,pdb_dict_check IN boolean DEFAULT FALSE ); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- procedure endTableSpaceResync; -- -- -- /*-----------------* * Datafile Resync * *-----------------*/ function beginDataFileResync( high_df_recid IN number ) return boolean; -- -- -- -- -- procedure checkDataFile(file# IN NUMBER, fname IN VARCHAR2, create_scn IN NUMBER, create_time IN DATE, blocks IN NUMBER, block_size IN NUMBER, ts# IN NUMBER, stop_scn IN NUMBER, read_only IN NUMBER, stop_time IN DATE DEFAULT NULL, rfile# IN NUMBER DEFAULT NULL, aux_fname IN VARCHAR2 DEFAULT NULL, foreign_dbid IN NUMBER DEFAULT 0, foreign_create_scn IN NUMBER DEFAULT 0, foreign_create_time IN DATE DEFAULT NULL, plugged_readonly IN VARCHAR2 DEFAULT 'NO', plugin_scn IN NUMBER DEFAULT 0, plugin_reset_scn IN NUMBER DEFAULT 0, plugin_reset_time IN DATE DEFAULT NULL, create_thread IN NUMBER DEFAULT NULL, create_size IN NUMBER DEFAULT NULL, con_id IN NUMBER DEFAULT 0, pdb_closed IN NUMBER DEFAULT 0, pdb_dict_check IN BOOLEAN DEFAULT FALSE, pdb_foreign_dbid IN NUMBER DEFAULT 0); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- procedure endDataFileResync; -- -- -- -- -- function beginDataFileResyncForStandby( high_df_recid IN number ) return boolean; procedure checkDataFileForStandby( file# IN NUMBER, fname IN VARCHAR2, create_scn IN NUMBER, create_time IN DATE, blocks IN NUMBER, block_size IN NUMBER, ts# IN NUMBER, rfile# IN NUMBER, stop_scn IN NUMBER, read_only IN NUMBER, foreign_dbid IN NUMBER, plugin_scn IN NUMBER); -- -- -- -- -- -- procedure endDataFileResyncForStandby; function beginTempFileResyncForStandby( high_tf_recid IN number ) return boolean; procedure checkTempFileForStandby (file# IN NUMBER, fname IN VARCHAR2, create_scn IN NUMBER, create_time IN DATE, blocks IN NUMBER, block_size IN NUMBER, ts# IN NUMBER, rfile# IN NUMBER, autoextend IN VARCHAR2, max_size IN NUMBER, next_size IN NUMBER, con_id IN NUMBER DEFAULT 0); procedure endTempFileResyncForStandby; procedure setDatafileSize( file# IN number ,create_scn IN number ,blocks IN number ,plugin_scn IN number DEFAULT 0 ); /*-----------------* * TempFile Resync * *-----------------*/ function tempFileToResync( high_tf_recid IN number ) return boolean; -- -- -- -- -- function beginTempFileResync( high_tf_recid IN number ) return boolean; -- -- -- -- -- procedure checkTempFile(file# IN NUMBER, fname IN VARCHAR2, create_scn IN NUMBER, create_time IN DATE, blocks IN NUMBER, block_size IN NUMBER, ts# IN NUMBER, rfile# IN NUMBER, autoextend IN VARCHAR2, max_size IN NUMBER, next_size IN NUMBER, con_id IN NUMBER DEFAULT 0, pdb_dict_check IN BOOLEAN DEFAULT FALSE); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- procedure endTempFileResync; -- -- -- /*---------------------* * Redo Thread resync * *---------------------*/ function beginThreadResync( high_rt_recid IN number ) return boolean; -- procedure checkThread( thread# IN number ,last_sequence# IN number ,enable_scn IN number ,enable_time IN date ,disable_scn IN number ,disable_time IN date ,status IN varchar2 ); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- procedure endThreadResync; -- /*------------------------* * Online Redo Log resync * *------------------------*/ function beginOnlineRedoLogResync( high_orl_recid IN number ) return boolean; -- procedure checkOnlineRedoLog( thread# IN number ,group# IN number ,fname IN varchar2 ,bytes IN number default null ,type IN varchar2 default 'ONLINE' ); -- -- -- procedure endOnlineRedoLogResync; -- /*---------------------------------* * Guaranteed Restore Point Resync * *---------------------------------*/ function beginGuaranteedRPResync( high_grsp_recid IN number ) return boolean; -- PROCEDURE checkGuaranteedRP( rspname IN VARCHAR2 ,from_scn IN NUMBER ,to_scn IN NUMBER ,resetlogs_change# IN NUMBER ,resetlogs_time IN DATE ,create_time IN DATE DEFAULT NULL ,rsp_time IN DATE DEFAULT NULL ,guaranteed IN VARCHAR2 DEFAULT 'YES' ,con_id IN NUMBER DEFAULT NULL ,clean IN VARCHAR2 DEFAULT 'NO' ); -- -- -- procedure endGuaranteedRPResync; -- -- /*----------------------------------* * RMAN Configration records resync * *----------------------------------*/ function beginConfigResync( high_conf_recid IN number ) return number; function beginConfigResync2( high_conf_recid IN number ) return number; -- -- procedure endConfigResync; procedure endConfigResync2(sync_to_cf_pending IN boolean DEFAULT FALSE); -- -- procedure getConfig( conf# OUT number ,name IN OUT varchar2 ,value IN OUT varchar2 ,first IN boolean); -- -- PROCEDURE setKeepOutputForSession(days IN number); -- /*-----------------------------* * Redo Log History resync * *-----------------------------*/ function beginLogHistoryResync return number; -- -- -- -- function getLogHistoryLowSCN return number; -- -- -- -- procedure checkLogHistory( rlh_recid IN number ,rlh_stamp IN number ,thread# IN number ,sequence# IN number ,low_scn IN number ,low_time IN date ,next_scn IN number ,reset_scn IN number default NULL ,reset_time IN date default NULL ); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- procedure endLogHistoryResync; -- -- /*-------------------------* * Archived Log resync * *-------------------------*/ function beginArchivedLogResync return number; -- procedure checkArchivedLog( al_recid IN number ,al_stamp IN number ,thread# IN number ,sequence# IN number ,reset_scn IN number ,reset_time IN date ,low_scn IN number ,low_time IN date ,next_scn IN number ,next_time IN date ,blocks IN number ,block_size IN number ,fname IN varchar2 ,archived IN varchar2 ,completion_time IN date ,status IN varchar2 ,is_standby IN varchar2 DEFAULT NULL ,dictionary_begin IN varchar2 DEFAULT NULL ,dictionary_end IN varchar2 DEFAULT NULL ,is_recovery_dest_file IN varchar2 default 'NO' ,compressed IN varchar2 default 'NO' ,creator IN varchar2 default NULL ,terminal IN varchar2 default 'NO' ,chk_last_recid IN boolean DEFAULT TRUE ); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- procedure endArchivedLogResync; -- -- /*-------------------------* * Offline range resync * *-------------------------*/ function beginOfflineRangeResync return number; -- -- procedure checkOfflineRange( offr_recid IN number ,offr_stamp IN number ,file# IN number ,create_scn IN number ,offline_scn IN number ,online_scn IN number ,online_time IN date ,cf_create_time IN date ,reset_scn IN number default NULL ,reset_time IN date default NULL ); -- -- -- -- -- -- procedure endOfflineRangeResync; -- /*-------------------------* * Backup Set resync * *-------------------------*/ function beginBackupSetResync return number; -- -- procedure checkBackupSet( bs_recid IN number ,bs_stamp IN number ,set_stamp IN number ,set_count IN number ,bck_type IN varchar2 ,incr_level IN number DEFAULT NULL ,pieces IN number ,start_time IN date ,completion_time IN date ,controlfile_included IN VARCHAR2 DEFAULT NULL ,input_file_scan_only IN VARCHAR2 DEFAULT NULL ,keep_options IN number DEFAULT 0 ,keep_until IN date DEFAULT NULL ,block_size IN number DEFAULT NULL ,multi_section IN varchar2 DEFAULT NULL ,chk_last_recid IN boolean DEFAULT TRUE ,guid IN raw DEFAULT NULL ,dropped_pdb IN binary_integer DEFAULT 0 ); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- procedure endBackupSetResync; -- /*-------------------------* * Backup piece resync * *-------------------------*/ function beginBackupPieceResync return number; procedure checkBackupPiece( bp_recid IN number ,bp_stamp IN number ,set_stamp IN number ,set_count IN number ,piece# IN number ,tag IN varchar2 ,device_type IN varchar2 ,handle IN varchar2 ,comments IN varchar2 ,media IN varchar2 ,concur IN varchar2 ,start_time IN date ,completion_time IN date ,status IN varchar2 ,copy# IN number default 1 ,media_pool IN number default 0 ,bytes IN number default NULL ,is_recovery_dest_file IN varchar2 default 'NO' ,rsr_recid IN number default NULL ,rsr_stamp IN number default NULL ,compressed IN varchar2 default 'NO' ,encrypted IN varchar2 default 'NO' ,backed_by_osb IN varchar2 default 'NO' ,ba_access IN varchar2 default 'U' ,vbkey IN number default NULL ,chk_last_recid IN boolean default TRUE ,lib_key IN number default NULL ,guid IN raw default NULL ,template_key IN number default NULL ,dropped_pdb IN binary_integer default 0 ); function checkBackupPiece( bp_recid IN number ,bp_stamp IN number ,set_stamp IN number ,set_count IN number ,piece# IN number ,tag IN varchar2 ,device_type IN varchar2 ,handle IN varchar2 ,comments IN varchar2 ,media IN varchar2 ,concur IN varchar2 ,start_time IN date ,completion_time IN date ,status IN varchar2 ,copy# IN number default 1 ,media_pool IN number default 0 ,bytes IN number default NULL ,is_recovery_dest_file IN varchar2 default 'NO' ,rsr_recid IN number default NULL ,rsr_stamp IN number default NULL ,compressed IN varchar2 default 'NO' ,encrypted IN varchar2 default 'NO' ,backed_by_osb IN varchar2 default 'NO' ,ba_access IN varchar2 default 'U' ,vbkey IN number default NULL ,chk_last_recid IN boolean default TRUE ,lib_key IN number default NULL ,guid IN raw default NULL ,template_key IN number default NULL ,dropped_pdb IN binary_integer default 0 ) return number; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- procedure endBackupPieceResync; /*-------------------------* * Backup Datafile resync * *-------------------------*/ function beginBackupDataFileResync return number; procedure checkBackupDataFile( bdf_recid IN number ,bdf_stamp IN number ,set_stamp IN number ,set_count IN number ,file# IN number ,create_scn IN number ,create_time IN date ,reset_scn IN number ,reset_time IN date ,incr_level IN number ,incr_scn IN number ,ckp_scn IN number ,ckp_time IN date ,abs_fuzzy_scn IN number ,datafile_blocks IN number ,blocks IN number ,block_size IN number ,min_offr_recid IN number ,completion_time IN date ,controlfile_type IN varchar2 DEFAULT NULL ,cfile_abck_year IN number DEFAULT NULL ,cfile_abck_mon_day IN number DEFAULT NULL ,cfile_abck_seq IN number DEFAULT NULL ,chk_last_recid IN boolean DEFAULT TRUE ,blocks_read IN number DEFAULT NULL ,used_chg_track IN varchar2 DEFAULT 'NO' ,used_optim IN varchar2 DEFAULT 'NO' ,foreign_dbid IN number DEFAULT 0 ,plugged_readonly IN varchar2 DEFAULT 'NO' ,plugin_scn IN number DEFAULT 0 ,plugin_reset_scn IN number DEFAULT 0 ,plugin_reset_time IN date DEFAULT NULL ,section_size IN number DEFAULT NULL ,guid IN raw DEFAULT NULL ,sparse_backup IN varchar2 DEFAULT 'NO' ,isResync IN boolean DEFAULT TRUE ,isVirtual IN boolean DEFAULT FALSE ,dropped_pdb IN binary_integer DEFAULT 0 ); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- procedure endBackupDataFileResync; /*-------------------------* * Backup SPFILE resync * *-------------------------*/ function beginBackupSpFileResync return number; procedure checkBackupSpFile( bsf_recid IN number ,bsf_stamp IN number ,set_stamp IN number ,set_count IN number ,modification_time IN date ,bytes IN number ,chk_last_recid IN boolean DEFAULT TRUE ,db_unique_name IN varchar2 DEFAULT NULL ,guid IN raw DEFAULT NULL ,dropped_pdb IN binary_integer DEFAULT 0 ); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- procedure endBackupSpFileResync; /*-------------------------* * Backup Redo Log resync * *-------------------------*/ function beginBackupRedoLogResync return number; procedure checkBackupRedoLog( brl_recid IN number ,brl_stamp IN number ,set_stamp IN number ,set_count IN number ,thread# IN number ,sequence# IN number ,reset_scn IN number ,reset_time IN date ,low_scn IN number ,low_time IN date ,next_scn IN number ,next_time IN date ,blocks IN number ,block_size IN number ,chk_last_recid IN boolean DEFAULT TRUE ,terminal IN varchar2 DEFAULT 'NO' ,activation IN varchar2 DEFAULT NULL ); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- procedure endBackupRedoLogResync; /*----------------------------* * Copy Datafile resync * *----------------------------*/ function beginDataFileCopyResync return number; procedure checkDataFileCopy( cdf_recid IN number ,cdf_stamp IN number ,fname IN varchar2 ,tag IN varchar2 ,file# IN number ,create_scn IN number ,create_time IN date ,reset_scn IN number ,reset_time IN date ,incr_level IN number ,ckp_scn IN number ,ckp_time IN date ,onl_fuzzy IN varchar2 ,bck_fuzzy IN varchar2 ,abs_fuzzy_scn IN number ,rcv_fuzzy_scn IN number ,rcv_fuzzy_time IN date ,blocks IN number ,block_size IN number ,min_offr_recid IN number ,completion_time IN date ,status IN varchar2 ,controlfile_type IN varchar2 DEFAULT NULL ,keep_options IN number DEFAULT 0 ,keep_until IN date DEFAULT NULL ,scanned IN varchar2 DEFAULT 'NO' ,is_recovery_dest_file IN varchar2 DEFAULT 'NO' ,rsr_recid IN number DEFAULT NULL ,rsr_stamp IN number DEFAULT NULL ,marked_corrupt IN number DEFAULT NULL ,foreign_dbid IN number DEFAULT 0 ,plugged_readonly IN varchar2 DEFAULT 'NO' ,plugin_scn IN number DEFAULT 0 ,plugin_reset_scn IN number DEFAULT 0 ,plugin_reset_time IN date DEFAULT NULL ,guid IN raw DEFAULT NULL ,sparse_backup IN varchar2 DEFAULT 'NO' ,dropped_pdb IN binary_integer DEFAULT 0 ); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- procedure endDataFileCopyResync; /*----------------------------* * Corrupt Block resync * *----------------------------*/ function beginBackupCorruptionResync return number; procedure checkBackupCorruption( bcb_recid IN number ,bcb_stamp IN number ,set_stamp IN number ,set_count IN number ,piece# IN number ,file# IN number ,block# IN number ,blocks IN number ,corrupt_scn IN number ,marked_corrupt IN varchar2 ,corruption_type IN varchar2 default NULL ); procedure endBackupCorruptionResync; function beginCopyCorruptionResync return number; procedure checkCopyCorruption( ccb_recid IN number ,ccb_stamp IN number ,cdf_recid IN number ,cdf_stamp IN number ,file# IN number ,block# IN number ,blocks IN number ,corrupt_scn IN number ,marked_corrupt IN varchar2 ,corruption_type IN varchar2 default NULL ); procedure endCopyCorruptionResync; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- /*----------------------------* * Deleted Object resync * *----------------------------*/ function beginDeletedObjectResync return number; procedure checkDeletedObject( do_recid IN number ,do_stamp IN number ,object_type IN varchar2 ,object_recid IN number ,object_stamp IN number ,object_data IN number DEFAULT NULL ,object_fname IN varchar2 DEFAULT NULL ,object_create_scn IN number DEFAULT NULL ,set_stamp IN number DEFAULT NULL ,set_count IN number DEFAULT NULL ,handle IN VARCHAR2 DEFAULT NULL ,device_type IN VARCHAR2 DEFAULT NULL ); procedure endDeletedObjectResync; /*-------------------* * Proxy Copy resync * *-------------------*/ function beginProxyResync return number; procedure checkProxyDataFile( xdf_recid IN number ,xdf_stamp IN number ,tag IN varchar2 ,file# IN number ,create_scn IN number ,create_time IN date ,reset_scn IN number ,reset_time IN date ,incr_level IN number ,ckp_scn IN number ,ckp_time IN date ,onl_fuzzy IN varchar2 ,bck_fuzzy IN varchar2 ,abs_fuzzy_scn IN number ,rcv_fuzzy_scn IN number ,rcv_fuzzy_time IN date ,blocks IN number ,block_size IN number ,min_offr_recid IN number ,device_type IN varchar2 ,handle IN varchar2 ,comments IN varchar2 ,media IN varchar2 ,media_pool IN number ,start_time IN date ,completion_time IN date ,status IN varchar2 ,controlfile_type IN varchar2 DEFAULT NULL ,keep_options IN number DEFAULT 0 ,keep_until IN date DEFAULT NULL ,rsr_recid IN number DEFAULT NULL ,rsr_stamp IN number DEFAULT NULL ,foreign_dbid IN number DEFAULT 0 ,plugged_readonly IN varchar2 DEFAULT 'NO' ,plugin_scn IN number DEFAULT 0 ,plugin_reset_scn IN number DEFAULT 0 ,plugin_reset_time IN date DEFAULT NULL ,guid IN raw DEFAULT NULL ,dropped_pdb IN binary_integer DEFAULT 0 ); PROCEDURE checkProxyArchivedLog( xal_recid IN NUMBER ,xal_stamp IN NUMBER ,tag IN VARCHAR2 ,thread# IN NUMBER ,sequence# IN NUMBER ,resetlogs_change# IN NUMBER ,resetlogs_time IN DATE ,first_change# IN NUMBER ,first_time IN DATE ,next_change# IN NUMBER ,next_time IN DATE ,blocks IN NUMBER ,block_size IN NUMBER ,device_type IN VARCHAR2 ,handle IN VARCHAR2 ,comments IN VARCHAR2 ,media IN VARCHAR2 ,media_pool IN NUMBER ,start_time IN DATE ,completion_time IN DATE ,status IN VARCHAR2 ,rsr_recid IN NUMBER ,rsr_stamp IN NUMBER ,terminal IN VARCHAR2 default 'NO' ,keep_until IN DATE default NULL ,keep_options IN NUMBER default 0 ); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- procedure endProxyResync; /*-------------------------* * Incarnation resync * *-------------------------*/ FUNCTION beginIncarnationResync(return_Recid in boolean DEFAULT FALSE) return number; -- -- -- -- function checkIncarnation(reset_scn IN NUMBER, reset_time IN DATE, prior_reset_scn IN NUMBER DEFAULT NULL, prior_reset_time IN DATE DEFAULT NULL, db_name IN VARCHAR2 DEFAULT 'UNKNOWN') return number; -- -- -- procedure endIncarnationResync(high_kccdivts IN NUMBER, high_ic_recid IN NUMBER DEFAULT 0); -- -- /*--------------------------------* * Pluggable DB Incaration Resync * *--------------------------------*/ FUNCTION beginPluggableDbincResync RETURN NUMBER; -- -- -- PROCEDURE checkPluggableDbinc( recid IN NUMBER ,guid IN RAW ,curr_pdbinc IN VARCHAR2 ,inc_scn IN NUMBER ,begin_reset_scn IN NUMBER ,begin_reset_time IN DATE ,end_reset_scn IN NUMBER ,db_reset_scn IN NUMBER ,db_reset_time IN DATE ,pr_inc_scn IN NUMBER ,pr_end_reset_scn IN NUMBER ,pr_db_reset_scn IN NUMBER ,pr_db_reset_time IN DATE ,chk_last_recid IN BOOLEAN ); -- -- -- PROCEDURE endPluggableDbincResync(high_pic_recid IN NUMBER); -- -- /*-----------------------------* * Normal restore point Resync * *-----------------------------*/ FUNCTION beginRestorePointResync RETURN NUMBER; PROCEDURE checkRestorePoint( nrsp_recid IN NUMBER ,nrsp_stamp IN NUMBER ,nrsp_name IN VARCHAR2 ,reset_scn IN NUMBER ,reset_time IN DATE ,to_scn IN NUMBER ,nrsp_time IN DATE ,create_time IN DATE ,deleted IN NUMBER ,con_id IN NUMBER DEFAULT NULL ,clean IN VARCHAR2 DEFAULT 'NO' ); PROCEDURE endRestorePointResync(lowrecid IN number); /*----------------------------* * RMAN Status resync * *----------------------------*/ FUNCTION beginRmanStatusResync RETURN NUMBER; -- -- PROCEDURE checkRmanStatus( recid IN NUMBER ,stamp IN NUMBER ,parent_recid IN NUMBER ,parent_stamp IN NUMBER ,row_level IN NUMBER ,row_type IN VARCHAR2 ,command_id IN VARCHAR2 ,operation IN VARCHAR2 ,status IN VARCHAR2 ,mbytes_processed IN NUMBER ,start_time IN DATE ,end_time IN DATE ,ibytes IN NUMBER default null ,obytes IN NUMBER default null ,optimized IN VARCHAR2 default null ,otype IN VARCHAR2 default null ,session_recid IN NUMBER default null ,session_stamp IN NUMBER default null ,odevtype IN VARCHAR2 default null ,osb_allocated IN VARCHAR2 default 'NO'); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE endRmanStatusResync(recid number); -- PROCEDURE updateRmanStatusRow( recid IN number ,stamp IN number ,mbytes IN number ,status IN binary_integer); -- /*----------------------------* * RMAN Output resync * *----------------------------*/ FUNCTION beginRmanOutputResync(start_timestamp in NUMBER) RETURN NUMBER; -- -- FUNCTION beginRmanOutputResync(start_timestamp IN NUMBER ,doRoutMining OUT BOOLEAN) RETURN NUMBER; PROCEDURE checkRmanOutput( recid IN NUMBER ,stamp IN NUMBER ,session_recid IN NUMBER ,session_stamp IN NUMBER ,rman_status_recid IN NUMBER ,rman_status_stamp IN NUMBER ,output IN VARCHAR2); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE endRmanOutputResync; -- /*----------------------------* * Block Corruption Resync * *----------------------------*/ function beginBlockCorruptionResync( low_bcr_recid IN number) return number; procedure checkBlockCorruption( bcr_recid IN number ,bcr_stamp IN number ,file# IN number ,create_scn IN number ,create_time IN date ,block# IN number ,blocks IN number ,corrupt_scn IN number ,corruption_type IN varchar2 ); procedure endBlockCorruptionResync; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- /*----------------------------* * Change Procedures * *----------------------------*/ procedure changeDataFileCopy( cdf_recid IN number ,cdf_stamp IN number ,status IN varchar2 ,keep_options IN number DEFAULT NULL -- null means don't update ,keep_until IN date DEFAULT NULL ,osite_key IN number DEFAULT NULL ,nsite_key IN number DEFAULT NULL ); -- -- -- procedure changeControlfileCopy( cdf_recid IN number ,cdf_stamp IN number ,status IN varchar2 ,keep_options IN number DEFAULT NULL -- null means don't update ,keep_until IN date DEFAULT NULL ,osite_key IN number DEFAULT NULL ,nsite_key IN number DEFAULT NULL ); -- -- procedure changeArchivedLog( al_recid IN number ,al_stamp IN number ,status IN varchar2 ,osite_key IN number DEFAULT NULL ,nsite_key IN number DEFAULT NULL ); -- -- procedure changeBackupSet( recid IN number ,stamp IN number ,keep_options IN number -- null means don't update ,keep_until IN date ,osite_key IN number DEFAULT NULL ,nsite_key IN number DEFAULT NULL ); -- -- -- procedure changeBackupPiece( bp_recid IN number ,bp_stamp IN number ,status IN varchar2 ,set_stamp IN number DEFAULT NULL ,set_count IN number DEFAULT NULL ,osite_key IN number DEFAULT NULL ,nsite_key IN number DEFAULT NULL ,handle IN VARCHAR2 DEFAULT NULL ,device_type IN VARCHAR2 DEFAULT NULL ); -- -- procedure changeProxyCopy( pc_recid IN number ,pc_stamp IN number ,status IN varchar2 ,keep_options IN number DEFAULT NULL -- null means don't update ,keep_until IN date DEFAULT NULL ,osite_key IN number DEFAULT NULL ,nsite_key IN number DEFAULT NULL ); -- -- /*----------------------------* * Reconcile for Replication * *----------------------------*/ PROCEDURE doReplicationReconcile(p_db_key IN NUMBER, p_lib_key IN NUMBER, p_server_key IN NUMBER); -- /*----------------------------* * Stored Script Procedures * *----------------------------*/ procedure createScript(name IN varchar2); procedure createScript(name IN varchar2, scr_com IN varchar2, global IN boolean); procedure replaceScript(name IN varchar2); procedure replaceScript(name IN varchar2, scr_com IN varchar2, global IN boolean); -- -- -- -- procedure putLine(line IN varchar2); -- -- -- -- procedure deleteScript(name IN varchar2); procedure deleteScript(name IN varchar2, glob IN number); -- procedure getScript(name IN varchar2); procedure getScript(name IN varchar2, glob IN number); -- -- -- function getLine return varchar2; -- -- procedure commitChanges(msg IN varchar2 default NULL); -- /*---------------------------------------* * Procedures for EM xml store support * The initial user of this API will be EM, however other client that intends * to save XML data in RMAN's recovery catalog can also use the API. * The API provides the versioned file system functionality, i.e. the clients * can save multiple version of same XML file, with additional option to * overwrite the latest version. *---------------------------------------*/ -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- procedure createXMLFile (name IN varchar2 ,name_tag IN varchar2 default null ,xmldoc IN clob ,doctype IN varchar2 default null ,xml_comment IN varchar2 default null ,schema_ver IN varchar2 default null); -- -- -- -- -- -- -- -- -- -- -- -- -- procedure updateXMLFile (name IN varchar2 ,name_tag IN varchar2 default null ,xmldoc IN clob default null ,xml_comment IN varchar2 default null ,schema_ver IN varchar2 default null ,new_name IN varchar2 default null ,new_name_tag IN varchar2 default null ,new_version IN BOOLEAN default FALSE); -- procedure deleteXMLFile (name IN varchar2 ,name_tag IN varchar2 default null); -- -- -- -- -- -- -- -- procedure readXMLFile (name IN varchar2 ,name_tag IN varchar2 default null ,version_num IN number default null ,xmldoc OUT clob); -- -- -- -- -- -- -- -- -- procedure getXMLFileAttr (name IN varchar2 ,name_tag IN varchar2 default null ,version_num IN number default null ,doctype OUT varchar2 ,file_size OUT number ,xml_comment OUT varchar2 ,schema_ver OUT varchar2); /*---------------------------------------* * Procedures for clone database support * *---------------------------------------*/ procedure setCloneName(file# IN number ,creation_change# IN number ,new_clone_fname IN varchar2 ,old_clone_fname IN varchar2 ,changedauxname OUT boolean ,plugin_change# IN number DEFAULT 0); FUNCTION getCloneName(file# IN number ,creation_change# IN number ,plugin_change# IN number DEFAULT 0) RETURN VARCHAR2; /*-----------------------------------* * Procedures for RMAN configuration * *-----------------------------------*/ PROCEDURE setConfig(conf# IN NUMBER ,name IN VARCHAR2 ,value IN VARCHAR2); PROCEDURE resetConfig; PROCEDURE setConfig2(conf# IN NUMBER ,name IN VARCHAR2 ,value IN VARCHAR2 ,nodespec IN BOOLEAN); PROCEDURE resetConfig2(nodespec IN BOOLEAN, high_conf_recid IN NUMBER DEFAULT NULL); PROCEDURE deleteConfig(conf# IN NUMBER); FUNCTION setConfig3(name IN VARCHAR2 ,value IN VARCHAR2 ,db_unique_name IN VARCHAR2) RETURN NUMBER; PROCEDURE deleteConfig3(conf# IN NUMBER ,db_unique_name IN VARCHAR2); /*----------------------------* * Version info * *----------------------------*/ function getPackageVersion return varchar2; function getCatalogVersion return varchar2; /*-------------------* * Utility functions * *-------------------*/ /* * NAME * bsStstusRecalc * DESCRIPTION * Recompute the backupset status for all backupset whose current * status is a specified value. This is intended to be used when * new values are introduced for the bs.status column. */ PROCEDURE bsStatusRecalc(status IN varchar2); -- -- -- -- -- -- -- -- -- PROCEDURE reNormalize(newname IN varchar2, oldname OUT varchar2); -- -- -- PROCEDURE sanityCheck; -- -- -- -- -- -- -- -- -- -- FUNCTION getDbid RETURN NUMBER; PROCEDURE listScriptNames(glob IN number, allnames IN number); -- -- -- -- -- -- PROCEDURE getScriptNames(dbname OUT varchar2, scnm OUT varchar2, sccom OUT varchar2); -- -- -- -- -- PROCEDURE updateOldestFlashbackSCN( oldest_flashback_scn IN NUMBER, oldest_flashback_time IN DATE DEFAULT NULL); -- -- FUNCTION getDbinc RETURN NUMBER; -- FUNCTION isDuplicateRecord(recid IN NUMBER ,stamp IN NUMBER ,type IN VARCHAR2) RETURN BOOLEAN; -- -- -- -- -- -- FUNCTION doDuplicateMining RETURN BOOLEAN; -- -- -- FUNCTION isRoutDuplicateRecord(recid IN NUMBER ,stamp IN NUMBER ,session_recid IN NUMBER ,session_stamp IN NUMBER ,rman_status_recid IN NUMBER ,rman_status_stamp IN NUMBER) RETURN BOOLEAN; -- -- PROCEDURE unregisterSite(db_unique_name IN VARCHAR2, incbcks IN binary_integer); -- -- PROCEDURE renameSite(from_db_unique_name IN VARCHAR2, to_db_unique_name IN VARCHAR2); -- -- PROCEDURE resyncAddDBUname(cdbunstr IN varchar2); -- -- FUNCTION getThisSiteKey(db_unique_name in VARCHAR2 DEFAULT NULL) return NUMBER; -- FUNCTION isAMSchema RETURN BOOLEAN; -- FUNCTION getAMTstlevel RETURN NUMBER; PROCEDURE enableResyncActions; PROCEDURE setReason(reason IN number, forceSet IN boolean default FALSE); FUNCTION getReason RETURN number; PROCEDURE incResyncActions(action IN number, objno IN number, objname IN varchar2); PROCEDURE getResyncActions(valid OUT boolean ,added OUT number ,dropped OUT number ,changed OUT number ,recreated OUT number ,renamed OUT number ,resized OUT number); PROCEDURE clearResyncActions; PROCEDURE dumpResyncActions; FUNCTION debOK (level IN number DEFAULT RCVCAT_LEVEL_DEFAULT) RETURN boolean; -- -- -- -- -- PROCEDURE createTempResource( name IN varchar2 ,data_type IN varchar2); -- -- -- -- -- -- -- FUNCTION lockTempResource( name IN varchar2 ,data_type IN varchar2) RETURN BOOLEAN; -- -- -- -- -- -- -- PROCEDURE cleanupTempResource; -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE addDbidToImport( first IN binary_integer ,idb IN varchar2 ,idbinc IN varchar2 ,dbid IN number DEFAULT NULL ,dbname IN varchar2 DEFAULT NULL); -- -- -- -- -- -- -- PROCEDURE lockDbidToImport( idb IN varchar2); -- -- -- -- -- -- -- -- PROCEDURE importSchema( dblink IN varchar2 ,idb IN varchar2 ,idbinc IN varchar2); -- -- -- -- -- PROCEDURE setArchiveFileScopeAttributes(logs_shared IN NUMBER); -- PROCEDURE setBackupFileScopeAttributes( disk_backups_shared IN NUMBER, tape_backups_shared IN NUMBER); -- -- -- -- -- -- PROCEDURE unregisterDatabase( idb IN varchar2); -- PROCEDURE clearUnarchivedLogs; /*--------------------------------------* * Virtual Private Catalog Procedures * *--------------------------------------*/ PROCEDURE grant_catalog(userid IN varchar2, dbname IN varchar2); PROCEDURE grant_catalog(userid IN varchar2, dbid IN number, reg_db_unique_name IN varchar2 default null); PROCEDURE grant_register(userid IN varchar2); PROCEDURE revoke_catalog(userid IN varchar2, dbname IN varchar2); PROCEDURE revoke_catalog(userid IN varchar2, dbid IN number, reg_db_unique_name IN varchar2 default null); PROCEDURE revoke_register(userid IN varchar2); PROCEDURE revoke_all(userid IN varchar2); PROCEDURE create_virtual_catalog; PROCEDURE drop_virtual_catalog; PROCEDURE setupVPD(i_oper IN NUMBER); PROCEDURE dumpPkgState (msg in varchar2 default NULL); /*--------------------------------------* * Recovery Server Catalog Procedures * *--------------------------------------*/ PROCEDURE put_bucket(bktname in varchar2); FUNCTION get_bucket(bktname in varchar2) return CLOB; PROCEDURE delete_bucket(bktname in varchar2); -- -- -- PROCEDURE put_object(bktname in varchar2, objname in varchar2, objtype in varchar2, objval in out CLOB); FUNCTION get_object(bktname in varchar2, objname in varchar2, parms in varchar2 DEFAULT null) return CLOB; PROCEDURE delete_object(bktname in varchar2, objname in varchar2); PROCEDURE writeFixedSections(bktname IN VARCHAR2 DEFAULT NULL); PROCEDURE readFixedSections(input_xml_filename IN VARCHAR2, bktname IN VARCHAR2 DEFAULT NULL); PROCEDURE rsWriteWaterMarks (input_xml_filename IN VARCHAR2, bktname IN VARCHAR2 DEFAULT NULL); PROCEDURE writeBackupSections(input_xml_filename IN VARCHAR2, bktname IN VARCHAR2 DEFAULT NULL); PROCEDURE readBackupSections(bktname IN VARCHAR2 DEFAULT NULL); PROCEDURE rsDeleteBackupPiece(bp_key IN number, purged IN varchar2); PROCEDURE addTimeZone( db_unique_name IN VARCHAR2 ,db_timezone IN VARCHAR2 ,tmz_src IN VARCHAR2 ,incarnations IN VARCHAR2 default 'CURRENT' ); -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION getValueFromConfig(entry IN VARCHAR2) RETURN VARCHAR2; -- -- PROCEDURE throttle_me(p_oam_job_id IN VARCHAR2, p_channels_reqd IN NUMBER, p_request_time IN DATE, p_wait OUT BOOLEAN, p_error_str OUT VARCHAR2); end dbms_rcvcat; >>> define dbmsrman_sql <<< create or replace package dbms_rcvman authid current_user is -- -- -- -- TRUE# CONSTANT number := 1; FALSE# CONSTANT number := 0; -- -- -- -- -- -- -- -- -- -- -- -- -- COPY CONSTANT NUMBER := 1; -- any image copy of a file FULL_DF_BACKUP CONSTANT NUMBER := 2; -- datafile in a full backup set INCREMENTAL_DF_BACKUP CONSTANT NUMBER := 3; -- datafile in an incr backup set BACKUP CONSTANT NUMBER := 4; -- any file in a backup set -- OFFLINE_RANGE CONSTANT NUMBER := 5; -- an offline range CUMULATIVE CONSTANT NUMBER := 6; -- cumulative incremental -- PROXY CONSTANT NUMBER := 7; -- any proxy copy of a file NONPROXY CONSTANT NUMBER := 9; -- any img, bs other than proxy AVMCOPY CONSTANT NUMBER := 10; -- only avm image copy of a file SPARSE CONSTANT NUMBER := 11; -- for sparse backup NONSPARSE CONSTANT NUMBER := 12; -- for nonsparse backup -- implicitOfflRange CONSTANT NUMBER := 2**0; cleanRange CONSTANT NUMBER := 2**1; applyOfflRange CONSTANT NUMBER := 2**2; dfCopy CONSTANT NUMBER := 2**3; proxyFull CONSTANT NUMBER := 2**4; buSet CONSTANT NUMBER := 2**5; applyIncremental CONSTANT NUMBER := 2**6; redo CONSTANT NUMBER := 2**7; -- maxKind CONSTANT NUMBER := redo; -- last real kind above allKind CONSTANT NUMBER := (maxKind*2) - 1; -- all real backup types fullKind CONSTANT NUMBER := dfCopy + proxyFull + buSet; tagKind CONSTANT NUMBER := fullKind + applyIncremental; -- deletedKind CONSTANT NUMBER := maxKind*2; -- action deleted -- -- -- BSavailable CONSTANT BINARY_INTEGER := 2**0; BSunavailable CONSTANT BINARY_INTEGER := 2**1; BSdeleted CONSTANT BINARY_INTEGER := 2**2; BSexpired CONSTANT BINARY_INTEGER := 2**3; -- -- -- -- BSpartial_avail CONSTANT BINARY_INTEGER := 2**4; -- -- -- BSdatafile_full CONSTANT BINARY_INTEGER := 2**0; BSdatafile_incr CONSTANT BINARY_INTEGER := 2**1; BSarchivelog CONSTANT BINARY_INTEGER := 2**2; -- -- -- BScfile_all CONSTANT BINARY_INTEGER := 2**0; -- shouldn't be altered BScfile_auto CONSTANT BINARY_INTEGER := 2**1; -- -- -- TYPE dfRec_t IS RECORD ( dfNumber number, dfCreationSCN number, dfCreationTime date, fileName varchar2(1024), tsName varchar2(30), tsNumber number, status number, blocks number, blockSize number, kbytes number, unrecovSCN number, stopSCN number, readOnly number, rfNumber number, inBackup number, -- if greater than 0 then -- auxName varchar2(1024), dbincKey number, dfOfflineSCN number, dfOnlineSCN number, dfOnlineTime date, encrypt number, -- encrypt value 1=ON, 2=OFF, 3=CLEAR foreignDbid number, -- foreign database id pluggedRonly binary_integer, -- 1 for read-only. Otherwise, 0 pluginSCN number, -- plugin change# pluginRlgSCN number, -- plugin resetlogs_change# pluginRlgTime date, -- plugin resetlogs_time newDfCreationSCN number, -- plugin scn or creation scn creation_thread number, -- creation thread creation_size number, -- creation size pdbId number, -- pdbid pdbKey number, -- pdbKey pdbName varchar2(128), -- pdbname pdbClosed number, -- pdbclosed pdbForeignDbid number, -- dbid of PDB from which this file came from noBackupPdb number -- this PDB is excluded from backup ); TYPE prePluginDfRec_t IS RECORD ( dfNumber number, pdbId number, prePluginDfNumber number ); -- -- -- TYPE tfRec_t IS RECORD ( tfNumber number, tfCreationSCN number, tfCreationTime date, fileName varchar2(1024), tsName varchar2(30), tsNumber number, status number, isSFT varchar2(3), blocks number, blockSize number, maxSize number, nextSize number, rfNumber number, dbincKey number, pdbId number, pdbKey number, pdbName varchar2(128) ); -- -- -- TYPE alRec_t IS RECORD ( key number, recid number, stamp number, thread number, sequence number, fileName varchar2(1024), lowSCN number, lowTime date, nextSCN number, nextTime date, rlgSCN number, rlgTime date, blocks number, blockSize number, status varchar2(1), compTime date, duplicate number, isrdf varchar2(3), compressed varchar2(3), stby varchar2(1), terminal varchar2(3), site_key number, site_key_order_col number, source_dbid number ); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- TYPE rcvRec_t IS RECORD ( -- type_con number, -- recovery container type key_con number, -- primary key recid_con number, -- recid stamp_con number, -- stamp setStamp_con number, -- set count if backup set (null) setCount_con number, -- set stamp if backup set (null) bsRecid_con number, -- backup set recid (null) bsStamp_con number, -- backup set stamp (null) bsKey_con number, -- backup set key (null) bsLevel_con number, -- backup set level (null) bsType_con varchar2(1), -- backup set type elapseSecs_con number, -- backup set elapse seconds (null) pieceCount_con number, -- backup set piece count (null) fileName_con varchar2(1024), -- filename if a copy (or) piece (null) tag_con varchar2(32), -- tag (null) -- -- copyNumber_con number, -- backup set copy# (null) maxlimit 256 -- status_con varchar2(1), -- status (null) blocks_con number, -- size of file in blocks (null) blockSize_con number, -- block size (null) deviceType_con varchar2(255), -- device type required (null) -- -- compTime_con date, -- completion time cfCreationTime_con date, -- controlfile creation time if -- pieceNumber_con number, bpCompTime_con date, bpCompressed_con varchar2(3), multi_section_con varchar2(1), -- multi-section backup piece -- type_act number, -- recovery action type fromSCN_act number, toSCN_act number, toTime_act date, rlgSCN_act number, rlgTime_act date, dbincKey_act number, level_act number, section_size_act number, -- dfNumber_obj number, dfCreationSCN_obj number, cfSequence_obj number, -- controlfile autobackup sequence cfDate_obj date, -- controlfile autobackup date logSequence_obj number, logThread_obj number, logRlgSCN_obj number, logRlgTime_obj date, logLowSCN_obj number, logLowTime_obj date, logNextSCN_obj number, logNextTime_obj date, logTerminal_obj varchar2(3), cfType_obj varchar2(1), -- controlfile type ('B' or 'S') pdbKey_obj number, -- keep_options number, keep_until date, -- afzSCN_act number, rfzTime_act date, rfzSCN_act number, -- media_con varchar2(80), -- media volume name for backup piece isrdf_con varchar2(3), -- site_key_con number, -- foreignDbid_obj number, -- foreign database id pluggedRonly_obj binary_integer, -- 1 for read-only. Otherwise, 0 pluginSCN_obj number, -- plugin change# pluginRlgSCN_obj number, -- plugin resetlogs change# pluginRlgTime_obj date, -- plugin resetlogs time -- newDfCreationSCN_obj number, -- plugin scn or creation scn newToSCN_act number, -- plugin scn or checkpoint scn newRlgSCN_act number, -- plugin rlgscn or rlgscn newRlgTime_act date, -- plugin rlgtime or rlgtime -- sfDbUniqueName_obj varchar2(30), -- sparse_backup_con varchar2(3), -- whether sparse or nonsparse backup ppl_pdb_id_con number, -- preplugin pdb id ppl_cdb_dbid_con number -- preplugin cdb database id ); -- -- -- -- -- -- -- -- -- -- -- -- offlineRangeRec_con_t CONSTANT NUMBER := 2**0; proxyCopy_con_t CONSTANT NUMBER := 2**1; imageCopy_con_t CONSTANT NUMBER := 2**2; backupSet_con_t CONSTANT NUMBER := 2**3; addredo_con_t CONSTANT NUMBER := 2**4; deleted_con_t CONSTANT NUMBER := 2**8; datafile_con_t CONSTANT NUMBER := 2**9; avmImageCopy_con_t CONSTANT NUMBER := 2**10; -- backupMask_con_t CONSTANT NUMBER := proxyCopy_con_t + imageCopy_con_t + backupSet_con_t; tagMask_con_t CONSTANT NUMBER := proxyCopy_con_t + imageCopy_con_t + backupSet_con_t; -- -- -- full_act_t CONSTANT NUMBER := 2**0; incremental_act_t CONSTANT NUMBER := 2**1; redo_act_t CONSTANT NUMBER := 2**2; offlineRange_act_t CONSTANT NUMBER := 2**3; cleanRange_act_t CONSTANT NUMBER := 2**4; implicitRange_act_t CONSTANT NUMBER := 2**5; spanningRange_act_t CONSTANT NUMBER := 2**6; createdatafile_act_t CONSTANT NUMBER := 2**7; -- -- -- -- -- -- getCfCopy CONSTANT NUMBER := 0; getDfCopy CONSTANT NUMBER := 1; getAnyProxy CONSTANT NUMBER := 2; getCfBackup CONSTANT NUMBER := 3; listCfCopy CONSTANT NUMBER := 4; listDfCopy CONSTANT NUMBER := 5; listCfBackup CONSTANT NUMBER := 6; listDfBackup CONSTANT NUMBER := 7; listAlBackup CONSTANT NUMBER := 8; listDfProxy CONSTANT NUMBER := 9; getRecovAction CONSTANT NUMBER := 10; getAlBackup CONSTANT NUMBER := 11; listAlCopy CONSTANT NUMBER := 12; listBSet CONSTANT NUMBER := 13; getSfBackup CONSTANT NUMBER := 14; listSfBackup CONSTANT NUMBER := 15; getAllBSet CONSTANT NUMBER := 16; listAlProxy CONSTANT NUMBER := 17; getRangeAlBackup CONSTANT NUMBER := 18; -- -- -- -- -- -- unknownCmd_t CONSTANT BINARY_INTEGER := 0; recoverCmd_t CONSTANT BINARY_INTEGER := 1; rcvCopyCmd_t CONSTANT BINARY_INTEGER := 2; obsoleteCmd_t CONSTANT BINARY_INTEGER := 3; restoreCmd_t CONSTANT BINARY_INTEGER := 4; blkRestoreCmd_t CONSTANT BINARY_INTEGER := 5; -- -- -- -- -- -- stuckMemorySize CONSTANT NUMBER := 50 * 1024 * 1024; -- -- -- TYPE bsRec_t IS RECORD ( recid number, stamp number, key number, setStamp number, setCount number, bsType varchar2(1), level number, elapseSecs number, compTime date, status varchar2(1), pieceCount number, keep_options number, keep_until date, multi_section varchar2(1), ppl_pdb_id number, -- preplugin pdb id ppl_cdb_dbid number -- preplugin cdb database id ); -- -- -- TYPE bpRec_t IS RECORD ( recid number, stamp number, key number, bskey number, setStamp number, setCount number, bsType varchar2(1), pieceNumber number, copyNumber number, status varchar2(1), compTime date, handle varchar2(1024), tag varchar2(32), deviceType varchar2(255), media varchar2(80), bytes number, compressed varchar2(3), site_key number, vb_key number, am_access varchar2(1), -- need for 12.0 compatibility ba_access varchar2(1), ppl_pdb_id number, -- preplugin pdb id ppl_cdb_dbid number -- preplugin cdb database id ); -- -- -- TYPE validBackupSetRec_t IS RECORD ( deviceType varchar2(255), tag varchar2(32), -- may be null order1 number, -- preference hint copyNumber number, -- null if code 2 or 3 code number -- 1 => same copy# -- -- -- ); bsRecCacheEnabled constant boolean := TRUE; -- FALSE to use pre10i method bsRecCacheLowLimit constant number := 2048; -- minimum cache size bsRecCacheHighLimit constant number := 32768; -- maximum cache size TYPE incarnation_t IS RECORD ( INCARNATION# NUMBER, RESETLOGS_CHANGE# NUMBER, RESETLOGS_TIME DATE, PRIOR_RESETLOGS_CHANGE# NUMBER, PRIOR_RESETLOGS_TIME DATE, STATUS VARCHAR2(7), RESETLOGS_ID NUMBER, PRIOR_INCARNATION# NUMBER ); TYPE pdb_incarnation_t IS RECORD ( CON_ID NUMBER, PDBINC_KEY NUMBER, INCSCN NUMBER, ERSCN NUMBER, STATUS VARCHAR2(7) ); -- -- -- TYPE bhistoryRec_t IS RECORD ( dfNumber number, create_scn number, reset_scn number, reset_time date, ckp_scn number, ckp_time date, stop_scn number, logThread number, logSequence number, setStamp number, setCount number, compTime date, nbackups number, logTerminal varchar2(3), next_scn number, pluggedRonly binary_integer, -- 1 for read-only. Otherwise, 0 pluginSCN number, pluginRlgSCN number, pluginRlgTime date, newcreate_scn number, -- create_scn or pluginSCN newreset_scn number, -- reset_scn or pluginRlgSCN newreset_time date -- reset_time or pluginRlgTime ); -- -- -- TYPE agedFileRec_t IS RECORD ( type number, key number, stamp number ); -- -- -- -- -- -- backupset_txt CONSTANT VARCHAR2(16) := 'BACKUP SET'; copy_txt CONSTANT VARCHAR2(16) := 'COPY'; proxycopy_txt CONSTANT VARCHAR2(16) := 'PROXY COPY'; datafile_txt CONSTANT VARCHAR2(16) := 'DATAFILE'; spfile_txt CONSTANT VARCHAR2(16) := 'SPFILE'; archivedlog_txt CONSTANT VARCHAR2(16) := 'ARCHIVED LOG'; controlfile_txt CONSTANT VARCHAR2(16) := 'CONTROLFILE'; piece_txt CONSTANT VARCHAR2(16) := 'PIECE'; available_txt CONSTANT VARCHAR2(16) := 'AVAILABLE'; unavailable_txt CONSTANT VARCHAR2(16) := 'UNAVAILABLE'; expired_txt CONSTANT VARCHAR2(16) := 'EXPIRED'; deleted_txt CONSTANT VARCHAR2(16) := 'DELETED'; other_txt CONSTANT VARCHAR2(16) := 'OTHER'; full_txt CONSTANT VARCHAR2(16) := 'FULL'; incr1_txt CONSTANT VARCHAR2(16) := 'INCR1'; incr2_txt CONSTANT VARCHAR2(16) := 'INCR2'; incr3_txt CONSTANT VARCHAR2(16) := 'INCR3'; incr4_txt CONSTANT VARCHAR2(16) := 'INCR4'; incr_txt CONSTANT VARCHAR2(16) := 'INCR'; -- level unknown -- -- -- -- -- -- -- TYPE lbRec_t IS RECORD ( list_order1 NUMBER, -- just hint to correctly order records list_order2 NUMBER, -- just hint to correctly order records pkey NUMBER, -- primary key -- -- -- backup_type VARCHAR2(32), -- Type of the backup: -- -- -- -- -- -- file_type VARCHAR2(32), -- Type of the file: -- -- -- -- -- -- -- keep VARCHAR2(3), keep_until DATE, keep_options VARCHAR2(13), status VARCHAR2(16), -- Status of the piece/copy: -- -- -- -- fname VARCHAR2(1024), -- piece or copy name tag VARCHAR2(32), -- piece or copy tag media VARCHAR2(80), recid NUMBER, stamp NUMBER, device_type VARCHAR2(255), block_size NUMBER, completion_time DATE, is_rdf VARCHAR2(3), compressed VARCHAR2(3), obsolete VARCHAR2(3), keep_for_dbpitr VARCHAR2(3), bytes NUMBER, -- -- bs_key NUMBER, bs_count NUMBER, bs_stamp NUMBER, bs_type VARCHAR2(32), -- Type of the backup set: -- -- bs_incr_type VARCHAR2(32), bs_pieces NUMBER, bs_copies NUMBER, bs_completion_time DATE, bs_status VARCHAR2(16), -- Status of the backup set: -- -- -- -- bs_bytes NUMBER, bs_compressed VARCHAR2(3), -- If backup set is compressed: -- -- -- bs_tag VARCHAR2(1024), -- List of all tags of pieces. -- -- bs_device_type VARCHAR2(255), -- List of device types of pieces. -- -- -- bp_piece# NUMBER, bp_copy# NUMBER, bp_vb_key NUMBER, bp_ba_access VARCHAR2(1), bp_lib_key NUMBER, -- -- df_file# NUMBER, df_ts# NUMBER, df_plugin_change# NUMBER, df_foreign_dbid NUMBER, df_tablespace VARCHAR2(30), df_resetlogs_change# NUMBER, df_creation_change# NUMBER, df_checkpoint_change# NUMBER, df_ckp_mod_time DATE, df_incremental_change# NUMBER, -- -- rl_thread# NUMBER, rl_sequence# NUMBER, rl_resetlogs_change# NUMBER, rl_first_change# NUMBER, rl_first_time DATE, rl_next_change# NUMBER, rl_next_time DATE, -- sf_db_unique_name VARCHAR2(30), -- con_id NUMBER ); -- -- -- TYPE lbDfRec_t IS RECORD ( dfRec dfRec_t, -- -- -- -- -- fullmin_scn NUMBER, fullmin_rlgscn NUMBER, -- -- -- -- -- incrmin_scn NUMBER, incrmin_rlgscn NUMBER, -- -- -- -- -- logmin_scn NUMBER, logmin_rlgscn NUMBER ); TYPE lbDfRecTab_t IS TABLE OF lbDfRec_t INDEX BY BINARY_INTEGER; TYPE lbRecTab_t IS TABLE OF lbRec_t INDEX BY BINARY_INTEGER; TYPE lbRecVar_t IS VARRAY(1) OF lbRec_t; TYPE rcvRecTabI_t IS TABLE OF rcvRec_t INDEX BY BINARY_INTEGER; TYPE rcvRecTabII_t IS TABLE OF rcvRecTabI_t INDEX BY BINARY_INTEGER; TYPE dfRecTab_t IS TABLE OF dfRec_t INDEX BY BINARY_INTEGER; TYPE numTab_t IS TABLE OF number INDEX BY BINARY_INTEGER; TYPE lbCursor_t IS REF CURSOR; -- -- -- -- -- TYPE lbState_t IS RECORD ( -- -- -- lbRecOutTab lbRecTab_t, lbRecOutTab_count binary_integer, -- -- lbRecTmpTab lbRecTab_t, -- lbRecCmn lbRec_t, -- -- lbDfRecTabUs lbDfRecTab_t, -- -- lbDfRecTab dfRecTab_t, -- -- lbMaxDfNumber number, -- lbNowTime date, -- -- lbPieceCountTab numTab_t, lbCopyCount binary_integer, -- -- lbMkTab rcvRecTabII_t, -- -- lbMkITab rcvRecTabII_t, -- -- -- -- -- -- -- -- -- lbMinGrsp number, -- -- -- -- -- lbFbUntilTime date, -- -- -- -- lbRlKeepRlgSCN number, -- -- -- -- -- -- lbRlKeepSCN number, -- -- -- -- -- lbObsoleteRetention boolean, lbKeepForDBPITR boolean, lbObsoleteKeep boolean, lbNeedObsoleteData boolean ); -- -- -- lbStatePck lbState_t; -- -- -- -- -- -- -- -- -- -- -- TYPE restoreRange_t IS RECORD ( lowTime DATE, highTime DATE, startScn NUMBER, lowScn NUMBER, highScn NUMBER, lowDbIncKey NUMBER, highDbIncKey NUMBER, lowRlgScn NUMBER, highRlgScn NUMBER, lowRlgTime DATE, highRlgTime DATE, rcvStartScn NUMBER, rcvStartTime DATE, isValidRange BOOLEAN, cfBkupFound BOOLEAN, con_id NUMBER ); TYPE restoreRangeTab_t IS TABLE OF restoreRange_t INDEX BY BINARY_INTEGER; -- TYPE failureRec_t IS RECORD ( priority VARCHAR2(8), failureId NUMBER, parentId NUMBER, childCount NUMBER, description VARCHAR2(1024), timeDetected DATE, status VARCHAR2(12), impacts VARCHAR2(1024) ); TYPE repairRec_t IS RECORD ( type NUMBER, failureidx NUMBER, repairidx NUMBER, description VARCHAR2(1024) ); TYPE repairParmsRec_t IS RECORD ( type NUMBER, failureidx NUMBER, repairidx NUMBER, name VARCHAR2(256), value VARCHAR2(512) ); TYPE repairOptionRec_t IS RECORD ( optionidx NUMBER, description VARCHAR2(1024) ); TYPE repairStepRec_t IS RECORD ( type NUMBER, failureidx NUMBER, repairidx NUMBER, repairstepidx NUMBER, workingrepair NUMBER, description VARCHAR2(1024), repairscript VARCHAR2(1024) ); -- -- -- TYPE pdbNameRec_t IS RECORD ( pdbId NUMBER, name VARCHAR2(128) ); TYPE pdbFileRec_t IS RECORD ( pdbId NUMBER, file# NUMBER, stopSCN NUMBER ); cdbRoot_txt CONSTANT VARCHAR2(8) := 'CDB$ROOT'; -- -- -- -- -- -- FUNCTION dumpState( lineno IN number) RETURN varchar2; PROCEDURE dumpPkgState(msg in varchar2 default null); PROCEDURE setDebugOn; PROCEDURE setDebugOff; -- -- -- -- -- -- -- PROCEDURE initialize(rman_vsn IN number); -- -- -- PROCEDURE set_package_constants; -- -- -- FUNCTION stamp2date(stamp IN number) RETURN date; -- -- -- PROCEDURE getCurrentIncarnation( db_id IN number ,reset_scn OUT number ,reset_time OUT date); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE setDatabase( db_name IN varchar2 ,reset_scn IN number ,reset_time IN date ,db_id IN number ,db_unique_name IN varchar2 default NULL ,site_aware IN boolean default FALSE ,dummy_instance IN boolean default FALSE ,ors_instance IN boolean default FALSE); -- -- -- FUNCTION getDbUniqueName( db_id IN number) RETURN varchar2; -- FUNCTION getDbKey RETURN NUMBER; -- FUNCTION getMinRcvStartScn RETURN NUMBER; -- PROCEDURE resetDbKey; -- -- FUNCTION DbUniqueNameIsStandby RETURN NUMBER; -- -- PROCEDURE setCanConvertCf(flag IN boolean); -- -- PROCEDURE setDbincKey( key IN number); -- -- -- FUNCTION getParentIncarnation( resetlogs_change# IN OUT number ,resetlogs_time IN OUT date) RETURN number; -- -- -- -- PROCEDURE getCheckpoint( scn OUT number ,seq OUT number); -- -- PROCEDURE getCheckpoint( scn OUT number ,seq OUT number ,ckp_key_1 OUT number ,ckp_key_2 OUT number); -- -- -- PROCEDURE SetGetSinceLastBackedAL(ntimes IN number DEFAULT 1, devtype IN varchar2 DEFAULT NULL, sbpscn IN number); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE setCompletedRange( after IN date ,before IN date); PROCEDURE setLikePattern( pattern IN varchar2); PROCEDURE setcanApplyAnyRedo( flag IN boolean); -- PROCEDURE setBigScnAware; -- PROCEDURE setAllFlag( flag IN boolean); PROCEDURE setAllIncarnations( flag IN boolean); PROCEDURE setUntilTime( unttime IN date); -- -- -- -- -- -- PROCEDURE setUntilScn( scn IN number ,rlgscn IN number DEFAULT NULL ,rlgtime IN date DEFAULT NULL ,flbrp IN boolean DEFAULT FALSE ,rpoint IN boolean DEFAULT FALSE); PROCEDURE setUntilLog( sequence# IN number ,thread# IN number); PROCEDURE setToLog( sequence# IN number ,thread# IN number); PROCEDURE setUntilResetlogs; PROCEDURE setGuid(guid IN varchar2 DEFAULT NULL); FUNCTION getUntilTime return date; FUNCTION getUntilScn return number; PROCEDURE resetUntil; -- -- -- -- -- -- -- PROCEDURE setFrom( restorefrom IN number DEFAULT NULL); -- -- -- -- -- -- PROCEDURE setSparseness( sparseness IN number DEFAULT NULL); -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE setDeviceType( type IN varchar2); -- -- PROCEDURE setStandby( stby IN boolean); PROCEDURE setDeviceTypeAny; -- PROCEDURE resetDeviceType; -- -- -- -- -- -- -- -- PROCEDURE setTag(tag IN varchar2 DEFAULT NULL); -- -- -- -- -- -- -- PROCEDURE setRecoveryDestFile(onlyrdf IN BOOLEAN); -- -- -- -- -- -- -- -- -- PROCEDURE setOrsFile(localOnly IN BOOLEAN, libKey IN NUMBER); -- -- -- -- -- PROCEDURE setSiteName(db_unique_name IN VARCHAR2, for_realfiles IN NUMBER); -- PROCEDURE clrSiteName; -- FUNCTION getSiteName(site_key IN NUMBER) RETURN VARCHAR2; -- FUNCTION getSiteKey(db_unique_name IN VARCHAR2) RETURN NUMBER; -- PROCEDURE setArchiveFileScopeAttributes(logs_shared IN NUMBER); -- PROCEDURE setFirstFullBckScopeAttributes(baseline_cap IN NUMBER); -- PROCEDURE setBackupFileScopeAttributes( disk_backups_shared IN NUMBER, tape_backups_shared IN NUMBER); -- -- PROCEDURE resetAll(transclause IN BOOLEAN DEFAULT TRUE); -- -- -- -- -- findValidBackupSetRcvRec rcvRec_t; -- place to save a rcvRec_t PROCEDURE findValidBackupSet( backupSetRec IN rcvRec_t ,deviceType IN varchar2 DEFAULT NULL ,tag IN varchar2 DEFAULT NULL ,available IN number DEFAULT TRUE# -- for compat. ,unavailable IN number DEFAULT FALSE# -- for compat. ,deleted IN number DEFAULT FALSE# -- for compat. ,expired IN number DEFAULT FALSE# -- for compat. ,availableMask IN binary_integer DEFAULT NULL); -- for compat. findValidBackupSetBsRec bsRec_t; -- place to save a bsRec_t -- PROCEDURE findValidBackupSet( backupSetRec IN bsRec_t ,deviceType IN varchar2 DEFAULT NULL ,tag IN varchar2 DEFAULT NULL ,available IN number DEFAULT TRUE# -- for compat. ,unavailable IN number DEFAULT FALSE# -- for compat. ,deleted IN number DEFAULT FALSE# -- for compat. ,expired IN number DEFAULT FALSE# -- for compat. ,availableMask IN binary_integer DEFAULT NULL); -- for compat. FUNCTION getValidBackupSet( validBackupSetRec OUT NOCOPY validBackupSetRec_t ,checkDeviceIsAllocated IN number DEFAULT FALSE#) RETURN number; -- TRUE# -> got a record -- -- -- -- -- -- -- -- -- -- FUNCTION getRcvRec( funCode IN number ,rcvRec OUT NOCOPY rcvRec_t ,callAgain OUT number) RETURN number; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE translateDatabase( sinceUntilSCN IN number DEFAULT NULL); PROCEDURE skipTableSpace( tsName IN varchar2 ,pdbId IN number DEFAULT 0); PROCEDURE translateTablespace( ts_name IN varchar2, pdb_id IN number DEFAULT 0); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE translateDataFile( fname IN varchar2); PROCEDURE translateDatafile( fno IN number); PROCEDURE translateDatafile( fno IN number ,ckpscn IN number); -- -- PROCEDURE translateAllDatafile; PROCEDURE translateCorruptList; PROCEDURE getDatafile( dfRec OUT NOCOPY dfRec_t ,oldClient IN boolean DEFAULT FALSE); -- PROCEDURE getDataFile( file# OUT number ,crescn OUT number ,creation_time OUT date ,fname OUT varchar2 ,ts_name OUT varchar2 ,status OUT number ,blksize OUT number ,kbytes OUT number ,blocks OUT number ,unrecoverable_change# OUT number ,stop_change# OUT number ,read_only OUT number); -- -- -- -- -- PROCEDURE translatePrePluginDf(con_id IN number); FUNCTION getPrePluginDf( prePluginDfRec OUT NOCOPY prePluginDfRec_t) RETURN NUMBER; -- -- -- -- -- PROCEDURE translateTempfile; PROCEDURE translateTempfile(fname IN varchar2); PROCEDURE translateTempfile(fno IN number); -- -- -- PROCEDURE getTempfile(tfRec OUT NOCOPY tfRec_t); -- -- -- -- -- PROCEDURE translateOnlineLogs(srls IN number DEFAULT 0); PROCEDURE getOnlineLog( fname OUT varchar2 ,thread# OUT number ,group# OUT number); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE getArchivedLog( alRec OUT NOCOPY alRec_t ,closeCursor IN boolean DEFAULT FALSE); PROCEDURE translateArchivedLogKey( al_key IN number ,available IN number DEFAULT 1 -- ignored (for compatability) ,unavailable IN number DEFAULT 1 -- ignored (for compatability) ,deleted IN number DEFAULT 1 -- ignored (for compatability) ,online IN number DEFAULT 1 -- ignored (for compatability) ,recid OUT number ,stamp OUT number ,thread# OUT number ,sequence# OUT number ,low_scn OUT number ,reset_scn OUT number ,block_size OUT number ,fname OUT varchar2 ,needstby IN number DEFAULT NULL); PROCEDURE translateArchivedLogName( fname IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,deleted IN number DEFAULT NULL -- for compatability ,online IN number -- ignored ,duplicates IN number ,statusMask IN binary_integer DEFAULT NULL -- for compatability ,needstby IN number DEFAULT NULL); -- for compatability -- -- -- -- -- PROCEDURE translateArchivedLogSeqRange( thread# IN number ,fromseq# IN number ,toseq# IN number ,pattern IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,deleted IN number DEFAULT NULL -- for compatability ,online IN number -- ignored ,duplicates IN number ,statusMask IN binary_integer DEFAULT NULL -- for compatability ,needstby IN number DEFAULT NULL -- for compatability ,foreignal IN binary_integer DEFAULT 0 -- for compatability ,incarn IN number DEFAULT NULL); -- for compatibility PROCEDURE translateArchivedLogTimeRange( thread# IN number ,fromTime IN date ,toTime IN date ,pattern IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,deleted IN number DEFAULT NULL -- for compatability ,online IN number -- ignored ,duplicates IN number ,statusMask IN binary_integer DEFAULT NULL -- for compatability ,needstby IN number DEFAULT NULL -- for compatability ,foreignal IN binary_integer DEFAULT 0 -- for compatability ,incarn IN number DEFAULT NULL); -- for compatibility PROCEDURE translateArchivedLogSCNRange( thread# IN number ,fromSCN IN number ,toSCN IN number ,pattern IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,deleted IN number DEFAULT NULL -- for compatability ,online IN number ,duplicates IN number ,statusMask IN binary_integer DEFAULT NULL -- for compatability ,needstby IN number DEFAULT NULL ,doingRecovery IN number DEFAULT FALSE# ,onlyrdf IN binary_integer DEFAULT 0 -- for compatability ,reset_scn IN number DEFAULT NULL -- for compatability ,reset_time IN date DEFAULT NULL -- for compatability ,sequence# IN number DEFAULT NULL -- for compatability ,foreignal IN binary_integer DEFAULT 0 -- for compatability ,incarn IN number DEFAULT NULL); -- for compatibility PROCEDURE translateArchivedLogPattern( pattern IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,deleted IN number DEFAULT NULL -- for compatability ,online IN number -- ignored ,duplicates IN number ,statusMask IN binary_integer DEFAULT NULL -- for compatability ,needstby IN number DEFAULT NULL -- for compatability ,foreignal IN binary_integer DEFAULT 0); -- for compatability PROCEDURE translateArchivedLogCancel; -- PROCEDURE sv_setSessionKey(skey IN NUMBER); PROCEDURE sv_setSessionTimeRange(fromTime IN DATE, untilTime IN DATE); FUNCTION sv_getSessionKey RETURN NUMBER; FUNCTION sv_getSessionfromTimeRange RETURN DATE; FUNCTION sv_getSessionUntilTimeRange RETURN DATE; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE getArchivedLog( recid OUT number ,stamp OUT number ,thread# OUT number ,sequence# OUT number ,low_scn OUT number ,nxt_scn OUT number ,fname OUT varchar2 ,reset_scn OUT number ,block_size OUT number ,blocks OUT number); -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE translateControlFileCopyName( fname IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,duplicates IN number ,statusMask IN binary_integer DEFAULT NULL -- for compatability ,onlyone IN number DEFAULT 1); PROCEDURE translateControlFileCopyTag( cftag IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,duplicates IN number ,statusMask IN binary_integer DEFAULT NULL -- for compatability ,onlyone IN number DEFAULT 1); PROCEDURE translateControlFileCopyKey( key IN number ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,statusMask IN binary_integer DEFAULT NULL); -- for compatability PROCEDURE getControlFileCopy( rcvRec IN OUT NOCOPY rcvRec_t); -- PROCEDURE getControlFileCopy( recid OUT number ,stamp OUT number ,reset_scn OUT number ,ckp_scn OUT number ,block_size OUT number); -- -- -- PROCEDURE getDataFileCopy( rcvRec OUT NOCOPY rcvRec_t ,closeCursor IN boolean DEFAULT FALSE); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE translateDataFileCopyKey( cdf_key IN number ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,statusMask IN binary_integer DEFAULT NULL); -- for compatability -- PROCEDURE translateDataFileCopyKey( cdf_key IN number ,available IN number ,unavailable IN number ,recid OUT number ,stamp OUT number ,file# OUT number ,fname OUT varchar2 ,reset_scn OUT number ,create_scn OUT number ,ckp_scn OUT number ,block_size OUT number ,blocks OUT number); PROCEDURE translateDataFileCopyName( fname IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,duplicates IN number ,statusMask IN binary_integer DEFAULT NULL -- for compatability ,onlyone IN number DEFAULT 1 ,pluginSCN IN number DEFAULT 0); PROCEDURE translateDataFileCopyTag( tag IN varchar2 ,available IN number DEFAULT NULL -- for compatibility ,unavailable IN number DEFAULT NULL -- for compatibility ,duplicates IN number ,statusMask IN binary_integer DEFAULT NULL -- for compatibility ,pluginSCN IN number DEFAULT 0 ,onlytc IN binary_integer DEFAULT FALSE#); -- for compatibility PROCEDURE translateDataFileCopyFno( fno IN number ,available IN number DEFAULT NULL ,unavailable IN number DEFAULT NULL ,duplicates IN number ,statusMask IN binary_integer DEFAULT NULL ,pluginSCN IN number DEFAULT 0); PROCEDURE translateDataFileCopy( duplicates IN number ,statusMask IN binary_integer ,onlyrdf IN binary_integer ,pluginSCN IN number DEFAULT 0); -- PROCEDURE translateDatafileCancel; -- PROCEDURE getDataFileCopy( recid OUT number ,stamp OUT number ,file# OUT number ,fname OUT varchar2 ,reset_scn OUT number ,create_scn OUT number ,ckp_scn OUT number ,block_size OUT number ,blocks OUT number); -- -- -- PROCEDURE getProxyCopy( rcvRec OUT NOCOPY rcvRec_t ,closeCursor IN boolean DEFAULT FALSE); PROCEDURE translateProxyCopyKey( pc_key IN number ,deviceType IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,deleted IN number DEFAULT NULL -- for compatability ,expired IN number DEFAULT NULL -- for compatability ,statusMask IN binary_integer DEFAULT NULL); -- for compatability -- PROCEDURE translateProxyCopyKey( pc_key IN number ,device_type IN varchar2 ,available IN number ,unavailable IN number ,deleted IN number ,recid OUT number ,stamp OUT number ,handle OUT varchar2); PROCEDURE translateProxyCopyHandle( handle IN varchar2 ,deviceType IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,deleted IN number DEFAULT NULL -- for compatability ,expired IN number DEFAULT NULL -- for compatability ,statusMask IN binary_integer DEFAULT NULL); -- for compatability -- PROCEDURE translateProxyCopyHandle( handle IN varchar2 ,device_type IN varchar2 ,available IN number ,unavailable IN number ,deleted IN number ,recid OUT number ,stamp OUT number); PROCEDURE translateProxyCopyTag( tag IN varchar2 ,device_type IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,deleted IN number DEFAULT NULL -- for compatability ,statusMask IN binary_integer DEFAULT NULL); -- for compatability PROCEDURE translateProxyCopyGuid( guid IN varchar2 ,device_type IN varchar2 ,statusMask IN binary_integer); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE getProxyCopy( recid OUT number ,stamp OUT number ,handle OUT varchar2); -- -- -- PROCEDURE getBackupPiece( bpRec OUT NOCOPY bpRec_t ,closeCursor IN boolean DEFAULT FALSE); PROCEDURE translateBackupPieceKey( key IN number ,available IN number DEFAULT TRUE# ,unavailable IN number DEFAULT TRUE# ,expired IN number DEFAULT TRUE# ,statusMask IN binary_integer DEFAULT NULL); -- for compatability PROCEDURE translateBackupPieceKey( -- only used in 8.1.6 bp_key IN number ,available IN number ,unavailable IN number ,recid OUT number ,stamp OUT number ,handle OUT varchar2 ,set_stamp OUT number ,set_count OUT number ,piece# OUT number); PROCEDURE translateBackupPieceHandle( handle IN varchar2 ,deviceType IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,expired IN number DEFAULT NULL -- for compatability ,statusMask IN binary_integer DEFAULT NULL); -- for compatability PROCEDURE translateBackupPieceHandle( -- only used in 8.1.6 handle IN varchar2 ,device_type IN varchar2 ,available IN number ,unavailable IN number ,recid OUT number ,stamp OUT number ,set_stamp OUT number ,set_count OUT number ,piece# OUT number); PROCEDURE translateBackupPieceTag( tag IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,statusMask IN binary_integer DEFAULT NULL); -- for compatability PROCEDURE translateBackupPieceGuid( guid IN varchar2 ,statusMask IN binary_integer); PROCEDURE translateBackupPieceBSKey( key IN number ,tag IN varchar2 DEFAULT NULL ,deviceType IN varchar2 DEFAULT NULL ,pieceCount IN number ,duplicates IN number DEFAULT TRUE# ,copyNumber IN number DEFAULT NULL ,available IN number DEFAULT TRUE# ,unavailable IN number DEFAULT FALSE# ,deleted IN number DEFAULT FALSE# ,expired IN number DEFAULT FALSE# ,statusMask IN binary_integer DEFAULT NULL); -- for compatability PROCEDURE translateBackupPieceBsKey( startBsKey IN number ,tag IN varchar2 DEFAULT NULL ,statusMask IN binary_integer DEFAULT NULL); -- -- PROCEDURE translateSeekBpBsKey( bsKey IN number ,deviceType IN varchar2 ,pieceCount IN number ,duplicates IN number DEFAULT TRUE# ,copyNumber IN number DEFAULT NULL); -- -- -- -- -- -- -- -- -- PROCEDURE translateBpBsKeyCancel; -- -- -- -- PROCEDURE translateBackupSetKey( bs_key IN number ,device_type IN varchar2 ,available IN number ,unavailable IN number ,deleted IN number ,duplicates IN number ,backup_type OUT varchar2 ,recid OUT number ,stamp OUT number ,set_stamp OUT number ,set_count OUT number ,bslevel OUT number ,completion_time OUT date); -- PROCEDURE translateBackupSetKey( bs_key IN number ,device_type IN varchar2 ,available IN number ,unavailable IN number ,deleted IN number ,duplicates IN number ,backup_type OUT varchar2 ,recid OUT number ,stamp OUT number); -- PROCEDURE translateBackupSetRecid( recid IN number ,stamp IN number ,device_type IN varchar2 ,bs_key OUT number ,bslevel OUT number ,completed OUT date); -- PROCEDURE translateBackupSetRecid( recid IN number ,stamp IN number ,device_type IN varchar2); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE getBackupPiece( recid OUT number ,stamp OUT number ,bpkey OUT number ,set_stamp OUT number ,set_count OUT number ,piece# OUT number ,copy# OUT number ,status OUT varchar2 ,completion OUT date ,handle OUT varchar2); -- PROCEDURE getBackupPiece( recid OUT number ,stamp OUT number ,set_stamp OUT number ,set_count OUT number ,piece# OUT number ,handle OUT varchar2); -- -- -- PROCEDURE translateBackupSetKey( key IN number ,bsRec OUT NOCOPY bsRec_t); PROCEDURE translateAllBackupSet( backupType IN binary_integer ,tag IN varchar2 ,statusMask IN binary_integer ,completedAfter IN date ,completedBefore IN date ,onlyrdf IN binary_integer DEFAULT 0); PROCEDURE getAllBackupSet( rcvRec OUT NOCOPY rcvRec_t); -- -- -- FUNCTION translatePdb2Name( pdbId IN NUMBER) RETURN VARCHAR2; -- -- -- -- -- -- -- -- -- PROCEDURE findControlfileBackup( allCopies IN boolean default FALSE, allBackups IN boolean default FALSE, allIncarnation IN boolean default FALSE, fromSCN IN number default 0, pdbid IN number default 0); -- -- FUNCTION getControlfileBackup( rcvRec OUT NOCOPY rcvRec_t) RETURN number; -- FUNCTION getPrimaryDfName(fno IN NUMBER) RETURN VARCHAR2; -- -- -- -- -- FUNCTION findControlFileBackup( type OUT number ,recid OUT number ,stamp OUT number ,fname OUT varchar2 ,device_type OUT varchar2 ,ckp_scn OUT number) RETURN number; -- FUNCTION findControlFileBackup( type OUT number ,recid OUT number ,stamp OUT number ,fname OUT varchar2 ,device_type OUT varchar2 ,ckp_scn OUT number ,rlg_scn OUT number ,blksize OUT number) RETURN number; -- -- -- PROCEDURE findRangeArchivedLogBackup( minthread IN number ,minsequence IN number ,minlowSCN IN number ,maxthread IN number ,maxsequence IN number ,maxlowSCN IN number ,allCopies IN boolean default FALSE); -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE findArchivedLogBackup( thread IN number ,sequence IN number ,lowSCN IN number ,allCopies IN boolean default FALSE); -- -- -- -- -- -- -- -- -- -- FUNCTION getArchivedLogBackup( rcvRec OUT NOCOPY rcvRec_t) RETURN binary_integer; -- FUNCTION findArchivedLogBackup( thread# IN number ,sequence# IN number ,low_scn IN number ,type OUT number ,recid OUT number ,stamp OUT number ,device_type OUT varchar2) RETURN number; -- -- -- -- -- -- -- PROCEDURE findSpfileBackup( allCopies IN boolean default FALSE ,redundancy IN number default NULL ,rmanCmd IN number default unknownCmd_t); PROCEDURE findSpfileBackup( allCopies IN boolean default FALSE ,redundancy IN number default NULL ,rmanCmd IN number default unknownCmd_t ,scn_warn OUT number); -- -- FUNCTION getSpfileBackup( rcvRec OUT NOCOPY rcvRec_t ,redundancy IN number default NULL ,rmanCmd IN number default unknownCmd_t) RETURN number; -- -- -- PROCEDURE listTranslateControlfileCopy( tag IN varchar2 ,completedAfter IN date ,completedBefore IN date ,statusMask IN binary_integer DEFAULT BSavailable+BSunavailable+BSexpired ,liststby IN binary_integer DEFAULT NULL -- default for 8.1 ,file_pattern IN varchar2 DEFAULT NULL); PROCEDURE listGetControlfileCopy( rcvRec OUT NOCOPY rcvRec_t); -- FUNCTION listGetControlfileCopy( bcfkey OUT number ,ckpscn OUT number ,ckptime OUT date ,status OUT varchar2 ,completion OUT date ,fname OUT varchar2) RETURN number; PROCEDURE listTranslateDataFileCopy( file# IN number ,creation_change# IN number ,tag IN varchar2 DEFAULT NULL ,file_name_pattern IN varchar2 DEFAULT NULL ,completedAfter IN date DEFAULT NULL ,completedBefore IN date DEFAULT NULL ,statusMask IN binary_integer DEFAULT BSavailable+BSunavailable -- ,pluginSCN IN number DEFAULT 0); PROCEDURE listGetDataFileCopy( rcvRec OUT NOCOPY rcvRec_t); -- FUNCTION listGetDataFileCopy( cdf_key OUT number ,status OUT varchar2 ,fname OUT varchar2 ,completion_time OUT date ,checkpoint_change# OUT number ,checkpoint_time OUT date) RETURN number; PROCEDURE listTranslateArchivedLogCopy( thread# IN number ,sequence# IN number ,first_change# IN number ,file_name_pattern IN varchar2 DEFAULT NULL ,completedAfter IN date DEFAULT NULL ,completedBefore IN date DEFAULT NULL ,statusMask IN binary_integer DEFAULT BSavailable+BSunavailable+BSexpired -- 8.0/8.1 defaults ,needstby IN number DEFAULT NULL); PROCEDURE listGetArchivedLogCopy( rcvRec OUT NOCOPY rcvRec_t); -- FUNCTION listGetArchivedLogCopy( al_key OUT number ,status OUT varchar2 ,fname OUT varchar2 ,completion_time OUT date) RETURN number; -- -- -- PROCEDURE listTranslateControlfileBackup( tag IN varchar2 ,completedAfter IN date ,completedBefore IN date ,statusMask IN binary_integer DEFAULT BSavailable+BSunavailable+BSexpired -- 8.0/8.1 defaults ,autobackup IN binary_integer DEFAULT BScfile_all ,liststby IN binary_integer DEFAULT NULL); PROCEDURE listGetControlfileBackup( rcvRec OUT NOCOPY rcvRec_t); -- FUNCTION listGetControlfileBackup( bskey OUT number, ckpscn OUT number, ckptime OUT date) RETURN number; PROCEDURE listTranslateSpfileBackup( completedAfter IN date ,completedBefore IN date); PROCEDURE listGetSpfileBackup( rcvRec OUT NOCOPY rcvRec_t); PROCEDURE listTranslateDataFileBackup( file# IN number ,creation_change# IN number ,tag IN varchar2 DEFAULT NULL ,completedAfter IN date DEFAULT NULL ,completedBefore IN date DEFAULT NULL ,statusMask IN binary_integer DEFAULT BSavailable+BSunavailable+BSexpired -- 8.0/8.1 defaults ,pluginSCN IN number DEFAULT 0); PROCEDURE listGetDataFileBackup( rcvRec OUT NOCOPY rcvRec_t); -- FUNCTION listGetDataFileBackup( bs_key OUT number ,backup_type OUT varchar2 ,incremental_level OUT number ,completion_time OUT date ,checkpoint_change# OUT number ,checkpoint_time OUT date) RETURN number; -- PROCEDURE translateBackupFile( bs_recid IN number ,bs_stamp IN number ,fno IN number ,bskey OUT number ,inclevel OUT number ,backup_type OUT varchar2 ,completed OUT date); -- PROCEDURE listTranslateArchivedLogBackup( thread# IN number ,sequence# IN number ,first_change# IN number ,completedAfter IN date DEFAULT NULL ,completedBefore IN date DEFAULT NULL ,statusMask IN binary_integer DEFAULT BSavailable+BSunavailable+BSexpired); -- 8.0/8.1 defaults PROCEDURE listGetArchivedLogBackup( rcvRec OUT NOCOPY rcvRec_t); -- FUNCTION listGetArchivedLogBackup( bs_key OUT number ,completion_time OUT date) RETURN number; -- PROCEDURE listTranslateArchivedLogBackup( thread# IN number DEFAULT NULL ,lowseq IN number DEFAULT NULL ,highseq IN number DEFAULT NULL ,lowscn IN number DEFAULT NULL ,highscn IN number DEFAULT NULL ,from_time IN date DEFAULT NULL ,until_time IN date DEFAULT NULL ,pattern IN varchar2 DEFAULT NULL); -- FUNCTION listGetArchivedLogBackup( bs_key OUT number ,thread# OUT number ,sequence# OUT number ,first_change# OUT number ,next_change# OUT number ,first_time OUT date ,next_time OUT date) RETURN number; -- -- -- PROCEDURE listTranslateBackupsetFiles( bs_key IN number); PROCEDURE listGetBackupsetFiles( rcvRec OUT NOCOPY rcvRec_t); -- -- -- -- PROCEDURE listTranslateProxyDataFile( file# IN number ,creation_change# IN number ,tag IN varchar2 DEFAULT NULL ,handle_pattern IN varchar2 DEFAULT NULL ,completedAfter IN date DEFAULT NULL ,completedBefore IN date DEFAULT NULL ,statusMask IN binary_integer DEFAULT BSavailable+BSunavailable+BSexpired ,liststby IN binary_integer DEFAULT NULL -- default for 8.1 ,pluginSCN IN number DEFAULT 0); PROCEDURE listGetProxyDataFile( rcvRec OUT NOCOPY rcvRec_t); -- FUNCTION listGetProxyDataFile( xdf_key OUT number ,recid OUT number ,stamp OUT number ,status OUT varchar2 ,handle OUT varchar2 ,completion_time OUT date ,checkpoint_change# OUT number ,checkpoint_time OUT date) RETURN number; -- -- -- -- -- -- -- -- PROCEDURE listTranslateProxyDFRecid( recid IN number ,stamp IN number ,xdf_key OUT number ,file# OUT number ,status OUT varchar2 ,handle OUT varchar2 ,completion_time OUT date ,checkpoint_change# OUT number ,checkpoint_time OUT date); PROCEDURE listTranslateProxyArchivedLog( thread# IN number ,sequence# IN number ,first_change# IN number ,tag IN varchar2 DEFAULT NULL ,handle_pattern IN varchar2 DEFAULT NULL ,completedAfter IN date DEFAULT NULL ,completedBefore IN date DEFAULT NULL ,statusMask IN binary_integer DEFAULT BSavailable+BSunavailable+BSexpired); PROCEDURE listGetProxyArchivedLog( rcvRec OUT NOCOPY rcvRec_t); -- -- -- PROCEDURE listTranslateDBIncarnation( db_name IN varchar2 DEFAULT NULL, all_databases IN number DEFAULT 0); FUNCTION listGetDBIncarnation( db_key OUT number ,dbinc_key OUT number ,db_name OUT varchar2 ,db_id OUT number ,current_inc OUT varchar2 ,resetlogs_change# OUT number ,resetlogs_time OUT date ,dbinc_status OUT varchar2) RETURN number; FUNCTION listGetDBIncarnation( db_key OUT number ,dbinc_key OUT number ,db_name OUT varchar2 ,db_id OUT number ,current_inc OUT varchar2 ,resetlogs_change# OUT number ,resetlogs_time OUT date) RETURN number; -- -- -- PROCEDURE listTranslateDBSite( db_name IN varchar2 DEFAULT NULL, alldbs IN binary_integer DEFAULT 1); FUNCTION listGetDBSite( db_key OUT number ,db_id OUT number ,db_name OUT varchar2 ,db_role OUT varchar2 ,db_unique_name OUT varchar2) RETURN number; -- -- -- PROCEDURE listRollbackSegTableSpace; FUNCTION listGetTableSpace( ts# OUT number ,ts_name OUT varchar2) RETURN number; FUNCTION listGetTableSpace( ts# OUT number ,ts_name OUT varchar2 ,pdbname OUT varchar2) RETURN number; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION getIncrementalScn( file# IN number ,create_scn IN number ,reset_scn IN number ,reset_time IN date ,incr_level IN number ,cumulative IN number ,sourcemask IN number DEFAULT NULL ,tag IN varchar2 DEFAULT NULL ,pluginSCN IN number DEFAULT 0) RETURN number; -- -- -- -- -- -- -- -- -- -- -- PROCEDURE getIncrementalScn( first IN boolean -- open the cursor if this is TRUE ,file# IN number ,create_scn IN number ,reset_scn IN number ,reset_time IN date ,incr_level IN number ,cumulative IN number ,rcvRec OUT NOCOPY rcvRec_t ,sourcemask IN number DEFAULT NULL ,tag IN varchar2 DEFAULT NULL ,pluginSCN IN number DEFAULT 0 ,keep IN boolean DEFAULT NULL); -- -- -- PROCEDURE findOfflineRangeCopy( offr_recid IN number ,offr_ckpscn IN number ,cf_cretime IN date ,dbinc_key IN number); PROCEDURE getOfflineRangeCopy( rcvRec OUT NOCOPY rcvRec_t); -- FUNCTION getOfflineRangeCopy RETURN varchar2; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE setComputeRecoveryActionMasks( containerMask IN number ,actionMask IN number ,allRecords IN number ,availableMask IN binary_integer ,fullBackups IN number DEFAULT NULL); -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE setComputeRecoveryActionMasks( containerMask IN number ,actionMask IN number ,allRecords IN number); -- PROCEDURE setRAflags( kindMask IN number ,allRecords IN boolean); FUNCTION computeRecoveryActions( fno IN number, -- Datafile number. crescn IN number, -- Datafile creation SCN. df_rlgscn IN number -- Datafile resetlogs SCN. Null if this is a RESTORE default null, -- command, else this is the value in the datafile -- df_rlgtime IN date -- Datafile resetlogs time. Null if df_rlgscn is default null, -- null, else value from datafile header. df_ckpscn IN number -- Datafile checkpoint SCN. Null if df_rlgscn is default null, -- null, else value from datafile header. offlscn IN number -- kccfeofs (may be null). default 0, onlscn IN number -- kccfeonc (null if offlscn is null). default 0, onltime IN date -- kccfeonc_time default null, cleanscn IN number -- kccfecps if either SOR or WCC set, else null. default 0, clean2scn IN number -- CF ckpt SCN if WCC set, infinity if SOR bit set default 0, -- else null. clean2time IN date -- cf ckpt time if WCC, SYSDATE if SOR default null, allowfuzzy IN boolean -- TRUE if can be fuzzy at until SCN/time, FALSE if default FALSE, -- not. default is FALSE. partial_rcv IN boolean -- TRUE if can do partial recovery, FALSE if not default FALSE, cf_scn IN number -- controlfile checkpoint SCN (NULL if none mounted) default NULL, cf_cretime IN date -- controlfile creation time (NULL if none mounted) default NULL, cf_offrrid IN number -- recid of oldest offline range in controlfile default NULL, -- (NULL if none mounted) allCopies IN boolean -- if TRUE, then stack all valid copies of a bu set default FALSE, df_cretime IN date -- datafile creation time default NULL, rmanCmd IN binary_integer default unknownCmd_t, foreignDbid IN number default 0, pluggedRonly IN binary_integer default 0, pluginSCN IN number default 0, pluginRlgSCN IN number default 0, pluginRlgTime IN date default NULL, creation_thread IN number default NULL, creation_size IN number default NULL, pdbId IN number default 1, pdbForeignDbid IN number default 0 ) return binary_integer; -- -- -- -- SUCCESS CONSTANT binary_integer := 0; UNAVAILABLE CONSTANT binary_integer := 1; AVAILABLE CONSTANT binary_integer := 2; RESTORABLE CONSTANT binary_integer := 3; NO_ACTION CONSTANT binary_integer := 4; -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION getRecoveryAction( action OUT NOCOPY rcvRec_t) RETURN binary_integer; -- FUNCTION getRecoveryAction( kind OUT number ,set_stamp OUT number ,set_count OUT number ,recid OUT number ,stamp OUT number ,fname OUT varchar2 ,blocksize OUT number ,blocks OUT number ,devtype OUT varchar2 ,from_scn OUT number ,to_scn OUT number ,to_time OUT date ,rlgscn OUT number ,rlgtime OUT date ,cfcretime OUT date ,dbinc_key OUT number) RETURN binary_integer; PROCEDURE printRecoveryActions; PROCEDURE trimRecoveryActions( maxActions IN number ,containerMask IN number ,actionMask IN number); -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE reportTranslateDFDel ; -- FUNCTION reportGetDFDel( file# OUT number ,filetype OUT number ,checkpoint_change# OUT number ,checkpoint_time OUT date ,resetlogs_change# OUT number ,resetlogs_time OUT date ,incremental_change# OUT number ,fuzzy_change# OUT number ,recid OUT number ,stamp OUT number ,fname OUT varchar2 ,restorable OUT number) RETURN number; -- FUNCTION reportGetDFDel( file# OUT number ,filetype OUT number ,checkpoint_change# OUT number ,checkpoint_time OUT date ,resetlogs_change# OUT number ,resetlogs_time OUT date ,incremental_change# OUT number ,fuzzy_change# OUT number ,recid OUT number ,stamp OUT number ,fname OUT varchar2 ,restorable OUT number ,key OUT number ,completion_time OUT date) RETURN number; -- -- -- FUNCTION getCloneName( fno IN number ,crescn IN number ,pluscn IN number DEFAULT 0) RETURN varchar2; -- -- -- FUNCTION wasFileOffline( fno IN number ,untilscn IN number) RETURN number; -- -- -- procedure getConfig( conf# OUT number ,name IN OUT varchar2 ,value IN OUT varchar2 ,first IN boolean); -- -- -- FUNCTION getmaxcopyno( bsstamp IN number ,bscount IN number) RETURN number; -- -- -- PROCEDURE bmrAddCorruptTable( dfnumber OUT number ,blknumber OUT number ,range OUT number ,first IN boolean); -- -- -- PROCEDURE getDfBackupHistory( backedUpDev IN varchar2 ,first IN boolean ,bhistoryRec OUT NOCOPY bhistoryRec_t ,recentbackup IN boolean DEFAULT FALSE -- get no: recent backups ,doingCmd IN varchar2 DEFAULT NULL ,keepTag IN varchar2 DEFAULT NULL ,toDest1 IN varchar2 DEFAULT NULL ,toDest2 IN varchar2 DEFAULT NULL ,toDest3 IN varchar2 DEFAULT NULL ,toDest4 IN varchar2 DEFAULT NULL); PROCEDURE getAlBackupHistory( backedUpDev IN varchar2 ,first IN boolean ,bhistoryRec OUT NOCOPY bhistoryRec_t ,doingCmd IN varchar2 DEFAULT NULL ,keepTag IN varchar2 DEFAULT NULL ,toDest1 IN varchar2 DEFAULT NULL ,toDest2 IN varchar2 DEFAULT NULL ,toDest3 IN varchar2 DEFAULT NULL ,toDest4 IN varchar2 DEFAULT NULL); PROCEDURE getBsBackupHistory( backedUpDev IN varchar2 ,first IN boolean ,set_stamp IN number DEFAULT NULL ,set_count IN number DEFAULT NULL ,bhistoryRec OUT NOCOPY bhistoryRec_t ,doingCmd IN varchar2 DEFAULT NULL ,keepTag IN varchar2 DEFAULT NULL ,toDest1 IN varchar2 DEFAULT NULL ,toDest2 IN varchar2 DEFAULT NULL ,toDest3 IN varchar2 DEFAULT NULL ,toDest4 IN varchar2 DEFAULT NULL); PROCEDURE getDcBackupHistory( backedUpDev IN varchar2 ,first IN boolean ,bhistoryRec OUT NOCOPY bhistoryRec_t ,doingCmd IN varchar2 DEFAULT NULL ,keepTag IN varchar2 DEFAULT NULL ,toDest1 IN varchar2 DEFAULT NULL ,toDest2 IN varchar2 DEFAULT NULL ,toDest3 IN varchar2 DEFAULT NULL ,toDest4 IN varchar2 DEFAULT NULL); -- PROCEDURE getBackupHistory( dfRec IN dfRec_t ,backedUpDev IN varchar2 ,nbackupsFlag IN number ,bscompletionFlag IN number ,nbackups OUT number ,bscompletion OUT date); -- PROCEDURE getBackupHistory( alRec IN alRec_t ,backedUpDev IN varchar2 ,nbackupsFlag IN number ,bscompletionFlag IN number ,nbackups OUT number ,bscompletion OUT date); PROCEDURE getBackupHistory( bpRec IN bpRec_t ,backedUpDev IN varchar2 ,nbackupsFlag IN number ,bscompletionFlag IN number ,nbackups OUT number ,bscompletion OUT date ,toDest1 IN varchar2 DEFAULT NULL ,toDest2 IN varchar2 DEFAULT NULL ,toDest3 IN varchar2 DEFAULT NULL ,toDest4 IN varchar2 DEFAULT NULL); -- -- -- FUNCTION getPackageVersion RETURN varchar2; -- -- -- FUNCTION isStatusMatch(status IN VARCHAR2, mask IN NUMBER) RETURN NUMBER; FUNCTION isDeviceTypeAllocated(deviceType IN varchar2) RETURN NUMBER; FUNCTION isBackupTypeMatch(btype IN VARCHAR2, mask IN binary_integer) RETURN NUMBER; -- -- -- PROCEDURE setRcvRecBackupAge(age IN number); -- -- -- PROCEDURE resetthisBackupAge; -- -- -- PROCEDURE getRetentionPolicy(recovery_window OUT number ,redundancy OUT number); -- -- -- -- FUNCTION listBackup(lbRecOut OUT NOCOPY lbRec_t ,firstCall IN boolean ,only_obsolete IN boolean ,redundancy IN number ,piped_call IN boolean ,lbCursor IN OUT NOCOPY lbCursor_t ,lbState IN OUT NOCOPY lbState_t ,extRlKeepSCN IN number DEFAULT NULL) RETURN boolean; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION getRestoreRangeSet(restoreRangeTab OUT restoreRangeTab_t ,opCode IN varchar2 ,db_id IN number) RETURN boolean; -- PROCEDURE setNeedObsoleteData(NeedObsoleteData IN boolean DEFAULT TRUE); -- -- -- -- -- PROCEDURE getCopyofDatafile( first IN boolean -- TRUE if this is the first time called ,itag IN varchar2 -- tag that the copy should have or NULL ,fno OUT number -- datafile number ,crescn OUT number -- creation scn of the datafile ,rlogscn OUT number -- resetlogs scn of the datafile ,rlgtime OUT date -- resetlogs time of the datafile ,recid OUT binary_integer -- recid of the latest datafilecopy ,stamp OUT binary_integer -- stamp of the latest datafilecopy ,name OUT varchar2 -- name of the datafilecopy ,otag OUT varchar2 -- tag of the datafilecopy ,status OUT varchar2 -- status of the datafilecopy ,nblocks OUT binary_integer -- number of blocks of datafilecopy ,bsz OUT binary_integer -- blocksize of the datafilecopy ,ctime OUT date -- creation time of the datafilecopy ,toscn OUT number -- checkpoint scn of the datafilecopy ,totime OUT date -- checkpoint time of the datafilecopy ,pluggedRonly OUT binary_integer -- 1 for read-only. Otherwise, 0 ,pluginSCN OUT number -- plugin scn ,pluginRlgSCN OUT number -- resetlogs when datafile was plugged ,pluginRlgTime OUT date); -- resetlog time when df was plugged -- -- -- -- PROCEDURE getCopyofDatafile( dfnumber IN number -- datafile number ,itag IN varchar2 -- tag that the copy should have or NULL ,crescn IN OUT number -- creation scn of the datafile ,rlogscn IN OUT number -- resetlogs scn of the datafile ,rlgtime IN OUT date -- resetlogs time of the datafile ,recid OUT binary_integer -- recid of the latest datafilecopy ,stamp OUT binary_integer -- stamp of the latest datafilecopy ,name OUT varchar2 -- name of the datafilecopy ,otag OUT varchar2 -- tag of the datafilecopy ,status OUT varchar2 -- status of the datafilecopy ,nblocks OUT binary_integer -- number of blocks of datafilecopy ,bsz OUT binary_integer -- blocksize of the datafilecopy ,ctime OUT date -- creation time of the datafilecopy ,toscn OUT number -- checkpoint scn of the datafilecopy ,totime OUT date -- checkpoint time of the datafilecopy ,pluggedRonly OUT binary_integer -- 1 for read-only. Otherwise, 0 ,pluginSCN IN number); -- plugin scn -- -- -- -- PROCEDURE getCopyofDatafile( dfnumber IN number -- datafile number ,itag IN varchar2 -- tag that the copy should have or NULL ,crescn IN number -- creation scn of the datafile ,rlogscn IN number -- resetlogs scn of the datafile ,rlgtime IN date -- resetlogs time of the datafile ,recid OUT binary_integer -- recid of the latest datafilecopy ,stamp OUT binary_integer -- stamp of the latest datafilecopy ,name OUT varchar2 -- name of the datafilecopy ,otag OUT varchar2 -- tag of the datafilecopy ,status OUT varchar2 -- status of the datafilecopy ,nblocks OUT binary_integer -- number of blocks of the datafilecopy ,bsz OUT binary_integer -- blocksize of the datafilecopy ,ctime OUT date -- creation time of the datafilecopy ,toscn OUT number -- checkpoint scn of the datafilecopy ,totime OUT date); -- checkpoint time of the datafilecopy -- -- -- PROCEDURE getdropOSFiles( first IN boolean ,agedFileRec OUT NOCOPY agedFileRec_t); PROCEDURE getBackedUpFiles( first IN boolean ,agedFileRec OUT NOCOPY agedFileRec_t); -- -- PROCEDURE getRedoLogDeletionPolicy( policy OUT varchar2); -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE setRedoLogDeletionPolicy( policy IN varchar2 ,alldest IN number); -- -- -- -- -- FUNCTION validateStandbyConfig( policy IN varchar2 ,alldest IN number) RETURN NUMBER; -- -- -- -- -- -- -- -- -- -- PROCEDURE getSCNForAppliedPolicy( minscn OUT number ,rlgscn OUT number); -- -- -- -- -- -- -- -- PROCEDURE getAppliedAl( first IN boolean ,agedFileRec OUT NOCOPY agedFileRec_t); -- -- -- -- -- PROCEDURE getRequiredSCN( reqscn OUT number ,rlgscn OUT number ,streams IN number DEFAULT 0 ,alldest IN number DEFAULT 0); -- -- PROCEDURE getAppliedSCN( appscn OUT number ,rlgscn OUT number ,alldest IN number); -- -- FUNCTION isTranslatedFno(fno IN number) RETURN NUMBER; -- -- FUNCTION isBsRecCacheMatch( key IN number ,deviceType IN varchar2 ,tag IN varchar2 ,status IN varchar2) RETURN NUMBER; -- PROCEDURE resetReclRecid; -- PROCEDURE setReclRecid( rectype IN binary_integer ,recid IN number); -- -- FUNCTION IsReclRecid( rectype IN binary_integer ,recid IN number) RETURN NUMBER; -- -- FUNCTION getSpaceRecl(ceilAsm IN binary_integer default 0) RETURN NUMBER; -- PROCEDURE getRestorePoint( name IN varchar2 ,rlgscn OUT number ,rlgtime OUT date ,scn OUT number ,guaranteed OUT number); -- PROCEDURE getRestorePoint( name IN varchar2 ,rlgscn OUT number ,rlgtime OUT date ,scn OUT number ,guaranteed OUT number ,con_id IN number ,clean OUT number ,out_con_id OUT number); -- PROCEDURE listTranslateRestorePoint( name IN varchar2); -- PROCEDURE listGetRestorePoint( name OUT varchar2 ,scn OUT number ,rsptime OUT date ,cretime OUT date ,rsptype OUT varchar2); PROCEDURE listGetRestorePoint( name OUT varchar2 ,scn OUT number ,rsptime OUT date ,cretime OUT date ,rsptype OUT varchar2 ,pdbname OUT varchar2); -- -- -- FUNCTION Num2DisplaySize(input_size IN NUMBER) return VARCHAR2; -- FUNCTION Sec2DisplayTime(input_secs IN NUMBER) return VARCHAR2; FUNCTION getEncryptTSCount RETURN BINARY_INTEGER; -- -- -- -- PROCEDURE setArchivedLogRecord( thread# IN number ,sequence# IN number ,first IN boolean); -- -- -- PROCEDURE setCanHandleTransportableTbs( flag IN boolean); -- -- FUNCTION getArchivedNextSCN RETURN NUMBER; -- -- FUNCTION isArchivedLogMissing(fromSCN IN NUMBER, untilSCN IN NUMBER) RETURN NUMBER; -- -- FUNCTION getNextAvailableSCN(fromScn IN NUMBER, nextAvailableSCN OUT NUMBER, isOrs IN NUMBER) RETURN BOOLEAN; -- FUNCTION findLogBreakPoint(logBreakPointScn OUT NUMBER, logBreakPointTime OUT DATE, logBreakPointDbIncKey OUT NUMBER, logBreakPointRlgScn OUT NUMBER, logBreakPointRlgTime OUT DATE, fromSCN IN NUMBER, untilSCN IN NUMBER, isOrs IN NUMBER) RETURN boolean; -- -- FUNCTION getMaxRedoSCN(maxScn OUT NUMBER, maxTime OUT DATE, maxDbIncKey OUT NUMBER, maxRlgScn OUT NUMBER, maxRlgTime OUT DATE, isOrs IN NUMBER) RETURN boolean; -- PROCEDURE setRestoreRangeDevTyp(typ IN VARCHAR2); -- PROCEDURE resetRestoreRangeDevTyp; PROCEDURE setSkipOfflineRangeAboveSCN(maxCheckpointSCN IN NUMBER); -- -- -- -- -- FUNCTION getDropSCN(dfNum IN NUMBER, creScn IN NUMBER, creTime IN DATE, plugScn IN NUMBER, foreignDbId IN NUMBER, dropScn OUT NUMBER, dropTime OUT DATE, dropDbIncKey OUT NUMBER, dropRlgScn OUT NUMBER, dropRlgTime OUT DATE) RETURN boolean; -- -- -- FUNCTION getIncarnationKey(untilSCN IN NUMBER) RETURN NUMBER; -- -- PROCEDURE setDbidTransClause(dbid IN number); -- -- FUNCTION isTranslatedDbid(dbid IN number) RETURN NUMBER; -- -- FUNCTION getMaxScn RETURN number; FUNCTION getMaxScn(logmaxnt OUT date) RETURN NUMBER; FUNCTION getActualDbinc RETURN number; -- -- -- -- -- -- PROCEDURE setStdbyCtrlScn(ctrlSCN IN NUMBER); -- -- FUNCTION translatePdbName(pdbName IN VARCHAR2) RETURN NUMBER; -- PROCEDURE resetPdbIdList; -- PROCEDURE setPdbId(pdbId IN NUMBER, first IN BOOLEAN); -- -- FUNCTION isTranslatedPdbId(pdbId IN NUMBER) RETURN NUMBER; -- -- FUNCTION isPdbScnOrphan(untilSCN IN NUMBER, pdbId IN NUMBER) RETURN NUMBER; -- -- FUNCTION setLocalOrsSiteKey(db_id IN NUMBER) RETURN boolean; -- PROCEDURE resetLocalOrsSiteKey; -- FUNCTION isNoBackupPdb(pdbname IN VARCHAR2) RETURN NUMBER; -- -- -- -- PROCEDURE listApplicationPdbs(root_con_id IN number); -- FUNCTION listGetAppPdb(pdb_name OUT varchar2) RETURN NUMBER; -- -- pragma TIMESTAMP('2000-03-12:13:51:00'); END; -- dbms_rcvman or x$dbms_rcvman >>> define dbmsrvpc_sql <<< CREATE OR REPLACE PACKAGE dbms_rcvvpc IS FUNCTION filter_pass_all ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_vpc_databases ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_db ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_dbinc ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_bp ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_bsf ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_bs ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_conf ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_deleted_object ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_do_seq ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_node ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_pdb ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_rout ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_watermarks ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_sbt_template_db ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_pdbinc ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_pdb_dbinc ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_al ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_bcf ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_bdf ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_brl ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_ccf ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_cdf ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_ckp ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_df ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_fb ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_grsp ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_nrsp ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_offr ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_orl ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_rlh ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_rr ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_rsr ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_rt ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_tf ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_tsatt ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_ts ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_xal ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_xcf ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_xdf ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_scr ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_rrcache ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_bcb ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_ccb ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_scrl ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_cfs ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_config ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_orsevent ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_rcfile ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_xmlstore ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_bcr ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_server ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_vpc_users ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_site_dfatt ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION f_site_tfatt ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2; END dbms_rcvvpc; >>> define dbmsunsetvpc_sql <<< DECLARE e_policy_notexists EXCEPTION; PRAGMA EXCEPTION_INIT(e_policy_notexists, -28102); e_insufficient_privs EXCEPTION; PRAGMA EXCEPTION_INIT(e_insufficient_privs, -6550); BEGIN FOR i IN ( SELECT object_name , policy_name FROM user_policies ) LOOP BEGIN EXECUTE IMMEDIATE ' BEGIN dbms_rls.drop_policy ( object_name => :1 , policy_name => :2 ); END;' USING i.object_name , i.policy_name; EXCEPTION WHEN e_policy_notexists THEN NULL; WHEN e_insufficient_privs THEN RAISE_APPLICATION_ERROR ( -20153 , ' Unable to drop the VPD protection policies!' || CHR(10) || CHR(13) || 'This recovery catalog does not have VPD support enabled!' || ' Exit this RMAN session.' || CHR(10) || CHR(13) || 'Execute ''?/rdbms/admin/dbmsrmanvpc.sql -vpd ' || USER || '''' || ' after connecting' || CHR(10) || CHR(13) || 'to a catalog database as SYS. Then perform the UPGRADE catalog.' ); END; END LOOP; END; >>> define dbmsrman2_sql <<< -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION isInFailureList( parentId IN number ,failureId IN number ,for_exclude IN binary_integer ) RETURN NUMBER; -- -- -- -- -- -- -- -- -- -- -- PROCEDURE createFailureList( first_call IN boolean ,failureId IN number ,for_exclude IN boolean); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE translateFailure( critical IN binary_integer ,high IN binary_integer ,low IN binary_integer ,unknown IN binary_integer default 0 ,closed IN binary_integer ,adviseId IN number); -- -- -- -- -- -- -- -- -- PROCEDURE getFailure( failureRec OUT NOCOPY failureRec_t); -- -- -- -- -- -- -- -- PROCEDURE translateRepair( adviseid IN number); -- -- -- -- -- -- -- -- -- PROCEDURE getRepair( repairRec OUT NOCOPY repairRec_t); -- -- -- -- -- -- -- -- PROCEDURE translateRepairParms( adviseid IN number); -- -- -- -- -- -- -- -- -- -- PROCEDURE getRepairParms( repairParmsRec OUT NOCOPY repairParmsRec_t); -- -- -- -- -- -- -- -- PROCEDURE translateRepairOption( adviseid IN number); -- -- -- -- -- -- -- -- -- -- PROCEDURE getRepairOption( repairOptionRec OUT NOCOPY repairOptionRec_t); -- -- -- -- -- -- -- -- PROCEDURE translateRepairStep( optionidx IN number); -- -- -- -- -- -- -- -- -- -- PROCEDURE getRepairStep( repairStepRec OUT NOCOPY repairStepRec_t); -- -- -- -- -- -- -- -- PROCEDURE translateManualRepair( adviseId IN number); -- -- -- -- -- -- -- -- -- -- FUNCTION getManualRepair( mandatory OUT varchar2) RETURN varchar2; -- -- -- -- -- -- -- -- -- -- FUNCTION getRepairScriptName( repairId IN number, description OUT varchar2) RETURN varchar2; pragma TIMESTAMP('2000-03-12:13:51:00'); END; -- dbms_rcvman or x$dbms_rcvman -- >>> define dbmsrman3_sql <<< -- @@?/rdbms/admin/dbmsrmansys.sql drop public synonym v$backup_files; drop view v_$backup_files; drop function v_listBackupPipe; drop type v_lbRecSetImpl_t; drop type v_lbRecSet_t; drop type v_lbRec_t; -- -- -- -- create type v_lbRec_t as object ( list_order1 NUMBER, list_order2 NUMBER, pkey NUMBER, backup_type VARCHAR2(32), file_type VARCHAR2(32), keep VARCHAR2(3), keep_until DATE, keep_options VARCHAR2(13), status VARCHAR2(16), fname VARCHAR2(1024), tag VARCHAR2(32), media VARCHAR2(80), recid NUMBER, stamp NUMBER, device_type VARCHAR2(255), block_size NUMBER, completion_time DATE, is_rdf VARCHAR2(3), compressed VARCHAR2(3), obsolete VARCHAR2(3), bytes NUMBER, bs_key NUMBER, bs_count NUMBER, bs_stamp NUMBER, bs_type VARCHAR2(32), bs_incr_type VARCHAR2(32), bs_pieces NUMBER, bs_copies NUMBER, bs_completion_time DATE, bs_status VARCHAR2(16), bs_bytes NUMBER, bs_compressed VARCHAR2(3), bs_tag VARCHAR2(1024), bs_device_type VARCHAR2(255), bp_piece# NUMBER, bp_copy# NUMBER, df_file# NUMBER, df_ts# NUMBER, df_plugin_change# NUMBER, df_foreign_dbid NUMBER, df_tablespace VARCHAR2(30), df_resetlogs_change# NUMBER, df_creation_change# NUMBER, df_checkpoint_change# NUMBER, df_ckp_mod_time DATE, df_incremental_change# NUMBER, rl_thread# NUMBER, rl_sequence# NUMBER, rl_resetlogs_change# NUMBER, rl_first_change# NUMBER, rl_first_time DATE, rl_next_change# NUMBER, rl_next_time DATE, con_id NUMBER ); / create type v_lbRecSet_t as table of v_lbRec_t; / create type v_lbRecSetImpl_t as object ( curval number, -- current rownum done number, -- done with the query needobsolete number, -- user requested obsolete column static function ODCITablePrepare(sctx OUT v_lbRecSetImpl_t, ti IN SYS.ODCITabFuncInfo) return number, static function ODCITableStart(sctx IN OUT v_lbRecSetImpl_t) return number, member function ODCITableFetch(self IN OUT v_lbRecSetImpl_t, nrows IN number, objSet OUT v_lbRecSet_t) return number, member function ODCITableClose(self IN v_lbRecSetImpl_t) return number ); / create or replace type body v_lbRecSetImpl_t is static function ODCITablePrepare(sctx OUT v_lbRecSetImpl_t, ti IN SYS.ODCITabFuncInfo) return number is begin -- sctx:=v_lbRecSetImpl_t(0, 0, 0); -- -- for i in ti.Attrs.first .. ti.Attrs.last loop if (ti.Attrs(i) = 20) then sctx.needobsolete := 1; exit; end if; end loop; return SYS.ODCIConst.Success; end ODCITablePrepare; static function ODCITableStart(sctx IN OUT v_lbRecSetImpl_t) return number is begin return SYS.ODCIConst.Success; end ODCITableStart; -- -- -- -- member function ODCITableFetch(self IN OUT v_lbRecSetImpl_t, nrows IN number, objSet OUT v_lbRecSet_t) return number is n number := 0; firstCall boolean := TRUE; ret boolean := TRUE; redundancy number; recovery_window number; untilTime date; lbRec sys.dbms_rcvman.lbrec_t; lbCursor sys.dbms_rcvman.lbCursor_t; lbState sys.dbms_rcvman.lbState_t; begin objSet:=v_lbRecSet_t(); -- sys.dbms_rcvman.resetAll; -- sys.dbms_rcvman.setDatabase(NULL, NULL, NULL, NULL); redundancy := 1; recovery_window := 0; -- -- -- sys.dbms_rcvman.getRetentionPolicy(recovery_window, redundancy); -- sys.dbms_rcvman.setAllIncarnations(TRUE); -- if (recovery_window > 0) then select (sysdate-recovery_window) into untilTime from dual; sys.dbms_rcvman.setUntilTime(untilTime); end if; sys.dbms_rcvman.setDeviceTypeAny; if (recovery_window = 0 and redundancy = 0) then -- sys.dbms_rcvman.setNeedObsoleteData(false); else if self.needobsolete = 1 then sys.dbms_rcvman.setNeedObsoleteData(true); else sys.dbms_rcvman.setNeedObsoleteData(false); end if; end if; while ret and self.done = 0 loop ret := sys.dbms_rcvman.listBackup(lbRec, firstCall, FALSE, redundancy, TRUE, lbCursor, lbState, null); if (lbRec.pkey is not null) then objSet.extend; n := n + 1; objSet(n):= v_lbRec_t( to_number(null), -- list_order1 to_number(null), -- list_order2 to_number(null), -- pkey to_char(null), -- backup_type to_char(null), -- file_type to_char(null), -- keep to_date(null), -- keep_until to_char(null), -- keep_options to_char(null), -- status to_char(null), -- fname to_char(null), -- tag to_char(null), -- media to_number(null), -- recid to_number(null), -- stamp to_char(null), -- device_type to_number(null), -- block_size to_date(null), -- completion_time to_char(null), -- is_rdf to_char(null), -- compressed to_char(null), -- obsolete to_number(null), -- bytes to_number(null), -- bs_key to_number(null), -- bs_count to_number(null), -- bs_stamp to_char(null), -- bs_type to_char(null), -- bs_incr_type to_number(null), -- bs_pieces to_number(null), -- bs_copies to_date(null), -- bs_completion_time to_char(null), -- bs_status to_number(null), -- bs_bytes to_char(null), -- bs_compressed to_char(null), -- bs_tag to_char(null), -- bs_device_type to_number(null), -- bp_piece# to_number(null), -- bp_copy# to_number(null), -- df_file# to_number(null), -- df_ts# to_number(null), -- df_plugin_change# to_number(null), -- df_foreign_dbid to_char(null), -- df_tablespace to_number(null), -- df_resetlogs_change# to_number(null), -- df_creation_change# to_number(null), -- df_checkpoint_change# to_date(null), -- df_ckp_mod_time to_number(null), -- df_incremental_change# to_number(null), -- rl_thread# to_number(null), -- rl_sequence# to_number(null), -- rl_resetlogs_change# to_number(null), -- rl_first_change# to_date(null), -- rl_first_time to_number(null), -- rl_next_change# to_date(null), -- rl_next_time to_number(null)); -- con_id objSet(n).list_order1 := lbRec.list_order1; objSet(n).list_order2 := lbRec.list_order2; objSet(n).pkey := lbRec.pkey; objSet(n).backup_type := lbRec.backup_type; objSet(n).file_type := lbRec.file_type; objSet(n).keep := lbRec.keep; objSet(n).keep_until := lbRec.keep_until; objSet(n).keep_options := lbRec.keep_options; objSet(n).status := lbRec.status; objSet(n).fname := lbRec.fname; objSet(n).tag := lbRec.tag; objSet(n).media := lbRec.media; objSet(n).recid := lbRec.stamp; objSet(n).stamp := lbRec.stamp; objSet(n).device_type := lbRec.device_type; objSet(n).block_size := lbRec.block_size; objSet(n).completion_time := lbRec.completion_time; objSet(n).is_rdf := lbRec.is_rdf; objSet(n).compressed := lbRec.compressed; objSet(n).obsolete := lbRec.obsolete; objSet(n).bytes := lbRec.bytes; objSet(n).bs_key := lbRec.bs_key; objSet(n).bs_count := lbRec.bs_count; objSet(n).bs_stamp := lbRec.bs_stamp; objSet(n).bs_type := lbRec.bs_type; objSet(n).bs_incr_type := lbRec.bs_incr_type; objSet(n).bs_pieces := lbRec.bs_pieces; objSet(n).bs_copies := lbRec.bs_copies; objSet(n).bs_completion_time := lbRec.bs_completion_time; objSet(n).bs_status := lbRec.bs_status; objSet(n).bs_bytes := lbRec.bs_bytes; objSet(n).bs_compressed := lbRec.bs_compressed; objSet(n).bs_tag := lbRec.bs_tag; objSet(n).bs_device_type := lbRec.bs_device_type; objSet(n).bp_piece# := lbRec.bp_piece#; objSet(n).bp_copy# := lbRec.bp_copy#; objSet(n).df_file# := lbRec.df_file#; objSet(n).df_ts# := lbRec.df_ts#; objSet(n).df_plugin_change# := lbRec.df_plugin_change#; objSet(n).df_foreign_dbid := lbRec.df_foreign_dbid; objSet(n).df_tablespace := lbRec.df_tablespace; objSet(n).df_resetlogs_change# := lbRec.df_resetlogs_change#; objSet(n).df_creation_change# := lbRec.df_creation_change#; objSet(n).df_checkpoint_change# := lbRec.df_checkpoint_change#; objSet(n).df_ckp_mod_time := lbRec.df_ckp_mod_time; objSet(n).df_incremental_change# := lbRec.df_incremental_change#; objSet(n).rl_thread# := lbRec.rl_thread#; objSet(n).rl_sequence# := lbRec.rl_sequence#; objSet(n).rl_resetlogs_change# := lbRec.rl_resetlogs_change#; objSet(n).rl_first_change# := lbRec.rl_first_change#; objSet(n).rl_first_time := lbRec.rl_first_time; objSet(n).rl_next_change# := lbRec.rl_next_change#; objSet(n).rl_next_time := lbRec.rl_next_time; objSet(n).con_id := lbRec.con_id; end if; firstCall := false; self.curval:=self.curval+1; if not ret then self.done := 1; end if; end loop; return SYS.ODCIConst.Success; end ODCITableFetch; member function ODCITableClose(self IN v_lbRecSetImpl_t) return number is begin return SYS.ODCIConst.Success; end ODCITableClose; end; / CREATE OR REPLACE FUNCTION v_listBackupPipe RETURN v_lbRecSet_t PIPELINED using v_lbRecSetImpl_t; / -- -- -- -- -- -- -- -- -- create or replace view v_$backup_files as select pkey, backup_type, file_type, keep, keep_until, keep_options, status, fname, tag, media, recid, stamp, device_type, block_size, completion_time, compressed, obsolete, bytes, bs_key, bs_count, bs_stamp, bs_type, bs_incr_type, bs_pieces, bs_copies, bs_completion_time, bs_status, bs_bytes, bs_compressed, bs_tag, bs_device_type, bp_piece#, bp_copy#, df_file#, df_tablespace, df_resetlogs_change#, df_creation_change#, df_checkpoint_change#, df_ckp_mod_time, rl_thread#, rl_sequence#, rl_resetlogs_change#, rl_first_change#, rl_first_time, rl_next_change#, rl_next_time, con_id from table(v_listBackupPipe); create or replace public synonym v$backup_files for v_$backup_files; / grant select on v_$backup_files to select_catalog_role; drop public synonym v$restore_range; drop view v_$restore_range; drop public synonym v$disk_restore_range; drop view v_$disk_restore_range; drop public synonym v$sbt_restore_range; drop view v_$sbt_restore_range; drop function v_listRsRangePipe; drop type v_RangeRecSetImpl_t; drop type v_RangeRecSet_t; drop type v_RangeRec_t; create type v_RangeRec_t as object ( db_id NUMBER, high_time DATE, low_time DATE, low_change# NUMBER, high_change# NUMBER, low_resetlogs_change# NUMBER, high_resetlogs_change# NUMBER, low_resetlogs_time DATE, high_resetlogs_time DATE, con_id NUMBER ); / create type v_RangeRecSet_t as table of v_RangeRec_t; / create type v_RangeRecSetImpl_t as object ( curval number, -- current rownum done number, -- done with the query opCode varchar2(10), static function ODCITableStart(sctx IN OUT v_RangeRecSetImpl_t, opCode IN varchar2) return number, member function ODCITableFetch(self IN OUT v_RangeRecSetImpl_t, nrows IN number, objSet OUT v_RangeRecSet_t) return number, member function ODCITableClose(self IN v_RangeRecSetImpl_t) return number ); / create or replace type body v_RangeRecSetImpl_t is static function ODCITableStart(sctx IN OUT v_RangeRecSetImpl_t, opCode IN varchar2) return number is begin -- sctx:=v_RangeRecSetImpl_t(0, 0, opCode); return SYS.ODCIConst.Success; end ODCITableStart; member function ODCITableFetch(self IN OUT v_RangeRecSetImpl_t, nrows IN number, objSet OUT v_RangeRecSet_t) return number is n number := 0; i number; indx number := 0; dbcount number; ret boolean; restoreRangeTab sys.dbms_rcvman.restoreRangeTab_t; CURSOR getAllDb_c IS SELECT dbid FROM v$database; dbDetail getAllDb_c%rowtype; begin open getAllDb_c; objSet := v_RangeRecSet_t(); select count(*) into dbcount from v$database; while n < dbcount and self.done = 0 loop n := n + 1; sys.dbms_rcvman.resetAll; sys.dbms_rcvman.resetDeviceType; sys.dbms_rcvman.setAllIncarnations(TRUE); if (opCode = 'V$ANY') then sys.dbms_rcvman.setDeviceTypeAny; elsif (opCode = 'V$DISK') then sys.dbms_rcvman.setDeviceType('DISK'); elsif (opCode = 'V$SBT') then sys.dbms_rcvman.setDeviceType('SBT_TAPE'); end if; fetch getAllDb_c into dbDetail; sys.dbms_rcvman.setdatabase(NULL, NULL, NULL, dbDetail.dbid); ret := sys.dbms_rcvman.getRestoreRangeSet(restoreRangeTab, opCode, dbDetail.dbid); i := to_number(null); LOOP IF (i is null) THEN i := restoreRangeTab.first; ELSE i := restoreRangeTab.next(i); END IF; EXIT WHEN i IS NULL; if (restoreRangeTab(i).isValidRange = TRUE) then objSet.extend; indx := indx + 1; objSet(indx) := v_RangeRec_t( to_number(null), to_date(null), to_date(null), to_number(null), to_number(null), to_number(null), to_number(null), to_date(null), to_date(null), to_number(null)); if (ret = TRUE) then objSet(indx).db_id := dbDetail.dbid; objSet(indx).low_time := restoreRangeTab(i).lowTime; objSet(indx).high_time := restoreRangeTab(i).highTime; objSet(indx).low_change# := restoreRangeTab(i).lowScn; objSet(indx).high_change# := restoreRangeTab(i).highScn; objSet(indx).low_resetlogs_change# := restoreRangeTab(i).lowRlgScn; objSet(indx).high_resetlogs_change# := restoreRangeTab(i).highRlgScn; objSet(indx).low_resetlogs_time := restoreRangeTab(i).lowRlgTime; objSet(indx).high_resetlogs_time := restoreRangeTab(i).highRlgTime; objSet(indx).con_id := restoreRangeTab(i).con_id; end if; end if; END LOOP; self.curval := self.curval + 1; if (self.curval = dbcount) then self.done := 1; close getAllDb_c; end if; end loop; return SYS.ODCIConst.Success; end ODCITableFetch; member function ODCITableClose(self IN v_RangeRecSetImpl_t) return number is begin return SYS.ODCIConst.Success; end ODCITableClose; end; / CREATE OR REPLACE FUNCTION v_listRsRangePipe (opCode IN varchar2) RETURN v_RangeRecSet_t PIPELINED using v_RangeRecSetImpl_t; / create or replace view v_$restore_range as select db_id, low_time, high_time, low_change#, high_change#, low_resetlogs_change#, high_resetlogs_change#, low_resetlogs_time, high_resetlogs_time, con_id from TABLE(v_listRsRangePipe('V$ANY')); / create or replace public synonym v$restore_range for v_$restore_range; / create or replace view v_$disk_restore_range as select db_id, low_time, high_time, low_change#, high_change#, low_resetlogs_change#, high_resetlogs_change#, low_resetlogs_time, high_resetlogs_time, con_id from TABLE(v_listRsRangePipe('V$DISK')); / create or replace public synonym v$disk_restore_range for v_$disk_restore_range; / create or replace view v_$sbt_restore_range as select db_id, low_time, high_time, low_change#, high_change#, low_resetlogs_change#, high_resetlogs_change#, low_resetlogs_time, high_resetlogs_time, con_id from TABLE(v_listRsRangePipe('V$SBT')); / create or replace public synonym v$sbt_restore_range for v_$sbt_restore_range; / grant select on v_$restore_range to select_catalog_role; grant select on v_$disk_restore_range to select_catalog_role; grant select on v_$sbt_restore_range to select_catalog_role; create or replace view v_$rman_backup_subjob_details as select * from v$rman_backup_subjob_details; create or replace public synonym v$rman_backup_subjob_details for v_$rman_backup_subjob_details; grant select on v_$rman_backup_subjob_details to select_catalog_role; create or replace view v_$rman_backup_job_details as select * from v$rman_backup_job_details; create or replace public synonym v$rman_backup_job_details for v_$rman_backup_job_details; grant select on v_$rman_backup_job_details to select_catalog_role; create or replace view v_$backup_set_details as select * from v$backup_set_details; create or replace public synonym v$backup_set_details for v_$backup_set_details; grant select on v_$backup_set_details to select_catalog_role; create or replace view v_$backup_piece_details as select * from v$backup_piece_details; create or replace public synonym v$backup_piece_details for v_$backup_piece_details; grant select on v_$backup_piece_details to select_catalog_role; create or replace view v_$backup_copy_details as select * from v$backup_copy_details; create or replace public synonym v$backup_copy_details for v_$backup_copy_details; grant select on v_$backup_copy_details to select_catalog_role; create or replace view v_$proxy_copy_details as select * from v$proxy_copy_details; create or replace public synonym v$proxy_copy_details for v_$proxy_copy_details; grant select on v_$proxy_copy_details to select_catalog_role; create or replace view v_$proxy_archivelog_details as select * from v$proxy_archivelog_details; create or replace public synonym v$proxy_archivelog_details for v_$proxy_archivelog_details; grant select on v_$proxy_archivelog_details to select_catalog_role; create or replace view v_$backup_datafile_details as select * from v$backup_datafile_details; create or replace public synonym v$backup_datafile_details for v_$backup_datafile_details; grant select on v_$backup_datafile_details to select_catalog_role; create or replace view v_$backup_controlfile_details as select * from v$backup_controlfile_details; create or replace public synonym v$backup_controlfile_details for v_$backup_controlfile_details; grant select on v_$backup_controlfile_details to select_catalog_role; create or replace view v_$backup_archivelog_details as select * from v$backup_archivelog_details; create or replace public synonym v$backup_archivelog_details for v_$backup_archivelog_details; grant select on v_$backup_archivelog_details to select_catalog_role; create or replace view v_$backup_spfile_details as select * from v$backup_spfile_details; create or replace public synonym v$backup_spfile_details for v_$backup_spfile_details; grant select on v_$backup_spfile_details to select_catalog_role; create or replace view v_$backup_set_summary as select * from v$backup_set_summary; create or replace public synonym v$backup_set_summary for v_$backup_set_summary; grant select on v_$backup_set_summary to select_catalog_role; create or replace view v_$backup_datafile_summary as select * from v$backup_datafile_summary; create or replace public synonym v$backup_datafile_summary for v_$backup_datafile_summary; grant select on v_$backup_datafile_summary to select_catalog_role; create or replace view v_$backup_controlfile_summary as select * from v$backup_controlfile_summary; create or replace public synonym v$backup_controlfile_summary for v_$backup_controlfile_summary; grant select on v_$backup_controlfile_summary to select_catalog_role; create or replace view v_$backup_archivelog_summary as select * from v$backup_archivelog_summary; create or replace public synonym v$backup_archivelog_summary for v_$backup_archivelog_summary; grant select on v_$backup_archivelog_summary to select_catalog_role; create or replace view v_$backup_spfile_summary as select * from v$backup_spfile_summary; create or replace public synonym v$backup_spfile_summary for v_$backup_spfile_summary; grant select on v_$backup_spfile_summary to select_catalog_role; create or replace view v_$backup_copy_summary as select * from v$backup_copy_summary; create or replace public synonym v$backup_copy_summary for v_$backup_copy_summary; grant select on v_$backup_copy_summary to select_catalog_role; create or replace view v_$proxy_copy_summary as select * from v$proxy_copy_summary; create or replace public synonym v$proxy_copy_summary for v_$proxy_copy_summary; grant select on v_$proxy_copy_summary to select_catalog_role; create or replace view v_$proxy_archivelog_summary as select * from v$proxy_archivelog_summary; create or replace public synonym v$proxy_archivelog_summary for v_$proxy_archivelog_summary; grant select on v_$proxy_archivelog_summary to select_catalog_role; create or replace view v_$unusable_backupfile_details as select * from v$unusable_backupfile_details; create or replace public synonym v$unusable_backupfile_details for v_$unusable_backupfile_details; grant select on v_$unusable_backupfile_details to select_catalog_role; create or replace view v_$rman_backup_type as select * from v$rman_backup_type; create or replace public synonym v$rman_backup_type for v_$rman_backup_type; grant select on v_$rman_backup_type to select_catalog_role; create or replace view v_$rman_encryption_algorithms as select * from v$rman_encryption_algorithms; create or replace public synonym v$rman_encryption_algorithms for v_$rman_encryption_algorithms; grant select on v_$rman_encryption_algorithms to select_catalog_role; -- >>> define rcver <<< CREATE TABLE rcver ( version varchar2(12) NOT NULL, constraint rcver_version_unique unique(version) ) &tablespace& >>> define raschemaver <<< CREATE TABLE raschemaver ( version number, CONSTRAINT raschemaver_p PRIMARY KEY (version), CONSTRAINT check_version CHECK (version >= 0 and version < 100) ) ORGANIZATION INDEX &tablespace& >>> define enable_plsql_warn <<< begin dbms_warning.set_warning_setting_string('enable:all', 'session'); dbms_warning.add_warning_setting_cat('performance','disable', 'session'); end; >>> define disable_plsql_warn <<< begin dbms_warning.set_warning_setting_string('disable:all', 'session'); end; >>> define disable_plsql_warn_5005_5021 <<< begin dbms_warning.add_warning_setting_num(5005, 'disable', 'session'); dbms_warning.add_warning_setting_num(5021, 'disable', 'session'); end; >>> define disable_plsql_warn_5004_6002 <<< begin dbms_warning.add_warning_setting_num(5004, 'disable', 'session'); dbms_warning.add_warning_setting_num(6002, 'disable', 'session'); end; >>> define disable_plsql_warn_5018_6010 <<< begin dbms_warning.add_warning_setting_num(5018, 'disable', 'session'); dbms_warning.add_warning_setting_num(6010, 'disable', 'session'); end; >>> define disable_plsql_warn_6006_6010 <<< begin dbms_warning.add_warning_setting_num(6006, 'disable', 'session'); dbms_warning.add_warning_setting_num(6010, 'disable', 'session'); end; >>> define disable_plsql_warn_6009 <<< begin dbms_warning.add_warning_setting_num(6009, 'disable', 'session'); end; >>> define create_sbt_template_db <<< create table sbt_template_db ( db_key number not null, template_key number not null, baseline_scn number, last_bp_key number, -- last bp_key queued so we can avoid -- curr_dbinc_key number, constraint sbt_template_db_p1 primary key (db_key, template_key) ) &tablespace& >>> define rcver_update <<< begin delete from rcver; insert into rcver values('12.02.00.01'); commit; end; >>> define raschemaver_update <<< begin delete from raschemaver; insert into raschemaver values (1); commit; end; >>> define set_reg_dbunqnm <<< declare cursor db_c is select reg_db_unique_name, db_key from db where reg_db_unique_name is null for update; l_reg_dbunqnm node.db_unique_name%TYPE; begin for dbrec in db_c loop select max(db_unique_name) into l_reg_dbunqnm from (select db_unique_name from node where dbrec.db_key = node.db_key and db_unique_name not like '%$%' order by database_role, db_unique_name) where rownum = 1; update db set reg_db_unique_name = l_reg_dbunqnm where current of db_c; end loop; commit; end; >>> define prvtrvct_plb <<< CREATE OR replace PACKAGE BODY dbms_rcvcat IS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- type version_list_type is table of varchar2(14) index by binary_integer; version_list version_list_type; version_max_index binary_integer; version_counter binary_integer := 1; /*-----------* * Constants * *-----------*/ MAXNUMVAL CONSTANT NUMBER := 2**32-1; catalogVersion CONSTANT VARCHAR2(11) := '12.02.00.01'; ZERO_GUID CONSTANT RAW(16) := HEXTORAW(RPAD('0', 32, '0')); /*-------------------------* * Package State Variables * *-------------------------*/ -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- debug BOOLEAN := FALSE; this_ckp_key NUMBER := NULL; this_ckp_scn NUMBER := NULL; this_ckp_time DATE := NULL; this_lib_key NUMBER := NULL; last_full_ckp_scn NUMBER := NULL; last_guid PDB.GUID%TYPE := NULL; last_con_id_ts# NUMBER; last_ts# NUMBER; last_file# NUMBER; last_thread# NUMBER; last_fname site_dfatt.fname%type; last_pdb_recid NUMBER; last_pic_recid NUMBER; last_ts_recid NUMBER; last_df_recid NUMBER; last_tf_recid NUMBER; last_rt_recid NUMBER; last_orl_recid NUMBER; last_conf_recid NUMBER; force_resync2cf VARCHAR2(3) := 'NO'; last_rlh_recid NUMBER; last_al_recid NUMBER; last_offr_recid NUMBER; last_bs_recid NUMBER; last_bp_recid NUMBER; last_bdf_recid NUMBER; last_bsf_recid NUMBER; last_brl_recid NUMBER; last_cdf_recid NUMBER; last_bcb_recid NUMBER; last_ccb_recid NUMBER; last_do_recid NUMBER; last_xdf_recid NUMBER := NULL; last_xal_recid NUMBER := NULL; last_rsr_recid NUMBER; last_rout_stamp NUMBER := NULL; last_inst_startup_stamp NUMBER := NULL; lrsr_key NUMBER; lrout_skey NUMBER; lsession_recid NUMBER; lsession_stamp NUMBER; lrman_status_recid NUMBER; lrman_status_stamp NUMBER; -- krbmror_llength_bytes NUMBER := 130; -- -- type rout_list is table of rout%ROWTYPE index by binary_integer; lrout_table rout_list; lrout_curridx binary_integer := 0; -- -- last_ic_recid NUMBER := NULL; scr_key NUMBER := NULL; scr_line NUMBER; scr_glob BOOLEAN; kccdivts NUMBER; type bskeys_v is table of number index by varchar2(128); duplicatebs bskeys_v; type bskeys is table of number index by binary_integer; cntbs NUMBER := 0; updatebs bskeys; last_reset_scn NUMBER; last_reset_time DATE; last_dbinc_key NUMBER; do_temp_ts_resync BOOLEAN := FALSE; -- indicates if temp_ts is resynced last_cf_version_time DATE; dbglvl NUMBER := RCVCAT_LEVEL_DEFAULT; low_nrsp_recid NUMBER; last_nrsp_recid NUMBER; last_grsp_recid NUMBER; last_rspname grsp.rspname%type; last_pdb_key NUMBER; last_bcr_recid NUMBER; last_resync_cksum NUMBER; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- this_cf_type VARCHAR2(7) := NULL; this_cf_version DATE := NULL; this_ckp_type VARCHAR2(10) := NULL; -- this_db_unique_name node.db_unique_name%TYPE; this_site_key NUMBER; -- Never NULL even for 9i RMAN client client_site_aware boolean := FALSE; -- logs_shared number := FALSE#; -- used only when client_site_aware disk_backups_shared number := TRUE#; -- indicates shared accross all sites tape_backups_shared number := TRUE#; -- indicates shared accross all sites -- session_keep_output number := NULL; rman_keep_output number := NULL; reNorm_state binary_integer; RENORM_DFATT CONSTANT binary_integer := 1; RENORM_ORL CONSTANT binary_integer := 2; RENORM_AL CONSTANT binary_integer := 3; RENORM_BP CONSTANT binary_integer := 4; RENORM_CCF CONSTANT binary_integer := 5; RENORM_CDF CONSTANT binary_integer := 6; RENORM_TFATT CONSTANT binary_integer := 7; -- -- -- -- -- -- type sessionWaterMarks_t is record ( last_kccdivts number := 0, -- check if ctl version is diff high_rout_stamp number := 0, -- for rman_output resync high_ic_recid number := 0, -- incarnation recid high_offr_recid number := 0, -- offline range (kkor) recid high_rlh_recid number := 0, -- log history (kcclh) recid high_al_recid number := 0, -- archived log (kccal) recid high_bs_recid number := 0, -- backup set (kccbs) recid high_bp_recid number := 0, -- backup piece (kccbp) recid high_bdf_recid number := 0, -- backup datafile (kccbf) recid high_cdf_recid number := 0, -- datafile copy (kccdc) recid high_brl_recid number := 0, -- backup redo log (kccbl) recid high_bcb_recid number := 0, -- backup datafile corruption recid high_ccb_recid number := 0, -- datafile copy corruption recid high_do_recid number := 0, -- deleted object recid high_pc_recid number := 0, -- proxy copy (kccpc) recid high_bsf_recid number := 0, -- backup SPFILE (kccbi) recid high_rsr_recid number := 0, -- RMAN status (kccrsr) recid high_nrsp_recid number := 0, -- normal restore point recid high_bcr_recid number := 0, -- high blk crpt (kccblkcor) recid high_pic_recid number := 0 -- high pdbinc recid ); init_sessionWaterMarks sessionWaterMarks_t; prev_sessionWaterMarks sessionWaterMarks_t; sessionWaterMarks sessionWaterMarks_t; -- type ts_name_list is table of ts.ts_name%type index by binary_integer; type numTab_t is table of number index by binary_integer; type key_columns_list is table of varchar2(30); type sp_columns_list is table of varchar2(1); -- -- -- import_dbid numTab_t; -- -- -- -- -- -- -- -- key_columns CONSTANT key_columns_list := key_columns_list ('DB_KEY' , 'DBINC_KEY' , 'CURR_DBINC_KEY' , 'PARENT_DBINC_KEY', 'CKP_KEY' , 'START_CKP_KEY' , 'END_CKP_KEY' , 'OFFR_KEY' , 'RR_KEY' , 'RLH_KEY' , 'AL_KEY' , 'BS_KEY' , 'BP_KEY' , 'BCF_KEY' , 'CCF_KEY' , 'XCF_KEY' , 'BSF_KEY' , 'BDF_KEY' , 'CDF_KEY' , 'XDF_KEY' , 'XAL_KEY' , 'BRL_KEY' , 'BDF_KEY' , 'RSR_KEY' , 'RSR_PKEY' , 'RSR_L0KEY' , 'SCR_KEY' , 'ROUT_SKEY' , 'SITE_KEY' , 'DF_KEY' , 'TF_KEY' , 'PDB_KEY' , 'LIB_KEY' , 'VB_KEY' , 'CT_KEY' , 'PDBINC_KEY' , 'CURR_PDBINC_KEY' , 'BORN_DBINC_KEY' , 'PARENT_PDBINC_KEY' , 'TS_PDBINC_KEY' , 'TEMPLATE_KEY'); -- -- import_dblink tempres.name%type; import_offset number; /*---------------------------------------------------* * package variables used for recovery server * *---------------------------------------------------*/ this_is_ors BOOLEAN := FALSE; this_is_ors_admin BOOLEAN := FALSE; orsadmin_user ALL_USERS.USERNAME%TYPE := NULL; this_server SERVER%ROWTYPE; this_amazon_server BOOLEAN := FALSE; this_server_uname VARCHAR2(512):= NULL; this_server_passw VARCHAR2(512):= NULL; this_server_url VARCHAR2(512):= NULL; this_xml_signature_beg VARCHAR2(50) := ' '; this_xml_signature_end VARCHAR2(50) := ' '; this_forwatermarks VARCHAR2(50) := 'forwatermarks_'; this_watermarks VARCHAR2(50) := 'watermarks_'; this_backupsets VARCHAR2(50) := 'backupsets_'; this_database VARCHAR2(50) := 'database_'; this_url_db_unique_name node.db_unique_name%TYPE; this_lock_ors_inspect BOOLEAN := FALSE; this_clr_ba_newinc_err BOOLEAN := FALSE; this_upstream_site_key NUMBER := NULL; this_enable_populate_rsr NUMBER := NULL; -- -- -- this_verrec RC_RCVER%ROWTYPE; this_curr_inc RC_DATABASE_INCARNATION%ROWTYPE; this_wmrec RC_WATERMARKS%ROWTYPE; this_upstream_dbrec RCI_RA_UPSTREAM_DATABASE%ROWTYPE; this_rsiterec RC_SITE%ROWTYPE; this_v_wmrec CLOB; this_curr_bp_recid NUMBER; this_high_bp_recid NUMBER; this_bp_key_poll NUMBER; FUNCTION assert_schema ( i_schema VARCHAR2 , i_enquote BOOLEAN DEFAULT FALSE ) RETURN VARCHAR2; PROCEDURE assert_schema ( o_schema OUT NOCOPY VARCHAR2 , o_eschema OUT NOCOPY VARCHAR2 , i_schema IN VARCHAR2 ); g_catowner CONSTANT user_users.username%TYPE := assert_schema(dbms_catowner); g_ecatowner CONSTANT VARCHAR2(130) := assert_schema(dbms_catowner, TRUE); e_no_vpd_setup CONSTANT NUMBER := -20153; e_no_vpd_setup_m CONSTANT VARCHAR2(64) := 'recovery catalog does not have VPD support enabled!'; -- -- -- -- -- TYPE vtr IS VARRAY(4) OF VARCHAR2(256); TYPE vtr_t IS TABLE OF vtr; vpd_table_list CONSTANT vtr_t := vtr_t ( vtr('VPC_DATABASES', 'SELECT', 'T', 'T') , vtr('DB', NULL, 'T', 'F') , vtr('DBINC', NULL, 'T', 'T') , vtr('BP', NULL, 'T', 'T') , vtr('BSF', NULL, 'T', 'T') , vtr('BS', NULL, 'T', 'T') , vtr('CONF', NULL, 'T', 'T') , vtr('DELETED_OBJECT', NULL, 'T', 'T') , vtr('DO_SEQ', NULL, 'T', 'T') , vtr('NODE', NULL, 'T', 'T') , vtr('PDB', NULL, 'T', 'T') , vtr('ROUT', NULL, 'T', 'T') , vtr('WATERMARKS', NULL, 'T', 'T') , vtr('PDBINC', NULL, 'T', 'T') , vtr('PDB_DBINC', NULL, 'T', 'T') , vtr('AL', NULL, 'T', 'T') , vtr('BCF', NULL, 'T', 'T') , vtr('BDF', NULL, 'T', 'T') , vtr('BRL', NULL, 'T', 'T') , vtr('CCF', NULL, 'T', 'T') , vtr('CDF', NULL, 'T', 'T') , vtr('CKP', NULL, 'T', 'T') , vtr('DF', NULL, 'T', 'T') , vtr('FB', NULL, 'T', 'T') , vtr('GRSP', NULL, 'T', 'T') , vtr('NRSP', NULL, 'T', 'T') , vtr('OFFR', NULL, 'T', 'T') , vtr('ORL', NULL, 'T', 'T') , vtr('RLH', NULL, 'T', 'T') , vtr('RR', NULL, 'T', 'T') , vtr('RSR', NULL, 'T', 'T') , vtr('RT', NULL, 'T', 'T') , vtr('TF', NULL, 'T', 'T') , vtr('TSATT', NULL, 'T', 'T') , vtr('TS', NULL, 'T', 'T') , vtr('XAL', NULL, 'T', 'T') , vtr('XCF', NULL, 'T', 'T') , vtr('XDF', NULL, 'T', 'T') , vtr('SCR', NULL, 'T', 'T') , vtr('BCB', NULL, 'T', 'T') , vtr('CCB', NULL, 'T', 'T') , vtr('SCRL', NULL, 'T', 'T') , vtr('CFS', 'SELECT', 'T', 'T') , vtr('CONFIG', 'SELECT', 'T', 'T') , vtr('ORSEVENT', NULL, 'T', 'T') , vtr('RCFILE', NULL, 'T', 'T') , vtr('XMLSTORE', 'SELECT', 'T', 'F') , vtr('BCR', NULL, 'T', 'T') , vtr('SERVER', NULL, 'T', 'F') , vtr('VPC_USERS', 'SELECT', 'T', 'T') , vtr('SITE_DFATT', NULL, 'T', 'T') , vtr('SITE_TFATT', NULL, 'T', 'T') , vtr('RCVER', 'SELECT', 'F', 'F') , vtr('RASCHEMAVER', 'SELECT', 'F', 'F') , vtr('RRCACHE', 'SELECT', 'T', 'T') , vtr('SBT_TEMPLATE_DB',NULL, 'T', 'T') ); -- -- g_vpd_required_policies NUMBER := 0; /*---------* * Cursors * *---------*/ -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- cursor pdbQ IS SELECT pdb.pdb_key, pdb.name, pdb.con_id, pdb.guid, pdb.create_scn, pdb.nobackup FROM pdb WHERE pdb.db_key = this_db_key AND pdb.con_id > 1 ORDER BY pdb.guid; cursor picQ IS SELECT pdbinc.pdb_key, pdbinc.pdbinc_key, pdb.con_id, pdb.guid, pdb.create_scn, pdbinc.inc_scn, pdbinc.begin_reset_scn, pdbinc.begin_reset_time, pdbinc.end_reset_scn, dbinc.reset_scn db_reset_scn, dbinc.reset_time db_reset_time, pdbinc.parent_pdbinc_key FROM pdbinc, pdb, dbinc WHERE pdb.pdb_key = pdbinc.pdb_key AND dbinc.dbinc_key = pdbinc.born_dbinc_key AND pdb.con_id > 1 AND pdb.db_key = this_db_key ORDER BY guid, con_id, create_scn, begin_reset_scn, begin_reset_time, end_reset_scn; -- -- cursor tsQ IS SELECT ts.ts_name, ts.ts#, ts.create_scn, ts.create_time, tsatt.rbs_count, ts.included_in_database_backup, ts.bigfile, ts.temporary, ts.encrypt_in_backup, ts.plugin_scn, ts.pdbinc_key, pdbinc.con_id, pdbinc.curr_pdbinc_key, pdbinc.pdb_key, pdbinc.drop_scn pdb_drop_scn FROM ts, tsatt, rci_pdbinc_this_dbinc pdbinc WHERE ts.dbinc_key = tsatt.dbinc_key AND ts.ts# = tsatt.ts# AND ts.pdbinc_key = pdbinc.pdbinc_key AND tsatt.pdbinc_key = pdbinc.pdbinc_key AND ts.create_scn = tsatt.create_scn AND ts.dbinc_key = this_dbinc_key AND ts.plugin_scn = tsatt.plugin_scn AND ts.drop_scn IS NULL --skip ones we know were dropped AND tsatt.end_ckp_key IS NULL AND pdbinc.dbinc_key = this_dbinc_key AND ts.create_scn < pdbinc.next_inc_scn --skip ones in orphan scn ORDER BY pdbinc.con_id, ts.ts#; -- client passes rows to checkTs in -- -- -- cursor dfQ IS SELECT df.file#, df.create_scn, df.create_time, df.plugin_scn, df.ts#, site_dfatt.fname, df.blocks, df.clone_fname, df.stop_scn, df.read_only, df.plugged_readonly, df.create_thread, df.create_size, df.foreign_dbid, df.pdb_closed, df.pdbinc_key, pdbinc.curr_pdbinc_key, pdbinc.pdb_key FROM df, site_dfatt, rci_pdbinc_this_dbinc pdbinc WHERE df.dbinc_key = this_dbinc_key -- our dbinc please AND df.drop_scn IS NULL -- df not dropped AND this_site_key = site_dfatt.site_key(+) -- select names for the site AND df.df_key = site_dfatt.df_key(+) -- join site_dfatt to df AND df.pdbinc_key = pdbinc.pdbinc_key AND df.create_scn < pdbinc.next_inc_scn -- skip ones in orphan scn AND df.plugin_scn < pdbinc.next_inc_scn AND pdbinc.dbinc_key = this_dbinc_key ORDER BY df.file#; -- client passes rows to checkDf in -- -- -- cursor tfQ IS SELECT tf.file#, tf.create_scn, tf.create_time, tf.ts#, site_tfatt.fname, site_tfatt.blocks, site_tfatt.autoextend, site_tfatt.max_size, site_tfatt.next_size, tf.tf_key tf_key, tf.pdb_key, pdb.con_id FROM tf, site_tfatt, pdb WHERE tf.dbinc_key = this_dbinc_key -- our dbinc please AND this_site_key = site_tfatt.site_key -- select names for the site AND tf.tf_key = site_tfatt.tf_key -- join site_tfatt to tf AND site_tfatt.drop_scn IS NULL -- tf not dropped AND tf.pdb_key = pdb.pdb_key ORDER BY tf.file#; -- client passes rows to checkTf in -- -- -- cursor rtQ IS SELECT rt.thread#, rt.sequence#, rt.enable_scn, rt.enable_time, rt.status FROM rt WHERE rt.dbinc_key = this_dbinc_key ORDER BY rt.thread#; -- cursor orlQ IS SELECT orl.thread#, orl.group#, orl.fname FROM orl WHERE orl.dbinc_key = this_dbinc_key AND orl.site_key = this_site_key ORDER BY nlssort(orl.fname, 'NLS_COMP=ANSI NLS_SORT=ASCII7'); -- bug 2107554 -- cursor grspQ IS SELECT grsp.rspname, grsp.from_scn, grsp.to_scn, grsp.pdb_key FROM grsp, dbinc, pdb WHERE grsp.dbinc_key = dbinc.dbinc_key AND dbinc.db_key = this_db_key AND grsp.site_key = this_site_key AND grsp.pdb_key = pdb.pdb_key ORDER BY pdb.con_id, grsp.pdb_key, nlssort(grsp.rspname, 'NLS_COMP=ANSI NLS_SORT=ASCII7'); -- -- cursor bpq(device_type VARCHAR2, handle VARCHAR2, bp_recid VARCHAR2, bp_stamp VARCHAR2) IS SELECT bp_key, bs_key FROM bp WHERE db_key = this_db_key AND status != 'D' AND device_type = bpq.device_type AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))) AND handle = bpq.handle AND handle_hashkey = substr(bpq.device_type,1,10) || substr(bpq.handle,1,10) || substr(bpq.handle,-10) AND NOT (bp_recid = bpq.bp_recid AND bp_stamp = bpq.bp_stamp); -- cursor scrlQ(key NUMBER) IS SELECT text FROM scrl WHERE scr_key = key ORDER BY linenum; -- cursor rcverQ IS SELECT version FROM rcver ORDER BY version; cursor reNorm_dfatt_c IS SELECT fname FROM site_dfatt WHERE df_key in (select df_key from df, dbinc where df.dbinc_key = dbinc.dbinc_key and dbinc.db_key = this_db_key) FOR UPDATE OF site_dfatt.df_key; cursor reNorm_orl_c IS SELECT fname FROM orl WHERE dbinc_key in (select dbinc_key from dbinc where db_key = this_db_key) FOR UPDATE OF orl.dbinc_key; cursor reNorm_al_c IS SELECT fname FROM al where dbinc_key in (select dbinc_key from dbinc where db_key = this_db_key) FOR UPDATE OF al.al_key; cursor reNorm_bp_c IS SELECT handle FROM bp WHERE device_type = 'DISK' and db_key = this_db_key FOR UPDATE OF bp.bp_key; cursor reNorm_ccf_c IS SELECT fname FROM ccf WHERE dbinc_key in (select dbinc_key from dbinc where db_key = this_db_key) FOR UPDATE OF ccf.ccf_key; cursor reNorm_cdf_c IS SELECT fname FROM cdf WHERE dbinc_key in (select dbinc_key from dbinc where db_key = this_db_key) FOR UPDATE OF cdf.dbinc_key; cursor reNorm_tfatt_c IS SELECT fname FROM site_tfatt WHERE tf_key in (select tf_key from tf, dbinc where tf.dbinc_key = dbinc.dbinc_key and dbinc.db_key = this_db_key) FOR UPDATE OF site_tfatt.tf_key; cursor lscrnames_c(glob number, allnames number) IS select 1 oby, rdbi.db_name dname, s.scr_name sname, s.scr_comment scomm from db rdb, dbinc rdbi, scr s where lscrnames_c.glob is null and lscrnames_c.allnames is null and rdbi.dbinc_key = rdb.curr_dbinc_key and rdb.db_key = s.db_key and s.db_key = this_db_key and s.db_key is not NULL UNION ALL select 2, 'ORA%GLOB', s.scr_name, s.scr_comment from scr s where s.db_key IS NULL UNION ALL select 3, rdbi.db_name, s.scr_name, s.scr_comment from db rdb, dbinc rdbi, scr s where lscrnames_c.glob is null and lscrnames_c.allnames is not null and rdbi.dbinc_key = rdb.curr_dbinc_key and rdb.db_key = s.db_key and s.db_key is not NULL order by 1 asc, 2 asc, 3 asc; getPolled_AL BOOLEAN := FALSE; getPolled_BP BOOLEAN := FALSE; -- RTYP_ARCHIVED_LOG CONSTANT number := 11; RTYP_BACKUP_PIECE CONSTANT number := 13; RTYP_DFILE_COPY CONSTANT number := 16; CURSOR feedback_al(bp_key_poll NUMBER) IS SELECT al_recid recid, al_stamp stamp, fname FROM al, (SELECT distinct dbinc_key, thread#, sequence# FROM brl WHERE bs_key IN (SELECT bs_key FROM bp WHERE db_key = this_db_key AND bp_key > bp_key_poll AND purged = 'N' AND device_type = 'SBT_TAPE' AND ba_access IN ('L', 'T') AND site_key IN (SELECT site_key FROM node WHERE db_unique_name like '$%' AND db_key=this_db_key))) bal WHERE al.site_key = this_site_key AND al.is_recovery_dest_file = 'YES' AND bal.dbinc_key=al.dbinc_key AND bal.thread# = al.thread# AND bal.sequence# = al.sequence#; CURSOR feedback_bp(bp_key_poll NUMBER) IS -- -- SELECT bs_key, piece#, device_type, site_key, bp_recid recid, bp_stamp stamp, ba_access, handle FROM bp WHERE db_key = this_db_key AND ((site_key=this_site_key AND is_recovery_dest_file = 'YES') OR (device_type = 'SBT_TAPE' and ba_access in ('L', 'T', 'D'))) AND bs_key in (SELECT bs_key FROM bp WHERE db_key = this_db_key AND bp_key > bp_key_poll AND purged = 'N' AND device_type = 'SBT_TAPE' AND ba_access IN ('L', 'T') AND site_key IN (SELECT site_key FROM node WHERE db_unique_name like '$%' AND db_key=this_db_key)) UNION -- -- SELECT bp.bs_key, piece#, device_type, site_key, bp_recid recid, bp_stamp stamp, ba_access, handle FROM bp, (SELECT distinct a.bs_key FROM bdf a, (SELECT bs_key, file#, create_scn, ckp_scn, dbinc_key FROM bdf WHERE bs_key IN (SELECT bs_key FROM bp WHERE db_key = this_db_key AND bp_key > bp_key_poll AND purged = 'N' AND device_type = 'SBT_TAPE' AND ba_access IN ('L', 'T') AND site_key IN (SELECT site_key FROM node WHERE db_unique_name like '$%' AND db_key=this_db_key))) b WHERE b.file#=a.file# AND b.create_scn=a.create_scn AND b.ckp_scn=a.ckp_scn AND b.dbinc_key=a.dbinc_key AND b.bs_key <> a.bs_key) c WHERE db_key = this_db_key AND site_key = this_site_key AND bp.bs_key = c.bs_key AND is_recovery_dest_file = 'YES' ORDER BY bs_key, piece#, device_type, ba_access desc; disk_bp_rec feedback_bp%ROWTYPE; curr_bp_key_poll NUMBER; /*----------------------* * Cursor Row Variables * *----------------------*/ -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- pdbRec pdbQ%rowtype; picRec picQ%rowtype; tsRec tsQ%rowtype; dfRec dfQ%rowtype; tfRec tfQ%rowtype; rtRec rtQ%rowtype; orlRec orlQ%rowtype; grspRec grspQ%rowtype; /*---------------* * Private Types * *---------------*/ /*-------------------* * Private functions * *-------------------*/ FUNCTION vtr_tname(i IN number) RETURN VARCHAR2 IS BEGIN RETURN vpd_table_list(i)(1); END; FUNCTION vtr_privs(i IN number) RETURN VARCHAR2 IS BEGIN RETURN NVL(vpd_table_list(i)(2), 'SELECT,UPDATE,DELETE,INSERT'); END; FUNCTION vtr_policy_required(i IN number) RETURN BOOLEAN IS BEGIN RETURN vpd_table_list(i)(3) = 'T'; END; FUNCTION vtr_update_check(i IN number) RETURN BOOLEAN IS BEGIN RETURN vpd_table_list(i)(4) = 'T'; END; PROCEDURE setDebugOn(dbglevel IN NUMBER DEFAULT RCVCAT_LEVEL_DEFAULT) IS BEGIN -- -- -- -- dbms_output.enable(buffer_size => null); debug := TRUE; dbglvl := dbglevel; END; PROCEDURE setDebugOff IS BEGIN dumpPkgState('Debug off'); dbms_output.disable; -- free memory debug := FALSE; END; PROCEDURE deb(line IN varchar2 ,level IN number DEFAULT RCVCAT_LEVEL_DEFAULT) IS BEGIN IF debOK(level) THEN IF this_is_ors_admin THEN EXECUTE IMMEDIATE 'BEGIN sys.kbrsi_icd.rsTrace(:1); END;' USING 'RCVCAT: ' || line; END IF; dbms_output.put_line('DBGRCVCAT: '||line); END IF; EXCEPTION WHEN others THEN dbms_output.put_line('(DO_NOT_IGNORE)caught exception during deb ' || substr(sqlerrm, 1, 512)); END deb; PROCEDURE deb_put(line IN varchar2 ,level IN number DEFAULT RCVCAT_LEVEL_DEFAULT) IS BEGIN if debOK(level) then dbms_output.put('DBGRCVCAT: '||line); end if; EXCEPTION WHEN others THEN dbms_output.put_line('(DO_NOT_IGNORE)caught exception during deb ' || substr(sqlerrm, 1, 512)); END deb_put; FUNCTION debOK(level IN number DEFAULT RCVCAT_LEVEL_DEFAULT) RETURN boolean IS BEGIN return (debug and dbglvl >= level); END debOK; PROCEDURE init_package_vars(p_server_key NUMBER DEFAULT NULL) IS proxy varchar2(512); got_srvr_info boolean := TRUE; no_ds_err EXCEPTION; PRAGMA EXCEPTION_INIT(no_ds_err, -1034); -- Oracle not available BEGIN BEGIN IF p_server_key IS NOT NULL THEN SELECT * INTO this_server FROM server WHERE filter_user=user AND server_key = p_server_key; ELSE SELECT * INTO this_server FROM server where filter_user=user; END IF; -- -- IF (INSTR(this_server.server_host, 'amazonaws.com') <> 0) THEN this_amazon_server := TRUE; this_server_url := this_server.server_host; if (this_server.server_port is not null) then this_server_url := this_server_url || ':' || this_server.server_port; end if; this_server_uname := NULL; this_server_passw := NULL; ELSE this_amazon_server := FALSE; IF p_server_key IS NOT NULL THEN BEGIN execute immediate 'begin dbms_rai_wallet2url( wallet_loc => :wallet_path, cred_alias => :wallet_alias, username => :username, password => :password, url => :url, client => ''REPLICATION''); end;' using in this_server.wallet_path, in this_server.wallet_alias, out this_server_uname, out this_server_passw, out this_server_url; EXCEPTION WHEN no_ds_err THEN got_srvr_info := FALSE; deb('INIT_PKG_VARS: Unable to communicate with downstream '|| 'replication server'); END; END IF; END IF; if got_srvr_info then if this_server.proxy_url is not null then proxy := this_server.proxy_url; if (this_server.proxy_port is not null) then proxy := proxy || ':' || this_server.proxy_port; end if; utl_http.set_proxy(proxy, null /* noproxy */); end if; utl_http.set_response_error_check(TRUE); utl_http.set_detailed_excp_support(TRUE); utl_http.set_wallet(path => this_server.wallet_path, password => null); end if; EXCEPTION WHEN NO_DATA_FOUND THEN deb('init_package_vars(no_data_found): ignore it'); WHEN TOO_MANY_ROWS THEN deb('init_package_vars(too_many_rows): ignore it'); WHEN OTHERS THEN deb('init_package_vars(fail): p_server_key=' || p_server_key || ',error='|| sqlerrm); RAISE; END; END init_package_vars; -- -- PROCEDURE checkResync IS BEGIN IF (this_ckp_key IS NULL) THEN raise_application_error(-20031, 'Resync not started'); END IF; IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; IF (this_dbinc_key IS NULL) THEN raise_application_error(-20020, 'Database incarnation not set'); END IF; IF (this_site_key IS NULL) THEN raise_application_error(-20199, 'Database site key not set'); END IF; END checkResync; -- function date2stamp(dt IN date) return number is stamp number; begin stamp := (((((to_number(to_char(dt, 'YYYY'))-1988)*12 + (to_number(to_char(dt, 'MM'))-1))*31 + (to_number(to_char(dt, 'DD'))-1))*24 + (to_number(to_char(dt, 'HH24'))))*60 + (to_number(to_char(dt, 'MI'))))*60 + (to_number(to_char(dt, 'SS'))); return stamp; end; -- function stamp2date(stamp IN number) return date IS x number; dt varchar2(19); begin if stamp is null then return null; end if; x := stamp; dt := to_char(mod(x,60), 'FM09'); -- seconds x := floor(x/60); dt := to_char(mod(x,60), 'FM09') || ':' || dt; -- minutes x := floor(x/60); dt := to_char(mod(x,24), 'FM09') || ':' || dt; -- hours x := floor(x/24); dt := to_char(mod(x,31)+1, 'FM09') || ' ' || dt; -- days x := floor(x/31); dt := to_char(mod(x,12)+1, 'FM09') || '/' || dt; -- months dt := to_char(floor(x/12)+1988) || '/' || dt; return to_date(dt, 'YYYY/MM/DD HH24:MI:SS'); end; -- PROCEDURE recomputeDbincStatus(db_key IN NUMBER, dbinc_key IN NUMBER) IS -- PROCEDURE updateDbincStatus(db_key IN NUMBER, dbinc_key IN NUMBER) IS parent_key NUMBER; BEGIN BEGIN deb('updateDbincStatus - for db_key='||db_key||' dbinc='||dbinc_key); update dbinc set dbinc_status='PARENT' where dbinc_key = updateDbincStatus.dbinc_key and db_key = updateDbincStatus.db_key; -- select parent_dbinc_key into parent_key from dbinc where dbinc_key= updateDbincStatus.dbinc_key and db_key = updateDbincStatus.db_key; updateDbincStatus(db_key, parent_key); deb('updateDbincStatus - normal return for dbinc=' || dbinc_key); EXCEPTION WHEN no_data_found THEN deb('updateDbincStatus- Last parent is ' || dbinc_key); IF (dbinc_key is NOT NULL) THEN -- set last incarnation in the chain update dbinc set dbinc_status='PARENT' where dbinc_key=updateDbincStatus.dbinc_key and db_key = updateDbincStatus.db_key; END IF; return; -- reached the last known parent WHEN OTHERS THEN deb('updateDbincStatus - rollback all, release locks'); rollback; RAISE; END; END updateDbincStatus; BEGIN -- UPDATE db SET curr_dbinc_key = recomputeDbincStatus.dbinc_key WHERE db_key = recomputeDbincStatus.db_key; UPDATE dbinc SET dbinc_status='ORPHAN' WHERE dbinc.db_key = recomputeDbincStatus.db_key; updateDbincStatus(db_key, dbinc_key); UPDATE dbinc SET dbinc_status='CURRENT' where dbinc_key=recomputeDbincStatus.dbinc_key and db_key = recomputeDbincStatus.db_key; END recomputeDbincStatus; -- -- FUNCTION isOrsMedia(media IN VARCHAR2) RETURN BOOLEAN IS BEGIN IF (media LIKE '%Recovery Appliance%') THEN RETURN TRUE; ELSE RETURN FALSE; END IF; END isOrsMedia; -- PROCEDURE initOrsAdmin IS BEGIN EXECUTE IMMEDIATE 'begin :owner := dbms_rai_owner; end;' USING OUT orsadmin_user; EXCEPTION WHEN OTHERS THEN deb('initOrsAdmin(DO_NOT_IGNORE):' || substr(sqlerrm, 1, 132)); END initOrsAdmin; -- PROCEDURE inheritPdbInc( db_key IN NUMBER ,dbinc_key IN NUMBER ,reset_scn IN NUMBER ,parent_dbinc_key IN NUMBER) IS BEGIN deb('inheritPdbInc - dbinc_key=' || dbinc_key || ' parent_dbinc_key=' || parent_dbinc_key); -- FOR r IN (SELECT pdb.pdb_key, pdbinc.pdbinc_key FROM pdbinc, pdb WHERE pdb.pdb_key = pdbinc.pdb_key AND pdb.db_key = inheritPdbInc.db_key AND pdb.con_id in (0, 1)) LOOP deb('inheritPdbInc root'); INSERT INTO pdb_dbinc (dbinc_key, pdb_key, drop_scn, drop_time, curr_pdbinc_key) VALUES (inheritPdbInc.dbinc_key, r.pdb_key, NULL, NULL, r.pdbinc_key); END LOOP; IF (parent_dbinc_key IS NULL) THEN RETURN; END IF; -- FOR r IN (SELECT pdb.pdb_key, pdb_dbinc.curr_pdbinc_key FROM pdb_dbinc, pdb WHERE pdb_dbinc.dbinc_key = inheritPdbInc.parent_dbinc_key AND pdb.pdb_key = pdb_dbinc.pdb_key AND pdb.create_scn < inheritPdbInc.reset_scn AND (pdb_dbinc.drop_scn IS NULL OR pdb_dbinc.drop_scn > inheritPdbInc.reset_scn) AND pdb.con_id > 1) LOOP deb('inheritPdbInc - pdb_key=' || r.pdb_key || ' curr_pdbinc_key=' || r.curr_pdbinc_key); INSERT INTO pdb_dbinc (dbinc_key, pdb_key, drop_scn, drop_time, curr_pdbinc_key) VALUES (inheritPdbInc.dbinc_key, r.pdb_key, NULL, NULL, r.curr_pdbinc_key); END LOOP; END inheritPdbInc; -- PROCEDURE recomputePluggableDbincStatus(dbinc_key IN NUMBER) IS CURSOR pdbincQ(dbinc_key NUMBER) IS SELECT curr_pdbinc_key, pdb_key FROM pdb_dbinc WHERE dbinc_key = pdbincQ.dbinc_key; -- PROCEDURE updatePluggableDbincStatus(pdbinc_key IN NUMBER) IS parent_key NUMBER; BEGIN UPDATE pdbinc SET pdbinc_status='PARENT' WHERE pdbinc_key = updatePluggableDbincStatus.pdbinc_key; -- SELECT parent_pdbinc_key INTO parent_key FROM pdbinc WHERE pdbinc_key= updatePluggableDbincStatus.pdbinc_key; updatePluggableDbincStatus(parent_key); EXCEPTION WHEN no_data_found THEN RETURN; -- reached the last known parent END updatePluggableDbincStatus; BEGIN deb('recomputePluggableDbincStatus for dbinc_key ' || dbinc_key); FOR pdbincQrec in pdbincQ(recomputePluggableDbincStatus.dbinc_key) LOOP -- UPDATE pdbinc SET pdbinc_status = 'ORPHAN' WHERE pdbinc.pdb_key = pdbincQrec.pdb_key; -- updatePluggableDbincStatus(pdbincQrec.curr_pdbinc_key); UPDATE pdbinc SET pdbinc_status='CURRENT' WHERE pdbinc.pdbinc_key = pdbincQrec.curr_pdbinc_key; END LOOP; END recomputePluggableDbincStatus; FUNCTION getPdbInc( birth_scn IN NUMBER ,con_id IN NUMBER ,out_pdb_key OUT NUMBER ) RETURN NUMBER IS local_pdbinc_key NUMBER; BEGIN IF (last_full_ckp_scn IS NULL) THEN deb('getPdbInc - full resync for first time'); SELECT pdbinc_key, pdb_key INTO local_pdbinc_key, out_pdb_key FROM rci_pdbinc_this_dbinc pdbinc WHERE pdbinc.dbinc_key = this_dbinc_key AND pdbinc.drop_scn IS NULL AND pdbinc.con_id = getPdbInc.con_id AND pdbinc.pdbinc_status = 'CURRENT'; ELSE deb('getPdbInc - last_full_ckp_scn ' || last_full_ckp_scn || ' birth_scn ' || birth_scn); FOR r IN (SELECT pdbinc.pdbinc_key, pdbinc.pdb_key, pdbinc.inc_scn, pdbinc.next_inc_scn FROM rci_pdbinc_this_dbinc pdbinc WHERE pdbinc.dbinc_key = this_dbinc_key AND pdbinc.drop_scn IS NULL AND pdbinc.con_id = getPdbInc.con_id AND pdbinc.next_inc_scn > last_full_ckp_scn ORDER BY pdbinc.inc_scn) LOOP -- IF (birth_scn >= r.inc_scn AND birth_scn <= r.next_inc_scn AND birth_scn >= last_full_ckp_scn) THEN local_pdbinc_key := r.pdbinc_key; out_pdb_key := r.pdb_key; EXIT; END IF; local_pdbinc_key := r.pdbinc_key; out_pdb_key := r.pdb_key; END LOOP; END IF; IF (local_pdbinc_key IS NULL) THEN raise_application_error(-20999, 'getPdbInc - pdbinc not known'); ELSE deb('getPdbInc - pdbinc ' || local_pdbinc_key); END IF; RETURN local_pdbinc_key; END getPdbInc; /* convert guid to pdb key */ FUNCTION guidToPdbKey(guid IN RAW, dropped_pdb IN binary_integer) RETURN NUMBER IS l_pdb_key NUMBER; BEGIN IF (guid IS NULL OR guid = ZERO_GUID) THEN SELECT pdb_key INTO l_pdb_key FROM pdb WHERE pdb.db_key = this_db_key AND pdb.con_id IN (1, 0); ELSE SELECT max(pdb_key) INTO l_pdb_key FROM pdb WHERE pdb.db_key = this_db_key AND pdb.guid = guidToPdbKey.guid; END IF; -- -- -- -- -- IF (l_pdb_key IS NULL) THEN IF (dropped_pdb > 0) THEN SELECT pdb_key INTO l_pdb_key FROM pdb WHERE pdb.db_key = this_db_key AND pdb.con_id IN (1, 0); ELSE RAISE no_data_found; END IF; END IF; RETURN l_pdb_key; EXCEPTION WHEN OTHERS THEN deb('guidToPdbKey translation failed for ' || guid); RAISE; END guidToPdbKey; /*-------------------* * Register Database * *-------------------*/ PROCEDURE registerDatabase(db_id IN NUMBER ,db_name IN VARCHAR2 ,reset_scn IN NUMBER ,reset_time IN DATE ,db_unique_name IN VARCHAR2 default null ,con_id IN NUMBER default 0 ,guid IN RAW default null ) IS loc_dbinc_key number; loc_db_key number; loc_pdb_key number; p_dbun node.db_unique_name%TYPE := upper(db_unique_name); BEGIN -- BEGIN SELECT NULL INTO loc_dbinc_key FROM rcver WHERE version = catalogVersion; EXCEPTION WHEN no_data_found THEN raise_application_error(-20298, 'Not compatible recovery catalog'); END; IF (this_ckp_key IS NOT NULL) THEN raise_application_error(-20030 , 'Resync in progress'); END IF; this_db_key := NULL; this_dbinc_key := NULL; -- -- IF p_dbun is NULL and registerDbPending.dbid is null THEN registerDbPending.dbid := db_id; registerDbPending.con_id := con_id; registerDbPending.guid := guid; deb('registerDatabase pushed to setDatabase stage for dbid = ' || db_id); RETURN; END IF; BEGIN INSERT INTO db(db_key, db_id, reg_db_unique_name) VALUES(rman_seq.nextval, db_id, p_dbun) RETURNING db_key INTO loc_db_key; EXCEPTION WHEN dup_val_on_index THEN raise_application_error(-20002, 'Database already registered'); END; INSERT INTO dbinc (dbinc_key, db_key, db_name, reset_scn, reset_time) VALUES (rman_seq.nextval, loc_db_key, upper(db_name), reset_scn, reset_time) RETURNING dbinc_key INTO loc_dbinc_key; -- recomputeDbincStatus(loc_db_key, loc_dbinc_key); deb('registerDatabase - ' || 'adding node row, db_unique_name value=' || p_dbun); INSERT INTO node(db_key, force_resync2cf, database_role, site_key, db_unique_name) VALUES(loc_db_key, 'NO', 'PRIMARY', rman_seq.nextval, p_dbun); deb('registerDatabase - adding a row to pdb for rootdb, con_id=' || con_id || ' guid=' || nvl(guid, ZERO_GUID)); IF (con_id IS NULL OR con_id NOT IN (0, 1)) THEN raise_application_error(-20999, 'internal error: only con_id 0 or 1 can register database'); END IF; INSERT INTO pdb (pdb_key, db_key, name, con_id, db_id, create_scn, guid) VALUES (rman_seq.nextval, loc_db_key, NULL, con_id, db_id, 1, nvl(guid, ZERO_GUID)) RETURNING pdb_key INTO loc_pdb_key; INSERT INTO pdbinc (pdbinc_key, pdb_key, born_dbinc_key, inc_scn, begin_reset_scn, begin_reset_time, end_reset_scn, parent_pdbinc_key, pdbinc_status) VALUES (rman_seq.nextval, loc_pdb_key, loc_dbinc_key, 1, reset_scn, reset_time, 1, NULL, 'CURRENT'); INSERT INTO pdb_dbinc (dbinc_key, pdb_key, drop_scn, drop_time, curr_pdbinc_key) VALUES (loc_dbinc_key, loc_pdb_key, NULL, NULL, rman_seq.currval); setReason(RESYNC_REASON_NOACTION); commitChanges('registerDatabase'); -- registerDbPending.dbid := null; -- EXCEPTION WHEN OTHERS THEN deb('registerDatabase - rollback, release locks'); rollback; -- registerDbPending.dbid := null; RAISE; END registerDatabase; -- -- PROCEDURE resetDatabase(db_id IN NUMBER ,db_name IN VARCHAR2 ,reset_scn IN NUMBER ,reset_time IN DATE ,parent_reset_scn IN NUMBER ,parent_reset_time IN DATE ) IS local dbinc%rowtype; -- local variables BEGIN -- BEGIN SELECT NULL INTO local.db_key FROM rcver WHERE version = catalogVersion; EXCEPTION WHEN no_data_found THEN raise_application_error(-20298, 'Not compatible with recovery catalog'); END; IF (this_ckp_key IS NOT NULL) THEN raise_application_error(-20030, 'Resync in progress'); END IF; IF (db_id IS NULL) THEN raise_application_error(-20007, 'db_id is null'); END IF; this_db_key := NULL; this_dbinc_key := NULL; BEGIN SELECT db_key, curr_dbinc_key INTO local.db_key, local.dbinc_key FROM db WHERE db.db_id = resetDatabase.db_id -- should return 1 row FOR UPDATE OF db.db_key; EXCEPTION WHEN no_data_found THEN raise_application_error(-20001, 'Database not found'); END; -- BEGIN SELECT dbinc_key INTO local.parent_dbinc_key FROM dbinc WHERE dbinc.db_key = local.db_key AND dbinc.reset_scn = resetDatabase.parent_reset_scn AND dbinc.reset_time = resetDatabase.parent_reset_time; EXCEPTION WHEN no_data_found THEN local.parent_dbinc_key := NULL; END; -- BEGIN INSERT INTO dbinc (dbinc_key, db_key, db_name, reset_scn, reset_time, parent_dbinc_key) VALUES (rman_seq.nextval, local.db_key, upper(db_name), reset_scn, reset_time, local.parent_dbinc_key) RETURNING dbinc_key INTO local.dbinc_key; EXCEPTION WHEN dup_val_on_index THEN raise_application_error(-20009, 'Db incarnation already registered'); END; inheritPdbInc( local.db_key, local.dbinc_key, reset_scn, local.parent_dbinc_key); -- recomputeDbincStatus(local.db_key, local.dbinc_key); recomputePluggableDbincStatus(local.dbinc_key); commitChanges('resetDatabase'); -- EXCEPTION WHEN OTHERS THEN deb('resetDatabase - rollback, release locks'); rollback; RAISE; END resetDatabase; -- FUNCTION resetDatabase(db_id IN NUMBER ,db_name IN VARCHAR2 ,reset_scn IN NUMBER ,reset_time IN DATE ,parent_reset_scn IN NUMBER ,parent_reset_time IN DATE ) RETURN NUMBER IS local dbinc%rowtype; -- local variables BEGIN -- BEGIN SELECT NULL INTO local.db_key FROM rcver WHERE version = catalogVersion; EXCEPTION WHEN no_data_found THEN raise_application_error(-20298, 'Not compatible with recovery catalog'); END; IF (this_ckp_key IS NOT NULL) THEN raise_application_error(-20030, 'Resync in progress'); END IF; IF (db_id IS NULL) THEN raise_application_error(-20007, 'db_id is null'); END IF; BEGIN SELECT db_key INTO local.db_key FROM db WHERE db.db_id = resetDatabase.db_id; -- should return 1 row EXCEPTION WHEN no_data_found THEN raise_application_error(-20001, 'Database not found'); END; SELECT dbinc_key INTO local.dbinc_key FROM dbinc WHERE dbinc.db_key = local.db_key AND dbinc.reset_scn = resetDatabase.reset_scn AND dbinc.reset_time = resetDatabase.reset_time; resetDatabase(local.dbinc_key, db_name); RETURN local.dbinc_key; END resetDatabase; -- PROCEDURE resetDatabase( dbinc_key IN NUMBER ,db_name IN VARCHAR2 ) IS local dbinc%rowtype; -- local variables BEGIN -- BEGIN SELECT NULL INTO local.db_key FROM rcver WHERE version = catalogVersion; EXCEPTION WHEN no_data_found THEN raise_application_error(-20298, 'Not compatible with recovery catalog'); END; IF (this_ckp_key IS NOT NULL) THEN raise_application_error(-20030, 'Resync in progress'); END IF; IF (dbinc_key IS NULL) THEN raise_application_error(-20008, 'Database incarnation key is missing'); END IF; this_db_key := NULL; this_dbinc_key := NULL; BEGIN SELECT db_key, db_name INTO local.db_key, local.db_name FROM dbinc WHERE dbinc.dbinc_key = resetDatabase.dbinc_key; EXCEPTION WHEN no_data_found THEN raise_application_error(-20010, 'Database incarnation not found'); END; -- IF (upper(db_name) <> local.db_name) THEN IF (db_name != 'UNKNOWN') THEN UPDATE dbinc SET db_name = upper(resetDatabase.db_name) WHERE dbinc.dbinc_key = resetDatabase.dbinc_key; ELSE raise_application_error(-20004, 'Database name does not match'); END IF; END IF; -- recomputeDbincStatus(local.db_key, resetDatabase.dbinc_key); recomputePluggableDbincStatus(resetDatabase.dbinc_key); commitChanges('resetDatabase'); -- EXCEPTION WHEN OTHERS THEN deb('resetDatabase - rollback, release locks'); rollback; RAISE; END resetDatabase; procedure resetDatabase( dbinc_key IN number ,db_name IN varchar2 ,reset_scn OUT number ,reset_time OUT date ,db_id IN number DEFAULT NULL ) IS local_db_key dbinc.db_key%TYPE; BEGIN IF db_id IS NOT NULL THEN BEGIN SELECT db_key INTO local_db_key FROM db WHERE db.db_id = resetDatabase.db_id; -- should return 1 row EXCEPTION WHEN no_data_found THEN raise_application_error(-20001, 'Database not found'); END; ELSE local_db_key := this_db_key; END IF; BEGIN SELECT reset_scn, reset_time INTO resetDatabase.reset_scn, resetDatabase.reset_time FROM dbinc WHERE dbinc.dbinc_key = resetDatabase.dbinc_key AND (db_id IS NULL OR dbinc.db_key = local_db_key); EXCEPTION WHEN no_data_found THEN raise_application_error(-20010, 'Database incarnation not found'); END; resetDatabase(dbinc_key, db_name); END resetDatabase; PROCEDURE unRegisterDatabase( db_key IN NUMBER DEFAULT NULL ,db_id IN NUMBER ) IS tmp NUMBER; cnt NUMBER := 0; BEGIN IF (this_ckp_key IS NOT NULL) THEN raise_application_error(-20030, 'Resync in progress'); END IF; -- BEGIN SELECT 0 INTO tmp FROM db WHERE db.db_id = unRegisterDatabase.db_id; EXCEPTION WHEN no_data_found THEN raise_application_error(-20001, 'Database not found'); END; -- -- SELECT count(*) INTO cnt FROM db WHERE storage_prov = 'Y' AND db.db_id = unRegisterDatabase.db_id; IF (cnt <> 0) THEN raise_application_error(-20301, 'Cannot unregister database'); END IF; -- -- SELECT 0 INTO tmp FROM db WHERE db.db_id = unRegisterDatabase.db_id FOR UPDATE OF db.db_key; DELETE FROM bp WHERE db_key = (select db_key from db where db.db_id = unRegisterDatabase.db_id); DELETE FROM db WHERE db.db_id = unRegisterDatabase.db_id; commitChanges('unRegisterDatabase'); -- EXCEPTION WHEN OTHERS THEN deb('unregisterDatabase - rollback, release locks'); rollback; RAISE; END unRegisterDatabase; -- PROCEDURE setArchiveFileScopeAttributes(logs_shared IN NUMBER) IS BEGIN deb('setArchiveFileScopeAttributes'); IF logs_shared > 0 THEN dbms_rcvcat.logs_shared := TRUE#; ELSE dbms_rcvcat.logs_shared := FALSE#; END IF; deb('logs_shared = ' || dbms_rcvcat.logs_shared); dbms_rcvman.setArchiveFileScopeAttributes(logs_shared); deb('exiting setArchiveFileScopeAttributes'); END setArchiveFileScopeAttributes; -- PROCEDURE setBackupFileScopeAttributes( disk_backups_shared IN NUMBER, tape_backups_shared IN NUMBER) IS lsite_key NUMBER; BEGIN deb('setBackupFileScopeAttributes'); IF disk_backups_shared IS NOT NULL THEN IF disk_backups_shared > 0 THEN dbms_rcvcat.disk_backups_shared := TRUE#; ELSE dbms_rcvcat.disk_backups_shared := FALSE#; END IF; END IF; IF tape_backups_shared IS NOT NULL THEN IF tape_backups_shared > 0 THEN dbms_rcvcat.tape_backups_shared := TRUE#; ELSE dbms_rcvcat.tape_backups_shared := FALSE#; END IF; END IF; deb('disk_backups_shared='||dbms_rcvcat.disk_backups_shared); deb('tape_backups_shared='||dbms_rcvcat.tape_backups_shared); dbms_rcvman.setBackupFileScopeAttributes(disk_backups_shared, tape_backups_shared); deb('exiting setBackupFileScopeAttributes'); END setBackupFileScopeAttributes; /*--------------* * Set Database * *--------------*/ -- PROCEDURE setDatabase(db_name IN VARCHAR2 ,reset_scn IN NUMBER ,reset_time IN DATE ,db_id IN NUMBER ,db_unique_name IN VARCHAR2 ,dummy_instance IN BOOLEAN ,cf_type IN NUMBER ,site_aware IN BOOLEAN default FALSE ,ors_instance IN BOOLEAN default FALSE) IS local dbinc%rowtype; -- local variables current_inc VARCHAR2(3); dbnm dbinc.db_name%TYPE; dbnm_in dbinc.db_name%TYPE; rid varchar2(18); local_site_key number; dbunqnm node.db_unique_name%TYPE; db_role node.database_role%type; dbunqnm_in node.db_unique_name%TYPE; l_reg_dbunqnm node.db_unique_name%TYPE; cat_version varchar2(12); vpd_version varchar2(12); prim_dbunqnm_in node.db_unique_name%TYPE; db_id_in number; tmp_dbunqnm_cnt number; tmp_primary_cnt number; cf_type_in number; my_dbunqnm watermarks.db_unique_name%TYPE; BEGIN -- BEGIN SELECT NULL INTO local.db_key FROM rcver WHERE version = catalogVersion; EXCEPTION WHEN no_data_found THEN raise_application_error(-20298, 'Not compatible with recovery catalog'); END; IF (this_ckp_key IS NOT NULL) THEN raise_application_error(-20030, 'Resync in progress'); END IF; this_db_key := NULL; -- clear in case exception raised this_dbinc_key := NULL; kccdivts := NULL; dbnm_in := upper(db_name); dbunqnm_in := upper(db_unique_name); db_id_in := db_id; cf_type_in := cf_type; -- -- IF registerDbPending.dbid = db_id AND NOT ors_instance THEN registerDatabase(db_id => db_id, db_name => dbnm_in, reset_scn => reset_scn, reset_time => reset_time, db_unique_name => dbunqnm_in, con_id => registerDbPending.con_id, guid => registerDbPending.guid); END IF; deb('setDatabase(db_unique_name)='||db_unique_name); -- IF ors_instance THEN IF db_unique_name IS NULL OR substr(db_unique_name, 1, 1) = '$' THEN raise_application_error(-20999, 'internal error: db_unique_name value is invalid=' || db_unique_name); END IF; IF db_id IS NULL THEN raise_application_error(-20999, 'internal error: db_id must be specified for ORS instance'); END IF; cf_type_in := CF_STANDBY; -- -- -- IF instr(dbunqnm_in, '$'|| db_id) = 0 THEN dbunqnm_in := dbunqnm_in || '$' || db_id; END IF; dbunqnm_in := '$' || dbunqnm_in; END IF; <> -- -- -- -- IF (db_id_in IS NOT NULL) THEN BEGIN SELECT db_key, curr_dbinc_key, db_name, reg_db_unique_name INTO local.db_key, local.dbinc_key, local.db_name, l_reg_dbunqnm FROM db WHERE db.db_id = db_id_in; -- should return 1 row EXCEPTION WHEN no_data_found THEN raise_application_error(-20001, 'Database not found'); END; -- IF (dbnm_in is NOT NULL AND db_id is NOT NULL) THEN -- -- -- -- BEGIN SELECT decode(dbinc.dbinc_key, db.curr_dbinc_key, 'YES', 'NO'), dbinc.db_name, dbinc.rowid INTO current_inc, dbnm, rid FROM db, dbinc WHERE db.db_key = dbinc.db_key AND db.db_id = setDatabase.db_id AND dbinc.reset_scn = setDatabase.reset_scn AND dbinc.reset_time = setDatabase.reset_time; EXCEPTION WHEN no_data_found THEN raise_application_error(-20003, 'Database incarnation not found'); END; IF (current_inc = 'NO') THEN raise_application_error(-20011, 'Database incarnation not current'); END IF; IF (dbnm != dbnm_in) THEN UPDATE dbinc SET dbinc.db_name = dbnm_in WHERE rowid = rid; commitChanges('setDatabase'); END IF; END IF; IF (NOT dummy_instance AND dbunqnm_in IS NOT NULL) THEN deb('setDatabase - check db_unique_name= ' || dbunqnm_in || ' cf_type_in= ' || cf_type_in); -- -- -- -- IF l_reg_dbunqnm IS NULL THEN UPDATE db SET db.reg_db_unique_name = dbunqnm_in WHERE db.db_key = local.db_key AND db.db_id = setDatabase.db_id AND db.reg_db_unique_name IS NULL; deb('setDatabase: updating null db_unique_name in DB with ' || dbunqnm_in || 'number of rows updated ' || sql%rowcount); commitChanges('setDatabase1'); END IF; -- -- -- -- -- -- SELECT count(*) into tmp_dbunqnm_cnt FROM node WHERE node.db_unique_name is NULL AND node.db_key = local.db_key; IF tmp_dbunqnm_cnt = 1 THEN SELECT count(*) into tmp_dbunqnm_cnt FROM node WHERE node.db_unique_name is not NULL AND node.db_key = local.db_key; IF tmp_dbunqnm_cnt > 0 THEN raise_application_error(-20999, 'internal error: found non-null and null site name'); END IF; UPDATE NODE SET node.db_unique_name = dbunqnm_in WHERE node.db_unique_name is NULL AND node.db_key = local.db_key; deb('setDatabase: updating null db_unique_name with ' ||dbunqnm_in || 'number of rows updated ' || sql%rowcount); END IF; BEGIN -- SELECT node.database_role, site_key INTO db_role, local_site_key FROM node WHERE node.db_key = local.db_key AND node.db_unique_name = dbunqnm_in; -- -- SELECT count(*) into tmp_primary_cnt FROM node WHERE node.database_role = 'PRIMARY' AND site_key <> local_site_key AND node.db_key = local.db_key; deb('setDatabase - check database_role'); IF (cf_type_in = CF_STANDBY AND db_role != 'STANDBY') THEN -- deb('setDatabase - database role not standby - updating'); UPDATE node SET node.database_role = decode(substr(node.db_unique_name,1,1), '$', 'RA', 'STANDBY'), node.high_conf_recid = 0 WHERE site_key = local_site_key AND (node.database_role <> decode(substr(node.db_unique_name,1,1), '$', 'RA', 'STANDBY')); commitChanges('setDatabase2'); ELSIF ((cf_type_in = CF_CURRENT OR cf_type_in = CF_BACKUP) AND (db_role != 'PRIMARY' OR tmp_primary_cnt > 1)) THEN -- deb('setDatabase - not primary or primary_cnt='||tmp_primary_cnt); -- UPDATE node SET node.database_role = decode(substr(node.db_unique_name,1,1), '$', 'RA', 'STANDBY'), node.high_conf_recid = 0 WHERE site_key <> local_site_key AND db_key = local.db_key; -- -- -- -- UPDATE node SET node.database_role = 'PRIMARY', node.high_conf_recid = 0, high_ic_recid = 0, high_ts_recid = NULL, high_df_recid = NULL, high_rt_recid = NULL, high_orl_recid = NULL, high_tf_recid = 0, high_pdb_recid = NULL, high_pic_recid = 0 WHERE site_key = local_site_key AND db_key = local.db_key; sessionWaterMarks.high_ic_recid := 0; sessionWaterMarks.high_pic_recid := 0; commitChanges('setDatabase3'); prev_sessionWaterMarks := sessionWaterMarks; END IF; EXCEPTION WHEN no_data_found THEN IF (cf_type_in = CF_CURRENT OR cf_type_in = CF_BACKUP) THEN deb('setDatabase: adding node row, new primary database...'); -- UPDATE node SET node.database_role = decode(substr(node.db_unique_name,1,1),'$', 'RA', 'STANDBY'), node.high_conf_recid = 0 WHERE db_key = local.db_key; INSERT INTO node(db_unique_name, db_key, force_resync2cf, database_role, site_key) VALUES(dbunqnm_in, local.db_key, 'NO', 'PRIMARY', rman_seq.nextval); commitChanges('setDatabase4'); ELSIF cf_type_in = CF_STANDBY THEN -- deb('setDatabase: adding node row, new standby database...'); BEGIN INSERT INTO node(db_unique_name, db_key, force_resync2cf, database_role, site_key) VALUES(dbunqnm_in, local.db_key, 'NO', decode(substr(dbunqnm_in,1,1), '$', 'RA', 'STANDBY'), rman_seq.nextval); commitChanges('setDatabase5'); EXCEPTION WHEN dup_val_on_index THEN deb('setDatabase - someone inserted same standby'); END; ELSE -- -- -- -- -- -- BEGIN deb('setDatabase - falking db_unique_name from'|| dbunqnm_in); SELECT db_unique_name into prim_dbunqnm_in from node WHERE db_key = local.db_key AND database_role = 'PRIMARY'; dbunqnm_in := prim_dbunqnm_in; deb('setDatabase - changing dbunqnm_in to ' || dbunqnm_in); EXCEPTION WHEN no_data_found THEN deb('setDatabase - unknown dbunqnm_in set to null'); dbunqnm_in := null; END; END IF; END; END IF; -- ELSIF (dbnm_in IS NOT NULL) THEN BEGIN SELECT db.db_key, db.curr_dbinc_key, db.db_id INTO local.db_key, local.dbinc_key, db_id_in FROM db, dbinc WHERE db.curr_dbinc_key = dbinc.dbinc_key AND dbinc.db_name = dbnm_in; EXCEPTION WHEN no_data_found THEN raise_application_error(-20001, 'Database not found'); WHEN too_many_rows THEN raise_application_error(-20005, 'Database name is ambiguous'); END; GOTO now_try_with_dbid; ELSE raise_application_error(-20006, 'Database name is missing'); END IF; -- -- this_db_unique_name := dbunqnm_in; this_db_key := local.db_key; this_dbinc_key := local.dbinc_key; deb('setDatabase - this_db_unique_name='||this_db_unique_name); deb('setDatabase - this_dbinc_key:'||to_char(this_dbinc_key)); deb('setDatabase - this_db_key:'||to_char(this_db_key)); BEGIN select site_key into this_site_key from node where db_unique_name=upper(dbunqnm_in) AND db_key = this_db_key; deb('setDatabase - this_site_key:'||this_site_key); EXCEPTION WHEN no_data_found THEN BEGIN select site_key, db_unique_name into this_site_key, dbunqnm_in from node where database_role='PRIMARY' AND db_key = this_db_key; deb('setDatabase - this_site_key(primary):'||this_site_key); EXCEPTION WHEN no_data_found THEN -- -- deb('setDatabase - this_site_key is null'); this_site_key := null; END; END; cntbs := 0; -- -- dbms_rcvman.setDatabase (dbnm_in, reset_scn, reset_time, db_id, this_db_unique_name, site_aware, dummy_instance, ors_instance); client_site_aware := site_aware; IF client_site_aware THEN setArchiveFileScopeAttributes(logs_shared => 0); setBackupFileScopeAttributes (disk_backups_shared => 0, tape_backups_shared => 1); END IF; IF this_is_ors THEN BEGIN IF this_is_ors_admin THEN EXECUTE IMMEDIATE 'select rtrim(ltrim(value)) from sys.v_$parameter where lower(name)=''db_unique_name''' into my_dbunqnm; ELSE my_dbunqnm := this_db_unique_name; END IF; INSERT INTO do_seq(db_key) VALUES (this_db_key); INSERT INTO watermarks(db_key, db_unique_name, rs_version_stamp) VALUES (this_db_key, my_dbunqnm, SYSDATE); commitChanges('setDatabase6 - added a row to watermarks,'||this_db_key); EXCEPTION WHEN dup_val_on_index THEN NULL; END; END IF; END setDatabase; -- PROCEDURE setDatabase(db_name IN VARCHAR2 ,reset_scn IN NUMBER ,reset_time IN DATE ,db_id IN NUMBER ,db_unique_name IN VARCHAR2 DEFAULT NULL) IS BEGIN setDatabase(db_name => db_name, reset_scn => reset_scn, reset_time => reset_time, db_id => db_id, db_unique_name => db_unique_name, dummy_instance => FALSE, cf_type => CF_CURRENT); END setDatabase; -- -- -- -- PROCEDURE setDatabase(dbinc_key number) IS dbinc_row dbinc%ROWTYPE; db_row db%ROWTYPE; BEGIN select * into dbinc_row from dbinc where dbinc_key = setDatabase.dbinc_key; select * into db_row from db where db_key = dbinc_row.db_key; setDatabase(db_name => dbinc_row.db_name, reset_scn => dbinc_row.reset_scn, reset_time => dbinc_row.reset_time, db_id => db_row.db_id); END setDatabase; procedure setDatabase IS dbinckey number; BEGIN select curr_dbinc_key into dbinckey from db; setDatabase(dbinckey); END setDatabase; -- -- -- -- -- -- -- -- -- PROCEDURE doReplicationReconcile(p_db_key IN NUMBER, p_lib_key IN NUMBER, p_server_key IN NUMBER) IS dbinckey NUMBER; dbinc_row dbinc%ROWTYPE; db_row db%ROWTYPE; l_dbun VARCHAR2(512); l_save_this_server SERVER%ROWTYPE; resync_done NUMBER; BEGIN deb('doReplicationReconcile: ' || '( p_db_key=>' || p_db_key|| ', p_lib_key=>' || p_lib_key|| ', p_server_key=>' || p_server_key|| ')'); select curr_dbinc_key into dbinckey from db WHERE db_key=p_db_key; select * into dbinc_row from dbinc where dbinc_key = dbinckey; select * into db_row from db where db_key = dbinc_row.db_key; execute immediate 'begin :url := dbms_ra_int.dbkey2name(:db_key); end;' using out this_url_db_unique_name, in dbinc_row.db_key; execute immediate 'select rtrim(ltrim(value)) from sys.v_$parameter ' || 'where lower(name)=''db_unique_name''' into l_dbun; deb('doReplicationReconcile: info for setDatabase ' || ' db_name=>' || dbinc_row.db_name || ', reset_scn=>' ||dbinc_row.reset_scn|| ', reset_time=>' ||dbinc_row.reset_time|| ', db_id=>' ||db_row.db_id|| ', db_unique_name=>' ||l_dbun|| ', this_url_db_unique_name=>' || this_url_db_unique_name); -- l_save_this_server := this_server; -- this_lib_key := p_lib_key; init_package_vars(p_server_key); setDatabase(db_name => dbinc_row.db_name, reset_scn => dbinc_row.reset_scn, reset_time => dbinc_row.reset_time, db_id => db_row.db_id, db_unique_name => l_dbun, dummy_instance => FALSE, cf_type => CF_STANDBY, site_aware => TRUE, ors_instance => TRUE); -- this_verrec := null; this_curr_inc := null; this_wmrec := null; this_v_wmrec := null; deb('clearing all variables used for reconcile'); select nvl(count(*), 0) into resync_done from ts where dbinc_key = this_dbinc_key; IF resync_done > 0 THEN writeFixedSections; readBackupSections; ELSE deb('doReplicationReconcile: resync not done, skipping reconcile'); END IF; this_server := l_save_this_server; this_lib_key := NULL; this_url_db_unique_name := NULL; this_verrec := null; this_curr_inc := null; this_wmrec := null; this_v_wmrec := null; deb('doReplicationReconcile: resync (suc)'); EXCEPTION WHEN OTHERS THEN deb('doReplicationReconcile: resync (fail):' || substr(sqlerrm, 1, 512)); this_server := l_save_this_server; this_url_db_unique_name := NULL; this_verrec := null; this_curr_inc := null; this_wmrec := null; this_v_wmrec := null; RAISE; END doReplicationReconcile; /*-----------------------------* * Recovery Catalog Checkpoint * *-----------------------------*/ PROCEDURE lockForCkpt(ors_inspect IN boolean DEFAULT FALSE) IS local_dbid NUMBER; local_dbkey NUMBER; start_time DATE := sysdate; BEGIN IF (this_ckp_key IS NOT NULL) THEN raise_application_error(-20030, 'Resync in progress'); END IF; IF (this_dbinc_key IS NULL) THEN raise_application_error(-20020, 'Database incarnation not set'); END IF; -- -- -- -- SELECT db_id INTO local_dbid FROM db WHERE db_key = this_db_key FOR UPDATE OF db.db_key; -- -- IF this_is_ors THEN SELECT high_bp_recid INTO this_curr_bp_recid FROM watermarks WHERE db_key = this_db_key FOR UPDATE OF watermarks.high_bp_recid; this_high_bp_recid := this_curr_bp_recid; END IF; this_lock_ors_inspect := ors_inspect; deb('lockForCkpt - took ' || ((sysdate - start_time) * 86400) || ' seconds'); deb('lockForCkpt - Obtained all locks for db ' || to_char(this_db_key)); -- -- -- -- END lockForCkpt; FUNCTION ckptNeeded( ckp_scn IN NUMBER ,ckp_cf_seq IN NUMBER ,cf_version IN DATE ,cf_type IN NUMBER ,high_df_recid IN NUMBER ,high_orl_recid IN NUMBER ,high_cdf_recid IN NUMBER ,high_al_recid IN NUMBER ,high_bp_recid IN NUMBER ,high_do_recid IN NUMBER ,high_offr_recid IN NUMBER ,high_pc_recid IN NUMBER DEFAULT NULL -- for compatibility ,high_conf_recid IN NUMBER DEFAULT NULL -- for compatibility ,rltime IN DATE DEFAULT NULL -- for compatibility ,high_ts_recid IN NUMBER DEFAULT NULL -- for compatibility ,high_bs_recid IN NUMBER DEFAULT NULL -- for compatibility ,lopen_reset_scn IN number DEFAULT NULL -- for compatibility ,lopen_reset_time IN DATE DEFAULT NULL -- for compatibility ,high_ic_recid IN NUMBER DEFAULT NULL -- for compatibility ,high_tf_recid IN NUMBER DEFAULT NULL -- for compatibility ,high_rt_recid IN NUMBER DEFAULT NULL -- for compatibility ,high_grsp_recid IN NUMBER DEFAULT NULL -- for compatibility ,high_nrsp_recid IN NUMBER DEFAULT NULL -- for compatibility ,high_bcr_recid IN NUMBER DEFAULT NULL -- for compatibility ,high_pdb_recid IN NUMBER DEFAULT NULL -- for compatibility ,high_pic_recid IN NUMBER DEFAULT NULL -- for compatibility ) RETURN NUMBER IS ckp_type NUMBER; local node%rowtype; local_dbid NUMBER := 0; local_reset_time DATE; local_reset_scn NUMBER := 0; cksum NUMBER; ckp_desc VARCHAR2(30); BEGIN IF (this_ckp_key IS NOT NULL) THEN raise_application_error(-20030, 'Resync in progress'); END IF; IF (this_dbinc_key IS NULL) THEN raise_application_error(-20020, 'Database incarnation not set'); END IF; IF (this_site_key IS NULL) THEN raise_application_error(-20199, 'Site key is not set'); END IF; SELECT db_id INTO local_dbid FROM db WHERE db.db_key = this_db_key FOR UPDATE OF db.db_key; deb('ckptNeeded - Obtained all locks for database ' || to_char(this_db_key)); -- cksum := high_df_recid + high_orl_recid + high_cdf_recid + high_al_recid + high_bp_recid + high_do_recid + high_offr_recid + nvl(high_pc_recid, 0) + nvl(high_conf_recid, 0) + nvl(high_ts_recid, 0) + nvl(high_bs_recid, 0) + nvl(high_ic_recid, 0) + nvl(high_tf_recid, 0) + nvl(high_rt_recid, 0) + nvl(high_grsp_recid, 0) + nvl(high_nrsp_recid, 0) + nvl(high_bcr_recid, 0) + nvl(high_pdb_recid, 0) + nvl(high_pic_recid, 0); -- -- -- -- -- -- SELECT cf_create_time, nvl(high_df_recid,0), nvl(high_ts_recid,0), nvl(high_orl_recid,0), nvl(high_cdf_recid,0), nvl(high_al_recid,0), nvl(high_bp_recid,0), nvl(high_do_recid,0), nvl(high_offr_recid,0), nvl(high_pc_recid,0), full_ckp_cf_seq, job_ckp_cf_seq, nvl(high_ic_recid,0), nvl(high_bs_recid,0), nvl(high_tf_recid, 0), nvl(high_rt_recid, 0), nvl(high_grsp_recid, 0), nvl(high_nrsp_recid, 0), nvl(high_bcr_recid, 0), high_conf_recid, force_resync2cf, nvl(high_pdb_recid, -1), nvl(high_pic_recid, 0) INTO local.cf_create_time, local.high_df_recid, local.high_ts_recid, local.high_orl_recid, local.high_cdf_recid, local.high_al_recid, local.high_bp_recid, local.high_do_recid, local.high_offr_recid, local.high_pc_recid, local.full_ckp_cf_seq, local.job_ckp_cf_seq, local.high_ic_recid, local.high_bs_recid, local.high_tf_recid, local.high_rt_recid, local.high_grsp_recid, local.high_nrsp_recid, local.high_bcr_recid, local.high_conf_recid, local.force_resync2cf, local.high_pdb_recid, local.high_pic_recid FROM node WHERE site_key = this_site_key; SELECT reset_scn, reset_time into local_reset_scn, local_reset_time FROM dbinc WHERE dbinc_key = this_dbinc_key; ckp_type := RESYNC_NONE; setReason(RESYNC_REASON_NONE); IF (rltime IS NOT NULL AND rltime != local_reset_time) THEN -- -- -- -- -- -- deb('ckptNeeded - rltime='||to_char(rltime)|| ', local_reset_time='||to_char(local_reset_time)); ckp_type := RESYNC_NONE; GOTO ret; ELSIF (cf_version = local.cf_create_time) THEN deb('ckptNeeded - local_reset_scn='||local_reset_scn|| ' lopen_reset_scn='||lopen_reset_scn); deb('ckptNeeded - local_reset_time='||local_reset_time|| ' lopen_reset_time='||lopen_reset_time); -- -- -- -- IF (cf_type = CF_CURRENT AND (lopen_reset_scn IS NULL or local_reset_scn = lopen_reset_scn) AND (lopen_reset_time IS NULL or local_reset_time = lopen_reset_time)) THEN deb('ckptNeeded - high_pdb_recid='||to_char(high_pdb_recid)|| ', local.high_pdb_recid='||to_char(local.high_pdb_recid)); IF (high_pdb_recid > local.high_pdb_recid) THEN ckp_type := RESYNC_FULL; IF local.high_pdb_recid <= 0 THEN setReason(RESYNC_REASON_NOACTION); ELSE setReason(RESYNC_REASON_PDB); END IF; GOTO ret; ELSIF (high_pdb_recid < local.high_pdb_recid) THEN raise_application_error(-20035, 'Invalid high recid'); END IF; deb('ckptNeeded - high_ts_recid='||to_char(high_ts_recid)|| ', local.high_ts_recid='||to_char(local.high_ts_recid)); IF (high_ts_recid > local.high_ts_recid) THEN ckp_type := RESYNC_FULL; IF local.high_ts_recid = 0 THEN setReason(RESYNC_REASON_NOACTION); ELSE setReason(RESYNC_REASON_TS); END IF; GOTO ret; ELSIF (high_ts_recid < local.high_ts_recid) THEN raise_application_error(-20035, 'Invalid high recid'); END IF; deb('ckptNeeded - high_df_recid='||to_char(high_df_recid)|| ', local.high_df_recid='||to_char(local.high_df_recid)); IF (high_df_recid > local.high_df_recid) THEN ckp_type := RESYNC_FULL; setReason(RESYNC_REASON_DF); GOTO ret; ELSIF (high_df_recid < local.high_df_recid) THEN -- -- -- -- raise_application_error(-20035, 'Invalid high recid'); END IF; deb('ckptNeeded - high_tf_recid='||to_char(high_tf_recid)|| ', local.high_tf_recid='||to_char(local.high_tf_recid)); IF (high_tf_recid > local.high_tf_recid) THEN ckp_type := RESYNC_FULL; setReason(RESYNC_REASON_TF); GOTO ret; ELSIF (high_tf_recid < local.high_tf_recid) THEN raise_application_error(-20035, 'Invalid high recid'); END IF; deb('ckptNeeded - high_rt_recid='||to_char(high_rt_recid)|| ', local.high_rt_recid='||to_char(local.high_rt_recid)); IF (high_rt_recid > local.high_rt_recid) THEN ckp_type := RESYNC_FULL; setReason(RESYNC_REASON_THR); GOTO ret; ELSIF (high_rt_recid < local.high_rt_recid) THEN raise_application_error(-20035, 'Invalid high recid'); END IF; deb('ckptNeeded - high_orl_recid='||to_char(high_orl_recid)|| ', local.high_orl_recid='||to_char(local.high_orl_recid)); IF (high_orl_recid > local.high_orl_recid) THEN ckp_type := RESYNC_FULL; setReason(RESYNC_REASON_ORL); GOTO ret; ELSIF (high_orl_recid < local.high_orl_recid) THEN raise_application_error(-20035, 'Invalid high recid'); END IF; -- -- -- deb('ckptNeeded - high_conf_recid='||high_conf_recid|| ', local.high_conf_recid='||local.high_conf_recid); deb(' local.force_resync2cf='||local.force_resync2cf); IF (high_conf_recid != local.high_conf_recid OR local.force_resync2cf = 'YES') THEN ckp_type := RESYNC_FULL; setReason(RESYNC_REASON_CONF); GOTO ret; END IF; -- -- -- deb('ckptNeeded - high_cdf_recid='||to_char(high_cdf_recid)|| ', local.high_cdf_recid='||to_char(local.high_cdf_recid)); IF (high_cdf_recid > local.high_cdf_recid) THEN ckp_type := RESYNC_PARTIAL; GOTO ret; ELSIF (high_cdf_recid < local.high_cdf_recid) THEN raise_application_error(-20035, 'Invalid high recid'); END IF; deb('ckptNeeded - high_al_recid='||to_char(high_al_recid)|| ', local.high_al_recid='||to_char(local.high_al_recid)); IF (high_al_recid > local.high_al_recid) THEN ckp_type := RESYNC_PARTIAL; GOTO ret; ELSIF (high_al_recid < local.high_al_recid) THEN raise_application_error(-20035, 'Invalid high recid'); END IF; deb('ckptNeeded - high_bp_recid='||to_char(high_bp_recid)|| ', local.high_bp_recid='||to_char(local.high_bp_recid)); IF (high_bp_recid > local.high_bp_recid) THEN ckp_type := RESYNC_PARTIAL; GOTO ret; ELSIF (high_bp_recid < local.high_bp_recid) THEN raise_application_error(-20035, 'Invalid high recid'); END IF; deb('ckptNeeded - high_bs_recid='||to_char(high_bs_recid)|| ', local.high_bs_recid='||to_char(local.high_bs_recid)); IF (high_bs_recid > local.high_bs_recid) THEN ckp_type := RESYNC_PARTIAL; GOTO ret; ELSIF (high_bs_recid < local.high_bs_recid) THEN raise_application_error(-20035, 'Invalid high recid'); END IF; deb('ckptNeeded - high_do_recid='||to_char(high_do_recid)|| ', local.high_do_recid='||to_char(local.high_do_recid)); IF (high_do_recid > local.high_do_recid) THEN ckp_type := RESYNC_PARTIAL; GOTO ret; ELSIF (high_do_recid < local.high_do_recid) THEN raise_application_error(-20035, 'Invalid high recid'); END IF; deb('ckptNeeded - high_offr_recid='||to_char(high_offr_recid)|| ', local.high_offr_recid='||to_char(local.high_offr_recid)); IF (high_offr_recid > local.high_offr_recid) THEN ckp_type := RESYNC_PARTIAL; GOTO ret; ELSIF (high_offr_recid < local.high_offr_recid) THEN raise_application_error(-20035, 'Invalid high recid'); END IF; deb('ckptNeeded - high_pc_recid='||to_char(high_pc_recid)|| ', local.high_pc_recid='||to_char(local.high_pc_recid)); IF (high_pc_recid > local.high_pc_recid) THEN ckp_type := RESYNC_PARTIAL; GOTO ret; ELSIF (high_pc_recid < local.high_pc_recid) THEN raise_application_error(-20035, 'Invalid high recid'); END IF; deb('ckptNeeded - high_ic_recid='||to_char(high_ic_recid)|| ', local.high_ic_recid='||to_char(local.high_ic_recid)); IF (high_ic_recid > local.high_ic_recid) THEN ckp_type := RESYNC_PARTIAL; GOTO ret; ELSIF (high_ic_recid < local.high_ic_recid) THEN raise_application_error(-20035, 'Invalid high recid'); END IF; deb('ckptNeeded: high_grsp_recid='||to_char(high_grsp_recid)|| ', local.high_grsp_recid='||to_char(local.high_grsp_recid)); IF (high_grsp_recid > local.high_grsp_recid) THEN ckp_type := RESYNC_PARTIAL; GOTO ret; ELSIF (high_grsp_recid < local.high_grsp_recid) THEN raise_application_error(-20035, 'Invalid high recid'); END IF; deb('ckptNeeded: high_bcr_recid='||to_char(high_bcr_recid)|| ', local.high_bcr_recid='||to_char(local.high_bcr_recid)); IF (high_bcr_recid > local.high_bcr_recid) THEN ckp_type := RESYNC_PARTIAL; GOTO ret; ELSIF (high_bcr_recid < local.high_bcr_recid) THEN raise_application_error(-20035, 'Invalid high recid'); END IF; deb('ckptNeeded: high_nrsp_recid='||to_char(high_nrsp_recid)|| ', local.high_nrsp_recid='||to_char(local.high_nrsp_recid)); IF (high_nrsp_recid > local.high_nrsp_recid) THEN ckp_type := RESYNC_PARTIAL; GOTO ret; ELSIF (high_nrsp_recid < local.high_nrsp_recid) THEN raise_application_error(-20035, 'Invalid high recid'); END IF; deb('ckptNeeded - high_pic_recid='||to_char(high_pic_recid)|| ', local.high_pic_recid='||to_char(local.high_pic_recid)); IF (high_pic_recid > local.high_pic_recid) THEN ckp_type := RESYNC_PARTIAL; GOTO ret; ELSIF (high_pic_recid < local.high_pic_recid) THEN raise_application_error(-20035, 'Invalid high recid'); END IF; ELSE -- IF (cksum = last_resync_cksum AND kccdivts = date2stamp(cf_version)) THEN deb('ckptNeeded - resync checksum same as last checksum'); ckp_type := RESYNC_NONE; ELSE ckp_type := RESYNC_PARTIAL; last_resync_cksum := cksum; END IF; END IF; ELSE -- -- -- -- IF (cf_type = CF_CURRENT) THEN deb('ckptNeeded - cf_type = CF_CURRENT'); ckp_type := RESYNC_FULL; setReason(RESYNC_REASON_CF); ELSE deb('ckptNeeded - cf_type != CF_CURRENT'); IF (cksum = last_resync_cksum AND kccdivts = date2stamp(cf_version)) THEN deb('ckptNeeded - resync checksum same as last checksum'); ckp_type := RESYNC_NONE; ELSE ckp_type := RESYNC_PARTIAL; last_resync_cksum := cksum; END IF; END IF; END IF; <> -- -- -- -- -- -- IF (ckp_type = RESYNC_PARTIAL AND cf_version = local.cf_create_time AND ckp_cf_seq = greatest(local.job_ckp_cf_seq, local.full_ckp_cf_seq)) THEN deb('ckptNeeded - cf_seq has not advanced - do not need a resync'); deb('ckptNeeded - ' || ckp_cf_seq || ',' || local.job_ckp_cf_seq || ',' || local.full_ckp_cf_seq); ckp_type := RESYNC_NONE; END IF; -- IF (ckp_type = RESYNC_NONE) THEN deb('ckptNeeded - resync not needed, rollback, release locks'); rollback; END IF; select decode(ckp_type, RESYNC_NONE, 'RESYNC_NONE', RESYNC_PARTIAL, 'RESYNC_PARTIAL', RESYNC_FULL, 'RESYNC_FULL', 'UNKNOWN') into ckp_desc from dual; deb('ckptNeeded - resync type is ' || ckp_desc); deb('ckptNeeded - returning ckp_type=' ||ckp_type); RETURN ckp_type; -- EXCEPTION WHEN OTHERS THEN deb('ckptNeeded - error, rollback, release locks'); rollback; RAISE; END ckptNeeded; PROCEDURE addTimeZone( db_unique_name IN VARCHAR2 ,db_timezone IN VARCHAR2 ,tmz_src IN VARCHAR2 ,incarnations IN VARCHAR2 default 'CURRENT' )IS prev_tmz node.db_timezone%type; prev_src node.timezone_src%type; l_db_key NUMBER; l_dbinc_key NUMBER; update_cur NUMBER :=0; comma_pos NUMBER; is_valid NUMBER; is_tmz_valid VARCHAR2(7); cur_dbinc NUMBER; tail_dbinc VARCHAR2(256); invalid_keys VARCHAR2(256); l_invalid_val VARCHAR2(256); l_err_no CONSTANT NUMBER := -20244; -- modify in upate_db -- tmz_err EXCEPTION; PRAGMA EXCEPTION_INIT(tmz_err, -20244); BEGIN -- -- -- IF tmz_src = 'P' OR tmz_src = 'A' THEN BEGIN select tz_offset(db_timezone) into is_tmz_valid from dual; EXCEPTION when others THEN l_invalid_val := 'timezone - ' || db_timezone; RAISE tmz_err; END; END IF; -- IF tmz_src = 'R' -- db_key already available during resync THEN l_db_key := this_db_key; select db_timezone, timezone_src into prev_tmz, prev_src from node where node.db_unique_name = upper(addTimeZone.db_unique_name) AND db_key = l_db_key; ELSE -- need to fetch db_key select db_key, db_timezone, timezone_src into l_db_key, prev_tmz, prev_src from node where node.db_unique_name = upper(addTimeZone.db_unique_name); END IF; -- select dbinc_key into l_dbinc_key from dbinc where db_key = l_db_key AND dbinc_status = 'CURRENT'; -- IF incarnations != 'CURRENT' THEN -- is_valid := LENGTH(TRIM(TRANSLATE(incarnations, ',0123456789', ' '))); IF is_valid IS NOT NULL THEN l_invalid_val := 'incarnations - ' || incarnations; RAISE tmz_err; END IF; tail_dbinc := incarnations; IF LENGTH(TRIM(tail_dbinc)) > 0 THEN LOOP comma_pos := instr(tail_dbinc, ','); IF comma_pos = 0 THEN cur_dbinc := TO_NUMBER(TRIM(tail_dbinc)); tail_dbinc := NULL; ELSE cur_dbinc := TO_NUMBER(TRIM(substr(tail_dbinc,1, comma_pos-1))); tail_dbinc := substr(tail_dbinc, comma_pos+1); END IF; -- IF l_dbinc_key = cur_dbinc THEN update_cur := 1; END IF; IF cur_dbinc IS NOT NULL THEN select count(*) into is_valid from dbinc where db_key = l_db_key AND dbinc_key = cur_dbinc; IF is_valid = 0 THEN IF invalid_keys is NULL THEN invalid_keys := cur_dbinc; ELSE invalid_keys := invalid_keys || ',' || cur_dbinc; END IF; END IF; END IF; EXIT WHEN tail_dbinc IS NULL; END LOOP; END IF; END IF; -- IF invalid_keys IS NOT NULL THEN l_invalid_val := 'invalid keys in incarnations - ' || invalid_keys; RAISE tmz_err; END IF; -- -- IF (prev_src IS NULL AND (update_cur = 1 OR incarnations = 'CURRENT')) OR ( --no need to re-update NOT(prev_src = tmz_src AND prev_tmz = db_timezone) AND ( (tmz_src = 'P') OR -- update if coming from parameter file -- (tmz_src = 'A' AND prev_src IN ('A', 'S', 'R') AND (update_cur=1 OR incarnations = 'CURRENT')) OR -- -- -- (tmz_src = 'S' AND prev_src IN ('S', 'P', 'R')) OR -- -- (tmz_src = 'R' AND prev_src = 'R') ) ) THEN UPDATE node SET node.db_timezone = addTimeZone.db_timezone, timezone_src = tmz_src WHERE node.db_unique_name = upper(addTimeZone.db_unique_name) AND db_key = l_db_key; -- could be from resync UPDATE dbinc SET dbinc_timezone = db_timezone WHERE db_key = l_db_key AND dbinc_status = 'CURRENT'; -- IF tmz_src = 'A' THEN update_cur := 2; END IF; END IF; -- IF incarnations != 'CURRENT' THEN -- IF update_cur = 1 AND -- did not allow -- NOT(prev_src = tmz_src AND prev_tmz = db_timezone) THEN l_invalid_val := 'Current incarnation cannot be updated'; RAISE tmz_err; ELSE tail_dbinc := incarnations; IF NVL(LENGTH(TRIM(tail_dbinc)),0) > 0 THEN LOOP comma_pos := NVL(instr(tail_dbinc, ','),0); IF comma_pos = 0 THEN cur_dbinc := TO_NUMBER(TRIM(tail_dbinc)); tail_dbinc := NULL; ELSE cur_dbinc := TO_NUMBER(TRIM(substr(tail_dbinc,1, comma_pos-1))); tail_dbinc := substr(tail_dbinc, comma_pos+1); END IF; IF cur_dbinc != l_dbinc_key -- also checks cur_dbinc is null THEN UPDATE dbinc SET dbinc_timezone = db_timezone WHERE dbinc_key = cur_dbinc AND db_key = l_db_key; END IF; EXIT WHEN tail_dbinc IS NULL; END LOOP; END IF; END IF; END IF; commitChanges('addTimeZone'); EXCEPTION WHEN tmz_err THEN deb(l_invalid_val); raise_application_error(l_err_no, l_invalid_val); WHEN OTHERS THEN deb('Error in addTimeZone, release locks'); ROLLBACK; RAISE; END addTimeZone; PROCEDURE beginCkpt( ckp_scn IN NUMBER ,ckp_cf_seq IN NUMBER ,cf_version IN DATE ,ckp_time IN DATE ,ckp_type IN VARCHAR2 ,ckp_db_status IN VARCHAR2 ,high_df_recid IN NUMBER ,cf_type IN VARCHAR2 DEFAULT 'CURRENT' -- for compatibility reasons ) IS local ckp%rowtype; node_count NUMBER; db_role node.database_role%type; local_dbid NUMBER; local_reset_watermarks boolean := TRUE; BEGIN IF (this_ckp_key IS NOT NULL) THEN raise_application_error(-20030, 'Resync in progress'); END IF; IF (this_dbinc_key IS NULL) THEN raise_application_error(-20020, 'Database incarnation not set'); END IF; IF (this_site_key IS NULL) THEN raise_application_error(-20199, 'Site key is not set'); END IF; IF (cf_type != 'CURRENT' AND ckp_type = 'FULL') THEN raise_application_error(-20072, 'full resync from noncurrent controlfile'); END IF; clearResyncActions; deb('beginCkpt - ckp_type = '||ckp_type||', cf_type ='||cf_type || ', ckp_scn =' || ckp_scn || ', site_key = ' || this_site_key); -- SELECT db_id INTO local_dbid FROM db WHERE db_key = this_db_key FOR UPDATE OF db.db_key; deb('beginCkpt - Obtained all locks for db '|| to_char(this_db_key)); -- -- -- -- -- -- -- -- kccdivts := date2stamp(cf_version); -- save in pkg global -- SELECT ckp_scn, cf_create_time, decode(beginCkpt.ckp_type, 'FULL', full_ckp_cf_seq, greatest(job_ckp_cf_seq, full_ckp_cf_seq)), dbinc_key INTO local.ckp_scn, local.cf_create_time, local.ckp_cf_seq, local.dbinc_key FROM node WHERE site_key = this_site_key; -- last_cf_version_time := local.cf_create_time; -- SELECT max(ckp_key) INTO local.ckp_key FROM ckp WHERE dbinc_key = this_dbinc_key; IF (local.ckp_key IS NULL) THEN deb('beginCkpt - first checkpoint for this incarnation '|| this_dbinc_key); local_reset_watermarks := TRUE; ELSIF (cf_type = 'CURRENT' OR (cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN -- -- -- -- -- -- IF (ckp_type = 'FULL' AND this_dbinc_key = local.dbinc_key) THEN IF (ckp_scn < local.ckp_scn) THEN deb('beginCkpt - cf scn='||ckp_scn||',catalog cf scn='||local.ckp_scn); raise_application_error(-20032, 'Invalid checkpoint SCN'); ELSIF (ckp_scn = local.ckp_scn AND ckp_cf_seq < local.ckp_cf_seq) THEN deb('beginCkpt - cf seq='||ckp_cf_seq||',catalog cf seq='|| local.ckp_cf_seq); raise_application_error(-20033, 'Invalid checkpoint cf seq#'); ELSIF (ckp_scn = local.ckp_scn AND ckp_cf_seq = local.ckp_cf_seq) THEN raise_application_error(-20034, 'Resync not needed'); END IF; END IF; deb('beginCkpt:last_cf_version' || local.cf_create_time); deb('beginCkpt:cf_version' || cf_version); IF (cf_version = local.cf_create_time) THEN deb('beginCkpt - Resync from same last control file'); -- -- -- -- -- IF (ckp_cf_seq < local.ckp_cf_seq AND this_dbinc_key = local.dbinc_key) THEN deb('beginCkpt - cf seq='||ckp_cf_seq||',catalog cf seq='|| local.ckp_cf_seq); raise_application_error(-20033, 'Invalid checkpoint cf seq#'); ELSIF (ckp_cf_seq = local.ckp_cf_seq AND this_dbinc_key = local.dbinc_key) THEN raise_application_error(-20034, 'Resync not needed'); END IF; local_reset_watermarks := FALSE; ELSE deb('beginCkpt - Resync from different control file'); local_reset_watermarks := TRUE; END IF; ELSE -- -- IF (ckp_db_status = 'BACKUP') THEN deb('beginCkpt - Resync from control file copy'); local_reset_watermarks := TRUE; ELSE -- -- IF (kccdivts = sessionWaterMarks.last_kccdivts) THEN deb('beginCkpt - Resync from same backup control file'); local_reset_watermarks := FALSE; ELSE deb('beginCkpt - Resync from different backup control file'); local_reset_watermarks := TRUE; END IF; END IF; END IF; IF (local_reset_watermarks) THEN deb('beginCkpt - init session watermarks'); sessionWaterMarks := init_sessionWaterMarks; sessionWaterMarks.last_kccdivts := kccdivts; END IF; -- -- IF (cf_type = 'CURRENT' OR cf_type = 'CREATED' OR (cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN IF NOT local_reset_watermarks THEN deb('beginCkpt - update ckp_scn and use existing water marks'); -- UPDATE node SET ckp_scn = greatest(ckp_scn, decode(beginCkpt.ckp_type, 'FULL', beginCkpt.ckp_scn, 0)), full_ckp_cf_seq = greatest(full_ckp_cf_seq, decode(beginCkpt.ckp_type, 'FULL', beginCkpt.ckp_cf_seq, 0)), job_ckp_cf_seq = greatest(job_ckp_cf_seq, decode(beginCkpt.ckp_type, 'PARTIAL', beginCkpt.ckp_cf_seq, 0)), bcr_in_use = nvl2(high_bcr_recid, 'YES', 'NO') WHERE site_key = this_site_key; ELSE -- -- -- -- -- -- -- -- -- -- -- deb('beginCkpt - update ckp_scn and reset water marks, this_site_key '|| this_site_key); UPDATE node SET cf_create_time = beginCkpt.cf_version, dbinc_key = this_dbinc_key, ckp_scn = decode(beginCkpt.ckp_type, 'FULL', beginCkpt.ckp_scn, 0), full_ckp_cf_seq = decode(beginCkpt.ckp_type, 'FULL', beginCkpt.ckp_cf_seq, 0), job_ckp_cf_seq = decode(beginCkpt.ckp_type, 'PARTIAL', beginCkpt.ckp_cf_seq, 0), high_ic_recid = 0, high_ts_recid = NULL, high_df_recid = NULL, high_rt_recid = NULL, high_orl_recid = NULL, high_offr_recid = 0, high_rlh_recid = 0, high_al_recid = 0, high_bs_recid = 0, high_bp_recid = 0, high_bdf_recid = 0, high_cdf_recid = 0, high_brl_recid = 0, high_bcb_recid = 0, high_ccb_recid = 0, high_do_recid = 0, high_pc_recid = 0, high_bsf_recid = 0, high_rsr_recid = 0, high_tf_recid = 0, high_grsp_recid = 0, high_nrsp_recid = 0, high_bcr_recid = 0, bcr_in_use = nvl2(high_bcr_recid, 'YES', 'NO'), high_pdb_recid = NULL, high_pic_recid = 0 WHERE site_key = this_site_key; END IF; ELSE -- UPDATE node SET cf_create_time = beginCkpt.cf_version, dbinc_key = this_dbinc_key, ckp_scn = decode(beginCkpt.ckp_type, 'FULL', beginCkpt.ckp_scn, 0), full_ckp_cf_seq = decode(beginCkpt.ckp_type, 'FULL', beginCkpt.ckp_cf_seq, 0), job_ckp_cf_seq = decode(beginCkpt.ckp_type, 'PARTIAL', beginCkpt.ckp_cf_seq, 0), bcr_in_use = nvl2(high_bcr_recid, 'YES', 'NO') WHERE site_key = this_site_key; END IF; SELECT max(ckp_scn) INTO last_full_ckp_scn FROM ckp WHERE ckp_type = 'FULL' AND dbinc_key = this_dbinc_key; deb('beginCkpt - last_full_ckp_scn ' || last_full_ckp_scn); -- BEGIN INSERT INTO ckp (ckp_key, ckp_scn, ckp_cf_seq, cf_create_time, ckp_time, dbinc_key, ckp_type, ckp_db_status, resync_time, site_key) VALUES (rman_seq.nextval, ckp_scn, ckp_cf_seq, cf_version, ckp_time, this_dbinc_key, beginCkpt.ckp_type, ckp_db_status, sysdate, this_site_key) RETURNING ckp_key INTO this_ckp_key; EXCEPTION WHEN dup_val_on_index THEN IF (cf_type = 'CURRENT' OR (cf_type = 'STANDBY' AND this_db_unique_name IS NOT NULL)) THEN RAISE; ELSE -- -- -- -- -- -- raise_application_error(-20034, 'Resync not needed'); END IF; END; SELECT count(*) INTO node_count FROM node WHERE node.db_key = this_db_key AND node.db_unique_name = this_db_unique_name; IF (node_count = 0 AND this_db_unique_name IS NOT NULL) THEN IF substr(this_db_unique_name,1,1) = '$' THEN db_role := 'RA'; ELSE IF (cf_type = 'STANDBY') THEN db_role := 'STANDBY'; ELSE db_role := 'PRIMARY'; END IF; END IF; deb('beginCkpt - adding node row with force_resync2cf=NO' || ', db_unique_name = ' || this_db_unique_name || ', db_role = ' || db_role); INSERT INTO node(db_unique_name, db_key, high_conf_recid, force_resync2cf, database_role, site_key) VALUES(this_db_unique_name, this_db_key, 0, 'NO', db_role, rman_seq.nextval); END IF; this_ckp_scn := ckp_scn; this_ckp_time := ckp_time; this_cf_type := cf_type; this_cf_version := cf_version; this_ckp_type := ckp_type; deb('beginCkpt:this_cf_type' || this_cf_type); deb('beginCkpt:this_cf_version' || this_cf_version); deb('beginCkpt: clearing watermark indexes'); -- -- select rman_seq.currval into this_bp_key_poll from dual; getPolled_AL := TRUE; IF feedback_al%ISOPEN THEN CLOSE feedback_al; END IF; IF feedback_bp%ISOPEN THEN CLOSE feedback_bp; END IF; IF this_is_ors THEN this_enable_populate_rsr := getValueFromConfig('_enable_populate_rsr_key'); END IF; -- EXCEPTION WHEN OTHERS THEN deb('beginCkpt - error, rollback, release locks'); rollback; RAISE; END beginCkpt; PROCEDURE clearCursorVariables IS BEGIN pdbRec.guid := NULL; picRec.guid := NULL; tsRec.ts# := NULL; dfRec.file# := NULL; tfRec.file# := NULL; rtRec.thread# := NULL; orlRec.fname := NULL; grspRec.rspname := NULL; END clearCursorVariables; PROCEDURE endCkpt IS BEGIN deb('endCkpt:Updating watermarks for backup related columns'); deb('endCkpt:this_curr_bp_recid=' || this_curr_bp_recid); deb('endCkpt:this_high_bp_recid=' || this_high_bp_recid); IF this_curr_bp_recid <> this_high_bp_recid THEN UPDATE watermarks SET high_bp_recid = this_high_bp_recid WHERE db_key = this_db_key; END IF; -- IF this_ckp_type = 'FULL' THEN deb('endCkpt:this_cf_version updated=' || this_cf_version); UPDATE watermarks SET cf_version_stamp = this_cf_version WHERE db_key = this_db_key; END IF; -- -- this_enable_populate_rsr := NULL; this_upstream_site_key := NULL; -- IF this_lock_ors_inspect THEN this_ckp_key := NULL; -- and update state variable this_ckp_scn := NULL; this_ckp_time := NULL; this_cf_type := NULL; this_cf_version := NULL; last_cf_version_time := NULL; this_ckp_type := NULL; commitChanges('endCkpt-1'); ELSE checkResync; IF (tsRec.ts# IS NOT NULL) THEN raise_application_error(-20041, 'Tablespace resync not completed'); END IF; IF (dfRec.file# IS NOT NULL) THEN raise_application_error(-20051, 'Datafile resync not completed'); END IF; this_ckp_key := NULL; -- and update state variable this_ckp_scn := NULL; this_ckp_time := NULL; this_cf_type := NULL; this_cf_version := NULL; last_cf_version_time := NULL; this_ckp_type := NULL; -- clearCursorVariables; -- -- -- IF this_clr_ba_newinc_err AND this_is_ors THEN deb('endckpt:fix_error for db_key = '||this_db_key); -- -- -- EXECUTE IMMEDIATE 'BEGIN dbms_rai_fix_error( error_num => -64735); END;' ; this_clr_ba_newinc_err := FALSE; END IF; commitChanges('endCkpt-2'); prev_sessionWaterMarks := sessionWaterMarks; /* Do not run cleanupTempResource when connected to a virtual catalog, * because we do not allow merging catalogs to be done by a virtual * catalog user. The cleanuopTempResource executes DDLs that will * automatically commit and release locks */ if user = g_catowner then cleanupTempResource; end if; END IF; END endCkpt; PROCEDURE cancelCkpt IS BEGIN deb('cancelCkpt - rollback, release locks'); rollback; -- -- this_enable_populate_rsr := NULL; this_upstream_site_key := NULL; -- -- IF this_lock_ors_inspect THEN return; END IF; sessionWaterMarks := prev_sessionWaterMarks; IF (this_ckp_key IS NOT NULL) THEN -- this_ckp_key := NULL; this_ckp_scn := NULL; this_ckp_time := NULL; END IF; IF pdbQ%ISOPEN THEN CLOSE pdbQ; END IF; IF picQ%ISOPEN THEN CLOSE picQ; END IF; IF tsQ%ISOPEN THEN CLOSE tsQ; END IF; IF dfQ%ISOPEN THEN CLOSE dfQ; END IF; IF tfQ%ISOPEN THEN CLOSE tfQ; END IF; IF rtQ%ISOPEN THEN CLOSE rtQ; END IF; IF orlQ%ISOPEN THEN CLOSE orlQ; END IF; IF grspQ%ISOPEN THEN CLOSE grspQ; END IF; IF bpq%ISOPEN THEN CLOSE bpq; END IF; IF feedback_al%ISOPEN THEN CLOSE feedback_al; END IF; IF feedback_bp%ISOPEN THEN CLOSE feedback_bp; END IF; -- clearCursorVariables; -- last_resync_cksum := NULL; END cancelCkpt; -- -- FUNCTION lastFullCkpt RETURN NUMBER IS BEGIN RETURN last_full_ckp_scn; END lastFullCkpt; /* Feedback about files polled by OAM */ FUNCTION getPolledAl (rec_type OUT NUMBER, recid OUT NUMBER, stamp OUT NUMBER, fname OUT VARCHAR2) RETURN BOOLEAN IS al_rec feedback_al%ROWTYPE; BEGIN IF NOT feedback_al%ISOPEN THEN deb('getPolledAl - open feedback_al, bp_key_poll=' || curr_bp_key_poll); OPEN feedback_al(curr_bp_key_poll); END IF; FETCH feedback_al INTO al_rec; IF feedback_al%NOTFOUND THEN CLOSE feedback_al; deb('getPolledAl - closing feedback_al'); RETURN FALSE; ELSE deb('getPolledAl - recid='||al_rec.recid||',stamp='||al_rec.stamp); deb('getPolledAl - fname='||al_rec.fname); rec_type := RTYP_ARCHIVED_LOG; recid := al_rec.recid; stamp := al_rec.stamp; fname := al_rec.fname; RETURN TRUE; END IF; END getPolledAl; FUNCTION haveProcessedBS (disk_bs_key IN NUMBER) RETURN BOOLEAN IS to_process NUMBER; BEGIN deb('haveProcessedBS - disk_bs_key='||disk_bs_key); -- -- to_process := 0; FOR cur_rec IN (SELECT file#, create_scn, ckp_scn, dbinc_key FROM bdf where bs_key=disk_bs_key MINUS SELECT a.file#, a.create_scn, a.ckp_scn, a.dbinc_key FROM bdf a, (SELECT bs_key, file#, create_scn, ckp_scn, dbinc_key FROM bdf WHERE bs_key=disk_bs_key) b WHERE b.file#=a.file# AND b.create_scn=a.create_scn AND b.ckp_scn=a.ckp_scn AND b.dbinc_key=a.dbinc_key AND b.bs_key <> a.bs_key AND a.bs_key IN (SELECT bs_key FROM bp WHERE handle like 'VB$%' AND db_key = this_db_key AND bp_key > curr_bp_key_poll)) LOOP to_process := to_process + 1; deb('haveProcessedBS - not processed file#='||cur_rec.file#|| ',create_scn='||cur_rec.create_scn|| ',ckp_scn='||cur_rec.ckp_scn|| ',dbinc_key='||cur_rec.dbinc_key); END LOOP; IF to_process = 0 THEN deb('haveProcessedBS - Disk backupset processed by OAM'); return TRUE; END IF; return FALSE; END haveProcessedBS; FUNCTION getPolledBP (rec_type OUT NUMBER, recid OUT NUMBER, stamp OUT NUMBER, fname OUT VARCHAR2) RETURN BOOLEAN IS to_process NUMBER; bp_rec feedback_bp%ROWTYPE; BEGIN IF NOT feedback_bp%ISOPEN THEN deb('getPolledBP - open feedback_bp, bp_key_poll=' || curr_bp_key_poll); OPEN feedback_bp(curr_bp_key_poll); END IF; IF disk_bp_rec.bs_key is NOT NULL THEN deb('getPolledBP - have cached disk piece = '||disk_bp_rec.handle); IF haveProcessedBS(disk_bp_rec.bs_key) THEN rec_type := RTYP_BACKUP_PIECE; recid := disk_bp_rec.recid; stamp := disk_bp_rec.stamp; fname := disk_bp_rec.handle; disk_bp_rec := null; deb('getPolledBP - Purgable'); RETURN TRUE; ELSE disk_bp_rec := null; deb('getPolledBP - Not purgable'); END IF; END IF; <> FETCH feedback_bp INTO bp_rec; IF feedback_bp%NOTFOUND THEN CLOSE feedback_bp; deb('getPolledBP - closing feedback_bp'); RETURN FALSE; ELSE deb('getPolledBP - bs_key='||bp_rec.bs_key||',piece#='||bp_rec.piece#|| ',device_type='||bp_rec.device_type||',ba_access='||bp_rec.ba_access); deb('getPolledBP - recid='||bp_rec.recid||',stamp='||bp_rec.stamp|| ',site_key='||bp_rec.site_key); deb('getPolledBP - handle='||bp_rec.handle); IF disk_bp_rec.bs_key is NULL AND bp_rec.device_type = 'DISK' THEN disk_bp_rec := bp_rec; deb('getPolledBP - fetch next; Chk disk piece=' ||disk_bp_rec.handle); goto get_next_rec; END IF; IF disk_bp_rec.bs_key is NULL THEN deb('getPolledBP - fetch next; No disk piece to check'); goto get_next_rec; END IF; IF bp_rec.device_type = 'SBT_TAPE' AND bp_rec.bs_key = disk_bp_rec.bs_key AND bp_rec.piece# = disk_bp_rec.piece# THEN -- -- IF bp_rec.ba_access = 'L' OR bp_rec.ba_access = 'T' THEN rec_type := RTYP_BACKUP_PIECE; recid := disk_bp_rec.recid; stamp := disk_bp_rec.stamp; fname := disk_bp_rec.handle; disk_bp_rec := null; deb('getPolledBP - Disk backuppiece copied by OAM'); RETURN TRUE; -- -- -- ELSIF bp_rec.ba_access = 'D' AND haveProcessedBS(disk_bp_rec.bs_key) THEN rec_type := RTYP_BACKUP_PIECE; recid := disk_bp_rec.recid; stamp := disk_bp_rec.stamp; fname := disk_bp_rec.handle; disk_bp_rec := null; deb('getPolledBP - Polled Disk backuppiece processed'); RETURN TRUE; END IF; ELSE -- -- IF haveProcessedBS(disk_bp_rec.bs_key) THEN rec_type := RTYP_BACKUP_PIECE; recid := disk_bp_rec.recid; stamp := disk_bp_rec.stamp; fname := disk_bp_rec.handle; IF bp_rec.device_type = 'DISK' THEN disk_bp_rec := bp_rec; -- save for next call, to avoid fetch ELSE disk_bp_rec := null; END IF; return TRUE; ELSE deb('getPolledBP - Disk backuppiece not processed - check next'); IF bp_rec.device_type = 'DISK' THEN disk_bp_rec := bp_rec; -- save for next call, to avoid fetch ELSE disk_bp_rec := null; END IF; END IF; END IF; deb('getPolledBP - fetch next'); goto get_next_rec; END IF; END getPolledBP; FUNCTION getPolledRec(rec_type OUT NUMBER, recid OUT NUMBER, stamp OUT NUMBER, fname OUT VARCHAR2) RETURN BOOLEAN IS BEGIN -- -- IF NOT (this_is_ors AND (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' and this_db_unique_name is not null))) THEN RETURN FALSE; END IF; SELECT bp_key_poll into curr_bp_key_poll FROM node WHERE site_key = this_site_key; IF getPolled_AL THEN IF (getPolledAL(rec_type, recid, stamp, fname)) THEN RETURN TRUE; ELSE getPolled_BP := TRUE; getPolled_AL := FALSE; END IF; END IF; IF getPolled_BP THEN IF (getPolledBP(rec_type, recid, stamp, fname)) THEN RETURN TRUE; END IF; END IF; -- -- deb('getPolledRec - Polling bp_key='||this_bp_key_poll); getPolled_BP := FALSE; getPolled_AL := FALSE; RETURN FALSE; END getPolledRec; /*---------------------* * Pluggable DB Resync * *---------------------*/ PROCEDURE fetchPdb IS -- this is private to the pkg body BEGIN FETCH pdbQ INTO pdbRec; -- get next row IF pdbQ%NOTFOUND THEN pdbRec.guid := NULL; -- indicate end of fetch CLOSE pdbQ; ELSE deb('fetchPdb - '||pdbRec.name||' ('||to_char(pdbRec.con_id)||') '|| to_char(pdbRec.guid)); END IF; END fetchPdb; PROCEDURE addPdb( name IN VARCHAR2 ,con_id IN NUMBER ,db_id IN NUMBER ,create_scn IN NUMBER ,guid IN RAW ,nobackup IN VARCHAR2) IS local pdb%rowtype; BEGIN deb('addPdb - db_id '|| to_char(db_id)); INSERT INTO pdb (pdb_key, db_key, name, con_id, db_id, create_scn, guid, nobackup) VALUES (rman_seq.nextval, this_db_key, name, con_id, db_id, create_scn, guid, nobackup); END addPdb; PROCEDURE dropPdb( -- private to package body pdb_key IN NUMBER ,drop_scn IN NUMBER ,drop_time IN DATE ) IS BEGIN deb('dropPdb - pdb_key ' || to_char(pdb_key)); UPDATE pdb_dbinc SET drop_scn = dropPdb.drop_scn, drop_time = dropPdb.drop_time WHERE pdb_dbinc.dbinc_key = this_dbinc_key AND pdb_dbinc.pdb_key = dropPdb.pdb_key AND pdb_dbinc.drop_scn IS NULL; END dropPdb; FUNCTION beginPluggableDBResync( high_pdb_recid IN NUMBER) RETURN BOOLEAN IS BEGIN checkResync; -- -- -- -- -- SELECT high_pdb_recid INTO last_pdb_recid FROM node WHERE site_key = this_site_key; IF (high_pdb_recid = last_pdb_recid) THEN deb('beginPluggableDBResync - Resync of PDBs not needed'); RETURN FALSE; ELSIF (high_pdb_recid > last_pdb_recid OR last_pdb_recid IS NULL) THEN deb('beginPluggableDBResync - Catalog pdb_recid: '|| last_pdb_recid); deb('beginPluggableDBResync - High pdb_recid: '|| high_pdb_recid); last_pdb_recid := high_pdb_recid; OPEN pdbQ; -- just open that cursor please fetchPdb; -- do priming read last_guid := NULL; -- initialize for ordering assert if resync_reason = RESYNC_REASON_PDB then fullResyncAction.active := TRUE; fullResyncAction.valid := TRUE; fullResyncAction.objtype := RESYNC_OBJECT_PDB; else fullResyncAction.active := FALSE; end if; RETURN TRUE; ELSE raise_application_error(-20035, 'Invalid high recid'); END IF; END beginPluggableDBResync; PROCEDURE checkPluggableDB( name IN VARCHAR2 ,con_id IN NUMBER ,db_id IN NUMBER ,create_scn IN NUMBER ,guid IN RAW ,nobackup IN VARCHAR2 DEFAULT 'N' ) IS dbinc_key number; BEGIN IF (last_guid >= guid) THEN raise_application_error(-20036, 'Invalid record order'); END IF; last_guid := guid; WHILE (guid > pdbRec.guid) LOOP dropPdb(pdbRec.pdb_key, this_ckp_scn, this_ckp_time); incResyncActions(RESYNC_ACTION_DROP, pdbRec.con_id, pdbRec.name); fetchPdb; END LOOP; IF (guid < pdbRec.guid OR pdbRec.guid IS NULL) THEN IF (con_id IN (1, 0)) THEN IF (guid != ZERO_GUID) THEN UPDATE pdb SET guid = checkPluggableDb.guid WHERE pdb.db_key = this_db_key AND pdb.con_id = checkPluggableDb.con_id; END IF; ELSE -- addPdb(name, con_id, db_id, create_scn, guid, nobackup); incResyncActions(RESYNC_ACTION_ADD, con_id, name); END IF; ELSE -- (guid = pdbRec.guid) -- IF (pdbRec.con_id != con_id OR pdbRec.create_scn != create_scn) THEN deb('checkPluggableDb - drop and add new pdb'); dropPdb(pdbRec.pdb_key, this_ckp_scn, this_ckp_time); UPDATE pdb SET name = checkPluggableDB.name, con_id = checkPluggableDB.con_id, create_scn = checkPluggableDB.create_scn, db_id = checkPluggableDB.db_id, nobackup = checkPluggableDB.nobackup WHERE pdb.pdb_key = pdbRec.pdb_key; incResyncActions(RESYNC_ACTION_RENAME, con_id, name); ELSIF (pdbRec.name != name OR pdbRec.nobackup != nobackup) THEN deb('checkPluggableDb - update name/nobackup'); UPDATE pdb SET name = checkPluggableDB.name, nobackup = checkPluggableDB.nobackup WHERE pdb.pdb_key = pdbRec.pdb_key; incResyncActions(RESYNC_ACTION_RENAME, con_id, name); ELSE deb('checkPluggableDb - pdb already known'); END IF; fetchPdb; END IF; END checkPluggableDB; PROCEDURE endPluggableDBResync IS BEGIN checkResync; WHILE (pdbRec.guid IS NOT NULL) LOOP -- while extra tablespaces in rcvcat dropPdb(pdbRec.pdb_key, this_ckp_scn, this_ckp_time); incResyncActions(RESYNC_ACTION_DROP, pdbRec.con_id, pdbRec.name); fetchPdb; END LOOP; -- pdbRec.guid := NULL; -- UPDATE node SET high_pdb_recid = nvl(last_pdb_recid, high_pdb_recid) WHERE site_key = this_site_key; last_pdb_recid := NULL; END endPluggableDBResync; /*-------------------* * Tablespace Resync * *-------------------*/ PROCEDURE fetchTs IS -- this is private to the pkg body BEGIN FETCH tsQ INTO tsRec; -- get next row IF tsQ%NOTFOUND THEN tsRec.con_id := MAXNUMVAL; -- indicate end of fetch tsRec.ts# := MAXNUMVAL; tsRec.pdb_drop_scn := NULL; CLOSE tsQ; ELSE deb('fetchTs - '||tsRec.ts_name||' ('||to_char(tsRec.ts#)||') '|| to_char(tsRec.create_scn) || ';plugin_scn='||to_char(tsRec.plugin_scn)); END IF; END fetchTs; PROCEDURE addTs( ts_name IN VARCHAR2 ,ts# IN NUMBER ,create_scn IN NUMBER ,create_time IN DATE ,rbs_count IN NUMBER ,included_in_database_backup IN VARCHAR2 ,bigfile IN VARCHAR2 ,temporary IN VARCHAR2 ,encrypt_in_backup IN VARCHAR2 ,plugin_scn IN NUMBER ,pdbinc_key IN NUMBER ) IS BEGIN deb('addTs - tablespace '||ts_name||' ('||to_char(ts#)||') '|| to_char(create_scn) || ',plugin_scn=' || to_char(plugin_scn)); INSERT INTO ts (dbinc_key, ts#, ts_name, create_scn, create_time, included_in_database_backup, bigfile, temporary, encrypt_in_backup, plugin_scn, pdbinc_key) VALUES (this_dbinc_key, ts#, ts_name, create_scn, create_time, included_in_database_backup, bigfile, temporary, encrypt_in_backup, plugin_scn, pdbinc_key); INSERT INTO tsatt (dbinc_key, ts#, create_scn, start_ckp_key, rbs_count, plugin_scn, pdbinc_key) VALUES (this_dbinc_key, ts#, create_scn, this_ckp_key, rbs_count, plugin_scn, pdbinc_key); END addTs; PROCEDURE dropTs( -- private to package body ts# IN NUMBER ,create_scn IN NUMBER ,drop_scn IN NUMBER ,drop_time IN DATE ,plugin_scn IN NUMBER ,pdbinc_key IN NUMBER ) IS BEGIN deb('dropTs - tablespace '||to_char(ts#)||' - '||to_char(create_scn) || ',plugin_scn - ' || plugin_scn); UPDATE ts SET drop_scn = dropTs.drop_scn, drop_time = dropTs.drop_time WHERE ts.dbinc_key = this_dbinc_key AND ts.pdbinc_key = dropTs.pdbinc_key AND ts.ts# = dropTs.ts# AND ts.create_scn = dropTs.create_scn AND ts.plugin_scn = dropTs.plugin_scn; deb('dropTs - returning'); END dropTs; PROCEDURE renameTs( ts_name IN VARCHAR2 ,dbinc_key IN NUMBER ,ts# IN NUMBER ,create_scn IN NUMBER ,plugin_scn IN NUMBER ,pdbinc_key IN NUMBER ) IS BEGIN UPDATE ts SET ts.ts_name = renameTs.ts_name WHERE ts.dbinc_key = renameTs.dbinc_key AND ts.pdbinc_key = renameTs.pdbinc_key AND ts.ts# = renameTs.ts# AND ts.create_scn = renameTs.create_scn AND ts.plugin_scn = renameTs.plugin_scn; END renameTs; FUNCTION beginTableSpaceResync( high_ts_recid IN NUMBER, force IN BOOLEAN DEFAULT FALSE) RETURN BOOLEAN IS BEGIN checkResync; -- -- -- -- -- -- -- SELECT high_ts_recid INTO last_ts_recid FROM node WHERE site_key = this_site_key; IF (high_ts_recid = last_ts_recid AND NOT force) THEN deb('beginTableSpaceResync - Resync of tablespaces not needed'); RETURN FALSE; ELSIF (high_ts_recid > last_ts_recid OR last_ts_recid IS NULL OR high_ts_recid IS NULL OR force) THEN deb('beginTableSpaceResync - Catalog ts_recid: '||last_ts_recid); deb('beginTableSpaceResync - High ts_recid: '||high_ts_recid); last_ts_recid := high_ts_recid; OPEN tsQ; -- just open that cursor please fetchTs; -- do priming read last_con_id_ts# := -1; -- initialize for ordering assert last_ts# := -1; -- initialize for ordering assert if resync_reason = RESYNC_REASON_TS then fullResyncAction.active := TRUE; fullResyncAction.valid := TRUE; fullResyncAction.objtype := RESYNC_OBJECT_TABLESPACE; else fullResyncAction.active := FALSE; end if; RETURN TRUE; ELSE raise_application_error(-20035, 'Invalid high recid'); END IF; END beginTableSpaceResync; PROCEDURE checkTableSpace( ts_name IN VARCHAR2 ,ts# IN NUMBER ,create_scn IN NUMBER ,create_time IN DATE ,rbs_count IN NUMBER DEFAULT NULL ,included_in_database_backup IN VARCHAR2 DEFAULT NULL ,bigfile IN VARCHAR2 DEFAULT NULL ,temporary IN VARCHAR2 DEFAULT NULL ,encrypt_in_backup IN VARCHAR2 DEFAULT NULL ,plugin_scn IN NUMBER DEFAULT 0 ,con_id IN NUMBER DEFAULT 0 ,pdb_dict_check IN BOOLEAN DEFAULT FALSE ) IS -- -- -- idb varchar2(3) := nvl(included_in_database_backup, 'YES'); -- bf varchar2(3) := nvl(bigfile, 'NO'); -- actual default value tmp varchar2(3) := nvl(temporary, 'NO'); -- actual default value ts_changed boolean := FALSE; local_pdbinc_key number; local_pdb_key number; BEGIN IF (tsRec.ts# IS NULL) THEN -- assert beginTableSpaceResync was called raise_application_error(-20040, 'Tablespace resync not started'); END IF; -- IF (last_con_id_ts# > con_id) THEN raise_application_error(-20036, 'Invalid record order'); END IF; IF (con_id > last_con_id_ts#) THEN last_ts# := -1; END IF; IF (last_ts# >= ts#) THEN raise_application_error(-20036, 'Invalid record order'); END IF; -- -- -- -- IF (temporary IS NOT NULL) THEN do_temp_ts_resync := TRUE; END IF; -- last_con_id_ts# := con_id; last_ts# := ts#; -- -- -- IF (create_scn > this_ckp_scn AND tmp = 'NO') THEN raise_application_error(-20042, 'Invalid tablespace create SCN'); END IF; -- -- -- -- -- -- -- deb('checkTableSpace - ts#: ' || ts# || ' tsRec.ts#: ' || tsRec.ts# || ' con_id ' || con_id || ' tsRec.con_id: ' || tsRec.con_id || ' tsRec.pdb_drop_scn ' || tsRec.pdb_drop_scn); WHILE (con_id > tsRec.con_id OR (tsRec.con_id = con_id AND ts# > tsRec.ts#) OR tsRec.pdb_drop_scn IS NOT NULL) LOOP IF (tsRec.temporary = 'NO' OR -- is a permanent tablespace do_temp_ts_resync) THEN -- is a 10gR2 or later rman client deb('checkTableSpace - before calling dropTS'); dropTs(tsRec.ts#, tsRec.create_scn, this_ckp_scn, this_ckp_time, tsRec.plugin_scn, tsRec.pdbinc_key); deb('checkTableSpace - before calling incResyncActions'); begin incResyncActions(RESYNC_ACTION_DROP, tsRec.ts#, tsRec.ts_name); exception when others then deb('checkTableSpace - (DO_NOT_IGNORE)caught exception ' || substr(sqlerrm, 1, 132)); end; deb('checkTableSpace - after calling incResyncActions'); END IF; deb('checkTableSpace - before calling fetchTS'); fetchTs; deb('checkTableSpace - after calling fetchTS'); END LOOP; deb('checkTableSpace -out of loop, ts#: ' || ts# || ' tsRec.ts#: ' || tsRec.ts# || ' con_id ' || con_id || ' tsRec.con_id: ' || tsRec.con_id); IF (con_id != tsRec.con_id OR ts# < tsRec.ts#) THEN IF (pdb_dict_check) THEN deb('checkTableSpace - skipping tablespace needs dictionary check'); ELSE -- local_pdbinc_key := getPdbInc(greatest(create_scn, plugin_scn), con_id, local_pdb_key); addTs(ts_name, ts#, create_scn, create_time, rbs_count, idb, bf, tmp, encrypt_in_backup, plugin_scn, local_pdbinc_key); END IF; incResyncActions(RESYNC_ACTION_ADD, ts#, ts_name); ELSE -- (con_id = tsRec.con_id AND ts# = tsRec.ts#) IF (pdb_dict_check) THEN deb('checkTableSpace - skipping tablespace needs dictionary check'); goto next_Ts; END IF; IF (create_scn = tsRec.create_scn) THEN -- -- IF (create_time <> tsRec.create_time) THEN raise_application_error(-20043, 'Invalid tablespace create time'); END IF; IF (plugin_scn > 0) THEN IF (tsRec.plugin_scn < checkTableSpace.plugin_scn) THEN deb('checkTableSpace - plugin read only tbs dropped and replugged'); -- -- -- dropTs(tsRec.ts#, tsRec.create_scn, this_ckp_scn, this_ckp_time, tsRec.plugin_scn, tsRec.pdbinc_key); incResyncActions(RESYNC_ACTION_DROP, tsRec.ts#, tsRec.ts_name); addTs(ts_name, ts#, create_scn, create_time, rbs_count, idb, bf, tmp, encrypt_in_backup, plugin_scn, tsRec.curr_pdbinc_key); incResyncActions(RESYNC_ACTION_ADD, ts#, ts_name); goto next_Ts; ELSIF (tsRec.plugin_scn > checkTableSpace.plugin_scn) THEN -- raise_application_error(-20055, 'Invalid tablespace plugin SCN'); ELSE -- -- deb('checkTableSpace - known plugged in tablespace'); END IF; END IF; -- -- IF (ts_name <> tsRec.ts_name) THEN renameTs(ts_name, this_dbinc_key, tsRec.ts#, tsRec.create_scn, tsRec.plugin_scn, tsRec.pdbinc_key); incResyncActions(RESYNC_ACTION_RENAME, tsRec.ts#, ts_name); END IF; -- -- IF (idb <> nvl(tsRec.included_in_database_backup,'XX')) THEN UPDATE ts SET ts.included_in_database_backup = checkTableSpace.included_in_database_backup WHERE ts.dbinc_key = this_dbinc_key AND ts.ts# = tsRec.ts# AND ts.pdbinc_key = tsRec.pdbinc_key AND ts.create_scn = tsRec.create_scn AND ts.plugin_scn = tsRec.plugin_scn; ts_changed := TRUE; END IF; -- -- IF (tsRec.encrypt_in_backup is null and encrypt_in_backup is not null OR tsRec.encrypt_in_backup is not null and encrypt_in_backup is null OR tsRec.encrypt_in_backup <> encrypt_in_backup) THEN UPDATE ts SET ts.encrypt_in_backup = checkTableSpace.encrypt_in_backup WHERE ts.dbinc_key = this_dbinc_key AND ts.ts# = tsRec.ts# AND ts.pdbinc_key = tsRec.pdbinc_key AND ts.create_scn = tsRec.create_scn AND ts.plugin_scn = tsRec.plugin_scn; ts_changed := TRUE; END IF; -- -- IF (rbs_count <> nvl(tsRec.rbs_count,-1)) THEN UPDATE tsatt SET end_ckp_key = this_ckp_key WHERE tsatt.dbinc_key = this_dbinc_key AND tsatt.ts# = tsRec.ts# AND tsatt.pdbinc_key = tsRec.pdbinc_key AND tsatt.create_scn = tsRec.create_scn AND tsatt.plugin_scn = tsRec.plugin_scn AND tsatt.end_ckp_key IS NULL; INSERT INTO tsatt(dbinc_key, ts#, create_scn, start_ckp_key, rbs_count, plugin_scn, pdbinc_key) VALUES(this_dbinc_key, tsRec.ts#, tsRec.create_scn, this_ckp_key, rbs_count, tsRec.plugin_scn, tsRec.pdbinc_key); ts_changed := TRUE; END IF; if ts_changed then incResyncActions(RESYNC_ACTION_CHANGE, tsRec.ts#, tsRec.ts_name); end if; ELSIF (create_scn = 0 AND tmp = 'YES') THEN -- -- -- dropTs(tsRec.ts#, tsRec.create_scn, create_scn, create_time, tsRec.plugin_scn, tsRec.pdbinc_key); DELETE FROM ts WHERE ts.dbinc_key = this_dbinc_key AND ts.ts# = checkTableSpace.ts# AND ts.pdbinc_key = tsRec.pdbinc_key AND ts.create_scn = 0 AND ts.plugin_scn = 0; addTs(ts_name, ts#, create_scn, create_time, rbs_count, idb, bf, tmp, encrypt_in_backup, plugin_scn, tsRec.curr_pdbinc_key); incResyncActions(RESYNC_ACTION_CHANGE, tsRec.ts#, ts_name); ELSE IF (tmp = 'YES') THEN -- -- IF (tsRec.temporary = 'NO') THEN dropTs(tsRec.ts#, tsRec.create_scn, create_scn, create_time, tsRec.plugin_scn, tsRec.pdbinc_key); END IF; -- -- -- -- -- DELETE FROM ts WHERE ts.dbinc_key = this_dbinc_key AND ts.ts# = checkTablespace.ts# AND ts.pdbinc_key = tsRec.pdbinc_key AND ts.temporary = 'YES'; deb('Deleting tablespace entry for ts#=' || ts# || ', ts_name=' || ts_name); addTs(ts_name, ts#, create_scn, create_time, rbs_count, idb, bf, tmp, encrypt_in_backup, plugin_scn, tsRec.curr_pdbinc_key); deb('Added tablespace entry for ts#=' || ts# || ', ts_name=' || ts_name); incResyncActions(RESYNC_ACTION_RECREATE, ts#, ts_name); ELSE IF (create_scn > tsRec.create_scn) THEN -- -- -- -- -- -- -- -- dropTs(tsRec.ts#, tsRec.create_scn, create_scn, create_time, tsRec.plugin_scn, tsRec.pdbinc_key); addTs(ts_name, ts#, create_scn, create_time, rbs_count, idb, bf, tmp, encrypt_in_backup, plugin_scn, tsRec.curr_pdbinc_key); incResyncActions(RESYNC_ACTION_RECREATE, tsRec.ts#, ts_name); ELSE -- (create_scn < tsRec.create_scn) -- -- -- -- raise_application_error(-20042, 'Invalid tablespace creation change#'); END IF; END IF; END IF; <> fetchTS; -- get next row from TS cursor END IF; -- (ts# < tsRec.ts) END checkTableSpace; PROCEDURE endTableSpaceResync IS BEGIN checkResync; deb('endTableSpaceResync - tsRec.ts#: ' || tsRec.ts#); -- -- -- begin WHILE (tsRec.con_id < MAXNUMVAL) LOOP -- while extra tablespaces in rcvcat IF (tsRec.temporary = 'NO' OR -- is a permanent tablespace do_temp_ts_resync) THEN -- is a 10gR2 or later rman client deb('endTableSpaceResync - before calling dropTS'); dropTs(tsRec.ts#, tsRec.create_scn, this_ckp_scn, this_ckp_time, tsRec.plugin_scn, tsRec.pdbinc_key); deb('endTableSpaceResync - before calling incResyncActions'); begin incResyncActions(RESYNC_ACTION_DROP, tsRec.ts#, tsRec.ts_name); exception when others then deb('endTableSpaceResync (DO_NOT_IGNORE)-caught exception ' || substr(sqlerrm, 1, 132)); end; deb('endTableSpaceResync - after calling incResyncActions'); END IF; deb('endTableSpaceResync - before calling fetchTS'); fetchTs; deb('endTableSpaceResync - after calling fetchTS'); END LOOP; exception when others then deb('checkTableSpace(DO_NOT_IGNORE) - caugth exception ' || substr(sqlerrm, 1, 132)); end; deb('endTableSpaceResync -out of loop, tsRec.ts#: ' || tsRec.ts#); -- tsRec.ts# := NULL; -- UPDATE node SET high_ts_recid = nvl(last_ts_recid, high_ts_recid) WHERE site_key = this_site_key; -- IF this_is_ors and this_ckp_type = 'FULL' THEN UPDATE watermarks SET high_ts_recid = nvl(last_ts_recid, high_ts_recid) WHERE db_key = this_db_key; END IF; last_ts_recid := NULL; -- -- IF (NOT do_temp_ts_resync) THEN UPDATE node SET high_tf_recid = 0 WHERE site_key = this_site_key; END IF; END endTableSpaceResync; /*-----------------* * Datafile Resync * *-----------------*/ PROCEDURE fetchDF IS -- private to package body BEGIN FETCH dfQ INTO dfRec; IF dfQ%NOTFOUND THEN dfRec.file# := MAXNUMVAL; -- indicate end-of-fetch CLOSE dfQ; ELSE deb('fetchDF - file#' || dfRec.file#); END IF; END fetchDF; PROCEDURE addDF(file# IN NUMBER, -- private to package body fname IN VARCHAR2, create_time IN DATE, create_scn IN NUMBER, blocks IN NUMBER, block_size IN NUMBER, ts# IN NUMBER, stop_scn IN NUMBER, stop_time IN DATE, read_only IN NUMBER, rfile# IN NUMBER, foreign_dbid IN NUMBER, foreign_create_scn IN NUMBER, foreign_create_time IN DATE, plugged_readonly IN varchar2, plugin_scn IN NUMBER, plugin_reset_scn IN NUMBER, plugin_reset_time IN DATE, create_thread IN NUMBER, create_size IN NUMBER, pdbinc_key IN NUMBER, pdb_key IN NUMBER, pdb_closed IN NUMBER, pdb_foreign_dbid IN NUMBER) IS ts_create_scn NUMBER; ts_plugin_scn NUMBER; ts_pdbinc_key NUMBER; ts_name ts.ts_name%type; local_df_key NUMBER; child_rec exception; pragma exception_init(child_rec, -2292); BEGIN SELECT ts.create_scn, ts.plugin_scn, ts.ts_name, ts.pdbinc_key INTO ts_create_scn, ts_plugin_scn, ts_name, ts_pdbinc_key FROM ts, rci_pdbinc_this_dbinc pdbinc WHERE ts.dbinc_key = this_dbinc_key AND ts.ts# = addDF.ts# AND ts.pdbinc_key = pdbinc.pdbinc_key AND pdbinc.pdb_key = addDF.pdb_key AND pdbinc.dbinc_key = this_dbinc_key AND ts.create_scn < pdbinc.next_inc_scn AND ts.drop_scn IS NULL; -- in case ts numbers are reused -- -- -- -- -- BEGIN select distinct df_key into local_df_key from df, dbinc where file# = addDF.file# and create_scn = addDF.create_scn and plugin_scn = addDF.plugin_scn and foreign_dbid = addDF.foreign_dbid and ts# = addDF.ts# and df.dbinc_key = dbinc.dbinc_key and dbinc.db_key = this_db_key; EXCEPTION WHEN no_data_found THEN select rman_seq.nextval into local_df_key from dual; END; -- -- -- -- INSERT INTO df(dbinc_key, file#, create_scn, create_time, ts#, ts_create_scn, ts_plugin_scn, block_size, stop_scn, stop_time, read_only, rfile#, df_key, blocks, foreign_dbid, foreign_create_scn, foreign_create_time, plugged_readonly, plugin_scn, plugin_reset_scn, plugin_reset_time, create_thread, create_size, pdbinc_key, ts_pdbinc_key, pdb_closed, pdb_foreign_dbid) VALUES(this_dbinc_key, file#, create_scn, create_time, ts#, ts_create_scn, ts_plugin_scn, block_size, stop_scn, stop_time, read_only, rfile#, local_df_key, nvl(blocks, 0), foreign_dbid, foreign_create_scn, foreign_create_time, plugged_readonly, plugin_scn, plugin_reset_scn, plugin_reset_time, create_thread, create_size, pdbinc_key, ts_pdbinc_key, pdb_closed, pdb_foreign_dbid); -- -- -- BEGIN INSERT INTO site_dfatt(df_key, fname, site_key) VALUES(local_df_key, fname, this_site_key); EXCEPTION WHEN dup_val_on_index THEN -- UPDATE site_dfatt SET fname = addDf.fname WHERE site_key = this_site_key AND df_key = local_df_key; END; END addDf; PROCEDURE setDatafileSize(file# IN number ,create_scn IN number ,blocks IN number ,plugin_scn IN number default 0) IS BEGIN IF (this_dbinc_key is NULL) THEN raise_application_error(-20020, 'Database incarnation not set'); END IF; update df set df.blocks = setDatafileSize.blocks where dbinc_key = this_dbinc_key and df.file# = setDatafileSize.file# and df.create_scn = setDatafileSize.create_scn and df.plugin_scn = setDatafileSize.plugin_scn; commitChanges('setDatafileSize'); END setDatafileSize; PROCEDURE dropDf( -- private to package body file# IN NUMBER ,create_scn IN NUMBER ,plugin_scn IN NUMBER ,drop_scn IN NUMBER ,drop_time IN DATE ,pdbinc_key IN NUMBER ) IS BEGIN -- -- -- -- -- -- -- -- UPDATE df SET drop_scn = dropDf.drop_scn, drop_time = dropDf.drop_time WHERE df.dbinc_key = this_dbinc_key AND df.file# = dropDf.file# AND df.create_scn = dropDf.create_scn AND df.plugin_scn = dropDf.plugin_scn AND df.pdbinc_key = dropDf.pdbinc_key; END dropDf; FUNCTION beginDataFileResyncForStandby( high_df_recid IN number ) return boolean IS BEGIN checkResync; SELECT high_df_recid INTO last_df_recid FROM node WHERE node.site_key = this_site_key; deb('high_df_recid='||high_df_recid||',last_df_recid='||last_df_recid); IF last_full_ckp_scn IS NULL THEN deb('beginDataFileResyncForStandby - no full resync'); raise_application_error(-20079, 'full resync from primary database is not done'); END IF; -- -- -- IF (high_df_recid > last_df_recid OR last_df_recid IS NULL) THEN last_df_recid := high_df_recid; last_file# := -1; -- initialize for ordering assert -- -- IF this_ckp_scn > last_full_ckp_scn THEN OPEN dfQ; fetchDf; -- do priming read END IF; RETURN TRUE; END IF; deb('no need to resync datafile names for '||this_db_unique_name|| ' standby site'); RETURN FALSE; END; PROCEDURE checkDataFileForStandby(file# IN NUMBER, fname IN VARCHAR2, create_scn IN NUMBER, create_time IN DATE, blocks IN NUMBER, block_size IN NUMBER, ts# IN NUMBER, rfile# IN NUMBER, stop_scn IN NUMBER, read_only IN NUMBER, foreign_dbid IN NUMBER, plugin_scn IN NUMBER) IS local_df_key NUMBER; BEGIN IF (last_file# >= file#) THEN -- assert rows passed in ascending raise_application_error(-20036, 'Invalid record order'); END IF; last_file# := file#; -- for checking next call -- -- IF this_ckp_scn > last_full_ckp_scn THEN IF (file# != dfRec.file#) THEN IF (file# > dfRec.file#) THEN deb('checkDataFileResyncForStandby - droped file#=' ||dfRec.file#); ELSE -- deb('checkDataFileResyncForStandby - added file#=' || file#); END IF; raise_application_error(-20079, 'full resync from primary database is not done'); ELSE -- -- -- -- -- IF (create_scn <> dfRec.create_scn OR plugin_scn <> dfRec.plugin_scn OR stop_scn <> dfRec.stop_scn OR stop_scn is null and dfRec.stop_scn is not null OR stop_scn is not null and dfRec.stop_scn is null OR read_only < dfRec.read_only OR read_only is null and dfRec.read_only is not null OR read_only is not null and dfRec.read_only is null) THEN deb('checkDataFileResyncForStandby - change for file#=' || file#); raise_application_error(-20079, 'full resync from primary database is not done'); END IF; END IF; fetchDF; END IF; BEGIN -- select distinct df_key into local_df_key from df, dbinc where file# = checkDataFileForStandby.file# and create_scn = checkDataFileForStandby.create_scn and plugin_scn = checkDataFileForStandby.plugin_scn and decode(foreign_dbid, 0, checkDataFileForStandby.foreign_dbid, foreign_dbid) = checkDataFileForStandby.foreign_dbid and ts# = checkDataFileForStandby.ts# and df.dbinc_key = dbinc.dbinc_key and dbinc.db_key = this_db_key; EXCEPTION -- -- WHEN no_data_found THEN raise_application_error(-20999, 'Internal error in checkDataFileForStandby - 1 '); -- WHEN too_many_rows THEN raise_application_error(-20999, 'Internal error in checkDataFileForStandby - 2 '); END; -- -- -- BEGIN INSERT INTO site_dfatt(df_key, fname, site_key) VALUES(local_df_key, checkDataFileForStandby.fname, this_site_key); EXCEPTION WHEN dup_val_on_index THEN -- UPDATE site_dfatt SET fname = checkDataFileForStandby.fname WHERE site_key = this_site_key AND df_key = local_df_key; END; END; PROCEDURE endDataFileResyncForStandby IS BEGIN checkResync; -- IF (this_ckp_scn > last_full_ckp_scn AND dfRec.file# < MAXNUMVAL) THEN deb('endDataFileResyncForStandby - dropped file# > ' || dfRec.file#); raise_application_error(-20079, 'full resync from primary database is not done'); IF dfQ%ISOPEN THEN CLOSE dfQ; END IF; END IF; -- dfRec.file# := NULL; -- UPDATE node SET high_df_recid = last_df_recid WHERE node.site_key = this_site_key; last_df_recid := NULL; END; FUNCTION beginDataFileResync( high_df_recid IN NUMBER ) RETURN BOOLEAN IS BEGIN checkResync; IF (tsRec.ts# IS NOT NULL) THEN raise_application_error(-20041, 'Tablespace resync not completed'); END IF; SELECT high_df_recid INTO last_df_recid FROM node WHERE site_key = this_site_key; IF (high_df_recid = last_df_recid) THEN deb('beginDataFileResync - Resync of datafiles not needed'); RETURN FALSE; ELSIF (high_df_recid > last_df_recid OR last_df_recid IS NULL) THEN deb('beginDataFileResync - Catalog df_recid: '||last_df_recid); deb('beginDataFileResync - High df_recid: '||high_df_recid); last_df_recid := high_df_recid; OPEN dfQ; fetchDf; -- do priming read last_file# := -1; -- initialize for ordering assert if resync_reason = RESYNC_REASON_DF then fullResyncAction.valid := TRUE; fullResyncAction.active := TRUE; fullResyncAction.objtype := RESYNC_OBJECT_DATAFILE; else fullResyncAction.active := FALSE; end if; RETURN TRUE; ELSE raise_application_error(-20035, 'Invalid high recid'); END IF; END beginDataFileResync; PROCEDURE checkDataFile(file# IN NUMBER, fname IN VARCHAR2, create_scn IN NUMBER, create_time IN DATE, blocks IN NUMBER, block_size IN NUMBER, ts# IN NUMBER, stop_scn IN NUMBER, read_only IN NUMBER, stop_time IN DATE DEFAULT NULL, rfile# IN NUMBER DEFAULT NULL, aux_fname IN VARCHAR2 DEFAULT NULL, foreign_dbid IN NUMBER DEFAULT 0, foreign_create_scn IN NUMBER DEFAULT 0, foreign_create_time IN DATE DEFAULT NULL, plugged_readonly IN VARCHAR2 DEFAULT 'NO', plugin_scn IN NUMBER DEFAULT 0, plugin_reset_scn IN NUMBER DEFAULT 0, plugin_reset_time IN DATE DEFAULT NULL, create_thread IN NUMBER DEFAULT NULL, create_size IN NUMBER DEFAULT NULL, con_id IN NUMBER DEFAULT 0, pdb_closed IN NUMBER DEFAULT 0, pdb_dict_check IN BOOLEAN DEFAULT FALSE, pdb_foreign_dbid IN NUMBER DEFAULT 0) IS local_df_key NUMBER; changedauxname BOOLEAN; local_pdbinc_key NUMBER; local_pdb_key NUMBER; existing_file BOOLEAN; BEGIN IF (dfRec.file# IS NULL) THEN -- assert beginDataFileResync was called raise_application_error(-20050, 'Datafile resync not started'); END IF; IF (last_file# >= file#) THEN -- assert rows passed in ascending raise_application_error(-20036, 'Invalid record order'); END IF; last_file# := file#; -- for checking next call IF (plugged_readonly = 'NO' AND create_scn > this_ckp_scn) THEN raise_application_error(-20052, 'Invalid datafile create SCN'); ELSIF (plugged_readonly = 'YES' AND plugin_scn > this_ckp_scn) THEN raise_application_error(-20055, 'Invalid datafile plugin SCN'); END IF; -- -- -- -- -- WHILE (file# > dfRec.file#) LOOP deb('checkDatafile - dropping file#: '||to_char(dfRec.file#)); dropDf(dfRec.file#, dfRec.create_scn, dfRec.plugin_scn, this_ckp_scn, this_ckp_time, dfRec.pdbinc_key); incResyncActions(RESYNC_ACTION_DROP, dfRec.file#, dfRec.fname); fetchDf; END LOOP; IF (file# < dfRec.file#) THEN IF (pdb_dict_check) THEN deb('checkDataFile - skipping df needs dictionary check'); ELSE local_pdbinc_key := getPdbInc(greatest(create_scn, plugin_scn), con_id, local_pdb_key); -- deb('checkDatafile - adding file#: '||to_char(file#)); addDF(file#, fname, create_time, create_scn, blocks, block_size, ts#, stop_scn, stop_time, read_only, rfile#, foreign_dbid, foreign_create_scn, foreign_create_time, plugged_readonly, plugin_scn, plugin_reset_scn, plugin_reset_time, create_thread, create_size, local_pdbinc_key, local_pdb_key, pdb_closed, pdb_foreign_dbid); -- -- -- IF (aux_fname is not NULL) THEN setCloneName(file#, create_scn, aux_fname, NULL, changedauxname, plugin_scn); END IF; END IF; incResyncActions(RESYNC_ACTION_ADD, file#, fname); ELSE -- (file# = dfRec.file#) existing_file := FALSE; IF (create_scn = dfRec.create_scn AND plugin_scn = dfRec.plugin_scn) THEN -- -- IF (create_time <> dfRec.create_time) THEN raise_application_error(-20053, 'Invalid datafile create time'); END IF; IF (ts# <> dfRec.ts#) THEN raise_application_error(-20054, 'Invalid datafile ts#'); END IF; existing_file := TRUE; SELECT DISTINCT df_key INTO local_df_key FROM df WHERE file# = checkDataFile.file# AND create_scn = checkDataFile.create_scn AND plugin_scn = checkDataFile.plugin_scn AND decode(foreign_dbid, 0, checkDataFile.foreign_dbid, foreign_dbid) = checkDataFile.foreign_dbid AND ts# = checkDataFile.ts# AND dbinc_key = this_dbinc_key; -- -- IF (fname <> dfRec.fname OR dfRec.fname is NULL) THEN -- -- -- -- -- IF (fname = dfRec.clone_fname and dfRec.fname is not null) THEN deb('checkDatafile - new datafilename is old auxname'); setCloneName(dfRec.file#, dfRec.create_scn, dfRec.fname, dfRec.clone_fname, changedauxname, dfRec.plugin_scn); END IF; incResyncActions(RESYNC_ACTION_RENAME, dfRec.file#, fname); UPDATE site_dfatt SET fname = checkDataFile.fname WHERE site_key = this_site_key AND df_key = local_df_key; -- -- IF sql%rowcount = 0 THEN INSERT INTO site_dfatt (df_key, fname, site_key) VALUES(local_df_key, checkDataFile.fname, this_site_key); END IF; END IF; END IF; IF (pdb_dict_check) THEN deb('checkDataFile - skipping df needs dictionary check'); ELSIF (existing_file) THEN -- -- IF ((create_thread is not null AND dfRec.create_thread is null) OR (create_size is not null AND dfRec.create_size is null)) THEN UPDATE df SET create_thread = checkDataFile.create_thread, create_size = checkDataFile.create_size WHERE df.df_key = local_df_key; END IF; -- -- IF foreign_dbid <> 0 AND dfrec.foreign_dbid = 0 THEN UPDATE df SET foreign_dbid = checkDataFile.foreign_dbid WHERE df.df_key = local_df_key; deb('checkDatafile - foreign_dbid for file#.df_key('|| local_df_key || ') changed to ' || checkDataFile.foreign_dbid); END IF; -- IF ((blocks <> dfrec.blocks) OR (stop_scn <> dfrec.stop_scn) OR (stop_scn IS NULL AND dfrec.stop_scn IS NOT NULL) OR (stop_scn IS NOT NULL AND dfrec.stop_scn IS NULL) OR (pdb_closed <> dfrec.pdb_closed)) THEN IF blocks <> dfRec.blocks THEN deb('checkDatafile - size changed for file#: '|| to_char(file#)||' from '||to_char(dfRec.blocks)||' to '|| to_char(blocks)); incResyncActions(RESYNC_ACTION_RESIZE, dfRec.file#, fname); ELSE deb('checkDatafile - stopSCN changed for file#: '|| to_char(file#)||' from '|| nvl(to_char(dfRec.stop_scn), 'NULL')||' to '|| nvl(to_char(checkDatafile.stop_scn), 'NULL')); incResyncActions(RESYNC_ACTION_CHANGE, dfRec.file#, fname); END IF; UPDATE df SET stop_scn = checkDataFile.stop_scn, stop_time = checkDataFile.stop_time, read_only = checkDataFile.read_only, blocks = checkDataFile.blocks, pdb_closed = checkDataFile.pdb_closed WHERE df.dbinc_key = this_dbinc_key AND df.file# = dfRec.file# AND df.create_scn = dfRec.create_scn AND df.plugin_scn = dfRec.plugin_scn AND df.pdbinc_key = dfRec.pdbinc_key; ELSE deb('checkDatafile - stopSCN remains the same for file#: '|| to_char(file#)); END IF; -- -- -- IF (aux_fname is not NULL) THEN setCloneName(dfRec.file#, dfRec.create_scn, aux_fname, dfRec.clone_fname, changedauxname, dfRec.plugin_scn); IF changedauxname THEN incResyncActions(RESYNC_ACTION_CHANGE, dfRec.file#, fname); END IF; END IF; ELSIF ((case when plugged_readonly = 'NO' then create_scn else plugin_scn end) > (case when dfRec.plugged_readonly = 'NO' then dfRec.create_scn else dfRec.plugin_scn end)) THEN -- -- -- -- -- -- -- -- -- deb('checkDatafile - file#: '||to_char(file#)||' recreated'); dropDf(dfRec.file#, dfRec.create_scn, dfRec.plugin_scn, this_ckp_scn, this_ckp_time, dfRec.pdbinc_key); local_pdbinc_key := getPdbInc(greatest(create_scn, plugin_scn), con_id, local_pdb_key); addDf(file#, fname, create_time, create_scn, blocks, block_size, ts#, stop_scn, stop_time, read_only, rfile#, foreign_dbid, foreign_create_scn, foreign_create_time, plugged_readonly, plugin_scn, plugin_reset_scn, plugin_reset_time, create_thread, create_size, local_pdbinc_key, local_pdb_key, pdb_closed, pdb_foreign_dbid); incResyncActions(RESYNC_ACTION_RECREATE, dfRec.file#, fname); ELSE -- (create_scn < dfRec.create_scn) -- -- -- -- -- IF (plugged_readonly = 'NO') THEN raise_application_error(-20052, 'Invalid datafile create SCN'); ELSE raise_application_error(-20055, 'Invalid datafile plugin SCN'); END IF; END IF; fetchDF; -- get next row from DF cursor END IF; -- (file# < dfRec.file#) END checkDataFile; PROCEDURE endDataFileResync IS BEGIN checkResync; -- WHILE (dfRec.file# < MAXNUMVAL) LOOP -- dropDf(dfRec.file#, dfRec.create_scn, dfRec.plugin_scn, this_ckp_scn, this_ckp_time, dfRec.pdbinc_key); begin incResyncActions(RESYNC_ACTION_DROP, dfRec.file#, dfRec.fname); exception when others then deb('endTableSpaceResync(DO_NOT_IGNORE) - caugth exception ' || substr(sqlerrm, 1, 132)); end; fetchDf; END LOOP; -- dfRec.file# := NULL; -- UPDATE node SET high_df_recid = last_df_recid WHERE site_key = this_site_key; -- IF this_is_ors and this_ckp_type = 'FULL' THEN UPDATE watermarks SET high_df_recid = last_df_recid WHERE db_key = this_db_key; END IF; last_df_recid := NULL; END endDataFileResync; /*-----------------* * Tempfile Resync * *-----------------*/ PROCEDURE fetchTf IS -- private to package body BEGIN -- IF tfRec.file# = MAXNUMVAL THEN return; END IF; FETCH tfQ INTO tfRec; IF tfQ%NOTFOUND THEN tfRec.file# := MAXNUMVAL; -- indicate end-of-fetch CLOSE tfQ; END IF; END fetchTf; PROCEDURE addTf(file# IN NUMBER, -- private to package body fname IN VARCHAR2, create_time IN DATE, create_scn IN NUMBER, blocks IN NUMBER, block_size IN NUMBER, ts# IN NUMBER, rfile# IN NUMBER, autoextend IN VARCHAR2, max_size IN NUMBER, next_size IN NUMBER, con_id IN NUMBER) IS ts_create_scn NUMBER; ts_pdbinc_key NUMBER; local_tf_key NUMBER; local_pdb_key NUMBER; BEGIN SELECT pdb.pdb_key INTO local_pdb_key FROM pdb, pdb_dbinc WHERE pdb_dbinc.drop_scn IS NULL AND pdb.con_id = addTf.con_id AND pdb.pdb_key = pdb_dbinc.pdb_key AND pdb_dbinc.dbinc_key = this_dbinc_key; BEGIN SELECT ts.create_scn, ts.pdbinc_key INTO ts_create_scn, ts_pdbinc_key FROM ts, rci_pdbinc_this_dbinc pdbinc WHERE ts.dbinc_key = this_dbinc_key AND ts.ts# = addTf.ts# AND ts.pdbinc_key = pdbinc.pdbinc_key AND pdbinc.pdb_key = local_pdb_key AND pdbinc.dbinc_key = this_dbinc_key AND ts.create_scn < pdbinc.next_inc_scn AND ts.drop_scn IS NULL; -- in case ts numbers are reused EXCEPTION WHEN no_data_found THEN -- -- -- IF (this_cf_type = 'STANDBY' AND this_db_unique_name is not null) THEN RETURN; END IF; END; deb('ts_create_scn=' || ts_create_scn); -- -- BEGIN SELECT DISTINCT tf.tf_key INTO local_tf_key FROM tf, dbinc WHERE tf.file# = addTf.file# AND tf.create_scn = addTf.create_scn AND (tf.create_time = addTf.create_time OR tf.create_time IS NULL AND addTf.create_time IS NULL) AND tf.ts# = addTf.ts# AND tf.rfile# = addTf.rfile# AND tf.dbinc_key = dbinc.dbinc_key AND dbinc.db_key = this_db_key; EXCEPTION WHEN no_data_found THEN SELECT rman_seq.nextval INTO local_tf_key FROM dual; END; BEGIN INSERT INTO tf(dbinc_key, file#, create_scn, create_time, ts#, ts_create_scn, block_size, rfile#, tf_key, pdb_key, ts_pdbinc_key) VALUES(this_dbinc_key, file#, create_scn, create_time, ts#, ts_create_scn, block_size, rfile#, local_tf_key, local_pdb_key, ts_pdbinc_key); EXCEPTION WHEN dup_val_on_index THEN -- -- -- IF create_scn = 0 THEN UPDATE tf SET create_time = addTf.create_time, ts# = addTf.ts#, ts_create_scn = addTf.ts_create_scn, block_size = addTf.block_size, rfile# = addTf.rfile#, pdb_key = local_pdb_key WHERE dbinc_key = this_dbinc_key AND file# = addTf.file# AND create_scn = addTf.create_scn; END IF; -- -- -- -- -- -- -- -- -- -- -- END; -- -- -- BEGIN INSERT INTO site_tfatt(tf_key, fname, site_key, blocks, autoextend, max_size, next_size) VALUES(local_tf_key, fname, this_site_key, nvl(addTf.blocks, 0), addTf.autoextend, addTf.max_size, addTf.next_size); -- EXCEPTION WHEN dup_val_on_index THEN -- UPDATE site_tfatt SET fname = addTf.fname, blocks = nvl(addTf.blocks, 0), autoextend = addTf.autoextend, max_size = addTf.max_size, next_size = addTf.next_size, drop_scn = NULL, drop_time = NULL WHERE site_key = this_site_key AND tf_key = local_tf_key; END; END addTf; PROCEDURE dropTf( -- private to package body tf_key IN NUMBER ,drop_scn IN NUMBER ,drop_time IN DATE ) IS BEGIN UPDATE site_tfatt SET drop_scn = dropTf.drop_scn, drop_time = dropTf.drop_time WHERE this_site_key = site_key AND tf_key = dropTf.tf_key; END dropTf; FUNCTION tempFileToResync( high_tf_recid IN NUMBER ) RETURN BOOLEAN IS tf_recid number; BEGIN checkResync; SELECT high_tf_recid INTO tf_recid FROM node WHERE site_key = this_site_key; IF (high_tf_recid = tf_recid) THEN RETURN FALSE; ELSIF (high_tf_recid > tf_recid OR tf_recid IS NULL) THEN RETURN TRUE; ELSE raise_application_error(-20035, 'Invalid high recid'); END IF; END tempFileToResync; -- -- -- FUNCTION beginTempFileResyncForStandby( high_tf_recid IN NUMBER ) RETURN BOOLEAN IS BEGIN RETURN beginTempFileResync (high_tf_recid); END beginTempFileResyncForStandby; -- -- -- -- -- -- -- -- PROCEDURE checkTempFileForStandby (file# IN NUMBER, fname IN VARCHAR2, create_scn IN NUMBER, create_time IN DATE, blocks IN NUMBER, block_size IN NUMBER, ts# IN NUMBER, rfile# IN NUMBER, autoextend IN VARCHAR2, max_size IN NUMBER, next_size IN NUMBER, con_id IN NUMBER DEFAULT 0) IS local_tf_key NUMBER; BEGIN checkTempFile(file#, fname, create_scn, create_time, blocks, block_size, ts#, rfile#, autoextend, max_size, next_size, con_id, FALSE); END checkTempFileForStandby; PROCEDURE endTempFileResyncForStandby IS BEGIN endTempFileResync; END endTempFileResyncForStandby; FUNCTION beginTempFileResync( high_tf_recid IN NUMBER ) RETURN BOOLEAN IS BEGIN checkResync; IF (tsRec.ts# IS NOT NULL) THEN raise_application_error(-20041, 'Tablespace resync not completed'); END IF; SELECT high_tf_recid INTO last_tf_recid FROM node WHERE site_key = this_site_key; IF (high_tf_recid = last_tf_recid) THEN deb('beginTempFileResync - Resync of tempfiles not needed'); RETURN FALSE; ELSIF (high_tf_recid > last_tf_recid OR last_tf_recid IS NULL) THEN deb('beginTempFileResync - Catalog tf_recid: '||last_tf_recid); deb('beginTempFileResync - High tf_recid: '||high_tf_recid); last_tf_recid := high_tf_recid; OPEN tfQ; fetchTf; -- do priming read last_file# := -1; -- initialize for ordering assert if resync_reason = RESYNC_REASON_TF then fullResyncAction.active := TRUE; fullResyncAction.valid := TRUE; fullResyncAction.objtype := RESYNC_OBJECT_TEMPFILE; else fullResyncAction.active := FALSE; end if; RETURN TRUE; ELSE raise_application_error(-20035, 'Invalid high recid'); END IF; END beginTempFileResync; PROCEDURE checkTempFile(file# IN NUMBER, fname IN VARCHAR2, create_scn IN NUMBER, create_time IN DATE, blocks IN NUMBER, block_size IN NUMBER, ts# IN NUMBER, rfile# IN NUMBER, autoextend IN VARCHAR2, max_size IN NUMBER, next_size IN NUMBER, con_id IN NUMBER DEFAULT 0, pdb_dict_check IN BOOLEAN DEFAULT FALSE) IS local_tf_key NUMBER; BEGIN IF (tfRec.file# IS NULL) THEN -- assert beginTempFileResync was called raise_application_error(-20050, 'Tempfile resync not started'); END IF; IF (last_file# >= file#) THEN -- assert rows passed in ascending raise_application_error(-20036, 'Invalid record order'); END IF; last_file# := file#; -- for checking next call -- -- -- -- -- -- -- -- -- WHILE (file# > tfRec.file#) LOOP dropTf(tfRec.tf_key, this_ckp_scn, this_ckp_time); incResyncActions(RESYNC_ACTION_DROP, tfRec.file#, tfRec.fname); fetchTf; END LOOP; IF (file# < tfRec.file#) THEN IF (pdb_dict_check) THEN deb('checkTempFile - skipping tf needs dictionary check'); ELSE addTf(file#, fname, create_time, create_scn, blocks, block_size, ts#, rfile#, autoextend, max_size, next_size, con_id); END IF; incResyncActions(RESYNC_ACTION_ADD, tfRec.file#, fname); ELSE -- (file# = tfRec.file#) IF (pdb_dict_check) THEN deb('checkTempFile - skipping tf needs dictionary check'); ELSIF (create_scn = 0) THEN addTf(file#, fname, create_time, create_scn, blocks, block_size, ts#, rfile#, autoextend, max_size, next_size, con_id); incResyncActions(RESYNC_ACTION_CHANGE, file#, fname); ELSIF (create_scn = tfRec.create_scn) THEN -- -- IF (create_time <> tfRec.create_time) THEN raise_application_error(-20053, 'Invalid tempfile create time'); END IF; IF (ts# <> tfRec.ts#) THEN raise_application_error(-20054, 'Invalid tempfile ts#'); END IF; -- addTf(file#, fname, create_time, create_scn, blocks, block_size, ts#, rfile#, autoextend, max_size, next_size, con_id); IF (fname <> tfRec.fname OR tfRec.fname is NULL) THEN incResyncActions(RESYNC_ACTION_RENAME, file#, fname); END IF; -- -- IF (blocks <> tfrec.blocks OR autoextend <> tfrec.autoextend OR max_size <> tfrec.max_size OR next_size <> tfrec.next_size ) THEN IF blocks <> tfrec.blocks THEN incResyncActions(RESYNC_ACTION_RESIZE, file#, fname); ELSE incResyncActions(RESYNC_ACTION_CHANGE, file#, fname); END IF; END IF; ELSE -- -- -- -- -- -- dropTf(tfRec.tf_key, create_scn, create_time); addTf(file#, fname, create_time, create_scn, blocks, block_size, ts#, rfile#, autoextend, max_size, next_size, con_id); incResyncActions(RESYNC_ACTION_RECREATE, file#, fname); END IF; fetchTf; -- get next row from Tf cursor END IF; -- (file# = tfRec.file#) END checkTempFile; PROCEDURE endTempFileResync IS BEGIN checkResync; -- deb('endTempFileResync - entering with tempfile number'||tfRec.file#); WHILE (tfRec.file# < MAXNUMVAL) LOOP dropTf(tfRec.tf_key, this_ckp_scn, this_ckp_time); incResyncActions(RESYNC_ACTION_DROP, tfRec.file#, tfRec.fname); fetchTf; deb('endTempFileResync - dropping tempfile '||tfRec.file#); END LOOP; -- tfRec.file# := NULL; -- UPDATE node SET high_tf_recid = last_tf_recid WHERE site_key = this_site_key; -- IF this_is_ors and this_ckp_type = 'FULL' THEN UPDATE watermarks SET high_tf_recid = last_tf_recid WHERE db_key = this_db_key; END IF; last_tf_recid := NULL; END endTempFileResync; /*---------------------* * Redo Thread resync * *---------------------*/ PROCEDURE fetchRt IS BEGIN FETCH rtQ INTO rtRec; IF rtQ%NOTFOUND THEN rtRec.thread# := MAXNUMVAL; CLOSE rtQ; END IF; END fetchRt; PROCEDURE addRt( thread# IN NUMBER ,last_sequence# IN NUMBER ,enable_scn IN NUMBER ,enable_time IN DATE ,disable_scn IN NUMBER ,disable_time IN DATE ,status IN VARCHAR2 ) IS BEGIN INSERT INTO rt (dbinc_key, thread#, sequence#, enable_scn, enable_time, disable_scn, disable_time, status) VALUES (this_dbinc_key, thread#, last_sequence#, enable_scn, enable_time, disable_scn, disable_time, status); END addRt; PROCEDURE dropRt(thread# IN NUMBER) IS BEGIN -- DELETE FROM rt WHERE rt.dbinc_key = this_dbinc_key AND rt.thread# = dropRt.thread#; END dropRt; FUNCTION beginThreadResync( high_rt_recid IN NUMBER ) RETURN BOOLEAN IS BEGIN checkResync; SELECT high_rt_recid INTO last_rt_recid FROM node WHERE site_key = this_site_key; IF (high_rt_recid = last_rt_recid) THEN deb('beginThreadResync - Resync of redo threads not needed'); RETURN FALSE; ELSIF (high_rt_recid > last_rt_recid OR last_rt_recid IS NULL) THEN deb('beginThreadResync - Catalog rt_recid: '||last_rt_recid); deb('beginThreadResync - High rt_recid: '||high_rt_recid); last_rt_recid := high_rt_recid; OPEN rtQ; fetchRt; -- do priming read last_thread# := -1; if resync_reason = RESYNC_REASON_THR then fullResyncAction.valid := TRUE; fullResyncAction.active := TRUE; fullResyncAction.objtype := RESYNC_OBJECT_REDOTHREAD; else fullResyncAction.active := FALSE; end if; RETURN TRUE; ELSE raise_application_error(-20035, 'Invalid high recid'); END IF; END beginThreadResync; PROCEDURE checkThread( thread# IN NUMBER ,last_sequence# IN NUMBER ,enable_scn IN NUMBER ,enable_time IN DATE ,disable_scn IN NUMBER ,disable_time IN DATE ,status IN VARCHAR2 ) IS BEGIN IF (rtRec.thread# IS NULL) THEN raise_application_error(-20061, 'Thread resync not started'); END IF; IF (last_thread# >= thread#) THEN raise_application_error(-20036, 'Invalid record order'); END IF; last_thread# := thread#; WHILE (thread# > rtRec.thread#) LOOP -- -- -- dropRt(rtRec.thread#); incResyncActions(RESYNC_ACTION_DROP, rtRec.thread#, to_char(NULL)); fetchRt; END LOOP; IF (thread# < rtRec.thread#) THEN -- addRt(thread#, last_sequence#, enable_scn, enable_time, disable_scn, disable_time, status); incResyncActions(RESYNC_ACTION_ADD, thread#, to_char(NULL)); ELSE -- (thread# = rtRec.thread#) -- UPDATE rt SET sequence# = checkThread.last_sequence#, enable_scn = checkThread.enable_scn, enable_time = checkThread.enable_time, disable_scn = checkThread.disable_scn, disable_time = checkThread.disable_time, status = checkThread.status WHERE rt.dbinc_key = this_dbinc_key AND rt.thread# = checkThread.thread#; incResyncActions(RESYNC_ACTION_CHANGE, rtRec.thread#, to_char(NULL)); fetchRt; END IF; END checkThread; PROCEDURE endThreadResync IS BEGIN WHILE (rtRec.thread# < MAXNUMVAL) LOOP -- -- -- dropRt(rtRec.thread#); fetchRt; END LOOP; rtRec.thread# := NULL; -- UPDATE node SET high_rt_recid = last_rt_recid WHERE site_key = this_site_key; last_rt_recid := NULL; END endThreadResync; /*------------------------* * Online Redo Log resync * *------------------------*/ -- -- -- -- -- -- -- -- -- -- FUNCTION nlsnamecmp(n1 IN varchar2, n2 IN varchar2) RETURN NUMBER IS CURSOR nlsnamecmp_c(n1 varchar2, n2 varchar2) IS SELECT name FROM (SELECT n1 name FROM dual UNION ALL SELECT n2 name FROM dual) ORDER BY nlssort(name, 'NLS_COMP=ANSI NLS_SORT=ASCII7'); ln1 varchar2(1024); ln2 varchar2(1024); BEGIN if (n1 is null or n2 is null) then return null; elsif (n1 = n2) then return 0; elsif (n1 = chr(1) or n2 = chr(255)) then return -1; elsif (n2 = chr(1) or n1 = chr(255)) then return 1; end if; open nlsnamecmp_c(n1, n2); fetch nlsnamecmp_c into ln1; fetch nlsnamecmp_c into ln2; close nlsnamecmp_c; if (ln1 = n1) then return -1; end if; return 1; END nlsnamecmp; PROCEDURE fetchOrl IS BEGIN FETCH orlQ INTO orlRec; IF orlQ%NOTFOUND THEN orlRec.fname := chr(255); -- assume chr(255) is greater than any name CLOSE orlQ; END IF; END fetchOrl; PROCEDURE addOrl( thread# IN NUMBER ,group# IN NUMBER ,fname IN VARCHAR2 ,bytes IN NUMBER ,type IN VARCHAR2 ) IS thread_not_found EXCEPTION; PRAGMA EXCEPTION_INIT(thread_not_found, -2291); BEGIN INSERT INTO orl (dbinc_key, thread#, group#, fname, bytes, type, site_key) VALUES (this_dbinc_key, thread#, group#, fname, bytes, type, this_site_key); EXCEPTION WHEN thread_not_found THEN -- -- IF type <> 'STANDBY' THEN raise_application_error(-20079, 'full resync from primary database is not done'); ELSE deb('ignored resync of standby redo log ' || fname); END IF; END addOrl; PROCEDURE dropOrl(fname IN VARCHAR2) IS BEGIN -- DELETE FROM orl WHERE orl.dbinc_key = this_dbinc_key AND orl.site_key = this_site_key AND orl.fname = dropOrl.fname; END dropOrl; FUNCTION beginOnlineRedoLogResync( high_orl_recid IN NUMBER ) RETURN BOOLEAN IS BEGIN checkResync; SELECT high_orl_recid INTO last_orl_recid FROM node WHERE site_key = this_site_key; IF (high_orl_recid = last_orl_recid) THEN deb('beginOnlineRedoLogResync - Resync of online logs not needed'); RETURN FALSE; ELSIF (high_orl_recid > last_orl_recid OR last_orl_recid IS NULL) THEN deb('beginOnlineRedoLogResync - Catalog orl_recid: '||last_orl_recid); deb('beginOnlineRedoLogResync - High orl_recid: '||high_orl_recid); last_orl_recid := high_orl_recid; OPEN orlQ; fetchOrl; last_fname := chr(1); -- assume chr(1) is less than any name if resync_reason = RESYNC_REASON_ORL then fullResyncAction.active := TRUE; fullResyncAction.valid := TRUE; fullResyncAction.objtype := RESYNC_OBJECT_ONLINELOG; else fullResyncAction.active := FALSE; end if; RETURN TRUE; ELSE raise_application_error(-20035, 'Invalid high recid'); END IF; END beginOnlineRedoLogResync; PROCEDURE checkOnlineRedoLog( thread# IN NUMBER ,group# IN NUMBER ,fname IN VARCHAR2 ,bytes IN NUMBER DEFAULT NULL ,type IN VARCHAR2 DEFAULT 'ONLINE' ) IS BEGIN IF (orlRec.fname IS NULL) THEN raise_application_error(-20061, 'Redo resync not started'); END IF; IF (nlsnamecmp(last_fname, fname) >= 0) THEN raise_application_error(-20036, 'Invalid record order'); END IF; last_fname := fname; WHILE (nlsnamecmp(fname, orlRec.fname) > 0) LOOP -- -- -- dropOrl(orlRec.fname); incResyncActions(RESYNC_ACTION_DROP, to_number(NULL), orlRec.fname); fetchOrl; END LOOP; IF (nlsnamecmp(fname, orlRec.fname) < 0) THEN -- addOrl(thread#, group#, fname, bytes, type); incResyncActions(RESYNC_ACTION_ADD, to_number(NULL), fname); ELSE -- (fname = orlRec.fname) UPDATE orl SET thread# = checkOnlineRedoLog.thread#, group# = checkOnlineRedoLog.group#, bytes = checkOnlineRedoLog.bytes, type = checkOnlineRedoLog.type WHERE orl.dbinc_key = this_dbinc_key AND orl.fname = checkOnlineRedoLog.fname AND orl.site_key = this_site_key; incResyncActions(RESYNC_ACTION_CHANGE, to_number(NULL), orlRec.fname); fetchOrl; END IF; END checkOnlineRedoLog; PROCEDURE endOnlineRedoLogResync IS BEGIN WHILE (orlRec.fname != chr(255)) LOOP -- -- -- dropOrl(orlRec.fname); incResyncActions(RESYNC_ACTION_DROP, to_number(NULL), orlRec.fname); fetchOrl; END LOOP; orlRec.fname := NULL; -- UPDATE node SET high_orl_recid = last_orl_recid WHERE site_key = this_site_key; last_orl_recid := NULL; END endOnlineRedoLogResync; /*---------------------------------* * Guaranteed restore point Resync * *---------------------------------*/ PROCEDURE fetchGrsp IS BEGIN FETCH grspQ INTO grspRec; IF grspQ%NOTFOUND THEN grspRec.rspname := chr(255); -- assume chr(255) is greater than any name grspRec.pdb_key := null; CLOSE grspQ; END IF; END fetchGrsp; PROCEDURE addGrsp( rspname IN VARCHAR2 ,from_scn IN NUMBER ,to_scn IN NUMBER ,dbinc_key IN NUMBER ,create_time IN DATE ,rsp_time IN DATE ,guaranteed IN VARCHAR2 ,pdb_key IN NUMBER ,clean IN VARCHAR2 ) IS BEGIN INSERT INTO grsp (dbinc_key, rspname, from_scn, to_scn, creation_time, rsptime, guaranteed, site_key, pdb_key, clean) VALUES (dbinc_key, rspname, from_scn, to_scn, create_time, rsp_time, guaranteed, this_site_key, pdb_key, clean); END addGrsp; PROCEDURE dropGrsp( rspname IN VARCHAR2 ,pdb_key IN NUMBER) IS BEGIN DELETE FROM grsp WHERE grsp.rspname = dropGrsp.rspname AND grsp.site_key = this_site_key AND grsp.pdb_key = dropGrsp.pdb_key; END dropGrsp; FUNCTION beginGuaranteedRPResync( high_grsp_recid IN NUMBER ) RETURN BOOLEAN IS BEGIN checkResync; SELECT node.high_grsp_recid INTO last_grsp_recid FROM node WHERE site_key = this_site_key; IF (high_grsp_recid = last_grsp_recid) THEN RETURN FALSE; ELSIF (high_grsp_recid > last_grsp_recid OR last_grsp_recid IS NULL) THEN last_grsp_recid := high_grsp_recid; OPEN grspQ; fetchGrsp; last_rspname := chr(1); -- assume chr(1) is less than any name last_pdb_key := -1; RETURN TRUE; ELSE raise_application_error(-20035, 'Invalid high recid'); END IF; END beginGuaranteedRPResync; PROCEDURE checkGuaranteedRP( rspname IN VARCHAR2 ,from_scn IN NUMBER ,to_scn IN NUMBER ,resetlogs_change# IN NUMBER ,resetlogs_time IN DATE ,create_time IN DATE DEFAULT NULL ,rsp_time IN DATE DEFAULT NULL ,guaranteed IN VARCHAR2 DEFAULT 'YES' ,con_id IN NUMBER DEFAULT NULL ,clean IN VARCHAR2 DEFAULT 'NO' ) IS dbinc_key number; local_pdb_key number; BEGIN IF (grspRec.rspname IS NULL) THEN raise_application_error(-20099, 'restore point resync not started'); END IF; dbinc_key := checkIncarnation(resetlogs_change#, resetlogs_time); -- -- SELECT pdb.pdb_key INTO local_pdb_key FROM pdb, pdb_dbinc WHERE pdb_dbinc.drop_scn IS NULL AND pdb.con_id IN (checkGuaranteedRP.con_id, 0, decode(checkGuaranteedRP.con_id, 0, 1)) AND pdb.pdb_key = pdb_dbinc.pdb_key AND pdb_dbinc.dbinc_key = this_dbinc_key; IF (nlsnamecmp(last_rspname, rspname) >= 0 AND (last_pdb_key = local_pdb_key)) THEN raise_application_error(-20036, 'Invalid record order'); END IF; last_rspname := rspname; last_pdb_key := local_pdb_key; WHILE (grspRec.pdb_key != local_pdb_key) LOOP -- -- -- dropGrsp(grspRec.rspname, grspRec.pdb_key); fetchGrsp; END LOOP; WHILE (grspRec.pdb_key = local_pdb_key AND nlsnamecmp(rspname, grspRec.rspname) > 0) LOOP -- -- -- dropGrsp(grspRec.rspname, grspRec.pdb_key); fetchGrsp; END LOOP; IF (grspRec.pdb_key != local_pdb_key OR nlsnamecmp(rspname, grspRec.rspname) < 0) THEN -- addGrsp(rspname, from_scn, to_scn, dbinc_key, create_time, rsp_time, guaranteed, local_pdb_key, clean); ELSE -- (rspname = grspRec.rspname) -- UPDATE grsp SET from_scn = checkGuaranteedRP.from_scn, to_scn = checkGuaranteedRP.to_scn, rsptime = checkGuaranteedRP.rsp_time, guaranteed = checkGuaranteedRP.guaranteed, dbinc_key = dbinc_key WHERE grsp.rspname = checkGuaranteedRP.rspname AND grsp.site_key = this_site_key AND grsp.pdb_key = local_pdb_key; fetchGrsp; END IF; END checkGuaranteedRP; PROCEDURE endGuaranteedRPResync IS BEGIN WHILE (grspRec.rspname != chr(255)) LOOP -- -- dropGrsp(grspRec.rspname, grspRec.pdb_key); fetchGrsp; END LOOP; grspRec.rspname := NULL; -- UPDATE node SET high_grsp_recid = last_grsp_recid WHERE site_key = this_site_key; last_grsp_recid := NULL; END endGuaranteedRPResync; /*-----------------------------------* * RMAN Configuration records resync * *-----------------------------------*/ FUNCTION beginConfigResync( high_conf_recid IN NUMBER ) RETURN NUMBER IS BEGIN checkResync; SELECT high_conf_recid INTO last_conf_recid FROM node WHERE site_key = this_site_key; IF (high_conf_recid = last_conf_recid) THEN RETURN CONFIGRESYNC_NO; -- no resync needed ELSIF (last_conf_recid IS NULL OR high_conf_recid > last_conf_recid) THEN last_conf_recid := high_conf_recid; RETURN CONFIGRESYNC_TORC; -- we need resync from CF to RC ELSE last_conf_recid := high_conf_recid; RETURN CONFIGRESYNC_TOCF; -- we need resync from RC to CF END IF; END beginConfigResync; PROCEDURE endConfigResync IS BEGIN -- UPDATE node SET high_conf_recid = last_conf_recid WHERE site_key = this_site_key; last_conf_recid := NULL; END endConfigResync; FUNCTION beginConfigResync2( high_conf_recid IN NUMBER ) RETURN NUMBER IS to_CF boolean := FALSE; to_Catalog boolean := FALSE; local_force_resync2cf VARCHAR2(3) := 'NO'; curr_cf_version_time DATE; conf_count NUMBER; BEGIN checkResync; SELECT node.high_conf_recid, node.force_resync2cf, cf_create_time INTO last_conf_recid, local_force_resync2cf, curr_cf_version_time FROM node WHERE site_key = this_site_key; -- IF (local_force_resync2cf = 'YES') THEN to_CF := TRUE; END IF; -- -- IF (last_cf_version_time is NULL) THEN SELECT COUNT(*) INTO conf_count FROM CONF WHERE site_key = this_site_key; IF conf_count = 0 THEN to_Catalog := TRUE; END IF; END IF; -- -- -- -- IF (last_cf_version_time <> curr_cf_version_time) THEN IF (this_cf_type = 'CURRENT') THEN IF high_conf_recid > last_conf_recid THEN to_Catalog := TRUE; ELSIF (high_conf_recid < last_conf_recid) THEN to_CF := TRUE; END IF; ELSE to_CF := TRUE; END IF; END IF; -- -- -- -- -- IF (last_cf_version_time = curr_cf_version_time) THEN IF (high_conf_recid > last_conf_recid) THEN to_Catalog := TRUE; ELSIF (high_conf_recid < last_conf_recid) THEN to_CF := TRUE; END IF; END IF; -- -- IF (NOT to_Catalog AND NOT to_CF) THEN RETURN CONFIGRESYNC_NO; END IF; -- -- last_conf_recid := high_conf_recid; -- IF (NOT to_Catalog AND to_CF) THEN RETURN CONFIGRESYNC_TOCF; END IF; -- IF (to_Catalog AND NOT to_CF) THEN RETURN CONFIGRESYNC_TORC; END IF; -- -- IF (to_Catalog AND to_CF) THEN RETURN CONFIGRESYNC_TORC_TOCF; END IF; END beginConfigResync2; PROCEDURE endConfigResync2(sync_to_cf_pending IN boolean DEFAULT FALSE) IS cf_pending number := 0; BEGIN IF sync_to_cf_pending THEN cf_pending := 1; END IF; IF (force_resync2cf = 'YES') THEN deb('endConfigResync2 - force_resync2cf = TRUE'); -- -- UPDATE node SET node.force_resync2cf = 'YES' WHERE node.db_key = this_db_key AND site_key <> this_site_key; END IF; -- -- -- -- -- UPDATE node SET node.high_conf_recid = last_conf_recid, node.force_resync2cf = decode(cf_pending, 1, 'YES', 'NO') WHERE site_key = this_site_key; deb('endConfigResync2 - last_conf_recid='||last_conf_recid); force_resync2cf := 'NO'; last_conf_recid := NULL; END endConfigResync2; PROCEDURE getConfig( conf# OUT number ,name IN OUT varchar2 ,value IN OUT varchar2 ,first IN boolean) IS eof boolean := FALSE; BEGIN -- -- dbms_rcvman.getConfig(conf#, name, value, first); END getConfig; PROCEDURE getRmanOutputLogging(days OUT number) IS conf_value varchar2(512); conf_name varchar2(512) := 'RMAN OUTPUT'; conf# binary_integer; len1 binary_integer; len2 binary_integer; len3 binary_integer; BEGIN deb('Entering getRmanOutputLogging'); days := 0; dbms_rcvman.getConfig(conf#, conf_name, conf_value, TRUE); len1 := length('TO KEEP FOR '); len2 := length(' DAYS'); len3 := length(conf_value); days := to_number(substr(conf_value, len1, len3-len2-len1+1)); deb('getRmanOutputLogging - days = '||days); EXCEPTION WHEN no_data_found THEN deb('getRmanOutputLogging - config not set, taking default'); days := 7; END getRmanOutputLogging; PROCEDURE setKeepOutputForSession(days IN number) IS BEGIN deb('setKeepOutputForSession - session_keep_output = ' || days); session_keep_output := days; END setKeepOutputForSession; PROCEDURE updateRestorePoint( lowscn IN NUMBER ,highscn IN NUMBER DEFAULT NULL -- next scn by another name ) IS nextscn number; refs number; BEGIN -- IF (highscn is null) THEN nextscn := lowscn + 1; ELSE nextscn := highscn; END IF; -- -- UPDATE nrsp r SET LONG_TERM = NULL WHERE r.to_scn >= lowscn AND r.to_scn <= nextscn AND r.long_term IS NOT NULL AND r.site_key = this_site_key; deb('updateRestorePoint - (lowscn ' || lowscn || ' - highscn ' || nextscn || ') rows updated ' || sql%rowcount); END updateRestorePoint; /*-------------------------* * Redo Log History resync * *-------------------------*/ FUNCTION beginLogHistoryResync RETURN NUMBER IS BEGIN checkResync; IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN -- -- SELECT high_rlh_recid INTO last_rlh_recid FROM node WHERE site_key = this_site_key; ELSE last_rlh_recid := sessionWaterMarks.high_rlh_recid; END IF; RETURN last_rlh_recid; END beginLogHistoryResync; FUNCTION getLogHistoryLowSCN RETURN NUMBER IS lowSCN number; BEGIN checkResync; SELECT nvl(max(low_scn), 0) INTO lowSCN FROM rlh WHERE rlh.dbinc_key = this_dbinc_key; RETURN lowSCN; END getLogHistoryLowSCN; PROCEDURE checkLogHistory( rlh_recid IN NUMBER ,rlh_stamp IN NUMBER ,thread# IN NUMBER ,sequence# IN NUMBER ,low_scn IN NUMBER ,low_time IN DATE ,next_scn IN NUMBER ,reset_scn IN number default NULL ,reset_time IN date default NULL ) IS local rlh%rowtype; BEGIN IF (last_rlh_recid IS NULL) THEN raise_application_error(-20037, 'Invalid last recid'); END IF; IF (rlh_recid < last_rlh_recid) THEN raise_application_error(-20036, 'Invalid record order'); END IF; IF (rlh_recid > last_rlh_recid + 1) THEN -- -- NULL; END IF; last_rlh_recid := rlh_recid; IF (last_dbinc_key is NULL or reset_scn is NULL) THEN deb('checkLogHistory - Init last_dbinc_key'); last_dbinc_key := this_dbinc_key; select reset_scn, reset_time into last_reset_scn, last_reset_time from dbinc where dbinc_key = this_dbinc_key; END IF; IF (reset_scn IS NOT NULL and reset_time IS NOT NULL) THEN IF (reset_scn <> last_reset_scn or reset_time <> last_reset_time) THEN BEGIN deb('checkLogHistory - new last_dbinc_key'); deb('checkLogHistory - for reset_time ' || checkLogHistory.reset_time || ' reset_scn ' || checkLogHistory.reset_scn || ' this_db_key ' || this_db_key); select dbinc_key into last_dbinc_key from dbinc where reset_time = checkLogHistory.reset_time and reset_scn = checkLogHistory.reset_scn and db_key = this_db_key; last_reset_scn := reset_scn; last_reset_time := reset_time; EXCEPTION WHEN others THEN raise_application_error(-29999, 'Unknown Incarnation'); END; END IF; END IF; deb('checkLogHistory - last_dbinc_key='||last_dbinc_key|| ' reset_scn '||reset_scn || ' reset_time '||reset_time); BEGIN INSERT INTO rlh( rlh_key, dbinc_key, rlh_recid, rlh_stamp, thread#, sequence#, low_scn, low_time, next_scn) VALUES( rman_seq.nextval, last_dbinc_key, rlh_recid, rlh_stamp, thread#, sequence#, low_scn, low_time, next_scn); EXCEPTION WHEN dup_val_on_index THEN -- -- RETURN; END; END checkLogHistory; PROCEDURE endLogHistoryResync IS BEGIN IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN -- UPDATE node SET high_rlh_recid = last_rlh_recid WHERE site_key = this_site_key; END IF; last_rlh_recid := NULL; END endLogHistoryResync; /*-------------------------* * Archived Log resync * *-------------------------*/ FUNCTION beginArchivedLogResync RETURN NUMBER IS BEGIN checkResync; IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN SELECT high_al_recid INTO last_al_recid FROM node WHERE site_key = this_site_key; ELSE last_al_recid := sessionWaterMarks.high_al_recid; END IF; RETURN last_al_recid; END beginArchivedLogResync; PROCEDURE deleteDuplicateAL(recid IN NUMBER, stamp IN NUMBER, fname in VARCHAR2) IS lfname al.fname%TYPE; BEGIN lfname := fname; IF lfname is null THEN BEGIN SELECT fname INTO lfname from AL WHERE al_recid = recid AND al_stamp = stamp AND al.dbinc_key in (select dbinc_key from dbinc where db_key = this_db_key); EXCEPTION WHEN no_data_found THEN RETURN; WHEN too_many_rows THEN -- unique key is dbinc_key, al_recid, al_stamp RETURN; END; END IF; -- -- DELETE al WHERE al.dbinc_key IN (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key) AND al.fname = lfname AND ((nvl(al.site_key, this_site_key) = this_site_key) OR (logs_shared = TRUE#)) AND al.fname_hashkey = substr(lfname,1,10)||substr(lfname,-10) AND NOT (al.al_recid = recid AND al.al_stamp = stamp ); END deleteDuplicateAL; PROCEDURE checkArchivedLog( al_recid IN NUMBER ,al_stamp IN NUMBER ,thread# IN NUMBER ,sequence# IN NUMBER ,reset_scn IN NUMBER ,reset_time IN DATE ,low_scn IN NUMBER ,low_time IN DATE ,next_scn IN NUMBER ,next_time IN DATE ,blocks IN NUMBER ,block_size IN NUMBER ,fname IN VARCHAR2 ,archived IN VARCHAR2 ,completion_time IN DATE ,status IN VARCHAR2 ,is_standby IN VARCHAR2 ,dictionary_begin IN VARCHAR2 default NULL ,dictionary_end IN VARCHAR2 default NULL ,is_recovery_dest_file IN VARCHAR2 default 'NO' ,compressed IN VARCHAR2 default 'NO' ,creator IN VARCHAR2 default NULL ,terminal IN VARCHAR2 default 'NO' ,chk_last_recid IN boolean default TRUE ) IS local al%rowtype; my_dbinc_key NUMBER; BEGIN -- -- IF chk_last_recid THEN IF (last_al_recid IS NULL) THEN raise_application_error(-20037, 'Invalid last recid'); END IF; IF (al_recid < last_al_recid) THEN raise_application_error(-20036, 'Invalid record order'); END IF; IF (al_recid > last_al_recid + 1) THEN -- -- NULL; END IF; last_al_recid := al_recid; END IF; IF (this_dbinc_key IS NULL) THEN raise_application_error(-20020, 'Database incarnation not set'); END IF; IF (al_stamp > 0 and al_stamp < kccdivts) THEN deb('checkArchivedLog - ignoring record kccdivts='||kccdivts); RETURN; -- obsolete record from a backup controlfile END IF; -- -- IF (sequence# = 0) THEN RETURN; END IF; -- -- -- my_dbinc_key := checkIncarnation(reset_scn, reset_time); BEGIN IF (status = 'D') THEN -- NULL; ELSE INSERT INTO al (al_key, dbinc_key, al_recid, al_stamp, thread#, sequence#, low_scn, low_time, next_scn, next_time, fname, fname_hashkey, archived, blocks, block_size, completion_time, status, is_standby, dictionary_begin, dictionary_end, is_recovery_dest_file, compressed, creator, terminal, site_key) VALUES (rman_seq.nextval, my_dbinc_key, al_recid, al_stamp, thread#, sequence#, low_scn, low_time, next_scn, next_time, fname, substr(fname,1,10)||substr(fname, -10), archived, blocks, checkArchivedLog.block_size, completion_time, status, is_standby, dictionary_begin, dictionary_end, is_recovery_dest_file, compressed, creator, terminal, this_site_key); deleteDuplicateAL(al_recid, al_stamp, fname); END IF; -- -- -- -- IF checkArchivedLog.archived = 'N' then UPDATE rlh SET status = decode(fname, NULL, 'C', status) WHERE rlh.dbinc_key = my_dbinc_key AND rlh.thread# = checkArchivedLog.thread# AND rlh.sequence# = checkArchivedLog.sequence# AND rlh.low_scn = checkArchivedLog.low_scn; END IF; EXCEPTION WHEN dup_val_on_index THEN deb('checkArchivedLog - Inside dup_val_on_index exception'); -- -- SELECT * INTO local FROM al WHERE al.dbinc_key = my_dbinc_key AND (al.is_standby = checkArchivedLog.is_standby OR (al.is_standby is NULL AND checkArchivedLog.is_standby is NULL)) AND al.al_recid = checkArchivedLog.al_recid AND al.al_stamp = checkArchivedLog.al_stamp; -- IF client_site_aware AND this_site_key <> local.site_key THEN raise_application_error(-20081, 'change stamp for the record'); END IF; -- IF (fname <> local.fname) THEN deb('checkArchivedLog - input fname ['||fname||']; local.fname ['|| local.fname || ']'); raise_application_error(-20080, 'Invalid archived log name'); END IF; END; END checkArchivedLog; PROCEDURE endArchivedLogResync IS BEGIN IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN UPDATE node SET high_al_recid = last_al_recid WHERE site_key = this_site_key; END IF; sessionWaterMarks.high_al_recid := last_al_recid; last_al_recid := NULL; END endArchivedLogResync; /*-------------------------* * Offline range resync * *-------------------------*/ FUNCTION beginOfflineRangeResync RETURN NUMBER IS BEGIN checkResync; IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN SELECT high_offr_recid INTO last_offr_recid FROM node WHERE site_key = this_site_key; ELSE last_offr_recid := sessionWaterMarks.high_offr_recid; END IF; RETURN last_offr_recid; END beginOfflineRangeResync; PROCEDURE checkOfflineRange( offr_recid IN NUMBER ,offr_stamp IN NUMBER ,file# IN NUMBER ,create_scn IN NUMBER ,offline_scn IN NUMBER ,online_scn IN NUMBER ,online_time IN DATE ,cf_create_time IN DATE ,reset_scn IN number default NULL ,reset_time IN date default NULL ) IS local offr%rowtype; -- -- BEGIN IF (last_offr_recid IS NULL AND offr_recid IS NOT NULL) THEN raise_application_error(-20037, 'Invalid last recid'); END IF; deb('Checkofflinerange - '|| ' recid: '|| nvl(to_char(offr_recid), 'NULL')|| ' stamp: '|| nvl(to_char(offr_stamp), 'NULL')|| ' file#: '|| file#|| ' create_scn: '|| nvl(to_char(create_scn), 'NULL')|| ' offline_scn: '|| offline_scn || ' online_scn: '|| online_scn|| ' online_time: '|| online_time|| ' cf_create_time: '|| cf_create_time|| ' reset_scn:'|| nvl(reset_scn, -1)); last_offr_recid := offr_recid; IF (last_dbinc_key is NULL OR reset_scn IS NULL) THEN deb('checkOfflineRange - Init dbinc_key: '||this_dbinc_key); last_dbinc_key := this_dbinc_key; SELECT reset_scn, reset_time INTO last_reset_scn, last_reset_time FROM dbinc WHERE dbinc_key = this_dbinc_key; END IF; IF (reset_scn IS NOT NULL and reset_time IS NOT NULL) THEN IF (reset_scn <> last_reset_scn or reset_time <> last_reset_time) THEN BEGIN deb('checkOfflineRange - new incarnation detected'|| ' reset_scn: '|| reset_scn|| ' last_reset_scn: '|| last_reset_scn); SELECT dbinc_key INTO last_dbinc_key FROM dbinc WHERE reset_time = checkOfflineRange.reset_time AND reset_scn = checkOfflineRange.reset_scn AND db_key = this_db_key; last_reset_scn := reset_scn; last_reset_time := reset_time; EXCEPTION WHEN others THEN raise_application_error(-20070, 'Unknown Incarnation'); END; END IF; END IF; deb('checkOfflineRange - dbinc_key is: '||last_dbinc_key); deb('checkOfflineRange - Looking if offline range record already '|| 'exists in OFFR'); BEGIN -- SELECT distinct file#, create_scn, offline_scn, online_scn, online_time INTO local.file#, local.create_scn, local.offline_scn, local.online_scn, local.online_time FROM offr WHERE dbinc_key = last_dbinc_key AND file# = checkOfflineRange.file# AND create_scn = checkOfflineRange.create_scn AND offline_scn = checkOfflineRange.offline_scn; IF local.online_scn <> checkOfflineRange.online_scn THEN deb('checkOfflineRange - Online_scn OK?'|| ' online_scn: ' || online_scn || ' local.online_scn: ' || local.online_scn); -- END IF; IF local.online_time <> checkOfflineRange.online_time THEN deb('checkOfflineRange - Online_time OK?'|| ' online_time: ' || online_time || ' local.online_time: ' || local.online_time); -- END IF; EXCEPTION WHEN no_data_found THEN NULL; -- offline range record not yet known to catalog, go to insert WHEN too_many_rows THEN RAISE; -- there must not be more then on offline range with same -- WHEN others THEN RAISE; END; BEGIN INSERT INTO offr(offr_key, dbinc_key, offr_recid, offr_stamp, file#, create_scn, offline_scn, online_scn, online_time, cf_create_time) VALUES(rman_seq.nextval, last_dbinc_key, offr_recid, nvl(offr_stamp,0), file#, create_scn, offline_scn, online_scn, online_time, cf_create_time); incResyncActions(RESYNC_ACTION_CHANGE, file#, to_char(NULL)); deb('checkOfflineRange - Succesfully inserted new OFFR.'); EXCEPTION WHEN dup_val_on_index THEN deb('checkOfflineRange - record already exists'); IF offr_recid > 0 AND offr_stamp > 0 THEN deb('checkOfflineRange - update new offr_recid, offr_stamp, '|| 'online_scn and online_time'); UPDATE OFFR SET offr_recid = checkOfflineRange.offr_recid, offr_stamp = checkOfflineRange.offr_stamp, online_scn = checkOfflineRange.online_scn, online_time= checkOfflineRange.online_time WHERE dbinc_key = last_dbinc_key AND file# = checkOfflineRange.file# AND create_scn = checkOfflineRange.create_scn AND offline_scn = checkOfflineRange.offline_scn AND cf_create_time = checkOfflineRange.cf_create_time; incResyncActions(RESYNC_ACTION_CHANGE, file#, to_char(NULL)); END IF; END; deb('checkOfflineRange - exiting'); END; PROCEDURE endOfflineRangeResync IS BEGIN IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN UPDATE node SET high_offr_recid = last_offr_recid WHERE site_key = this_site_key; END IF; -- IF this_is_ors and this_ckp_type = 'FULL' THEN UPDATE watermarks SET high_offr_recid = last_offr_recid WHERE db_key = this_db_key; END IF; sessionWaterMarks.high_offr_recid := last_offr_recid; last_offr_recid := NULL; END endOfflineRangeResync; /*-------------------------* * Backup Set resync * *-------------------------*/ -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE updateBackupSetRec(bs_key IN NUMBER) IS total_pieces NUMBER; backup_validate VARCHAR2(3); available_pieces NUMBER; new_status VARCHAR2(1); bskeep NUMBER; bstype VARCHAR2(1); low NUMBER := NULL; high NUMBER := NULL; bs_site_key NUMBER := NULL; not_purged NUMBER := 0; pieces_on_msite NUMBER; new_site_key NUMBER; need_resync NUMBER := 0; dbkey NUMBER; incr_lvl NUMBER; ra_node_count NUMBER; BEGIN deb('updateBackupSetRec, bs_key=' || bs_key); -- -- BEGIN SELECT pieces,input_file_scan_only, keep_options, bck_type, site_key, incr_level, db_key INTO total_pieces,backup_validate, bskeep, bstype, bs_site_key, incr_lvl, dbkey FROM bs WHERE bs.bs_key = updateBackupSetRec.bs_key; EXCEPTION WHEN no_data_found THEN new_status := 'D'; -- all pieces are deleted or not there END; IF nvl(backup_validate,'NO') <> 'YES' THEN SELECT max(count(DISTINCT piece#)) INTO available_pieces FROM bp WHERE bp.bs_key = updateBackupSetRec.bs_key AND bp.status = 'A' GROUP BY device_type; SELECT count(*) INTO not_purged FROM bp WHERE bp.bs_key = updateBackupSetRec.bs_key AND bp.purged = 'N' AND bp.ba_access IN ('L', 'D'); END IF; -- IF bs_site_key IS NULL OR bs_site_key <> this_site_key THEN SELECT count(distinct nvl(site_key, 0)) INTO pieces_on_msite FROM bp WHERE bs_key = updateBackupSetRec.bs_key; IF pieces_on_msite = 1 THEN SELECT distinct site_key INTO new_site_key FROM BP WHERE bs_key = updateBackupSetRec.bs_key; END IF; -- UPDATE bs SET site_key = new_site_key WHERE bs.bs_key = updateBackupSetRec.bs_key; END IF; deb('updateBackupSetRec, total_piece='||total_pieces|| ', available_pieces='||available_pieces|| ', not_purged='||not_purged); IF (total_pieces = 0 or backup_validate = 'YES') THEN -- new_status := 'D'; ELSIF (available_pieces = total_pieces) THEN new_status := 'A'; ELSE BEGIN -- SELECT 'O' INTO new_status FROM bp WHERE bp.bs_key = updateBackupSetRec.bs_key AND bp.status != 'D' AND rownum < 2; EXCEPTION WHEN no_data_found THEN new_status := 'D'; -- all pieces are deleted or not there END; END IF; deb('updateBackupSetRec, new_status='||new_status||',val='||backup_validate); IF (new_status in ('O', 'A') OR backup_validate = 'YES' OR not_purged != 0) THEN UPDATE bs SET status = new_status WHERE bs.bs_key = updateBackupSetRec.bs_key; ELSE -- IF (bskeep > 0 and bstype = 'L') THEN SELECT min(low_scn), max(next_scn) INTO low, high FROM brl WHERE bs_key = updateBackupSetRec.bs_key; END IF; IF (bskeep > 0 and bstype = 'D') THEN SELECT min(ckp_scn) INTO low FROM bdf WHERE bs_key = updateBackupSetRec.bs_key; END IF; -- -- -- IF (this_is_ors AND incr_lvl IS NOT NULL AND this_enable_populate_rsr = 1) THEN BEGIN -- -- IF this_upstream_site_key IS NULL THEN SELECT site_key INTO this_upstream_site_key FROM node WHERE node.db_key = dbkey AND database_role = 'RA' AND db_unique_name like '$%$%' AND db_unique_name not like '$%$%$%'; END IF; deb('updateBackupSetRec, this_upstream_site_key = ' || this_upstream_site_key); -- -- SELECT count(*) INTO need_resync FROM bp WHERE bs_key = updateBackupSetRec.bs_key AND ((ba_access = 'L' AND vb_key IS NULL AND substr(handle,1,6) != 'RA_SBT') -- -- OR (ba_access = 'D' AND rsr_key IS NULL)) -- -- -- AND site_key = this_upstream_site_key; EXCEPTION WHEN no_data_found THEN deb('updateBackupSetRec, node table has no RA rows with db_key ' || dbkey); END; END IF; IF need_resync = 0 THEN -- -- deb('updateBackupSetRec, deleting rows from BP and BS for bs_key=' || updateBackupSetRec.bs_key); DELETE from bp WHERE bp.bs_key = updateBackupSetRec.bs_key; deb('updateBackupSetRec, deleted rows from bp =' || SQL%ROWCOUNT); DELETE FROM bs WHERE bs.bs_key = updateBackupSetRec.bs_key; deb('updateBackupSetRec, deleted rows from bs =' || SQL%ROWCOUNT); ELSE deb('updateBackupSetRec, Skipping deletion of bs_key = ' || bs_key || '. Waiting till resync happens to delete this.'); END IF; -- IF (low IS NOT NULL) THEN updateRestorePoint(low, high); END IF; END IF; END updateBackupSetRec; FUNCTION beginBackupSetResync RETURN NUMBER IS BEGIN checkResync; IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN SELECT high_bs_recid INTO last_bs_recid FROM node WHERE site_key = this_site_key; ELSE last_bs_recid := sessionWaterMarks.high_bs_recid; END IF; RETURN last_bs_recid; END beginBackupSetResync; PROCEDURE checkBackupSet( bs_recid IN NUMBER ,bs_stamp IN NUMBER ,set_stamp IN NUMBER ,set_count IN NUMBER ,bck_type IN VARCHAR2 ,incr_level IN NUMBER DEFAULT NULL ,pieces IN NUMBER ,start_time IN DATE ,completion_time IN DATE ,controlfile_included IN VARCHAR2 DEFAULT NULL ,input_file_scan_only IN VARCHAR2 DEFAULT NULL ,keep_options IN NUMBER DEFAULT 0 ,keep_until IN DATE DEFAULT NULL ,block_size IN NUMBER DEFAULT NULL ,multi_section IN VARCHAR2 DEFAULT NULL ,chk_last_recid IN BOOLEAN DEFAULT TRUE ,guid IN RAW DEFAULT NULL ,dropped_pdb IN BINARY_INTEGER DEFAULT 0 ) IS local bs%rowtype; newbskey number; l_pdb_key number; BEGIN IF (chk_last_recid) THEN IF (last_bs_recid IS NULL) THEN raise_application_error(-20037, 'Invalid last recid'); END IF; IF (bs_recid < last_bs_recid) THEN raise_application_error(-20036, 'Invalid record order'); END IF; IF (bs_recid > last_bs_recid + 1) THEN -- NULL; END IF; last_bs_recid := bs_recid; END IF; IF (bs_stamp > 0 and bs_stamp < kccdivts) THEN deb('checkBackupSet - ignoring record kccdivts='||kccdivts); RETURN; -- obsolete record from a backup controlfile END IF; IF (bck_type NOT IN ('D','I','L') OR bck_type IS NULL) THEN raise_application_error(-20090, 'Invalid backup set type'); END IF; IF (incr_level NOT IN (0,1,2,3,4) OR (bck_type NOT IN ('D','I') AND incr_level <> 0)) THEN raise_application_error(-20091, 'Invalid backup set level'); END IF; l_pdb_key := guidToPdbKey(guid, dropped_pdb); BEGIN -- -- INSERT INTO bs (bs_key, db_key, bs_recid, bs_stamp, set_stamp, set_count, bck_type, incr_level, pieces, start_time, completion_time, status, controlfile_included, input_file_scan_only, keep_options, keep_until, block_size, site_key, multi_section, pdb_key) VALUES (rman_seq.nextval, this_db_key, bs_recid, bs_stamp, set_stamp, set_count, bck_type, incr_level, pieces, start_time, completion_time, 'D', decode(controlfile_included, 'SBY','STANDBY','YES','BACKUP','NONE'), input_file_scan_only, keep_options, keep_until, block_size, this_site_key, decode(multi_section,'YES','Y',null), l_pdb_key) RETURNING bs_key INTO newbskey; cntbs := cntbs + 1; updatebs(cntbs) := newbskey; EXCEPTION WHEN dup_val_on_index THEN deb('checkBackupSet - Inside dup_val_on_index exception'); -- SELECT * INTO local FROM bs WHERE bs.db_key = this_db_key AND bs.set_stamp = checkBackupSet.set_stamp AND bs.set_count = checkBackupSet.set_count; duplicatebs(local.bs_key) := 1; -- -- -- IF (pieces > local.pieces) THEN UPDATE bs SET bs.pieces = checkBackupSet.pieces WHERE bs.db_key = this_db_key AND bs.bs_key = local.bs_key; -- cntbs:= cntbs + 1; updatebs(cntbs) := local.bs_key; END IF; -- -- -- -- -- -- IF local.site_key IS NULL AND cntbs > 0 AND updatebs(cntbs) <> local.bs_key THEN cntbs := cntbs + 1; updatebs(cntbs) := local.bs_key; END IF; IF (local.completion_time <> checkBackupSet.completion_time) THEN UPDATE bs SET completion_time = checkBackupSet.completion_time WHERE bs.db_key = this_db_key AND bs.bs_key = local.bs_key; END IF; END; END checkBackupSet; PROCEDURE endBackupSetResync IS BEGIN IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN -- UPDATE node SET high_bs_recid = last_bs_recid WHERE site_key = this_site_key; END IF; sessionWaterMarks.high_bs_recid := last_bs_recid; last_bs_recid := NULL; END endBackupSetResync; /*-------------------------* * Backup piece resync * *-------------------------*/ FUNCTION beginBackupPieceResync RETURN NUMBER IS BEGIN checkResync; IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN SELECT high_bp_recid INTO last_bp_recid FROM node WHERE site_key = this_site_key; ELSE last_bp_recid := sessionWaterMarks.high_bp_recid; END IF; RETURN last_bp_recid; END beginBackupPieceResync; PROCEDURE deleteDuplicateBP(recid IN NUMBER, stamp IN NUMBER, bs_key IN NUMBER, device_type IN VARCHAR2, handle IN VARCHAR2) IS ldevice_type bp.device_type%TYPE; lhandle bp.device_type%TYPE; BEGIN ldevice_type := device_type; lhandle := handle; IF ldevice_type IS NULL OR lhandle IS NULL THEN BEGIN SELECT device_type, handle INTO ldevice_type, lhandle FROM BP WHERE bp.db_key = this_db_key AND bp_recid = recid AND bp_stamp = stamp AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))) AND deleteDuplicateBP.bs_key = bp.bs_key; EXCEPTION WHEN no_data_found THEN RETURN; WHEN too_many_rows THEN -- unique key is bs_key, recid, stamp RETURN; END; END IF; IF this_is_ors AND this_ckp_key IS NULL THEN this_enable_populate_rsr := getValueFromConfig('_enable_populate_rsr_key'); END IF; -- -- -- -- FOR bprec IN bpq(ldevice_type, lhandle, recid, stamp) LOOP UPDATE bp SET bp.status = 'D' WHERE bp.bp_key = bprec.bp_key; updateBackupSetRec(bprec.bs_key); -- update the backupset status END LOOP; -- -- IF this_is_ors AND this_ckp_key IS NULL THEN this_enable_populate_rsr := NULL; this_upstream_site_key := NULL; END IF; END deleteDuplicateBP; PROCEDURE checkBackupPiece( bp_recid IN NUMBER ,bp_stamp IN NUMBER ,set_stamp IN NUMBER ,set_count IN NUMBER ,piece# IN NUMBER ,tag IN VARCHAR2 ,device_type IN VARCHAR2 ,handle IN VARCHAR2 ,comments IN VARCHAR2 ,media IN VARCHAR2 ,concur IN VARCHAR2 ,start_time IN DATE ,completion_time IN DATE ,status IN VARCHAR2 ,copy# IN NUMBER default 1 ,media_pool IN NUMBER default 0 ,bytes IN NUMBER default NULL ,is_recovery_dest_file IN VARCHAR2 default 'NO' ,rsr_recid IN NUMBER default NULL ,rsr_stamp IN NUMBER default NULL ,compressed IN VARCHAR2 default 'NO' ,encrypted IN VARCHAR2 default 'NO' ,backed_by_osb IN VARCHAR2 default 'NO' ,ba_access IN VARCHAR2 default 'U' ,vbkey IN NUMBER default NULL ,chk_last_recid IN BOOLEAN default TRUE ,lib_key IN NUMBER default NULL ,guid IN RAW default NULL ,template_key IN NUMBER default NULL ,dropped_pdb IN BINARY_INTEGER default 0 ) IS bp_key NUMBER; BEGIN bp_key := checkBackupPiece( bp_recid => bp_recid ,bp_stamp => bp_stamp ,set_stamp => set_stamp ,set_count => set_count ,piece# => piece# ,tag => tag ,device_type => device_type ,handle => handle ,comments => comments ,media => media ,concur => concur ,start_time => start_time ,completion_time => completion_time ,status => status ,copy# => copy# ,media_pool => media_pool ,bytes => bytes ,is_recovery_dest_file => is_recovery_dest_file ,rsr_recid => rsr_recid ,rsr_stamp => rsr_stamp ,compressed => compressed ,encrypted => encrypted ,backed_by_osb => backed_by_osb ,ba_access => ba_access ,vbkey => vbkey ,chk_last_recid => chk_last_recid ,lib_key => lib_key ,guid => guid ,template_key => template_key ,dropped_pdb => dropped_pdb); END checkBackupPiece; FUNCTION checkBackupPiece( bp_recid IN NUMBER ,bp_stamp IN NUMBER ,set_stamp IN NUMBER ,set_count IN NUMBER ,piece# IN NUMBER ,tag IN VARCHAR2 ,device_type IN VARCHAR2 ,handle IN VARCHAR2 ,comments IN VARCHAR2 ,media IN VARCHAR2 ,concur IN VARCHAR2 ,start_time IN DATE ,completion_time IN DATE ,status IN VARCHAR2 ,copy# IN NUMBER default 1 -- No longer in use ,media_pool IN NUMBER default 0 ,bytes IN NUMBER default NULL ,is_recovery_dest_file IN VARCHAR2 default 'NO' ,rsr_recid IN NUMBER default NULL ,rsr_stamp IN NUMBER default NULL ,compressed IN VARCHAR2 default 'NO' ,encrypted IN VARCHAR2 default 'NO' ,backed_by_osb IN VARCHAR2 default 'NO' ,ba_access IN VARCHAR2 default 'U' ,vbkey IN NUMBER default NULL ,chk_last_recid IN BOOLEAN default TRUE ,lib_key IN NUMBER default NULL ,guid IN RAW default NULL ,template_key IN NUMBER default NULL ,dropped_pdb IN BINARY_INTEGER default 0 ) RETURN NUMBER IS localbs bs%rowtype; localbp bp%rowtype; localrsr rsr%rowtype; piece_exists BINARY_INTEGER := 0; l_copyno NUMBER := 1; l_update_bs_pieces BOOLEAN := FALSE; l_pdb_key NUMBER; l_bp_recid NUMBER; BEGIN IF (chk_last_recid) THEN IF (last_bp_recid IS NULL) THEN raise_application_error(-20037, 'Invalid last recid'); END IF; IF (bp_recid < last_bp_recid) THEN deb('checkBackupPiece - last_bp_recid=' || last_bp_recid); raise_application_error(-20036, 'Invalid record order'); END IF; IF (bp_recid > last_bp_recid + 1) THEN -- -- NULL; END IF; last_bp_recid := bp_recid; END IF; IF (bp_stamp > 0 and bp_stamp < kccdivts) THEN deb('checkBackupPiece - ignoring record kccdivts='||kccdivts); RETURN NULL; -- obsolete record from a backup controlfile END IF; -- IF handle IS NULL AND status != 'D' THEN deb('checkBackupPiece - handle is null, ignore this row'); RETURN NULL; END IF; -- -- -- -- -- -- -- -- -- IF bp_recid = 0 OR this_wmrec.high_bp_recid >= 0 THEN this_high_bp_recid := this_high_bp_recid + 1; l_bp_recid := this_high_bp_recid; deb('checkBackupPiece - generating bp_recid=' || l_bp_recid || ', ba_access=' || ba_access || ',handle=' || handle); ELSE l_bp_recid := bp_recid; END IF; -- -- -- l_pdb_key := guidToPdbKey(guid, dropped_pdb); -- BEGIN SELECT * into localbs from bs WHERE bs.db_key = this_db_key AND bs.set_stamp = checkBackupPiece.set_stamp AND bs.set_count = checkBackupPiece.set_count FOR UPDATE OF bs.bs_key; deb('checkBackupPiece - locked bs_key' || localbs.bs_key); IF this_db_unique_name = upper(this_server.wallet_alias) THEN deb('checkBackupPiece - doing reconcile is TRUE'); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- END IF; EXCEPTION WHEN no_data_found THEN IF status != 'D' THEN INSERT INTO bs (bs_key, db_key, bs_recid, bs_stamp, set_stamp, set_count, bck_type, incr_level, pieces, start_time, completion_time, status, controlfile_included, site_key, multi_section, pdb_key) VALUES -- -- -- -- -- -- -- -- (rman_seq.nextval, this_db_key, 0, checkBackupPiece.set_stamp, checkBackupPiece.set_stamp, checkBackupPiece.set_count, NULL, NULL, checkBackupPiece.piece#, checkBackupPiece.start_time, checkBackupPiece.completion_time, 'O', 'NONE', this_site_key, NULL, l_pdb_key) RETURNING bs_key INTO localbs.bs_key; cntbs := cntbs + 1; updatebs(cntbs) := localbs.bs_key; ELSE -- RETURN NULL; END IF; END; -- -- IF (status = 'D') THEN cntbs:= cntbs + 1; updatebs(cntbs) := localbs.bs_key; RETURN NULL; END IF; -- IF (localbs.bs_recid is null OR localbs.bs_recid = 0) AND checkBackupPiece.piece# > localbs.pieces THEN l_update_bs_pieces := TRUE; ELSE -- -- -- -- SELECT NVL(MAX(copy#), 0)+1 INTO l_copyno FROM bp WHERE piece# = checkBackupPiece.piece# AND bs_key = localbs.bs_key; END IF; -- BEGIN SELECT rsr_key INTO localrsr.rsr_key FROM rsr WHERE rsr.dbinc_key = this_dbinc_key AND (rsr.site_key = this_site_key OR rsr.site_key is null AND this_site_key is NULL) AND rsr.rsr_stamp = checkBackupPiece.rsr_stamp AND rsr.rsr_recid = checkBackupPiece.rsr_recid; EXCEPTION WHEN no_data_found THEN -- NULL; END; SELECT MAX(bp_key) INTO localbp.bp_key FROM bp WHERE bp.handle = checkBackupPiece.handle AND bp.device_type = checkBackupPiece.device_type AND bp.bs_key = localbs.bs_key AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))); BEGIN IF (localbp.bp_key IS NOT NULL) THEN UPDATE bp SET bp_recid = l_bp_recid, bp_stamp = checkBackupPiece.bp_stamp, comments = checkBackupPiece.comments, media = checkBackupPiece.media, media_pool = checkBackupPiece.media_pool, concur = decode(checkBackupPiece.concur, 'YES', 'Y', 'N'), start_time = checkBackupPiece.start_time, completion_time = checkBackupPiece.completion_time, bytes = checkBackupPiece.bytes, is_recovery_dest_file = checkBackupPiece.is_recovery_dest_file, rsr_key = localrsr.rsr_key, site_key = this_site_key, backed_by_osb = decode(checkBackupPiece.backed_by_osb, 'YES', 'Y', 'N') WHERE bp_key = localbp.bp_key; ELSE -- -- -- IF (this_is_ors AND -- in ORS schema? ba_access = 'U' AND -- record pushed by rman resync? isOrsMedia(checkBackupPiece.media)) THEN deb('checkBackupPiece - ORS media backup piece - skipping'); cntbs:= cntbs + 1; updatebs(cntbs) := localbs.bs_key; RETURN NULL; END IF; INSERT INTO bp (bp_key, bs_key, piece#, db_key, bp_recid, bp_stamp, tag, device_type, copy#, handle, handle_hashkey, comments, media, media_pool, concur, start_time, completion_time, status, bytes, is_recovery_dest_file, rsr_key, compressed, site_key, encrypted, backed_by_osb, ba_access, vb_key, lib_key, purged, pdb_key, template_key) VALUES (rman_seq.nextval, localbs.bs_key, checkBackupPiece.piece#, this_db_key, l_bp_recid, checkBackupPiece.bp_stamp, checkBackupPiece.tag, checkBackupPiece.device_type, l_copyno, checkBackupPiece.handle, substr(checkBackupPiece.device_type,1,10) || substr(checkBackupPiece.handle,1,10) || substr(checkBackupPiece.handle,-10), checkBackupPiece.comments, checkBackupPiece.media, checkBackupPiece.media_pool, decode(checkBackupPiece.concur,'YES','Y','N'), checkBackupPiece.start_time, checkBackupPiece.completion_time, checkBackupPiece.status, checkBackupPiece.bytes, checkBackupPiece.is_recovery_dest_file, localrsr.rsr_key, checkBackupPiece.compressed, this_site_key, decode(checkBackupPiece.encrypted, 'YES', 'Y', 'N'), decode(checkBackupPiece.backed_by_osb, 'YES', 'Y', 'N'), checkBackupPiece.ba_access, checkBackupPiece.vbkey, checkBackupPiece.lib_key, decode(checkBackupPiece.ba_access, 'U', 'U', 'N'), l_pdb_key, checkBackupPiece.template_key) RETURNING bp_key INTO localbp.bp_key; -- IF this_is_ors THEN UPDATE sbt_template_db std SET std.last_bp_key = localbp.bp_key WHERE std.db_key = this_db_key AND std.last_bp_key > localbp.bp_key; END IF; END IF; -- IF this_is_ors AND getValueFromConfig('_enable_populate_rsr_key') = 1 THEN EXECUTE IMMEDIATE 'BEGIN dbms_rai_populate_rsr_key(:1,:2); END;' USING localbp.bp_key, localbs.bs_key; END IF; -- deleteDuplicateBP(l_bp_recid, bp_stamp, localbs.bs_key, device_type, handle); -- -- IF l_update_bs_pieces THEN UPDATE bs SET bs.pieces = checkBackupPiece.piece# WHERE bs.bs_key = localbs.bs_key AND bs.bck_type IS NULL; END IF; -- updateBackupSetRec(localbs.bs_key); EXCEPTION WHEN dup_val_on_index THEN deb('checkBackupPiece - Inside dup_val_on_index exception'); -- -- SELECT * INTO localbp FROM bp WHERE bp.bs_key = localbs.bs_key AND bp.bp_recid = l_bp_recid AND bp.bp_stamp = checkBackupPiece.bp_stamp; -- IF client_site_aware AND this_site_key <> localbp.site_key THEN raise_application_error(-20081, 'change stamp for the record'); END IF; -- IF (piece# <> localbp.piece#) THEN raise_application_error(-20093, 'Invalid piece#'); END IF; -- IF localbp.site_key IS NULL THEN UPDATE bp SET site_key = this_site_key WHERE bp.bs_key = localbs.bs_key AND bp.bp_recid = l_bp_recid AND bp.bp_stamp = checkBackupPiece.bp_stamp; END IF; WHEN OTHERS THEN deb('checkBackupPiece - inside exception hndle='||sqlerrm); RAISE; END; RETURN localbp.bp_key; END checkBackupPiece; PROCEDURE endBackupPieceResync IS BEGIN IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN deb('endBackupPieceResync - last_bp_recid=' || last_bp_recid); UPDATE node SET high_bp_recid = last_bp_recid WHERE site_key = this_site_key; END IF; sessionWaterMarks.high_bp_recid := last_bp_recid; last_bp_recid := NULL; END endBackupPieceResync; /*-------------------------* * Backup Datafile resync * *-------------------------*/ PROCEDURE addBackupControlFile( bs_key IN NUMBER ,bcf_recid IN NUMBER ,bcf_stamp IN NUMBER ,dbinc_key IN NUMBER ,ckp_scn IN NUMBER ,ckp_time IN DATE ,create_time IN DATE ,min_offr_recid IN NUMBER ,blocks IN NUMBER ,block_size IN NUMBER ,controlfile_type IN VARCHAR2 ,cfile_abck_year IN number ,cfile_abck_mon_day IN number ,cfile_abck_seq IN number ,pdb_key IN NUMBER ) IS local bcf%rowtype; l_conflict_count NUMBER := 0; BEGIN BEGIN INSERT INTO bcf(bcf_key, bs_key, dbinc_key, bcf_recid, bcf_stamp, ckp_scn, ckp_time, create_time, min_offr_recid, block_size, controlfile_type, blocks, autobackup_date, autobackup_sequence, pdb_key) VALUES (rman_seq.nextval, bs_key, dbinc_key, bcf_recid, bcf_stamp, ckp_scn, ckp_time, create_time, min_offr_recid,block_size, controlfile_type, blocks, decode(cfile_abck_year, 0, to_date(NULL), to_date(to_char(cfile_abck_year)|| lpad(to_char(cfile_abck_mon_day), 4, '0'), 'YYYYMMDD', 'NLS_CALENDAR=Gregorian')), cfile_abck_seq, pdb_key); IF (duplicatebs.exists(addBackupControlFile.bs_key)) THEN DECLARE CURSOR bcf_conflicts(bs_key_new IN NUMBER ) IS SELECT bs_key, bcf_key, dbinc_key, ckp_scn, ckp_time, block_size, controlfile_type, blocks, pdb_key FROM bcf WHERE bcf.bs_key = bs_key_new; conflict_rec bcf_conflicts%rowtype; BEGIN FOR conflict_rec IN bcf_conflicts(addBackupControlFile.bs_key) LOOP deb('addBackupControlfile set stamp set count conflict rec- ' || ' bs_key ' || to_char(conflict_rec.bs_key) || ' bcf_key ' || to_char(conflict_rec.bcf_key) || ' dbinc_key ' || to_char(conflict_rec.dbinc_key) || ' ckp_scn ' || to_char(conflict_rec.ckp_scn) || ' ckp_time ' || to_char(conflict_rec.ckp_time) || ' block_size ' || to_char(conflict_rec.block_size) || ' controlfile_type ' || conflict_rec.controlfile_type || ' blocks ' || to_char(conflict_rec.blocks) || ' pdb_key ' || to_char(conflict_rec.pdb_key)); END LOOP; END; raise_application_error(-20110, 'set stamp set count conflict'); END IF; EXCEPTION WHEN dup_val_on_index THEN deb('addBackupControlfile - Inside dup_val_on_index exception'); SELECT count(*) INTO l_conflict_count FROM bcf WHERE bcf.bs_key = addBackupControlFile.bs_key AND ( bcf.ckp_scn <> addBackupControlFile.ckp_scn OR bcf.ckp_time <> addBackupControlFile.ckp_time OR bcf.block_size <> addBackupControlFile.block_size OR bcf.controlfile_type <> addBackupControlFile.controlfile_type OR bcf.blocks <> addBackupControlFile.blocks ) AND ROWNUM = 1 ; IF (l_conflict_count > 0) THEN DECLARE CURSOR bcf_conflicts(bs_key_new IN NUMBER, ckp_scn_new IN NUMBER, ckp_time_new IN DATE, block_size_new IN NUMBER, controlfile_type_new IN VARCHAR2, blocks_new IN NUMBER) IS SELECT bs_key, bcf_key, dbinc_key, ckp_scn, ckp_time, block_size, controlfile_type, blocks, pdb_key FROM bcf WHERE bcf.bs_key = bs_key_new AND ( bcf.ckp_scn <> ckp_scn_new OR bcf.ckp_time <> ckp_time_new OR bcf.block_size <> block_size_new OR bcf.controlfile_type <> controlfile_type_new OR bcf.blocks <> blocks_new ); BEGIN FOR conflict_rec IN bcf_conflicts(addBackupControlFile.bs_key, addBackupControlFile.ckp_scn, addBackupControlFile.ckp_time, addBackupControlFile.block_size, addBackupControlFile.controlfile_type, addBackupControlFile.blocks) LOOP deb('addBackupControlfile set stamp set count existing rec- ' || ' bs_key ' || to_char(conflict_rec.bs_key) || ' bcf_key ' || to_char(conflict_rec.bcf_key) || ' dbinc_key ' || to_char(conflict_rec.dbinc_key) || ' ckp_scn ' || to_char(conflict_rec.ckp_scn) || ' ckp_time ' || to_char(conflict_rec.ckp_time) || ' block_size ' || to_char(conflict_rec.block_size) || ' controlfile_type ' || conflict_rec.controlfile_type || ' blocks ' || to_char(conflict_rec.blocks) || ' pdb_key ' || to_char(conflict_rec.pdb_key)); END LOOP; deb('addBackupControlfile set stamp set count new conflict rec- ' || ' bs_key ' || to_char(addBackupControlfile.bs_key) || ' dbinc_key ' || to_char(addBackupControlfile.dbinc_key) || ' ckp_scn ' || to_char(addBackupControlfile.ckp_scn) || ' ckp_time ' || to_char(addBackupControlfile.ckp_time) || ' block_size ' || to_char(addBackupControlfile.block_size) || ' controlfile_type ' || addBackupControlfile.controlfile_type || ' blocks ' || to_char(addBackupControlfile.blocks) || ' pdb_key ' || to_char(addBackupControlfile.pdb_key)); END; raise_application_error(-20110, 'set stamp set count conflict'); END IF; -- -- SELECT ckp_scn, ckp_time, bcf_recid, bcf_stamp INTO local.ckp_scn, local.ckp_time, local.bcf_recid, local.bcf_stamp FROM bcf WHERE bcf.bs_key = addBackupControlFile.bs_key; -- IF (ckp_scn <> local.ckp_scn or ckp_time <> local.ckp_time) THEN deb('addBackupControlfile - ckp_scn '||ckp_scn||' ckp_time '|| to_char(ckp_time)); deb('addBackupControlfile - lckp_scn '||local.ckp_scn||' lckp_time '|| to_char(local.ckp_time)); raise_application_error(-20095, 'Invalid ckp_scn or ckp_time'); END IF; -- IF local.bcf_recid <> bcf_recid or local.bcf_stamp <> bcf_stamp THEN UPDATE bcf set bcf_recid = addBackupControlFile.bcf_recid, bcf_stamp = addBackupControlFile.bcf_stamp WHERE bcf.bs_key = addBackupControlFile.bs_key; END IF; END; END addBackupControlFile; PROCEDURE addBackupDataFile( bs_key IN NUMBER ,bdf_recid IN NUMBER ,bdf_stamp IN NUMBER ,file# IN NUMBER ,create_scn IN NUMBER ,dbinc_key IN NUMBER ,incr_level IN NUMBER ,incr_scn IN NUMBER ,ckp_scn IN NUMBER ,ckp_time IN DATE ,abs_fuzzy_scn IN NUMBER ,datafile_blocks IN NUMBER ,blocks IN NUMBER ,block_size IN NUMBER ,completion_time IN DATE ,blocks_read IN NUMBER ,create_time IN DATE ,marked_corrupt IN NUMBER ,used_chg_track IN VARCHAR2 ,used_optim IN VARCHAR2 ,foreign_dbid IN NUMBER ,plugged_readonly IN VARCHAR2 ,plugin_scn IN NUMBER ,plugin_reset_scn IN NUMBER ,plugin_reset_time IN DATE ,section_size IN NUMBER ,pdb_key IN NUMBER ,sparse_backup IN VARCHAR2 ,isReSync IN BOOLEAN ,isVirtual IN BOOLEAN ) IS local bdf%rowtype; l_conflict_count NUMBER := 0; l_UB4MAXVAL CONSTANT NUMBER := 4294967295; BEGIN deb('addBackupDataFile - bs_key ' || bs_key || ' file# ' || file#); BEGIN INSERT INTO bdf(bdf_key, dbinc_key, bdf_recid, bdf_stamp, bs_key, file#, create_scn, incr_level, incr_scn, ckp_scn, ckp_time, abs_fuzzy_scn, datafile_blocks, blocks, block_size, completion_time, blocks_read, create_time, marked_corrupt, used_chg_track, used_optim, foreign_dbid, plugged_readonly, plugin_scn, plugin_reset_scn, plugin_reset_time, section_size, pdb_key, sparse_backup) VALUES (rman_seq.nextval, dbinc_key, bdf_recid, bdf_stamp, bs_key, file#, create_scn, incr_level, incr_scn, ckp_scn, ckp_time, abs_fuzzy_scn, datafile_blocks, blocks, block_size, completion_time, nvl(blocks_read, datafile_blocks), create_time, marked_corrupt, decode(used_chg_track, 'YES', 'Y', 'N'), decode(used_optim, 'YES', 'Y', 'N'), foreign_dbid, plugged_readonly, plugin_scn, plugin_reset_scn, plugin_reset_time, section_size, pdb_key, sparse_backup); IF (duplicatebs.exists(addBackupDataFile.bs_key)) THEN DECLARE CURSOR bdf_conflicts(bs_key_new IN NUMBER) IS SELECT bs_key, bdf_key, dbinc_key, file#, bdf_recid, bdf_stamp, ckp_scn, ckp_time, datafile_blocks, block_size, plugin_scn, section_size FROM bdf WHERE bdf.bs_key = bs_key_new; conflict_rec bdf_conflicts%rowtype; BEGIN FOR conflict_rec IN bdf_conflicts(addBackupDatafile.bs_key) LOOP deb('addBackupDatafile set stamp set count conflict - ' || ' bs_key ' || to_char(conflict_rec.bs_key) || ' bdf_key ' || to_char(conflict_rec.bdf_key) || ' dbinc_key ' || to_char(conflict_rec.dbinc_key) || ' file# ' || to_char(conflict_rec.file#) || ' bdf_recid ' || to_char(conflict_rec.bdf_recid) || ' bdf_stamp ' || to_char(conflict_rec.bdf_stamp) || ' ckp_scn ' || to_char(conflict_rec.ckp_scn) || ' ckp_time ' || to_char(conflict_rec.ckp_time) || ' datafile_blocks ' || to_char(conflict_rec.datafile_blocks) || ' block_size ' || to_char(conflict_rec.block_size) || ' plugin_scn ' || to_char(conflict_rec.plugin_scn) || ' section_size ' || to_char(conflict_rec.section_size)); END LOOP; END; raise_application_error(-20110, 'set stamp set count conflict'); END IF; EXCEPTION WHEN dup_val_on_index THEN deb('addBackupDataFile - Inside dup_val_on_index exception'); SELECT count(*) INTO l_conflict_count FROM bdf WHERE bdf.bs_key = addBackupDataFile.bs_key AND bdf.file# = addBackupDataFile.file# AND ( bdf.ckp_scn <> addBackupDataFile.ckp_scn OR bdf.ckp_time <> addBackupDataFile.ckp_time OR bdf.datafile_blocks <> addBackupDataFile.datafile_blocks OR bdf.block_size <> addBackupDataFile.block_size OR bdf.plugin_scn <> addBackupDataFile.plugin_scn ) AND ROWNUM = 1; deb('addBackupDataFile - l_conflict_count: '|| l_conflict_count); deb('addBackupDataFile - sect size: '|| addBackupDataFile.section_size); IF (l_conflict_count > 0 AND addBackupDataFile.section_size = 0 ) THEN DECLARE CURSOR bdf_conflicts(bs_key_new IN NUMBER, file_new IN NUMBER, ckp_scn_new IN NUMBER, ckp_time_new IN DATE, datafile_blocks_new IN NUMBER, block_size_new IN NUMBER, plugin_scn_new IN NUMBER) IS SELECT bs_key, bdf_key, dbinc_key, file#, bdf_recid, bdf_stamp, ckp_scn, ckp_time, datafile_blocks, block_size, plugin_scn, section_size FROM bdf WHERE bdf.bs_key = bs_key_new AND bdf.file# = file_new AND ( bdf.ckp_scn <> ckp_scn_new OR bdf.ckp_time <> ckp_time_new OR bdf.datafile_blocks <> datafile_blocks_new OR bdf.block_size <> block_size_new OR bdf.plugin_scn <> plugin_scn_new ); conflict_rec bdf_conflicts%rowtype; BEGIN FOR conflict_rec IN bdf_conflicts(addBackupDatafile.bs_key, addBackupDatafile.file#, addBackupDatafile.ckp_scn, addBackupDatafile.ckp_time, addBackupDatafile.datafile_blocks, addBackupDatafile.block_size, addBackupDatafile.plugin_scn) LOOP deb('addBackupDatafile set stamp set count existing rec-' || ' bs_key ' || to_char(conflict_rec.bs_key) || ' bdf_key ' || to_char(conflict_rec.bdf_key) || ' dbinc_key ' || to_char(conflict_rec.dbinc_key) || ' file# ' || to_char(conflict_rec.file#) || ' bdf_recid ' || to_char(conflict_rec.bdf_recid) || ' bdf_stamp ' || to_char(conflict_rec.bdf_stamp) || ' ckp_scn ' || to_char(conflict_rec.ckp_scn) || ' ckp_time ' || to_char(conflict_rec.ckp_time) || ' datafile_blocks ' || to_char(conflict_rec.datafile_blocks) || ' block_size ' || to_char(conflict_rec.block_size) || ' plugin_scn ' || to_char(conflict_rec.plugin_scn) || ' section_size ' || to_char(conflict_rec.section_size)); END LOOP; deb('addBackupDatafile set stamp set count new conflict rec- ' || ' bs_key ' || to_char(addBackupDataFile.bs_key) || ' dbinc_key' || to_char(addBackupDataFile.dbinc_key) || ' file# ' || to_char(addBackupDataFile.file#) || ' bdf_recid ' || to_char(addBackupDataFile.bdf_recid) || ' bdf_stamp ' || to_char(addBackupDataFile.bdf_stamp) || ' ckp_scn ' || to_char(addBackupDataFile.ckp_scn) || ' ckp_time ' || to_char(addBackupDataFile.ckp_time) || ' datafile_blocks ' || to_char(addBackupDataFile.datafile_blocks) || ' block_size ' || to_char(addBackupDataFile.block_size) || ' plugin_scn ' || to_char(addBackupDataFile.plugin_scn) || ' section_size ' || to_char(addBackupDataFile.section_size)); END; raise_application_error(-20110, 'set stamp set count conflict'); END IF; -- -- SELECT dbinc_key, create_scn, bdf_recid, bdf_stamp, plugin_scn, completion_time, abs_fuzzy_scn, blocks, nvl(blocks_read, datafile_blocks), ckp_scn, ckp_time, decode(used_optim, 'YES', 'Y', 'N'), decode(used_chg_track, 'YES', 'Y', 'N'), nvl(marked_corrupt, 0) INTO local.dbinc_key, local.create_scn,local.bdf_recid, local.bdf_stamp, local.plugin_scn, local.completion_time, local.abs_fuzzy_scn, local.blocks, local.blocks_read, local.ckp_scn, local.ckp_time, local.used_optim, local.used_chg_track, local.marked_corrupt FROM bdf WHERE bdf.bs_key = addBackupDataFile.bs_key AND bdf.file# = addBackupDataFile.file#; -- deb('addBackupDataFile - dbinc_key: '||to_char(dbinc_key)); deb('addBackupDataFile - local.dbinc_key: '|| to_char(local.dbinc_key) || ' local.completion_time: '|| to_char(local.completion_time) || ' local.abs_fuzzy_scn: '|| to_char(local.abs_fuzzy_scn) || ' local.blocks_read: '|| to_char(local.blocks_read) || ' local.marked_corrupt: '|| to_char(local.marked_corrupt)); IF (dbinc_key <> local.dbinc_key) THEN raise_application_error(-20096, 'Invalid dbinc_key'); END IF; IF (create_scn <> local.create_scn AND plugin_scn <> local.plugin_scn) THEN raise_application_error(-20097, 'Invalid create scn'); END IF; -- IF bdf_recid <> local.bdf_recid or bdf_stamp <> local.bdf_stamp THEN UPDATE bdf set bdf_recid = addBackupDataFile.bdf_recid, bdf_stamp = addBackupDataFile.bdf_stamp WHERE bdf.bs_key = addBackupDataFile.bs_key; END IF; IF (local.completion_time <> addBackupDataFile.completion_time) THEN UPDATE bdf SET completion_time = addBackupDataFile.completion_time WHERE bdf.bs_key = addBackupDataFile.bs_key AND bdf.file# = addBackupDataFile.file#; END IF; /* * Following are the scenarios that traverse this code path: * * 1. Resync: resync can happen for both normal msection * backups and virtual msection backups. If a resync * happens during processing of these backups, like say * there are 5 section pieces, and the resync happens * once after the 3rd piece, and once after all 5 pieces, * then the data stored in blocks_read, blocks and marked_corrupt * may be a little more than it needs to be. However, * ckp_scn and abs_fuzzy_scn would be fine as we are taking * the minimum and maximum of each respectively. * In the case of the other parameters, we need to accumulate * their values across sections and there is no easy way * to achieve that. * 2. Prior to 12.2, parameters blocks_read, blocks and marked_corrupt * are at value '0'. However, there is a fix in progress to * capture the actual values. Once that lands, the scenario * listed in #1 will further manifest itself, with larger than * possible values for blocks, blocks_read and marked_corrupt * 3. We need to limit the calculations for copy#1, that way copy to tape * or additional copies created on the backup command using copies * does not further throw off the values on blocks_read, blocks * or marked_corrupt. However, there is no easy way to determine * that at this point in code. Copy2tape currently sets a value * of zero only. * * For now, we will take minimum of checkpoint scn's and maximum of * absolute fuzzy scn's. And only in the case of msection case, * add the values of blocks, blocks_read and marked_corrupt */ -- -- IF (addBackupDataFile.ckp_scn < local.ckp_scn) THEN UPDATE bdf SET ckp_scn = addBackupDataFile.ckp_scn, ckp_time = addBackupDataFile.ckp_time WHERE bdf.bs_key = addBackupDataFile.bs_key AND bdf.file# = addBackupDataFile.file#; deb('addBackupDataFile - updated bdf ckp_scn: '|| to_char(addBackupDataFile.ckp_scn) || ' local bdf ckp_scn:' || to_char(local.ckp_scn)); END IF; /* * This applies to regular backups as well but more so for multi-section * backup. * Lets assume that there are two sections (ckp_scn, abs_scn) notation. * * Section 1: (100, 101) * Section 2: (200, 0) this is not fuzzy. however there can be blocks * at 150, 160.. * IF you were to perform a point in time recovery scenario to 150 and * if you take the minimum of the checkpointscns and the maximum of the * absolute fuzzy then the restored datafile will be (100, 101). * This is wrong as recovery will not be able to unfuzzy the block at * scn 150, 160.. as it cannot roll backwards. * * The correct way of addressing this is to update the bdf with the * appropriate fuzziness by also taking into fact the checkpoint of the * file * This is done in restore logic as below (krbr.c:krbr3b2) * f->curfuzz_krbrf = * (*KSCNMAX(f->pkcvfh_krbrf->kcvfhafs, * KSCNMAX(f->pkcvfh_krbrf->kcvfhrfs, * f->pkcvfh_krbrf->kcvfhckp.kcvcpscn))); * * The same is being done below. */ -- IF (addBackupDataFile.abs_fuzzy_scn > local.abs_fuzzy_scn) THEN UPDATE bdf SET abs_fuzzy_scn = addBackupDataFile.abs_fuzzy_scn WHERE bdf.bs_key = addBackupDataFile.bs_key AND bdf.file# = addBackupDataFile.file#; deb('addBackupDataFile - updated bdf abs_fuzzy_scn: '|| to_char(addBackupDataFile.abs_fuzzy_scn) || ' local bdf abs_fuzzy_scn:' || to_char(local.abs_fuzzy_scn)); ELSIF (addBackupDataFile.section_size <> 0 AND local.abs_fuzzy_scn < addBackupDataFile.ckp_scn) THEN UPDATE bdf SET abs_fuzzy_scn = addBackupDataFile.ckp_scn WHERE bdf.bs_key = addBackupDataFile.bs_key AND bdf.file# = addBackupDataFile.file#; deb('addBackupDataFile - updated bdf abs_fuzzy_scn to ckp_scn: '|| to_char(addBackupDataFile.ckp_scn) || ' local bdf abs_fuzzy_scn:' || to_char(local.abs_fuzzy_scn)); END IF; IF addBackupDataFile.section_size <> 0 AND this_is_ors THEN deb ('Multi-section on ORS'); -- -- -- -- -- -- IF (isReSync AND NOT isVirtual) THEN deb('addBackupDataFile - isResync:TRUE isVirtual:FALSE'|| to_char(local.blocks_read) || ' ' || to_char(addBackupDataFile.blocks_read)); deb('addBackupDataFile - isResync:TRUE isVirtual:FALSE'|| to_char(local.blocks) || ' ' || to_char(addBackupDataFile.blocks)); UPDATE bdf SET blocks_read = addBackupDataFile.blocks_read, blocks = addBackupDataFile.blocks, marked_corrupt = addBackupDataFile.marked_corrupt WHERE bdf.bs_key = addBackupDataFile.bs_key AND bdf.file# = addBackupDataFile.file# AND (local.blocks_read <> addBackupDataFile.blocks_read OR local.blocks <> addBackupDataFile.blocks OR local.marked_corrupt <> addBackupDataFile.marked_corrupt); ELSIF (NOT isReSync AND NOT isVirtual) THEN -- -- -- -- deb('addBackupDataFile - isResync:FALSE isVirtual:FALSE'|| to_char(local.blocks_read) || ' ' || to_char(addBackupDataFile.blocks_read)); deb('addBackupDataFile - isResync:FALSE isVirtual:FALSE'|| to_char(local.blocks) || ' ' || to_char(addBackupDataFile.blocks)); UPDATE bdf SET blocks_read = CASE WHEN local.blocks_read = 0 THEN addBackupDataFile.blocks_read ELSE local.blocks_read END, blocks = CASE WHEN local.blocks = 0 THEN addBackupDataFile.blocks ELSE local.blocks END, marked_corrupt = CASE WHEN local.marked_corrupt = 0 THEN addBackupDataFile.marked_corrupt ELSE local.marked_corrupt END WHERE bdf.bs_key = addBackupDataFile.bs_key AND bdf.file# = addBackupDataFile.file# AND (local.blocks_read = 0 OR local.blocks = 0 OR local.marked_corrupt = 0); ELSIF (NOT isReSync AND isVirtual) THEN -- -- -- deb('addBackupDataFile - isResync:FALSE isVirtual:TRUE'|| to_char(local.blocks_read) || ' ' || to_char(addBackupDataFile.blocks_read)); deb('addBackupDataFile - isResync:FALSE isVirtual:TRUE'|| to_char(local.blocks) || ' ' || to_char(addBackupDataFile.blocks)); -- local.marked_corrupt := local.marked_corrupt + addBackupDataFile.marked_corrupt; -- local.blocks_read := local.blocks_read + addBackupDataFile.blocks_read; local.blocks := local.blocks + addBackupDataFile.blocks; local.blocks := LEAST(local.blocks, addBackupDataFile.datafile_blocks); local.blocks_read := LEAST(local.blocks_read, addBackupDataFile.datafile_blocks); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- IF (local.blocks > l_UB4MAXVAL) THEN -- deb('addBackupDataFile - blocks overflow'|| to_char(local.blocks) || ' ' || to_char(addBackupDataFile.blocks)); local.blocks := l_UB4MAXVAL; END IF; IF (local.blocks_read > l_UB4MAXVAL) THEN -- deb('addBackupDataFile - blocks_read overflow'|| to_char(local.blocks_read) || ' ' || to_char(addBackupDataFile.blocks_read)); local.blocks_read := l_UB4MAXVAL; END IF; UPDATE bdf SET marked_corrupt = local.marked_corrupt, blocks_read = local.blocks_read, blocks = local.blocks WHERE bdf.bs_key = addBackupDataFile.bs_key AND bdf.file# = addBackupDataFile.file#; END IF; UPDATE bdf SET used_chg_track = CASE WHEN (local.used_chg_track = 'Y' OR addBackupDataFile.used_chg_track = 'YES') THEN 'Y' ELSE 'N' END, used_optim = CASE WHEN (local.used_optim = 'Y' OR addBackupDataFile.used_optim = 'YES') THEN 'Y' ELSE 'N' END WHERE bdf.bs_key = addBackupDataFile.bs_key AND bdf.file# = addBackupDataFile.file# AND (local.used_chg_track <> decode(addBackupDataFile.used_chg_track, 'YES', 'Y', 'N') OR local.used_optim <> decode(addBackupDataFile.used_optim, 'YES', 'Y', 'N')); ELSE -- deb('addBackupDataFile - Regular RMAN catalog'); IF (local.completion_time <> addBackupDataFile.completion_time) THEN UPDATE bdf SET blocks_read = addBackupDataFile.blocks_read, marked_corrupt = addBackupDataFile.marked_corrupt WHERE bdf.bs_key = addBackupDataFile.bs_key AND bdf.file# = addBackupDataFile.file#; END IF; END IF; END; END addBackupDataFile; FUNCTION beginBackupDataFileResync RETURN NUMBER IS BEGIN checkResync; IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN SELECT high_bdf_recid INTO last_bdf_recid FROM node WHERE site_key = this_site_key; ELSE last_bdf_recid := sessionWaterMarks.high_bdf_recid; END IF; deb('beginBackupDataFileResync returning' || last_bdf_recid); RETURN last_bdf_recid; END beginBackupDataFileResync; PROCEDURE checkBackupDataFile( bdf_recid IN NUMBER ,bdf_stamp IN NUMBER ,set_stamp IN NUMBER ,set_count IN NUMBER ,file# IN NUMBER ,create_scn IN NUMBER ,create_time IN DATE ,reset_scn IN NUMBER ,reset_time IN DATE ,incr_level IN NUMBER ,incr_scn IN NUMBER ,ckp_scn IN NUMBER ,ckp_time IN DATE ,abs_fuzzy_scn IN NUMBER ,datafile_blocks IN NUMBER ,blocks IN NUMBER ,block_size IN NUMBER ,min_offr_recid IN NUMBER ,completion_time IN DATE ,controlfile_type IN VARCHAR2 DEFAULT NULL ,cfile_abck_year IN NUMBER DEFAULT NULL -- contains marked_corrupt ,cfile_abck_mon_day IN NUMBER DEFAULT NULL -- contains media_corrupt ,cfile_abck_seq IN NUMBER DEFAULT NULL -- contains logical_corrupt ,chk_last_recid IN BOOLEAN DEFAULT TRUE ,blocks_read IN NUMBER DEFAULT NULL ,used_chg_track IN VARCHAR2 DEFAULT 'NO' ,used_optim IN VARCHAR2 DEFAULT 'NO' ,foreign_dbid IN NUMBER DEFAULT 0 ,plugged_readonly IN VARCHAR2 DEFAULT 'NO' ,plugin_scn IN NUMBER DEFAULT 0 ,plugin_reset_scn IN NUMBER DEFAULT 0 ,plugin_reset_time IN DATE DEFAULT NULL ,section_size IN NUMBER DEFAULT NULL ,guid IN RAW DEFAULT NULL ,sparse_backup IN VARCHAR2 DEFAULT 'NO' ,isReSync IN BOOLEAN DEFAULT TRUE ,isVirtual IN BOOLEAN DEFAULT FALSE ,dropped_pdb IN BINARY_INTEGER DEFAULT 0 ) IS bs_key NUMBER; dbinc_key NUMBER; l_pdb_key NUMBER; BEGIN -- IF chk_last_recid THEN IF (last_bdf_recid IS NULL) THEN raise_application_error(-20037, 'Invalid last recid'); END IF; IF (bdf_recid < last_bdf_recid) THEN raise_application_error(-20036, 'Invalid record order'); END IF; IF (bdf_recid > last_bdf_recid + 1) THEN -- NULL; END IF; last_bdf_recid := bdf_recid; END IF; -- BEGIN SELECT bs_key INTO bs_key FROM bs WHERE bs.db_key = this_db_key AND bs.set_stamp = checkBackupDataFile.set_stamp AND bs.set_count = checkBackupDataFile.set_count FOR UPDATE OF bs.bs_key; deb('checkBackupDataFile - locked bs_key' || bs_key); EXCEPTION WHEN no_data_found THEN -- -- -- -- -- -- -- return; END; BEGIN -- -- IF (checkBackupDatafile.incr_level > 0) THEN UPDATE bs SET bs.incr_level = checkBackupDataFile.incr_level, bs.bck_type = 'I' WHERE bs.bs_key = checkBackupDataFile.bs_key AND bs.bck_type IS NULL; ELSE UPDATE bs SET bs.incr_level = checkBackupDataFile.incr_level, bs.bck_type = 'D' WHERE bs.bs_key = checkBackupDataFile.bs_key AND bs.bck_type IS NULL; END IF; IF (file# = 0 and controlfile_type is not null) then UPDATE bs SET bs.controlfile_included= decode(checkBackupDatafile.controlfile_type,'B','BACKUP', 'S','STANDBY', 'NONE') WHERE bs.bs_key = checkBackupDataFile.bs_key AND bs.controlfile_included = 'NONE'; END IF; END; -- dbinc_key := checkIncarnation(reset_scn, reset_time); l_pdb_key := guidToPdbKey(guid, dropped_pdb); IF (file# = 0) THEN addBackupControlFile(bs_key, bdf_recid, bdf_stamp, dbinc_key, ckp_scn, ckp_time, create_time, min_offr_recid, blocks, block_size, controlfile_type, cfile_abck_year, cfile_abck_mon_day, cfile_abck_seq, l_pdb_key); ELSE addBackupDataFile(bs_key, bdf_recid, bdf_stamp, file#, create_scn, dbinc_key, incr_level, incr_scn, ckp_scn, ckp_time, abs_fuzzy_scn, datafile_blocks, blocks, block_size, completion_time, blocks_read, create_time, cfile_abck_year, used_chg_track, used_optim, foreign_dbid, plugged_readonly, plugin_scn, plugin_reset_scn, plugin_reset_time, section_size, l_pdb_key, sparse_backup, isReSync, isVirtual); END IF; END checkBackupDataFile; PROCEDURE endBackupDataFileResync IS BEGIN IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN UPDATE node SET high_bdf_recid = last_bdf_recid WHERE site_key = this_site_key; END IF; sessionWaterMarks.high_bdf_recid := last_bdf_recid; last_bdf_recid := NULL; END endBackupDataFileResync; /*-----------------------* * Backup SPFILE resync * *-----------------------*/ FUNCTION beginBackupSpFileResync RETURN NUMBER IS BEGIN checkResync; IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN SELECT high_bsf_recid INTO last_bsf_recid FROM node WHERE site_key = this_site_key; ELSE last_bsf_recid := sessionWaterMarks.high_bsf_recid; END IF; RETURN last_bsf_recid; END beginBackupSpFileResync; PROCEDURE addBackupSpFile( bs_key IN NUMBER ,bsf_recid IN NUMBER ,bsf_stamp IN NUMBER ,modification_time IN DATE ,bytes IN NUMBER ,db_unique_name IN VARCHAR2 ,pdb_key IN NUMBER ) IS local bsf%rowtype; l_conflict_count number := 0 ; BEGIN deb('addBackupSpfile'); INSERT INTO bsf(bsf_key, bs_key, db_key, bsf_recid, bsf_stamp, modification_time, bytes, db_unique_name, pdb_key) VALUES (rman_seq.nextval, bs_key, this_db_key, bsf_recid, bsf_stamp, modification_time, bytes, db_unique_name, pdb_key); IF (duplicatebs.exists(addBackupSpFile.bs_key)) THEN DECLARE CURSOR bsf_conflicts(bs_key_new IN NUMBER ) IS SELECT bs_key, bsf_key, bsf_recid, bsf_stamp, bytes, pdb_key FROM bsf WHERE bsf.bs_key = bs_key_new; conflict_rec bsf_conflicts%rowtype; BEGIN FOR conflict_rec IN bsf_conflicts(addBackupSpFile.bs_key) LOOP deb('addBackupSpFile set stamp set count conflict - ' || ' bs_key ' || to_char(conflict_rec.bs_key) || ' bsf_key ' || to_char(conflict_rec.bsf_key) || ' bsf_recid ' || to_char(conflict_rec.bsf_recid) || ' bsf_stamp ' || to_char(conflict_rec.bsf_stamp) || ' bytes ' || to_char(conflict_rec.bytes) || ' pdb_key ' || to_char(conflict_rec.pdb_key)); END LOOP; END; raise_application_error(-20110, 'set stamp set count conflict'); END IF; EXCEPTION WHEN dup_val_on_index THEN deb('addBackupSpfile - Inside dup_val_on_index exception'); -- -- -- -- -- -- SELECT * INTO local FROM bsf WHERE bsf.bs_key = addBackupSpFile.bs_key; -- IF (modification_time <> local.modification_time) THEN raise_application_error(-20101, 'Invalid modification_time'); END IF; -- IF (db_unique_name <> local.db_unique_name) THEN raise_application_error(-20101, 'Invalid db_unique_name=' || db_unique_name || 'expected db_unique_name=' || local.db_unique_name); END IF; -- IF local.bsf_recid <> bsf_recid or local.bsf_stamp <> bsf_stamp THEN UPDATE bsf set bsf_recid = addBackupSpFile.bsf_recid, bsf_stamp = addBackupSpFile.bsf_stamp WHERE bsf.bs_key = addBackupSpFile.bs_key; END IF; END addBackupSpFile; PROCEDURE checkBackupSpFile( bsf_recid IN NUMBER ,bsf_stamp IN NUMBER ,set_stamp IN NUMBER ,set_count IN NUMBER ,modification_time IN DATE ,bytes IN NUMBER ,chk_last_recid IN BOOLEAN DEFAULT TRUE ,db_unique_name IN VARCHAR2 DEFAULT NULL ,guid IN RAW DEFAULT NULL ,dropped_pdb IN BINARY_INTEGER DEFAULT 0 ) IS bs_key NUMBER; site_key NUMBER; l_pdb_key NUMBER; BEGIN IF chk_last_recid THEN IF (last_bsf_recid IS NULL) THEN raise_application_error(-20037, 'Invalid last recid'); END IF; IF (bsf_recid < last_bsf_recid) THEN raise_application_error(-20036, 'Invalid record order'); END IF; IF (bsf_recid > last_bsf_recid + 1) THEN -- NULL; END IF; last_bsf_recid := bsf_recid; END IF; -- BEGIN SELECT bs_key INTO bs_key FROM bs WHERE bs.db_key = this_db_key AND bs.set_stamp = checkBackupSpFile.set_stamp AND bs.set_count = checkBackupSpFile.set_count FOR UPDATE OF bs.bs_key; deb('checkBackupSpFile - locked bs_key' || bs_key); EXCEPTION WHEN no_data_found THEN return; END; -- -- UPDATE bs SET bs.bck_type = 'D' WHERE bs.bs_key = checkBackupSpFile.bs_key AND bs.bck_type IS NULL; l_pdb_key := guidToPdbKey(guid, dropped_pdb); addBackupSpFile(bs_key, bsf_recid, bsf_stamp, modification_time, bytes, db_unique_name, l_pdb_key); END checkBackupSpFile; PROCEDURE endBackupSpFileResync IS BEGIN IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN UPDATE node SET high_bsf_recid = last_bsf_recid WHERE site_key = this_site_key; END IF; sessionWaterMarks.high_bsf_recid := last_bsf_recid; last_bsf_recid := NULL; END endBackupSpFileResync; /*-------------------------* * Backup Redo Log resync * *-------------------------*/ FUNCTION beginBackupRedoLogResync RETURN NUMBER IS BEGIN checkResync; IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN SELECT high_brl_recid INTO last_brl_recid FROM node WHERE site_key = this_site_key; ELSE last_brl_recid := sessionWaterMarks.high_brl_recid; END IF; RETURN last_brl_recid; END beginBackupRedoLogResync; PROCEDURE checkBackupRedoLog( brl_recid IN NUMBER ,brl_stamp IN NUMBER ,set_stamp IN NUMBER ,set_count IN NUMBER ,thread# IN NUMBER ,sequence# IN NUMBER ,reset_scn IN NUMBER ,reset_time IN DATE ,low_scn IN NUMBER ,low_time IN DATE ,next_scn IN NUMBER ,next_time IN DATE ,blocks IN NUMBER ,block_size IN NUMBER ,chk_last_recid IN BOOLEAN DEFAULT TRUE ,terminal IN VARCHAR2 DEFAULT 'NO' ,activation IN VARCHAR2 DEFAULT NULL ) IS local brl%rowtype; bskeep number; l_conflict_count number :=0; BEGIN -- -- -- IF brl_stamp = 0 THEN deb('checkBackupRedoLog: ignoring this record as brl_stamp is 0'); RETURN; END IF; -- IF chk_last_recid THEN IF (last_brl_recid IS NULL) THEN raise_application_error(-20037, 'Invalid last recid'); END IF; IF (brl_recid < last_brl_recid) THEN raise_application_error(-20036, 'Invalid record order'); END IF; IF (brl_recid > last_brl_recid + 1) THEN -- -- NULL; END IF; last_brl_recid := brl_recid; END IF; IF (this_dbinc_key IS NULL) THEN raise_application_error(-20020, 'Database incarnation not set'); END IF; -- BEGIN SELECT bs_key,keep_options INTO local.bs_key, bskeep FROM bs WHERE bs.db_key = this_db_key AND bs.set_stamp = checkBackupRedoLog.set_stamp AND bs.set_count = checkBackupRedoLog.set_count FOR UPDATE OF bs.bs_key; deb('checkBackupRedoLog - locked bs_key' || local.bs_key); EXCEPTION WHEN no_data_found THEN RETURN; END; BEGIN -- -- UPDATE bs SET bs.bck_type = 'L' WHERE bs.bs_key = local.bs_key AND bs.bck_type IS NULL; END; -- local.dbinc_key := checkIncarnation(reset_scn, reset_time); BEGIN INSERT INTO brl (brl_key, dbinc_key, brl_recid, brl_stamp, thread#, sequence#, low_scn, low_time, next_scn, next_time, blocks, block_size, bs_key, terminal, activation) VALUES (rman_seq.nextval, local.dbinc_key, brl_recid, brl_stamp, thread#, sequence#, low_scn, low_time, next_scn, next_time, blocks, block_size, local.bs_key, terminal, activation); IF (duplicatebs.exists(local.bs_key)) THEN DECLARE CURSOR brl_conflicts(bs_key_new IN NUMBER) IS SELECT bs_key, brl_key, dbinc_key, brl_recid, brl_stamp, thread#, sequence#, blocks, block_size FROM brl WHERE brl.bs_key = bs_key_new; conflict_rec brl_conflicts%rowtype; BEGIN FOR conflict_rec IN brl_conflicts(local.bs_key) LOOP deb('checkBackupRedoLog set stamp set count conflict - ' || ' bs_key ' || to_char(conflict_rec.bs_key) || ' brl_key ' || to_char(conflict_rec.brl_key) || ' dbinc_key ' || to_char(conflict_rec.dbinc_key) || ' brl_recid ' || to_char(conflict_rec.brl_recid) || ' brl_stamp ' || to_char(conflict_rec.brl_stamp) || ' thread# ' || to_char(conflict_rec.thread#) || ' sequence# ' || to_char(conflict_rec.sequence#) || ' blocks ' || to_char(conflict_rec.blocks) || ' block_size ' || to_char(conflict_rec.block_size)); END LOOP; END; raise_application_error(-20110, 'set stamp set count conflict'); END IF; EXCEPTION WHEN dup_val_on_index THEN deb('checkBackupRedoLog - Inside dup_val_on_index exception'); -- SELECT count(*) INTO l_conflict_count FROM brl WHERE brl.bs_key = local.bs_key AND brl.thread# = checkBackupRedoLog.thread# AND brl.sequence# = checkBackupRedoLog.sequence# AND ( brl.blocks <> checkBackupRedoLog.blocks OR brl.block_size <> checkBackupRedoLog.block_size ) AND ROWNUM = 1; IF (l_conflict_count > 0) THEN DECLARE CURSOR brl_conflicts(bs_key_new IN NUMBER, thread_new IN NUMBER, sequence_new IN NUMBER, blocks_new IN NUMBER, block_size_new IN NUMBER ) IS SELECT bs_key, brl_key, dbinc_key, brl_recid, brl_stamp, thread#, sequence#, blocks, block_size FROM brl WHERE brl.bs_key = bs_key_new AND brl.thread# = thread_new AND brl.sequence# = sequence_new AND ( brl.blocks = blocks_new OR brl.block_size = block_size_new ); conflict_rec brl_conflicts%rowtype; BEGIN FOR conflict_rec IN brl_conflicts(local.bs_key, checkBackupRedoLog.thread#, checkBackupRedoLog.sequence#, checkBackupRedoLog.blocks, checkBackupRedoLog.block_size) LOOP deb('checkBackupRedoLog set stamp set count existing rec- ' || ' bs_key ' || to_char(conflict_rec.bs_key) || ' brl_key ' || to_char(conflict_rec.brl_key) || ' dbinc_key ' || to_char(conflict_rec.dbinc_key) || ' brl_recid ' || to_char(conflict_rec.brl_recid) || ' brl_stamp ' || to_char(conflict_rec.brl_stamp) || ' thread# ' || to_char(conflict_rec.thread#) || ' sequence# ' || to_char(conflict_rec.sequence#) || ' blocks ' || to_char(conflict_rec.blocks) || ' block_size ' || to_char(conflict_rec.block_size)); END LOOP; deb('checkBackupRedoLog set stamp set count new conflict rec- ' || ' bs_key ' || to_char(local.bs_key) || ' dbinc_key ' || to_char(local.dbinc_key) || ' brl_recid ' || to_char(checkBackupRedoLog.brl_recid) || ' brl_stamp ' || to_char(checkBackupRedoLog.brl_stamp) || ' thread# ' || to_char(checkBackupRedoLog.thread#) || ' sequence# ' || to_char(checkBackupRedoLog.sequence#) || ' blocks ' || to_char(checkBackupRedoLog.blocks) || ' block_size ' || to_char(checkBackupRedoLog.block_size)); END; raise_application_error(-20110, 'set stamp set count conflict'); END IF; -- -- SELECT low_scn, brl_recid, brl_stamp INTO local.low_scn, local.brl_recid, local.brl_stamp FROM brl WHERE brl.bs_key = local.bs_key AND brl.thread# = checkBackupRedoLog.thread# AND brl.sequence# = checkBackupRedoLog.sequence#; -- IF (low_scn <> local.low_scn) THEN raise_application_error(-20098, 'Invalid low scn'); END IF; -- IF local.brl_recid <> brl_recid or local.brl_stamp <> brl_stamp THEN UPDATE brl set brl_recid = checkBackupRedoLog.brl_recid, brl_stamp = checkBackupRedoLog.brl_stamp WHERE brl.bs_key = local.bs_key AND brl.thread# = checkBackupRedoLog.thread# AND brl.sequence# = checkBackupRedoLog.sequence#; END IF; END; IF (bskeep > 0) THEN updateRestorePoint(low_scn, next_scn); END IF; END checkBackupRedoLog; PROCEDURE endBackupRedoLogResync IS BEGIN IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN UPDATE node SET high_brl_recid = last_brl_recid WHERE site_key = this_site_key; END IF; sessionWaterMarks.high_brl_recid := last_brl_recid; last_brl_recid := NULL; END endBackupRedoLogResync; /*----------------------------* * Datafile Copy resync * *----------------------------*/ PROCEDURE deleteDuplicateCCF(recid IN NUMBER, stamp IN NUMBER, fname IN VARCHAR2) IS lfname ccf.fname%TYPE; BEGIN lfname := fname; IF lfname IS NULL THEN BEGIN SELECT fname INTO lfname FROM ccf WHERE ccf.dbinc_key IN (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key) AND ccf_recid = recid AND ccf_stamp = stamp; EXCEPTION WHEN no_data_found THEN RETURN; WHEN too_many_rows THEN -- unique_key is dbinc_key, recid and stamp RETURN; END; END IF; -- DELETE ccf WHERE ccf.dbinc_key IN (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key) AND ccf.fname = lfname AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(ccf.site_key, this_site_key))) AND ccf.fname_hashkey = substr(lfname, 1, 10) || substr(lfname, -10) AND NOT (ccf.ccf_recid = recid AND ccf.ccf_stamp = stamp); END deleteDuplicateCCF; PROCEDURE addControlFileCopy( ccf_recid IN NUMBER ,ccf_stamp IN NUMBER ,fname IN VARCHAR2 ,tag IN VARCHAR2 ,dbinc_key IN NUMBER ,ckp_scn IN NUMBER ,ckp_time IN DATE ,create_time IN DATE ,min_offr_recid IN NUMBER ,block_size IN NUMBER ,completion_time IN DATE ,status IN VARCHAR2 ,controlfile_type IN VARCHAR2 DEFAULT NULL ,keep_options IN NUMBER DEFAULT 0 ,keep_until IN DATE DEFAULT NULL ,is_recovery_dest_file IN VARCHAR2 ,rsr_key IN NUMBER DEFAULT NULL ,blocks IN NUMBER ,pdb_key IN NUMBER ) IS local ccf%rowtype; BEGIN BEGIN IF (status <> 'D') THEN INSERT INTO ccf(ccf_key, dbinc_key, ccf_recid, ccf_stamp, fname, fname_hashkey, tag, ckp_scn, ckp_time, create_time, min_offr_recid, block_size, completion_time, status, controlfile_type, keep_options, keep_until, is_recovery_dest_file, rsr_key, blocks, site_key, pdb_key) VALUES (rman_seq.nextval, dbinc_key, ccf_recid, ccf_stamp, fname, substr(fname,1,10)||substr(fname,-10), tag, ckp_scn, ckp_time, create_time, min_offr_recid, block_size, completion_time, status, controlfile_type, keep_options, keep_until, is_recovery_dest_file, rsr_key, blocks, this_site_key, pdb_key); deleteDuplicateCCF(ccf_recid, ccf_stamp, fname); END IF; EXCEPTION WHEN dup_val_on_index THEN deb('addControlFileCopy - Inside dup_val_on_index exception'); -- SELECT * INTO local FROM ccf WHERE ccf.dbinc_key = addControlFileCopy.dbinc_key AND ccf.ccf_recid = addControlFileCopy.ccf_recid AND ccf.ccf_stamp = addControlFileCopy.ccf_stamp; -- IF client_site_aware AND this_site_key <> local.site_key THEN raise_application_error(-20081, 'change stamp for the record'); END IF; -- IF (ckp_scn <> local.ckp_scn) THEN raise_application_error(-20095, 'Invalid ckp_scn'); END IF; -- IF local.site_key IS NULL THEN UPDATE ccf SET site_key = this_site_key WHERE ccf.dbinc_key = addControlFileCopy.dbinc_key AND ccf.ccf_recid = addControlFileCopy.ccf_recid AND ccf.ccf_stamp = addControlFileCopy.ccf_stamp; END IF; END; END addControlFileCopy; PROCEDURE deleteDuplicateCDF(recid IN NUMBER, stamp IN NUMBER, fname IN VARCHAR2) IS lfname cdf.fname%TYPE; BEGIN lfname := fname; IF lfname IS NULL THEN BEGIN SELECT fname INTO lfname FROM cdf WHERE cdf.dbinc_key IN (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key) AND cdf_recid = recid AND cdf_stamp = stamp; EXCEPTION WHEN no_data_found THEN RETURN; WHEN too_many_rows THEN -- unique_key is dbinc_key, recid and stamp RETURN; END; END IF; -- DELETE cdf WHERE cdf.dbinc_key IN (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key) AND cdf.fname = lfname AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(cdf.site_key, this_site_key))) AND cdf.fname_hashkey = substr(lfname, 1, 10) || substr(lfname, -10) AND NOT (cdf.cdf_recid = recid AND cdf.cdf_stamp = stamp); END deleteDuplicateCDF; PROCEDURE addDataFileCopy( cdf_recid IN NUMBER ,cdf_stamp IN NUMBER ,fname IN VARCHAR2 ,tag IN VARCHAR2 ,file# IN NUMBER ,create_scn IN NUMBER ,dbinc_key IN NUMBER ,incr_level IN NUMBER ,ckp_scn IN NUMBER ,ckp_time IN DATE ,onl_fuzzy IN VARCHAR2 ,bck_fuzzy IN VARCHAR2 ,abs_fuzzy_scn IN NUMBER ,rcv_fuzzy_scn IN NUMBER ,rcv_fuzzy_time IN DATE ,blocks IN NUMBER ,block_size IN NUMBER ,completion_time IN DATE ,status IN VARCHAR2 ,keep_options IN NUMBER ,keep_until IN DATE ,scanned IN VARCHAR2 ,is_recovery_dest_file IN VARCHAR2 ,rsr_key IN NUMBER ,create_time IN DATE ,marked_corrupt IN NUMBER ,foreign_dbid IN NUMBER ,plugged_readonly IN VARCHAR2 ,plugin_scn IN NUMBER ,plugin_reset_scn IN NUMBER ,plugin_reset_time IN DATE ,pdb_key IN NUMBER ,sparse_backup IN VARCHAR2 ) IS local cdf%rowtype; BEGIN BEGIN IF (status <> 'D') THEN INSERT INTO cdf(cdf_key, dbinc_key, cdf_recid, cdf_stamp, file#, create_scn, fname, fname_hashkey, tag, incr_level, ckp_scn, ckp_time, onl_fuzzy, bck_fuzzy, abs_fuzzy_scn, rcv_fuzzy_scn, rcv_fuzzy_time, blocks, block_size, completion_time, status, keep_options, keep_until, scanned, is_recovery_dest_file, rsr_key, create_time, marked_corrupt, site_key, foreign_dbid, plugged_readonly, plugin_scn, plugin_reset_scn, plugin_reset_time, pdb_key, sparse_backup) VALUES (rman_seq.nextval, dbinc_key, cdf_recid, cdf_stamp, file#, create_scn, fname, substr(fname,1,10)||substr(fname, -10), tag, incr_level, ckp_scn, ckp_time, decode(onl_fuzzy,'YES','Y','NO','N'), decode(bck_fuzzy,'YES','Y','NO','N'), abs_fuzzy_scn, rcv_fuzzy_scn, rcv_fuzzy_time, blocks, block_size, completion_time, status, keep_options, keep_until, decode(scanned,'YES','Y','NO','N'), is_recovery_dest_file, rsr_key, create_time, marked_corrupt, this_site_key, foreign_dbid, plugged_readonly, plugin_scn, plugin_reset_scn, plugin_reset_time, pdb_key, sparse_backup); deleteDuplicateCDF(cdf_recid, cdf_stamp, fname); END IF; EXCEPTION WHEN dup_val_on_index THEN deb('addDataFileCopy - Inside dup_val_on_index exception'); SELECT * INTO local FROM cdf WHERE cdf.dbinc_key = addDataFileCopy.dbinc_key AND cdf.cdf_recid = addDataFileCopy.cdf_recid AND cdf.cdf_stamp = addDataFileCopy.cdf_stamp; -- IF client_site_aware AND this_site_key <> local.site_key THEN raise_application_error(-20081, 'change stamp for the record'); END IF; -- IF (file# <> local.file#) THEN raise_application_error(-20096, 'Invalid file'); END IF; IF (create_scn <> local.create_scn AND plugin_scn <> local.plugin_scn) THEN raise_application_error(-20097, 'Invalid create scn'); END IF; -- IF local.site_key IS NULL THEN UPDATE cdf SET site_key = this_site_key WHERE cdf.dbinc_key = addDataFileCopy.dbinc_key AND cdf.cdf_recid = addDataFileCopy.cdf_recid AND cdf.cdf_stamp = addDataFileCopy.cdf_stamp; END IF; END; END addDataFileCopy; FUNCTION beginDataFileCopyResync RETURN NUMBER IS BEGIN checkResync; IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN SELECT high_cdf_recid INTO last_cdf_recid FROM node WHERE site_key = this_site_key; ELSE last_cdf_recid := sessionWaterMarks.high_cdf_recid; END IF; RETURN last_cdf_recid; END beginDataFileCopyResync; PROCEDURE checkDataFileCopy( cdf_recid IN NUMBER ,cdf_stamp IN NUMBER ,fname IN VARCHAR2 ,tag IN VARCHAR2 ,file# IN NUMBER ,create_scn IN NUMBER ,create_time IN DATE ,reset_scn IN NUMBER ,reset_time IN DATE ,incr_level IN NUMBER ,ckp_scn IN NUMBER ,ckp_time IN DATE ,onl_fuzzy IN VARCHAR2 ,bck_fuzzy IN VARCHAR2 ,abs_fuzzy_scn IN NUMBER ,rcv_fuzzy_scn IN NUMBER ,rcv_fuzzy_time IN DATE ,blocks IN NUMBER ,block_size IN NUMBER ,min_offr_recid IN NUMBER ,completion_time IN DATE ,status IN VARCHAR2 ,controlfile_type IN VARCHAR2 DEFAULT NULL ,keep_options IN NUMBER DEFAULT 0 ,keep_until IN DATE DEFAULT NULL ,scanned IN VARCHAR2 DEFAULT 'NO' ,is_recovery_dest_file IN VARCHAR2 DEFAULT 'NO' ,rsr_recid IN NUMBER DEFAULT NULL ,rsr_stamp IN NUMBER DEFAULT NULL ,marked_corrupt IN NUMBER DEFAULT NULL ,foreign_dbid IN NUMBER DEFAULT 0 ,plugged_readonly IN VARCHAR2 DEFAULT 'NO' ,plugin_scn IN NUMBER DEFAULT 0 ,plugin_reset_scn IN NUMBER DEFAULT 0 ,plugin_reset_time IN DATE DEFAULT NULL ,guid IN RAW DEFAULT NULL ,sparse_backup IN VARCHAR2 DEFAULT 'NO' ,dropped_pdb IN BINARY_INTEGER DEFAULT 0 ) IS dbinc_key NUMBER; localrsr rsr%rowtype; l_pdb_key NUMBER; BEGIN IF (last_cdf_recid IS NULL) THEN raise_application_error(-20037, 'Invalid last recid'); END IF; IF (cdf_recid < last_cdf_recid) THEN raise_application_error(-20036, 'Invalid record order'); END IF; IF (cdf_recid > last_cdf_recid + 1) THEN -- -- NULL; END IF; last_cdf_recid := cdf_recid; IF (cdf_stamp > 0 and cdf_stamp < kccdivts) THEN deb('checkBackupDatafileCopy - ignoring record kccdivts='||kccdivts); RETURN; -- obsolete record from a backup controlfile END IF; -- dbinc_key := checkIncarnation(reset_scn, reset_time); l_pdb_key := guidToPdbKey(guid, dropped_pdb); -- BEGIN SELECT rsr_key INTO localrsr.rsr_key FROM rsr WHERE rsr.dbinc_key = this_dbinc_key AND (rsr.site_key = this_site_key OR rsr.site_key is null AND this_site_key is null) AND rsr.rsr_stamp = checkDataFileCopy.rsr_stamp AND rsr.rsr_recid = checkDataFileCopy.rsr_recid; EXCEPTION WHEN no_data_found THEN -- NULL; END; IF (file# = 0) THEN addControlFileCopy(cdf_recid, cdf_stamp, fname, tag, dbinc_key, ckp_scn, ckp_time, create_time, min_offr_recid, block_size, completion_time, status, controlfile_type, keep_options, keep_until, is_recovery_dest_file, localrsr.rsr_key, blocks, l_pdb_key); ELSE addDataFileCopy(cdf_recid, cdf_stamp, fname, tag, file#, create_scn, dbinc_key, incr_level, ckp_scn, ckp_time, onl_fuzzy, bck_fuzzy, abs_fuzzy_scn, rcv_fuzzy_scn, rcv_fuzzy_time, blocks, block_size, completion_time, status, keep_options, keep_until, scanned, is_recovery_dest_file, localrsr.rsr_key, create_time, marked_corrupt, foreign_dbid, plugged_readonly, plugin_scn, plugin_reset_scn, plugin_reset_time, l_pdb_key, sparse_backup); END IF; END checkDataFileCopy; PROCEDURE endDataFileCopyResync IS BEGIN IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN UPDATE node SET high_cdf_recid = last_cdf_recid WHERE site_key = this_site_key; END IF; sessionWaterMarks.high_cdf_recid := last_cdf_recid; last_cdf_recid := NULL; END endDataFileCopyResync; /*----------------------------* * Proxy Datafile resync * *----------------------------*/ PROCEDURE deleteDuplicateXCF(recid IN NUMBER, stamp IN NUMBER, device_type IN VARCHAR2, handle IN VARCHAR2) IS lhandle xcf.handle%TYPE; ldevice_type xcf.device_type%TYPE; BEGIN lhandle := handle; IF lhandle IS NULL OR ldevice_type IS NULL THEN BEGIN SELECT handle, device_type INTO lhandle, ldevice_type FROM xcf WHERE xcf.dbinc_key IN (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key) AND xcf_recid = recid AND xcf_stamp = stamp; EXCEPTION WHEN no_data_found THEN RETURN; WHEN too_many_rows THEN -- unique_key is dbinc_key, recid and stamp RETURN; END; END IF; -- DELETE xcf WHERE xcf.dbinc_key IN (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key) AND xcf.device_type = ldevice_type AND xcf.handle = lhandle AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xcf.site_key, this_site_key))) AND xcf.handle_hashkey = substr(ldevice_type, 1, 10) || substr(lhandle, 1, 10) || substr(lhandle, -10) AND NOT (xcf.xcf_recid = recid AND xcf.xcf_stamp = stamp); END deleteDuplicateXCF; PROCEDURE addProxyControlFile( dbinc_key IN NUMBER ,xcf_recid IN NUMBER ,xcf_stamp IN NUMBER ,tag IN VARCHAR2 ,ckp_scn IN NUMBER ,ckp_time IN DATE ,create_time IN DATE ,min_offr_recid IN NUMBER ,block_size IN NUMBER ,device_type IN VARCHAR2 ,handle IN VARCHAR2 ,comments IN VARCHAR2 ,media IN VARCHAR2 ,media_pool IN NUMBER ,start_time IN VARCHAR2 ,completion_time IN DATE ,status IN VARCHAR2 ,controlfile_type IN VARCHAR2 ,keep_options IN NUMBER ,keep_until IN DATE ,rsr_key IN NUMBER ,blocks IN NUMBER ,pdb_key IN NUMBER ) IS local xcf%rowtype; BEGIN BEGIN IF (status <> 'D') THEN INSERT INTO xcf(xcf_key, dbinc_key, xcf_recid, xcf_stamp, tag, ckp_scn, ckp_time, create_time, min_offr_recid, block_size, device_type, handle, handle_hashkey, comments, media, media_pool, start_time, completion_time, status, controlfile_type, keep_options, keep_until, rsr_key, site_key, pdb_key) VALUES (rman_seq.nextval, dbinc_key, xcf_recid, xcf_stamp, tag, ckp_scn, ckp_time, create_time, min_offr_recid, block_size, device_type, handle, substr(device_type,1,10)||substr(handle,1,10)||substr(handle,-10), comments, media, media_pool, start_time, completion_time, status, controlfile_type, keep_options, keep_until, rsr_key, this_site_key, pdb_key); deleteDuplicateXCF(xcf_recid, xcf_stamp, device_type, handle); END IF; EXCEPTION WHEN dup_val_on_index THEN deb('addProxyControlFile - Inside dup_val_on_index exception'); -- SELECT * INTO local FROM xcf WHERE xcf.dbinc_key = addProxyControlFile.dbinc_key AND xcf.xcf_recid = addProxyControlFile.xcf_recid AND xcf.xcf_stamp = addProxyControlFile.xcf_stamp; -- IF client_site_aware AND this_site_key <> local.site_key THEN raise_application_error(-20081, 'change stamp for the record'); END IF; -- IF (ckp_scn <> local.ckp_scn) THEN raise_application_error(-20095, 'Invalid ckp_scn'); END IF; -- IF local.site_key IS NULL THEN UPDATE xcf SET site_key = this_site_key WHERE xcf.dbinc_key = addProxyControlFile.dbinc_key AND xcf.xcf_recid = addProxyControlFile.xcf_recid AND xcf.xcf_stamp = addProxyControlFile.xcf_stamp; END IF; END; END addProxyControlFile; PROCEDURE deleteDuplicateXDF(recid IN NUMBER, stamp IN NUMBER, device_type IN VARCHAR2, handle IN VARCHAR2) IS lhandle xdf.handle%TYPE; ldevice_type xdf.device_type%TYPE; BEGIN lhandle := handle; IF lhandle IS NULL OR ldevice_type IS NULL THEN BEGIN SELECT handle, device_type INTO lhandle, ldevice_type FROM xdf WHERE xdf.dbinc_key IN (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key) AND xdf_recid = recid AND xdf_stamp = stamp; EXCEPTION WHEN no_data_found THEN RETURN; WHEN too_many_rows THEN -- unique_key is dbinc_key, recid and stamp RETURN; END; END IF; -- DELETE xdf WHERE xdf.dbinc_key IN (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key) AND xdf.device_type = ldevice_type AND xdf.handle = lhandle AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xdf.site_key, this_site_key))) AND xdf.handle_hashkey = substr(ldevice_type, 1, 10) || substr(lhandle, 1, 10) || substr(lhandle, -10) AND NOT (xdf.xdf_recid = recid AND xdf.xdf_stamp = stamp); END deleteDuplicateXDF; PROCEDURE addProxyDataFile( dbinc_key IN NUMBER ,xdf_recid IN NUMBER ,xdf_stamp IN NUMBER ,tag IN VARCHAR2 ,file# IN NUMBER ,create_scn IN NUMBER ,incr_level IN NUMBER ,ckp_scn IN NUMBER ,ckp_time IN DATE ,onl_fuzzy IN VARCHAR2 ,bck_fuzzy IN VARCHAR2 ,abs_fuzzy_scn IN NUMBER ,rcv_fuzzy_scn IN NUMBER ,rcv_fuzzy_time IN DATE ,blocks IN NUMBER ,block_size IN NUMBER ,device_type IN VARCHAR2 ,handle IN VARCHAR2 ,comments IN VARCHAR2 ,media IN VARCHAR2 ,media_pool IN NUMBER ,start_time IN VARCHAR2 ,completion_time IN DATE ,status IN VARCHAR2 ,keep_options IN NUMBER DEFAULT 0 ,keep_until IN DATE DEFAULT NULL ,rsr_key IN NUMBER ,create_time IN DATE ,foreign_dbid IN NUMBER ,plugged_readonly IN VARCHAR2 ,plugin_scn IN NUMBER ,plugin_reset_scn IN NUMBER ,plugin_reset_time IN DATE ,pdb_key IN NUMBER ) IS local xdf%rowtype; BEGIN BEGIN IF (status <> 'D') THEN INSERT INTO xdf(xdf_key, dbinc_key, xdf_recid, xdf_stamp, file#, create_scn, tag, incr_level, ckp_scn, ckp_time, onl_fuzzy, bck_fuzzy, abs_fuzzy_scn, rcv_fuzzy_scn, rcv_fuzzy_time, blocks, block_size, device_type, handle, handle_hashkey, comments, media, media_pool, start_time, completion_time, status, keep_options, keep_until, rsr_key, site_key, foreign_dbid, plugged_readonly, plugin_scn, plugin_reset_scn, plugin_reset_time, pdb_key) VALUES (rman_seq.nextval, dbinc_key, xdf_recid, xdf_stamp, file#, create_scn, tag, incr_level, ckp_scn, ckp_time, decode(onl_fuzzy,'YES','Y','NO','N'), decode(bck_fuzzy,'YES','Y','NO','N'), abs_fuzzy_scn, rcv_fuzzy_scn, rcv_fuzzy_time, blocks, block_size, device_type, handle, substr(device_type,1,10)||substr(handle,1,10)||substr(handle,-10), comments, media, media_pool, start_time, completion_time, status, keep_options, keep_until, rsr_key, this_site_key, foreign_dbid, plugged_readonly, plugin_scn, plugin_reset_scn, plugin_reset_time, pdb_key); deleteDuplicateXDF(xdf_recid, xdf_stamp, device_type, handle); END IF; EXCEPTION WHEN dup_val_on_index THEN deb('addProxyDatafile - Inside dup_val_on_index exception'); SELECT * INTO local FROM xdf WHERE xdf.dbinc_key = addProxyDataFile.dbinc_key AND xdf.xdf_recid = addProxyDataFile.xdf_recid AND xdf.xdf_stamp = addProxyDataFile.xdf_stamp; -- IF client_site_aware AND this_site_key <> local.site_key THEN raise_application_error(-20081, 'change stamp for the record'); END IF; -- IF (file# <> local.file#) THEN raise_application_error(-20096, 'Invalid file'); END IF; IF (create_scn <> local.create_scn AND plugin_scn <> local.plugin_scn) THEN raise_application_error(-20097, 'Invalid create scn'); END IF; -- IF local.site_key IS NULL THEN UPDATE xdf SET site_key = this_site_key WHERE xdf.dbinc_key = addProxyDataFile.dbinc_key AND xdf.xdf_recid = addProxyDataFile.xdf_recid AND xdf.xdf_stamp = addProxyDataFile.xdf_stamp; END IF; END; END addProxyDataFile; PROCEDURE deleteDuplicateXAL(recid IN NUMBER, stamp IN NUMBER, device_type IN VARCHAR2, handle IN VARCHAR2) IS lhandle xal.handle%TYPE; ldevice_type xal.device_type%TYPE; BEGIN lhandle := handle; IF lhandle IS NULL OR ldevice_type IS NULL THEN BEGIN SELECT handle, device_type INTO lhandle, ldevice_type FROM xal WHERE xal.dbinc_key IN (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key) AND xal_recid = recid AND xal_stamp = stamp; EXCEPTION WHEN no_data_found THEN RETURN; WHEN too_many_rows THEN -- unique_key is dbinc_key, recid and stamp RETURN; END; END IF; -- DELETE xal WHERE xal.dbinc_key IN (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key) AND xal.device_type = ldevice_type AND xal.handle = lhandle AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xal.site_key, this_site_key))) AND xal.handle_hashkey = substr(ldevice_type, 1, 10) || substr(lhandle, 1, 10) || substr(lhandle, -10) AND NOT (xal.xal_recid = recid AND xal.xal_stamp = stamp); END deleteDuplicateXAL; PROCEDURE addProxyArchivedLog( dbinc_key IN NUMBER ,xal_recid IN NUMBER ,xal_stamp IN NUMBER ,tag IN VARCHAR2 ,thread# IN NUMBER ,sequence# IN NUMBER ,resetlogs_change# IN NUMBER ,resetlogs_time IN DATE ,first_change# IN NUMBER ,first_time IN DATE ,next_change# IN NUMBER ,next_time IN DATE ,blocks IN NUMBER ,block_size IN NUMBER ,device_type IN VARCHAR2 ,handle IN VARCHAR2 ,comments IN VARCHAR2 ,media IN VARCHAR2 ,media_pool IN NUMBER ,start_time IN VARCHAR2 ,completion_time IN DATE ,status IN VARCHAR2 ,rsr_key IN NUMBER ,terminal IN VARCHAR2 default 'NO' ,keep_until IN DATE default NULL ,keep_options IN NUMBER default 0 ) IS local xal%rowtype; BEGIN BEGIN IF (status <> 'D') THEN INSERT INTO xal(xal_key, dbinc_key, xal_recid, xal_stamp, tag, thread#, sequence#, low_scn, low_time, next_scn, next_time, blocks, block_size, device_type, handle, handle_hashkey, comments, media, media_pool, start_time, completion_time, status, rsr_key, terminal, keep_until, keep_options, site_key) VALUES (rman_seq.nextval, dbinc_key, xal_recid, xal_stamp, tag, thread#, sequence#, first_change#, first_time, next_change#, next_time, blocks, block_size, device_type, handle, substr(device_type,1,10)||substr(handle,1,10)||substr(handle,-10), comments, media, media_pool, start_time, completion_time, status, rsr_key, terminal, keep_until, keep_options, this_site_key); deleteDuplicateXAL(xal_recid, xal_stamp, device_type, handle); END IF; EXCEPTION WHEN dup_val_on_index THEN deb('addProxyArchivedLog - Inside dup_val_on_index exception'); SELECT * INTO local FROM xal WHERE xal.dbinc_key = addProxyArchivedLog.dbinc_key AND xal.xal_recid = addProxyArchivedLog.xal_recid AND xal.xal_stamp = addProxyArchivedLog.xal_stamp; -- IF client_site_aware AND this_site_key <> local.site_key THEN raise_application_error(-20081, 'change stamp for the record'); END IF; -- IF (first_change# <> local.low_scn) THEN raise_application_error(-20098, 'Invalid low scn'); END IF; -- IF local.site_key IS NULL THEN UPDATE xal SET site_key = this_site_key WHERE xal.dbinc_key = addProxyArchivedLog.dbinc_key AND xal.xal_recid = addProxyArchivedLog.xal_recid AND xal.xal_stamp = addProxyArchivedLog.xal_stamp; END IF; END; IF (keep_options > 0) THEN updateRestorePoint(first_change#, next_change#); END IF; END addProxyArchivedLog; -- -- FUNCTION beginProxyResync RETURN NUMBER IS BEGIN checkResync; IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN SELECT high_pc_recid INTO last_xdf_recid FROM node WHERE site_key = this_site_key; ELSE last_xdf_recid := sessionWaterMarks.high_pc_recid; END IF; last_xal_recid := last_xdf_recid; RETURN last_xdf_recid; END beginProxyResync; PROCEDURE checkProxyDataFile( xdf_recid IN NUMBER ,xdf_stamp IN NUMBER ,tag IN VARCHAR2 ,file# IN NUMBER ,create_scn IN NUMBER ,create_time IN DATE ,reset_scn IN NUMBER ,reset_time IN DATE ,incr_level IN NUMBER ,ckp_scn IN NUMBER ,ckp_time IN DATE ,onl_fuzzy IN VARCHAR2 ,bck_fuzzy IN VARCHAR2 ,abs_fuzzy_scn IN NUMBER ,rcv_fuzzy_scn IN NUMBER ,rcv_fuzzy_time IN DATE ,blocks IN NUMBER ,block_size IN NUMBER ,min_offr_recid IN NUMBER ,device_type IN VARCHAR2 ,handle IN VARCHAR2 ,comments IN VARCHAR2 ,media IN VARCHAR2 ,media_pool IN NUMBER ,start_time IN DATE ,completion_time IN DATE ,status IN VARCHAR2 ,controlfile_type IN VARCHAR2 DEFAULT NULL ,keep_options IN NUMBER DEFAULT 0 ,keep_until IN DATE DEFAULT NULL ,rsr_recid IN NUMBER DEFAULT NULL ,rsr_stamp IN NUMBER DEFAULT NULL ,foreign_dbid IN NUMBER DEFAULT 0 ,plugged_readonly IN VARCHAR2 DEFAULT 'NO' ,plugin_scn IN NUMBER DEFAULT 0 ,plugin_reset_scn IN NUMBER DEFAULT 0 ,plugin_reset_time IN DATE DEFAULT NULL ,guid IN RAW DEFAULT NULL ,dropped_pdb IN BINARY_INTEGER DEFAULT 0 ) IS dbinc_key NUMBER; localrsr rsr%rowtype; l_pdb_key NUMBER; BEGIN IF (last_xdf_recid IS NULL) THEN raise_application_error(-20037, 'Invalid last recid'); END IF; IF (xdf_recid < last_xdf_recid) THEN raise_application_error(-20036, 'Invalid record order'); END IF; -- -- last_xdf_recid := xdf_recid; IF (xdf_stamp > 0 and xdf_stamp < kccdivts) THEN deb('checkProxyDatafile - ignoring record kccdivts='||kccdivts); RETURN; -- obsolete record from a backup controlfile END IF; -- -- dbinc_key := checkIncarnation(reset_scn, reset_time); l_pdb_key := guidToPdbKey(guid, dropped_pdb); -- BEGIN SELECT rsr_key INTO localrsr.rsr_key FROM rsr WHERE rsr.dbinc_key = this_dbinc_key AND (rsr.site_key = this_site_key OR rsr.site_key is null AND this_site_key is null) AND rsr.rsr_stamp = checkProxyDataFile.rsr_stamp AND rsr.rsr_recid = checkProxyDataFile.rsr_recid; EXCEPTION WHEN no_data_found THEN -- NULL; END; IF (file# = 0) THEN addProxyControlFile(dbinc_key, xdf_recid, xdf_stamp, tag, ckp_scn, ckp_time, create_time, min_offr_recid, block_size, device_type, handle, comments, media, media_pool, start_time, completion_time, status, controlfile_type, keep_options, keep_until, localrsr.rsr_key, blocks, l_pdb_key); ELSE addProxyDataFile(dbinc_key, xdf_recid, xdf_stamp, tag, file#, create_scn, incr_level, ckp_scn, ckp_time, onl_fuzzy, bck_fuzzy, abs_fuzzy_scn, rcv_fuzzy_scn, rcv_fuzzy_time, blocks, block_size, device_type, handle, comments, media, media_pool, start_time, completion_time, status, keep_options, keep_until, localrsr.rsr_key, create_time, foreign_dbid, plugged_readonly, plugin_scn, plugin_reset_scn, plugin_reset_time, l_pdb_key); END IF; END checkProxyDataFile; PROCEDURE checkProxyArchivedLog( xal_recid IN NUMBER ,xal_stamp IN NUMBER ,tag IN VARCHAR2 ,thread# IN NUMBER ,sequence# IN NUMBER ,resetlogs_change# IN NUMBER ,resetlogs_time IN DATE ,first_change# IN NUMBER ,first_time IN DATE ,next_change# IN NUMBER ,next_time IN DATE ,blocks IN NUMBER ,block_size IN NUMBER ,device_type IN VARCHAR2 ,handle IN VARCHAR2 ,comments IN VARCHAR2 ,media IN VARCHAR2 ,media_pool IN NUMBER ,start_time IN DATE ,completion_time IN DATE ,status IN VARCHAR2 ,rsr_recid IN NUMBER ,rsr_stamp IN NUMBER ,terminal IN VARCHAR2 default 'NO' ,keep_until IN DATE default NULL ,keep_options IN NUMBER default 0 ) IS dbinc_key NUMBER; localrsr rsr%rowtype; BEGIN IF (last_xal_recid IS NULL) THEN raise_application_error(-20037, 'Invalid last recid'); END IF; IF (xal_recid < last_xal_recid) THEN raise_application_error(-20036, 'Invalid record order'); END IF; -- -- last_xal_recid := xal_recid; IF (xal_stamp > 0 and xal_stamp < kccdivts) THEN deb('checkProxyArchivedLog - ignoring record kccdivts='||kccdivts); RETURN; -- obsolete record from a backup controlfile END IF; -- -- dbinc_key := checkIncarnation(resetlogs_change#, resetlogs_time); -- BEGIN SELECT rsr_key INTO localrsr.rsr_key FROM rsr WHERE rsr.dbinc_key = this_dbinc_key AND (rsr.site_key = this_site_key OR rsr.site_key is null AND this_site_key is null) AND rsr.rsr_stamp = checkProxyArchivedLog.rsr_stamp AND rsr.rsr_recid = checkProxyArchivedLog.rsr_recid; EXCEPTION WHEN no_data_found THEN -- NULL; END; addProxyArchivedLog(dbinc_key, xal_recid, xal_stamp, tag, thread#, sequence#, resetlogs_change#, resetlogs_time, first_change#, first_time, next_change#, next_time, blocks, block_size, device_type, handle, comments, media, media_pool, start_time, completion_time, status, localrsr.rsr_key, terminal, keep_until, keep_options); END checkProxyArchivedLog; PROCEDURE endProxyResync IS last_pc_recid number := greatest(nvl(last_xdf_recid,0), nvl(last_xal_recid,0)); BEGIN IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN UPDATE node SET high_pc_recid = last_pc_recid WHERE site_key = this_site_key; END IF; sessionWaterMarks.high_pc_recid := last_pc_recid; last_xdf_recid := NULL; last_xal_recid := NULL; END endProxyResync; /*----------------------------* * Corrupt Block resync * *----------------------------*/ FUNCTION beginBackupCorruptionResync RETURN NUMBER IS BEGIN checkResync; IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN SELECT high_bcb_recid INTO last_bcb_recid FROM node WHERE site_key = this_site_key; ELSE last_bcb_recid := sessionWaterMarks.high_bcb_recid; END IF; RETURN last_bcb_recid; END beginBackupCorruptionResync; PROCEDURE checkBackupCorruption( bcb_recid IN NUMBER ,bcb_stamp IN NUMBER ,set_stamp IN NUMBER ,set_count IN NUMBER ,piece# IN NUMBER ,file# IN NUMBER ,block# IN NUMBER ,blocks IN NUMBER ,corrupt_scn IN NUMBER ,marked_corrupt IN VARCHAR2 ,corruption_type IN VARCHAR2 ) IS local bcb%rowtype; BEGIN IF (last_bcb_recid IS NULL) THEN raise_application_error(-20037, 'Invalid last recid'); END IF; IF (bcb_recid < last_bcb_recid) THEN raise_application_error(-20036, 'Invalid record order'); END IF; IF (bcb_recid > last_bcb_recid + 1) THEN -- -- NULL; END IF; last_bcb_recid := bcb_recid; IF (bcb_stamp > 0 and bcb_stamp < kccdivts) THEN deb('checkBackupCorruption - ignoring record kccdivts='||kccdivts); RETURN; -- obsolete record from a backup controlfile END IF; -- BEGIN SELECT bdf_key INTO local.bdf_key FROM bdf, bs WHERE bdf.bs_key = bs.bs_key AND bs.db_key = this_db_key AND bs.set_stamp = checkBackupCorruption.set_stamp AND bs.set_count = checkBackupCorruption.set_count AND bdf.file# = checkBackupCorruption.file#; EXCEPTION WHEN no_data_found THEN -- RETURN; END; BEGIN INSERT INTO bcb (bdf_key, bcb_recid, bcb_stamp, piece#, block#, blocks, corrupt_scn, marked_corrupt, corruption_type) VALUES (local.bdf_key, bcb_recid, bcb_stamp, piece#, block#, blocks, corrupt_scn, decode(marked_corrupt,'YES','Y','NO','N'), corruption_type); EXCEPTION WHEN dup_val_on_index THEN -- RETURN; END; END checkBackupCorruption; PROCEDURE endBackupCorruptionResync IS BEGIN IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN UPDATE node SET high_bcb_recid = last_bcb_recid WHERE site_key = this_site_key; END IF; sessionWaterMarks.high_bcb_recid := last_bcb_recid; last_bcb_recid := NULL; END endBackupCorruptionResync; FUNCTION beginCopyCorruptionResync RETURN NUMBER IS BEGIN checkResync; IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN SELECT high_ccb_recid INTO last_ccb_recid FROM node WHERE site_key = this_site_key; ELSE last_ccb_recid := sessionWaterMarks.high_ccb_recid; END IF; RETURN last_ccb_recid; END beginCopyCorruptionResync; PROCEDURE checkCopyCorruption( ccb_recid IN NUMBER ,ccb_stamp IN NUMBER ,cdf_recid IN NUMBER ,cdf_stamp IN NUMBER ,file# IN NUMBER ,block# IN NUMBER ,blocks IN NUMBER ,corrupt_scn IN NUMBER ,marked_corrupt IN VARCHAR2 ,corruption_type IN VARCHAR2 ) IS local ccb%rowtype; BEGIN IF (last_ccb_recid IS NULL) THEN raise_application_error(-20037, 'Invalid last recid'); END IF; IF (ccb_recid < last_ccb_recid) THEN raise_application_error(-20036, 'Invalid record order'); END IF; IF (ccb_recid > last_ccb_recid + 1) THEN -- -- NULL; END IF; last_ccb_recid := ccb_recid; IF (ccb_stamp > 0 and ccb_stamp < kccdivts) THEN deb('checkCopyCorruption - ignoring record kccdivts='||kccdivts); RETURN; -- obsolete record from a backup controlfile END IF; -- BEGIN SELECT cdf_key INTO local.cdf_key FROM cdf WHERE cdf.dbinc_key = this_dbinc_key AND cdf.cdf_recid = checkCopyCorruption.cdf_recid AND cdf.cdf_stamp = checkCopyCorruption.cdf_stamp AND cdf.file# = checkCopyCorruption.file#; EXCEPTION WHEN no_data_found THEN -- RETURN; END; BEGIN INSERT INTO ccb (cdf_key, ccb_recid, ccb_stamp, block#, blocks, corrupt_scn, marked_corrupt, corruption_type) VALUES (local.cdf_key, ccb_recid, ccb_stamp, block#, blocks, corrupt_scn, decode(marked_corrupt,'YES','Y','NO','N'), corruption_type); EXCEPTION WHEN dup_val_on_index THEN -- RETURN; END; END checkCopyCorruption; PROCEDURE endCopyCorruptionResync IS BEGIN IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN UPDATE node SET high_ccb_recid = last_ccb_recid WHERE site_key = this_site_key; END IF; sessionWaterMarks.high_ccb_recid := last_ccb_recid; last_ccb_recid := NULL; END endCopyCorruptionResync; FUNCTION beginBlockCorruptionResync( low_bcr_recid IN number) RETURN NUMBER IS old_bcr_recid number; BEGIN checkResync; SELECT high_bcr_recid, low_bcr_recid INTO last_bcr_recid, old_bcr_recid FROM node WHERE site_key = this_site_key; -- -- -- -- -- -- -- -- IF (old_bcr_recid != low_bcr_recid) THEN DELETE bcr WHERE site_key = this_site_key AND bcr_recid < low_bcr_recid; UPDATE node SET low_bcr_recid = low_bcr_recid WHERE site_key = this_site_key; END IF; RETURN last_bcr_recid; END beginBlockCorruptionResync; PROCEDURE checkBlockCorruption( bcr_recid IN NUMBER ,bcr_stamp IN NUMBER ,file# IN NUMBER ,create_scn IN NUMBER ,create_time IN DATE ,block# IN NUMBER ,blocks IN NUMBER ,corrupt_scn IN NUMBER ,corruption_type IN VARCHAR2 ) IS local df%rowtype; BEGIN IF (last_bcr_recid IS NULL) THEN raise_application_error(-20037, 'Invalid last recid'); END IF; IF (bcr_recid < last_bcr_recid) THEN raise_application_error(-20036, 'Invalid record order'); END IF; IF (bcr_recid > last_bcr_recid + 1) THEN -- -- NULL; END IF; last_bcr_recid := bcr_recid; -- BEGIN SELECT distinct df.df_key INTO local.df_key FROM df, site_dfatt WHERE df.df_key = site_dfatt.df_key AND site_dfatt.site_key = this_site_key AND df.file# = checkBlockCorruption.file# AND df.create_scn = checkBlockCorruption.create_scn AND df.create_time = checkBlockCorruption.create_time; EXCEPTION WHEN no_data_found THEN -- deb('checkBlockCorruption - no df_key found'); RETURN; END; deb('checkBlockCorruption - df_key=' || local.df_key); BEGIN INSERT INTO bcr (bcr_recid, bcr_stamp, df_key, site_key, block#, blocks, corrupt_scn, corruption_type) VALUES (bcr_recid, bcr_stamp, local.df_key, this_site_key, block#, blocks, corrupt_scn, corruption_type); EXCEPTION WHEN dup_val_on_index THEN -- RETURN; END; END checkBlockCorruption; PROCEDURE endBlockCorruptionResync IS BEGIN IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN UPDATE node SET high_bcr_recid = last_bcr_recid WHERE site_key = this_site_key; END IF; sessionWaterMarks.high_bcr_recid := last_bcr_recid; last_bcr_recid := NULL; END endBlockCorruptionResync; /*----------------------------* * Deleted Object resync * *----------------------------*/ FUNCTION beginDeletedObjectResync RETURN NUMBER IS BEGIN checkResync; IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN SELECT high_do_recid INTO last_do_recid FROM node WHERE site_key = this_site_key; ELSE last_do_recid := sessionWaterMarks.high_do_recid; END IF; deb('beginDeletedObjectResync - last_do_recid='||last_do_recid); RETURN last_do_recid; END beginDeletedObjectResync; PROCEDURE checkDeletedObject( do_recid IN NUMBER ,do_stamp IN NUMBER ,object_type IN VARCHAR2 ,object_recid IN NUMBER ,object_stamp IN NUMBER ,object_data IN NUMBER DEFAULT NULL ,object_fname IN VARCHAR2 DEFAULT NULL ,object_create_scn IN NUMBER DEFAULT NULL ,set_stamp IN NUMBER DEFAULT NULL ,set_count IN NUMBER DEFAULT NULL ,handle IN VARCHAR2 DEFAULT NULL ,device_type IN VARCHAR2 DEFAULT NULL) IS local bp%rowtype; new_status VARCHAR2(1); rc boolean; keep_options number := NULL; keep_until date := NULL; BEGIN IF (last_do_recid IS NULL) THEN raise_application_error(-20037, 'Invalid last recid'); END IF; IF (do_recid < last_do_recid) THEN deb('checkDeletedObject - last_do_recid=' || last_do_recid); raise_application_error(-20036, 'Invalid record order'); END IF; -- IF (do_recid > last_do_recid + 1) THEN -- NULL; END IF; last_do_recid := do_recid; IF (do_stamp > 0 AND do_stamp < kccdivts) THEN deb('checkDeletedObject - ignoring record kccdivts='||kccdivts); RETURN; -- obsolete record from a backup controlfile END IF; -- -- -- IF (object_type like 'BACKUP SET%') THEN IF (object_type = 'BACKUP SET KEEP UNTIL') THEN IF (object_data > 0) THEN keep_until := stamp2date(object_data); END IF; ELSIF (object_type = 'BACKUP SET KEEP OPTIONS') THEN keep_options := object_data; ELSE raise_application_error(-20999, 'Internal error in checkDeletedObject(): bad object_type '|| object_type); END IF; changeBackupSet(object_recid, object_stamp, keep_options, keep_until); END IF; IF (object_type like 'BACKUP PIECE%') THEN IF (object_type = 'BACKUP PIECE') THEN new_status := 'D'; ELSIF (object_type = 'BACKUP PIECE AVAILABLE') THEN new_status := 'A'; ELSIF (object_type = 'BACKUP PIECE EXPIRED') THEN new_status := 'X'; ELSIF (object_type = 'BACKUP PIECE UNAVAILABLE') THEN new_status := 'U'; ELSE raise_application_error(-20999, 'Internal error in checkDeletedObject(): bad object_type '|| object_type); END IF; changeBackupPiece(object_recid, object_stamp, new_status, set_stamp, set_count, NULL /* osite_key */, NULL /*nsite_key */, handle, device_type); END IF; IF (object_type like 'DATAFILE COPY%') THEN IF (object_type = 'DATAFILE COPY') THEN new_status := 'D'; ELSIF (object_type = 'DATAFILE COPY AVAILABLE') THEN new_status := 'A'; ELSIF (object_type = 'DATAFILE COPY EXPIRED') THEN new_status := 'X'; ELSIF (object_type = 'DATAFILE COPY UNAVAILABLE') THEN new_status := 'U'; ELSIF (object_type = 'DATAFILE COPY KEEP UNTIL') THEN new_status := NULL; keep_until := stamp2date(object_data); ELSIF (object_type = 'DATAFILE COPY KEEP OPTIONS') THEN new_status := NULL; keep_options := object_data; ELSE raise_application_error(-20999, 'Internal error in checkDeletedObject(): bad object_type '|| object_type); END IF; changeDatafileCopy(object_recid, object_stamp, new_status, keep_options, keep_until); END IF; IF (object_type like 'ARCHIVED LOG%') THEN IF (object_type = 'ARCHIVED LOG') THEN new_status := 'D'; ELSIF (object_type = 'ARCHIVED LOG AVAILABLE') THEN new_status := 'A'; ELSIF (object_type = 'ARCHIVED LOG EXPIRED') THEN new_status := 'X'; ELSIF (object_type = 'ARCHIVED LOG UNAVAILABLE') THEN new_status := 'U'; ELSE raise_application_error(-20999, 'Internal error in checkDeletedObject(): bad object_type '|| object_type); END IF; changeArchivedLog(object_recid, object_stamp, new_status); END IF; IF (object_type like 'PROXY COPY%') THEN IF (object_type = 'PROXY COPY') THEN new_status := 'D'; ELSIF (object_type = 'PROXY COPY AVAILABLE') THEN new_status := 'A'; ELSIF (object_type = 'PROXY COPY EXPIRED') THEN new_status := 'X'; ELSIF (object_type = 'PROXY COPY UNAVAILABLE') THEN new_status := 'U'; ELSIF (object_type = 'PROXY COPY KEEP UNTIL') THEN new_status := NULL; keep_until := stamp2date(object_data); ELSIF (object_type = 'PROXY COPY KEEP OPTIONS') THEN new_status := NULL; keep_options := object_data; ELSE raise_application_error(-20999, 'Internal error in checkDeletedObject(): bad object_type '|| object_type); END IF; changeProxyCopy(object_recid, object_stamp, new_status, keep_options, keep_until); END IF; IF (object_type = 'DATAFILE RENAME ON RESTORE') THEN deb('checkDeletedObject - renaming file#='||object_data||' to '|| object_fname); -- -- -- -- -- DECLARE local_df_key NUMBER; BEGIN SELECT DISTINCT df_key INTO local_df_key FROM df WHERE dbinc_key = this_dbinc_key AND df.file# = object_data AND df.create_scn = object_create_scn; UPDATE site_dfatt SET fname = object_fname WHERE site_key = this_site_key AND df_key = local_df_key; IF (NOT SQL%FOUND) THEN deb('checkDeletedObject - doing an insert'); INSERT INTO site_dfatt (fname, df_key, site_key) VALUES (object_fname, local_df_key, this_site_key); END IF; EXCEPTION WHEN no_data_found THEN NULL; END; END IF; IF (object_type = 'PLUGGED READONLY RENAME') THEN deb('In checkDeletedObject, renaming plugged readonly file#='|| object_data||' to ' ||object_fname); -- -- -- -- -- -- -- DECLARE CURSOR df_key_plugin_cur(file# IN NUMBER, plugin_scn IN NUMBER) IS SELECT df_key FROM df WHERE dbinc_key = this_dbinc_key AND df.file# = df_key_plugin_cur.file# AND df.plugin_scn = df_key_plugin_cur.plugin_scn; BEGIN FOR plugin_df_key IN df_key_plugin_cur(object_data, object_create_scn) LOOP UPDATE site_dfatt SET fname = object_fname WHERE site_key = this_site_key AND df_key = plugin_df_key.df_key; IF (NOT SQL%FOUND) THEN deb('checkDeletedObject - doing an insert'); INSERT INTO site_dfatt (fname, df_key, site_key) VALUES (object_fname, plugin_df_key.df_key, this_site_key); END IF; END LOOP; END; END IF; IF (object_type = 'TEMPFILE RENAME') THEN deb('checkDeletedObject - renaming temp file#='||object_data||' to'|| object_fname); -- -- -- -- -- DECLARE local_tf_key NUMBER; BEGIN SELECT tf_key INTO local_tf_key FROM tf WHERE dbinc_key = this_dbinc_key AND tf.file# = object_data AND tf.create_scn = object_create_scn; UPDATE site_tfatt SET fname = object_fname WHERE site_key = this_site_key AND tf_key = local_tf_key; IF (NOT SQL%FOUND) THEN INSERT INTO site_tfatt (fname, tf_key, site_key) VALUES (object_fname, local_tf_key, this_site_key); END IF; EXCEPTION WHEN no_data_found THEN NULL; END; END IF; IF (object_type = 'DATABASE BLOCK CORRUPTION') THEN DELETE bcr WHERE site_key = this_site_key AND bcr_recid = object_recid AND bcr_stamp = object_stamp; END IF; IF (object_type = 'RESTORE POINT') THEN DELETE nrsp WHERE site_key = this_site_key AND nrsp_recid = object_recid AND nrsp_stamp = object_stamp; END IF; IF (object_type = 'INSTANT RESTORE') THEN -- -- -- -- deb('checkDeletedObject - type ='||object_type|| ' datafile no ='||object_data||' backing file ='||object_fname); END IF; END checkDeletedObject; PROCEDURE endDeletedObjectResync IS BEGIN IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN deb('endDeletedObjectResync - last_do_recid=' || last_do_recid); UPDATE node SET high_do_recid = last_do_recid WHERE site_key = this_site_key; END IF; sessionWaterMarks.high_do_recid := last_do_recid; last_do_recid := NULL; END endDeletedObjectResync; /*----------------------------* * RMAN Output resync * *----------------------------*/ FUNCTION beginRmanOutputResync(start_timestamp IN NUMBER) RETURN NUMBER IS doRoutMining BOOLEAN; last_rout_stamp NUMBER; BEGIN last_rout_stamp := beginRmanOutputResync(start_timestamp, doRoutMining); RETURN last_rout_stamp; END beginRmanOutputResync; FUNCTION beginRmanOutputResync(start_timestamp IN NUMBER, doRoutMining OUT BOOLEAN) RETURN NUMBER IS BEGIN -- getRmanOutputLogging(rman_keep_output); -- IF (session_keep_output = 0) or (rman_keep_output = 0) THEN deb('beginRmanOutputResync - rman output logging is disabled'); return MAXNUMVAL; END IF; deb('beginRmanOutputResync - input instance start time='||start_timestamp); checkResync; -- SELECT inst_startup_stamp, high_rout_stamp into last_inst_startup_stamp, last_rout_stamp from node where node.db_key = this_db_key and ((this_db_unique_name is null and node.db_unique_name is null) or node.db_unique_name = this_db_unique_name); deb('beginRmanOutputResync - last_inst_startup_stamp='|| last_inst_startup_stamp||',last_rout_stamp='||last_rout_stamp); -- -- IF (last_inst_startup_stamp <> start_timestamp) THEN last_rout_stamp := sessionWaterMarks.high_rout_stamp; last_inst_startup_stamp := start_timestamp; doRoutMining := TRUE; ELSE doRoutMining := FALSE; END IF; RETURN last_rout_stamp; END beginRmanOutputResync; -- PROCEDURE insertCachedROUT IS errors NUMBER; dml_errors EXCEPTION; PRAGMA EXCEPTION_INIT(dml_errors, -24381); BEGIN IF lrout_curridx = 0 THEN RETURN; END IF; deb('doing bulk update of ' || lrout_curridx || ' rows into ROUT'); BEGIN FORALL i in 1..lrout_curridx SAVE EXCEPTIONS INSERT INTO ROUT VALUES lrout_table(i); EXCEPTION WHEN dml_errors THEN errors := SQL%BULK_EXCEPTIONS.COUNT; deb('Number of statements that failed: ' || errors); FOR i IN 1..errors LOOP deb('Error #' || i || ' occurred during '|| 'iteration #' || SQL%BULK_EXCEPTIONS(i).ERROR_INDEX); deb('Error message is ' || SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE)); -- IF -SQL%BULK_EXCEPTIONS(i).ERROR_CODE = -1 THEN UPDATE /*+ index(ROUT ROUT_U1) */ ROUT SET rout_text = lrout_table(i).rout_text WHERE db_key = this_db_key AND rsr_key = lrout_table(i).rsr_key AND rout_skey = lrout_table(i).rout_skey AND rout_stamp = lrout_table(i).rout_stamp AND rout_recid = lrout_table(i).rout_recid AND site_key = this_site_key; ELSE lrout_curridx := 0; RAISE; END IF; END LOOP; END; lrout_curridx := 0; END insertCachedROUT; PROCEDURE checkRmanOutput( recid IN NUMBER ,stamp IN NUMBER ,session_recid IN NUMBER ,session_stamp IN NUMBER ,rman_status_recid IN NUMBER ,rman_status_stamp IN NUMBER ,output IN VARCHAR2) IS BEGIN deb('checkRmanOutput', RCVCAT_LEVEL_HI); -- IF (session_keep_output = 0) or (rman_keep_output = 0) THEN deb('checkRmanOutput - rman output logging is disabled'); return; END IF; -- IF (last_rout_stamp < stamp) THEN last_rout_stamp := stamp; END IF; IF lrman_status_recid = rman_status_recid AND lrman_status_stamp = rman_status_stamp THEN goto rsr_key_known; END IF; deb('checkRmanOutput - Find rsr_ key'); BEGIN select rsr_key into lrsr_key from rsr where rsr.dbinc_key = this_dbinc_key and ((rsr.site_key = this_site_key) or (rsr.site_key is null AND this_site_key is null)) and rsr.rsr_recid = rman_status_recid and rsr.rsr_stamp = rman_status_stamp; EXCEPTION WHEN no_data_found THEN -- deb('checkRmanOutput - ignoring following RMAN output row'); RETURN; END; <> IF lsession_recid = session_recid AND lsession_stamp = session_stamp THEN goto rout_skey_known; END IF; deb('checkRmanOutput - Find session key'); BEGIN -- -- -- -- -- select max(rsr_key) into lrout_skey from rsr, dbinc where rsr.dbinc_key = dbinc.dbinc_key and dbinc.db_key = this_db_key and (rsr.site_key = this_site_key or rsr.site_key is null AND this_site_key is null) and rsr.rsr_srecid = session_recid and rsr.rsr_sstamp = session_stamp and rsr.rsr_type = 'SESSION'; EXCEPTION WHEN no_data_found THEN -- deb('checkRmanOutput - ignoring following RMAN output row, cause2'); RETURN; WHEN others THEN deb('checkRmanOutput - signal error for RMAN output row'); RAISE; END; <> IF lrout_skey is null THEN -- deb('checkRmanOutput: skey not found, ignoring RMAN output row'); RETURN; END IF; -- -- BEGIN lrout_curridx := lrout_curridx + 1; lrout_table(lrout_curridx).db_key := this_db_key; lrout_table(lrout_curridx).rsr_key := lrsr_key; lrout_table(lrout_curridx).rout_skey := lrout_skey; lrout_table(lrout_curridx).rout_recid := recid; lrout_table(lrout_curridx).rout_stamp := stamp; lrout_table(lrout_curridx).site_key := this_site_key; lrout_table(lrout_curridx).rout_text := substrb(output, 1, krbmror_llength_bytes); -- bug 5906892 -- IF lrout_curridx = 1000 THEN insertCachedROUT; END IF; END; lrman_status_recid := rman_status_recid; lrman_status_stamp := rman_status_stamp; lsession_recid := session_recid; lsession_stamp := session_stamp; END checkRmanOutput; PROCEDURE endRmanOutputResync IS BEGIN -- IF (session_keep_output = 0) or (rman_keep_output = 0) THEN deb('endRmanOutputResync - rman output logging is disabled'); return; END IF; IF lrout_curridx > 0 THEN insertCachedROUT; END IF; UPDATE node SET high_rout_stamp = last_rout_stamp, inst_startup_stamp = last_inst_startup_stamp WHERE node.db_key = this_db_key and ((this_db_unique_name is null and node.db_unique_name is null) or node.db_unique_name = this_db_unique_name); sessionWaterMarks.high_rout_stamp := last_rout_stamp; last_rout_stamp := NULL; last_inst_startup_stamp := NULL; lrsr_key := NULL; lrout_skey := NULL; lsession_recid := NULL; lsession_stamp := NULL; lrman_status_recid := NULL; lrman_status_stamp := NULL; END endRmanOutputResync; /*----------------------------* * RMAN Status resync * *----------------------------*/ FUNCTION beginRmanStatusResync RETURN NUMBER IS BEGIN checkResync; IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN SELECT high_rsr_recid INTO last_rsr_recid FROM node WHERE site_key = this_site_key; ELSE last_rsr_recid := sessionWaterMarks.high_rsr_recid; END IF; RETURN last_rsr_recid; END beginRmanStatusResync; PROCEDURE checkRmanStatus( recid IN NUMBER ,stamp IN NUMBER ,parent_recid IN NUMBER ,parent_stamp IN NUMBER ,row_level IN NUMBER ,row_type IN VARCHAR2 ,command_id IN VARCHAR2 ,operation IN VARCHAR2 ,status IN VARCHAR2 ,mbytes_processed IN NUMBER ,start_time IN DATE ,end_time IN DATE ,ibytes IN NUMBER default null ,obytes IN NUMBER default null ,optimized IN VARCHAR2 default null ,otype IN VARCHAR2 default null ,session_recid IN NUMBER default null ,session_stamp IN NUMBER default null ,odevtype IN VARCHAR2 default null ,osb_allocated IN VARCHAR2 default 'NO') IS parent rsr%rowtype; BEGIN IF (last_rsr_recid IS NULL) THEN raise_application_error(-20037, 'Invalid last recid'); END IF; IF (recid < last_rsr_recid) THEN raise_application_error(-20036, 'Invalid record order'); END IF; IF (stamp < kccdivts) THEN RETURN; -- obsolete record from a backup controlfile END IF; parent.rsr_pkey := NULL; parent.rsr_l0key := NULL; -- -- -- IF (checkRmanStatus.row_level > 0) THEN deb('checkRmanStatus - row_level='||to_char(checkRmanStatus.row_level)); BEGIN SELECT rsr_key, decode(rsr_level, 0, rsr_key, rsr_l0key) INTO parent.rsr_key, parent.rsr_l0key FROM rsr WHERE rsr.dbinc_key = this_dbinc_key AND (rsr.site_key = this_site_key OR rsr.site_key is null AND this_site_key is null) AND rsr.rsr_stamp = checkRmanStatus.parent_stamp AND rsr.rsr_recid = checkRmanStatus.parent_recid; EXCEPTION WHEN no_data_found THEN -- deb('checkRmanStatus - ignoring this record'); RETURN; END; END IF; BEGIN deb('checkRmanStatus - inserting into rsr'); deb('checkRmanStatus - this_dbinc_key:'||to_char(this_dbinc_key)); deb('checkRmanStatus - recid: '||to_char(recid)); deb('checkRmanStatus - stamp: '||to_char(stamp)); deb('checkRmanStatus - srecid: '||to_char(session_recid)); deb('checkRmanStatus - sstamp: '||to_char(session_stamp)); INSERT INTO rsr (rsr_key, dbinc_key, rsr_recid, rsr_stamp, rsr_pkey, rsr_l0key, rsr_level, rsr_type, rsr_oper, rsr_cmdid, rsr_status, rsr_mbytes, rsr_start, rsr_end, rsr_ibytes, rsr_obytes, rsr_optimized, rsr_otype, rsr_srecid, rsr_sstamp, rsr_odevtype, site_key, rsr_osb_allocated) VALUES (rman_seq.nextval, this_dbinc_key, recid, stamp, parent.rsr_key, parent.rsr_l0key, row_level, row_type, operation, command_id, status, mbytes_processed, start_time, end_time, ibytes, obytes, optimized, otype, session_recid, session_stamp, odevtype, this_site_key, decode(osb_allocated, 'YES', 'Y', 'N')); -- -- DELETE rsr WHERE rsr.dbinc_key = this_dbinc_key AND rsr.rsr_recid = recid AND rsr.rsr_stamp = stamp AND ((this_site_key is not null AND rsr.site_key is NULL) OR (this_site_key is null and rsr.site_key is not null)); EXCEPTION WHEN dup_val_on_index THEN -- deb('checkRmanStatus - exception catch'); deb('checkRmanStatus - this_dbinc_key:'||to_char(this_dbinc_key)); deb('checkRmanStatus - recid: '||to_char(recid)); deb('checkRmanStatus - stamp: '||to_char(stamp)); deb('checkRmanStatus - srecid: '||to_char(session_recid)); deb('checkRmanStatus - sstamp: '||to_char(session_stamp)); UPDATE rsr SET rsr_pkey = parent.rsr_key, rsr_l0key = parent.rsr_l0key, rsr_level = row_level, rsr_type = row_type, rsr_oper = operation, rsr_cmdid = command_id, rsr_status = status, rsr_mbytes = mbytes_processed, rsr_start = start_time, rsr_end = end_time, rsr_ibytes = ibytes, rsr_obytes = obytes, rsr_optimized = optimized, rsr_otype = otype, rsr_odevtype = odevtype, rsr_osb_allocated = decode(osb_allocated, 'YES', 'Y', 'N') WHERE rsr.rsr_stamp = stamp AND rsr.rsr_recid = recid AND (rsr.site_key = this_site_key OR rsr.site_key is null and this_site_key is null) AND rsr.rsr_srecid = session_recid AND rsr.rsr_sstamp = session_stamp AND rsr.dbinc_key = this_dbinc_key; END; END checkRmanStatus; PROCEDURE endRmanStatusResync(recid number) IS BEGIN IF (last_rsr_recid IS NULL) THEN raise_application_error(-20037, 'Invalid last recid'); END IF; IF (recid < last_rsr_recid) THEN raise_application_error(-20036, 'Invalid record order'); END IF; IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN UPDATE node SET high_rsr_recid = recid WHERE site_key = this_site_key; END IF; sessionWaterMarks.high_rsr_recid := recid; last_rsr_recid := NULL; END endRmanStatusResync; PROCEDURE updateRmanStatusRow( recid IN number ,stamp IN number ,mbytes IN number ,status IN binary_integer ) IS BEGIN IF (this_dbinc_key IS NULL) THEN return; END IF; UPDATE rsr SET rsr_status = decode(status, 1, 'RUNNING', 1+8, 'RUNNING WITH WARNINGS', 1+16, 'RUNNING WITH ERRORS', 1+8+16, 'RUNNING WITH ERRORS', 2, 'COMPLETED', 2+8, 'COMPLETED WITH WARNINGS', 2+16, 'COMPLETED WITH ERRORS', 2+8+16, 'COMPLETED WITH ERRORS', 'FAILED'), rsr_mbytes = mbytes WHERE rsr.rsr_stamp = stamp AND rsr.rsr_recid = recid AND (rsr.site_key = this_site_key OR rsr.site_key is null AND this_site_key is null) AND rsr.dbinc_key = this_dbinc_key; commitChanges('updateRmanStatusRow'); END updateRmanStatusRow; PROCEDURE rsDeleteBackupPiece(bp_key IN number, purged IN varchar2) IS bs_key number; db_key number; retention_time timestamp with time zone; BEGIN -- SELECT bp.bs_key, bp.db_key INTO bs_key, db_key FROM bp, bs WHERE bp.bp_key = rsDeleteBackupPiece.bp_key AND bp.bs_key = bs.bs_key FOR UPDATE OF bs.bs_key; deb('rsDeleteBackupPiece - locked bs_key' || bs_key); -- UPDATE bp SET bp.status = 'D', bp.purged = rsDeleteBackupPiece.purged WHERE bp.bp_key = rsDeleteBackupPiece.bp_key; IF (purged = 'Y') THEN IF this_is_ors THEN this_enable_populate_rsr := getValueFromConfig('_enable_populate_rsr_key'); END IF; updateBackupSetRec(bs_key); -- -- IF this_is_ors THEN this_enable_populate_rsr := NULL; this_upstream_site_key := NULL; END IF; END IF; -- END rsDeleteBackupPiece; FUNCTION getValueFromConfig(entry IN VARCHAR2) RETURN varchar2 IS entryVal config.value%TYPE; BEGIN SELECT UPPER(value) INTO entryVal FROM config WHERE name = entry; return entryVal; END getValueFromConfig; /*-------------------* * Change Procedures * *-------------------*/ /* * In these change procedures, we don't check that we found the record, * because we are processing a DL record - i.e. we already processed the * other cf records and hence it might already be flagged deleted. This * applies to any status change because we might make it available and * then delete the object, so the object would be marked as deleted when * we process the object and the available status change (first DL) would * fail to find the object, so would a following DL that marks it deleted. */ PROCEDURE changeDatafileCopy( cdf_recid IN NUMBER ,cdf_stamp IN NUMBER ,status IN VARCHAR2 ,keep_options IN NUMBER DEFAULT NULL -- null means do not update ,keep_until IN DATE DEFAULT NULL ,osite_key IN number DEFAULT NULL -- old site_key for the record ,nsite_key IN number DEFAULT NULL -- null means do not update ) IS local dbinc%rowtype; fno cdf.file#%type; BEGIN IF (this_dbinc_key IS NULL) THEN raise_application_error(-20020, 'Database incarnation not set'); END IF; -- BEGIN -- SELECT file# into fno FROM cdf WHERE dbinc_key in (select dbinc_key from dbinc where db_key = this_db_key) AND ((osite_key is null AND cdf.site_key is null) OR cdf.site_key = nvl(osite_key, cdf.site_key)) AND cdf.cdf_recid = changeDatafileCopy.cdf_recid AND cdf.cdf_stamp = changeDatafileCopy.cdf_stamp; EXCEPTION WHEN no_data_found THEN BEGIN -- SELECT 0 into fno FROM ccf WHERE dbinc_key in (select dbinc_key from dbinc where db_key = this_db_key) AND ((osite_key is null AND ccf.site_key is null) OR ccf.site_key = nvl(osite_key, ccf.site_key)) AND ccf.ccf_recid = changeDatafileCopy.cdf_recid AND ccf.ccf_stamp = changeDatafileCopy.cdf_stamp; -- changeControlfileCopy(cdf_recid, cdf_stamp, status, keep_options, keep_until, osite_key, nsite_key); RETURN; EXCEPTION WHEN no_data_found THEN RETURN; -- already deleted (we are processing a DL record) END; WHEN OTHERS THEN RAISE; END; IF status IS NULL THEN -- -- IF keep_until IS NOT NULL THEN UPDATE cdf SET keep_until = changeDatafileCopy.keep_until WHERE cdf.dbinc_key in (select dbinc_key from dbinc where dbinc.db_key = this_db_key) AND ((osite_key is null AND cdf.site_key is null) OR cdf.site_key = nvl(osite_key, cdf.site_key)) AND cdf.cdf_recid = changeDatafileCopy.cdf_recid AND cdf.cdf_stamp = changeDatafileCopy.cdf_stamp; END IF; IF keep_options IS NOT NULL THEN UPDATE cdf SET keep_options = changeDatafileCopy.keep_options WHERE cdf.dbinc_key in (select dbinc_key from dbinc where dbinc.db_key = this_db_key) AND ((osite_key is null AND cdf.site_key is null) OR cdf.site_key = nvl(osite_key, cdf.site_key)) AND cdf.cdf_recid = changeDatafileCopy.cdf_recid AND cdf.cdf_stamp = changeDatafileCopy.cdf_stamp; END IF; ELSIF status IN ('A','U','X') THEN -- -- UPDATE cdf SET status = changeDatafileCopy.status, site_key = nvl(nsite_key, site_key) WHERE cdf.dbinc_key in (select dbinc_key from dbinc where dbinc.db_key = this_db_key) AND ((osite_key is null AND cdf.site_key is null) OR cdf.site_key = nvl(osite_key, cdf.site_key)) AND cdf.cdf_recid = changeDatafileCopy.cdf_recid AND cdf.cdf_stamp = changeDatafileCopy.cdf_stamp; -- IF sql%rowcount > 0 and nsite_key is not null THEN deleteDuplicateCDF(cdf_recid, cdf_stamp, null); END IF; ELSIF status IN ('R','D') THEN DELETE FROM cdf WHERE cdf.dbinc_key in (select dbinc_key from dbinc where dbinc.db_key = this_db_key) AND ((osite_key is null AND cdf.site_key is null) OR cdf.site_key = nvl(osite_key, cdf.site_key)) AND cdf.cdf_recid = changeDatafileCopy.cdf_recid AND cdf.cdf_stamp = changeDatafileCopy.cdf_stamp; ELSE raise_application_error(-20100, 'Invalid status'); END IF; -- commitChanges('changeDatafileCopy'); END changeDatafileCopy; PROCEDURE changeControlfileCopy( cdf_recid IN NUMBER ,cdf_stamp IN NUMBER ,status IN VARCHAR2 ,keep_options IN NUMBER DEFAULT NULL -- null means do not update ,keep_until IN DATE DEFAULT NULL ,osite_key IN number DEFAULT NULL -- old site_key for the record ,nsite_key IN number DEFAULT NULL -- null means do not update ) IS local dbinc%rowtype; BEGIN IF (this_dbinc_key IS NULL) THEN raise_application_error(-20020, 'Database incarnation not set'); END IF; IF status IS NULL THEN -- -- IF keep_until IS NOT NULL THEN UPDATE ccf SET keep_until = changeControlfileCopy.keep_until WHERE ccf.dbinc_key in (select dbinc_key from dbinc where dbinc.db_key = this_db_key) AND ((osite_key is null AND ccf.site_key is null) OR ccf.site_key = nvl(osite_key, ccf.site_key)) AND ccf.ccf_recid = changeControlfileCopy.cdf_recid AND ccf.ccf_stamp = changeControlfileCopy.cdf_stamp; END IF; IF keep_options IS NOT NULL THEN UPDATE ccf SET keep_options = changeControlfileCopy.keep_options WHERE ccf.dbinc_key in (select dbinc_key from dbinc where dbinc.db_key = this_db_key) AND ((osite_key is null AND ccf.site_key is null) OR ccf.site_key = nvl(osite_key, ccf.site_key)) AND ccf.ccf_recid = changeControlfileCopy.cdf_recid AND ccf.ccf_stamp = changeControlfileCopy.cdf_stamp; END IF; ELSIF status IN ('A','U','X') THEN -- -- UPDATE ccf SET status = changeControlfileCopy.status, site_key = nvl(nsite_key, site_key) WHERE ccf.dbinc_key in (select dbinc_key from dbinc where dbinc.db_key = this_db_key) AND ((osite_key is null AND ccf.site_key is null) OR ccf.site_key = nvl(osite_key, ccf.site_key)) AND ccf.ccf_recid = changeControlfileCopy.cdf_recid AND ccf.ccf_stamp = changeControlfileCopy.cdf_stamp; -- IF sql%rowcount > 0 and nsite_key is not null THEN deleteDuplicateCCF(cdf_recid, cdf_stamp, null); END IF; ELSIF status IN ('R','D') THEN DELETE FROM ccf WHERE ccf.dbinc_key in (select dbinc_key from dbinc where dbinc.db_key = this_db_key) AND ((osite_key is null AND ccf.site_key is null) OR ccf.site_key = nvl(osite_key, ccf.site_key)) AND ccf.ccf_recid = changeControlfileCopy.cdf_recid AND ccf.ccf_stamp = changeControlfileCopy.cdf_stamp; ELSE raise_application_error(-20100, 'Invalid status'); END IF; -- commitChanges('changeControlfileCopy'); END changeControlfileCopy; PROCEDURE changeArchivedLog( al_recid IN NUMBER ,al_stamp IN NUMBER ,status IN VARCHAR2 ,osite_key IN NUMBER DEFAULT NULL -- old site_key for the record ,nsite_key IN NUMBER DEFAULT NULL -- null means do not update ) IS BEGIN IF (this_dbinc_key IS NULL) THEN raise_application_error(-20020, 'Database incarnation not set'); END IF; IF status IN ('A','U','X') THEN -- -- UPDATE al SET status = changeArchivedLog.status, site_key = nvl(nsite_key, site_key) WHERE al.dbinc_key in (select dbinc_key from dbinc where dbinc.db_key = this_db_key) AND al.al_recid = changeArchivedLog.al_recid AND al.al_stamp = changeArchivedLog.al_stamp AND ((osite_key is null AND al.site_key is null) OR al.site_key = nvl(osite_key, al.site_key)); -- IF sql%rowcount > 0 and nsite_key is not null THEN deleteDuplicateAL(al_recid, al_stamp, null); END IF; ELSIF status IN ('R','D') THEN -- -- -- DELETE FROM al WHERE al.dbinc_key IN (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key) AND ((osite_key is null AND al.site_key is null) OR al.site_key = nvl(osite_key, al.site_key)) AND al.al_recid = changeArchivedLog.al_recid AND al.al_stamp = changeArchivedLog.al_stamp; ELSE raise_application_error(-20100, 'Invalid status'); END IF; -- commitChanges('changeArchivedLog'); END changeArchivedLog; PROCEDURE changeBackupSet( recid IN number ,stamp IN number ,keep_options IN number -- null means do not update ,keep_until IN date ,osite_key IN number DEFAULT NULL -- old site_key for the record ,nsite_key IN number DEFAULT NULL -- null means do not update ) IS local bs%rowtype; CURSOR dflist IS SELECT * FROM bdf WHERE bdf.bs_key = local.bs_key; CURSOR rllist IS SELECT * FROM brl WHERE brl.bs_key = local.bs_key; has_virtual boolean := TRUE; l_virtual number := 0; BEGIN IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; BEGIN SELECT * INTO local FROM bs WHERE bs.db_key = this_db_key AND bs.bs_recid = changeBackupSet.recid AND bs.bs_stamp = changeBackupSet.stamp FOR UPDATE OF bs.bs_key; deb('changeBackupSet - locked bs_key' || local.bs_key); EXCEPTION WHEN NO_DATA_FOUND THEN RETURN; -- already deleted (we are processing a DL record) END; BEGIN SELECT bp.vb_key INTO l_virtual FROM bp,bs WHERE bp.bs_key = bs.bs_key AND bp.vb_key IS NOT NULL AND bs.bs_key = local.bs_key; EXCEPTION WHEN NO_DATA_FOUND THEN has_virtual := FALSE; -- no virtual found END; IF has_virtual THEN deb('changeBackupSet - virtual backup piece key (AM)' || l_virtual); END IF; IF nsite_key is not null THEN UPDATE bp SET site_key = nsite_key WHERE bs_key = local.bs_key; UPDATE bs SET site_key = nsite_key WHERE bs_key = local.bs_key; END IF; IF NOT has_virtual THEN UPDATE bs SET bs.keep_until = changeBackupSet.keep_until WHERE bs.bs_key = local.bs_key; END IF; IF NOT has_virtual AND keep_options IS NOT NULL THEN UPDATE bs SET bs.keep_options = changeBackupSet.keep_options WHERE bs.bs_key = local.bs_key; -- IF (local.bck_type = 'L') THEN FOR rlrec IN rllist LOOP updateRestorePoint(rlrec.low_scn, rlrec.next_scn); END LOOP; END IF; IF (local.bck_type = 'D') THEN FOR dfrec IN dflist LOOP updateRestorePoint(dfrec.ckp_scn, null); END LOOP; END IF; END IF; -- commitChanges('changeBackupSet'); END changeBackupSet; PROCEDURE changeBackupPiece( bp_recid IN NUMBER ,bp_stamp IN NUMBER ,status IN VARCHAR2 ,set_stamp IN NUMBER DEFAULT NULL ,set_count IN NUMBER DEFAULT NULL ,osite_key IN NUMBER DEFAULT NULL -- old site_key for the record ,nsite_key IN NUMBER DEFAULT NULL -- null means do not update ,handle IN VARCHAR2 DEFAULT NULL -- null means not known ,device_type IN VARCHAR2 DEFAULT NULL -- null means not known ) IS CURSOR bsQ(bp_recid IN NUMBER, bp_stamp IN NUMBER) IS SELECT bs_key FROM bp WHERE bp.db_key = this_db_key AND ((osite_key is null AND bp.site_key is null) OR bp.site_key = nvl(osite_key, bp.site_key)) AND bp.bp_recid = bsQ.bp_recid AND bp.bp_stamp = bsQ.bp_stamp; bsQrec bsQ%ROWTYPE; totalbp number; chgbskey number := NULL; l_ba_access bp.ba_access%type; l_bp_key number; l_bp_recid number; l_bp_stamp number; BEGIN IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; l_bp_recid := changeBackupPiece.bp_recid; l_bp_stamp := changeBackupPiece.bp_stamp; -- -- IF (set_stamp is not null AND set_count is not null) THEN BEGIN SELECT bs_key INTO chgbskey FROM bs WHERE bs.db_key = this_db_key AND bs.set_stamp = changeBackupPiece.set_stamp AND bs.set_count = changeBackupPiece.set_count FOR UPDATE OF bs.bs_key; deb('changeBackupPiece - locked bs_key' || chgbskey); EXCEPTION WHEN NO_DATA_FOUND THEN RETURN; -- already deleted (we are processing a DL record) END; deb('changeBackupPiece - chgbskey=' || chgbskey); ELSE -- -- -- -- -- SELECT count(*) INTO totalbp FROM bp WHERE bp.db_key = this_db_key AND ((osite_key is null AND bp.site_key is null) OR bp.site_key = nvl(osite_key, bp.site_key)) AND bp.bp_recid = l_bp_recid AND bp.bp_stamp = l_bp_stamp AND bp.bs_key = nvl(chgbskey, bp.bs_key); deb('changeBackupPiece - number of backup pieces match ' || totalbp); IF totalbp = 0 then RETURN; -- already deleted (we are processing a DL record) END IF; END IF; IF changeBackupPiece.handle is NOT NULL AND chgbskey IS NOT NULL THEN BEGIN deb('changeBackupPiece - Override bp_recid/bp_stamp for ' || handle || ', on ' || device_type); SELECT bp_recid, bp_stamp INTO l_bp_recid, l_bp_stamp FROM bp WHERE bp.db_key = this_db_key AND bp.bs_key = chgbskey AND bp.handle = changeBackupPiece.handle AND bp.device_type = changeBackupPiece.device_type; EXCEPTION WHEN NO_DATA_FOUND THEN deb('changeBackupPiece - Not found '); WHEN OTHERS THEN deb('changeBackupPiece(DO_NOT_IGNORE) - Error ' || sqlerrm); END; deb('changeBackupPiece - recid='||l_bp_recid||', stamp='||l_bp_stamp); END IF; -- -- -- IF status in ('A','U','X') THEN -- -- UPDATE bp SET status = changeBackupPiece.status, site_key = nvl(nsite_key, site_key) WHERE bp.db_key = this_db_key AND ((osite_key is null AND bp.site_key is null) OR bp.site_key = nvl(osite_key, bp.site_key)) AND bp.bp_recid = l_bp_recid AND bp.bp_stamp = l_bp_stamp AND bp.bs_key = nvl(chgbskey, bp.bs_key) AND bp.ba_access != 'L' -- AM: no status changing AND bp.status != 'D'; -- IF sql%rowcount > 0 and nsite_key is not null THEN -- -- IF chgbskey is not null THEN UPDATE bs SET site_key=null WHERE bs_key = chgbskey; ELSE UPDATE bs SET site_key=null WHERE bs_key in (SELECT bs_key FROM bp WHERE bp.db_key = this_db_key AND ((osite_key is null AND bp.site_key is null) OR bp.site_key = nvl(osite_key, bp.site_key)) AND bp.bp_recid = l_bp_recid AND bp.bp_stamp = l_bp_stamp); END IF; deleteDuplicateBP(l_bp_recid, l_bp_stamp, chgbskey, null, null); END IF; ELSIF status not in ('R', 'D') THEN raise_application_error(-20100, 'Invalid status'); END IF; IF this_is_ors AND this_ckp_key IS NULL THEN this_enable_populate_rsr := getValueFromConfig('_enable_populate_rsr_key'); END IF; IF (chgbskey IS NULL) THEN FOR bsQrec in bsQ(l_bp_recid, l_bp_stamp) LOOP -- -- IF status in ('R', 'D') THEN UPDATE bp SET bp.status = 'D' WHERE bp.db_key = this_db_key AND ((osite_key is null AND bp.site_key is null) OR bp.site_key = nvl(osite_key, bp.site_key)) AND bp.bp_recid = l_bp_recid AND bp.bp_stamp = l_bp_stamp AND bp.bs_key = bsQrec.bs_key RETURNING bp.ba_access, bp.bp_key INTO l_ba_access, l_bp_key; -- IF l_ba_access != 'U' THEN DELETE FROM bp WHERE bp.bp_key = l_bp_key; END IF; END IF; -- updateBackupSetRec(bsQrec.bs_key); END LOOP; ELSE IF status in ('R', 'D') THEN UPDATE bp SET bp.status = 'D' WHERE bp.db_key = this_db_key AND ((osite_key is null AND bp.site_key is null) OR bp.site_key = nvl(osite_key, bp.site_key)) AND bp.bp_recid = l_bp_recid AND bp.bp_stamp = l_bp_stamp AND bp.bs_key = chgbskey AND bp.ba_access != 'L' -- AM: no status changing RETURNING bp.ba_access, bp.bp_key INTO l_ba_access, l_bp_key; -- IF l_ba_access = 'U' THEN DELETE FROM bp WHERE bp.bp_key = l_bp_key; END IF; END IF; -- updateBackupSetRec(chgbskey); END IF; -- -- IF this_is_ors AND this_ckp_key IS NULL THEN this_enable_populate_rsr := NULL; this_upstream_site_key := NULL; END IF; -- commitChanges('changeBackupPiece'); END changeBackupPiece; PROCEDURE changeProxyCopy( pc_recid IN NUMBER ,pc_stamp IN NUMBER ,status IN VARCHAR2 ,keep_options IN NUMBER DEFAULT NULL -- null means do not update ,keep_until IN DATE DEFAULT NULL ,osite_key IN number DEFAULT NULL -- old site_key for the record ,nsite_key IN number DEFAULT NULL -- null means do not update ) IS low_scn number; next_scn number; xobjid rowid; -- proxy object rowid BEGIN IF this_db_key IS NULL THEN raise_application_error(-20021, 'Database not set'); END IF; IF status IS NULL THEN -- -- IF keep_until IS NOT NULL THEN UPDATE xdf SET xdf.keep_until = changeProxyCopy.keep_until WHERE xdf.dbinc_key in (select dbinc_key from dbinc where dbinc.db_key = this_db_key) AND ((osite_key is null AND xdf.site_key is null) OR xdf.site_key = nvl(osite_key, xdf.site_key)) AND xdf.xdf_recid = changeProxyCopy.pc_recid AND xdf.xdf_stamp = changeProxyCopy.pc_stamp; -- IF sql%rowcount = 0 THEN UPDATE xcf SET xcf.keep_until = changeProxyCopy.keep_until WHERE xcf.dbinc_key in (select dbinc_key from dbinc where dbinc.db_key = this_db_key) AND ((osite_key is null AND xcf.site_key is null) OR xcf.site_key = nvl(osite_key, xcf.site_key)) AND xcf.xcf_recid = changeProxyCopy.pc_recid AND xcf.xcf_stamp = changeProxyCopy.pc_stamp; END IF; END IF; IF keep_options IS NOT NULL THEN SELECT min(ckp_scn), min(rowid) into low_scn, xobjid FROM xdf WHERE xdf.dbinc_key in (select dbinc_key from dbinc where dbinc.db_key = this_db_key) AND ((osite_key is null AND xdf.site_key is null) OR xdf.site_key = nvl(osite_key, xdf.site_key)) AND xdf.xdf_recid = changeProxyCopy.pc_recid AND xdf.xdf_stamp = changeProxyCopy.pc_stamp; -- IF xobjid IS NOT NULL THEN updateRestorePoint(low_scn, null); UPDATE xdf SET xdf.keep_options = changeProxyCopy.keep_options WHERE rowid = xobjid; ELSE -- UPDATE xcf SET xcf.keep_options = changeProxyCopy.keep_options WHERE xcf.dbinc_key in (select dbinc_key from dbinc where dbinc.db_key = this_db_key) AND ((osite_key is null AND xcf.site_key is null) OR xcf.site_key = nvl(osite_key, xcf.site_key)) AND xcf.xcf_recid = changeProxyCopy.pc_recid AND xcf.xcf_stamp = changeProxyCopy.pc_stamp; -- IF sql%rowcount = 0 THEN SELECT min(xal.low_scn), min(xal.next_scn), min(rowid) into low_scn, next_scn, xobjid FROM xal WHERE xal.dbinc_key in (select dbinc_key from dbinc where dbinc.db_key = this_db_key) AND ((osite_key is null AND xal.site_key is null) OR xal.site_key = nvl(osite_key, xal.site_key)) AND xal.xal_recid = changeProxyCopy.pc_recid AND xal.xal_stamp = changeProxyCopy.pc_stamp; -- IF xobjid IS NOT NULL THEN updateRestorePoint(low_scn, next_scn); UPDATE xal SET xal.keep_options = changeProxyCopy.keep_options WHERE rowid = xobjid; END IF; END IF; END IF; END IF; ELSIF status in ('A','U','X') THEN -- -- UPDATE xdf SET status = changeProxyCopy.status, site_key = nvl(nsite_key, site_key) WHERE xdf.dbinc_key in (select dbinc_key from dbinc where dbinc.db_key = this_db_key) AND ((osite_key is null AND xdf.site_key is null) OR xdf.site_key = nvl(osite_key, xdf.site_key)) AND xdf.xdf_recid = changeProxyCopy.pc_recid AND xdf.xdf_stamp = changeProxyCopy.pc_stamp; -- IF sql%rowcount > 0 and nsite_key is not null THEN deleteDuplicateXDF(pc_recid, pc_stamp, null, null); END IF; -- IF sql%rowcount = 0 THEN UPDATE xcf SET status = changeProxyCopy.status, site_key = nvl(nsite_key, site_key) WHERE xcf.dbinc_key in (select dbinc_key from dbinc where dbinc.db_key = this_db_key) AND ((osite_key is null AND xcf.site_key is null) OR xcf.site_key = nvl(osite_key, xcf.site_key)) AND xcf.xcf_recid = changeProxyCopy.pc_recid AND xcf.xcf_stamp = changeProxyCopy.pc_stamp; -- IF sql%rowcount > 0 and nsite_key is not null THEN deleteDuplicateXCF(pc_recid, pc_stamp, null, null); END IF; END IF; -- IF sql%rowcount = 0 THEN UPDATE xal SET status = changeProxyCopy.status, site_key = nvl(nsite_key, site_key) WHERE xal.dbinc_key in (select dbinc_key from dbinc where dbinc.db_key = this_db_key) AND ((osite_key is null AND xal.site_key is null) OR xal.site_key = nvl(osite_key, xal.site_key)) AND xal.xal_recid = changeProxyCopy.pc_recid AND xal.xal_stamp = changeProxyCopy.pc_stamp; -- IF sql%rowcount > 0 and nsite_key is not null THEN deleteDuplicateXAL(pc_recid, pc_stamp, null, null); END IF; END IF; ELSIF status IN ('R','D') THEN -- SELECT min(ckp_scn), min(rowid) into low_scn, xobjid FROM xdf WHERE xdf.dbinc_key in (select dbinc_key from dbinc where dbinc.db_key = this_db_key) AND ((osite_key is null AND xdf.site_key is null) OR xdf.site_key = nvl(osite_key, xdf.site_key)) AND xdf.xdf_recid = changeProxyCopy.pc_recid AND xdf.xdf_stamp = changeProxyCopy.pc_stamp; -- IF xobjid IS NOT NULL THEN updateRestorePoint(low_scn, null); DELETE FROM xdf WHERE rowid = xobjid; ELSE -- DELETE FROM xcf WHERE xcf.dbinc_key in (select dbinc_key from dbinc where dbinc.db_key = this_db_key) AND ((osite_key is null AND xcf.site_key is null) OR xcf.site_key = nvl(osite_key, xcf.site_key)) AND xcf.xcf_recid = changeProxyCopy.pc_recid AND xcf.xcf_stamp = changeProxyCopy.pc_stamp; -- IF sql%rowcount = 0 THEN SELECT min(xal.low_scn), min(xal.next_scn), min(rowid) into low_scn, next_scn, xobjid FROM xal WHERE xal.dbinc_key in (select dbinc_key from dbinc where dbinc.db_key = this_db_key) AND ((osite_key is null AND xal.site_key is null) OR xal.site_key = nvl(osite_key, xal.site_key)) AND xal.xal_recid = changeProxyCopy.pc_recid AND xal.xal_stamp = changeProxyCopy.pc_stamp; IF xobjid IS NOT NULL THEN updateRestorePoint(low_scn, next_scn); DELETE FROM xal WHERE rowid = xobjid; END IF; END IF; END IF; ELSE raise_application_error(-20100, 'Invalid status'); END IF; -- commitChanges('changeProxyCopy'); END changeProxyCopy; /*----------------------------* * Stored Script Procedures * *----------------------------*/ PROCEDURE createScript(name IN VARCHAR2) IS BEGIN createScript(name, NULL, FALSE); END; PROCEDURE createScript(name IN VARCHAR2, scr_com IN VARCHAR2, global IN boolean) IS foo NUMBER; dbkey NUMBER := this_db_key; BEGIN scr_key := NULL; -- for safety IF global THEN dbkey := NULL; scr_glob := TRUE; ELSE scr_glob := FALSE; IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; END IF; SELECT count(*) INTO foo FROM scr WHERE ((dbkey is not null and scr.db_key = dbkey) OR (dbkey is null and scr.db_key is null)) AND scr.scr_name = createScript.name; IF foo > 0 THEN raise_application_error(-20401, 'script '||name||' already exists'); END IF; INSERT INTO scr VALUES(rman_seq.nextval, dbkey, name, scr_com) RETURNING scr_key INTO scr_key; scr_line := 1; -- commitChanges('createScript'); END; PROCEDURE replaceScript(name IN VARCHAR2) IS BEGIN replaceScript(name, NULL, FALSE); END; PROCEDURE replaceScript(name IN VARCHAR2, scr_com IN VARCHAR2, global IN boolean) IS dbkey NUMBER := this_db_key; BEGIN IF global THEN dbkey := NULL; scr_glob := TRUE; ELSE scr_glob := FALSE; IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; END IF; SELECT scr_key INTO scr_key FROM scr WHERE ((dbkey is not null and scr.db_key = dbkey) OR (dbkey is null and scr.db_key is null)) AND scr.scr_name = replaceScript.name; UPDATE scr SET scr_comment = scr_com WHERE scr.scr_key = dbms_rcvcat.scr_key; DELETE FROM scrl WHERE scrl.scr_key = dbms_rcvcat.scr_key; scr_line := 1; -- commitChanges('replaceScript'); EXCEPTION WHEN NO_DATA_FOUND THEN createScript(name, scr_com, global); END; PROCEDURE putLine(line IN VARCHAR2) IS BEGIN IF not scr_glob and this_db_key IS NULL THEN raise_application_error(-20021, 'Database not set'); END IF; IF (scr_key IS NULL) THEN raise_application_error(-20402, 'createScript or replaceScript not done'); END IF; INSERT INTO scrl(scr_key, linenum, text) VALUES(scr_key, scr_line, line); scr_line := scr_line + 1; END; PROCEDURE deleteScript(name IN VARCHAR2) IS BEGIN deleteScript(name, 0); END; PROCEDURE deleteScript(name IN VARCHAR2, glob IN NUMBER) IS dbkey NUMBER := this_db_key; BEGIN IF glob = 1 THEN dbkey := NULL; ELSE IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; END IF; SELECT scr_key INTO scr_key FROM scr WHERE ((dbkey is not null and scr.db_key = dbkey) OR (dbkey is null and scr.db_key is null)) AND scr.scr_name = deleteScript.name; DELETE FROM scr WHERE scr.scr_key = dbms_rcvcat.scr_key; scr_key := NULL; -- commitChanges('deleteScript'); EXCEPTION WHEN NO_DATA_FOUND THEN scr_key := NULL; raise_application_error(-20400, 'stored script not found'); END; PROCEDURE getScript(name IN VARCHAR2) IS BEGIN getScript(name, 0); END; PROCEDURE getScript(name IN VARCHAR2, glob IN NUMBER) IS dbkey NUMBER := this_db_key; BEGIN IF glob = 1 THEN dbkey := NULL; scr_glob := TRUE; ELSE scr_glob := FALSE; IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; END IF; SELECT scr_key INTO scr_key FROM scr WHERE ((dbkey is not null and scr.db_key = dbkey) OR (dbkey is null and scr.db_key is null)) AND scr.scr_name = getScript.name; IF scrlQ%ISOPEN THEN CLOSE scrlQ; END IF; OPEN scrlQ(scr_key); EXCEPTION WHEN NO_DATA_FOUND THEN scr_key := NULL; raise_application_error(-20400, 'stored script not found'); END; FUNCTION getLine RETURN VARCHAR2 IS scrl_row scrlQ%rowtype; BEGIN IF not scr_glob and this_db_key IS NULL THEN raise_application_error(-20021, 'Database not set'); END IF; IF NOT scrlQ%ISOPEN THEN raise_application_error(-20403, 'getScript not done'); END IF; FETCH scrlQ INTO scrl_row; IF scrlQ%NOTFOUND THEN -- end of fetch close scrlQ; return NULL; END IF; RETURN scrl_row.text; END; PROCEDURE commitChanges(msg IN varchar2 DEFAULT NULL) IS BEGIN IF (this_ckp_key IS NULL) THEN deb(msg || ',commitChanges commit, release locks'); commit; ELSE deb(msg || ',resync active, commitChanges ignored'); END IF; END; /*---------------------------------------* * Procedures for EM xml store support * *---------------------------------------*/ procedure createXMLFile (name IN varchar2 ,name_tag IN varchar2 ,xmldoc IN clob ,doctype IN varchar2 ,xml_comment IN varchar2 ,schema_ver IN varchar2 ) IS begin -- insert into xmlstore (store_key, creation_time, name, name_tag, doctype, schema_ver, xml_comment, xmldoc) values (rman_seq.nextval, sys_extract_utc(systimestamp), createXMLFile.name, createXMLFile.name_tag, createXMLFile.doctype, createXMLFile.schema_ver, createXMLFile.xml_comment, XMLType.createXML(createXMLFile.xmldoc, schema_ver)); commitChanges('createXMLFile'); end createXMLFile; procedure updateXMLFile (name IN varchar2 ,name_tag IN varchar2 ,xmldoc IN clob ,xml_comment IN varchar2 ,schema_ver IN varchar2 ,new_name IN varchar2 ,new_name_tag IN varchar2 ,new_version IN BOOLEAN ) IS oldrec xmlstore%ROWTYPE; begin -- begin select * into oldrec from xmlstore where name = updateXMLFile.name and (name_tag = updateXMLFile.name_tag or (name_tag is null and updateXMLFile.name_tag is null)) for update; exception when too_many_rows then select * into oldrec from xmlstore where name = updateXMLFile.name and (name_tag = updateXMLFile.name_tag or (name_tag is null and updateXMLFile.name_tag is null)) and version_num = (select max(version_num) from xmlstore where name = updateXMLFile.name and (name_tag = updateXMLFile.name_tag or (name_tag is null and updateXMLFile.name_tag is null))) for update; end; -- if xmldoc is not null then oldrec.xmldoc := XMLType.createXML(xmldoc, nvl(schema_ver, oldrec.schema_ver)); end if; if xml_comment is not null then oldrec.xml_comment := xml_comment; end if; if schema_ver is not null then oldrec.schema_ver := schema_ver; end if; if new_name is not null then oldrec.name := new_name; end if; if new_name_tag is not null then oldrec.name_tag := new_name_tag; end if; -- -- if new_version then oldrec.version_num := oldrec.version_num + 1; select rman_seq.nextval into oldrec.store_key from dual; insert into xmlstore values oldrec; else oldrec.modified_time := sys_extract_utc(systimestamp); update xmlstore p set row = oldrec where p.name = updateXMLFile.name and (p.name_tag = updateXMLFile.name_tag or (p.name_tag is null and updateXMLFile.name_tag is null)) and p.version_num = oldrec.version_num; end if; commitChanges('updateXMLFile'); end updateXMLFile; procedure deleteXMLFile (name IN varchar2 ,name_tag IN varchar2) IS begin -- delete xmlstore where name = deleteXMLFile.name and (name_tag = deleteXMLFile.name_tag or (name_tag is null and deleteXMLFile.name_tag is null)); if sql%rowcount = 0 then raise no_data_found; end if; commitChanges('deleteXMLFile'); end deleteXMLFile; procedure readXMLFile (name IN varchar2 ,name_tag IN varchar2 ,version_num IN number ,xmldoc OUT clob) IS begin -- if version_num is null then begin select XMLType.getClobVal(xmldoc) into readXMLFile.xmldoc from xmlstore where name = readXMLFile.name and (name_tag = readXMLFile.name_tag or (name_tag is null and readXMLFile.name_tag is null)); exception when too_many_rows then select XMLType.getClobVal(xmldoc) into readXMLFile.xmldoc from xmlstore where name = readXMLFile.name and (name_tag = readXMLFile.name_tag or (name_tag is null and readXMLFile.name_tag is null)) and version_num = (select max(version_num) from xmlstore where name = readXMLFile.name and (name_tag = readXMLFile.name_tag or (name_tag is null and readXMLFile.name_tag is null))); end; else select XMLType.getClobVal(xmldoc) into readXMLFile.xmldoc from xmlstore where name = readXMLFile.name and (name_tag = readXMLFile.name_tag or (name_tag is null and readXMLFile.name_tag is null)) and version_num = readXMLFile.version_num; end if; end readXMLFile; procedure getXMLFileAttr (name IN varchar2 ,name_tag IN varchar2 ,version_num IN number ,doctype OUT varchar2 ,file_size OUT number ,xml_comment OUT varchar2 ,schema_ver OUT varchar2) is myrec xmlstore%ROWTYPE; begin -- -- if version_num is null then begin select * into myrec from xmlstore where name = getXMLFileAttr.name and (name_tag = getXMLFileAttr.name_tag or (name_tag is null and getXMLFileAttr.name_tag is null)); exception when too_many_rows then select * into myrec from xmlstore where name = getXMLFileAttr.name and (name_tag = getXMLFileAttr.name_tag or (name_tag is null and getXMLFileAttr.name_tag is null)) and version_num = (select max(version_num) from xmlstore where name = getXMLFileAttr.name and (name_tag = getXMLFileAttr.name_tag or (name_tag is null and getXMLFileAttr.name_tag is null))); end; else select * into myrec from xmlstore where name = getXMLFileAttr.name and (name_tag = getXMLFileAttr.name_tag or (name_tag is null and getXMLFileAttr.name_tag is null)) and version_num = getXMLFileAttr.version_num; end if; -- doctype := myrec.doctype; file_size := dbms_lob.getlength(XMLType.getClobVal(myrec.xmldoc)); xml_comment := myrec.xml_comment; schema_ver := myrec.schema_ver; end getXMLFileAttr; -- -- -- FUNCTION getPackageVersion RETURN VARCHAR2 IS version raschemaver.version%type; table_not_found EXCEPTION; PRAGMA EXCEPTION_INIT(table_not_found, -942); BEGIN if version_counter > version_max_index then version_counter := 1; return null; end if; version_counter := version_counter + 1; -- BEGIN SELECT to_char(max(version), '09') INTO version FROM raschemaver; EXCEPTION WHEN table_not_found THEN version := NULL; END; IF (version IS NULL) THEN version := '00'; END IF; -- return version_list(version_counter - 1) || '.' || version; END; FUNCTION getCatalogVersion RETURN VARCHAR2 IS version rcver.version%type; BEGIN IF NOT rcverQ%ISOPEN THEN open rcverQ; END IF; FETCH rcverQ into version; IF rcverQ%NOTFOUND THEN -- end of fetch close rcverQ; return NULL; END IF; RETURN version; END; /*---------------------------------------* * Procedures for clone database support * *---------------------------------------*/ PROCEDURE setCloneName(file# IN NUMBER ,creation_change# IN NUMBER ,new_clone_fname IN VARCHAR2 ,old_clone_fname IN VARCHAR2 ,changedauxname OUT boolean ,plugin_change# IN NUMBER DEFAULT 0) IS lfname df.clone_fname%TYPE; BEGIN deb('setCloneName: file#=' || to_char(file#)|| ', creation_fname=' || to_char(nvl(creation_change#, ''))|| ', plugin_change#=' || to_char(nvl(plugin_change#, ''))|| ', old_clone_fname=' || old_clone_fname || ', new_clone_fname=' || new_clone_fname); changedauxname := FALSE; -- -- IF (new_clone_fname = 'UNKNOWN') THEN RETURN; END IF; IF old_clone_fname is NULL THEN IF new_clone_fname = 'NONE' THEN -- RETURN; ELSE lfname := new_clone_fname; END IF; ELSE IF new_clone_fname = 'NONE' THEN lfname := NULL; ELSIF old_clone_fname = new_clone_fname THEN -- RETURN; ELSE lfname := new_clone_fname; END IF; END IF; UPDATE df SET df.clone_fname = lfname WHERE df.dbinc_key = this_dbinc_key AND df.file# = setCloneName.file# AND df.create_scn = setCloneName.creation_change# AND df.plugin_scn = setCloneName.plugin_change#; changedauxname := TRUE; deb('setCloneName - changed auxname for file# '||to_char(file#)|| ' from '||nvl(old_clone_fname, 'NULL')||' to '|| nvl(lfname, 'NULL')); EXCEPTION WHEN NO_DATA_FOUND THEN raise_application_error(-20105, 'datafile missing'); END; -- -- FUNCTION getCloneName( file# IN NUMBER ,creation_change# IN NUMBER ,plugin_change# IN NUMBER DEFAULT 0) RETURN VARCHAR2 IS ret df.clone_fname%TYPE; BEGIN -- -- ret := dbms_rcvman.getCloneName(file#, creation_change#, plugin_change#); RETURN ret; EXCEPTION WHEN NO_DATA_FOUND THEN raise_application_error(-20105, 'datafile missing'); END; /*-----------------------------------* * Procedures for RMAN configuration * *-----------------------------------*/ -- PROCEDURE setConfig(conf# IN NUMBER ,name IN VARCHAR2 ,value IN VARCHAR2) IS BEGIN IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; INSERT INTO conf( db_key, conf#, name, value, cleanup, db_unique_name, site_key) VALUES(this_db_key, conf#, name, value, 'YES', NULL, 0); EXCEPTION WHEN dup_val_on_index THEN UPDATE conf SET conf.name = name, conf.value = value WHERE conf.conf# = conf# AND conf.db_key = this_db_key; RETURN; END; -- PROCEDURE setConfig2(conf# IN NUMBER ,name IN VARCHAR2 ,value IN VARCHAR2 ,nodespec IN BOOLEAN) IS lname conf.name%TYPE; lvalue conf.value%TYPE; BEGIN IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; -- -- IF (nodespec) THEN INSERT INTO conf( db_key, conf#, name, value, cleanup, db_unique_name, site_key) VALUES(this_db_key, conf#, name, value, 'NO', this_db_unique_name, this_site_key); ELSE INSERT INTO conf( db_key, conf#, name, value, cleanup, db_unique_name, site_key) VALUES(this_db_key, conf#, name, value, 'NO', NULL, 0); END IF; deb('setConfig - Added name=(' || name || '), value=(' || value || ') to node ' || this_db_unique_name || '('|| conf# ||')'); EXCEPTION -- -- WHEN dup_val_on_index THEN select name, value into lname, lvalue from conf where conf.conf# = setConfig2.conf# AND conf.db_key = this_db_key AND db_unique_name = this_db_unique_name; IF (lname = name AND lvalue = value) THEN RETURN; END IF; deb('setConfig - lname=' || lname || ', lvalue=' || lvalue); RAISE; WHEN others THEN deb('setConfig - this_db_unique_name='||this_db_unique_name|| ', conf#='||conf#); RAISE; END; -- -- FUNCTION setConfig3(name IN VARCHAR2 ,value IN VARCHAR2 ,db_unique_name IN VARCHAR2) RETURN NUMBER IS lname conf.name%TYPE NOT NULL := name; lvalue conf.value%TYPE NOT NULL := value; ldbuname conf.db_unique_name%TYPE NOT NULL := upper(db_unique_name); lsite_key NUMBER; lconf_key NUMBER; BEGIN IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; deb('setConfig3 - Remote setConfig for '||ldbuname); SELECT site_key into lsite_key from node where node.db_unique_name = ldbuname AND node.db_key = this_db_key; deb('setConfig3 - remote_site_key='||lsite_key); -- -- INSERT INTO conf(db_key, conf#, name, value, cleanup, db_unique_name, site_key) VALUES(this_db_key, rman_seq.nextval, name, value, 'NO', ldbuname, lsite_key) RETURNING conf# INTO lconf_key; UPDATE node SET node.force_resync2cf = 'YES' WHERE node.db_key = this_db_key AND node.db_unique_name = ldbuname; commitChanges('setConfig3'); deb('setConfig3 - Added name=(' || lname || '), value=(' || lvalue || ') to node ' || ldbuname || '('|| lconf_key ||')'); RETURN lconf_key; EXCEPTION WHEN OTHERS THEN deb('setConfig3 - rollback all, release locks'); ROLLBACK; RAISE; END; -- -- PROCEDURE deleteConfig3(conf# IN NUMBER ,db_unique_name IN VARCHAR2) IS BEGIN IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; -- -- -- DELETE conf WHERE conf.db_key = this_db_key AND conf.db_unique_name = deleteConfig3.db_unique_name AND conf.conf# = deleteConfig3.conf#; IF sql%rowcount <> 1 AND sql%rowcount <> 0 THEN raise_application_error(-20999, 'Internal error in deleteConfig3, deleted rows= ' || sql%rowcount); END IF; UPDATE node SET node.force_resync2cf = 'YES' WHERE node.db_key = this_db_key AND node.db_unique_name = deleteconfig3.db_unique_name; commitChanges('deleteConfig3'); EXCEPTION WHEN OTHERS THEN deb('deleteConfig3 - rollback all, release locks'); ROLLBACK; RAISE; END; PROCEDURE resetConfig IS BEGIN IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; DELETE conf WHERE conf.db_key = this_db_key; EXCEPTION WHEN NO_DATA_FOUND THEN -- RETURN; END resetConfig; PROCEDURE resetConfig2 (nodespec IN BOOLEAN, high_conf_recid IN NUMBER DEFAULT NULL) IS BEGIN IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; -- -- -- DELETE conf WHERE conf.db_key = this_db_key AND conf.cleanup = 'YES'; -- -- -- IF (nodespec) THEN DELETE conf WHERE conf.db_key = this_db_key AND conf.db_unique_name = this_db_unique_name; ELSE -- -- -- force_resync2cf := 'YES'; DELETE conf WHERE conf.db_key = this_db_key AND conf.db_unique_name IS NULL; END IF; IF high_conf_recid IS NOT NULL THEN last_conf_recid := high_conf_recid; deb('resetConfig2 - updated last_conf_recid=' || last_conf_recid); END IF; EXCEPTION WHEN NO_DATA_FOUND THEN -- RETURN; END resetConfig2; PROCEDURE deleteConfig(conf# IN NUMBER) IS BEGIN -- -- raise_application_error(-20999, 'Internal error in deleteConfig should not be called '); END; /*-------------------------* * Catalog upgrade support * *-------------------------*/ /* NOTES: * * These procedures *must* tolerate being called *before* dbinc_key * has been set. */ /*-------------------* * Utility functions * *-------------------*/ PROCEDURE bsStatusRecalc(status IN varchar2) IS cursor bsQ(status varchar2) IS SELECT bs_key FROM bs WHERE bs.status = bsStatusRecalc.status -- AND bs.db_key = this_db_key; bsQrec bsQ%ROWTYPE; BEGIN IF this_is_ors AND this_ckp_key IS NULL THEN this_enable_populate_rsr := getValueFromConfig('_enable_populate_rsr_key'); END IF; FOR bsQrec in bsQ(status) LOOP updateBackupSetRec(bsQrec.bs_key); END LOOP; -- -- IF this_is_ors AND this_ckp_key IS NULL THEN this_enable_populate_rsr := NULL; this_upstream_site_key := NULL; END IF; END; PROCEDURE reNormalize(newname IN varchar2, oldname OUT varchar2) IS BEGIN IF newname IS NULL THEN -- initialize IF reNorm_dfatt_c%ISOPEN THEN CLOSE reNorm_dfatt_c; END IF; IF reNorm_orl_c%ISOPEN THEN CLOSE reNorm_orl_c; END IF; IF reNorm_al_c%ISOPEN THEN CLOSE reNorm_al_c; END IF; IF reNorm_bp_c%ISOPEN THEN CLOSE reNorm_bp_c; END IF; IF reNorm_ccf_c%ISOPEN THEN CLOSE reNorm_ccf_c; END IF; IF reNorm_cdf_c%ISOPEN THEN CLOSE reNorm_cdf_c; END IF; IF reNorm_tfatt_c%ISOPEN THEN CLOSE reNorm_tfatt_c; END IF; reNorm_state := RENORM_DFATT; ELSE -- update the previous row IF reNorm_state = RENORM_DFATT THEN UPDATE site_dfatt SET fname = newname WHERE CURRENT OF reNorm_dfatt_c; ELSIF reNorm_state = RENORM_ORL THEN UPDATE orl SET fname = newname WHERE CURRENT OF reNorm_orl_c; ELSIF reNorm_state = RENORM_AL THEN UPDATE al SET fname = newname, fname_hashkey = substr(newname,1,10) || substr(newname, -10) WHERE CURRENT OF reNorm_al_c; ELSIF reNorm_state = RENORM_BP THEN UPDATE bp SET handle = newname, handle_hashkey = substr(device_type,1,10) || substr(newname,1,10) || substr(newname,-10) WHERE CURRENT OF reNorm_bp_c; ELSIF reNorm_state = RENORM_CCF THEN UPDATE ccf SET fname = newname, fname_hashkey = substr(newname,1,10) || substr(newname, -10) WHERE CURRENT OF reNorm_ccf_c; ELSIF reNorm_state = RENORM_CDF THEN UPDATE cdf SET fname = newname, fname_hashkey = substr(newname,1,10) || substr(newname, -10) WHERE CURRENT OF reNorm_cdf_c; ELSIF reNorm_state = RENORM_TFATT THEN UPDATE site_tfatt SET fname = newname WHERE CURRENT OF reNorm_tfatt_c; END IF; END IF; IF reNorm_state = RENORM_DFATT THEN IF NOT reNorm_dfatt_c%ISOPEN THEN OPEN reNorm_dfatt_c; END IF; FETCH reNorm_dfatt_c INTO oldname; IF reNorm_dfatt_c%NOTFOUND THEN CLOSE reNorm_dfatt_c; reNorm_state := RENORM_ORL; END IF; END IF; IF reNorm_state = RENORM_ORL THEN IF NOT reNorm_orl_c%ISOPEN THEN OPEN reNorm_orl_c; END IF; FETCH reNorm_orl_c INTO oldname; IF reNorm_orl_c%NOTFOUND THEN CLOSE reNorm_orl_c; reNorm_state := RENORM_AL; END IF; END IF; IF reNorm_state = RENORM_AL THEN IF NOT reNorm_al_c%ISOPEN THEN OPEN reNorm_al_c; END IF; FETCH reNorm_al_c INTO oldname; IF reNorm_al_c%NOTFOUND THEN CLOSE reNorm_al_c; reNorm_state := RENORM_BP; END IF; END IF; IF reNorm_state = RENORM_BP THEN IF NOT reNorm_bp_c%ISOPEN THEN OPEN reNorm_bp_c; END IF; FETCH reNorm_bp_c INTO oldname; IF reNorm_bp_c%NOTFOUND THEN CLOSE reNorm_bp_c; reNorm_state := RENORM_CCF; END IF; END IF; IF reNorm_state = RENORM_CCF THEN IF NOT reNorm_ccf_c%ISOPEN THEN OPEN reNorm_ccf_c; END IF; FETCH reNorm_ccf_c INTO oldname; IF reNorm_ccf_c%NOTFOUND THEN CLOSE reNorm_ccf_c; reNorm_state := RENORM_CDF; END IF; END IF; IF reNorm_state = RENORM_CDF THEN IF NOT reNorm_cdf_c%ISOPEN THEN OPEN reNorm_cdf_c; END IF; FETCH reNorm_cdf_c INTO oldname; IF reNorm_cdf_c%NOTFOUND THEN CLOSE reNorm_cdf_c; reNorm_state := RENORM_TFATT; END IF; END IF; IF reNorm_state = RENORM_TFATT THEN IF NOT reNorm_tfatt_c%ISOPEN THEN OPEN reNorm_tfatt_c; END IF; FETCH reNorm_tfatt_c INTO oldname; IF reNorm_tfatt_c%NOTFOUND THEN CLOSE reNorm_tfatt_c; reNorm_state := NULL; oldname := NULL; commitChanges('reNormalize'); END IF; END IF; END reNormalize; -- -- -- -- PROCEDURE cleanupResyncedBS; PROCEDURE cleanupCKP; PROCEDURE cleanupRLH; PROCEDURE cleanupRSR; PROCEDURE cleanupBV; PROCEDURE cleanupROUT; PROCEDURE cleanupNRS; PROCEDURE cleanupDO; PROCEDURE sanityCheck IS BEGIN cleanupResyncedBS; cleanupCKP; cleanupRLH; cleanupRSR; cleanupBV; cleanupROUT; cleanupNRS; cleanupDO; END sanityCheck; PROCEDURE cleanupDO IS start_time DATE := sysdate; BEGIN -- DELETE deleted_object WHERE db_key = this_db_key AND create_time < start_time - 30; deb('cleanupDO - deleted ' || sql%rowcount || ' rows from deleted_object'); deb('cleanupDO - took ' || ((sysdate - start_time) * 86400) || ' seconds'); END cleanupDO; PROCEDURE cleanupResyncedBS IS cnt number; BEGIN -- -- -- -- deb('cleanupResyncedBS - cntbs='||cntbs); IF cntbs is NULL THEN raise_application_error(-20107, 'invalid bskey counter'); END IF; FOR i IN 1 .. cntbs LOOP SELECT count(*) into cnt from bs where bs_key = updatebs(i); IF cnt > 0 THEN deb('cleanupResyncedBS - updating bs_key='||updatebs(i)); updateBackupSetRec(updatebs(i)); END IF; END LOOP; cntbs := 0; END cleanupResyncedBS; PROCEDURE cleanupCKP IS scn NUMBER; seq NUMBER; keep_ckp_key_1 NUMBER; keep_ckp_key_2 NUMBER; start_time DATE := sysdate; BEGIN -- -- -- -- IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; dbms_rcvman.getCheckpoint(scn, seq, keep_ckp_key_1, keep_ckp_key_2); deb('cleanupCKP - scn=' || scn); deb('cleanupCKP - seq=' || seq); deb('cleanupCKP - keep_ckp_key_1=' || keep_ckp_key_1); deb('cleanupCKP - keep_ckp_key_2=' || keep_ckp_key_2); -- -- -- delete from ckp where dbinc_key = this_dbinc_key and ckp_key in (select ckp_key1 from (select ckp_key ckp_key1 from ckp where dbinc_key = this_dbinc_key) ckp1, (select keep_ckp_key_1 ckp_key2 from dual union select keep_ckp_key_2 from dual union select nvl(max(ckp_key),0) from ckp where dbinc_key=this_dbinc_key union select start_ckp_key from tsatt where dbinc_key = this_dbinc_key union select nvl(end_ckp_key,0) from tsatt where dbinc_key = this_dbinc_key) ckp2 where ckp_key1 = ckp_key2(+) and ckp_key2 is null) and site_key = this_site_key; deb('cleanupCKP - deleted ' || sql%rowcount || ' rows from ckp table'); deb('cleanupCKP - took ' || ((sysdate - start_time) * 86400) || ' seconds'); END cleanupCKP; PROCEDURE cleanupRLH IS oldscn NUMBER; start_time DATE := sysdate; BEGIN -- -- -- -- -- IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; SELECT nvl(min(scn),power(2,64)-1) INTO oldscn FROM ( SELECT min(brl.low_scn) scn FROM brl WHERE brl.dbinc_key = this_dbinc_key UNION SELECT min(al.low_scn) FROM al WHERE al.dbinc_key = this_dbinc_key UNION SELECT min(xal.low_scn) FROM xal WHERE xal.dbinc_key = this_dbinc_key UNION SELECT min(bdf.ckp_scn) FROM bdf WHERE bdf.dbinc_key = this_dbinc_key UNION SELECT min(cdf.ckp_scn) FROM cdf WHERE cdf.dbinc_key = this_dbinc_key UNION SELECT min(xdf.ckp_scn) FROM xdf WHERE xdf.dbinc_key = this_dbinc_key UNION SELECT min(bcf.ckp_scn) FROM bcf WHERE bcf.dbinc_key = this_dbinc_key UNION SELECT min(ccf.ckp_scn) FROM ccf WHERE ccf.dbinc_key = this_dbinc_key UNION SELECT min(xcf.ckp_scn) FROM xcf WHERE xcf.dbinc_key = this_dbinc_key ); deb('cleanupRLH - scn='||oldscn); DELETE FROM rlh WHERE rlh.dbinc_key = this_dbinc_key AND low_scn < oldscn; deb('cleanupRLH - deleted ' || sql%rowcount || ' rows from rlh table'); deb('cleanupRLH - took ' || ((sysdate - start_time) * 86400) || ' seconds'); END cleanupRLH; PROCEDURE cleanupBV IS start_time DATE := sysdate; BEGIN -- -- -- DELETE FROM bs WHERE db_key = this_db_key AND ((input_file_scan_only='YES' AND SYSDATE - completion_time >= 60) OR (nvl(input_file_scan_only,'NO')='NO' AND status='D')) AND NOT EXISTS (SELECT 1 FROM bp WHERE bp.bs_key = bs.bs_key); deb('cleanupBV - deleted ' || sql%rowcount || ' rows from bs table'); deb('cleanupBV - took ' || ((sysdate - start_time) * 86400) || ' seconds'); END cleanupBV; FUNCTION getDbid RETURN NUMBER IS dbid NUMBER; BEGIN SELECT db.db_id INTO dbid FROM db WHERE db_key = this_db_key AND curr_dbinc_key = this_dbinc_key; RETURN dbid; EXCEPTION WHEN no_data_found THEN raise_application_error(-20001, 'Database not found'); END getDbid; FUNCTION beginIncarnationResync(return_Recid in boolean DEFAULT FALSE) RETURN NUMBER IS local_kccdivts number; BEGIN checkResync; IF return_Recid THEN IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN SELECT high_ic_recid INTO last_ic_recid FROM node WHERE site_key = this_site_key; ELSE last_ic_recid := sessionWaterMarks.high_ic_recid; END IF; RETURN last_ic_recid; ELSE IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN SELECT last_kccdivts INTO local_kccdivts FROM node WHERE site_key = this_site_key; ELSE local_kccdivts := 0; END IF; IF (local_kccdivts IS NULL) THEN local_kccdivts := 0; END IF; RETURN local_kccdivts; END IF; END beginIncarnationResync; -- -- -- FUNCTION checkIncarnation(reset_scn IN NUMBER, reset_time IN DATE, prior_reset_scn IN NUMBER DEFAULT NULL, prior_reset_time IN DATE DEFAULT NULL, db_name IN VARCHAR2 DEFAULT 'UNKNOWN') RETURN NUMBER IS local dbinc%rowtype; prior_dbinc_key number := NULL; d_name VARCHAR2(8); BEGIN BEGIN SELECT dbinc_key, parent_dbinc_key, db_name INTO local.dbinc_key, local.parent_dbinc_key, local.db_name FROM dbinc WHERE dbinc.db_key = this_db_key AND dbinc.reset_scn = checkIncarnation.reset_scn AND dbinc.reset_time = checkIncarnation.reset_time; EXCEPTION WHEN no_data_found THEN local.dbinc_key := NULL; local.parent_dbinc_key := NULL; local.db_name := 'UNKNOWN'; END; IF (local.parent_dbinc_key IS NULL AND checkIncarnation.prior_reset_scn IS NOT NULL) THEN BEGIN SELECT dbinc_key INTO prior_dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key AND dbinc.reset_scn = checkIncarnation.prior_reset_scn AND dbinc.reset_time = checkIncarnation.prior_reset_time; EXCEPTION WHEN no_data_found THEN prior_dbinc_key := NULL; END; END IF; IF (local.dbinc_key IS NOT NULL) THEN -- IF (local.parent_dbinc_key IS NULL AND prior_dbinc_key IS NOT NULL) THEN UPDATE dbinc SET parent_dbinc_key = prior_dbinc_key WHERE dbinc.dbinc_key = local.dbinc_key; END IF; -- IF (local.db_name != 'UNKNOWN' AND checkIncarnation.db_name != 'UNKNOWN') THEN UPDATE dbinc SET db_name = checkIncarnation.db_name WHERE dbinc.dbinc_key = local.dbinc_key; END IF; RETURN local.dbinc_key; END IF; IF (this_lock_ors_inspect) THEN -- -- deb('checkincarnation:server_error for db_key='||this_db_key); EXECUTE IMMEDIATE 'BEGIN dbms_ra_scheduler.log_error( p_component => ''INSPECT'', p_severity => dbms_ra_scheduler.SEVERITY_WARNING, p_db_key => :1, p_keep_stack => TRUE, p_errno => dbms_ra_scheduler.E_NEW_INC_ERROR_NUM); END;' USING this_db_key ; END IF; -- BEGIN -- d_name := checkIncarnation.db_name; IF (d_name = 'UNKNOWN') THEN BEGIN SELECT db_name INTO d_name FROM db, dbinc WHERE dbinc.db_key = this_db_key AND db.curr_dbinc_key = dbinc.dbinc_key; EXCEPTION WHEN no_data_found THEN deb('database name not set'); d_name := checkIncarnation.db_name; END; END IF; INSERT INTO dbinc (dbinc_key, db_key, db_name, reset_scn, reset_time, parent_dbinc_key) VALUES (rman_seq.nextval, this_db_key, upper(d_name), checkIncarnation.reset_scn,checkIncarnation.reset_time, prior_dbinc_key) RETURNING dbinc_key INTO local.dbinc_key; EXCEPTION WHEN dup_val_on_index THEN raise_application_error(-20009, 'Db incarnation already registered'); END; inheritPdbInc( this_db_key, local.dbinc_key, reset_scn, prior_dbinc_key); RETURN local.dbinc_key; END checkIncarnation; PROCEDURE endIncarnationResync(high_kccdivts IN NUMBER, high_ic_recid IN NUMBER DEFAULT 0) IS BEGIN -- -- IF (last_ic_recid IS NOT NULL) THEN IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN -- UPDATE node SET high_ic_recid = endIncarnationResync.high_ic_recid, last_kccdivts = endIncarnationResync.high_kccdivts WHERE site_key = this_site_key; END IF; sessionWaterMarks.high_ic_recid := high_ic_recid; last_ic_recid := NULL; ELSE IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN UPDATE node SET last_kccdivts = high_kccdivts WHERE site_key = this_site_key; END IF; END IF; -- recomputeDbincStatus(this_db_key, this_dbinc_key); -- -- IF NOT this_lock_ors_inspect THEN this_clr_ba_newinc_err := TRUE; END IF; END endIncarnationResync; /*--------------------------------* * Pluggable DB Incaration Resync * *--------------------------------*/ PROCEDURE fetchPic IS -- this is private to the pkg body BEGIN FETCH picQ INTO picRec; -- get next row IF picQ%NOTFOUND THEN picRec := NULL; picRec.guid := NULL; -- indicate end of fetch CLOSE picQ; ELSE deb('fetchPic - '||picRec.con_id||'('||to_char(picRec.con_id)||') '|| to_char(picRec.pdbinc_key)); END IF; END fetchPic; FUNCTION beginPluggableDbincResync RETURN NUMBER IS BEGIN checkResync; IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN SELECT high_pic_recid INTO last_pic_recid FROM node WHERE site_key = this_site_key; ELSE last_pic_recid := sessionWaterMarks.high_pic_recid; END IF; IF (picQ%ISOPEN) THEN CLOSE picQ; END IF; OPEN picQ; -- just open that cursor please fetchPic; -- do priming read RETURN last_pic_recid; END beginPluggableDbincResync; PROCEDURE checkPluggableDbinc( recid IN NUMBER ,guid IN RAW ,curr_pdbinc IN VARCHAR2 ,inc_scn IN NUMBER ,begin_reset_scn IN NUMBER ,begin_reset_time IN DATE ,end_reset_scn IN NUMBER ,db_reset_scn IN NUMBER ,db_reset_time IN DATE ,pr_inc_scn IN NUMBER ,pr_end_reset_scn IN NUMBER ,pr_db_reset_scn IN NUMBER ,pr_db_reset_time IN DATE ,chk_last_recid IN BOOLEAN ) IS local_pdb_key number; local_pdbinc_key number; local_pr_pdbinc_key number; born_dbinc_key number; pr_born_dbinc_key number; pr_pdbinc_key number; BEGIN IF (chk_last_recid) THEN IF (last_pic_recid IS NULL) THEN raise_application_error(-20037, 'Invalid last recid'); END IF; -- -- -- -- last_pic_recid := recid; END IF; IF (end_reset_scn = 0) THEN deb('checkPluggableDbinc - skipping partial record'); RETURN; END IF; -- WHILE (guid > picRec.guid) LOOP fetchPic; END LOOP; -- WHILE (guid = picRec.guid AND (begin_reset_scn > picRec.begin_reset_scn OR begin_reset_time > picRec.begin_reset_time OR end_reset_scn > picRec.end_reset_scn)) LOOP fetchPic; END LOOP; -- IF (guid = picRec.guid AND begin_reset_scn = picRec.begin_reset_scn AND begin_reset_time = picRec.begin_reset_time AND end_reset_scn = picRec.end_reset_scn) THEN deb('checkPluggableDbinc - pdbinc already known'); -- local_pdb_key := picRec.pdb_key; local_pdbinc_key := picRec.pdbinc_key; local_pr_pdbinc_key := picRec.parent_pdbinc_key; END IF; IF (local_pr_pdbinc_key IS NULL) THEN -- IF (local_pdb_key IS NULL) THEN local_pdb_key := guidToPdbKey(checkPluggableDbinc.guid, 0); deb('checkPluggableDbinc - pdb_key=' || local_pdb_key); END IF; IF (pr_db_reset_scn = 0 OR pr_end_reset_scn = 0) THEN pr_pdbinc_key := NULL; deb('checkPluggableDbinc - no parent_pdbinc_key'); ELSE -- pr_born_dbinc_key := checkIncarnation(pr_db_reset_scn, pr_db_reset_time); deb('checkPluggableDbinc - pr_born_dbinc_key=' || pr_born_dbinc_key); BEGIN SELECT pdbinc_key INTO pr_pdbinc_key FROM pdbinc WHERE pdbinc.born_dbinc_key = pr_born_dbinc_key AND pdbinc.pdb_key = local_pdb_key AND pdbinc.end_reset_scn = pr_end_reset_scn; EXCEPTION WHEN no_data_found THEN pr_pdbinc_key := NULL; END; deb('checkPluggableDbinc - parent_pdbinc_key=' || pr_pdbinc_key); END IF; END IF; IF (local_pdbinc_key IS NULL) THEN born_dbinc_key := checkIncarnation(db_reset_scn, db_reset_time); deb('checkPluggableDbinc - born_dbinc_key=' || born_dbinc_key); -- INSERT INTO pdbinc (pdbinc_key, pdb_key, born_dbinc_key, inc_scn, begin_reset_scn, begin_reset_time, end_reset_scn, parent_pdbinc_key) VALUES (rman_seq.nextval, local_pdb_key, born_dbinc_key, inc_scn, begin_reset_scn, begin_reset_time, end_reset_scn, pr_pdbinc_key) RETURNING pdbinc_key INTO local_pdbinc_key; ELSE IF (local_pr_pdbinc_key IS NULL AND pr_pdbinc_key IS NOT NULL) THEN UPDATE pdbinc SET parent_pdbinc_key = pr_pdbinc_key WHERE pdbinc_key = local_pdbinc_key; END IF; END IF; IF (curr_pdbinc = 'YES') THEN UPDATE pdb_dbinc SET curr_pdbinc_key = local_pdbinc_key, drop_scn = NULL WHERE dbinc_key = this_dbinc_key AND pdb_key = local_pdb_key; IF (sql%rowcount = 0) THEN INSERT INTO pdb_dbinc (dbinc_key, pdb_key, drop_scn, drop_time, curr_pdbinc_key) VALUES (this_dbinc_key, local_pdb_key, NULL, NULL, local_pdbinc_key); END IF; END IF; END checkPluggableDbinc; PROCEDURE endPluggableDbincResync(high_pic_recid IN NUMBER) IS BEGIN IF (last_pic_recid IS NOT NULL) THEN IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN UPDATE node SET high_pic_recid = endPluggableDbincResync.high_pic_recid WHERE site_key = this_site_key; END IF; sessionWaterMarks.high_pic_recid := high_pic_recid; last_pic_recid := NULL; END IF; -- recomputePluggableDbincStatus(this_dbinc_key); IF (picQ%ISOPEN) THEN picRec.guid := NULL; -- indicate end of fetch CLOSE picQ; END IF; END endPluggableDbincResync; /*-----------------------------* * Normal restore point Resync * *-----------------------------*/ FUNCTION beginRestorePointResync RETURN NUMBER IS BEGIN checkResync; IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN SELECT high_nrsp_recid INTO last_nrsp_recid FROM node WHERE site_key = this_site_key; ELSE last_nrsp_recid := sessionWaterMarks.high_nrsp_recid; END IF; RETURN last_nrsp_recid; END beginRestorePointResync; PROCEDURE checkRestorePoint( nrsp_recid IN NUMBER ,nrsp_stamp IN NUMBER ,nrsp_name IN VARCHAR2 ,reset_scn IN NUMBER ,reset_time IN DATE ,to_scn IN NUMBER ,nrsp_time IN DATE ,create_time IN DATE ,deleted IN NUMBER ,con_id IN NUMBER DEFAULT NULL ,clean IN VARCHAR2 DEFAULT 'NO' ) IS my_dbinc_key NUMBER; inscheck NUMBER; local_pdb_key NUMBER; BEGIN IF (last_nrsp_recid IS NULL) THEN raise_application_error(-20037, 'Invalid last recid'); END IF; IF (nrsp_recid < last_nrsp_recid) THEN raise_application_error(-20036, 'Invalid record order'); END IF; IF (nrsp_recid > last_nrsp_recid + 1) THEN -- -- NULL; END IF; last_nrsp_recid := nrsp_recid; IF (this_dbinc_key IS NULL) THEN raise_application_error(-20020, 'Database incarnation not set'); END IF; IF (nrsp_stamp > 0 and nrsp_stamp < kccdivts) THEN deb('checkRestorePoint - ignoring record kccdivts='||kccdivts); RETURN; -- obsolete record from a backup controlfile END IF; -- my_dbinc_key := checkIncarnation(reset_scn, reset_time); -- -- SELECT pdb.pdb_key INTO local_pdb_key FROM pdb, pdb_dbinc WHERE pdb_dbinc.drop_scn IS NULL AND pdb.con_id IN (checkRestorePoint.con_id, 0, decode(checkRestorePoint.con_id, 0, 1)) AND pdb.pdb_key = pdb_dbinc.pdb_key AND pdb_dbinc.dbinc_key = this_dbinc_key; -- IF (deleted = 1) THEN DELETE nrsp WHERE checkRestorePoint.nrsp_recid = nrsp_recid AND checkRestorePoint.nrsp_stamp = nrsp_stamp AND my_dbinc_key = nrsp.dbinc_key AND this_site_key = site_key; ELSE -- -- DELETE nrsp WHERE this_site_key = nrsp.site_key AND local_pdb_key = nrsp.pdb_key AND checkRestorePoint.nrsp_name = nrsp.rspname; IF SQL%ROWCOUNT > 0 THEN deb('checkRestorePoint:deleted duplicate restore point:' || checkRestorePoint.nrsp_name); END IF; INSERT INTO nrsp (nrsp_recid ,nrsp_stamp ,rspname ,dbinc_key ,site_key ,to_scn ,rsptime ,creation_time ,long_term ,pdb_key ,clean) VALUES (checkRestorePoint.nrsp_recid ,checkRestorePoint.nrsp_stamp ,checkRestorePoint.nrsp_name ,my_dbinc_key ,this_site_key ,checkRestorePoint.to_scn ,checkRestorePoint.nrsp_time ,checkRestorePoint.create_time ,NULL -- UNKNOWN: cleanupNRS will reset to YES/NO ,local_pdb_key ,clean); END IF; EXCEPTION WHEN dup_val_on_index THEN deb('checkRestorePoint - Inside dup_val_on_index exception for' || ' recid ' || checkRestorePoint.nrsp_recid || ' stamp ' || checkRestorePoint.nrsp_stamp); SELECT min(nrsp.nrsp_recid) INTO inscheck FROM nrsp WHERE nrsp.nrsp_recid = checkRestorePoint.nrsp_recid AND nrsp.nrsp_stamp = checkRestorePoint.nrsp_stamp AND nrsp.dbinc_key = my_dbinc_key AND nrsp.site_key = this_site_key AND nrsp.rspname = checkRestorePoint.nrsp_name AND nrsp.to_scn = checkRestorePoint.to_scn AND nrsp.pdb_key = local_pdb_key; IF inscheck IS NULL THEN -- Some internal error to indicate no match raise_application_error(-20999, 'internal error: no match for restore point'); END IF; RETURN; WHEN others THEN RAISE; END checkRestorePoint; PROCEDURE endRestorePointResync(lowrecid IN number) IS lowscn number; BEGIN -- IF (lowrecid = 0) THEN low_nrsp_recid := NULL; ELSE low_nrsp_recid := lowrecid; END IF; -- IF (this_cf_type = 'CURRENT' OR (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN UPDATE node SET high_nrsp_recid = last_nrsp_recid WHERE site_key = this_site_key; END IF; sessionWaterMarks.high_nrsp_recid := last_nrsp_recid; last_nrsp_recid := NULL; END endRestorePointResync; PROCEDURE listScriptNames(glob IN number, allnames IN number) IS lglob number := NULL; lalln number := NULL; BEGIN deb('listScriptNames - List script Names called with glob: '|| nvl(to_char(glob), 'NULL')||'and allnames: '|| nvl(to_char(allnames), 'NULL')); IF glob = 1 then lglob := 1; END IF; IF allnames = 1 then lalln := 1; END IF; IF lscrnames_c%ISOPEN THEN deb('listScriptNames - Closing lscrnames_c cursor'); CLOSE lscrnames_c; END IF; deb('listScriptNames - Opening lscrnames_c cursor'); OPEN lscrnames_c(lglob, lalln); END listScriptNames; PROCEDURE getScriptNames(dbname OUT varchar2, scnm OUT varchar2, sccom OUT varchar2) IS ldum number := NULL; BEGIN IF NOT lscrnames_c%ISOPEN THEN raise_application_error(-20403, 'listScriptNames not done'); END IF; deb('getScriptNames - Fetching lscrnames_c cursor'); FETCH lscrnames_c INTO ldum, dbname, scnm, sccom; IF lscrnames_c%NOTFOUND THEN deb('getScriptNames - Closing lscrnames_c cursor'); CLOSE lscrnames_c; raise no_data_found; END IF; END getScriptNames; -- -- PROCEDURE cleanupRSR IS nowTime date; BEGIN SELECT SYSDATE INTO nowTime from dual; IF (this_dbinc_key IS NULL) THEN raise_application_error(-20020, 'Database incarnation not set'); END IF; -- -- -- -- DELETE FROM rsr WHERE rsr_end < nowTime-60 AND rsr.dbinc_key IN (select dbinc_key from dbinc where dbinc.db_key = this_db_key); deb('cleanupRSR - deleted ' || sql%rowcount || ' rows from rsr table'); deb('cleanupRSR - took ' || ((sysdate - nowTime) * 86400) || ' seconds'); END cleanupRSR; -- -- PROCEDURE cleanupROUT IS start_time date; high_stamp number; high_session_key number; days number; BEGIN IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; IF session_keep_output IS NULL THEN getRmanOutputLogging(days); deb('cleanupROUT - keep output is configured to ' || days); ELSIF session_keep_output = 0 THEN deb('cleanupROUT - session keep output is set to 0, not cleaning up'); return; ELSE days := session_keep_output; deb('cleanupROUT - session keep output is set to ' || days); END IF; start_time := SYSDATE; high_stamp := date2stamp(start_time-days); SELECT max(rsr_key) into high_session_key FROM rsr, dbinc WHERE dbinc.db_key = this_db_key AND rsr.dbinc_key = dbinc.dbinc_key AND rsr.site_key = this_site_key AND rsr.rsr_stamp < high_stamp; deb('cleanupROUT select took ' || ((sysdate - start_time) * 86400) || ' seconds'); -- If high_session_key IS NOT NULL THEN DELETE FROM rout WHERE db_key = this_db_key AND (site_key IS NULL) or (site_key = this_site_key) AND rout_skey <= high_session_key; deb('cleanupROUT deleted ' || sql%rowcount || ' rows from rout table'); END IF; deb('cleanupROUT took ' || ((sysdate - start_time) * 86400) || ' seconds'); END cleanupROUT; -- PROCEDURE cleanupNRS IS start_time date; BEGIN deb('cleanupNRS - low_nrsp_recid is ' || NVL(TO_CHAR(low_nrsp_recid), 'NULL')); start_time := SYSDATE; -- -- -- -- -- -- -- -- -- -- -- -- UPDATE nrsp SET LONG_TERM = 'YES' WHERE long_term IS NULL AND this_site_key = site_key AND nrsp_recid in (SELECT nrsp.nrsp_recid FROM bs, brl, nrsp WHERE bs.bs_key = brl.bs_key AND bs.keep_options > 0 AND brl.low_scn <= nrsp.to_scn AND brl.next_scn > nrsp.to_scn AND this_site_key = bs.site_key AND this_site_key = nrsp.site_key UNION SELECT nrsp.nrsp_recid FROM xal, nrsp WHERE xal.keep_options > 0 AND xal.low_scn <= nrsp.to_scn AND xal.next_scn > nrsp.to_scn AND this_site_key = xal.site_key AND this_site_key = nrsp.site_key UNION SELECT nrsp_recid FROM bs, bdf, nrsp WHERE bs.bs_key = bdf.bs_key AND bs.keep_options > 0 AND bdf.ckp_scn = nrsp.to_scn+1 AND this_site_key = bs.site_key AND this_site_key = nrsp.site_key UNION SELECT nrsp_recid FROM xdf, nrsp WHERE xdf.keep_options > 0 AND xdf.ckp_scn = nrsp.to_scn+1 AND this_site_key = xdf.site_key AND this_site_key = nrsp.site_key); deb('cleanupNRS - updated ' || sql%rowcount || ' rows to LONG_TERM = YES'); -- UPDATE nrsp SET LONG_TERM = 'NO' WHERE long_term IS NULL AND this_site_key = site_key; deb('cleanupNRS - updated ' || sql%rowcount || ' rows to LONG_TERM = NO'); -- -- DELETE nrsp WHERE nrsp_recid < low_nrsp_recid AND long_term = 'NO' AND site_key = this_site_key; low_nrsp_recid := NULL; deb('cleanupNRS - deleted ' || sql%rowcount || ' rows from nrsp table'); deb('cleanupNRS - took ' || ((sysdate - start_time) * 86400) || ' seconds'); END; PROCEDURE updateOldestFlashbackSCN ( oldest_flashback_scn IN NUMBER -- obsolete column ,oldest_flashback_time IN DATE DEFAULT NULL ) IS tmp NUMBER; BEGIN deb('updateOldestFlashbackSCN - guaranteed_flashback_scn=' || nvl(to_char(oldest_flashback_scn), 'NULL') || ' flashback_time=' || nvl(to_char(oldest_flashback_time), 'NULL')); -- IF (oldest_flashback_scn IS NULL AND oldest_flashback_time IS NULL) THEN DELETE FROM fb WHERE db_unique_name = this_db_unique_name AND dbinc_key = this_dbinc_key; RETURN; END IF; BEGIN SELECT 0 INTO tmp FROM fb WHERE db_unique_name = this_db_unique_name AND dbinc_key = this_dbinc_key; EXCEPTION WHEN no_data_found THEN INSERT INTO fb (dbinc_key, db_unique_name, oldest_flashback_scn, oldest_flashback_time) VALUES (this_dbinc_key, this_db_unique_name, oldest_flashback_scn, oldest_flashback_time); RETURN; WHEN others THEN RAISE; END; UPDATE fb SET oldest_flashback_scn = updateOldestFlashbackSCN.oldest_flashback_scn, oldest_flashback_time = updateOldestFlashbackSCN.oldest_flashback_time WHERE db_unique_name = this_db_unique_name AND dbinc_key = this_dbinc_key; END updateOldestFlashbackSCN; FUNCTION getDbinc RETURN NUMBER IS BEGIN IF (this_dbinc_key IS NULL) THEN raise_application_error(-20020, 'Database incarnation not set'); END IF; RETURN this_dbinc_key; END getDbinc; -- -- -- FUNCTION isDuplicateRecord(recid IN NUMBER ,stamp IN NUMBER ,type IN VARCHAR2) RETURN BOOLEAN IS rec_count NUMBER; BEGIN checkResync; IF (type = 'AL') THEN SELECT count(*) INTO rec_count FROM al, dbinc WHERE dbinc.db_key = this_db_key AND al.dbinc_key = dbinc.dbinc_key AND isDuplicateRecord.recid = al.al_recid AND isDuplicateRecord.stamp = al.al_stamp AND al.site_key = this_site_key; ELSIF (type = 'BP') THEN SELECT count(*) INTO rec_count FROM bp WHERE bp.db_key = this_db_key AND isDuplicateRecord.recid = bp.bp_recid AND isDuplicateRecord.stamp = bp.bp_stamp AND bp.site_key = this_site_key; ELSIF (type = 'DC') THEN SELECT count(*) INTO rec_count FROM cdf, dbinc WHERE dbinc.db_key = this_db_key AND cdf.dbinc_key = dbinc.dbinc_key AND isDuplicateRecord.recid = cdf.cdf_recid AND isDuplicateRecord.stamp = cdf.cdf_stamp AND cdf.site_key = this_site_key; IF (rec_count = 0) THEN SELECT count(*) INTO rec_count FROM ccf, dbinc WHERE dbinc.db_key = this_db_key AND ccf.dbinc_key = dbinc.dbinc_key AND isDuplicateRecord.recid = ccf.ccf_recid AND isDuplicateRecord.stamp = ccf.ccf_stamp AND ccf.site_key = this_site_key; END IF; ELSE raise_application_error(-20999, 'Internal error in isDuplicateRecord(): bad type '|| type); END IF; IF rec_count > 0 THEN RETURN TRUE; ELSE RETURN FALSE; END IF; END isDuplicateRecord; -- -- -- -- -- -- FUNCTION doDuplicateMining RETURN BOOLEAN IS last_recid number; BEGIN checkResync; IF (this_cf_type != 'CURRENT' and this_cf_type != 'STANDBY') THEN RETURN TRUE; END IF; -- -- IF (this_cf_type = 'STANDBY' and this_db_unique_name is NULL) THEN RETURN TRUE; END IF; -- -- -- SELECT high_rlh_recid INTO last_recid FROM node WHERE site_key = this_site_key; IF (last_recid = 0) THEN deb('doDuplicateMining returns TRUE'); RETURN TRUE; ELSE RETURN FALSE; END IF; END doDuplicateMining; -- FUNCTION isRoutDuplicateRecord(recid IN NUMBER ,stamp IN NUMBER ,session_recid IN NUMBER ,session_stamp IN NUMBER ,rman_status_recid IN NUMBER ,rman_status_stamp IN NUMBER) RETURN BOOLEAN IS lrsrkey NUMBER; lroutskey NUMBER; rec_count NUMBER; BEGIN checkResync; deb('isRoutDuplicateRecord - Find rsr_ key'); BEGIN select rsr_key into lrsrkey from rsr, dbinc where rsr.dbinc_key = dbinc.dbinc_key and dbinc.db_key = this_db_key and dbinc.dbinc_key = this_dbinc_key and ((rsr.site_key = this_site_key) or (rsr.site_key is null AND this_site_key is null)) and rsr.rsr_recid = rman_status_recid and rsr.rsr_stamp = rman_status_stamp; EXCEPTION WHEN no_data_found THEN -- deb('isRoutDuplicateRecord - ignoring following RMAN output row'); RETURN FALSE; END; deb('isRoutDuplicateRecord - Find session key'); BEGIN -- -- -- -- -- select rsr_key into lroutskey from rsr, dbinc where rsr.dbinc_key = dbinc.dbinc_key and dbinc.db_key = this_db_key and (rsr.site_key = this_site_key or rsr.site_key is null AND this_site_key is null) and rsr.rsr_srecid = session_recid and rsr.rsr_sstamp = session_stamp and rsr.rsr_type = 'SESSION'; EXCEPTION WHEN no_data_found THEN -- deb('isRoutDuplicateRecord -ignoring following RMAN output row, cause2'); RETURN FALSE; WHEN others THEN deb('isRoutDuplicateRecord(DO_NOT_IGNORE) - signal err'); RETURN FALSE; END; -- SELECT count(*) INTO rec_count FROM rout, db WHERE db.db_key = this_db_key AND rout.rout_recid = isRoutDuplicateRecord.recid AND rout.rout_stamp = isRoutDuplicateRecord.stamp AND rout.rsr_key = lrsrkey AND rout.rout_skey = lroutskey AND rout.site_key = this_site_key; IF rec_count > 0 THEN deb('isRoutDuplicateRecord - Return TRUE'); RETURN TRUE; ELSE deb('isRoutDuplicateRecord - Return FALSE'); RETURN FALSE; END IF; END isRoutDuplicateRecord; PROCEDURE unregisterSite(db_unique_name IN VARCHAR2, incbcks IN BINARY_INTEGER ) IS lsite_key number; new_ckp_site_key number; cnt number := 0; db_role node.database_role%TYPE; BEGIN deb('unregisterSite - remove meta-data for node '|| db_unique_name); IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; -- IF this_db_unique_name = upper(db_unique_name) THEN raise_application_error(-20244, db_unique_name || ' can not unregister connected target database'); END IF; -- BEGIN select site_key, database_role into lsite_key, db_role from node where node.db_unique_name = upper(unregisterSite.db_unique_name) and node.db_key = this_db_key; EXCEPTION WHEN no_data_found THEN raise_application_error( -20243, upper(unregisterSite.db_unique_name) || ' db_unique_name unknown to recovery catalog:'); END; lockForCkpt; -- -- select count(*) into cnt from bp where bp.site_key = lsite_key and bp.ba_access != 'U'; IF (cnt <> 0) THEN cancelCkpt; raise_application_error(-20301, 'Cannot unregister database'); END IF; -- -- -- -- select site_key into new_ckp_site_key from (select site_key from node where db_key=this_db_key and site_key <> lsite_key order by database_role) where rownum = 1; IF new_ckp_site_key is not null THEN update ckp set site_key = new_ckp_site_key where site_key = lsite_key and ckp_type = 'FULL' and ckp_key in (select start_ckp_key from tsatt where dbinc_key in (select dbinc_key from dbinc where db_key=this_db_key) union select end_ckp_key from tsatt where dbinc_key in (select dbinc_key from dbinc where db_key=this_db_key)); deb('updated ' || sql%rowcount || ' rows in ckp, site_key to ' || new_ckp_site_key); END IF; -- IF incbcks <> 0 THEN delete bp WHERE site_key = lsite_key; deb('deleted ' || sql%rowcount || ' rows from bp table'); delete bs WHERE site_key = lsite_key; deb('deleted ' || sql%rowcount || ' rows from bs table'); delete ccf WHERE site_key = lsite_key; deb('deleted ' || sql%rowcount || ' rows from ccf table'); delete xcf WHERE site_key = lsite_key; deb('deleted ' || sql%rowcount || ' rows from xcf table'); delete cdf WHERE site_key = lsite_key; deb('deleted ' || sql%rowcount || ' rows from cdf table'); delete xdf WHERE site_key = lsite_key; deb('deleted ' || sql%rowcount || ' rows from xdf table'); delete xal WHERE site_key = lsite_key; deb('deleted ' || sql%rowcount || ' rows from xal table'); ELSE update bp set site_key = NULL WHERE site_key = lsite_key; deb('updated ' || sql%rowcount || ' rows from bp table'); update bs set site_key = NULL WHERE site_key = lsite_key; deb('updated ' || sql%rowcount || ' rows from bs table'); update ccf set site_key = NULL WHERE site_key = lsite_key; deb('updated ' || sql%rowcount || ' rows from ccf table'); update xcf set site_key = NULL WHERE site_key = lsite_key; deb('updated ' || sql%rowcount || ' rows from xcf table'); update cdf set site_key = NULL WHERE site_key = lsite_key; deb('updated ' || sql%rowcount || ' rows from cdf table'); update xdf set site_key = NULL WHERE site_key = lsite_key; deb('updated ' || sql%rowcount || ' rows from xdf table'); update xal set site_key = NULL WHERE site_key = lsite_key; deb('updated ' || sql%rowcount || ' rows from xal table'); END IF; -- delete node where site_key = lsite_key; deb('deleted ' || sql%rowcount || ' rows from node table'); delete fb where db_unique_name = unregisterSite.db_unique_name and dbinc_key in (select dbinc_key from dbinc where db_key = this_db_key); deb('deleted ' || sql%rowcount || ' rows from fb table'); UPDATE db SET reg_db_unique_name = (SELECT max(db_unique_name) FROM (SELECT db_unique_name FROM node, db WHERE node.db_key = this_db_key AND node.db_unique_name <> unRegisterSite.db_unique_name AND node.db_unique_name <> db.reg_db_unique_name AND node.db_unique_name NOT LIKE '%$%' AND node.database_role IN ('PRIMARY','STANDBY') ORDER BY node.database_role, node.db_unique_name) WHERE ROWNUM =1) WHERE db_key = this_db_key AND reg_db_unique_name = unregisterSite.db_unique_name; -- -- -- delete conf where name = 'DB_UNIQUE_NAME' and db_key = this_db_key and upper(unregisterSite.db_unique_name) = upper(substr(value, 2, instr(substr(value, 2, 32), substr(value, 1,1))-1)) and db_unique_name is null; deb('deleted ' || sql%rowcount || ' rows from conf table(2)'); -- -- if sql%rowcount <> 0 then update node set force_resync2cf = 'YES' where db_key = this_db_key; end if; -- delete conf where site_key = lsite_key; deb('deleted ' || sql%rowcount || ' rows from conf table (site rows)'); commitChanges('unregisterSite'); END unregisterSite; -- PROCEDURE renameSite(from_db_unique_name IN VARCHAR2, to_db_unique_name IN VARCHAR2) IS rec_count NUMBER; my_dbinc_key NUMBER; BEGIN deb('renameSite - rename meta-data from '|| from_db_unique_name || ' to ' || to_db_unique_name); -- IF this_db_key IS NULL THEN BEGIN SELECT curr_dbinc_key into my_dbinc_key FROM db WHERE db_key = (SELECT db_key FROM node where db_unique_name = upper(from_db_unique_name)); setDatabase(my_dbinc_key); EXCEPTION WHEN no_data_found THEN raise_application_error(-20243, from_db_unique_name || ' site unknown to recovery catalog:'); END; END IF; IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; -- IF this_db_unique_name = upper(from_db_unique_name) THEN raise_application_error(-20244, from_db_unique_name || ' can not rename connected target database'); END IF; -- SELECT count(*) INTO rec_count FROM node WHERE node.db_unique_name = upper(from_db_unique_name) AND node.db_key = this_db_key; IF rec_count = 0 THEN raise_application_error(-20243, from_db_unique_name || ' site unknown to recovery catalog:'); END IF; -- SELECT count(*) INTO rec_count FROM node WHERE node.db_unique_name = upper(to_db_unique_name) AND node.db_key = this_db_key; IF rec_count = 1 THEN raise_application_error(-20246, to_db_unique_name || ' site known to recovery catalog:'); END IF; UPDATE NODE SET db_unique_name = upper(to_db_unique_name) WHERE db_unique_name = upper(from_db_unique_name) AND db_key = this_db_key; deb('renamed db_unique_name ' || sql%rowcount || ' row updated'); UPDATE CONF SET db_unique_name = upper(to_db_unique_name) WHERE db_unique_name = upper(from_db_unique_name) AND db_key = this_db_key; deb('updated ' || sql%rowcount || ' rows in conf table'); -- UPDATE FB SET db_unique_name = upper(to_db_unique_name) WHERE db_unique_name = upper(from_db_unique_name) AND dbinc_key IN (select dbinc_key from dbinc where db_key = this_db_key); deb('updated ' || sql%rowcount || ' rows in fb table'); commitChanges('renameSite'); END renameSite; -- -- PROCEDURE resyncAddDBUname(cdbunstr IN varchar2) IS dbuname node.db_unique_name%TYPE; numentries number; BEGIN -- -- -- -- -- -- -- -- -- -- -- deb('resyncAddDBUname - cdbunstr = '|| cdbunstr); dbuname := substr(cdbunstr, 2, 30); -- strip out the first quote -- -- deb('resyncAddDBUname - dbuname before = '|| dbuname); dbuname := substr(dbuname, 1, instr(dbuname, substr(cdbunstr,1,1))-1); deb('resyncAddDBUname - db_unique_name = '|| dbuname); -- -- insert into node (db_unique_name, db_key, force_resync2cf, database_role, site_key) values(upper(dbuname), this_db_key, 'YES', 'STANDBY', rman_seq.nextval); deb('resyncAddDBUname - adding node row with value ' || dbuname); EXCEPTION WHEN dup_val_on_index THEN -- RETURN; END resyncAddDBUname; -- FUNCTION getThisSiteKey(db_unique_name in VARCHAR2 DEFAULT NULL) return NUMBER IS ret_site_key number; BEGIN deb('getThisSiteKey - This site key is '||this_site_key); if db_unique_name is not null then ret_site_key := dbms_rcvman.getSiteKey(db_unique_name); else ret_site_key := this_site_key; end if; deb('Returning site key is '||ret_site_key); return ret_site_key; END getThisSiteKey; -- FUNCTION isAMSchema RETURN BOOLEAN IS BEGIN return this_is_ors; END isAMSchema; -- FUNCTION getAMTstlevel RETURN NUMBER IS am_tst_level number := 0; BEGIN if this_is_ors then select nvl(max(value), 0) into am_tst_level from config where name = '_oam_tst_level'; deb('getAMTstlevel from config ='||am_tst_level); else deb('getAMTstlevel='||am_tst_level||' for non-OAM schema'); end if; return am_tst_level; END getAMTstlevel; PROCEDURE enableResyncActions IS BEGIN deb('enableResyncActions - resync action tracing enabled'); doResyncReasons := TRUE; END enableResyncActions; PROCEDURE setReason(reason IN number, forceSet IN boolean default FALSE) IS BEGIN IF doResyncReasons THEN -- -- IF resync_reason = RESYNC_REASON_NONE OR forceSet THEN resync_reason := reason; deb('setReason - resync_reason: '||to_char(resync_reason)); END IF; ELSE resync_reason := RESYNC_REASON_NOACTION; END IF; END setReason; FUNCTION getReason RETURN number IS BEGIN IF doResyncReasons THEN deb('getReason - resync_reason: '||to_char(resync_reason)); RETURN resync_reason; ELSE RETURN RESYNC_REASON_NOACTION; END IF; END getReason; PROCEDURE incResyncActions(action IN number, objno IN number, objname IN varchar2) IS BEGIN IF not doResyncReasons THEN deb('incResynActions - Not debugging'); RETURN; END IF; BEGIN deb('incResynActions - for action: '||to_char(action)||' objno '|| nvl(to_char(objno), 'IS NULL')||' objname '||nvl(objname, 'IS NULL'), RCVCAT_LEVEL_HI); IF debOK(RCVCAT_LEVEL_HI) THEN dumpResyncActions; END IF; IF not fullResyncAction.active THEN RETURN; END IF; IF objno is NOT NULL THEN IF fullResyncAction.lastobjno = objno THEN IF fullResyncAction.actTaken(action) THEN -- deb('incResyncActions - '|| RESYNC_ACTION_OBJECTS(fullResyncAction.objtype)||' '|| to_char(objno)||' already '|| RESYNC_ACTION_NAMES(action), RCVCAT_LEVEL_HI); RETURN; ELSE fullResyncAction.actTaken(action) := TRUE; END IF; ELSE -- fullResyncAction.lastobjno := objno; fullResyncAction.actTaken := resyncActionTaken_t(FALSE, FALSE, FALSE, FALSE, FALSE, FALSE); fullResyncAction.actTaken(action) := TRUE; END IF; END IF; fullResyncAction.actCount(action) := fullResyncAction.actCount(action) + 1; fullResyncAction.valid := TRUE; IF objno is NOT NULL THEN IF objname is NOT NULL THEN deb('incResyncActions - '|| RESYNC_ACTION_OBJECTS(fullResyncAction.objtype)||' '|| objname||'('||to_char(objno)||') '|| RESYNC_ACTION_NAMES(action), RCVCAT_LEVEL_HI); ELSE deb('incResyncActions - '|| RESYNC_ACTION_OBJECTS(fullResyncAction.objtype)||' '|| to_char(objno)||' '|| RESYNC_ACTION_NAMES(action), RCVCAT_LEVEL_HI); END IF; ELSE deb('incResyncActions - '|| RESYNC_ACTION_OBJECTS(fullResyncAction.objtype)||' '|| to_char(objname)||' '|| RESYNC_ACTION_NAMES(action), RCVCAT_LEVEL_HI); END IF; deb('incResyncActions - Exiting', RCVCAT_LEVEL_HI); EXCEPTION WHEN others THEN deb('incResyncActions(DO_NOT_IGNORE) - caught exception '|| substr(sqlerrm, 1, 132) || ' for '|| to_char(action) || ' objno ' || nvl(to_char(objno), 'IS NULL') || ' objname ' || nvl(objname, 'IS NULL')); END; END incResyncActions; PROCEDURE dumpResyncActions IS i number; BEGIN IF not doResyncReasons OR not debOK(RCVCAT_LEVEL_HI) THEN RETURN; END IF; deb('dumpResyncActions - resync_reason: '||to_char(nvl(resync_reason, -1))); IF resync_reason = RESYNC_REASON_NOACTION THEN RETURN; END IF; IF fullResyncAction.active THEN deb('dumpResyncActions - Container is active'); ELSE deb('dumpResyncActions - Container is NOT active'); END IF; IF fullResyncAction.valid THEN deb('dumpResyncActions - Container is valid'); ELSE deb('dumpResyncActions - Container is NOT valid'); END IF; IF fullResyncAction.objtype IS NOT NULL THEN deb('dumpResyncActions - objtype: '|| RESYNC_ACTION_OBJECTS(fullResyncAction.objtype)); ELSE deb('dumpResyncActions - objtype is NULL'); END IF; IF fullResyncAction.lastobjno IS NOT NULL THEN deb('dumpResyncActions - lastobjno: '|| to_char(fullResyncAction.lastobjno)); ELSE deb('dumpResyncActions - lastobjno is NULL'); END IF; FOR i IN 1..6 LOOP IF fullResyncAction.actTaken(i) THEN deb('dumpResyncActions - '||RESYNC_ACTION_NAMES(i)||' TRUE - '|| fullResyncAction.actCount(i)); ELSE deb('dumpResyncActions - '||RESYNC_ACTION_NAMES(i)||' FALSE - '|| fullResyncAction.actCount(i)); END IF; END LOOP; END dumpResyncActions; PROCEDURE getResyncActions(valid OUT boolean ,added OUT number ,dropped OUT number ,changed OUT number ,recreated OUT number ,renamed OUT number ,resized OUT number) IS BEGIN IF doResyncReasons THEN IF debOK(RCVCAT_LEVEL_HI) THEN deb('getResyncActions - called', RCVCAT_LEVEL_HI); dumpResyncActions; END IF; fullResyncAction.active := FALSE; valid := fullResyncAction.valid; fullResyncAction.valid := FALSE; added := fullResyncAction.actCount(RESYNC_ACTION_ADD); dropped := fullResyncAction.actCount(RESYNC_ACTION_DROP); changed := fullResyncAction.actCount(RESYNC_ACTION_CHANGE); recreated := fullResyncAction.actCount(RESYNC_ACTION_RECREATE); renamed := fullResyncAction.actCount(RESYNC_ACTION_RENAME); resized := fullResyncAction.actCount(RESYNC_ACTION_RESIZE); setReason(RESYNC_REASON_NONE, TRUE); ELSE setReason(RESYNC_REASON_NOACTION, TRUE); END IF; END getResyncActions; PROCEDURE clearResyncActions IS BEGIN fullResyncAction.active := FALSE; fullResyncAction.valid := FALSE; fullResyncAction.lastobjno := -1; fullResyncAction.objtype := NULL; fullResyncAction.actTaken := resyncActionTaken_t(FALSE, FALSE, FALSE, FALSE, FALSE, FALSE); fullResyncAction.actCount := resyncActionCounts_t(0, 0, 0, 0, 0, 0); dumpResyncActions; END clearResyncActions; /*-------------------------------------------------* * Private functions for import catalog processing * *-------------------------------------------------*/ -- -- -- -- -- -- PROCEDURE adjustRmanSeq IS currval NUMBER; newval NUMBER; incseq NUMBER; BEGIN LOOP SELECT rman_seq.nextval INTO currval FROM dual; EXECUTE IMMEDIATE 'SELECT rman_seq.nextval@' || dbms_assert.qualified_sql_name(import_dblink) || ' FROM dual' INTO incseq; EXECUTE IMMEDIATE 'ALTER SEQUENCE rman_seq INCREMENT BY ' || incseq; SELECT rman_seq.nextval - incseq INTO import_offset FROM dual; EXECUTE IMMEDIATE 'ALTER SEQUENCE rman_seq INCREMENT BY 1'; -- -- -- -- EXIT WHEN (import_offset >= currval); END LOOP; END adjustRmanSeq; -- -- -- -- -- -- -- FUNCTION isColumnASeq( column_name IN VARCHAR2 ) RETURN BOOLEAN IS BEGIN IF (column_name LIKE '%KEY') THEN FOR i in 1..key_columns.COUNT LOOP IF (key_columns(i) = column_name) THEN RETURN TRUE; END IF; END LOOP; -- -- -- -- RAISE_APPLICATION_ERROR(-20999, 'Internal error in ' || 'isColumnASeq(): bad column '|| column_name); END IF; RETURN FALSE; END isColumnASeq; -- -- -- -- -- -- -- FUNCTION getColumnName( table_name IN VARCHAR2 , offset IN NUMBER DEFAULT NULL ) RETURN VARCHAR2 IS v_table user_objects.object_name%TYPE; v_column VARCHAR2(1024); isaseq BOOLEAN; CURSOR column_c(tname VARCHAR2) IS SELECT column_name, data_type FROM user_tab_columns WHERE table_name = tname ORDER BY column_name; FUNCTION add_comma ( v_column IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN IF (v_column IS NULL) THEN RETURN NULL; ELSE RETURN ','; END IF; END add_comma; FUNCTION add_offset( offset IN NUMBER , data_type IN VARCHAR2 , column_name IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN IF (offset IS NULL) THEN RETURN NULL; END IF; IF (data_type = 'NUMBER' AND isColumnASeq(column_name)) THEN RETURN '+' || offset; END IF; RETURN null; END add_offset; BEGIN SELECT object_name INTO v_table FROM user_objects WHERE object_name = UPPER(table_name) AND object_type = 'TABLE'; -- FOR cRec in column_c(v_table) LOOP v_column := v_column || add_comma(v_column) || dbms_assert.simple_sql_name(table_name) || '.' || dbms_assert.simple_sql_name(cRec.column_name) || add_offset(offset, cRec.data_type, cRec.column_name); END LOOP; RETURN v_column; END getColumnName; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE importTable ( table_name IN VARCHAR2 , from_table IN ts_name_list , uniq_rows IN BOOLEAN , where_clause IN VARCHAR2 ) IS insert_columns VARCHAR2(2048); from_columns VARCHAR2(2048); source_table VARCHAR2(2048); uniq_keyword VARCHAR2(8); start_time DATE; BEGIN deb('Entering importTable table=' || table_name); insert_columns := getColumnName(table_name); from_columns := getColumnName(table_name, import_offset); source_table := dbms_assert.qualified_sql_name( table_name || '@' || import_dblink ); FOR i IN 1..from_table.COUNT LOOP source_table := source_table || ',' || dbms_assert.qualified_sql_name( from_table(i) || '@' || import_dblink ); END LOOP; IF (uniq_rows) THEN uniq_keyword := 'DISTINCT'; END IF; -- -- -- -- -- -- -- -- start_time := SYSDATE; EXECUTE IMMEDIATE 'INSERT INTO ' || dbms_assert.qualified_sql_name(table_name) || '(' || insert_columns || ')' || 'SELECT ' || uniq_keyword || ' ' || from_columns || ' FROM ' || source_table || ' ' || where_clause; deb('imported rows = ' || SQL%ROWCOUNT); deb('importTable took ' || ((SYSDATE - start_time) * 86400) || ' seconds'); deb('Finished importTable table=' || table_name); END importTable; -- -- -- -- -- -- -- -- PROCEDURE registerImportDb ( idb IN VARCHAR2 , idbinc IN VARCHAR2 ) IS TYPE cur_typ IS ref CURSOR; update_c cur_typ; from_table ts_name_list; from_columns VARCHAR2(2048); currkeys numTab_t; dbids numTab_t; dbkeys numTab_t; reg_dbuname key_columns_list; strg_prov sp_columns_list; BEGIN deb('Entering registerImportDb'); from_columns := getColumnName('db', import_offset); -- -- -- -- -- -- -- -- EXECUTE IMMEDIATE 'INSERT INTO db (db.db_key, db.db_id)' || 'SELECT db.db_key + ' || import_offset || ' , db.db_id' || ' FROM db@' || dbms_assert.qualified_sql_name(import_dblink) || ' ,' || dbms_assert.qualified_sql_name(idb || '@' || import_dblink) || ' WHERE db.db_key = ' || dbms_assert.simple_sql_name(idb) || '.db_key'; deb('Total db imported = ' || SQL%ROWCOUNT); -- from_table.DELETE; from_table(1) := idbinc; importTable ( table_name => 'dbinc' , from_table => from_table , uniq_rows => FALSE , where_clause => 'WHERE dbinc.dbinc_key = ' || idbinc || '.dbinc_key' ); -- -- OPEN update_c FOR -- -- -- -- -- -- -- 'SELECT ' || from_columns || ' FROM db@' || dbms_assert.qualified_sql_name(import_dblink) || ',' || dbms_assert.qualified_sql_name(idb || '@' || import_dblink) || ' WHERE db.db_key = ' || dbms_assert.simple_sql_name(idb) || '.db_key'; FETCH update_c BULK COLLECT INTO currkeys, dbids, dbkeys, reg_dbuname, strg_prov; CLOSE update_c; -- FORALL i IN 1..dbids.COUNT UPDATE db SET curr_dbinc_key = currkeys(i) , reg_db_unique_name = reg_dbuname(i) , storage_prov = strg_prov(i) WHERE db.db_key = dbkeys(i); deb('Finished registerImportDb'); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN RAISE_APPLICATION_ERROR(-20512, 'Database already registered'); END registerImportDb; -- -- -- -- -- -- -- -- PROCEDURE dropTempResource ( name IN VARCHAR2 , data_type IN VARCHAR2 ) IS e_dblink_not_found EXCEPTION; e_dblink_not_open EXCEPTION; e_resource_not_found EXCEPTION; e_table_not_found EXCEPTION; PRAGMA EXCEPTION_INIT(e_dblink_not_found, -2024); PRAGMA EXCEPTION_INIT(e_dblink_not_open, -2081); PRAGMA EXCEPTION_INIT(e_resource_not_found, -20509); PRAGMA EXCEPTION_INIT(e_table_not_found, -942); BEGIN deb('Entering dropTempResource name = ' || name || ' , data_type = '|| data_type); commitChanges('dropTempResource'); -- IF (NOT lockTempResource(name, data_type)) THEN deb('Finished dropTempResource - resource busy'); RETURN; END IF; IF (data_type = 'TABLE') THEN EXECUTE IMMEDIATE 'DROP TABLE ' || dbms_assert.qualified_sql_name(name); ELSIF (data_type = 'DBLINK') THEN BEGIN EXECUTE IMMEDIATE 'ALTER SESSION CLOSE DATABASE LINK ' || dbms_assert.qualified_sql_name(name); EXCEPTION WHEN e_dblink_not_open THEN NULL; END; EXECUTE IMMEDIATE 'DROP DATABASE LINK ' || dbms_assert.qualified_sql_name(name); END IF; -- DELETE tempres WHERE tempres.name = dropTempResource.name; commitChanges('dropTempResource-2'); deb('Finished dropTempResource'); EXCEPTION WHEN e_resource_not_found THEN DELETE FROM tempres WHERE tempres.name = dropTempResource.name; commitChanges('dropTempResource-3'); deb('Finished dropTempResource - resource_not_found ' || name); WHEN e_dblink_not_found THEN deb('Finished dropTempResource - dblink_not_found' || name); WHEN e_table_not_found THEN deb('Finished dropTempResource - table_not_found' || name); WHEN OTHERS THEN deb('(DO_NOT_IGNORE)caught exception during dropTempResource ' || SUBSTR(SQLERRM, 1, 512)); END dropTempResource; -- -- -- -- -- -- -- -- PROCEDURE importGlobalScript IS type cur_typ is ref cursor; global_scr_c cur_typ; global_scr_q varchar2(1024); local scr%rowtype; given_name scr.scr_name%type; from_table ts_name_list; from_columns varchar2(2048); copycnt number; unique_violated exception; pragma exception_init(unique_violated, -1); BEGIN -- from_columns := getColumnName('scr'); global_scr_q := 'SELECT ' || from_columns || ' FROM scr@' || dbms_assert.qualified_sql_name(import_dblink) || ' WHERE db_key IS NULL'; OPEN global_scr_c FOR global_scr_q; LOOP FETCH global_scr_c INTO local.db_key, local.scr_comment, local.scr_key, local.scr_name; EXIT WHEN global_scr_c%NOTFOUND; copycnt := 0; given_name := local.scr_name; <> BEGIN -- -- -- -- -- EXECUTE IMMEDIATE 'INSERT INTO scr (' || from_columns || ') VALUES ' || '( null,' || case when local.scr_comment is not null then '''' || local.scr_comment || ''',' else 'null,' end || local.scr_key || '+' || import_offset || ',' || '''' || local.scr_name || ''')'; EXCEPTION WHEN unique_violated THEN -- copycnt := copycnt + 1; IF (copycnt = 1) THEN local.scr_name := 'COPY OF ' || given_name; ELSE local.scr_name := 'COPY(' || copycnt || ') OF ' || given_name; END IF; goto tryagain; END; END LOOP; -- from_table.delete; from_table(1) := 'scr'; importTable(table_name => 'scrl' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where scr.db_key is null' || ' and scr.scr_key = scrl.scr_key'); END importGlobalScript; /*------------------------------------------------* * Public functions for import catalog processing * *------------------------------------------------*/ -- -- -- -- -- PROCEDURE createTempResource( name IN varchar2 ,data_type IN varchar2) IS unique_violated exception; pragma exception_init(unique_violated ,-1); BEGIN -- INSERT INTO tempres (name, data_type) VALUES (name, data_type); commitChanges('createTempResource'); EXCEPTION WHEN unique_violated THEN raise_application_error(-20508, 'resource already in use ' || name); END createTempResource; -- -- -- -- -- -- FUNCTION lockTempResource( name IN varchar2 ,data_type IN varchar2) RETURN BOOLEAN IS local tempres%ROWTYPE; found number; resource_busy exception; pragma exception_init(resource_busy, -54); BEGIN deb('Entering lockTempResource ' || name); SELECT name, data_type INTO local.name, local.data_type FROM tempres WHERE name = lockTempResource.name FOR UPDATE NOWAIT; IF (data_type = 'TABLE') THEN SELECT count(*) INTO found FROM user_tab_columns WHERE table_name = lockTempResource.name; ELSIF (data_type = 'DBLINK') THEN SELECT count(*) INTO found FROM user_db_links WHERE db_link = lockTempResource.name; ELSE raise_application_error(-20999, 'Internal error in localTempResource(): bad data_type '|| data_type); END IF; IF (found = 0) THEN deb('Finished lockTempResource with resource not found'); raise_application_error(-20509, 'resource not found ' || name); END IF; deb('Finished lockTempResource'); RETURN TRUE; EXCEPTION WHEN resource_busy THEN deb('Finished lockTempResource with resource_busy'); RETURN FALSE; WHEN no_data_found THEN deb('Finished lockTempResource with no_data_found'); RETURN FALSE; END lockTempResource; -- -- -- -- -- PROCEDURE cleanupTempResource IS CURSOR temp_c IS SELECT name, data_type FROM tempres; BEGIN FOR tempRec in temp_c LOOP dropTempResource(tempRec.name, tempRec.data_type); END LOOP; END cleanupTempResource; -- -- -- -- -- -- -- -- PROCEDURE addDbidToImport( first IN binary_integer ,idb IN varchar2 ,idbinc IN varchar2 ,dbid IN number DEFAULT NULL ,dbname IN varchar2 DEFAULT NULL) IS dummy tempres.name%TYPE; ldbid db.db_id%TYPE := dbid; dbid_exists number; BEGIN -- IF (NOT lockTempResource(idb, 'TABLE')) THEN raise_application_error(-20508, 'resource already in use ' || idb); ELSIF (NOT lockTempResource(idbinc, 'TABLE')) THEN raise_application_error(-20508, 'resource already in use ' || idbinc); END IF; IF (dbid IS NULL AND dbname IS NULL) THEN EXECUTE IMMEDIATE 'INSERT INTO ' || idb || '(db_key, db_id) ' || '(SELECT db_key, db_id FROM db)'; IF (sql%rowcount = 0) THEN raise_application_error(-20510, 'import database not found'); END IF; EXECUTE IMMEDIATE 'INSERT INTO ' || idbinc || '(dbinc_key) ' || '(SELECT dbinc_key ' || ' FROM dbinc, ' || idb || ' WHERE dbinc.db_key = ' || idb ||'.db_key)'; commitChanges('addDbidToImport'); RETURN; ELSIF (dbname IS NOT NULL) THEN BEGIN SELECT db.db_id INTO ldbid FROM db, dbinc WHERE db.curr_dbinc_key = dbinc.dbinc_key AND dbinc.db_name = upper(addDbidtoImport.dbname); EXCEPTION WHEN no_data_found THEN raise_application_error(-20510, 'import database not found'); WHEN too_many_rows THEN raise_application_error(-20511, 'import database name is ambiguous'); END; ELSE BEGIN SELECT db.db_id INTO ldbid FROM db WHERE db.db_id = ldbid; EXCEPTION WHEN no_data_found THEN raise_application_error(-20510, 'import database not found'); END; END IF; -- -- IF (first = 0) THEN FOR i in 1..import_dbid.count LOOP EXECUTE IMMEDIATE 'SELECT count(*) FROM ' || idb || ' WHERE ' || idb || '.db_id =' || import_dbid(i) INTO dbid_exists; IF (dbid_exists != 1) THEN raise_application_error(-20508, 'resource already in use ' || idb); END IF; END LOOP; EXECUTE IMMEDIATE 'SELECT count(*) FROM ' || idb INTO dbid_exists; IF (dbid_exists != import_dbid.count) THEN raise_application_error(-20508, 'resource already in use ' || idb); END IF; import_dbid(import_dbid.count + 1) := ldbid; ELSE import_dbid.delete; import_dbid(1) := ldbid; END IF; EXECUTE IMMEDIATE 'INSERT INTO ' || idb || '(db_key, db_id) ' || '(SELECT db_key, db_id FROM db ' || ' WHERE db_id = ' || ldbid || ')'; EXECUTE IMMEDIATE 'INSERT INTO ' || idbinc || '(dbinc_key) ' || '(SELECT dbinc_key ' || ' FROM dbinc, ' || idb || ' WHERE dbinc.db_key = ' || idb || '.db_key ' || ' AND ' || idb || '.db_id = ' || ldbid || ')'; commitChanges('addDbidToImport-2'); -- IF (NOT lockTempResource(idb, 'TABLE')) THEN raise_application_error(-20508, 'resource already in use ' || idb); ELSIF (NOT lockTempResource(idbinc, 'TABLE')) THEN raise_application_error(-20508, 'resource already in use ' || idbinc); END IF; END addDbidToImport; -- -- -- -- -- -- -- PROCEDURE lockDbidToImport( idb IN varchar2) IS TYPE cur_typ IS ref CURSOR; idb_c cur_typ; idb_q varchar2(512); local_db_key db.db_key%TYPE; local_db_id db.db_key%TYPE; BEGIN idb_q := 'SELECT db_key FROM ' || idb; OPEN idb_c FOR idb_q; LOOP FETCH idb_c INTO local_db_key; EXIT WHEN idb_c%NOTFOUND; SELECT db_id INTO local_db_id FROM db WHERE db.db_key = local_db_key FOR UPDATE OF db.db_key; END LOOP; END lockDbidToImport; -- -- -- -- -- -- PROCEDURE importSchema( dblink IN varchar2 ,idb IN varchar2 ,idbinc IN varchar2) IS from_table ts_name_list; BEGIN import_dblink := dblink; adjustRmanSeq; registerImportDb(idb, idbinc); -- from_table.delete; from_table(1) := idb; importTable(table_name => 'pdb' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where pdb.db_key = ' || idb || '.db_key'); -- from_table.delete; from_table(1) := idb; from_table(2) := 'pdb'; importTable(table_name => 'pdbinc' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where pdb.db_key = ' || idb || '.db_key' || ' and pdbinc.pdb_key = pdb.pdb_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'pdb_dbinc' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where pdb_dbinc.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idb; importTable(table_name => 'conf' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where conf.db_key = ' || idb || '.db_key'); -- from_table.delete; from_table(1) := idb; importTable(table_name => 'node' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where node.db_key = ' || idb || '.db_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'ckp' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where ckp.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'ts' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where ts.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'tsatt' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where tsatt.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'df' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where df.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idb; from_table(2) := 'node'; importTable(table_name => 'site_dfatt' ,from_table => from_table ,uniq_rows => TRUE ,where_clause => 'where node.db_key = ' || idb || '.db_key' || ' and site_dfatt.site_key = node.site_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'offr' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where offr.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'tf' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where tf.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idb; from_table(2) := 'node'; importTable(table_name => 'site_tfatt' ,from_table => from_table ,uniq_rows => TRUE ,where_clause => 'where node.db_key = ' || idb || '.db_key' || ' and site_tfatt.site_key = node.site_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'rr' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where rr.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'rt' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where rt.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'orl' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where orl.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'rlh' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where rlh.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'al' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where al.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idb; importTable(table_name => 'bs' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where bs.db_key = ' || idb || '.db_key'); -- from_table.delete; from_table(1) := idb; importTable(table_name => 'bp' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where bp.db_key = ' || idb || '.db_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'bcf' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where bcf.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'ccf' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where ccf.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'xcf' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where xcf.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idb; importTable(table_name => 'bsf' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where bsf.db_key = ' || idb || '.db_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'bdf' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where bdf.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'cdf' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where cdf.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'xdf' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where xdf.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'xal' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where xal.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'brl' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where brl.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idbinc; from_table(2) := 'bdf'; importTable(table_name => 'bcb' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where bdf.bdf_key = bcb.bdf_key' || ' and bdf.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idbinc; from_table(2) := 'cdf'; importTable(table_name => 'ccb' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where cdf.cdf_key = ccb.cdf_key' || ' and cdf.dbinc_key = ' || idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'rsr' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where rsr.dbinc_key= ' ||idbinc|| '.dbinc_key'); -- from_table.delete; from_table(1) := idb; importTable(table_name => 'scr' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where scr.db_key = ' || idb || '.db_key'); -- from_table.delete; from_table(1) := idb; from_table(2) := 'scr'; importTable(table_name => 'scrl' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where scr.db_key = ' || idb || '.db_key' || ' and scr.scr_key = scrl.scr_key'); -- importGlobalScript; -- from_table.delete; from_table(1) := idb; importTable(table_name => 'rout' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where rout.db_key = ' || idb || '.db_key'); -- -- -- -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'fb' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where fb.dbinc_key = '|| idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'grsp' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where grsp.dbinc_key = '|| idbinc || '.dbinc_key'); -- from_table.delete; from_table(1) := idb; from_table(2) := 'node'; importTable(table_name => 'bcr' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where bcr.site_key = node.site_key' || ' and node.db_key = ' || idb || '.db_key'); -- from_table.delete; from_table(1) := idbinc; importTable(table_name => 'nrsp' ,from_table => from_table ,uniq_rows => FALSE ,where_clause => 'where nrsp.dbinc_key = '|| idbinc || '.dbinc_key'); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- commitChanges('importSchema'); EXCEPTION WHEN others THEN deb('importSchema - release locks'); ROLLBACK; RAISE; END importSchema; -- -- -- -- -- -- PROCEDURE unregisterDatabase( idb IN varchar2) IS TYPE cur_typ IS ref CURSOR; idb_c cur_typ; idb_q varchar2(512); local_db_id db.db_id%TYPE; BEGIN idb_q := 'SELECT db_id FROM ' || idb; OPEN idb_c FOR idb_q; LOOP FETCH idb_c INTO local_db_id; EXIT WHEN idb_c%NOTFOUND; unregisterDatabase(db_id => local_db_id); END LOOP; END unregisterDatabase; PROCEDURE clearUnarchivedLogs IS BEGIN deb('clearUnarchivedLogs for this_db_key='||this_db_key); delete from al where archived = 'N' and dbinc_key in (select dbinc_key from dbinc where db_key = this_db_key); commitChanges('clearUnarchivedLogs'); END clearUnarchivedLogs; /*----------------------------* * Virtual Private Catalog * *----------------------------*/ -- -- -- -- -- -- -- -- -- -- FUNCTION grant_get_dbid(dbname IN varchar2) RETURN number IS dbid number; cnt number; BEGIN select max(db_id), count(*) into dbid, cnt from db join (select distinct db_key,db_name from dbinc) using(db_key) where db_name = dbname; deb('grant_get_dbid - got dbid and cnt ' || dbid || ' cnt ' || cnt); if cnt = 0 then raise_application_error(-20018, 'database ' || dbname || ' not found in recovery catalog'); end if; if cnt > 1 then raise_application_error(-20019, 'database ' || dbname || ' not unique in recovery catalog'); end if; return dbid; END; FUNCTION get_db_numeric_uid(uname IN VARCHAR2) RETURN NUMBER IS numeric_uid NUMBER; BEGIN SELECT user_id INTO numeric_uid FROM all_users WHERE username = uname; RETURN numeric_uid; EXCEPTION WHEN NO_DATA_FOUND THEN raise_application_error(-20022, 'user ' || uname || ' not found'); END; PROCEDURE clean_old_uids IS BEGIN DELETE vpc_databases WHERE filter_uid NOT IN (SELECT user_id FROM all_users); DELETE vpc_users WHERE filter_uid NOT IN (SELECT user_id FROM all_users); -- -- END; FUNCTION is_vpd_enabled ( i_full_check BOOLEAN DEFAULT TRUE ) RETURN BOOLEAN IS l_dummy VARCHAR2(1); BEGIN -- -- IF (this_is_ors) THEN RETURN TRUE; END IF; -- -- IF (SYS_CONTEXT('SYS_SESSION_ROLES', 'RECOVERY_CATALOG_OWNER_VPD') = 'TRUE') THEN NULL; ELSE -- -- BEGIN SELECT 'x' INTO l_dummy FROM session_privs WHERE privilege IN ( -- 'ADMINISTER DATABASE TRIGGER' -- , 'CREATE ANY SYNONYM', 'DROP ANY SYNONYM' ) HAVING COUNT(*) = 3; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN FALSE; END; END IF; -- -- -- BEGIN SELECT 'x' INTO l_dummy FROM all_tab_privs WHERE (table_schema, table_name, privilege, grantee) IN ( ('SYS', 'DBMS_RLS', 'EXECUTE', 'RECOVERY_CATALOG_OWNER_VPD') , ('SYS', 'DBMS_RLS', 'EXECUTE', 'RECOVERY_CATALOG_OWNER') , ('SYS', 'DBMS_RLS', 'EXECUTE', g_catowner) ) HAVING COUNT(*) > 0; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN FALSE; END; IF (i_full_check) THEN -- -- -- BEGIN SELECT 'x' INTO l_dummy FROM user_policies HAVING COUNT(*) = g_vpd_required_policies; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN FALSE; END; -- BEGIN SELECT 'x' INTO l_dummy FROM user_triggers WHERE trigger_name = 'VPC_CONTEXT_TRG'; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN FALSE; END; END IF; RETURN TRUE; END; PROCEDURE revoke_clean_userid ( userid IN VARCHAR2 ) IS l_privs_remaining NUMBER; l_schema user_users.username%TYPE; l_eschema VARCHAR2(130); e_no_synonym EXCEPTION; PRAGMA EXCEPTION_INIT(e_no_synonym, -1434); BEGIN assert_schema(l_schema, l_eschema, userid); DELETE vpc_users WHERE filter_user = userid AND add_new_db = 'N' AND NOT EXISTS ( SELECT * FROM vpc_databases WHERE filter_user = l_schema ); commitChanges('revoke_clean_userid'); SELECT COUNT(*) INTO l_privs_remaining FROM vpc_users WHERE filter_user = l_schema; deb('revoke_clean_userid - commit, release locks, userid=' || l_schema || ', privs_remaining=' || l_privs_remaining); IF l_privs_remaining > 0 THEN RETURN; END IF; IF (NOT this_is_ors) THEN BEGIN EXECUTE IMMEDIATE 'REVOKE recovery_catalog_user FROM ' || l_eschema; EXCEPTION WHEN OTHERS THEN deb('revoke_clean_userid(DO_NOT_IGNORE)'); END; END IF; BEGIN EXECUTE IMMEDIATE 'DROP SYNONYM ' || l_eschema || '."DBMS_RCVMAN"'; EXCEPTION WHEN e_no_synonym THEN NULL; END; BEGIN EXECUTE IMMEDIATE 'DROP SYNONYM ' || l_eschema || '."DBMS_RCVCAT"'; EXCEPTION WHEN e_no_synonym THEN NULL; END; END; PROCEDURE do_vpc_grants ( userid IN VARCHAR2 ) IS l_schema user_users.username%TYPE; l_eschema VARCHAR2(130); BEGIN IF (NOT is_vpd_enabled) THEN RAISE_APPLICATION_ERROR(e_no_vpd_setup, e_no_vpd_setup_m); END IF; assert_schema(l_schema, l_eschema, userid); IF (NOT this_is_ors) THEN EXECUTE IMMEDIATE 'GRANT recovery_catalog_user TO ' || l_eschema; END IF; /* While stemming from rman client PL/SQL context alter session * set current_schema has no effect as far as visibility to packages * are concerned. So the additional steps below. (bandaid) * Since DDL is, in general, bad activity we have to limit it * making sure that the synonyms are created only if they don't * exist. */ FOR s IN ( SELECT synonym_name FROM ( SELECT 'DBMS_RCVMAN' synonym_name FROM dual UNION ALL SELECT 'DBMS_RCVCAT' FROM dual ) x WHERE NOT EXISTS ( SELECT NULL FROM all_synonyms s WHERE s.table_owner = g_catowner AND s.table_name = x.synonym_name AND s.owner = userid AND s.synonym_name = x.synonym_name ) ) LOOP EXECUTE IMMEDIATE 'CREATE OR REPLACE SYNONYM ' || l_eschema || '.' || s.synonym_name || ' FOR ' || g_ecatowner || '.' || s.synonym_name; END LOOP; END; PROCEDURE grant_catalog(userid IN varchar2, dbname IN varchar2) IS BEGIN grant_catalog(userid, grant_get_dbid(dbname)); END; PROCEDURE grant_catalog(userid IN varchar2, dbid IN number, reg_db_unique_name IN varchar2 default null) IS user_count number; numeric_uid number; p_dbun node.db_unique_name%TYPE := upper(reg_db_unique_name); p_dbid number not null := dbid; BEGIN clean_old_uids; do_vpc_grants(userid); SELECT COUNT(*), MAX(filter_uid) INTO user_count, numeric_uid FROM vpc_users WHERE filter_user = userid; if user_count = 0 then numeric_uid := get_db_numeric_uid(userid); insert into vpc_users(filter_user, filter_uid, add_new_db) values(userid, numeric_uid, 'N'); end if; insert into vpc_databases (filter_user, filter_uid, reg_db_unique_name, db_id) select userid, numeric_uid, decode(dbid, 0, p_dbun, null), dbid from dual where not exists (select 1 from vpc_databases where filter_user = userid and ((db_id = 0 and reg_db_unique_name = p_dbun) or (db_id <> 0 and db_id = dbid)) ); commitChanges('grant_catalog'); END; PROCEDURE grant_register(userid IN varchar2) IS numeric_uid number := get_db_numeric_uid(userid); BEGIN clean_old_uids; do_vpc_grants(userid); MERGE INTO vpc_users USING dual ON (filter_user = userid) WHEN MATCHED THEN UPDATE SET add_new_db = 'Y' WHEN NOT MATCHED THEN INSERT(filter_user, filter_uid, add_new_db) VALUES(userid, numeric_uid, 'Y'); commitChanges('grant_register'); END; PROCEDURE revoke_catalog(userid IN varchar2, dbname IN varchar2) IS BEGIN revoke_catalog(userid, grant_get_dbid(dbname)); END; PROCEDURE revoke_catalog(userid IN varchar2, dbid IN number, reg_db_unique_name IN varchar2 default null) IS p_dbun node.db_unique_name%TYPE := upper(reg_db_unique_name); p_dbid number not null := dbid; BEGIN IF (NOT is_vpd_enabled) THEN RAISE_APPLICATION_ERROR(e_no_vpd_setup, e_no_vpd_setup_m); END IF; clean_old_uids; deb('revoke_catalog - After clean_old_uids'); delete from vpc_databases where filter_user = userid and ((dbid <> 0 and db_id = dbid) or (dbid = 0 and reg_db_unique_name = p_dbun)); revoke_clean_userid(userid); commitChanges('revoke_catalog'); END; PROCEDURE revoke_register(userid IN varchar2) IS BEGIN IF (NOT is_vpd_enabled) THEN RAISE_APPLICATION_ERROR(e_no_vpd_setup, e_no_vpd_setup_m); END IF; clean_old_uids; update vpc_users set add_new_db='N' where filter_user=userid; revoke_clean_userid(userid); commitChanges('revoke_register'); END; PROCEDURE revoke_all ( userid IN VARCHAR2 ) IS BEGIN clean_old_uids; DELETE vpc_databases WHERE filter_user = userid; DELETE vpc_users WHERE filter_user = userid; revoke_clean_userid(userid); commitChanges('revoke_all'); END; PROCEDURE create_virtual_catalog IS BEGIN NULL; END create_virtual_catalog; PROCEDURE drop_virtual_catalog IS BEGIN NULL; END drop_virtual_catalog; /* * New VPC based on VPD * This routine is setup to be idempotent, can be called * again and again. * Input i_oper: Can be used to drop the policies on an upgrade * when i_oper == 0. Sets the policies when i_oper <> 0 */ PROCEDURE setupVPD ( i_oper NUMBER ) IS lc_policy_str CONSTANT VARCHAR2(32) := 'dbms_rcvvpc.f_'; lc_policy_str_passall CONSTANT VARCHAR2(32) := 'dbms_rcvvpc.filter_pass_all'; l_policy_str VARCHAR2(64); e_policy_notexists EXCEPTION; PRAGMA EXCEPTION_INIT(e_policy_notexists, -28102); l_granted_to VARCHAR2(32) := CASE WHEN this_is_ors THEN 'PUBLIC' ELSE 'recovery_catalog_user' END; BEGIN -- -- -- -- -- IF ( SYS_CONTEXT('USERENV', 'SESSION_USER') <> g_catowner OR NOT is_vpd_enabled(i_full_check => FALSE) ) THEN RETURN; END IF; FOR i IN 1..vpd_table_list.COUNT LOOP EXECUTE IMMEDIATE 'GRANT ' || vtr_privs(i) || ' ON ' || vtr_tname(i) || ' TO ' || l_granted_to; IF vtr_policy_required(i) THEN BEGIN EXECUTE IMMEDIATE ' BEGIN dbms_rls.drop_policy ( object_schema => :1 , object_name => :2 , policy_name => :3 ); END;' USING g_catowner , vtr_tname(i) , vtr_tname(i); EXCEPTION WHEN e_policy_notexists THEN NULL; END; IF (i_oper = 0) THEN l_policy_str := lc_policy_str_passall; ELSE l_policy_str := lc_policy_str || vtr_tname(i); END IF; IF (vtr_update_check(i)) THEN EXECUTE IMMEDIATE ' BEGIN dbms_rls.add_policy ( object_schema => :1 , object_name => :2 , policy_name => :3 , function_schema => :4 , policy_function => :5 , policy_type => dbms_rls.shared_context_sensitive , update_check => TRUE ); END;' USING g_catowner , vtr_tname(i) , vtr_tname(i) , g_catowner , l_policy_str; ELSE EXECUTE IMMEDIATE ' BEGIN dbms_rls.add_policy ( object_schema => :1 , object_name => :2 , policy_name => :3 , function_schema => :4 , policy_function => :5 , policy_type => dbms_rls.shared_context_sensitive , update_check => FALSE ); END;' USING g_catowner , vtr_tname(i) , vtr_tname(i) , g_catowner , l_policy_str; END IF; END IF; END LOOP; FOR r IN ( SELECT view_name FROM user_views WHERE view_name LIKE 'RC~_%' ESCAPE '~' OR view_name LIKE 'RCI~_%' ESCAPE '~' OR view_name LIKE '~_RS~_RC~_%' ESCAPE '~' OR view_name LIKE '~_RS~_RCI~_%' ESCAPE '~' ) LOOP EXECUTE IMMEDIATE 'GRANT SELECT ON ' || dbms_assert.enquote_name(r.view_name) || ' TO ' || l_granted_to; END LOOP; IF (this_is_ors) THEN EXECUTE IMMEDIATE 'GRANT EXECUTE ON dbms_rai_owner TO PUBLIC'; EXECUTE IMMEDIATE 'CREATE OR REPLACE PUBLIC SYNONYM dbms_rai_owner FOR dbms_rai_owner'; EXECUTE IMMEDIATE 'GRANT EXECUTE ON dbms_rai_verifier TO PUBLIC'; EXECUTE IMMEDIATE 'GRANT EXECUTE ON dbms_rai_inst_addresses TO PUBLIC'; EXECUTE IMMEDIATE 'GRANT EXECUTE ON dbms_rai_sbt_parms TO PUBLIC'; EXECUTE IMMEDIATE 'GRANT EXECUTE ON dbms_rai_url TO PUBLIC'; EXECUTE IMMEDIATE 'GRANT EXECUTE ON dbms_rai_wallet2url TO PUBLIC'; EXECUTE IMMEDIATE 'GRANT EXECUTE ON dbms_rai_throttle_alloc TO PUBLIC'; EXECUTE IMMEDIATE 'GRANT EXECUTE ON dbms_rai_fix_error TO PUBLIC'; EXECUTE IMMEDIATE 'GRANT EXECUTE ON dbms_rai_populate_rsr_key TO PUBLIC'; END IF; deb('setupVPD - after adding policy and grants'); -- -- -- IF (i_oper <> 0) THEN IF (this_is_ors) THEN EXECUTE IMMEDIATE REGEXP_REPLACE(q'{ CREATE OR REPLACE TRIGGER vpc_context_trg AFTER LOGON ON DATABASE WHEN ( SYS_CONTEXT('USERENV', 'SESSION_USER') NOT IN ( 'SYSBACKUP', 'XDB', 'SYSMAN', 'ANONYMOUS', 'APPQOSSYS' , 'AUDSYS', 'CTXSYS', 'DIP' , 'DMSYS', 'EXFSYS', 'GSMADMIN_INTERNAL', 'GSMCATUSER' , 'GSMUSER' , 'MDSYS', 'ORABPEL', 'ORACLE_OCM' , 'ORAESB', 'ORAWSM', 'ORDPLUGINS', 'ORDSYS', 'OUTLN' , 'SI_INFORMTN_SCHEMA', 'SYSDG', 'SYSKM', 'TSMSYS' , 'WKSYS', 'WMSYS', 'XS$NULL' ) ) DECLARE l_dummy VARCHAR2(1); BEGIN -- -- -- IF ( SYS_CONTEXT('USERENV', 'SESSION_USER') IN ( '%o', 'SYS', 'SYSTEM', 'DBSNMP' ) ) THEN EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ''.,'''; ELSE -- -- SELECT 'Y' INTO l_dummy FROM vpc_users WHERE filter_uid = SYS_CONTEXT('USERENV', 'SESSION_USERID'); EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ''.,'' CURRENT_SCHEMA = %o'; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN -- All regular users who have access to RA catalog must -- IF (SYS_CONTEXT('SYS_SESSION_ROLES', 'RA_CATALOG_SELECT') = 'TRUE') THEN EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ''.,'''; END IF; END; }', '%o', g_catowner); ELSE EXECUTE IMMEDIATE REGEXP_REPLACE(q'{ CREATE OR REPLACE TRIGGER vpc_context_trg AFTER LOGON ON DATABASE WHEN ( SYS_CONTEXT('USERENV', 'SESSION_USER') NOT IN ( '%o', 'SYS', 'SYSTEM', 'SYSBACKUP' , 'XDB', 'SYSMAN', 'ANONYMOUS', 'APPQOSSYS' , 'AUDSYS', 'CTXSYS', 'DIP' , 'DMSYS', 'EXFSYS', 'GSMADMIN_INTERNAL', 'GSMCATUSER' , 'GSMUSER' , 'MDSYS', 'ORABPEL', 'ORACLE_OCM' , 'ORAESB', 'ORAWSM', 'ORDPLUGINS', 'ORDSYS', 'OUTLN' , 'SI_INFORMTN_SCHEMA', 'SYSDG', 'SYSKM', 'TSMSYS' , 'WKSYS', 'WMSYS', 'XS$NULL' ) ) DECLARE l_dummy VARCHAR2(1); BEGIN SELECT 'Y' INTO l_dummy FROM vpc_users WHERE filter_uid = SYS_CONTEXT('USERENV', 'SESSION_USERID'); EXECUTE IMMEDIATE 'ALTER SESSION SET CURRENT_SCHEMA = %o'; EXCEPTION WHEN NO_DATA_FOUND THEN NULL; END; }', '%o', g_catowner); END IF; END IF; deb('setupVPD - create or replace trigger'); END setupVPD; PROCEDURE dumpPkgState (msg in varchar2 default NULL) IS begin deb('Global variables package state ' || nvl(msg,' ')); deb('Number variables'); deb('dbglvl: ' || nvl(to_char(dbglvl), 'NULL')); deb('this_db_key: ' || nvl(to_char(this_db_key), 'NULL')); deb('this_dbinc_key: ' || nvl(to_char(this_dbinc_key), 'NULL')); deb('this_ckp_key: ' || nvl(to_char(this_ckp_key), 'NULL')); deb('this_ckp_scn: ' || nvl(to_char(this_ckp_scn), 'NULL')); deb('this_site_key: ' || nvl(to_char(this_site_key), 'NULL')); deb('logs_shared: ' || nvl(to_char(logs_shared), 'NULL')); deb('disk_backups_shared: ' || nvl(to_char(disk_backups_shared), 'NULL')); deb('tape_backups_shared: ' || nvl(to_char(tape_backups_shared), 'NULL')); deb('reNorm_state: ' || nvl(to_char(reNorm_state), 'NULL')); deb('resync_reason: ' || nvl(to_char(resync_reason), 'NULL')); deb('scr_key: ' || nvl(to_char(scr_key), 'NULL')); deb('scr_line: ' || nvl(to_char(scr_line), 'NULL')); deb('kccdivts: ' || nvl(to_char(kccdivts), 'NULL')); deb('cntbs: ' || nvl(to_char(cntbs), 'NULL')); deb('last_full_ckp_scn: ' || nvl(to_char(last_full_ckp_scn), 'NULL')); deb('last_con_id_ts#: ' || nvl(to_char(last_con_id_ts#), 'NULL')); deb('last_ts#: ' || nvl(to_char(last_ts#), 'NULL')); deb('last_file#: ' || nvl(to_char(last_file#), 'NULL')); deb('last_thread#: ' || nvl(to_char(last_thread#), 'NULL')); deb('last_ts_recid: ' || nvl(to_char(last_ts_recid), 'NULL')); deb('last_df_recid: ' || nvl(to_char(last_df_recid), 'NULL')); deb('last_tf_recid: ' || nvl(to_char(last_tf_recid), 'NULL')); deb('last_rt_recid: ' || nvl(to_char(last_rt_recid), 'NULL')); deb('last_orl_recid: ' || nvl(to_char(last_orl_recid), 'NULL')); deb('last_conf_recid: ' || nvl(to_char(last_conf_recid), 'NULL')); deb('force_resync2cf: ' || nvl(to_char(force_resync2cf), 'NULL')); deb('last_rlh_recid: ' || nvl(to_char(last_rlh_recid), 'NULL')); deb('last_al_recid: ' || nvl(to_char(last_al_recid), 'NULL')); deb('last_offr_recid: ' || nvl(to_char(last_offr_recid), 'NULL')); deb('last_bs_recid: ' || nvl(to_char(last_bs_recid), 'NULL')); deb('last_bp_recid: ' || nvl(to_char(last_bp_recid), 'NULL')); deb('last_bdf_recid: ' || nvl(to_char(last_bdf_recid), 'NULL')); deb('last_bsf_recid: ' || nvl(to_char(last_bsf_recid), 'NULL')); deb('last_brl_recid: ' || nvl(to_char(last_brl_recid), 'NULL')); deb('last_cdf_recid: ' || nvl(to_char(last_cdf_recid), 'NULL')); deb('last_bcb_recid: ' || nvl(to_char(last_bcb_recid), 'NULL')); deb('last_ccb_recid: ' || nvl(to_char(last_ccb_recid), 'NULL')); deb('last_do_recid: ' || nvl(to_char(last_do_recid), 'NULL')); deb('last_xdf_recid: ' || nvl(to_char(last_xdf_recid), 'NULL')); deb('last_xal_recid: ' || nvl(to_char(last_xal_recid), 'NULL')); deb('last_rsr_recid: ' || nvl(to_char(last_rsr_recid), 'NULL')); deb('last_rout_stamp: ' || nvl(to_char(last_rout_stamp), 'NULL')); deb('last_inst_startup_stamp: ' || nvl(to_char(last_inst_startup_stamp), 'NULL')); deb('lrsr_key: ' || nvl(to_char(lrsr_key), 'NULL')); deb('lrout_skey: ' || nvl(to_char(lrout_skey), 'NULL')); deb('lsession_recid: ' || nvl(to_char(lsession_recid), 'NULL')); deb('lsession_stamp: ' || nvl(to_char(lsession_stamp), 'NULL')); deb('lrman_status_recid: ' || nvl(to_char(lrman_status_recid), 'NULL')); deb('lrman_status_stamp: ' || nvl(to_char(lrman_status_stamp), 'NULL')); deb('krbmror_llength_bytes: ' || nvl(to_char(krbmror_llength_bytes), 'NULL')); deb('last_ic_recid: ' || nvl(to_char(last_ic_recid), 'NULL')); deb('last_reset_scn: ' || nvl(to_char(last_reset_scn), 'NULL')); deb('last_dbinc_key: ' || nvl(to_char(last_dbinc_key), 'NULL')); deb('low_nrsp_recid: ' || nvl(to_char(low_nrsp_recid), 'NULL')); deb('last_nrsp_recid: ' || nvl(to_char(last_nrsp_recid), 'NULL')); deb('last_grsp_recid: ' || nvl(to_char(last_grsp_recid), 'NULL')); deb('last_bcr_recid: ' || nvl(to_char(last_bcr_recid), 'NULL')); deb('last_pdb_recid: ' || nvl(to_char(last_pdb_recid), 'NULL')); deb('last_resync_cksum: ' || nvl(to_char(last_resync_cksum), 'NULL')); deb('Date variables'); deb('this_ckp_time: ' || nvl(to_char(this_ckp_time, 'DD/MM/YYYY HH24:MI:SS'), 'NULL')); deb('last_reset_time: ' || nvl(to_char(last_reset_time, 'DD/MM/YYYY HH24:MI:SS'), 'NULL')); deb('last_cf_version_time: ' || nvl(to_char(last_cf_version_time, 'DD/MM/YYYY HH24:MI:SS'), 'NULL')); deb('Char variables'); deb('last_fname: ' || nvl(last_fname, 'NULL')); deb('last_rspname: '|| nvl(last_rspname, 'NULL')); deb('last_pdb_key: '|| last_pdb_key); deb('this_cf_type: '|| nvl(this_cf_type, 'NULL')); deb('this_db_unique_name: ' || nvl(this_db_unique_name, 'NULL')); deb('Boolean variables'); if debug is NULL then deb('debug is NULL'); elsif scr_glob then deb('debug is TRUE'); else deb('debug is FALSE'); end if; if client_site_aware is NULL then deb('client_site_aware is NULL'); elsif client_site_aware then deb('client_site_aware is TRUE'); else deb('client_site_ware is FALSE'); end if; if scr_glob is NULL then deb('scr_glob is NULL'); elsif scr_glob then deb('scr_glob is TRUE'); else deb('scr_glob is FALSE'); end if; if do_temp_ts_resync is NULL then deb('do_temp_ts_resync is NULL'); elsif do_temp_ts_resync then deb('do_temp_ts_resync is TRUE'); else deb('do_temp_ts_resync is FALSE'); end if; end dumpPkgState; /*--------------------------------------------------* * package private fns required for recover server * *--------------------------------------------------*/ PROCEDURE read_from_http(resp IN OUT utl_http.resp, clobvar IN OUT CLOB) IS data raw(1024); pos Integer; amt Binary_Integer; BEGIN dbms_lob.createtemporary(clobvar, TRUE); pos := 1; BEGIN LOOP utl_http.read_raw(resp, data); amt := length(utl_raw.cast_to_varchar2(data)); dbms_lob.write(clobvar, amt, pos, utl_raw.cast_to_varchar2(data)); pos := pos + amt; END LOOP; EXCEPTION WHEN utl_http.end_of_body THEN NULL; END; END; PROCEDURE display_http_response(resp IN OUT utl_http.resp) IS hdrcnt integer; name varchar2(256); value varchar2(256); BEGIN IF not debug THEN RETURN; END IF; hdrcnt := utl_http.get_header_count(resp); deb('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ '); deb('Response header count = ' || hdrcnt); deb('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ '); loop exit when hdrcnt = 0; utl_http.get_header(resp, hdrcnt, name, value); deb('Hdr# '|| hdrcnt || ' Name= ' || name || ' Value= ' || value); hdrcnt := hdrcnt - 1; end loop; END; PROCEDURE display_clob(val IN CLOB) IS buf varchar2(2048 CHAR); origlen integer; len integer; pos integer; amt integer; BEGIN IF not debug THEN RETURN; END IF; deb('DISPLAY_CLOB BEGIN'); amt := 2048; -- amount to read at a time len := dbms_lob.getlength(val); origlen := len; deb('xmlfile len = ' || len); pos := 1; loop exit when pos > origlen; if len < amt then dbms_lob.read(val, len, pos, buf); pos := pos + len; else dbms_lob.read(val, amt, pos, buf); len := len - amt; pos := pos + amt; end if; -- -- -- end loop; deb('DISPLAY_CLOB END'); END; FUNCTION get_Complete_URL (bktname in varchar2, objname in varchar2, awsr OUT varchar2, parms in varchar2 DEFAULT null) RETURN VARCHAR2 IS complete_url varchar2(2048); aws_resource varchar2(512); BEGIN IF this_amazon_server THEN complete_url := bktname || '.' || this_server_url; ELSE complete_url := this_server_url || '/orssv'; aws_resource := '/orssv'; END IF; IF this_server_url IS NULL THEN raise_application_error(-20999, 'internal error:this_server_url'); END IF; IF this_url_db_unique_name IS NULL THEN raise_application_error(-20999, 'internal error:this_url_db_unique_name'); END IF; complete_url := complete_url || '/rcfile/' || objname || '?' || 'x-DBUName=' || this_url_db_unique_name; if parms is not null then complete_url := complete_url || '&' || parms; end if; aws_resource := aws_resource || '/rcfile/' || objname; awsr := aws_resource; IF debug THEN deb('URL=' || complete_url); deb('awsr=' || awsr); END IF; RETURN complete_url; END get_Complete_URL; /*----------------------------------------------------* * package public fns required for recover server * * The concept of bucket is used only for amazon S3 * *----------------------------------------------------*/ PROCEDURE put_bucket(bktname in varchar2) IS objval CLOB := NULL; BEGIN IF this_amazon_server THEN put_object(bktname, null, null, objval); END IF; END; FUNCTION get_bucket(bktname in varchar2) RETURN CLOB IS BEGIN IF this_amazon_server THEN return get_object(bktname, null); END IF; return NULL; END; PROCEDURE delete_bucket(bktname in varchar2) IS BEGIN IF this_amazon_server THEN delete_object(bktname, null); END IF; END; PROCEDURE utl_httl_12cR1fns(req IN OUT utl_http.req, awsr IN VARCHAR2) IS BEGIN $IF DBMS_DB_VERSION.VERSION < 12 $THEN raise_application_error(-20999, 'internal error: not support database version'); $ELSE IF this_amazon_server then execute immediate 'begin utl_http.set_property( :req, ''aws-canonicalized-resource'', :awsr); end;' using in out req, in awsr; deb('sqlcode after set_property on: ' || sqlcode); execute immediate ' begin utl_http.set_authentication_from_wallet( r => :req, alias => :wallet_alias, scheme => ''AWS''); end;' using in out req, in this_server.wallet_alias; deb('sqlcode after set_authentication_from_wallet on: ' || sqlcode); ELSE execute immediate ' begin utl_http.set_authentication( r => :req, username => :username, password => :password, scheme => ''Digest''); end;' using in out req, in this_server_uname, in this_server_passw; deb('sqlcode after set_authentication on: ' || sqlcode); END IF; $END END; PROCEDURE put_object(bktname in varchar2, objname in varchar2, objtype in varchar2, objval in out CLOB) is req utl_http.req; resp utl_http.resp; len Integer; pos Integer; amt Integer; origlen Integer; buf raw(2048); cbuf varchar2(2048 CHAR); local_response_val CLOB; ct timestamp(0); cdt varchar2(50); awsr varchar2(512); timeout_secs number; retries number := -1; BEGIN IF this_server.server_host IS NULL THEN deb('put_object: this_server.server_host is null'); return; END IF; deb('Enter put_object ' || objname); timeout_secs := this_server.timeout_secs; <> BEGIN retries := retries + 1; deb('retries count is ' || retries); timeout_secs := timeout_secs + retries * timeout_secs; select sys_extract_utc(current_timestamp) into ct from dual; cdt := to_char(ct, 'Dy, DD Mon YYYY HH24:MI:SS') || ' GMT'; utl_http.set_transfer_timeout(timeout_secs); req := utl_http.begin_request(get_Complete_URL(bktname, objname, awsr), 'PUT', utl_http.HTTP_VERSION_1_1); utl_http.set_header(req, 'Date', cdt); if objname is not null then utl_http.set_header(req, 'Content-Type', objtype); end if; utl_httl_12cR1fns( req, awsr); IF objname is null THEN utl_http.set_header(req, 'Content-Length', 0); ELSE dbms_lob.open(objval, dbms_lob.lob_readonly); len := dbms_lob.getlength(objval); deb('Content-length = ' || len); utl_http.set_header(req, 'Content-Length',len); origlen := len; amt := 2048; pos := 1; if lower(objtype) = 'text/xml' then loop exit when pos > origlen; if len < amt then dbms_lob.read(objval, len, pos, cbuf); pos := pos + len; else dbms_lob.read(objval, amt, pos, cbuf); len := len - amt; pos := pos + amt; end if; utl_http.write_raw(req, utl_raw.cast_to_raw(cbuf)); end loop; ELSE loop exit when pos > origlen; if len < amt then dbms_lob.read(objval, len, pos, buf); pos := pos + len; else dbms_lob.read(objval, amt, pos, buf); len := len - amt; pos := pos + amt; end if; utl_http.write_raw(req, buf); end loop; end if; dbms_lob.close(objval); END IF; resp := utl_http.get_response(req); display_http_response(resp); read_from_http(resp, local_response_val); display_clob(local_response_val); utl_http.end_response(resp); deb('Exit put_object'); EXCEPTION WHEN Utl_Http.request_failed THEN deb ('Request_Failed:' || Utl_Http.get_detailed_sqlerrm); Utl_Http.end_request (req); WHEN Utl_Http.http_server_error THEN deb ('Http_Server_Error: ' || Utl_Http.get_detailed_sqlerrm); Utl_Http.end_request (req); WHEN Utl_Http.http_client_error THEN deb ('Http_Client_Error: ' || Utl_Http.get_detailed_sqlerrm); Utl_Http.end_request (req); WHEN OTHERS THEN deb('HTTP Other error:' || sqlerrm); if retries <= 5 and substr(sqlerrm, 1, 9) = 'ORA-29276' then goto retry_request_again; else raise; end if; END; END put_object; PROCEDURE delete_object(bktname in varchar2, objname in varchar2) is req utl_http.req; resp utl_http.resp; tmpfile CLOB := NULL; ct timestamp(0); cdt varchar2(50); awsr varchar2(512); BEGIN IF this_server.server_host IS NULL THEN deb('delete_object: this_server.server_host is null'); return; END IF; deb('Enter delete_object'); select sys_extract_utc(current_timestamp) into ct from dual; cdt := to_char(ct, 'Dy, DD Mon YYYY HH24:MI:SS') || ' GMT'; utl_http.set_transfer_timeout(this_server.timeout_secs); req := utl_http.begin_request(get_Complete_URL(bktname, objname, awsr), 'DELETE', utl_http.HTTP_VERSION_1_1); utl_http.set_header(req, 'Date', cdt); utl_httl_12cR1fns( req, awsr); resp := utl_http.get_response(req); display_http_response(resp); read_from_http(resp, tmpfile); display_clob(tmpfile); utl_http.end_response(resp); deb('Exit delete_object'); EXCEPTION WHEN Utl_Http.request_failed THEN deb ('Request_Failed:' || Utl_Http.get_detailed_sqlerrm); Utl_Http.end_request (req); WHEN Utl_Http.http_server_error THEN deb ('Http_Server_Error: ' || Utl_Http.get_detailed_sqlerrm); Utl_Http.end_request (req); WHEN Utl_Http.http_client_error THEN deb ('Http_Client_Error: ' || Utl_Http.get_detailed_sqlerrm); Utl_Http.end_request (req); return; WHEN OTHERS THEN deb('HTTP Other error: ' || sqlerrm); raise; END delete_object; FUNCTION get_object(bktname in varchar2, objname in varchar2, parms in varchar2 DEFAULT null) return CLOB is req utl_http.req; resp utl_http.resp; objval CLOB := NULL; ct timestamp(0); cdt varchar2(50); awsr varchar2(512); timeout_secs number; retries number := -1; begin IF this_server.server_host IS NULL THEN deb('get_object: this_server.server_host is null'); return NULL; END IF; deb('Enter get_object ' || objname); timeout_secs := this_server.timeout_secs; <> BEGIN retries := retries + 1; deb('retries count is ' || retries); timeout_secs := timeout_secs + retries * timeout_secs; select sys_extract_utc(current_timestamp) into ct from dual; cdt := to_char(ct, 'Dy, DD Mon YYYY HH24:MI:SS') || ' GMT'; utl_http.set_transfer_timeout(timeout_secs); req := utl_http.begin_request( get_Complete_URL(bktname,objname,awsr,parms), 'GET', utl_http.HTTP_VERSION_1_1); utl_http.set_header(req, 'Date', cdt); utl_httl_12cR1fns( req, awsr); resp := utl_http.get_response(req); display_http_response(resp); read_from_http(resp, objval); display_clob(objval); utl_http.end_response(resp); IF dbms_lob.getlength(objval) > 0 then IF objname is null THEN delete from rcfile where name = parms; insert into rcfile(rcfile_key, creation_time, name, xmldoc) values (rman_seq.nextval, sys_extract_utc(systimestamp), parms, XMLType.createXML(objval)); deb('got rows for ' || parms); commitChanges('get_object-1'); ELSE delete from rcfile where name = objname; insert into rcfile(rcfile_key, creation_time, name, xmldoc) values (rman_seq.nextval, sys_extract_utc(systimestamp),objname, XMLType.createXML(objval)); deb('got rows for ' || objname); commitChanges('get_object-2'); END IF; END IF; deb('Exit get_object'); return objval; EXCEPTION WHEN Utl_Http.request_failed THEN deb ('Request_Failed:' || Utl_Http.get_detailed_sqlerrm); Utl_Http.end_request (req); WHEN Utl_Http.http_server_error THEN deb ('Http_Server_Error: ' || Utl_Http.get_detailed_sqlerrm); Utl_Http.end_request (req); WHEN Utl_Http.http_client_error THEN deb ('Http_Client_Error: ' || Utl_Http.get_detailed_sqlerrm); Utl_Http.end_request (req); WHEN OTHERS THEN deb('HTTP Other error: ' || sqlerrm); if retries <= 5 and substr(sqlerrm, 1, 9) = 'ORA-29276' then goto retry_request_again; else raise; end if; END; END get_object; PROCEDURE displayRCWatermarks(cmt IN VARCHAR2, wmrec IN RC_WATERMARKS%ROWTYPE) IS BEGIN IF NOT debug THEN RETURN; END IF; deb(cmt || 'DB_KEY=' || wmrec.DB_KEY); deb(cmt || 'DB_UNIQUE_NAME=' || wmrec.DB_UNIQUE_NAME); deb(cmt || 'RS_VERSION_STAMP=' || wmrec.RS_VERSION_STAMP); deb(cmt || 'HIGH_BP_RECID=' || wmrec.HIGH_BP_RECID); deb(cmt || 'HIGH_DO_KEY=' || wmrec.HIGH_DO_KEY); deb(cmt || 'CF_VERSION_STAMP=' || wmrec.CF_VERSION_STAMP); deb(cmt || 'HIGH_DF_RECID=' || wmrec.HIGH_DF_RECID); deb(cmt || 'HIGH_TS_RECID=' || wmrec.HIGH_TS_RECID); deb(cmt || 'HIGH_TF_RECID=' || wmrec.HIGH_TF_RECID); deb(cmt || 'HIGH_OFFR_RECID=' || wmrec.HIGH_OFFR_RECID); END displayRCWatermarks; PROCEDURE displayRCSite(cmt IN VARCHAR2, siterec IN RC_SITE%ROWTYPE) IS BEGIN IF NOT debug THEN RETURN; END IF; deb(cmt || 'SITE_KEY=' || siterec.SITE_KEY); deb(cmt || 'DB_KEY=' || siterec.DB_KEY); deb(cmt || 'DATABASE_ROLE=' || siterec.DATABASE_ROLE); deb(cmt || 'CF_CREATE_TIME=' || siterec.CF_CREATE_TIME); deb(cmt || 'DB_UNIQUE_NAME=' || siterec.DB_UNIQUE_NAME); deb(cmt || 'HIGH_CONF_RECID=' || siterec.HIGH_CONF_RECID); deb(cmt || 'FORCE_RESYNC2CF=' || siterec.FORCE_RESYNC2CF); deb(cmt || 'HIGH_ROUT_STAMP=' || siterec.HIGH_ROUT_STAMP); deb(cmt || 'INST_STARTUP_STAMP=' || siterec.INST_STARTUP_STAMP); deb(cmt || 'LAST_KCCDIVTS=' || stamp2date(siterec.LAST_KCCDIVTS)); deb(cmt || 'HIGH_IC_RECID=' || siterec.HIGH_IC_RECID); deb(cmt || 'DBINC_KEY=' || siterec.DBINC_KEY); deb(cmt || 'CKP_SCN=' || siterec.CKP_SCN); deb(cmt || 'FULL_CKP_CF_SEQ=' || siterec.FULL_CKP_CF_SEQ); deb(cmt || 'JOB_CKP_CF_SEQ=' || siterec.JOB_CKP_CF_SEQ); deb(cmt || 'HIGH_TS_RECID=' || siterec.HIGH_TS_RECID); deb(cmt || 'HIGH_DF_RECID=' || siterec.HIGH_DF_RECID); deb(cmt || 'HIGH_RT_RECID=' || siterec.HIGH_RT_RECID); deb(cmt || 'HIGH_ORL_RECID=' || siterec.HIGH_ORL_RECID); deb(cmt || 'HIGH_OFFR_RECID=' || siterec.HIGH_OFFR_RECID); deb(cmt || 'HIGH_RLH_RECID=' || siterec.HIGH_RLH_RECID); deb(cmt || 'HIGH_AL_RECID=' || siterec.HIGH_AL_RECID); deb(cmt || 'HIGH_BS_RECID=' || siterec.HIGH_BS_RECID); deb(cmt || 'HIGH_BP_RECID=' || siterec.HIGH_BP_RECID); deb(cmt || 'HIGH_BDF_RECID=' || siterec.HIGH_BDF_RECID); deb(cmt || 'HIGH_CDF_RECID=' || siterec.HIGH_CDF_RECID); deb(cmt || 'HIGH_BRL_RECID=' || siterec.HIGH_BRL_RECID); deb(cmt || 'HIGH_BCB_RECID=' || siterec.HIGH_BCB_RECID); deb(cmt || 'HIGH_CCB_RECID=' || siterec.HIGH_CCB_RECID); deb(cmt || 'HIGH_DO_RECID=' || siterec.HIGH_DO_RECID); deb(cmt || 'HIGH_PC_RECID=' || siterec.HIGH_PC_RECID); deb(cmt || 'HIGH_BSF_RECID=' || siterec.HIGH_BSF_RECID); deb(cmt || 'HIGH_RSR_RECID=' || siterec.HIGH_RSR_RECID); deb(cmt || 'HIGH_TF_RECID=' || siterec.HIGH_TF_RECID); deb(cmt || 'HIGH_GRSP_RECID=' || siterec.HIGH_GRSP_RECID); deb(cmt || 'HIGH_NRSP_RECID=' || siterec.HIGH_NRSP_RECID); deb(cmt || 'HIGH_BCR_RECID=' || siterec.HIGH_BCR_RECID); deb(cmt || 'LOW_BCR_RECID=' || siterec.LOW_BCR_RECID); deb(cmt || 'BCR_IN_USE=' || siterec.BCR_IN_USE); deb(cmt || 'HIGH_PDB_RECID=' || siterec.HIGH_PDB_RECID); deb(cmt || 'HIGH_PIC_RECID=' || siterec.HIGH_PIC_RECID); END displayRCSite; PROCEDURE displayRCDatabaseIncarnation (cmt IN VARCHAR2, icrec IN RC_DATABASE_INCARNATION%ROWTYPE) IS BEGIN IF NOT debug THEN RETURN; END IF; deb(cmt || 'DB_KEY=' || icrec.DB_KEY); deb(cmt || 'DBID=' || icrec.DBID); deb(cmt || 'DBINC_KEY=' || icrec.DBINC_KEY); deb(cmt || 'NAME=' || icrec.NAME); deb(cmt || 'RESETLOGS_CHANGE#=' || icrec.RESETLOGS_CHANGE#); deb(cmt || 'RESETLOGS_TIME=' || icrec.RESETLOGS_TIME); deb(cmt || 'CURRENT_INCARNATION=' || icrec.CURRENT_INCARNATION); deb(cmt || 'PARENT_DBINC_KEY=' || icrec.PARENT_DBINC_KEY); deb(cmt || 'PRIOR_RESETLOGS_CHANGE#=' || icrec.PRIOR_RESETLOGS_CHANGE#); deb(cmt || 'PRIOR_RESETLOGS_TIME=' || icrec.PRIOR_RESETLOGS_TIME); deb(cmt || 'STATUS=' || icrec.STATUS); deb(cmt || 'REG_DB_UNIQUE_NAME=' || icrec.REG_DB_UNIQUE_NAME); deb(cmt || 'CON_ID=' || icrec.CON_ID); deb(cmt || 'GUID=' || icrec.GUID); END displayRCDatabaseIncarnation; PROCEDURE writeForWatermarks(bktname IN VARCHAR2 DEFAULT NULL, full_ckpt IN BOOLEAN) IS v_ctx DBMS_XMLGen.ctxHandle; v_xml CLOB; v_xml_tmp CLOB; type record_sql_type is table of varchar2(2048) index by binary_integer; type record_tbl_type is table of varchar2(30) index by binary_integer; record_sql record_sql_type; record_tbl record_tbl_type; my_dbid number; write_xml_filename rcfile.name%TYPE; BEGIN -- IF this_server.server_host IS NULL THEN deb('writeForWaterMarks: this_server.server_host is null'); return; END IF; IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; SELECT DBID INTO MY_DBID FROM RC_DATABASE WHERE DB_KEY=this_db_key; record_tbl(0) := 'RC_DATABASE'; record_sql(0) := 'SELECT * FROM RC_DATABASE ' || 'WHERE DB_KEY = ' || this_db_key; record_tbl(1) := 'RC_DATABASE_INCARNATION'; record_sql(1) := 'SELECT * FROM RC_DATABASE_INCARNATION ' || 'WHERE DB_KEY = ' || this_db_key; record_tbl(2) := 'RC_SITE'; IF full_ckpt THEN deb('writeForWatermarks for remote readFixedSections'); -- -- -- record_sql(2) := 'SELECT -1 high_bp_recid FROM RCI_SITE ' || 'WHERE DB_KEY = ' || this_db_key || ' AND SITE_KEY = ' || this_site_key; ELSE deb('writeForWatermarks for local readBackupSections'); record_sql(2) := 'SELECT * FROM RCI_SITE ' || 'WHERE DB_KEY = ' || this_db_key || ' AND SITE_KEY = ' || this_site_key; END IF; v_xml := this_xml_signature_beg; dbms_session.set_nls('NLS_DATE_FORMAT','''DD-MM-YYYY HH24:MI:SS'''); FOR idx in 0..2 LOOP deb('writing XML file for ' || idx); deb('executing query:'|| record_sql(idx)); v_ctx := DBMS_XMLGen.newContext(record_sql(idx)); -- DBMS_XMLGen.setRowsetTag(v_ctx, 'TABLE_' || record_tbl(idx)); v_xml_tmp := DBMS_XMLGen.GetXML(v_ctx); DBMS_XMLGen.closeContext(v_ctx); deb('XML len for ' || idx || '=' || DBMS_LOB.GETLENGTH(v_xml_tmp)); IF v_xml_tmp IS NOT NULL THEN DBMS_LOB.COPY(v_xml, v_xml_tmp, DBMS_LOB.LOBMAXSIZE, DBMS_LOB.GETLENGTH(v_xml), DBMS_LOB.INSTR(v_xml_tmp, '')); END IF; END LOOP; v_xml := v_xml || this_xml_signature_end; write_xml_filename := this_forwatermarks || my_dbid || '.xml'; put_bucket(bktname); put_object(bktname, write_xml_filename, 'text/xml', v_xml); END writeForWatermarks; PROCEDURE rsReadWaterMarks(bktname IN VARCHAR2 DEFAULT NULL) IS xml_filename RCFILE.NAME%TYPE; my_dbid NUMBER; v_xml_tmp CLOB; v_ctx DBMS_XMLGen.ctxHandle; verrec RC_RCVER%ROWTYPE; curr_inc RC_DATABASE_INCARNATION%ROWTYPE; wmrec RC_WATERMARKS%ROWTYPE; CURSOR rc_rcver_c IS SELECT VERSION FROM "_RS_RC_RCVER_" WHERE RS_RCFILE_NAME = xml_filename; CURSOR rc_watermarks_c IS SELECT DB_KEY, DB_UNIQUE_NAME, RS_VERSION_STAMP, HIGH_BP_RECID, HIGH_DO_KEY, CF_VERSION_STAMP, HIGH_DF_RECID, HIGH_TS_RECID, HIGH_TF_RECID, HIGH_OFFR_RECID FROM "_RS_RC_WATERMARKS_" WHERE RS_RCFILE_NAME = xml_filename; CURSOR rc_database_incarnation_c IS SELECT DB_KEY, DBID, DBINC_KEY, NAME, RESETLOGS_CHANGE#, RESETLOGS_TIME, CURRENT_INCARNATION, PARENT_DBINC_KEY, PRIOR_RESETLOGS_CHANGE#, PRIOR_RESETLOGS_TIME, STATUS, REG_DB_UNIQUE_NAME, CON_ID, GUID FROM "_RS_RC_DATABASE_INCARNATION_" WHERE RS_RCFILE_NAME = xml_filename AND STATUS = 'CURRENT'; upstream_dbrec RCI_RA_UPSTREAM_DATABASE%ROWTYPE; CURSOR rci_ra_upstream_database_c IS SELECT DBID, NAME FROM "_RS_RCI_RA_UPSTREAM_DATABASE_" WHERE RS_RCFILE_NAME = xml_filename; CURSOR local_current_incarnation_c IS SELECT * FROM RC_DATABASE_INCARNATION WHERE DBINC_KEY = this_dbinc_key; local_curr_inc RC_DATABASE_INCARNATION%ROWTYPE; BEGIN -- IF this_server.server_host IS NULL THEN deb('rsReadWaterMarks: this_server.server_host is null'); return; END IF; IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; SELECT DBID INTO MY_DBID FROM RC_DATABASE WHERE DB_KEY=this_db_key; -- -- xml_filename := this_watermarks || my_dbid || '.xml'; v_xml_tmp := get_object(bktname, xml_filename); -- dbms_session.set_nls('NLS_DATE_FORMAT','''DD-MM-YYYY HH24:MI:SS'''); -- OPEN rc_rcver_c; FETCH rc_rcver_c INTO verrec; CLOSE rc_rcver_c; -- OPEN rc_watermarks_c; FETCH rc_watermarks_c INTO wmrec; CLOSE rc_watermarks_c; -- OPEN rc_database_incarnation_c; FETCH rc_database_incarnation_c INTO curr_inc; CLOSE rc_database_incarnation_c; -- OPEN local_current_incarnation_c; FETCH local_current_incarnation_c INTO local_curr_inc; CLOSE local_current_incarnation_c; -- OPEN rci_ra_upstream_database_c; FETCH rci_ra_upstream_database_c INTO upstream_dbrec; CLOSE rci_ra_upstream_database_c; -- IF curr_inc.dbid <> rsReadWaterMarks.my_dbid THEN raise_application_error(-20141, 'Target database id mismatch with registered database in ORS'); END IF; -- -- -- -- v_ctx := DBMS_XMLGen.newContext('SELECT DB_KEY, DB_UNIQUE_NAME, ' || 'RS_VERSION_STAMP,'|| 'HIGH_BP_RECID,'|| 'HIGH_DO_KEY, CF_VERSION_STAMP,'|| 'HIGH_DF_RECID, '|| 'HIGH_TS_RECID, HIGH_TF_RECID, HIGH_OFFR_RECID '|| 'FROM "_RS_RC_WATERMARKS_" '|| 'WHERE RS_RCFILE_NAME = ''' || xml_filename || ''''); -- DBMS_XMLGen.setRowsetTag(v_ctx, 'TABLE_RC_WATERMARKS'); this_v_wmrec := DBMS_XMLGen.GetXML(v_ctx); DBMS_XMLGen.closeContext(v_ctx); IF upstream_dbrec.name IS NULL THEN raise_application_error(-20999, 'internal error: no rows for upstreamdb'); END IF; this_verrec := verrec; this_curr_inc := curr_inc; this_wmrec := wmrec; this_upstream_dbrec := upstream_dbrec; IF debug THEN deb('rsReadWatermarks: remote reconcile dbname=' || this_upstream_dbrec.name); deb('this_curr_inc.dbid: ' || this_curr_inc.dbid); displayRCWatermarks('rsReadWatermarks remote:', this_wmrec); displayRCDatabaseIncarnation('rsReadWatermarks remote:', curr_inc); displayRCDatabaseIncarnation('rsReadWatermarks local:', local_curr_inc); END IF; -- -- IF curr_inc.resetlogs_change# <> local_curr_inc.resetlogs_change# OR curr_inc.resetlogs_time <> local_curr_inc.resetlogs_time THEN deb('Clearing this_wmrec.cf_version_stamp so all fixed records are sent'); this_wmrec.cf_version_stamp := NULL; END IF; END rsReadWaterMarks; -- PROCEDURE rsWriteWaterMarks (input_xml_filename IN VARCHAR2, bktname IN VARCHAR2 DEFAULT NULL) IS v_ctx DBMS_XMLGen.ctxHandle; v_xml CLOB; v_xml_tmp CLOB; type record_sql_type is table of varchar2(2048) index by binary_integer; type record_tbl_type is table of varchar2(30) index by binary_integer; record_sql record_sql_type; record_tbl record_tbl_type; my_dbid number; l_max_do_key number; l_high_do_key number; write_xml_filename rcfile.name%TYPE; curr_inc RC_DATABASE_INCARNATION%ROWTYPE; CURSOR rc_database_incarnation_c(curr_inc_val IN VARCHAR2 DEFAULT NULL) IS SELECT DB_KEY, DBID, DBINC_KEY, NAME, RESETLOGS_CHANGE#, RESETLOGS_TIME, CURRENT_INCARNATION, PARENT_DBINC_KEY, PRIOR_RESETLOGS_CHANGE#, PRIOR_RESETLOGS_TIME, STATUS, REG_DB_UNIQUE_NAME, CON_ID, GUID FROM "_RS_RC_DATABASE_INCARNATION_" WHERE RS_RCFILE_NAME = input_xml_filename AND (curr_inc_val IS NULL OR CURRENT_INCARNATION = curr_inc_val); CURSOR rc_site_c IS SELECT SITE_KEY, DB_KEY, DATABASE_ROLE, CF_CREATE_TIME, DB_UNIQUE_NAME, HIGH_CONF_RECID, FORCE_RESYNC2CF, HIGH_ROUT_STAMP, INST_STARTUP_STAMP, LAST_KCCDIVTS, HIGH_IC_RECID, DBINC_KEY, CKP_SCN, FULL_CKP_CF_SEQ, JOB_CKP_CF_SEQ, HIGH_TS_RECID, HIGH_DF_RECID, HIGH_RT_RECID, HIGH_ORL_RECID, HIGH_OFFR_RECID, HIGH_RLH_RECID, HIGH_AL_RECID, HIGH_BS_RECID, HIGH_BP_RECID, HIGH_BDF_RECID, HIGH_CDF_RECID, HIGH_BRL_RECID, HIGH_BCB_RECID, HIGH_CCB_RECID, HIGH_DO_RECID, HIGH_PC_RECID, HIGH_BSF_RECID, HIGH_RSR_RECID, HIGH_TF_RECID, HIGH_GRSP_RECID, HIGH_NRSP_RECID, HIGH_BCR_RECID, LOW_BCR_RECID, BCR_IN_USE, HIGH_PDB_RECID, HIGH_PIC_RECID FROM "_RS_RC_SITE_" WHERE RS_RCFILE_NAME = input_xml_filename; l_stmts NUMBER; BEGIN -- my_dbid := to_number(substr(input_xml_filename, length(this_forwatermarks)+1, instr(input_xml_filename,'.xml')-1 -length(this_forwatermarks))); deb('rsWriteWaterMarks:remote my_dbid=' || my_dbid); -- dbms_session.set_nls('NLS_DATE_FORMAT','''DD-MM-YYYY HH24:MI:SS'''); -- OPEN rc_database_incarnation_c(curr_inc_val => 'YES'); FETCH rc_database_incarnation_c INTO curr_inc; CLOSE rc_database_incarnation_c; -- OPEN rc_site_c; FETCH rc_site_c INTO this_rsiterec; CLOSE rc_site_c; IF debug THEN displayRCSite('rsWriteWaterMarks:remote ', this_rsiterec); END IF; -- IF curr_inc.dbid <> my_dbid THEN raise_application_error(-20141, 'Target database id mismatch with registered database in ORS'); END IF; record_tbl(0) := 'RCI_RA_UPSTREAM_DATABASE'; record_sql(0) := 'SELECT * FROM RCI_RA_UPSTREAM_DATABASE'; record_tbl(1) := 'RC_RCVER'; record_sql(1) := 'SELECT * FROM RC_RCVER '; l_stmts := 1; -- BEGIN SELECT DB_KEY INTO this_db_key FROM DB WHERE db_id = my_dbid; deb('rsWriteWaterMarks:this_db_key=' || this_db_key); -- dbms_session.set_nls('NLS_DATE_FORMAT','''DD-MM-YYYY HH24:MI:SS'''); record_tbl(2) := 'RC_DATABASE_INCARNATION'; record_sql(2) := 'SELECT * FROM RC_DATABASE_INCARNATION ' || 'WHERE DB_KEY = ' || this_db_key; record_tbl(3) := 'RC_WATERMARKS'; record_sql(3) := 'SELECT * FROM RC_WATERMARKS ' || 'WHERE DB_KEY = ' || this_db_key; l_stmts := 3; -- BEGIN SELECT high_do_key INTO l_high_do_key FROM watermarks WHERE db_key = this_db_key; SELECT curr_value INTO l_max_do_key FROM do_seq WHERE db_key = this_db_key; IF l_max_do_key > l_high_do_key THEN UPDATE watermarks SET high_do_key = l_max_do_key WHERE db_key = this_db_key; commitChanges('rsWritewaterMarks, set high_do_key='||l_max_do_key); END IF; EXCEPTION WHEN NO_DATA_FOUND THEN NULL; END; EXCEPTION WHEN NO_DATA_FOUND THEN deb('rsWritewaterMarks: database with dbid=' || my_dbid || ' not found in recovery catalog'); END; -- v_xml := this_xml_signature_beg; FOR idx in 0..l_stmts LOOP deb('writing XML file for ' || idx); deb('executing query:'|| record_sql(idx)); v_ctx := DBMS_XMLGen.newContext(record_sql(idx)); -- DBMS_XMLGen.setRowsetTag(v_ctx, 'TABLE_' || record_tbl(idx)); v_xml_tmp := DBMS_XMLGen.GetXML(v_ctx); DBMS_XMLGen.closeContext(v_ctx); deb('XML len for ' || idx || '=' || DBMS_LOB.GETLENGTH(v_xml_tmp)); IF v_xml_tmp IS NOT NULL THEN DBMS_LOB.COPY(v_xml, v_xml_tmp, DBMS_LOB.LOBMAXSIZE, DBMS_LOB.GETLENGTH(v_xml), DBMS_LOB.INSTR(v_xml_tmp, '')); END IF; END LOOP; v_xml := v_xml || this_xml_signature_end; -- write_xml_filename := this_watermarks || my_dbid || '.xml'; IF this_amazon_server THEN put_object(null /*bktname */, write_xml_filename, 'text/xml', v_xml); ELSE delete rcfile where name = write_xml_filename; insert into rcfile(rcfile_key, creation_time, name, xmldoc) values (rman_seq.nextval, sys_extract_utc(systimestamp), write_xml_filename, XMLType.createXML(v_xml)); END IF; -- IF this_rsiterec.high_bp_recid >= 0 THEN deb('rsWritewaterMarks called for remote readBackupSections'); writeBackupSections(input_xml_filename, bktname); ELSE deb('rsWritewaterMarks called for local readFixedSections'); END IF; -- IF this_amazon_server THEN delete_object(null, this_forwatermarks || my_dbid || '.xml'); ELSE delete rcfile where name = this_forwatermarks || my_dbid || '.xml'; END IF; commitChanges('rsWritewaterMarks(suc)'); EXCEPTION WHEN OTHERS THEN deb('rsWriteWatermarks(fail)- rollback (release locks):' || sqlerrm); rollback; raise; END rsWriteWaterMarks; PROCEDURE writeFixedSections(bktname IN VARCHAR2 DEFAULT NULL) IS v_ctx DBMS_XMLGen.ctxHandle; v_xml CLOB; v_xml_tmp CLOB; type record_sql_type is table of varchar2(2048) index by binary_integer; type record_tbl_type is table of varchar2(30) index by binary_integer; type record_watermarks_type is table of number index by binary_integer; record_sql record_sql_type; record_tbl record_tbl_type; read_wm record_watermarks_type; curr_wm record_watermarks_type; my_dbid number; write_xml_filename rcfile.name%TYPE; full_ckp_key number; curr_dbinc_key number; full_ckp_site_key number; noderec node%ROWTYPE; BEGIN deb('writeFixedSections - enter'); -- IF this_server.server_host IS NULL THEN deb('writeFixedSections: this_server.server_host is null'); return; END IF; IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; -- -- BEGIN writeForWatermarks(bktname, TRUE); rsReadWaterMarks(bktname); EXCEPTION WHEN OTHERS THEN deb('writeFixedSections: error during watermarks read:' || sqlerrm); RAISE; END; -- BEGIN SELECT ckp_key, site_key INTO full_ckp_key, full_ckp_site_key FROM RC_CHECKPOINT WHERE CKP_KEY = (SELECT MAX(CKP_KEY) FROM RC_CHECKPOINT WHERE DB_KEY = this_db_key AND CKP_TYPE = 'FULL'); EXCEPTION WHEN no_data_found THEN deb('writeFixedSections: no full resync yet done for this database'); return; END; SELECT dbinc_key INTO curr_dbinc_key FROM RC_DATABASE WHERE DB_KEY = this_db_key; SELECT * INTO noderec FROM NODE WHERE SITE_KEY=full_ckp_site_key; deb('noderec.cf_version_stamp: ' || noderec.cf_create_time); deb('noderec.db_unique_name: ' || noderec.db_unique_name); deb('noderec.high_df_recid: ' || noderec.high_df_recid); deb('noderec.high_tf_recid: ' || noderec.high_tf_recid); deb('noderec.high_ts_recid: ' || noderec.high_ts_recid); select nvl(max(offr_key), 0) INTO noderec.high_offr_recid from rc_offline_range where db_key=this_db_key; deb('noderec.high_offr_recid: ' || noderec.high_offr_recid); -- IF noderec.cf_create_time = this_wmrec.cf_version_stamp AND noderec.high_ts_recid = this_wmrec.high_ts_recid AND noderec.high_df_recid = this_wmrec.high_df_recid AND noderec.high_tf_recid = this_wmrec.high_tf_recid AND noderec.high_offr_recid = this_wmrec.high_offr_recid THEN deb('writeFixedSections: No event of interest occured at catalog'); return; END IF; IF noderec.cf_create_time <> this_wmrec.cf_version_stamp OR this_wmrec.cf_version_stamp IS NULL THEN deb('Clearing fixed record section watermarks'); this_wmrec.high_df_recid := NULL; this_wmrec.high_ts_recid := NULL; this_wmrec.high_tf_recid := NULL; this_wmrec.high_offr_recid := NULL; END IF; SELECT DBID INTO MY_DBID FROM RC_DATABASE WHERE DB_KEY=this_db_key; record_tbl(0) := 'RC_DATABASE'; record_sql(0) := 'SELECT * FROM RC_DATABASE ' || 'WHERE DB_KEY = ' || this_db_key; read_wm(0) := -1; /* no watermark check for this record */ record_tbl(1) := 'RC_DATABASE_INCARNATION'; record_sql(1) := 'SELECT * FROM RC_DATABASE_INCARNATION ' || 'WHERE DB_KEY = ' || this_db_key; read_wm(1) := -1; /* no watermark check for this record */ record_tbl(2) := 'RC_SITE'; record_sql(2) := 'SELECT * FROM RCI_SITE ' || 'WHERE DB_KEY = ' || this_db_key || ' AND SITE_KEY = ' || full_ckp_site_key; read_wm(2) := -1; /* no watermark check for this record */ record_tbl(3) := 'RC_RMAN_CONFIGURATION'; record_sql(3) := 'SELECT * FROM RC_RMAN_CONFIGURATION ' || 'WHERE DB_KEY = ' || this_db_key || ' AND (SITE_KEY = ' || full_ckp_site_key || ' OR SITE_KEY = 0)'; read_wm(3) := -1; /* no watermark check for this record */ record_tbl(4) := 'RC_TABLESPACE'; record_sql(4) := 'SELECT * FROM RC_TABLESPACE ' || 'WHERE DB_KEY = ' || this_db_key || ' AND DBINC_KEY = ' || curr_dbinc_key || ' AND DROP_CHANGE# IS NULL'; read_wm(4) := -1; /* watermark check only if required */ IF this_wmrec.cf_version_stamp = noderec.cf_create_time THEN read_wm(4) := this_wmrec.high_ts_recid; curr_wm(4) := noderec.high_ts_recid; END IF; record_tbl(5) := 'RC_REDO_THREAD'; record_sql(5) := 'SELECT * FROM RC_REDO_THREAD ' || 'WHERE DB_KEY = ' || this_db_key || ' AND DBINC_KEY = ' || curr_dbinc_key; read_wm(5) := -1; /* no watermark check for this record */ record_tbl(6) := 'RCI_DATAFILE'; record_sql(6) := 'SELECT * FROM RCI_DATAFILE ' || 'WHERE DB_KEY = ' || this_db_key || ' AND DBINC_KEY = ' || curr_dbinc_key || ' AND SITE_KEY = ' || full_ckp_site_key || ' AND DROP_CHANGE# IS NULL'; read_wm(6) := -1; /* watermark check only if required */ IF this_wmrec.cf_version_stamp = noderec.cf_create_time THEN read_wm(6) := this_wmrec.high_df_recid; curr_wm(6) := noderec.high_df_recid; END IF; record_tbl(7) := 'RCI_TEMPFILE'; record_sql(7) := 'SELECT * FROM RCI_TEMPFILE ' || 'WHERE DB_KEY = ' || this_db_key || ' AND DBINC_KEY = ' || curr_dbinc_key || ' AND SITE_KEY = ' || full_ckp_site_key || ' AND DROP_CHANGE# IS NULL'; read_wm(7) := -1; /* watermark check only if required */ IF this_wmrec.cf_version_stamp = noderec.cf_create_time THEN read_wm(7) := this_wmrec.high_tf_recid; curr_wm(7) := noderec.high_tf_recid; END IF; record_tbl(8) := 'RC_REDO_LOG'; record_sql(8) := 'SELECT * FROM RC_REDO_LOG ' || 'WHERE DB_KEY = ' || this_db_key || ' AND DBINC_KEY = ' || curr_dbinc_key || ' AND SITE_KEY = ' || full_ckp_site_key; read_wm(8) := -1; /* no watermark check for this record */ record_tbl(9) := 'RC_CHECKPOINT'; record_sql(9) := 'SELECT * FROM RC_CHECKPOINT ' || 'WHERE CKP_KEY = ' || full_ckp_key; read_wm(9) := -1; /* no watermark check for this record */ record_tbl(10) := 'RC_OFFLINE_RANGE'; record_sql(10) := 'SELECT * FROM RC_OFFLINE_RANGE ' || 'WHERE DB_KEY = ' || this_db_key || ' AND OFFR_KEY >'||nvl(this_wmrec.high_offr_recid,0); read_wm(10) := -1; /* watermark check not required, send new records */ record_tbl(11) := 'RCI_PDBS'; record_sql(11) := 'SELECT * FROM RCI_PDBS ' || 'WHERE DB_KEY = ' || this_db_key; read_wm(11) := -1; /* no watermark check for this record */ record_tbl(12) := 'RC_PLUGGABLE_DATABASE_INC'; record_sql(12) := 'SELECT * FROM RC_PLUGGABLE_DATABASE_INC ' || 'WHERE DB_KEY = ' || this_db_key; read_wm(12) := -1; /* no watermark check for this record */ record_tbl(13) := 'RCI_RA_UPSTREAM_DATABASE'; record_sql(13) := 'SELECT * FROM RCI_RA_UPSTREAM_DATABASE'; read_wm(13) := -1; /* no watermark check for this record */ -- v_xml := this_xml_signature_beg; dbms_session.set_nls('NLS_DATE_FORMAT','''DD-MM-YYYY HH24:MI:SS'''); FOR idx in 0..13 LOOP deb('writing XML file for ' || idx); IF read_wm (idx) <> -1 AND read_wm(idx) <> 0 AND read_wm(idx) = curr_wm(idx) THEN deb('skipping query:'|| record_sql(idx)); ELSE deb('executing query:'|| record_sql(idx)); v_ctx := DBMS_XMLGen.newContext(record_sql(idx)); -- DBMS_XMLGen.setRowsetTag(v_ctx, 'TABLE_' || record_tbl(idx)); v_xml_tmp := DBMS_XMLGen.GetXML(v_ctx); DBMS_XMLGen.closeContext(v_ctx); deb('XML len for ' || idx || '=' || DBMS_LOB.GETLENGTH(v_xml_tmp)); IF v_xml_tmp IS NOT NULL THEN DBMS_LOB.COPY(v_xml, v_xml_tmp, DBMS_LOB.LOBMAXSIZE, DBMS_LOB.GETLENGTH(v_xml), DBMS_LOB.INSTR(v_xml_tmp, '')); END IF; END IF; END LOOP; deb('XML len for v_wmrec=' || DBMS_LOB.GETLENGTH(this_v_wmrec)); IF this_v_wmrec IS NOT NULL THEN DBMS_LOB.COPY(v_xml, this_v_wmrec, DBMS_LOB.LOBMAXSIZE, DBMS_LOB.GETLENGTH(v_xml), DBMS_LOB.INSTR(this_v_wmrec, '')); ELSE deb('writeFixedSections: no watermarks added to uploaded file'); END IF; v_xml := v_xml || this_xml_signature_end; -- write_xml_filename := this_database || my_dbid || '.xml'; put_bucket(bktname); put_object(bktname, write_xml_filename, 'text/xml', v_xml); -- -- -- -- -- -- -- -- -- -- -- -- -- deb('writeFixedSections:(suc)'); END writeFixedSections; -- PROCEDURE readFixedSections(input_xml_filename IN VARCHAR2, bktname IN VARCHAR2 DEFAULT NULL) IS ckp_type NUMBER; database_already_registered EXCEPTION; PRAGMA EXCEPTION_INIT(database_already_registered, -20002); incarnation_already_registered EXCEPTION; PRAGMA EXCEPTION_INIT(incarnation_already_registered, -20009); resync_not_needed EXCEPTION; PRAGMA EXCEPTION_INIT(resync_not_needed, -20034); local_wmrec RC_WATERMARKS%ROWTYPE; wmrec RC_WATERMARKS%ROWTYPE; CURSOR rc_watermarks_c IS SELECT DB_KEY, DB_UNIQUE_NAME, RS_VERSION_STAMP, HIGH_BP_RECID, HIGH_DO_KEY, CF_VERSION_STAMP, HIGH_DF_RECID, HIGH_TS_RECID, HIGH_TF_RECID, HIGH_OFFR_RECID FROM "_RS_RC_WATERMARKS_" WHERE RS_RCFILE_NAME = input_xml_filename; local_siterec RC_SITE%ROWTYPE; siterec RC_SITE%ROWTYPE; CURSOR rc_site_c IS SELECT SITE_KEY, DB_KEY, DATABASE_ROLE, CF_CREATE_TIME, DB_UNIQUE_NAME, HIGH_CONF_RECID, FORCE_RESYNC2CF, HIGH_ROUT_STAMP, INST_STARTUP_STAMP, LAST_KCCDIVTS, HIGH_IC_RECID, DBINC_KEY, CKP_SCN, FULL_CKP_CF_SEQ, JOB_CKP_CF_SEQ, HIGH_TS_RECID, HIGH_DF_RECID, HIGH_RT_RECID, HIGH_ORL_RECID, HIGH_OFFR_RECID, HIGH_RLH_RECID, HIGH_AL_RECID, HIGH_BS_RECID, HIGH_BP_RECID, HIGH_BDF_RECID, HIGH_CDF_RECID, HIGH_BRL_RECID, HIGH_BCB_RECID, HIGH_CCB_RECID, HIGH_DO_RECID, HIGH_PC_RECID, HIGH_BSF_RECID, HIGH_RSR_RECID, HIGH_TF_RECID, HIGH_GRSP_RECID, HIGH_NRSP_RECID, HIGH_BCR_RECID, LOW_BCR_RECID, BCR_IN_USE, HIGH_PDB_RECID, HIGH_PIC_RECID FROM "_RS_RC_SITE_" WHERE RS_RCFILE_NAME = input_xml_filename; upstream_dbrec rci_ra_upstream_database%ROWTYPE; CURSOR rci_ra_upstream_database_c IS SELECT DBID, NAME FROM "_RS_RCI_RA_UPSTREAM_DATABASE_" WHERE RS_RCFILE_NAME = input_xml_filename; icrec RC_DATABASE_INCARNATION%ROWTYPE; curr_inc RC_DATABASE_INCARNATION%ROWTYPE; CURSOR rc_database_incarnation_c(curr_inc_val IN VARCHAR2 DEFAULT NULL) IS SELECT DB_KEY, DBID, DBINC_KEY, NAME, RESETLOGS_CHANGE#, RESETLOGS_TIME, CURRENT_INCARNATION, PARENT_DBINC_KEY, PRIOR_RESETLOGS_CHANGE#, PRIOR_RESETLOGS_TIME, STATUS, REG_DB_UNIQUE_NAME, CON_ID, GUID FROM "_RS_RC_DATABASE_INCARNATION_" WHERE RS_RCFILE_NAME = input_xml_filename AND (curr_inc_val IS NULL OR CURRENT_INCARNATION = curr_inc_val) ORDER BY RESETLOGS_CHANGE#; tbsrec RC_TABLESPACE%ROWTYPE; CURSOR rc_tablespace_c IS SELECT DB_KEY, DBINC_KEY, DB_NAME, CON_ID, PDB_NAME, PDB_KEY, PDBINC_KEY, TS#, NAME, CREATION_CHANGE#, CREATION_TIME, DROP_CHANGE#, DROP_TIME, INCLUDED_IN_DATABASE_BACKUP, BIGFILE, TEMPORARY, ENCRYPT_IN_BACKUP, PLUGIN_CHANGE# FROM "_RS_RC_TABLESPACE_" WHERE RS_RCFILE_NAME = input_xml_filename ORDER BY CON_ID, TS#; dfrec RCI_DATAFILE%ROWTYPE; CURSOR rci_datafile_c IS SELECT DB_KEY, DBINC_KEY, DB_NAME, CON_ID, PDB_NAME, PDB_KEY, PDB_CLOSED, PDBINC_KEY, TS#, TABLESPACE_NAME, FILE#, CREATION_CHANGE#, CREATION_TIME, DROP_CHANGE#, DROP_TIME, BYTES, BLOCKS, BLOCK_SIZE, NAME, STOP_CHANGE#, STOP_TIME, READ_ONLY, RFILE#, INCLUDED_IN_DATABASE_BACKUP, AUX_NAME, ENCRYPT_IN_BACKUP, SITE_KEY, DB_UNIQUE_NAME, FOREIGN_DBID, FOREIGN_CREATION_CHANGE#, FOREIGN_CREATION_TIME, PLUGGED_READONLY, PLUGIN_CHANGE#, PLUGIN_RESETLOGS_CHANGE#, PLUGIN_RESETLOGS_TIME, CREATION_THREAD, CREATION_SIZE, PDB_FOREIGN_DBID, PDB_NOBACKUP FROM "_RS_RCI_DATAFILE_" WHERE RS_RCFILE_NAME = input_xml_filename ORDER BY FILE#; tfrec RCI_TEMPFILE%ROWTYPE; CURSOR rci_tempfile_c IS SELECT DB_KEY, DBINC_KEY, DB_NAME, CON_ID, PDB_NAME, PDB_KEY, TS#, TABLESPACE_NAME, FILE#, CREATION_CHANGE#, CREATION_TIME, DROP_CHANGE#, DROP_TIME, BYTES, BLOCKS, BLOCK_SIZE, NAME, RFILE#, AUTOEXTEND, MAXSIZE, NEXTSIZE, BIGFILE, SITE_KEY, DB_UNIQUE_NAME, TABLESPACE_CREATION_CHANGE#, TABLESPACE_CREATION_TIME, TABLESPACE_DROP_CHANGE#, TABLESPACE_DROP_TIME FROM "_RS_RCI_TEMPFILE_" WHERE RS_RCFILE_NAME = input_xml_filename ORDER BY FILE#; rtrec RC_REDO_THREAD%ROWTYPE; CURSOR rc_redo_thread_c IS SELECT DB_KEY, DBINC_KEY, DB_NAME, THREAD#, STATUS, SEQUENCE#, ENABLE_CHANGE#, ENABLE_TIME, DISABLE_CHANGE#, DISABLE_TIME FROM "_RS_RC_REDO_THREAD_" WHERE RS_RCFILE_NAME = input_xml_filename ORDER BY THREAD#; orlrec RC_REDO_LOG%ROWTYPE; CURSOR rc_redo_log_c IS SELECT DB_KEY, DBINC_KEY, DB_NAME, THREAD#, GROUP#, NAME, SITE_KEY, BYTES, TYPE FROM "_RS_RC_REDO_LOG_" WHERE RS_RCFILE_NAME = input_xml_filename ORDER BY NAME; ckprec RC_CHECKPOINT%ROWTYPE; CURSOR rc_checkpoint_c IS SELECT DB_KEY, DBINC_KEY, DB_NAME, CKP_KEY, CKP_SCN, CKP_CF_SEQ, CKP_TIME, CKP_TYPE, CKP_DB_STATUS, SITE_KEY FROM "_RS_RC_CHECKPOINT_" WHERE RS_RCFILE_NAME = input_xml_filename; offrrec RC_OFFLINE_RANGE%ROWTYPE; CURSOR rc_offline_range_c IS SELECT DB_KEY, DBINC_KEY, DB_NAME, RECID, STAMP, FILE#, CREATION_CHANGE#, OFFLINE_CHANGE#, ONLINE_CHANGE#, ONLINE_TIME, CF_CREATE_TIME, RESETLOGS_CHANGE#, RESETLOGS_TIME, OFFR_KEY FROM "_RS_RC_OFFLINE_RANGE_" WHERE RS_RCFILE_NAME = input_xml_filename ORDER BY OFFR_KEY; pdbrec RCI_PDBS%ROWTYPE; CURSOR rci_pdbs_c IS SELECT PDB_KEY, DB_KEY, NAME, CON_ID, DBID, CREATION_CHANGE#, GUID, NOBACKUP FROM "_RS_RCI_PDBS_" WHERE RS_RCFILE_NAME = input_xml_filename; picrec1 RC_PLUGGABLE_DATABASE_INC%ROWTYPE; CURSOR rc_pluggable_database_inc_c IS SELECT PDB_KEY, NAME, CON_ID, DBID, GUID, CREATE_SCN, PDBINC_KEY, DB_KEY, CURRENT_INCARNATION, INCARNATION_SCN, BEGIN_RESETLOGS_SCN, BEGIN_RESETLOGS_TIME, END_RESETLOGS_SCN, DBINC_KEY, DB_RESETLOGS_SCN, DB_RESETLOGS_TIME, PRIOR_PDBINC_KEY, PRIOR_INCARNATION_SCN, PRIOR_BEGIN_RESETLOGS_SCN, PRIOR_BEGIN_RESETLOGS_TIME, PRIOR_END_RESETLOGS_SCN, PRIOR_DBINC_KEY, PRIOR_DB_RESETLOGS_SCN, PRIOR_DB_RESETLOGS_TIME, STATUS FROM "_RS_RC_PLUGGABLE_DATABASE_INC_" WHERE RS_RCFILE_NAME = input_xml_filename ORDER BY PDBINC_KEY; offr_key NUMBER; parent_dbinc_key NUMBER; dbid NUMBER; foundrec BOOLEAN; newincarnation BOOLEAN := FALSE; loc_db_key NUMBER; cdb_mode NUMBER; last_full_ckp_scn NUMBER; local_dbincrec RC_DATABASE_INCARNATION%ROWTYPE; BEGIN deb('readFixedSections - enter'); -- dbms_session.set_nls('NLS_DATE_FORMAT','''DD-MM-YYYY HH24:MI:SS'''); -- dbid := to_number(substr(input_xml_filename,length(this_database)+1, instr(input_xml_filename,'.xml')-1-length(this_database))); deb('readFixedSections: dbid=' || dbid); -- OPEN rc_watermarks_c; LOOP FETCH rc_watermarks_c INTO wmrec; EXIT WHEN rc_watermarks_c%NOTFOUND; END LOOP; CLOSE rc_watermarks_c; IF debug THEN displayRCWatermarks('readFixedSections remote:', wmrec); END IF; -- OPEN rc_site_c; FETCH rc_site_c INTO siterec; CLOSE rc_site_c; IF debug THEN displayRCSite('readFixedSections:remote ', siterec); END IF; -- OPEN rci_ra_upstream_database_c; FETCH rci_ra_upstream_database_c INTO upstream_dbrec; CLOSE rci_ra_upstream_database_c; this_upstream_dbrec := upstream_dbrec; deb('readFixedSections: upstream dbname=' || this_upstream_dbrec.name || 'reconcile dbname' || siterec.db_unique_name); -- OPEN rc_database_incarnation_c(curr_inc_val => 'YES'); FETCH rc_database_incarnation_c INTO curr_inc; CLOSE rc_database_incarnation_c; IF debug THEN displayRCDatabaseIncarnation('readFixedSections: remote ', curr_inc); END IF; -- OPEN rc_checkpoint_c; FETCH rc_checkpoint_c INTO ckprec; CLOSE rc_checkpoint_c; -- IF curr_inc.dbid IS NULL THEN raise_application_error(-20999, 'internal error: no rows for curr_inc'); END IF; -- IF curr_inc.dbid <> readFixedSections.dbid THEN raise_application_error(-20141, 'Target database id mismatch with registered database in ORS'); END IF; -- BEGIN registerDatabase(db_id => curr_inc.dbid, db_name => curr_inc.name, reset_scn => curr_inc.resetlogs_change#, reset_time => curr_inc.resetlogs_time, db_unique_name => curr_inc.reg_db_unique_name, con_id => curr_inc.con_id, guid => curr_inc.guid); deb('readFixedSections: registered dbname=' || siterec.db_unique_name); EXCEPTION WHEN database_already_registered THEN deb('database already registered'); NULL; WHEN no_data_found THEN deb('database has yet to be added via add_db, dbuname=' || siterec.db_unique_name); raise_application_error(-20140, 'Database not yet registered in ORS'); END; -- -- -- BEGIN SELECT * INTO local_dbincrec FROM rc_database_incarnation WHERE dbid = dbid AND resetlogs_change# = curr_inc.resetlogs_change# AND resetlogs_time = curr_inc.resetlogs_time; IF local_dbincrec.status = 'CURRENT' THEN -- -- SELECT max(ckp_scn) INTO last_full_ckp_scn FROM ckp WHERE ckp_type = 'FULL' AND dbinc_key = local_dbincrec.dbinc_key; IF last_full_ckp_scn > ckprec.ckp_scn THEN deb('readFixedSections (wait):Downstream ahead of upstream'); RETURN; END IF; ELSE -- -- -- -- deb('readFixedSections: Upstream is in a different incarnation'); IF debug THEN displayRCDatabaseIncarnation('readFixedSections: local ', local_dbincrec); END IF; IF local_dbincrec.status = 'ORPHAN' THEN deb('readFixedSections: local incarnation is orphan'); ELSE deb('readFixedSections (wait): Let upstream catchup'); RETURN; END IF; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN deb('readFixedSections: New incarnation in upstream'); IF debug THEN displayRCDatabaseIncarnation('readFixedSections: remote ', curr_inc); END IF; END; -- BEGIN resetDatabase(db_id => curr_inc.dbid, db_name => curr_inc.name, reset_scn => curr_inc.resetlogs_change#, reset_time => curr_inc.resetlogs_time, parent_reset_scn => curr_inc.prior_resetlogs_change#, parent_reset_time => curr_inc.prior_resetlogs_time); deb('readFixedSections: registered newinc ' || siterec.db_unique_name); newincarnation := TRUE; EXCEPTION WHEN incarnation_already_registered THEN deb('database incarnation already known'); NULL; END; -- -- curr_inc.dbinc_key := resetDatabase(db_id => curr_inc.dbid, db_name => curr_inc.name, reset_scn => curr_inc.resetlogs_change#, reset_time => curr_inc.resetlogs_time, parent_reset_scn => curr_inc.prior_resetlogs_change#, parent_reset_time => curr_inc.prior_resetlogs_time); deb('current dbinc_key = ' || curr_inc.dbinc_key); -- IF this_upstream_dbrec.name IS NULL THEN raise_application_error(-20999, 'internal error: no rows for upstreamdb'); END IF; IF siterec.site_key IS NULL THEN raise_application_error(-20999, 'internal error: no rows for siterec'); END IF; setDatabase(db_name => curr_inc.name, reset_scn => curr_inc.resetlogs_change#, reset_time => curr_inc.resetlogs_time, db_id => curr_inc.dbid, db_unique_name => this_upstream_dbrec.name||'$'||siterec.db_unique_name, dummy_instance => FALSE, cf_type => CF_STANDBY, site_aware => TRUE, ors_instance => TRUE); -- IF newincarnation THEN deb('Clearing watermarks at catalog'); UPDATE watermarks SET high_df_recid = 0, high_ts_recid = 0, high_tf_recid = 0, high_offr_recid = 0, cf_version_stamp = null WHERE db_key = this_db_key; UPDATE node SET high_df_recid = 0, high_ts_recid = 0, high_tf_recid = 0, high_offr_recid = 0 WHERE db_key = this_db_key AND site_key = this_site_key; commitChanges('readFixedSections-1'); END IF; select * into local_siterec from rci_site where db_key = this_db_key and site_key = this_site_key; displayRCSite('readFixedSections:local ', local_siterec); -- -- -- BEGIN SELECT db_key, db_unique_name, rs_version_stamp, high_bp_recid, high_do_key, cf_version_stamp, high_df_recid, high_ts_recid, high_tf_recid, high_offr_recid INTO local_wmrec FROM watermarks WHERE db_key = this_db_key; IF debug THEN displayRCWatermarks('readFixedSections:local ', local_wmrec); END IF; EXCEPTION WHEN NO_DATA_FOUND THEN deb('readFixedSections:database with db_key=' || this_db_key || ' no watermarks set yet'); END; -- -- -- IF local_siterec.last_kccdivts = 0 THEN local_siterec.last_kccdivts := date2stamp(local_wmrec.cf_version_stamp); update node set last_kccdivts = local_siterec.last_kccdivts, cf_create_time = local_wmrec.cf_version_stamp, high_ts_recid = local_wmrec.high_ts_recid, high_df_recid = local_wmrec.high_df_recid, high_tf_recid = local_wmrec.high_tf_recid, high_offr_recid = local_wmrec.high_offr_recid, high_bp_recid = local_wmrec.high_bp_recid, high_do_recid = local_wmrec.high_do_key where db_key = this_db_key and site_key = this_site_key; commitChanges('readFixedSections-2'); select * into local_siterec from rci_site where db_key = this_db_key and site_key = this_site_key; displayRCSite('readFixedSections:local,re-fetch ', local_siterec); END IF; deb('CRossed from watermarks'); -- -- -- IF wmrec.rs_version_stamp is not null AND local_wmrec.rs_version_stamp <> wmrec.rs_version_stamp THEN raise_application_error(-20142, 'The version stamp of backup XML set is different'); END IF; -- -- lockForCkpt; ckp_type := ckptNeeded(ckp_scn => siterec.ckp_scn, ckp_cf_seq => siterec.full_ckp_cf_seq, cf_version => stamp2date(siterec.last_kccdivts), cf_type => CF_CURRENT, high_df_recid => siterec.high_df_recid, high_orl_recid => siterec.high_orl_recid, high_cdf_recid => NULL, high_al_recid => NULL, high_bp_recid => NULL, high_do_recid => NULL, high_offr_recid => siterec.high_offr_recid, high_pc_recid => NULL, high_conf_recid => siterec.high_conf_recid, rltime => curr_inc.resetlogs_time, high_ts_recid => siterec.high_ts_recid, high_bs_recid => NULL, lopen_reset_scn => NULL, lopen_reset_time => NULL, high_ic_recid => siterec.high_ic_recid, high_tf_recid => siterec.high_tf_recid, high_rt_recid => siterec.high_rt_recid, high_grsp_recid => NULL, high_nrsp_recid => NULL, high_bcr_recid => NULL, high_pdb_recid => siterec.high_pdb_recid, high_pic_recid => siterec.high_pic_recid); IF ckp_type <> RESYNC_FULL AND ckp_type <> RESYNC_PARTIAL THEN deb('readFixedSections (abort) - ckptNeeded returned ' || ckp_type); cancelCkpt; return; END IF; BEGIN beginCkpt(ckp_scn => siterec.ckp_scn, ckp_cf_seq => siterec.full_ckp_cf_seq, cf_version => stamp2date(siterec.last_kccdivts), ckp_time => ckprec.ckp_time, ckp_type => 'FULL', ckp_db_status => ckprec.ckp_db_status, high_df_recid => siterec.high_df_recid, cf_type => 'CURRENT'); EXCEPTION WHEN resync_not_needed THEN deb('readFixedSections (abort) - resync not needed ' || ckp_type); return; END; deb('readFixedSections: have records to read ' || siterec.db_unique_name); -- foundrec := FALSE; IF beginPluggableDBResync(siterec.high_pdb_recid) then OPEN rci_pdbs_c; LOOP FETCH rci_pdbs_c INTO pdbrec; EXIT WHEN rci_pdbs_c%NOTFOUND; deb('Calling checkPluggableDB name=' || pdbrec.name || ' dbid=' || pdbrec.dbid); checkPluggableDB(pdbrec.name, pdbrec.con_id, pdbrec.dbid, pdbrec.creation_change#, pdbrec.guid, pdbrec.nobackup); foundrec := TRUE; END LOOP; CLOSE rci_pdbs_c; endPluggableDBResync; IF NOT foundrec THEN -- -- raise_application_error(-20150, 'no records found to resync for plugged databases'); END IF; END IF; -- foundrec := FALSE; newincarnation := FALSE; IF siterec.high_ic_recid > beginIncarnationResync(return_recid => TRUE) THEN OPEN rc_database_incarnation_c; LOOP FETCH rc_database_incarnation_c INTO icrec; EXIT WHEN rc_database_incarnation_c%NOTFOUND; deb('Calling checkIncarnation from readfixedsection'); parent_dbinc_key := dbms_rcvcat.checkIncarnation(icrec.resetlogs_change#, icrec.resetlogs_time, icrec.prior_resetlogs_change#, icrec.prior_resetlogs_time, icrec.name); foundrec := TRUE; newincarnation := TRUE; END LOOP; CLOSE rc_database_incarnation_c; endIncarnationResync(siterec.last_kccdivts, siterec.high_ic_recid); IF NOT foundrec THEN -- -- raise_application_error(-20143, 'no records found to resync for incarnation view'); END IF; END IF; -- -- SELECT count(*) INTO cdb_mode FROM pdb WHERE con_id >= 1 AND db_key = this_db_key; -- foundrec := FALSE; IF ((cdb_mode > 0) AND (siterec.high_pic_recid > beginPluggableDbincResync OR newincarnation)) THEN OPEN rc_pluggable_database_inc_c; LOOP FETCH rc_pluggable_database_inc_c INTO picrec1; EXIT WHEN rc_pluggable_database_inc_c%NOTFOUND; deb('Calling checkPluggableDbinc for record' || ' pdbname= ' || picrec1.name || ' dbid=' || picrec1.dbid || ' curr=' || picrec1.current_incarnation || ' inc_scn=' || picrec1.incarnation_scn || ' end_reset_scn=' || picrec1.end_resetlogs_scn || ' pr_inc_scn=' || nvl(picrec1.prior_incarnation_scn, '') || ' pr_reset_scn=' || nvl(picrec1.prior_end_resetlogs_scn, '')); checkPluggableDbinc( NULL, picrec1.guid, picrec1.current_incarnation, picrec1.incarnation_scn, picrec1.begin_resetlogs_scn, picrec1.begin_resetlogs_time, picrec1.end_resetlogs_scn, picrec1.db_resetlogs_scn, picrec1.db_resetlogs_time, picrec1.prior_incarnation_scn, picrec1.prior_end_resetlogs_scn, picrec1.prior_db_resetlogs_scn, picrec1.prior_db_resetlogs_time, FALSE); foundrec := TRUE; END LOOP; CLOSE rc_pluggable_database_inc_c; endPluggableDbincResync(siterec.high_pic_recid); IF NOT foundrec THEN -- -- raise_application_error(-20151, 'no records found to resync for pluggable db incarnation view'); END IF; END IF; -- foundrec := FALSE; IF beginTableSpaceResync(siterec.high_ts_recid, FALSE) THEN OPEN rc_tablespace_c; LOOP FETCH rc_tablespace_c INTO tbsrec; EXIT WHEN rc_tablespace_c%NOTFOUND; -- -- deb('Calling checkTableSpace'); checkTableSpace(tbsrec.name, tbsrec.ts#, tbsrec.creation_change#, tbsrec.creation_time, 0 /* rbs_count not populated */, tbsrec.included_in_database_backup, tbsrec.bigfile, tbsrec.temporary, tbsrec.encrypt_in_backup, tbsrec.plugin_change#, tbsrec.con_id, FALSE); foundrec := TRUE; END LOOP; CLOSE rc_tablespace_c; endTableSpaceResync; IF NOT foundrec THEN -- -- raise_application_error(-20144, 'no records found to resync for tablespace view'); END IF; END IF; -- foundrec := FALSE; IF beginDataFileResync(siterec.high_df_recid) THEN OPEN rci_datafile_c; LOOP FETCH rci_datafile_c INTO dfrec; EXIT WHEN rci_datafile_c%NOTFOUND; checkDataFile( file# => dfRec.file#, fname => dfRec.name, create_scn => dfRec.creation_change#, create_time => dfRec.creation_time, blocks => dfRec.blocks, block_size => dfRec.block_size, ts# => dfRec.ts#, stop_scn => dfRec.stop_change#, read_only => dfRec.read_only, stop_time => dfRec.stop_time, rfile# => dfRec.rfile#, aux_fname => dfRec.aux_name, foreign_dbid => dfRec.foreign_dbid, foreign_create_scn => dfRec.foreign_creation_change#, foreign_create_time => dfRec.foreign_creation_time, plugged_readonly => dfRec.plugged_readonly, plugin_scn => dfRec.plugin_change#, plugin_reset_scn => dfRec.plugin_resetlogs_change#, plugin_reset_time => dfRec.plugin_resetlogs_time, create_thread => dfRec.creation_thread, create_size => dfRec.creation_size, con_id => dfRec.con_id, pdb_closed => dfRec.pdb_closed, pdb_dict_check => FALSE, pdb_foreign_dbid => dfRec.pdb_foreign_dbid); foundrec := TRUE; END LOOP; CLOSE rci_datafile_c; endDataFileResync; IF NOT foundrec THEN -- -- raise_application_error(-20145, 'no records found to resync for datafile view'); END IF; END IF; -- -- foundrec := FALSE; IF beginTempFileResync(siterec.high_tf_recid) THEN OPEN rci_tempfile_c; LOOP FETCH rci_tempfile_c INTO tfrec; EXIT WHEN rci_tempfile_c%NOTFOUND; checkTempFile( file# => tfrec.file#, fname => tfrec.name, create_scn => tfrec.creation_change#, create_time => tfrec.creation_time, blocks => tfrec.blocks, block_size => tfrec.block_size, ts# => tfrec.ts#, rfile# => tfrec.rfile#, autoextend => tfrec.autoextend, max_size => tfrec.maxsize, next_size => tfrec.nextsize, con_id => tfrec.con_id, pdb_dict_check => FALSE); foundrec := TRUE; END LOOP; CLOSE rci_tempfile_c; endTempFileResync; IF NOT foundrec THEN -- -- raise_application_error(-20145, 'no records found to resync for tempfile view'); END IF; END IF; -- foundrec := FALSE; IF beginThreadResync(siterec.high_rt_recid) THEN OPEN rc_redo_thread_c; LOOP FETCH rc_redo_thread_c INTO rtrec; EXIT WHEN rc_redo_thread_c%NOTFOUND; dbms_rcvcat.checkThread (rtrec.thread#, rtrec.sequence#, rtrec.enable_change#, rtrec.enable_time, rtrec.disable_change#, rtrec.disable_time, rtrec.status); foundrec := TRUE; END LOOP; CLOSE rc_redo_thread_c; endThreadResync; IF NOT foundrec THEN -- -- raise_application_error(-20146, 'no records found to resync for thread view'); END IF; END IF; -- foundrec := FALSE; IF beginOnlineRedoLogResync(siterec.high_orl_recid) THEN OPEN rc_redo_log_c; LOOP FETCH rc_redo_log_c INTO orlrec; EXIT WHEN rc_redo_log_c%NOTFOUND; checkOnlineRedoLog (orlrec.thread#, orlrec.group#, orlrec.name, orlrec.bytes, orlrec.type); foundrec := TRUE; END LOOP; CLOSE rc_redo_log_c; endOnlineRedoLogResync; IF NOT foundrec THEN -- -- raise_application_error(-20147, 'no records found to resync for online redo log view'); END IF; END IF; offr_key := beginOfflineRangeResync; IF ((wmrec.high_offr_recid IS NOT NULL AND wmrec.high_offr_recid > 0 AND local_wmrec.high_offr_recid = wmrec.high_offr_recid) OR (siterec.high_offr_recid = 0)) THEN foundrec := TRUE; ELSE foundrec := FALSE; END IF; OPEN rc_offline_range_c; LOOP FETCH rc_offline_range_c INTO offrrec; EXIT WHEN rc_offline_range_c%NOTFOUND; -- -- -- checkOfflineRange( offrrec.offr_key, offrrec.stamp, offrrec.file#, offrrec.creation_change#, offrrec.offline_change#, offrrec.online_change#, offrrec.online_time, offrrec.cf_create_time, offrrec.resetlogs_change#, offrrec.resetlogs_time); foundrec := TRUE; END LOOP; CLOSE rc_offline_range_c; endOfflineRangeResync; IF NOT foundrec THEN -- -- deb('wmrec.high_offr_recid=' || wmrec.high_offr_recid); deb('local_wmrec.high_offr_recid=' || local_wmrec.high_offr_recid); raise_application_error(-20148, 'no records found to resync for offline range view'); END IF; -- sanityCheck; endCkpt; deb('readFixedSections: (suc) ' || siterec.db_unique_name); EXCEPTION WHEN OTHERS THEN deb('readFixedSections: (fail) ' || siterec.db_unique_name); cancelCkpt; raise; END readFixedSections; -- -- PROCEDURE writeBackupSections(input_xml_filename IN VARCHAR2, bktname IN VARCHAR2 DEFAULT NULL) IS v_ctx DBMS_XMLGen.ctxHandle; v_xml CLOB; v_xml_tmp CLOB; type record_sql_type is table of varchar2(2048) index by binary_integer; type record_tbl_type is table of varchar2(30) index by binary_integer; record_sql record_sql_type; record_tbl record_tbl_type; my_dbid number; write_xml_filename rcfile.name%TYPE; local_wmrec rc_watermarks%ROWTYPE; l_prefix rcfile.name%TYPE; l_job_ckp_cf_seq number; BEGIN deb('writeBackupSections:enter, expects caller to commit'); -- my_dbid := to_number(substr(input_xml_filename, length(this_forwatermarks)+1, instr(input_xml_filename,'.xml')-1 -length(this_forwatermarks))); deb('writeBackupSections:my_dbid=' || my_dbid); BEGIN SELECT DB_KEY INTO this_db_key FROM DB WHERE db_id = my_dbid; EXCEPTION WHEN NO_DATA_FOUND THEN deb('writeBackupSections:database with dbid=' || my_dbid || ' not found in recovery catalog'); RETURN; END; deb('writeBackupSections:this_db_key=' || this_db_key); BEGIN select * into local_wmrec from rc_watermarks where db_key = this_db_key; displayRCWatermarks('writeBackupSections local:', local_wmrec); EXCEPTION WHEN NO_DATA_FOUND THEN deb('writeBackupSections:database with dbid=' || my_dbid || ' no setDatabase called yet'); RETURN; END; -- l_job_ckp_cf_seq := local_wmrec.high_bp_recid + local_wmrec.high_do_key; IF this_rsiterec.cf_create_time = local_wmrec.rs_version_stamp AND this_rsiterec.job_ckp_cf_seq = l_job_ckp_cf_seq THEN deb('writeBackupSections:No new backup piece or deleted object added'); RETURN; END IF; record_tbl(0) := 'RC_DATABASE'; record_sql(0) := 'SELECT * FROM RC_DATABASE ' || 'WHERE DB_KEY = ' || this_db_key; record_tbl(1) := 'RCI_BACKUP_SET'; record_sql(1) := 'SELECT * FROM RCI_BACKUP_SET ' || 'WHERE DB_KEY = ' || this_db_key || ' AND BS_KEY IN ' || ' (SELECT DISTINCT BS_KEY FROM BP ' || ' WHERE BP_RECID > '|| NVL(this_rsiterec.high_bp_recid, 0) || ' )'; record_tbl(2) := 'RCI_BACKUP_PIECE'; record_sql(2) := 'SELECT * FROM RCI_BACKUP_PIECE ' || 'WHERE DB_KEY = ' || this_db_key || ' AND RECID > ' || NVL(this_rsiterec.high_bp_recid,0); record_tbl(3) := 'RCI_BACKUP_DATAFILE'; record_sql(3) := 'SELECT * FROM RCI_BACKUP_DATAFILE ' || 'WHERE DB_KEY = ' || this_db_key || ' AND BS_KEY IN ' || ' (SELECT DISTINCT BS_KEY FROM BP ' || ' WHERE BP_RECID > ' || NVL(this_rsiterec.high_bp_recid, 0) || ' )'; record_tbl(4) := 'RCI_BACKUP_CONTROLFILE'; record_sql(4) := 'SELECT * FROM RCI_BACKUP_CONTROLFILE ' || 'WHERE DB_KEY = ' || this_db_key || ' AND BS_KEY IN ' || ' (SELECT DISTINCT BS_KEY FROM BP ' || ' WHERE BP_RECID > ' || NVL(this_rsiterec.high_bp_recid, 0) || ' )'; record_tbl(5) := 'RC_BACKUP_REDOLOG'; record_sql(5) := 'SELECT * FROM RC_BACKUP_REDOLOG ' || 'WHERE DB_KEY = ' || this_db_key || ' AND BS_KEY IN ' || ' (SELECT DISTINCT BS_KEY FROM BP ' || ' WHERE BP_RECID > ' || NVL(this_rsiterec.high_bp_recid, 0) || ' )'; record_tbl(6) := 'RCI_BACKUP_SPFILE'; record_sql(6) := 'SELECT * FROM RCI_BACKUP_SPFILE ' || 'WHERE DB_KEY = ' || this_db_key || ' AND BS_KEY IN ' || ' (SELECT DISTINCT BS_KEY FROM BP ' || ' WHERE BP_RECID > ' || NVL(this_rsiterec.high_bp_recid, 0) || ' )'; record_tbl(7) := 'RC_RCVER'; record_sql(7) := 'SELECT * FROM RC_RCVER '; record_tbl(8) := 'RC_WATERMARKS'; record_sql(8) := 'SELECT * FROM RC_WATERMARKS ' || 'WHERE DB_KEY = ' || this_db_key; record_tbl(9) := 'RC_DELETED_OBJECT'; record_sql(9) := 'SELECT * FROM RC_DELETED_OBJECT ' || 'WHERE DB_KEY = ' || this_db_key || ' AND DO_KEY > ' || NVL(this_rsiterec.high_do_recid, 0); -- v_xml := this_xml_signature_beg; FOR idx in 0..9 LOOP deb('writing XML file for ' || idx); deb('executing query:'|| record_sql(idx)); v_ctx := DBMS_XMLGen.newContext(record_sql(idx)); -- DBMS_XMLGen.setRowsetTag(v_ctx, 'TABLE_' || record_tbl(idx)); v_xml_tmp := DBMS_XMLGen.GetXML(v_ctx); DBMS_XMLGen.closeContext(v_ctx); deb('XML len for '||idx||'=' || DBMS_LOB.GETLENGTH(v_xml_tmp)); IF v_xml_tmp IS NOT NULL THEN DBMS_LOB.COPY(v_xml, v_xml_tmp, DBMS_LOB.LOBMAXSIZE, DBMS_LOB.GETLENGTH(v_xml), DBMS_LOB.INSTR(v_xml_tmp, '')); END IF; END LOOP; v_xml := v_xml || this_xml_signature_end; -- l_prefix := this_backupsets || my_dbid || '_' || date2stamp(local_wmrec.rs_version_stamp) || '_'; write_xml_filename := l_prefix || l_job_ckp_cf_seq || '.xml'; IF this_amazon_server THEN put_object(null /*bktname */, write_xml_filename, 'text/xml', v_xml); ELSE DELETE rcfile WHERE name LIKE l_prefix || '%'; IF SQL%ROWCOUNT > 0 THEN deb('writeBackupSections:deleted old backupset rows:' ||SQL%ROWCOUNT); END IF; INSERT INTO rcfile(rcfile_key, creation_time, name, xmldoc) VALUES (rman_seq.nextval, sys_extract_utc(systimestamp), write_xml_filename, XMLType.createXML(v_xml)); END IF; deb('writeBackupSections:(suc) file:' || write_xml_filename); END writeBackupSections; PROCEDURE readBackupSections(bktname IN VARCHAR2 DEFAULT NULL) IS bs_xml_filename RCFILE.NAME%TYPE; bsrec RCI_BACKUP_SET%ROWTYPE; CURSOR rci_backup_set_c IS SELECT DB_KEY, DB_ID, BS_KEY, RECID, STAMP, SET_STAMP, SET_COUNT, BACKUP_TYPE, INCREMENTAL_LEVEL, PIECES, START_TIME, COMPLETION_TIME, ELAPSED_SECONDS, STATUS, CONTROLFILE_INCLUDED, INPUT_FILE_SCAN_ONLY, KEEP, KEEP_UNTIL, decode (KEEP_OPTIONS, 'LOGS' , 256 , 'NOLOGS' , 512 , 'BACKUP_LOGS' , 1024 , 0) KEEP_OPTIONS, BLOCK_SIZE, SITE_KEY, MULTI_SECTION, GUID, PDB_KEY FROM "_RS_RCI_BACKUP_SET_" WHERE RS_RCFILE_NAME = bs_xml_filename ORDER BY RECID; bprec RCI_BACKUP_PIECE%ROWTYPE; CURSOR rci_backup_piece_c IS SELECT DB_KEY, DB_ID, BP_KEY, RECID, STAMP, BS_KEY, SET_STAMP, SET_COUNT, BACKUP_TYPE, INCREMENTAL_LEVEL, PIECE#, COPY#, DEVICE_TYPE, HANDLE, COMMENTS, MEDIA, MEDIA_POOL, CONCUR, TAG, START_TIME, COMPLETION_TIME, ELAPSED_SECONDS, STATUS, BYTES, IS_RECOVERY_DEST_FILE, RSR_KEY, COMPRESSED, SITE_KEY, ENCRYPTED, BACKED_BY_OSB, SUBSTR(BA_ACCESS,1,1) BA_ACCESS, VB_KEY, VIRTUAL, LIB_KEY, GUID, PDB_KEY FROM "_RS_RCI_BACKUP_PIECE_" WHERE RS_RCFILE_NAME = bs_xml_filename ORDER BY RECID; bdfrec RCI_BACKUP_DATAFILE%ROWTYPE; CURSOR rci_backup_datafile_c IS SELECT DB_KEY, DBINC_KEY, DB_NAME, BDF_KEY, RECID, STAMP, BS_KEY, SET_STAMP, SET_COUNT, BS_RECID, BS_STAMP, BACKUP_TYPE, INCREMENTAL_LEVEL, COMPLETION_TIME, FILE#, CREATION_CHANGE#, CREATION_TIME, RESETLOGS_CHANGE#, RESETLOGS_TIME, INCREMENTAL_CHANGE#, CHECKPOINT_CHANGE#, CHECKPOINT_TIME, ABSOLUTE_FUZZY_CHANGE#, DATAFILE_BLOCKS, BLOCKS, BLOCK_SIZE, STATUS, BS_LEVEL, PIECES, BLOCKS_READ, MARKED_CORRUPT, USED_CHANGE_TRACKING, USED_OPTIMIZATION, PCT_NOTREAD, FOREIGN_DBID, PLUGGED_READONLY, PLUGIN_CHANGE#, PLUGIN_RESETLOGS_CHANGE#, PLUGIN_RESETLOGS_TIME, SECTION_SIZE, GUID, SPARSE_BACKUP, PDB_KEY FROM "_RS_RCI_BACKUP_DATAFILE_" WHERE RS_RCFILE_NAME = bs_xml_filename UNION SELECT DB_KEY, DBINC_KEY, DB_NAME, BCF_KEY, RECID, STAMP, BS_KEY, SET_STAMP, SET_COUNT, BS_RECID, BS_STAMP, decode(BS_LEVEL, 0, 'D', null, 'D', 'I') BACKUP_TYPE, BS_LEVEL INCREMENTAL_LEVEL, COMPLETION_TIME, 0 FILE#, 0 CREATION_CHANGE#, CREATION_TIME, RESETLOGS_CHANGE#, RESETLOGS_TIME, 0 INCREMENTAL_CHANGE#, CHECKPOINT_CHANGE#, CHECKPOINT_TIME, 0 ABSOLUTE_FUZZY_CHANGE#, 0 DATAFILE_BLOCKS, BLOCKS, BLOCK_SIZE, STATUS, BS_LEVEL, NULL PIECES, NULL BLOCKS_READ, -- -- -- to_number(to_char(to_date(autobackup_date),'YYYY')) MARKED_CORRUPT, 'NO' USED_CHANGE_TRACKING, 'NO' USED_OPTIMIZATION, AUTOBACKUP_SEQUENCE PCT_NOTREAD, 0 FOREIGN_DBID, CONTROLFILE_TYPE PLUGGED_READONLY, OLDEST_OFFLINE_RANGE PLUGIN_CHANGE#, to_number(to_char(to_date(autobackup_date),'MM')|| to_char(to_date(autobackup_date),'DD')) PLUGIN_RESETLOGS_CHANGE#, NULL PLUGIN_RESETLOGS_TIME, NULL SECTION_SIZE, GUID, 'NO' sparse_backup, PDB_KEY FROM "_RS_RCI_BACKUP_CONTROLFILE_" WHERE RS_RCFILE_NAME = bs_xml_filename ORDER BY 5; bsfrec RCI_BACKUP_SPFILE%ROWTYPE; CURSOR rci_backup_spfile_c IS SELECT DB_KEY, BSF_KEY, RECID, STAMP, BS_KEY, SET_STAMP, SET_COUNT, MODIFICATION_TIME, STATUS, BS_RECID, BS_STAMP, COMPLETION_TIME, BYTES, DB_UNIQUE_NAME, GUID FROM "_RS_RCI_BACKUP_SPFILE_" WHERE RS_RCFILE_NAME = bs_xml_filename ORDER BY RECID; brlrec RC_BACKUP_REDOLOG%ROWTYPE; CURSOR rc_backup_redolog_c IS SELECT DB_KEY, DBINC_KEY, DB_NAME, BRL_KEY, RECID, STAMP, BS_KEY, SET_STAMP, SET_COUNT, BACKUP_TYPE, COMPLETION_TIME, THREAD#, SEQUENCE#, RESETLOGS_CHANGE#, RESETLOGS_TIME, FIRST_CHANGE#, FIRST_TIME, NEXT_CHANGE#, NEXT_TIME, BLOCKS, BLOCK_SIZE, STATUS, BS_RECID, BS_STAMP, PIECES, TERMINAL, PARTIAL FROM "_RS_RC_BACKUP_REDOLOG_" WHERE RS_RCFILE_NAME = bs_xml_filename ORDER BY RECID; dlrec RC_DELETED_OBJECT%ROWTYPE; CURSOR rc_deleted_object_c IS SELECT DB_KEY, DO_KEY, OBJECT_TYPE, OBJECT_KEY, OBJECT_STAMP, OBJECT_DATA, SET_STAMP, SET_COUNT, HANDLE, DEVICE_TYPE FROM "_RS_RC_DELETED_OBJECT_" WHERE RS_RCFILE_NAME = bs_xml_filename ORDER BY DO_KEY; bsname "_RS_RC_GET_OBJECT_LIST_"%ROWTYPE; CURSOR bsnames_c(prefix in varchar2) IS SELECT * FROM "_RS_RC_GET_OBJECT_LIST_" WHERE prefix = bsnames_c.prefix ORDER BY rcfile_name asc; my_dbid NUMBER; ckp_type NUMBER; v_xml_tmp CLOB; -- TODO remove this after changing get_object prototype local_node NODE%ROWTYPE; prefix_value "_RS_RC_GET_OBJECT_LIST_".PREFIX%TYPE; resync_not_needed EXCEPTION; PRAGMA EXCEPTION_INIT(resync_not_needed, -20034); incarnation_not_known EXCEPTION; PRAGMA EXCEPTION_INIT(incarnation_not_known, -20003); max_copy_num NUMBER; l_bs_key NUMBER; cursor_name INTEGER; dummy INTEGER; r_bp_key NUMBER; r_dbver NUMBER; r_dbid NUMBER; r_db_name dbinc.db_name%TYPE; r_handle bp.handle%TYPE; r_setstamp NUMBER; r_setcount NUMBER; r_pieceno NUMBER; r_pieceblksize NUMBER; r_tag bp.tag%TYPE; r_bstyp NUMBER; r_cnt NUMBER; l_dbkey NUMBER; l_cnt NUMBER; l_compressed bp.compressed%TYPE; l_encrypted bp.encrypted%TYPE; l_incremental NUMBER; l_bstyp NUMBER; l_recid NUMBER; l_job_ckp_cf_seq NUMBER; BEGIN deb('readBackupSections - enter'); -- IF this_server.server_host IS NULL THEN deb('readBackupSections: this_server.server_host is null'); return; END IF; IF this_curr_inc.dbid IS NULL OR this_wmrec.cf_version_stamp IS NULL THEN deb('readBackupSections: DB was registered or inc mismatch, re-read'); writeForWatermarks(bktname, TRUE); rsReadWaterMarks(bktname); END IF; -- IF this_upstream_dbrec.name IS NULL THEN raise_application_error(-20999, 'internal error: no rows for upstreamdb'); END IF; IF this_url_db_unique_name IS NULL THEN raise_application_error(-20999,'internal error:this_url_db_unique_name2'); END IF; IF (this_curr_inc.dbid IS NULL) THEN raise_application_error(-20021, 'Database not set'); END IF; BEGIN setDatabase(db_name => this_curr_inc.name, reset_scn => this_curr_inc.resetlogs_change#, reset_time => this_curr_inc.resetlogs_time, db_id => this_curr_inc.dbid, db_unique_name => this_upstream_dbrec.name||'$'|| this_url_db_unique_name, dummy_instance => FALSE, cf_type => CF_STANDBY, site_aware => TRUE, ors_instance => TRUE); EXCEPTION WHEN incarnation_not_known THEN -- -- -- deb('readBackupSections: New incarnation not yet known to upstream'); IF debug THEN displayRCDatabaseIncarnation('readBackupSections: remote ', this_curr_inc); END IF; RETURN; END; -- dbms_session.set_nls('NLS_DATE_FORMAT','''DD-MM-YYYY HH24:MI:SS'''); -- -- BEGIN writeForWatermarks(bktname, FALSE); rsReadWaterMarks(bktname); EXCEPTION WHEN OTHERS THEN deb('readBackupSections: error during watermarks read:' || sqlerrm); RAISE; END; IF this_wmrec.rs_version_stamp is NULL THEN deb('readBackupSections: no watermarks yet populated at ORS'); RETURN; END IF; SELECT * into local_node FROM NODE WHERE db_key = this_db_key AND site_key = this_site_key; -- l_job_ckp_cf_seq := this_wmrec.high_bp_recid + this_wmrec.high_do_key; IF local_node.cf_create_time = this_wmrec.rs_version_stamp AND local_node.job_ckp_cf_seq = l_job_ckp_cf_seq THEN -- deb('readBackuupSections: no events to reconcile from ORS to catalog'); return; END IF; deb('local_node.cf_create_time='||local_node.cf_create_time); deb('local_node.job_ckp_cf_seq='||local_node.job_ckp_cf_seq); -- lockForCkpt; ckp_type := ckptNeeded(ckp_scn => 0, ckp_cf_seq => l_job_ckp_cf_seq, cf_version => this_wmrec.rs_version_stamp, cf_type => CF_STANDBY, high_df_recid => 0, high_orl_recid => 0, high_cdf_recid => 0, high_al_recid => 0, high_bp_recid => this_wmrec.high_bp_recid, high_do_recid => this_wmrec.high_do_key, high_offr_recid => 0, high_pc_recid => 0, high_conf_recid => 0, rltime => this_curr_inc.resetlogs_time, high_ts_recid => 0, high_bs_recid => 0, lopen_reset_scn => NULL, lopen_reset_time => NULL, high_ic_recid => 0, high_tf_recid => 0, high_rt_recid => 0, high_grsp_recid => 0, high_nrsp_recid => 0, high_bcr_recid => 0, high_pdb_recid => 0, high_pic_recid => 0); IF ckp_type <> RESYNC_PARTIAL THEN deb('readBackupSections: resync not required, ckp_type=' || ckp_type); cancelCkpt; return; END IF; BEGIN beginCkpt(ckp_scn => 0, ckp_cf_seq => l_job_ckp_cf_seq, cf_version => this_wmrec.rs_version_stamp, ckp_time => NULL, ckp_type => 'PARTIAL', ckp_db_status => NULL, high_df_recid => 0, cf_type => 'STANDBY'); EXCEPTION WHEN resync_not_needed THEN deb('readBackupSections:resync not needed from beginCkpt'); return; END; -- -- SELECT DBID INTO MY_DBID FROM RC_DATABASE WHERE DB_KEY=this_db_key; -- prefix_value := this_backupsets || my_dbid || '_' || date2stamp(this_wmrec.rs_version_stamp) || '_'; -- -- -- v_xml_tmp := get_object(bktname, null, 'prefix='||prefix_value); OPEN bsnames_c(prefix_value); LOOP FETCH bsnames_c INTO bsname; EXIT WHEN bsnames_c%NOTFOUND; bs_xml_filename := bsname.rcfile_name; deb('readBackupSections: got file ' || bs_xml_filename); -- v_xml_tmp := get_object(bktname, bs_xml_filename); -- l_recid := beginBackupsetResync; OPEN rci_backup_set_c; LOOP FETCH rci_backup_set_c INTO bsrec; EXIT WHEN rci_backup_set_c%NOTFOUND; deb('Calling checkBackupset'); dbms_rcvcat.checkBackupSet( bsrec.recid, bsrec.stamp, bsrec.set_stamp, bsrec.set_count, bsrec.backup_type, bsrec.incremental_level, bsrec.pieces, bsrec.start_time, bsrec.completion_time, bsrec.controlfile_included, bsrec.input_file_scan_only, bsrec.keep_options, bsrec.keep_until, bsrec.block_size, bsrec.multi_section, FALSE /* chk_last_recid */, bsrec.guid); END LOOP; CLOSE rci_backup_set_c; endBackupsetResync; -- l_recid := beginBackupPieceResync; OPEN rci_backup_piece_c; LOOP FETCH rci_backup_piece_c INTO bprec; EXIT WHEN rci_backup_piece_c%NOTFOUND; -- SELECT bs_key INTO l_bs_key FROM bs WHERE bs.db_key = this_db_key AND bs.set_stamp = bprec.set_stamp AND bs.set_count = bprec.set_count; SELECT NVL(MAX(copy#), 0) INTO max_copy_num FROM bp WHERE bs_key = l_bs_key; IF bprec.ba_access != 'U' THEN deb('Calling CheckBackupPiece, handle='|| bprec.handle ||',tag=' || bprec.tag || ',max_copy_num=' || max_copy_num ||',l_bs_key=' || l_bs_key || ',bp_recid=' || bprec.recid); dbms_rcvcat.checkBackupPiece( bprec.recid, bprec.stamp, bprec.set_stamp, bprec.set_count, bprec.piece#, bprec.tag, 'SBT_TAPE', bprec.handle, bprec.comments, this_server.rep_server_name, bprec.concur, bprec.start_time, bprec.completion_time, bprec.status, max_copy_num + 1, bprec.media_pool, bprec.bytes, bprec.is_recovery_dest_file, bprec.rsr_key, null /* rman_status_stamp */, bprec.compressed, bprec.encrypted, bprec.backed_by_osb, 'R', NULL /* bprec.vb_key */, TRUE /* chk_last_recid */, this_lib_key, bprec.guid, NULL); -- SELECT bp_key INTO r_bp_key FROM bp WHERE handle=bprec.handle AND piece#=bprec.piece#; -- -- EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM sbt_catalog WHERE bp_key=:1' INTO l_cnt USING r_bp_key; IF l_cnt = 0 THEN -- -- cursor_name := dbms_sql.open_cursor; sys.dbms_sql.parse(cursor_name, 'begin sys.kbrsi_icd.rsAddToSbtCatalog( bpkey => :l_bpkey, dbver => :l_dbver, dbname => :l_dbname, dbid => :l_dbid, handle => :l_handle, setstamp => :l_setstamp, setcount => :l_setcount, pieceno => :l_pieceno, pieceblksize => :l_pieceblksize, tag => :l_tag, bstyp => :l_bstyp ); end;', DBMS_SQL.NATIVE); -- -- -- IF l_dbkey IS NULL THEN SELECT db_key INTO l_dbkey FROM db WHERE db_id=bprec.db_id; EXECUTE IMMEDIATE 'SELECT MAX(cmpvsn) FROM vbdf WHERE db_key=:1' INTO r_dbver USING l_dbkey; SELECT db_name INTO r_db_name FROM dbinc WHERE dbinc_key = (SELECT curr_dbinc_key FROM db WHERE db_key = l_dbkey); END IF; IF r_dbver IS NULL THEN -- -- -- -- -- -- -- -- -- -- -- deb ('readBackupSections: r_dbver is NULL - set to 0.0.0.0'); r_dbver := 0; END IF; SELECT block_size, incr_level INTO r_pieceblksize, l_incremental FROM bs WHERE bs_key=l_bs_key; r_dbid := bprec.db_id; r_handle := bprec.handle; r_setstamp := bprec.set_stamp; r_setcount := bprec.set_count; r_pieceno := bprec.piece#; r_tag := bprec.tag; -- -- r_bstyp := 4; -- -- IF l_incremental IS NOT NULL THEN r_bstyp := r_bstyp + 16; END IF; IF bprec.compressed = 'YES' THEN r_bstyp := r_bstyp + 32; END IF; IF bprec.encrypted = 'Y' THEN r_bstyp := r_bstyp + 64; END IF; DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_bpkey', r_bp_key ); DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_dbver', r_dbver ); DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_dbname', r_db_name ); DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_dbid', r_dbid ); DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_handle', r_handle ); DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_setstamp',r_setstamp ); DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_setcount',r_setcount ); DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_pieceno', r_pieceno ); DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_pieceblksize', r_pieceblksize); DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_tag', r_tag ); DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_bstyp', r_bstyp ); deb('Calling rsAddToSbtCatalog'); dummy := sys.dbms_sql.execute(cursor_name); sys.dbms_sql.close_cursor(cursor_name); END IF; ELSE deb('Calling CheckBackupPiece ***NOT***, handle='||bprec.handle|| ',tag=' || bprec.tag || ',max_copy_num=' || max_copy_num || ',l_bs_key=' || l_bs_key || ',bp_recid=' || bprec.recid); deb('Ignoring BP rec with bprec.ba_access=' || bprec.ba_access); END IF; END LOOP; CLOSE rci_backup_piece_c; endBackupPieceResync; -- l_recid := beginBackupDataFileResync; OPEN rci_backup_datafile_c; LOOP FETCH rci_backup_datafile_c INTO bdfrec; EXIT WHEN rci_backup_datafile_c%NOTFOUND; deb('Calling checkBackupDatafile'); dbms_rcvcat.checkBackupDataFile( bdfrec.recid, bdfrec.stamp, bdfrec.set_stamp, bdfrec.set_count, bdfrec.file#, bdfrec.creation_change#, bdfrec.creation_time, bdfrec.resetlogs_change#, bdfrec.resetlogs_time, bdfrec.incremental_level, bdfrec.incremental_change#, bdfrec.checkpoint_change#, bdfrec.checkpoint_time, bdfrec.absolute_fuzzy_change#, bdfrec.datafile_blocks, bdfrec.blocks, bdfrec.block_size, bdfrec.plugin_change# /*oldest_offline_range*/, bdfrec.completion_time, bdfrec.plugged_readonly /*controlfile_type*/, bdfrec.marked_corrupt /* cfile_abck_year */, bdfrec.plugin_resetlogs_change# /* cfile_abck_mon_day */, bdfrec.pct_notread /* cfile_abck_seq */, FALSE /* chk_last_recid */, bdfrec.blocks_read, bdfrec.used_change_tracking, bdfrec.used_optimization, bdfrec.foreign_dbid, bdfrec.plugged_readonly, bdfrec.plugin_change#, bdfrec.plugin_resetlogs_change#, bdfrec.plugin_resetlogs_time, bdfrec.section_size, bdfrec.guid, bdfrec.sparse_backup); END LOOP; CLOSE rci_backup_datafile_c; endBackupDatafileResync; -- l_recid := beginBackupRedoLogResync; OPEN rc_backup_redolog_c; LOOP FETCH rc_backup_redolog_c INTO brlrec; EXIT WHEN rc_backup_redolog_c%NOTFOUND; deb('Calling checkBackupRedoLog'); dbms_rcvcat.checkBackupRedoLog( brlrec.recid, brlrec.stamp, brlrec.set_stamp, brlrec.set_count, brlrec.thread#, brlrec.sequence#, brlrec.resetlogs_change#, brlrec.resetlogs_time, brlrec.first_change#, brlrec.first_time, brlrec.next_change#, brlrec.next_time, brlrec.blocks, brlrec.block_size, FALSE /* chk_last_recid */, brlrec.terminal); END LOOP; CLOSE rc_backup_redolog_c; endBackupRedoLogResync; -- l_recid := beginBackupSpFileResync; OPEN rci_backup_spfile_c; LOOP FETCH rci_backup_spfile_c INTO bsfrec; EXIT WHEN rci_backup_spfile_c%NOTFOUND; deb('Calling checkBackupSpFile'); dbms_rcvcat.checkBackupSpFile( bsfrec.recid, bsfrec.stamp, bsfrec.set_stamp, bsfrec.set_count, bsfrec.modification_time, bsfrec.bytes, FALSE /* chk_last_recid */, bsfrec.db_unique_name, bsfrec.guid); END LOOP; CLOSE rci_backup_spfile_c; endBackupSpFileResync; -- l_recid := beginDeletedObjectResync; OPEN rc_deleted_object_c; LOOP FETCH rc_deleted_object_c INTO dlrec; EXIT WHEN rc_deleted_object_c%NOTFOUND; deb('Calling checkDeletedObject for do_key(recid) ' || dlrec.do_key ||' object type ' || dlrec.object_type ||' with key ' || dlrec.object_key ||', stamp ' || dlrec.object_stamp ||', data ' || dlrec.object_data ||' and set_stamp ' || nvl(to_char(dlrec.set_stamp), 'NULL') ||' and set_count ' || nvl(to_char(dlrec.set_count), 'NULL') ||', handle ' || dlrec.handle ||', device_type ' || dlrec.device_type); dbms_rcvcat.checkDeletedObject( dlrec.do_key /* do_recid */, 0 /* do_stamp */, dlrec.object_type, dlrec.object_key, dlrec.object_stamp, dlrec.object_data, null /* dlrec.object_fname */, null /* dlrec.object_create_scn */, dlrec.set_stamp, dlrec.set_count, dlrec.handle, dlrec.device_type); END LOOP; CLOSE rc_deleted_object_c; endDeletedObjectResync; END LOOP; CLOSE bsnames_c; sanityCheck; -- deb('readBackupSections:last xml file resynced ' || bs_xml_filename); delete rcfile where name like prefix_value || '%' and name <> bs_xml_filename; IF bs_xml_filename IS NOT NULL THEN endCkpt; deb('readBackupSections(suc)'); ELSE deb('readBackupSections(no_files_found - re-try again)'); cancelCkpt; END IF; EXCEPTION WHEN OTHERS THEN deb('readBackupSections(fail):'||sqlerrm); cancelCkpt; raise; END readBackupSections; /*---------------------------------------------------------------------------- * This is for oam front end congestion control. If the requirement for a new * backup job exceeds the system bottleneck the job will have to wait. *--------------------------------------------------------------------------*/ PROCEDURE throttle_me(p_oam_job_id IN VARCHAR2, p_channels_reqd IN NUMBER, p_request_time IN DATE, p_wait OUT BOOLEAN, p_error_str OUT VARCHAR2) IS l_wait integer; BEGIN -- IF NOT this_is_ors THEN p_wait := false; RETURN; END IF; deb ('throttle_me: request for db: ' || this_db_unique_name); EXECUTE IMMEDIATE 'begin dbms_rai_throttle_alloc( :p_oam_job_id, :p_db_unique_name, :p_channels_reqd, :p_request_time, :l_wait, :p_error_str); end;' USING IN p_oam_job_id, IN this_db_unique_name, IN p_channels_reqd, IN p_request_time, OUT l_wait, OUT p_error_str; p_wait := (l_wait > 0); END throttle_me; FUNCTION assert_schema ( i_schema IN VARCHAR2 , i_enquote IN BOOLEAN DEFAULT FALSE ) RETURN VARCHAR2 IS l_eschema VARCHAR2(130); l_schema VARCHAR2(130); BEGIN dbms_utility.canonicalize( dbms_assert.enquote_name(i_schema, FALSE) , l_eschema, 130 ); l_schema := dbms_assert.schema_name(l_eschema); IF (i_enquote) THEN RETURN l_eschema; ELSE RETURN l_schema; END IF; END assert_schema; PROCEDURE assert_schema ( o_schema OUT NOCOPY VARCHAR2 , o_eschema OUT NOCOPY VARCHAR2 , i_schema IN VARCHAR2 ) IS BEGIN dbms_utility.canonicalize(dbms_assert.enquote_name(i_schema), o_eschema, 130); o_schema := dbms_assert.schema_name(o_eschema); END assert_schema; /*--------------------------------------------------* * Package Instantiation: Initialize Package State * *--------------------------------------------------*/ BEGIN tsRec.ts# := NULL; -- not in TableSpaceResync dfRec.file# := NULL; -- not in middle of dfResync version_list(1) := '08.00.04.00'; -- -- -- -- -- -- version_list(2) := '08.00.05.00'; -- -- version_list(3) := '08.01.03.00'; -- -- version_list(4) := '08.01.06.00'; -- -- -- -- -- -- -- version_list(5) := '08.01.07.00'; -- -- -- -- -- version_list(6) := '09.00.00.00'; -- -- -- -- -- -- version_list(7) := '09.02.00.00'; -- -- -- version_list(8) := '10.01.00.00'; -- version_list(9) := '10.02.00.00'; version_list(10) := '10.02.00.01'; -- version_list(11) := '11.01.00.00'; version_list(12) := '11.01.00.01'; version_list(13) := '11.01.00.02'; version_list(14) := '11.01.00.03'; version_list(15) := '11.01.00.04'; version_list(16) := '11.01.00.05'; version_list(17) := '11.01.00.06'; version_list(18) := '11.01.00.07'; version_list(19) := '11.02.00.00'; version_list(20) := '11.02.00.01'; version_list(21) := '11.02.00.02'; -- version_list(22) := '12.01.00.00'; version_list(23) := '12.01.00.01'; version_list(24) := '12.01.00.02'; -- version_list(25) := '12.02.00.00'; version_list(26) := '12.02.00.01'; version_max_index := 26; -- initOrsAdmin; IF (orsadmin_user = user) THEN this_is_ors_admin := TRUE; END IF; IF (orsadmin_user IS NOT NULL) THEN this_is_ors := TRUE; END IF; -- FOR i IN 1..vpd_table_list.COUNT LOOP IF (vtr_policy_required(i)) THEN g_vpd_required_policies := g_vpd_required_policies + 1; END IF; END LOOP; init_package_vars(NULL); END dbms_rcvcat; >>> define prvtrmnu_plb <<< -- -- -- CREATE OR REPLACE PACKAGE BODY dbms_rcvman IS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- MAXSCNVAL CONSTANT number := 9e125; -- guaranteed higher than any SCN UB6MAXVAL CONSTANT number := 281474976710655; UB8MAXVAL CONSTANT number := 18446744073709551615; MAXSEQVAL CONSTANT number := 2**32-1; MINDATEVAL CONSTANT date := to_date('01/01/1900','MM/DD/YYYY'); MAXDATEVAL CONSTANT date := to_date('12/31/9999','MM/DD/YYYY'); CONST2GVAL CONSTANT number := 2**31; CONST4GVAL CONSTANT number := 2**32; -- KEEP_NO CONSTANT number := 0; KEEP_LOGS CONSTANT number := 256; KEEP_NOLOGS CONSTANT number := 512; KEEP_CONSIST CONSTANT number := 1024; DEB_UNDEF CONSTANT number := 0; DEB_PRINT CONSTANT number := 0; DEB_ENTER CONSTANT number := 1; DEB_EXIT CONSTANT number := 2; DEB_IN CONSTANT number := 3; DEB_OPEN CONSTANT number := 4; DEB_DEF_PNAME CONSTANT varchar2(50) := 'prvtrmnu'; -- BACKUP_SPARSENESS_UNSPECIFIED CONSTANT number := 0; BACKUP_SPARSENESS_SPARSE CONSTANT number := 1; BACKUP_SPARSENESS_NONSPARSE CONSTANT number := 2; -- -- -- -- -- -- highscnval number := UB6MAXVAL; this_db_key number := NULL; this_dbinc_key number := NULL; this_reset_scn number := NULL; this_reset_time date; this_db_unique_name node.db_unique_name%TYPE; -- used only to identify rows of this_site_key number := NULL; -- configuration and flashback tbl -- -- this_dummy_instance boolean := FALSE; this_stdby_controlfile_scn number := NULL; -- standby controlfile scn used -- -- -- -- -- -- -- -- -- translation_site_key NUMBER := NULL; -- Never NULL realf_site_key number := NULL; -- override df/tf/online log txln user_site_key number := NULL; -- override log/backups/conf/rp txln user_db_unique_name node.db_unique_name%TYPE; -- corresponds to user_site_key client_site_aware number := 0; -- -- -- -- -- -- logs_shared number := 0; -- used only when client_site_aware is 1 disk_backups_shared number := 1; -- indicates shared accross all sites tape_backups_shared number := 1; -- indicates shared accross all sites -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- TYPE incarnation_set_c IS TABLE OF rc_database_incarnation%ROWTYPE index by binary_integer; inc_list incarnation_set_c; -- 0th one is current incarnation, see setDatabase max_inc_idx binary_integer; currInc binary_integer; -- temp variable used to keep track of incarnation -- TYPE pdb_incarnation_set_t IS TABLE OF pdb_incarnation_t index by binary_integer; TYPE pdb_incarnation_coll_t IS TABLE OF pdb_incarnation_set_t index by binary_integer; pdb_inc_list pdb_incarnation_coll_t; -- 0th one is current sub incarnation type pnames is table of varchar2(50) index by binary_integer; pname_i number :=0; last_pnames pnames; debug boolean := FALSE; rsdebug boolean := NULL; -- -- -- -- -- -- -- -- this_baseline_cap number; this_baseline_cap_scn number := NULL; -- -- -- TYPE rcvRecTab_t IS TABLE OF rcvRec_t; -- recovery record stack type rcvRecStack rcvRecTab_t := rcvRecTab_t(); -- recovery record stack -- -- -- TYPE versionList_t IS TABLE OF varchar2(11) INDEX BY binary_integer; versionList versionList_t; versionMaxIndex binary_integer; versionCounter binary_integer; -- -- -- catalogVersion CONSTANT VARCHAR2(11) := '12.02.00.01'; -- getParentIncarnationKey number; -- -- -- allIncarnations number; -- allow records from non-current -- ignoreCreationSCN number; -- a stupid flag that is here -- -- -- -- -- lbacked_al_next_scn NUMBER; standby_became_primary_scn NUMBER; -- -- TYPE lognames_set_c IS TABLE OF al.fname%TYPE index by binary_integer; lognames_list lognames_set_c; -- All the log names returned for same logseq max_lognames_idx binary_integer; -- -- -- -- canApplyAnyRedo number := FALSE#; -- -- -- -- craGetAllCfBackups number := FALSE#; -- -- -- canConvert_Cf number := FALSE#; redoRec rcvRec_t; untilSCN number; untilTime date; rpoint_set boolean; restoreSource number; restoreSparse number := BACKUP_SPARSENESS_UNSPECIFIED; restoreTag bp.tag%TYPE; onlyStandby number; -- -- -- TYPE deviceList_t IS TABLE OF rc_backup_piece.device_type%TYPE INDEX BY binary_integer; deviceList deviceList_t; deviceCount number; diskDevice boolean; anyDevice number; -- -- -- recoveryDestFile boolean; -- -- -- localOrsSiteKey number := null; -- -- -- restoreRangeDevTyp varchar2(10) := null; -- -- -- skipOfflineRangeAboveSCN number := null; -- -- -- orsLocalFile boolean := null; orsLibKey number := null; orsAnyFile boolean := null; -- -- -- -- -- -- -- -- -- redoLogDeletionPolicyType varchar2(512) := 'TO NONE'; -- -- -- extendFullSCN CONSTANT BINARY_INTEGER := 2**0; extendIncrSCN CONSTANT BINARY_INTEGER := 2**1; extendLogSCN CONSTANT BINARY_INTEGER := 2**2; extendAllSCN CONSTANT BINARY_INTEGER := extendFullSCN + extendIncrSCN + extendLogSCN; -- -- -- -- -- -- -- -- -- -- -- -- -- -- noHint constant binary_integer := 0; redundantHint constant binary_integer := 1; localityHint constant binary_integer := 2; TYPE cacheBsRecRow_t IS RECORD ( deviceindx binary_integer, -- index into cacheBsRecTable.devicelist tag varchar2(32), -- may be null copyNumber binary_integer, -- null if code 2 or 3 code binary_integer -- 1 => same copy# -- -- ); TYPE cacheBsRecIndex_t IS TABLE OF cacheBsRecRow_t INDEX BY BINARY_INTEGER; TYPE cacheBsRecHash_t IS RECORD ( bskey number, -- backupset key mixcopy boolean := FALSE, -- TRUE if mixcopy can make set usuable copy cacheBsRecIndex_t -- list of copies ); TYPE cacheBsRecHashList_t IS TABLE OF cacheBsRecHash_t INDEX BY BINARY_INTEGER; TYPE cacheBsRecBsKey_t IS RECORD ( bsindex binary_integer := 1, -- index into bslist bslist cacheBsRecHashList_t -- list of backupset keys in hash table ); TYPE cacheBsRec_t IS TABLE OF cacheBsRecBsKey_t INDEX BY BINARY_INTEGER; TYPE cacheBsRecTable_t IS RECORD ( initlimit boolean := FALSE, -- is limit initialized? limit number := bsRecCacheLowLimit, -- cache size chit number := 0, -- no: of hits in cache mixcopy boolean := FALSE, -- does cache have mix of copyno? minbskey number := 0, -- minimum valid bskey hint binary_integer := noHint, -- access pattern hint -- -- -- -- devicetype rc_backup_piece.device_type%TYPE, mask binary_integer, tag rc_backup_piece.tag%TYPE, devicelist deviceList_t, -- list of devices devicecount binary_integer := 0, -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- bsRec cacheBsRec_t, -- -- -- hitindex binary_integer := 1, -- index into hit list hitlist numTab_t -- -- -- -- -- -- -- -- -- -- -- ); cacheBsRecTable cacheBsRecTable_t; TYPE cacheRequest_t IS RECORD ( bskey number, icopy binary_integer ); findValidCacheRequest cacheRequest_t; -- -- -- TYPE rcvRecStackState_t IS RECORD ( lowAction number, -- action with lowest from_scn on -- -- -- -- -- savePoint number, -- most recently added full_act_t fullBackups number, -- number of full_act_t top number -- top of stack at start of a recursive -- -- ); rcvRecStackState rcvRecStackState_t; -- -- -- computeRA_allRecords number; -- do not stop at first full backup and -- computeRA_fullBackups number; -- stop when reached these many full -- computeRA_restorable boolean; -- cannot recover the datafile we've -- -- -- computeRA_available boolean; -- there is a backup available on -- computeRA_availableMask binary_integer; computeRA_rcvCopy_avail boolean; -- there is a backup available on -- -- -- -- action_OK number := 0; action_FAIL number := 1; action_SKIP number := 2; action_OLD_REDO number := 3; action_WRONG_INCARNATION number := 4; action_OLD_INC_REDO number := 5; old_redo exception; -- redo from old incarnation pragma exception_init(old_redo, -20501); -- -- -- getRA_containerMask number; getRA_actionMask number; getRA_likePattern cdf.fname%TYPE; getRA_completedAfter date; getRA_completedBefore date; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- rcvRecBackupAge number; -- requested age of backup thisBackupAge number; -- current age of backup getBS_status number; -- status of current backup -- -- -- tc_thread number; tc_fromTime date; tc_toTime date; tc_fromSCN number; tc_toSCN number; tc_fromSeq number; tc_toSeq number; tc_pattern varchar2(512); TYPE fileTab_t IS TABLE of boolean index by binary_integer; tc_fno fileTab_t; tc_database number; TYPE sequenceTab_t IS TABLE of boolean index by binary_integer; TYPE threadseqTab_t IS TABLE of sequenceTab_t index by binary_integer; tc_threadSeq threadSeqTab_t; TYPE dbidTab_t IS TABLE OF boolean index by binary_integer; tc_dbid dbidTab_t; tc_anydbid number; -- -- -- -- -- canHandleTransportableTbs number := FALSE#; guidQualifier varchar2(32); guid2pdbkeyQualifier number; -- -- -- actual_dbinc_key number := NULL; -- see comments on getActualDbinc -- -- SESSION_KEY number; SESSION_FROMTIME DATE; SESSION_UNTILTIME DATE; -- -- -- -- -- -- -- lb_NeedObsoleteData number := TRUE#; CURSOR listBackup_c RETURN lbRec_t IS SELECT -- bs.bs_key list_order1, 0 list_order2, bs.bs_key pkey, backupset_txt backup_type, backupset_txt file_type, decode(bs.keep_options, 0, 'NO', 'YES') keep, bs.keep_until keep_until, decode(bs.keep_options, 256, 'LOGS', 512, 'NOLOGS', 1024, 'BACKUP_LOGS', null) keep_options, null status, null fname, null tag, null media, bs.bs_recid recid, bs.bs_stamp stamp, null device_type, 0 block_size, bs.completion_time completion_time, 'NO' is_rdf, null compressed, null obsolete, null keep_for_dbpitr, null bytes, bs.bs_key bs_key, bs.set_count bs_count, bs.set_stamp bs_stamp, decode(bs.bck_type, 'L', archivedlog_txt, datafile_txt) bs_type, decode(bs.incr_level, 0, full_txt, 1, incr1_txt, 2, incr2_txt, 3, incr3_txt, 4, incr4_txt, decode(bs.bck_type, 'I', incr_txt, full_txt)) bs_incr_type, bs.pieces bs_pieces, null bs_copies, bs.completion_time bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, null df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, null df_resetlogs_change#, null df_creation_change#, null df_checkpoint_change#, null df_ckp_mod_time, null df_incremental_change#, null rl_thread#, null rl_sequence#, null rl_resetlogs_change#, null rl_first_change#, null rl_first_time, null rl_next_change#, null rl_next_time, null sf_db_unique_name, null con_id FROM bs WHERE bs.db_key = this_db_key AND (bs.site_key IS NULL OR -- always return null site_key user_site_key = bs.site_key OR -- user interested in one site (user_site_key IS NULL AND -- return rows per access attr (disk_backups_shared = TRUE# OR tape_backups_shared = TRUE# OR this_site_key = bs.site_key))) UNION ALL SELECT -- bp.bs_key list_order1, 1 list_order2, bp.bp_key pkey, backupset_txt backup_type, piece_txt file_type, null keep, null keep_until, null keep_options, decode(bp.status, 'A', available_txt, 'U', unavailable_txt, 'X', expired_txt, other_txt) status, bp.handle fname, bp.tag tag, bp.media media, bp.bp_recid recid, bp.bp_stamp stamp, bp.device_type device_type, 0 block_size, bp.completion_time completion_time, bp.is_recovery_dest_file is_rdf, bp.compressed compressed, null obsolete, null keep_for_dbpitr, bp.bytes bytes, bp.bs_key bs_key, null bs_count, null bs_stamp, null bs_type, null bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, bp.piece# bp_piece#, bp.copy# bp_copy#, bp.vb_key bp_vb_key, bp.ba_access bp_ba_access, bp.lib_key bp_lib_key, null df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, null df_resetlogs_change#, null df_creation_change#, null df_checkpoint_change#, null df_ckp_mod_time, null df_incremental_change#, null rl_thread#, null rl_sequence#, null rl_resetlogs_change#, null rl_first_change#, null rl_first_time, null rl_next_change#, null rl_next_time, null sf_db_unique_name, null con_id FROM bp WHERE bp.db_key = this_db_key AND bp.status != 'D' AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) UNION ALL SELECT -- bdf.bs_key list_order1, 2 list_order2, bdf.bdf_key pkey, backupset_txt backup_type, datafile_txt file_type, null keep, null keep_until, null keep_options, null status, null fname, null tag, null media, bdf.bdf_recid recid, bdf.bdf_stamp stamp, null device_type, bdf.block_size block_size, bdf.completion_time completion_time, 'NO' is_rdf, null compressed, null obsolete, null keep_for_dbpitr, bdf.block_size * bdf.blocks bytes, bdf.bs_key bs_key, null bs_count, null bs_stamp, null bs_type, decode(bdf.incr_level, 0, full_txt, 1, incr1_txt, 2, incr2_txt, 3, incr3_txt, 4, incr4_txt, decode(greatest(bdf.create_scn, bdf.incr_scn), bdf.create_scn, full_txt, incr_txt)) bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, bdf.file# df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, dbinc.reset_scn df_resetlogs_change#, bdf.create_scn df_creation_change#, bdf.ckp_scn df_checkpoint_change#, bdf.ckp_time df_ckp_mod_time, bdf.incr_scn df_incremental_change#, null rl_thread#, null rl_sequence#, null rl_resetlogs_change#, null rl_first_change#, null rl_first_time, null rl_next_change#, null rl_next_time, null sf_db_unique_name, null con_id FROM bdf, dbinc WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = bdf.dbinc_key UNION ALL SELECT -- bcf.bs_key list_order1, 2 list_order2, bcf.bcf_key pkey, backupset_txt backup_type, controlfile_txt file_type, null keep, null keep_until, null keep_options, null status, null fname, null tag, null media, bcf.bcf_recid recid, bcf.bcf_stamp stamp, null device_type, bcf.block_size block_size, null completion_time, 'NO' is_rdf, null compressed, null obsolete, null keep_for_dbpitr, bcf.block_size * bcf.blocks bytes, bcf.bs_key bs_key, null bs_count, null bs_stamp, null bs_type, full_txt bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, 0 df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, dbinc.reset_scn df_resetlogs_change#, 0 df_creation_change#, bcf.ckp_scn df_checkpoint_change#, bcf.ckp_time df_ckp_mod_time, null df_incremental_change#, null rl_thread#, null rl_sequence#, null rl_resetlogs_change#, null rl_first_change#, null rl_first_time, null rl_next_change#, null rl_next_time, null sf_db_unique_name, null con_id FROM bcf, dbinc WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = bcf.dbinc_key UNION ALL SELECT -- brl.bs_key list_order1, 2 list_order2, brl.brl_key pkey, backupset_txt backup_type, archivedlog_txt file_type, null keep, null keep_until, null keep_options, null status, null fname, null tag, null media, brl.brl_recid recid, brl.brl_stamp stamp, null device_type, brl.block_size block_size, null completion_time, 'NO' is_rdf, null compressed, null obsolete, null keep_for_dbpitr, brl.block_size * brl.blocks bytes, brl.bs_key bs_key, null bs_count, null bs_stamp, null bs_type, null bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, null df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, null df_resetlogs_change#, null df_creation_change#, null df_checkpoint_change#, null df_ckp_mod_time, null df_incremental_change#, brl.thread# rl_thread#, brl.sequence# rl_sequence#, dbinc.reset_scn rl_resetlogs_change#, brl.low_scn rl_first_change#, brl.low_time rl_first_time, brl.next_scn rl_next_change#, brl.next_time rl_next_time, null sf_db_unique_name, null con_id FROM brl, dbinc WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = brl.dbinc_key UNION ALL SELECT -- bsf.bs_key list_order1, 2 list_order2, bsf.bsf_key pkey, backupset_txt backup_type, spfile_txt file_type, null keep, null keep_until, null keep_options, null status, null fname, null tag, null media, bsf.bsf_recid recid, bsf.bsf_stamp stamp, null device_type, 0 block_size, null completion_time, 'NO' is_rdf, null compressed, null obsolete, null keep_for_dbpitr, bsf.bytes bytes, bsf.bs_key bs_key, null bs_count, null bs_stamp, null bs_type, full_txt bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, null df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, 0 df_resetlogs_change#, 0 df_creation_change#, 0 df_checkpoint_change#, bsf.modification_time df_ckp_mod_time, null df_incremental_change#, null rl_thread#, null rl_sequence#, null rl_resetlogs_change#, null rl_first_change#, null rl_first_time, null rl_next_change#, null rl_next_time, db_unique_name sf_db_unique_name, null con_id FROM bsf WHERE bsf.db_key = this_db_key UNION ALL SELECT -- cdf.cdf_key list_order1, -1 list_order2, cdf.cdf_key pkey, copy_txt backup_type, datafile_txt file_type, decode(cdf.keep_options, 0, 'NO', 'YES') keep, cdf.keep_until keep_until, decode(cdf.keep_options, 256, 'LOGS', 512, 'NOLOGS', 1024, 'BACKUP_LOGS', NULL) keep_options, decode(cdf.status, 'A', available_txt, 'U', unavailable_txt, 'X', expired_txt, other_txt) status, cdf.fname fname, cdf.tag tag, null media, cdf.cdf_recid recid, cdf.cdf_stamp stamp, 'DISK' device_type, cdf.block_size block_size, cdf.completion_time completion_time, cdf.is_recovery_dest_file is_rdf, null compressed, null obsolete, null keep_for_dbpitr, cdf.block_size * cdf.blocks bytes, null bs_key, null bs_count, null bs_stamp, null bs_type, null bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, cdf.file# df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, dbinc.reset_scn df_resetlogs_change#, cdf.create_scn df_creation_change#, cdf.ckp_scn df_checkpoint_change#, cdf.ckp_time df_ckp_mod_time, null df_incremental_change#, null rl_thread#, null rl_sequence#, null rl_resetlogs_change#, null rl_first_change#, null rl_first_time, null rl_next_change#, null rl_next_time, null sf_db_unique_name, null con_id FROM cdf, dbinc WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = cdf.dbinc_key AND ((user_site_key = cdf.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(cdf.site_key, this_site_key))))) UNION ALL SELECT -- ccf.ccf_key list_order1, -1 list_order2, ccf.ccf_key pkey, copy_txt backup_type, controlfile_txt file_type, decode(ccf.keep_options, 0, 'NO', 'YES') keep, ccf.keep_until keep_until, decode(ccf.keep_options, 256, 'LOGS', 512, 'NOLOGS', 1024, 'BACKUP_LOGS', NULL) keep_options, decode(ccf.status, 'A', available_txt, 'U', unavailable_txt, 'X', expired_txt, other_txt) status, ccf.fname fname, ccf.tag tag, null media, ccf.ccf_recid recid, ccf.ccf_stamp stamp, 'DISK' device_type, ccf.block_size block_size, ccf.completion_time completion_time, ccf.is_recovery_dest_file is_rdf, null compressed, null obsolete, null keep_for_dbpitr, null bytes, null bs_key, null bs_count, null bs_stamp, null bs_type, null bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, 0 df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, dbinc.reset_scn df_resetlogs_change#, 0 df_creation_change#, ccf.ckp_scn df_checkpoint_change#, ccf.ckp_time df_ckp_mod_time, null df_incremental_change#, null rl_thread#, null rl_sequence#, null rl_resetlogs_change#, null rl_first_change#, null rl_first_time, null rl_next_change#, null rl_next_time, null sf_db_unique_name, null con_id FROM ccf, dbinc WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = ccf.dbinc_key AND ((user_site_key = ccf.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(ccf.site_key, this_site_key))))) UNION ALL SELECT -- al.al_key list_order1, -1 list_order2, al.al_key pkey, copy_txt backup_type, archivedlog_txt file_type, null keep, null keep_until, null keep_options, decode(al.status, 'A', available_txt, 'U', unavailable_txt, 'X', expired_txt, other_txt) status, al.fname fname, null tag, null media, al.al_recid recid, al.al_stamp stamp, 'DISK' device_type, al.block_size block_size, al.completion_time completion_time, al.is_recovery_dest_file is_rdf, al.compressed compressed, null obsolete, null keep_for_dbpitr, al.block_size * al.blocks bytes, null bs_key, null bs_count, null bs_stamp, null bs_type, null bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, null df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, null df_resetlogs_change#, null df_creation_change#, null df_checkpoint_change#, null df_ckp_mod_time, null df_incremental_change#, al.thread# rl_thread#, al.sequence# rl_sequence#, dbinc.reset_scn rl_resetlogs_change#, al.low_scn rl_first_change#, al.low_time rl_first_time, al.next_scn rl_next_change#, al.next_time rl_next_time, null sf_db_unique_name, null con_id FROM dbinc, al LEFT OUTER JOIN grsp ON al.next_scn >= grsp.from_scn AND al.low_scn <= (grsp.to_scn + 1) AND al.dbinc_key = grsp.dbinc_key AND grsp.from_scn <= grsp.to_scn -- filter clean grp AND grsp.from_scn != 0 AND grsp.guaranteed = 'YES' WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = al.dbinc_key AND al.archived = 'Y' AND grsp.from_scn is null AND ((client_site_aware = TRUE# AND ((user_site_key = al.site_key) OR (user_site_key IS NULL AND (logs_shared = TRUE# OR this_site_key = nvl(al.site_key, this_site_key))))) OR (client_site_aware = FALSE#)) UNION ALL SELECT -- xdf.xdf_key list_order1, -1 list_order2, xdf.xdf_key pkey, proxycopy_txt backup_type, datafile_txt file_type, decode(xdf.keep_options, 0, 'NO', 'YES') keep, xdf.keep_until keep_until, decode(xdf.keep_options, 256, 'LOGS', 512, 'NOLOGS', 1024, 'BACKUP_LOGS', NULL) keep_options, decode(xdf.status, 'A', available_txt, 'U', unavailable_txt, 'X', expired_txt, other_txt) status, xdf.handle fname, xdf.tag tag, xdf.media media, xdf.xdf_recid recid, xdf.xdf_stamp stamp, xdf.device_type device_type, xdf.block_size block_size, xdf.completion_time completion_time, 'NO' is_rdf, null compressed, null obsolete, null keep_for_dbpitr, xdf.block_size * xdf.blocks bytes, null bs_key, null bs_count, null bs_stamp, null bs_type, null bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, xdf.file# df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, dbinc.reset_scn df_resetlogs_change#, xdf.create_scn df_creation_change#, xdf.ckp_scn df_checkpoint_change#, xdf.ckp_time df_ckp_mod_time, null df_incremental_change#, null rl_thread#, null rl_sequence#, null rl_resetlogs_change#, null rl_first_change#, null rl_first_time, null rl_next_change#, null rl_next_time, null sf_db_unique_name, null con_id FROM xdf, dbinc WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = xdf.dbinc_key AND ((user_site_key = xdf.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xdf.site_key, this_site_key))))) UNION ALL SELECT -- xcf.xcf_key list_order1, -1 list_order2, xcf.xcf_key pkey, proxycopy_txt backup_type, controlfile_txt file_type, decode(xcf.keep_options, 0, 'NO', 'YES') keep, xcf.keep_until keep_until, decode(xcf.keep_options, 256, 'LOGS', 512, 'NOLOGS', 1024, 'BACKUP_LOGS', NULL) keep_options, decode(xcf.status, 'A', available_txt, 'U', unavailable_txt, 'X', expired_txt, other_txt) status, xcf.handle fname, xcf.tag tag, xcf.media media, xcf.xcf_recid recid, xcf.xcf_stamp stamp, xcf.device_type device_type, xcf.block_size block_size, xcf.completion_time completion_time, 'NO' is_rdf, null compressed, null obsolete, null keep_for_dbpitr, null bytes, null bs_key, null bs_count, null bs_stamp, null bs_type, null bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, 0 df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, dbinc.reset_scn df_resetlogs_change#, 0 df_creation_change#, xcf.ckp_scn df_checkpoint_change#, xcf.ckp_time df_ckp_mod_time, null df_incremental_change#, null rl_thread#, null rl_sequence#, null rl_resetlogs_change#, null rl_first_change#, null rl_first_time, null rl_next_change#, null rl_next_time, null sf_db_unique_name, null con_id FROM xcf, dbinc WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = xcf.dbinc_key AND ((user_site_key = xcf.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xcf.site_key, this_site_key))))) UNION ALL SELECT -- xal.xal_key list_order1, -1 list_order2, xal.xal_key pkey, proxycopy_txt backup_type, archivedlog_txt file_type, decode(xal.keep_options, 0, 'NO', 'YES') keep, xal.keep_until keep_until, decode(xal.keep_options, 256, 'LOGS', 512, 'NOLOGS', 1024, 'BACKUP_LOGS', NULL) keep_options, decode(xal.status, 'A', available_txt, 'U', unavailable_txt, 'X', expired_txt, other_txt) status, xal.handle fname, xal.tag tag, xal.media media, xal.xal_recid recid, xal.xal_stamp stamp, xal.device_type device_type, xal.block_size block_size, xal.completion_time completion_time, 'NO' is_rdf, null compressed, null obsolete, null keep_for_dbpitr, xal.block_size * xal.blocks bytes, null bs_key, null bs_count, null bs_stamp, null bs_type, null bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, null df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, dbinc.reset_scn df_resetlogs_change#, 0 df_creation_change#, null df_checkpoint_change#, null df_ckp_mod_time, null df_incremental_change#, xal.thread# rl_thread#, xal.sequence# rl_sequence#, dbinc.reset_scn rl_resetlogs_change#, xal.low_scn rl_first_change#, xal.low_time rl_first_time, xal.next_scn rl_next_change#, xal.next_time rl_next_time, null sf_db_unique_name, null con_id FROM xal, dbinc WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = xal.dbinc_key AND ((user_site_key = xal.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xal.site_key, this_site_key))))) -- -- ORDER BY list_order1, list_order2, bp_piece#; -- -- -- -- -- -- -- CURSOR findControlfileBackup_c( sourcemask IN number ,currentIncarnation IN number DEFAULT TRUE# ,tag IN varchar2 DEFAULT NULL ,pattern IN varchar2 DEFAULT NULL ,completedAfter IN date DEFAULT NULL ,completedBefore IN date DEFAULT NULL ,untilSCN IN number DEFAULT NULL ,statusMask IN binary_integer DEFAULT BSavailable -- ,needstby IN number DEFAULT NULL ,typemask IN binary_integer DEFAULT BScfile_all ,fromSCN IN number DEFAULT 0 -- ) RETURN rcvRec_t IS SELECT imageCopy_con_t type_con, ccf_key key_con, ccf_recid recid_con, ccf_stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, fname fileName_con, tag tag_con, to_number(null) copyNumber_con, status status_con, to_number(null) blocks_con, -- ccf doesn't have blocks block_size blockSize_con, 'DISK' deviceType_con, completion_time compTime_con, create_time cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, full_act_t type_act, 0 fromSCN_act, ccf.ckp_scn toSCN_act, ccf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, ccf.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, 0 dfNumber_obj, 0 dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, nvl(controlfile_type, 'B') cfType_obj, ccf.pdb_key pdbKey_obj, ccf.keep_options keep_options, ccf.keep_until keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, is_recovery_dest_file isrdf_con, site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM ccf, dbinc WHERE dbinc.db_key = this_db_key -- belongs to this database AND dbinc.dbinc_key = ccf.dbinc_key AND (findControlfileBackup_c.currentIncarnation = FALSE# OR this_dbinc_key = ccf.dbinc_key) AND (findControlfileBackup_c.tag is NULL OR findControlfileBackup_c.tag = tag) AND (findControlfileBackup_c.pattern is NULL OR fname LIKE replace(replace(findControlfileBackup_c.pattern, '*','**'), '_', '*_') ESCAPE '*') AND (findControlfileBackup_c.completedAfter is NULL OR completion_time >= findControlfileBackup_c.completedAfter) AND (findControlfileBackup_c.completedBefore is NULL OR completion_time <= findControlfileBackup_c.completedBefore) AND (findControlfileBackup_c.untilSCN is NULL OR ccf.ckp_scn <= findControlfileBackup_c.untilSCN) AND decode(statusMask, BSavailable, decode(status, 'A', TRUE#, FALSE#), isStatusMatch(status, statusMask)) = TRUE# AND (needstby is NULL OR nvl(controlfile_type,'B') = decode(needstby, TRUE#, 'S', 'B') OR canConvert_Cf = TRUE#) AND (sourcemask is NULL OR bitand(sourcemask, imageCopy_con_t) != 0) AND ((user_site_key = ccf.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(ccf.site_key, this_site_key))))) AND ccf.ckp_scn >= findControlfileBackup_c.fromSCN AND (guidQualifier IS NULL OR ccf.pdb_key = guid2pdbKeyQualifier) UNION ALL SELECT proxyCopy_con_t type_con, xcf_key key_con, xcf_recid recid_con, xcf_stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, handle fileName_con, tag tag_con, to_number(null) copyNumber_con, status status_con, to_number(null) blocks_con, -- xcf doesn't have blocks block_size blockSize_con, device_type deviceType_con, completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, full_act_t type_act, 0 fromSCN_act, xcf.ckp_scn toSCN_act, xcf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, xcf.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, 0 dfNumber_obj, 0 dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, nvl(controlfile_type, 'B') cfType_obj, xcf.pdb_key pdbKey_obj, xcf.keep_options keep_options, xcf.keep_until keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, media media_con, 'NO' isrdf_con, site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM xcf, dbinc WHERE db_key = this_db_key -- belongs to this database AND dbinc.dbinc_key = xcf.dbinc_key AND (findControlfileBackup_c.currentIncarnation = FALSE# OR this_dbinc_key = xcf.dbinc_key) AND (findControlfileBackup_c.tag is NULL OR findControlfileBackup_c.tag = tag) AND (findControlfileBackup_c.pattern is NULL OR handle LIKE replace(replace(findControlfileBackup_c.pattern, '*','**'), '_', '*_') ESCAPE '*') AND (findControlfileBackup_c.completedAfter is NULL OR completion_time >= findControlfileBackup_c.completedAfter) AND (findControlfileBackup_c.completedBefore is NULL OR completion_time <= findControlfileBackup_c.completedBefore) AND (findControlfileBackup_c.untilSCN is NULL OR xcf.ckp_scn <= findControlfileBackup_c.untilSCN) AND decode(statusMask, BSavailable, decode(status, 'A', TRUE#, FALSE#), isStatusMatch(status, statusMask)) = TRUE# AND (needstby is NULL OR nvl(controlfile_type,'B') = decode(needstby, TRUE#, 'S', 'B') OR canConvert_Cf = TRUE#) AND (sourcemask is NULL OR bitand(sourcemask, proxyCopy_con_t) != 0) AND ((user_site_key = xcf.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xcf.site_key, this_site_key))))) AND xcf.ckp_scn >= findControlfileBackup_c.fromSCN AND (guidQualifier IS NULL OR xcf.pdb_key = guid2pdbKeyQualifier) UNION ALL SELECT backupSet_con_t type_con, bcf_key key_con, bcf_recid recid_con, bcf_stamp stamp_con, bs.set_stamp setStamp_con, bs.set_count setCount_con, bs.bs_recid bsRecid_con, bs.bs_stamp bsStamp_con, bs.bs_key bsKey_con, bs.incr_level bsLevel_con, bs.bck_type bsType_con, abs((bs.completion_time - bs.start_time) * 86400) elapseSecs_con, bs.pieces pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, bcf.blocks blocks_con, bcf.block_size blockSize_con, to_char(null) deviceType_con, bs.completion_time compTime_con, bcf.create_time cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, multi_section multi_section_con, full_act_t type_act, 0 fromSCN_act, bcf.ckp_scn toSCN_act, bcf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, bcf.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, 0 dfNumber_obj, 0 dfCreationSCN_obj, bcf.autobackup_sequence cfSequence_obj, bcf.autobackup_date cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, nvl(controlfile_type, 'B') cfType_obj, bcf.pdb_key pdbKey_obj, bs.keep_options keep_options, bs.keep_until keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, bs.site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM bs, bcf, dbinc WHERE dbinc.db_key = this_db_key -- belongs to this database AND bs.db_key = this_db_key -- belongs to this database AND bcf.dbinc_key = dbinc.dbinc_key -- join bcf and dbinc AND bcf.bs_key = bs.bs_key -- join bcf and bs AND bs.bck_type != 'L' -- ignore archivelog backups AND (findControlfileBackup_c.currentIncarnation = FALSE# OR this_dbinc_key = bcf.dbinc_key) AND (findControlfileBackup_c.completedAfter is NULL OR bs.completion_time >= findControlfileBackup_c.completedAfter) AND (findControlfileBackup_c.completedBefore is NULL OR bs.completion_time <= findControlfileBackup_c.completedBefore) AND (findControlfileBackup_c.untilSCN is NULL OR bcf.ckp_scn <= findControlfileBackup_c.untilSCN) AND (needstby is NULL OR nvl(controlfile_type,'B') = decode(needstby, TRUE#, 'S', 'B') OR canConvert_Cf = TRUE#) AND ((typemask = 0 AND bcf.autobackup_date IS NULL) OR -- no autobackups (bitand(typemask, BScfile_all) != 0) OR -- all backups (bcf.autobackup_date IS NOT NULL AND -- only autobackups bitand(typemask, BScfile_auto) != 0)) AND (sourcemask is NULL OR bitand(sourcemask, backupSet_con_t) != 0) AND (bs.site_key IS NULL OR -- always return null site_key user_site_key = bs.site_key OR -- user interested in one site (user_site_key IS NULL AND -- return rows per access attr (disk_backups_shared = TRUE# OR tape_backups_shared = TRUE# OR this_site_key = bs.site_key))) AND bcf.ckp_scn >= findControlfileBackup_c.fromSCN AND (guidQualifier IS NULL OR bcf.pdb_key = guid2pdbKeyQualifier) ORDER BY toSCN_act desc, stamp_con desc; -- -- -- CURSOR findSpfileBackup_c( completedAfter IN date DEFAULT NULL ,completedBefore IN date DEFAULT NULL ,untilTime IN date DEFAULT NULL ,rmanCmd IN number DEFAULT unknownCmd_t) RETURN rcvRec_t IS -- SELECT backupSet_con_t type_con, bsf_key key_con, bsf_recid recid_con, bsf_stamp stamp_con, bs.set_stamp setStamp_con, bs.set_count setCount_con, bs.bs_recid bsRecid_con, bs.bs_stamp bsStamp_con, bs.bs_key bsKey_con, bs.incr_level bsLevel_con, bs.bck_type bsType_con, abs((bs.completion_time - bs.start_time) * 86400) elapseSecs_con, bs.pieces pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, 0 blocks_con, 0 blockSize_con, to_char(null) deviceType_con, bs.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, multi_section multi_section_con, full_act_t type_act, 0 fromSCN_act, 0 toSCN_act, nvl(modification_time, bs.completion_time) toTime_act, to_number(null) rlgSCN_act, to_date(null) rlgTime_act, to_number(null) dbincKey_act, to_number(null) level_act, 0 section_size_act, to_number(null) dfNumber_obj, to_number(null) dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, bsf.pdb_key pdbKey_obj, bs.keep_options keep_options, bs.keep_until keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, bs.site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, db_unique_name sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM bsf, bs, db -- -- -- WHERE rmanCmd != obsoleteCmd_t AND bsf.bs_key = bs.bs_key -- join bsf and bs AND bs.bck_type != 'L' -- ignore archivelog backups AND bs.db_key = this_db_key -- belongs to this database AND bsf.db_key = db.db_key -- join bsf and db AND (findSpfileBackup_c.completedAfter is NULL OR bs.completion_time >= findSpfileBackup_c.completedAfter) AND (findSpfileBackup_c.completedBefore is NULL OR bs.completion_time <= findSpfileBackup_c.completedBefore) AND (findSpfileBackup_c.untilTime is NULL OR nvl(modification_time,bs.start_time) <= findSpfileBackup_c.untilTime) AND (rmanCmd != restoreCmd_t OR (rmanCmd = restoreCmd_t AND (bsf.db_unique_name is NULL OR nvl(user_db_unique_name, this_db_unique_name) = bsf.db_unique_name))) AND (bs.site_key IS NULL OR -- always return null site_key (disk_backups_shared = TRUE# OR tape_backups_shared = TRUE# OR this_site_key = bs.site_key)) AND (guidQualifier IS NULL OR bsf.pdb_key = guid2pdbKeyQualifier) UNION ALL -- SELECT backupSet_con_t type_con, bsf_key key_con, bsf_recid recid_con, bsf_stamp stamp_con, bs.set_stamp setStamp_con, bs.set_count setCount_con, bs.bs_recid bsRecid_con, bs.bs_stamp bsStamp_con, bs.bs_key bsKey_con, bs.incr_level bsLevel_con, bs.bck_type bsType_con, abs((bs.completion_time - bs.start_time) * 86400) elapseSecs_con, bs.pieces pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, 0 blocks_con, 0 blockSize_con, to_char(null) deviceType_con, bs.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, multi_section multi_section_con, full_act_t type_act, 0 fromSCN_act, 0 toSCN_act, nvl(modification_time, bs.completion_time) toTime_act, to_number(null) rlgSCN_act, to_date(null) rlgTime_act, to_number(null) dbincKey_act, to_number(null) level_act, 0 section_size_act, to_number(null) dfNumber_obj, to_number(null) dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, bsf.pdb_key pdbKey_obj, bs.keep_options keep_options, bs.keep_until keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, bs.site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, db_unique_name sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM bsf, bs, db, (SELECT bs_key, count(distinct piece#) pieces FROM bp WHERE rmanCmd = obsoleteCmd_t AND bp.db_key = this_db_key -- this database AND bp.status = 'A' AND (anyDevice = TRUE# OR isDeviceTypeAllocated(bp.device_type) = TRUE#) AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared=TRUE# AND bp.device_type='DISK') OR (tape_backups_shared=TRUE# AND bp.device_type<>'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) GROUP BY bs_key, device_type) bp -- -- -- WHERE rmanCmd = obsoleteCmd_t AND bsf.bs_key = bs.bs_key -- join bsf and bs AND bs.bck_type != 'L' -- ignore archivelog backups AND bs.db_key = this_db_key -- belongs to this database AND bs.bs_key = bp.bs_key -- join bs and bp AND bs.pieces = bp.pieces AND bsf.db_key = db.db_key -- join bsf and db AND (findSpfileBackup_c.completedAfter is NULL OR bs.completion_time >= findSpfileBackup_c.completedAfter) AND (findSpfileBackup_c.completedBefore is NULL OR bs.completion_time <= findSpfileBackup_c.completedBefore) AND (findSpfileBackup_c.untilTime is NULL OR nvl(modification_time,bs.start_time) <= findSpfileBackup_c.untilTime) AND (guidQualifier IS NULL OR bsf.pdb_key = guid2pdbKeyQualifier) ORDER BY toTime_act desc, -- for finding best backup stamp_con desc; -- to get most recent -- -- -- getDatafileBackupLast rcvRec_t; CURSOR findDatafileBackup_c( sourcemask IN number ,fno IN number DEFAULT NULL ,crescn IN number DEFAULT NULL -- ,tag IN varchar2 DEFAULT NULL ,pattern IN varchar2 DEFAULT NULL ,reset_scn IN number DEFAULT NULL ,reset_time IN date DEFAULT NULL ,level IN number DEFAULT NULL ,completedAfter IN date DEFAULT NULL ,completedBefore IN date DEFAULT NULL ,untilSCN IN number DEFAULT NULL ,statusMask IN binary_integer DEFAULT BSavailable -- ,onlyrdf IN binary_integer DEFAULT 0 -- ,duplicates IN number DEFAULT NULL ,onlytc IN binary_integer DEFAULT FALSE# -- ,pluginSCN IN number DEFAULT 0 ,allowCumuLevelN IN binary_integer DEFAULT FALSE# -- ) RETURN rcvRec_t IS SELECT imageCopy_con_t type_con, cdf.cdf_key key_con, cdf.cdf_recid recid_con, cdf.cdf_stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, cdf.fname fileName_con, cdf.tag tag_con, to_number(null) copyNumber_con, cdf.status status_con, cdf.blocks blocks_con, cdf.block_size blockSize_con, 'DISK' deviceType_con, cdf.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, full_act_t type_act, 0 fromSCN_act, cdf.ckp_scn toSCN_act, cdf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, cdf.dbinc_key dbincKey_act, cdf.incr_level level_act, 0 section_size_act, cdf.file# dfNumber_obj, cdf.create_scn dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, cdf.pdb_key pdbKey_obj, cdf.keep_options keep_options, cdf.keep_until keep_until, cdf.abs_fuzzy_scn afzSCN_act, cdf.rcv_fuzzy_time rfzTime_act, cdf.rcv_fuzzy_scn rfzSCN_act, to_char(null) media_con, is_recovery_dest_file isrdf_con, site_key site_key_con, cdf.foreign_dbid foreignDbid_obj, decode(cdf.plugged_readonly, 'YES', 1, 0) pluggedRonly_obj, cdf.plugin_scn pluginSCN_obj, cdf.plugin_reset_scn pluginRlgSCN_obj, cdf.plugin_reset_time pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, decode(cdf.plugged_readonly, 'NO', cdf.ckp_scn, cdf.plugin_scn) newToSCN_act, decode(cdf.plugin_scn, 0, dbinc.reset_scn, cdf.plugin_reset_scn) newRlgSCN_act, decode(cdf.plugin_scn, 0, dbinc.reset_time, cdf.plugin_reset_time) newRlgTime_act, to_char(null) sfDbUniqueName_obj, cdf.sparse_backup sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM cdf, dbinc, (SELECT DISTINCT max(cdf_recid) duprecid FROM cdf, dbinc WHERE (findDatafileBackup_c.tag is NULL OR tag = findDatafileBackup_c.tag) AND cdf.dbinc_key = dbinc.dbinc_key AND dbinc.db_key = this_db_key AND (findDatafileBackup_c.pattern is NULL OR cdf.fname LIKE replace(replace(findDatafileBackup_c.pattern, '*','**'), '_', '*_') ESCAPE '*') GROUP BY cdf.file#, cdf.create_scn, dbinc.reset_scn, dbinc.reset_time, cdf.ckp_time, cdf.ckp_scn, cdf.abs_fuzzy_scn, cdf.rcv_fuzzy_scn, cdf.bck_fuzzy, cdf.onl_fuzzy, dbinc.db_key, cdf.plugin_scn, cdf.plugin_reset_scn, cdf.plugin_reset_time) dup WHERE cdf.cdf_recid = dup.duprecid(+) AND (sourcemask is NULL OR bitand(sourcemask, imageCopy_con_t) != 0) AND (dbinc.db_key = this_db_key) -- belongs to this database AND (dbinc.dbinc_key = cdf.dbinc_key) -- join cdf and dbinc AND (findDatafileBackup_c.reset_scn is NULL OR canApplyAnyRedo = TRUE# OR (cdf.plugged_readonly = 'NO' AND findDatafileBackup_c.reset_scn = dbinc.reset_scn AND findDatafileBackup_c.reset_time = dbinc.reset_time) OR (cdf.plugged_readonly = 'YES' AND findDatafileBackup_c.reset_scn = cdf.plugin_reset_scn AND findDatafileBackup_c.reset_time = cdf.plugin_reset_time)) AND cdf.file# = nvl(findDatafileBackup_c.fno, cdf.file#) -- -- AND cdf.file# != 0 -- no ctrl bkps AND (onlytc = FALSE# OR tc_database = TRUE# OR isTranslatedFno(cdf.file#) = TRUE#) -- only tnslated files AND ((findDatafileBackup_c.pluginSCN = 0 AND cdf.plugin_scn = 0 AND cdf.create_scn = findDatafileBackup_c.crescn) OR (findDatafileBackup_c.pluginSCN != 0 AND cdf.plugin_scn = findDatafileBackup_c.pluginSCN) OR (findDatafileBackup_c.pluginSCN = 0 AND findDatafileBackup_c.crescn IS NULL)) AND decode(statusMask, BSavailable, decode(status, 'A', TRUE#, FALSE#), isStatusMatch(status, statusMask)) = TRUE# AND (findDatafileBackup_c.tag is NULL OR tag = findDatafileBackup_c.tag) AND (findDatafileBackup_c.pattern is NULL OR cdf.fname LIKE replace(replace(findDatafileBackup_c.pattern, '*','**'), '_', '*_') ESCAPE '*') AND (findDatafileBackup_c.completedAfter is NULL OR cdf.completion_time >= findDatafileBackup_c.completedAfter) AND (findDatafileBackup_c.completedBefore is NULL OR cdf.completion_time <= findDatafileBackup_c.completedBefore) AND (findDatafileBackup_c.untilSCN is NULL OR (cdf.plugged_readonly = 'NO' AND cdf.ckp_scn <= findDatafileBackup_c.untilSCN) OR (cdf.plugged_readonly = 'YES' AND cdf.plugin_scn <= findDatafileBackup_c.untilSCN)) AND (findDatafileBackup_c.level is NULL OR cdf.incr_level <= findDatafileBackup_c.level) AND (findDatafileBackup_c.onlyrdf = 0 OR cdf.is_recovery_dest_file = 'YES') AND (duplicates IS NULL OR duplicates = TRUE# OR (duplicates = FALSE# AND duprecid IS NOT NULL)) AND ((user_site_key = cdf.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(cdf.site_key, this_site_key))))) AND (guidQualifier IS NULL OR cdf.pdb_key = guid2pdbKeyQualifier) UNION ALL SELECT proxyCopy_con_t type_con, xdf.xdf_key key_con, xdf.xdf_recid recid_con, xdf.xdf_stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, xdf.handle fileName_con, xdf.tag tag_con, to_number(null) copyNumber_con, xdf.status status_con, xdf.blocks blocks_con, xdf.block_size blockSize_con, xdf.device_type deviceType_con, xdf.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, full_act_t type_act, 0 fromSCN_act, xdf.ckp_scn toSCN_act, xdf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, xdf.dbinc_key dbincKey_act, xdf.incr_level level_act, 0 section_size_act, xdf.file# dfNumber_obj, xdf.create_scn dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, xdf.pdb_key pdbKey_obj, xdf.keep_options keep_options, xdf.keep_until keep_until, xdf.abs_fuzzy_scn afzSCN_act, xdf.rcv_fuzzy_time rfzTime_act, xdf.rcv_fuzzy_scn rfzSCN_act, xdf.media media_con, 'NO' isrdf_con, site_key site_key_con, xdf.foreign_dbid foreignDbid_obj, decode(xdf.plugged_readonly, 'YES', 1, 0) pluggedRonly_obj, xdf.plugin_scn pluginSCN_obj, xdf.plugin_reset_scn pluginRlgSCN_obj, xdf.plugin_reset_time pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, decode(xdf.plugged_readonly, 'NO', xdf.ckp_scn, xdf.plugin_scn) newToSCN_act, decode(xdf.plugin_reset_scn, 0, dbinc.reset_scn, xdf.plugin_reset_scn) newRlgSCN_act, nvl(xdf.plugin_reset_time, dbinc.reset_time) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM xdf, dbinc WHERE (sourcemask is NULL OR bitand(sourcemask, proxyCopy_con_t) != 0) AND (findDatafileBackup_c.onlyrdf = 0) AND (dbinc.db_key = this_db_key) -- belongs to this database AND (dbinc.dbinc_key = xdf.dbinc_key) -- join xdf and dbinc AND (findDatafileBackup_c.reset_scn is NULL OR canApplyAnyRedo = TRUE# OR (xdf.plugged_readonly = 'NO' AND findDatafileBackup_c.reset_scn = dbinc.reset_scn AND findDatafileBackup_c.reset_time = dbinc.reset_time) OR (xdf.plugged_readonly = 'YES' AND findDatafileBackup_c.reset_scn = xdf.plugin_reset_scn AND findDatafileBackup_c.reset_time = xdf.plugin_reset_time)) AND xdf.file# = nvl(findDatafileBackup_c.fno, xdf.file#) AND xdf.file# != 0 -- no ctrl bkps AND (onlytc = FALSE# OR tc_database = TRUE# OR isTranslatedFno(xdf.file#) = TRUE#) -- only tnslated files AND ((findDatafileBackup_c.pluginSCN = 0 AND xdf.plugin_scn = 0 AND xdf.create_scn = findDatafileBackup_c.crescn) OR (findDatafileBackup_c.pluginSCN != 0 AND xdf.plugin_scn = findDatafileBackup_c.pluginSCN) OR (findDatafileBackup_c.pluginSCN = 0 AND findDatafileBackup_c.crescn IS NULL)) AND decode(statusMask, BSavailable, decode(xdf.status, 'A', TRUE#, FALSE#), isStatusMatch(xdf.status, statusMask)) = TRUE# AND (findDatafileBackup_c.tag is NULL OR xdf.tag = findDatafileBackup_c.tag) AND (findDatafileBackup_c.pattern is NULL OR xdf.handle LIKE replace(replace(findDatafileBackup_c.pattern, '*','**'), '_', '*_') ESCAPE '*') AND (findDatafileBackup_c.completedAfter is NULL OR xdf.completion_time >= findDatafileBackup_c.completedAfter) AND (findDatafileBackup_c.completedBefore is NULL OR xdf.completion_time <= findDatafileBackup_c.completedBefore) AND (findDatafileBackup_c.untilSCN is NULL OR (xdf.plugged_readonly = 'NO' AND xdf.ckp_scn <= findDatafileBackup_c.untilSCN) OR (xdf.plugged_readonly = 'YES' AND xdf.plugin_scn <= findDatafileBackup_c.untilSCN)) AND (findDatafileBackup_c.level is NULL OR xdf.incr_level <= findDatafileBackup_c.level) AND dbinc.db_key=this_db_key AND ((user_site_key = xdf.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xdf.site_key, this_site_key))))) AND (guidQualifier IS NULL OR xdf.pdb_key = guid2pdbKeyQualifier) UNION ALL SELECT backupSet_con_t type_con, bdf.bdf_key key_con, bdf.bdf_recid recid_con, bdf.bdf_stamp stamp_con, bs.set_stamp setStamp_con, bs.set_count setCount_con, bs.bs_recid bsRecid_con, bs.bs_stamp bsStamp_con, bs.bs_key bsKey_con, bs.incr_level bsLevel_con, bs.bck_type bsType_con, abs((bs.completion_time - bs.start_time) * 86400) elapseSecs_con, bs.pieces pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, bdf.blocks blocks_con, bdf.block_size blockSize_con, to_char(null) deviceType_con, bs.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, multi_section multi_section_con, decode(bdf.incr_scn, 0, full_act_t, incremental_act_t) type_act, bdf.incr_scn fromSCN_act, bdf.ckp_scn toSCN_act, bdf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, bdf.dbinc_key dbincKey_act, bdf.incr_level level_act, bdf.section_size section_size_act, bdf.file# dfNumber_obj, bdf.create_scn dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, bdf.pdb_key pdbKey_obj, bs.keep_options keep_options, bs.keep_until keep_until, bdf.abs_fuzzy_scn afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, bs.site_key site_key_con, bdf.foreign_dbid foreignDbid_obj, decode(bdf.plugged_readonly, 'YES', 1, 0) pluggedRonly_obj, bdf.plugin_scn pluginSCN_obj, bdf.plugin_reset_scn pluginRlgSCN_obj, bdf.plugin_reset_time pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, decode(bdf.plugged_readonly, 'NO', bdf.ckp_scn, bdf.plugin_scn) newToSCN_act, decode(bdf.plugin_scn, 0, dbinc.reset_scn, bdf.plugin_reset_scn) newRlgSCN_act, decode(bdf.plugin_scn, 0, dbinc.reset_time, bdf.plugin_reset_time) newRlgTime_act, to_char(null) sfDbUniqueName_obj, bdf.sparse_backup sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con -- -- -- FROM bs, bdf, dbinc WHERE (sourcemask is NULL OR bitand(sourcemask, backupSet_con_t) != 0) AND (findDatafileBackup_c.onlyrdf = 0) AND (dbinc.db_key = this_db_key) -- belongs to this database AND (bs.db_key = this_db_key) -- belongs to this database AND (bdf.dbinc_key = dbinc.dbinc_key) -- join bdf and dbinc AND (bdf.bs_key = bs.bs_key) -- join bdf and bs AND bs.bck_type != 'L' -- only datafile backups AND (findDatafileBackup_c.reset_scn is NULL OR canApplyAnyRedo = TRUE# OR (bdf.plugged_readonly = 'NO' AND findDatafileBackup_c.reset_scn = dbinc.reset_scn AND findDatafileBackup_c.reset_time = dbinc.reset_time) OR (bdf.plugged_readonly = 'YES' AND findDatafileBackup_c.reset_scn = bdf.plugin_reset_scn AND findDatafileBackup_c.reset_time = bdf.plugin_reset_time)) AND bdf.file# = nvl(findDatafileBackup_c.fno, bdf.file#) AND bdf.file# != 0 -- no ctrl bkps AND (onlytc = FALSE# OR tc_database = TRUE# OR isTranslatedFno(bdf.file#) = TRUE#) -- only tnslated files AND ((findDatafileBackup_c.pluginSCN = 0 AND bdf.plugin_scn = 0 AND bdf.create_scn = findDatafileBackup_c.crescn) OR (findDatafileBackup_c.pluginSCN != 0 AND bdf.plugin_scn = findDatafileBackup_c.pluginSCN) OR (findDatafileBackup_c.pluginSCN = 0 AND findDatafileBackup_c.crescn IS NULL)) AND (findDatafileBackup_c.completedAfter is NULL OR bs.completion_time >= findDatafileBackup_c.completedAfter) AND (findDatafileBackup_c.completedBefore is NULL OR bs.completion_time <= findDatafileBackup_c.completedBefore) AND (findDatafileBackup_c.untilSCN is NULL OR (bdf.plugged_readonly = 'NO' AND bdf.ckp_scn <= findDatafileBackup_c.untilSCN) OR (bdf.plugged_readonly = 'YES' AND bdf.plugin_scn <= findDatafileBackup_c.untilSCN)) -- -- -- -- -- -- -- AND (findDatafileBackup_c.level is NULL OR bdf.incr_level <= findDatafileBackup_c.level OR (findDatafileBackup_c.allowCumuLevelN = TRUE# AND bdf.create_scn = bdf.incr_scn AND bdf.foreign_dbid = 0)) AND (bs.site_key IS NULL OR -- always return null site_key user_site_key = bs.site_key OR -- user interested in one site (user_site_key IS NULL AND -- return rows per access attr (disk_backups_shared = TRUE# OR tape_backups_shared = TRUE# OR this_site_key = bs.site_key))) AND (guidQualifier IS NULL OR bdf.pdb_key = guid2pdbKeyQualifier) ORDER BY dfNumber_obj, -- dfNumber_obj newRlgSCN_act desc, -- rlgSCN_act, last incarnation first newRlgTime_act desc, -- rlgTime_act newToSCN_act desc, -- toSCN_act stamp_con desc; -- stamp_con CURSOR findDatafileCopyKey( copyKey IN number ,statusMask IN binary_integer) RETURN rcvRec_t IS -- SELECT imageCopy_con_t type_con, cdf_key key_con, cdf_recid recid_con, cdf_stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, fname fileName_con, tag tag_con, to_number(null) copyNumber_con, status status_con, blocks blocks_con, block_size blockSize_con, 'DISK' deviceType_con, completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, full_act_t type_act, 0 fromSCN_act, cdf.ckp_scn toSCN_act, cdf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, cdf.dbinc_key dbincKey_act, incr_level level_act, 0 section_size_act, file# dfNumber_obj, create_scn dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, cdf.pdb_key pdbKey_obj, cdf.keep_options keep_options, cdf.keep_until keep_until, cdf.abs_fuzzy_scn afzSCN_act, cdf.rcv_fuzzy_time rfzTime_act, cdf.rcv_fuzzy_scn rfzSCN_act, to_char(null) media_con, is_recovery_dest_file isrdf_con, site_key site_key_con, cdf.foreign_dbid foreignDbid_obj, decode(cdf.plugged_readonly, 'YES', 1, 0) pluggedRonly_obj, cdf.plugin_scn pluginSCN_obj, cdf.plugin_reset_scn pluginRlgSCN_obj, cdf.plugin_reset_time pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, cdf.sparse_backup sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM cdf, dbinc WHERE dbinc.db_key = this_db_key -- belongs to this database AND dbinc.dbinc_key = cdf.dbinc_key -- join cdf and dbinc AND (findDatafileCopyKey.copyKey = cdf_key) AND decode(statusMask, BSavailable, decode(status, 'A', TRUE#, FALSE#), isStatusMatch(status, statusMask)) = TRUE# AND ((user_site_key = cdf.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(cdf.site_key, this_site_key))))) ORDER BY dfNumber_obj, -- for duplicate filtering decode(pluggedRonly_obj, 0, toSCN_act, pluginSCN_obj) desc, -- stamp_con desc; -- to get most recent CURSOR findControlFileCopyKey( copyKey IN number ,statusMask IN binary_integer) RETURN rcvRec_t IS -- SELECT imageCopy_con_t type_con, ccf_key key_con, ccf_recid recid_con, ccf_stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, fname fileName_con, tag tag_con, to_number(null) copyNumber_con, status status_con, to_number(null) blocks_con, block_size blockSize_con, 'DISK' deviceType_con, completion_time compTime_con, create_time cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, full_act_t type_act, 0 fromSCN_act, ccf.ckp_scn toSCN_act, ccf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, ccf.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, 0 dfNumber_obj, 0 dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, nvl(controlfile_type, 'B') cfType_obj, ccf.pdb_key pdbKey_obj, ccf.keep_options keep_options, ccf.keep_until keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, is_recovery_dest_file isrdf_con, site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM ccf, dbinc WHERE dbinc.db_key = this_db_key -- belongs to this database AND dbinc.dbinc_key = ccf.dbinc_key -- join cdf and dbinc AND (findControlFileCopyKey.copyKey = ccf_key) AND decode(statusMask, BSavailable, decode(status, 'A', TRUE#, FALSE#), isStatusMatch(status, statusMask)) = TRUE# AND ((user_site_key = ccf.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(ccf.site_key, this_site_key))))) ORDER BY toSCN_act desc, -- for tag translation stamp_con desc; -- to get most recent CURSOR findBackupsetFiles( bskey IN number) RETURN rcvRec_t IS -- SELECT backupSet_con_t type_con, bdf_key key_con, bdf_recid recid_con, bdf_stamp stamp_con, bs.set_stamp setStamp_con, bs.set_count setCount_con, bs.bs_recid bsRecid_con, bs.bs_stamp bsStamp_con, bs.bs_key bsKey_con, bs.incr_level bsLevel_con, bs.bck_type bsType_con, abs((bs.completion_time - bs.start_time) * 86400) elapseSecs_con, bs.pieces pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, bdf.blocks blocks_con, bdf.block_size blockSize_con, to_char(null) deviceType_con, bs.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, decode(bdf.incr_scn, 0, full_act_t, incremental_act_t) type_act, bdf.incr_scn fromSCN_act, bdf.ckp_scn toSCN_act, bdf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, bdf.dbinc_key dbincKey_act, bdf.incr_level level_act, bdf.section_size section_size_act, file# dfNumber_obj, create_scn dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, bdf.pdb_key pdbKey_obj, bs.keep_options keep_options, bs.keep_until keep_until, bdf.abs_fuzzy_scn afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, bs.site_key site_key_con, bdf.foreign_dbid foreignDbid_obj, decode(bdf.plugged_readonly, 'YES', 1, 0) pluggedRonly_obj, bdf.plugin_scn pluginSCN_obj, bdf.plugin_reset_scn pluginRlgSCN_obj, bdf.plugin_reset_time pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, bdf.sparse_backup sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM bdf, bs, dbinc WHERE (allIncarnations = TRUE# OR canApplyAnyRedo = TRUE# OR dbinc.dbinc_key = this_dbinc_key) AND dbinc.db_key = this_db_key -- belongs to this database AND dbinc.dbinc_key = bdf.dbinc_key -- join bdf and dbinc AND bdf.bs_key = bs.bs_key -- join bdf and bs AND bs.bs_key = bskey AND bs.bck_type != 'L' -- only datafile backups AND (bs.site_key IS NULL OR -- always return null site_key user_site_key = bs.site_key OR -- user interested in one site (user_site_key IS NULL AND -- return rows per access attr (disk_backups_shared = TRUE# OR tape_backups_shared = TRUE# OR this_site_key = bs.site_key))) UNION ALL -- SELECT backupSet_con_t type_con, bcf_key key_con, bcf_recid recid_con, bcf_stamp stamp_con, bs.set_stamp setStamp_con, bs.set_count setCount_con, bs.bs_recid bsRecid_con, bs.bs_stamp bsStamp_con, bs.bs_key bsKey_con, bs.incr_level bsLevel_con, bs.bck_type bsType_con, abs((bs.completion_time - bs.start_time) * 86400) elapseSecs_con, bs.pieces pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, nvl(bcf.blocks,0) blocks_con, bcf.block_size blockSize_con, to_char(null) deviceType_con, bs.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, multi_section multi_section_con, full_act_t type_act, to_number(null) fromSCN_act, bcf.ckp_scn toSCN_act, bcf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, bcf.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, 0 dfNumber_obj, 0 dfCreationSCN_obj, bcf.autobackup_sequence cfSequence_obj, bcf.autobackup_date cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, nvl(controlfile_type, 'B') cfType_obj, bcf.pdb_key pdbKey_obj, bs.keep_options keep_options, bs.keep_until keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, bs.site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM bcf, bs, dbinc WHERE (allIncarnations = TRUE# OR canApplyAnyRedo = TRUE# OR dbinc.dbinc_key = this_dbinc_key) AND dbinc.db_key = this_db_key -- belongs to this database AND dbinc.dbinc_key = bcf.dbinc_key -- join bcf and dbinc AND bcf.bs_key = bs.bs_key -- join bcf and bs AND bs.bs_key = bskey AND bs.bck_type != 'L' -- ignore archivelog backups AND (bs.site_key IS NULL OR -- always return null site_key user_site_key = bs.site_key OR -- user interested in one site (user_site_key IS NULL AND -- return rows per access attr (disk_backups_shared = TRUE# OR tape_backups_shared = TRUE# OR this_site_key = bs.site_key))) UNION ALL -- SELECT backupSet_con_t type_con, bsf_recid key_con, bsf_recid recid_con, bsf_stamp stamp_con, bs.set_stamp setStamp_con, bs.set_count setCount_con, bs.bs_recid bsRecid_con, bs.bs_stamp bsStamp_con, bs.bs_key bsKey_con, bs.incr_level bsLevel_con, bs.bck_type bsType_con, abs((bs.completion_time - bs.start_time) * 86400) elapseSecs_con, bs.pieces pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, 0 blocks_con, 0 blockSize_con, to_char(null) deviceType_con, bs.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, multi_section multi_section_con, full_act_t type_act, 0 fromSCN_act, 0 toSCN_act, modification_time toTime_act, to_number(null) rlgSCN_act, to_date(null) rlgTime_act, to_number(null) dbincKey_act, to_number(null) level_act, 0 section_size_act, to_number(null) dfNumber_obj, to_number(null) dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, bsf.pdb_key pdbKey_obj, bs.keep_options keep_options, bs.keep_until keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, bs.site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM bsf, bs, db WHERE bsf.bs_key = bs.bs_key -- join bsf and bs AND bs.db_key = this_db_key -- belongs to this database AND bsf.db_key = db.db_key -- join bsf and db AND bs.bs_key = bskey AND bs.bck_type != 'L' -- ignore archivelog backups AND (bs.site_key IS NULL OR -- always return null site_key user_site_key = bs.site_key OR -- user interested in one site (user_site_key IS NULL AND -- return rows per access attr (disk_backups_shared = TRUE# OR tape_backups_shared = TRUE# OR this_site_key = bs.site_key))) UNION ALL -- SELECT backupSet_con_t type_con, brl.brl_key key_con, brl.brl_recid recid_con, brl.brl_stamp stamp_con, bs.set_stamp setStamp_con, bs.set_count setCount_con, bs.bs_recid bsRecid_con, bs.bs_stamp bsStamp_con, bs.bs_key bsKey_con, to_number(null) bsLevel_con, bs.bck_type bsType_con, abs((bs.completion_time - bs.start_time) * 86400) elapseSecs_con, bs.pieces pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, brl.blocks blocks_con, brl.block_size blockSize_con, to_char(null) deviceType_con, bs.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, multi_section multi_section_con, full_act_t type_act, to_number(null) fromSCN_act, to_number(null) toSCN_act, to_date(null) toTime_act, to_number(null) rlgSCN_act, to_date(null) rlgTime_act, dbinc.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, to_number(null) dfNumber_obj, to_number(null) dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, brl.sequence# logSequence_obj, brl.thread# logThread_obj, dbinc.reset_scn logRlgSCN_obj, dbinc.reset_time logRlgTime_obj, brl.low_scn logLowSCN_obj, brl.low_time logLowTime_obj, brl.next_scn logNextSCN_obj, brl.next_time logNextTime_obj, brl.terminal logTerminal_obj, to_char(null) cfType_obj, to_number(null) pdbKey_obj, to_number(null) keep_options, to_date(null) keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, bs.site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM brl, bs, dbinc WHERE (allIncarnations = TRUE# OR canApplyAnyRedo = TRUE# OR dbinc.dbinc_key = this_dbinc_key) AND dbinc.db_key = this_db_key -- belongs to this database AND dbinc.dbinc_key = brl.dbinc_key -- join brl and dbinc AND brl.bs_key = bs.bs_key -- join brl and bs AND bs.bs_key = bskey AND bs.bck_type = 'L' -- only archivelog backups AND (bs.site_key IS NULL OR -- always return null site_key user_site_key = bs.site_key OR -- user interested in one site (user_site_key IS NULL AND -- return rows per access attr (disk_backups_shared = TRUE# OR tape_backups_shared = TRUE# OR this_site_key = bs.site_key))) -- ORDER BY dfNumber_obj, logThread_obj, logSequence_obj, logTerminal_obj desc; -- -- -- CURSOR findProxyCopy( tag IN varchar2 DEFAULT NULL ,handle IN varchar2 DEFAULT NULL ,deviceType IN varchar2 DEFAULT NULL ,statusMask IN binary_integer ,pdbKey IN number DEFAULT NULL ,guid IN varchar2 DEFAULT NULL) RETURN rcvRec_t IS SELECT proxyCopy_con_t type_con, xdf_key key_con, xdf_recid recid_con, xdf_stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, handle fileName_con, tag tag_con, to_number(null) copyNumber_con, status status_con, blocks blocks_con, block_size blockSize_con, device_type deviceType_con, completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, full_act_t type_act, 0 fromSCN_act, xdf.ckp_scn toSCN_act, xdf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, xdf.dbinc_key dbincKey_act, incr_level level_act, 0 section_size_act, file# dfNumber_obj, create_scn dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, xdf.pdb_key pdbKey_obj, xdf.keep_options keep_options, xdf.keep_until keep_until, xdf.abs_fuzzy_scn afzSCN_act, xdf.rcv_fuzzy_time rfzTime_act, xdf.rcv_fuzzy_scn rfzSCN_act, xdf.media media_con, 'NO' isrdf_con, site_key site_key_con, xdf.foreign_dbid foreignDbid_obj, decode(xdf.plugged_readonly, 'YES', 1, 0) pluggedRonly_obj, xdf.plugin_scn pluginSCN_obj, xdf.plugin_reset_scn pluginRlgSCN_obj, xdf.plugin_reset_time pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM xdf, dbinc WHERE dbinc.db_key = this_db_key -- belongs to this database AND dbinc.dbinc_key = xdf.dbinc_key -- join xdf and dbinc AND (findProxyCopy.tag IS NULL OR findProxyCopy.tag = tag) AND (findProxyCopy.handle IS NULL OR findProxyCopy.handle = handle) AND (findProxyCopy.deviceType IS NULL OR findProxyCopy.deviceType = device_type) AND decode(statusMask, BSavailable, decode(status, 'A', TRUE#, FALSE#), isStatusMatch(status, statusMask)) = TRUE# AND ((user_site_key = xdf.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xdf.site_key, this_site_key))))) AND (guid IS NULL OR findProxyCopy.pdbKey = xdf.pdb_key) UNION ALL SELECT proxyCopy_con_t type_con, xcf_key key_con, xcf_recid recid_con, xcf_stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, handle fileName_con, tag tag_con, to_number(null) copyNumber_con, status status_con, to_number(null) blocks_con, -- xcf doesn't have blocks block_size blockSize_con, device_type deviceType_con, completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, full_act_t type_act, 0 fromSCN_act, xcf.ckp_scn toSCN_act, xcf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, xcf.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, 0 dfNumber_obj, 0 dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, nvl(controlfile_type, 'B') cfType_obj, xcf.pdb_key pdbKey_obj, xcf.keep_options keep_options, xcf.keep_until keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, media media_con, 'NO' isrdf_con, site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM xcf, dbinc WHERE db_key = this_db_key -- belongs to this database AND dbinc.dbinc_key = xcf.dbinc_key -- join dbinc and xcf AND (findProxyCopy.tag IS NULL OR findProxyCopy.tag = tag) AND (findProxyCopy.handle IS NULL OR findProxyCopy.handle = handle) AND (findProxyCopy.deviceType IS NULL OR findProxyCopy.deviceType = device_type) AND decode(statusMask, BSavailable, decode(status, 'A', TRUE#, FALSE#), isStatusMatch(status, statusMask)) = TRUE# AND ((user_site_key = xcf.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xcf.site_key, this_site_key))))) AND (guid IS NULL OR findProxyCopy.pdbKey = xcf.pdb_key) UNION ALL SELECT proxyCopy_con_t type_con, xal_key key_con, xal_recid recid_con, xal_stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, handle fileName_con, tag tag_con, to_number(null) copyNumber_con, xal.status status_con, xal.blocks blocks_con, xal.block_size blockSize_con, xal.device_type deviceType_con, xal.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, redo_act_t type_act, 0 fromSCN_act, to_number(null) toSCN_act, to_date(null) toTime_act, to_number(null) rlgSCN_act, to_date(null) rlgTime_act, dbinc.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, -1 dfNumber_obj, -- to sort last to_number(null) dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, xal.sequence# logSequence_obj, xal.thread# logThread_obj, dbinc.reset_scn logRlgSCN_obj, dbinc.reset_time logRlgTime_obj, xal.low_scn logLowSCN_obj, xal.low_time logLowTime_obj, xal.next_scn logNextSCN_obj, xal.next_time logNextTime_obj, xal.terminal logTerminal_obj, to_char(null) cfType_obj, to_number(null) pdbKey_obj, to_number(null) keep_options, to_date(null) keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, media media_con, 'NO' isrdf_con, site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM xal, dbinc WHERE db_key = this_db_key -- belongs to this database AND dbinc.dbinc_key = xal.dbinc_key -- join dbinc and xal -- AND (findProxyCopy.tag IS NULL OR findProxyCopy.tag = tag) AND (findProxyCopy.handle IS NULL OR findProxyCopy.handle = handle) AND (findProxyCopy.deviceType IS NULL OR findProxyCopy.deviceType = device_type) AND decode(statusMask, BSavailable, decode(status, 'A', TRUE#, FALSE#), isStatusMatch(status, statusMask)) = TRUE# AND ((user_site_key = xal.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xal.site_key, this_site_key))))) AND (findProxyCopy.guid IS NULL) ORDER BY dfnumber_obj; CURSOR findProxyCopyKey( key IN number DEFAULT NULL ,deviceType IN varchar2 DEFAULT NULL ,statusMask IN binary_integer) RETURN rcvRec_t IS SELECT proxyCopy_con_t type_con, xdf_key key_con, xdf_recid recid_con, xdf_stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, handle fileName_con, tag tag_con, to_number(null) copyNumber_con, status status_con, blocks blocks_con, block_size blockSize_con, device_type deviceType_con, completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, full_act_t type_act, 0 fromSCN_act, xdf.ckp_scn toSCN_act, xdf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, xdf.dbinc_key dbincKey_act, incr_level level_act, 0 section_size_act, file# dfNumber_obj, create_scn dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, xdf.pdb_key pdbKey_obj, xdf.keep_options keep_options, xdf.keep_until keep_until, xdf.abs_fuzzy_scn afzSCN_act, xdf.rcv_fuzzy_time rfzTime_act, xdf.rcv_fuzzy_scn rfzSCN_act, media media_con, 'NO' isrdf_con, site_key site_key_con, xdf.foreign_dbid foreignDbid_obj, decode(xdf.plugged_readonly, 'YES', 1, 0) pluggedRonly_obj, xdf.plugin_scn pluginSCN_obj, xdf.plugin_reset_scn pluginRlgSCN_obj, xdf.plugin_reset_time pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM xdf, dbinc WHERE dbinc.db_key = this_db_key -- belongs to this database AND dbinc.dbinc_key = xdf.dbinc_key -- join xdf and dbinc AND (findProxyCopyKey.key = xdf_key) AND (findProxyCopyKey.deviceType IS NULL OR findProxyCopyKey.deviceType = device_type) AND decode(statusMask, BSavailable, decode(status, 'A', TRUE#, FALSE#), isStatusMatch(status, statusMask)) = TRUE# AND ((user_site_key = xdf.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xdf.site_key, this_site_key))))) UNION ALL SELECT proxyCopy_con_t type_con, xcf_key key_con, xcf_recid recid_con, xcf_stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, handle fileName_con, tag tag_con, to_number(null) copyNumber_con, status status_con, to_number(null) blocks_con, -- xcf doesn't have blocks block_size blockSize_con, device_type deviceType_con, completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, full_act_t type_act, 0 fromSCN_act, xcf.ckp_scn toSCN_act, xcf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, xcf.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, 0 dfNumber_obj, 0 dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, nvl(controlfile_type, 'B') cfType_obj, xcf.pdb_key pdbKey_obj, xcf.keep_options keep_options, xcf.keep_until keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, media media_con, 'NO' isrdf_con, site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM xcf, dbinc WHERE db_key = this_db_key -- belongs to this database AND dbinc.dbinc_key = xcf.dbinc_key -- join dbinc and xcf AND (findProxyCopyKey.key = xcf_key) AND (findProxyCopyKey.deviceType IS NULL OR findProxyCopyKey.deviceType = device_type) AND decode(statusMask, BSavailable, decode(status, 'A', TRUE#, FALSE#), isStatusMatch(status, statusMask)) = TRUE# AND ((user_site_key = xcf.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xcf.site_key, this_site_key))))) UNION ALL SELECT proxyCopy_con_t type_con, xal_key key_con, xal_recid recid_con, xal_stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, handle fileName_con, tag tag_con, to_number(null) copyNumber_con, xal.status status_con, xal.blocks blocks_con, xal.block_size blockSize_con, xal.device_type deviceType_con, xal.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, redo_act_t type_act, 0 fromSCN_act, to_number(null) toSCN_act, to_date(null) toTime_act, to_number(null) rlgSCN_act, to_date(null) rlgTime_act, dbinc.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, to_number(null) dfNumber_obj, to_number(null) dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, xal.sequence# logSequence_obj, xal.thread# logThread_obj, dbinc.reset_scn logRlgSCN_obj, dbinc.reset_time logRlgTime_obj, xal.low_scn logLowSCN_obj, xal.low_time logLowTime_obj, xal.next_scn logNextSCN_obj, xal.next_time logNextTime_obj, xal.terminal logTerminal_obj, to_char(null) cfType_obj, to_number(null) pdbKey_obj, to_number(null) keep_options, to_date(null) keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, media media_con, 'NO' isrdf_con, site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM xal, dbinc WHERE db_key = this_db_key -- belongs to this database AND dbinc.dbinc_key = xal.dbinc_key -- join dbinc and xal AND (findProxyCopyKey.key = xal_key) AND (findProxyCopyKey.deviceType IS NULL OR findProxyCopyKey.deviceType = device_type) AND ((user_site_key = xal.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xal.site_key, this_site_key))))) AND decode(statusMask, BSavailable, decode(status, 'A', TRUE#, FALSE#), isStatusMatch(status, statusMask)) = TRUE#; -- -- -- -- -- -- -- -- -- CURSOR findArchivedLogCopy( currentIncarnation IN number ,thread IN number ,sequence IN number ,lowSCN IN number ,pattern IN varchar2 DEFAULT NULL ,completedAfter IN date DEFAULT NULL ,completedBefore IN date DEFAULT NULL ,statusMask IN binary_integer ,needstby IN number DEFAULT NULL) RETURN rcvRec_t IS -- SELECT imageCopy_con_t type_con, al_key key_con, recid recid_con, stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, name fileName_con, to_date(null) tag_con, to_number(null) copyNumber_con, status status_con, blocks blocks_con, block_size blockSize_con, 'DISK' deviceType_con, completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, full_act_t type_act, to_number(null) fromSCN_act, to_number(null) toSCN_act, to_date(null) toTime_act, to_number(null) rlgSCN_act, to_date(null) rlgTime_act, dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, to_number(null) dfNumber_obj, to_number(null) dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, sequence# logSequence_obj, thread# logThread_obj, resetlogs_change# logRlgSCN_obj, resetlogs_time logRlgTime_obj, first_change# logLowSCN_obj, first_time logLowTime_obj, next_change# logNextSCN_obj, next_time logNextTime_obj, terminal logTerminal_obj, to_char(null) cfType_obj, to_number(null) pdbKey_obj, to_number(null) keep_options, to_date(null) keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, is_recovery_dest_file isrdf_con, site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM rc_archived_log WHERE db_key = this_db_key -- belongs to this database AND(findArchivedLogCopy.currentIncarnation = FALSE# OR canApplyAnyRedo = TRUE# OR this_dbinc_key = dbinc_key) AND (thread IS NULL OR thread# = thread) AND (sequence IS NULL OR sequence# = sequence) AND (lowSCN IS NULL OR first_change# = lowSCN) -- -- -- -- AND (pattern IS NULL OR name LIKE pattern) AND (completedAfter IS NULL OR completion_time >= completedAfter) AND (completedBefore IS NULL OR completion_time <= completedBefore) AND decode(statusMask, BSavailable, decode(status, 'A', TRUE#, FALSE#), isStatusMatch(status, statusMask)) = TRUE# AND ((client_site_aware = TRUE# AND ((user_site_key = site_key) OR -- interested in specific site (user_site_key IS NULL AND ((logs_shared = TRUE#) OR (this_site_key = nvl(site_key, this_site_key)))))) OR (client_site_aware = FALSE# AND (needstby is NULL OR nvl(is_standby, 'NO') = decode(needstby, TRUE#, 'YES', 'NO') OR (terminal = 'YES') OR (first_change# >= lbacked_al_next_scn AND first_change# <= standby_became_primary_scn)))) -- -- AND (archived = 'YES') AND (tc_thread IS NULL OR thread# = tc_thread) AND (tc_fromSeq IS NULL OR sequence# >= tc_fromSeq) AND (tc_toSeq IS NULL OR sequence# <= tc_toSeq) AND (tc_fromSCN IS NULL OR next_change# > tc_fromSCN) AND (tc_toSCN IS NULL OR first_change# < tc_toSCN) AND (tc_pattern IS NULL OR name like tc_pattern) AND (tc_fromTime IS NULL OR next_time > tc_fromTime) AND (tc_toTime IS NULL OR first_time <= tc_toTime) ORDER BY resetlogs_change#, resetlogs_time, thread#, sequence#, terminal desc, stamp_con desc; CURSOR findArcLogBackup( sourcemask IN number ,currentIncarnation IN number DEFAULT TRUE# ,thread IN number ,sequence IN number ,lowSCN IN number ,tag IN varchar2 DEFAULT NULL ,pattern IN varchar2 DEFAULT NULL ,completedAfter IN date DEFAULT NULL ,completedBefore IN date DEFAULT NULL ,statusMask IN binary_integer DEFAULT BSavailable) RETURN rcvRec_t IS SELECT backupSet_con_t type_con, brl.brl_key key_con, brl.brl_recid recid_con, brl.brl_stamp stamp_con, bs.set_stamp setStamp_con, bs.set_count setCount_con, bs.bs_recid bsRecid_con, bs.bs_stamp bsStamp_con, bs.bs_key bsKey_con, to_number(null) bsLevel_con, bs.bck_type bsType_con, abs((bs.completion_time - bs.start_time) * 86400) elapseSecs_con, bs.pieces pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, brl.blocks blocks_con, brl.block_size blockSize_con, to_char(null) deviceType_con, bs.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, multi_section multi_section_con, full_act_t type_act, to_number(null) fromSCN_act, to_number(null) toSCN_act, to_date(null) toTime_act, to_number(null) rlgSCN_act, to_date(null) rlgTime_act, dbinc.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, to_number(null) dfNumber_obj, to_number(null) dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, brl.sequence# logSequence_obj, brl.thread# logThread_obj, dbinc.reset_scn logRlgSCN_obj, dbinc.reset_time logRlgTime_obj, brl.low_scn logLowSCN_obj, brl.low_time logLowTime_obj, brl.next_scn logNextSCN_obj, brl.next_time logNextTime_obj, brl.terminal logTerminal_obj, to_char(null) cfType_obj, to_number(null) pdbKey_obj, to_number(null) keep_options, to_date(null) keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, bs.site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM brl, bs, dbinc WHERE (sourcemask is NULL OR bitand(sourcemask, backupSet_con_t) != 0) AND dbinc.db_key = this_db_key -- belongs to this database AND (currentIncarnation = FALSE# OR canApplyAnyRedo = TRUE# OR this_dbinc_key = dbinc.dbinc_key) AND (thread IS NULL OR brl.thread# = thread) AND (sequence IS NULL OR brl.sequence# = sequence) AND (lowSCN IS NULL OR brl.low_scn = lowSCN) AND dbinc.dbinc_key = brl.dbinc_key -- join dbinc, brl AND bs.bs_key = brl.bs_key -- join bs, brl AND bs.bck_type = 'L' -- only archivelog backups -- -- AND (completedAfter IS NULL OR bs.completion_time >= completedAfter) AND (completedBefore IS NULL OR bs.completion_time <= completedBefore) AND (tc_thread IS NULL OR brl.thread# = tc_thread) AND (tc_fromSeq IS NULL OR brl.sequence# >= tc_fromSeq) AND (tc_toSeq IS NULL OR brl.sequence# <= tc_toSeq) AND (tc_fromSCN IS NULL OR brl.next_scn > tc_fromSCN) AND (tc_toSCN IS NULL OR brl.low_scn < tc_toSCN) AND (tc_fromTime IS NULL OR brl.next_time > tc_fromTime) AND (tc_toTime IS NULL OR brl.low_time <= tc_toTime) AND (bs.site_key IS NULL OR -- always return null site_key user_site_key = bs.site_key OR -- user interested in one site (user_site_key IS NULL AND -- return rows per access attr (disk_backups_shared = TRUE# OR tape_backups_shared = TRUE# OR this_site_key = bs.site_key))) UNION ALL -- SELECT proxyCopy_con_t type_con, xal_key key_con, xal_recid recid_con, xal_stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, handle fileName_con, tag tag_con, to_number(null) copyNumber_con, xal.status status_con, xal.blocks blocks_con, xal.block_size blockSize_con, xal.device_type deviceType_con, xal.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, redo_act_t type_act, 0 fromSCN_act, to_number(null) toSCN_act, to_date(null) toTime_act, to_number(null) rlgSCN_act, to_date(null) rlgTime_act, dbinc.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, to_number(null) dfNumber_obj, to_number(null) dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, xal.sequence# logSequence_obj, xal.thread# logThread_obj, dbinc.reset_scn logRlgSCN_obj, dbinc.reset_time logRlgTime_obj, xal.low_scn logLowSCN_obj, xal.low_time logLowTime_obj, xal.next_scn logNextSCN_obj, xal.next_time logNextTime_obj, xal.terminal logTerminal_obj, to_char(null) cfType_obj, to_number(null) pdbKey_obj, xal.keep_options keep_options, xal.keep_until keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, media media_con, 'NO' isrdf_con, site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM xal, dbinc WHERE (sourcemask is NULL OR bitand(sourcemask, proxyCopy_con_t) != 0) AND dbinc.db_key = this_db_key -- belongs to this database AND (currentIncarnation = FALSE# OR canApplyAnyRedo = TRUE# OR this_dbinc_key = dbinc.dbinc_key) AND (thread IS NULL OR xal.thread# = thread) AND (sequence IS NULL OR xal.sequence# = sequence) AND (lowSCN IS NULL OR xal.low_scn = lowSCN) AND dbinc.dbinc_key = xal.dbinc_key -- join dbinc, xal AND decode(statusMask, BSavailable, decode(xal.status, 'A', TRUE#, FALSE#), isStatusMatch(xal.status, statusMask)) = TRUE# AND (findArcLogBackup.tag is NULL OR tag = findArcLogBackup.tag) AND (findArcLogBackup.pattern IS NULL OR xal.handle LIKE findArcLogBackup.pattern) AND (completedAfter IS NULL OR xal.completion_time >= completedAfter) AND (completedBefore IS NULL OR xal.completion_time <= completedBefore) AND (tc_thread IS NULL OR xal.thread# = tc_thread) AND (tc_fromSeq IS NULL OR xal.sequence# >= tc_fromSeq) AND (tc_toSeq IS NULL OR xal.sequence# <= tc_toSeq) AND (tc_fromSCN IS NULL OR xal.next_scn > tc_fromSCN) AND (tc_toSCN IS NULL OR xal.low_scn < tc_toSCN) AND (tc_fromTime IS NULL OR xal.next_time > tc_fromTime) AND (tc_toTime IS NULL OR xal.low_time <= tc_toTime) AND ((user_site_key = xal.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xal.site_key, this_site_key))))) -- ORDER BY logRlgSCN_obj, logRlgTime_obj, logThread_obj, logSequence_obj, logTerminal_obj desc, stamp_con desc; -- -- -- CURSOR findRangeArcLogBackup( sourcemask IN number ,currentIncarnation IN number DEFAULT TRUE# ,minthread IN number ,minsequence IN number ,minlowSCN IN number ,maxthread IN number ,maxsequence IN number ,maxlowSCN IN number ,tag IN varchar2 DEFAULT NULL ,pattern IN varchar2 DEFAULT NULL ,completedAfter IN date DEFAULT NULL ,completedBefore IN date DEFAULT NULL ,statusMask IN binary_integer DEFAULT BSavailable) RETURN rcvRec_t IS SELECT backupSet_con_t type_con, brl.brl_key key_con, brl.brl_recid recid_con, brl.brl_stamp stamp_con, bs.set_stamp setStamp_con, bs.set_count setCount_con, bs.bs_recid bsRecid_con, bs.bs_stamp bsStamp_con, bs.bs_key bsKey_con, to_number(null) bsLevel_con, bs.bck_type bsType_con, abs((bs.completion_time - bs.start_time) * 86400) elapseSecs_con, bs.pieces pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, brl.blocks blocks_con, brl.block_size blockSize_con, to_char(null) deviceType_con, bs.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, multi_section multi_section_con, full_act_t type_act, to_number(null) fromSCN_act, to_number(null) toSCN_act, to_date(null) toTime_act, to_number(null) rlgSCN_act, to_date(null) rlgTime_act, dbinc.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, to_number(null) dfNumber_obj, to_number(null) dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, brl.sequence# logSequence_obj, brl.thread# logThread_obj, dbinc.reset_scn logRlgSCN_obj, dbinc.reset_time logRlgTime_obj, brl.low_scn logLowSCN_obj, brl.low_time logLowTime_obj, brl.next_scn logNextSCN_obj, brl.next_time logNextTime_obj, brl.terminal logTerminal_obj, to_char(null) cfType_obj, to_number(null) pdbKey_obj, to_number(null) keep_options, to_date(null) keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, bs.site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM brl, bs, dbinc WHERE (sourcemask is NULL OR bitand(sourcemask, backupSet_con_t) != 0) AND dbinc.db_key = this_db_key -- belongs to this database AND (currentIncarnation = FALSE# OR canApplyAnyRedo = TRUE# OR this_dbinc_key = dbinc.dbinc_key) AND brl.thread# between minthread and maxthread AND brl.sequence# between minsequence and maxsequence AND brl.low_scn between minlowSCN and maxlowSCN AND dbinc.dbinc_key = brl.dbinc_key -- join dbinc, brl AND bs.bs_key = brl.bs_key -- join bs, brl AND bs.bck_type = 'L' -- only archivelog backups -- -- AND (completedAfter IS NULL OR bs.completion_time >= completedAfter) AND (completedBefore IS NULL OR bs.completion_time <= completedBefore) AND (bs.site_key IS NULL OR -- always return null site_key user_site_key = bs.site_key OR -- user interested in one site (user_site_key IS NULL AND -- return rows per access attr (disk_backups_shared = TRUE# OR tape_backups_shared = TRUE# OR this_site_key = bs.site_key))) UNION ALL -- SELECT proxyCopy_con_t type_con, xal_key key_con, xal_recid recid_con, xal_stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, handle fileName_con, tag tag_con, to_number(null) copyNumber_con, xal.status status_con, xal.blocks blocks_con, xal.block_size blockSize_con, xal.device_type deviceType_con, xal.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, redo_act_t type_act, 0 fromSCN_act, to_number(null) toSCN_act, to_date(null) toTime_act, to_number(null) rlgSCN_act, to_date(null) rlgTime_act, dbinc.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, to_number(null) dfNumber_obj, to_number(null) dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, xal.sequence# logSequence_obj, xal.thread# logThread_obj, dbinc.reset_scn logRlgSCN_obj, dbinc.reset_time logRlgTime_obj, xal.low_scn logLowSCN_obj, xal.low_time logLowTime_obj, xal.next_scn logNextSCN_obj, xal.next_time logNextTime_obj, xal.terminal logTerminal_obj, to_char(null) cfType_obj, to_number(null) pdbKey_obj, to_number(null) keep_options, to_date(null) keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, media media_con, 'NO' isrdf_con, site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM xal, dbinc WHERE (sourcemask is NULL OR bitand(sourcemask, proxyCopy_con_t) != 0) AND dbinc.db_key = this_db_key -- belongs to this database AND (currentIncarnation = FALSE# OR canApplyAnyRedo = TRUE# OR this_dbinc_key = dbinc.dbinc_key) AND xal.thread# between minthread and maxthread AND xal.sequence# between minsequence and maxsequence AND xal.low_scn between minlowSCN and maxlowSCN AND dbinc.dbinc_key = xal.dbinc_key -- join dbinc, xal AND decode(statusMask, BSavailable, decode(xal.status, 'A', TRUE#, FALSE#), isStatusMatch(xal.status, statusMask)) = TRUE# AND (findRangeArcLogBackup.tag is NULL OR tag = findRangeArcLogBackup.tag) AND (findRangeArcLogBackup.pattern IS NULL OR xal.handle LIKE findRangeArcLogBackup.pattern) AND (completedAfter IS NULL OR xal.completion_time >= completedAfter) AND (completedBefore IS NULL OR xal.completion_time <= completedBefore) AND ((user_site_key = xal.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xal.site_key, this_site_key))))) -- -- ORDER BY logRlgSCN_obj desc, logRlgTime_obj desc, logLowSCN_obj desc, logTerminal_obj desc, -- records marked 'YES' must be first stamp_con desc; CURSOR findAllBackupPiece( backupType IN binary_integer ,tag IN varchar2 ,statusMask IN binary_integer ,completedAfter IN date ,completedBefore IN date ,onlyrdf IN binary_integer) RETURN rcvRec_t IS SELECT backupset_con_t type_con, bp.bp_key key_con, bp.bp_recid recid_con, bp.bp_stamp stamp_con, bs.set_stamp setStamp_con, bs.set_count setCount_con, bs.bs_recid bsRecid_con, bs.bs_stamp bsStamp_con, bs.bs_key bsKey_con, bs.incr_level bsLevel_con, bs.bck_type bsType_con, abs((bs.completion_time - bs.start_time) * 86400) elapseSecs_con, bs.pieces pieceCount_con, bp.handle fileName_con, bp.tag tag_con, bp.copy# copyNumber_con, bp.status status_con, ceil(bp.bytes / bs.block_size) blocks_con, bs.block_size blockSize_con, bp.device_type deviceType_con, bs.completion_time compTime_con, to_date(null) cfCreationTime_con, bp.piece# pieceNumber_con, bp.completion_time bpCompTime_con, bp.compressed bpCompressed_con, multi_section multi_section_con, to_number(null) type_act, to_number(null) fromSCN_act, to_number(null) toSCN_act, to_date(null) toTime_act, to_number(null) rlgSCN_act, to_date(null) rlgTime_act, to_number(null) dbincKey_act, to_number(null) level_act, 0 section_size_act, to_number(null) dfNumber_obj, to_number(null) dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, to_number(null) pdbKey_obj, bs.keep_options keep_options, bs.keep_until keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, bp.media media_con, is_recovery_dest_file isrdf_con, bs.site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM bp, bs WHERE (bp.bs_key = bs.bs_key) -- join bp and bs AND (bs.db_key = this_db_key) -- this database AND (bp.status != 'D') AND (completedAfter IS NULL OR bs.completion_time >= completedAfter) AND (completedBefore IS NULL OR bs.completion_time <= completedBefore) AND (findAllBackupPiece.tag IS NULL or bp.tag = findAllBackupPiece.tag) AND (anyDevice = TRUE# OR isDeviceTypeAllocated(bp.device_type) = TRUE#) AND decode(statusMask, BSavailable, decode(bp.status, 'A', TRUE#, FALSE#), isStatusMatch(bp.status, statusMask)) = TRUE# AND (findAllBackupPiece.backupType IS NULL OR isBackupTypeMatch(bs.bck_type, backupType) = TRUE#) AND (findAllBackupPiece.onlyrdf = 0 OR bp.is_recovery_dest_file = 'YES') AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) -- ORDER BY bs.bs_key, bp.device_type, bp.tag, bp.copy#, bp.piece#; -- -- -- getValidBackupSetLast validBackupSetRec_t; getValidBackupSetCursor varchar2(30); -- to indicate what cursor was used -- -- -- -- -- -- -- -- -- -- CURSOR findValidBackupSet_c( bsKey IN number ,pieceCount IN number ,deviceType IN varchar2 DEFAULT NULL ,tag IN varchar2 DEFAULT NULL ,mask IN binary_integer) RETURN dbms_rcvman.validBackupSetRec_t IS -- -- -- -- -- -- -- -- SELECT device_type, tag, decode(ba_access, 'Replication', 3, 'Tape', 2, nvl2(vb_key, 1, 0)), copy#, 1 FROM rc_backup_piece WHERE bs_key = findValidBackupSet_c.bsKey AND decode(mask, BSavailable, decode(status, 'A', TRUE#, FALSE#), isStatusMatch(status, mask)) = TRUE# AND (findValidBackupSet_c.tag IS NULL OR findValidBackupSet_c.tag = tag) AND (findValidBackupSet_c.deviceType IS NULL OR findValidBackupSet_c.deviceType = device_type) AND ((user_site_key = rc_backup_piece.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND rc_backup_piece.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND rc_backup_piece.device_type <> 'DISK') OR (this_site_key = nvl(rc_backup_piece.site_key, this_site_key))))) AND (localOrsSiteKey IS NULL OR (restoreRangeDevTyp IN ('RA$DISK', 'RA$ANY') AND rc_backup_piece.ba_access IN ('Disk', 'Local')) OR (restoreRangeDevTyp IN ('RA$SBT', 'RA$ANY') AND rc_backup_piece.ba_access IN ('Tape', 'Replication') AND localOrsSiteKey = rc_backup_piece.site_key)) GROUP BY device_type, tag, copy# HAVING ((bitand(mask, dbms_rcvman.BSpartial_avail) = 0 AND count(DISTINCT piece#) = findValidBackupSet_c.pieceCount) OR (bitand(mask, dbms_rcvman.BSpartial_avail) <> 0 AND count(DISTINCT piece#) <= findValidBackupSet_c.pieceCount)) UNION ALL -- -- -- SELECT device_type, tag, decode(ba_access, 'Replication', 3, 'Tape', 2, nvl2(vb_key, 1, 0)), to_number(null), 2 FROM rc_backup_piece WHERE bs_key = findValidBackupSet_c.bsKey AND decode(mask, BSavailable, decode(status, 'A', TRUE#, FALSE#), isStatusMatch(status, mask)) = TRUE# AND (findValidBackupSet_c.tag IS NULL OR findValidBackupSet_c.tag = tag) AND (findValidBackupSet_c.deviceType IS NULL OR findValidBackupSet_c.deviceType = device_type) AND ((user_site_key = rc_backup_piece.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND rc_backup_piece.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND rc_backup_piece.device_type <> 'DISK') OR (this_site_key = nvl(rc_backup_piece.site_key, this_site_key))))) AND (localOrsSiteKey IS NULL OR (restoreRangeDevTyp IN ('RA$DISK', 'RA$ANY') AND rc_backup_piece.ba_access IN ('Disk', 'Local')) OR (restoreRangeDevTyp IN ('RA$SBT', 'RA$ANY') AND rc_backup_piece.ba_access IN ('Tape', 'Replication') AND localOrsSiteKey = rc_backup_piece.site_key)) GROUP BY device_type, tag HAVING ((bitand(mask, dbms_rcvman.BSpartial_avail) = 0 AND count(DISTINCT piece#) = findValidBackupSet_c.pieceCount) OR (bitand(mask, dbms_rcvman.BSpartial_avail) <> 0 AND count(DISTINCT piece#) <= findValidBackupSet_c.pieceCount)) UNION ALL -- -- -- -- -- -- -- SELECT device_type, to_char(null), decode(ba_access, 'Replication', 3, 'Tape', 2, nvl2(vb_key, 1, 0)), to_number(null), 3 FROM rc_backup_piece WHERE bs_key = findValidBackupSet_c.bsKey AND decode(mask, BSavailable, decode(status, 'A', TRUE#, FALSE#), isStatusMatch(status, mask)) = TRUE# AND (findValidBackupSet_c.tag IS NULL OR findValidBackupSet_c.tag = tag) AND (findValidBackupSet_c.deviceType IS NULL OR findValidBackupSet_c.deviceType = device_type) AND ((user_site_key = rc_backup_piece.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND rc_backup_piece.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND rc_backup_piece.device_type <> 'DISK') OR (this_site_key = nvl(rc_backup_piece.site_key, this_site_key))))) AND (localOrsSiteKey IS NULL OR (restoreRangeDevTyp IN ('RA$DISK', 'RA$ANY') AND rc_backup_piece.ba_access IN ('Disk', 'Local')) OR (restoreRangeDevTyp IN ('RA$SBT', 'RA$ANY') AND rc_backup_piece.ba_access IN ('Tape', 'Replication') AND localOrsSiteKey = rc_backup_piece.site_key)) GROUP BY device_type HAVING ((bitand(mask, dbms_rcvman.BSpartial_avail) = 0 AND count(DISTINCT piece#) = findValidBackupSet_c.pieceCount) OR (bitand(mask, dbms_rcvman.BSpartial_avail) <> 0 AND count(DISTINCT piece#) <= findValidBackupSet_c.pieceCount)) ORDER BY 1,2,3,4,5; -- -- -- CURSOR findValidBackupSet1P_c( bsKey IN number ,pieceCount IN number ,deviceType IN varchar2 DEFAULT NULL ,tag IN varchar2 DEFAULT NULL ,mask IN binary_integer) RETURN validBackupSetRec_t IS -- -- -- -- -- -- -- -- -- SELECT device_type, tag, decode(ba_access, 'Replication', 3, 'Tape', 2, nvl2(vb_key, 1, 0)), copy#, 1 FROM rc_backup_piece WHERE bs_key = findValidBackupSet1P_c.bsKey AND decode(mask, BSavailable, decode(status, 'A', TRUE#, FALSE#), isStatusMatch(status, mask)) = TRUE# AND ((user_site_key = rc_backup_piece.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND rc_backup_piece.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND rc_backup_piece.device_type <> 'DISK') OR (this_site_key = nvl(rc_backup_piece.site_key, this_site_key))))) AND (findValidBackupSet1P_c.tag IS NULL OR findValidBackupSet1P_c.tag = tag) AND (findValidBackupSet1P_c.deviceType IS NULL OR findValidBackupSet1P_c.deviceType = device_type) ; -- -- -- -- -- -- -- CURSOR findBackupPiece_c( tag IN varchar2 DEFAULT NULL ,handle IN varchar2 DEFAULT NULL ,deviceType IN varchar2 DEFAULT NULL ,copyNumber IN number DEFAULT NULL ,statusMask IN binary_integer ,pdbKey IN number DEFAULT NULL ,guid IN varchar2 DEFAULT NULL) RETURN bpRec_t IS SELECT bp_recid, bp_stamp, bp_key, bp.bs_key, set_stamp, set_count, bs.bck_type, piece#, copy#, bp.status, bp.completion_time, handle, tag, device_type, media, bytes, compressed, bs.site_key, bp.vb_key, bp.ba_access am_access, bp.ba_access, 0 ppl_pdb_id, 0 ppl_cdb_dbid FROM bp, bs WHERE bp.db_key = this_db_key -- belongs to this db AND bs.db_key = this_db_key -- belongs to this db AND bp.bs_key = bs.bs_key -- join bp and bs AND bp.status != 'D' AND (findBackupPiece_c.tag IS NULL OR tag = findBackupPiece_c.tag) AND (findBackupPiece_c.handle IS NULL OR handle = findBackupPiece_c.handle) AND (findBackupPiece_c.deviceType IS NULL OR device_type = findBackupPiece_c.deviceType) AND (findBackupPiece_c.copyNumber IS NULL OR copy# = findBackupPiece_c.copyNumber) AND decode(statusMask, BSavailable, decode(bp.status, 'A', TRUE#, FALSE#), isStatusMatch(bp.status, statusMask)) = TRUE# AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) AND (guid IS NULL OR pdbKey = bp.pdb_key) -- -- ORDER BY piece#, decode(ba_access, 'R', 3, 'T', 2, nvl2(vb_key, 1, 0)), copy# desc, bp_stamp desc; CURSOR findBackupPieceBpKey( bpKey IN number ,tag IN varchar2 DEFAULT NULL ,handle IN varchar2 DEFAULT NULL ,deviceType IN varchar2 DEFAULT NULL ,copyNumber IN number DEFAULT NULL ,statusMask IN binary_integer) RETURN bpRec_t IS SELECT bp_recid, bp_stamp, bp_key, bp.bs_key, set_stamp, set_count, bs.bck_type, piece#, copy#, bp.status, bp.completion_time, handle, tag, device_type, media, bytes, compressed, bs.site_key, bp.vb_key, bp.ba_access am_access, bp.ba_access, 0 ppl_pdb_id, 0 ppl_cdb_dbid FROM bp, bs WHERE bp.db_key = this_db_key AND bs.db_key = this_db_key AND bp.status != 'D' AND bp.bs_key = bs.bs_key AND (bp_key = findBackupPieceBpKey.bpkey) AND (findBackupPieceBpKey.tag IS NULL OR tag = findBackupPieceBpKey.tag) AND (findBackupPieceBpKey.handle IS NULL OR handle = findBackupPieceBpKey.handle) AND (findBackupPieceBpKey.deviceType IS NULL OR device_type = findBackupPieceBpKey.deviceType) AND (findBackupPieceBpKey.copyNumber IS NULL OR copy# = findBackupPieceBpKey.copyNumber) AND decode(statusMask, BSavailable, decode(bp.status, 'A', TRUE#, FALSE#), isStatusMatch(bp.status, statusMask)) = TRUE# AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) -- -- ORDER BY piece#, decode(ba_access, 'R', 3, 'T', 2, nvl2(vb_key, 1, 0)), copy# desc, bp_stamp desc; CURSOR findBackupPieceBsKey1( bsKey IN number ,tag IN varchar2 DEFAULT NULL ,handle IN varchar2 DEFAULT NULL ,deviceType IN varchar2 DEFAULT NULL ,copyNumber IN number DEFAULT NULL ,statusMask IN binary_integer) RETURN bpRec_t IS SELECT bp_recid, bp_stamp, bp_key, bp.bs_key, set_stamp, set_count, bs.bck_type, piece#, copy#, bp.status, bp.completion_time, handle, tag, device_type, media, bytes, compressed, bs.site_key, bp.vb_key, bp.ba_access am_access, bp.ba_access, 0 ppl_pdb_id, 0 ppl_cdb_dbid FROM bp, bs WHERE bp.db_key = this_db_key AND bs.db_key = this_db_key AND bp.status != 'D' AND bp.bs_key = bs.bs_key AND (bs.bs_key = findBackupPieceBsKey1.bsKey) AND (findBackupPieceBsKey1.tag IS NULL OR tag = findBackupPieceBsKey1.tag) AND (findBackupPieceBsKey1.handle IS NULL OR handle = findBackupPieceBsKey1.handle) AND (findBackupPieceBsKey1.deviceType IS NULL OR device_type = findBackupPieceBsKey1.deviceType) AND (findBackupPieceBsKey1.copyNumber IS NULL OR copy# = findBackupPieceBsKey1.copyNumber) AND decode(statusMask, BSavailable, decode(bp.status, 'A', TRUE#, FALSE#), isStatusMatch(bp.status, statusMask)) = TRUE# AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) -- -- ORDER BY piece#, decode(ba_access, 'R', 3, 'T', 2, nvl2(vb_key, 1, 0)), copy# desc, bp_stamp desc; CURSOR findBackupPieceBsKey2( startBsKey IN number ,tag IN varchar2 ,statusMask IN binary_integer) RETURN bpRec_t IS SELECT bp_recid, bp_stamp, bp_key, bp.bs_key, set_stamp, set_count, bs.bck_type, piece#, copy#, bp.status, bp.completion_time, handle, tag, device_type, media, bytes, compressed, bs.site_key, bp.vb_key, bp.ba_access am_access, bp.ba_access, 0 ppl_pdb_id, 0 ppl_cdb_dbid FROM bp, bs WHERE bp.db_key = this_db_key AND bs.db_key = this_db_key AND bp.status != 'D' AND bp.bs_key = bs.bs_key AND (bs.bs_key >= startBsKey) AND (findBackupPieceBsKey2.tag IS NULL OR bp.tag = findBackupPieceBsKey2.tag) AND decode(statusMask, BSavailable, decode(bp.status, 'A', TRUE#, FALSE#), isStatusMatch(bp.status, statusMask)) = TRUE# AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) -- -- ORDER BY bs.bs_key, device_type, piece#, decode(ba_access, 'R', 3, 'T', 2, nvl2(vb_key, 1, 0)), copy# desc, bp_stamp desc; -- -- -- TYPE noRows_t IS RECORD ( error number, -- error number msg varchar2(100) -- error msg ); -- -- TYPE tablespace_t IS RECORD ( name rc_tablespace.name%TYPE, -- tablespace name pdbId number -- pdb id ); TYPE tablespaceList_t IS TABLE OF tablespace_t INDEX BY BINARY_INTEGER; skipTablespaceList tablespaceList_t; -- TYPE pdbNameList_t is table of number index by rc_pdbs.name%TYPE; pdbNameList pdbNameList_t; -- -- TYPE pdbIdList_t is table of boolean index by binary_integer; pdbIdList pdbIdList_t; -- TYPE pdbFileList_t is table of pdbFileRec_t index by binary_integer; pdbFileList pdbFileList_t; -- -- -- getDatafileCursor varchar2(30); -- pointer to current cursor getDatafileNoRows noRows_t; -- Set by function that opens cursor getDatafileLast dfRec_t; -- The last row returned -- -- -- -- -- -- -- -- CURSOR translateDatabase_c( fromSCN number, toSCN number) RETURN dfRec_t IS SELECT rcd.file#, rcd.creation_change#, creation_time, name, tablespace_name, ts#, null, blocks, block_size, bytes / 1024, null, stop_change#, read_only, rfile#, decode(included_in_database_backup, 'YES', 1, 0), aux_name, rcd.dbinc_key, offr.offline_scn, offr.online_scn, offr.online_time, decode(encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt, -- rcd.foreign_dbid, decode(rcd.plugged_readonly, 'YES', 1, 0), rcd.plugin_change#, rcd.plugin_resetlogs_change#, rcd.plugin_resetlogs_time, to_number(null) newDfCreationSCN, creation_thread, creation_size, con_id pdbId, pdb_key pdbKey, pdb_name pdbName, pdb_closed pdbClosed, rcd.pdb_foreign_dbid pdbForeignDbid, decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb FROM rci_datafile_this_dbinc rcd, offr WHERE db_key = this_db_key AND -- belongs to this database rcd.dbinc_key = this_dbinc_key AND (this_stdby_controlfile_scn is NULL OR decode(rcd.plugin_change#, 0, rcd.creation_change#, rcd.plugin_change#) <= this_stdby_controlfile_scn) AND offr.file#(+) = rcd.file# AND -- outer join with offr offr.create_scn(+) = creation_change# AND offr.dbinc_key(+) = this_dbinc_key AND offr.offr_stamp(+) = 0 AND -- only offline ranges from kccfe decode(rcd.plugin_change#, 0, rcd.creation_change#, rcd.plugin_change#) <= toSCN AND (drop_change# is null OR drop_change# > fromSCN) AND (canHandleTransportableTbs = TRUE# OR rcd.plugged_readonly = 'NO') AND -- -- (nvl(realf_site_key, translation_site_key) = site_key) ORDER BY rcd.file#; CURSOR translateDatabaseOfPdbId_c( fromSCN number, toSCN number, pdbId number) RETURN dfRec_t IS SELECT rcd.file#, rcd.creation_change#, creation_time, name, tablespace_name, ts#, null, blocks, block_size, bytes / 1024, null, stop_change#, read_only, rfile#, decode(included_in_database_backup, 'YES', 1, 0), aux_name, rcd.dbinc_key, offr.offline_scn, offr.online_scn, offr.online_time, decode(encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt, -- rcd.foreign_dbid, decode(rcd.plugged_readonly, 'YES', 1, 0), rcd.plugin_change#, rcd.plugin_resetlogs_change#, rcd.plugin_resetlogs_time, to_number(null) newDfCreationSCN, creation_thread, creation_size, con_id pdbId, pdb_key pdbKey, pdb_name pdbName, pdb_closed pdbClosed, rcd.pdb_foreign_dbid pdbForeignDbid, decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb FROM rci_datafile_this_dbinc rcd, offr WHERE db_key = this_db_key AND -- belongs to this database rcd.dbinc_key = this_dbinc_key AND (this_stdby_controlfile_scn is NULL OR decode(rcd.plugin_change#, 0, rcd.creation_change#, rcd.plugin_change#) <= this_stdby_controlfile_scn) AND offr.file#(+) = rcd.file# AND -- outer join with offr offr.create_scn(+) = creation_change# AND offr.dbinc_key(+) = this_dbinc_key AND offr.offr_stamp(+) = 0 AND -- only offline ranges from kccfe decode(rcd.plugin_change#, 0, rcd.creation_change#, rcd.plugin_change#) <= toSCN AND (drop_change# is null OR drop_change# > fromSCN) AND (canHandleTransportableTbs = TRUE# OR rcd.plugged_readonly = 'NO') AND -- -- (nvl(realf_site_key, translation_site_key) = site_key) AND con_id = translateDatabaseOfPdbId_c.pdbId ORDER BY rcd.file#; CURSOR translateDatabaseOfPdbIdL_c( fromSCN number, toSCN number) RETURN dfRec_t IS SELECT rcd.file#, rcd.creation_change#, creation_time, name, tablespace_name, ts#, null, blocks, block_size, bytes / 1024, null, stop_change#, read_only, rfile#, decode(included_in_database_backup, 'YES', 1, 0), aux_name, rcd.dbinc_key, offr.offline_scn, offr.online_scn, offr.online_time, decode(encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt, -- rcd.foreign_dbid, decode(rcd.plugged_readonly, 'YES', 1, 0), rcd.plugin_change#, rcd.plugin_resetlogs_change#, rcd.plugin_resetlogs_time, to_number(null) newDfCreationSCN, creation_thread, creation_size, con_id pdbId, pdb_key pdbKey, pdb_name pdbName, pdb_closed pdbClosed, rcd.pdb_foreign_dbid pdbForeignDbid, decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb FROM rci_datafile_this_dbinc rcd, offr WHERE db_key = this_db_key AND -- belongs to this database rcd.dbinc_key = this_dbinc_key AND (this_stdby_controlfile_scn is NULL OR decode(rcd.plugin_change#, 0, rcd.creation_change#, rcd.plugin_change#) <= this_stdby_controlfile_scn) AND offr.file#(+) = rcd.file# AND -- outer join with offr offr.create_scn(+) = creation_change# AND offr.dbinc_key(+) = this_dbinc_key AND offr.offr_stamp(+) = 0 AND -- only offline ranges from kccfe decode(rcd.plugin_change#, 0, rcd.creation_change#, rcd.plugin_change#) <= toSCN AND (drop_change# is null OR drop_change# > fromSCN) AND (canHandleTransportableTbs = TRUE# OR rcd.plugged_readonly = 'NO') AND -- -- (nvl(realf_site_key, translation_site_key) = site_key) AND isTranslatedPdbId(con_id) = TRUE# ORDER BY rcd.file#; -- -- CURSOR translateTablespace_c( tsName varchar2 ,pdbId number) RETURN dfRec_t IS SELECT file#, creation_change#, creation_time, name, tablespace_name, ts#, null, blocks, block_size, bytes / 1024, null, stop_change#, read_only, rfile#, decode(included_in_database_backup, 'YES', 1, 0), aux_name, dbinc_key, NULL, NULL, NULL, decode(encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt, -- rcd.foreign_dbid, decode(rcd.plugged_readonly, 'YES', 1, 0), rcd.plugin_change#, rcd.plugin_resetlogs_change#, rcd.plugin_resetlogs_time, to_number(null) newDfCreationSCN, creation_thread, creation_size, con_id pdbId, pdb_key pdbKey, pdb_name pdbName, pdb_closed pdbClosed, rcd.pdb_foreign_dbid pdbForeignDbid, decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb FROM rci_datafile_this_dbinc rcd WHERE db_key = this_db_key AND -- part of this db tablespace_name = translateTablespace_c.tsName AND dbinc_key = this_dbinc_key AND (this_stdby_controlfile_scn is NULL OR decode(rcd.plugin_change#, 0, rcd.creation_change#, rcd.plugin_change#) <= this_stdby_controlfile_scn) AND ((untilSCN is null AND drop_change# is null) OR ((decode(plugin_change#, 0, creation_change#, plugin_change#) <= untilSCN) AND (drop_change# is null or drop_change# > untilSCN))) AND (nvl(realf_site_key, translation_site_key) = site_key) AND (canHandleTransportableTbs = TRUE# OR rcd.plugged_readonly = 'NO') AND con_id = translateTablespace_c.pdbId ORDER BY file#; -- -- CURSOR translateDatafileName( fileName varchar2) RETURN dfRec_t IS SELECT file#, creation_change#, creation_time, name, tablespace_name, ts#, null, blocks, block_size, bytes / 1024, null, stop_change#, read_only, rfile#, decode(included_in_database_backup, 'YES', 1, 0), aux_name, dbinc_key, NULL, NULL, NULL, decode(encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt, -- rcd.foreign_dbid, decode(rcd.plugged_readonly, 'YES', 1, 0), rcd.plugin_change#, rcd.plugin_resetlogs_change#, rcd.plugin_resetlogs_time, to_number(null) newDfCreationSCN, creation_thread, creation_size, con_id pdbId, pdb_key pdbKey, pdb_name pdbName, pdb_closed pdbClosed, rcd.pdb_foreign_dbid pdbForeignDbid, decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb FROM rci_datafile_this_dbinc rcd WHERE db_key = this_db_key AND -- belongs to this database name = translateDatafilename.fileName AND -- filename matches dbinc_key = this_dbinc_key AND drop_change# is null AND -- filename currently part of db (untilSCN is null OR decode(plugin_change#, 0, creation_change#, plugin_change#) < untilSCN) AND -- ((untilSCN is null) OR -- no until clause ((untilTime is not null) AND NOT EXISTS (SELECT 1 FROM rci_datafile_this_dbinc WHERE dbinc_key = this_dbinc_key AND name = translateDatafilename.fileName AND (plugin_change# != 0 OR nvl(creation_time, MINDATEVAL) < untilTime) AND drop_time > untilTime AND (nvl(realf_site_key, translation_site_key) = site_key))) OR ((untilSCN is not null) AND NOT EXISTS (SELECT 1 FROM rci_datafile_this_dbinc WHERE dbinc_key = this_dbinc_key AND name = translateDatafilename.fileName AND decode(plugin_change#, 0, creation_change#, plugin_change#) < untilSCN AND drop_change# > untilSCN AND (nvl(realf_site_key, translation_site_key)=site_key)))) AND (canHandleTransportableTbs = TRUE# OR plugged_readonly = 'NO'); -- -- CURSOR translateDatafileNumber( fno number) RETURN dfRec_t IS SELECT file#, creation_change#, creation_time, name, tablespace_name, ts#, null, blocks, block_size, bytes / 1024, null, stop_change#, read_only, rfile#, decode(included_in_database_backup, 'YES', 1, 0), aux_name, dbinc_key, NULL, NULL, NULL, decode(encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt, -- rcd.foreign_dbid, decode(rcd.plugged_readonly, 'YES', 1, 0), rcd.plugin_change#, rcd.plugin_resetlogs_change#, rcd.plugin_resetlogs_time, to_number(null) newDfCreationSCN, creation_thread, creation_size, con_id pdbId, pdb_key pdbKey, pdb_name pdbName, pdb_closed pdbClosed, rcd.pdb_foreign_dbid pdbForeignDbid, decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb FROM rci_datafile_this_dbinc rcd WHERE db_key = this_db_key AND -- belongs to this database file# = translateDataFileNumber.fno AND -- filenumber matches dbinc_key = this_dbinc_key AND ((untilSCN is null AND drop_change# is null) OR ((nvl(creation_time, MINDATEVAL) < untilTime OR decode(plugin_change#, 0, creation_change#, plugin_change#) < untilSCN) AND (drop_time > untilTime OR drop_change# > untilSCN OR drop_change# is null))) AND (nvl(realf_site_key, translation_site_key) = site_key) AND (canHandleTransportableTbs = TRUE# OR plugged_readonly = 'NO'); -- -- CURSOR translateDatafileCheckpoint( fno number ,ckpSCN number) RETURN dfRec_t IS SELECT file#, creation_change#, creation_time, name, tablespace_name, ts#, null, blocks, block_size, bytes / 1024, null, stop_change#, read_only, rfile#, decode(included_in_database_backup, 'YES', 1, 0), aux_name, dbinc_key, NULL, NULL, NULL, decode(encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt, -- rcd.foreign_dbid, decode(rcd.plugged_readonly, 'YES', 1, 0), rcd.plugin_change#, rcd.plugin_resetlogs_change#, rcd.plugin_resetlogs_time, to_number(null) newDfCreationSCN, creation_thread, creation_size, con_id pdbId, pdb_key pdbKey, pdb_name pdbName, pdb_closed pdbClosed, rcd.pdb_foreign_dbid pdbForeignDbid, decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb FROM rci_datafile_this_dbinc rcd WHERE db_key = this_db_key -- belongs to this database AND file# = translateDatafileCheckpoint.fno -- filenumber matches AND dbinc_key = this_dbinc_key AND translateDatafileCheckpoint.ckpSCN >= decode(plugin_change#, 0, creation_change#, plugin_change#) AND (drop_change# IS NULL OR translateDatafileCheckpoint.ckpSCN < drop_change#) AND (canHandleTransportableTbs = TRUE# OR plugged_readonly = 'NO') AND (nvl(realf_site_key, translation_site_key) = site_key); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- CURSOR translateAllDf_c RETURN dfRec_t IS SELECT DISTINCT file# dfNumber, creation_change# dfCreationSCN, creation_time dfCreationTime, name fileName, tablespace_name tsName, ts# tsNumber, to_char(null) status, blocks blocks, block_size blockSize, bytes / 1024 kbytes, to_number(null) unrecovSCN, stop_change# stopSCN, FALSE# readOnly, rfile# rfNumber, decode(included_in_database_backup, 'YES', 1, 0) inBackup, aux_name auxNAme, dbinc_key dbincKey, NULL dfOfflineSCN, NULL dfOnlineSCN, NULL dfOnlineTime, decode(encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt, -- rcd.foreign_dbid, decode(rcd.plugged_readonly, 'YES', 1, 0), rcd.plugin_change#, rcd.plugin_resetlogs_change#, rcd.plugin_resetlogs_time, decode(rcd.plugin_change#, 0, rcd.creation_change#, rcd.plugin_change#) newDfCreationSCN, creation_thread, creation_size, con_id pdbId, pdb_key pdbKey, pdb_name pdbName, pdb_closed pdbClosed, rcd.pdb_foreign_dbid pdbForeignDbid, decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb FROM rci_datafile rcd WHERE db_key = this_db_key AND (canHandleTransportableTbs = TRUE# OR plugged_readonly = 'NO') AND (nvl(realf_site_key, translation_site_key) = site_key) ORDER BY file#, decode(dbinc_key, this_dbinc_key, 0, 1), newDfCreationSCN desc; CURSOR translateAllDfOfPdbId_c( pdbId number) RETURN dfRec_t IS SELECT DISTINCT file# dfNumber, creation_change# dfCreationSCN, creation_time dfCreationTime, name fileName, tablespace_name tsName, ts# tsNumber, to_char(null) status, blocks blocks, block_size blockSize, bytes / 1024 kbytes, to_number(null) unrecovSCN, stop_change# stopSCN, FALSE# readOnly, rfile# rfNumber, decode(included_in_database_backup, 'YES', 1, 0) inBackup, aux_name auxNAme, dbinc_key dbincKey, NULL dfOfflineSCN, NULL dfOnlineSCN, NULL dfOnlineTime, decode(encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt, -- rcd.foreign_dbid, decode(rcd.plugged_readonly, 'YES', 1, 0), rcd.plugin_change#, rcd.plugin_resetlogs_change#, rcd.plugin_resetlogs_time, decode(rcd.plugin_change#, 0, rcd.creation_change#, rcd.plugin_change#) newDfCreationSCN, creation_thread, creation_size, con_id pdbId, pdb_key pdbKey, pdb_name pdbName, pdb_closed pdbClosed, rcd.pdb_foreign_dbid pdbForeignDbid, decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb FROM rci_datafile rcd WHERE db_key = this_db_key AND (canHandleTransportableTbs = TRUE# OR plugged_readonly = 'NO') AND (nvl(realf_site_key, translation_site_key) = site_key) AND con_id = translateAllDfOfPdbId_c.pdbId ORDER BY file#, decode(dbinc_key, this_dbinc_key, 0, 1), newDfCreationSCN desc; CURSOR translateAllDfOfPdbIdL_c RETURN dfRec_t IS SELECT DISTINCT file# dfNumber, creation_change# dfCreationSCN, creation_time dfCreationTime, name fileName, tablespace_name tsName, ts# tsNumber, to_char(null) status, blocks blocks, block_size blockSize, bytes / 1024 kbytes, to_number(null) unrecovSCN, stop_change# stopSCN, FALSE# readOnly, rfile# rfNumber, decode(included_in_database_backup, 'YES', 1, 0) inBackup, aux_name auxNAme, dbinc_key dbincKey, NULL dfOfflineSCN, NULL dfOnlineSCN, NULL dfOnlineTime, decode(encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt, -- rcd.foreign_dbid, decode(rcd.plugged_readonly, 'YES', 1, 0), rcd.plugin_change#, rcd.plugin_resetlogs_change#, rcd.plugin_resetlogs_time, decode(rcd.plugin_change#, 0, rcd.creation_change#, rcd.plugin_change#) newDfCreationSCN, creation_thread, creation_size, con_id pdbId, pdb_key pdbKey, pdb_name pdbName, pdb_closed pdbClosed, rcd.pdb_foreign_dbid pdbForeignDbid, decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb FROM rci_datafile rcd WHERE db_key = this_db_key AND (canHandleTransportableTbs = TRUE# OR plugged_readonly = 'NO') AND (nvl(realf_site_key, translation_site_key) = site_key) AND isTranslatedPdbId(con_id) = TRUE# ORDER BY file#, decode(dbinc_key, this_dbinc_key, 0, 1), newDfCreationSCN desc; -- -- CURSOR translateCorruptList_c RETURN dfRec_t IS SELECT DISTINCT rcd.file#, rcd.creation_change#, rcd.creation_time, rcd.name, rcd.tablespace_name, rcd.ts#, null, rcd.blocks, rcd.block_size, rcd.bytes / 1024, null, rcd.stop_change#, rcd.read_only, rcd.rfile#, decode(rcd.included_in_database_backup, 'YES', 1, 0), aux_name, rcd.dbinc_key, NULL, NULL, NULL, decode(rcd.encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt, -- rcd.foreign_dbid, decode(rcd.plugged_readonly, 'YES', 1, 0), rcd.plugin_change#, rcd.plugin_resetlogs_change#, rcd.plugin_resetlogs_time, to_number(null) newDfCreationSCN, rcd.creation_thread, rcd.creation_size, rcd.con_id pdbId, rcd.pdb_key pdbKey, rcd.pdb_name pdbName, rcd.pdb_closed pdbClosed, rcd.pdb_foreign_dbid pdbForeignDbid, decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb FROM rci_datafile_this_dbinc rcd, (select distinct file# from rc_database_block_corruption where dbinc_key = this_dbinc_key and corruption_type != 'NOLOGGING') bc WHERE rcd.db_key = this_db_key AND -- belongs to this database rcd.file# = bc.file# AND -- filenumber matches rcd.dbinc_key = this_dbinc_key AND (canHandleTransportableTbs = TRUE# OR rcd.plugged_readonly = 'NO') AND ((untilSCN is null AND rcd.drop_change# is null) OR ((nvl(rcd.creation_time, MINDATEVAL) < untilTime OR decode(rcd.plugin_change#, 0, rcd.creation_change#, rcd.plugin_change#) < untilSCN) AND (rcd.drop_time > untilTime OR rcd.drop_change# > untilSCN OR rcd.drop_change# is null))) AND (nvl(realf_site_key, translation_site_key) = site_key) ORDER BY rcd.file#; -- do not change this as krmkcortr is -- -- -- -- getTempfileCursor varchar2(30); -- pointer to current cursor -- -- -- -- CURSOR translateTempfile_c RETURN tfRec_t IS SELECT file# tfNumber, creation_change# tfCreationSCN, creation_time tfCreationTime, name fileName, tablespace_name tsName, ts# tsNumber, decode(autoextend, 'ON', 16, 0) status, bigfile isSFT, blocks blocks, block_size blockSize, maxsize maxSize, nextsize nextSize, rfile# rfNumber, dbinc_key dbincKey, con_id pdbId, pdb_key pdbKey, pdb_name pdbName FROM rc_tempfile WHERE dbinc_key = this_dbinc_key -- belongs to this incarnation AND drop_change# is NULL -- tempfile exists now AND (untilSCN is NULL OR ((tablespace_creation_change# < untilSCN OR nvl(tablespace_creation_time, MINDATEVAL) < untilTime) AND tablespace_drop_change# IS NULL)) AND (nvl(realf_site_key, translation_site_key) = site_key) AND name is not NULL ORDER BY file#; CURSOR translateTempfileOfPdbId_c( pdbId number) RETURN tfRec_t IS SELECT file# tfNumber, creation_change# tfCreationSCN, creation_time tfCreationTime, name fileName, tablespace_name tsName, ts# tsNumber, decode(autoextend, 'ON', 16, 0) status, bigfile isSFT, blocks blocks, block_size blockSize, maxsize maxSize, nextsize nextSize, rfile# rfNumber, dbinc_key dbincKey, con_id pdbId, pdb_key pdbKey, pdb_name pdbName FROM rc_tempfile WHERE dbinc_key = this_dbinc_key -- belongs to this incarnation AND drop_change# is NULL -- tempfile exists now AND (untilSCN is NULL OR ((tablespace_creation_change# < untilSCN OR nvl(tablespace_creation_time, MINDATEVAL) < untilTime) AND tablespace_drop_change# IS NULL)) AND (nvl(realf_site_key, translation_site_key) = site_key) AND name is not NULL AND con_id = translateTempfileOfPdbId_c.pdbId ORDER BY file#; CURSOR translateTempfileOfPdbIdL_c RETURN tfRec_t IS SELECT file# tfNumber, creation_change# tfCreationSCN, creation_time tfCreationTime, name fileName, tablespace_name tsName, ts# tsNumber, decode(autoextend, 'ON', 16, 0) status, bigfile isSFT, blocks blocks, block_size blockSize, maxsize maxSize, nextsize nextSize, rfile# rfNumber, dbinc_key dbincKey, con_id pdbId, pdb_key pdbKey, pdb_name pdbName FROM rc_tempfile WHERE dbinc_key = this_dbinc_key -- belongs to this incarnation AND drop_change# is NULL -- tempfile exists now AND (untilSCN is NULL OR ((tablespace_creation_change# < untilSCN OR nvl(tablespace_creation_time, MINDATEVAL) < untilTime) AND tablespace_drop_change# IS NULL)) AND (nvl(realf_site_key, translation_site_key) = site_key) AND name is not NULL AND isTranslatedPdbId(con_id) = TRUE# ORDER BY file#; CURSOR translateTempfileName_c(fileName IN varchar2) RETURN tfRec_t IS SELECT file# tfNumber, creation_change# tfCreationSCN, creation_time tfCreationTime, name fileName, tablespace_name tsName, ts# tsNumber, decode(autoextend, 'ON', 16, 0) status, bigfile isSFT, blocks blocks, block_size blockSize, maxsize maxSize, nextsize nextSize, rfile# rfNumber, dbinc_key dbincKey, con_id pdbId, pdb_key pdbKey, pdb_name pdbName FROM rc_tempfile WHERE dbinc_key = this_dbinc_key -- belongs to this incarnation AND drop_change# is NULL -- tempfile exists now AND (untilSCN is NULL OR ((tablespace_creation_change# < untilSCN OR nvl(tablespace_creation_time, MINDATEVAL) < untilTime) AND tablespace_drop_change# IS NULL)) AND name = translateTempfileName_c.fileName -- filename matches AND (nvl(realf_site_key, translation_site_key) = site_key) AND name is not NULL ORDER BY file#; CURSOR translateTempfileNumber_c(fno IN number) RETURN tfRec_t IS SELECT file# tfNumber, creation_change# tfCreationSCN, creation_time tfCreationTime, name fileName, tablespace_name tsName, ts# tsNumber, decode(autoextend, 'ON', 16, 0) status, bigfile isSFT, blocks blocks, block_size blockSize, maxsize maxSize, nextsize nextSize, rfile# rfNumber, dbinc_key dbincKey, con_id pdbId, pdb_key pdbKey, pdb_name pdbName FROM rc_tempfile WHERE dbinc_key = this_dbinc_key -- belongs to this incarnation AND drop_change# is NULL -- tempfile exists now AND (untilSCN is NULL OR ((tablespace_creation_change# < untilSCN OR nvl(tablespace_creation_time, MINDATEVAL) < untilTime) AND tablespace_drop_change# IS NULL)) AND file# = translateTempfileNumber_c.fno -- filenumber matches AND (nvl(realf_site_key, translation_site_key) = site_key) AND name is not NULL ORDER BY file#; -- -- -- CURSOR translateOnlineLogs_c(srls IN number) IS SELECT thread#, group#, name FROM rc_redo_log WHERE dbinc_key = this_dbinc_key AND (nvl(realf_site_key, translation_site_key) = site_key) AND ((type = 'ONLINE' AND srls = 0) OR (type = 'STANDBY' AND srls = 1)) ORDER BY thread#, group#, name; -- -- -- getArchivedLogNoRows noRows_t; getArchivedLogDuplicates number; -- Duplicate filtering flag getArchivedLogLast alRec_t; -- used for duplicate filtering getArchivedLogCursor varchar2(40); getArchivedLogDoingRecovery number; -- for filtering orphan logs getArchivedLogOnlyrdf number := 0; getrcvRecLast rcvRec_t; CURSOR translateArcLogKey( alKey IN number) RETURN alRec_t IS SELECT al_key, recid, stamp, thread#, sequence#, name, first_change#, first_time, next_change#, next_time, resetlogs_change#, resetlogs_time, blocks, block_size, status, completion_time, 0, is_recovery_dest_file, compressed, decode(is_standby, 'YES', 'Y', 'N') stby, terminal, site_key, 0 site_key_order_col, 0 source_dbid FROM rc_archived_log WHERE db_key = this_db_key AND archived = 'YES' AND al_key = translateArcLogKey.alKey; CURSOR translateArcLogName( fname IN varchar2 ,statusMask IN binary_integer ,online IN number -- IGNORED! ,needstby IN number DEFAULT NULL) RETURN alRec_t IS SELECT al_key, recid, stamp, thread#, sequence#, name, first_change#, first_time, next_change#, next_time, resetlogs_change#, resetlogs_time, blocks, block_size, status, completion_time, 0, is_recovery_dest_file, compressed, decode(is_standby, 'YES', 'Y', 'N') stby, terminal, site_key, 0 site_key_order_col, 0 source_dbid FROM rc_archived_log WHERE db_key = this_db_key AND name = translateArcLogName.fname AND decode(statusMask, BSavailable, decode(status, 'A', TRUE#, FALSE#), isStatusMatch(status, statusMask)) = TRUE# AND ((client_site_aware = TRUE# AND ((user_site_key = site_key) OR -- interested in specific site (user_site_key IS NULL AND ((logs_shared = TRUE#) OR (this_site_key = nvl(site_key, this_site_key)))))) OR (client_site_aware = FALSE# AND (needstby is NULL OR nvl(is_standby, 'NO') = decode(needstby, TRUE#, 'YES', 'NO') OR (terminal = 'YES') OR (first_change# >= lbacked_al_next_scn AND first_change# <= standby_became_primary_scn)))) ORDER BY is_recovery_dest_file desc, stamp desc; CURSOR translateArcLogSeqRange( thread# IN number ,incarn IN number ,fromseq# IN number ,toseq# IN number ,pattern IN varchar2 ,statusMask IN binary_integer ,online IN number -- IGNORED! ,needstby IN number DEFAULT NULL) RETURN alRec_t IS SELECT al_key, recid, stamp, thread#, sequence#, name, first_change#, first_time, next_change#, next_time, resetlogs_change#, resetlogs_time, blocks, block_size, status, completion_time, 0, is_recovery_dest_file, compressed, decode(is_standby, 'YES', 'Y', 'N') stby, terminal, site_key, 0 site_key_order_col, 0 source_dbid FROM rc_archived_log WHERE db_key = this_db_key AND dbinc_key = DECODE (translateArcLogSeqRange.incarn, -1, this_dbinc_key, 0, dbinc_key, translateArcLogSeqRange.incarn) AND (translateArcLogSeqRange.thread# IS NULL OR thread# = translateArcLogSeqRange.thread#) AND sequence# between nvl(fromseq#, 0) and nvl(toseq#, MAXSEQVAL) AND (pattern is null OR name like pattern) AND isstatusMatch(status,statusMask) = TRUE# AND archived = 'YES' -- this will also filter out cleared logs AND ((client_site_aware = TRUE# AND ((user_site_key = site_key) OR -- interested in specific site (user_site_key IS NULL AND ((logs_shared = TRUE#) OR (this_site_key = NVL(site_key, this_site_key)))))) OR (client_site_aware = FALSE# AND (needstby IS NULL OR nvl(is_standby, 'NO') = DECODE(needstby, TRUE#, 'YES', 'NO') OR (terminal = 'YES') OR (first_change# >= lbacked_al_next_scn AND first_change# <= standby_became_primary_scn)))) ORDER BY thread#, sequence#, terminal DESC, is_recovery_dest_file DESC, stamp DESC; -- CURSOR translateArcLogSeqRange2( thread# IN number ,incarn IN number ,fromseq# IN number ,toseq# IN number ,statusMask IN binary_integer -- must atleast have BSdeleted ,online IN number ,needstby IN number DEFAULT NULL) RETURN alRec_t IS SELECT al_key, recid, DECODE(next_change#, highscnval, -2, stamp) stamp, thread#, sequence#, name, first_change#, first_time, next_change#, next_time, resetlogs_change#, resetlogs_time, blocks, block_size, status, completion_time, 0, is_recovery_dest_file, compressed, decode(is_standby, 'YES', 'Y', 'N') stby, terminal, site_key, 0 site_key_order_col, 0 source_dbid FROM rc_archived_log WHERE db_key = this_db_key AND dbinc_key = DECODE (translateArcLogSeqRange2.incarn, -1, this_dbinc_key, 0, dbinc_key, translateArcLogSeqRange2.incarn) AND (translateArcLogSeqRange2.thread# IS NULL OR thread# = translateArcLogSeqRange2.thread#) AND sequence# between NVL(fromseq#, 0) and NVL(toseq#, MAXSEQVAL) AND (archived = 'YES' OR -- this will also filter out cleared logs (online = TRUE# and archived = 'NO' and name IS NOT NULL)) AND ((client_site_aware = TRUE# AND ((user_site_key = site_key) OR -- interested in specific site (user_site_key IS NULL AND ((logs_shared = TRUE#) OR (this_site_key = NVL(site_key, this_site_key)))))) OR (client_site_aware = FALSE# AND (needstby IS NULL OR nvl(is_standby, 'NO') = decode(needstby, TRUE#, 'YES', 'NO') OR (terminal = 'YES') OR (first_change# >= lbacked_al_next_scn AND first_change# <= standby_became_primary_scn)))) AND isstatusMatch(status,statusMask) = TRUE# UNION ALL SELECT DISTINCT -- to filter duplicates TO_NUMBER(NULL), TO_NUMBER(NULL), -1, -- to sort last (desc) brl.thread#, brl.sequence#, TO_CHAR(NULL), brl.low_scn, brl.low_time, brl.next_scn, brl.next_time, dbinc.reset_scn, dbinc.reset_time, brl.blocks, brl.block_size, 'D', TO_DATE(NULL), 0, 'NO', 'NO', 'N', brl.terminal, 0, 0 site_key_order_col, 0 source_dbid FROM brl, dbinc WHERE brl.dbinc_key = dbinc.dbinc_key -- join condition AND dbinc.db_key = this_db_key AND brl.dbinc_key = DECODE (translateArcLogSeqRange2.incarn, -1, this_dbinc_key, 0, brl.dbinc_key, translateArcLogSeqRange2.incarn) AND (translateArcLogSeqRange2.thread# IS NULL OR brl.thread# = translateArcLogSeqRange2.thread#) AND brl.sequence# BETWEEN NVL(fromseq#, 0) AND NVL(toseq#, MAXSEQVAL) -- -- UNION -- to filter duplicates between brl and xal SELECT DISTINCT -- to filter duplicates TO_NUMBER(NULL), TO_NUMBER(NULL), -1, -- to sort last (desc) xal.thread#, xal.sequence#, TO_CHAR(NULL), xal.low_scn, xal.low_time, xal.next_scn, xal.next_time, dbinc.reset_scn, dbinc.reset_time, xal.blocks, xal.block_size, 'D', TO_DATE(NULL), 0, 'NO', 'NO', 'N', xal.terminal, xal.site_key, 0 site_key_order_col, 0 source_dbid FROM xal, dbinc WHERE xal.dbinc_key = dbinc.dbinc_key -- join condition AND dbinc.db_key = this_db_key AND xal.dbinc_key = DECODE (translateArcLogSeqRange2.incarn, -1, this_dbinc_key, 0, xal.dbinc_key, translateArcLogSeqRange2.incarn) AND (translateArcLogSeqRange2.thread# IS NULL OR xal.thread# = translateArcLogSeqRange2.thread#) AND xal.sequence# BETWEEN NVL(fromseq#, 0) AND NVL(toseq#, MAXSEQVAL) -- -- AND ((user_site_key = xal.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = NVL(xal.site_key, this_site_key))))) -- -- ORDER BY 4, 5, 21 DESC, 18 DESC, 3 DESC; -- CURSOR translateArcLogTimeRange( thread# IN number ,incarn IN number ,fromTime IN date ,toTime IN date ,pattern IN varchar2 ,statusMask IN binary_integer ,online IN number -- IGNORED! ,needstby IN number DEFAULT NULL) RETURN alRec_t IS SELECT al_key, recid, stamp, thread#, sequence#, name, first_change#, first_time, next_change#, next_time, resetlogs_change#, resetlogs_time, blocks, block_size, status, completion_time, 0, is_recovery_dest_file, compressed, decode(is_standby, 'YES', 'Y', 'N') stby, terminal, site_key, 0 site_key_order_col, 0 source_dbid FROM rc_archived_log WHERE db_key = this_db_key AND (canApplyAnyRedo = TRUE# OR dbinc_key = this_dbinc_key) AND dbinc_key = DECODE (translateArcLogTimeRange.incarn, -1, this_dbinc_key, 0, dbinc_key, translateArcLogTimeRange.incarn) AND (translateArcLogTimeRange.thread# IS NULL OR thread# = translateArcLogTimeRange.thread#) AND next_time > NVL(fromTime, MINDATEVAL) AND first_time <= NVL(toTime, MAXDATEVAL) AND (pattern IS NULL OR name LIKE pattern) AND DECODE(statusMask, BSavailable, DECODE(status, 'A', TRUE#, FALSE#), isStatusMatch(status, statusMask)) = TRUE# AND archived = 'YES' -- this will also filter out cleared logs AND ((client_site_aware = TRUE# AND ((user_site_key = site_key) OR -- interested in specific site (user_site_key IS NULL AND ((logs_shared = TRUE#) OR (this_site_key = NVL(site_key, this_site_key)))))) OR (client_site_aware = FALSE# AND (needstby IS NULL OR nvl(is_standby, 'NO') = DECODE(needstby, TRUE#, 'YES', 'NO') OR (terminal = 'YES') OR (first_change# >= lbacked_al_next_scn AND first_change# <= standby_became_primary_scn)))) -- ORDER BY resetlogs_change#, resetlogs_time, thread#, sequence#, terminal DESC, is_recovery_dest_file DESC, stamp DESC; -- -- CURSOR translateArcLogTimeRange2( thread# IN number ,incarn IN number ,fromTime IN date ,toTime IN date ,statusMask IN binary_integer -- must atleast have BSdeleted ,online IN number ,needstby IN number DEFAULT NULL) RETURN alRec_t IS SELECT al_key, recid, DECODE(next_change#, highscnval, -2, stamp) stamp, thread#, sequence#, name, first_change#, first_time, next_change#, next_time, resetlogs_change#, resetlogs_time, blocks, block_size, status, completion_time, 0, is_recovery_dest_file, compressed, DECODE(is_standby, 'YES', 'Y', 'N') stby, terminal, site_key, 0 site_key_order_col, 0 source_dbid FROM rc_archived_log WHERE db_key = this_db_key AND (canApplyAnyRedo = TRUE# OR dbinc_key = this_dbinc_key) AND dbinc_key = DECODE (translateArcLogTimeRange2.incarn, -1, this_dbinc_key, 0, dbinc_key, translateArcLogTimeRange2.incarn) AND (translateArcLogTimeRange2.thread# IS NULL OR thread# = translateArcLogTimeRange2.thread#) AND next_time > NVL(fromTime, MINDATEVAL) AND first_time <= NVL(toTime, MAXDATEVAL) AND (archived = 'YES' OR -- this will also filter out cleared logs (online = TRUE# AND archived = 'NO' AND name IS NOT NULL AND resetlogs_change# = this_reset_scn AND resetlogs_time = this_reset_time)) AND ((client_site_aware = TRUE# AND ((user_site_key = site_key) OR -- interested in specific site (user_site_key IS NULL AND ((logs_shared = TRUE#) OR (this_site_key = NVL(site_key, this_site_key)))))) OR (client_site_aware = FALSE# AND (needstby IS NULL OR NVL(is_standby, 'NO') = DECODE(needstby, TRUE#, 'YES', 'NO') OR (terminal = 'YES') OR (first_change# >= lbacked_al_next_scn AND first_change# <= standby_became_primary_scn)))) AND isstatusMatch(status,statusMask) = TRUE# UNION ALL SELECT DISTINCT -- to filter duplicates TO_NUMBER(NULL), TO_NUMBER(NULL), -1, -- to sort last thread#, sequence#, TO_CHAR(NULL), low_scn, low_time, next_scn, next_time, reset_scn, reset_time, blocks, block_size, 'D', TO_DATE(NULL), 0, 'NO', 'NO', 'N', terminal, 0, 0 site_key_order_col, 0 source_dbid FROM brl, dbinc WHERE brl.dbinc_key = dbinc.dbinc_key -- join condition AND dbinc.db_key = this_db_key AND (canApplyAnyRedo = TRUE# OR brl.dbinc_key = this_dbinc_key) AND dbinc.dbinc_key = DECODE (translateArcLogTimeRange2.incarn, -1, this_dbinc_key, 0, dbinc.dbinc_key, translateArcLogTimeRange2.incarn) AND next_time > NVL(fromTime, MINDATEVAL) AND low_time <= NVL(toTime, MAXDATEVAL) AND (translateArcLogTimeRange2.thread# IS NULL OR thread# = translateArcLogTimeRange2.thread#) -- -- UNION -- to filter duplicates between brl and xal SELECT DISTINCT -- to filter duplicates TO_NUMBER(NULL), TO_NUMBER(NULL), -1, -- to sort last thread#, sequence#, TO_CHAR(NULL), low_scn, low_time, next_scn, next_time, reset_scn, reset_time, blocks, block_size, 'D', TO_DATE(NULL), 0, 'NO', 'NO', 'N', terminal, site_key, 0 site_key_order_col, 0 source_dbid FROM xal, dbinc WHERE xal.dbinc_key = dbinc.dbinc_key -- join condition AND dbinc.db_key = this_db_key AND (canApplyAnyRedo = TRUE# OR xal.dbinc_key = this_dbinc_key) AND dbinc.dbinc_key = DECODE (translateArcLogTimeRange2.incarn, -1, this_dbinc_key, 0, dbinc.dbinc_key, translateArcLogTimeRange2.incarn) AND next_time > NVL(fromTime, MINDATEVAL) AND low_time <= NVL(toTime, MAXDATEVAL) AND (translateArcLogTimeRange2.thread# IS NULL OR thread# = translateArcLogTimeRange2.thread#) -- -- -- -- -- AND ((user_site_key = xal.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = NVL(xal.site_key, this_site_key))))) ORDER BY 11, 12, 4, 5, 21 DESC, 18 DESC, 3 DESC; -- -- CURSOR translateArcLogSCNRange( thread# IN number ,incarn IN number ,sequence# IN number ,fromSCN IN number ,toSCN IN number ,pattern IN varchar2 ,statusMask IN binary_integer ,online IN number ,needstby IN number DEFAULT NULL ,reset_scn IN number ,reset_time IN date) RETURN alRec_t IS SELECT al_key, recid, DECODE(next_change#, highscnval, -2, stamp) stamp, thread#, sequence#, name, first_change#, first_time, next_change#, next_time, resetlogs_change#, resetlogs_time, blocks, block_size, status, completion_time, 0, is_recovery_dest_file, compressed, DECODE(is_standby, 'YES', 'Y', 'N') stby, terminal, site_key, 0 site_key_order_col, 0 source_dbid FROM rc_archived_log WHERE db_key = this_db_key AND ((canApplyAnyRedo = TRUE# AND (translateArcLogSCNRange.reset_scn IS NULL OR (translateArcLogSCNRange.reset_scn = resetlogs_change# AND translateArcLogSCNRange.reset_time = resetlogs_time))) OR (dbinc_key = this_dbinc_key)) AND dbinc_key = DECODE (translateArcLogSCNRange.incarn, -1, this_dbinc_key, 0, dbinc_key, translateArcLogSCNRange.incarn) AND (translateArcLogSCNRange.thread# IS NULL OR thread# = translateArcLogSCNRange.thread#) AND (translateArcLogSCNRange.sequence# IS NULL OR sequence# = translateArcLogSCNRange.sequence#) AND next_change# > NVL(fromSCN, 0) AND first_change# < NVL(toSCN, MAXSCNVAL) AND (pattern IS NULL OR name LIKE pattern) AND decode(statusMask, BSavailable, DECODE(status, 'A', TRUE#, FALSE#), isStatusMatch(status, statusMask)) = TRUE# AND (archived = 'YES' OR -- this will also filter out cleared logs (online = TRUE# and archived = 'NO' and name IS NOT NULL and resetlogs_change# = this_reset_scn and resetlogs_time = this_reset_time)) AND ((client_site_aware = TRUE# AND ((user_site_key = site_key) OR -- interested in specific site (user_site_key IS NULL AND ((logs_shared = TRUE#) OR (this_site_key = NVL(site_key, this_site_key)))))) OR (client_site_aware = FALSE# AND (needstby IS NULL OR NVL(is_standby, 'NO') = DECODE(needstby, TRUE#, 'YES', 'NO') OR (terminal = 'YES') OR (first_change# >= lbacked_al_next_scn AND first_change# <= standby_became_primary_scn)))) -- ORDER BY resetlogs_change#, resetlogs_time, thread#, sequence#, terminal DESC, is_recovery_dest_file DESC, stamp DESC; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- CURSOR translateArcLogSCNRange2( thread# IN number ,incarn IN number ,sequence# IN number ,fromSCN IN number ,toSCN IN number ,toTime IN date ,statusMask IN binary_integer -- must atleast have BSdeleted ,online IN number ,needstby IN number DEFAULT NULL -- IGNORED ,reset_scn IN number ,reset_time IN date) RETURN alRec_t IS SELECT al_key, recid, DECODE(next_change#, highscnval, -2, stamp) stamp, thread#, sequence#, name, first_change#, first_time, next_change#, next_time, resetlogs_change#, resetlogs_time, blocks, block_size, status, completion_time, 0, is_recovery_dest_file, compressed, DECODE(is_standby, 'YES', 'Y', 'N') stby, terminal, site_key, DECODE(next_change#, highscnval, -1, DECODE(site_key, this_site_key, 1, 0)) site_key_order_col, 0 source_dbid FROM rc_archived_log WHERE db_key = this_db_key AND ((canApplyAnyRedo = TRUE# AND (translateArcLogSCNRange2.reset_scn IS NULL OR (translateArcLogSCNRange2.reset_scn = resetlogs_change# AND translateArcLogSCNRange2.reset_time = resetlogs_time))) OR (dbinc_key = this_dbinc_key)) AND dbinc_key = DECODE (translateArcLogSCNRange2.incarn, -1, this_dbinc_key, 0, dbinc_key, translateArcLogSCNRange2.incarn) AND (translateArcLogSCNRange2.thread# IS NULL OR thread# = translateArcLogSCNRange2.thread#) AND (translateArcLogSCNRange2.sequence# IS NULL OR sequence# = translateArcLogSCNRange2.sequence#) AND next_change# > NVL(fromSCN, 0) AND first_change# < NVL(toSCN, MAXSCNVAL) AND (toTime IS NULL OR first_time < toTime) AND (archived = 'YES' OR -- this will also filter out cleared logs (online = TRUE# and archived = 'NO' and name IS NOT NULL and resetlogs_change# = this_reset_scn and resetlogs_time = this_reset_time)) AND isstatusMatch(status,statusMask) = TRUE# UNION ALL SELECT DISTINCT -- to filter duplicates TO_NUMBER(NULL), TO_NUMBER(NULL), -1, -- to sort last brl.thread#, brl.sequence#, TO_CHAR(NULL), brl.low_scn, brl.low_time, brl.next_scn, brl.next_time, dbinc.reset_scn, dbinc.reset_time, brl.blocks, brl.block_size, 'D', TO_DATE(NULL), 0, 'NO', 'NO', 'N', brl.terminal, 0, 0 site_key_order_col, 0 source_dbid FROM brl, dbinc WHERE brl.dbinc_key = dbinc.dbinc_key -- join condition AND dbinc.db_key = this_db_key AND ((canApplyAnyRedo = TRUE# AND (translateArcLogSCNRange2.reset_scn IS NULL OR (translateArcLogSCNRange2.reset_scn = dbinc.reset_scn AND translateArcLogSCNRange2.reset_time = dbinc.reset_time))) OR (dbinc.dbinc_key = this_dbinc_key)) AND brl.dbinc_key = DECODE (translateArcLogSCNRange2.incarn, -1, this_dbinc_key, 0, brl.dbinc_key, translateArcLogSCNRange2.incarn) AND (translateArcLogSCNRange2.thread# IS NULL OR thread# = translateArcLogSCNRange2.thread#) AND (translateArcLogSCNRange2.sequence# IS NULL OR sequence# = translateArcLogSCNRange2.sequence#) AND next_scn > NVL(fromSCN, 0) AND low_scn < NVL(toSCN, MAXSCNVAL) AND (toTime IS NULL OR low_time < toTime) -- -- UNION -- to filter duplicates between brl and xal SELECT DISTINCT -- to filter duplicates TO_NUMBER(NULL), TO_NUMBER(NULL), -1, -- to sort last xal.thread#, xal.sequence#, TO_CHAR(NULL), xal.low_scn, xal.low_time, xal.next_scn, xal.next_time, dbinc.reset_scn, dbinc.reset_time, xal.blocks, xal.block_size, 'D', TO_DATE(NULL), 0, 'NO', 'NO', 'N', xal.terminal, xal.site_key, 0 site_key_order_col, 0 source_dbid FROM xal, dbinc WHERE xal.dbinc_key = dbinc.dbinc_key -- join condition AND dbinc.db_key = this_db_key AND ((canApplyAnyRedo = TRUE# AND (translateArcLogSCNRange2.reset_scn IS NULL OR (translateArcLogSCNRange2.reset_scn = dbinc.reset_scn AND translateArcLogSCNRange2.reset_time = dbinc.reset_time))) OR (dbinc.dbinc_key = this_dbinc_key)) AND xal.dbinc_key = DECODE (translateArcLogSCNRange2.incarn, -1, this_dbinc_key, 0, xal.dbinc_key, translateArcLogSCNRange2.incarn) AND (translateArcLogSCNRange2.thread# IS NULL OR thread# = translateArcLogSCNRange2.thread#) AND (translateArcLogSCNRange2.sequence# IS NULL OR sequence# = translateArcLogSCNRange2.sequence#) AND next_scn > NVL(fromSCN, 0) AND low_scn < NVL(toSCN, MAXSCNVAL) AND (toTime IS NULL OR low_time < toTime) -- -- AND ((user_site_key = xal.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = NVL(xal.site_key, this_site_key))))) -- -- -- ORDER BY 11, 12, 4, 5, 21 DESC, 23 DESC, 18 DESC, 3 DESC; CURSOR translateArcLogPattern( pattern IN varchar2 ,statusMask IN binary_integer ,online IN number -- IGNORED! ,needstby IN number DEFAULT NULL) RETURN alRec_t IS SELECT al_key, recid, stamp, thread#, sequence#, name, first_change#, first_time, next_change#, next_time, resetlogs_change#, resetlogs_time, blocks, block_size, status, completion_time, 0, is_recovery_dest_file, compressed, decode(is_standby, 'YES', 'Y', 'N') stby, terminal, site_key, 0 site_key_order_col, 0 source_dbid FROM rc_archived_log WHERE (canApplyAnyRedo = TRUE# OR dbinc_key = this_dbinc_key) AND db_key = this_db_key AND (pattern is null or name like pattern) AND decode(statusMask, BSavailable, decode(status, 'A', TRUE#, FALSE#), isStatusMatch(status, statusMask)) = TRUE# AND archived = 'YES' AND ((client_site_aware = TRUE# AND ((user_site_key = site_key) OR -- interested in specific site (user_site_key IS NULL AND ((logs_shared = TRUE#) OR (this_site_key = nvl(site_key, this_site_key)))))) OR (client_site_aware = FALSE# AND (needstby is NULL OR nvl(is_standby, 'NO') = decode(needstby, TRUE#, 'YES', 'NO') OR (terminal = 'YES') OR (first_change# >= lbacked_al_next_scn AND first_change# <= standby_became_primary_scn)))) -- ORDER BY resetlogs_change#, resetlogs_time, thread#, sequence#, terminal desc, is_recovery_dest_file desc, stamp desc; -- -- -- getControlFileCopySingleRow boolean; getControlFileCopyCursor varchar2(30); -- -- -- getDatafileCopyCursor varchar2(30); getDatafileCopyNoRows noRows_t; getDatafileCopyDuplicates number; -- match file number getDatafileCopyLast rcvRec_t; getDatafileCopySingleRow boolean; getDatafileCopyLatestOnly boolean; -- -- -- getProxyCopyCursor varchar2(30); getProxyCopyNoRows noRows_t; getProxyCopyByHandle boolean; -- -- -- getBackupPieceCursor varchar2(30); getBackupPieceNoRows noRows_t; getBackupPieceDuplicates number; -- TRUE# -> duplicates OK -- getBackupPieceLast bpRec_t; -- -- getBackupPieceDeviceType bp.device_type%TYPE; getBackupPieceExpectedPieces number; getBackupPiecePieceCount number; getBackupPieceByHandle boolean; getBackupPieceAvailableMask binary_integer; getBackupPieceSeekLast bpRec_t; getBackupPieceCopyNumber number; getBackupPieceBskey number; -- -- -- findSpfileBackupCursor boolean; -- TRUE# -> cursor opened findControlfileBackupCursor boolean; -- TRUE# -> cursor opened -- -- -- listGetBackupTag bp.tag%TYPE; listGetBackupAvailableMask binary_integer; listGetProxyDatafileCursor varchar2(30); -- -- CURSOR lbal2(thread# number, lowseq number, highseq number, lowscn number, highscn number, from_time date , until_time date) RETURN rcvRec_t IS SELECT backupSet_con_t type_con, brl.brl_key key_con, brl.brl_recid recid_con, brl.brl_stamp stamp_con, bs.set_stamp setStamp_con, bs.set_count setCount_con, bs.bs_recid bsRecid_con, bs.bs_stamp bsStamp_con, bs.bs_key bsKey_con, to_number(null) bsLevel_con, bs.bck_type bsType_con, abs((bs.completion_time - bs.start_time) * 86400) elapseSecs_con, bs.pieces pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, brl.blocks blocks_con, brl.block_size blockSize_con, to_char(null) deviceType_con, bs.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, multi_section multi_section_con, full_act_t type_act, to_number(null) fromSCN_act, to_number(null) toSCN_act, to_date(null) toTime_act, to_number(null) rlgSCN_act, to_date(null) rlgTime_act, dbinc.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, to_number(null) dfNumber_obj, to_number(null) dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, brl.sequence# logSequence_obj, brl.thread# logThread_obj, dbinc.reset_scn logRlgSCN_obj, dbinc.reset_time logRlgTime_obj, brl.low_scn logLowSCN_obj, brl.low_time logLowTime_obj, brl.next_scn logNextSCN_obj, brl.next_time logNextTime_obj, brl.terminal logTerminal_obj, to_char(null) cfType_obj, to_number(null) pdbKey_obj, to_number(null) keep_options, to_date(null) keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, bs.site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con from brl, bs, dbinc where dbinc.db_key = this_db_key -- this database and dbinc.dbinc_key = brl.dbinc_key -- join dbinc, brl and bs.bs_key = brl.bs_key -- join bs, brl and (lbal2.thread# is null or brl.thread# = lbal2.thread#) and (brl.sequence# between nvl(lbal2.lowseq, 0) and nvl(lbal2.highseq, MAXSEQVAL)) and (lowscn is null or brl.low_scn >= lowscn) and (highscn is null or brl.next_scn< highscn) and (from_time is null or bs.completion_time >= from_time) and (until_time is null or bs.completion_time <= until_time) -- and bs.status != 'D' and bs.bck_type = 'L' -- only archivelog backups order by bs.bs_key, brl.thread#, brl.sequence#, brl.terminal desc; CURSOR ldbi( db_name varchar2, all_databases number) IS SELECT db_key, dbinc_key, name, dbid, current_incarnation, resetlogs_change#, resetlogs_time, status dbinc_status FROM rc_database_incarnation WHERE (all_databases = 1) OR -- user wants all database incarnations ((all_databases = 0) AND ((name = ldbi.db_name) OR -- user asked for specific database (db_name is NULL AND this_db_key=db_key))) -- user wants mounted db ORDER BY db_key, resetlogs_change#, dbinc_key; CURSOR lnni( db_name varchar2, alldbs number) IS SELECT node.db_key, dbid, name, database_role, db_unique_name FROM rc_database, node WHERE rc_database.db_key = node.db_key AND ((alldbs = 1) OR (lnni.db_name IS NOT NULL AND upper(lnni.db_name) = name) OR (lnni.db_name IS NULL AND this_db_key = node.db_key)) AND substr(nvl(db_unique_name, 'A'),1,1) <> '$' ORDER BY dbid, database_role; -- CURSOR lrtbs IS SELECT DISTINCT ts.ts#, ts.ts_name, pdbinc.name FROM ts, tsatt, ckp, rci_pdbinc_this_dbinc pdbinc -- WHERE pdbinc.dbinc_key = this_dbinc_key AND ts.pdbinc_key = pdbinc.pdbinc_key AND (untilSCN is NULL or pdbinc.create_scn < untilSCN) AND (pdbinc.drop_scn is NULL or pdbinc.drop_scn > untilSCN) AND ts.dbinc_key = tsatt.dbinc_key AND ts.ts# = tsatt.ts# AND ts.pdbinc_key = tsatt.pdbinc_key AND ts.create_scn = tsatt.create_scn -- -- -- AND ckp.ckp_key(+) = tsatt.end_ckp_key -- AND ts.dbinc_key = this_dbinc_key -- -- -- AND (ts.create_scn < untilSCN or untilSCN is NULL) -- -- -- -- -- AND (ts.drop_scn > untilSCN or ts.drop_scn is NULL) -- -- -- -- AND (ckp.ckp_scn > untilSCN or ckp.ckp_scn is NULL) -- -- AND tsatt.rbs_count > 0 ORDER BY 1, -- ts# 3; -- pdbname -- -- -- rcvRec_last rcvRec_t; -- last record returned from: -- -- -- -- -- CURSOR getOfflineRangeCopy_c( offrRecid number ,offrCkpSCN number ,cfCreTime date ,dbincKey number) RETURN rcvRec_t IS SELECT imageCopy_con_t type_con, ccf_key key_con, ccf_recid recid_con, ccf_stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, fname fileName_con, tag tag_con, to_number(null) copyNumber_con, status status_con, to_number(null) blocks_con, -- ccf doesn't have blocks block_size blockSize_con, 'DISK' deviceType_con, completion_time compTime_con, create_time cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, full_act_t type_act, 0 fromSCN_act, ccf.ckp_scn toSCN_act, ccf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, ccf.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, 0 dfNumber_obj, 0 dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, ccf.pdb_key pdbKey_obj, ccf.keep_options keep_options, ccf.keep_until keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, is_recovery_dest_file isrdf_con, site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, to_number(null) newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM ccf, dbinc WHERE dbinc.dbinc_key = getOfflineRangeCopy_c.dbincKey AND dbinc.dbinc_key = ccf.dbinc_key AND getOfflineRangeCopy_c.cfCretime = create_time AND getOfflineRangeCopy_c.offrCkpSCN < ccf.ckp_scn AND getOfflineRangeCopy_c.offrRecid >= min_offr_recid AND status = 'A' AND ((user_site_key = ccf.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(ccf.site_key, this_site_key))))) ORDER BY stamp_con desc; -- -- cursor rddf is -- select 2 preference, file#, COPY filetype, checkpoint_change#, checkpoint_time, resetlogs_change#, resetlogs_time, 0 incremental_change#, decode(decode(online_fuzzy,'NO',0,1)+decode(backup_fuzzy,'NO',0,1), 0,greatest(nvl(absolute_fuzzy_change#,0), nvl(recovery_fuzzy_change#,0)), maxscnval) fuzzy_change#, recid, stamp, name, 0 set_stamp, 0 set_count, cdf_key key, completion_time, 'DISK' device_type from rc_datafile_copy where db_key = this_db_key and status != 'D' and ((user_site_key = rc_datafile_copy.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(rc_datafile_copy.site_key, this_site_key))))) union all -- select 3, file#, PROXY, checkpoint_change#, checkpoint_time, resetlogs_change#, resetlogs_time, 0, decode(decode(online_fuzzy,'NO',0,1)+decode(backup_fuzzy,'NO',0,1), 0,greatest(nvl(absolute_fuzzy_change#,0), nvl(recovery_fuzzy_change#,0)), maxscnval), recid, stamp, handle, 0, 0, xdf_key, completion_time, device_type from rc_proxy_datafile where db_key = this_db_key and status != 'D' and ((user_site_key = rc_proxy_datafile.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(rc_proxy_datafile.site_key, this_site_key))))) union all -- select decode(bs.bck_type, 'D', 4, 'I', 5), file#, decode(bs.bck_type, 'D', FULL_DF_BACKUP, 'I', INCREMENTAL_DF_BACKUP), bdf.ckp_scn, bdf.ckp_time, dbinc.reset_scn, dbinc.reset_time, bdf.incr_scn, nvl(bdf.abs_fuzzy_scn,0), bs.bs_recid, bs.bs_stamp, null, bs.set_stamp, bs.set_count, bs.bs_key, bs.completion_time, null from bdf, bs, dbinc where dbinc.db_key = this_db_key -- this database and dbinc.dbinc_key = bdf.dbinc_key -- join dbinc, bdf and bdf.bs_key = bs.bs_key -- join bdf, bs and bs.status != 'D' and bs.bck_type != 'L' -- only datafile backups and (bs.site_key IS NULL OR -- always return null site_key user_site_key = bs.site_key OR -- user interested in one site (user_site_key IS NULL AND -- return rows per access attr (disk_backups_shared = TRUE# OR tape_backups_shared = TRUE# OR this_site_key = bs.site_key))) union all -- select 2, 0, COPY, checkpoint_change#, checkpoint_time, resetlogs_change#, resetlogs_time, 0, 0, recid, stamp, name, 0, 0, ccf_key, completion_time, 'DISK' from rc_controlfile_copy where db_key = this_db_key and status != 'D' and ((user_site_key = rc_controlfile_copy.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(rc_controlfile_copy.site_key,this_site_key))))) union all -- select 3, 0, PROXY, checkpoint_change#, checkpoint_time, resetlogs_change#, resetlogs_time, 0, 0, recid, stamp, handle, 0, 0, xcf_key, completion_time, device_type from rc_proxy_controlfile where db_key = this_db_key and status != 'D' and ((user_site_key = rc_proxy_controlfile.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key =nvl(rc_proxy_controlfile.site_key,this_site_key))))) union all -- select 4, 0, FULL_DF_BACKUP, bcf.ckp_scn, bcf.ckp_time, dbinc.reset_scn, dbinc.reset_time, 0, 0, bs.bs_recid, bs.bs_stamp, null, bs.set_stamp, bs.set_count, bs.bs_key, bs.completion_time, null from bcf, bs, dbinc where dbinc.db_key = this_db_key -- this database and dbinc.dbinc_key = bcf.dbinc_key -- join dbinc, bcf and bcf.bs_key = bs.bs_key -- join bcf, bs and bs.status != 'D' and bs.bck_type != 'L' -- ignore archivelog backups and (bs.site_key IS NULL OR -- always return null site_key user_site_key = bs.site_key OR -- user interested in one site (user_site_key IS NULL AND -- return rows per access attr (disk_backups_shared = TRUE# OR tape_backups_shared = TRUE# OR this_site_key = bs.site_key))) union all -- select 1, file#, OFFLINE_RANGE, online_change#, online_time, resetlogs_change#, resetlogs_time, offline_change#, 0, recid, stamp, null, 0, 0, 0, online_time, null from rc_offline_range ofr where ofr.db_key = this_db_key -- -- order by 2 asc, -- file# 4 desc, -- checkpoint_change# 1 asc, -- preference 15 desc; -- completion_time, to break ties if all else is equal -- -- -- -- CURSOR translateDatabaseCorruption_c(dfnumber IN number) IS SELECT file#, block#, blocks FROM rc_database_block_corruption bc WHERE bc.db_key = this_db_key AND -- belongs to this database bc.dbinc_key = this_dbinc_key AND bc.file# = nvl(translateDatabaseCorruption_c.dfnumber, bc.file#) AND bc.corruption_type != 'NOLOGGING' ORDER BY file#, block#; -- order same as in translateCorruptList_c. -- -- -- -- -- -- CURSOR cntConfig_c IS SELECT COUNT(*) FROM CONF WHERE db_key = this_db_key AND db_unique_name = nvl(user_db_unique_name, this_db_unique_name); CURSOR getPrimarySite_c IS SELECT db_unique_name FROM NODE WHERE db_key = this_db_key AND database_role = 'PRIMARY'; CURSOR findConfig_c( name varchar2, value varchar2, db_unique_name varchar2) IS SELECT conf#, name, value FROM rc_rman_configuration rm WHERE db_key = this_db_key -- part of this database AND (findConfig_c.name is null OR UPPER(findConfig_c.name) = UPPER(rm.name)) AND (findConfig_c.value is null OR UPPER(findConfig_c.value) = UPPER(rm.value)) AND -- ((nvl(findConfig_c.db_unique_name, rm.db_unique_name) = rm.db_unique_name) OR rm.db_unique_name IS NULL) -- generic conf rows ORDER BY conf#; -- -- -- -- -- getLastBackupHistory bhistoryRec_t; -- CURSOR dfBackupHistory_c1( file# IN number ,crescn IN number ,device_type IN varchar2) RETURN bhistoryRec_t IS SELECT bdf.file# dfNumber, bdf.create_scn create_scn, dbinc.reset_scn reset_scn, dbinc.reset_time reset_time, bdf.ckp_scn ckp_scn, bdf.ckp_time ckp_time, nvl(df.stop_scn, 0) stop_scn, to_number(null) logThread, to_number(null) logSequence, to_number(null) setStamp, to_number(null) setCount, bs.completion_time compTime, 0 nbackups, to_char(null) logTerminal, to_number(null) next_scn, 0 pluggedRonly, 0 pluginSCN, 0 pluginRlgSCN, to_date(null) pluginRlgTime, to_number(null) newcreate_scn, to_number(null) newreset_scn, to_date(null) newreset_time FROM bdf, dbinc, rci_pdbinc_this_dbinc pdbinc, (SELECT /*+no_merge*/ file#, create_scn, stop_scn, pdbinc_key FROM df WHERE create_scn = dfBackupHistory_c1.crescn AND file# = dfBackupHistory_c1.file# AND dbinc_key = this_dbinc_key) df, (SELECT bs.bs_key, bs.completion_time FROM bs, bp WHERE bp.status = 'A' -- only available pieces AND bs.bck_type != 'L' -- ignore al backups AND bs.bs_key = bp.bs_key -- join bs, bp AND bs.db_key = this_db_key -- this database AND bp.db_key = this_db_key -- this database AND (dfBackupHistory_c1.device_type IS NULL OR dfBackupHistory_c1.device_type = bp.device_type) AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <>'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) GROUP BY bs.bs_key, bp.device_type, bp.copy#, bs.pieces, bs.completion_time HAVING count(distinct bp.piece#) = bs.pieces) bs WHERE bdf.dbinc_key = dbinc.dbinc_key -- join dbinc, bdf AND dbinc.db_key = this_db_key -- this database AND bdf.create_scn = df.create_scn -- create scn match AND bdf.file# = df.file# -- join bdf, df AND bdf.bs_key = bs.bs_key -- join bdf, bs AND df.pdbinc_key = pdbinc.pdbinc_key AND pdbinc.dbinc_key = this_dbinc_key AND bdf.ckp_scn NOT BETWEEN -- filter out orphan backups pdbinc.next_inc_scn AND pdbinc.next_end_reset_scn UNION ALL SELECT cdf.file# dfNumber, cdf.create_scn create_scn, dbinc.reset_scn reset_scn, dbinc.reset_time reset_time, cdf.ckp_scn ckp_scn, cdf.ckp_time ckp_time, nvl(df.stop_scn, 0) stop_scn, to_number(null) logThread, to_number(null) logSequence, to_number(null) setStamp, to_number(null) setCount, cdf.completion_time compTime, 0 nbackups, to_char(null) logTerminal, to_number(null) next_scn, 0 pluggedRonly, 0 pluginSCN, 0 pluginRlgSCN, to_date(null) pluginRlgTime, to_number(null) newcreate_scn, to_number(null) newreset_scn, to_date(null) newreset_time FROM cdf, dbinc, rci_pdbinc_this_dbinc pdbinc, (SELECT /*+no_merge */ file#, create_scn, stop_scn, pdbinc_key FROM df WHERE create_scn = dfBackupHistory_c1.crescn AND file# = dfBackupHistory_c1.file# AND dbinc_key = this_dbinc_key) df WHERE cdf.dbinc_key = dbinc.dbinc_key -- join dbinc, cdf AND dbinc.db_key = this_db_key -- this database AND cdf.create_scn = df.create_scn -- create scn match AND cdf.file# = df.file# -- join cdf, df AND cdf.status = 'A' -- available copy AND (dfBackupHistory_c1.device_type IS NULL OR dfBackupHistory_c1.device_type = 'DISK') AND ((user_site_key = cdf.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(cdf.site_key, this_site_key))))) AND df.pdbinc_key = pdbinc.pdbinc_key AND pdbinc.dbinc_key = dbinc.dbinc_key AND pdbinc.dbinc_key = this_dbinc_key AND cdf.ckp_scn NOT BETWEEN -- filter out orphan backups pdbinc.next_inc_scn AND pdbinc.next_end_reset_scn UNION ALL SELECT xdf.file# dfNumber, xdf.create_scn create_scn, dbinc.reset_scn reset_scn, dbinc.reset_time reset_time, xdf.ckp_scn ckp_scn, xdf.ckp_time ckp_time, nvl(df.stop_scn, 0) stop_scn, to_number(null) logThread, to_number(null) logSequence, to_number(null) setStamp, to_number(null) setCount, xdf.completion_time compTime, 0 nbackups, to_char(null) logTerminal, to_number(null) next_scn, 0 pluggedRonly, 0 pluginSCN, 0 pluginRlgSCN, to_date(null) pluginRlgTime, to_number(null) newcreate_scn, to_number(null) newreset_scn, to_date(null) newreset_time FROM xdf, dbinc, rci_pdbinc_this_dbinc pdbinc, (SELECT /*+no_merge*/ file#, create_scn, stop_scn, pdbinc_key FROM df WHERE create_scn = dfBackupHistory_c1.crescn AND file# = dfBackupHistory_c1.file# AND dbinc_key = this_dbinc_key) df WHERE xdf.dbinc_key = dbinc.dbinc_key -- join xdf, dbinc AND dbinc.db_key = this_db_key -- this database AND xdf.create_scn = df.create_scn -- create scn match AND xdf.file# = df.file# -- join xdf, df AND xdf.status = 'A' -- available proxy df AND (dfBackupHistory_c1.device_type IS NULL OR dfBackupHistory_c1.device_type = xdf.device_type) AND ((user_site_key = xdf.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xdf.site_key, this_site_key))))) AND df.pdbinc_key = pdbinc.pdbinc_key AND pdbinc.dbinc_key = this_dbinc_key AND xdf.ckp_scn NOT BETWEEN -- filter out orphan backups pdbinc.next_inc_scn AND pdbinc.next_end_reset_scn -- ORDER BY dfNumber, create_scn, reset_scn, reset_time, ckp_scn desc, stop_scn desc, compTime; CURSOR dfBackupHistory_c2( device_type IN varchar2 ,cmd IN varchar2 ,ktag IN varchar2 ,pattern1 IN varchar2 ,pattern2 IN varchar2 ,pattern3 IN varchar2 ,pattern4 IN varchar2) RETURN bhistoryRec_t IS SELECT bdf.file# dfNumber, bdf.create_scn create_scn, dbinc.reset_scn reset_scn, dbinc.reset_time reset_time, bdf.ckp_scn ckp_scn, bdf.ckp_time ckp_time, nvl(df.stop_scn, 0) stop_scn, to_number(null) logThread, to_number(null) logSequence, to_number(null) setStamp, to_number(null) setCount, bs.completion_time compTime, 0 nbackups, to_char(null) logTerminal, to_number(null) next_scn, decode(bdf.plugged_readonly, 'YES', 1, 0) pluggedRonly, bdf.plugin_scn pluginSCN, bdf.plugin_reset_scn pluginRlgSCN, bdf.plugin_reset_time pluginRlgTime, decode(bdf.plugin_scn, 0, bdf.create_scn, bdf.plugin_scn) newcreate_scn, decode(bdf.plugin_reset_scn, 0, dbinc.reset_scn, bdf.plugin_reset_scn) newreset_scn, nvl(bdf.plugin_reset_time, dbinc.reset_time) newreset_time FROM bdf, dbinc, df, rci_pdbinc_this_dbinc pdbinc, (SELECT bs.bs_key, bs.completion_time FROM bs, bp WHERE bp.status = 'A' -- only available pieces AND bs.bck_type != 'L' -- ignore al backups AND bs.bs_key = bp.bs_key -- join bs, bp AND bs.db_key = this_db_key -- this database AND bp.db_key = this_db_key -- this database AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <>'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) AND (dfBackupHistory_c2.cmd is null OR -- bug 6658764 dfBackupHistory_c2.cmd != 'B' OR (dfBackupHistory_c2.cmd = 'B' AND -- Backup command and (dfBackupHistory_c2.ktag is null AND -- nokeep cmd matches bs.keep_options = 0) OR -- nokeep backup or (dfBackupHistory_c2.ktag = bp.tag and -- keep backup cmd tag bs.keep_options != 0))) -- matches keep backup AND (dfBackupHistory_c2.device_type IS NULL OR dfBackupHistory_c2.device_type = bp.device_type) AND ((dfBackupHistory_c2.pattern1 IS NULL AND dfBackupHistory_c2.pattern2 IS NULL AND dfBackupHistory_c2.pattern3 IS NULL AND dfBackupHistory_c2.pattern4 IS NULL) OR (bp.handle LIKE dfBackupHistory_c2.pattern1 OR bp.handle LIKE dfBackupHistory_c2.pattern2 OR bp.handle LIKE dfBackupHistory_c2.pattern3 OR bp.handle LIKE dfBackupHistory_c2.pattern4)) GROUP BY bs.bs_key, bp.device_type, bp.copy#, bs.pieces, bs.completion_time HAVING count(distinct bp.piece#) = bs.pieces) bs WHERE bdf.dbinc_key = dbinc.dbinc_key -- join dbinc, bdf AND dbinc.db_key = this_db_key -- this database AND df.dbinc_key = this_dbinc_key -- this incarnation AND ((df.plugin_scn = 0 AND -- create/plugin scn match bdf.plugin_scn = 0 AND bdf.create_scn = df.create_scn) OR (df.plugin_scn != 0 AND bdf.plugin_scn = df.plugin_scn)) AND bdf.file# = df.file# -- join bdf, df AND bdf.bs_key = bs.bs_key -- join bdf, bs AND (tc_database = TRUE# OR isTranslatedFno(df.file#) = TRUE#) AND df.pdbinc_key = pdbinc.pdbinc_key AND pdbinc.dbinc_key = this_dbinc_key AND bdf.ckp_scn NOT BETWEEN -- filter out orphan backups pdbinc.next_inc_scn AND pdbinc.next_end_reset_scn UNION ALL SELECT cdf.file# dfNumber, cdf.create_scn create_scn, dbinc.reset_scn reset_scn, dbinc.reset_time reset_time, cdf.ckp_scn ckp_scn, cdf.ckp_time ckp_time, nvl(df.stop_scn, 0) stop_scn, to_number(null) logThread, to_number(null) logSequence, to_number(null) setStamp, to_number(null) setCount, cdf.completion_time compTime, 0 nbackups, to_char(null) logTerminal, to_number(null) next_scn, decode(cdf.plugged_readonly, 'YES', 1, 0) pluggedRonly, cdf.plugin_scn pluginSCN, cdf.plugin_reset_scn pluginRlgSCN, cdf.plugin_reset_time pluginRlgTime, decode(cdf.plugin_scn, 0, cdf.create_scn, cdf.plugin_scn) newcreate_scn, decode(cdf.plugin_reset_scn, 0, dbinc.reset_scn, cdf.plugin_reset_scn) newreset_scn, nvl(cdf.plugin_reset_time, dbinc.reset_time) newreset_time FROM cdf, dbinc, df, rci_pdbinc_this_dbinc pdbinc WHERE cdf.dbinc_key = dbinc.dbinc_key -- join dbinc, cdf AND dbinc.db_key = this_db_key -- this database AND df.dbinc_key = this_dbinc_key -- this incarnation AND ((df.plugin_scn = 0 AND -- create/plugin scn match cdf.plugin_scn = 0 AND cdf.create_scn = df.create_scn) OR (df.plugin_scn != 0 AND cdf.plugin_scn = df.plugin_scn)) AND cdf.file# = df.file# -- join cdf, df AND cdf.status = 'A' -- available copy AND (tc_database = TRUE# OR isTranslatedFno(df.file#) = TRUE#) AND (dfBackupHistory_c2.cmd is null OR -- bug 6658764 dfBackupHistory_c2.cmd != 'B' OR (dfBackupHistory_c2.cmd = 'B' AND -- Backup command and (dfBackupHistory_c2.ktag is null AND -- nokeep cmd matches cdf.keep_options = 0) OR -- nokeep backup or (dfBackupHistory_c2.ktag = cdf.tag and -- keep backup cmd tag cdf.keep_options != 0))) -- matches keep backup AND (dfBackupHistory_c2.device_type IS NULL OR dfBackupHistory_c2.device_type = 'DISK') AND ((dfBackupHistory_c2.pattern1 IS NULL AND dfBackupHistory_c2.pattern2 IS NULL AND dfBackupHistory_c2.pattern3 IS NULL AND dfBackupHistory_c2.pattern4 IS NULL) OR (cdf.fname LIKE dfBackupHistory_c2.pattern1 OR cdf.fname LIKE dfBackupHistory_c2.pattern2 OR cdf.fname LIKE dfBackupHistory_c2.pattern3 OR cdf.fname LIKE dfBackupHistory_c2.pattern4)) AND ((user_site_key = cdf.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(cdf.site_key, this_site_key))))) AND df.pdbinc_key = pdbinc.pdbinc_key AND pdbinc.dbinc_key = this_dbinc_key AND cdf.ckp_scn NOT BETWEEN -- filter out orphan backups pdbinc.next_inc_scn AND pdbinc.next_end_reset_scn UNION ALL SELECT xdf.file# dfNumber, xdf.create_scn create_scn, dbinc.reset_scn reset_scn, dbinc.reset_time reset_time, xdf.ckp_scn ckp_scn, xdf.ckp_time ckp_time, nvl(df.stop_scn, 0) stop_scn, to_number(null) logThread, to_number(null) logSequence, to_number(null) setStamp, to_number(null) setCount, xdf.completion_time compTime, 0 nbackups, to_char(null) logTerminal, to_number(null) next_scn, decode(xdf.plugged_readonly, 'YES', 1, 0) pluggedRonly, xdf.plugin_scn pluginSCN, xdf.plugin_reset_scn pluginRlgSCN, xdf.plugin_reset_time pluginRlgTime, decode(xdf.plugin_scn, 0, xdf.create_scn, xdf.plugin_scn) newcreate_scn, decode(xdf.plugin_reset_scn, 0, dbinc.reset_scn, xdf.plugin_reset_scn) newreset_scn, nvl(xdf.plugin_reset_time, dbinc.reset_time) newreset_time FROM xdf, dbinc, df, rci_pdbinc_this_dbinc pdbinc WHERE xdf.dbinc_key = dbinc.dbinc_key -- join xdf, dbinc AND dbinc.db_key = this_db_key -- this database AND df.dbinc_key = this_dbinc_key -- this incarnation AND ((df.plugin_scn = 0 AND -- create/plugin scn match xdf.plugin_scn = 0 AND xdf.create_scn = df.create_scn) OR (df.plugin_scn != 0 AND xdf.plugin_scn = df.plugin_scn)) AND xdf.file# = df.file# -- join xdf, df AND xdf.status = 'A' -- available proxy df AND (tc_database = TRUE# OR isTranslatedFno(df.file#) = TRUE#) AND (dfBackupHistory_c2.cmd is null OR -- bug 6658764 dfBackupHistory_c2.cmd != 'B' OR (dfBackupHistory_c2.cmd = 'B' AND -- Backup command and (dfBackupHistory_c2.ktag is null AND -- nokeep cmd matches xdf.keep_options = 0) OR -- nokeep backup or (dfBackupHistory_c2.ktag = xdf.tag and -- keep backup cmd tag xdf.keep_options != 0))) -- matches keep backup AND (dfBackupHistory_c2.device_type IS NULL OR dfBackupHistory_c2.device_type = xdf.device_type) AND ((dfBackupHistory_c2.pattern1 IS NULL AND dfBackupHistory_c2.pattern2 IS NULL AND dfBackupHistory_c2.pattern3 IS NULL AND dfBackupHistory_c2.pattern4 IS NULL) OR (xdf.handle LIKE dfBackupHistory_c2.pattern1 OR xdf.handle LIKE dfBackupHistory_c2.pattern2 OR xdf.handle LIKE dfBackupHistory_c2.pattern3 OR xdf.handle LIKE dfBackupHistory_c2.pattern4)) AND ((user_site_key = xdf.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xdf.site_key, this_site_key))))) AND df.pdbinc_key = pdbinc.pdbinc_key AND pdbinc.dbinc_key = this_dbinc_key AND xdf.ckp_scn NOT BETWEEN -- filter out orphan backups pdbinc.next_inc_scn AND pdbinc.next_end_reset_scn -- ORDER BY dfNumber, newcreate_scn, newreset_scn, newreset_time, ckp_scn desc, stop_scn desc, compTime desc; --bug 8412297 CURSOR dcBackupHistory_c( device_type IN varchar2 ,cmd IN varchar2 ,ktag IN varchar2 ,pattern1 IN varchar2 ,pattern2 IN varchar2 ,pattern3 IN varchar2 ,pattern4 IN varchar2) RETURN bhistoryRec_t IS SELECT bdf.file# dfNumber, bdf.create_scn create_scn, dbinc.reset_scn reset_scn, dbinc.reset_time reset_time, bdf.ckp_scn ckp_scn, bdf.ckp_time ckp_time, cdf.ckp_scn stop_scn, to_number(null) logThread, to_number(null) logSequence, to_number(null) setStamp, to_number(null) setCount, bs.completion_time compTime, 0 nbackups, to_char(null) logTerminal, to_number(null) next_scn, decode(bdf.plugged_readonly, 'YES', 1, 0) pluggedRonly, bdf.plugin_scn pluginSCN, bdf.plugin_reset_scn pluginRlgSCN, bdf.plugin_reset_time pluginRlgTime, decode(bdf.plugin_scn, 0, bdf.create_scn, bdf.plugin_scn) newcreate_scn, decode(bdf.plugin_reset_scn, 0, dbinc.reset_scn, bdf.plugin_reset_scn) newreset_scn, nvl(bdf.plugin_reset_time, dbinc.reset_time) newreset_time FROM bdf, dbinc, (SELECT DISTINCT cdf.file#, cdf.create_scn, cdf.plugin_scn, cdf.plugged_readonly, cdf.ckp_scn, cdf.ckp_time, cdf.dbinc_key FROM cdf, dbinc WHERE cdf.dbinc_key = dbinc.dbinc_key AND dbinc.db_key = this_db_key AND ((user_site_key = cdf.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(cdf.site_key, this_site_key))))) AND cdf.status = 'A') cdf, (SELECT bs.bs_key, bs.completion_time FROM bs, bp WHERE bp.status = 'A' -- only available pieces AND bs.bck_type != 'L' -- ignore al backups AND bs.bs_key = bp.bs_key -- join bs, bp AND bs.db_key = this_db_key -- this database AND bp.db_key = this_db_key -- this database AND (dcBackupHistory_c.cmd is null OR -- bug 6658764 dcBackupHistory_c.cmd != 'B' OR (dcBackupHistory_c.cmd = 'B' AND -- Backup command and (dcBackupHistory_c.ktag is null AND -- nokeep cmd matches bs.keep_options = 0) OR -- nokeep backup or (dcBackupHistory_c.ktag = bp.tag and -- keep backup cmd tag bs.keep_options != 0))) -- matches keep backup AND (dcBackupHistory_c.device_type IS NULL OR dcBackupHistory_c.device_type = bp.device_type) AND ((dcBackupHistory_c.pattern1 IS NULL AND dcBackupHistory_c.pattern2 IS NULL AND dcBackupHistory_c.pattern3 IS NULL AND dcBackupHistory_c.pattern4 IS NULL) OR (bp.handle LIKE dcBackupHistory_c.pattern1 OR bp.handle LIKE dcBackupHistory_c.pattern2 OR bp.handle LIKE dcBackupHistory_c.pattern3 OR bp.handle LIKE dcBackupHistory_c.pattern4)) AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <>'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) GROUP BY bs.bs_key, bp.device_type, bp.copy#, bs.pieces, bs.completion_time HAVING count(distinct bp.piece#) = bs.pieces) bs WHERE bdf.dbinc_key = dbinc.dbinc_key -- join dbinc, bdf AND dbinc.db_key = this_db_key -- this database (all inc) AND cdf.plugin_scn = bdf.plugin_scn AND cdf.plugged_readonly = bdf.plugged_readonly AND bdf.create_scn = cdf.create_scn -- create scn match AND bdf.file# = cdf.file# -- join bdf, cdf AND bdf.ckp_scn = cdf.ckp_scn AND bdf.ckp_time = cdf.ckp_time AND bdf.dbinc_key = cdf.dbinc_key AND (bdf.incr_scn = 0 OR bdf.incr_scn = cdf.create_scn) -- full backup AND bdf.bs_key = bs.bs_key -- join bdf, bs UNION ALL SELECT 0 dfNumber, 0 create_scn, dbinc.reset_scn reset_scn, dbinc.reset_time reset_time, bcf.ckp_scn ckp_scn, bcf.ckp_time ckp_time, ccf.ckp_scn stop_scn, to_number(null) logThread, to_number(null) logSequence, to_number(null) setStamp, to_number(null) setCount, bs.completion_time compTime, 0 nbackups, to_char(null) logTerminal, to_number(null) next_scn, 0 pluggedRonly, 0 pluginSCN, 0 pluginRlgSCN, to_date(null) pluginRlgTime, 0 newcreate_scn, dbinc.reset_scn newreset_scn, dbinc.reset_time newreset_time FROM bcf, dbinc, (SELECT DISTINCT ccf.ckp_scn, ccf.ckp_time, ccf.dbinc_key FROM ccf, dbinc WHERE ccf.dbinc_key = dbinc.dbinc_key AND dbinc.db_key = this_db_key AND ccf.status = 'A') ccf, (SELECT bs.bs_key, bs.completion_time FROM bs, bp WHERE bp.status = 'A' -- only available pieces AND bs.bck_type != 'L' -- ignore al backups AND bs.bs_key = bp.bs_key -- join bs, bp AND bs.db_key = this_db_key -- this database AND bp.db_key = this_db_key -- this database AND (dcBackupHistory_c.cmd is null OR -- bug 6658764 dcBackupHistory_c.cmd != 'B' OR (dcBackupHistory_c.cmd = 'B' AND -- Backup command and (dcBackupHistory_c.ktag is null AND -- nokeep cmd matches bs.keep_options = 0) OR -- nokeep backup or (dcBackupHistory_c.ktag = bp.tag and -- keep backup cmd tag bs.keep_options != 0))) -- matches keep backup AND (dcBackupHistory_c.device_type IS NULL OR dcBackupHistory_c.device_type = bp.device_type) AND ((dcBackupHistory_c.pattern1 IS NULL AND dcBackupHistory_c.pattern2 IS NULL AND dcBackupHistory_c.pattern3 IS NULL AND dcBackupHistory_c.pattern4 IS NULL) OR (bp.handle LIKE dcBackupHistory_c.pattern1 OR bp.handle LIKE dcBackupHistory_c.pattern2 OR bp.handle LIKE dcBackupHistory_c.pattern3 OR bp.handle LIKE dcBackupHistory_c.pattern4)) AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <>'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) GROUP BY bs.bs_key, bp.device_type, bp.copy#, bs.pieces, bs.completion_time HAVING count(distinct bp.piece#) = bs.pieces) bs WHERE bcf.dbinc_key = dbinc.dbinc_key -- join dbinc, bcf AND dbinc.db_key = this_db_key -- this database (all inc) AND bcf.ckp_scn = ccf.ckp_scn AND bcf.ckp_time = ccf.ckp_time AND bcf.dbinc_key = ccf.dbinc_key AND bcf.bs_key = bs.bs_key -- join bcf, bs UNION ALL SELECT cdf.file# dfNumber, cdf.create_scn create_scn, dbinc.reset_scn reset_scn, dbinc.reset_time reset_time, cdf.ckp_scn ckp_scn, cdf.ckp_time ckp_time, cdf.ckp_scn stop_scn, to_number(null) logThread, to_number(null) logSequence, to_number(null) setStamp, to_number(null) setCount, cdf.completion_time compTime, 0 nbackups, to_char(null) logTerminal, to_number(null) next_scn, decode(cdf.plugged_readonly, 'YES', 1, 0) pluggedRonly, cdf.plugin_scn pluginSCN, cdf.plugin_reset_scn pluginRlgSCN, cdf.plugin_reset_time pluginRlgTime, decode(cdf.plugin_scn, 0, cdf.create_scn, cdf.plugin_scn) newcreate_scn, decode(cdf.plugin_reset_scn, 0, dbinc.reset_scn, cdf.plugin_reset_scn) newreset_scn, nvl(cdf.plugin_reset_time, dbinc.reset_time) newreset_time FROM cdf, dbinc WHERE cdf.dbinc_key = dbinc.dbinc_key -- join xdf, dbinc AND dbinc.db_key = this_db_key -- this database (all inc) AND cdf.status = 'A' -- available backup AND (dcBackupHistory_c.cmd is null OR -- bug 6658764 dcBackupHistory_c.cmd != 'B' OR (dcBackupHistory_c.cmd = 'B' AND -- Backup command and (dcBackupHistory_c.ktag is null AND -- nokeep cmd matches cdf.keep_options = 0) OR -- nokeep backup or (dcBackupHistory_c.ktag = cdf.tag and -- keep backup cmd tag cdf.keep_options != 0))) -- matches keep backup AND (dcBackupHistory_c.device_type IS NULL OR dcBackupHistory_c.device_type = 'DISK') AND (dcBackupHistory_c.pattern1 IS NOT NULL OR dcBackupHistory_c.pattern2 IS NOT NULL OR dcBackupHistory_c.pattern3 IS NOT NULL OR dcBackupHistory_c.pattern4 IS NOT NULL) AND (cdf.fname LIKE dcBackupHistory_c.pattern1 OR cdf.fname LIKE dcBackupHistory_c.pattern2 OR cdf.fname LIKE dcBackupHistory_c.pattern3 OR cdf.fname LIKE dcBackupHistory_c.pattern4) AND ((user_site_key = cdf.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(cdf.site_key, this_site_key))))) UNION ALL SELECT xdf.file# dfNumber, xdf.create_scn create_scn, dbinc.reset_scn reset_scn, dbinc.reset_time reset_time, xdf.ckp_scn ckp_scn, xdf.ckp_time ckp_time, cdf.ckp_scn stop_scn, to_number(null) logThread, to_number(null) logSequence, to_number(null) setStamp, to_number(null) setCount, xdf.completion_time compTime, 0 nbackups, to_char(null) logTerminal, to_number(null) next_scn, decode(xdf.plugged_readonly, 'YES', 1, 0) pluggedRonly, xdf.plugin_scn pluginSCN, xdf.plugin_reset_scn pluginRlgSCN, xdf.plugin_reset_time pluginRlgTime, decode(xdf.plugin_scn, 0, xdf.create_scn, xdf.plugin_scn) newcreate_scn, decode(xdf.plugin_reset_scn, 0, dbinc.reset_scn, xdf.plugin_reset_scn) newreset_scn, nvl(xdf.plugin_reset_time, dbinc.reset_time) newreset_time FROM xdf, dbinc, (SELECT DISTINCT cdf.file#, cdf.create_scn, cdf.plugin_scn, cdf.plugged_readonly, cdf.ckp_scn, cdf.ckp_time, cdf.dbinc_key FROM cdf, dbinc WHERE cdf.dbinc_key = dbinc.dbinc_key AND dbinc.db_key = this_db_key AND cdf.status = 'A') cdf WHERE xdf.dbinc_key = dbinc.dbinc_key -- join xdf, dbinc AND dbinc.db_key = this_db_key -- this database (all inc) AND xdf.file# = cdf.file# -- join xdf, cdf AND xdf.plugged_readonly = cdf.plugged_readonly AND xdf.plugin_scn = cdf.plugin_scn AND xdf.create_scn = cdf.create_scn -- create scn match AND xdf.dbinc_key = cdf.dbinc_key AND xdf.ckp_scn = cdf.ckp_scn AND xdf.ckp_time = cdf.ckp_time AND xdf.status = 'A' -- available proxy df AND (dcBackupHistory_c.cmd is null OR -- bug 6658764 dcBackupHistory_c.cmd != 'B' OR (dcBackupHistory_c.cmd = 'B' AND -- Backup command and (dcBackupHistory_c.ktag is null AND -- nokeep cmd matches xdf.keep_options = 0) OR -- nokeep backup or (dcBackupHistory_c.ktag = xdf.tag and -- keep backup cmd tag xdf.keep_options != 0))) -- matches keep backup AND (dcBackupHistory_c.device_type IS NULL OR dcBackupHistory_c.device_type = xdf.device_type) AND ((dcBackupHistory_c.pattern1 IS NULL AND dcBackupHistory_c.pattern2 IS NULL AND dcBackupHistory_c.pattern3 IS NULL AND dcBackupHistory_c.pattern4 IS NULL) OR (xdf.handle LIKE dcBackupHistory_c.pattern1 OR xdf.handle LIKE dcBackupHistory_c.pattern2 OR xdf.handle LIKE dcBackupHistory_c.pattern3 OR xdf.handle LIKE dcBackupHistory_c.pattern4)) AND ((user_site_key = xdf.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xdf.site_key, this_site_key))))) -- ORDER BY dfNumber, newcreate_scn, newreset_scn, newreset_time, ckp_scn desc, stop_scn desc, compTime; -- CURSOR alBackupHistory_c1( thread# IN number, sequence# IN number, device_type IN varchar2) RETURN bhistoryRec_t IS SELECT to_number(null) dfNumber, to_number(null) create_scn, dbinc.reset_scn reset_scn, dbinc.reset_time reset_time, to_number(null) ckp_scn, to_date(null) ckp_time, to_number(null) stop_scn, brl.thread# logThread, brl.sequence# logSequence, to_number(null) setStamp, to_number(null) setCount, bs.completion_time compTime, 0 nbackups, brl.terminal logTerminal, brl.next_scn next_scn, 0 pluggedRonly, 0 pluginSCN, 0 pluginRlgSCN, to_date(null) pluginRlgTime, to_number(null) newcreate_scn, to_number(null) newreset_scn, to_date(null) newreset_time FROM brl, dbinc, (SELECT /*+no_merge*/ DISTINCT thread#, sequence# FROM al WHERE al.thread# = alBackupHistory_c1.thread# AND al.sequence# = alBackupHistory_c1.sequence# AND al.dbinc_key = this_dbinc_key AND al.status = 'A' AND al.archived = 'Y') al, (SELECT bs.bs_key, bs.completion_time FROM bs, bp WHERE bp.status = 'A' -- only available pieces AND bs.bck_type = 'L' -- only al backups AND bs.bs_key = bp.bs_key -- join bs, bp AND bs.db_key = this_db_key -- this database AND bp.db_key = this_db_key -- this database AND (alBackupHistory_c1.device_type IS NULL OR alBackupHistory_c1.device_type = bp.device_type) AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <>'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) GROUP BY bs.bs_key, bp.device_type, bp.copy#, bs.pieces, bs.completion_time HAVING count(distinct bp.piece#) = bs.pieces) bs WHERE dbinc.dbinc_key = this_dbinc_key -- this incarnation AND brl.dbinc_key = dbinc.dbinc_key -- join brl, dbinc AND dbinc.db_key = this_db_key AND brl.thread# = al.thread# -- join brl and al AND brl.sequence# = al.sequence# AND brl.dbinc_key = this_dbinc_key AND brl.bs_key = bs.bs_key -- join brl,bs UNION ALL SELECT to_number(null) dfNumber, to_number(null) crescn, dbinc.reset_scn reset_scn, dbinc.reset_time reset_time, to_number(null) ckp_scn, to_date(null) ckp_time, to_number(null) stop_scn, xal.thread# logThread, xal.sequence# logSequence, to_number(null) setStamp, to_number(null) setCount, xal.completion_time compTime, 0 nbackups, xal.terminal logTerminal, xal.next_scn next_scn, 0 pluggedRonly, 0 pluginSCN, 0 pluginRlgSCN, to_date(null) pluginRlgTime, to_number(null) newcreate_scn, to_number(null) newreset_scn, to_date(null) newreset_time FROM xal, dbinc, (SELECT /*+no_merge*/ DISTINCT thread#, sequence# FROM al WHERE al.thread# = alBackupHistory_c1.thread# AND al.sequence# = alBackupHistory_c1.sequence# AND al.dbinc_key = this_dbinc_key AND al.status = 'A' AND al.archived = 'Y') al WHERE xal.dbinc_key = dbinc.dbinc_key -- join xal, dbinc AND dbinc.db_key = this_db_key -- this database AND xal.thread# = al.thread# AND xal.sequence# = al.sequence# AND xal.dbinc_key = this_dbinc_key AND xal.status = 'A' AND (alBackupHistory_c1.device_type IS NULL OR alBackupHistory_c1.device_type = xal.device_type) AND ((user_site_key = xal.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xal.site_key, this_site_key))))) -- -- -- ORDER BY reset_scn, reset_time, logThread, logSequence, logTerminal desc, compTime; CURSOR alBackupHistory_c2( device_type IN varchar2 ,cmd IN varchar2 ,ktag IN varchar2 ,pattern1 IN varchar2 ,pattern2 IN varchar2 ,pattern3 IN varchar2 ,pattern4 IN varchar2) RETURN bhistoryRec_t IS SELECT to_number(null) dfNumber, to_number(null) create_scn, dbinc.reset_scn reset_scn, dbinc.reset_time reset_time, to_number(null) ckp_scn, to_date(null) ckp_time, to_number(null) stop_scn, brl.thread# logThread, brl.sequence# logSequence, to_number(null) setStamp, to_number(null) setCount, bs.completion_time compTime, 0 nbackups, brl.terminal logTerminal, brl.next_scn next_scn, 0 pluggedRonly, 0 pluginSCN, 0 pluginRlgSCN, to_date(null) pluginRlgTime, to_number(null) newcreate_scn, to_number(null) newreset_scn, to_date(null) newreset_time FROM brl, dbinc, (SELECT DISTINCT al.thread#, al.sequence#, al.dbinc_key FROM al, dbinc WHERE dbinc.dbinc_key = al.dbinc_key AND dbinc.db_key = this_db_key AND al.status = 'A' AND al.archived = 'Y' AND (tc_thread IS NULL OR al.thread# = tc_thread) AND (tc_fromSeq IS NULL OR al.sequence# >= tc_fromSeq) AND (tc_toSeq IS NULL OR al.sequence# <= tc_toSeq) AND (tc_fromSCN IS NULL OR al.next_scn > tc_fromSCN) AND (tc_toSCN IS NULL OR al.low_scn < tc_toSCN) AND (tc_pattern IS NULL OR al.fname like tc_pattern) AND (tc_fromTime IS NULL OR al.next_time > tc_fromTime) AND (tc_toTime IS NULL OR al.low_time <= tc_toTime)) al, (SELECT DISTINCT bs.bs_key, bs.completion_time FROM bs, bp WHERE bp.status = 'A' -- only available pieces AND bs.bck_type = 'L' -- only al backups AND bs.status = 'A' -- available backupset AND bs.bs_key = bp.bs_key -- join bs, bp AND bs.db_key = this_db_key -- this database AND bp.db_key = this_db_key -- this database AND (alBackupHistory_c2.cmd is null OR -- bug 6658764 (alBackupHistory_c2.cmd != 'B' AND alBackupHistory_c2.cmd != 'D') OR ((alBackupHistory_c2.cmd = 'B' OR -- Backup command or alBackupHistory_c2.cmd = 'D') AND -- Delete command and ((alBackupHistory_c2.ktag is null AND -- nokeep cmd matches bs.keep_options = 0) OR -- nokeep backup or (alBackupHistory_c2.ktag = bp.tag AND -- keep backup cmd tag bs.keep_options != 0)))) -- matches keep backup AND (alBackupHistory_c2.device_type IS NULL OR alBackupHistory_c2.device_type = bp.device_type) AND ((alBackupHistory_c2.pattern1 IS NULL AND alBackupHistory_c2.pattern2 IS NULL AND alBackupHistory_c2.pattern3 IS NULL AND alBackupHistory_c2.pattern4 IS NULL) OR (bp.handle LIKE alBackupHistory_c2.pattern1 OR bp.handle LIKE alBackupHistory_c2.pattern2 OR bp.handle LIKE alBackupHistory_c2.pattern3 OR bp.handle LIKE alBackupHistory_c2.pattern4)) AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <>'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) GROUP BY bs.bs_key, bp.device_type, bp.copy#, bs.pieces, bs.completion_time HAVING count(distinct bp.piece#) = bs.pieces) bs WHERE (canApplyAnyRedo = TRUE# OR dbinc.dbinc_key = this_dbinc_key) AND brl.dbinc_key = dbinc.dbinc_key -- join brl, dbinc AND dbinc.db_key = this_db_key AND brl.thread# = al.thread# -- join brl and al AND brl.sequence# = al.sequence# AND brl.dbinc_key = al.dbinc_key AND brl.bs_key = bs.bs_key -- join brl,bs UNION ALL SELECT to_number(null) dfNumber, to_number(null) crescn, dbinc.reset_scn reset_scn, dbinc.reset_time reset_time, to_number(null) ckp_scn, to_date(null) ckp_time, to_number(null) stop_scn, xal.thread# logThread, xal.sequence# logSequence, to_number(null) setStamp, to_number(null) setCount, xal.completion_time compTime, 0 nbackups, xal.terminal logTerminal, xal.next_scn next_scn, 0 pluggedRonly, 0 pluginSCN, 0 pluginRlgSCN, to_date(null) pluginRlgTime, to_number(null) newcreate_scn, to_number(null) newreset_scn, to_date(null) newreset_time FROM xal, dbinc, (SELECT DISTINCT al.thread#, al.sequence#, al.dbinc_key FROM al, dbinc WHERE dbinc.dbinc_key = al.dbinc_key AND dbinc.db_key = this_db_key AND al.status = 'A' AND al.archived = 'Y' AND (tc_thread IS NULL OR al.thread# = tc_thread) AND (tc_fromSeq IS NULL OR al.sequence# >= tc_fromSeq) AND (tc_toSeq IS NULL OR al.sequence# <= tc_toSeq) AND (tc_fromSCN IS NULL OR al.next_scn > tc_fromSCN) AND (tc_toSCN IS NULL OR al.low_scn < tc_toSCN) AND (tc_pattern IS NULL OR al.fname like tc_pattern) AND (tc_fromTime IS NULL OR al.next_time > tc_fromTime) AND (tc_toTime IS NULL OR al.low_time <= tc_toTime)) al WHERE (canApplyAnyRedo = TRUE# OR dbinc.dbinc_key = this_dbinc_key) AND xal.dbinc_key = dbinc.dbinc_key -- join xal, dbinc AND dbinc.db_key = this_db_key -- this database AND xal.thread# = al.thread# AND xal.sequence# = al.sequence# AND xal.dbinc_key = al.dbinc_key AND xal.status = 'A' AND (alBackupHistory_c2.cmd is null OR -- bug 6658764 (alBackupHistory_c2.cmd != 'B' AND alBackupHistory_c2.cmd != 'D') OR ((alBackupHistory_c2.cmd = 'B' OR -- Backup command or alBackupHistory_c2.cmd = 'D') AND -- Delete command and ((alBackupHistory_c2.ktag is null AND -- nokeep cmd matches xal.keep_options = 0) OR -- nokeep backup or (alBackupHistory_c2.ktag = xal.tag AND -- keep backup cmd tag xal.keep_options != 0)))) -- matches keep backup AND (alBackupHistory_c2.device_type IS NULL OR alBackupHistory_c2.device_type = xal.device_type) AND ((alBackupHistory_c2.pattern1 IS NULL AND alBackupHistory_c2.pattern2 IS NULL AND alBackupHistory_c2.pattern3 IS NULL AND alBackupHistory_c2.pattern4 IS NULL) OR (xal.handle LIKE alBackupHistory_c2.pattern1 OR xal.handle LIKE alBackupHistory_c2.pattern2 OR xal.handle LIKE alBackupHistory_c2.pattern3 OR xal.handle LIKE alBackupHistory_c2.pattern4)) AND ((user_site_key = xal.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xal.site_key, this_site_key))))) -- -- -- ORDER BY reset_scn, reset_time, logThread, logSequence, logTerminal desc, compTime; CURSOR bsBackupHistory_c1( set_stamp IN number ,set_count IN number ,device_type IN varchar2 ,pattern1 IN varchar2 ,pattern2 IN varchar2 ,pattern3 IN varchar2 ,pattern4 IN varchar2 ) RETURN bhistoryRec_t IS SELECT to_number(null) dfNumber, to_number(null) create_scn, to_number(null) reset_scn, to_date(null) reset_time, to_number(null) ckp_scn, to_date(null) ckp_time, to_number(null) stop_scn, to_number(null) logThread, to_number(null) logSequence, bs.set_stamp setStamp, bs.set_count setCount, max(bp.completion_time) compTime, 0 nbackups, to_char(null) logTerminal, to_number(null) next_scn, 0 pluggedRonly, 0 pluginSCN, 0 pluginRlgSCN, to_date(null) pluginRlgTime, to_number(null) newcreate_scn, to_number(null) newreset_scn, to_date(null) newreset_time FROM bs, bp WHERE bs.db_key = this_db_key -- this database AND bp.bs_key = bs.bs_key -- join bs, bp AND bs.set_stamp = bsBackupHistory_c1.set_stamp AND bs.set_count = bsBackupHistory_c1.set_count AND bs.status = 'A' AND bp.status != 'D' AND (bsBackupHistory_c1.device_type IS NULL OR bsBackupHistory_c1.device_type = bp.device_type) AND ((bsBackupHistory_c1.pattern1 IS NULL AND bsBackupHistory_c1.pattern2 IS NULL AND bsBackupHistory_c1.pattern3 IS NULL AND bsBackupHistory_c1.pattern4 IS NULL) OR (bp.handle LIKE bsBackupHistory_c1.pattern1 OR bp.handle LIKE bsBackupHistory_c1.pattern2 OR bp.handle LIKE bsBackupHistory_c1.pattern3 OR bp.handle LIKE bsBackupHistory_c1.pattern4)) AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) GROUP BY bs.set_stamp, bs.set_count, bs.pieces, bp.copy#, bp.device_type HAVING count(distinct bp.piece#) = bs.pieces -- ORDER BY setStamp, setCount, compTime; CURSOR bsBackupHistory_c2( device_type IN varchar2 ,cmd IN varchar2 ,ktag IN varchar2 ,pattern1 IN varchar2 ,pattern2 IN varchar2 ,pattern3 IN varchar2 ,pattern4 IN varchar2) RETURN bhistoryRec_t IS SELECT to_number(null) dfNumber, to_number(null) create_scn, to_number(null) reset_scn, to_date(null) reset_time, to_number(null) ckp_scn, to_date(null) ckp_time, to_number(null) stop_scn, to_number(null) logThread, to_number(null) logSequence, bs.set_stamp setStamp, bs.set_count setCount, max(bp.completion_time) compTime, 0 nbackups, to_char(null) logTerminal, to_number(null) next_scn, 0 pluggedRonly, 0 pluginSCN, 0 pluginRlgSCN, to_date(null) pluginRlgTime, to_number(null) newcreate_scn, to_number(null) newreset_scn, to_date(null) newreset_time FROM bs, bp WHERE bs.db_key = this_db_key -- this database AND bp.bs_key = bs.bs_key -- join bs, bp AND bs.status = 'A' AND bp.status != 'D' AND (bsBackupHistory_c2.device_type IS NULL OR bsBackupHistory_c2.device_type = bp.device_type) AND ((bsBackupHistory_c2.pattern1 IS NULL AND bsBackupHistory_c2.pattern2 IS NULL AND bsBackupHistory_c2.pattern3 IS NULL AND bsBackupHistory_c2.pattern4 IS NULL) OR (bp.handle LIKE bsBackupHistory_c2.pattern1 OR bp.handle LIKE bsBackupHistory_c2.pattern2 OR bp.handle LIKE bsBackupHistory_c2.pattern3 OR bp.handle LIKE bsBackupHistory_c2.pattern4)) AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) GROUP BY bs.set_stamp, bs.set_count, bs.pieces, bp.copy#, bp.device_type HAVING count(distinct bp.piece#) = bs.pieces -- ORDER BY setStamp, setCount, compTime; -- -- -- CURSOR getCopyofDatafile_c2( itag varchar2 ) IS SELECT /*+ first_rows */ file#, creation_change#, resetlogs_change#, resetlogs_time, recid, stamp, name, tag, status, blocks, block_size, completion_time, checkpoint_change#, checkpoint_time, decode(plugged_readonly, 'YES', 1, 0) pluggedRonly, plugin_change#, plugin_resetlogs_change#, plugin_resetlogs_time FROM rc_datafile_copy WHERE status = 'A' AND (itag is NULL or tag = itag) AND (tc_database = TRUE# OR isTranslatedFno(file#) = TRUE#) -- only translated files AND ((user_site_key = rc_datafile_copy.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(rc_datafile_copy.site_key, this_site_key))))) ORDER BY file#, decode(plugged_readonly, 'YES', plugin_change#, checkpoint_change#) desc, recid desc; -- -- -- -- CURSOR getCopyofDatafile_c( dfnumber number ,itag varchar2 ,crescn number ,rlgscn number ,rlgtime date ,pluginSCN number ) IS SELECT /*+ first_rows */ recid, stamp, name, tag, status, blocks, block_size, completion_time, checkpoint_change#, checkpoint_time, creation_change#, resetlogs_change#, resetlogs_time, decode(plugged_readonly, 'YES', 1, 0) pluggedRonly FROM rc_datafile_copy WHERE status = 'A' AND (itag is NULL or tag = itag) AND file# = dfnumber AND ((pluginSCN = 0 AND creation_change# = crescn) OR (pluginSCN != 0 AND plugin_change# = pluginSCN)) AND ((plugged_readonly = 'NO' AND resetlogs_change# = rlgscn AND resetlogs_time = rlgtime) OR (plugged_readonly = 'YES' AND plugin_resetlogs_change# = rlgscn AND plugin_resetlogs_time = rlgtime)) AND ((user_site_key = rc_datafile_copy.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(rc_datafile_copy.site_key, this_site_key))))) ORDER BY decode(plugged_readonly, 'YES', plugin_change#, checkpoint_change#) desc; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- TYPE rcvRecCursor_t IS RECORD ( currc1 rcvRec_t, -- current fetched rcvRecCursor1_c data reqfno number, -- requested file number reqcrescn number, -- requested file number's create scn reqpluginSCN number, -- requested file number's plugin scn excludeAction binary_integer -- type of action that is excluded ); rcvRecCursor rcvRecCursor_t; CURSOR rcvRecCursor1_c( rmanCmd IN binary_integer ) RETURN rcvRec_t IS -- SELECT offlineRangeRec_con_t type_con, offr.offr_key key_con, offr.offr_recid recid_con, offr.offr_stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, to_number(null) blocks_con, to_number(null) blockSize_con, to_char(null) deviceType_con, to_date(null) compTime_con, offr.cf_create_time cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, offlineRange_act_t type_act, offr.offline_scn fromSCN_act, offr.online_scn toSCN_act, offr.online_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, dbinc.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, offr.file# dfNumber_obj, offr.create_scn dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, to_number(null) pdbKey_obj, to_number(null) keep_options, to_date(null) keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, 0 site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, offr.create_scn newDfCreationSCN_obj, offr.online_scn newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM offr, dbinc WHERE (tc_database = TRUE# OR isTranslatedFno(offr.file#) = TRUE#) AND (untilSCN is null OR offr.online_scn < untilSCN) -- -- -- -- -- -- AND offr.cf_create_time is not null -- AND offr.offr_stamp <> 0 -- stamp = 0 -> from kccfe AND offr.dbinc_key = this_dbinc_key AND offr.dbinc_key = dbinc.dbinc_key UNION ALL -- SELECT imageCopy_con_t type_con, cdf.cdf_key key_con, cdf.cdf_recid recid_con, cdf.cdf_stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, cdf.fname fileName_con, cdf.tag tag_con, to_number(null) copyNumber_con, cdf.status status_con, cdf.blocks blocks_con, cdf.block_size blockSize_con, 'DISK' deviceType_con, cdf.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, full_act_t type_act, 0 fromSCN_act, cdf.ckp_scn toSCN_act, cdf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, dbinc.dbinc_key dbincKey_act, cdf.incr_level level_act, 0 section_size_act, cdf.file# dfNumber_obj, cdf.create_scn dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, cdf.pdb_key pdbKey_obj, cdf.keep_options keep_options, cdf.keep_until keep_until, cdf.abs_fuzzy_scn afzSCN_act, cdf.rcv_fuzzy_time rfzTime_act, cdf.rcv_fuzzy_scn rfzSCN_act, to_char(null) media_con, cdf.is_recovery_dest_file isrdf_con, site_key site_key_con, cdf.foreign_dbid foreignDbid_obj, decode(cdf.plugged_readonly, 'YES', 1, 0) pluggedRonly_obj, cdf.plugin_scn pluginSCN_obj, cdf.plugin_reset_scn pluginRlgSCN_obj, cdf.plugin_reset_time pluginRlgTime_obj, decode(cdf.plugin_scn, 0, cdf.create_scn, cdf.plugin_scn) newDfCreation_obj, decode(cdf.plugged_readonly, 'NO', cdf.ckp_scn, cdf.plugin_scn) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, cdf.sparse_backup sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM cdf, dbinc WHERE (tc_database = TRUE# OR isTranslatedFno(cdf.file#) = TRUE#) AND (untilSCN is null OR (cdf.plugged_readonly = 'NO' AND greatest(cdf.ckp_scn, cdf.abs_fuzzy_scn, cdf.rcv_fuzzy_scn) <= untilSCN) OR (cdf.plugged_readonly = 'YES' AND cdf.plugin_scn <= untilSCN)) AND cdf.status = 'A' AND (restoreSource is NULL OR bitand(restoreSource, imageCopy_con_t) != 0) AND cdf.dbinc_key = dbinc.dbinc_key AND dbinc.db_key = this_db_key AND rmanCmd != recoverCmd_t AND ((user_site_key = cdf.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(cdf.site_key, this_site_key))))) AND (cdf.file# = 0 OR -- backup mode is not applicable for control files restoreSparse = BACKUP_SPARSENESS_UNSPECIFIED OR (restoreSparse = BACKUP_SPARSENESS_SPARSE AND cdf.sparse_backup = 'YES') OR (restoreSparse = BACKUP_SPARSENESS_NONSPARSE AND cdf.sparse_backup = 'NO')) UNION ALL -- SELECT imageCopy_con_t type_con, ccf.ccf_key key_con, ccf.ccf_recid recid_con, ccf.ccf_stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, ccf.fname fileName_con, ccf.tag tag_con, to_number(null) copyNumber_con, ccf.status status_con, to_number(null) blocks_con, ccf.block_size blockSize_con, 'DISK' deviceType_con, ccf.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, full_act_t type_act, 0 fromSCN_act, ccf.ckp_scn toSCN_act, ccf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, dbinc.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, 0 dfNumber_obj, 0 dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, nvl(ccf.controlfile_type, 'B') cfType_obj, ccf.pdb_key pdbKey_obj, ccf.keep_options keep_options, ccf.keep_until keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, is_recovery_dest_file isrdf_con, site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, 0 newDfCreationSCN_obj, ccf.ckp_scn newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM ccf, dbinc WHERE (tc_database = TRUE# OR isTranslatedFno(0) = TRUE#) AND (untilSCN is null OR ccf.ckp_scn <= untilSCN) AND ccf.status = 'A' AND (restoreSource is NULL OR bitand(restoreSource, imageCopy_con_t) != 0) AND ccf.dbinc_key = dbinc.dbinc_key AND dbinc.db_key = this_db_key AND rmanCmd NOT IN (recoverCmd_t, blkRestoreCmd_t) AND ((user_site_key = ccf.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(ccf.site_key, this_site_key))))) UNION ALL -- -- SELECT backupSet_con_t type_con, bdf.bdf_key key_con, bdf.bdf_recid recid_con, bdf.bdf_stamp stamp_con, bs.set_stamp setStamp_con, bs.set_count setCount_con, bs.bs_recid bsRecid_con, bs.bs_stamp bsStamp_con, bs.bs_key bsKey_con, bs.incr_level bsLevel_con, bs.bck_type bsType_con, abs((bs.completion_time - bs.start_time) * 86400) elapseSecs_con, bs.pieces pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, bdf.blocks blocks_con, bdf.block_size blockSize_con, to_char(null) deviceType_con, bdf.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, multi_section multi_section_con, decode(bdf.incr_scn, 0, full_act_t, bdf.create_scn, decode(rmanCmd, rcvCopyCmd_t, incremental_act_t, recoverCmd_t, incremental_act_t, full_act_t), incremental_act_t) type_act, decode(bdf.incr_scn, bdf.create_scn, decode(rmanCmd, rcvCopyCmd_t, bdf.incr_scn, recoverCmd_t, bdf.incr_scn, 0), bdf.incr_scn) fromSCN_act, bdf.ckp_scn toSCN_act, bdf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, dbinc.dbinc_key dbincKey_act, bdf.incr_level level_act, bdf.section_size section_size_act, bdf.file# dfNumber_obj, bdf.create_scn dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, bdf.pdb_key pdbKey_obj, bs.keep_options keep_options, bs.keep_until keep_until, bdf.abs_fuzzy_scn afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, bs.site_key site_key_con, bdf.foreign_dbid foreignDbid_obj, decode(bdf.plugged_readonly, 'YES', 1, 0) pluggedRonly_obj, bdf.plugin_scn pluginSCN_obj, bdf.plugin_reset_scn pluginRlgSCN_obj, bdf.plugin_reset_time pluginRlgTime_obj, decode(bdf.plugin_scn, 0, bdf.create_scn, bdf.plugin_scn) newDfCreationSCN_obj, decode(bdf.plugged_readonly, 'NO', bdf.ckp_scn, bdf.plugin_scn) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, bdf.sparse_backup sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM bdf, bs, dbinc -- -- -- WHERE rmanCmd != obsoleteCmd_t AND (tc_database = TRUE# OR isTranslatedFno(bdf.file#) = TRUE#) AND bs.status = 'A' AND bs.bck_type != 'L' -- only datafile backups AND (untilSCN IS NULL OR (bdf.plugged_readonly = 'NO' AND greatest(bdf.ckp_scn, bdf.abs_fuzzy_scn) <= untilSCN) OR (bdf.plugged_readonly = 'YES' AND bdf.plugin_scn <= untilSCN)) AND dbinc.dbinc_key = bdf.dbinc_key -- join dbinc, bdf AND bs.bs_key = bdf.bs_key -- join bs, bdf AND dbinc.db_key = this_db_key AND (rmanCmd = rcvCopyCmd_t OR -- use incr for recover copy cmd rmanCmd = recoverCmd_t OR (restoreSource IS NULL OR bitand(restoreSource, backupSet_con_t) != 0)) AND (bdf.file# = 0 OR -- backup mode is not applicable for control files restoreSparse = BACKUP_SPARSENESS_UNSPECIFIED OR (restoreSparse = BACKUP_SPARSENESS_SPARSE AND bdf.sparse_backup = 'YES') OR (restoreSparse = BACKUP_SPARSENESS_NONSPARSE AND bdf.sparse_backup = 'NO')) AND ((rmanCmd = rcvCopyCmd_t AND bdf.incr_scn > 0) OR (rmanCmd = recoverCmd_t AND bdf.incr_scn > 0) OR (rmanCmd IN (restoreCmd_t, blkRestoreCmd_t) AND bdf.incr_scn <= bdf.create_scn) OR (rmanCmd = unknownCmd_t)) AND (bs.site_key IS NULL OR -- always return null site_key user_site_key = bs.site_key OR -- user interested in one site (user_site_key IS NULL AND -- return rows per access attr (disk_backups_shared = TRUE# OR tape_backups_shared = TRUE# OR this_site_key = bs.site_key))) UNION ALL -- -- SELECT backupSet_con_t type_con, bdf.bdf_key key_con, bdf.bdf_recid recid_con, bdf.bdf_stamp stamp_con, bs.set_stamp setStamp_con, bs.set_count setCount_con, bs.bs_recid bsRecid_con, bs.bs_stamp bsStamp_con, bs.bs_key bsKey_con, bs.incr_level bsLevel_con, bs.bck_type bsType_con, abs((bs.completion_time - bs.start_time) * 86400) elapseSecs_con, bs.pieces pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, bdf.blocks blocks_con, bdf.block_size blockSize_con, to_char(null) deviceType_con, bdf.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, multi_section multi_section_con, decode(bdf.incr_scn, 0, full_act_t, bdf.create_scn, full_act_t, incremental_act_t) type_act, bdf.incr_scn fromSCN_act, bdf.ckp_scn toSCN_act, bdf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, dbinc.dbinc_key dbincKey_act, bdf.incr_level level_act, bdf.section_size section_size_act, bdf.file# dfNumber_obj, bdf.create_scn dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, bdf.pdb_key pdbKey_obj, bs.keep_options keep_options, bs.keep_until keep_until, bdf.abs_fuzzy_scn afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, bs.site_key site_key_con, bdf.foreign_dbid foreignDbid_obj, decode(bdf.plugged_readonly, 'YES', 1, 0) pluggedRonly_obj, bdf.plugin_scn pluginSCN_obj, bdf.plugin_reset_scn pluginRlgSCN_obj, bdf.plugin_reset_time pluginRlgTime_obj, decode(bdf.plugin_scn, 0, bdf.create_scn, bdf.plugin_scn) newDfCreationSCN_obj, decode(bdf.plugged_readonly, 'NO', bdf.ckp_scn, bdf.plugin_scn) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, bdf.sparse_backup sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM bdf, bs, dbinc, (SELECT bs_key, count(distinct piece#) pieces FROM bp WHERE rmanCmd = obsoleteCmd_t AND bp.db_key = this_db_key -- this database AND bp.status = 'A' AND (anyDevice = TRUE# OR isDeviceTypeAllocated(bp.device_type) = TRUE#) AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared =TRUE# AND bp.device_type='DISK') OR (tape_backups_shared =TRUE# AND bp.device_type<>'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) GROUP BY bs_key, device_type) bp -- -- -- WHERE rmanCmd = obsoleteCmd_t -- -- -- AND bs.status = 'A' AND bs.bck_type != 'L' -- only datafile backups AND (untilSCN IS NULL OR (bdf.plugged_readonly = 'NO' AND greatest(bdf.ckp_scn, bdf.abs_fuzzy_scn) <= untilSCN) OR (bdf.plugged_readonly = 'YES' AND bdf.plugin_scn <= untilSCN)) AND dbinc.dbinc_key = bdf.dbinc_key -- join dbinc, bdf AND bs.bs_key = bdf.bs_key -- join bs, bdf AND dbinc.db_key = this_db_key AND (restoreSource IS NULL OR bitand(restoreSource, backupSet_con_t) != 0) AND (bdf.file# = 0 OR -- backup mode is not applicable for control files restoreSparse = BACKUP_SPARSENESS_UNSPECIFIED OR (restoreSparse = BACKUP_SPARSENESS_SPARSE AND bdf.sparse_backup = 'YES') OR (restoreSparse = BACKUP_SPARSENESS_NONSPARSE AND bdf.sparse_backup = 'NO')) AND bp.bs_key = bs.bs_key AND bp.pieces = bs.pieces UNION ALL -- -- SELECT backupSet_con_t type_con, bcf.bcf_key key_con, bcf.bcf_recid recid_con, bcf.bcf_stamp stamp_con, bs.set_stamp setStamp_con, bs.set_count setCount_con, bs.bs_recid bsRecid_con, bs.bs_stamp bsStamp_con, bs.bs_key bsKey_con, 0 bsLevel_con, bs.bck_type bsType_con, abs((bs.completion_time - bs.start_time) * 86400) elapseSecs_con, bs.pieces pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, to_number(null) blocks_con, bcf.block_size blockSize_con, to_char(null) deviceType_con, bs.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, multi_section multi_section_con, full_act_t type_act, 0 fromSCN_act, bcf.ckp_scn toSCN_act, bcf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, dbinc.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, 0 dfNumber_obj, 0 dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, nvl(bcf.controlfile_type, 'B') cfType_obj, bcf.pdb_key pdbKey_obj, bs.keep_options keep_options, bs.keep_until keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, bs.site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, 0 newDfCreationSCN_obj, bcf.ckp_scn newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM bcf, bs, dbinc -- -- -- WHERE rmanCmd != obsoleteCmd_t AND (tc_database = TRUE# OR isTranslatedFno(0) = TRUE#) AND bs.status = 'A' AND bs.bck_type != 'L' -- ignore archivelog backups AND (untilSCN IS NULL OR bcf.ckp_scn <= untilSCN) AND (restoreSource IS NULL OR bitand(restoreSource, backupSet_con_t) != 0) AND dbinc.dbinc_key = bcf.dbinc_key -- join dbinc, bcf AND bs.bs_key = bcf.bs_key -- join bs, bcf AND dbinc.db_key = this_db_key AND rmanCmd NOT IN (recoverCmd_t, blkRestoreCmd_t) AND (bs.site_key IS NULL OR -- always return null site_key user_site_key = bs.site_key OR -- user interested in one site (user_site_key IS NULL AND -- return rows per access attr (disk_backups_shared = TRUE# OR tape_backups_shared = TRUE# OR this_site_key = bs.site_key))) UNION ALL -- -- SELECT backupSet_con_t type_con, bcf.bcf_key key_con, bcf.bcf_recid recid_con, bcf.bcf_stamp stamp_con, bs.set_stamp setStamp_con, bs.set_count setCount_con, bs.bs_recid bsRecid_con, bs.bs_stamp bsStamp_con, bs.bs_key bsKey_con, 0 bsLevel_con, bs.bck_type bsType_con, abs((bs.completion_time - bs.start_time) * 86400) elapseSecs_con, bs.pieces pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, to_number(null) blocks_con, bcf.block_size blockSize_con, to_char(null) deviceType_con, bs.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, multi_section multi_section_con, full_act_t type_act, 0 fromSCN_act, bcf.ckp_scn toSCN_act, bcf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, dbinc.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, 0 dfNumber_obj, 0 dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, nvl(bcf.controlfile_type, 'B') cfType_obj, bcf.pdb_key pdbKey_obj, bs.keep_options keep_options, bs.keep_until keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, bs.site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, 0 newDfCreationSCN_obj, bcf.ckp_scn newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM bcf, bs, dbinc, (SELECT bs_key, count(distinct piece#) pieces FROM bp WHERE rmanCmd = obsoleteCmd_t AND bp.db_key = this_db_key -- this database AND bp.status = 'A' AND (anyDevice = TRUE# OR isDeviceTypeAllocated(bp.device_type) = TRUE#) AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared =TRUE# AND bp.device_type ='DISK') OR (tape_backups_shared =TRUE# AND bp.device_type<>'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) GROUP BY bs_key, device_type) bp -- -- -- WHERE rmanCmd = obsoleteCmd_t -- -- -- AND bs.status = 'A' AND bs.bck_type != 'L' -- ignore archivelog backups AND (untilSCN IS NULL OR bcf.ckp_scn <= untilSCN) AND (restoreSource IS NULL OR bitand(restoreSource, backupSet_con_t) != 0) AND dbinc.dbinc_key = bcf.dbinc_key -- join dbinc, bcf AND bs.bs_key = bcf.bs_key -- join bs, bcf AND dbinc.db_key = this_db_key AND bs.bs_key = bp.bs_key -- join bp, bs AND bp.pieces = bs.pieces UNION ALL -- SELECT proxyCopy_con_t type_con, xdf.xdf_key key_con, xdf.xdf_recid recid_con, xdf.xdf_stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, xdf.handle fileName_con, xdf.tag tag_con, to_number(null) copyNumber_con, xdf.status status_con, xdf.blocks blocks_con, xdf.block_size blockSize_con, xdf.device_type deviceType_con, xdf.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, full_act_t type_act, 0 fromSCN_act, xdf.ckp_scn toSCN_act, xdf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, dbinc.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, xdf.file# dfNumber_obj, xdf.create_scn dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, xdf.pdb_key pdbKey_obj, keep_options keep_options, keep_until keep_until, xdf.abs_fuzzy_scn afzSCN_act, xdf.rcv_fuzzy_time rfzTime_act, xdf.rcv_fuzzy_scn rfzSCN_act, xdf.media media_con, 'NO' isrdf_con, site_key site_key_con, xdf.foreign_dbid foreignDbid_obj, decode(xdf.plugged_readonly, 'YES', 1, 0) pluggedRonly_obj, xdf.plugin_scn pluginSCN_obj, xdf.plugin_reset_scn pluginRlgSCN_obj, xdf.plugin_reset_time pluginRlgTime_obj, decode(xdf.plugin_scn, 0, xdf.create_scn, xdf.plugin_scn) newDfCreationSCN_obj, decode(xdf.plugged_readonly, 'NO', xdf.ckp_scn, xdf.plugin_scn) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM xdf, dbinc WHERE (tc_database = TRUE# OR isTranslatedFno(xdf.file#) = TRUE#) AND (untilSCN IS NULL OR (xdf.plugged_readonly = 'NO' AND greatest(xdf.ckp_scn, xdf.abs_fuzzy_scn, xdf.rcv_fuzzy_scn) <= untilSCN) OR (xdf.plugged_readonly = 'YES' AND xdf.plugin_scn <= untilSCN)) AND xdf.status = 'A' AND (restoreSource is NULL OR bitand(restoreSource, proxyCopy_con_t) != 0) AND dbinc.db_key = this_db_key AND xdf.dbinc_key = dbinc.dbinc_key AND rmanCmd NOT IN (recoverCmd_t, blkRestoreCmd_t) AND ((user_site_key = xdf.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xdf.site_key, this_site_key))))) UNION ALL -- SELECT proxyCopy_con_t type_con, xcf.xcf_key key_con, xcf.xcf_recid recid_con, xcf.xcf_stamp stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, xcf.handle fileName_con, xcf.tag tag_con, to_number(null) copyNumber_con, xcf.status status_con, to_number(null) blocks_con, xcf.block_size blockSize_con, xcf.device_type deviceType_con, xcf.completion_time compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, full_act_t type_act, 0 fromSCN_act, xcf.ckp_scn toSCN_act, xcf.ckp_time toTime_act, dbinc.reset_scn rlgSCN_act, dbinc.reset_time rlgTime_act, dbinc.dbinc_key dbincKey_act, to_number(null) level_act, 0 section_size_act, 0 dfNumber_obj, 0 dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, nvl(xcf.controlfile_type, 'B') cfType_obj, xcf.pdb_key pdbKey_obj, xcf.keep_options keep_options, xcf.keep_until keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, xcf.media media_con, 'NO' isrdf_con, site_key site_key_con, 0 foreignDbid_obj, 0 pluggedRonly_obj, 0 pluginSCN_obj, 0 pluginRlgSCN_obj, to_date(null) pluginRlgTime_obj, 0 newDfCreationSCN_obj, xcf.ckp_scn newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM xcf, dbinc WHERE (tc_database = TRUE# OR isTranslatedFno(0) = TRUE#) AND (untilSCN IS NULL OR xcf.ckp_scn <= untilSCN) AND xcf.status = 'A' AND (restoreSource is NULL OR bitand(restoreSource, proxyCopy_con_t) != 0) AND dbinc.db_key = this_db_key AND xcf.dbinc_key = dbinc.dbinc_key AND rmanCmd NOT IN (recoverCmd_t, blkRestoreCmd_t) AND ((user_site_key = xcf.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xcf.site_key, this_site_key))))) ORDER BY dfNumber_obj asc, newDfCreationSCN_obj asc, newToSCN_act desc, fromSCN_act asc, type_con asc, setStamp_con desc, /* better value, but may be null */ setCount_con desc, /* ensures uniqueness with ORS */ stamp_con desc; /* needed when setStamp is null */ /* ORS Preference: Latest backup is returned first. Since virtual copy ** has higher set_count, they go first in the restore list than file chunks. ** We really don't have the meta-data here to find out whether the piece ** exists on tape, replication or file chunk to sort it out. This ** requires another join with bp table which is expensive. */ -- CURSOR rcvRecCursor1Filter_c( dbincKey IN number ,fno IN number ,creSCN IN number ,dfCkpSCN IN number ,dbincRlgSCN IN number ,dbincRlgTime IN date ,offlSCN IN number ,onlSCN IN number ,onlTime IN date ,cleanSCN IN number ,clean2SCN IN number ,clean2Time IN date ,targetSCN IN number ,c1rec IN rcvRec_t ,foreignDbid IN number ,pluggedRonly IN binary_integer ,pluginSCN IN number ,pluginRlgSCN IN number ,pluginRlgTime IN date ,rmanCmd IN binary_integer) RETURN rcvRec_t IS -- SELECT c1rec.type_con type_con, c1rec.key_con key_con, c1rec.recid_con recid_con, c1rec.stamp_con stamp_con, c1rec.setStamp_con setStamp_con, c1rec.setCount_con setCount_con, c1rec.bsRecid_con bsRecid_con, c1rec.bsStamp_con bsStamp_con, c1rec.bsKey_con bsKey_con, c1rec.bsLevel_con bsLevel_con, c1rec.bsType_con bsType_con, c1rec.elapseSecs_con elapseSecs_con, c1rec.pieceCount_con pieceCount_con, c1rec.fileName_con fileName_con, c1rec.tag_con tag_con, c1rec.copyNumber_con copyNumber_con, c1rec.status_con status_con, c1rec.blocks_con blocks_con, c1rec.blockSize_con blockSize_con, c1rec.deviceType_con deviceType_con, c1rec.compTime_con compTime_con, c1rec.cfCreationTime_con cfCreationTime_con, c1rec.pieceNumber_con pieceNumber_con, c1rec.bpCompTime_con bpCompTime_con, c1rec.bpCompressed_con bpCompressed_con, c1rec.multi_section_con multi_section_con, c1rec.type_act type_act, c1rec.fromSCN_act fromSCN_act, c1rec.toSCN_act toSCN_act, c1rec.toTime_act toTime_act, c1rec.rlgSCN_act rlgSCN_act, c1rec.rlgTime_act rlgTime_act, c1rec.dbincKey_act dbincKey_act, c1rec.level_act level_act, c1rec.section_size_act section_size_act, c1rec.dfNumber_obj dfNumber_obj, c1rec.dfCreationSCN_obj dfCreationSCN_obj, c1rec.cfSequence_obj cfSequence_obj, c1rec.cfDate_obj cfDate_obj, c1rec.logSequence_obj logSequence_obj, c1rec.logThread_obj logThread_obj, c1rec.logRlgSCN_obj logRlgSCN_obj, c1rec.logRlgTime_obj logRlgTime_obj, c1rec.logLowSCN_obj logLowSCN_obj, c1rec.logLowTime_obj logLowTime_obj, c1rec.logNextSCN_obj logNextSCN_obj, c1rec.logNextTime_obj logNextTime_obj, c1rec.logTerminal_obj logTerminal_obj, c1rec.cfType_obj cfType_obj, c1rec.pdbKey_obj pdbKey_obj, c1rec.keep_options keep_options, c1rec.keep_until keep_until, c1rec.afzSCN_act afzSCN_act, c1rec.rfzTime_act rfzTime_act, c1rec.rfzSCN_act rfzSCN_act, c1rec.media_con media_con, c1rec.isrdf_con isrdf_con, c1rec.site_key_con site_key_con, c1rec.foreignDbid_obj foreignDbid_obj, c1rec.pluggedRonly_obj pluggedRonly_obj, c1rec.pluginSCN_obj pluginSCN_obj, c1rec.pluginRlgSCN_obj pluginRlgSCN_obj, c1rec.pluginRlgTime_obj pluginRlgTime_obj, c1rec.newDfCreationSCN_obj newDfCreationSCN_obj, c1rec.newToSCN_act newToSCN_act, c1rec.newRlgSCN_act newRlgSCN_act, c1rec.newRlgTime_act newRlgTime_act, c1rec.sfDbUniqueName_obj sfDbUniqueName_obj, c1rec.sparse_backup_con sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM dual WHERE c1rec.type_con = offlineRangeRec_con_t AND rcvRecCursor1Filter_c.pluggedRonly = 0 AND c1rec.dbincKey_act = rcvRecCursor1Filter_c.dbincKey AND (rcvRecCursor1Filter_c.dfCkpSCN is null OR rcvRecCursor1Filter_c.dfCkpSCN <= c1rec.fromSCN_act) AND (rcvRecCursor1Filter_c.targetSCN is null OR c1rec.toSCN_act <= rcvRecCursor1Filter_c.targetSCN) UNION ALL -- SELECT c1rec.type_con type_con, c1rec.key_con key_con, c1rec.recid_con recid_con, c1rec.stamp_con stamp_con, c1rec.setStamp_con setStamp_con, c1rec.setCount_con setCount_con, c1rec.bsRecid_con bsRecid_con, c1rec.bsStamp_con bsStamp_con, c1rec.bsKey_con bsKey_con, c1rec.bsLevel_con bsLevel_con, c1rec.bsType_con bsType_con, c1rec.elapseSecs_con elapseSecs_con, c1rec.pieceCount_con pieceCount_con, c1rec.fileName_con fileName_con, c1rec.tag_con tag_con, c1rec.copyNumber_con copyNumber_con, c1rec.status_con status_con, c1rec.blocks_con blocks_con, c1rec.blockSize_con blockSize_con, c1rec.deviceType_con deviceType_con, c1rec.compTime_con compTime_con, c1rec.cfCreationTime_con cfCreationTime_con, c1rec.pieceNumber_con pieceNumber_con, c1rec.bpCompTime_con bpCompTime_con, c1rec.bpCompressed_con bpCompressed_con, c1rec.multi_section_con multi_section_con, c1rec.type_act type_act, c1rec.fromSCN_act fromSCN_act, c1rec.toSCN_act toSCN_act, c1rec.toTime_act toTime_act, c1rec.rlgSCN_act rlgSCN_act, c1rec.rlgTime_act rlgTime_act, c1rec.dbincKey_act dbincKey_act, c1rec.level_act level_act, c1rec.section_size_act section_size_act, c1rec.dfNumber_obj dfNumber_obj, c1rec.dfCreationSCN_obj dfCreationSCN_obj, c1rec.cfSequence_obj cfSequence_obj, c1rec.cfDate_obj cfDate_obj, c1rec.logSequence_obj logSequence_obj, c1rec.logThread_obj logThread_obj, c1rec.logRlgSCN_obj logRlgSCN_obj, c1rec.logRlgTime_obj logRlgTime_obj, c1rec.logLowSCN_obj logLowSCN_obj, c1rec.logLowTime_obj logLowTime_obj, c1rec.logNextSCN_obj logNextSCN_obj, c1rec.logNextTime_obj logNextTime_obj, c1rec.logTerminal_obj logTerminal_obj, c1rec.cfType_obj cfType_obj, c1rec.pdbKey_obj pdbKey_obj, c1rec.keep_options keep_options, c1rec.keep_until keep_until, c1rec.afzSCN_act afzSCN_act, c1rec.rfzTime_act rfzTime_act, c1rec.rfzSCN_act rfzSCN_act, c1rec.media_con media_con, c1rec.isrdf_con isrdf_con, c1rec.site_key_con site_key_con, c1rec.foreignDbid_obj foreignDbid_obj, c1rec.pluggedRonly_obj pluggedRonly_obj, c1rec.pluginSCN_obj pluginSCN_obj, c1rec.pluginRlgSCN_obj pluginRlgSCN_obj, c1rec.pluginRlgTime_obj pluginRlgTime_obj, c1rec.newDfCreationSCN_obj newDfCreationSCN_obj, c1rec.newToSCN_act newToSCN_act, c1rec.newRlgSCN_act newRlgSCN_act, c1rec.newRlgTime_act newRlgTime_act, c1rec.sfDbUniqueName_obj sfDbUniqueName_obj, c1rec.sparse_backup_con sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM dual WHERE c1rec.type_con = imageCopy_con_t AND ((canApplyAnyRedo = TRUE# AND c1rec.dfNumber_obj <> 0) OR (craGetAllCfBackups = TRUE# AND c1rec.dfNumber_obj = 0) OR (c1rec.pluggedRonly_obj = 0 AND c1rec.dbincKey_act = rcvRecCursor1Filter_c.dbincKey) OR (c1rec.pluggedRonly_obj != 0 AND c1rec.pluginRlgSCN_obj = rcvRecCursor1Filter_c.dbincRlgSCN AND c1rec.pluginRlgTime_obj = rcvRecCursor1Filter_c.dbincRlgTime)) AND (rcvRecCursor1Filter_c.dfCkpSCN is null OR rmanCmd = blkRestoreCmd_t OR rcvRecCursor1Filter_c.dfCkpSCN <= c1rec.toSCN_act) AND (rcvRecCursor1Filter_c.targetSCN is null OR (c1rec.pluggedRonly_obj = 0 AND c1rec.toSCN_act <= rcvRecCursor1Filter_c.targetSCN) OR (c1rec.pluggedRonly_obj != 0 AND c1rec.pluginSCN_obj <= rcvRecCursor1Filter_c.targetSCN)) AND (restoreTag is NULL OR c1rec.tag_con = restoreTag OR computeRA_allRecords = TRUE#) AND ((c1rec.foreignDbid_obj = rcvRecCursor1Filter_c.foreignDbid) OR (c1rec.foreignDbid_obj = 0 AND c1rec.pluginSCN_obj = 0 AND rcvRecCursor1Filter_c.pluginSCN = 0)) -- -- -- UNION ALL -- SELECT c1rec.type_con type_con, c1rec.key_con key_con, c1rec.recid_con recid_con, c1rec.stamp_con stamp_con, c1rec.setStamp_con setStamp_con, c1rec.setCount_con setCount_con, c1rec.bsRecid_con bsRecid_con, c1rec.bsStamp_con bsStamp_con, c1rec.bsKey_con bsKey_con, c1rec.bsLevel_con bsLevel_con, c1rec.bsType_con bsType_con, c1rec.elapseSecs_con elapseSecs_con, c1rec.pieceCount_con pieceCount_con, c1rec.fileName_con fileName_con, c1rec.tag_con tag_con, c1rec.copyNumber_con copyNumber_con, c1rec.status_con status_con, c1rec.blocks_con blocks_con, c1rec.blockSize_con blockSize_con, c1rec.deviceType_con deviceType_con, c1rec.compTime_con compTime_con, c1rec.cfCreationTime_con cfCreationTime_con, c1rec.pieceNumber_con pieceNumber_con, c1rec.bpCompTime_con bpCompTime_con, c1rec.bpCompressed_con bpCompressed_con, c1rec.multi_section_con multi_section_con, c1rec.type_act type_act, c1rec.fromSCN_act fromSCN_act, c1rec.toSCN_act toSCN_act, c1rec.toTime_act toTime_act, c1rec.rlgSCN_act rlgSCN_act, c1rec.rlgTime_act rlgTime_act, c1rec.dbincKey_act dbincKey_act, c1rec.level_act level_act, c1rec.section_size_act section_size_act, c1rec.dfNumber_obj dfNumber_obj, c1rec.dfCreationSCN_obj dfCreationSCN_obj, c1rec.cfSequence_obj cfSequence_obj, c1rec.cfDate_obj cfDate_obj, c1rec.logSequence_obj logSequence_obj, c1rec.logThread_obj logThread_obj, c1rec.logRlgSCN_obj logRlgSCN_obj, c1rec.logRlgTime_obj logRlgTime_obj, c1rec.logLowSCN_obj logLowSCN_obj, c1rec.logLowTime_obj logLowTime_obj, c1rec.logNextSCN_obj logNextSCN_obj, c1rec.logNextTime_obj logNextTime_obj, c1rec.logTerminal_obj logTerminal_obj, c1rec.cfType_obj cfType_obj, c1rec.pdbKey_obj pdbKey_obj, c1rec.keep_options keep_options, c1rec.keep_until keep_until, c1rec.afzSCN_act afzSCN_act, c1rec.rfzTime_act rfzTime_act, c1rec.rfzSCN_act rfzSCN_act, c1rec.media_con media_con, c1rec.isrdf_con isrdf_con, c1rec.site_key_con site_key_con, c1rec.foreignDbid_obj foreignDbid_obj, c1rec.pluggedRonly_obj pluggedRonly_obj, c1rec.pluginSCN_obj pluginSCN_obj, c1rec.pluginRlgSCN_obj pluginRlgSCN_obj, c1rec.pluginRlgTime_obj pluginRlgTime_obj, c1rec.newDfCreationSCN_obj newDfCreationSCN_obj, c1rec.newToSCN_act newToSCN_act, c1rec.newRlgSCN_act newRlgSCN_act, c1rec.newRlgTime_act newRlgTime_act, c1rec.sfDbUniqueName_obj sfDbUniqueName_obj, c1rec.sparse_backup_con sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM dual WHERE c1rec.type_con = backupSet_con_t AND ((canApplyAnyRedo = TRUE# AND c1rec.dfNumber_obj <> 0) OR (craGetAllCfBackups = TRUE# AND c1rec.dfNumber_obj = 0) OR (c1rec.pluggedRonly_obj = 0 AND c1rec.dbincKey_act = rcvRecCursor1Filter_c.dbincKey) OR (c1rec.pluggedRonly_obj != 0 AND c1rec.pluginRlgSCN_obj = rcvRecCursor1Filter_c.dbincRlgSCN AND c1rec.pluginRlgTime_obj = rcvRecCursor1Filter_c.dbincRlgTime)) AND (rcvRecCursor1Filter_c.dfCkpSCN IS NULL OR rmanCmd = blkRestoreCmd_t OR rcvRecCursor1Filter_c.dfCkpSCN < c1rec.toSCN_act) AND (rcvRecCursor1Filter_c.targetSCN IS NULL OR (c1rec.pluggedRonly_obj = 0 AND c1rec.toSCN_act <= rcvRecCursor1Filter_c.targetSCN) OR (c1rec.pluggedRonly_obj != 0 AND c1rec.pluginSCN_obj <= rcvRecCursor1Filter_c.targetSCN)) AND ((c1rec.foreignDbid_obj = rcvRecCursor1Filter_c.foreignDbid) OR (c1rec.foreignDbid_obj = 0 AND c1rec.pluginSCN_obj = 0 AND rcvRecCursor1Filter_c.pluginSCN = 0)) -- -- -- UNION ALL -- SELECT c1rec.type_con type_con, c1rec.key_con key_con, c1rec.recid_con recid_con, c1rec.stamp_con stamp_con, c1rec.setStamp_con setStamp_con, c1rec.setCount_con setCount_con, c1rec.bsRecid_con bsRecid_con, c1rec.bsStamp_con bsStamp_con, c1rec.bsKey_con bsKey_con, c1rec.bsLevel_con bsLevel_con, c1rec.bsType_con bsType_con, c1rec.elapseSecs_con elapseSecs_con, c1rec.pieceCount_con pieceCount_con, c1rec.fileName_con fileName_con, c1rec.tag_con tag_con, c1rec.copyNumber_con copyNumber_con, c1rec.status_con status_con, c1rec.blocks_con blocks_con, c1rec.blockSize_con blockSize_con, c1rec.deviceType_con deviceType_con, c1rec.compTime_con compTime_con, c1rec.cfCreationTime_con cfCreationTime_con, c1rec.pieceNumber_con pieceNumber_con, c1rec.bpCompTime_con bpCompTime_con, c1rec.bpCompressed_con bpCompressed_con, c1rec.multi_section_con multi_section_con, c1rec.type_act type_act, c1rec.fromSCN_act fromSCN_act, c1rec.toSCN_act toSCN_act, c1rec.toTime_act toTime_act, c1rec.rlgSCN_act rlgSCN_act, c1rec.rlgTime_act rlgTime_act, c1rec.dbincKey_act dbincKey_act, c1rec.level_act level_act, c1rec.section_size_act section_size_act, c1rec.dfNumber_obj dfNumber_obj, c1rec.dfCreationSCN_obj dfCreationSCN_obj, c1rec.cfSequence_obj cfSequence_obj, c1rec.cfDate_obj cfDate_obj, c1rec.logSequence_obj logSequence_obj, c1rec.logThread_obj logThread_obj, c1rec.logRlgSCN_obj logRlgSCN_obj, c1rec.logRlgTime_obj logRlgTime_obj, c1rec.logLowSCN_obj logLowSCN_obj, c1rec.logLowTime_obj logLowTime_obj, c1rec.logNextSCN_obj logNextSCN_obj, c1rec.logNextTime_obj logNextTime_obj, c1rec.logTerminal_obj logTerminal_obj, c1rec.cfType_obj cfType_obj, c1rec.pdbKey_obj pdbKey_obj, c1rec.keep_options keep_options, c1rec.keep_until keep_until, c1rec.afzSCN_act afzSCN_act, c1rec.rfzTime_act rfzTime_act, c1rec.rfzSCN_act rfzSCN_act, c1rec.media_con media_con, c1rec.isrdf_con isrdf_con, c1rec.site_key_con site_key_con, c1rec.foreignDbid_obj foreignDbid_obj, c1rec.pluggedRonly_obj pluggedRonly_obj, c1rec.pluginSCN_obj pluginSCN_obj, c1rec.pluginRlgSCN_obj pluginRlgSCN_obj, c1rec.pluginRlgTime_obj pluginRlgTime_obj, c1rec.newDfCreationSCN_obj newDfCreationSCN_obj, c1rec.newToSCN_act newToSCN_act, c1rec.newRlgSCN_act newRlgSCN_act, c1rec.newRlgTime_act newRlgTime_act, c1rec.sfDbUniqueName_obj sfDbUniqueName_obj, c1rec.sparse_backup_con sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM dual WHERE c1rec.type_con = proxyCopy_con_t AND rmanCmd != blkRestoreCmd_t AND ((canApplyAnyRedo = TRUE# AND c1rec.dfNumber_obj <> 0) OR (craGetAllCfBackups = TRUE# AND c1rec.dfNumber_obj = 0) OR (c1rec.pluggedRonly_obj = 0 AND c1rec.dbincKey_act = rcvRecCursor1Filter_c.dbincKey) OR (c1rec.pluggedRonly_obj != 0 AND c1rec.pluginRlgSCN_obj = rcvRecCursor1Filter_c.dbincRlgSCN AND c1rec.pluginRlgTime_obj = rcvRecCursor1Filter_c.dbincRlgTime)) AND (rcvRecCursor1Filter_c.dfCkpSCN IS NULL OR rcvRecCursor1Filter_c.dfCkpSCN < c1rec.toSCN_act) AND (rcvRecCursor1Filter_c.targetSCN IS NULL OR (c1rec.pluggedRonly_obj = 0 AND c1rec.toSCN_act <= rcvRecCursor1Filter_c.targetSCN) OR (c1rec.pluggedRonly_obj != 0 AND c1rec.pluginSCN_obj <= rcvRecCursor1Filter_c.targetSCN)) AND (restoreTag is NULL OR c1rec.tag_con = restoreTag OR computeRA_allRecords = TRUE#) AND ((c1rec.foreignDbid_obj = rcvRecCursor1Filter_c.foreignDbid) OR (c1rec.foreignDbid_obj = 0 AND c1rec.pluginSCN_obj = 0 AND rcvRecCursor1Filter_c.pluginSCN = 0)); -- -- -- CURSOR rcvRecCursor2_c( dbincKey IN number ,fno IN number ,creSCN IN number ,dfCkpSCN IN number ,dbincRlgSCN IN number ,dbincRlgTime IN date ,offlSCN IN number ,onlSCN IN number ,onlTime IN date ,cleanSCN IN number ,clean2SCN IN number ,clean2Time IN date ,targetSCN IN number ,c1frec IN rcvRec_t ,excludeAction IN binary_integer ,foreignDbid IN number ,pluggedRonly IN binary_integer ,pluginSCN IN number ,pluginRlgSCN IN number ,pluginRlgTime IN date) RETURN rcvRec_t IS -- SELECT c1frec.type_con type_con, c1frec.key_con key_con, c1frec.recid_con recid_con, c1frec.stamp_con stamp_con, c1frec.setStamp_con setStamp_con, c1frec.setCount_con setCount_con, c1frec.bsRecid_con bsRecid_con, c1frec.bsStamp_con bsStamp_con, c1frec.bsKey_con bsKey_con, c1frec.bsLevel_con bsLevel_con, c1frec.bsType_con bsType_con, c1frec.elapseSecs_con elapseSecs_con, c1frec.pieceCount_con pieceCount_con, c1frec.fileName_con fileName_con, c1frec.tag_con tag_con, c1frec.copyNumber_con copyNumber_con, c1frec.status_con status_con, c1frec.blocks_con blocks_con, c1frec.blockSize_con blockSize_con, c1frec.deviceType_con deviceType_con, c1frec.compTime_con compTime_con, c1frec.cfCreationTime_con cfCreationTime_con, c1frec.pieceNumber_con pieceNumber_con, c1frec.bpCompTime_con bpCompTime_con, c1frec.bpCompressed_con bpCompressed_con, c1frec.multi_section_con multi_section_con, c1frec.type_act type_act, c1frec.fromSCN_act fromSCN_act, c1frec.toSCN_act toSCN_act, c1frec.toTime_act toTime_act, c1frec.rlgSCN_act rlgSCN_act, c1frec.rlgTime_act rlgTime_act, c1frec.dbincKey_act dbincKey_act, c1frec.level_act level_act, c1frec.section_size_act section_size_act, c1frec.dfNumber_obj dfNumber_obj, c1frec.dfCreationSCN_obj dfCreationSCN_obj, c1frec.cfSequence_obj cfSequence_obj, c1frec.cfDate_obj cfDate_obj, c1frec.logSequence_obj logSequence_obj, c1frec.logThread_obj logThread_obj, c1frec.logRlgSCN_obj logRlgSCN_obj, c1frec.logRlgTime_obj logRlgTime_obj, c1frec.logLowSCN_obj logLowSCN_obj, c1frec.logLowTime_obj logLowTime_obj, c1frec.logNextSCN_obj logNextSCN_obj, c1frec.logNextTime_obj logNextTime_obj, c1frec.logTerminal_obj logTerminal_obj, c1frec.cfType_obj cfType_obj, c1frec.pdbKey_obj pdbKey_obj, c1frec.keep_options keep_options, c1frec.keep_until keep_until, c1frec.afzSCN_act afzSCN_act, c1frec.rfzTime_act rfzTime_act, c1frec.rfzSCN_act rfzSCN_act, c1frec.media_con media_con, c1frec.isrdf_con isrdf_con, c1frec.site_key_con site_key_con, c1frec.foreignDbid_obj foreignDbid_obj, c1frec.pluggedRonly_obj pluggedRonly_obj, c1frec.pluginSCN_obj pluginSCN_obj, c1frec.pluginRlgSCN_obj pluginRlgSCN_obj, c1frec.pluginRlgTime_obj pluginRlgTime_obj, c1frec.newDfCreationSCN_obj newDfCreationSCN_obj, c1frec.newToSCN_act newToSCN_act, c1frec.newRlgSCN_act newRlgSCN_act, c1frec.newRlgTime_act newRlgTime_act, c1frec.sfDbUniqueName_obj sfDbUniqueName_obj, c1frec.sparse_backup_con sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM dual WHERE c1frec.type_con is not null UNION ALL -- -- SELECT offlineRangeRec_con_t type_con, to_number(null) key_con, to_number(null) recid_con, to_number(null) stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, to_number(null) blocks_con, to_number(null) blockSize_con, to_char(null) deviceType_con, to_date(null) compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, implicitRange_act_t type_act, rcvRecCursor2_c.offlSCN fromSCN_act, rcvRecCursor2_c.onlSCN toSCN_act, rcvRecCursor2_c.onlTime toTime_act, rcvRecCursor2_c.dbincRlgSCN rlgSCN_act, rcvRecCursor2_c.dbincRlgTime rlgTime_act, rcvRecCursor2_c.dbincKey dbincKey_act, to_number(null) level_act, 0 section_size_act, fno dfNumber_obj, crescn dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, to_number(null) pdbKey_obj, to_number(null) keep_options, to_date(null) keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, 0 site_key_con, rcvRecCursor2_c.foreignDbid foreignDbid_obj, rcvRecCursor2_c.pluggedRonly pluggedRonly_obj, rcvRecCursor2_c.pluginSCN pluginSCN_obj, rcvRecCursor2_c.pluginRlgSCN pluginRlgSCN_obj, rcvRecCursor2_c.pluginRlgTime pluginRlgTime_obj, crescn newDfCreationSCN_obj, rcvRecCursor2_c.onlSCN newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM dual WHERE bitand(rcvRecCursor2_c.excludeAction,implicitRange_act_t) = 0 AND rcvRecCursor2_c.pluggedRonly = 0 AND offlSCN <> 0 AND (rcvRecCursor2_c.dfCkpSCN is null OR rcvRecCursor2_c.dfCkpSCN <= rcvRecCursor2_c.offlSCN) AND (rcvRecCursor2_c.onlSCN >= -- belongs to this incarnation rcvRecCursor2_c.dbincRlgSCN) AND (rcvRecCursor2_c.targetSCN is null OR rcvRecCursor2_c.onlscn <= -- don't advance ckpt beyond rcvRecCursor2_c.targetSCN) -- targetSCN AND (untilSCN is null OR -- don't advance ckpt beyond until scn rcvRecCursor2_c.onlSCN < untilSCN) UNION ALL SELECT offlineRangeRec_con_t type_con, to_number(null) key_con, to_number(null) recid_con, to_number(null) stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, to_number(null) blocks_con, to_number(null) blockSize_con, to_char(null) deviceType_con, to_date(null) compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, cleanRange_act_t type_act, rcvRecCursor2_c.cleanSCN fromSCN_act, rcvRecCursor2_c.clean2SCN toSCN_act, rcvRecCursor2_c.clean2Time toTime_act, rcvRecCursor2_c.dbincRlgSCN rlgSCN_act, rcvRecCursor2_c.dbincRlgTime rlgTime_act, rcvRecCursor2_c.dbincKey dbincKey_act, to_number(null) level_act, 0 section_size_act, fno dfNumber_obj, crescn dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, to_number(null) pdbKey_obj, to_number(null) keep_options, to_date(null) keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, 0 site_key_con, rcvRecCursor2_c.foreignDbid foreignDbid_obj, rcvRecCursor2_c.pluggedRonly pluggedRonly_obj, rcvRecCursor2_c.pluginSCN pluginSCN_obj, rcvRecCursor2_c.pluginRlgSCN pluginRlgSCN_obj, rcvRecCursor2_c.pluginRlgTime pluginRlgTime_obj, crescn newDfCreationSCN_obj, rcvRecCursor2_c.clean2SCN newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM dual WHERE bitand(rcvRecCursor2_c.excludeAction, cleanRange_act_t) = 0 AND rcvRecCursor2_c.pluggedRonly = 0 AND rcvRecCursor2_c.cleanscn <> 0 AND (rcvRecCursor2_c.dfCkpSCN is null OR rcvRecCursor2_c.dfCkpSCN <= rcvRecCursor2_c.cleanscn) AND -- belongs to this incarnation (rcvRecCursor2_c.clean2scn >= rcvRecCursor2_c.dbincRlgSCN) AND -- ignore if starts beyond target (rcvRecCursor2_c.targetscn is null OR rcvRecCursor2_c.cleanscn < rcvRecCursor2_c.targetSCN) AND -- If clean2scn is infinite, then we processed this when scanning -- (rcvRecCursor2_c.targetSCN is null OR rcvRecCursor2_c.clean2SCN <= rcvRecCursor2_c.targetSCN) AND -- don't advance ckpt beyond until scn, unless we don't know -- (untilscn is null OR rcvRecCursor2_c.clean2SCN <= untilSCN OR rcvRecCursor2_c.clean2SCN = highscnval) UNION ALL SELECT offlineRangeRec_con_t type_con, to_number(null) key_con, to_number(null) recid_con, to_number(null) stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, to_number(null) blocks_con, to_number(null) blockSize_con, to_char(null) deviceType_con, to_date(null) compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, cleanRange_act_t type_act, rcvRecCursor2_c.pluginSCN fromSCN_act, rcvRecCursor2_c.clean2SCN toSCN_act, rcvRecCursor2_c.clean2Time toTime_act, rcvRecCursor2_c.dbincRlgSCN rlgSCN_act, rcvRecCursor2_c.dbincRlgTime rlgTime_act, rcvRecCursor2_c.dbincKey dbincKey_act, to_number(null) level_act, 0 section_size_act, fno dfNumber_obj, crescn dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, to_number(null) pdbKey_obj, to_number(null) keep_options, to_date(null) keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, 0 site_key_con, rcvRecCursor2_c.foreignDbid foreignDbid_obj, rcvRecCursor2_c.pluggedRonly pluggedRonly_obj, rcvRecCursor2_c.pluginSCN pluginSCN_obj, rcvRecCursor2_c.pluginRlgSCN pluginRlgSCN_obj, rcvRecCursor2_c.pluginRlgTime pluginRlgTime_obj, crescn newDfCreationSCN_obj, rcvRecCursor2_c.clean2SCN newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM dual WHERE bitand(rcvRecCursor2_c.excludeAction, cleanRange_act_t) = 0 AND rcvRecCursor2_c.pluggedRonly = 1 AND rcvRecCursor2_c.cleanscn <> 0 AND rcvRecCursor2_c.cleanscn <= rcvRecCursor2_c.pluginSCN AND (rcvRecCursor2_c.dfCkpSCN is null OR rcvRecCursor2_c.dfCkpSCN <= rcvRecCursor2_c.pluginSCN) AND -- belongs to this incarnation (rcvRecCursor2_c.clean2scn >= rcvRecCursor2_c.dbincRlgSCN) AND -- ignore if starts beyond target (rcvRecCursor2_c.targetscn is null OR rcvRecCursor2_c.pluginSCN < rcvRecCursor2_c.targetSCN) AND -- If clean2scn is infinite, then we processed this when scanning -- (rcvRecCursor2_c.targetSCN is null OR rcvRecCursor2_c.clean2SCN <= rcvRecCursor2_c.targetSCN) AND -- don't advance ckpt beyond until scn, unless we don't know -- (untilscn is null OR rcvRecCursor2_c.clean2SCN <= untilSCN OR rcvRecCursor2_c.clean2SCN = highscnval) UNION ALL SELECT offlineRangeRec_con_t type_con, to_number(null) key_con, to_number(null) recid_con, to_number(null) stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, to_number(null) blocks_con, to_number(null) blockSize_con, to_char(null) deviceType_con, to_date(null) compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, cleanRange_act_t type_act, rcvRecCursor2_c.pluginSCN fromSCN_act, rcvRecCursor2_c.crescn toSCN_act, to_date(null) toTime_act, rcvRecCursor2_c.dbincRlgSCN rlgSCN_act, rcvRecCursor2_c.dbincRlgTime rlgTime_act, rcvRecCursor2_c.dbincKey dbincKey_act, to_number(null) level_act, 0 section_size_act, fno dfNumber_obj, crescn dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, to_number(null) pdbKey_obj, to_number(null) keep_options, to_date(null) keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, 0 site_key_con, rcvRecCursor2_c.foreignDbid foreignDbid_obj, rcvRecCursor2_c.pluggedRonly pluggedRonly_obj, rcvRecCursor2_c.pluginSCN pluginSCN_obj, rcvRecCursor2_c.pluginRlgSCN pluginRlgSCN_obj, rcvRecCursor2_c.pluginRlgTime pluginRlgTime_obj, crescn newDfCreationSCN_obj, crescn newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM dual WHERE bitand(rcvRecCursor2_c.excludeAction, cleanRange_act_t) = 0 AND rcvRecCursor2_c.pluggedRonly = 0 AND rcvRecCursor2_c.pluginSCN <> 0 AND (rcvRecCursor2_c.dfCkpSCN is null OR rcvRecCursor2_c.dfCkpSCN <= rcvRecCursor2_c.pluginSCN) AND -- belongs to this incarnation (crescn >= rcvRecCursor2_c.dbincRlgSCN) AND (rcvRecCursor2_c.targetSCN is null OR crescn <= -- don't advance ckpt beyond rcvRecCursor2_c.targetSCN) -- targetSCN AND -- don't advance ckpt beyond until scn, unless we don't know -- (untilscn is null OR crescn < untilSCN) UNION ALL SELECT offlineRangeRec_con_t type_con, to_number(null) key_con, to_number(null) recid_con, to_number(null) stamp_con, to_number(null) setStamp_con, to_number(null) setCount_con, to_number(null) bsRecid_con, to_number(null) bsStamp_con, to_number(null) bsKey_con, to_number(null) bsLevel_con, to_char(null) bsType_con, to_number(null) elapseSecs_con, to_number(null) pieceCount_con, to_char(null) fileName_con, to_char(null) tag_con, to_number(null) copyNumber_con, to_char(null) status_con, to_number(null) blocks_con, to_number(null) blockSize_con, to_char(null) deviceType_con, to_date(null) compTime_con, to_date(null) cfCreationTime_con, to_number(null) pieceNumber_con, to_date(null) bpCompTime_con, to_char(null) bpCompressed_con, to_char(null) multi_section_con, spanningRange_act_t type_act, rcvRecCursor2_c.targetSCN fromSCN_act, to_number(null) toSCN_act, to_date(null) toTime_act, rcvRecCursor2_c.dbincRlgSCN rlgSCN_act, rcvRecCursor2_c.dbincRlgTime rlgTime_act, rcvRecCursor2_c.dbincKey dbincKey_act, to_number(null) level_act, 0 section_size_act, fno dfNumber_obj, crescn dfCreationSCN_obj, to_number(null) cfSequence_obj, to_date(null) cfDate_obj, to_number(null) logSequence_obj, to_number(null) logThread_obj, to_number(null) logRlgSCN_obj, to_date(null) logRlgTime_obj, to_number(null) logLowSCN_obj, to_date(null) logLowTime_obj, to_number(null) logNextSCN_obj, to_date(null) logNextTime_obj, to_char(null) logTerminal_obj, to_char(null) cfType_obj, to_number(null) pdbKey_obj, to_number(null) keep_options, to_date(null) keep_until, to_number(null) afzSCN_act, to_date(null) rfzTime_act, to_number(null) rfzSCN_act, to_char(null) media_con, 'NO' isrdf_con, 0 site_key_con, rcvRecCursor2_c.foreignDbid foreignDbid_obj, rcvRecCursor2_c.pluggedRonly pluggedRonly_obj, rcvRecCursor2_c.pluginSCN pluginSCN_obj, rcvRecCursor2_c.pluginRlgSCN pluginRlgSCN_obj, rcvRecCursor2_c.pluginRlgTime pluginRlgTime_obj, crescn newDfCreationSCN_obj, to_number(null) newToSCN_act, to_number(null) newRlgSCN_act, to_date(null) newRlgTime_act, to_char(null) sfDbUniqueName_obj, to_char(null) sparse_backup_con, 0 ppl_pdb_id_con, 0 ppl_cdb_dbid_con FROM dual WHERE bitand(rcvRecCursor2_c.excludeAction, spanningRange_act_t) = 0 -- -- AND rcvRecCursor2_c.pluggedRonly = 0 AND rcvRecCursor2_c.targetSCN < rcvRecCursor2_c.dbincRlgSCN ORDER BY newToSCN_act desc, fromSCN_act desc, type_con asc, stamp_con desc; -- -- -- CURSOR sinceLastBackedAL_c (devtype IN VARCHAR2, numofbackups IN NUMBER) IS SELECT * FROM ( SELECT low_scn, next_scn, next_time, count(*) over (partition by sequence#, thread#, dbinc_key) nbackups FROM ( SELECT sequence#, thread#, low_scn, next_scn, next_time, dbinc_key FROM brl, (SELECT UNIQUE bs.bs_key, copy#, pieces, count(piece#) over (partition by bs.bs_key, copy#) pieces_count, device_type, bs.completion_time FROM bs, bp WHERE bs.db_key = this_db_key AND bp.status = 'A' AND bs.bck_type = 'L' AND bs.bs_key = bp.bs_key AND (devtype IS NULL OR devtype = device_type) AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared=TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared=TRUE# AND bp.device_type <>'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) ) allbs WHERE brl.bs_key = allbs.bs_key AND allbs.pieces_count = allbs.pieces UNION ALL SELECT sequence#, thread#, first_change#, next_change#, next_time, dbinc_key FROM rc_proxy_archivedlog WHERE db_key = this_db_key AND status = 'A' AND (devtype IS NULL OR devtype = device_type) ) ) WHERE nbackups >= numofbackups ORDER BY next_time DESC; -- CURSOR restore_point_c (con_id IN NUMBER, name IN VARCHAR2) IS SELECT r.name, r.dbinc_key dbinc#, scn, creation_time, restore_point_time, guarantee_flashback_database guaranteed, preserved, d.reset_scn, d.reset_time, pdb.con_id con_id, r.clean clean FROM rc_restore_point r, dbinc d, pdb, pdb_dbinc WHERE d.dbinc_key = r.dbinc_key AND site_key = nvl(user_site_key, this_site_key) AND (r.name = restore_point_c.name OR restore_point_c.name is null) AND pdb.db_key = this_db_key AND r.pdb_key = pdb.pdb_key AND pdb_dbinc.pdb_key = pdb.pdb_key AND pdb_dbinc.drop_scn IS NULL AND pdb_dbinc.dbinc_key = this_dbinc_key ORDER BY decode(pdb.con_id, restore_point_c.con_id, -1, pdb.con_id), scn, creation_time; -- CURSOR translatePdbName_c IS SELECT con_id, name FROM rci_pdbinc_this_dbinc pdbinc WHERE pdbinc.dbinc_key = this_dbinc_key AND (untilSCN IS NULL OR pdbinc.create_scn < untilSCN) AND (pdbinc.drop_scn IS NULL OR pdbinc.drop_scn > untilSCN) AND con_id > 1 ORDER BY pdbinc.drop_scn desc; -- CURSOR translatePdbFile_c(fromSCN IN number, toSCN IN number) IS SELECT con_id, file#, stop_change# stopSCN FROM rci_datafile_this_dbinc rcd WHERE rcd.dbinc_key = this_dbinc_key AND decode(plugin_change#, 0, creation_change#, plugin_change#) <= toSCN AND (drop_change# is null OR drop_change# > fromSCN) AND (nvl(realf_site_key, translation_site_key) = site_key); CURSOR translateNoBackupPdb_c(pdbname IN varchar2) IS SELECT decode(pdbinc.nobackup, 'Y', 1, 0) noBackupPdb FROM rci_pdbinc_this_dbinc pdbinc WHERE pdbinc.dbinc_key = this_dbinc_key AND pdbinc.name = translateNoBackupPdb_c.pdbname AND (untilSCN IS NULL OR pdbinc.create_scn < untilSCN) AND (pdbinc.drop_scn IS NULL OR pdbinc.drop_scn > untilSCN); -- PROCEDURE debout( line IN varchar2 ) IS isrs number; BEGIN -- -- IF rsdebug IS NULL THEN SELECT COUNT(*) INTO isrs FROM user_tables WHERE table_name = 'BLOCKS'; rsdebug := isrs > 0; END IF; -- IF rsdebug THEN EXECUTE IMMEDIATE 'BEGIN sys.kbrsi_icd.rsTrace(:1); END;' USING line; ELSE dbms_output.put_line(line); END IF; EXCEPTION WHEN others THEN dbms_output.put_line(line); END debout; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE deb( type IN number ,line IN varchar2 DEFAULT NULL ) IS pname varchar2(512); pref varchar2(11) := 'DBGRCVMAN: '; dstr varchar2(1000); BEGIN IF (not debug) THEN RETURN; END IF; IF type = DEB_ENTER THEN pname := line; dstr := (pref||rpad(' ',pname_i)||'ENTERING '||pname); pname_i := pname_i + 1; last_pnames(pname_i) := pname; ELSIF type = DEB_IN THEN dstr := (pref||rpad(' ',pname_i+2)||last_pnames(pname_i)|| ' '||line); ELSIF type = DEB_EXIT THEN IF (pname_i >= 1) THEN pname := last_pnames(pname_i); pname_i := pname_i - 1; ELSE pname := DEB_DEF_PNAME; END IF; IF line is not NULL THEN dstr := (pref||rpad(' ', pname_i)||'EXITING '||pname|| ' '||line); ELSE dstr := (pref||rpad(' ', pname_i)||'EXITING '||pname); END IF; ELSIF type = DEB_OPEN THEN pname := last_pnames(pname_i); dstr := (pref||rpad(' ', pname_i)||'OPENING cursor '|| line||' in '||pname); ELSE dstr := (pref||line); END IF; debout(dstr); EXCEPTION WHEN others THEN debout('caught exception during deb ' || substr(sqlerrm, 1, 512)); END; FUNCTION bool2char( flag IN boolean) RETURN varchar2 IS BEGIN IF (flag) THEN RETURN 'TRUE'; ELSE RETURN 'FALSE'; END IF; END bool2char; -- -- -- -- PROCEDURE setAlTransClause( thread IN NUMBER DEFAULT NULL ,fromTime IN DATE DEFAULT NULL ,toTime IN DATE DEFAULT NULL ,fromSCN IN NUMBER DEFAULT NULL ,toSCN IN NUMBER DEFAULT NULL ,fromSeq IN NUMBER DEFAULT NULL ,toSeq IN NUMBER DEFAULT NULL ,pattern IN VARCHAR2 DEFAULT NULL) IS BEGIN tc_thread := thread; tc_fromTime := fromTime; tc_toTime := toTime; tc_fromSCN := fromSCN; tc_toSCN := toSCN; tc_fromSeq := fromSeq; tc_toSeq := toSeq; tc_pattern := pattern; deb(DEB_PRINT, 'tc_thread=' || tc_thread); deb(DEB_PRINT, 'tc_fromSCN=' || fromSCN); deb(DEB_PRINT, 'tc_toSCN=' || toSCN); deb(DEB_PRINT, 'tc_fromSeq=' || fromSeq); deb(DEB_PRINT, 'tc_fromTime=' || fromTime); deb(DEB_PRINT, 'tc_toTime=' || toTime); deb(DEB_PRINT, 'tc_toSeq=' || toSeq); deb(DEB_PRINT, 'tc_pattern=' || pattern); END setAlTransClause; -- PROCEDURE setDfTransClause( fno IN NUMBER) IS BEGIN tc_fno(fno) := TRUE; END setDfTransClause; -- PROCEDURE setDBTransClause IS BEGIN deb(DEB_PRINT, 'tc_database=TRUE'); tc_database := TRUE#; END setDBTransClause; -- PROCEDURE resetAlTransClause IS BEGIN tc_thread := to_number(null); tc_fromTime := to_date(null); tc_toTime := to_date(null); tc_fromSCN := to_number(null); tc_toSCN := to_number(null); tc_fromSeq := to_number(null); tc_toSeq := to_number(null); tc_pattern := to_char(null); currInc := -1; getArchivedLogDoingRecovery := FALSE#; -- clear for next time getArchivedLogOnlyrdf := 0; tc_threadSeq.delete; END resetAlTransClause; -- PROCEDURE resetDBTransClause IS BEGIN tc_database := FALSE#; tc_fno.delete; END resetDBTransClause; -- PROCEDURE resetDbidTransClause IS BEGIN tc_anydbid := FALSE#; tc_dbid.delete; END resetDBidTransClause; -- -- -- -- -- FUNCTION skipTableSpace( tsName IN varchar2 ,pdbId IN number) RETURN boolean IS BEGIN deb(DEB_ENTER, 'skipTableSpace'); FOR i in 1..skipTablespaceList.count LOOP IF (tsName = skipTablespaceList(i).name AND pdbId = skipTablespaceList(i).pdbId) THEN deb(DEB_EXIT, 'with: TRUE'); RETURN TRUE; END IF; END LOOP; deb(DEB_EXIT, 'with: FALSE'); RETURN FALSE; END; -- FUNCTION isDeviceTypeAllocated( deviceType IN varchar2) RETURN NUMBER IS BEGIN IF (anyDevice = TRUE#) THEN RETURN TRUE#; END IF; FOR i IN 1..deviceCount LOOP IF deviceType = deviceList(i) THEN RETURN TRUE#; END IF; END LOOP; RETURN FALSE#; END isDeviceTypeAllocated; -- -- -- -- -- -- -- FUNCTION computeAvailableMask( available IN number ,unavailable IN number ,deleted IN number ,expired IN number ,partial_avail IN number DEFAULT 0) RETURN binary_integer IS rc binary_integer := 0; BEGIN deb(DEB_ENTER, 'computeAvailableMask'); IF (available > 0) THEN rc := rc + dbms_rcvman.BSavailable; END IF; IF (unavailable > 0 ) THEN rc := rc + dbms_rcvman.BSunavailable; END IF; IF (deleted > 0 ) THEN rc := rc + dbms_rcvman.BSdeleted; END IF; IF (expired > 0 ) THEN rc := rc + dbms_rcvman.BSexpired; END IF; IF (partial_avail > 0 ) THEN rc := rc + dbms_rcvman.BSpartial_avail; END IF; deb(DEB_EXIT, 'with rc:'||to_char(rc)); RETURN rc; END computeAvailableMask; -- FUNCTION validateBackupSet0( tag IN varchar2 DEFAULT NULL ,tagMatchRequired IN boolean DEFAULT TRUE ,checkDeviceIsAllocated IN boolean DEFAULT TRUE ,validRec OUT NOCOPY validBackupSetRec_t) RETURN binary_integer IS local validBackupSetRec_t; rc binary_integer; gotRecord number; BEGIN deb(DEB_ENTER, 'validateBackupSet0'); <> LOOP <> gotRecord := getValidBackupSet(validBackupSetRec => local, checkDeviceIsAllocated => FALSE#); EXIT WHEN gotRecord = FALSE#; -- cursor is closed already IF (checkDeviceIsAllocated) THEN IF (anyDevice = FALSE# AND isDeviceTypeAllocated(local.deviceType) = FALSE#) THEN deb(DEB_IN, 'device is not allocated'); -- -- IF (rc IS NULL OR rc <> SUCCESS) THEN deb(DEB_IN, 'set rc to available'); rc := dbms_rcvman.AVAILABLE; END IF; GOTO nextRow; END IF; END IF; validRec := local; -- set OUT mode arg IF (tag IS NOT NULL AND NOT tagMatchRequired) THEN -- -- -- -- IF (tag = local.tag) THEN -- -- -- -- -- -- -- deb(DEB_IN, 'tag matches'); rc := SUCCESS; deb(DEB_IN, 'exiting loop with rc: SUCCESS'); EXIT validationLoop; ELSE -- -- -- deb(DEB_IN, 'tag does not match, continuing search'); rc := SUCCESS; END IF; ELSE -- -- -- rc := SUCCESS; deb(DEB_IN, 'exiting loop with rc: SUCCESS'); EXIT validationLoop; END IF; END LOOP; IF (rc IS NULL) THEN deb(DEB_IN, 'rc is null, setting to unavailable'); rc := dbms_rcvman.UNAVAILABLE; END IF; deb(DEB_EXIT, 'with rc:'||to_char(rc)); RETURN rc; END validateBackupSet0; -- -- -- -- FUNCTION getRecStackCount RETURN binary_integer IS BEGIN RETURN rcvRecStack.count; END getRecStackCount; -- FUNCTION getRecFullCount RETURN binary_integer IS BEGIN RETURN rcvRecStackState.fullBackups; END getRecFullCount; -- PROCEDURE rcvRecPush( rcvRec IN rcvRec_t) IS BEGIN rcvRecStack.extend; deb(DEB_PRINT,'rcvRecPush:from_scn='||rcvRec.fromSCN_act||',to_scn='||rcvRec.toSCN_act||',rcvRecStackCount='||rcvRecStack.count); rcvRecStack(rcvRecStack.last) := rcvRec; END rcvRecPush; -- PROCEDURE rcvRecGet( indx IN number ,rcvRec OUT NOCOPY rcvRec_t) IS BEGIN rcvRec := rcvRecStack(indx); END rcvRecGet; -- PROCEDURE rcvRecTop( rcvRec OUT NOCOPY rcvRec_t) IS BEGIN IF (rcvRecStack.count = 0) THEN rcvRec := NULL; ELSE rcvRecGet(rcvRecStack.count, rcvRec); deb(DEB_PRINT,'rcvRecPop:from_scn='||rcvRec.fromSCN_act|| ',to_scn='||rcvRec.toSCN_act|| ',rcvRecStackCount='||rcvRecStack.count ); END IF; END rcvRecTop; -- PROCEDURE rcvRecPop( rcvRec OUT NOCOPY rcvRec_t) IS BEGIN rcvRecTop(rcvRec); rcvRecStack.trim; END rcvRecPop; -- PROCEDURE rcvRecConvert( rcvRec IN OUT NOCOPY rcvRec_t) IS BEGIN -- -- rcvRec.recid_con := nvl(rcvRec.recid_con, 0); rcvRec.stamp_con := nvl(rcvRec.stamp_con, 0); rcvRec.setStamp_con := nvl(rcvRec.setStamp_con, 0); rcvRec.setCount_con := nvl(rcvRec.setCount_con, 0); rcvRec.fileName_con := nvl(rcvRec.fileName_con, 'NULL'); rcvRec.blockSize_con := nvl(rcvRec.blockSize_con, 0); rcvRec.blocks_con := nvl(rcvRec.blocks_con, 0); rcvRec.deviceType_con := nvl(rcvRec.deviceType_con, 'NULL'); END rcvRecConvert; -- PROCEDURE printRcvRec( action IN rcvRec_t ,summary IN boolean default FALSE) IS l varchar2(600); cfcretime varchar2(100); action_deleted boolean; procedure prt(str in out varchar2) is begin if length(str) > 2 then deb(DEB_PRINT, str); str := ' '; end if; end; BEGIN -- -- -- deb(DEB_PRINT, 'DUMPING RECOVERY CONTAINER'); -- IF (action.type_con = backupSet_con_t) THEN IF (action.type_act = full_act_t) THEN deb(DEB_PRINT, ' Full Backup Set'); ELSE deb(DEB_PRINT, ' Incremental Backup Set'); END IF; ELSIF (action.type_con = proxyCopy_con_t) THEN deb(DEB_PRINT, ' Proxy Backup'); ELSIF (action.type_con = imageCopy_con_t) THEN deb(DEB_PRINT, ' Datafile Copy'); ELSIF (action.type_con = offlineRangeRec_con_t) THEN IF (action.type_act = offlineRange_act_t) THEN deb(DEB_PRINT, ' Offline Range Record'); ELSIF (action.type_act = cleanRange_act_t) THEN deb(DEB_PRINT, ' Clean Range'); ELSIF (action.type_act = implicitRange_act_t) THEN deb(DEB_PRINT, ' Implicit Offline Range'); ELSIF (action.type_act = spanningRange_act_t) THEN deb(DEB_PRINT, ' Spanning Offline Range'); ELSE deb(DEB_PRINT, ' Unknown Offline Range Action Type'); END IF; ELSIF (action.type_con = datafile_con_t) THEN deb(DEB_PRINT, ' datafile container type'); ELSIF (action.type_con = addredo_con_t) THEN deb(DEB_PRINT,'Add Redo'); ELSE deb(DEB_PRINT, ' Unknown recovery container type'); END IF; -- IF (action.type_con = backupSet_con_t) THEN deb(DEB_PRINT, ' bsKey=' || to_char(action.bsKey_con) || ' bsRecid=' || to_char(action.bsRecid_con) || ' bsStamp=' || to_char(action.bsStamp_con) || ' setStamp=' || to_char(action.setStamp_con) || ' setCount=' || to_char(action.setCount_con) || ' site_key=' || to_char(action.site_key_con)); deb(DEB_PRINT, ' bsLevel=' || to_char(action.bsLevel_con) || ' bsType=' || action.bsType_con || ' pieceCount=' || to_char(action.pieceCount_con)); deb(DEB_PRINT, ' multi_section=' || nvl(action.multi_section_con, 'NULL')); ELSIF (action.type_con = proxyCopy_con_t OR action.type_con = imageCopy_con_t) THEN deb(DEB_PRINT, ' fileName=' || action.fileName_con); deb(DEB_PRINT, ' media=' || action.media_con); END IF; IF (summary) THEN RETURN; END IF; -- l := ' '; -- IF (action.key_con is not null) THEN l := l || ' key=' || to_char(action.key_con); END IF; -- IF (action.recid_con is not null) THEN l := l || ' recid=' || to_char(action.recid_con) || ' stamp=' || to_char(action.stamp_con); END IF; -- IF (action.status_con is not null) THEN l := l || ' status=' || action.status_con; END IF; IF (action.type_con = imageCopy_con_t OR action.type_con = backupSet_con_t) THEN l := l || ' sparse_backup_con =' || action.sparse_backup_con; END IF; prt(l); -- IF (action.tag_con is not null) THEN l := l || ' tag=' || action.tag_con; END IF; -- IF (action.compTime_con is not null) THEN l := l || ' compTime=' || to_char(action.compTime_con); END IF; prt(l); IF (action.deviceType_con is not null) THEN l := l || ' deviceType=' || action.deviceType_con; END IF; IF (action.blocks_con is not null) THEN l := l || ' blocks=' || to_char(action.blocks_con) || ' blockSize=' || to_char(action.blockSize_con); END IF; IF (action.cfCreationTime_con is not null) THEN l := l || ' cfCreationTime=' || to_char(action.cfCreationTime_con); END IF; IF (action.pieceNumber_con is not null) THEN l := l || ' pieceNumberl=' || to_char(action.pieceNumber_con); END IF; IF (action.bpCompTime_con is not null) THEN l := l || ' bpCompTime=' || to_char(action.bpCompTime_con); END IF; IF (action.bpCompressed_con is not null) THEN l := l || ' bpCompressed=' || to_char(action.bpCompressed_con); END IF; prt(l); -- -- -- -- IF (action.fromSCN_act is not null) THEN l := l || ' fromSCN=' || to_char(action.fromSCN_act); END IF; -- IF (action.toSCN_act is not null) THEN l := l || ' toSCN=' || to_char(action.toSCN_act) || ' toTime=' || to_char(action.toTime_act); END IF; -- IF (action.level_act is not null) THEN l := l || ' level=' || to_char(action.level_act); END IF; -- IF (action.section_size_act is not null) THEN l := l || ' section_size=' || to_char(action.section_size_act); END IF; prt(l); IF (action.rlgSCN_act is not null) THEN l := l || ' rlgSCN=' || to_char(action.rlgSCN_act) || ' rlgTime=' || to_char(action.rlgTime_act) || ' dbincKey=' || to_char(action.dbincKey_act); END IF; prt(l); IF (action.afzSCN_act is not null) THEN l := l || ' afzSCN=' || to_char(action.afzSCN_act); END IF; prt(l); IF (action.rfzSCN_act is not null AND action.rfzSCN_act != 0) THEN l := l || ' rfzSCN=' || to_char(action.rfzSCN_act) || ' rfzTime=' || nvl(to_char(action.rfzTime_act), 'NULL'); END IF; prt(l); -- -- -- IF (action.pdbKey_obj IS NOT NULL) THEN l := l || ' pdbKey=' || to_char(action.pdbKey_obj); END IF; prt(l); IF (action.dfNumber_obj IS NOT NULL) THEN l := l || ' dfNumber=' || to_char(action.dfNumber_obj) || ' creationSCN=' || to_char(action.dfCreationSCN_obj) || ' pluginSCN=' || to_char(action.pluginSCN_obj) || ' foreignDbid=' || to_char(action.foreignDbid_obj) || ' pluggedRonly=' || to_char(action.pluggedRonly_obj); deb(DEB_PRINT, l); l := ' '; l := l || ' cfType=' || nvl(action.cfType_obj, 'NULL'); deb(DEB_PRINT, l); l := ' '; l := l || ' keep_options=' || nvl(to_char(action.keep_options), 'NULL') || ' keep_until=' || nvl(to_char(action.keep_until), 'NULL'); deb(DEB_PRINT, l); IF (action.cfSequence_obj IS NOT NULL) THEN l := ' '; l := l || ' cfSequence=' || to_char(action.cfSequence_obj) || ' cfDate=' || nvl(to_char(action.cfDate_obj), 'NULL'); deb(DEB_PRINT, l); END IF; ELSIF (action.logSequence_obj IS NOT NULL) THEN l := l || ' logSequence=' || to_char(action.logSequence_obj); deb(DEB_PRINT, l); l := ' '; l := l || ' logThread=' || to_char(action.logThread_obj); deb(DEB_PRINT, l); l := ' '; l := l || ' logLowSCN=' || to_char(action.logLowSCN_obj); deb(DEB_PRINT, l); l := ' '; l := l || ' logLowTime=' || to_char(action.logLowTime_obj); deb(DEB_PRINT, l); l := ' '; l := l || ' logNextSCN=' || nvl(to_char(action.logNextSCN_obj), 'NULL'); deb(DEB_PRINT, l); l := ' '; l := l || ' logNextTime=' || nvl(to_char(action.logNextTime_obj), 'NULL'); deb(DEB_PRINT, l); l := ' '; l := l || ' logTerminalEor=' || action.logTerminal_obj; deb(DEB_PRINT, l); l := ' '; l := l || ' logRlgSCN=' || nvl(to_char(action.logRlgSCN_obj), 'NULL'); deb(DEB_PRINT, l); l := ' '; l := l || ' logRlgTime=' || nvl(to_char(action.logRlgTime_obj), 'NULL'); deb(DEB_PRINT, l); ELSIF (action.toTime_act IS NOT NULL) THEN deb(DEB_PRINT, ' SPFILE'); deb(DEB_PRINT, ' modification_time=' || to_char(action.toTime_act)); deb(DEB_PRINT, ' db_unique_name=' || action.sfDbUniqueName_obj); l := ' '; l := l || ' keep_options=' || nvl(to_char(action.keep_options), 'NULL') || ' keep_until=' || nvl(to_char(action.keep_until), 'NULL'); deb(DEB_PRINT, l); ELSE deb(DEB_PRINT, ' Unknown Recovery Object'); END IF; EXCEPTION WHEN OTHERS THEN deb(DEB_PRINT, 'printRcvRec: caught an exception, aborting print'); RETURN; END printRcvRec; -- -- -- -- FUNCTION redoNeeded( action IN rcvRec_t) RETURN boolean IS BEGIN deb(DEB_ENTER, 'redoNeeded'); IF (rcvRecStackState.lowAction > 0 AND -- Have a non-full_act_t on stack? action.toSCN_act < rcvRecStack(rcvRecStackState.lowAction).fromSCN_act) THEN deb(DEB_EXIT, 'with: TRUE'); RETURN TRUE; ELSE deb(DEB_EXIT, 'with: FALSE'); RETURN FALSE; END IF; END redoNeeded; -- FUNCTION canAddRedo( isAncestor IN boolean ,from_scn IN number ,from_rlgscn IN number ,to_action IN rcvRec_t ,partial_rcv IN boolean ,doingRecovery IN boolean) RETURN number IS BEGIN deb(DEB_ENTER, 'canAddRedo'); IF (from_rlgscn = this_reset_scn) THEN IF (partial_rcv) THEN deb(DEB_EXIT, 'with: action_OK'); RETURN action_OK; ELSE -- -- -- -- -- -- -- -- -- -- -- -- deb(DEB_EXIT, 'with: action_FAIL'); RETURN action_FAIL; END IF; ELSE deb(DEB_IN, 'from_rlgscn=' || nvl(to_char(from_rlgscn), 'NULL') || ' this_reset_scn=' || to_char(this_reset_scn)); IF (isAncestor) THEN deb(DEB_IN, 'isAncestor is TRUE;'); IF (canApplyAnyRedo = TRUE# AND from_scn >= nvl(inc_list(max_inc_idx-1).prior_resetlogs_change#, inc_list(max_inc_idx-1).resetlogs_change#)) THEN deb(DEB_PRINT, 'canAddRedo: return action_OLD_INC_REDO'); return action_OLD_INC_REDO; ELSE -- -- -- -- -- -- -- -- -- -- -- -- -- -- IF (doingRecovery) THEN deb(DEB_PRINT, 'with: action_OLD_REDO (doingRecovery)'); RETURN action_OLD_REDO; ELSIF (allIncarnations = TRUE#) THEN deb(DEB_PRINT, 'canAddRedo: returning action_OK'); RETURN action_OK; ELSE deb(DEB_PRINT, 'canAddRedo: returning action_OLD_REDO'); RETURN action_OLD_REDO; END IF; END IF; ELSE deb(DEB_IN, 'isAncestor is FALSE;'); -- -- deb(DEB_EXIT, 'with: action_OLD_REDO'); RETURN action_OLD_REDO; END IF; END IF; deb(DEB_EXIT, 'with undefined status'); END canAddRedo; -- FUNCTION addRedo( isAncestor IN boolean ,from_scn IN number ,from_rlgscn IN number ,to_action IN rcvRec_t ,partial_rcv IN boolean ,doingRecovery IN boolean) RETURN number IS canAdd number; BEGIN deb(DEB_ENTER, 'addRedo'); deb(DEB_IN,'Enter - from_scn=' || from_scn|| ',from_rlgscn=' ||from_rlgscn); canAdd := canAddRedo(isAncestor, from_scn, from_rlgscn, to_action, partial_rcv, doingRecovery); IF (canAdd = action_FAIL) THEN -- -- -- -- -- -- -- -- -- -- -- -- rcvRecStackState.lowAction := 0; rcvRecStack.trim(rcvRecStack.last - greatest(rcvRecStackState.savePoint, rcvRecStackState.top)); deb(DEB_IN,'trimming savepoint1, rcvRecStackCount='|| rcvRecStack.count); deb(DEB_EXIT, 'with: action_FAIL'); RETURN action_FAIL; ELSIF (canAdd = action_OK) THEN redoRec.type_act := redo_act_t; redoRec.fromSCN_act := from_scn; redoRec.toSCN_act := to_action.fromSCN_act; redoRec.toTime_act := to_date(null); redoRec.rlgSCN_act := from_rlgscn; redoRec.dfNumber_obj := to_action.dfNumber_obj; redoRec.dfCreationSCN_obj := to_action.dfCreationSCN_obj; redoRec.pluginSCN_obj := 0; redoRec.pluggedRonly_obj := 0; rcvRecPush(redoRec); deb(DEB_EXIT, 'with: action_OK'); RETURN action_OK; ELSIF (canAdd = action_OLD_INC_REDO) THEN redoRec.type_con := addredo_con_t; redoRec.type_act := redo_act_t; redoRec.fromSCN_act := from_scn; redoRec.toSCN_act := to_action.fromSCN_act; redoRec.toTime_act := to_date(null); redoRec.rlgSCN_act := from_rlgscn; redoRec.dfNumber_obj := to_action.dfNumber_obj; redoRec.dfCreationSCN_obj := to_action.dfCreationSCN_obj; redoRec.pluginSCN_obj := 0; redoRec.pluggedRonly_obj := 0; deb(DEB_EXIT, 'with: action_OLD_INC_REDO'); RETURN action_OLD_INC_REDO; ELSE -- ancestral incarnation -- -- -- -- deb(DEB_EXIT, 'with: action_OLD_REDO'); RETURN action_OLD_REDO; END IF; deb(DEB_EXIT, 'with undefined status'); END addRedo; -- -- FUNCTION isPdbScnOrphan(fromSCN IN NUMBER, toSCN IN NUMBER, afzSCN IN NUMBER, pdbId IN NUMBER) RETURN BOOLEAN IS -- l_afzSCN NUMBER := nvl(greatest(afzSCN, toSCN), toSCN); BEGIN IF (pdb_inc_list.exists(pdbId)) THEN FOR inc_idx in 0..pdb_inc_list(pdbId).count-1 LOOP IF ((fromSCN = 0 OR fromSCN > pdb_inc_list(pdbId)(inc_idx).erscn) AND (l_afzSCN > pdb_inc_list(pdbId)(inc_idx).erscn)) THEN EXIT; END IF; IF ((fromSCN >= pdb_inc_list(pdbId)(inc_idx).incscn AND fromSCN <= pdb_inc_list(pdbId)(inc_idx).erscn) OR (l_afzSCN >= pdb_inc_list(pdbId)(inc_idx).incscn AND l_afzSCN <= pdb_inc_list(pdbId)(inc_idx).erscn)) THEN deb(DEB_PRINT, 'isPdbScnOrphan: inc=' || inc_idx|| ',fromSCN =' || fromSCN || ',toSCN =' || toSCN || ',afzSCN =' || nvl(afzSCN, '') || ',incSCN =' || pdb_inc_list(pdbId)(inc_idx).incscn || ',erscn=' || pdb_inc_list(pdbId)(inc_idx).erscn); deb(DEB_PRINT, 'isPdbScnOrphan: belongs to orphan branch ' || 'of this sub incarnation:'); RETURN TRUE; END IF; END LOOP; END IF; RETURN FALSE; END isPdbScnOrphan; -- -- -- FUNCTION CheckRecAction( action IN rcvRec_t ,pdbId IN number ,cleanSCN IN number) RETURN number IS rlgSCN number; rlgTime date; toSCN number; fromSCN number; afzSCN number; creSCN number; BEGIN IF (canApplyAnyRedo = FALSE#) THEN return SUCCESS; END IF; IF (action.pluggedRonly_obj != 0) THEN deb(DEB_PRINT, 'CheckRecAction called for plugged readonly action'); rlgSCN := action.pluginRlgSCN_obj; rlgTime := action.pluginRlgTime_obj; toSCN := action.pluginSCN_obj; fromSCN := action.pluginSCN_obj; creSCN := action.pluginSCN_obj; ELSE rlgSCN := action.rlgSCN_act; rlgTime := action.rlgTime_act; toSCN := action.toSCN_act; fromSCN := action.fromSCN_act; afzSCN := action.afzSCN_act; creSCN := action.dfCreationSCN_obj; END IF; deb(DEB_PRINT, ' CheckRecAction called '|| to_char(rlgTime,'MM/DD/RR HH24:MI:SS')|| '; rlgscn='||rlgSCN || '; pdbId=' || pdbId || '; cleanscn=' || nvl(to_char(cleanSCN), 'NULL')); IF (action.type_con = backupSet_con_t OR action.type_con = imageCopy_con_t OR action.type_con = proxyCopy_con_t OR action.type_con = offlineRangeRec_con_t) THEN FOR inc_idx in 0..max_inc_idx-1 LOOP IF (rlgSCN = inc_list(inc_idx).resetlogs_change# AND rlgTime = inc_list(inc_idx).resetlogs_time ) THEN IF (inc_idx = 0 OR toSCN <= inc_list(inc_idx-1).resetlogs_change#) THEN deb(DEB_PRINT, 'CheckRecAction:matches inc='||inc_idx|| ',fromscn='|| fromSCN || ',toscn=' || toSCN || ',afzSCN=' || nvl(afzSCN, '')); IF (pdbId > 1 AND isPdbScnOrphan(fromSCN, toSCN, afzSCN, pdbId)) THEN return action_SKIP; END IF; IF (action.type_con = offlineRangeRec_con_t AND (fromSCN > skipOfflineRangeAboveSCN OR toSCN > skipOfflineRangeAboveSCN)) THEN return action_SKIP; ELSE return SUCCESS; END IF; ELSE deb(DEB_PRINT, 'CheckRecAction: inc='||inc_idx|| ',toscn='||toSCN|| ' exceeds '||inc_list(inc_idx-1).resetlogs_change#); deb(DEB_PRINT, 'CheckRecAction:belongs to orphan branch ' || 'of this incarnation:'); return action_SKIP; END IF; END IF; END LOOP; deb(DEB_PRINT, 'CheckRecAction:not known to incarnation table'); -- IF (nvl(afzSCN,0) = 0 AND toSCN = cleanSCN) THEN deb(DEB_PRINT, 'CheckRecAction: ok because backup ckpscn eq cleanscn'); return SUCCESS; END IF; ELSE return SUCCESS; END IF; -- -- -- return action_SKIP; END CheckRecAction; -- FUNCTION isValidAction(action IN rcvRec_t) RETURN boolean IS valid boolean := TRUE; BEGIN IF (bitand(action.type_con, getRA_containerMask) = 0) THEN deb(DEB_PRINT, 'isValidAction: skipping non-selected container type'); deb(DEB_PRINT, 'isValidAction: Container type : '|| action.type_con); deb(DEB_PRINT, 'isValidAction: Container Mask : '|| getRA_containerMask); valid := FALSE; -- then skip this action ELSIF (bitand(action.type_act, getRA_actionMask) = 0) THEN deb(DEB_PRINT, 'isValidAction: skipping non-selected action type'); deb(DEB_PRINT, 'isValidAction: Action type : '|| action.type_act); deb(DEB_PRINT, 'isValidAction: Action Mask : '|| getRA_actionMask); valid := FALSE; -- then skip this action ELSIF (bitand(action.type_con, deleted_con_t) > 0) THEN deb(DEB_PRINT, 'isValidAction: deleted action skipped:'); valid := FALSE; -- then skip this action -- ELSIF (computeRA_allRecords = TRUE# AND restoreTag is not null AND bitand(action.type_con, tagMask_con_t) > 0 AND (action.tag_con <> restoreTag OR action.tag_con is null)) THEN deb(DEB_PRINT, 'isValidAction: tag mismatch - skipped:'); valid := FALSE; -- then skip this action -- -- ELSIF (getRA_completedAfter IS NOT NULL AND action.compTime_con < getRA_completedAfter) THEN deb(DEB_PRINT, 'isValidAction: compTime < completedAfter - skipped:'); valid := FALSE; -- then skip this action -- ELSIF (getRA_completedBefore IS NOT NULL AND action.compTime_con > getRA_completedBefore) THEN deb(DEB_PRINT, 'isValidAction: compTime > completedBefore - skipped:'); valid := FALSE; -- ELSIF (getRA_likePattern IS NOT NULL AND action.fileName_con NOT LIKE getRA_likePattern) THEN deb(DEB_PRINT, 'isValidAction: LikePattern not matched - skipped:'); valid := FALSE; END IF; RETURN valid; END isValidAction; -- PROCEDURE resetrcvRecStack IS BEGIN IF (rcvRecStack.count > 0) THEN rcvRecStack.trim(rcvRecStack.count); END IF; rcvRecStackState.lowAction := 0; rcvRecStackState.savePoint := 0; rcvRecStackState.fullBackups := 0; rcvRecStackState.top := 0; END resetrcvRecStack; -- -- -- -- -- -- -- -- PROCEDURE fetchCursor1RecoveryAction( dbincKey IN number ,fno IN number ,creSCN IN number ,dfCkpSCN IN number ,dbincRlgSCN IN number ,dbincRlgTime IN date ,offlSCN IN number ,onlSCN IN number ,onlTime IN date ,cleanSCN IN number ,clean2SCN IN number ,clean2Time IN date ,targetSCN IN number ,opcode IN binary_integer -- 1 => seeknext, 2 => seekcurrent ,foreignDbid IN number ,pluggedRonly IN binary_integer -- 1 => readonly, 0 => readwrite ,pluginSCN IN number ,pluginRlgSCN IN number ,pluginRlgTime IN date ,rmanCmd IN binary_integer) IS action rcvRec_t; actCreSCN number; inpCreSCN number; BEGIN deb(DEB_ENTER, 'fetchCursor1RecoveryAction'); deb(DEB_IN, 'opcode=' || to_char(opcode)); -- IF (rcvRecCursor1_c%NOTFOUND) THEN rcvRecCursor.currc1.type_con := to_number(null); deb(DEB_EXIT, 'no more records'); RETURN; END IF; IF (pluginSCN != 0) THEN inpCreSCN := pluginSCN; ELSE inpCreSCN := creSCN; END IF; -- IF (opcode = 1) THEN goto seekNext; ELSIF (opcode = 2) THEN goto seekCurrent; ELSE raise_application_error(-20999, 'fetchCursor1RecoveryAction - 1'); END IF; -- <> deb(DEB_IN, 'seekNext'); LOOP rcvRecCursor.currc1.type_con := to_number(null); FETCH rcvRecCursor1_c INTO rcvRecCursor.currc1; IF (rcvRecCursor1_c%NOTFOUND) THEN rcvRecCursor.currc1.type_con := to_number(null); deb(DEB_IN, 'no more records'); EXIT; END IF; -- IF (rcvRecCursor.currc1.pluggedRonly_obj = 1) THEN deb(DEB_IN, 'rcvRecCursor1_c plugged read only object'); deb(DEB_IN, 'adjust toSCN ' || rcvRecCursor.currc1.toSCN_act || ' to pluginSCN ' || rcvRecCursor.currc1.pluginSCN_obj); rcvRecCursor.currc1.toSCN_act := rcvRecCursor.currc1.pluginSCN_obj; END IF; IF (rcvRecCursor.currc1.pluginSCN_obj != 0) THEN actCreSCN := rcvRecCursor.currc1.pluginSCN_obj; ELSE actCreSCN := rcvRecCursor.currc1.dfCreationSCN_obj; END IF; deb(DEB_IN, 'rcvRecCursor1_c record'); printRcvRec(rcvRecCursor.currc1); IF (rcvRecCursor.currc1.dfNumber_obj > fno OR (rcvRecCursor.currc1.dfNumber_obj = fno AND actCreSCN > inpCreSCN) OR (rcvRecCursor.currc1.dfNumber_obj = fno AND actCreSCN = inpCreSCN)) THEN -- -- EXIT; END IF; IF (debug) THEN deb(DEB_IN, 'skipped following record: summary'); printRcvRec(rcvRecCursor.currc1, TRUE); END IF; END LOOP; <> IF (rcvRecCursor.currc1.pluginSCN_obj != 0) THEN actCreSCN := rcvRecCursor.currc1.pluginSCN_obj; ELSE actCreScN := rcvRecCursor.currc1.dfCreationSCN_obj; END IF; IF (rcvRecCursor.currc1.type_con is null OR rcvRecCursor.currc1.dfNumber_obj > fno OR (rcvRecCursor.currc1.dfNumber_obj = fno AND actCreSCN > inpCreSCN)) THEN deb(DEB_EXIT, 'seekCurrent - beyond current fno, creSCN'); RETURN; END IF; IF (rcvRecCursor.currc1.dfNumber_obj != fno OR actCreSCN != inpCreSCN) THEN raise_application_error(-20999, 'fetchCursor1RecoveryAction ' || 'dfNumber_obj=' || to_char(rcvRecCursor.currc1.dfNumber_obj) || ' dfCreationSCN_obj=' || to_char(actCreSCN)); END IF; -- -- IF (rmanCmd = blkRestoreCmd_t) THEN IF (rcvRecCursor.currc1.toSCN_act > targetSCN) THEN deb(DEB_IN, 'a. simple filter rejected - trying next'); goto seekNext; END IF; ELSE IF (rcvRecCursor.currc1.toSCN_act < dfCkpSCN AND rcvRecCursor.currc1.fromSCN_act < dfCkpSCN) THEN deb(DEB_IN, 'b. simple filter rejected - trying next'); goto seekNext; END IF; END IF; -- OPEN rcvRecCursor1Filter_c( dbincKey => dbincKey ,fno => fno ,creSCN => creSCN ,dfCkpSCN => dfCkpSCN ,dbincRlgSCN => dbincRlgSCN ,dbincRlgTime => dbincRlgTime ,offlSCN => offlSCN ,onlSCN => onlSCN ,onlTime => onlTime ,cleanSCN => cleanSCN ,clean2SCN => clean2SCN ,clean2Time => clean2Time ,targetSCN => targetSCN ,c1rec => rcvRecCursor.currc1 ,foreignDbid => foreignDbid ,pluggedRonly => pluggedRonly ,pluginSCN => pluginSCN ,pluginRlgSCN => pluginRlgSCN ,pluginRlgTime => pluginRlgTime ,rmanCmd => rmanCmd); FETCH rcvRecCursor1Filter_c INTO action; IF (rcvRecCursor1Filter_c%NOTFOUND) THEN -- CLOSE rcvRecCursor1Filter_c; deb(DEB_IN, 'real filter rejected - trying next'); goto seekNext; END IF; CLOSE rcvRecCursor1Filter_c; deb(DEB_EXIT, 'filter accepted'); END fetchCursor1RecoveryAction; -- FUNCTION fetchRecoveryAction( dbincKey IN number ,fno IN number ,creSCN IN number ,dfCkpSCN IN number ,dbincRlgSCN IN number ,dbincRlgTime IN date ,offlSCN IN number ,onlSCN IN number ,onlTime IN date ,cleanSCN IN number ,clean2SCN IN number ,clean2Time IN date ,targetSCN IN number ,action IN OUT NOCOPY rcvRec_t ,rmanCmd IN binary_integer ,foreignDbid IN number ,pluggedRonly IN binary_integer -- 1 => readonly, 0 => readwrite ,pluginSCN IN number ,pluginRlgSCN IN number ,pluginRlgTime IN date) RETURN boolean IS top rcvRec_t; c1frec rcvRec_t; -- filtered cursor1 record actCreSCN number; inpCreSCN number; actRlgSCN number; topRlgSCN number; BEGIN deb(DEB_ENTER, 'fetchRecoveryAction'); IF (pluginSCN != 0) THEN inpCreSCN := pluginSCN; ELSE inpCreSCN := creSCN; END IF; <> IF (rcvRecCursor.currc1.pluginSCN_obj != 0) THEN actCreSCN := rcvRecCursor.currc1.pluginSCN_obj; ELSE actCreSCN := rcvRecCursor.currc1.dfCreationSCN_obj; END IF; IF (rcvRecCursor.currc1.type_con is null OR rcvRecCursor.currc1.dfNumber_obj != fno OR actCreSCN != inpCreSCN) THEN c1frec.type_con := to_number(null); ELSE c1frec := rcvRecCursor.currc1; END IF; OPEN rcvRecCursor2_c( dbincKey => dbincKey ,fno => fno ,creSCN => creSCN ,dfCkpSCN => dfCkpSCN ,dbincRlgSCN => dbincRlgSCN ,dbincRlgTime => dbincRlgTime ,offlSCN => offlSCN ,onlSCN => onlSCN ,onlTime => onlTime ,cleanSCN => cleanSCN ,clean2SCN => clean2SCN ,clean2Time => clean2Time ,targetSCN => targetSCN ,c1frec => c1frec ,excludeAction => rcvRecCursor.excludeAction ,foreignDbid => foreignDbid ,pluggedRonly => pluggedRonly ,pluginSCN => pluginSCN ,pluginRlgSCN => pluginRlgSCN ,pluginRlgTime => pluginRlgTime); FETCH rcvRecCursor2_c INTO action; IF (rcvRecCursor2_c%NOTFOUND) THEN action.type_con := NULL; action.type_act := NULL; CLOSE rcvRecCursor2_c; deb(DEB_EXIT, 'no_data_found with: FALSE'); RETURN FALSE; END IF; IF (action.type_act = spanningRange_act_t OR action.type_act = cleanRange_act_t OR action.type_act = implicitRange_act_t) THEN -- rcvRecCursor.excludeAction := rcvRecCursor.excludeAction + action.type_act; ELSE -- fetchCursor1RecoveryAction( dbincKey => dbincKey ,fno => fno ,creSCN => creSCN ,dfCkpSCN => dfCkpSCN ,dbincRlgSCN => dbincRlgSCN ,dbincRlgTime => dbincRlgTime ,offlSCN => offlSCN ,onlSCN => onlSCN ,onlTime => onlTime ,cleanSCN => cleanSCN ,clean2SCN => clean2SCN ,clean2Time => clean2Time ,targetSCN => targetSCN ,opcode => 1 ,foreignDbid => foreignDbid ,pluggedRonly => pluggedRonly ,pluginSCN => pluginSCN ,pluginRlgSCN => pluginRlgSCN ,pluginRlgTime => pluginRlgTime ,rmanCmd => rmanCmd); END IF; IF (action.compTime_con IS NULL AND -- was null in 8.0.2 action.type_con = backupSet_con_t) THEN action.compTime_con := stamp2date(action.bsStamp_con); END IF; IF (rmanCmd = obsoleteCmd_t AND action.type_act = incremental_act_t) THEN deb(DEB_PRINT, 'fetchRecoveryAction: incr backup set for obsolete cmd'); ELSE IF (computeRA_allRecords = TRUE#) THEN CLOSE rcvRecCursor2_c; deb(DEB_EXIT, 'with TRUE'); RETURN TRUE; END IF; IF (computeRA_fullBackups > 1) THEN CLOSE rcvRecCursor2_c; deb(DEB_EXIT, 'with TRUE'); RETURN TRUE; END IF; END IF; -- -- -- -- -- IF (rcvRecStack.count > 0) THEN rcvRecTop(top); IF (action.pluginSCN_obj != 0) THEN actRlgSCN := action.pluginRlgSCN_obj; ELSE actRlgSCN := action.rlgSCN_act; END IF; IF (top.pluginSCN_obj != 0) THEN topRlgSCN := top.pluginRlgSCN_obj; ELSE topRlgSCN := top.rlgSCN_act; END IF; IF (not (action.fromSCN_act < top.fromSCN_act) AND actrlgSCN = toprlgSCN) THEN IF (debug) THEN deb(DEB_IN, 'discarding this action:'); printRcvRec(action); END IF; CLOSE rcvRecCursor2_c; GOTO retry; END IF; END IF; CLOSE rcvRecCursor2_c; deb(DEB_EXIT, 'with TRUE'); RETURN TRUE; END fetchRecoveryAction; -- PROCEDURE openRecoveryActionCursor( dbincKey IN number ,fno IN number ,creSCN IN number ,dfCkpSCN IN number ,dbincRlgSCN IN number ,dbincRlgTime IN date ,offlSCN IN number ,onlSCN IN number ,onlTime IN date ,cleanSCN IN number ,clean2SCN IN number ,clean2Time IN date ,targetSCN IN number ,rmanCmd IN binary_integer ,foreignDbid IN number ,pluggedRonly IN binary_integer ,pluginSCN IN number ,pluginRlgSCN IN number ,pluginRlgTime IN date) IS openCursor1 boolean := FALSE; -- TRUE if cursor1 is to be opened opcode binary_integer := 0; -- seekNext or seekCurrent reqCreSCN number; inpCreSCN number; actCreSCN number; BEGIN deb(DEB_ENTER, 'openRecoveryActionCursor'); IF (pluginSCN != 0) THEN inpCreSCN := pluginSCN; ELSE inpCreSCN := creSCN; END IF; deb(DEB_IN,'target scn is ' || nvl(to_char(targetSCN), 'NULL') || ',creSCN=' || creSCN || ',dfCkpSCN=' || dfCkpSCN || ',dbincRlgSCN=' || dbincRlgSCN || ',offlSCN=' || offlSCN || ',onlSCN=' || onlSCN || ',cleanSCN=' || cleanSCN || ',clean2SCN=' || clean2SCN || ',fno=' || fno || ',pluginSCN=' || pluginSCN || ',rmanCmd=' || rmanCmd); deb(DEB_IN, 'currc1.type_con=' || nvl(to_char(rcvRecCursor.currc1.type_con),'NULL') || ' currc1.fno=' || nvl(to_char(rcvRecCursor.currc1.dfNumber_obj), 'NULL') || ' currc1.crescn=' || nvl(to_char(rcvRecCursor.currc1.dfCreationSCN_obj), 'NULL')); deb(DEB_IN, 'restoreSource=' || restoreSource || ', restoreSparse='|| restoreSparse); IF (rcvRecCursor1_c%ISOPEN) THEN deb(DEB_IN, 'cursor1 already open'); IF (tc_database = TRUE# OR isTranslatedFno(fno) = TRUE#) THEN deb(DEB_IN,'cursor1 translated'); IF (rcvRecCursor.reqpluginSCN != 0) THEN reqCreSCN := rcvRecCursor.reqpluginSCN; ELSE reqCreSCN := rcvRecCursor.reqcrescn; END IF; IF (rcvRecCursor.currc1.pluginSCN_obj != 0) THEN actCreSCN := rcvRecCursor.currc1.pluginSCN_obj; ELSE actCreSCN := rcvRecCursor.currc1.dfCreationSCN_obj; END IF; IF ((rcvRecCursor.reqfno = fno AND reqCreSCN >= inpCreSCN) OR (rcvRecCursor.reqfno > fno)) THEN -- -- deb(DEB_IN, 'cursor1 unusable'); openCursor1 := TRUE; ELSIF (rcvRecCursor.currc1.type_con is null OR rcvRecCursor.currc1.dfNumber_obj < fno OR (rcvRecCursor.currc1.dfNumber_obj = fno AND actCreSCN < inpCreSCN)) THEN deb(DEB_IN,'reusing cursor1 after seek'); opcode := 1; -- seekNext ELSIF (rcvRecCursor.currc1.dfNumber_obj = fno AND actCreSCN = inpCreSCN) THEN deb(DEB_IN,'reusing cursor1 with no seek'); opcode := 2; -- seekCurrent ELSE deb(DEB_IN,'do nothing to cursor1'); END IF; ELSE deb(DEB_IN,'cursor1 did not translate'); openCursor1 := TRUE; END IF; ELSE deb(DEB_IN,'cursor1 not open yet'); openCursor1 := TRUE; END IF; IF (openCursor1) THEN IF (rcvRecCursor1_c%ISOPEN) THEN CLOSE rcvRecCursor1_c; END IF; setDfTransClause(fno => fno); rcvRecCursor.currc1.type_con := to_number(null); deb(DEB_OPEN, 'rcvRecCursor1_c'); OPEN rcvRecCursor1_c(rmanCmd => rmanCmd); opcode := 1; -- seekNext END IF; -- IF (opcode != 0) THEN fetchCursor1RecoveryAction( dbincKey => dbincKey ,fno => fno ,creSCN => creSCN ,dfCkpSCN => dfCkpSCN ,dbincRlgSCN => dbincRlgSCN ,dbincRlgTime => dbincRlgTime ,offlSCN => offlSCN ,onlSCN => onlSCN ,onlTime => onlTime ,cleanSCN => cleanSCN ,clean2SCN => clean2SCN ,clean2Time => clean2Time ,targetSCN => targetSCN ,opcode => opcode ,foreignDbid => foreignDbid ,pluggedRonly => pluggedRonly ,pluginSCN => pluginSCN ,pluginRlgSCN => pluginRlgSCN ,pluginRlgTime => pluginRlgTime ,rmanCmd => rmanCmd); END IF; -- rcvRecCursor.excludeAction := 0; -- rcvRecCursor.reqfno := fno; rcvRecCursor.reqcrescn := creSCN; rcvRecCursor.reqpluginSCN := pluginSCN; -- IF (rcvRecCursor1Filter_c%ISOPEN) THEN CLOSE rcvRecCursor1Filter_c; END IF; IF (rcvRecCursor2_c%ISOPEN) THEN CLOSE rcvRecCursor2_c; END IF; deb(DEB_EXIT); END openRecoveryActionCursor; -- FUNCTION trimRecoveryActions( maxActions IN number ,containerMask IN number ,actionMask IN number) RETURN NUMBER IS dummy rcvRec_t; remaining number; BEGIN deb(DEB_ENTER,'trimRecoveryActions[function](maxactions='||maxActions||')'); IF (rcvRecStack.count > 0) THEN rcvRecPop(dummy); remaining := trimRecoveryActions(maxActions, containerMask, actionMask); -- -- -- -- -- -- IF ((bitand(dummy.type_con, containerMask) = 0) OR (bitand(dummy.type_act, actionMask) = 0)) THEN -- -- rcvRecPush(dummy); deb(DEB_EXIT, 'with: '||to_char(remaining)); RETURN remaining; ELSE IF (remaining < maxActions) THEN rcvRecPush(dummy); -- put back on stack deb(DEB_EXIT, 'with: '||to_char(remaining+1)); RETURN remaining + 1; ELSE -- IF (debug) THEN deb(DEB_IN, 'deleting action:'); printRcvRec(dummy); deb(DEB_EXIT, 'with: '||to_char(remaining)); END IF; RETURN remaining; END IF; END IF; ELSE deb(DEB_EXIT, 'with: 0'); RETURN 0; END IF; END trimRecoveryActions; -- PROCEDURE setCraGetAllCfBackups( flag IN boolean) IS BEGIN IF (flag) THEN deb(DEB_PRINT, 'craGetAllCfBackups is set to TRUE'); craGetAllCfBackups := TRUE#; ELSE deb(DEB_PRINT, 'craGetAllCfBackups is set to FALSE'); craGetAllCfBackups := FALSE#; END IF; END setCraGetAllCfBackups; -- -- FUNCTION isTranslatedArchivedLog( thread# IN number ,sequence# IN number) RETURN BOOLEAN IS thrbck binary_integer; seqbck binary_integer; BEGIN -- IF (thread# >= CONST2GVAL) THEN thrbck := CONST2GVAL - thread#; ELSE thrbck := thread#; END IF; -- IF (sequence# >= CONST2GVAL) THEN seqbck := CONST2GVAL - sequence#; ELSE seqbck := sequence#; END IF; IF NOT tc_threadSeq.exists(thrbck) THEN RETURN FALSE; ELSIF NOT tc_threadSeq(thrbck).exists(seqbck) THEN RETURN FALSE; ELSE RETURN TRUE; END IF; END isTranslatedArchivedLog; -- FUNCTION getRangeArchivedLogBackup( rcvRec OUT NOCOPY rcvRec_t) RETURN binary_integer IS local rcvRec_t; BSstatus number; BEGIN deb(DEB_ENTER, 'getRangeArchivedLogBackup'); IF (getRecStackCount = 0) THEN -- -- deb(DEB_EXIT, 'with: UNAVAILABLE'); RETURN UNAVAILABLE; END IF; rcvRecPop(local); -- -- IF (local.status_con = '*') THEN local.status_con := 'A'; BSstatus := AVAILABLE; ELSE BSstatus := SUCCESS; END IF; IF (debug) THEN printRcvRec(local); END IF; rcvRec := local; IF (BSstatus = AVAILABLE) THEN deb(DEB_EXIT, 'with: AVAILABLE'); RETURN AVAILABLE; ELSE deb(DEB_EXIT, 'with: SUCCESS'); RETURN SUCCESS; END IF; END getRangeArchivedLogBackup; -- -- FUNCTION startWithPattern( toDest IN varchar2) RETURN VARCHAR2 IS BEGIN IF (toDest IS NULL) THEN RETURN NULL; END IF; RETURN toDest || '%'; END startWithPattern; -- -- PROCEDURE extendKeepSCN(lbDfRec IN OUT NOCOPY lbDfRec_t, toSCN IN number, rlgSCN IN number, extendMask IN binary_integer, force IN boolean, dbgcomment IN varchar2) IS BEGIN IF (bitand(extendMask, extendFullSCN) != 0) THEN IF (force OR toSCN < lbDfRec.fullmin_scn) THEN lbDfRec.fullmin_scn := toSCN; lbDfRec.fullmin_rlgscn := rlgSCN; IF (debug) THEN deb(DEB_PRINT, dbgcomment || ': Extending fullmin_scn to ' || to_char(toSCN)); deb(DEB_PRINT, dbgcomment || ': Extending fullmin_rlgscn to ' || nvl(to_char(rlgSCN), 'null')); END IF; END IF; END IF; IF (bitand(extendMask, extendIncrSCN) != 0) THEN IF (force OR toSCN < lbDfRec.incrmin_scn) THEN lbDfRec.incrmin_scn := toSCN; lbDfRec.incrmin_rlgscn := rlgSCN; IF (debug) THEN deb(DEB_PRINT, dbgcomment || ': Extending incrmin_scn to ' || to_char(toSCN)); deb(DEB_PRINT, dbgcomment || ': Extending incrmin_rlgscn to ' || nvl(to_char(rlgSCN), 'null')); END IF; END IF; END IF; IF (bitand(extendMask, extendLogSCN) != 0) THEN IF (force OR toSCN < lbDfRec.logmin_scn) THEN lbDfRec.logmin_scn := toSCN; lbDfRec.logmin_rlgscn := rlgSCN; IF (debug) THEN deb(DEB_PRINT, dbgcomment || ': Extending logmin_scn to ' || to_char(toSCN)); deb(DEB_PRINT, dbgcomment || ': Extending logmin_rlgscn to ' || nvl(to_char(rlgSCN), 'null')); END IF; END IF; END IF; END extendKeepSCN; -- PROCEDURE resetPdbNameList IS BEGIN pdbNameList.delete; END resetPdbNameList; -- PROCEDURE initPdbNameList IS local pdbNameRec_t; BEGIN IF (pdbNameList.count != 0) THEN RETURN; END IF; IF (translatePdbName_c%ISOPEN) THEN raise_application_error(-20203, 'Translation already started'); END IF; resetPdbNameList; OPEN translatePdbName_c; <> FETCH translatePdbName_c INTO local; IF translatePdbName_c%NOTFOUND THEN CLOSE translatePdbName_c; ELSE pdbNameList(local.name) := local.pdbId; goto nextRow; END IF; pdbNameList(cdbRoot_txt) := 1; END initPdbNameList; -- PROCEDURE resetPdbFileList IS BEGIN pdbFileList.delete; END resetPdbFileList; -- PROCEDURE initPdbFileList IS local pdbFileRec_t; BEGIN IF (pdbFileList.count != 0) THEN RETURN; END IF; IF (translatePdbFile_c%ISOPEN) THEN raise_application_error(-20203, 'Translation already started'); END IF; deb(DEB_PRINT, 'initPdbFileList'); resetPdbFileList; OPEN translatePdbFile_c( fromSCN => nvl(untilSCN, MAXSCNVAL), toSCN => nvl(untilSCN, MAXSCNVAL)); <> FETCH translatePdbFile_c INTO local; IF translatePdbFile_c%NOTFOUND THEN CLOSE translatePdbFile_c; ELSE pdbFileList(local.file#) := local; goto nextRow; END IF; local.file# := 0; local.pdbId := 0; local.stopSCN := null; pdbFileList(0) := local; END initPdbFileList; -- FUNCTION translatePdbFile( file# IN NUMBER ,cleanSCN OUT NUMBER) RETURN NUMBER IS local pdbFileRec_t; BEGIN initPdbFileList; IF (pdbFileList.exists(file#)) THEN local := pdbFileList(file#); cleanSCN := local.stopSCN; ELSE deb(DEB_PRINT, 'translatePdbFile could not find file# ' || file#); IF (NOT pdbFileList.exists(1)) THEN raise_application_error(-20999, 'internal error: translatePdbFile'); END IF; local := pdbFileList(1); cleanSCN := NULL; END IF; RETURN local.pdbId; END translatePdbFile; -- -- PROCEDURE resetBsRecCache( reload IN boolean) IS BEGIN BEGIN deb(DEB_PRINT, '*****BsRecCache Statistics*****'); deb(DEB_PRINT, 'Cache size=' || to_char(cacheBsRecTable.bsRec.count) || ' hit=' || to_char(cacheBsRecTable.chit)); EXCEPTION WHEN no_data_found THEN deb(DEB_PRINT, 'No statistics available'); END; cacheBsRecTable.bsRec.delete; IF (NOT reload) THEN cacheBsRecTable.hitlist.delete; cacheBsRecTable.hitindex := 1; cacheBsRecTable.hint := noHint; END IF; cacheBSRecTable.chit := 0; cacheBsRecTable.mixcopy := FALSE; cacheBsRecTable.minbskey := 0; END resetBsRecCache; -- FUNCTION setCachedDeviceType( type IN varchar2) RETURN binary_integer IS BEGIN FOR i IN 1..cacheBsRecTable.devicecount LOOP IF cacheBsRecTable.devicelist(i) = type THEN RETURN i; END IF; END LOOP; cacheBsRecTable.devicecount := cacheBsRecTable.devicecount + 1; cacheBsRecTable.devicelist(cacheBsRecTable.devicecount) := type; RETURN cacheBsRecTable.devicecount; END setCachedDeviceType; -- PROCEDURE lkBsRecCache( bskey IN number ,icopy IN binary_integer ,bsrec OUT NOCOPY cacheBsRecRow_t) IS bucket number; sb4_bucket binary_integer; BEGIN bucket := mod(bskey, CONST4GVAL); IF (bucket >= CONST2GVAL) THEN sb4_bucket := CONST2GVAL - bucket; ELSE sb4_bucket := bucket; END IF; BEGIN FOR i in 1..cacheBsRecTable.bsRec(sb4_bucket).bslist.count LOOP IF (cacheBsRecTable.bsRec(sb4_bucket).bslist(i).bskey = bskey) THEN bsrec := cacheBsRecTable.bsRec(sb4_bucket).bslist(i).copy(icopy); RETURN; END IF; END LOOP; EXCEPTION WHEN no_data_found THEN NULL; END; RAISE no_data_found; END lkBsRecCache; -- FUNCTION addKeyToBsRecCache( bskey IN number) RETURN BOOLEAN IS bsk cacheBsRecBsKey_t; bslist cacheBsRecHash_t; bucket number; sb4_bucket binary_integer; bsindex binary_integer; BEGIN bucket := mod(bskey, CONST4GVAL); IF (bucket >= CONST2GVAL) THEN sb4_bucket := CONST2GVAL - bucket; ELSE sb4_bucket := bucket; END IF; -- IF (cacheBsRecTable.bsRec.exists(sb4_bucket)) THEN FOR i in 1..cacheBsRecTable.bsRec(sb4_bucket).bslist.count LOOP IF (cacheBsRecTable.bsRec(sb4_bucket).bslist(i).bskey = bskey) THEN RETURN FALSE; END IF; END LOOP; bsindex := cacheBsRecTable.bsRec(sb4_bucket).bsindex; ELSE cacheBsRecTable.bsRec(sb4_bucket) := bsk; bsindex := cacheBsRecTable.bsRec(sb4_bucket).bsindex; cacheBsRecTable.bsRec(sb4_bucket).bslist(bsindex) := bslist; END IF; -- cacheBsRecTable.bsRec(sb4_bucket).bslist(bsindex).bskey := bskey; cacheBsRecTable.bsRec(sb4_bucket).bsindex := bsindex + 1; RETURN TRUE; END addKeyToBsRecCache; -- PROCEDURE addToBsRecCache( bskey IN number ,icopy IN binary_integer ,deviceindx IN binary_integer ,tag IN varchar2 ,copyNumber IN binary_integer ,code IN binary_integer) IS bsrec cacheBsRecRow_t; bucket number; sb4_bucket binary_integer; bsindex binary_integer; BEGIN bucket := mod(bskey, CONST4GVAL); IF (bucket >= CONST2GVAL) THEN sb4_bucket := CONST2GVAL - bucket; ELSE sb4_bucket := bucket; END IF; bsrec.deviceindx := deviceindx; bsrec.tag := tag; bsrec.copyNumber := copyNumber; bsrec.code := code; IF (NOT cacheBsRecTable.bsRec.exists(sb4_bucket)) THEN raise_application_error(-20999, 'internal error: addToBsRecCache1'); END IF; FOR i in 1..cacheBsRecTable.bsRec(sb4_bucket).bslist.count LOOP IF (cacheBsRecTable.bsRec(sb4_bucket).bslist(i).bskey = bskey) THEN cacheBsRecTable.bsRec(sb4_bucket).bslist(i).copy(icopy) := bsrec; RETURN; END IF; END LOOP; -- raise_application_error(-20999, 'internal error: addToBsRecCache2'); END addToBsRecCache; -- FUNCTION hitBsRecCache( bskey IN number ,deviceType IN varchar2 ,tag IN varchar2 ,mask IN binary_integer) RETURN BOOLEAN IS bucket number; sb4_bucket binary_integer; BEGIN -- IF (deviceType != cacheBsRecTable.deviceType AND (deviceType IS NOT NULL OR cacheBsRecTable.deviceType IS NOT NULL)) THEN RETURN FALSE; END IF; -- IF (nvl(tag, ' ') != nvl(cacheBsRecTable.tag, nvl(tag, ' '))) THEN RETURN FALSE; END IF; -- IF (mask != cacheBsRecTable.mask) THEN RETURN FALSE; END IF; bucket := mod(bskey, CONST4GVAL); IF (bucket >= CONST2GVAL) THEN sb4_bucket := CONST2GVAL - bucket; ELSE sb4_bucket := bucket; END IF; IF (NOT cacheBsRecTable.bsRec.exists(sb4_bucket)) THEN IF (bskey < cacheBsRecTable.minbskey) THEN -- -- -- -- RETURN TRUE; ELSE RETURN FALSE; END IF; END IF; FOR i in 1..cacheBsRecTable.bsRec(sb4_bucket).bslist.count LOOP IF (cacheBsRecTable.bsRec(sb4_bucket).bslist(i).bskey = bskey) THEN cacheBsRecTable.chit := cacheBsRecTable.chit + 1; -- IF (cacheBsRecTable.hitindex > bsRecCacheLowLimit * 0.25) THEN cacheBsRecTable.hitindex := 1; END IF; -- cacheBsRecTable.hitlist(cacheBsRecTable.hitindex) := bskey; cacheBsRecTable.hitindex := cacheBsRecTable.hitindex + 1; RETURN TRUE; END IF; END LOOP; RETURN FALSE; END hitBsRecCache; -- FUNCTION canMixCopy( bskey IN number) RETURN BOOLEAN IS bucket number; sb4_bucket binary_integer; BEGIN bucket := mod(bskey, CONST4GVAL); IF (bucket >= CONST2GVAL) THEN sb4_bucket := CONST2GVAL - bucket; ELSE sb4_bucket := bucket; END IF; IF (NOT cacheBsRecTable.bsRec.exists(sb4_bucket)) THEN raise_application_error(-20999, 'internal error: canMixCopy1'); END IF; FOR i in 1..cacheBsRecTable.bsRec(sb4_bucket).bslist.count LOOP IF (cacheBsRecTable.bsRec(sb4_bucket).bslist(i).bskey = bskey) THEN RETURN cacheBsRecTable.bsRec(sb4_bucket).bslist(i).mixCopy; END IF; END LOOP; raise_application_error(-20999, 'internal error: canMixCopy2'); END canMixCopy; -- PROCEDURE loadBsRecCache( from_bsRec IN rcvRec_t ,deviceType IN varchar2 DEFAULT NULL ,tag IN varchar2 DEFAULT NULL ,mask IN binary_integer ,mixcopy IN number) IS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- CURSOR loadBsRecCache_c IS SELECT bs.bs_key bskey, bp.device_type deviceType, bp.tag tag, bp.copy# copyNumber, 1 code, decode(bp.ba_access, 'R', 3, 'T', 2, nvl2(vb_key, 1, 0)) order1, bs.pieces pieces FROM bp, bs WHERE loadBsRecCache.mixcopy = FALSE# AND bs.db_key = this_db_key AND bp.db_key = this_db_key AND bp.status != 'D' AND bp.bs_key = bs.bs_key AND isBsRecCacheMatch(bs.bs_key, bp.device_type, bp.tag, bp.status) = TRUE# -- See NOTE AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) GROUP BY bs.bs_key, bs.pieces, bp.device_type, bp.tag, bp.copy#, bp.ba_access, bp.vb_key HAVING ((bitand(mask, dbms_rcvman.BSpartial_avail) = 0 AND count(DISTINCT piece#) = bs.pieces) OR (bitand(mask, dbms_rcvman.BSpartial_avail) <> 0 AND count(DISTINCT piece#) <= bs.pieces)) UNION ALL -- -- -- SELECT bs.bs_key bskey, bp.device_type deviceType, bp.tag tag, to_number(null) copyNumber, 2 code, 0 order1, bs.pieces pieces FROM bp, bs WHERE loadBsRecCache.mixcopy = TRUE# AND bs.db_key = this_db_key AND bp.db_key = this_db_key AND bp.status != 'D' AND bp.bs_key = bs.bs_key AND isBsRecCacheMatch(bs.bs_key, bp.device_type, bp.tag, bp.status) = TRUE# -- See NOTE AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) GROUP BY bs.bs_key, bs.pieces, bp.device_type, bp.tag HAVING ((bitand(mask, dbms_rcvman.BSpartial_avail) = 0 AND count(DISTINCT piece#) = bs.pieces) OR (bitand(mask, dbms_rcvman.BSpartial_avail) <> 0 AND count(DISTINCT piece#) <= bs.pieces)) UNION ALL -- -- -- SELECT bs.bs_key bskey, bp.device_type deviceType, to_char(null) tag, to_number(null) copyNumber, 3 code, 0 order1, bs.pieces pieces FROM bp, bs WHERE loadBsRecCache.mixcopy = TRUE# AND bs.db_key = this_db_key AND bp.db_key = this_db_key AND bp.status != 'D' AND bp.bs_key = bs.bs_key AND isBsRecCacheMatch(bs.bs_key, bp.device_type, bp.tag, bp.status) = TRUE# -- See NOTE AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) GROUP BY bs.bs_key, bs.pieces, bp.device_type, bp.ba_access, bp.vb_key HAVING ((bitand(mask, dbms_rcvman.BSpartial_avail) = 0 AND count(DISTINCT piece#) = bs.pieces) OR (bitand(mask, dbms_rcvman.BSpartial_avail) <> 0 AND count(DISTINCT piece#) <= bs.pieces)) ORDER BY 1, -- bskey 5, -- code 6; -- order1 CURSOR loadRedundDf_c IS SELECT bs_key FROM (SELECT bs_key, file# FROM bdf, dbinc WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = bdf.dbinc_key AND file# >= nvl(from_bsRec.dfNumber_obj, 0) UNION ALL SELECT bs_key, 0 file# FROM bcf, dbinc WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = bcf.dbinc_key AND nvl(from_bsRec.dfNumber_obj, 0) = 0 UNION ALL SELECT bs_key, -1 file# FROM bsf WHERE from_bsRec.dfNumber_obj IS NULL AND from_bsRec.fromSCN_act = 0 AND bsf.db_key = this_db_key) GROUP BY bs_key ORDER BY min(file#), abs(bs_key - from_bsRec.bsKey_con); CURSOR loadRedundAl_c IS SELECT bs_key FROM (SELECT bs_key, thread#, sequence# FROM brl, dbinc WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = brl.dbinc_key AND low_scn >= from_bsRec.logLowSCN_obj AND ((thread# = from_bsRec.logThread_obj AND sequence# >= from_bsRec.logSequence_obj) OR (thread# > from_bsRec.logThread_obj))) GROUP BY bs_key ORDER BY min(thread#), min(sequence#), abs(bs_key - from_bsRec.bsKey_con); CURSOR loadLocality_c(minbskey IN number, backupType IN varchar2) IS SELECT bs_key bskey FROM bs WHERE bs.db_key = this_db_key AND bs.bs_key >= loadLocality_c.minbskey AND (loadLocality_c.backupType IS NULL OR decode(bs.bck_type, 'L', 'L', 'D')=loadLocality_c.backupType) ORDER BY abs(bs_key - from_bsRec.bsKey_con); icopy binary_integer := 0; bsrec cacheBsRec_t; bsrow cacheBsRecRow_t; prev_bskey number := 0; low_bskey number; deviceindx binary_integer; addperset binary_integer; -- no: entries added to cache per set bslist numTab_t; addstatus boolean; freec number; backupType varchar2(1); BEGIN deb(DEB_ENTER, 'loadBsRecCache'); deb(DEB_IN, 'mixcopy=' || to_char(mixcopy)); -- IF (NOT cacheBsRecTable.initlimit AND this_db_key IS NOT NULL) THEN -- SELECT count(*) INTO cacheBsRecTable.limit FROM bs, dbinc WHERE dbinc.db_key = this_db_key -- belongs to this database AND dbinc.db_key = bs.db_key; -- join bs and dbinc IF (cacheBsRecTable.limit > bsRecCacheHighLimit) THEN cacheBsRecTable.limit := bsRecCacheHighLimit; ELSIF (cacheBsRecTable.limit < bsRecCacheLowLimit) THEN cacheBsRecTable.limit := bsRecCacheLowLimit; END IF; cacheBsRecTable.initlimit := TRUE; END IF; IF (mixcopy = FALSE#) THEN -- resetBsRecCache(TRUE); cacheBsRecTable.bsRec := bsrec; -- cacheBsRecTable.tag := tag; cacheBsRecTable.deviceType := deviceType; cacheBsRecTable.mask := mask; ELSIF (cacheBsRecTable.mixcopy) THEN deb(DEB_EXIT, 'loadBsRecCache already loaded with mixcopy'); RETURN; ELSE cacheBsRecTable.mixcopy := TRUE; FOR rec in loadBsRecCache_c LOOP deviceindx := setCachedDeviceType(rec.deviceType); -- -- -- -- -- <> FOR i in 1..255 LOOP BEGIN lkBsRecCache(bskey => rec.bskey, icopy => i, bsrec => bsrow); EXIT mixCopyLoop WHEN (bsrow.deviceindx = deviceindx AND bsrow.code < rec.code); EXCEPTION WHEN no_data_found THEN addToBsRecCache(bskey => rec.bskey, icopy => i, deviceindx => deviceindx, tag => rec.tag, copyNumber => rec.copyNumber, code => rec.code); EXIT mixCopyLoop; END; END LOOP; END LOOP; deb(DEB_EXIT, 'loadBsRecCache loaded with mixcopy'); RETURN; END IF; -- addstatus := addKeyToBsRecCache(bskey => from_bsRec.bsKey_con); -- -- IF (cacheBsRecTable.hint = redundantHint) THEN freec := cacheBsRecTable.limit; -- only redundant ELSIF (cacheBsRecTable.hint = localityHint) THEN freec := 0; -- only locality ELSE freec := floor(cacheBsRecTable.limit/2); -- redundant + locality END IF; -- IF (freec != 0) THEN IF (from_bsRec.dfNumber_obj IS NOT NULL OR from_bsRec.fromSCN_act = 0) THEN deb(DEB_IN, 'loadRedundDf_c'); OPEN loadRedundDf_c; FETCH loadRedundDf_c BULK COLLECT INTO bslist LIMIT freec; CLOSE loadRedundDf_c; ELSIF (from_bsRec.logLowSCN_obj IS NOT NULL) THEN deb(DEB_IN, 'loadRedundAl_c'); OPEN loadRedundAl_c; FETCH loadRedundAl_c BULK COLLECT INTO bslist LIMIT freec; CLOSE loadRedundAl_c; END IF; -- FOR i in 1..bslist.count LOOP addstatus := addKeyToBsRecCache(bslist(i)); END LOOP; END IF; freec := cacheBsRecTable.limit - bslist.count; bslist.delete; -- free memory -- FOR i in 1..cacheBsRecTable.hitlist.count LOOP IF (addKeyToBsRecCache(cacheBsRecTable.hitlist(i))) THEN freec := freec - 1; END IF; EXIT WHEN (freec <= 0); END LOOP; IF (cacheBsRecTable.minbskey = 0) THEN BEGIN SELECT nvl(min(bp.bs_key), 0) INTO cacheBsRecTable.minbskey FROM bp WHERE bp.db_key = this_db_key AND bp.status != 'D' AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <>'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) AND ((mask = BSavailable AND bp.status = 'A') OR isStatusMatch(bp.status, mask) = TRUE#); EXCEPTION WHEN no_data_found THEN cacheBsRecTable.minbskey := 0; END; END IF; -- -- IF (freec > 0) THEN backupType := to_char(null); IF (cacheBsRecTable.hint = redundantHint) THEN -- BEGIN SELECT decode(bck_type, 'L', 'L', 'D') INTO backupType FROM bs WHERE bs_key = from_bsRec.bsKey_con; EXCEPTION WHEN no_data_found THEN backupType := 'D'; END; END IF; -- OPEN loadLocality_c(cacheBsRecTable.minbskey, backupType); LOOP FETCH loadLocality_c BULK COLLECT INTO bslist LIMIT freec; FOR i in 1..bslist.count LOOP IF (addKeyToBsRecCache(bslist(i))) THEN freec := freec - 1; END IF; END LOOP; bslist.delete; -- free memory EXIT WHEN (loadLocality_c%NOTFOUND OR freec <= 0); END LOOP; CLOSE loadLocality_c; END IF; -- FOR rec in loadBsRecCache_c LOOP deviceindx := setCachedDeviceType(rec.deviceType); -- IF (prev_bskey = rec.bskey AND prev_bskey != 0) THEN icopy := icopy + 1; ELSE icopy := 1; -- start with index 1 because this is new set END IF; addToBsRecCache(bskey => rec.bskey, icopy => icopy, deviceindx => deviceindx, tag => rec.tag, copyNumber => rec.copyNumber, code => rec.code); -- prev_bskey := rec.bskey; END LOOP; deb(DEB_IN, 'tag=' || nvl(cacheBsRecTable.tag, 'NULL') || ' deviceType=' || nvl(cacheBsRecTable.deviceType, 'NULL') || ' mask=' || to_char(mask)); -- deb(DEB_IN, 'Cache contains ' || to_char(cacheBsRecTable.bsRec.count) || ' buckets'); -- -- -- -- -- deb(DEB_IN, 'Minimum bskey=' || to_char(cacheBsRecTable.minbskey)); deb(DEB_EXIT); END loadBsRecCache; -- PROCEDURE cacheFindValidBackupSet( bsRec IN rcvRec_t ,deviceType IN varchar2 DEFAULT NULL ,tag IN varchar2 DEFAULT NULL ,availableMask IN binary_integer) IS BEGIN deb(DEB_PRINT,'cacheFindValidBackupSet:' || ' bskey =' || to_char(bsRec.bsKey_con) || ' tag=' || nvl(tag, 'NULL') || ' deviceType=' || nvl(deviceType, 'NULL') || ' mask=' || to_char(availableMask)); IF (NOT hitBsRecCache(bskey => bsRec.bsKey_con, deviceType => deviceType, tag => tag, mask => availableMask)) THEN loadBsRecCache(from_bsRec => bsRec, deviceType => deviceType, tag => tag, mask => availableMask, mixcopy => FALSE#); cacheBsRecTable.chit := cacheBsRecTable.chit + 1; END IF; findValidCacheRequest.bskey := bsRec.bsKey_con; findValidCacheRequest.icopy := 0; END cacheFindValidBackupSet; -- FUNCTION cacheGetValidBackupSet( validBackupSetRec OUT NOCOPY validBackupSetRec_t ,checkDeviceIsAllocated IN number DEFAULT FALSE#) RETURN number IS local validBackupSetRec_t; bsrec cacheBsRecRow_t; nullbsrec rcvRec_t; BEGIN <> findValidCacheRequest.icopy := findValidCacheRequest.icopy + 1; BEGIN lkBsRecCache( bskey => findValidCacheRequest.bskey, icopy => findValidCacheRequest.icopy, bsrec => bsrec); EXCEPTION WHEN no_data_found THEN -- IF (findValidCacheRequest.icopy != 1) THEN RAISE; END IF; IF (findValidCacheRequest.bskey< cacheBsRecTable.minbskey) THEN deb(DEB_PRINT, 'bskey < cacheBsRecTable.minbskey'); RAISE; END IF; IF (NOT canMixCopy(bskey => findValidCacheRequest.bskey)) THEN RAISE; END IF; -- loadBsRecCache(from_bsRec => nullbsrec, deviceType => cacheBsRecTable.deviceType, tag => cacheBsRecTable.tag, mask => cacheBsRecTable.mask, mixcopy => TRUE#); lkBsRecCache( bskey => findValidCacheRequest.bskey, icopy => findValidCacheRequest.icopy, bsrec => bsrec); END; -- local.deviceType := cacheBsRecTable.devicelist(bsrec.deviceindx); local.tag := bsrec.tag; local.copyNumber := bsrec.copyNumber; local.code := bsrec.code; IF (checkDeviceIsAllocated = TRUE#) THEN IF (anyDevice = FALSE# AND isDeviceTypeAllocated(local.deviceType) = FALSE#) THEN GOTO nextRow; END IF; END IF; validBackupSetRec := local; -- set OUT mode arg deb(DEB_PRINT,'cacheGetValidBackupSet: returning valid rec deviceType=' || local.deviceType || ' tag=' || local.tag || ' copyNumber=' || to_char(local.copyNumber)); RETURN TRUE#; EXCEPTION WHEN no_data_found THEN RETURN FALSE#; END cacheGetValidBackupSet; -- -- -- -- PROCEDURE validateState( anyCursor IN varchar2) IS BEGIN deb(DEB_ENTER,'validateState'); IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'database not set'); END IF; IF (this_dbinc_key IS NULL) THEN raise_application_error(-20020, 'Database incarnation not set'); END IF; IF (translation_site_key IS NULL) THEN raise_application_error(-20082, 'Translation site key not set'); END IF; IF (anyCursor IS NOT NULL) THEN raise_application_error(-20203, 'Translation already started'); END IF; -- -- IF this_db_unique_name is NOT NULL AND this_site_key is NULL AND NOT this_dummy_instance THEN select site_key into this_site_key from node where db_unique_name=this_db_unique_name and db_key = this_db_key; deb(DEB_PRINT,'this_site_key=' || this_site_key); END IF; deb(DEB_EXIT,'validateState'); END; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE computeUntilSCN( timeStamp IN date ,scn OUT number ,allinc IN number) IS mySCN number; BEGIN deb(DEB_ENTER, 'computeUntilSCN'); -- -- -- SELECT nvl(max(rlh.low_scn),0) INTO mySCN FROM rlh, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc WHERE allinc = TRUE# START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE rlh.dbinc_key = d2.dbinc_key AND (allinc = FALSE# OR d2.next_reset_scn IS NULL OR (rlh.low_scn >= d2.reset_scn AND rlh.low_scn < d2.next_reset_scn)) AND rlh.low_time <= timeStamp; SELECT greatest(nvl(max(al.low_scn), 0), mySCN) INTO mySCN FROM al, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc WHERE allinc = TRUE# START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE al.dbinc_key = d2.dbinc_key AND (allinc = FALSE# OR d2.next_reset_scn IS NULL OR (al.low_scn >= d2.reset_scn AND al.low_scn < d2.next_reset_scn)) AND al.low_time <= timeStamp; SELECT greatest(nvl(max(bdf.ckp_scn),0), mySCN) INTO mySCN FROM bdf, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc WHERE allinc = TRUE# START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE bdf.dbinc_key = d2.dbinc_key AND (allinc = FALSE# OR d2.next_reset_scn IS NULL OR (bdf.ckp_scn >= d2.reset_scn AND bdf.ckp_scn < d2.next_reset_scn)) AND bdf.ckp_time <= timeStamp; SELECT greatest(nvl(max(bcf.ckp_scn),0), mySCN) INTO mySCN FROM bcf, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc WHERE allinc = TRUE# START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE bcf.dbinc_key = d2.dbinc_key AND (allinc = FALSE# OR d2.next_reset_scn IS NULL OR (bcf.ckp_scn >= d2.reset_scn AND bcf.ckp_scn < d2.next_reset_scn)) AND bcf.ckp_time <= timeStamp; SELECT greatest(nvl(max(cdf.ckp_scn),0), mySCN) INTO mySCN FROM cdf, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc WHERE allinc = TRUE# START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE cdf.dbinc_key = d2.dbinc_key AND (allinc = FALSE# OR d2.next_reset_scn IS NULL OR (cdf.ckp_scn >= d2.reset_scn AND cdf.ckp_scn < d2.next_reset_scn)) AND cdf.ckp_time <= timeStamp; SELECT greatest(nvl(max(cdf.rcv_fuzzy_scn),0), mySCN) INTO mySCN FROM cdf, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc WHERE allinc = TRUE# START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE cdf.dbinc_key = d2.dbinc_key AND (allinc = FALSE# OR d2.next_reset_scn IS NULL OR (cdf.rcv_fuzzy_scn >= d2.reset_scn AND cdf.rcv_fuzzy_scn < d2.next_reset_scn)) AND cdf.rcv_fuzzy_time <= timeStamp; SELECT greatest(nvl(max(ccf.ckp_scn),0), mySCN) INTO mySCN FROM ccf, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc WHERE allinc = TRUE# START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE ccf.dbinc_key = d2.dbinc_key AND (allinc = FALSE# OR d2.next_reset_scn IS NULL OR (ccf.ckp_scn >= d2.reset_scn AND ccf.ckp_scn < d2.next_reset_scn)) AND ccf.ckp_time <= timeStamp; SELECT greatest(nvl(max(xdf.ckp_scn),0), mySCN) INTO mySCN FROM xdf, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc WHERE allinc = TRUE# START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE xdf.dbinc_key = d2.dbinc_key AND (allinc = FALSE# OR d2.next_reset_scn IS NULL OR (xdf.ckp_scn >= d2.reset_scn AND xdf.ckp_scn < d2.next_reset_scn)) AND xdf.ckp_time <= timeStamp; SELECT greatest(nvl(max(xdf.rcv_fuzzy_scn),0), mySCN) INTO mySCN FROM xdf, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc WHERE allinc = TRUE# START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE xdf.dbinc_key = d2.dbinc_key AND (allinc = FALSE# OR d2.next_reset_scn IS NULL OR (xdf.rcv_fuzzy_scn >= d2.reset_scn AND xdf.rcv_fuzzy_scn < d2.next_reset_scn)) AND xdf.rcv_fuzzy_time<= timeStamp; SELECT greatest(nvl(max(df.create_scn), 0), mySCN) INTO mySCN FROM df, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc WHERE allinc = TRUE# START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE df.dbinc_key = d2.dbinc_key AND (allinc = FALSE# OR d2.next_reset_scn IS NULL OR (df.create_scn >= d2.reset_scn AND df.create_scn < d2.next_reset_scn)) AND df.create_time <= timeStamp; SELECT greatest(nvl(max(df.stop_scn), 0), mySCN) INTO mySCN FROM df, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc WHERE allinc = TRUE# START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE df.dbinc_key = d2.dbinc_key AND (allinc = FALSE# OR d2.next_reset_scn IS NULL OR (df.stop_scn >= d2.reset_scn AND df.stop_scn < d2.next_reset_scn)) AND df.stop_time <= timeStamp; SELECT greatest(nvl(max(offr.online_scn), 0), mySCN) INTO mySCN FROM offr, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc WHERE allinc = TRUE# START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE offr.dbinc_key = d2.dbinc_key AND (allinc = FALSE# OR d2.next_reset_scn IS NULL OR (offr.online_scn >= d2.reset_scn AND offr.online_scn < d2.next_reset_scn)) AND offr.online_time <= timeStamp; scn := mySCN; deb(DEB_EXIT, 'with '||to_char(scn)); END computeUntilSCN; -- PROCEDURE computeSpfileTime( inSCN IN number ,outTime OUT date ,allinc IN number ,estimated OUT boolean) IS startTime date; BEGIN deb(DEB_ENTER, 'computeSpfileTime'); outTime := NULL; -- IF rpoint_set THEN estimated := FALSE; SELECT MIN(rtime) INTO outTime FROM (SELECT NVL(rsptime, creation_time) rtime FROM nrsp WHERE to_scn = inSCN - 1 UNION SELECT NVL(rsptime, creation_time) rtime FROM grsp WHERE to_scn = inSCN - 1); END IF; -- IF outTime IS NULL THEN estimated := TRUE; startTime := to_date('01/01/1900','DD/MM/YYYY'); -- SELECT nvl(max(bs.start_time), startTime) INTO outTime FROM bcf,bs, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc WHERE allinc = TRUE# START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE bcf.dbinc_key = d2.dbinc_key AND bs.bs_key = bcf.bs_key AND (allinc = FALSE# OR d2.next_reset_scn IS NULL OR (bcf.ckp_scn >= d2.reset_scn AND bcf.ckp_scn < d2.next_reset_scn)) AND bcf.ckp_scn <= inSCN; -- -- SELECT greatest(nvl(max(xcf.start_time), startTime), outTime) INTO outTime FROM xcf, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc WHERE allinc = TRUE# START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE xcf.dbinc_key = d2.dbinc_key AND (allinc = FALSE# OR d2.next_reset_scn IS NULL OR (xcf.ckp_scn >= d2.reset_scn AND xcf.ckp_scn < d2.next_reset_scn)) AND xcf.ckp_scn <= inSCN; -- IF startTime = outTime THEN outTime := NULL; END IF; END IF; -- -- outTime := outTime + 1/24/60/60; -- Add one second deb(DEB_EXIT, 'with ' || to_char(outTime, 'DD-MON-YY HH24:MI:SS')); END computeSpfileTime; -- -- -- -- -- PROCEDURE findBackupSet( bsKey IN number DEFAULT NULL ,recid IN number DEFAULT NULL ,stamp IN number DEFAULT NULL ,bsRec OUT NOCOPY bsRec_t) IS BEGIN deb(DEB_ENTER, 'findBackupSet'); deb(DEB_IN, 'bsKey:'||nvl(bsKey, -1)); IF (bsKey IS NOT NULL) THEN SELECT recid, stamp, bs_key, set_stamp, set_count, backup_type, incremental_level, elapsed_seconds, completion_time, status, pieces, decode (keep_options, 'LOGS' , KEEP_LOGS , 'NOLOGS' , KEEP_NOLOGS , 'BACKUP_LOGS' , KEEP_CONSIST , KEEP_NO), keep_until, substr(multi_section, 1, 1), 0 ppl_pdb_id, 0 ppl_cdb_dbid INTO bsRec FROM rc_backup_set WHERE db_key = this_db_key AND findBackupSet.bsKey = bs_key; ELSE SELECT recid, stamp, bs_key, set_stamp, set_count, backup_type, incremental_level, elapsed_seconds, completion_time, status, pieces, decode (keep_options, 'LOGS' , KEEP_LOGS , 'NOLOGS' , KEEP_NOLOGS , 'BACKUP_LOGS' , KEEP_CONSIST , KEEP_NO), keep_until, substr(multi_section, 1, 1), 0 ppl_pdb_id, 0 ppl_cdb_dbid INTO bsRec FROM rc_backup_set WHERE db_key = this_db_key AND findBackupSet.recid = recid AND findBackupSet.stamp = stamp; END IF; deb(DEB_EXIT); EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with error 20215'); raise_application_error(-20215, 'Backup set is missing'); END findBackupSet; -- -- -- -- -- -- -- PROCEDURE findValidBackupSet( bsKey IN number ,pieceCount IN number ,deviceType IN varchar2 DEFAULT NULL ,tag IN varchar2 DEFAULT NULL ,availableMask IN binary_integer) IS bsRec rcvRec_t; BEGIN IF (bsRecCacheEnabled) THEN bsRec.bsKey_con := bsKey; bsRec.pieceCount_con := pieceCount; cacheFindValidBackupSet(bsRec => bsRec, deviceType => deviceType, tag => tag, availableMask => availableMask); RETURN; END IF; deb(DEB_ENTER, 'findValidBackupSet'); IF (pieceCount = 1) THEN IF (findValidBackupSet1P_c%ISOPEN) THEN CLOSE findValidBackupSet1P_c; END IF; -- -- -- -- deb(DEB_OPEN, 'findValidBackupSet1P_c'); OPEN findValidBackupSet1P_c(bsKey => bsKey, pieceCount => pieceCount, deviceType => deviceType, tag => tag, mask => availableMask); getValidBackupSetCursor := 'findValidBackupSet1P_c'; ELSE -- more than one piece exists in this set IF (findValidBackupSet_c%ISOPEN) THEN CLOSE findValidBackupSet_c; END IF; deb(DEB_OPEN, 'findValidBackupSet_c'); OPEN findValidBackupSet_c(bsKey => bsKey, pieceCount => pieceCount, deviceType => deviceType, tag => tag, mask => availableMask); getValidBackupSetCursor := 'findValidBackupSet_c'; END IF; deb(DEB_IN, 'bsKey=' || to_char(bsKey) || ' pieceCount=' || to_char(pieceCount) ||' tag=' || nvl(tag, 'NULL')); deb(DEB_IN, ' deviceType=' || nvl(deviceType, 'NULL') || ' mask=' || to_char(availableMask)); getValidBackupSetLast.code := 99; -- init for getValidBackupSet deb(DEB_EXIT); END findValidBackupSet; -- FUNCTION validateBackupSet( backupSetRec IN rcvRec_t ,tag IN varchar2 DEFAULT NULL ,tagMatchRequired IN boolean DEFAULT TRUE ,checkDeviceIsAllocated IN boolean DEFAULT TRUE ,availableMask IN binary_integer ,validRec OUT NOCOPY validBackupSetRec_t) RETURN binary_integer IS findTag bp.tag%TYPE; BEGIN deb(DEB_ENTER, 'validateBackupSet'); IF (tagMatchRequired) THEN findTag := tag; ELSE -- -- -- findTag := NULL; END IF; deb(DEB_IN, 'calling findValidBackupSet with:'); deb(DEB_IN, ' tag=' || nvl(tag, 'NULL') || ' findTag=' || nvl(findTag, 'NULL') || ' tagMatchRequired=' || bool2char(tagMatchRequired) || ' checkDevice=' || bool2char(checkDeviceIsAllocated) || ' availableMask=' || to_char(availableMask)); IF (bsRecCacheEnabled) THEN cacheFindValidBackupSet(bsRec => backupSetRec, tag => findTag, availableMask => availableMask); ELSE findValidBackupSet(bsKey => backupSetRec.bsKey_con, pieceCount => backupSetRec.pieceCount_con, tag => findTag, availableMask => availableMask); END IF; deb(DEB_EXIT, 'with result from validateBackupSet0'); RETURN validateBackupSet0( tag => tag, tagMatchRequired => tagMatchRequired, checkDeviceIsAllocated => checkDeviceIsAllocated, validRec => validRec); END validateBackupSet; -- -- -- -- PROCEDURE findBackupPiece( bpKey IN number DEFAULT NULL ,bsKey IN number DEFAULT NULL ,tag IN varchar2 DEFAULT NULL ,handle IN varchar2 DEFAULT NULL ,deviceType IN varchar2 DEFAULT NULL ,copyNumber IN number DEFAULT NULL ,statusMask IN binary_integer DEFAULT BSavailable ,startBsKey IN number DEFAULT NULL ,pdbKey IN number DEFAULT NULL ,guid IN varchar2 DEFAULT NULL) IS BEGIN deb(DEB_ENTER, 'findBackupPiece'); deb(DEB_IN, 'bpKey:'||nvl(bpKey, -1)|| ' and bsKey:'||nvl(bsKey, -1)); validateState(getBackupPieceCursor); IF (bpKey IS NOT NULL) THEN deb(DEB_OPEN, 'findBackupPieceBpKey'); OPEN findBackupPieceBpKey(bpKey => bpKey, tag => tag, handle => handle, deviceType => deviceType, copyNumber => copyNumber, statusMask => statusMask); getBackupPieceCursor := 'findBackupPieceBpKey'; ELSIF (bsKey IS NOT NULL) THEN deb(DEB_OPEN, 'findBackupPieceBsKey1'); OPEN findBackupPieceBsKey1(bsKey => bsKey, tag => tag, handle => handle, deviceType => deviceType, copyNumber => copyNumber, statusMask => statusMask); getBackupPieceCursor := 'findBackupPieceBsKey1'; ELSIF (startBsKey IS NOT NULL) THEN OPEN findBackupPieceBsKey2(startBsKey => startBsKey, tag => tag, statusMask => statusMask); getBackupPieceCursor := 'findBackupPieceBsKey2'; ELSE deb(DEB_OPEN, 'findBackupPiece_c'); OPEN findBackupPiece_c( tag => tag, handle => handle, deviceType => deviceType, copyNumber => copyNumber, statusMask => statusMask, pdbKey => pdbKey, guid => guid); getBackupPieceCursor := 'findBackupPiece_c'; END IF; -- -- getBackupPieceNoRows.error := NULL; getBackupPieceDuplicates := TRUE#; getBackupPieceLast.pieceNumber := NULL; getBackupPieceDeviceType := deviceType; getBackupPieceExpectedPieces := NULL; getBackupPiecePieceCount := 0; getBackupPieceByHandle := FALSE; getBackupPieceAvailableMask := NULL; getBackupPieceSeekLast.bskey := NULL; getBackupPieceCopyNumber := NULL; getBackupPieceBskey := bsKey; deb(DEB_EXIT); END findBackupPiece; -- -- -- -- FUNCTION addAction( -- add to the rcvRecStack actionIN IN rcvRec_t -- if a backup set, we fill -- ,partial_rcv IN boolean ,isAncestor IN boolean ,cf_scn IN number DEFAULT NULL ,cf_cretime IN date DEFAULT NULL ,cf_offrrid IN number DEFAULT NULL ,allCopies IN boolean DEFAULT FALSE ,doingRecovery IN boolean ,rmanCmd IN binary_integer ,pdbId IN number ,cleanSCN IN number) RETURN number IS dummy rcvRec_t; action rcvRec_t; validate_rc number; cf_count number; addRedo_rc number; chkact_rc number; tagMatchRequired boolean; validationRec validBackupSetRec_t; lowAction rcvRec_t; canrecover boolean; toSCN number; BEGIN deb(DEB_ENTER, 'addAction'); deb(DEB_IN, ' action.type_con='|| to_char(action.type_con)); action := actionIN; -- copy to local variable -- -- -- -- -- -- -- -- IF (redoNeeded(action)) THEN -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- rcvRecGet(rcvRecStackState.lowAction, lowAction); addRedo_rc := addRedo(isAncestor, action.toSCN_act, action.rlgSCN_act, lowAction, partial_rcv, doingRecovery); IF (addRedo_rc = action_OLD_REDO) THEN -- -- -- deb(DEB_EXIT, 'with addRedo_rc: '||to_char(addRedo_rc)); RETURN addRedo_rc; ELSE -- -- -- -- -- NULL; END IF; ELSE -- redo not needed -- -- -- -- NULL; END IF; -- -- chkact_rc := CheckRecAction(action, pdbId, cleanSCN); IF (chkact_rc = action_SKIP) THEN deb(DEB_EXIT, 'with action_SKIP'); RETURN action_SKIP; END IF; -- -- -- -- IF (action.type_con = backupSet_con_t) THEN IF (computeRA_allRecords = TRUE# OR restoreTag IS NULL) THEN tagMatchRequired := FALSE; ELSE tagMatchRequired := TRUE; END IF; IF (rmanCmd = rcvCopyCmd_t) THEN -- -- tagMatchRequired := FALSE; END IF; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- IF (rmanCmd != obsoleteCmd_t OR (restoreTag IS NOT NULL AND this_baseline_cap >= 0)) THEN validate_rc := validateBackupSet(backupSetRec => action, tag => restoreTag, tagMatchRequired => tagMatchRequired, checkDeviceIsAllocated => TRUE, availableMask => computeRA_availableMask, validRec => validationRec); ELSE -- -- validate_rc := SUCCESS; END IF; IF (validate_rc = dbms_rcvman.UNAVAILABLE) THEN deb(DEB_EXIT, '(backup set is unavailable) with: action_FAIL'); RETURN action_FAIL; ELSIF (validate_rc = dbms_rcvman.AVAILABLE) THEN -- -- -- deb(DEB_IN,'dont have required device type'); -- -- -- -- IF (rmanCmd = rcvCopyCmd_t) THEN computeRA_rcvCopy_avail := TRUE; ELSE computeRA_available := TRUE; END IF; deb(DEB_EXIT, 'returning FAIL'); RETURN action_FAIL; END IF; -- -- -- ELSIF (action.type_con = proxyCopy_con_t) THEN -- IF (anyDevice = FALSE# AND isDeviceTypeAllocated(action.deviceType_con) = FALSE#) THEN -- -- -- IF (rmanCmd = rcvCopyCmd_t) THEN computeRA_rcvCopy_avail := TRUE; ELSE computeRA_available := TRUE; END IF; deb(DEB_EXIT, '(dont have required device type for proxy)'|| ' with: action_FAIL'); RETURN action_FAIL; END IF; ELSIF (action.type_con = imageCopy_con_t) THEN -- -- -- IF (rmanCmd != rcvCopyCmd_t AND not diskDevice) THEN -- -- computeRA_available := TRUE; deb(DEB_EXIT, '(dont have required device type for imagecopy)'|| ' with: action_FAIL'); RETURN action_FAIL; END IF; -- -- -- IF (rmanCmd = rcvCopyCmd_t) THEN canrecover := FALSE; computeRA_available := computeRA_rcvCopy_avail; toSCN := action.toSCN_act; deb(DEB_IN,'rcvCopyCmd count= ' || rcvRecStack.count || ' lowAction= ' || rcvRecStackState.lowAction || ' toSCN= ' || toSCN); IF (rcvRecStack.count > 0) THEN FOR i IN REVERSE 1..rcvRecStackState.lowAction LOOP rcvRecGet(i, dummy); -- IF (dummy.type_act = incremental_act_t OR dummy.type_con = offlineRangeRec_con_t) THEN -- -- -- -- EXIT WHEN (toSCN < dummy.fromSCN_act); -- IF (dummy.type_con = offlineRangeRec_con_t) THEN toSCN := dummy.toSCN_act; deb(DEB_IN,'extending toSCN= ' || toSCN); ELSE -- this is incremental IF (anyDevice = TRUE# OR isDeviceTypeAllocated(dummy.deviceType_con)=TRUE#) THEN -- deb(DEB_IN,'canrecover is TRUE - 2'); canrecover := TRUE; computeRA_available := NULL; EXIT; ELSE -- -- -- deb(DEB_IN,'canrecover is FALSE'); canrecover := FALSE; computeRA_available := TRUE; END IF; END IF; ELSIF (debug) THEN deb(DEB_IN,'rcvCopyCmd skipping'); printRcvRec(dummy); END IF; END LOOP; END IF; -- -- -- IF not canrecover THEN resetrcvRecStack; deb(DEB_EXIT, 'no valid incrementals with: action_FAIL'); RETURN action_FAIL; END IF; END IF; ELSIF (action.type_con = offlineRangeRec_con_t AND action.type_act = offlineRange_act_t) THEN -- -- -- -- -- -- IF (cf_cretime IS NULL AND rmanCmd = obsoleteCmd_t) THEN -- -- NULL; ELSIF (cf_cretime = action.cfCreationTime_con AND action.recid_con >= cf_offrrid AND cf_offrrid > 0 AND -- contains at least 1 record cf_scn >= action.toSCN_act) THEN NULL; -- range is in current cf, we're cool ELSE SELECT count(*) INTO cf_count FROM ccf WHERE ccf.create_time = action.cfCreationTime_con AND ccf.min_offr_recid <= action.recid_con AND ccf.ckp_scn >= action.toSCN_act AND ((user_site_key = ccf.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(ccf.site_key, this_site_key))))) AND ccf.min_offr_recid > 0; -- contains at least 1 record IF (cf_count = 0) THEN deb(DEB_EXIT, '(no controlfile copy with offline range)'|| ' with: action_FAIL'); RETURN action_FAIL; END IF; END IF; END IF; -- -- IF (addRedo_rc = action_OLD_INC_REDO) THEN rcvRecStackState.lowAction := 0; rcvRecStack.trim(rcvRecStack.last - greatest(rcvRecStackState.savePoint, rcvRecStackState.top)); deb(DEB_IN,'trimming stack, rcvRecStackCount='|| rcvRecStack.count); END IF; <> -- -- -- IF (validate_rc = SUCCESS AND action.type_con = backupSet_con_t AND (rmanCmd != obsoleteCmd_t OR (restoreTag IS NOT NULL AND this_baseline_cap >= 0))) THEN -- -- -- -- -- -- -- IF (validationRec.tag = restoreTag OR restoreTag IS NULL) THEN action.tag_con := validationRec.tag; END IF; action.deviceType_con := validationRec.deviceType; action.copyNumber_con := validationRec.copyNumber; END IF; IF (debug) THEN printRcvRec(action); END IF; IF (action.type_act = full_act_t) THEN IF (thisBackupAge < rcvRecBackupAge) THEN -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- deb(DEB_IN, 'skipping action because thisBackupAge (' || thisBackupAge || ') < rcvRecBackupAge(' || rcvRecBackupAge || ')'); thisBackupAge := thisBackupAge + 1; deb(DEB_EXIT, 'with: action_SKIP'); RETURN action_SKIP; END IF; -- IF (rcvRecStackState.fullBackups >= computeRA_fullBackups) THEN -- -- IF (rmanCmd = obsoleteCmd_t AND action.keep_options = 0) THEN deb(DEB_IN, 'skipping action because this action has NO KEEP'); deb(DEB_EXIT, 'with action_SKIP'); RETURN action_SKIP; ELSIF (rmanCmd != obsoleteCmd_t) THEN deb(DEB_IN, 'skipping action because stack has enough fullBackups'); deb(DEB_EXIT, 'with action_SKIP'); RETURN action_SKIP; END IF; END IF; END IF; -- IF (rmanCmd = obsoleteCmd_t and NOT isValidAction(action)) THEN deb(DEB_EXIT, 'with action_SKIP'); RETURN action_SKIP; END IF; rcvRecPush(action); -- add record for this action deb(DEB_IN, ' Added action:'); IF (allCopies AND action.type_con = backupSet_con_t) THEN -- deb(DEB_IN,'allCopies is TRUE, trying to add other copies'); validate_rc := validateBackupSet0(tag => restoreTag, tagMatchRequired => tagMatchRequired, checkDeviceIsAllocated => TRUE, validRec => validationRec); IF (validate_rc <> SUCCESS) THEN GOTO done; END IF; GOTO addAnother; END IF; <> -- IF (action.type_act = full_act_t) THEN -- deb(DEB_IN, ' action.type_act is range/full => setting savePoint='|| to_char(rcvRecStack.last)); rcvRecStackState.savePoint := rcvRecStack.last; -- -- IF (rmanCmd != obsoleteCmd_t OR action.keep_options = KEEP_NO) THEN rcvRecStackState.fullBackups := rcvRecStackState.fullBackups + 1; END IF; ELSIF (rcvRecStackState.lowAction = 0) THEN -- rcvRecStackState.lowAction := rcvRecStack.last; ELSIF (action.fromSCN_act < rcvRecStack(rcvRecStackState.lowAction).fromSCN_act) THEN rcvRecStackState.lowAction := rcvRecStack.last; -- new lowAction END IF; deb(DEB_EXIT, 'with: action_OK'); RETURN action_OK; END addAction; -- -- -- FUNCTION computeRecoveryActions2( fno IN number -- Datafile number. ,crescn IN number -- Datafile creation SCN. ,cretime IN date -- Datafile creation time. ,df_rlgscn IN number -- Datafile resetlogs SCN. -- -- -- ,df_rlgtime IN date -- Datafile resetlogs time. -- -- ,df_ckpscn IN number -- Datafile checkpoint SCN. -- -- ,offlscn IN number -- kccfeofs (may be 0). ,onlscn IN number -- kccfeonc (0 if offlscn is 0). ,onltime IN date -- kccfeonc_time (ignored if kccfeofs is 0) ,cleanscn IN number -- kccfecps if either SOR or WCC set, else 0. ,clean2scn IN number -- CF ckpt SCN if WCC set. -- ,clean2time IN date -- cf_checkpoint_time if WCC, -- ,allowfuzzy IN boolean -- TRUE if can be fuzzy at until SCN/time, -- ,partial_rcv IN boolean ,target_scn IN number -- This is the SCN to which we want to recover -- -- -- -- -- -- -- -- -- -- ,dbinc_key IN number -- The key of the database incarnation to -- -- -- ,cf_scn IN number ,cf_cretime IN date -- controlfile creation time. -- ,cf_offrrid IN number -- recid of oldest offline range in controlfile -- ,test_search IN boolean -- if TRUE, then we have called ourself -- -- ,done IN OUT boolean -- set to TRUE if successful. (IN mode so -- ,allCopies IN boolean -- if true, then stack all copies of -- ,recover IN boolean ,rmanCmd IN binary_integer ,foreignDbid IN number ,pluggedRonly IN binary_integer -- 1 => readonly, 0 => readwrite ,pluginSCN IN number ,pluginRlgSCN IN number ,pluginRlgTime IN date ,creation_thread IN number ,creation_size IN number ,pdbId IN number ,pdbForeignDbid IN number) -- -- -- -- -- -- -- RETURN boolean IS -- -- -- null_action rcvRec_t; action rcvRec_t; -- current row lastAction rcvRec_t; parentDbincKey number; -- my parent dbinc's key dbinc_rlgscn number; -- resetlogs scn for dbinc_key dbinc_rlgtime date; -- resetlogs time for dbinc_key CURSOR dbinc_cursor(db_key number, rstscn number) IS SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = dbinc_cursor.db_key AND dbinc.reset_scn < dbinc_cursor.rstscn; dbinc_row dbinc_cursor%ROWTYPE; savedrcvRecStackState rcvRecStackState_t; addAction_rc number; -- return code addRedo_rc number; -- return code isAncestor boolean; -- TRUE if we find an action we could -- rc boolean; -- return code from recursive search -- done_flag boolean; -- for use in recursive calls doingRecovery boolean; -- doing RECOVER stack_df_rlgscn number; savedBackupAge number; BEGIN deb(DEB_ENTER, 'computeRecoveryActions2'); done := FALSE; doingRecovery := recover; IF (doingRecovery is null) THEN -- -- IF (df_rlgscn is not null) THEN -- doing RECOVER doingRecovery := TRUE; ELSE doingRecovery := FALSE; END IF; END IF; IF (doingRecovery) THEN -- doing RECOVER deb(DEB_IN, ' Doing recovery.'); ELSE deb(DEB_IN, ' Not doing recovery.'); END IF; -- SELECT reset_scn, reset_time INTO dbinc_rlgscn, dbinc_rlgtime FROM dbinc WHERE dbinc.dbinc_key = computeRecoveryActions2.dbinc_key; IF (doingRecovery AND canApplyAnyRedo = FALSE# ) THEN -- -- -- -- IF (dbinc_rlgscn < df_rlgscn) THEN deb(DEB_IN, 'dbinc_rlgscn < df_rlgscn (' || to_char(dbinc_rlgscn) || ' < ' || to_char(df_rlgscn) || ')'); deb(DEB_EXIT,'computeRecoveryActions2 - 1 with FALSE'); RETURN FALSE; ELSIF (dbinc_rlgscn = df_rlgscn AND dbinc_rlgtime <> df_rlgtime) THEN deb(DEB_IN, 'dbinc_rlgtime <> df_rlgtime'); deb(DEB_EXIT,'computeRecoveryActions2 - 2 with FALSE'); RETURN FALSE; END IF; END IF; IF (not test_search) THEN -- -- deb(DEB_IN, ' This is ancestor.'); isAncestor := TRUE; ELSE isAncestor := FALSE; END IF; openRecoveryActionCursor( dbincKey => dbinc_key ,fno => fno ,creSCN => crescn ,dfCkpSCN => df_ckpscn ,dbincRlgSCN => dbinc_rlgscn ,dbincRlgTime => dbinc_rlgtime ,offlSCN => offlscn ,onlSCN => onlscn ,onlTime => onltime ,cleanSCN => cleanscn ,clean2SCN => clean2scn ,clean2Time => clean2time ,targetSCN => target_scn ,rmanCmd => rmanCmd ,foreignDbid => foreignDbid ,pluggedRonly => pluggedRonly ,pluginSCN => pluginSCN ,pluginRlgSCN => pluginRlgSCN ,pluginRlgTime=> pluginRlgTime); -- -- -- <> LOOP <> IF (fetchRecoveryAction( dbincKey => dbinc_key ,fno => fno ,creSCN => crescn ,dfCkpSCN => df_ckpscn ,dbincRlgSCN => dbinc_rlgscn ,dbincRlgTime => dbinc_rlgtime ,offlSCN => offlscn ,onlSCN => onlscn ,onlTime => onltime ,cleanSCN => cleanscn ,clean2SCN => clean2scn ,clean2Time => clean2time ,targetSCN => target_scn ,action => action ,rmanCmd => rmanCmd ,foreignDbid => foreignDbid ,pluggedRonly => pluggedRonly ,pluginSCN => pluginSCN ,pluginRlgSCN => pluginRlgSCN ,pluginRlgTime=> pluginRlgTime)) THEN deb(DEB_PRINT, 'fetched recovery action'); printRcvRec(action); -- -- -- IF (bitand(action.type_con, backupMask_con_t) > 0 AND action.toSCN_act = target_scn) THEN deb(DEB_IN, ' This is ancestor.'); isAncestor := TRUE; END IF; IF (action.type_con = offlineRangeRec_con_t) THEN -- -- -- deb(DEB_IN, ' found an offline range' || ' from=' || to_char(action.fromSCN_act) || ' to=' || to_char(action.toSCN_act)); IF (action.type_act = spanningRange_act_t) THEN -- -- -- deb(DEB_IN, ' offline range started before this resetlogs SCN'); -- -- -- addAction_rc := action_OK; ELSE addAction_rc := addAction(actionIN => action, partial_rcv => partial_rcv, isAncestor => isAncestor, cf_scn => cf_scn, cf_cretime => cf_cretime, cf_offrrid => cf_offrrid, doingRecovery => doingRecovery, rmanCmd => rmanCmd, pdbId => pdbId, cleanSCN => cleanSCN); END IF; ELSIF (action.type_con = backupSet_con_t AND action.type_act = incremental_act_t) THEN -- -- -- deb(DEB_IN, 'found an incremental backup set'); addAction_rc := addAction(actionIN => action, partial_rcv => partial_rcv, isAncestor => isAncestor, allCopies => allCopies, doingRecovery => doingRecovery, rmanCmd => rmanCmd, pdbId => pdbId, cleanSCN => cleanSCN); ELSIF (action.type_act = full_act_t) THEN -- -- -- deb(DEB_IN, 'found a copy/full/level0/proxy copy'); IF (doingRecovery) THEN -- if doing a RECOVER -- -- -- -- -- -- IF (rmanCmd = rcvCopyCmd_t) THEN addAction_rc := addAction(actionIN => action, partial_rcv => partial_rcv, isAncestor => isAncestor, allCopies => allCopies, doingRecovery => doingRecovery, rmanCmd => rmanCmd, pdbId => pdbId, cleanSCN => cleanSCN); ELSE IF (isAncestor) THEN rcvRecTop(lastAction); IF (not redoNeeded(action) OR canAddRedo(isAncestor, action.toSCN_act, action.rlgSCN_act, lastAction, partial_rcv, doingRecovery) <> action_OLD_REDO) THEN computeRA_restorable := TRUE; END IF; END IF; addAction_rc := action_SKIP; END IF; ELSE -- not doing a RECOVER addAction_rc := addAction(actionIN => action, partial_rcv => partial_rcv, isAncestor => isAncestor, allCopies => allCopies, doingRecovery => doingRecovery, rmanCmd => rmanCmd, pdbId => pdbId, cleanSCN => cleanSCN); END IF; ELSE -- -- -- deb(DEB_IN, 'unknown container type: ' || to_char(action.type_con) || ' or action type: ' || to_char(action.type_act)); -- -- deb(DEB_EXIT, 'with error 20999'); raise_application_error(-20999, 'unknown action kind'); END IF; -- "switch" on ACTION.KIND -- -- -- deb(DEB_IN, 'addAction returned code ' || to_char(addAction_rc)); IF (addAction_rc = action_OK) THEN -- the action was added -- -- -- IF (action.type_act = full_act_t AND this_baseline_cap >= 0 AND (action.toSCN_act < this_baseline_cap_scn OR this_baseline_cap_scn IS NULL)) THEN deb(DEB_IN, 'Found a backup older than baseline_cap'); done := TRUE; deb(DEB_PRINT,'done set to true - 0'); EXIT action_loop; END IF; IF (rcvRecStackState.savePoint > 0 AND computeRA_allRecords = FALSE# AND rcvRecStackState.fullBackups >= computeRA_fullBackups) THEN -- -- -- -- -- deb(DEB_IN, 'savePoint > 0' || ' and computeRA_allRecords = FALSE#'); done := TRUE; deb(DEB_PRINT,'done set to true - 1'); EXIT action_loop; END IF; IF (doingRecovery) THEN -- if doing RECOVER IF (action.type_con = offlineRangeRec_con_t) THEN -- -- IF (df_ckpscn = action.fromSCN_act) THEN done := TRUE; deb(DEB_PRINT,'done set to true - 2'); EXIT action_loop; END IF; ELSE -- -- IF (df_ckpscn >= action.fromSCN_act) THEN done := TRUE; deb(DEB_PRINT,'done set to true - 3'); EXIT action_loop; END IF; END IF; END IF; -- -- -- -- -- -- -- IF (action.type_con = offlineRangeRec_con_t AND action.fromSCN_act < dbinc_rlgscn AND canApplyAnyRedo = FALSE#) THEN deb(DEB_IN, 'offline range spanning a resetlogs'); -- -- -- -- -- -- -- SELECT parent_dbinc_key INTO parentDbincKey FROM dbinc WHERE dbinc.dbinc_key = computeRecoveryActions2.dbinc_key; IF (parentDbincKey is null) THEN -- we don't know our parent -- -- -- -- -- -- deb(DEB_OPEN, 'dbinc_cursor'); OPEN dbinc_cursor(this_db_key, dbinc_rlgscn); deb(DEB_IN, 'doing scan of all possible parent incarnations, top=' || to_char(rcvRecStack.last)); <> LOOP FETCH dbinc_cursor INTO dbinc_row; EXIT WHEN dbinc_cursor%NOTFOUND; deb(DEB_IN, 'starting test search of incarnation key=' || to_char(dbinc_row.dbinc_key)); savedrcvRecStackState := rcvRecStackState; rcvRecStackState.top := rcvRecStack.last; savedBackupAge := thisBackupAge; -- -- -- thisBackupAge := rcvRecBackupAge; rc := computeRecoveryActions2(fno, crescn, cretime, df_rlgscn, df_rlgtime, df_ckpscn, offlscn, onlscn, onltime, cleanscn, clean2scn, clean2time, allowfuzzy, partial_rcv, rcvRecStack(rcvRecStack.count).fromSCN_act, dbinc_row.dbinc_key, cf_scn, cf_cretime, cf_offrrid, TRUE, done_flag, allCopies, doingRecovery, rmanCmd, foreignDbid, pluggedRonly, pluginSCN, pluginRlgSCN, pluginRlgTime, creation_thread, creation_size, pdbId, pdbForeignDbid); -- -- -- -- deb(DEB_IN, 'last=' || to_char(rcvRecStack.last) || ' trimming last ' || to_char(rcvRecStack.last - rcvRecStackState.top) ); rcvRecStack.trim(rcvRecStack.last - rcvRecStackState.top); rcvRecStackState := savedrcvRecStackState; deb(DEB_PRINT,'restoring rcvRecStackCount after test search'||rcvRecStack.count); thisBackupAge := savedBackupAge; deb(DEB_IN, 'count is now '|| to_char(rcvRecStack.count)); IF (rc) THEN -- -- -- -- -- -- -- -- -- -- -- -- -- IF (parentDbincKey is null) THEN parentDbincKey := dbinc_row.dbinc_key; ELSE -- -- -- deb(DEB_IN, 'aborting search due to ambiguous ancestory'); CLOSE dbinc_cursor; EXIT action_loop; END IF; END IF; END LOOP; -- dbinc_loop END IF; -- if we don't know our parent -- -- IF (parentDbincKey is not null) THEN deb(DEB_IN, 'starting search of parent incarnation key='|| to_char(parentDbincKey)); rc := computeRecoveryActions2(fno, crescn, cretime, df_rlgscn, df_rlgtime, df_ckpscn, offlscn, onlscn, onltime, cleanscn, clean2scn, clean2time, allowfuzzy, partial_rcv, rcvRecStack(rcvRecStack.last).fromSCN_act, parentDbincKey, cf_scn, cf_cretime, cf_offrrid, FALSE, done_flag, allCopies, doingRecovery, rmanCmd, foreignDbid, pluggedRonly, pluginSCN, pluginRlgSCN, pluginRlgTime, creation_thread, creation_size, pdbId, pdbForeignDbid); IF (done_flag) THEN deb(DEB_PRINT,'done set to true - 4'); done := TRUE; END IF; IF (action.type_act = spanningRange_act_t) THEN -- -- -- -- -- -- isAncestor := rc; END IF; END IF; -- we know or found our parent EXIT action_loop; END IF; -- offline range start SCN < dbinc_rlgscn ELSIF (addAction_rc = action_FAIL) THEN -- FAIL -- -- NULL; ELSIF (addAction_rc = action_SKIP) THEN -- SKIP -- NULL; ELSIF (addAction_rc = action_OLD_REDO) THEN -- OLD_REDO -- -- -- -- -- -- EXIT action_loop; ELSE -- unknown return code deb(DEB_EXIT, 'with error 20999'); raise_application_error(-20999, 'unknown add action return code'); END IF; ELSE -- rcvRecCursor exhausted deb(DEB_IN, 'end of cursor reached'); EXIT action_loop; END IF; -- if fetchRecoveryAction END LOOP; IF (done) THEN deb(DEB_EXIT,'computeRecoveryActions2 - 3'); RETURN isAncestor; END IF; -- -- -- IF (doingRecovery) THEN -- if doing RECOVER deb(DEB_PRINT,'computeRecoveryActions2:recovery final check'); deb(DEB_IN, 'crescn=' || crescn ||';this_reset_scn='||this_reset_scn); deb(DEB_IN, 'df_rlgscn='||df_rlgscn||';df_rlgtime='|| to_char(df_rlgtime)); IF (rmanCmd = rcvCopyCmd_t) THEN -- -- -- deb(DEB_PRINT,'computeRecoveryActions2: no copies stacked'); resetrcvRecStack; done := FALSE; ELSIF (rcvRecStack.count > 0) THEN -- if found some action deb(DEB_PRINT,'computeRecoveryActions2:'|| rcvRecStack.count || ' actions stacked'); -- -- -- -- rcvRecTop(lastAction); stack_df_rlgscn := df_rlgscn; IF (df_rlgscn is NULL) THEN stack_df_rlgscn := this_reset_scn; END IF; addRedo_rc := addRedo(isAncestor, df_ckpscn, stack_df_rlgscn, lastAction, partial_rcv, doingRecovery); IF (addRedo_rc = action_OK OR addRedo_rc = action_FAIL OR addRedo_rc = action_OLD_INC_REDO) THEN -- -- -- -- -- -- done := TRUE; END IF; IF (addRedo_rc = action_OLD_INC_REDO) THEN -- rcvRecStack.trim(rcvRecStack.count); END IF; ELSE deb(DEB_PRINT,'computeRecoveryActions2: no actions stacked'); -- -- IF (df_rlgscn = this_reset_scn AND df_rlgtime = this_reset_time) THEN done := TRUE; ELSIF (action_OLD_INC_REDO = addRedo(isAncestor, df_ckpscn, df_rlgscn, null, partial_rcv, doingRecovery)) THEN done := TRUE; END IF; -- -- -- IF (df_rlgscn is NULL AND -- df may be created during rcv cretime > cf_cretime AND -- df created after cf creation crescn > nvl(inc_list(max_inc_idx-1).prior_resetlogs_change#, inc_list(max_inc_idx-1).resetlogs_change#)) THEN -- done := TRUE; END IF; END IF; ELSE -- not doing a RECOVER -- -- -- IF (rcvRecStackState.savePoint = 0) THEN -- -- -- -- -- deb(DEB_IN, 'could try create datafile'); rcvRecStack.trim(rcvRecStack.count - rcvRecStackState.top); rcvRecStackState.lowAction := rcvRecStack.count; deb(DEB_IN, 'rcvRecStackState :' || rcvRecStackState.top || ' ' || rcvRecStackState.savePoint || ' ' || rcvRecStackState.lowAction); -- -- -- -- -- -- -- IF ((computeRA_available = FALSE) AND -- no backup found pluginSCN = 0 AND -- not a plugin file foreignDbid = 0 AND -- not a foreign file pdbForeignDbid = 0 AND -- not a pdb plugin file (creation_thread IS NULL or creation_thread > 0) AND -- (creation_size IS NULL or creation_size > 0) AND -- (cretime > cf_cretime) AND -- df created after cf (crescn > nvl(inc_list(max_inc_idx-1).prior_resetlogs_change#, inc_list(max_inc_idx-1).resetlogs_change#)) AND -- (bitand(createdatafile_act_t, getRA_actionMask) != 0) AND -- restoreTag is null) THEN -- from tag not specified action := null_action; action.type_con := datafile_con_t; action.type_act := createdatafile_act_t; action.dfNumber_obj := fno; action.dfCreationSCN_obj := crescn; action.fromSCN_act := 0; action.toSCN_act := crescn; action.toTime_act := cretime; action.pluggedRonly_obj := 0; action.pluginSCN_obj := 0; FOR inc_idx in 0..max_inc_idx-1 LOOP IF (crescn > inc_list(inc_idx).resetlogs_change#) THEN deb(DEB_PRINT, 'data file created with resetlogs scn='|| inc_list(inc_idx).resetlogs_change#); action.rlgSCN_act := inc_list(inc_idx).resetlogs_change#; action.rlgTime_act := inc_list(inc_idx).resetlogs_time; exit; END IF; END LOOP; IF (action.rlgSCN_act IS NULL) THEN deb(DEB_IN, 'rlgSCN is null'); addAction_rc := action_FAIL; ELSE addAction_rc := addAction(actionIN => action, partial_rcv => partial_rcv, isAncestor => isAncestor, allCopies => allCopies, doingRecovery => doingRecovery, rmanCmd => rmanCmd, pdbId => pdbId, cleanSCN => cleanSCN); END IF; IF (addAction_rc = action_OK) THEN -- the action was added done := TRUE; deb(DEB_IN, 'added create datafile action for '||fno); ELSE deb(DEB_IN, 'failed to add create datafile action for '||fno); END IF; END IF; IF computeRA_available = TRUE THEN deb(DEB_IN, 'need different device type channels to restore'); END IF; ELSE -- -- -- -- -- deb(DEB_IN, 'trim all actions after savePoint='|| to_char(greatest(rcvRecStackState.savePoint, rcvRecStackState.top))); rcvRecStack.trim(rcvRecStack.last - greatest(rcvRecStackState.savePoint, rcvRecStackState.top)); done := TRUE; END IF; deb(DEB_PRINT,'computeRecoveryActions2: set rcvRecStackCount='||rcvRecStack.count); END IF; -- if doing recover IF (done) THEN deb(DEB_IN, 'done is TRUE'); ELSE deb(DEB_IN, 'done is FALSE'); END IF; deb(DEB_EXIT,'computeRecoveryActions2 - 4'); RETURN isAncestor; END computeRecoveryActions2; -- FUNCTION getParentIncarnation( dbinc_key OUT number ,resetlogs_change# OUT number) RETURN number IS BEGIN deb(DEB_ENTER, 'getParentIncarnation'); SELECT resetlogs_change#, parent_dbinc_key INTO resetlogs_change#, dbinc_key FROM rc_database_incarnation where dbinc_key = getParentIncarnationKey; deb(DEB_EXIT, 'with: TRUE#'); EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with: FALSE#'); RETURN FALSE#; END getParentIncarnation; -- -- -- FUNCTION getPointInTimeInc( toscn IN number) RETURN NUMBER IS pitrlgscn number; BEGIN IF (getPointInTimeInc.toscn >= this_reset_scn) THEN RETURN this_reset_scn; END IF; SELECT dbinc.reset_scn INTO pitrlgscn FROM (SELECT reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key) dbinc WHERE dbinc.reset_scn <= getPointInTimeInc.toscn AND dbinc.next_reset_scn > getPointInTimeInc.toscn; RETURN pitrlgscn; EXCEPTION WHEN no_data_found THEN RETURN NULL; END getPointInTimeInc; -- -- -- -- FUNCTION get_cfUntilScn RETURN number IS ret_scn number := untilSCN; max_scn number; max_tag bp.tag%type; -- CURSOR keepscn(scn NUMBER) IS SELECT bckscn, tag FROM (SELECT brl.next_scn bckscn, bp.tag FROM bs, brl, bp WHERE bs.bs_key = brl.bs_key AND bs.bs_key = bp.bs_key AND bs.keep_options > 0 AND bp.status = 'A' AND brl.low_scn <= scn AND brl.next_scn > scn AND this_site_key = bs.site_key AND this_dbinc_key = dbinc_key UNION SELECT xal.next_scn bckscn, xal.tag FROM xal WHERE xal.keep_options > 0 AND xal.status = 'A' AND xal.low_scn <= scn AND xal.next_scn > scn AND this_site_key = xal.site_key AND this_dbinc_key = dbinc_key UNION SELECT bdf.ckp_scn bckscn, bp.tag FROM bs, bdf, bp WHERE bs.bs_key = bdf.bs_key AND bs.bs_key = bp.bs_key AND bs.keep_options > 0 AND bp.status = 'A' AND bdf.ckp_scn = scn+1 AND this_site_key = bs.site_key AND this_dbinc_key = dbinc_key UNION SELECT xdf.ckp_scn bckscn, xdf.tag FROM xdf WHERE xdf.keep_options > 0 AND xdf.status = 'A' AND xdf.ckp_scn = scn+1 AND this_site_key = xdf.site_key AND this_dbinc_key = dbinc_key) ORDER BY bckscn DESC; BEGIN IF rpoint_set THEN -- OPEN keepscn(untilSCN - 1); FETCH keepscn INTO max_scn, max_tag; CLOSE keepscn; -- SELECT NVL(MIN(cfscn)+1, untilSCN) INTO ret_scn FROM (SELECT bcf.ckp_scn cfscn FROM bcf, bs, bp WHERE bcf.bs_key = bs.bs_key AND bs.bs_key = bp.bs_key AND bp.status = 'A' AND this_site_key = bs.site_key AND this_dbinc_key = dbinc_key AND bp.tag = max_tag AND bcf.ckp_scn > max_scn UNION ALL SELECT ckp_scn FROM ccf WHERE this_site_key = site_key AND this_dbinc_key = dbinc_key AND status = 'A' AND tag = max_tag AND ckp_scn > max_scn UNION ALL SELECT ckp_scn FROM xcf WHERE this_site_key = site_key AND this_dbinc_key = dbinc_key AND status = 'A' AND tag = max_tag AND ckp_scn > max_scn); deb(DEB_PRINT, 'new scn is ' || ret_scn); END IF; RETURN ret_scn; END get_cfUntilScn; -- -- FUNCTION IsDuplicateAlName(samelog IN number, filename varchar2) RETURN BOOLEAN IS duplicate number; BEGIN -- -- -- -- duplicate := FALSE#; IF (samelog = TRUE#) THEN FOR log_idx in 0..max_lognames_idx-1 LOOP IF lognames_list(log_idx) = filename THEN duplicate := TRUE#; EXIT; END IF; END LOOP; lognames_list(max_lognames_idx) := filename; max_lognames_idx := max_lognames_idx + 1; ELSE lognames_list(0) := filename; max_lognames_idx := 1; END IF; IF duplicate = TRUE# THEN deb(DEB_PRINT, 'Filter duplicate log name' || filename); RETURN TRUE; ELSE RETURN FALSE; END IF; END IsDuplicateAlName; -- -- -- -- -- -- PROCEDURE getCurrentIncarnation( db_id IN number ,reset_scn OUT number ,reset_time OUT date) IS BEGIN deb(DEB_ENTER, ' getCurrentIncarnation'); deb(DEB_IN, ' db_id=' || to_char(db_id)); SELECT dbinc.reset_scn, dbinc.reset_time INTO reset_scn, reset_time FROM db, dbinc WHERE db_id = getCurrentIncarnation.db_id -- should return 1 row AND dbinc.dbinc_key = db.curr_dbinc_key; deb(DEB_EXIT, 'reset_scn='||reset_scn||' reset_time='||reset_time); EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with error 20001'); raise_application_error(-20001, 'Database not found'); END; -- -- -- FUNCTION getPrimaryDfName( fno IN number) RETURN varchar2 IS local_fname varchar2(513); BEGIN SELECT fname INTO local_fname FROM site_dfatt s, df, node WHERE node.database_role = 'PRIMARY' AND node.db_key = this_db_key AND node.site_key = s.site_key AND s.df_key = df.df_key AND df.dbinc_key = node.dbinc_key AND df.file# = fno AND df.dbinc_key = this_dbinc_key AND df.drop_scn is NULL AND ROWNUM=1; RETURN local_fname; END getPrimaryDfName; -- PROCEDURE setDbincLst IS CURSOR inc_record_c IS SELECT * from rc_database_incarnation WHERE db_key=this_db_key START WITH dbinc_key=this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key ORDER BY resetlogs_change# DESC; CURSOR pdb_inc_record_c IS SELECT pdbinc.con_id con_id, pdbinc.pdbinc_key, pdbinc.inc_scn incscn, pdbinc.end_reset_scn erscn, pdbinc_status status FROM rci_pdbinc_this_dbinc pdbinc WHERE pdbinc.dbinc_key = this_dbinc_key AND pdbinc.con_id > 1 ORDER BY pdbinc.con_id, pdbinc.end_reset_scn DESC; inc_rec rc_database_incarnation%ROWTYPE; inc_idx binary_integer; pdb_inc_set pdb_incarnation_set_t; pdb_inc_rec pdb_incarnation_t; BEGIN deb(DEB_ENTER, 'setDbincLst'); IF this_dbinc_key is NULL OR this_db_key is NULL THEN raise_application_error(-20999, 'internal err: setDbincLst-1'); END IF; deb(DEB_PRINT, 'Setting incarnation records as per this_dbinc_key'); inc_idx := 0; FOR inc_rec IN inc_record_c LOOP inc_list(inc_idx) := inc_rec; deb(DEB_PRINT, 'incarnation record id=' || inc_idx); deb(DEB_PRINT, 'icprs=' ||inc_list(inc_idx).prior_resetlogs_change# || ',icprc='|| inc_list(inc_idx).prior_resetlogs_time); deb(DEB_PRINT, 'icrls=' || inc_list(inc_idx).resetlogs_change# || ',icrlc='|| inc_list(inc_idx).resetlogs_time); deb(DEB_PRINT, 'icpinc=' || inc_list(inc_idx).parent_dbinc_key); deb(DEB_PRINT, 'icflg=' || inc_list(inc_idx).status); inc_idx := inc_idx + 1; END LOOP; max_inc_idx := inc_idx; deb(DEB_PRINT, 'number of incarnation=' || max_inc_idx); -- deb(DEB_PRINT, 'Fetching pdb sub incarnation records'); pdb_inc_list.delete; FOR pdb_inc_rec in pdb_inc_record_c LOOP IF (NOT pdb_inc_list.exists(pdb_inc_rec.con_id)) THEN pdb_inc_list(pdb_inc_rec.con_id) := pdb_inc_set; END IF; inc_idx := pdb_inc_list(pdb_inc_rec.con_id).count; pdb_inc_list(pdb_inc_rec.con_id)(inc_idx) := pdb_inc_rec; deb(DEB_PRINT, 'incarnation record id=' || inc_idx); deb(DEB_PRINT, 'con_id=' || pdb_inc_rec.con_id || ',pdbinc_key=' || pdb_inc_rec.pdbinc_key); deb(DEB_PRINT, 'incscn=' || pdb_inc_rec.incscn || ',erscn=' || pdb_inc_rec.erscn); deb(DEB_PRINT, 'status=' || pdb_inc_rec.status); END LOOP; deb(DEB_EXIT); END setDbincLst; -- -- -- -- PROCEDURE setDatabase( db_name IN varchar2 ,reset_scn IN number ,reset_time IN date ,db_id IN number ,db_unique_name IN varchar2 default NULL ,site_aware IN boolean default FALSE ,dummy_instance IN boolean default FALSE ,ors_instance IN boolean default FALSE) IS local dbinc%rowtype; -- local variables dbnm dbinc.db_name%TYPE; dbnm_in dbinc.db_name%TYPE; current_inc varchar2(3); rid varchar2(18); ever_resynced number; BEGIN deb(DEB_ENTER, 'setDatabase'); this_db_key := NULL; -- clear in case exception raised this_dbinc_key := NULL; this_reset_scn := NULL; this_reset_time := NULL; this_db_unique_name := NULL; translation_site_key := NULL; this_site_key := NULL; dbnm_in := upper(db_name); -- BEGIN SELECT null INTO local.db_key FROM rcver WHERE version = catalogVersion; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with error 20299'); raise_application_error(-20299, 'Recovery catalog version mismatch'); END; -- -- -- -- IF (db_id is not NULL) THEN deb(DEB_IN, ' db_id=' || to_char(db_id)); IF dbms_rcvcat.registerDbPending.dbid = db_id THEN dbms_rcvcat.registerDatabase( db_id, dbnm_in, reset_scn, reset_time, db_unique_name, dbms_rcvcat.registerDbPending.con_id, dbms_rcvcat.registerDbPending.guid); END IF; BEGIN SELECT db.db_key, curr_dbinc_key, dbinc.reset_scn, dbinc.reset_time, dbinc.db_name INTO local.db_key, local.dbinc_key, local.reset_scn, local.reset_time, local.db_name FROM db, dbinc WHERE db_id = setDatabase.db_id -- should return 1 row AND dbinc.dbinc_key = db.curr_dbinc_key; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with error 20001'); raise_application_error(-20001, 'Database not found'); END; -- IF (dbnm_in is NOT NULL) THEN -- -- -- -- BEGIN SELECT decode(dbinc.dbinc_key, db.curr_dbinc_key, 'YES', 'NO'), dbinc.db_name, dbinc.rowid INTO current_inc, dbnm, rid FROM db, dbinc WHERE db.db_key = dbinc.db_key AND db.db_id = setDatabase.db_id AND dbinc.reset_scn = setDatabase.reset_scn AND dbinc.reset_time = setDatabase.reset_time; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with error 20003'); raise_application_error(-20003, 'Database incarnation not found'); END; IF (current_inc = 'NO') THEN deb(DEB_EXIT, 'with error 20011'); raise_application_error(-20011, 'Database incarnation not current'); END IF; IF (dbnm != dbnm_in) THEN deb(DEB_PRINT, 'DB_NAME changed from '||dbnm||' to '|| dbnm_in); UPDATE dbinc SET dbinc.db_name = dbnm_in WHERE rowid = rid; COMMIT; END IF; END IF; ELSIF (dbnm_in is NOT NULL) THEN -- deb(DEB_IN, 'db_id is null'); BEGIN SELECT db.db_key, db.curr_dbinc_key, dbinc.reset_scn, dbinc.reset_time INTO local.db_key, local.dbinc_key, local.reset_scn, local.reset_time FROM db, dbinc WHERE db.curr_dbinc_key = dbinc.dbinc_key AND dbinc.db_name = dbnm_in; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with error 20001'); raise_application_error(-20001, 'Database not found'); WHEN too_many_rows THEN deb(DEB_EXIT, 'with error 20005'); raise_application_error(-20005, 'Database name is ambiguous'); END; ELSE deb(DEB_EXIT, 'with error 20006'); raise_application_error(-20006, 'Database name is missing'); END IF; -- -- IF dummy_instance THEN deb(DEB_PRINT, 'dummy_instance is TRUE'); this_dummy_instance := TRUE; END IF; this_db_unique_name := upper(db_unique_name); this_db_key := local.db_key; this_dbinc_key := local.dbinc_key; this_reset_scn := local.reset_scn; this_reset_time := local.reset_time; -- -- -- IF ors_instance THEN IF db_unique_name IS NULL THEN raise_application_error(-20999, 'internal error:db_unique_name must be specified for ORS instance'); END IF; IF db_id IS NULL THEN raise_application_error(-20999, 'internal error: db_id must be specified for ORS instance'); END IF; IF instr(this_db_unique_name, '$'|| db_id) = 0 THEN this_db_unique_name := this_db_unique_name || '$' || db_id; END IF; IF substr(this_db_unique_name, 1, 1) <> '$' THEN this_db_unique_name := '$' || this_db_unique_name; END IF; END IF; deb(DEB_PRINT, 'this_db_unique_name= ' || this_db_unique_name); deb(DEB_PRINT, 'this_site_key= ' || this_site_key); deb(DEB_PRINT, 'this_db_key='||this_db_key); deb(DEB_PRINT, 'this_dbinc_key='||this_dbinc_key); setDbincLst; BEGIN SELECT site_key into this_site_key FROM node where db_unique_name=upper(this_db_unique_name) AND db_key = this_db_key; deb(DEB_PRINT, 'this_site_key=' || this_site_key); EXCEPTION WHEN no_data_found THEN deb(DEB_PRINT, 'this_site_key is NULL'); END; BEGIN IF site_aware THEN client_site_aware := 1; deb(DEB_PRINT, 'client_site_aware=' || client_site_aware); END IF; IF NOT ors_instance AND site_aware AND this_site_key is not NULL THEN translation_site_key := this_site_key; deb(DEB_PRINT, 'translation_site_key=' || translation_site_key); ELSE BEGIN SELECT site_key into translation_site_key FROM node WHERE database_role='PRIMARY' AND db_key = this_db_key; deb(DEB_PRINT, 'translation_site_key(primary)=' || translation_site_key); EXCEPTION WHEN no_data_found THEN -- -- -- -- -- -- -- -- select count(*) into ever_resynced from rci_datafile where site_key = this_site_key; IF ever_resynced > 0 THEN translation_site_key := this_site_key; ELSE select max(site_key) into translation_site_key from node where db_key=this_db_key; END IF; deb(DEB_PRINT, 'translation_site_key(no_data_found)=' || translation_site_key); WHEN too_many_rows THEN -- -- -- -- select max(site_key) into translation_site_key from node where db_key=this_db_key and database_role ='PRIMARY'; deb(DEB_PRINT, 'translation_site_key(too_many_rows)=' || translation_site_key); END; END IF; EXCEPTION WHEN no_data_found THEN deb(DEB_PRINT, 'translation_site_key is NULL'); END; IF site_aware AND this_site_key is NULL THEN this_site_key := translation_site_key; deb(DEB_PRINT, 'this_site_key is set to same as translation_site_key'); END IF; IF site_aware THEN setArchiveFileScopeAttributes(logs_shared => 0); setBackupFileScopeAttributes (disk_backups_shared => 0, tape_backups_shared => 1); END IF; deb(DEB_EXIT); END setDatabase; -- FUNCTION getDbUniqueName( db_id IN number) RETURN varchar2 IS dbunqnm node.db_unique_name%TYPE; CURSOR dbunqnm_c IS SELECT node.db_unique_name FROM node, db WHERE db.db_id = getDbUniqueName.db_id AND db.db_key = node.db_key; BEGIN SELECT node.db_unique_name INTO dbunqnm FROM node, db WHERE db.db_id = getDbUniqueName.db_id AND db.db_key = node.db_key; RETURN dbunqnm; EXCEPTION WHEN no_data_found THEN RETURN NULL; END getDbUniqueName; -- FUNCTION getDbKey RETURN NUMBER IS BEGIN return this_db_key; END; -- FUNCTION getMinRcvStartScn RETURN NUMBER IS minrcvstartScn NUMBER; BEGIN SELECT NVL(min(LOW_SCN), 0) INTO minrcvstartScn FROM rrcache WHERE range_type = 'RA$DISK' AND db_key = this_db_key; RETURN minrcvstartScn; END; -- PROCEDURE resetDbKey IS BEGIN this_db_key := NULL; END; -- PROCEDURE setDbincKey( key IN number) IS BEGIN deb(DEB_ENTER, 'setDbincKey'); IF (key is not null) THEN this_dbinc_key := key; ELSE -- SELECT curr_dbinc_key INTO this_dbinc_key FROM db; END IF; SELECT db_key, reset_scn, reset_time INTO this_db_key, this_reset_scn, this_reset_time FROM dbinc WHERE dbinc_key = this_dbinc_key; setDbincLst; deb(DEB_EXIT); END setDbincKey; -- FUNCTION getParentIncarnation( resetlogs_change# IN OUT number ,resetlogs_time IN OUT date) RETURN number IS BEGIN deb(DEB_ENTER, 'getParentIncarnation'); -- -- IF (resetlogs_change# is null) THEN getParentIncarnationKey := this_dbinc_key; END IF; SELECT resetlogs_change#, resetlogs_time, parent_dbinc_key INTO resetlogs_change#, resetlogs_time, getParentIncarnationKey FROM rc_database_incarnation where dbinc_key = getParentIncarnationKey; deb(DEB_EXIT, 'with: TRUE#'); RETURN TRUE#; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with: FALSE#'); RETURN FALSE#; END getParentIncarnation; -- PROCEDURE getCheckpoint( scn OUT number ,seq OUT number ,ckp_key_1 OUT number ,ckp_key_2 OUT number) IS full_row ckp%ROWTYPE; either_row ckp%ROWTYPE; BEGIN deb(DEB_ENTER, 'getCheckpoint'); IF (this_dbinc_key is NULL) THEN deb(DEB_EXIT, 'with error 20020'); raise_application_error(-20020, 'Database incarnation not set'); END IF; -- -- -- -- -- -- -- -- -- -- -- -- FOR r IN (SELECT /*+ first_rows */ * FROM ckp WHERE dbinc_key = this_dbinc_key AND ckp_type = 'FULL' AND site_key = this_site_key ORDER BY ckp_scn DESC, cf_create_time DESC, ckp_cf_seq DESC) LOOP full_row := r; EXIT; END LOOP; FOR r IN (SELECT /*+ first_rows */ * FROM ckp WHERE dbinc_key = this_dbinc_key AND cf_create_time = full_row.cf_create_time AND site_key = this_site_key ORDER BY ckp_scn DESC, ckp_cf_seq DESC, ckp_type DESC) LOOP either_row := r; EXIT; END LOOP; IF either_row.ckp_key IS NOT NULL THEN scn := either_row.ckp_scn; seq := either_row.ckp_cf_seq; ckp_key_1 := full_row.ckp_key; ckp_key_2 := either_row.ckp_key; ELSE scn := 0; seq := 0; ckp_key_1 := 0; ckp_key_2 := 0; END IF; deb(DEB_EXIT); END getCheckpoint; PROCEDURE getCheckpoint( scn OUT number ,seq OUT number) IS ckp_key_1 number; ckp_key_2 number; BEGIN getCheckpoint(scn, seq, ckp_key_1, ckp_key_2); END getCheckpoint; -- -- -- -- PROCEDURE setUntilTime( unttime IN date) IS walk_dbinc_key number := NULL; parent_dbinc_key number := NULL; BEGIN deb(DEB_ENTER, 'setUntilTime'); IF (this_dbinc_key is NULL) THEN deb(DEB_EXIT, 'with error 20020'); raise_application_error(-20020, 'Database incarnation not set'); END IF; walk_dbinc_key := this_dbinc_key; <> untilSCN := NULL; untilTime := unttime; rpoint_set := FALSE; BEGIN SELECT resetlogs_change# INTO untilSCN FROM rc_database_incarnation WHERE dbinc_key = walk_dbinc_key AND resetlogs_time < untilTime; EXCEPTION WHEN no_data_found THEN BEGIN IF (allIncarnations = TRUE#) THEN SELECT parent_dbinc_key INTO parent_dbinc_key FROM dbinc WHERE dbinc.dbinc_key = walk_dbinc_key; walk_dbinc_key := parent_dbinc_key; IF (walk_dbinc_key IS NULL) THEN deb(DEB_IN, 'parent_dbinc_key=NULL -> exiting'); untilSCN := 0; -- begining of world ELSE deb(DEB_IN, 'parent_dbinc_key=' || to_char(parent_dbinc_key)); GOTO parent_inc; -- get scn of parent incarnation END IF; ELSE deb(DEB_EXIT, 'with error 20207'); raise_application_error(-20207, 'until time is before resetlogs time'); END IF; END; END; IF walk_dbinc_key != this_dbinc_key THEN actual_dbinc_key := walk_dbinc_key; deb(DEB_IN, 'actual_dbinc_key set to: '||to_char(actual_dbinc_key)); END IF; -- -- -- -- -- deb(DEB_IN, 'calling computeUntilSCN. untilSCN= '||to_char(untilSCN)); deb(DEB_IN, 'calling computeUntilSCN. untilTime= '||to_char(untilTime)); computeUntilSCN(untilTime, untilSCN, allIncarnations); deb(DEB_IN, 'untilSCN= '||to_char(untilSCN)); deb(DEB_EXIT, 'untilTime='||to_char(untilTime)); IF (untilSCN IS NULL) THEN raise_application_error(-20213, 'UNTIL TIME could not be translated to an UNTIL CHANGE'); END IF; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with error 20207'); raise_application_error(-20207, 'until time is before resetlogs time'); END setUntilTime; -- PROCEDURE setUntilScn( scn IN number ,rlgscn IN number DEFAULT NULL ,rlgtime IN date DEFAULT NULL ,flbrp IN boolean DEFAULT FALSE ,rpoint IN boolean DEFAULT FALSE) IS walk_dbinc_key number := NULL; walk_dbinc_scn number := NULL; walk_dbinc_time date := NULL; parent_dbinc_key number := NULL; BEGIN deb(DEB_ENTER, 'setUntilSCN'); IF (this_dbinc_key is NULL) THEN deb(DEB_EXIT, 'with error 20020'); raise_application_error(-20020, 'Database incarnation not set'); END IF; IF (flbrp AND rlgscn IS NOT NULL AND rlgtime IS NOT NULL) THEN -- -- BEGIN SELECT dbinc_key INTO walk_dbinc_key FROM rc_database_incarnation WHERE resetlogs_change# = rlgscn AND resetlogs_time = rlgtime AND db_key = this_db_key; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with error 20212'); raise_application_error(-20212, 'until SCN is an orphan incarnation'); END; ELSE walk_dbinc_Key := this_dbinc_key; END IF; <> untilSCN := scn; untilTime := NULL; BEGIN SELECT untilSCN, resetlogs_change#, resetlogs_time INTO untilSCN, walk_dbinc_scn, walk_dbinc_time FROM rc_database_incarnation WHERE dbinc_key = walk_dbinc_key AND resetlogs_change# < untilSCN; EXCEPTION WHEN no_data_found THEN BEGIN IF (allIncarnations = TRUE#) THEN SELECT parent_dbinc_key INTO parent_dbinc_key FROM dbinc WHERE dbinc.dbinc_key = walk_dbinc_key; walk_dbinc_key := parent_dbinc_key; IF (walk_dbinc_key IS NULL) THEN deb(DEB_EXIT, 'parent_dbinc_key=NULL, with error 20208'); raise_application_error(-20208, 'until SCN is before resetlogs SCN'); ELSE deb(DEB_IN, 'parent_dbinc_key=' || to_char(parent_dbinc_key)); GOTO parent_inc; -- get scn of parent incarnation END IF; ELSE deb(DEB_EXIT, 'with error 20208'); raise_application_error(-20208, 'until SCN is before resetlogs SCN'); END IF; END; END; IF (rlgscn != walk_dbinc_scn OR rlgtime != walk_dbinc_time) THEN deb(DEB_EXIT, 'with error 20212'); raise_application_error(-20212, 'until SCN is an orphan incarnation'); END IF; -- rpoint_set := rpoint and not flbrp; IF walk_dbinc_key != this_dbinc_key THEN actual_dbinc_key := walk_dbinc_key; deb(DEB_IN, 'actual_dbinc_key set to: '||to_char(actual_dbinc_key)); END IF; deb(DEB_EXIT); EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with error 20208'); raise_application_error(-20208,'until SCN is before resetlogs SCN'); END setUntilScn; -- PROCEDURE setUntilLog( sequence# IN number ,thread# IN number) IS walk_dbinc_key number := NULL; parent_dbinc_key number := NULL; BEGIN deb(DEB_ENTER, 'setUntilLog'); rpoint_set := FALSE; IF (this_dbinc_key is NULL) THEN deb(DEB_EXIT, 'with error 20020'); raise_application_error(-20020, 'Database incarnation not set'); END IF; IF (sequence# is NULL) THEN deb(DEB_EXIT, 'with error 20205'); raise_application_error(-20205, 'Incomplete UNTIL clause'); END IF; walk_dbinc_Key := this_dbinc_key; <> untilTime := NULL; untilSCN := NULL; BEGIN -- SELECT first_change# INTO untilSCN FROM rc_log_history WHERE dbinc_key = walk_dbinc_key AND thread# = nvl(setUntilLog.thread#, 1) -- default thread# is 1 AND sequence# = setUntilLog.sequence#; EXCEPTION WHEN no_data_found THEN BEGIN -- -- SELECT next_change# INTO untilSCN FROM rc_log_history WHERE dbinc_key = this_dbinc_key -- AND thread# = nvl(setUntilLog.thread#, 1) AND sequence# = setUntilLog.sequence# - 1; EXCEPTION WHEN no_data_found THEN BEGIN IF (allIncarnations = TRUE#) THEN SELECT parent_dbinc_key INTO parent_dbinc_key FROM dbinc WHERE dbinc.dbinc_key = walk_dbinc_key; walk_dbinc_key := parent_dbinc_key; IF (walk_dbinc_key IS NULL) THEN deb(DEB_EXIT, 'with error 20206'); raise_application_error(-20206, 'Specified log does not exist'); ELSE deb(DEB_IN, 'parent_dbinc_key=' || to_char(parent_dbinc_key)); GOTO parent_inc; -- get scn of parent incarnation END IF; ELSE deb(DEB_EXIT, 'with error 20206'); raise_application_error(-20206, 'Specified log does not exist'); END IF; END; END; END; IF walk_dbinc_key != this_dbinc_key THEN actual_dbinc_key := walk_dbinc_key; deb(DEB_IN, 'actual_dbinc_key set to: '||to_char(actual_dbinc_key)); END IF; deb(DEB_EXIT); END setUntilLog; -- PROCEDURE setToLog( sequence# IN number ,thread# IN number) IS BEGIN deb(DEB_ENTER, 'setToLog'); untilTime := NULL; untilSCN := NULL; rpoint_set := FALSE; IF (this_dbinc_key is NULL) THEN deb(DEB_EXIT, 'with error 20020'); raise_application_error(-20020, 'Database incarnation not set'); END IF; IF (sequence# is NULL) THEN deb(DEB_EXIT, 'with error 20205'); raise_application_error(-20205, 'Incomplete TO clause'); END IF; BEGIN -- SELECT (next_change# - 1) INTO untilSCN FROM rc_log_history WHERE dbinc_key = this_dbinc_key AND thread# = nvl(setToLog.thread#, 1) -- default thread# is 1 AND sequence# = setToLog.sequence#; EXCEPTION WHEN no_data_found THEN BEGIN -- -- SELECT (first_change# - 1) INTO untilSCN FROM rc_log_history WHERE dbinc_key = this_dbinc_key -- AND thread# = nvl(setToLog.thread#, 1) AND sequence# = setToLog.sequence# + 1; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with error 20206'); raise_application_error(-20206, 'Specified log does not exist'); END; END; deb(DEB_EXIT); END setToLog; -- PROCEDURE getRedoLogDeletionPolicy( policy OUT varchar2) IS BEGIN raise_application_error(-20999, 'Not supported in recovery catalog'); END getRedoLogDeletionPolicy; -- PROCEDURE setRedoLogDeletionPolicy( policy IN varchar2 ,alldest IN number) IS BEGIN raise_application_error(-20999, 'Not supported in recovery catalog'); END setRedoLogDeletionPolicy; -- PROCEDURE resetAll( transclause IN boolean DEFAULT TRUE) IS BEGIN deb(DEB_PRINT, 'resetAll'); -- setRAflags(kindMask => allKind, allRecords => FALSE); setAllFlag(FALSE); setLikePattern(NULL); setCompletedRange(after => NULL, before => NULL); resetUntil; setFrom(NULL); resetDeviceType; setTag(NULL); -- restoreTag := NULL setStandby(NULL); setGuid(NULL); versionCounter := 1; -- for getPackageVersion getArchivedLogCursor := NULL; getBackupPieceCursor := NULL; getDatafileCopyCursor := NULL; getDatafileCursor := NULL; getProxyCopyCursor := NULL; localOrsSiteKey := NULL; IF (transclause) THEN deb(DEB_PRINT, 'reset transclause'); resetAlTransClause; -- reset AlTransClause resetDBTransClause; -- reset DBTransClause resetDbidTransClause; -- reset DbidTransClause resetPdbIdList; -- reset PdbIdList resetPdbNameList; -- reset PdbNameList resetPdbFileList; -- reset PdbFileList END IF; resetBsRecCache(FALSE); -- reset findvalid backupset cache setRcvRecBackupAge(0); -- reset backup age variables setRecoveryDestFile(FALSE); -- reset to all files setOrsFile(NULL, NULL); -- reset to all files findSpfileBackupCursor := FALSE; findControlfileBackupCursor := FALSE; -- rcvRecCursor.currc1.type_con := to_number(null); rcvRecCursor.reqfno := to_number(null); rcvRecCursor.reqcrescn := to_number(null); rcvRecCursor.reqpluginSCN := 0; rcvRecCursor.excludeAction := 0; -- resetrcvRecStack; pname_i := 0; -- reset debuging IF findControlfileBackup_c%ISOPEN THEN CLOSE findControlfileBackup_c; END IF; IF findSpfileBackup_c%ISOPEN THEN CLOSE findSpfileBackup_c; END IF; IF findControlFileCopyKey%ISOPEN THEN CLOSE findControlFileCopyKey; END IF; IF findDatafileCopyKey%ISOPEN THEN CLOSE findDatafileCopyKey; END IF; IF findDatafileBackup_c%ISOPEN THEN CLOSE findDatafileBackup_c; END IF; IF findProxyCopy%ISOPEN THEN CLOSE findProxyCopy; END IF; IF findProxyCopyKey%ISOPEN THEN CLOSE findProxyCopyKey; END IF; IF findArchivedLogCopy%ISOPEN THEN CLOSE findArchivedLogCopy; END IF; IF findArcLogBackup%ISOPEN THEN CLOSE findArcLogBackup; END IF; IF findRangeArcLogBackup%ISOPEN THEN CLOSE findRangeArcLogBackup; END IF; IF findValidBackupSet_c%ISOPEN THEN CLOSE findValidBackupSet_c; END IF; IF findValidBackupSet1P_c%ISOPEN THEN CLOSE findValidBackupSet1P_c; END IF; IF findBackupPiece_c%ISOPEN THEN CLOSE findBackupPiece_c; END IF; IF findBackupPieceBpKey%ISOPEN THEN CLOSE findBackupPieceBpKey; END IF; IF findBackupPieceBsKey1%ISOPEN THEN CLOSE findBackupPieceBsKey1; END IF; IF findBackupPieceBsKey2%ISOPEN THEN CLOSE findBackupPieceBsKey2; END IF; IF translateDatabase_c%ISOPEN THEN CLOSE translateDatabase_c; END IF; IF translateDatabaseOfPdbId_c%ISOPEN THEN CLOSE translateDatabaseOfPdbId_c; END IF; IF translateDatabaseOfPdbIdL_c%ISOPEN THEN CLOSE translateDatabaseOfPdbIdL_c; END IF; IF translateTablespace_c%ISOPEN THEN CLOSE translateTablespace_c; END IF; IF translateDatafileName%ISOPEN THEN CLOSE translateDatafileName; END IF; IF translateDatafileNumber%ISOPEN THEN CLOSE translateDatafileNumber; END IF; IF translateDatafileCheckpoint%ISOPEN THEN CLOSE translateDatafileCheckpoint; END IF; IF translateAllDf_c%ISOPEN THEN CLOSE translateAllDf_c; END IF; IF translateAllDfOfPdbId_c%ISOPEN THEN CLOSE translateAllDfOfPdbId_c; END IF; IF translateAllDfOfPdbIdL_c%ISOPEN THEN CLOSE translateAllDfOfPdbIdL_c; END IF; IF translateCorruptList_c%ISOPEN THEN CLOSE translateCorruptList_c; END IF; IF translateTempfile_c%ISOPEN THEN CLOSE translateTempfile_c; END IF; IF translateTempfileOfPdbId_c%ISOPEN THEN CLOSE translateTempfileOfPdbId_c; END IF; IF translateTempfileOfPdbIdL_c%ISOPEN THEN CLOSE translateTempfileOfPdbIdL_c; END IF; IF translateTempfileName_c%ISOPEN THEN CLOSE translateTempfileName_c; END IF; IF translateTempfileNumber_c%ISOPEN THEN CLOSE translateTempfileNumber_c; END IF; IF translateOnlineLogs_c%ISOPEN THEN CLOSE translateOnlineLogs_c; END IF; IF translateArcLogKey%ISOPEN THEN CLOSE translateArcLogKey; END IF; IF translateArcLogName%ISOPEN THEN CLOSE translateArcLogName; END IF; IF translateArcLogSeqRange%ISOPEN THEN CLOSE translateArcLogSeqRange; END IF; IF translateArcLogSeqRange2%ISOPEN THEN CLOSE translateArcLogSeqRange2; END IF; IF translateArcLogTimeRange%ISOPEN THEN CLOSE translateArcLogTimeRange; END IF; IF translateArcLogTimeRange2%ISOPEN THEN CLOSE translateArcLogTimeRange2; END IF; IF translateArcLogSCNRange%ISOPEN THEN CLOSE translateArcLogSCNRange; END IF; IF translateArcLogSCNRange2%ISOPEN THEN CLOSE translateArcLogSCNRange2; END IF; IF translateArcLogPattern%ISOPEN THEN CLOSE translateArcLogPattern; END IF; IF lbal2%ISOPEN THEN CLOSE lbal2; END IF; IF ldbi%ISOPEN THEN CLOSE ldbi; END IF; IF lnni%ISOPEN THEN CLOSE lnni; END IF; IF lrtbs%ISOPEN THEN CLOSE lrtbs; END IF; IF getOfflineRangeCopy_c%ISOPEN THEN CLOSE getOfflineRangeCopy_c; END IF; IF rddf%ISOPEN THEN CLOSE rddf; END IF; IF translateDatabaseCorruption_c%ISOPEN THEN CLOSE translateDatabaseCorruption_c; END IF; IF findConfig_c%ISOPEN THEN CLOSE findConfig_c; END IF; IF findBackupsetFiles%ISOPEN THEN CLOSE findBackupsetFiles; END IF; IF findAllBackupPiece%ISOPEN THEN CLOSE findAllBackupPiece; END IF; IF dfBackupHistory_c1%ISOPEN THEN CLOSE dfBackupHistory_c1; END IF; IF dfBackupHistory_c2%ISOPEN THEN CLOSE dfBackupHistory_c2; END IF; IF dcBackupHistory_c%ISOPEN THEN CLOSE dcBackupHistory_c; END IF; IF alBackupHistory_c1%ISOPEN THEN CLOSE alBackupHistory_c1; END IF; IF alBackupHistory_c2%ISOPEN THEN CLOSE alBackupHistory_c2; END IF; IF bsBackupHistory_c1%ISOPEN THEN CLOSE bsBackupHistory_c1; END IF; IF bsBackupHistory_c1%ISOPEN THEN CLOSE bsBackupHistory_c1; END IF; IF getCopyofDatafile_c%ISOPEN THEN CLOSE getCopyofDatafile_c; END IF; IF getCopyofDatafile_c2%ISOPEN THEN CLOSE getCopyofDatafile_c2; END IF; IF rcvRecCursor1_c%ISOPEN THEN CLOSE rcvRecCursor1_c; END IF; IF rcvRecCursor1Filter_c%ISOPEN THEN CLOSE rcvRecCursor1Filter_c; END IF; IF rcvRecCursor2_c%ISOPEN THEN CLOSE rcvRecCursor2_c; END IF; IF listBackup_c%ISOPEN THEN CLOSE listBackup_c; END IF; IF translatePdbName_c%ISOPEN THEN CLOSE translatePdbName_c; END IF; IF translatePdbFile_c%ISOPEN THEN CLOSE translatePdbFile_c; END IF; getArchivedLogLast := NULL; -- clear for next time getArchivedLogDoingRecovery := FALSE#; -- clear for next time getArchivedLogOnlyrdf := 0; lbacked_al_next_scn := NULL; standby_became_primary_scn := NULL; getrcvRecLast := NULL; setSkipOfflineRangeAboveSCN(NULL); END resetAll; -- -- -- -- PROCEDURE findValidBackupSet( backupSetRec IN rcvRec_t ,deviceType IN varchar2 DEFAULT NULL ,tag IN varchar2 DEFAULT NULL ,available IN number DEFAULT TRUE# -- for compat. ,unavailable IN number DEFAULT FALSE# -- for compat. ,deleted IN number DEFAULT FALSE# -- for compat. ,expired IN number DEFAULT FALSE# -- for compat. ,availableMask IN binary_integer DEFAULT NULL) -- for compat. IS BEGIN deb(DEB_ENTER, 'findValidBackupSet'); IF (bsRecCacheEnabled) THEN cacheFindValidBackupSet( bsRec => backupSetRec, deviceType => deviceType, tag => tag, availableMask => NVL(availableMask, computeAvailableMask(available, unavailable, deleted, expired))); ELSE findValidBackupSet( bsKey => backupSetRec.bsKey_con, pieceCount => backupSetRec.pieceCount_con, deviceType => deviceType, tag => tag, availableMask => NVL(availableMask, computeAvailableMask(available, unavailable, deleted, expired))); END IF; deb(DEB_EXIT); END findValidBackupSet; -- -- PROCEDURE findValidBackupSet( backupSetRec IN bsRec_t ,deviceType IN varchar2 DEFAULT NULL ,tag IN varchar2 DEFAULT NULL ,available IN number DEFAULT TRUE# -- for compat. ,unavailable IN number DEFAULT FALSE# -- for compat. ,deleted IN number DEFAULT FALSE# -- for compat. ,expired IN number DEFAULT FALSE# -- for compat. ,availableMask IN binary_integer DEFAULT NULL) -- for compat. IS BEGIN deb(DEB_ENTER, 'findValidBackupSet bsRec_t'); findValidBackupSet(bsKey => backupSetRec.key, pieceCount => backupSetRec.pieceCount, deviceType => deviceType, tag => tag, availableMask => NVL(availableMask, computeAvailableMask(available, unavailable, deleted, expired))); deb(DEB_EXIT); END findValidBackupSet; -- -- PROCEDURE getDatafile( file# OUT number ,crescn OUT number ,creation_time OUT date ,fname OUT varchar2 ,ts_name OUT varchar2 ,status OUT number ,blksize OUT number ,kbytes OUT number ,blocks OUT number ,unrecoverable_change# OUT number ,stop_change# OUT number ,read_only OUT number) IS dfRec dfRec_t; BEGIN deb(DEB_ENTER, 'getDataFile_2'); getDatafile(dfRec, oldClient => TRUE); file# := dfRec.dfNumber; crescn := dfRec.dfCreationSCN; creation_time := dfRec.dfCreationTime; fname := dfRec.fileName; ts_name := dfRec.tsName; status := 0; -- this is kccfesta, which we don't have blksize := dfRec.blockSize; kbytes := dfRec.kbytes; blocks := dfRec.blocks; unrecoverable_change# := 0; -- this is kccfeurs which isn't kept in rcvcat stop_change# := dfRec.stopSCN; read_only := dfRec.readOnly; deb(DEB_EXIT); EXCEPTION WHEN no_data_found THEN -- file# := NULL; deb(DEB_EXIT, 'with no more records'); END getDatafile; -- -- -- -- -- -- -- -- -- PROCEDURE listTranslateProxyDFRecid( recid IN number ,stamp IN number ,xdf_key OUT number ,file# OUT number ,status OUT varchar2 ,handle OUT varchar2 ,completion_time OUT date ,checkpoint_change# OUT number ,checkpoint_time OUT date) IS BEGIN deb(DEB_ENTER, 'listTranslateProxyDFRecid'); -- -- -- -- -- IF (recid <> rcvRec_last.recid_con OR stamp <> rcvRec_last.stamp_con) THEN select d.xdf_key, d.file#, d.status, d.handle, d.completion_time, d.checkpoint_change#, d.checkpoint_time into xdf_key, file#, status, handle, completion_time, checkpoint_change#, checkpoint_time from rc_proxy_datafile d where db_key = this_db_key and ((user_site_key = d.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(d.site_key, this_site_key))))) and d.recid = listTranslateProxyDFRecid.recid and d.stamp = listTranslateProxyDFRecid.stamp union all select c.xcf_key, 0, c.status, c.handle, c.completion_time, c.checkpoint_change#, c.checkpoint_time from rc_proxy_controlfile c where db_key = this_db_key and ((user_site_key = c.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(c.site_key, this_site_key))))) and c.recid = listTranslateProxyDFRecid.recid and c.stamp = listTranslateProxyDFRecid.stamp; ELSE deb(DEB_PRINT, 'listTranslateProxyDFRecid: using cached rcvRec_last'); xdf_key := rcvRec_last.key_con; file# := rcvRec_last.dfNumber_obj; status := rcvRec_last.status_con; handle := rcvRec_last.fileName_con; completion_time := rcvRec_last.compTime_con; checkpoint_change# := rcvRec_last.toSCN_act; checkpoint_time := rcvRec_last.toTime_act; END IF; deb(DEB_EXIT); END listTranslateProxyDFRecid; -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE findOfflineRangeCopy( offr_recid IN number ,offr_ckpscn IN number ,cf_cretime IN date ,dbinc_key IN number) IS BEGIN deb(DEB_ENTER, 'findOfflineRangeCopy'); validateState(null); deb(DEB_OPEN, 'getOfflineRangeCopy_c'); OPEN getOfflineRangeCopy_c(offrRecid => offr_recid, offrCkpSCN => offr_ckpscn, cfCreTime => cf_cretime, dbincKey => dbinc_key); deb(DEB_EXIT); END findOfflineRangeCopy; -- PROCEDURE getOfflineRangeCopy( rcvRec OUT NOCOPY rcvRec_t) IS BEGIN deb(DEB_ENTER, 'getOfflineRangeCopy'); IF (NOT getOfflineRangeCopy_c%ISOPEN) THEN deb(DEB_EXIT, 'with error 20204'); raise_application_error(-20204, 'Translation not started'); END IF; FETCH getOfflineRangeCopy_c INTO rcvRec; IF (getOfflineRangeCopy_c%NOTFOUND) THEN CLOSE getOfflineRangeCopy_c; deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; END IF; CLOSE getOfflineRangeCopy_c; deb(DEB_EXIT); END getOfflineRangeCopy; -- -- FUNCTION getOfflineRangeCopy RETURN varchar2 IS rcvRec rcvRec_t; BEGIN deb(DEB_ENTER, 'getOfflineRangeCopy815'); getOfflineRangeCopy(rcvRec); deb(DEB_EXIT, 'with: fileName'); RETURN rcvRec.fileName_con; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with: NULL'); RETURN NULL; END getOfflineRangeCopy; -- -- -- -- FUNCTION computeRecoveryActions( fno IN number, -- Datafile number. crescn IN number, -- Datafile creation SCN. df_rlgscn IN number -- Datafile resetlogs SCN. Null unless we are doing default null, -- a RECOVER, in which case is the value in the -- df_rlgtime IN date -- Datafile resetlogs time. Null if df_rlgscn is default null, -- null, else value from datafile header. df_ckpscn IN number -- Datafile checkpoint SCN. Null if df_rlgscn is default null, -- null, else value from datafile header. offlscn IN number -- kccfeofs (0 -> no offline range) default 0, onlscn IN number -- kccfeonc (0 if offlscn is 0). default 0, onltime IN date -- kccfonc_time default null, cleanscn IN number -- kccfecps if either SOR or WCC set, else 0. default 0, clean2scn IN number -- CF ckpt SCN if WCC set, infinity if SOR bit set default 0, -- else 0. clean2time IN date -- controlfile ckpt time if WCC, SYSDATE if SOR, else default null, -- this is ignored if cleanscn is 0 allowfuzzy IN boolean -- TRUE if can be fuzzy at until SCN/time, FALSE if default FALSE, -- not. default is FALSE. partial_rcv IN boolean -- TRUE if can do partial recovery, FALSE if not. default FALSE, -- A partial recovery would be to recover a datafile -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- cf_scn IN number -- controlfile ckpt SCN (NULL if none mounted) default NULL, cf_cretime IN date -- controlfile creation time (NULL if none mounted) default NULL, cf_offrrid IN number -- recid of oldest offline range in controlfile default NULL, -- (NULL if none mounted) allCopies IN boolean default FALSE, df_cretime IN DATE default NULL, rmanCmd IN binary_integer default unknownCmd_t, foreignDbid IN number default 0, pluggedRonly IN binary_integer default 0, pluginSCN IN number default 0, pluginRlgSCN IN number default 0, pluginRlgTime IN date default NULL, creation_thread IN number default NULL, creation_size IN number default NULL, pdbId IN number default 1, pdbForeignDbid IN number default 0) RETURN binary_integer IS rc boolean; last number; this number; succ_flag boolean; thisAct rcvRec_t; doingRecovery boolean; lrmanCmd binary_integer := rmanCmd; target_scn number := to_number(null); BEGIN deb(DEB_ENTER, 'computeRecoveryActions'); IF (this_dbinc_key is NULL) THEN deb(DEB_EXIT, 'with error 20020'); raise_application_error(-20020, 'Database incarnation not set'); END IF; deb(DEB_IN, ' fno: '||fno); deb(DEB_IN, ' crescn: '||crescn); deb(DEB_IN, ' df_rlgscn: '||df_rlgscn); deb(DEB_IN, ' df_ckpscn: '||to_char(df_ckpscn)); deb(DEB_IN, ' offlscn: '||to_char(offlscn)); deb(DEB_IN, ' onlscn: '||to_char(onlscn)); deb(DEB_IN, ' cleanscn: '||to_char(cleanscn)); deb(DEB_IN, ' clean2scn: '||to_char(clean2scn)); deb(DEB_IN, ' cf_scn: '||to_char(cf_scn)); deb(DEB_IN, ' cf_offrrid: '||to_char(cf_offrrid)); deb(DEB_IN, ' foreignDbid: '||to_char(foreignDbid)); deb(DEB_IN, ' pluggedRonly: '||to_char(pluggedRonly)); deb(DEB_IN, ' pluginSCN: '||to_char(pluginSCN)); deb(DEB_IN, ' pluginRlgSCN: '||to_char(pluginRlgSCN)); deb(DEB_IN, ' creation_thread: '||to_char(creation_thread)); deb(DEB_IN, ' creation_size: '||to_char(creation_size)); deb(DEB_IN, ' pdbid: '||to_char(pdbId)); deb(DEB_IN, ' pdbForeignDbid: '||to_char(pdbForeignDbid)); resetrcvRecStack; computeRA_restorable := FALSE; computeRA_available := FALSE; computeRA_rcvCopy_avail := FALSE; IF (allCopies) THEN deb(DEB_IN, 'allCopies is TRUE'); ELSE deb(DEB_IN, 'allCopies is FALSE'); END IF; IF (df_cretime is null AND -- pre10g rman client lrmanCmd = unknownCmd_t AND df_ckpscn is not null) THEN deb(DEB_IN, 'rmanCmd set to recoverCmd_t for pre10g rman'); lrmanCmd := recoverCmd_t; END IF; IF (lrmanCmd = rcvCopyCmd_t) THEN deb(DEB_PRINT, 'doing recover copy'); doingRecovery := TRUE; ELSIF (lrmanCmd = recoverCmd_t) THEN deb(DEB_PRINT, 'doing recover'); doingRecovery := TRUE; ELSIF (lrmanCmd = obsoleteCmd_t) THEN deb(DEB_PRINT, 'doing report obsolete'); doingRecovery := NULL; IF (allCopies) THEN -- -- -- -- raise_application_error(-20999, 'internal error: computeRecoveryActions ' || 'obsoleteCmd cannot be called with allCopies'); END IF; IF (tc_database = FALSE#) THEN -- -- raise_application_error(-20999, 'internal error: computeRecoveryActions ' || 'obsoleteCmd cannot be called for specific files'); END IF; ELSIF (lrmanCmd = restoreCmd_t) THEN deb(DEB_PRINT, 'doing restore'); doingRecovery := NULL; ELSIF (lrmanCmd = blkRestoreCmd_t) THEN deb(DEB_PRINT, 'doing block restore'); doingRecovery := FALSE; target_scn := df_ckpscn; ELSIF (lrmanCmd = unknownCmd_t) THEN deb(DEB_PRINT, 'command unknown or called by pre-10i rman'); doingRecovery := NULL; ELSE raise_application_error(-20999, 'internal error: computeRecoveryActions' || ' rmanCmd='||nvl(to_char(lrmanCmd), 'NULL')); END IF; deb(DEB_IN, 'this_dbinc_key is:'||to_char(this_dbinc_key)); rc := computeRecoveryActions2(fno, crescn, df_cretime, df_rlgscn, df_rlgtime, df_ckpscn, offlscn, onlscn, onltime, cleanscn, clean2scn, clean2time, allowfuzzy, partial_rcv, target_scn, this_dbinc_key, cf_scn, cf_cretime, cf_offrrid, FALSE, succ_flag, allCopies, doingRecovery, lrmanCmd, foreignDbid, pluggedRonly, pluginSCN, pluginRlgSCN, pluginRlgTime, creation_thread, creation_size, pdbId, pdbForeignDbid); IF (succ_flag) THEN IF (rcvRecStack.count > 0) THEN IF (computeRA_allRecords = FALSE#) THEN -- -- -- -- -- -- -- -- -- -- -- -- -- -- last := rcvRecStack.count; deb(DEB_IN,'computeRecoveryActions: Top of stack='|| rcvRecStack.count); FOR this IN REVERSE 2..rcvRecStack.count - 1 LOOP IF ((rcvRecStack(last).toSCN_act >= rcvRecStack(this-1).fromSCN_act) AND NOT -- (allCopies AND ((rcvRecStack(last).key_con = rcvRecStack(this).key_con AND rcvRecStack(last).type_con = rcvRecStack(this).type_con) OR (rcvRecStack(this-1).key_con = rcvRecStack(this).key_con AND rcvRecStack(this-1).type_con = rcvRecStack(this).type_con)))) THEN deb(DEB_PRINT, 'computeRecoveryActions: marking this action deleted:'); rcvRecGet(this, thisAct); IF (debug) THEN printRcvRec(thisAct); END IF; rcvRecStack(this).type_con := rcvRecStack(this).type_con + deleted_con_t; ELSE -- last := this; END IF; END LOOP; END IF; -- computeRA_allRecords = FALSE# deb(DEB_EXIT, 'with: SUCCESS'); RETURN SUCCESS; ELSE deb(DEB_EXIT, 'with: NO_ACTION'); RETURN NO_ACTION; -- a recovery that can only use redo END IF; ELSIF (computeRA_available) THEN deb(DEB_EXIT, 'with: AVAILABLE'); RETURN dbms_rcvman.AVAILABLE; ELSIF (computeRA_restorable) THEN deb(DEB_EXIT, 'with: RESTORABLE'); RETURN RESTORABLE; ELSE deb(DEB_EXIT, 'with: UNAVAILABLE'); RETURN dbms_rcvman.UNAVAILABLE; END IF; END computeRecoveryActions; -- -- -- -- -- FUNCTION reportGetDFDel( file# OUT number ,filetype OUT number ,checkpoint_change# OUT number ,checkpoint_time OUT date ,resetlogs_change# OUT number ,resetlogs_time OUT date ,incremental_change# OUT number ,fuzzy_change# OUT number ,recid OUT number ,stamp OUT number ,fname OUT varchar2 ,restorable OUT number ,key OUT number ,completion_time OUT date) RETURN number IS device_type rc_backup_piece.device_type%TYPE; mytype number; set_stamp number; set_count number; pref number; bsRec bsRec_t; validRec validBackupSetRec_t; rcvRec rcvRec_t; BEGIN deb(DEB_ENTER, 'reportGetDFDel'); FETCH rddf INTO pref, file#, mytype, checkpoint_change#, checkpoint_time, resetlogs_change#, resetlogs_time, incremental_change#, fuzzy_change#, recid, stamp, fname, set_stamp, set_count, key, completion_time, device_type; filetype := mytype; IF (rddf%found) THEN IF (mytype in (FULL_DF_BACKUP, INCREMENTAL_DF_BACKUP)) THEN findBackupSet(recid => recid, stamp => stamp, bsRec => bsRec); -- -- rcvRec.bsKey_con := bsRec.key; rcvRec.elapseSecs_con := bsRec.elapseSecs; rcvRec.pieceCount_con := bsRec.pieceCount; restorable := validateBackupSet( backupSetRec => rcvRec, checkDeviceIsAllocated => TRUE, availableMask => dbms_rcvman.BSavailable, validRec => validRec); ELSIF (mytype = OFFLINE_RANGE) THEN restorable := SUCCESS; ELSE IF (anyDevice = TRUE# OR isDeviceTypeAllocated(device_type) = TRUE#) THEN restorable := SUCCESS; ELSE restorable := dbms_rcvman.AVAILABLE; END IF; END IF; deb(DEB_EXIT, 'with: '||TRUE#); RETURN TRUE#; ELSE CLOSE rddf; deb(DEB_EXIT, 'with: '||FALSE#); RETURN FALSE#; END IF; END reportGetDFDel; -- -- -- -- FUNCTION getCloneName( fno IN number ,crescn IN number ,pluscn IN number DEFAULT 0) RETURN varchar2 IS fname rci_datafile.aux_name%TYPE; BEGIN deb(DEB_ENTER, 'getCloneName'); IF (this_dbinc_key is NULL) THEN deb(DEB_EXIT, 'with error 20020'); raise_application_error(-20020, 'Database incarnation not set'); END IF; SELECT aux_name INTO fname FROM rci_datafile_this_dbinc WHERE dbinc_key = this_dbinc_key AND (nvl(realf_site_key, translation_site_key) = site_key) AND file# = fno AND creation_change# = crescn AND plugin_change# = pluscn AND drop_change# IS NULL; deb(DEB_EXIT, 'with: '||fname); RETURN fname; EXCEPTION WHEN no_data_found THEN -- -- deb(DEB_EXIT, 'with error 20218'); raise_application_error(-20218, 'Datafile not found in recovery catalog'); WHEN others THEN deb(DEB_EXIT, 'Just raising error'); raise; END getCloneName; -- -- -- -- FUNCTION wasFileOffline( fno IN number ,untilscn IN number) RETURN number IS x number; BEGIN deb(DEB_ENTER, 'wasFileOffline'); select 1 into x from rc_offline_range ofr, rc_database_incarnation di where ofr.db_key = this_db_key and di.db_key = this_db_key and ofr.dbinc_key = di.dbinc_key and untilscn >= offline_change# and untilscn < online_change# and file# = fno; deb(DEB_EXIT, 'with: TRUE#'); RETURN TRUE#; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with: FALSE#'); RETURN FALSE#; END wasFileOffline; -- -- -- -- FUNCTION getmaxcopyno( bsstamp IN number ,bscount IN number) RETURN number IS maxcopy number; BEGIN select max(copy#) into maxcopy from rc_backup_piece bp where bp.set_stamp = bsstamp and bp.set_count = bscount -- -- -- -- -- -- and bp.db_key = this_db_key; return maxcopy; END getmaxcopyno; -- FUNCTION getMaxDfNumber RETURN number IS maxfile# number; BEGIN select max(file#) into maxfile# from df; return maxfile#; END getMaxDfNumber; -- PROCEDURE getdropOSFiles( first IN boolean ,agedFileRec OUT NOCOPY agedFileRec_t) IS BEGIN raise_application_error(-20999, 'Not supported in recovery catalog'); END getdropOSFiles; -- PROCEDURE getBackedUpFiles( first IN boolean ,agedFileRec OUT NOCOPY agedFileRec_t) IS BEGIN raise_application_error(-20999, 'Not supported in recovery catalog'); END getBackedUpFiles; -- FUNCTION validateStandbyConfig( policy IN varchar2 ,alldest IN number) RETURN NUMBER IS BEGIN raise_application_error(-20999, 'Not supported in recovery catalog'); return dbms_rcvman.FALSE#; END validateStandbyConfig; -- PROCEDURE getSCNForAppliedPolicy( minscn OUT number ,rlgscn OUT number) IS BEGIN raise_application_error(-20999, 'Not supported in recovery catalog'); END getSCNForAppliedPolicy; -- PROCEDURE getAppliedAl( first IN boolean ,agedFileRec OUT NOCOPY agedFileRec_t) IS BEGIN raise_application_error(-20999, 'Not supported in recovery catalog'); END getAppliedAl; -- PROCEDURE getRequiredSCN( reqscn OUT number ,rlgscn OUT number ,streams IN number DEFAULT 0 ,alldest IN number DEFAULT 0) IS BEGIN raise_application_error(-20999, 'Not supported in recovery catalog'); END getRequiredSCN; -- PROCEDURE getAppliedSCN( appscn OUT number ,rlgscn OUT number ,alldest IN number) IS BEGIN raise_application_error(-20999, 'Not supported in recovery catalog'); END getAppliedSCN; -- FUNCTION isBsRecCacheMatch( key IN number ,deviceType IN varchar2 ,tag IN varchar2 ,status IN varchar2) RETURN NUMBER IS bucket number; sb4_bucket binary_integer; BEGIN bucket := mod(key, CONST4GVAL); IF (bucket >= CONST2GVAL) THEN sb4_bucket := CONST2GVAL - bucket; ELSE sb4_bucket := bucket; END IF; IF (NOT cacheBsRecTable.bsRec.exists(sb4_bucket)) THEN RETURN FALSE#; END IF; FOR i in 1..cacheBsRecTable.bsRec(sb4_bucket).bslist.count LOOP IF (cacheBsRecTable.bsRec(sb4_bucket).bslist(i).bskey = key) THEN -- IF (cacheBsRecTable.mask = BSavailable) THEN IF (status != 'A') THEN RETURN FALSE#; END IF; ELSIF (isStatusMatch(status, cacheBsRecTable.mask) = FALSE#) THEN RETURN FALSE#; END IF; -- IF (deviceType != cacheBsRecTable.deviceType) THEN RETURN FALSE#; END IF; -- IF (nvl(tag, ' ') != nvl(cacheBsRecTable.tag, nvl(tag, ' '))) THEN RETURN FALSE#; END IF; -- cacheBsRecTable.bsRec(sb4_bucket).bslist(i).mixcopy := TRUE; RETURN TRUE#; END IF; END LOOP; RETURN FALSE#; END isBsRecCacheMatch; -- PROCEDURE resetReclRecid IS BEGIN raise_application_error(-20999, 'Not supported in recovery catalog'); END resetReclRecid; -- PROCEDURE setReclRecid( rectype IN binary_integer ,recid IN number) IS BEGIN raise_application_error(-20999, 'Not supported in recovery catalog'); END setReclRecid; -- FUNCTION IsReclRecid( rectype IN binary_integer ,recid IN number) RETURN NUMBER IS BEGIN raise_application_error(-20999, 'Not supported in recovery catalog'); END IsReclRecid; -- FUNCTION getSpaceRecl(ceilAsm IN binary_integer default 0) RETURN NUMBER IS BEGIN raise_application_error(-20999, 'Not supported in recovery catalog'); END getSpaceRecl; -- -- -- PROCEDURE getFlashbackInfo( fbUntilTime OUT DATE ,minGrsp OUT NUMBER) IS clean_grsp number; count_grsp number; BEGIN BEGIN SELECT nvl(oldest_flashback_time, MAXDATEVAL) INTO fbUntiltime FROM fb WHERE dbinc_key = this_dbinc_key AND db_unique_name = this_db_unique_name; EXCEPTION WHEN no_data_found THEN fbUntilTime := MAXDATEVAL; END; BEGIN SELECT min(to_scn), count(*), count(case when from_scn <= to_scn then 1 else 0 end) INTO minGrsp, count_grsp, clean_grsp FROM grsp, dbinc WHERE grsp.dbinc_key = dbinc.dbinc_key AND dbinc.db_key = this_db_key AND grsp.site_key = this_site_key AND grsp.guaranteed = 'YES' AND from_scn != 0; -- -- IF (clean_grsp = 1 AND count_grsp = 1) THEN minGrsp := MAXSCNVAL; END IF; EXCEPTION WHEN no_data_found THEN minGrsp := MAXSCNVAL; END; deb(DEB_PRINT, 'getFlashbackInfo: fbUntilTime=' || to_char(fbUntilTime) || ' minGrsp=' || minGrsp); END getFlashbackInfo; -- PROCEDURE openLbCursor(lbc OUT NOCOPY lbCursor_t) IS BEGIN IF (lbc%ISOPEN) THEN CLOSE lbc; END IF; OPEN lbc FOR SELECT -- bs.bs_key list_order1, 0 list_order2, bs.bs_key pkey, backupset_txt backup_type, backupset_txt file_type, decode(bs.keep_options, 0, 'NO', 'YES') keep, bs.keep_until keep_until, decode(bs.keep_options, 256, 'LOGS', 512, 'NOLOGS', 1024, 'BACKUP_LOGS', null) keep_options, null status, null fname, null tag, null media, bs.bs_recid recid, bs.bs_stamp stamp, null device_type, 0 block_size, bs.completion_time completion_time, 'NO' is_rdf, null compressed, null obsolete, null keep_for_dbpitr, null bytes, bs.bs_key bs_key, bs.set_count bs_count, bs.set_stamp bs_stamp, decode(bs.bck_type, 'L', archivedlog_txt, datafile_txt) bs_type, decode(bs.incr_level, 0, full_txt, 1, incr1_txt, 2, incr2_txt, 3, incr3_txt, 4, incr4_txt, decode(bs.bck_type, 'I', incr_txt, full_txt)) bs_incr_type, bs.pieces bs_pieces, null bs_copies, bs.completion_time bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, null df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, null df_resetlogs_change#, null df_creation_change#, null df_checkpoint_change#, null df_ckp_mod_time, null df_incremental_change#, null rl_thread#, null rl_sequence#, null rl_resetlogs_change#, null rl_first_change#, null rl_first_time, null rl_next_change#, null rl_next_time, null sf_db_unique_name, null con_id FROM bs WHERE bs.db_key = this_db_key UNION ALL SELECT -- bp.bs_key list_order1, 1 list_order2, bp.bp_key pkey, backupset_txt backup_type, piece_txt file_type, null keep, null keep_until, null keep_options, decode(bp.status, 'A', available_txt, 'U', unavailable_txt, 'X', expired_txt, other_txt) status, bp.handle fname, bp.tag tag, bp.media media, bp.bp_recid recid, bp.bp_stamp stamp, bp.device_type device_type, 0 block_size, bp.completion_time completion_time, bp.is_recovery_dest_file is_rdf, bp.compressed compressed, null obsolete, null keep_for_dbpitr, bp.bytes bytes, bp.bs_key bs_key, null bs_count, null bs_stamp, null bs_type, null bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, bp.piece# bp_piece#, bp.copy# bp_copy#, bp.vb_key bp_vb_key, null bp_ba_access, null bp_lib_key, null df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, null df_resetlogs_change#, null df_creation_change#, null df_checkpoint_change#, null df_ckp_mod_time, null df_incremental_change#, null rl_thread#, null rl_sequence#, null rl_resetlogs_change#, null rl_first_change#, null rl_first_time, null rl_next_change#, null rl_next_time, null sf_db_unique_name, null con_id FROM bp WHERE bp.db_key = this_db_key AND bp.status != 'D' AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <>'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) UNION ALL SELECT -- bdf.bs_key list_order1, 2 list_order2, bdf.bdf_key pkey, backupset_txt backup_type, datafile_txt file_type, null keep, null keep_until, null keep_options, null status, null fname, null tag, null media, bdf.bdf_recid recid, bdf.bdf_stamp stamp, null device_type, bdf.block_size block_size, bdf.completion_time completion_time, 'NO' is_rdf, null compressed, null obsolete, null keep_for_dbpitr, bdf.block_size * bdf.blocks bytes, bdf.bs_key bs_key, null bs_count, null bs_stamp, null bs_type, decode(bdf.incr_level, 0, full_txt, 1, incr1_txt, 2, incr2_txt, 3, incr3_txt, 4, incr4_txt, decode(greatest(bdf.create_scn, bdf.incr_scn), bdf.create_scn, full_txt, incr_txt)) bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, bdf.file# df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, dbinc.reset_scn df_resetlogs_change#, bdf.create_scn df_creation_change#, bdf.ckp_scn df_checkpoint_change#, bdf.ckp_time df_ckp_mod_time, bdf.incr_scn df_incremental_change#, null rl_thread#, null rl_sequence#, null rl_resetlogs_change#, null rl_first_change#, null rl_first_time, null rl_next_change#, null rl_next_time, null sf_db_unique_name, null con_id FROM bdf, dbinc WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = bdf.dbinc_key UNION ALL SELECT -- bcf.bs_key list_order1, 2 list_order2, bcf.bcf_key pkey, backupset_txt backup_type, controlfile_txt file_type, null keep, null keep_until, null keep_options, null status, null fname, null tag, null media, bcf.bcf_recid recid, bcf.bcf_stamp stamp, null device_type, bcf.block_size block_size, null completion_time, 'NO' is_rdf, null compressed, null obsolete, null keep_for_dbpitr, bcf.block_size * bcf.blocks bytes, bcf.bs_key bs_key, null bs_count, null bs_stamp, null bs_type, full_txt bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, 0 df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, dbinc.reset_scn df_resetlogs_change#, 0 df_creation_change#, bcf.ckp_scn df_checkpoint_change#, bcf.ckp_time df_ckp_mod_time, null df_incremental_change#, null rl_thread#, null rl_sequence#, null rl_resetlogs_change#, null rl_first_change#, null rl_first_time, null rl_next_change#, null rl_next_time, null sf_db_unique_name, null con_id FROM bcf, dbinc WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = bcf.dbinc_key UNION ALL SELECT -- brl.bs_key list_order1, 2 list_order2, brl.brl_key pkey, backupset_txt backup_type, archivedlog_txt file_type, null keep, null keep_until, null keep_options, null status, null fname, null tag, null media, brl.brl_recid recid, brl.brl_stamp stamp, null device_type, brl.block_size block_size, null completion_time, 'NO' is_rdf, null compressed, null obsolete, null keep_for_dbpitr, brl.block_size * brl.blocks bytes, brl.bs_key bs_key, null bs_count, null bs_stamp, null bs_type, null bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, null df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, null df_resetlogs_change#, null df_creation_change#, null df_checkpoint_change#, null df_ckp_mod_time, null df_incremental_change#, brl.thread# rl_thread#, brl.sequence# rl_sequence#, dbinc.reset_scn rl_resetlogs_change#, brl.low_scn rl_first_change#, brl.low_time rl_first_time, brl.next_scn rl_next_change#, brl.next_time rl_next_time, null sf_db_unique_name, null con_id FROM brl, dbinc WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = brl.dbinc_key UNION ALL SELECT -- bsf.bs_key list_order1, 2 list_order2, bsf.bsf_key pkey, backupset_txt backup_type, spfile_txt file_type, null keep, null keep_until, null keep_options, null status, null fname, null tag, null media, bsf.bsf_recid recid, bsf.bsf_stamp stamp, null device_type, 0 block_size, null completion_time, 'NO' is_rdf, null compressed, null obsolete, null keep_for_dbpitr, bsf.bytes bytes, bsf.bs_key bs_key, null bs_count, null bs_stamp, null bs_type, full_txt bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, null df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, 0 df_resetlogs_change#, 0 df_creation_change#, 0 df_checkpoint_change#, bsf.modification_time df_ckp_mod_time, null df_incremental_change#, null rl_thread#, null rl_sequence#, null rl_resetlogs_change#, null rl_first_change#, null rl_first_time, null rl_next_change#, null rl_next_time, db_unique_name sf_db_unique_name, null con_id FROM bsf WHERE bsf.db_key = this_db_key UNION ALL SELECT -- cdf.cdf_key list_order1, -1 list_order2, cdf.cdf_key pkey, copy_txt backup_type, datafile_txt file_type, decode(cdf.keep_options, 0, 'NO', 'YES') keep, cdf.keep_until keep_until, decode(cdf.keep_options, 256, 'LOGS', 512, 'NOLOGS', 1024, 'BACKUP_LOGS', NULL) keep_options, decode(cdf.status, 'A', available_txt, 'U', unavailable_txt, 'X', expired_txt, other_txt) status, cdf.fname fname, cdf.tag tag, null media, cdf.cdf_recid recid, cdf.cdf_stamp stamp, 'DISK' device_type, cdf.block_size block_size, cdf.completion_time completion_time, cdf.is_recovery_dest_file is_rdf, null compressed, null obsolete, null keep_for_dbpitr, cdf.block_size * cdf.blocks bytes, null bs_key, null bs_count, null bs_stamp, null bs_type, null bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, cdf.file# df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, dbinc.reset_scn df_resetlogs_change#, cdf.create_scn df_creation_change#, cdf.ckp_scn df_checkpoint_change#, cdf.ckp_time df_ckp_mod_time, null df_incremental_change#, null rl_thread#, null rl_sequence#, null rl_resetlogs_change#, null rl_first_change#, null rl_first_time, null rl_next_change#, null rl_next_time, null sf_db_unique_name, null con_id FROM cdf, dbinc WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = cdf.dbinc_key AND ((user_site_key = cdf.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(cdf.site_key, this_site_key))))) UNION ALL SELECT -- ccf.ccf_key list_order1, -1 list_order2, ccf.ccf_key pkey, copy_txt backup_type, controlfile_txt file_type, decode(ccf.keep_options, 0, 'NO', 'YES') keep, ccf.keep_until keep_until, decode(ccf.keep_options, 256, 'LOGS', 512, 'NOLOGS', 1024, 'BACKUP_LOGS', NULL) keep_options, decode(ccf.status, 'A', available_txt, 'U', unavailable_txt, 'X', expired_txt, other_txt) status, ccf.fname fname, ccf.tag tag, null media, ccf.ccf_recid recid, ccf.ccf_stamp stamp, 'DISK' device_type, ccf.block_size block_size, ccf.completion_time completion_time, ccf.is_recovery_dest_file is_rdf, null compressed, null obsolete, null keep_for_dbpitr, null bytes, null bs_key, null bs_count, null bs_stamp, null bs_type, null bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, 0 df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, dbinc.reset_scn df_resetlogs_change#, 0 df_creation_change#, ccf.ckp_scn df_checkpoint_change#, ccf.ckp_time df_ckp_mod_time, null df_incremental_change#, null rl_thread#, null rl_sequence#, null rl_resetlogs_change#, null rl_first_change#, null rl_first_time, null rl_next_change#, null rl_next_time, null sf_db_unique_name, null con_id FROM ccf, dbinc WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = ccf.dbinc_key AND ((user_site_key = ccf.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE#) OR (this_site_key = nvl(ccf.site_key, this_site_key))))) UNION ALL SELECT -- al.al_key list_order1, -1 list_order2, al.al_key pkey, copy_txt backup_type, archivedlog_txt file_type, null keep, null keep_until, null keep_options, decode(al.status, 'A', available_txt, 'U', unavailable_txt, 'X', expired_txt, other_txt) status, al.fname fname, null tag, null media, al.al_recid recid, al.al_stamp stamp, 'DISK' device_type, al.block_size block_size, al.completion_time completion_time, al.is_recovery_dest_file is_rdf, al.compressed compressed, null obsolete, null keep_for_dbpitr, al.block_size * al.blocks bytes, null bs_key, null bs_count, null bs_stamp, null bs_type, null bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, null df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, null df_resetlogs_change#, null df_creation_change#, null df_checkpoint_change#, null df_ckp_mod_time, null df_incremental_change#, al.thread# rl_thread#, al.sequence# rl_sequence#, dbinc.reset_scn rl_resetlogs_change#, al.low_scn rl_first_change#, al.low_time rl_first_time, al.next_scn rl_next_change#, al.next_time rl_next_time, null sf_db_unique_name, null con_id FROM dbinc, al LEFT OUTER JOIN grsp ON al.next_scn >= grsp.from_scn AND al.low_scn <= (grsp.to_scn + 1) AND al.dbinc_key = grsp.dbinc_key AND grsp.from_scn <= grsp.to_scn -- filter clean grp AND grsp.from_scn != 0 AND grsp.guaranteed = 'YES' WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = al.dbinc_key AND al.archived = 'Y' AND grsp.from_scn is null AND ((client_site_aware = TRUE# AND ((user_site_key = al.site_key) OR -- interested in specific site (user_site_key IS NULL AND ((logs_shared = TRUE#) OR (this_site_key = nvl(al.site_key, this_site_key)))))) OR (client_site_aware = FALSE#)) UNION ALL SELECT -- xdf.xdf_key list_order1, -1 list_order2, xdf.xdf_key pkey, proxycopy_txt backup_type, datafile_txt file_type, decode(xdf.keep_options, 0, 'NO', 'YES') keep, xdf.keep_until keep_until, decode(xdf.keep_options, 256, 'LOGS', 512, 'NOLOGS', 1024, 'BACKUP_LOGS', NULL) keep_options, decode(xdf.status, 'A', available_txt, 'U', unavailable_txt, 'X', expired_txt, other_txt) status, xdf.handle fname, xdf.tag tag, xdf.media media, xdf.xdf_recid recid, xdf.xdf_stamp stamp, xdf.device_type device_type, xdf.block_size block_size, xdf.completion_time completion_time, 'NO' is_rdf, null compressed, null obsolete, null keep_for_dbpitr, xdf.block_size * xdf.blocks bytes, null bs_key, null bs_count, null bs_stamp, null bs_type, null bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, xdf.file# df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, dbinc.reset_scn df_resetlogs_change#, xdf.create_scn df_creation_change#, xdf.ckp_scn df_checkpoint_change#, xdf.ckp_time df_ckp_mod_time, null df_incremental_change#, null rl_thread#, null rl_sequence#, null rl_resetlogs_change#, null rl_first_change#, null rl_first_time, null rl_next_change#, null rl_next_time, null sf_db_unique_name, null con_id FROM xdf, dbinc WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = xdf.dbinc_key AND ((user_site_key = xdf.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xdf.site_key, this_site_key))))) UNION ALL SELECT -- xcf.xcf_key list_order1, -1 list_order2, xcf.xcf_key pkey, proxycopy_txt backup_type, controlfile_txt file_type, decode(xcf.keep_options, 0, 'NO', 'YES') keep, xcf.keep_until keep_until, decode(xcf.keep_options, 256, 'LOGS', 512, 'NOLOGS', 1024, 'BACKUP_LOGS', NULL) keep_options, decode(xcf.status, 'A', available_txt, 'U', unavailable_txt, 'X', expired_txt, other_txt) status, xcf.handle fname, xcf.tag tag, xcf.media media, xcf.xcf_recid recid, xcf.xcf_stamp stamp, xcf.device_type device_type, xcf.block_size block_size, xcf.completion_time completion_time, 'NO' is_rdf, null compressed, null obsolete, null keep_for_dbpitr, null bytes, null bs_key, null bs_count, null bs_stamp, null bs_type, null bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, 0 df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, dbinc.reset_scn df_resetlogs_change#, 0 df_creation_change#, xcf.ckp_scn df_checkpoint_change#, xcf.ckp_time df_ckp_mod_time, null df_incremental_change#, null rl_thread#, null rl_sequence#, null rl_resetlogs_change#, null rl_first_change#, null rl_first_time, null rl_next_change#, null rl_next_time, null sf_db_unique_name, null con_id FROM xcf, dbinc WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = xcf.dbinc_key AND ((user_site_key = xcf.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xcf.site_key, this_site_key))))) UNION ALL SELECT -- xal.xal_key list_order1, -1 list_order2, xal.xal_key pkey, proxycopy_txt backup_type, archivedlog_txt file_type, decode(xal.keep_options, 0, 'NO', 'YES') keep, xal.keep_until keep_until, decode(xal.keep_options, 256, 'LOGS', 512, 'NOLOGS', 1024, 'BACKUP_LOGS', NULL) keep_options, decode(xal.status, 'A', available_txt, 'U', unavailable_txt, 'X', expired_txt, other_txt) status, xal.handle fname, xal.tag tag, xal.media media, xal.xal_recid recid, xal.xal_stamp stamp, xal.device_type device_type, xal.block_size block_size, xal.completion_time completion_time, 'NO' is_rdf, null compressed, null obsolete, null keep_for_dbpitr, xal.block_size * xal.blocks bytes, null bs_key, null bs_count, null bs_stamp, null bs_type, null bs_incr_type, null bs_pieces, null bs_copies, null bs_completion_time, null bs_status, null bs_bytes, null bs_compressed, null bs_tag, null bs_device_type, null bp_piece#, null bp_copy#, null bp_vb_key, null bp_ba_access, null bp_lib_key, 0 df_file#, null df_ts#, null df_plugin_change#, null df_foreign_dbid, null df_tablespace, dbinc.reset_scn df_resetlogs_change#, 0 df_creation_change#, null df_checkpoint_change#, null df_ckp_mod_time, null df_incremental_change#, xal.thread# rl_thread#, xal.sequence# rl_sequence#, dbinc.reset_scn rl_resetlogs_change#, xal.low_scn rl_first_change#, xal.low_time rl_first_time, xal.next_scn rl_next_change#, xal.next_time rl_next_time, null sf_db_unique_name, null con_id FROM xal, dbinc WHERE dbinc.db_key = this_db_key AND dbinc.dbinc_key = xal.dbinc_key AND ((user_site_key = xal.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = nvl(xal.site_key, this_site_key))))) -- -- ORDER BY list_order1, list_order2, bp_piece#; END openLbCursor; -- -- FUNCTION DbUniqueNameIsStandby RETURN NUMBER IS is_standby number; BEGIN deb(DEB_ENTER, 'DbUniqueNameIsStandby'); IF NOT this_dummy_instance THEN -- -- SELECT count(*) INTO is_standby FROM node WHERE node.db_key = this_db_key AND node.db_unique_name = this_db_unique_name AND node.database_role = 'STANDBY'; END IF; IF is_standby is NULL THEN is_standby := 0; END IF; deb(DEB_EXIT, ' with ' || is_standby); return is_standby; END DbUniqueNameIsStandby; -- -- -- PROCEDURE clrSiteName IS BEGIN deb(DEB_ENTER, 'clrSiteName, user_site_key, realf_site_key set to null'); user_site_key := NULL; realf_site_key := NULL; user_db_unique_name := NULL; deb(DEB_EXIT); END clrSiteName; -- FUNCTION getSiteKey(db_unique_name IN VARCHAR2) RETURN NUMBER IS resynced NUMBER; ret_site_key NUMBER; BEGIN -- -- IF (this_db_key IS NULL) THEN raise_application_error(-20021, 'database not set'); END IF; -- SELECT count(*) INTO resynced FROM node WHERE node.db_unique_name = upper(getSiteKey.db_unique_name) AND node.db_key = this_db_key; IF resynced = 0 THEN raise_application_error(-20243, getSiteKey.db_unique_name || 'site unknown to recovery catalog:'); END IF; SELECT site_key into ret_site_key FROM node WHERE node.db_unique_name = upper(getSiteKey.db_unique_name) AND node.db_key = this_db_key; RETURN ret_site_key; END getSiteKey; -- FUNCTION getSiteName(site_key IN NUMBER) RETURN VARCHAR2 IS ldb_unique_name node.db_unique_name%TYPE; BEGIN deb(DEB_ENTER, 'getSiteName, site_key=' || site_key); SELECT db_unique_name INTO ldb_unique_name FROM node WHERE site_key = getSiteName.site_key; deb(DEB_EXIT, ' with ' || ldb_unique_name); RETURN ldb_unique_name; END getSiteName; -- PROCEDURE setSiteName(db_unique_name IN VARCHAR2, for_realfiles IN NUMBER) IS BEGIN deb(DEB_ENTER, 'setSiteName'||db_unique_name); If db_unique_name IS NOT NULL THEN IF for_realfiles != 0 THEN realf_site_key := getSiteKey(db_unique_name); ELSE user_site_key := getSiteKey(db_unique_name); user_db_unique_name := upper(db_unique_name); END IF; deb(DEB_PRINT, 'user_site_key='|| user_site_key); deb(DEB_PRINT, 'realf_site_key=' || realf_site_key); deb(DEB_PRINT, 'user_db_unique_name='||user_db_unique_name); END IF; deb(DEB_EXIT); END setSiteName; -- -- PROCEDURE setArchiveFileScopeAttributes(logs_shared IN NUMBER) IS BEGIN deb(DEB_ENTER, 'setArchiveFileScopeAttributes'); IF logs_shared > 0 THEN dbms_rcvman.logs_shared := TRUE#; ELSE dbms_rcvman.logs_shared := FALSE#; END IF; deb(DEB_PRINT, 'logs_shared = ' || dbms_rcvman.logs_shared); deb(DEB_EXIT); END setArchiveFileScopeAttributes; -- -- PROCEDURE setFirstFullBckScopeAttributes(baseline_cap IN NUMBER) IS BEGIN deb(DEB_ENTER, 'setFirstFullBckScopeAttributes'); this_baseline_cap := baseline_cap; this_baseline_cap_scn := NULL; deb(DEB_PRINT, 'baseline_cap = ' || this_baseline_cap); deb(DEB_EXIT); END setFirstFullBckScopeAttributes; -- -- PROCEDURE setBackupFileScopeAttributes( disk_backups_shared IN NUMBER, tape_backups_shared IN NUMBER) IS lsite_key NUMBER; BEGIN deb(DEB_ENTER, 'setBackupFileScopeAttributes'); IF disk_backups_shared IS NOT NULL THEN IF disk_backups_shared > 0 THEN dbms_rcvman.disk_backups_shared := TRUE#; ELSE dbms_rcvman.disk_backups_shared := FALSE#; END IF; END IF; IF tape_backups_shared IS NOT NULL THEN IF tape_backups_shared > 0 THEN dbms_rcvman.tape_backups_shared := TRUE#; ELSE dbms_rcvman.tape_backups_shared := FALSE#; END IF; END IF; deb(DEB_PRINT, 'disk_backups_shared='||dbms_rcvman.disk_backups_shared); deb(DEB_PRINT, 'tape_backups_shared='||dbms_rcvman.tape_backups_shared); deb(DEB_EXIT); END setBackupFileScopeAttributes; -- PROCEDURE addBackupToMKL(lbMkTab IN OUT NOCOPY rcvRecTabII_t ,rcvRec IN rcvRec_t) IS nelem number; -- number of elements in each bucket key number; -- key to be added to table bucket number; i binary_integer; rcvRecI rcvRecTabI_t; BEGIN IF (rcvRec.type_con = backupSet_con_t) THEN key := rcvRec.bsKey_con; ELSIF (rcvRec.type_con = imageCopy_con_t OR rcvRec.type_con = proxyCopy_con_t) THEN key := rcvRec.key_con; ELSE raise_application_error(-20999, 'internal error: addBackupToMKL' || ' type=' || rcvRec.type_con); END IF; bucket := mod(key, CONST4GVAL); IF (bucket >= CONST2GVAL) THEN i := CONST2GVAL - bucket; ELSE i := bucket; END IF; IF (NOT lbMkTab.exists(i)) THEN lbMkTab(i) := rcvRecI; END IF; -- nelem := lbMkTab(i).count; IF (nelem > 0) THEN FOR j in 0 ..nelem-1 LOOP IF (rcvRec.type_con = lbMkTab(i)(j).type_con) THEN -- IF (rcvRec.type_con = backupSet_con_t AND (lbMkTab(i)(j).bsKey_con = rcvRec.bsKey_con OR (lbMkTab(i)(j).setStamp_con = rcvRec.setStamp_con AND lbMkTab(i)(j).setCount_con = rcvRec.setCount_con))) THEN RETURN; ELSIF ((rcvRec.type_con = imageCopy_con_t AND rcvRec.type_con = proxyCopy_con_t) OR lbMkTab(i)(j).recid_con = rcvRec.recid_con AND lbMkTab(i)(j).stamp_con = rcvRec.stamp_con AND lbMkTab(i)(j).key_con = rcvRec.key_con) THEN RETURN; END IF; END IF; END LOOP; END IF; lbMkTab(i)(nelem) := rcvRec; END addBackupToMKL; -- -- FUNCTION listBackupInMKL(lbMkTab IN rcvRecTabII_t ,lbRec IN lbRec_t) RETURN BOOLEAN IS nelem number; -- number of elements in each bucket key number; -- key in question? bucket number; i binary_integer; BEGIN IF (lbRec.backup_type = backupset_txt) THEN key := lbRec.bs_key; ELSIF (lbRec.backup_type = copy_txt OR lbRec.backup_type = proxycopy_txt) THEN key := lbRec.pkey; ELSE raise_application_error(-20999, 'internal error: listBackupToMKL' || ' type=' || lbRec.backup_type); END IF; bucket := mod(key, CONST4GVAL); IF (bucket >= CONST2GVAL) THEN i := CONST2GVAL - bucket; ELSE i := bucket; END IF; IF (NOT lbMkTab.exists(i)) THEN RETURN FALSE; END IF; nelem := lbMkTab(i).count; FOR j in 0 ..nelem-1 LOOP -- IF (lbMkTab(i)(j).type_con = backupSet_con_t AND lbRec.backup_type = backupset_txt AND (lbMkTab(i)(j).bsKey_con = lbRec.bs_key OR (lbMkTab(i)(j).setStamp_con = lbRec.bs_stamp AND lbMkTab(i)(j).setCount_con = lbRec.bs_count))) THEN RETURN TRUE; ELSIF (((lbMkTab(i)(j).type_con = imageCopy_con_t AND lbRec.backup_type = copy_txt) OR (lbMkTab(i)(j).type_con = proxyCopy_con_t AND lbRec.backup_type = proxycopy_txt)) AND lbMkTab(i)(j).recid_con = lbRec.recid AND lbMkTab(i)(j).stamp_con = lbRec.stamp AND lbMkTab(i)(j).key_con = lbRec.pkey) THEN RETURN TRUE; END IF; END LOOP; RETURN FALSE; END listBackupInMKL; -- -- -- PROCEDURE SetGetSinceLastBackedAL(ntimes IN number DEFAULT 1, devtype IN varchar2 DEFAULT NULL, sbpscn IN number) IS last_alrec sinceLastBackedAL_c%ROWTYPE; BEGIN deb(DEB_ENTER, 'SetGetSinceLastBackedAl'); -- lbacked_al_next_scn := 0; standby_became_primary_scn := 0; IF client_site_aware = TRUE# or sbpscn IS NULL or sbpscn = 0 THEN deb(DEB_IN, 'SetGetSinceLastBackedAl: lbacked_al_next_scn is 0'); ELSE -- -- -- -- standby_became_primary_scn := sbpscn + 1; OPEN sinceLastBackedAL_c(devtype, ntimes); FETCH sinceLastBackedAL_c into last_alrec; IF NOT sinceLastBackedAL_c%NOTFOUND THEN lbacked_al_next_scn := nvl(last_alrec.next_scn, last_alrec.low_scn); END IF; CLOSE sinceLastBackedAL_c; END IF; deb(DEB_IN, 'SetGetSinceLastBackedAl: al_next_scn=' || lbacked_al_next_scn || ' sbpscn=' || standby_became_primary_scn); deb(DEB_EXIT, 'SetGetSinceLastBackedAl'); END SetGetSinceLastBackedAL; -- FUNCTION getEncryptTSCount RETURN BINARY_INTEGER IS encrypt_ts_count NUMBER; BEGIN SELECT count(*) into encrypt_ts_count FROM rc_tablespace WHERE dbinc_key=this_dbinc_key AND encrypt_in_backup = 'ON'; RETURN encrypt_ts_count; END getEncryptTSCount; -- -- -- -- -- FUNCTION getArchivedNextSCN RETURN NUMBER IS mySCN number; BEGIN deb(DEB_ENTER, 'getArchivedNextSCN'); SELECT nvl(max(al.next_scn),0) INTO mySCN FROM al, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE al.archived = 'Y' AND al.dbinc_key = d2.dbinc_key AND (d2.next_reset_scn IS NULL OR (al.low_scn >= d2.reset_scn AND al.low_scn < d2.next_reset_scn)); SELECT greatest(nvl(max(brl.next_scn), 0), mySCN) INTO mySCN FROM brl, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE brl.dbinc_key = d2.dbinc_key AND (d2.next_reset_scn IS NULL OR (brl.low_scn >= d2.reset_scn AND brl.low_scn < d2.next_reset_scn)); SELECT greatest(nvl(max(xal.next_scn), 0), mySCN) INTO mySCN FROM xal, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE xal.dbinc_key = d2.dbinc_key AND (d2.next_reset_scn IS NULL OR (xal.low_scn >= d2.reset_scn AND xal.low_scn < d2.next_reset_scn)); deb(DEB_EXIT, 'with '||to_char(mySCN)); RETURN mySCN; END getArchivedNextSCN; -- FUNCTION isArchivedLogMissing(fromSCN IN NUMBER, untilSCN IN NUMBER) RETURN number IS thread number; sequence number; dbinc_key number; BEGIN deb(DEB_ENTER, 'isArchivedLogMissing'); deb(DEB_IN, 'fromSCN =' || nvl(to_char(fromSCN), 'NULL') || ' untilSCN=' || nvl(to_char(untilSCN), 'NULL')); -- -- SELECT thread#, sequence#, dbinc_key INTO thread, sequence, dbinc_key FROM (SELECT dbinc_key, thread#, sequence#, lead(sequence#, 1, sequence#+1) OVER (PARTITION BY thread#, dbinc_key ORDER BY sequence#) nextseq FROM (SELECT al.thread#, al.sequence#, al.dbinc_key FROM al, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE al.dbinc_key = d2.dbinc_key AND (d2.next_reset_scn IS NULL OR (al.low_scn >= d2.reset_scn AND al.low_scn < d2.next_reset_scn)) AND low_scn >= fromSCN AND (untilSCN IS NULL OR low_scn < untilSCN) UNION ALL SELECT brl.thread#, brl.sequence#, brl.dbinc_key FROM brl, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE brl.dbinc_key = d2.dbinc_key AND (d2.next_reset_scn IS NULL OR (brl.low_scn >= d2.reset_scn AND brl.low_scn < d2.next_reset_scn)) AND low_scn >= fromSCN AND (untilSCN IS NULL OR low_scn < untilSCN) UNION ALL SELECT xal.thread#, xal.sequence#, xal.dbinc_key FROM xal, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE xal.dbinc_key = d2.dbinc_key AND (d2.next_reset_scn IS NULL OR (xal.low_scn >= d2.reset_scn AND xal.low_scn < d2.next_reset_scn)) AND low_scn >= fromSCN AND (untilSCN IS NULL OR low_scn < untilSCN)) ) WHERE nextseq NOT IN (sequence#, sequence#+1) AND rownum = 1; deb(DEB_IN, 'missing sequence is (dbinc_key, thread, sequence)=('|| to_char(dbinc_key) || ',' || to_char(thread) || ',' || to_char(sequence+1) || ')'); deb(DEB_EXIT, 'with TRUE'); RETURN TRUE#; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with FALSE'); RETURN FALSE#; END isArchivedLogMissing; -- FUNCTION getMaxRedoSCN(maxScn OUT NUMBER, maxTime OUT DATE, maxDbIncKey OUT NUMBER, maxRlgScn OUT NUMBER, maxRlgTime OUT DATE, isOrs IN NUMBER) RETURN boolean IS highScn number; highTime date; dbIncKey number; rlgscn number; BEGIN deb(DEB_ENTER,'getMaxRedoSCN'); SELECT next_scn, next_time, dbinc_key, reset_scn INTO highScn, highTime, dbIncKey, rlgscn FROM (SELECT next_scn, next_time, dbinc_key, reset_scn FROM (SELECT (CASE WHEN al.next_scn > d2.next_reset_scn THEN d2.next_reset_scn ELSE al.next_scn END) next_scn, al.next_time, al.dbinc_key, d2.reset_scn FROM al, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE al.dbinc_key = d2.dbinc_key AND (d2.next_reset_scn IS NULL OR (al.low_scn >= d2.reset_scn AND al.low_scn < d2.next_reset_scn)) AND (isOrs = TRUE# OR (restoreRangeDevTyp IN ('RC$DISK', 'RC$ANY'))) AND (localOrsSiteKey IS NULL OR localOrsSiteKey = al.site_key) AND ((client_site_aware = TRUE# AND ((user_site_key = al.site_key) OR (user_site_key IS NULL AND (logs_shared = TRUE# OR this_site_key = nvl(al.site_key, this_site_key))))) OR (client_site_aware = FALSE#)) UNION ALL SELECT (CASE WHEN brl.next_scn > d2.next_reset_scn THEN d2.next_reset_scn ELSE brl.next_scn END) next_scn, brl.next_time, brl.dbinc_key, d2.reset_scn FROM brl, bp, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE brl.bs_key = bp.bs_key AND brl.dbinc_key = d2.dbinc_key AND (d2.next_reset_scn IS NULL OR (brl.low_scn >= d2.reset_scn AND brl.low_scn < d2.next_reset_scn)) AND (isOrs = TRUE# OR ((restoreRangeDevTyp = 'RC$DISK' AND bp.device_type = 'DISK') OR (restoreRangeDevTyp = 'RC$SBT' AND bp.device_type = 'SBT_TAPE') OR restoreRangeDevTyp = 'RC$ANY')) AND (localOrsSiteKey IS NULL OR (restoreRangeDevTyp IN ('RA$DISK', 'RA$ANY') AND bp.ba_access IN ('D', 'L')) OR (restoreRangeDevTyp IN ('RA$SBT', 'RA$ANY') AND (bp.ba_access IN ('T', 'R') AND localOrsSiteKey = bp.site_key))) AND bp.db_key = this_db_key AND bp.status != 'D' AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) UNION ALL SELECT (CASE WHEN xal.next_scn > d2.next_reset_scn THEN d2.next_reset_scn ELSE xal.next_scn END) next_scn, xal.next_time, xal.dbinc_key, d2.reset_scn FROM xal, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE xal.dbinc_key = d2.dbinc_key AND (d2.next_reset_scn IS NULL OR (xal.low_scn >= d2.reset_scn AND xal.low_scn < d2.next_reset_scn)) AND (isOrs = TRUE# OR (restoreRangeDevTyp IN ('RC$SBT', 'RC$ANY'))) AND (localOrsSiteKey IS NULL OR localOrsSiteKey = xal.site_key) AND ((user_site_key = xal.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = NVL(xal.site_key, this_site_key))))) ) ORDER BY next_scn DESC) WHERE rownum = 1; maxScn := highScn; maxTime := highTime; maxDbIncKey := dbIncKey; maxRlgScn := rlgscn; deb(DEB_IN, 'Max scn is = '||to_char(maxScn)); deb(DEB_EXIT, 'with TRUE'); RETURN TRUE; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with FALSE'); RETURN FALSE; END getMaxRedoSCN; -- FUNCTION getNextAvailableSCN(fromScn IN NUMBER, nextAvailableSCN OUT NUMBER, isOrs IN NUMBER) RETURN boolean IS lowScn number; BEGIN deb(DEB_ENTER,'getNextAvailableSCN'); deb(DEB_IN, 'finding next avilable scn after ' || nvl(to_char(fromSCN), 'NULL')); SELECT min(low_scn) INTO lowScn FROM (SELECT al.low_scn FROM al, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE al.dbinc_key = d2.dbinc_key AND (d2.next_reset_scn IS NULL OR (al.low_scn >= d2.reset_scn AND al.low_scn < d2.next_reset_scn)) AND al.low_scn > fromScn AND (isOrs = TRUE# OR (restoreRangeDevTyp IN ('RC$DISK', 'RC$ANY'))) AND (localOrsSiteKey IS NULL OR localOrsSiteKey = al.site_key) AND ((client_site_aware = TRUE# AND ((user_site_key = al.site_key) OR (user_site_key IS NULL AND (logs_shared = TRUE# OR this_site_key = nvl(al.site_key, this_site_key))))) OR (client_site_aware = FALSE#)) UNION ALL SELECT brl.low_scn FROM brl, bp, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE brl.bs_key = bp.bs_key AND brl.dbinc_key = d2.dbinc_key AND (d2.next_reset_scn IS NULL OR (brl.low_scn >= d2.reset_scn AND brl.low_scn < d2.next_reset_scn)) AND brl.low_scn > fromScn AND (isOrs = TRUE# OR ((restoreRangeDevTyp = 'RC$DISK' AND bp.device_type = 'DISK') OR (restoreRangeDevTyp = 'RC$SBT' AND bp.device_type = 'SBT_TAPE') OR restoreRangeDevTyp = 'RC$ANY')) AND (localOrsSiteKey IS NULL OR (restoreRangeDevTyp IN ('RA$DISK', 'RA$ANY') AND bp.ba_access IN ('D', 'L')) OR (restoreRangeDevTyp IN ('RA$SBT', 'RA$ANY') AND (bp.ba_access IN ('T', 'R') AND localOrsSiteKey = bp.site_key))) AND bp.db_key = this_db_key AND bp.status != 'D' AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) UNION ALL SELECT xal.low_scn FROM xal, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE xal.dbinc_key = d2.dbinc_key AND (d2.next_reset_scn IS NULL OR (xal.low_scn >= d2.reset_scn AND xal.low_scn < d2.next_reset_scn)) AND xal.low_scn > fromScn AND (isOrs = TRUE# OR (restoreRangeDevTyp IN ('RC$SBT', 'RC$ANY'))) AND (localOrsSiteKey IS NULL OR localOrsSiteKey = xal.site_key) AND ((user_site_key = xal.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = NVL(xal.site_key, this_site_key)))))); nextAvailableSCN := lowScn; deb(DEB_IN, 'next available scn is = '||to_char(nextAvailableSCN)); deb(DEB_EXIT, 'with TRUE'); RETURN TRUE; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with FALSE'); RETURN FALSE; END getNextAvailableSCN; -- FUNCTION findLogBreakPoint(logBreakPointScn OUT NUMBER, logBreakPointTime OUT DATE, logBreakPointDbIncKey OUT NUMBER, logBreakPointRlgScn OUT NUMBER, logBreakPointRlgTime OUT DATE, fromSCN IN NUMBER, untilSCN IN NUMBER, isOrs IN NUMBER) RETURN boolean IS thread number; sequence number; dbinc_key number; nxtscn number; nxttime date; rlgscn number; BEGIN deb(DEB_ENTER, 'findLogBreakPoint'); deb(DEB_IN, 'fromSCN =' || nvl(to_char(fromSCN), 'NULL') || ' untilSCN=' || nvl(to_char(untilSCN), 'NULL')); -- -- SELECT thread#, sequence#, dbinc_key, next_scn, next_time, reset_scn INTO thread, sequence, dbinc_key, nxtscn, nxttime, rlgscn FROM (SELECT dbinc_key, thread#, sequence#, next_scn, next_time, reset_scn, lead(sequence#, 1, sequence#+1) OVER (PARTITION BY thread#, dbinc_key ORDER BY sequence#) nextseq FROM ( SELECT al.thread#, al.sequence#, al.dbinc_key, (CASE WHEN al.next_scn > d2.next_reset_scn THEN d2.next_reset_scn ELSE al.next_scn END) next_scn, al.next_time, d2.reset_scn FROM al, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE al.dbinc_key = d2.dbinc_key AND (d2.next_reset_scn IS NULL OR (al.low_scn >= d2.reset_scn AND al.low_scn < d2.next_reset_scn)) AND next_scn >= fromSCN AND (untilSCN IS NULL OR low_scn < untilSCN) AND (isOrs = TRUE# OR (restoreRangeDevTyp IN ('RC$DISK', 'RC$ANY'))) AND (localOrsSiteKey IS NULL OR localOrsSiteKey = al.site_key) AND ((client_site_aware = TRUE# AND ((user_site_key = al.site_key) OR (user_site_key IS NULL AND (logs_shared = TRUE# OR this_site_key = nvl(al.site_key, this_site_key))))) OR (client_site_aware = FALSE#)) UNION ALL SELECT brl.thread#, brl.sequence#, brl.dbinc_key, (CASE WHEN brl.next_scn > d2.next_reset_scn THEN d2.next_reset_scn ELSE brl.next_scn END) next_scn, brl.next_time, d2.reset_scn FROM brl, bp, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE brl.bs_key = bp.bs_key AND brl.dbinc_key = d2.dbinc_key AND (d2.next_reset_scn IS NULL OR (brl.low_scn >= d2.reset_scn AND brl.low_scn < d2.next_reset_scn)) -- -- -- AND next_scn >= fromSCN AND (untilSCN IS NULL OR low_scn < untilSCN) AND (isOrs = TRUE# OR ((restoreRangeDevTyp = 'RC$DISK' AND bp.device_type = 'DISK') OR (restoreRangeDevTyp = 'RC$SBT' AND bp.device_type = 'SBT_TAPE') OR restoreRangeDevTyp = 'RC$ANY')) AND (localOrsSiteKey IS NULL OR (restoreRangeDevTyp IN ('RA$DISK', 'RA$ANY') AND bp.ba_access IN ('D', 'L')) OR (restoreRangeDevTyp IN ('RA$SBT', 'RA$ANY') AND (bp.ba_access IN ('T', 'R') AND localOrsSiteKey = bp.site_key))) AND bp.db_key = this_db_key AND bp.status != 'D' AND ((user_site_key = bp.site_key) OR (user_site_key IS NULL AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR (this_site_key = nvl(bp.site_key, this_site_key))))) UNION ALL SELECT xal.thread#, xal.sequence#, xal.dbinc_key, (CASE WHEN xal.next_scn > d2.next_reset_scn THEN d2.next_reset_scn ELSE xal.next_scn END) next_scn, xal.next_time, d2.reset_scn FROM xal, (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key UNION ALL SELECT this_dbinc_key dbinc_key, null reset_scn, null next_reset_scn FROM dual) d2 WHERE xal.dbinc_key = d2.dbinc_key AND (d2.next_reset_scn IS NULL OR (xal.low_scn >= d2.reset_scn AND xal.low_scn < d2.next_reset_scn)) AND next_scn >= fromSCN AND (untilSCN IS NULL OR low_scn < untilSCN) AND (isOrs = TRUE# OR (restoreRangeDevTyp IN ('RC$SBT', 'RC$ANY'))) AND (localOrsSiteKey IS NULL OR localOrsSiteKey = xal.site_key) AND ((user_site_key = xal.site_key) OR (user_site_key IS NULL AND ((tape_backups_shared = TRUE#) OR (this_site_key = NVL(xal.site_key, this_site_key)))))) ) WHERE nextseq NOT IN (sequence#, sequence#+1) AND rownum = 1; logBreakPointScn := nxtscn; logBreakPointTime := nxttime; logBreakPointDbIncKey := dbinc_key; logBreakPointRlgScn := rlgscn; deb(DEB_IN, 'missing sequence is (dbinc_key, thread, sequence, nextscn)=('|| to_char(dbinc_key) || ',' || to_char(thread) || ',' || to_char(sequence+1) || ',' || to_char(nxtscn) || ')'); deb(DEB_EXIT, 'with TRUE'); RETURN TRUE; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with FALSE'); RETURN FALSE; END findLogBreakPoint; -- FUNCTION getDropSCN(dfNum IN NUMBER, creScn IN NUMBER, creTime IN DATE, plugScn IN NUMBER, foreignDbId IN NUMBER, dropScn OUT NUMBER, dropTime OUT DATE, dropDbIncKey OUT NUMBER, dropRlgScn OUT NUMBER, dropRlgTime OUT DATE) RETURN boolean IS BEGIN deb(DEB_ENTER, 'getDropSCN'); SELECT drop_scn, drop_time, dbinc_key, reset_scn, reset_time INTO dropScn, dropTime, dropDbIncKey, dropRlgScn, dropRlgTime FROM (SELECT drop_scn, drop_time, df.dbinc_key, reset_scn, reset_time FROM df, dbinc WHERE df.dbinc_key = dbinc.dbinc_key AND dbinc.db_key = this_db_key AND file# = dfNum AND create_scn = creScn AND create_time = creTime AND plugin_scn = plugScn AND foreign_dbid = foreignDbId AND (dbinc_status = 'PARENT' OR dbinc_status = 'CURRENT') ORDER BY reset_scn desc) WHERE rownum = 1; IF (dropScn IS NULL) THEN deb(DEB_EXIT, 'with FALSE'); RETURN FALSE; ELSE deb(DEB_EXIT, 'with TRUE'); RETURN TRUE; END IF; EXCEPTION WHEN OTHERS THEN deb(DEB_IN, 'found exception: ' || substr(sqlerrm, 1, 512)); deb(DEB_EXIT, 'with FALSE'); RETURN FALSE; END getDropSCN; -- FUNCTION setLocalOrsSiteKey(db_id IN NUMBER) RETURN boolean IS dbUnqName node.db_unique_name%TYPE; l_db_id NUMBER; BEGIN deb(DEB_ENTER, 'setLocalOrsSiteKey ' || db_id); l_db_id := db_id; localOrsSiteKey := NULL; IF (user_site_key IS NOT NULL) THEN deb(DEB_IN, 'user_site_key is set'); deb(DEB_EXIT, 'with TRUE'); return TRUE; END IF; BEGIN EXECUTE IMMEDIATE 'select rtrim(ltrim(value)) from sys.v_$parameter where lower(name)=''db_unique_name''' into dbUnqName; EXCEPTION WHEN OTHERS THEN deb(DEB_EXIT, 'with FALSE'); RETURN FALSE; END; deb(DEB_IN, 'ORS db_uniqune_name is ' || dbUnqName); IF l_db_id IS NULL THEN SELECT db_id INTO l_db_id from db where db_key = this_db_key; deb(DEB_IN, 'using default db_id from setDatabase ' || l_db_id); END IF; BEGIN SELECT SITE_KEY INTO localOrsSiteKey FROM node WHERE UPPER(DB_UNIQUE_NAME) = UPPER('$'||dbUnqName||'$'||to_char(l_db_id)); EXCEPTION WHEN OTHERS THEN deb(DEB_EXIT, 'with FALSE'); RETURN FALSE; END; deb(DEB_IN, 'Local Ors site key ' || to_char(localOrsSiteKey)); deb(DEB_EXIT, 'with TRUE'); return TRUE; END setLocalOrsSiteKey; -- PROCEDURE resetLocalOrsSiteKey IS BEGIN deb(DEB_ENTER, 'resetLocalOrsSiteKey'); localOrsSiteKey := NULL; deb(DEB_EXIT); END resetLocalOrsSiteKey; -- FUNCTION getIncarnationKey(untilSCN IN NUMBER) RETURN number IS myInc number; BEGIN deb(DEB_ENTER, 'getIncarnationKey'); IF (untilSCN <= this_reset_scn) THEN SELECT dbinc.dbinc_key INTO myInc FROM (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc START WITH dbinc_key = this_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key) dbinc WHERE dbinc.reset_scn < untilSCN AND dbinc.next_reset_scn >= untilSCN; ELSE myInc := 0; END IF; deb(DEB_EXIT, 'with incKey=' || to_char(myInc)); RETURN myInc; END getIncarnationKey; -- FUNCTION getMaxScn RETURN number IS logmaxnt date; BEGIN return getMaxScn(logmaxnt); END; FUNCTION getMaxScn(logmaxnt OUT date) return number IS minmaxnc number; minmaxnt date; BEGIN IF (this_dbinc_key is NULL) THEN deb(DEB_EXIT, 'with error 20020'); raise_application_error(-20020, 'Database incarnation not set'); END IF; /* Bug 2377581: Find SCN from enabled threads only. */ select min(maxnc), min(maxnt) into minmaxnc, minmaxnt from (select max(next_scn) maxnc, max(NEXT_TIME) maxnt from (select a.next_scn, a.next_time, a.thread# tno from al a, rt t where a.THREAD# = t.THREAD# and a.ARCHIVED = 'Y' and t.status not in ('D', 'I') and t.dbinc_key = this_dbinc_key and a.dbinc_key = this_dbinc_key union select b.next_scn, b.next_time, b.thread# tno from brl b, rt t where b.THREAD# = t.THREAD# and t.status not in ('D', 'I') and t.dbinc_key = this_dbinc_key and b.dbinc_key = this_dbinc_key) group by tno); logmaxnt := minmaxnt; return minmaxnc; END getMaxScn; -- FUNCTION getActualDbinc RETURN NUMBER IS BEGIN return actual_dbinc_key; END getActualDbinc; -- PROCEDURE setStdbyCtrlScn( ctrlSCN IN NUMBER) IS BEGIN deb(DEB_PRINT, 'Setting this_stdby_controlfile_scn' || ctrlSCN); this_stdby_controlfile_scn := ctrlSCN; END setStdbyCtrlScn; -- FUNCTION guidToPdbKey(guid IN VARCHAR2) RETURN NUMBER IS pdbKey NUMBER; BEGIN IF (guid IS NULL) THEN RETURN NULL; END IF; SELECT max(pdb_key) INTO pdbKey FROM pdb WHERE pdb.guid = guidToPdbKey.guid AND pdb.db_key = this_db_key; RETURN pdbKey; END guidToPdbKey; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION dumpState( lineno IN number) RETURN varchar2 IS BEGIN IF lineno = 1 THEN RETURN 'this_db_key=' || nvl(to_char(this_db_key), 'NULL'); ELSIF lineno = 2 THEN RETURN 'this_dbinc_key=' || nvl(to_char(this_dbinc_key), 'NULL'); ELSIF lineno = 3 THEN RETURN 'this_reset_scn=' || nvl(to_char(this_reset_scn), 'NULL'); ELSIF lineno = 4 THEN RETURN 'this_reset_time=' || nvl(to_char(this_reset_time), 'NULL'); ELSIF lineno = 5 THEN RETURN 'untilSCN=' || nvl(to_char(untilSCN), 'NULL'); ELSIF lineno = 6 THEN RETURN 'untilTime=' || nvl(to_char(untilTime), 'NULL'); ELSIF lineno = 7 THEN RETURN 'getRA_completedAfter=' || nvl(to_char(getRA_completedAfter), 'NULL'); ELSIF lineno = 8 THEN RETURN 'getRA_completedBefore=' || nvl(to_char(getRA_completedBefore), 'NULL'); ELSIF lineno = 9 THEN RETURN 'getRA_likePattern=' || nvl(getRA_likePattern, 'NULL'); ELSIF lineno = 10 THEN RETURN 'getRA_containerMask=' || nvl(to_char(getRA_containerMask), 'NULL'); ELSIF lineno = 11 THEN RETURN 'getRA_actionMask=' || nvl(to_char(getRA_actionMask), 'NULL'); ELSIF lineno = 12 THEN RETURN 'computeRA_allRecords=' || nvl(to_char(computeRA_allRecords), 'NULL'); ELSIF lineno = 13 THEN RETURN 'computeRA_fullBackups=' || nvl(to_char(computeRA_fullBackups), 'NULL'); ELSIF lineno = 14 THEN RETURN 'allIncarnations=' || nvl(to_char(allIncarnations), 'NULL'); ELSE RETURN NULL; END IF; END dumpState; -- PROCEDURE dumpPkgState(msg in varchar2 default null) IS line varchar2(132); lno number := 1; BEGIN deb(DEB_ENTER, 'dumpPkgState ' || nvl(msg, ' ')); loop line := dumpState(lno); if line is NULL then exit; else deb(DEB_PRINT, line); lno := lno + 1; end if; end loop; deb(DEB_EXIT); END dumpPkgState; -- PROCEDURE setDebugOn IS BEGIN if debug is null or not debug then -- -- -- -- dbms_output.enable(buffer_size => null); debug := TRUE; else deb(DEB_PRINT, 'Debug on - debug lready enabled'); end if; END setDebugOn; -- PROCEDURE setDebugOff IS BEGIN dumpPkgState('Debug Off'); dbms_output.disable; -- free memory debug := FALSE; END setDebugOff; -- -- -- -- -- -- -- -- PROCEDURE initialize( rman_vsn IN number) IS BEGIN NULL; END initialize; -- PROCEDURE set_package_constants IS BEGIN -- -- -- -- NULL; END set_package_constants; -- -- -- -- FUNCTION stamp2date( stamp IN number) RETURN date IS x number; dt varchar2(19); BEGIN x := stamp; dt := to_char(mod(x,60), 'FM09'); -- seconds x := floor(x/60); dt := to_char(mod(x,60), 'FM09') || ':' || dt; -- minutes x := floor(x/60); dt := to_char(mod(x,24), 'FM09') || ':' || dt; -- hours x := floor(x/24); dt := to_char(mod(x,31)+1, 'FM09') || ' ' || dt; -- days x := floor(x/31); dt := to_char(mod(x,12)+1, 'FM09') || '/' || dt; -- months dt := to_char(floor(x/12)+1988) || '/' || dt; RETURN to_date(dt, 'YYYY/MM/DD HH24:MI:SS'); END stamp2date; -- -- -- -- -- PROCEDURE setAllFlag( flag IN boolean) IS BEGIN setAllIncarnations(flag); IF (flag) THEN ignoreCreationSCN := TRUE#; ELSE ignoreCreationSCN := FALSE#; END IF; END setAllFlag; -- FUNCTION getUntilTime RETURN date IS BEGIN RETURN untilTime; END getUntilTime; -- FUNCTION getUntilScn RETURN number IS BEGIN RETURN untilScn; END getUntilScn; -- PROCEDURE resetUntil IS BEGIN untilSCN := NULL; untilTime := NULL; rpoint_set := FALSE; END resetUntil; -- PROCEDURE setFrom( restorefrom IN number DEFAULT NULL) IS BEGIN IF (restorefrom = BACKUP) THEN restoreSource := backupSet_con_t + proxyCopy_con_t; ELSIF (restorefrom = COPY) THEN restoreSource := imageCopy_con_t; ELSIF (restorefrom = NONPROXY) THEN restoreSource := imageCopy_con_t + backupSet_con_t; ELSIF (restorefrom = AVMCOPY) THEN -- IF (dbms_rcvcat.isAMSchema) THEN restoreSource := avmImageCopy_con_t; END IF; -- IF (bitand(nvl(restoreSource, 0), avmImageCopy_con_t) = 0) THEN raise_application_error(-20514, 'feature requires Availability Machine recovery catalog'); END IF; ELSIF (restorefrom is NULL) THEN restoreSource := NULL; ELSE raise_application_error(-20200, 'Invalid restore source'); END IF; END setFrom; -- PROCEDURE setSparseness( sparseness IN number DEFAULT NULL) IS BEGIN deb(DEB_ENTER, 'setSparseness'); deb(DEB_IN, 'restoreSparse='|| restoreSparse); IF (sparseness = SPARSE) THEN restoreSparse := BACKUP_SPARSENESS_SPARSE; ELSIF (sparseness = NONSPARSE) THEN restoreSparse := BACKUP_SPARSENESS_NONSPARSE; ELSE restoreSparse := BACKUP_SPARSENESS_UNSPECIFIED; END IF; deb(DEB_IN, 'restoreSparse='|| restoreSparse); deb(DEB_EXIT); END setSparseness; -- PROCEDURE setDeviceType( type IN varchar2) IS BEGIN IF (deviceCount >= 8) THEN raise_application_error(-20280, 'Too many device types'); END IF; deviceCount := deviceCount + 1; deviceList(deviceCount) := type; IF (type = 'DISK') THEN diskDevice := TRUE; END IF; END setDeviceType; -- PROCEDURE setStandby( stby IN boolean) IS BEGIN if stby is NULL then onlyStandby := NULL; elsif stby then onlyStandby := TRUE#; else onlyStandby := FALSE#; end if; END setStandby; -- PROCEDURE setDeviceTypeAny IS BEGIN diskDevice := TRUE; anyDevice := TRUE#; deviceCount := 0; END setDeviceTypeAny; -- PROCEDURE resetDeviceType IS BEGIN FOR i in 1..8 LOOP deviceList(i) := NULL; END LOOP; deviceCount := 0; diskDevice := FALSE; anyDevice := FALSE#; END resetDeviceType; -- PROCEDURE setTag( tag IN varchar2 DEFAULT NULL) IS BEGIN restoreTag := tag; END setTag; -- PROCEDURE setRecoveryDestFile(onlyrdf IN BOOLEAN) IS BEGIN if onlyrdf then recoveryDestFile := TRUE; else recoveryDestFile := FALSE; end if; END setRecoveryDestFile; -- PROCEDURE setOrsFile(localOnly IN BOOLEAN, libKey IN NUMBER) IS BEGIN orsLocalFile := localOnly; orsLibKey := libKey; orsAnyFile := (NOT localOnly AND libKey IS NULL); END setOrsFile; -- -- -- -- FUNCTION getValidBackupSet( validBackupSetRec OUT NOCOPY validBackupSetRec_t ,checkDeviceIsAllocated IN number DEFAULT FALSE#) RETURN number IS lastCode number; checkRc number; local validBackupSetRec_t; BEGIN IF (bsRecCacheEnabled) THEN RETURN cacheGetValidBackupSet( validBackupSetRec => validBackupSetRec, checkDeviceIsAllocated => checkDeviceIsAllocated); END IF; deb(DEB_ENTER, 'getValidBackupSet'); -- IF (getValidBackupSetCursor = 'findValidBackupSet1P_c') THEN IF (NOT findValidBackupSet1P_c%ISOPEN) THEN RETURN FALSE#; END IF; ELSIF (getValidBackupSetCursor = 'findValidBackupSet_c') THEN IF (NOT findValidBackupSet_c%ISOPEN) THEN RETURN FALSE#; END IF; ELSE raise_application_error(-20204, 'Translation not started'); END IF; <> IF (getValidBackupSetCursor = 'findValidBackupSet1P_c') THEN FETCH findValidBackupSet1P_c INTO local; IF (findValidBackupSet1P_c%NOTFOUND) THEN CLOSE findValidBackupSet1P_c; deb(DEB_EXIT, 'with: FALSE#'); RETURN FALSE#; END IF; ELSIF (getValidBackupSetCursor = 'findValidBackupSet_c') THEN FETCH findValidBackupSet_c INTO local; IF (findValidBackupSet_c%NOTFOUND) THEN CLOSE findValidBackupSet_c; deb(DEB_EXIT, 'with: FALSE#'); RETURN FALSE#; END IF; END IF; lastCode := getValidBackupSetLast.code; -- save for test below getValidBackupSetLast := local; -- save for next time here IF (local.code <= lastCode) THEN -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- IF (checkDeviceIsAllocated = TRUE#) THEN IF (anyDevice = FALSE# AND isDeviceTypeAllocated(local.deviceType) = FALSE#) THEN deb(DEB_IN, 'device type not allocated: ' || local.deviceType); GOTO nextRow; END IF; END IF; validBackupSetRec := local; -- set OUT mode arg deb(DEB_IN, 'returning valid rec deviceType=' || local.deviceType || ' tag=' || local.tag || ' copyNumber=' || to_char(local.copyNumber)); deb(DEB_EXIT, 'with: TRUE#'); RETURN TRUE#; ELSE deb(DEB_IN, ' local.code=' || to_char(local.code) || ' lastCode=' || to_char(lastCode)); GOTO nextRow; END IF; deb(DEB_EXIT); END getValidBackupSet; -- -- -- -- FUNCTION getRcvRec( funCode IN number ,rcvRec OUT NOCOPY rcvRec_t ,callAgain OUT number) RETURN number IS rc number; BEGIN deb(DEB_ENTER, 'getRcvRec'); rc := 0; -- init for procedures callAgain := TRUE#; deb(DEB_IN, ' funCode=' || to_char(funCode)); IF (funCode = getCfCopy) THEN getControlfileCopy(rcvRec); ELSIF (funCode = getDfCopy) THEN getDatafileCopy(rcvRec); ELSIF (funCode = getAnyProxy) THEN getProxyCopy(rcvRec); ELSIF (funCode = getCfBackup) THEN rc := getControlfileBackup(rcvRec); IF (rc != SUCCESS OR NOT findControlfileBackupCursor) THEN callAgain := FALSE#; END IF; ELSIF (funCode = getSfBackup) THEN rc := getSpfileBackup(rcvRec => rcvRec); IF (rc != SUCCESS OR NOT findSpfileBackupCursor) THEN callAgain := FALSE#; END IF; ELSIF (funCode = listCfCopy) THEN listGetControlfileCopy(rcvRec); ELSIF (funCode = listDfCopy) THEN listGetDatafileCopy(rcvRec); ELSIF (funCode = listCfBackup) THEN listGetControlfileBackup(rcvRec); ELSIF (funCode = listSfBackup) THEN listGetSpfileBackup(rcvRec); ELSIF (funCode = listDfBackup) THEN listGetDatafileBackup(rcvRec); ELSIF (funCode = listAlBackup) THEN listGetArchivedLogBackup(rcvRec); ELSIF (funCode = listDfProxy) THEN listGetProxyDatafile(rcvRec); ELSIF (funCode = listAlProxy) THEN listGetProxyArchivedLog(rcvRec); ELSIF (funCode = getRecovAction) THEN callAgain := getRecoveryAction(rcvRec); ELSIF (funCode = getAlBackup) THEN rc := getArchivedLogBackup(rcvRec); IF (rc != SUCCESS) THEN callAgain := FALSE#; END IF; ELSIF (funCode = getRangeAlBackup) THEN rc := getRangeArchivedLogBackup(rcvRec); IF (rc = UNAVAILABLE) THEN callAgain := FALSE#; END IF; ELSIF (funCode = listAlCopy) THEN listGetArchivedLogCopy(rcvRec); ELSIF (funCode = listBSet) THEN listGetBackupsetFiles(rcvRec); ELSIF (funCode = getAllBSet) THEN getAllBackupSet(rcvRec); ELSE deb(DEB_EXIT, 'with error 20999'); raise_application_error(-20999, 'getRcvRec: unknown funCode: ' || to_char(funCode)); END IF; IF (debug) THEN printRcvRec(rcvRec); deb(DEB_EXIT, 'with rc:'||TO_CHAR(rc)); END IF; -- -- -- RETURN rc; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; END getRcvRec; -- -- -- -- PROCEDURE translateDatabase( sinceUntilSCN IN number DEFAULT NULL) IS fromSCN number; toSCN number; BEGIN deb(DEB_ENTER, 'translateDatabase'); validateState(getDatafileCursor); IF (untilSCN is NULL) THEN -- fromSCN := MAXSCNVAL; toSCN := MAXSCNVAL; ELSE -- an until clause is in effect fromSCN := untilSCN; IF (sinceUntilSCN = TRUE#) THEN -- -- -- toSCN := MAXSCNVAL; ELSE -- -- -- toSCN := fromSCN; END IF; END IF; IF (pdbIdList.count = 0) THEN deb(DEB_OPEN, 'translateDatabase_c'); OPEN translateDatabase_c(fromSCN, toSCN); getDatafileCursor := 'translateDatabase'; getDatafileNoRows.error := NULL; -- error not possible ELSIF (pdbIdList.count = 1) THEN deb(DEB_OPEN, 'translateDatabaseOfPdbId_c'); OPEN translateDatabaseOfPdbId_c (fromSCN, toSCN, pdbIdList.first + CONST2GVAL); getDatafileCursor := 'translateDatabaseOfPdbId'; ELSE deb(DEB_OPEN, 'translateDatabaseOfPdbIdL_c'); OPEN translateDatabaseOfPdbIdL_c(fromSCN, toSCN); getDatafileCursor := 'translateDatabaseOfPdbIdL'; END IF; IF (untilSCN IS NOT NULL AND pdbIdList.count != 0) THEN getDatafileNoRows.error := -20513; getDatafileNoRows.msg := 'UNTIL TIME or SCN is before plugggable database CREATION SCN'; END IF; getDatafileLast.dfNumber := NULL; -- no last row yet skipTablespaceList.delete; setDBTransClause; deb(DEB_EXIT); END translateDatabase; -- -- PROCEDURE skipTableSpace( tsName IN varchar2 ,pdbId IN number DEFAULT 0) IS tsRec tablespace_t; BEGIN tsRec.name := tsName; tsRec.pdbId := pdbId; skipTablespaceList(skipTablespaceList.count + 1) := tsRec; END skipTableSpace; -- PROCEDURE translateTablespace( ts_name IN varchar2 ,pdb_id IN number DEFAULT 0) IS BEGIN deb(DEB_ENTER, 'translateTablespace'); validateState(getDatafileCursor); deb(DEB_OPEN, 'translateTablespace_c'); OPEN translateTablespace_c(tsName => ts_name, pdbId => pdb_id); getDatafileCursor := 'translateTablespace'; getDatafileNoRows.error := -20202; getDatafileNoRows.msg := 'Tablespace does not exist'; getDatafileLast.dfNumber := NULL; -- no last row yet skipTablespaceList.delete; deb(DEB_EXIT); END translateTablespace; -- PROCEDURE translateDataFile( fname IN varchar2) IS BEGIN deb(DEB_ENTER, 'translateDataFile_1'); validateState(getDatafileCursor); deb(DEB_OPEN, 'translateDatafileName'); OPEN translateDatafileName(fileName => fname); IF (untilSCN is NULL and untilTime is NULL) THEN getDatafileNoRows.error := -20201; getDatafileNoRows.msg := 'Datafile does not exist'; ELSE getDatafileNoRows.error := -20222; getDatafileNoRows.msg := 'Datafile name does not exist or is ambiguous'; END IF; getDatafileCursor := 'translateDatafileName'; getDatafileLast.dfNumber := NULL; -- no last row yet skipTablespaceList.delete; deb(DEB_EXIT); END translateDatafile; -- PROCEDURE translateDataFile( fno IN number) IS BEGIN deb(DEB_ENTER, 'translateDataFile_2'); validateState(getDatafileCursor); deb(DEB_OPEN, 'translateDatafileNumber'); OPEN translateDatafileNumber(fno => fno); getDatafileCursor := 'translateDatafileNumber'; getDatafileNoRows.error := -20201; getDatafileNoRows.msg := 'Datafile does not exist'; getDatafileLast.dfNumber := NULL; -- no last row yet skipTablespaceList.delete; setDfTransClause(fno => fno); deb(DEB_EXIT); END translateDatafile; -- PROCEDURE translateDataFile( fno IN number ,ckpscn IN number) IS BEGIN deb(DEB_ENTER, 'translateDataFile_3'); validateState(getDatafileCursor); deb(DEB_OPEN, 'translateDatafileCheckpoint'); OPEN translateDatafileCheckpoint(fno => fno, ckpSCN => ckpscn); getDatafileCursor := 'translateDatafileCheckpoint'; getDatafileNoRows.error := -20201; getDatafileNoRows.msg := 'Datafile does not exist'; getDatafileLast.dfNumber := NULL; -- no last row yet skipTablespaceList.delete; setDfTransClause(fno => fno); deb(DEB_EXIT); END translateDatafile; -- PROCEDURE translateAllDatafile IS BEGIN deb(DEB_ENTER, 'translateAllDataFile'); validateState(getDatafileCursor); IF (pdbIdList.count = 0) THEN deb(DEB_OPEN, 'translateAllDf_c'); OPEN translateAllDf_c; getDatafileCursor := 'translateAllDf'; ELSIF (pdbIdList.count = 1) THEN deb(DEB_OPEN, 'translateAllDfOfPdbId_c'); OPEN translateAllDfOfPdbId_c(pdbIdList.first + CONST2GVAL); getDatafileCursor := 'translateAllDfOfPdbId'; ELSE deb(DEB_OPEN, 'translateAllDfOfPdbIdL_c'); OPEN translateAllDfOfPdbIdL_c; getDatafileCursor := 'translateAllDfOfPdbIdList'; END IF; getDatafileNoRows.error := NULL; -- error not possible getDatafileLast.dfNumber := NULL; -- no last row yet skipTablespaceList.delete; setDBTransClause; deb(DEB_EXIT); END; -- PROCEDURE translateCorruptList IS BEGIN validateState(getDatafileCursor); OPEN translateCorruptList_c; getDatafileCursor := 'translateCorruptList'; getDatafileNoRows.error := -20504; getDatafileNoRows.msg := 'Corruption List does not exist'; getDatafileLast.dfNumber := NULL; -- no last row yet skipTablespaceList.delete; END translateCorruptList; -- -- PROCEDURE getDatafile( dfRec OUT NOCOPY dfRec_t ,oldClient IN boolean DEFAULT FALSE) IS getDatafileRowcount number; local dfRec_t; BEGIN deb(DEB_ENTER, 'getDataFile_1'); <> IF (getDatafileCursor = 'translateDatabase') THEN FETCH translateDatabase_c INTO local; IF (translateDatabase_c%NOTFOUND) THEN -- getDatafileRowcount := translateDatabase_c%ROWCOUNT; CLOSE translateDatabase_c; END IF; ELSIF (getDatafileCursor = 'translateDatabaseOfPdbId') THEN FETCH translateDatabaseOfPdbId_c INTO local; IF (translateDatabaseOfPdbId_c%NOTFOUND) THEN -- getDatafileRowcount := translateDatabaseOfPdbId_c%ROWCOUNT; CLOSE translateDatabaseOfPdbId_c; END IF; ELSIF (getDatafileCursor = 'translateDatabaseOfPdbIdL') THEN FETCH translateDatabaseOfPdbIdL_c INTO local; IF (translateDatabaseOfPdbIdL_c%NOTFOUND) THEN -- getDatafileRowcount := translateDatabaseOfPdbIdL_c%ROWCOUNT; CLOSE translateDatabaseOfPdbIdL_c; END IF; ELSIF (getDatafileCursor = 'translateAllDf') THEN FETCH translateAllDf_c INTO local; IF (translateAllDf_c%NOTFOUND) THEN -- getDatafileRowcount := translateAllDf_c%ROWCOUNT; CLOSE translateAllDf_c; END IF; ELSIF (getDatafileCursor = 'translateAllDfOfPdbId') THEN FETCH translateAllDfOfPdbId_c INTO local; IF (translateAllDfOfPdbId_c%NOTFOUND) THEN -- getDatafileRowcount := translateAllDfOfPdbId_c%ROWCOUNT; CLOSE translateAllDfOfPdbId_c; END IF; ELSIF (getDatafileCursor = 'translateAllDfOfPdbIdList') THEN FETCH translateAllDfOfPdbIdL_c INTO local; IF (translateAllDfOfPdbIdL_c%NOTFOUND) THEN -- getDatafileRowcount := translateAllDfOfPdbIdL_c%ROWCOUNT; CLOSE translateAllDfOfPdbIdL_c; END IF; ELSIF (getDatafileCursor = 'translateTablespace') THEN FETCH translateTablespace_c INTO local; IF (translateTablespace_c%NOTFOUND) THEN -- getDatafileRowcount := translateTablespace_c%ROWCOUNT; CLOSE translateTablespace_c; END IF; ELSIF (getDatafileCursor = 'translateDatafileName') THEN FETCH translateDatafileName INTO local; IF (translateDatafileName%NOTFOUND) THEN -- getDatafileRowcount := translateDatafileName%ROWCOUNT; CLOSE translateDatafileName; END IF; IF (oldClient) THEN -- IF (translateDatafileName%ISOPEN) THEN CLOSE translateDatafileName; END IF; getDatafileCursor := NULL; END IF; ELSIF (getDatafileCursor = 'translateDatafileNumber') THEN FETCH translateDatafileNumber INTO local; IF (translateDatafileNumber%NOTFOUND) THEN -- getDatafileRowcount := translateDatafileNumber%ROWCOUNT; CLOSE translateDatafileNumber; END IF; IF (oldClient) THEN -- IF (translateDatafileNumber%ISOPEN) THEN CLOSE translateDatafileNumber; END IF; getDatafileCursor := NULL; END IF; ELSIF (getDatafileCursor = 'translateDatafileCheckpoint') THEN FETCH translateDatafileCheckpoint INTO local; IF (translateDatafileCheckpoint%NOTFOUND) THEN -- getDatafileRowcount := translateDatafileCheckpoint%ROWCOUNT; CLOSE translateDatafileCheckpoint; END IF; IF (oldClient) THEN -- IF (translateDatafileCheckpoint%ISOPEN) THEN CLOSE translateDatafileCheckpoint; END IF; getDatafileCursor := NULL; END IF; ELSIF (getDatafileCursor = 'translateCorruptList') THEN FETCH translateCorruptList_c INTO local; IF (translateCorruptList_c%NOTFOUND) THEN -- getDatafileRowcount := translateCorruptList_c%ROWCOUNT; CLOSE translateCorruptList_c; END IF; ELSE deb(DEB_EXIT, 'with error 20204'); raise_application_error(-20204, 'Translation not started'); END IF; IF (getDatafileRowcount IS NOT NULL) THEN -- if %NOTFOUND getDatafileCursor := NULL; -- we closed it above IF (getDatafileRowcount = 0 AND getDatafileNoRows.error IS NOT NULL) THEN -- deb(DEB_EXIT, 'with norows error'); raise_application_error(getDatafileNoRows.error, getDatafileNoRows.msg); ELSE deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; -- signal end-of-fetch END IF; END IF; IF (skipTablespace(local.tsName, local.pdbId)) THEN GOTO nextRow; END IF; -- IF (getDatafileLast.dfNumber = local.dfNumber) THEN IF (getDatafileLast.pluginSCN != 0) THEN IF (getDatafileLast.pluginSCN = local.pluginSCN) THEN deb(DEB_PRINT, 'not returning' || local.fileName); GOTO nextRow; END IF; ELSIF (getDatafileLast.dfCreationSCN = local.dfCreationSCN) THEN deb(DEB_PRINT, 'not returning' || local.fileName); GOTO nextRow; END IF; END IF; -- -- -- IF (local.pdbName IS NULL) THEN local.pdbName := translatePdb2Name(local.pdbId); END IF; getDatafileLast := local; setDfTransClause(fno => local.dfNumber); dfRec := local; -- set OUT mode arg deb(DEB_EXIT); END getDatafile; -- -- -- -- PROCEDURE translateOnlineLogs(srls IN number DEFAULT 0) IS BEGIN deb(DEB_ENTER, 'translateOnlineLogs'); IF (translateOnlineLogs_c%ISOPEN) THEN validateState('translateOnlineLogs_c'); -- raise the error END IF; deb(DEB_OPEN, 'translateOnlineLogs_c, srls='||srls); OPEN translateOnlineLogs_c(srls); deb(DEB_EXIT); END translateOnlineLogs; -- PROCEDURE getOnlineLog( fname OUT varchar2 ,thread# OUT number ,group# OUT number) IS BEGIN deb(DEB_ENTER, 'getOnlineLog'); FETCH translateOnlineLogs_c INTO thread#, group#, fname; IF (translateOnlineLogs_c%NOTFOUND) THEN CLOSE translateOnlineLogs_c; deb(DEB_EXIT, 'with NULL (no archivelog found)'||fname); fname := NULL; -- indicate end-of-fetch RETURN; END IF; deb(DEB_EXIT, 'with archivelog:'||fname); END getOnlineLog; -- -- -- -- PROCEDURE getArchivedLog( alRec OUT NOCOPY alRec_t, closeCursor IN boolean DEFAULT FALSE) IS getArchivedLogRowcount number; local alRec_t; BEGIN deb(DEB_ENTER, 'getArchivedLog'); <> IF (getArchivedLogCursor = 'translateArcLogKey') THEN FETCH translateArcLogKey INTO local; IF (translateArcLogKey%NOTFOUND) THEN getArchivedLogRowcount := translateArcLogKey%ROWCOUNT; CLOSE translateArcLogKey; END IF; IF (closeCursor AND translateArcLogKey%ISOPEN) THEN CLOSE translateArcLogKey; END IF; ELSIF (getArchivedLogCursor = 'translateArcLogName') THEN FETCH translateArcLogName INTO local; IF (translateArcLogName%NOTFOUND) THEN getArchivedLogRowcount := translateArcLogName%ROWCOUNT; CLOSE translateArcLogName; END IF; IF (closeCursor AND translateArcLogName%ISOPEN) THEN CLOSE translateArcLogName; END IF; ELSIF (getArchivedLogCursor = 'translateArcLogSeqRange') THEN FETCH translateArcLogSeqRange INTO local; IF (translateArcLogSeqRange%NOTFOUND) THEN getArchivedLogRowcount := translateArcLogSeqRange%ROWCOUNT; CLOSE translateArcLogSeqRange; END IF; IF (closeCursor AND translateArcLogSeqRange%ISOPEN) THEN CLOSE translateArcLogSeqRange; END IF; ELSIF (getArchivedLogCursor = 'translateFrgnArcLogSeqRange') THEN -- raise_application_error(-20999, 'Not supported in recovery catalog'); -- ELSIF (getArchivedLogCursor = 'translateArcLogSeqRange2') THEN FETCH translateArcLogSeqRange2 INTO local; IF (translateArcLogSeqRange2%NOTFOUND) THEN getArchivedLogRowcount := translateArcLogSeqRange2%ROWCOUNT; CLOSE translateArcLogSeqRange2; END IF; IF (closeCursor AND translateArcLogSeqRange2%ISOPEN) THEN CLOSE translateArcLogSeqRange2; END IF; ELSIF (getArchivedLogCursor = 'translateArcLogTimeRange') THEN FETCH translateArcLogTimeRange INTO local; IF (translateArcLogTimeRange%NOTFOUND) THEN getArchivedLogRowcount := translateArcLogTimeRange%ROWCOUNT; CLOSE translateArcLogTimeRange; END IF; IF (closeCursor AND translateArcLogTimeRange%ISOPEN) THEN CLOSE translateArcLogTimeRange; END IF; ELSIF (getArchivedLogCursor = 'translateFrgnArcLogTimeRange') THEN -- raise_application_error(-20999, 'Not supported in recovery catalog'); -- ELSIF (getArchivedLogCursor = 'translateArcLogTimeRange2') THEN FETCH translateArcLogTimeRange2 INTO local; IF (translateArcLogTimeRange2%NOTFOUND) THEN getArchivedLogRowcount := translateArcLogTimeRange2%ROWCOUNT; CLOSE translateArcLogTimeRange2; END IF; IF (closeCursor AND translateArcLogTimeRange2%ISOPEN) THEN CLOSE translateArcLogTimeRange2; END IF; ELSIF (getArchivedLogCursor = 'translateArcLogSCNRange') THEN FETCH translateArcLogSCNRange INTO local; IF (translateArcLogSCNRange%NOTFOUND) THEN getArchivedLogRowcount := translateArcLogSCNRange%ROWCOUNT; CLOSE translateArcLogSCNRange; END IF; IF (closeCursor AND translateArcLogSCNRange%ISOPEN) THEN CLOSE translateArcLogSCNRange; END IF; ELSIF (getArchivedLogCursor = 'translateFrgnArcLogSCNRange') THEN -- raise_application_error(-20999, 'Not supported in recovery catalog'); -- ELSIF (getArchivedLogCursor = 'translateArcLogSCNRange2') THEN FETCH translateArcLogSCNRange2 INTO local; IF (translateArcLogSCNRange2%NOTFOUND) THEN getArchivedLogRowcount := translateArcLogSCNRange2%ROWCOUNT; CLOSE translateArcLogSCNRange2; END IF; IF (closeCursor AND translateArcLogSCNRange2%ISOPEN) THEN CLOSE translateArcLogSCNRange2; END IF; ELSIF (getArchivedLogCursor = 'translateArcLogPattern') THEN FETCH translateArcLogPattern INTO local; IF (translateArcLogPattern%NOTFOUND) THEN getArchivedLogRowcount := translateArcLogPattern%ROWCOUNT; CLOSE translateArcLogPattern; END IF; IF (closeCursor AND translateArcLogPattern%ISOPEN) THEN CLOSE translateArcLogPattern; END IF; ELSIF (getArchivedLogCursor = 'translateFrgnArcLogPattern') THEN -- raise_application_error(-20999, 'Not supported in recovery catalog'); -- ELSE deb(DEB_EXIT, 'with error 20204'); raise_application_error(-20204, 'Translation not started'); END IF; IF (closeCursor) THEN getArchivedLogCursor := NULL; END IF; IF (getArchivedLogRowcount IS NOT NULL) THEN getArchivedLogCursor := NULL; -- we closed it above getArchivedLogDoingRecovery := FALSE#; -- clear for next time getArchivedLogOnlyrdf := 0; -- clear for next time currInc := -1; deb(DEB_PRINT, 'getArchivedLogDoingRecovery cleared'); -- -- IF ((getArchivedLogRowcount = 0 OR getArchivedLogLast.thread is NULL) AND getArchivedLogNoRows.error IS NOT NULL) THEN -- getArchivedLogLast := NULL; -- clear for next time deb(DEB_EXIT, 'with norows error'); raise_application_error(getArchivedLogNoRows.error, getArchivedLogNoRows.msg); ELSE deb(DEB_EXIT, 'with no more records'); getArchivedLogLast := NULL; -- clear for next time RAISE no_data_found; -- signal end-of-fetch END IF; END IF; deb(DEB_PRINT, 'getArchivedLog - resetscn='||local.rlgSCN|| ' thread='||local.thread|| ' seq='||local.sequence|| ' lowscn='||local.lowSCN|| ' nextscn='||local.nextSCN|| ' terminal='||local.terminal|| ' site_key_order_col='||local.site_key_order_col|| ' isrdf='||local.isrdf|| ' stamp='||local.stamp); -- IF (getArchivedLogDoingRecovery = TRUE#) THEN -- IF (getArchivedLogLast.rlgSCN = local.rlgSCN AND getArchivedLogLast.rlgTime = local.rlgTime AND currInc <> -1) THEN deb(DEB_PRINT, 'getArchivedLog - currInc =' || currInc); -- IF (currInc > 0 AND local.lowSCN >= inc_list(currInc-1).resetlogs_change#-1) THEN deb(DEB_PRINT, 'getArchivedLog - Skip log - belongs to orphan branch'); GOTO nextRow; END IF; ELSE -- currInc := -1; FOR inc_idx in 0..max_inc_idx-1 LOOP -- -- IF tc_fromSCN > inc_list(inc_idx).resetlogs_change# AND local.rlgSCN < inc_list(inc_idx).resetlogs_change# THEN deb(DEB_PRINT, 'getArchivedLog -Skip log precedes recovery SCN - '||inc_idx); EXIT; END IF; -- -- -- -- IF (local.rlgSCN = inc_list(inc_idx).resetlogs_change# AND local.rlgTime = inc_list(inc_idx).resetlogs_time) THEN -- -- IF inc_idx > 0 THEN IF local.lowSCN < inc_list(inc_idx-1).resetlogs_change# - 1 THEN currInc := inc_idx; deb(DEB_PRINT, 'getArchivedLog - currInc2 set to '||currInc); END IF; ELSE currInc := inc_idx; deb(DEB_PRINT, 'getArchivedLog - currIn3 set to '||currInc); END IF; EXIT; END IF; END LOOP; IF (currInc = -1) THEN deb(DEB_PRINT,'getArchivedLog - Skip log - not required by recovery'); GOTO nextRow; END IF; END IF; END IF; -- IF (local.thread = getArchivedLogLast.thread AND local.sequence = getArchivedLogLast.sequence AND local.terminal = getArchivedLogLast.terminal AND local.lowSCN = getArchivedLogLast.lowSCN AND local.rlgSCN = getArchivedLogLast.rlgSCN AND local.rlgTime = getArchivedLogLast.rlgTime) THEN local.duplicate := TRUE#; END IF; IF (getArchivedLogDuplicates = FALSE# AND -- if don't want duplicates local.duplicate = TRUE#) THEN deb(DEB_PRINT, 'getArchivedLog - dont want duplicates'); GOTO nextRow; END IF; -- -- -- -- -- -- -- -- -- -- -- IF (getArchivedLogOnlyrdf = 1 AND local.duplicate = FALSE# AND local.isrdf = 'NO') THEN deb(DEB_PRINT, 'getArchiveLog - dont want non-recovery area log '); GOTO nextRow; END IF; -- -- -- IF IsDuplicateAlName(local.duplicate, local.filename) THEN GOTO nextRow; END IF; -- -- IF (local.thread = getArchivedLogLast.thread AND local.sequence = getArchivedLogLast.sequence AND local.lowSCN = getArchivedLogLast.lowSCN AND local.rlgSCN = getArchivedLogLast.rlgSCN AND local.rlgTime = getArchivedLogLast.rlgTime AND getArchivedLogLast.terminal = 'YES' AND local.terminal = 'NO') THEN deb(DEB_PRINT, 'getArchivedLog - Skip log - not an EOR log'); GOTO nextRow; END IF; -- -- IF (getArchivedLogDoingRecovery = TRUE#) THEN IF (local.thread = getArchivedLogLast.thread AND local.lowSCN <> getArchivedLogLast.lowSCN AND local.sequence = getArchivedLogLast.sequence) THEN deb(DEB_PRINT, 'getArchivedLog - Skip log - filter bad sequence log'); GOTO nextRow; END IF; END IF; -- -- IF (local.stamp <= 0) THEN local.stamp := NULL; END IF; IF getArchivedLogCursor IS NULL THEN getArchivedLogLast := NULL; -- clear for next time getArchivedLogDoingRecovery := FALSE#; -- clear for next time getArchivedLogOnlyrdf := 0; currInc := -1; deb(DEB_PRINT, 'getArchivedLogDoingRecovery cleared'); deb(DEB_PRINT, 'getArchivedLogLast := NULL'); ELSE getArchivedLogLast := local; deb(DEB_PRINT,'getArchivedLogLast('||getArchivedLogCursor||') := local'); deb(DEB_PRINT, 'getArchivedLogLast := local'); END IF; alRec := local; -- set OUT mode arg deb(DEB_EXIT); END getArchivedLog; -- PROCEDURE translateArchivedLogKey( alKey IN number ,needstby IN number DEFAULT NULL) IS BEGIN deb(DEB_ENTER, 'translateArchivedLogKey'); validateState(getArchivedLogCursor); deb(DEB_OPEN, 'translateArcLogKey'); OPEN translateArcLogKey(alKey => alKey); getArchivedLogCursor := 'translateArcLogKey'; getArchivedLogDuplicates := NULL; getArchivedLogNoRows.error := -20240; getArchivedLogNoRows.msg := 'Archived log does not exist'; deb(DEB_EXIT); END translateArchivedLogKey; -- PROCEDURE translateArchivedLogKey( al_key IN number ,available IN number DEFAULT 1 -- ignored (for compatability) ,unavailable IN number DEFAULT 1 -- ignored (for compatability) ,deleted IN number DEFAULT 1 -- ignored (for compatability) ,online IN number DEFAULT 1 -- ignored (for compatability) ,recid OUT number ,stamp OUT number ,thread# OUT number ,sequence# OUT number ,low_scn OUT number ,reset_scn OUT number ,block_size OUT number ,fname OUT varchar2 ,needstby IN number DEFAULT NULL) IS alRec alRec_t; BEGIN deb(DEB_ENTER, 'translateArchivedLogKey816'); translateArchivedLogKey(alKey => al_key, needstby => needstby); getArchivedLog(alRec => alRec, closeCursor => TRUE); recid := alRec.recid; stamp := alRec.stamp; thread# := alRec.thread; sequence# := alRec.sequence; low_scn := alRec.lowSCN; reset_scn := alRec.rlgSCN; block_size := alRec.blockSize; fname := alRec.fileName; deb(DEB_EXIT); END translateArchivedLogKey; -- -- -- -- -- PROCEDURE translateArchivedLogName( fname IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,deleted IN number DEFAULT NULL -- for compatability ,online IN number -- ignored ,duplicates IN number ,statusMask IN binary_integer DEFAULT NULL -- for compatability ,needstby IN number DEFAULT NULL) IS BEGIN deb(DEB_ENTER, 'translateArchivedLogName'); validateState(getArchivedLogCursor); deb(DEB_OPEN, 'translateArcLogName'); OPEN translateArcLogName(fname => fname, online => online, statusMask => NVL(statusMask, computeAvailableMask(available, unavailable, deleted, 0)), needstby => needstby); getARchivedLogCursor := 'translateArcLogName'; getArchivedLogDuplicates := duplicates; getArchivedLogNoRows.error := -20240; getArchivedLogNoRows.msg := 'Archived log does not exist'; deb(DEB_EXIT); END translateArchivedLogName; -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE translateArchivedLogSeqRange( thread# IN number ,fromseq# IN number ,toseq# IN number ,pattern IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,deleted IN number DEFAULT NULL -- for compatability ,online IN number -- ignored ,duplicates IN number ,statusMask IN binary_integer DEFAULT NULL -- for compatability ,needstby IN number DEFAULT NULL -- for compatability ,foreignal IN binary_integer DEFAULT 0 -- for compatability ,incarn IN number DEFAULT NULL) -- for compatibility IS mask number := NVL(statusMask, computeAvailableMask(available, unavailable, deleted, 0)); lincarn number := incarn; BEGIN deb(DEB_ENTER, 'translateArchivedLogSeqRange'); validateState(getArchivedLogCursor); IF (thread# is NULL) THEN deb(DEB_EXIT, 'with error 20210'); raise_application_error(-20210, 'Thread# is missing'); END IF; setAlTransClause(thread => thread#, fromSeq => fromseq#, toSeq => toseq#, pattern => pattern); -- -- -- -- IF (foreignal != 0) THEN IF (tc_dbid.count = 0) THEN tc_anydbid := TRUE#; END IF; deb(DEB_OPEN, 'translateFrgnArcLogSeqRange'); -- raise_application_error(-20999, 'Not supported in recovery catalog'); -- ELSE IF (bitand(mask,BSdeleted) != 0 AND pattern IS NULL) THEN -- -- -- -- deb(DEB_OPEN, 'translateArcLogSeqRange2'); OPEN translateArcLogSeqRange2(thread# => thread#, incarn => NVL(lincarn,-1), fromseq# => fromseq#, toseq# => toseq#, statusMask => mask, online => online, needstby => needstby); getArchivedLogCursor := 'translateArcLogSeqRange2'; ELSE deb(DEB_OPEN, 'translateArcLogSeqRange'); OPEN translateArcLogSeqRange(thread# => thread#, incarn => NVL(lincarn,-1), fromseq# => fromseq#, toseq# => toseq#, pattern => pattern, statusMask => mask, online => online, needstby => needstby); getArchivedLogCursor := 'translateArcLogSeqRange'; END IF; getArchivedLogNoRows.error := -20242; getArchivedLogNoRows.msg := 'No archived logs in the range specified'; END IF; getArchivedLogDuplicates := duplicates; deb(DEB_EXIT); END translateArchivedLogSeqRange; -- -- -- -- -- -- -- -- PROCEDURE translateArchivedLogTimeRange( thread# IN number ,fromTime IN date ,toTime IN date ,pattern IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,deleted IN number DEFAULT NULL -- for compatability ,online IN number -- ignored ,duplicates IN number ,statusMask IN binary_integer DEFAULT NULL -- for compatability ,needstby IN number DEFAULT NULL -- for compatability ,foreignal IN binary_integer DEFAULT 0 -- for compatability ,incarn IN number DEFAULT NULL) -- for compatibility IS mask number := NVL(statusMask, computeAvailableMask(available, unavailable, deleted, 0)); lincarn number := incarn; BEGIN deb(DEB_ENTER, 'translateArchivedLogTimeRange'); validateState(getArchivedLogCursor); setAlTransClause(thread => thread#, fromTime => fromTime, toTime => toTime, pattern => pattern); -- -- -- -- IF (foreignal != 0) THEN IF (tc_dbid.count = 0) THEN tc_anydbid := TRUE#; END IF; deb(DEB_OPEN, 'translateFrgnArcLogTimeRange'); -- raise_application_error(-20999, 'Not supported in recovery catalog'); -- ELSE IF (bitand(mask,BSdeleted) != 0 AND pattern IS NULL) THEN -- -- -- -- deb(DEB_OPEN, 'translateArcLogTimeRange2'); OPEN translateArcLogTimeRange2(thread# => thread#, incarn => NVL(lincarn,0), fromTime => fromTime, toTime => toTime, statusMask => mask, online => online, needstby => needstby); getArchivedLogCursor := 'translateArcLogTimeRange2'; ELSE deb(DEB_OPEN, 'translateArcLogTimeRange'); OPEN translateArcLogTimeRange(thread# => thread#, incarn => NVL(lincarn,0), fromTime => fromTime, toTime => toTime, pattern => pattern, statusMask => mask, online => online, needstby => needstby); getArchivedLogCursor := 'translateArcLogTimeRange'; END IF; getArchivedLogNoRows.error := -20242; getArchivedLogNoRows.msg := 'No archived logs in the range specified'; END IF; getArchivedLogDuplicates := duplicates; deb(DEB_EXIT); END translateArchivedLogTimeRange; -- -- -- -- -- -- -- -- PROCEDURE translateArchivedLogSCNRange( thread# IN number ,fromSCN IN number ,toSCN IN number ,pattern IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,deleted IN number DEFAULT NULL -- for compatability ,online IN number ,duplicates IN number ,statusMask IN binary_integer DEFAULT NULL -- for compatability ,needstby IN number DEFAULT NULL ,doingRecovery IN number DEFAULT FALSE# ,onlyrdf IN binary_integer DEFAULT 0 ,reset_scn IN number DEFAULT NULL -- for compatibility ,reset_time IN date DEFAULT NULL -- for compatibility ,sequence# IN number DEFAULT NULL -- for compatibility ,foreignal IN binary_integer DEFAULT 0 -- for compatability ,incarn IN number DEFAULT NULL) -- for compatibility IS adjusted_toSCN number; mask number := NVL(statusMask, computeAvailableMask(available, unavailable, deleted, 0)); lincarn number := incarn; BEGIN deb(DEB_ENTER, 'translateArchivedLogSCNRange'); validateState(getArchivedLogCursor); IF (untilTime IS NULL) THEN -- -- -- -- adjusted_toSCN := least(nvl(toSCN, untilSCN), nvl(untilSCN, toSCN)); ELSE -- -- -- -- -- -- adjusted_toSCN := toSCN; END IF; -- -- -- -- -- IF (adjusted_toSCN <= fromSCN) THEN adjusted_toSCN := fromSCN+1; END IF; setAlTransClause(thread => thread#, fromSCN => fromSCN, toSCN => adjusted_toSCN, pattern => pattern); -- -- -- -- IF (foreignal != 0) THEN IF (tc_dbid.count = 0) THEN tc_anydbid := TRUE#; END IF; deb(DEB_OPEN, 'translateFrgnArcLogSCNRange'); -- raise_application_error(-20999, 'Not supported in recovery catalog'); -- ELSE IF (bitand(mask,BSdeleted) != 0 AND pattern IS NULL) THEN -- -- -- -- deb(DEB_OPEN, 'translateArcLogSCNRange2'); OPEN translateArcLogSCNRange2(thread# => thread#, incarn => NVL(lincarn,0), sequence# => sequence#, fromSCN => fromSCN, toSCN => adjusted_toSCN, toTime => untilTime, statusMask => mask, online => online, needstby => needstby, reset_scn => reset_scn, reset_time => reset_time); getArchivedLogCursor := 'translateArcLogSCNRange2'; deb(DEB_IN, ' using cursor 2 fromSCN=' || to_char(fromSCN) || ' toSCN=' || to_char(adjusted_toSCN)); ELSE deb(DEB_OPEN, 'translateArcLogSCNRange'); OPEN translateArcLogSCNRange(thread# => thread#, incarn => NVL(lincarn,0), sequence# => sequence#, fromSCN => fromSCN, toSCN => adjusted_toSCN, pattern => pattern, statusMask => mask, online => online, needstby => needstby, reset_scn => reset_scn, reset_time => reset_time); getArchivedLogCursor := 'translateArcLogSCNRange'; END IF; getArchivedLogNoRows.error := -20242; getArchivedLogNoRows.msg := 'No archived logs in the range specified'; END IF; getArchivedLogDuplicates := duplicates; getArchivedLogDoingRecovery := DoingRecovery; IF (DoingRecovery = TRUE#) THEN deb(DEB_PRINT, 'getArchivedLogDoingRecovery set to TRUE'); END IF; getArchivedLogOnlyrdf := onlyrdf; deb(DEB_EXIT); END translateArchivedLogSCNRange; -- -- -- PROCEDURE translateArchivedLogPattern( pattern IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,deleted IN number DEFAULT NULL -- for compatability ,online IN number ,duplicates IN number ,statusMask IN binary_integer DEFAULT NULL -- for compatability ,needstby IN number DEFAULT NULL -- for compatability ,foreignal IN binary_integer DEFAULT 0) -- for compatability IS mask number := NVL(statusMask, computeAvailableMask(available, unavailable, deleted, 0)); BEGIN deb(DEB_ENTER, 'translateArchivedLogPattern'); IF (bitand(mask,BSdeleted) != 0 AND pattern IS NULL) THEN -- -- -- -- -- translateArchivedLogSCNRange( thread# => NULL, fromscn => 0, toscn => highscnval+1, pattern => NULL, statusMask => mask, online => online, duplicates => duplicates, foreignal => foreignal); ELSE validateState(getArchivedLogCursor); setAlTransClause(pattern => pattern); IF (foreignal != 0) THEN IF (tc_dbid.count = 0) THEN tc_anydbid := TRUE#; END IF; deb(DEB_OPEN, 'translateFrgnArcLogPattern'); -- raise_application_error(-20999, 'Not supported in recovery catalog'); -- ELSE deb(DEB_OPEN, 'translateArcLogPattern'); OPEN translateArcLogPattern(pattern => pattern, statusMask => mask, online => online); getArchivedLogCursor := 'translateArcLogPattern'; getArchivedLogNoRows.error := -20242; getArchivedLogNoRows.msg := 'No archived logs in the range specified'; END IF; getArchivedLogDuplicates := duplicates; END IF; deb(DEB_EXIT); END translateArchivedLogPattern; -- PROCEDURE translateArchivedLogCancel IS BEGIN deb(DEB_ENTER, 'translateArchivedLogCancel'); IF (getArchivedLogCursor = 'translateArcLogKey') THEN CLOSE translateArcLogKey; ELSIF (getArchivedLogCursor = 'translateArcLogName') THEN CLOSE translateArcLogName; ELSIF (getArchivedLogCursor = 'translateArcLogSeqRange') THEN CLOSE translateArcLogSeqRange; ELSIF (getArchivedLogCursor = 'translateFrgnArcLogSeqRange') THEN -- raise_application_error(-20999, 'Not supported in recovery catalog'); -- ELSIF (getArchivedLogCursor = 'translateArcLogSeqRange2') THEN CLOSE translateArcLogSeqRange2; ELSIF (getArchivedLogCursor = 'translateArcLogTimeRange') THEN CLOSE translateArcLogTimeRange; ELSIF (getArchivedLogCursor = 'translateFrgnArcLogTimeRange') THEN -- raise_application_error(-20999, 'Not supported in recovery catalog'); -- ELSIF (getArchivedLogCursor = 'translateArcLogTimeRange2') THEN CLOSE translateArcLogTimeRange2; ELSIF (getArchivedLogCursor = 'translateArcLogSCNRange') THEN CLOSE translateArcLogSCNRange; ELSIF (getArchivedLogCursor = 'translateFrgnArcLogSCNRange') THEN -- raise_application_error(-20999, 'Not supported in recovery catalog'); -- ELSIF (getArchivedLogCursor = 'translateArcLogSCNRange2') THEN CLOSE translateArcLogSCNRange2; ELSIF (getArchivedLogCursor = 'translateArcLogPattern') THEN CLOSE translateArcLogPattern; ELSIF (getArchivedLogCursor = 'translateFrgnArcLogPattern') THEN -- raise_application_error(-20999, 'Not supported in recovery catalog'); -- END IF; getArchivedLogCursor := NULL; -- we closed it above getArchivedLogLast := NULL; -- clear for next time getArchivedLogDoingRecovery := FALSE#; -- clear for next time resetAlTransClause; deb(DEB_EXIT); END translateArchivedLogCancel; -- -- -- -- PROCEDURE getArchivedLog( recid OUT number ,stamp OUT number ,thread# OUT number ,sequence# OUT number ,low_scn OUT number ,nxt_scn OUT number ,fname OUT varchar2 ,reset_scn OUT number ,block_size OUT number ,blocks OUT number) IS alRec alRec_t; BEGIN deb(DEB_ENTER, 'getArchivedLog'); <> getArchivedLog(alRec); -- -- -- -- recid := nvl(alRec.recid,0); -- no null indicator before 8.1.6 stamp := nvl(alRec.stamp, 0); -- no null indicator before 8.1.6 thread# := alRec.thread; sequence# := alRec.sequence; low_scn := alRec.lowSCN; nxt_scn := alRec.nextSCN; fname := nvl(alRec.fileName, 'null'); -- no null indicator reset_scn := alRec.rlgSCN; block_size := alRec.blockSize; blocks := alRec.blocks; deb(DEB_EXIT); EXCEPTION WHEN no_data_found THEN recid := NULL; -- indicate end-of-fetch stamp := NULL; deb(DEB_EXIT, 'with no more records'); END getArchivedLog; -- -- -- -- -- PROCEDURE translateControlFileCopyName( fname IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,duplicates IN number ,statusMask IN binary_integer DEFAULT NULL -- for compatability ,onlyone IN number DEFAULT 1) IS BEGIN deb(DEB_ENTER, 'translateControlFileCopyName'); -- getControlFileCopyCursor := 'findControlfileBackup_c'; deb(DEB_OPEN, 'findControlfileBackup_c'); OPEN findControlfileBackup_c(sourcemask => imageCopy_con_t, pattern => fname, currentIncarnation => FALSE#, statusMask => NVL(statusMask, computeAvailableMask(available,unavailable,0,0))); -- IF (duplicates = FALSE# and onlyone is NOT NULL) THEN getControlFileCopySingleRow := TRUE; ELSE getControlFileCopySingleRow := FALSE; END IF; deb(DEB_EXIT); END translateControlFileCopyName; -- -- PROCEDURE translateControlFileCopyTag( cftag IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,duplicates IN number ,statusMask IN binary_integer DEFAULT NULL ,onlyone IN number DEFAULT 1) IS BEGIN deb(DEB_ENTER, 'translateControlFileCopyTag'); -- deb(DEB_OPEN, 'findControlfileBackup_c'); getControlFileCopyCursor := 'findControlfileBackup_c'; OPEN findControlfileBackup_c( sourcemask => imageCopy_con_t, tag => cftag, currentIncarnation => FALSE#, statusMask => NVL(statusMask, computeAvailableMask(available,unavailable,0,0))); -- IF (duplicates = FALSE# and onlyone is NOT NULL) THEN getControlFileCopySingleRow := TRUE; ELSE getControlFileCopySingleRow := FALSE; END IF; deb(DEB_EXIT); END translateControlFileCopyTag; -- -- PROCEDURE translateControlFileCopyKey( key IN number ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,statusMask IN binary_integer DEFAULT NULL) IS -- for compatability BEGIN deb(DEB_ENTER, 'translateControlFileCopyKey'); -- deb(DEB_OPEN, 'findControlFileCopyKey'); -- -- getControlFileCopyCursor := 'findControlFileCopyKey'; OPEN findControlFileCopyKey( copyKey => key, statusMask => NVL(statusMask, computeAvailableMask(available,unavailable,0,0))); deb(DEB_EXIT); END translateControlFileCopyKey; -- PROCEDURE getControlFileCopy( rcvRec IN OUT NOCOPY rcvRec_t) IS getControlFileCopyRowcount number; BEGIN deb(DEB_ENTER, 'getControlFileCopy'); IF (getControlFileCopyCursor = 'findControlFileCopyKey' AND findControlFileCopyKey%ISOPEN) THEN FETCH findControlFileCopyKey INTO rcvRec; <> IF (findControlFileCopyKey%NOTFOUND) THEN -- getControlFileCopyRowcount := findControlFileCopyKey%ROWCOUNT; CLOSE findControlFileCopyKey; IF (getControlFileCopyRowcount = 0) THEN deb(DEB_EXIT, 'with error 20220'); raise_application_error(-20220, 'Controlfile copy does not exist'); ELSE deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; -- signal end-of-fetch END IF; END IF; IF (getControlFileCopySingleRow = TRUE AND findControlFileCopyKey%ROWCOUNT > 1) THEN -- -- CLOSE findControlFileCopyKey; deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; END IF; ELSIF (getControlFileCopyCursor = 'findControlfileBackup_c' AND findControlfileBackup_c%ISOPEN) THEN FETCH findControlfileBackup_c INTO rcvRec; IF (findControlfileBackup_c%NOTFOUND) THEN -- getControlFileCopyRowcount := findControlfileBackup_c%ROWCOUNT; CLOSE findControlfileBackup_c; IF (getControlFileCopyRowcount = 0) THEN deb(DEB_EXIT, 'with error 20220'); raise_application_error(-20220, 'Controlfile copy does not exist'); ELSE deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; -- signal end-of-fetch END IF; END IF; IF (getControlFileCopySingleRow = TRUE AND findControlfileBackup_c%ROWCOUNT > 1) THEN -- -- CLOSE findControlfileBackup_c; deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; END IF; ELSE deb(DEB_EXIT, 'with error 20204'); raise_application_error(-20204, 'Translation not started (' || getControlFileCopyCursor || ')'); END IF; deb(DEB_EXIT); END getControlFileCopy; -- -- PROCEDURE getControlFileCopy( recid OUT number ,stamp OUT number ,reset_scn OUT number ,ckp_scn OUT number ,block_size OUT number) IS rcvRec rcvRec_t; BEGIN deb(DEB_ENTER, 'getControlFileCopy'); getControlFileCopy(rcvRec); recid := rcvRec.recid_con; stamp := rcvRec.stamp_con; reset_scn := rcvRec.rlgSCN_act; ckp_scn := rcvRec.toSCN_act; block_size := rcvRec.blockSize_con; deb(DEB_EXIT); EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with no more records'); -- recid := NULL; -- signal end-of-fetch to caller END getControlFileCopy; -- -- -- -- PROCEDURE getDataFileCopy( rcvRec OUT NOCOPY rcvRec_t ,closeCursor IN boolean DEFAULT FALSE) IS getDataFileCopyRowcount number; local rcvRec_t; BEGIN deb(DEB_ENTER, 'getDataFileCopy'); <> IF (getDatafileCopyCursor = 'findDatafileCopyKey') THEN FETCH findDatafileCopyKey INTO local; IF (findDatafileCopyKey%NOTFOUND) THEN getDataFileCopyRowcount := findDatafileCopyKey%ROWCOUNT; CLOSE findDatafileCopyKey; END IF; IF (closeCursor AND findDatafileCopyKey%ISOPEN) THEN CLOSE findDatafileCopyKey; END IF; ELSIF (getDatafileCopyCursor = 'findDatafileBackup_c') THEN IF (getDataFileCopySingleRow = TRUE AND findDatafileBackup_c%ROWCOUNT > 1) THEN -- -- CLOSE findDatafileBackup_c; getDatafileCopyCursor := NULL; deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; END IF; FETCH findDatafileBackup_c INTO local; IF (findDatafileBackup_c%NOTFOUND) THEN getDataFileCopyRowcount := findDatafileBackup_c%ROWCOUNT; CLOSE findDatafileBackup_c; END IF; IF (closeCursor AND findDatafileBackup_c%ISOPEN) THEN CLOSE findDatafileBackup_c; END IF; ELSE deb(DEB_EXIT, 'with error 20204'); raise_application_error(-20204, 'Translation not started'); END IF; IF (closeCursor) THEN getDatafileCopyCursor := NULL; END IF; IF (getDataFileCopyRowcount IS NOT NULL) THEN getDatafileCopyCursor := NULL; IF (getDataFileCopyRowcount = 0 AND getDatafileCopyNoRows.error IS NOT NULL) THEN deb(DEB_EXIT, 'with norows error'); raise_application_error(getDatafileCopyNoRows.error, getDatafileCopyNoRows.msg); ELSE deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; -- signal end-of-fetch END IF; END IF; IF (getDataFileCopyLatestOnly = TRUE AND getDataFileCopyLast.dfNumber_obj = local.dfNumber_obj) THEN GOTO nextRow; END IF; getDataFileCopyLast := local; -- save for duplicate filtering rcvRec := local; -- set OUT mode arg setDfTransClause(fno => local.dfNumber_obj); deb(DEB_EXIT); END getDataFileCopy; -- PROCEDURE translateDataFileCopyKey( cdf_key IN number ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,statusMask IN binary_integer DEFAULT NULL) -- for compatability IS BEGIN deb(DEB_ENTER, 'translateDataFileCopyKey'); validateState(getDatafileCopyCursor); -- deb(DEB_OPEN, 'findDataFileCopyKey'); OPEN findDataFileCopyKey(copyKey => cdf_key, statusMask => NVL(statusMask, computeAvailableMask(available, unavailable, 0, 0))); getDatafileCopyCursor := 'findDatafileCopyKey'; getDataFileCopyNoRows.error := -20230; getDataFileCopyNoRows.msg := 'Datafile copy does not exist'; getDataFileCopyDuplicates := NULL; getDataFileCopySingleRow := NULL; deb(DEB_EXIT); END translateDatafileCopyKey; -- -- PROCEDURE translateDataFileCopyKey( cdf_key IN number ,available IN number ,unavailable IN number ,recid OUT number ,stamp OUT number ,file# OUT number ,fname OUT varchar2 ,reset_scn OUT number ,create_scn OUT number ,ckp_scn OUT number ,block_size OUT number ,blocks OUT number) IS rcvRec rcvRec_t; BEGIN deb(DEB_ENTER, 'translateDataFileCopyKey815'); translateDataFileCopyKey(cdf_key => cdf_key, available => available, unavailable => unavailable); getDataFileCopy(rcvRec => rcvRec, closeCursor => TRUE); recid := rcvRec.recid_con; stamp := rcvRec.stamp_con; file# := rcvRec.dfNumber_obj; fname := rcvRec.fileName_con; reset_scn := rcvRec.rlgSCN_act; create_scn := rcvRec.dfCreationSCN_obj; ckp_scn := rcvRec.toSCN_act; block_size := rcvRec.blockSize_con; blocks := rcvRec.blocks_con; deb(DEB_EXIT); END translateDataFileCopyKey; -- -- -- -- -- PROCEDURE translateDatafileCopyName( fname IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,duplicates IN number ,statusMask IN binary_integer DEFAULT NULL -- for compatability ,onlyone IN number DEFAULT 1 ,pluginSCN IN number DEFAULT 0) IS BEGIN deb(DEB_ENTER, 'translateDatafileCopyName'); validateState(getDatafileCopyCursor); -- deb(DEB_OPEN, 'findDatafileBackup_c'); OPEN findDatafileBackup_c( sourcemask => imageCopy_con_t, pattern => fname, statusMask => nvl(statusMask, computeAvailableMask(available, unavailable, 0, 0)), duplicates => duplicates, pluginSCN => pluginSCN ); getDatafileCopyCursor := 'findDatafileBackup_c'; getDatafileCopyNoRows.error := -20230; getDatafileCopyNoRows.msg := 'Datafile copy does not exist'; getDatafileCopyDuplicates := duplicates; getDatafileCopyLast.dfNumber_obj := NULL; getDatafileCopyLatestOnly := FALSE; IF (duplicates = FALSE# and onlyone is NOT NULL) THEN getDatafileCopySingleRow := TRUE; ELSE getDatafileCopySingleRow := FALSE; END IF; deb(DEB_EXIT); END translateDatafileCopyName; -- -- -- -- -- -- -- -- -- PROCEDURE translateDataFileCopyTag( tag IN varchar2 ,available IN number DEFAULT NULL -- for compatibility ,unavailable IN number DEFAULT NULL -- for compatibility ,duplicates IN number ,statusMask IN binary_integer DEFAULT NULL -- for compatibility ,pluginSCN IN number DEFAULT 0 ,onlytc IN binary_integer DEFAULT FALSE#) -- for compatibility IS BEGIN deb(DEB_ENTER, 'translateDataFileCopyTag'); validateState(getDatafileCopyCursor); -- -- -- -- deb(DEB_OPEN, 'findDataFileBackup_c'); if (onlytc != FALSE#) THEN deb(DEB_PRINT, 'onytc is TRUE#'); end if; OPEN findDatafileBackup_c( sourcemask => imageCopy_con_t, tag => tag, reset_scn => this_reset_scn, reset_time => this_reset_time, statusMask => nvl(statusMask, computeAvailableMask(available, unavailable, 0, 0)), duplicates => duplicates, pluginSCN => pluginSCN, onlytc => onlytc ); getDatafileCopyCursor := 'findDatafileBackup_c'; getDataFileCopyNoRows.error := -20232; getDataFileCopyNoRows.msg := 'Datafile copy tag does not match'; getDataFileCopyDuplicates := duplicates; getDataFileCopyLast.dfNumber_obj := NULL; getDataFileCopySingleRow := FALSE; getDataFileCopyLatestOnly := FALSE; deb(DEB_EXIT); END translateDataFileCopyTag; -- -- -- -- -- PROCEDURE translateDatafileCopyFno( fno IN number ,available IN number DEFAULT NULL ,unavailable IN number DEFAULT NULL ,duplicates IN number ,statusMask IN binary_integer DEFAULT NULL ,pluginSCN IN number DEFAULT 0) IS BEGIN deb(DEB_ENTER, 'translateDatafileCopyFno'); validateState(getDatafileCopyCursor); deb(DEB_OPEN, 'findDatafileBackup_c'); OPEN findDatafileBackup_c( duplicates => duplicates, sourcemask => imageCopy_con_t, fno => fno, statusMask => NVL(statusMask, computeAvailableMask(available, unavailable, 0, 0)), pluginSCN => pluginSCN ); getDatafileCopyCursor := 'findDatafileBackup_c'; getDatafileCopyNoRows.error := -20230; getDatafileCopyNoRows.msg := 'Datafile copy does not exist'; getDatafileCopyDuplicates := duplicates; getDatafileCopyLatestOnly := FALSE; getDatafileCopyLast.dfNumber_obj := NULL; IF (duplicates = FALSE#) THEN getDatafileCopySingleRow := TRUE; ELSE getDatafileCopySingleRow := FALSE; END IF; setDfTransClause(fno => fno); deb(DEB_EXIT); END translateDatafileCopyFno; -- -- PROCEDURE getDataFileCopy( recid OUT number ,stamp OUT number ,file# OUT number ,fname OUT varchar2 ,reset_scn OUT number ,create_scn OUT number ,ckp_scn OUT number ,block_size OUT number ,blocks OUT number) IS rcvRec rcvRec_t; BEGIN deb(DEB_ENTER, 'getDataFileCopy'); getDataFileCopy(rcvRec); recid := rcvRec.recid_con; stamp := rcvRec.stamp_con; file# := rcvRec.dfNumber_obj; fname := rcvRec.fileName_con; reset_scn := rcvRec.rlgSCN_act; create_scn := rcvRec.dfCreationSCN_obj; ckp_scn := rcvRec.toSCN_act; block_size := rcvRec.blockSize_con; blocks := rcvRec.blocks_con; deb(DEB_EXIT); EXCEPTION WHEN no_data_found THEN recid := NULL; -- signal end-of-fetch to client deb(DEB_EXIT, 'with no more records'); END getDataFileCopy; -- -- -- -- PROCEDURE getProxyCopy( rcvRec OUT NOCOPY rcvRec_t ,closeCursor IN boolean DEFAULT FALSE) IS getProxyCopyRowcount number; dummy rcvRec_t; BEGIN deb(DEB_ENTER, 'getProxyCopy'); IF (getProxyCopyCursor = 'findProxyCopy') THEN FETCH findProxyCopy INTO rcvRec; IF (findProxyCopy%NOTFOUND) THEN getProxyCopyRowcount := findProxyCopy%ROWCOUNT; CLOSE findProxyCopy; ELSE IF (getProxyCopyByHandle) THEN -- FETCH findProxyCopy INTO dummy; IF (NOT findProxyCopy%NOTFOUND) THEN CLOSE findProxyCopy; deb(DEB_EXIT, 'with error 20311'); raise_application_error(-20311, 'Ambiguous proxy copy handle'); END IF; END IF; END IF; IF (closeCursor AND findProxyCopy%ISOPEN) THEN CLOSE findProxyCopy; END IF; ELSIF (getProxyCopyCursor = 'findProxyCopyKey') THEN FETCH findProxyCopyKey INTO rcvRec; IF (findProxyCopyKey%NOTFOUND) THEN getProxyCopyRowcount := findProxyCopyKey%ROWCOUNT; CLOSE findProxyCopyKey; END IF; IF (closeCursor AND findProxyCopyKey%ISOPEN) THEN CLOSE findProxyCopyKey; END IF; ELSE deb(DEB_EXIT, 'with errors 20204'); raise_application_error(-20204, 'Translation not started'); END IF; IF (closeCursor) THEN getProxyCopyCursor := NULL; END IF; IF (getProxyCopyRowcount IS NOT NULL) THEN getProxyCopyCursor := NULL; IF (getProxyCopyRowcount = 0 AND getProxyCopyNoRows.error IS NOT NULL) THEN deb(DEB_EXIT, 'with norows error'); raise_application_error(getProxyCopyNoRows.error, getProxyCopyNoRows.msg); ELSE deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; -- signal end-of-fetch END IF; END IF; deb(DEB_EXIT); END getProxyCopy; -- PROCEDURE translateProxyCopyKey( pc_key IN number ,deviceType IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,deleted IN number DEFAULT NULL -- for compatability ,expired IN number DEFAULT NULL -- for compatability ,statusMask IN binary_integer DEFAULT NULL) -- for compatability IS BEGIN deb(DEB_ENTER, 'translateProxyCopyKey'); validateState(getProxyCopyCursor); deb(DEB_OPEN, 'findProxyCopyKey'); OPEN findProxyCopyKey(key => pc_key, deviceType => deviceType, statusMask => NVL(statusMask, computeAvailableMask(available, unavailable, deleted, expired))); getProxyCopyCursor := 'findProxyCopyKey'; getProxyCopyNoRows.error := -20310; getProxyCopyNoRows.msg := 'proxy copy is missing'; getProxyCopyByHandle := FALSE; deb(DEB_EXIT); END translateProxyCopyKey; -- -- PROCEDURE translateProxyCopyKey( pc_key IN number ,device_type IN varchar2 ,available IN number ,unavailable IN number ,deleted IN number ,recid OUT number ,stamp OUT number ,handle OUT varchar2) IS rcvRec rcvRec_t; BEGIN deb(DEB_ENTER, 'translateProxyCopyKey815'); translateProxyCopyKey(pc_key => pc_key, deviceType => device_type, available => available, unavailable => unavailable, deleted => deleted, expired => unavailable); getProxyCopy(rcvRec => rcvRec, closeCursor => TRUE); recid := rcvRec.recid_con; stamp := rcvRec.stamp_con; handle := rcvRec.fileName_con; deb(DEB_EXIT); END translateProxyCopyKey; -- PROCEDURE translateProxyCopyHandle( handle IN varchar2 ,deviceType IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,deleted IN number DEFAULT NULL -- for compatability ,expired IN number DEFAULT NULL -- for compatability ,statusMask IN binary_integer DEFAULT NULL) -- for compatability IS BEGIN deb(DEB_ENTER, 'translateProxyCopyHandle'); validateState(getProxyCopyCursor); deb(DEB_OPEN, 'findProxyCopy'); OPEN findProxyCopy(handle => handle, deviceType => deviceType, statusMask => NVL(statusMask, computeAvailableMask(available, unavailable, deleted, expired))); getProxyCopyCursor := 'findProxyCopy'; getProxyCopyNoRows.error := -20310; getProxyCopyNoRows.msg := 'proxy copy is missing'; getProxyCopyByHandle := TRUE; deb(DEB_EXIT); END translateProxyCopyHandle; -- -- PROCEDURE translateProxyCopyHandle( handle IN varchar2 ,device_type IN varchar2 ,available IN number ,unavailable IN number ,deleted IN number ,recid OUT number ,stamp OUT number) IS rcvRec rcvRec_t; BEGIN deb(DEB_ENTER, 'translateProxyCopyHandle815'); translateProxyCopyHandle(handle => handle, deviceType => device_type, available => available, unavailable => unavailable, deleted => deleted, expired => unavailable); getProxyCopy(rcvRec => rcvRec, closeCursor => TRUE); recid := rcvRec.recid_con; stamp := rcvRec.stamp_con; deb(DEB_EXIT); END translateProxyCopyHandle; -- -- PROCEDURE translateProxyCopyTag( tag IN varchar2 ,device_type IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,deleted IN number DEFAULT NULL -- for compatability ,statusMask IN binary_integer DEFAULT NULL) -- for compatability IS BEGIN deb(DEB_ENTER, 'translateProxyCopyTag'); validateState(getProxyCopyCursor); deb(DEB_OPEN, 'findProxyCopy'); OPEN findProxyCopy(tag => tag, deviceType => device_type, statusMask => NVL(statusMask, computeAvailableMask(available, unavailable, deleted, unavailable/*expired*/))); getProxyCopyCursor := 'findProxyCopy'; getProxyCopyNoRows.error := -20310; getProxyCopyNoRows.msg := 'no matching proxy copy found'; getProxyCopyByHandle := FALSE; deb(DEB_EXIT); END translateProxyCopyTag; -- PROCEDURE translateProxyCopyGuid( guid IN varchar2 ,device_type IN varchar2 ,statusMask IN binary_integer) IS pdbKey number := NULL; BEGIN deb(DEB_ENTER, 'translateProxyCopyGuid'); validateState(getProxyCopyCursor); deb(DEB_OPEN, 'findProxyCopy'); -- pdbKey := guidToPdbKey(guid); -- OPEN findProxyCopy(pdbKey => pdbKey, guid => guid, deviceType => device_type, statusMask => NVL(statusMask, 0)); getProxyCopyCursor := 'findProxyCopy'; getProxyCopyNoRows.error := -20310; getProxyCopyNoRows.msg := 'no matching proxy copy found'; getProxyCopyByHandle := FALSE; deb(DEB_EXIT); END translateProxyCopyGuid; -- -- PROCEDURE getProxyCopy( recid OUT number ,stamp OUT number ,handle OUT varchar2) IS rcvRec rcvRec_t; BEGIN deb(DEB_ENTER, 'getProxyCopyHandle'); getProxyCopy(rcvRec); recid := rcvRec.recid_con; stamp := rcvRec.stamp_con; handle := rcvRec.fileName_con; deb(DEB_EXIT); EXCEPTION WHEN no_data_found THEN recid := NULL; -- indicate end-of-fetch deb(DEB_EXIT, 'with no more records'); END getProxyCopy; -- -- -- -- PROCEDURE getBackupPiece( bpRec OUT NOCOPY bpRec_t ,closeCursor IN boolean DEFAULT FALSE) IS dummy bpRec_t; local bpRec_t; eof boolean := FALSE; eob boolean := FALSE; raiseError boolean := FALSE; BEGIN deb(DEB_ENTER, 'getBackupPiece'); IF (getBackupPieceDuplicates = FALSE# AND getBackupPieceDeviceType IS NULL) THEN -- -- -- deb(DEB_EXIT, 'with error 20999'); raise_application_error(-20999, 'deviceType must be specified'); END IF; <> IF (getBackupPieceCursor = 'findBackupPieceBpKey') THEN FETCH findBackupPieceBpKey INTO local; IF (findBackupPieceBpKey%NOTFOUND) THEN eof := TRUE; CLOSE findBackupPieceBpKey; END IF; IF (closeCursor AND findBackupPieceBpKey%ISOPEN) THEN CLOSE findBackupPieceBpKey; END IF; ELSIF (getBackupPieceCursor = 'findBackupPieceBsKey1') THEN FETCH findBackupPieceBsKey1 INTO local; IF (findBackupPieceBsKey1%NOTFOUND) THEN eof := TRUE; CLOSE findBackupPieceBsKey1; END IF; IF (closeCursor AND findBackupPieceBsKey1%ISOPEN) THEN CLOSE findBackupPieceBsKey1; END IF; ELSIF (getBackupPieceCursor = 'findBackupPieceBsKey2') THEN -- local := getBackupPieceSeekLast; deb(DEB_PRINT, 'bskey = ' || local.bskey); -- IF (local.bskey != getBackupPieceBsKey OR local.deviceType != getBackupPieceDeviceType OR (getBackupPieceCopyNumber IS NOT NULL AND local.copyNumber != getBackupPieceCopyNumber)) THEN eob := TRUE; deb(DEB_PRINT, 'end of backupset'); ELSE <> LOOP -- FETCH findBackupPieceBsKey2 INTO dummy; IF (findBackupPieceBsKey2%NOTFOUND) THEN CLOSE findBackupPieceBsKey2; dummy.bskey := 0; END IF; IF (dummy.bskey != getBackupPieceBsKey OR dummy.deviceType != getBackupPieceDeviceType OR getBackupPieceCopyNumber IS NULL OR dummy.copyNumber = getBackupPieceCopyNumber) THEN getBackupPieceSeekLast := dummy; EXIT checkAgain; END IF; END LOOP; deb(DEB_PRINT, 'next bskey=' || getBackupPieceSeekLast.bskey); END IF; ELSIF (getBackupPieceCursor = 'findBackupPiece_c') THEN FETCH findBackupPiece_c INTO local; IF (findBackupPiece_c%NOTFOUND) THEN eof := TRUE; CLOSE findBackupPiece_c; ELSE IF (getBackupPieceByHandle) THEN -- FETCH findBackupPiece_c INTO dummy; IF (NOT findBackupPiece_c%NOTFOUND) THEN raiseError := TRUE; -- -- -- -- -- -- -- -- IF (raiseError) THEN CLOSE findBackupPiece_c; deb(DEB_EXIT, 'with error 20261'); raise_application_error(-20261, 'Ambiguous backup piece handle'); END IF; END IF; END IF; END IF; IF (closeCursor AND findBackupPiece_c%ISOPEN) THEN CLOSE findBackupPiece_c; END IF; ELSE deb(DEB_EXIT, 'with error 20204'); raise_application_error(-20204, 'Translation not started'); END IF; IF (closeCursor OR eof) THEN getBackupPieceCursor := NULL; END IF; IF (eof OR eob) THEN -- if end of fetch or end of backupset -- -- IF (getBackupPieceDuplicates = FALSE#) THEN -- -- -- IF (getBackupPieceExpectedPieces IS NOT NULL AND (getBackupPieceAvailableMask IS NULL OR bitand(getBackupPieceAvailableMask, dbms_rcvman.BSpartial_avail) = 0) AND getBackupPieceExpectedPieces <> getBackupPiecePieceCount) THEN deb(DEB_EXIT, 'with error 20216'); raise_application_error(-20216, 'Backup piece is missing'); END IF; END IF; IF (getBackupPiecePieceCount = 0 AND getBackupPieceNoRows.error IS NOT NULL) THEN deb(DEB_EXIT, 'with norows error'); raise_application_error(getBackupPieceNoRows.error, getBackupPieceNoRows.msg); ELSE deb(DEB_EXIT, 'no more records'); RAISE no_data_found; END IF; END IF; IF (getBackupPieceDuplicates = FALSE#) THEN -- -- IF (local.pieceNumber = getBackupPieceLast.pieceNumber) THEN -- GOTO nextRow; END IF; END IF; getBackupPieceLast := local; bpRec := local; -- set OUT mode arg getBackupPiecePieceCount := getBackupPiecePieceCount + 1; deb(DEB_EXIT); END getBackupPiece; -- PROCEDURE translateBackupPieceKey( key IN number ,available IN number DEFAULT TRUE# ,unavailable IN number DEFAULT TRUE# ,expired IN number DEFAULT TRUE# ,statusMask IN binary_integer DEFAULT NULL) -- for compatability IS BEGIN -- -- -- -- -- deb(DEB_ENTER, 'translateBackupPieceKey'); findBackupPiece(bpKey => key, statusMask => NVL(statusMask, computeAvailableMask(available, unavailable, 0, unavailable))); getBackupPieceNoRows.error := -20260; getBackupPieceNoRows.msg := 'Backup piece is missing'; getBackupPieceAvailableMask := statusMask; deb(DEB_EXIT); END translateBackupPieceKey; -- PROCEDURE translateBackupPieceKey( bp_key IN number ,available IN number ,unavailable IN number ,recid OUT number ,stamp OUT number ,handle OUT varchar2 ,set_stamp OUT number ,set_count OUT number ,piece# OUT number) IS bpRec bpRec_t; BEGIN deb(DEB_ENTER, 'translateBackupPieceKey'); -- -- -- -- -- -- -- translateBackupPieceKey(key => bp_key, statusMask => computeAvailableMask(available, unavailable, 0, unavailable/*expired*/)); getBackupPiece(bpRec => bpRec, closeCursor => TRUE); recid := bpRec.recid; stamp := bpRec.stamp; handle := bpRec.handle; set_stamp := bpRec.setStamp; set_count := bpRec.setCount; piece# := bpRec.pieceNumber; deb(DEB_EXIT); END translateBackupPieceKey; -- PROCEDURE translateBackupPieceHandle( handle IN varchar2 ,deviceType IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,expired IN number DEFAULT NULL -- for compatability ,statusMask IN binary_integer DEFAULT NULL) -- for compatability IS BEGIN deb(DEB_ENTER, 'translateBackupPieceHandle'); findBackupPiece(handle => handle, deviceType => deviceType, statusMask => NVL(statusMask, computeAvailableMask(available, unavailable, 0, expired))); getBackupPieceNoRows.error := -20260; getBackupPieceNoRows.msg := 'Backup piece is missing'; getBackupPieceByHandle := TRUE; getBackupPieceAvailableMask := statusMask; deb(DEB_EXIT); END translateBackupPieceHandle; -- PROCEDURE translateBackupPieceHandle( -- only used in 8.1.6 handle IN varchar2 ,device_type IN varchar2 ,available IN number ,unavailable IN number ,recid OUT number ,stamp OUT number ,set_stamp OUT number ,set_count OUT number ,piece# OUT number) IS bpRec bpRec_t; BEGIN deb(DEB_ENTER, 'translateBackupPieceHandle816'); translateBackupPieceHandle(handle => handle, deviceType => device_type, statusMask => computeAvailableMask(available, unavailable, 0, unavailable/*expired*/)); getBackupPiece(bpRec => bpRec, closeCursor => TRUE); recid := bpRec.recid; stamp := bpRec.stamp; set_stamp := bpRec.setStamp; set_count := bpRec.setCount; piece# := bpRec.pieceNumber; deb(DEB_EXIT); END translateBackupPieceHandle; -- -- PROCEDURE translateBackupPieceTag( tag IN varchar2 ,available IN number DEFAULT NULL -- for compatability ,unavailable IN number DEFAULT NULL -- for compatability ,statusMask IN binary_integer DEFAULT NULL) IS BEGIN deb(DEB_ENTER, 'translateBackupPieceTag'); findBackupPiece(tag => tag, statusMask => NVL(statusMask, computeAvailableMask(available, unavailable, 0, /* expired = */unavailable))); deb(DEB_EXIT); END translateBackupPieceTag; -- -- PROCEDURE translateBackupPieceGuid( guid IN varchar2 ,statusMask IN binary_integer) IS pdbKey number := NULL; BEGIN deb(DEB_ENTER, 'translateBackupPieceGuid'); -- pdbKey := guidToPdbKey(guid); -- findBackupPiece(pdbKey => pdbKey, guid => guid, statusMask => NVL(statusMask, 0)); deb(DEB_EXIT); END translateBackupPieceGuid; -- PROCEDURE translateBackupPieceBSKey( key IN number ,tag IN varchar2 DEFAULT NULL ,deviceType IN varchar2 DEFAULT NULL ,pieceCount IN number ,duplicates IN number DEFAULT TRUE# ,copyNumber IN number DEFAULT NULL ,available IN number DEFAULT TRUE# ,unavailable IN number DEFAULT FALSE# ,deleted IN number DEFAULT FALSE# ,expired IN number DEFAULT FALSE# ,statusMask IN binary_integer DEFAULT NULL) IS BEGIN deb(DEB_ENTER, 'translateBackupPieceBSKey'); findBackupPiece(bsKey => key, tag => tag, deviceType => deviceType, copyNumber => copyNumber, statusMask => NVL(statusMask, computeAvailableMask(available, unavailable, deleted, expired))); getBackupPieceDuplicates := duplicates; getBackupPieceExpectedPieces := pieceCount; getBackupPieceAvailableMask := statusMask; deb(DEB_EXIT); END translateBackupPieceBSKey; -- PROCEDURE translateBackupPieceBsKey( startBsKey IN number ,tag IN varchar2 DEFAULT NULL ,statusMask IN binary_integer DEFAULT NULL) IS BEGIN findBackupPiece(startBsKey => startBskey, tag => tag, statusMask => NVL(statusMask, computeAvailableMask(TRUE# /* available */, FALSE# /* unavailable */, FALSE# /* deleted */, FALSE# /* expired */))); getBackupPieceAvailableMask := statusMask; END translateBackupPieceBsKey; -- PROCEDURE translateSeekBpBsKey( bsKey IN number ,deviceType IN varchar2 ,pieceCount IN number ,duplicates IN number DEFAULT TRUE# ,copyNumber IN number DEFAULT NULL) IS BEGIN deb(DEB_ENTER, 'translateSeekBpBsKey'); deb(DEB_IN, 'bskey=' || bsKey); IF (getBackupPieceCursor IS NULL OR getBackupPieceCursor != 'findBackupPieceBsKey2') THEN raise_application_error(-20204, 'Translation not started'); ELSIF (deviceType IS NULL) THEN raise_application_error(-20999, 'deviceType must be specified'); END IF; -- -- getBackupPieceNoRows.error := NULL; getBackupPieceDuplicates := duplicates; getBackupPieceLast.pieceNumber := NULL; getBackupPieceDeviceType := deviceType; getBackupPieceExpectedPieces := pieceCount; getBackupPiecePieceCount := 0; getBackupPieceByHandle := FALSE; getBackupPieceCopyNumber := copyNumber; getBackupPieceBskey := bsKey; <> LOOP IF (NOT findBackupPieceBsKey2%ISOPEN) THEN -- all done deb(DEB_EXIT, 'cursor not open'); RAISE no_data_found; END IF; IF (getBackupPieceSeekLast.bskey > bsKey) THEN -- gone over the key deb(DEB_EXIT, 'gone over key seek=' || getBackupPieceSeekLast.bskey || ' key=' || bsKey); RAISE no_data_found; END IF; -- IF (getBackupPieceSeekLast.bskey = bsKey AND getBackupPieceSeekLast.deviceType = deviceType AND (copyNumber IS NULL OR getBackupPieceSeekLast.copyNumber = copyNumber)) THEN EXIT checkAgain; END IF; FETCH findBackupPieceBsKey2 INTO getBackupPieceSeekLast; IF (findBackupPieceBsKey2%NOTFOUND) THEN -- all done CLOSE findBackupPieceBsKey2; deb(DEB_EXIT, 'no more data'); RAISE no_data_found; END IF; END LOOP; deb(DEB_EXIT, 'got key=' || bsKey); END translateSeekBpBsKey; -- PROCEDURE translateBpBsKeyCancel IS BEGIN IF (findBackupPieceBsKey1%ISOPEN) THEN CLOSE findBackupPieceBsKey1; END IF; IF (findBackupPieceBsKey2%ISOPEN) THEN CLOSE findBackupPieceBsKey2; END IF; getBackupPieceCursor := NULL; END translateBpBsKeyCancel; -- -- PROCEDURE translateBackupSetKey( bs_key IN number ,device_type IN varchar2 ,available IN number ,unavailable IN number ,deleted IN number ,duplicates IN number ,backup_type OUT varchar2 ,recid OUT number ,stamp OUT number ,set_stamp OUT number ,set_count OUT number ,bslevel OUT number ,completion_time OUT date) IS bsRec bsRec_t; BEGIN deb(DEB_ENTER, 'translateBackupSetKey815'); findBackupSet(bsKey => bs_key, -- Lookup backset by key bsRec => bsRec); backup_type := bsRec.bsType; recid := bsRec.recid; stamp := bsRec.stamp; set_stamp := bsRec.setStamp; set_count := bsRec.setCount; bslevel := bsRec.level; completion_time := bsRec.compTime; -- -- -- -- -- -- -- translateBackupPieceBSKey(key => bs_key, deviceType => device_type, pieceCount => bsRec.pieceCount, available => available, unavailable => unavailable, deleted => deleted, expired => unavailable); getBackupPieceDuplicates := duplicates; IF (device_type IS NULL) THEN -- -- -- -- -- -- -- -- -- getBackupPieceDuplicates := TRUE#; -- yes, we want duplicates END IF; IF (getBackupPieceDuplicates = FALSE#) THEN -- -- -- getBackupPieceExpectedPieces := bsRec.pieceCount; END IF; deb(DEB_EXIT); END translateBackupSetKey; -- -- PROCEDURE translateBackupSetKey( bs_key IN number ,device_type IN varchar2 ,available IN number ,unavailable IN number ,deleted IN number ,duplicates IN number ,backup_type OUT varchar2 ,recid OUT number ,stamp OUT number) IS set_stamp number; set_count number; bslevel number; completion_time date; BEGIN deb(DEB_ENTER, 'translateBackupSetKey80'); translateBackupSetKey(bs_key, device_type, available, unavailable, deleted, duplicates, backup_type, recid, stamp, set_stamp, set_count, bslevel, completion_time); deb(DEB_EXIT); END translateBackupSetKey; -- -- PROCEDURE translateBackupSetRecid( recid IN number ,stamp IN number ,device_type IN varchar2 ,bs_key OUT number ,bslevel OUT number ,completed OUT date) IS bsRec bsRec_t; pieceCount number; validationRec validBackupSetRec_t; gotRecord number; duplicates_flag number; BEGIN deb(DEB_ENTER, 'translateBackupSetRecid815'); findBackupSet(recid => recid, stamp => stamp, bsRec => bsRec); bs_key := bsRec.key; bslevel := bsRec.level; completed := bsRec.compTime; -- -- -- -- findValidBackupSet(backupSetRec => bsRec, tag => restoreTag, deviceType => device_type, available => TRUE#); gotRecord := getValidBackupSet(validBackupSetRec => validationRec); IF (getValidBackupSetCursor = 'findValidBackupSet_c') THEN CLOSE findValidBackupSet_c; ELSIF (getValidBackupSetCursor = 'findValidBackupSet1P_c') THEN CLOSE findValidBackupSet1P_c; END IF; IF (gotRecord = FALSE#) THEN -- -- -- -- validationRec.copyNumber := NULL; END IF; IF (device_type IS NULL) THEN -- duplicates_flag := TRUE#; ELSE -- duplicates_flag := FALSE#; END IF; translateBackupPieceBSKey(key => bsRec.key, tag => validationRec.tag, deviceType => device_type, pieceCount => bsRec.pieceCount, duplicates => duplicates_flag, copyNumber => validationRec.copyNumber, available => TRUE#); deb(DEB_EXIT); END translateBackupSetRecid; -- -- PROCEDURE translateBackupSetRecid( recid IN number ,stamp IN number ,device_type IN varchar2) IS bs_key number; bslevel number; completed date; BEGIN deb(DEB_ENTER, 'translateBackupSetRecid80'); translateBackupSetRecid(recid, stamp, device_type, bs_key, bslevel, completed); deb(DEB_EXIT); END translateBackupSetRecid; -- -- PROCEDURE getBackupPiece( recid OUT number ,stamp OUT number ,bpkey OUT number ,set_stamp OUT number ,set_count OUT number ,piece# OUT number ,copy# OUT number ,status OUT varchar2 ,completion OUT date ,handle OUT varchar2) IS bpRec bpRec_t; BEGIN deb(DEB_ENTER, 'getBackupPiece815'); getBackupPiece(bpRec); recid := bpRec.recid; stamp := bpRec.stamp; bpkey := bpRec.key; set_stamp := bpRec.setStamp; set_count := bpRec.setCount; piece# := bpRec.pieceNumber; copy# := bpRec.copyNumber; status := bpRec.status; completion := bpRec.compTime; handle := bpRec.handle; deb(DEB_EXIT); EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with no more records'); bpRec.recid := NULL; -- indicate end-of-fetch to client END getBackupPiece; -- -- PROCEDURE getBackupPiece( recid OUT number ,stamp OUT number ,set_stamp OUT number ,set_count OUT number ,piece# OUT number ,handle OUT varchar2) IS bpRec bpRec_t; BEGIN deb(DEB_ENTER, 'getBackupPiece80'); getBackupPiece(bpRec); recid := bpRec.recid; stamp := bpRec.stamp; set_stamp := bpRec.setStamp; set_count := bpRec.setCount; piece# := bpRec.pieceNumber; handle := bpRec.handle; deb(DEB_EXIT); EXCEPTION WHEN no_data_found THEN bpRec.recid := NULL; -- indicate end-of-fetch to client deb(DEB_EXIT, 'with no more records'); END getBackupPiece; -- -- -- -- PROCEDURE translateBackupSetKey( key IN number ,bsRec OUT NOCOPY bsRec_t) IS BEGIN deb(DEB_ENTER, 'translateBackupSetKey'); findBackupSet(bsKey => key, bsRec => bsRec); deb(DEB_EXIT); END translateBackupSetKey; -- -- -- -- -- FUNCTION findControlFileBackup( type OUT number ,recid OUT number ,stamp OUT number ,fname OUT varchar2 ,device_type OUT varchar2 ,ckp_scn OUT number) RETURN number IS rcvRec rcvRec_t; rc number; BEGIN deb(DEB_ENTER, 'findControlFileBackup804'); rc := getControlfileBackup(rcvRec); IF (rc = SUCCESS) THEN IF (rcvRec.type_con = imageCopy_con_t) THEN type := COPY; ELSIF (rcvRec.type_con = backupSet_con_t) THEN type := BACKUP; ELSIF (rcvRec.type_con = proxyCopy_con_t) THEN type := PROXY; ELSE -- deb(DEB_EXIT, 'with: UNAVAILABLE'); RETURN dbms_rcvman.UNAVAILABLE; END IF; IF (type = BACKUP) THEN recid := rcvRec.bsRecid_con; stamp := rcvRec.bsStamp_con; ELSE recid := rcvRec.recid_con; stamp := rcvRec.stamp_con; END IF; fname := rcvRec.fileName_con; device_type := rcvRec.deviceType_con; ckp_scn := rcvRec.toSCN_act; deb(DEB_EXIT, 'with: SUCCESS'); RETURN SUCCESS; ELSE deb(DEB_EXIT, 'with: '||to_char(rc)); RETURN rc; END IF; deb(DEB_EXIT); END findControlFileBackup; -- -- FUNCTION findControlFileBackup( type OUT number ,recid OUT number ,stamp OUT number ,fname OUT varchar2 ,device_type OUT varchar2 ,ckp_scn OUT number ,rlg_scn OUT number ,blksize OUT number) RETURN number IS rcvRec rcvRec_t; rc number; BEGIN deb(DEB_ENTER, 'findControlFileBackup815'); rc := getControlfileBackup(rcvRec); IF (rc = SUCCESS) THEN IF (rcvRec.type_con = imageCopy_con_t) THEN type := COPY; ELSIF (rcvRec.type_con = backupSet_con_t) THEN type := BACKUP; ELSIF (rcvRec.type_con = proxyCopy_con_t) THEN type := PROXY; rcvRec_last := rcvRec; -- save for translateProxyDFRecid ELSE -- deb(DEB_EXIT, 'with: UNAVAILABLE'); RETURN dbms_rcvman.UNAVAILABLE; END IF; IF (type = BACKUP) THEN recid := rcvRec.bsRecid_con; stamp := rcvRec.bsStamp_con; ELSE recid := rcvRec.recid_con; stamp := rcvRec.stamp_con; END IF; fname := rcvRec.fileName_con; device_type := rcvRec.deviceType_con; ckp_scn := rcvRec.toSCN_act; rlg_scn := rcvRec.rlgSCN_act; blksize := rcvRec.blockSize_con; deb(DEB_EXIT, 'with: SUCCESS'); RETURN SUCCESS; ELSE deb(DEB_EXIT, 'with: '||to_char(rc)); RETURN rc; END IF; END findControlFileBackup; -- -- -- -- -- FUNCTION findArchivedLogBackup( thread# IN number ,sequence# IN number ,low_scn IN number ,type OUT number ,recid OUT number ,stamp OUT number ,device_type OUT varchar2) RETURN number IS rcvRec rcvRec_t; RC binary_integer; BEGIN deb(DEB_ENTER, 'findArchivedLogBackup'); -- -- -- findArchivedLogBackup(thread#, sequence#, low_scn); RC := getArchivedLogbackup(rcvRec); IF (RC = SUCCESS) THEN type := BACKUP; recid := rcvRec.bsRecid_con; stamp := rcvRec.bsStamp_con; device_type := rcvRec.deviceType_con; END IF; deb(DEB_EXIT, 'with: '||to_char(RC)); RETURN RC; END findArchivedLogBackup; -- -- -- -- PROCEDURE listTranslateControlfileCopy( tag IN varchar2 ,completedAfter IN date ,completedBefore IN date ,statusMask IN binary_integer DEFAULT BSavailable+BSunavailable+BSexpired ,liststby IN binary_integer DEFAULT NULL -- default for 8.1 ,file_pattern IN varchar2 DEFAULT NULL) IS currentIncarnation number; BEGIN deb(DEB_ENTER, 'listTranslateControlfileCopy'); IF (findControlfileBackup_c%ISOPEN) THEN -- should not be open CLOSE findControlfileBackup_c; END IF; IF (allIncarnations = TRUE#) THEN currentIncarnation := FALSE#; -- don't care about dbinc_key ELSE currentIncarnation := TRUE#; END IF; -- deb(DEB_OPEN, 'findControlfileBackup_c'); OPEN findControlfileBackup_c( sourcemask => imageCopy_con_t, currentIncarnation => currentIncarnation, tag => tag, completedAfter => completedAfter, completedBefore => completedBefore, statusMask => statusMask, pattern => file_pattern, needstby => liststby); deb(DEB_EXIT); END listTranslateControlfileCopy; -- PROCEDURE listGetControlfileCopy( rcvRec OUT NOCOPY rcvRec_t) IS BEGIN deb(DEB_ENTER, 'listGetControlfileCopy'); FETCH findControlfileBackup_c INTO rcvRec; IF (findControlfileBackup_c%NOTFOUND) THEN CLOSE findControlfileBackup_c; deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; END IF; -- -- -- deb(DEB_EXIT); END listGetControlfileCopy; -- -- FUNCTION listGetControlfileCopy( bcfkey OUT number, ckpscn OUT number, ckptime OUT date, status OUT varchar2, completion OUT date, fname OUT varchar2) RETURN number IS rcvRec rcvRec_t; BEGIN deb(DEB_ENTER, 'listGetControlfileCopy'); listGetControlfileCopy(rcvRec); bcfkey := rcvRec.key_con; ckpscn := rcvRec.toSCN_act; ckptime := rcvRec.toTime_act; status := rcvRec.status_con; completion := rcvRec.compTime_con; fname := rcvRec.fileName_con; deb(DEB_EXIT, 'with: TRUE#'); RETURN TRUE#; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with: FALSE#'); RETURN FALSE#; END listGetControlfileCopy; -- PROCEDURE listTranslateDataFileCopy( file# IN number ,creation_change# IN number ,tag IN varchar2 DEFAULT NULL ,file_name_pattern IN varchar2 DEFAULT NULL ,completedAfter IN date DEFAULT NULL ,completedBefore IN date DEFAULT NULL ,statusMask IN binary_integer DEFAULT BSavailable+BSunavailable -- ,pluginSCN IN number DEFAULT 0) IS creationSCN number; reset_scn number := NULL; reset_time date := NULL; BEGIN deb(DEB_ENTER, 'listTranslateDataFileCopy'); IF (allIncarnations = TRUE#) THEN reset_scn := NULL; reset_time := NULL; IF (ignoreCreationSCN = TRUE#) THEN -- -- -- -- creationSCN := NULL; ELSE creationSCN := creation_change#; END IF; ELSE reset_scn := this_reset_scn; reset_time := this_reset_time; creationSCN := creation_change#; END IF; -- deb(DEB_OPEN, 'findDatafileBackup_c'); OPEN findDatafileBackup_c(sourcemask => imageCopy_con_t, fno => file#, crescn => creationSCN, reset_scn => reset_scn, reset_time => reset_time, tag => tag, pattern => file_name_pattern, completedAfter => completedAfter, completedBefore => completedBefore, statusMask => statusMask, pluginSCN => pluginSCN); deb(DEB_EXIT); END listTranslateDataFileCopy; -- PROCEDURE listGetDataFileCopy( rcvRec OUT NOCOPY rcvRec_t) IS BEGIN deb(DEB_ENTER, 'listGetDataFileCopy'); FETCH findDatafileBackup_c INTO rcvRec; IF (findDatafileBackup_c%NOTFOUND) THEN CLOSE findDatafileBackup_c; deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; END IF; -- -- -- deb(DEB_EXIT); END listGetDatafileCopy; -- -- FUNCTION listGetDataFileCopy( cdf_key OUT number ,status OUT varchar2 ,fname OUT varchar2 ,completion_time OUT date ,checkpoint_change# OUT number ,checkpoint_time OUT date) RETURN number IS rcvRec rcvRec_t; BEGIN deb(DEB_ENTER, 'listGetDataFileCopy815'); listGetDatafileCopy(rcvRec); cdf_key := rcvRec.key_con; status := rcvRec.status_con; fname := rcvRec.fileName_con; completion_time := rcvRec.compTime_con; checkpoint_change# := rcvRec.toSCN_act; checkpoint_time := rcvRec.toTime_act; deb(DEB_EXIT, 'with: TRUE#'); RETURN TRUE#; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with: FALSE#'); RETURN FALSE#; END listGetDataFileCopy; -- PROCEDURE listTranslateArchivedLogCopy( thread# IN number ,sequence# IN number ,first_change# IN number ,file_name_pattern IN varchar2 DEFAULT NULL ,completedAfter IN date DEFAULT NULL ,completedBefore IN date DEFAULT NULL ,statusMask IN binary_integer DEFAULT BSavailable+BSunavailable+BSexpired -- 8.0/8.1 defaults ,needstby IN number DEFAULT NULL) IS currentIncarnation number; BEGIN deb(DEB_ENTER, 'listTranslateArchivedLogCopy'); IF (allIncarnations = TRUE#) THEN currentIncarnation := FALSE#; -- don't care about dbinc_key ELSE currentIncarnation := TRUE#; END IF; deb(DEB_OPEN, 'findArchivedLogCopy'); OPEN findArchivedLogCopy(currentIncarnation => currentIncarnation, thread => thread#, sequence => sequence#, lowSCN => first_change#, pattern => file_name_pattern, completedAfter => completedAfter, completedBefore => completedBefore, statusMask => statusMask, -- needstby => NULL); getrcvRecLast := NULL; deb(DEB_EXIT); END listTranslateArchivedLogCopy; -- PROCEDURE listGetArchivedLogCopy( rcvRec OUT NOCOPY rcvRec_t) IS duplicate number; -- used for filtering duplicate names BEGIN deb(DEB_ENTER, 'listGetArchivedLogCopy'); -- -- -- IF (restoreTag is not NULL OR not diskDevice) THEN CLOSE findArchivedLogCopy; deb(DEB_EXIT, 'tag specified or no diskDevice allocated'); RAISE no_data_found; END IF; -- IF (guidQualifier IS NOT NULL) THEN IF (findArchivedLogCopy%ISOPEN) THEN CLOSE findArchivedLogCopy; END IF; deb(DEB_EXIT, 'guid not valid for archivelog'); RAISE no_data_found; END IF; <> FETCH findArchivedLogCopy INTO rcvRec; IF (findArchivedLogCopy%NOTFOUND) THEN CLOSE findArchivedLogCopy; deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; END IF; -- -- -- IF (rcvRec.logThread_obj = getrcvRecLast.logThread_obj AND rcvRec.logSequence_obj = getrcvRecLast.logSequence_obj AND rcvRec.loglowSCN_obj = getrcvRecLast.loglowSCN_obj AND rcvRec.logrlgSCN_obj = getrcvRecLast.logrlgSCN_obj AND rcvRec.logrlgTime_obj = getrcvRecLast.logrlgTime_obj ) THEN duplicate := TRUE#; ELSE duplicate := FALSE#; END IF; IF IsDuplicateAlName(duplicate, rcvRec.filename_con) THEN GOTO nextRow; END IF; getrcvRecLast := rcvRec; -- deb(DEB_EXIT); END listGetArchivedLogCopy; -- -- FUNCTION listGetArchivedLogCopy( al_key OUT number ,status OUT varchar2 ,fname OUT varchar2 ,completion_time OUT date) RETURN number IS rcvRec rcvRec_t; BEGIN deb(DEB_ENTER, 'listGetArchivedLogCopy'); listGetArchivedLogCopy(rcvRec); al_key := rcvRec.key_con; status := rcvRec.status_con; fname := rcvRec.fileName_con; completion_time := rcvRec.compTime_con; deb(DEB_EXIT, 'with: TRUE#'); RETURN TRUE#; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with: FALSE#'); RETURN FALSE#; END listGetArchivedLogCopy; -- -- -- -- PROCEDURE listTranslateControlfileBackup( tag IN varchar2 ,completedAfter IN date ,completedBefore IN date ,statusMask IN binary_integer DEFAULT BSavailable+BSunavailable+BSexpired -- 8.0/8.1 defaults ,autobackup IN binary_integer DEFAULT BScfile_all ,liststby IN binary_integer DEFAULT NULL) IS currentIncarnation number; BEGIN deb(DEB_ENTER, 'listTranslateControlfileBackup'); IF (findControlfileBackup_c%ISOPEN) THEN -- should not be open CLOSE findControlfileBackup_c; END IF; IF (allIncarnations = TRUE#) THEN currentIncarnation := FALSE#; -- don't care about dbinc_key ELSE currentIncarnation := TRUE#; END IF; -- -- deb(DEB_OPEN, 'findControlfileBackup_c'); OPEN findControlfileBackup_c(sourcemask => backupSet_con_t, currentIncarnation => currentIncarnation, completedAfter => completedAfter, completedBefore => completedBefore, typemask => autobackup, needstby => liststby); -- -- -- -- -- listGetBackupTag := tag; listGetBackupAvailableMask := statusMask; deb(DEB_EXIT); END listTranslateControlfileBackup; -- PROCEDURE listGetControlfileBackup( rcvRec OUT NOCOPY rcvRec_t) IS BEGIN deb(DEB_ENTER, 'listGetControlfileBackup'); FETCH findControlfileBackup_c INTO rcvRec; -- -- IF (findControlfileBackup_c%NOTFOUND) THEN CLOSE findControlfileBackup_c; deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; END IF; deb(DEB_EXIT); END listGetControlfileBackup; -- -- FUNCTION listGetControlfileBackup( bskey OUT number, ckpscn OUT number, ckptime OUT date) RETURN number IS rcvRec rcvRec_t; validationRec validBackupSetRec_t; validationRC binary_integer; BEGIN deb(DEB_ENTER, 'listGetControlfileBackup815'); <> BEGIN listGetControlfileBackup(rcvRec); EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with: FALSE#'); RETURN FALSE#; END; validationRC := validateBackupSet(backupSetRec => rcvRec, tag => listGetBackupTag, tagMatchRequired => TRUE, checkDeviceIsAllocated => TRUE, availableMask => listGetBackupAvailableMask, validRec => validationRec); IF (validationRC <> SUCCESS) THEN GOTO nextRow; END IF; bskey := rcvRec.bsKey_con; ckpscn := rcvRec.toSCN_act; ckptime := rcvRec.toTime_act; deb(DEB_EXIT, 'with: TRUE#'); RETURN TRUE#; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with: FALSE#'); RETURN FALSE#; END listGetControlfileBackup; -- PROCEDURE listTranslateSpfileBackup( completedAfter IN date ,completedBefore IN date) IS BEGIN deb(DEB_ENTER, 'listTranslateSpfileBackup'); IF (findSpfileBackup_c%ISOPEN) THEN -- should not be open CLOSE findSpfileBackup_c; END IF; deb(DEB_OPEN, 'findSpfileBackup_c'); OPEN findSpfileBackup_c(completedAfter => completedAfter, completedBefore => completedBefore); deb(DEB_EXIT); END listTranslateSpfileBackup; -- PROCEDURE listGetSpfileBackup( rcvRec OUT NOCOPY rcvRec_t) IS BEGIN deb(DEB_ENTER, 'listGetSpfileBackup'); FETCH findSpfileBackup_c INTO rcvRec; -- -- IF (findSpfileBackup_c%NOTFOUND) THEN CLOSE findSpfileBackup_c; deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; END IF; deb(DEB_EXIT); END listGetSpfileBackup; -- PROCEDURE listTranslateDataFileBackup( file# IN number ,creation_change# IN number ,tag IN varchar2 DEFAULT NULL ,completedAfter IN date DEFAULT NULL ,completedBefore IN date DEFAULT NULL ,statusMask IN binary_integer DEFAULT BSavailable+BSunavailable+BSexpired -- 8.0/8.1 defaults ,pluginSCN IN number DEFAULT 0) IS rlgSCN number; rlgTime date; crescn number; BEGIN deb(DEB_ENTER, 'listTranslateDataFileBackup'); IF (findDatafileBackup_c%ISOPEN) THEN CLOSE findDatafileBackup_c; END IF; IF (allIncarnations = TRUE#) THEN IF (ignoreCreationSCN = TRUE#) THEN -- -- -- -- -- crescn := NULL; ELSE crescn := creation_change#; END IF; ELSE -- -- rlgSCN := this_reset_scn; rlgTime := this_reset_time; crescn := creation_change#; END IF; -- deb(DEB_OPEN, 'findDatafileBackup_c'); OPEN findDatafileBackup_c(sourceMask => backupSet_con_t, fno => file#, crescn => crescn, reset_scn => rlgSCN, reset_time => rlgTime, completedAfter => completedAfter, completedBefore => completedBefore, pluginSCN => pluginSCN); -- -- -- -- -- listGetBackupTag := tag; listGetBackupAvailableMask := statusMask; deb(DEB_EXIT); END listTranslateDataFileBackup; -- PROCEDURE listGetDataFileBackup( rcvRec OUT NOCOPY rcvRec_t) IS BEGIN deb(DEB_ENTER, 'listGetDataFileBackup'); FETCH findDatafileBackup_c INTO rcvRec; IF (findDatafileBackup_c%NOTFOUND) THEN CLOSE findDatafileBackup_c; deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; END IF; deb(DEB_EXIT); END listGetDataFileBackup; -- -- FUNCTION listGetDataFileBackup( bs_key OUT number ,backup_type OUT varchar2 ,incremental_level OUT number ,completion_time OUT date ,checkpoint_change# OUT number ,checkpoint_time OUT date) RETURN number IS rcvRec rcvRec_t; valRC binary_integer; validationRec validBackupSetRec_t; BEGIN deb(DEB_ENTER, 'listGetDataFileBackup815'); <> BEGIN listGetDataFileBackup(rcvRec => rcvRec); EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with: FALSE#'); RETURN FALSE#; END; valRC := validateBackupSet(backupSetRec => rcvRec, tag => listGetBackupTag, tagMatchRequired => TRUE, checkDeviceIsAllocated => TRUE, availableMask => listGetBackupAvailableMask, validRec => validationRec); IF (valRC <> SUCCESS) THEN GOTO nextRow; END IF; bs_key := rcvRec.bsKey_con; IF (rcvRec.fromSCN_act = 0) THEN backup_type := 'Full'; ELSE backup_type := 'Incremental'; END IF; incremental_level := rcvRec.level_act; completion_time := rcvRec.compTime_con; -- somewhat bogus checkpoint_change# := rcvRec.toSCN_act; checkpoint_time := rcvRec.toTime_act; deb(DEB_EXIT, 'with: TRUE#'); RETURN TRUE#; END listGetDataFileBackup; -- -- PROCEDURE translateBackupFile( bs_recid IN number ,bs_stamp IN number ,fno IN number ,bskey OUT number ,inclevel OUT number ,backup_type OUT varchar2 ,completed OUT date) IS BEGIN deb(DEB_ENTER, 'translateBackupFile'); -- -- -- -- -- -- -- IF (rcvRec_last.type_con <> backupSet_con_t OR rcvRec_last.bsRecid_con <> bs_recid OR rcvRec_last.bsStamp_con <> bs_stamp) THEN deb(DEB_EXIT, 'with error 20204'); raise_application_error(-20204, 'Translation not started'); END IF; bskey := rcvRec_last.bsKey_con; inclevel := rcvRec_last.level_act; completed := rcvRec_last.compTime_con; IF (rcvRec_last.logSequence_obj IS NOT NULL) THEN backup_type := 'Archived Log'; ELSE IF (rcvRec_last.fromSCN_act = 0) THEN backup_type := 'Full'; ELSE backup_type := 'Incremental'; END IF; END IF; deb(DEB_EXIT); END translateBackupFile; -- -- PROCEDURE listTranslateArchivedLogBackup( thread# IN number ,sequence# IN number ,first_change# IN number ,completedAfter IN date DEFAULT NULL ,completedBefore IN date DEFAULT NULL ,statusMask IN binary_integer DEFAULT BSavailable+BSunavailable+BSexpired) -- 8.0/8.1 defaults IS currentInc number; BEGIN deb(DEB_ENTER, 'listTranslateArchivedLogBackup'); IF (allIncarnations = TRUE#) THEN currentInc := FALSE#; -- don't care about dbinc_key ELSE currentInc := TRUE#; END IF; deb(DEB_OPEN, 'findArcLogBackup'); OPEN findArcLogBackup(sourcemask => backupSet_con_t, currentIncarnation => currentInc, thread => thread#, sequence => sequence#, lowSCN => first_change#, completedAfter => completedAfter, completedBefore => completedBefore); listGetBackupAvailableMask := statusMask; deb(DEB_EXIT); END listTranslateArchivedLogBackup; -- PROCEDURE listGetArchivedLogBackup( rcvRec OUT NOCOPY rcvRec_t) IS BEGIN deb(DEB_ENTER, 'listGetArchivedLogBackup'); -- IF (guidQualifier IS NOT NULL) THEN IF (findArcLogBackup%ISOPEN) THEN CLOSE findArcLogBackup; END IF; deb(DEB_EXIT, 'guid not valid for archivelog'); RAISE no_data_found; END IF; FETCH findArcLogBackup INTO rcvRec; IF (findArcLogBackup%NOTFOUND) THEN CLOSE findArcLogBackup; deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; END IF; deb(DEB_EXIT); END listGetArchivedLogBackup; -- -- FUNCTION listGetArchivedLogBackup( bs_key OUT number ,completion_time OUT date) RETURN number IS rcvRec rcvRec_t; validRec validBackupSetRec_t; valRC binary_integer; BEGIN deb(DEB_ENTER, 'listGetArchivedLogBackup'); <> listGetArchivedLogBackup(rcvRec); valRC := validateBackupSet(backupSetRec => rcvRec, checkDeviceIsAllocated => TRUE, availableMask => listGetBackupAvailableMask, validRec => validRec); IF (valRC <> SUCCESS) THEN GOTO get_next; END IF; bs_key := rcvRec.bsKey_con; completion_time := rcvRec.compTime_con; deb(DEB_EXIT, 'with: TRUE#'); RETURN TRUE#; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with: FALSE#'); RETURN FALSE#; END listGetArchivedLogBackup; -- -- -- -- PROCEDURE listTranslateArchivedLogBackup( thread# IN number DEFAULT NULL ,lowseq IN number DEFAULT NULL ,highseq IN number DEFAULT NULL ,lowscn IN number DEFAULT NULL ,highscn IN number DEFAULT NULL ,from_time IN date DEFAULT NULL ,until_time IN date DEFAULT NULL ,pattern IN varchar2 DEFAULT NULL) IS BEGIN deb(DEB_ENTER, 'listTranslateArchivedLogBackup815'); if lbal2%isopen then close lbal2; end if; deb(DEB_OPEN, 'lbal2'); open lbal2(thread#, lowseq, highseq, lowscn, highscn, from_time, until_time); deb(DEB_EXIT); END listTranslateArchivedLogBackup; -- -- FUNCTION listGetArchivedLogBackup( bs_key OUT number ,thread# OUT number ,sequence# OUT number ,first_change# OUT number ,next_change# OUT number ,first_time OUT date ,next_time OUT date) RETURN number IS rcvRec rcvRec_t; validRec validBackupSetRec_t; BEGIN deb(DEB_ENTER, 'listGetArchivedLogBackup815'); <> fetch lbal2 into rcvRec; if lbal2%found then IF (debug) THEN deb(DEB_PRINT, 'listGetArchivedLogBackup: got a backupset:'); printRcvRec(rcvRec); END IF; if validateBackupSet(backupSetRec => rcvRec, checkDeviceIsAllocated => TRUE, availableMask => dbms_rcvman.BSavailable + dbms_rcvman.BSunavailable + dbms_rcvman.BSexpired, validRec => validRec) <> SUCCESS then goto get_next; end if; bs_key := rcvRec.bsKey_con; thread# := rcvRec.logThread_obj; sequence# := rcvRec.logSequence_obj; first_change# := rcvRec.logLowSCN_obj; next_change# := rcvRec.logNextSCN_obj; first_time := rcvRec.logLowTime_obj; next_time := rcvRec.logNextTime_obj; deb(DEB_EXIT, 'with: TRUE#'); RETURN TRUE#; else close lbal2; deb(DEB_EXIT, 'with: FALSE#'); RETURN FALSE#; end if; END listGetArchivedLogBackup; -- -- -- PROCEDURE listTranslateBackupsetFiles( bs_key IN number) IS BEGIN IF findBackupsetFiles%ISOPEN THEN CLOSE findBackupsetFiles; END IF; OPEN findBackupsetFiles(bs_key); END; PROCEDURE listGetBackupsetFiles( rcvRec OUT NOCOPY rcvRec_t) IS BEGIN FETCH findBackupsetFiles INTO rcvRec; IF (findBackupsetFiles%NOTFOUND) THEN CLOSE findBackupsetFiles; RAISE no_data_found; END IF; END; -- -- -- PROCEDURE translateAllBackupSet( backupType IN binary_integer ,tag IN varchar2 ,statusMask IN binary_integer ,completedAfter IN date ,completedBefore IN date ,onlyrdf IN binary_integer DEFAULT 0) IS BEGIN IF findAllBackupPiece%ISOPEN THEN CLOSE findAllBackupPiece; END IF; OPEN findAllBackupPiece(backupType => backupType ,tag => tag ,statusMask => statusMask ,completedAfter => completedAfter ,completedBefore => completedBefore ,onlyrdf => onlyrdf); END; PROCEDURE getAllBackupSet( rcvRec OUT NOCOPY rcvRec_t) IS BEGIN FETCH findAllBackupPiece INTO rcvRec; IF (findAllBackupPiece%NOTFOUND) THEN CLOSE findAllBackupPiece; RAISE no_data_found; END IF; END; -- -- -- -- -- PROCEDURE listTranslateProxyDataFile( file# IN number ,creation_change# IN number ,tag IN varchar2 DEFAULT NULL ,handle_pattern IN varchar2 DEFAULT NULL ,completedAfter IN date DEFAULT NULL ,completedBefore IN date DEFAULT NULL ,statusMask IN binary_integer DEFAULT BSavailable+BSunavailable+BSexpired ,liststby IN binary_integer DEFAULT NULL ,pluginSCN IN number DEFAULT 0) IS currentInc number; crescn number; reset_scn number := NULL; reset_time date := NULL; BEGIN deb(DEB_ENTER, 'listTranslateProxyDataFile'); validateState(null); IF (allIncarnations = TRUE#) THEN currentInc := FALSE#; -- don't care about dbinc_key IF (ignoreCreationSCN = TRUE#) THEN -- -- -- -- crescn := NULL; ELSE crescn := creation_change#; END IF; ELSE currentInc := TRUE#; crescn := creation_change#; END IF; IF (currentInc = TRUE#) THEN reset_scn := this_reset_scn; reset_time := this_reset_time; END IF; IF (file# = 0) THEN IF (findControlfileBackup_c%ISOPEN) THEN CLOSE findControlfileBackup_c; END IF; -- deb(DEB_OPEN, 'findControlfileBackup_c'); OPEN findControlfileBackup_c( sourcemask => proxyCopy_con_t, currentIncarnation => currentInc, tag => tag, pattern => handle_pattern, completedAfter => completedAfter, completedBefore => completedBefore, statusMask => statusMask, needstby => liststby); listGetProxyDatafileCursor := 'findControlfileBackup_c'; ELSE IF (findDatafileBackup_c%ISOPEN) THEN CLOSE findDatafileBackup_c; END IF; -- OPEN findDatafileBackup_c(sourcemask => proxyCopy_con_t, fno => file#, crescn => crescn, reset_scn => reset_scn, reset_time => reset_time, tag => tag, pattern => handle_pattern, completedAfter => completedAfter, completedBefore => completedBefore, statusMask => statusMask, pluginSCN => pluginSCN); listGetProxyDatafileCursor := 'findDatafileBackup_c'; END IF; deb(DEB_EXIT); END listTranslateProxyDataFile; -- PROCEDURE listGetProxyDataFile( rcvRec OUT NOCOPY rcvRec_t) IS local rcvRec_t; BEGIN deb(DEB_ENTER, 'listGetProxyDataFile'); <> IF (listGetProxyDatafileCursor = 'findControlfileBackup_c') THEN FETCH findControlfileBackup_c INTO local; IF (findControlfileBackup_c%NOTFOUND) THEN CLOSE findControlfileBackup_c; deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; END IF; ELSIF (listGetProxyDatafileCursor = 'findDatafileBackup_c') THEN FETCH findDatafileBackup_c INTO local; IF (findDatafileBackup_c%NOTFOUND) THEN CLOSE findDatafileBackup_c; deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; END IF; ELSE deb(DEB_EXIT, 'with error 20204'); raise_application_error(-20204, 'Translation not started'); END IF; -- -- IF (anyDevice = FALSE# AND isDeviceTypeAllocated(local.deviceType_con) = FALSE#) THEN GOTO nextRow; END IF; rcvRec := local; -- set OUT mode arg deb(DEB_EXIT); END listGetProxyDataFile; -- -- FUNCTION listGetProxyDataFile( xdf_key OUT number ,recid OUT number ,stamp OUT number ,status OUT varchar2 ,handle OUT varchar2 ,completion_time OUT date ,checkpoint_change# OUT number ,checkpoint_time OUT date) RETURN number IS rcvRec rcvRec_t; BEGIN deb(DEB_ENTER, 'listGetProxyDataFile815'); listGetProxyDataFile(rcvRec); xdf_key := rcvRec.key_con; recid := rcvRec.recid_con; stamp := rcvRec.stamp_con; status := rcvRec.status_con; handle := rcvRec.fileName_con; completion_time := rcvRec.compTime_con; checkpoint_change# := rcvRec.toSCN_act; checkpoint_time := rcvRec.toTime_act; deb(DEB_EXIT, 'with: TRUE#'); RETURN TRUE#; EXCEPTION WHEN no_data_found THEN deb(DEB_EXIT, 'with: FALSE#'); RETURN FALSE#; END listGetProxyDataFile; -- PROCEDURE listTranslateProxyArchivedLog( thread# IN number ,sequence# IN number ,first_change# IN number ,tag IN varchar2 DEFAULT NULL ,handle_pattern IN varchar2 DEFAULT NULL ,completedAfter IN date DEFAULT NULL ,completedBefore IN date DEFAULT NULL ,statusMask IN binary_integer DEFAULT BSavailable+BSunavailable+BSexpired) IS currentIncarnation number; BEGIN deb(DEB_ENTER, 'listTranslateProxyArchivedLog'); IF (allIncarnations = TRUE#) THEN currentIncarnation := FALSE#; -- don't care about dbinc_key ELSE currentIncarnation := TRUE#; END IF; deb(DEB_OPEN, 'findArcLogBackup'); OPEN findArcLogBackup(sourcemask => proxyCopy_con_t, currentIncarnation => currentIncarnation, thread => thread#, sequence => sequence#, lowSCN => first_change#, tag => tag, pattern => handle_pattern, completedAfter => completedAfter, completedBefore => completedBefore, statusMask => statusMask); deb(DEB_EXIT); END listTranslateProxyArchivedLog; -- PROCEDURE listGetProxyArchivedLog( rcvRec OUT NOCOPY rcvRec_t) IS local rcvRec_t; BEGIN deb(DEB_ENTER, 'listGetProxyArchivedLog'); -- IF (guidQualifier IS NOT NULL) THEN IF (findArcLogBackup%ISOPEN) THEN CLOSE findArcLogBackup; END IF; deb(DEB_EXIT, 'guid not valid for archivelog'); RAISE no_data_found; END IF; <> FETCH findArcLogBackup INTO local; IF (findArcLogBackup%NOTFOUND) THEN CLOSE findArcLogBackup; deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; END IF; -- -- IF (anyDevice = FALSE# AND isDeviceTypeAllocated(local.deviceType_con) = FALSE#) THEN GOTO nextRow; END IF; rcvRec := local; -- set OUT mode arg deb(DEB_EXIT); END listGetProxyArchivedLog; -- -- -- -- PROCEDURE listTranslateDBIncarnation( db_name IN varchar2 DEFAULT NULL, all_databases IN number DEFAULT 0) IS BEGIN deb(DEB_ENTER, 'listTranslateDBIncarnation'); IF (ldbi%isopen) THEN CLOSE ldbi; END IF; deb(DEB_OPEN, 'ldbi'); OPEN ldbi(upper(db_name), all_databases); deb(DEB_EXIT); END listTranslateDBIncarnation; -- FUNCTION listGetDBIncarnation( db_key OUT number ,dbinc_key OUT number ,db_name OUT varchar2 ,db_id OUT number ,current_inc OUT varchar2 ,resetlogs_change# OUT number ,resetlogs_time OUT date ,dbinc_status OUT varchar2) RETURN number IS BEGIN deb(DEB_ENTER, 'listGetDBIncarnation'); FETCH ldbi INTO db_key, dbinc_key, db_name, db_id, current_inc, resetlogs_change#, resetlogs_time, dbinc_status; IF (ldbi%found) THEN deb(DEB_EXIT, 'with: TRUE#'); RETURN TRUE#; ELSE CLOSE ldbi; deb(DEB_EXIT, 'with: FALSE#'); RETURN FALSE#; END IF; deb(DEB_EXIT); END listGetDBIncarnation; -- FUNCTION listGetDBIncarnation( db_key OUT number ,dbinc_key OUT number ,db_name OUT varchar2 ,db_id OUT number ,current_inc OUT varchar2 ,resetlogs_change# OUT number ,resetlogs_time OUT date) RETURN number IS dbinc_status varchar2(9); BEGIN RETURN listGetDBIncarnation(db_key, dbinc_key, db_name, db_id, current_inc, resetlogs_change#, resetlogs_time, dbinc_status); END listGetDBIncarnation; -- -- -- -- PROCEDURE listTranslateDBSite( db_name IN varchar2 DEFAULT NULL, alldbs IN binary_integer DEFAULT 1) IS BEGIN deb(DEB_ENTER, 'listTranslateDBSite'); IF (lnni%isopen) THEN CLOSE lnni; END IF; deb(DEB_OPEN, 'lnni'); OPEN lnni(db_name, alldbs); deb(DEB_EXIT); END listTranslateDBSite; -- FUNCTION listGetDBSite( db_key OUT number ,db_id OUT number ,db_name OUT varchar2 ,db_role OUT varchar2 ,db_unique_name OUT varchar2) RETURN number IS BEGIN deb(DEB_ENTER, 'listGetDBSite'); FETCH lnni INTO db_key, db_id, db_name, db_role, db_unique_name; deb(DEB_PRINT, 'site name =['||db_unique_name||']'); IF (lnni%found) THEN deb(DEB_EXIT, 'with: TRUE#'); RETURN TRUE#; ELSE CLOSE lnni; deb(DEB_EXIT, 'with: FALSE#'); RETURN FALSE#; END IF; deb(DEB_EXIT); END listGetDBSite; -- -- -- -- PROCEDURE listRollbackSegTableSpace IS BEGIN deb(DEB_ENTER, 'listRollbackSegTableSpace'); -- IF (lrtbs%ISOPEN) THEN CLOSE lrtbs; END IF; deb(DEB_OPEN, 'lrtbs'); OPEN lrtbs; -- -- deb(DEB_EXIT); END listRollbackSegTableSpace; -- FUNCTION listGetTableSpace( ts# OUT number ,ts_name OUT varchar2) RETURN number IS pdbname varchar2(128); BEGIN RETURN listGetTableSpace(ts#, ts_name, pdbname); END listGetTableSpace; FUNCTION listGetTableSpace( ts# OUT number ,ts_name OUT varchar2 ,pdbname OUT varchar2) RETURN number IS BEGIN deb(DEB_ENTER, 'listGetTableSpace'); -- FETCH lrtbs INTO ts#, ts_name, pdbname; IF (lrtbs%FOUND) THEN deb(DEB_EXIT, 'with: TRUE#'); RETURN TRUE#; ELSE CLOSE lrtbs; deb(DEB_EXIT, 'with: FALSE#'); RETURN FALSE#; END IF; -- -- deb(DEB_EXIT); END listGetTableSpace; -- -- -- -- PROCEDURE getIncrementalScn( first IN boolean -- open the cursor if this is TRUE ,file# IN number ,create_scn IN number ,reset_scn IN number ,reset_time IN date ,incr_level IN number ,cumulative IN number ,rcvRec OUT NOCOPY rcvRec_t ,sourcemask IN number DEFAULT NULL ,tag IN varchar2 DEFAULT NULL ,pluginSCN IN number DEFAULT 0 ,keep IN boolean DEFAULT NULL) IS ilevel number; local rcvRec_t; validRec validBackupSetRec_t; usable_incr rcvRec_t; available_fromSCN_act number; pdbId number; cleanSCN number; BEGIN deb(DEB_ENTER, 'getIncrementalScn'); IF (incr_level not in (1,2,3,4) OR incr_level is NULL) THEN raise_application_error(-20270, 'invalid incremental level'); END IF; IF (cumulative not in (0,1) OR cumulative is NULL) THEN raise_application_error(-20271, 'invalid cumulative option'); END IF; -- -- -- -- -- -- -- -- -- IF (cumulative = TRUE#) THEN ilevel := incr_level - 1; -- Consider only higher level backups ELSE ilevel := incr_level; END IF; -- IF (file# IS NOT NULL) THEN setDfTransClause(fno => file#); END IF; IF first THEN IF (findDatafileBackup_c%ISOPEN) THEN CLOSE findDatafileBackup_c; END IF; getDatafileBackupLast.type_con := NULL; -- clear the last backup record -- cacheBsRecTable.hint := redundantHint; -- OPEN findDatafileBackup_c( sourcemask => sourcemask, fno => file#, crescn => create_scn, reset_scn => nvl(reset_scn, this_reset_scn), reset_time => nvl(reset_time, this_reset_time), level => ilevel, statusMask => BSavailable, tag => tag, onlytc => TRUE#, pluginSCN => pluginSCN, allowCumuLevelN => TRUE#); END IF; IF (NOT findDatafileBackup_c%ISOPEN) THEN raise_application_error(-20272, 'cannot take incremental backup'); END IF; LOOP <> FETCH findDatafileBackup_c INTO local; IF (findDatafileBackup_c%NOTFOUND) THEN deb(DEB_PRINT, 'closing cursor'); CLOSE findDatafileBackup_c; cacheBsRecTable.hint := noHint; IF (file# is NOT NULL) THEN -- deb(DEB_EXIT, 'with: cannot take incr backup'); raise_application_error(-20272, 'cannot take incremental backup'); ELSE deb(DEB_EXIT, 'with: no data found'); raise no_data_found; -- no more datafile backups END IF; END IF; -- -- -- -- -- IF (keep IS NOT NULL AND -- NULL means 10g client ((local.keep_options != 0 AND NOT keep) OR -- local_keep and not keep (local.keep_options = 0 AND keep))) THEN -- not local_keep and keep deb(DEB_PRINT, 'Keep does not match for ' || local.key_con || ' completed at ' || to_char(local.compTime_con, 'DD-MON-YY HH24:MI:SS')); GOTO nextRow; -- keep attributes do not match END IF; IF (available_fromSCN_act IS NULL AND getDatafileBackupLast.type_con IS NOT NULL AND getDatafileBackupLast.dfNumber_obj = local.dfNumber_obj) THEN deb(DEB_PRINT, 'already returned incremental scn for file# ' || local.dfNumber_obj); GOTO nextRow; -- this is a duplicate of what we returned earlier END IF; -- -- -- IF (available_fromSCN_act IS NOT NULL AND (usable_incr.dfNumber_obj <> local.dfNumber_obj OR (usable_incr.dfNumber_obj = local.dfNumber_obj AND usable_incr.dfCreationSCN_obj <> local.dfCreationSCN_obj))) THEN deb(DEB_PRINT, 'no level 0 found for this file# ' || usable_incr.dfNumber_obj || ', creation_scn '|| usable_incr.dfCreationSCN_obj); usable_incr := NULL; available_fromSCN_act := NULL; END IF; pdbId := translatePdbFile(local.dfNumber_obj, cleanSCN); IF (CheckRecAction(local, pdbId, cleanSCN) = action_SKIP) THEN deb(DEB_PRINT, 'on orphan branch'); GOTO nextRow; -- this action belongs to orphan branch END IF; IF (usable_incr.dfNumber_obj = local.dfNumber_obj AND usable_incr.dfCreationSCN_obj = local.dfCreationSCN_obj AND local.fromSCN_act > 0 AND available_fromSCN_act < local.fromSCN_act) THEN deb(DEB_PRINT, 'overlapping incremental found for file# ' || usable_incr.dfNumber_obj || ', creation_scn '|| usable_incr.dfCreationSCN_obj); GOTO nextRow; -- overlapping incremental END IF; IF (local.type_con = backupSet_con_t) THEN -- -- IF (validateBackupSet(backupSetRec => local, tag => tag, tagMatchRequired => TRUE, checkDeviceIsAllocated => FALSE, availableMask => BSavailable, validRec => validRec) = dbms_rcvman.UNAVAILABLE) THEN deb(DEB_PRINT, 'incremental is unavailable'); GOTO nextRow; -- can't create an incr based on unavail backup END IF; -- -- -- -- -- -- -- IF (available_fromSCN_act IS NULL OR (usable_incr.dfNumber_obj = local.dfNumber_obj AND usable_incr.dfCreationSCN_obj = local.dfCreationSCN_obj AND local.toSCN_act < available_fromSCN_act)) THEN IF (available_fromSCN_act IS NULL) THEN deb(DEB_PRINT, 'available_fromSCN_act set to ' || available_fromSCN_act || ' for file# ' || local.dfNumber_obj || ', creation_scn '|| local.dfCreationSCN_obj); ELSE deb(DEB_PRINT, 'broken chain, available_fromSCN_act set to ' || available_fromSCN_act || ' for file ' || local.dfNumber_obj || ', creation_scn '|| local.dfCreationSCN_obj); END IF; usable_incr := local; available_fromSCN_act := local.fromSCN_act; END IF; END IF; -- -- -- IF (usable_incr.dfNumber_obj = local.dfNumber_obj AND usable_incr.dfCreationSCN_obj = local.dfCreationSCN_obj AND local.toSCN_act >= available_fromSCN_act AND local.fromSCN_act < available_fromSCN_act) THEN available_fromSCN_act := local.fromSCN_act; deb(DEB_PRINT, 'available_fromSCN_act moved to ' || available_fromSCN_act || ' for file# ' || local.dfNumber_obj || ', creation_scn '|| local.dfCreationSCN_obj); END IF; -- -- IF (available_fromSCN_act != usable_incr.dfCreationSCN_obj AND available_fromSCN_act > 0) THEN deb(DEB_PRINT, 'need more incrementals to validate chain'); GOTO nextRow; END IF; If (available_fromSCN_act = usable_incr.dfCreationSCN_obj OR available_fromSCN_act = 0) THEN deb(DEB_PRINT, 'validated incremental to level 0, incremental scn=' || usable_incr.toSCN_act || 'for file ' || usable_incr.dfNumber_obj); rcvRec := usable_incr; ELSE rcvRec := local; deb(DEB_PRINT, 'using level0 proxy/copy, incremental scn=' || local.toSCN_act || ' for file ' || local.dfNumber_obj); END IF; getDatafileBackupLast := rcvRec; -- remember the last record returned deb(DEB_EXIT, 'with: valid record '); EXIT; -- valid record. Create Incremental based on this SCN END LOOP; EXCEPTION WHEN others THEN cacheBsRecTable.hint := noHint; deb(DEB_PRINT, 'caught an exception during getIncrementalScn'); deb(DEB_EXIT, substr(sqlerrm, 1, 512)); raise; END getIncrementalScn; -- FUNCTION getIncrementalScn( file# IN number ,create_scn IN number ,reset_scn IN number ,reset_time IN date ,incr_level IN number ,cumulative IN number ,sourcemask IN number DEFAULT NULL ,tag IN varchar2 DEFAULT NULL ,pluginSCN IN number DEFAULT 0) RETURN number IS rcvRec rcvRec_t; BEGIN getIncrementalScn( first => TRUE ,file# => file# ,create_scn => create_scn ,reset_scn => reset_scn ,reset_time => reset_time ,incr_level => incr_level ,cumulative => cumulative ,rcvRec => rcvRec ,sourcemask => sourcemask ,tag => tag ,pluginSCN => pluginSCN); IF (findDatafileBackup_c%ISOPEN) THEN CLOSE findDatafileBackup_c; -- close the one opened in getIncrementalScn END IF; RETURN rcvRec.toSCN_act; END getIncrementalScn; -- -- -- -- PROCEDURE setComputeRecoveryActionMasks( containerMask IN number ,actionMask IN number ,allRecords IN number ,availableMask IN binary_integer ,fullBackups IN number DEFAULT NULL) IS BEGIN deb(DEB_ENTER, 'setComputeRecoveryActionMasks'); IF (allRecords = FALSE# AND fullBackups IS NULL) THEN computeRA_fullBackups := 1; ELSE computeRA_fullBackups := fullBackups; END IF; getRA_containerMask := containerMask; getRA_actionMask := actionMask; computeRA_allRecords := allRecords; computeRA_availableMask := availableMask; -- -- -- -- IF (restoreSource IS NULL) THEN restoreSource := proxyCopy_con_t + imageCopy_con_t + backupSet_con_t; IF (bitand(getRA_containerMask, proxyCopy_con_t) = 0) THEN restoreSource := restoreSource - proxyCopy_con_t; END IF; IF (bitand(getRA_containerMask, imageCopy_con_t) = 0) THEN restoreSource := restoreSource - imageCopy_con_t; END IF; IF (bitand(getRA_containerMask, backupSet_con_t) = 0) THEn restoreSource := restoreSource - backupSet_con_t; END IF; IF (restoreSource = 0) THEN restoreSource := NULL; END IF; END IF; deb(DEB_EXIT); END setComputeRecoveryActionMasks; -- -- PROCEDURE setComputeRecoveryActionMasks( containerMask IN number ,actionMask IN number ,allRecords IN number) IS BEGIN deb(DEB_ENTER, 'setComputeRecoveryActionMasks816'); setComputeRecoveryActionMasks( containerMask => containerMask, actionMask => actionMask, allRecords => allRecords, availableMask => dbms_rcvman.BSavailable, fullBackups => to_number(null)); deb(DEB_EXIT); END setComputeRecoveryActionMasks; -- -- PROCEDURE setRAflags( kindMask IN number ,allRecords IN boolean) IS containerMask number; actionMask number; allRecs number; BEGIN deb(DEB_ENTER, 'setRAflags'); -- containerMask := 0; IF (bitand(kindMask, implicitOfflRange + cleanRange + applyOfflRange) > 0) THEN containerMask := containerMask + offlineRangeRec_con_t; END IF; IF (bitand(kindMask, dfCopy) > 0) THEN containerMask := containerMask + imageCopy_con_t; END IF; IF (bitand(kindMask, buSet + applyIncremental) > 0) THEN containerMask := containerMask + backupSet_con_t; END IF; IF (bitand(kindMask, proxyFull) > 0) THEN containerMask := containerMask + proxyCopy_con_t; END IF; -- actionMask := 0; IF (bitand(kindMask, dfCopy + ProxyFull + buSet) > 0) THEN actionMask := actionMask + full_act_t; END IF; IF (bitand(kindMask, applyIncremental) > 0) THEN actionMask := actionMask + incremental_act_t; END IF; IF (bitand(kindMask, redo) > 0) THEN actionMask := actionMask + redo_act_t; END IF; IF (bitand(kindMask, implicitOfflRange) > 0) THEN actionMask := actionMask + implicitRange_act_t; END IF; IF (bitand(kindMask, cleanRange) > 0) THEN actionMask := actionMask + cleanRange_act_t; END IF; IF (bitand(kindMask, applyOfflRange) > 0) THEN actionMask := actionMask + offlineRange_act_t; END IF; IF (allRecords) THEN allRecs := TRUE#; ELSE allRecs := FALSE#; END IF; deb(DEB_PRINT, 'setRAflags kindMask=' || to_char(kindMask) || ' containerMask=' || to_char(containerMask) || ' actionMask=' || to_char(actionMask)); setComputeRecoveryActionMasks(containerMask, actionMask, allRecs); deb(DEB_EXIT); END setRAflags; -- FUNCTION getRecoveryAction( action OUT NOCOPY rcvRec_t) RETURN binary_integer IS redoAction rcvRec_t; local rcvRec_t; top rcvRec_t; BEGIN deb(DEB_ENTER, 'getRecoveryAction'); <> IF (rcvRecStack.count = 0) THEN -- -- -- -- -- -- -- -- -- -- -- deb(DEB_EXIT, 'with no more records'); raise no_data_found; END IF; rcvRecPop(local); -- IF (not isValidAction(local)) THEN IF (debug) THEN printRcvRec(local); END IF; goto getNext; END IF; <> IF (rcvRecStack.count > 0) THEN -- -- -- rcvRecTop(top); IF (local.type_act = redo_act_t AND top.type_act = redo_act_t) THEN -- -- -- redoAction := local; rcvRecPop(local); local.fromSCN_act := redoAction.fromSCN_act; GOTO merge_actions; END IF; action := local; rcvRec_last := local; deb(DEB_EXIT, 'with: TRUE#'); RETURN TRUE#; -- more actions to return yet ELSE action := local; rcvRec_last := local; deb(DEB_EXIT, 'with: FALSE#'); RETURN FALSE#; -- this is the last action END IF; END getRecoveryAction; -- -- FUNCTION getRecoveryAction( kind OUT number ,set_stamp OUT number ,set_count OUT number ,recid OUT number ,stamp OUT number ,fname OUT varchar2 ,blocksize OUT number ,blocks OUT number ,devtype OUT varchar2 ,from_scn OUT number ,to_scn OUT number ,to_time OUT date ,rlgscn OUT number ,rlgtime OUT date ,cfcretime OUT date ,dbinc_key OUT number) RETURN binary_integer IS rcvRec rcvRec_t; rc binary_integer; BEGIN deb(DEB_ENTER, 'getRecoveryAction815'); rc := getRecoveryAction(rcvRec); IF (rcvRec.type_con = offlineRangeRec_con_t) THEN IF (rcvRec.type_act = offlineRange_act_t) THEN kind := applyOfflRange; ELSIF (rcvRec.type_act = cleanRange_act_t) THEN kind := cleanRange; ELSIF (rcvRec.type_act = implicitRange_act_t) THEN kind := implicitOfflRange; ELSE deb(DEB_PRINT, 'cannot convert type_con=' || to_char(rcvRec.type_con) || ' type_act=' || to_char(rcvRec.type_act) || ' to recovery action kind'); deb(DEB_EXIT, 'with error 20999'); raise_application_error(-20999, 'internal error: getRecoveryAction'); END IF; ELSIF (rcvRec.type_con = backupSet_con_t) THEN IF (rcvRec.type_act = full_act_t) THEN kind := buSet; ELSE kind := applyIncremental; END IF; ELSIF (rcvRec.type_con = proxyCopy_con_t) THEN kind := proxyFull; ELSIF (rcvRec.type_con = imageCopy_con_t) THEN kind := dfCopy; ELSIF (rcvRec.type_con IS NULL) THEN IF (rcvRec.type_act = redo_act_t) THEN kind := redo; END IF; END IF; deb(DEB_PRINT, 'getRecoveryAction: kind=' || nvl(to_char(kind), 'null')); rcvRecConvert(rcvRec); -- get rid of nulls IF (debug) THEN printRcvRec(rcvRec); END IF; set_stamp := rcvRec.setStamp_con; set_count := rcvRec.setCount_con; IF (rcvRec.type_con = backupSet_con_t) THEN recid := rcvRec.bsRecid_con; stamp := rcvRec.bsStamp_con; ELSE recid := rcvRec.recid_con; stamp := rcvRec.stamp_con; END IF; fname := rcvRec.fileName_con; blocksize := rcvRec.blockSize_con; blocks := rcvRec.blocks_con; devtype := rcvRec.deviceType_con; from_scn := rcvRec.fromSCN_act; to_scn := rcvRec.toSCN_act; to_time := rcvRec.toTime_act; -- null OK rlgscn := rcvRec.rlgSCN_act; rlgtime := rcvRec.rlgTime_act; cfcretime := rcvRec.cfCreationTime_con; -- null OK dbinc_key := rcvRec.dbincKey_act; -- null OK deb(DEB_EXIT, 'with: '||to_char(rc)); RETURN rc; END; -- PROCEDURE printRecoveryActions IS action rcvRec_t; rc number; BEGIN IF (not debug) THEN return; END IF; deb(DEB_PRINT, '===== ' || to_char(rcvRecStack.count) || ' actions stacked ====='); IF (rcvRecStack.count = 0) THEN return; END IF; LOOP rc := getRecoveryAction(action); printRcvRec(action); EXIT WHEN rc = FALSE#; END LOOP; END printRecoveryActions; -- PROCEDURE trimRecoveryActions( maxActions IN number ,containerMask IN number ,actionMask IN number) IS n number; BEGIN deb(DEB_ENTER, 'trimRecoveryActions[procedure]'); n := trimRecoveryActions(maxActions, containerMask, actionMask); deb(DEB_PRINT, 'trimRecoveryActions[procedure] returned '||n); deb(DEB_EXIT); END trimRecoveryActions; -- -- -- -- PROCEDURE reportTranslateDFDel IS BEGIN deb(DEB_ENTER, 'reportTranslateDFDel'); IF (rddf%isopen) THEN CLOSE rddf; END IF; deb(DEB_OPEN, 'rddf'); OPEN rddf; deb(DEB_EXIT); END reportTranslateDFDel; -- -- FUNCTION reportGetDFDel( file# OUT number ,filetype OUT number ,checkpoint_change# OUT number ,checkpoint_time OUT date ,resetlogs_change# OUT number ,resetlogs_time OUT date ,incremental_change# OUT number ,fuzzy_change# OUT number ,recid OUT number ,stamp OUT number ,fname OUT varchar2 ,restorable OUT number) RETURN number IS rc number; mytype number; key number; completion_time date; BEGIN deb(DEB_ENTER, 'reportGetDFDel80'); <> rc := reportGetDFDel( file# ,mytype ,checkpoint_change# ,checkpoint_time ,resetlogs_change# ,resetlogs_time ,incremental_change# ,fuzzy_change# ,recid ,stamp ,fname ,restorable ,key ,completion_time); IF (rc = TRUE#) THEN IF (mytype = PROXY) THEN GOTO get_next; END IF; filetype := mytype; END IF; deb(DEB_EXIT, 'with: '||to_char(rc)); RETURN rc; END reportGetDFDel; -- -- -- -- PROCEDURE getConfig( conf# OUT number ,name IN OUT varchar2 ,value IN OUT varchar2 ,first IN boolean) IS eof boolean := FALSE; conf_exist number := 0; primary_db_unique_name varchar2(512); /* node.db_unique_name%TYPE */ BEGIN IF (first) THEN IF (findConfig_c%ISOPEN) THEN CLOSE findConfig_c; END IF; OPEN cntConfig_c; FETCH cntConfig_c INTO conf_exist; CLOSE cntConfig_c; IF conf_exist > 0 THEN IF user_db_unique_name is not null THEN deb(DEB_PRINT, 'getConfig: configurations exists for user site'); OPEN findConfig_c(name, value, user_db_unique_name); ELSE deb(DEB_PRINT, 'getConfig: configurations exists for this site'); OPEN findConfig_c(name, value, this_db_unique_name); END IF; ELSE OPEN getPrimarySite_c; FETCH getPrimarySite_c INTO primary_db_unique_name; IF getPrimarySite_c%NOTFOUND THEN deb(DEB_PRINT, 'getConfig: no/multiple primary/site conf'); OPEN findConfig_c(name, value, NULL); ELSE deb(DEB_PRINT, 'getConfig: using primary configurations'); OPEN findConfig_c(name, value, primary_db_unique_name); END IF; CLOSE getPrimarySite_c; END IF; END IF; FETCH findConfig_c INTO conf#, name, value; IF (findConfig_c%NOTFOUND) THEN eof := TRUE; CLOSE findConfig_c; END IF; IF (eof) THEN --- if end of fetch RAISE no_data_found; END IF; END getConfig; -- -- -- -- PROCEDURE bmrAddCorruptTable( dfnumber OUT number ,blknumber OUT number ,range OUT number ,first IN boolean) IS eof boolean := FALSE; BEGIN IF (first) THEN IF (translateDatabaseCorruption_c%ISOPEN) THEN CLOSE translateDatabaseCorruption_c; END IF; OPEN translateDatabaseCorruption_c(dfnumber => NULL); END IF; FETCH translateDatabaseCorruption_c INTO dfnumber, blknumber, range; IF (translateDatabaseCorruption_c%NOTFOUND) THEN eof := TRUE; CLOSE translateDatabaseCorruption_c; END IF; IF (eof) THEN --- if end of fetch RAISE no_data_found; END IF; END bmrAddCorruptTable; -- -- -- -- -- -- -- FUNCTION getPackageVersion RETURN varchar2 IS BEGIN deb(DEB_ENTER, 'getPackageVersion'); IF (versionCounter > versionMaxIndex) THEN versionCounter := 1; deb(DEB_EXIT, 'with: NULL'); RETURN NULL; END IF; versionCounter := versionCounter + 1; deb(DEB_EXIT, 'with: '||versionList(versionCounter - 1)); RETURN versionList(versionCounter - 1); END getPackageVersion; FUNCTION isStatusMatch(status IN VARCHAR2, mask IN NUMBER) RETURN NUMBER IS BEGIN -- -- -- -- IF (bitand(mask, BSavailable) != 0 AND status = 'A') OR (bitand(mask, BSunavailable) != 0 AND status = 'U') OR (bitand(mask, BSdeleted) != 0 AND status = 'D') OR (bitand(mask, BSexpired) != 0 AND status = 'X') THEN RETURN TRUE#; ELSE RETURN FALSE#; END IF; END isStatusMatch; -- FUNCTION isBackupTypeMatch(btype IN VARCHAR2, mask IN binary_integer) RETURN NUMBER IS BEGIN IF (bitand(mask, BSdatafile_full) !=0 AND btype = 'D') OR (bitand(mask, BSdatafile_incr) !=0 AND btype = 'I') OR (bitand(mask, BSarchivelog) !=0 AND btype = 'L') THEN RETURN TRUE#; ELSE RETURN FALSE#; END IF; END isBackupTypeMatch; -- PROCEDURE setRcvRecBackupAge(age IN number) IS BEGIN rcvRecBackupAge := age; deb(DEB_PRINT, 'rcvRecBackupAge= ' || rcvRecBackupAge); resetthisBackupAge; END setRcvRecBackupAge; -- PROCEDURE resetthisBackupAge IS BEGIN thisBackupAge := 0; deb(DEB_PRINT, 'thisBackupAge= ' || thisBackupAge); END resetthisBackupAge; -- PROCEDURE printLbRec( lbRec IN lbRec_t) IS BEGIN deb(DEB_ENTER, 'printLbRec'); deb(DEB_IN, 'fetch backup_type: '||lbRec.backup_type); deb(DEB_IN, ' file_type: '||lbRec.file_type); deb(DEB_IN, ' pkey: '||lbRec.pkey); deb(DEB_IN, ' recid: '||lbRec.recid); deb(DEB_IN, ' stamp: '||lbRec.stamp); deb(DEB_IN, ' is_rdf: '||lbRec.is_rdf); IF (lbRec.file_type = datafile_txt) THEN deb(DEB_IN, ' df_file#: '||lbRec.df_file#); deb(DEB_IN, ' df_ts#: '||lbRec.df_ts#); deb(DEB_IN, ' df_plugin_change#: '||lbRec.df_plugin_change#); deb(DEB_IN, ' df_foreidn_dbid: '||lbRec.df_foreign_dbid); deb(DEB_IN, ' df_creation_change#:'||lbRec.df_creation_change#); deb(DEB_IN, ' df_checkpoint_change#:'||lbRec.df_checkpoint_change#); deb(DEB_IN, ' df_incremental_change#:'|| nvl(to_char(lbRec.df_incremental_change#), 'NULL')); END IF; IF (lbRec.file_type = archivedlog_txt) THEN deb(DEB_IN, ' rl_thread#: '||lbRec.rl_thread#); deb(DEB_IN, ' rl_sequence#: '||lbRec.rl_sequence#); deb(DEB_IN, ' rl_next_change#:'||lbRec.rl_next_change#); END IF; IF (lbRec.backup_type = backupset_txt) THEN deb(DEB_IN, ' bs_key: '||lbRec.bs_key); deb(DEB_IN, ' bs_stamp: '||lbRec.bs_stamp); deb(DEB_IN, ' bs_count: '||lbRec.bs_count); deb(DEB_IN, ' bs_incr_type: '||lbRec.bs_incr_type); END IF; IF (lbRec.file_type = piece_txt) THEN deb(DEB_IN, ' bp_piece#: '||lbRec.bp_piece#); deb(DEB_IN, ' bp_copy#: '||lbRec.bp_copy#); deb(DEB_IN, ' status: '||lbRec.status); deb(DEB_IN, ' device_type: '||lbRec.device_type); deb(DEB_IN, ' tag: '||lbRec.tag); END IF; deb(DEB_EXIT, 'ok'); EXCEPTION WHEN OTHERS THEN deb(DEB_EXIT, 'with exception: '||substr(sqlerrm, 1, 512)); RETURN; END printLbRec; -- -- FUNCTION listBackupInMKS(lbDfRecTabUs IN lbDfRecTab_t ,lbRec IN lbRec_t ,maxDfNumber IN number ,forIncr IN boolean) RETURN BOOLEAN IS i number; min_scn number; min_rlgscn number; BEGIN -- -- -- i := lbRec.df_file#; <> LOOP IF (NOT lbDfRecTabUs.exists(i)) THEN deb(DEB_PRINT,'Dropped datafile: df_file#=' || lbRec.df_file#); IF (lbRec.df_ckp_mod_time < untilTime OR (untilTime IS NULL AND lbRec.df_checkpoint_change# <= untilSCN)) THEN deb(DEB_PRINT,'Outside untilTime/untilSCN'); RETURN FALSE; ELSE deb(DEB_PRINT,'Inside untilTime/untilSCN'); RETURN TRUE; END IF; END IF; IF (lbDfRecTabUs(i).dfRec.dfNumber = lbRec.df_file# AND (lbRec.df_file# = 0 OR lbDfRecTabUs(i).dfRec.dfCreationSCN = lbRec.df_creation_change#)) THEN IF (forIncr) THEN min_scn := lbDfRecTabUs(i).incrmin_scn; min_rlgscn := lbDfRecTabUs(i).incrmin_rlgscn; ELSE min_scn := lbDfRecTabUs(i).fullmin_scn; min_rlgscn := lbDfRecTabUs(i).fullmin_rlgscn; END IF; IF (min_scn < lbRec.df_checkpoint_change# AND (min_rlgscn IS NULL OR min_rlgscn = lbRec.df_resetlogs_change# OR min_scn <= lbRec.df_resetlogs_change#)) THEN RETURN TRUE; ELSE RETURN FALSE; END IF; END IF; i := i + maxDfNumber; END LOOP; RETURN FALSE; END listBackupInMKS; -- PROCEDURE listBackupProcessPiece(lbRec IN lbRec_t ,lbRecOut OUT NOCOPY lbRec_t ,lbState IN OUT NOCOPY lbState_t) IS BEGIN IF (debug) THEN -- protect for performance deb(DEB_ENTER, 'listBackupProcessPiece'); END IF; -- -- -- -- -- -- IF (anyDevice = TRUE# OR isDeviceTypeAllocated(lbRec.device_type) = TRUE#) THEN IF (recoveryDestFile AND lbRec.is_rdf = 'NO') OR (orsAnyFile AND lbRec.bp_ba_access IN ('U','D')) OR ((orsLocalFile OR orsLibKey IS NOT NULL) AND (lbRec.bp_ba_access IN ('U','D') OR nvl(lbRec.bp_lib_key, 0) != nvl(orsLibKey, 0))) THEN IF (debug) THEN -- protect for performance deb(DEB_IN, 'file_type: ' || lbRec.file_type || ' not a recovery area or ors file pkey: ' || lbRec.pkey); END IF; ELSE -- IF (lbRec.bp_copy# > lbState.lbCopyCount) THEN lbState.lbCopyCount := lbRec.bp_copy#; END IF; -- -- BEGIN lbState.lbPieceCountTab(lbRec.bp_copy#-1) := lbState.lbPieceCountTab(lbRec.bp_copy#-1) + 1; EXCEPTION WHEN no_data_found THEN -- lbPieceCountTab(i) uninitialized lbState.lbPieceCountTab(lbRec.bp_copy#-1) := 1; -- -- lbState.lbRecCmn.bs_copies := lbState.lbRecCmn.bs_copies + 1; END; -- -- IF (lbState.lbRecCmn.bs_status is NULL) THEN lbState.lbRecCmn.bs_status := lbRec.status; ELSIF (lbRec.status <> lbState.lbRecCmn.bs_status) THEN -- -- lbState.lbRecCmn.bs_status := other_txt; END IF; -- -- -- -- lbState.lbRecCmn.bs_bytes := lbState.lbRecCmn.bs_bytes + lbRec.bytes; -- -- IF (lbState.lbRecCmn.bs_device_type is NULL) THEN lbState.lbRecCmn.bs_device_type := lbRec.device_type; ELSIF (instr(lbState.lbRecCmn.bs_device_type, lbRec.device_type) = 0) THEN BEGIN lbState.lbRecCmn.bs_device_type := lbState.lbRecCmn.bs_device_type||','||lbRec.device_type; EXCEPTION WHEN value_error THEN deb(DEB_IN, 'dev buffer overflow length=' || lengthb(lbState.lbRecCmn.bs_device_type)); END; END IF; -- -- IF (lbState.lbRecCmn.bs_compressed is NULL) THEN lbState.lbRecCmn.bs_compressed := lbRec.compressed; ELSIF (lbState.lbRecCmn.bs_compressed != lbRec.compressed) THEN lbState.lbRecCmn.bs_compressed := '###'; END IF; -- -- IF (lbRec.tag IS NOT NULL) THEN IF (lbState.lbRecCmn.bs_tag is NULL) THEN lbState.lbRecCmn.bs_tag := lbRec.tag; ELSIF (instr(lbState.lbRecCmn.bs_tag, lbRec.tag) = 0) THEN BEGIN lbState.lbRecCmn.bs_tag := lbState.lbRecCmn.bs_tag||','||lbRec.tag; EXCEPTION WHEN value_error THEN deb(DEB_IN, 'tag buffer overflow length=' || lengthb(lbState.lbRecCmn.bs_tag)); eND; END IF; END IF; END IF; ELSE IF (debug) THEN deb(DEB_IN, 'device type not allocated'); END IF; END IF; IF (debug) THEN -- protect for performance deb(DEB_EXIT, 'OK'); END IF; END listBackupProcessPiece; PROCEDURE setNeedObsoleteData(NeedObsoleteData IN boolean DEFAULT TRUE) IS BEGIN IF NeedObsoleteData THEN lb_NeedObsoleteData := TRUE#; ELSE lb_NeedObsoleteData := FALSE#; END IF; END; -- FUNCTION listBackup(lbRecOut OUT NOCOPY lbRec_t ,firstCall IN boolean ,only_obsolete IN boolean ,redundancy IN number ,piped_call IN boolean -- not called by RMAN client ,lbCursor IN OUT NOCOPY lbCursor_t ,lbState IN OUT NOCOPY lbState_t ,extRlKeepSCN IN number DEFAULT NULL) RETURN boolean IS lbRec lbRec_t; null_lbRec lbRec_t := NULL; i binary_integer; j binary_integer; tmp binary_integer; rc binary_integer; found boolean; lbCursor_notfound boolean := FALSE; numBackups number; oldest_flashback_scn number; fullBackups number; actionMask number; containerMask number; -- full_df_backup boolean; incr_df_backup boolean; arc_log_backup boolean; keep varchar2(3); keep_until date; -- save_dbinc_key number; save_reset_scn number; dfRec dfRec_t; rcvRecNxt rcvRec_t; rcvRec rcvRec_t; rcvRecStack_count binary_integer; extendMask binary_integer; BEGIN -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- IF (debug) THEN -- protect for performance deb(DEB_ENTER, 'listBackup'); END IF; -- lbRecOut := NULL; IF (firstCall) THEN IF (debug) THEN -- protect for performance deb(DEB_IN, 'FIRST'); END IF; -- validateState(NULL); -- setAllIncarnations(TRUE); -- -- -- -- setCanApplyAnyRedo(TRUE); setCanHandleTransportableTbs(TRUE); -- cacheBsRecTable.hint := redundantHint; -- lbState.lbRecOutTab.delete; lbState.lbRecOutTab_count := 0; -- lbState.lbRecTmpTab.delete; -- -- lbState.lbDfRecTabUs.delete; -- lbState.lbDfRecTab.delete; -- -- -- lbState.lbPieceCountTab.delete; lbState.lbCopyCount := 0; -- lbState.lbMkTab.delete; -- lbState.lbMkITab.delete; -- -- SELECT SYSDATE INTO lbState.lbNowTime from dual; -- -- -- -- -- -- -- dfRec.dfNumber := 0; dfRec.dfCreationSCN := 0; dfRec.inBackup := 1; dfRec.noBackupPdb := 0; dfRec.foreignDbid := 0; dfRec.pluggedRonly := 0; dfRec.pluginSCN := 0; lbState.lbDfRecTabUs(0).dfRec := dfRec; lbState.lbDfRecTabUs(0).fullmin_scn := MAXSCNVAL; lbState.lbDfRecTabUs(0).fullmin_rlgscn := MAXSCNVAL; lbState.lbDfRecTabUs(0).incrmin_scn := MAXSCNVAL; lbState.lbDfRecTabUs(0).incrmin_rlgscn := MAXSCNVAL; lbState.lbDfRecTabUs(0).logmin_scn := MAXSCNVAL; lbState.lbDfRecTabUs(0).logmin_rlgscn := MAXSCNVAL; IF lb_NeedObsoleteData = TRUE# THEN lbState.lbNeedObsoleteData := TRUE; ELSE lbState.lbNeedObsoleteData := FALSE; deb(DEB_PRINT,'listBackup:caller not interested in Obsolete Data'); END IF; -- save_dbinc_key := this_dbinc_key; save_reset_scn := this_reset_scn; -- lbState.lbMaxDfNumber := getMaxDfNumber; <> LOOP translateDatabase(TRUE#); <> LOOP BEGIN getDatafile(dfRec); EXCEPTION WHEN no_data_found THEN EXIT loop_genDfRecTab; END; -- -- -- -- -- j := dfRec.dfNumber; <> LOOP BEGIN -- -- -- -- -- IF (lbState.lbDfRecTabUs(j).dfRec.dfNumber = 0) THEN RAISE no_data_found; END IF; IF (dfRec.dfNumber = lbState.lbDfRecTabUs(j).dfRec.dfNumber AND dfRec.dfCreationSCN = lbState.lbDfRecTabUs(j).dfRec.dfCreationSCN) THEN -- EXIT loop_scanDfRecTab; ELSE -- -- j := j + lbState.lbMaxDfNumber; END IF; EXCEPTION WHEN no_data_found THEN lbState.lbDfRecTabUs(j).dfRec := dfRec; lbState.lbDfRecTabUs(j).fullmin_scn := MAXSCNVAL; lbState.lbDfRecTabUs(j).fullmin_rlgscn := MAXSCNVAL; lbState.lbDfRecTabUs(j).logmin_scn := MAXSCNVAL; lbState.lbDfRecTabUs(j).logmin_rlgscn := MAXSCNVAL; lbState.lbDfRecTabUs(j).incrmin_scn := MAXSCNVAL; lbState.lbDfRecTabUs(j).incrmin_rlgscn := MAXSCNVAL; END; END LOOP; END LOOP; -- -- -- -- IF (untilSCN IS NOT NULL AND untilSCN < this_reset_scn) THEN rc := getParentIncarnation(this_dbinc_key, this_reset_scn); EXIT loop_travelinc WHEN rc = FALSE#; ELSE EXIT loop_travelinc; END IF; END LOOP; -- this_dbinc_key := save_dbinc_key; this_reset_scn := save_reset_scn; -- getFlashbackInfo(lbState.lbFbUntilTime, lbState.lbMinGrsp); IF (debug) THEN deb(DEB_IN, 'lbFbUntilTime= ' || to_char(lbState.lbFbUntilTime) || ' lbMinGrsp=' || to_char(lbState.lbMinGrsp)); END IF; lbState.lbRlKeepRlgSCN := MAXSCNVAL; lbState.lbRlKeepSCN := MAXSCNVAL; IF (extRlKeepSCN IS NOT NULL) THEN lbState.lbRlKeepSCN := extRlKeepSCN; lbState.lbRlKeepRlgSCN := getPointInTimeInc(extRlKeepSCN); IF (debug) THEN deb(DEB_IN, 'Extending lbRlKeepSCN for external keepscn to '|| to_char(lbState.lbRlKeepSCN)); deb(DEB_IN, 'Extending lbRlKeepRlgSCN for external keepscn to '|| to_char(lbState.lbRlKeepRlgSCN)); END IF; END IF; IF (this_baseline_cap >= 0) THEN this_baseline_cap_scn := untilSCN; deb(DEB_IN, 'baseline_cap_scn = ' || this_baseline_cap_scn); -- -- -- resetUntil; -- -- setDeviceType('SBT_TAPE'); containerMask := backupSet_con_t + imageCopy_con_t + offlineRangeRec_con_t; ELSE containerMask := backupSet_con_t + proxyCopy_con_t + imageCopy_con_t + offlineRangeRec_con_t; END IF; -- -- -- actionMask := full_act_t + offlineRange_act_t + implicitRange_act_t + cleanRange_act_t; IF (untilTime IS NOT NULL OR untilSCN IS NOT NULL) THEN actionMask := actionMask + incremental_act_t; END IF; -- -- -- setComputeRecoveryActionMasks(containerMask => containerMask, actionMask => actionMask, allRecords => TRUE#, availableMask => BSavailable, fullBackups => redundancy); -- -- -- setCraGetAllCfBackups(TRUE); -- -- -- -- IF NOT (lbState.lbNeedObsoleteData OR this_baseline_cap >= 0) THEN goto ObsoleteDataSkip; END IF; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- i := to_number(null); LOOP IF (i is null) THEN i := lbState.lbDfRecTabUs.first; ELSE i := lbState.lbDfRecTabUs.next(i); END IF; EXIT WHEN i IS NULL; dfRec := lbState.lbDfRecTabUs(i).dfRec; IF (this_baseline_cap >= 0) AND NOT setLocalOrsSiteKey(db_id => NULL) THEN deb(DEB_IN, 'local ORS site_key not set, no backups yet recieved'); ELSE -- -- -- -- -- -- -- rc := computeRecoveryActions( fno => dfRec.dfNumber, crescn => dfRec.dfCreationSCN, allowfuzzy => FALSE, partial_rcv => FALSE, allCopies => FALSE, cleanscn => dfRec.stopSCN, clean2scn => highscnval, clean2time => lbState.lbNowTime, onlscn => dfRec.dfOnlineSCN, offlscn => dfRec.dfOfflineSCN, onltime => dfRec.dfOnlineTime, rmanCmd => obsoleteCmd_t, foreignDbid => dfRec.foreignDbid, pluggedRonly => dfRec.pluggedRonly, pluginSCN => dfRec.pluginSCN, pluginRlgSCN => dfRec.pluginRlgSCN, pluginRlgTime => dfRec.pluginRlgTime, creation_thread => dfRec.creation_thread, creation_size => dfRec.creation_size, pdbId => dfRec.pdbId, pdbForeignDbid => dfRec.pdbForeignDbid); END IF; IF (this_baseline_cap >= 0) THEN deb(DEB_IN, 'Found a new datafile ' || dfRec.dfNumber); lbRec.df_file# := dfRec.dfNumber; lbRec.df_ts# := dfRec.tsNumber; lbRec.df_plugin_change# := dfRec.pluginSCN; lbRec.df_foreign_dbid := dfRec.foreignDbid; lbRec.df_tablespace := dfRec.tsName; lbRec.df_creation_change# := dfRec.dfCreationSCN; lbRec.file_type := NULL; lbRec.backup_type := NULL; lbRec.bs_key := NULL; lbRec.df_checkpoint_change# := NULL; END IF; numBackups := 0; fullBackups := getRecFullCount; LOOP EXIT WHEN (getRecStackCount = 0 OR (this_baseline_cap >= 0 AND lbRec.bs_key IS NOT NULL)); -- -- IF (this_baseline_cap >= 0) THEN IF getRecStackCount = 1 THEN rcvRecPop(rcvRec); ELSIF getRecStackCount > 1 THEN rcvRecGet(1, rcvRec); rcvRecGet(2, rcvRecNxt); END IF; deb(DEB_IN, 'Newest RcvRec record'); printRcvRec(rcvRec, TRUE); deb(DEB_IN, 'Next to New RcvRec record'); printRcvRec(rcvRecNxt, TRUE); ELSE rcvRecPop(rcvRec); END IF; IF (this_baseline_cap >= 0) THEN IF (rcvRec.type_act = full_act_t AND (rcvRec.toSCN_act > this_baseline_cap_scn OR this_baseline_cap_scn IS NULL)) THEN lbRec.bs_key := rcvRec.bsKey_con; lbRec.df_checkpoint_change# := rcvRec.toSCN_act; deb(DEB_IN, 'Found-1 newest backup within baseline_cap for ' || lbRec.df_file# || ' as ' || lbRec.bs_key); ELSE IF (rcvRecNxt.type_act = full_act_t AND ((rcvRec.type_act = offlineRange_act_t OR rcvRec.type_act = cleanRange_act_t OR rcvRec.type_act = implicitRange_act_t) AND (rcvRec.toSCN_act >= this_baseline_cap_scn OR rcvRec.toSCN_act = MAXSCNVAL))) THEN lbRec.bs_key := rcvRecNxt.bsKey_con; lbRec.df_checkpoint_change# := rcvRec.toSCN_act; deb(DEB_IN, 'Found-2 newest backup with baseline_cap for ' || lbRec.df_file# || ' as ' || lbRec.bs_key); END IF; END IF; EXIT; END IF; IF (rcvRec.type_act = full_act_t) THEN IF (rcvRec.keep_options = KEEP_NO) -- nokeep backup THEN addBackupToMKL(lbState.lbMkTab, rcvRec); extendKeepSCN(lbState.lbDfRecTabUs(i), rcvRec.toSCN_act, rcvRec.rlgSCN_act, extendAllSCN, FALSE, 'extendFullBackup (NoKeep)'); numBackups := numBackups+1; -- bump the number of backups ELSIF (NVL(rcvRec.keep_until,MAXDATEVAL) > lbState.lbNowTime) -- THEN -- -- IF (rcvRec.keep_options = KEEP_LOGS) -- keep logs? THEN extendKeepSCN(lbState.lbDfRecTabUs(i), rcvRec.toSCN_act, rcvRec.rlgSCN_act, extendLogSCN + extendIncrSCN, FALSE, 'extendFullBackup (Keep)'); END IF; END IF; ELSIF (rcvRec.type_act = offlineRange_act_t OR rcvRec.type_act = cleanRange_act_t OR rcvRec.type_act = implicitRange_act_t) THEN extendMask := 0; IF (lbState.lbDfRecTabUs(i).fullmin_scn = rcvRec.fromSCN_act) THEN extendMask := extendMask + extendFullSCN; END IF; IF (lbState.lbDfRecTabUs(i).incrmin_scn = rcvRec.fromSCN_act) THEN extendMask := extendMask + extendIncrSCN; END IF; IF (lbState.lbDfRecTabUs(i).logmin_scn = rcvRec.fromSCN_act) THEN extendMask := extendMask + extendLogSCN; END IF; extendKeepSCN(lbState.lbDfRecTabUs(i), rcvRec.toSCN_act, rcvRec.rlgSCN_act, extendMask, TRUE, 'extendMiscRange'); ELSIF (rcvRec.type_act = incremental_act_t) THEN IF (lbState.lbDfRecTabUs(i).incrmin_scn >= rcvRec.fromSCN_act AND lbState.lbDfRecTabUs(i).incrmin_scn < rcvRec.toSCN_act) THEN addBackupToMKL(lbState.lbMkITab, rcvRec); extendKeepSCN(lbState.lbDfRecTabUs(i), rcvRec.toSCN_act, rcvRec.rlgSCN_act, extendIncrSCN, TRUE, 'extendIncrBackup'); END IF; END IF; END LOOP; -- -- -- -- -- -- -- IF ((lbState.lbDfRecTabUs(i).fullmin_scn = MAXSCNVAL OR -- no bkp numBackups < redundancy) AND -- not enough backups dfRec.inBackup = 1 AND -- file not excluded dfRec.noBackupPdb = 0 AND -- not a excluded PDB dfRec.pluggedRonly = 0) -- not a plugged readonly THEN extendKeepSCN(lbState.lbDfRecTabUs(i), dfRec.dfCreationSCN, getPointInTimeInc(dfRec.dfCreationSCN), extendAllSCN, TRUE, 'extendNoBackup'); END IF; -- -- IF (lbState.lbRlKeepSCN > lbState.lbDfRecTabUs(i).logmin_scn) THEN lbState.lbRlKeepSCN := lbState.lbDfRecTabUs(i).logmin_scn; lbState.lbRlKeepRlgSCN := lbState.lbDfRecTabUs(i).logmin_rlgscn; IF (debug) THEN -- protect for performance deb(DEB_IN, 'Extending lbRlKeepSCN to '|| to_char(lbState.lbRlKeepSCN)); deb(DEB_IN, 'Extending lbRlKeepRlgSCN to '|| nvl(to_char(lbState.lbRlKeepRlgSCN), 'null')); END IF; END IF; IF (this_baseline_cap >= 0) THEN lbState.lbRecOutTab(lbState.lbRecOutTab_count) := lbRec; lbState.lbRecOutTab_count := lbState.lbRecOutTab_count + 1; END IF; END LOOP; -- LOOP BEGIN -- IF (getSpfileBackup(rcvRec => rcvRec, redundancy => redundancy, rmanCmd => obsoleteCmd_t) = SUCCESS) THEN addBackupToMKL(lbState.lbMkTab, rcvRec); ELSE EXIT; END IF; EXCEPTION WHEN no_data_found THEN EXIT; END; END LOOP; <> -- -- translateAllDatafile; LOOP BEGIN getDatafile(dfRec); EXCEPTION WHEN no_data_found THEN EXIT; END; lbState.lbDfRecTab(lbState.lbDfRecTab.count) := dfRec; END LOOP; -- -- IF (piped_call) THEN openLbCursor(lbCursor); ELSE IF (listBackup_c%ISOPEN) THEN CLOSE listBackup_c; END IF; OPEN listBackup_c; END IF; -- -- -- -- -- -- lbState.lbObsoleteRetention := FALSE; lbState.lbKeepForDbpitr := FALSE; -- -- lbState.lbObsoleteKeep := FALSE; -- lbState.lbRecTmpTab.delete; lbState.lbCopyCount := 0; lbState.lbPieceCountTab.delete; lbState.lbRecCmn := null_lbRec; IF (debug) THEN deb(DEB_IN, 'Must Keep List:'); i := lbState.lbMkTab.first; LOOP EXIT WHEN i IS NULL; FOR j in 0..lbState.lbMkTab(i).count-1 LOOP IF (lbState.lbMkTab(i)(j).type_con = backupSet_con_t) THEN deb(DEB_PRINT, 'Backup Set bskey=' || lbState.lbMkTab(i)(j).bsKey_con || ' set_stamp=' || lbState.lbMkTab(i)(j).setStamp_con || ' set_count=' || lbState.lbMkTab(i)(j).setCount_con); ELSIF (lbState.lbMkTab(i)(j).type_con = imageCopy_con_t) THEN deb(DEB_PRINT, 'Datafile Copy key=' || lbState.lbMkTab(i)(j).key_con || ' recid=' || lbState.lbMkTab(i)(j).recid_con || ' stamp=' || lbState.lbMkTab(i)(j).stamp_con); ELSIF (lbState.lbMkTab(i)(j).type_con = proxyCopy_con_t) THEN deb(DEB_PRINT, 'Proxy Backup key=' || lbState.lbMkTab(i)(j).key_con || ' recid=' || lbState.lbMkTab(i)(j).recid_con || ' stamp=' || lbState.lbMkTab(i)(j).stamp_con); ELSE deb(DEB_PRINT, 'Unknown Type=' || lbState.lbMkTab(i)(j).type_con); END IF; END LOOP; i := lbState.lbMkTab.next(i); END LOOP; END IF; -- -- cacheBsRecTable.hint := noHint; END IF; -- first call IF (this_baseline_cap >= 0) THEN goto listBackup_returnRec; END IF; <> WHILE (lbState.lbRecOutTab_count = 0) -- while there is nothing to return LOOP IF (piped_call) THEN FETCH lbCursor INTO lbRec; IF (lbCursor%NOTFOUND) THEN lbCursor_notfound := TRUE; END IF; ELSE FETCH listBackup_c INTO lbRec; IF (listBackup_c%NOTFOUND) THEN lbCursor_notfound := TRUE; END IF; END IF; IF (lbCursor_notfound OR (lbRec.file_type = backupset_txt) OR (lbRec.backup_type IN (copy_txt, proxycopy_txt)) OR (lbRec.backup_type = backupset_txt AND lbRec.file_type <> backupset_txt AND (lbState.lbRecCmn.recid IS NULL OR lbState.lbRecCmn.bs_stamp <> lbRec.bs_stamp OR lbState.lbRecCmn.bs_count <> lbRec.bs_count))) THEN -- -- -- -- -- -- -- -- IF (lbState.lbRecTmpTab.count > 0 AND lbState.lbCopyCount > 0 AND (NOT only_obsolete OR lbState.lbObsoleteRetention OR lbState.lbObsoleteKeep)) THEN -- -- -- IF lbState.lbNeedObsoleteData THEN IF (lbState.lbObsoleteRetention OR lbState.lbObsoleteKeep) THEN IF (debug) THEN -- protect for performance deb(DEB_IN, 'E: Obsolete!!!'); END IF; lbState.lbRecCmn.obsolete := 'YES'; lbState.lbRecCmn.keep_for_dbpitr := 'NO'; ELSE IF (debug) THEN -- protect for performance deb(DEB_IN, 'E: Not obsolete!!!'); END IF; lbState.lbRecCmn.obsolete := 'NO'; IF (lbState.lbKeepForDbpitr) THEN lbState.lbRecCmn.keep_for_dbpitr := 'YES'; ELSE lbState.lbRecCmn.keep_for_dbpitr := 'NO'; END IF; END IF; END IF; -- -- IF (lbState.lbRecCmn.status <> other_txt) THEN <> FOR i IN 0..lbState.lbCopyCount-1 LOOP BEGIN IF (lbState.lbRecCmn.bs_pieces != lbState.lbPieceCountTab(i)) THEN lbState.lbRecCmn.status := other_txt; EXIT loop_copy; END IF; EXCEPTION WHEN no_data_found THEN -- lbPieceCountTab(i) uninitialized EXIT loop_copy; END; END LOOP; END IF; -- IF (debug) THEN -- protect for performance deb(DEB_IN, 'pipelineing backup set '||lbState.lbRecCmn.bs_key); END IF; FOR i IN 0..lbState.lbRecTmpTab.count-1 LOOP -- IF (recoveryDestFile AND lbState.lbRecTmpTab(i).is_rdf = 'NO') OR (orsAnyFile AND lbState.lbRecTmpTab(i).bp_ba_access IN ('U','D')) OR (orsLocalFile AND lbState.lbRecTmpTab(i).bp_ba_access IN ('U','D','T','R')) OR (orsLibKey IS NOT NULL AND nvl(lbState.lbRecTmpTab(i).bp_lib_key, 0) != orsLibKey) THEN -- IF (debug) THEN -- protect for performance deb(DEB_IN, 'not a recovery area or ors file type'); END IF; ELSIF (anyDevice = FALSE# AND -- not all device is allocated lbState.lbRecTmpTab(i).file_type = piece_txt AND isDevicetypeAllocated(lbState.lbRecTmpTab(i).device_type) = FALSE#) THEN -- -- -- IF (debug) THEN -- protect for performance deb(DEB_IN, 'device type not allocated'); END IF; ELSE -- -- -- tmp := lbState.lbRecOutTab_count; lbState.lbRecOutTab(tmp) := lbState.lbRecTmpTab(i); lbState.lbRecOutTab(tmp).obsolete := lbState.lbRecCmn.obsolete; lbState.lbRecOutTab(tmp).keep_for_dbpitr := lbState.lbRecCmn.keep_for_dbpitr; lbState.lbRecOutTab(tmp).bs_status := lbState.lbRecCmn.bs_status; lbState.lbRecOutTab(tmp).bs_copies := lbState.lbRecCmn.bs_copies; lbState.lbRecOutTab(tmp).bs_bytes := lbState.lbRecCmn.bs_bytes / lbState.lbRecCmn.bs_copies; lbState.lbRecOutTab(tmp).bs_compressed := lbState.lbRecCmn.bs_compressed; lbState.lbRecOutTab(tmp).bs_tag := lbState.lbRecCmn.bs_tag; lbState.lbRecOutTab(tmp).bs_device_type := lbState.lbRecCmn.bs_device_type; IF (lbState.lbRecCmn.recid IS NOT NULL) THEN -- -- lbState.lbRecOutTab(tmp).backup_type := lbState.lbRecCmn.backup_type; lbState.lbRecOutTab(tmp).keep := lbState.lbRecCmn.keep; lbState.lbRecOutTab(tmp).keep_options:= lbState.lbRecCmn.keep_options; lbState.lbRecOutTab(tmp).keep_until := lbState.lbRecCmn.keep_until; lbState.lbRecOutTab(tmp).bs_key := lbState.lbRecCmn.bs_key; lbState.lbRecOutTab(tmp).bs_count := lbState.lbRecCmn.bs_count; lbState.lbRecOutTab(tmp).bs_stamp := lbState.lbRecCmn.bs_stamp; lbState.lbRecOutTab(tmp).bs_type := lbState.lbRecCmn.bs_type; lbState.lbRecOutTab(tmp).bs_incr_type := lbState.lbRecCmn.bs_incr_type; lbState.lbRecOutTab(tmp).bs_pieces := lbState.lbRecCmn.bs_pieces; lbState.lbRecOutTab(tmp).bs_completion_time := lbState.lbRecCmn.bs_completion_time; END IF; lbState.lbRecOutTab_count := tmp + 1; END IF; END LOOP; END IF; -- IF (lbCursor_notfound) THEN exit main_loop; END IF; -- -- -- -- -- IF (lbRec.file_type <> backupset_txt AND lbRec.backup_type = backupset_txt) THEN IF (debug) THEN deb(DEB_IN, 'setting lbObsoleteRetention to FALSE'); END IF; lbState.lbObsoleteRetention := FALSE; ELSE IF (debug) THEN deb(DEB_IN, 'setting lbObsoleteRetention to TRUE'); END IF; lbState.lbObsoleteRetention := TRUE; END IF; -- -- lbState.lbObsoleteKeep := FALSE; lbState.lbKeepForDbpitr := FALSE; -- lbState.lbRecTmpTab.delete; lbState.lbCopyCount := 0; lbState.lbPieceCountTab.delete; lbState.lbRecCmn := null_lbRec; END IF; IF (debug) THEN -- protect for performance printLbRec(lbRec); -- -- IF (lbRec.backup_type = backupset_txt AND lbRec.file_type <> backupset_txt) THEN IF ((lbState.lbRecCmn.bs_stamp = lbRec.bs_stamp AND lbState.lbRecCmn.bs_count = lbRec.bs_count) OR lbState.lbRecCmn.bs_key = lbRec.bs_key) THEN deb(DEB_IN, 'bs->bp->bdf/bsf/brl same bs'); ELSE deb(DEB_IN, 'bs->bp->bdf/bsf/brl **no** bs (or) **not** same bs'); END IF; END IF; END IF; -- -- -- -- If lbState.lbNeedObsoleteData THEN lbRec.obsolete := 'YES'; -- assume that backup is obsolete lbRec.keep_for_dbpitr := 'NO'; END IF; IF (lbState.lbObsoleteRetention AND NOT lbState.lbObsoleteKeep AND lbState.lbNeedObsoleteData) THEN -- full_df_backup := FALSE; incr_df_backup := FALSE; arc_log_backup := FALSE; IF (lbRec.backup_type = backupset_txt) THEN IF (lbRec.file_type = archivedlog_txt) THEN arc_log_backup := TRUE; ELSIF (lbRec.file_type IN (spfile_txt, controlfile_txt)) THEN full_df_backup := TRUE; ELSIF (lbRec.file_type = datafile_txt) THEN IF (lbRec.df_incremental_change# = lbRec.df_creation_change# OR lbRec.bs_incr_type = full_txt) THEN full_df_backup := TRUE; ELSIF (lbRec.bs_incr_type <> full_txt) THEN incr_df_backup := TRUE; END IF; END IF; ELSIF (lbRec.backup_type IN (copy_txt, proxycopy_txt) AND lbRec.file_type IN (datafile_txt, controlfile_txt)) THEN full_df_backup := TRUE; END IF; -- keep := NVL(lbRec.keep, 'NO'); keep_until := NVL(lbRec.keep_until, MAXDATEVAL); IF ((full_df_backup OR arc_log_backup OR incr_df_backup) AND lbRec.backup_type = backupset_txt) THEN keep := NVL(lbState.lbRecCmn.keep, 'NO'); keep_until := NVL(lbState.lbRecCmn.keep_until, MAXDATEVAL); END IF; -- IF (keep = 'YES') THEN IF (debug) THEN -- protect for performance deb(DEB_IN, 'Keep backup until ' || keep_until || ' - Checking ...'); END IF; IF (keep_until < lbState.lbNowtime) THEN IF (debug) THEN -- protect for performance deb(DEB_IN, 'expired -> obsolete by keep'); END IF; lbState.lbObsoleteKeep := TRUE; ELSE IF (debug) THEN -- protect for performance deb(DEB_IN, 'not expired -> no obsolete'); END IF; lbState.lbObsoleteRetention := FALSE; END IF; END IF; -- IF (full_df_backup) THEN IF (keep != 'YES') THEN -- nokeep backup IF (debug) THEN -- protect for performance deb(DEB_IN, 'Full backup - Checking ...'); END IF; IF ((lbRec.file_type = spfile_txt AND lbRec.df_ckp_mod_time < -- it is SPFILE outside RW NVL(untilTime, MAXDATEVAL)) OR (lbRec.file_type <> spfile_txt AND -- other file outside RW ((untilTime IS NULL AND untilSCN IS NULL) OR lbRec.df_ckp_mod_time < untilTime OR (untilTime IS NULL AND lbRec.df_checkpoint_change# <= untilSCN)))) THEN IF (debug) THEN -- protect for performance deb(DEB_IN, 'nokeep backup outside RW'); END IF; IF (listBackupInMKL(lbState.lbMkTab, lbRec)) THEN IF (debug) THEN -- protect for performance deb(DEB_IN, 'inside MKL -> no obsolete'); deb(DEB_IN, 'keep_for_dbpitr = YES'); END IF; lbState.lbObsoleteRetention := FALSE; lbState.lbKeepForDbpitr := TRUE; ELSIF (listBackupInMKS(lbState.lbDfRecTabUs, lbRec, lbState.lbMaxDfNumber, FALSE)) THEN -- -- -- -- IF (debug) THEN -- protect for performance deb(DEB_IN, 'inside MKS -> no obsolete'); END IF; lbState.lbObsoleteRetention := FALSE; lbState.lbKeepForDbpitr := FALSE; END IF; ELSE -- inside Recovery Win, not obsolete IF (debug) THEN -- protect for performance deb(DEB_IN, 'nokeep backup: inside RW -> no obsolete'); END IF; lbState.lbObsoleteRetention := FALSE; END IF; END IF; ELSIF (incr_df_backup) THEN IF (debug) THEN -- protect for performance deb(DEB_IN, 'Incremental backup - Checking ...'); END IF; IF (listBackupInMKL(lbState.lbMkITab, lbRec)) THEN IF (debug) THEN -- protect for performance deb(DEB_IN, 'inside MKL -> no obsolete'); deb(DEB_IN, 'keep_for_dbpitr = YES'); END IF; lbState.lbObsoleteRetention := FALSE; lbState.lbKeepForDbpitr := TRUE; ELSIF (listBackupInMKS(lbState.lbDfRecTabUs, lbRec, lbState.lbMaxDfNumber, TRUE)) THEN IF (debug) THEN -- protect for performance deb(DEB_IN, 'inside MKS -> no obsolete'); END IF; lbState.lbObsoleteRetention := FALSE; -- need this incremental lbState.lbKeepForDbpitr := FALSE; END IF; ELSIF (lbRec.file_type = archivedlog_txt) THEN --- redo log -- -- -- -- IF ((lbRec.rl_next_change# >= lbState.lbMinGrsp AND lbRec.backup_type != copy_txt) OR -- (a) lbRec.rl_next_time >= lbState.lbFbUntilTime OR -- (b) (lbRec.rl_next_change# >= lbState.lbRlKeepSCN AND -- (c) (lbState.lbRlKeepRlgSCN IS NULL OR lbRec.rl_resetlogs_change# = lbState.lbRlKeepRlgSCN OR lbRec.rl_resetlogs_change# >= lbState.lbRlKeepSCN))) THEN IF (debug) THEN -- protect for performance IF (lbRec.rl_next_time >= lbState.lbFbUntilTime) THEN deb(DEB_IN, 'Redolog after lbFbUntilTime -> no obsolete'); ELSIF (lbRec.rl_next_change# >= lbState.lbMinGrsp AND lbRec.backup_type != copy_txt) THEN deb(DEB_IN, 'Redolog after lbMinGrsp -> no obsolete'); ELSE deb(DEB_IN, 'Redolog after lbRlkeepSCN -> no obsolete'); END IF; END IF; lbState.lbObsoleteRetention := FALSE; -- this redo must be kept END IF; END IF; END IF; IF (NOT lbState.lbKeepForDbpitr AND lbRec.file_type = archivedlog_txt) THEN IF (lbRec.rl_next_change# >= lbState.lbRlKeepSCN AND (lbRec.rl_first_change# <= untilSCN OR lbRec.rl_first_time <= untilTime) AND (lbState.lbRlKeepRlgSCN IS NULL OR lbRec.rl_resetlogs_change# = lbState.lbRlKeepRlgSCN OR lbRec.rl_resetlogs_change# >= lbState.lbRlKeepSCN)) THEN IF (debug) THEN deb(DEB_IN, 'keep_for_dbpitr = YES'); END IF; lbState.lbKeepForDbpitr := TRUE; END IF; END IF; -- -- IF (NOT lbState.lbObsoleteRetention AND NOT lbState.lbObsoleteKeep AND lbState.lbNeedObsoleteData) THEN IF (debug) THEN deb(DEB_IN, 'Not obsolete'); END IF; lbRec.obsolete := 'NO'; lbState.lbRecCmn.obsolete := 'NO'; IF (lbState.lbKeepForDbpitr) THEN lbState.lbRecCmn.keep_for_dbpitr := 'YES'; lbRec.keep_for_dbpitr := 'YES'; ELSE lbState.lbRecCmn.keep_for_dbpitr := 'NO'; lbRec.keep_for_dbpitr := 'NO'; END IF; IF (only_obsolete) THEN GOTO listBackup_end; END IF; END IF; -- -- -- IF (lbRec.backup_type IN (backupset_txt, copy_txt) AND lbRec.file_type = datafile_txt) THEN found := FALSE; -- -- <> FOR i in lbRec.df_file#-1..lbState.lbDfRecTab.count-1 LOOP IF (lbState.lbDfRecTab(i).dfNumber = lbRec.df_file# AND lbState.lbDfRecTab(i).dfCreationSCN = lbRec.df_creation_change#) THEN IF (lbRec.backup_type = backupset_txt) THEN lbRec.fname := lbState.lbDfRecTab(i).fileName; END IF; lbRec.df_tablespace := lbState.lbDfRecTab(i).tsName; found := TRUE; EXIT loop_lbDfRecTab; ELSIF (lbState.lbDfRecTab(i).dfNumber > lbRec.df_file#) THEN EXIT loop_lbDfRecTab; END IF; END LOOP; IF (NOT found) THEN -- <> FOR i in REVERSE 0..least(lbRec.df_file#-1, lbState.lbDfRecTab.count-1) LOOP IF (lbState.lbDfRecTab(i).dfNumber = lbRec.df_file# AND lbState.lbDfRecTab(i).dfCreationSCN = lbRec.df_creation_change#) THEN IF (lbRec.backup_type = backupset_txt) THEN lbRec.fname := lbState.lbDfRecTab(i).fileName; END IF; lbRec.df_tablespace := lbState.lbDfRecTab(i).tsName; found := TRUE; EXIT reverse_loop_lbDfRecTab; ELSIF (lbState.lbDfRecTab(i).dfNumber < lbRec.df_file#) THEN EXIT reverse_loop_lbDfRecTab; END IF; END LOOP; END IF; END IF; -- -- -- -- -- IF (lbRec.backup_type = backupset_txt) THEN IF (lbRec.file_type = backupset_txt) THEN -- -- -- -- lbState.lbRecTmpTab.delete; lbState.lbCopyCount := 0; lbState.lbPieceCountTab.delete; -- -- lbState.lbRecCmn := lbRec; lbState.lbRecCmn.bs_copies := 0; lbState.lbRecCmn.bs_bytes := 0; ELSIF lbRec.file_type in (datafile_txt, controlfile_txt, spfile_txt , archivedlog_txt, piece_txt) THEN IF (NOT only_obsolete OR lbRec.file_type = piece_txt) THEN -- lbState.lbRecTmpTab(lbState.lbRecTmpTab.count) := lbRec; IF (lbRec.file_type = piece_txt) THEN listBackupProcessPiece(lbRec, lbRecOut, lbState); END IF; END IF; ELSE -- deb(DEB_EXIT, 'with error 20999'); raise_application_error(-20999, 'internal error: listBackup_2'); END IF; ELSIF (lbRec.backup_type = copy_txt) THEN -- -- -- -- -- -- -- IF (diskDevice) THEN IF (recoveryDestFile AND lbRec.is_rdf = 'NO') THEN IF (debug) THEN -- protect for performance deb(DEB_IN, 'copy not recovery area or ors file pkey: ' || lbRec.pkey); END IF; ELSE IF (debug) THEN -- protect for performance deb(DEB_IN, 'device allocated: pipelineing copy '||lbRec.pkey); END IF; lbState.lbRecOutTab(lbState.lbRecOutTab_count) := lbRec; lbState.lbRecOutTab_count := lbState.lbRecOutTab_count+1; END IF; ELSE IF (debug) THEN -- protect for performance deb(DEB_IN, 'device not allocated: skiping copy '||lbRec.pkey); END IF; END IF; ELSIF (lbRec.backup_type = proxycopy_txt) THEN -- -- -- -- -- -- -- IF (anyDevice = TRUE# OR isDeviceTypeAllocated(lbRec.device_type) = TRUE#) THEN IF (recoveryDestFile AND lbRec.is_rdf = 'NO') THEN IF (debug) THEN -- protect for performance deb(DEB_IN, 'proxycopy not a recovery area file pkey: ' || lbRec.pkey); END IF; ELSE IF (debug) THEN -- protect for performance deb(DEB_IN, 'device allocated: pipelineing proxycopy '|| lbRec.pkey); END IF; lbState.lbRecOutTab(lbState.lbRecOutTab_count) := lbRec; lbState.lbRecOutTab_count := lbState.lbRecOutTab_count+1; END IF; ELSE IF (debug) THEN -- protect for performance deb(DEB_IN, 'device not allocated: skiping proxycopy '||lbRec.pkey); END IF; END IF; ELSE deb(DEB_EXIT, 'with error 20999'); raise_application_error(-20999, 'internal error: listBackup_3'); END IF; END LOOP; <> -- IF (lbState.lbRecOutTab_count > 0) THEN lbState.lbRecOutTab_count := lbState.lbRecOutTab_count - 1; lbRecOut := lbState.lbRecOutTab(lbState.lbRecOutTab_count); END IF; <> -- -- IF (lbState.lbRecOutTab_count = 0) THEN IF (this_baseline_cap >= 0) THEN deb(DEB_EXIT, 'FALSE'); RETURN FALSE; END IF; IF (piped_call) THEN IF (lbCursor%NOTFOUND) THEN CLOSE lbCursor; cacheBsRecTable.hint := noHint; IF (debug) THEN -- protect for performance deb(DEB_EXIT, 'FALSE'); END IF; RETURN FALSE; END IF; ELSE IF (listBackup_c%NOTFOUND) THEN CLOSE listBackup_c; cacheBsRecTable.hint := noHint; IF (debug) THEN -- protect for performance deb(DEB_EXIT, 'FALSE'); END IF; RETURN FALSE; END IF; END IF; END IF; deb(DEB_EXIT, 'TRUE'); RETURN TRUE; EXCEPTION WHEN OTHERS THEN IF (piped_call) THEN IF (lbCursor%ISOPEN) THEN CLOSE lbCursor; END IF; ELSE IF (listBackup_c%ISOPEN) THEN CLOSE listBackup_c; END IF; END IF; deb(DEB_EXIT, 'with exception: '||substr(sqlerrm, 1, 512)); RAISE; END listBackup; -- FUNCTION getRestoreRangeSet(restoreRangeTab OUT restoreRangeTab_t, opCode IN varchar2, db_id IN number) RETURN boolean IS i number; j number; ret boolean; rc binary_integer; restoreRange restoreRange_t; dfRecTab dfRecTab_t; dfRec dfRec_t; rcvRec rcvRec_t; maxScn number; maxRlgScn number; maxRlgTime date; minScn number; fromScn number; tmpScn number; dropScn number; dropTime date; dropDbIncKey number; dropRlgScn number; dropRlgTime date; lastBkupScn number; cfcrescn number; cfcretime date; tmpDbIncKey number; tmpRlgScn number; tmpRlgTime date; actionMask number; dfBackupFound number; offlnRngFound number; dfCreation number; logBreakPointScn number; logBreakPointTime date; logBreakDbIncKey number; logBreakRlgScn number; logBreakRlgTime date; nextAvailableScn number; logMissing boolean; nxtScnExist boolean; maxScnExist boolean; dropScnExist boolean; maxTime date; maxDbIncKey number; tmpTime date; nowTime date; logRangeCount number; isOrs number; type isActnFoundTab is table of boolean index by binary_integer; isActnFound isActnFoundTab; con_id number; canCreateDf boolean; dfCreateSCN number; BEGIN deb(DEB_ENTER, 'getRestoreRangeSet'); deb(DEB_IN, 'backupLocation = ' || opCode); if (substr(opCode, 4, 3) = 'ANY') then restoreRangeDevTyp := substr(opCode, 1, 6); elsif (substr(opCode, 4, 4) = 'DISK') then restoreRangeDevTyp := substr(opCode, 1, 7); elsif (substr(opCode, 4, 3) = 'SBT') then restoreRangeDevTyp := substr(opCode, 1, 6); elsif (substr(opCode, 1, 5) = 'V$ANY') then restoreRangeDevTyp := substr(opCode, 3, 3); elsif (substr(opCode, 1, 6) = 'V$DISK') then restoreRangeDevTyp := substr(opCode, 3, 4); elsif (substr(opCode, 1, 5) = 'V$SBT') then restoreRangeDevTyp := substr(opCode, 3, 3); end if; -- IF (opCode = 'RA$ANY' OR opCode = 'RA$DISK' OR opCode = 'RA$SBT') THEN IF user_site_key IS NULL THEN ret := setLocalOrsSiteKey(db_id); IF ret = FALSE THEN resetLocalOrsSiteKey; deb(DEB_EXIT, 'with FALSE'); return FALSE; END IF; END IF; isOrs := TRUE#; ELSE isOrs := FALSE#; END IF; restoreRangeTab.delete; setCraGetAllCfBackups(TRUE); setAllIncarnations(TRUE); canApplyAnyRedo := TRUE#; -- maxScnExist := getMaxRedoSCN(maxScn, maxTime, maxDbIncKey, maxRlgScn, maxRlgTime, isOrs); IF (maxScnExist = FALSE) THEN resetLocalOrsSiteKey; deb(DEB_EXIT, 'with FALSE'); return FALSE; END IF; deb(DEB_IN, 'Max scn is ' || to_char(maxScn)); -- nxtScnExist := getNextAvailableSCN(0, minScn, isOrs); IF (nxtScnExist = FALSE) THEN resetLocalOrsSiteKey; deb(DEB_EXIT, 'with FALSE'); return FALSE; END IF; fromScn := minScn; -- -- -- -- -- -- -- -- -- i := 0; LOOP EXIT WHEN fromScn >= maxScn; logMissing := findLogBreakPoint(logBreakPointScn, logBreakPointTime, logBreakDbIncKey, logBreakRlgScn, logBreakRlgTime, fromScn, maxScn, isOrs); -- IF (logMissing = FALSE) THEN restoreRangeTab(i).startScn := fromScn; restoreRangeTab(i).highScn := maxScn; restoreRangeTab(i).highTime := maxTime; restoreRangeTab(i).highDbIncKey := maxDbIncKey; restoreRangeTab(i).highRlgScn := maxRlgScn; restoreRangeTab(i).highRlgTime := maxRlgTime; restoreRangeTab(i).con_id := con_id; EXIT; -- -- ELSE restoreRangeTab(i).startScn := fromScn; restoreRangeTab(i).highScn := logBreakPointScn; restoreRangeTab(i).highTime := logBreakPointTime; restoreRangeTab(i).highDbIncKey := logBreakDbIncKey; restoreRangeTab(i).highRlgScn := logBreakRlgScn; restoreRangeTab(i).highRlgTime := logBreakRlgTime; restoreRangeTab(i).con_id := con_id; -- nxtScnExist := getNextAvailableSCN(logBreakPointScn, nextAvailableScn, isOrs); IF (nxtScnExist = TRUE) THEN fromScn := nextAvailableScn; ELSE EXIT; END IF; END IF; i := i + 1; END LOOP; -- logRangeCount := i + 1; -- i := 0; WHILE i < logRangeCount LOOP restoreRangeTab(i).isValidRange := FALSE; restoreRangeTab(i).cfBkupFound := FALSE; i := i + 1; END LOOP; deb(DEB_IN, 'Printing continuous log-ranges'); i := 0; WHILE i < logRangeCount LOOP deb(DEB_IN, 'Range '||to_char(i+1)||' lowscn = '|| to_char(restoreRangeTab(i).startScn) ||' highscn = '|| to_char(restoreRangeTab(i).highScn)); i := i + 1; END LOOP; -- dfRecTab.delete; translateAllDatafile; LOOP BEGIN getDatafile(dfRec); EXCEPTION WHEN no_data_found THEN EXIT; END; dfRecTab(dfRecTab.count) := dfRec; END LOOP; SELECT SYSDATE INTO nowTime from dual; -- -- actionMask := full_act_t + offlineRange_act_t + implicitRange_act_t + cleanRange_act_t + incremental_act_t + createdatafile_act_t; -- -- -- setComputeRecoveryActionMasks(containerMask => backupSet_con_t + offlineRangeRec_con_t + imageCopy_con_t, actionMask => actionMask, allRecords => TRUE#, availableMask => BSavailable, fullBackups => NULL); -- -- findControlfileBackup(FALSE, FALSE, TRUE, 0, 0); IF getRecStackCount <> 0 THEN rcvRecPop(rcvRec); cfcrescn := 0; cfcretime := rcvRec.cfCreationTime_con; END IF; -- -- j := to_number(null); LOOP IF (j is null) THEN j := dfRecTab.first; ELSE j := dfRecTab.next(j); END IF; EXIT WHEN j IS NULL; dfRec := dfRecTab(j); -- -- IF (dfRec.pluginSCN = 0 AND dfRec.foreignDbid = 0 AND dfRec.pdbForeignDbid = 0 AND dfRec.creation_thread > 0 AND dfRec.creation_size > 0) THEN canCreateDf := TRUE; ELSE canCreateDf := FALSE; END IF; dfCreateSCN := dfRec.dfCreationSCN; dropScnExist := getDropSCN(dfRec.dfNumber, dfRec.dfCreationSCN, dfRec.dfCreationTime, dfRec.pluginSCN, dfRec.foreignDbid, dropScn, dropTime, dropDbIncKey, dropRlgScn, dropRlgTime); IF (dropScnExist = TRUE) THEN deb(DEB_IN, 'Datafile belongs to tablespace# ' || to_char(dfRec.dfNumber) || 'which has a dropscn' || dropScn); END IF; -- rc := computeRecoveryActions(fno => dfRec.dfNumber, crescn => dfRec.dfCreationSCN, df_cretime => dfRec.dfCreationTime, cf_scn => cfcrescn, cf_cretime => cfcretime, allowfuzzy => FALSE, partial_rcv => FALSE, allCopies => FALSE, cleanscn => dfRec.stopSCN, clean2scn => highscnval, clean2time => nowTime, onlscn => dfRec.dfOnlineSCN, offlscn => dfRec.dfOfflineSCN, onltime => dfRec.dfOnlineTime, rmanCmd => restoreCmd_t, foreignDbid => dfRec.foreignDbid, pluggedRonly => dfRec.pluggedRonly, pluginSCN => dfRec.pluginSCN, pluginRlgSCN => dfRec.pluginRlgSCN, pluginRlgTime => dfRec.pluginRlgTime, creation_thread => dfRec.creation_thread, creation_size => dfRec.creation_size, pdbId => dfRec.pdbId, pdbForeignDbid => dfRec.pdbForeignDbid); -- deb(DEB_IN, 'Considering backups for the datafile ' ||to_char(dfRec.dfNumber)); -- -- -- -- i := 0; WHILE i < logRangeCount LOOP isActnFound(i) := FALSE; i := i + 1; END LOOP; -- IF (rc = SUCCESS) THEN LOOP EXIT WHEN getRecStackCount = 0; rcvRecPop(rcvRec); dfBackupFound := FALSE#; offlnRngFound := FALSE#; dfCreation := FALSE#; -- IF (rcvRec.type_act = full_act_t) THEN -- tmpScn := rcvRec.toSCN_act; tmpTime := rcvRec.toTime_act; tmpDbIncKey := rcvRec.dbincKey_act; tmpRlgScn := rcvRec.rlgSCN_act; tmpRlgTime := rcvRec.rlgTime_act; dfBackupFound := TRUE#; -- ELSIF (rcvRec.type_act = createdatafile_act_t) THEN dfCreation := TRUE#; deb(DEB_IN, 'The df can be created'); -- ELSIF (rcvRec.type_act = cleanRange_act_t) THEN deb(DEB_IN, 'A clean range found'); lastBkupScn := tmpScn; offlnRngFound := TRUE#; END IF; -- IF (dfRec.dfNumber = 1 and dfBackupFound = TRUE#) THEN deb(DEB_IN, 'backup scn = ' || to_char(tmpScn)); -- i := 0; WHILE i < logRangeCount LOOP IF (restoreRangeTab(i).startScn <= tmpScn AND restoreRangeTab(i).highScn >= tmpScn AND isActnFound(i) = FALSE) THEN -- -- restoreRangeTab(i).lowScn := tmpScn; restoreRangeTab(i).lowTime := tmpTime; restoreRangeTab(i).lowDbIncKey := tmpDbIncKey; restoreRangeTab(i).lowRlgScn := tmpRlgScn; restoreRangeTab(i).lowRlgTime := tmpRlgTime; restoreRangeTab(i).rcvStartScn := tmpScn; restoreRangeTab(i).rcvStartTime := tmpTime; isActnFound(i) := TRUE; restoreRangeTab(i).isValidRange := TRUE; deb(DEB_IN, 'backup belongs to ' || to_char(i+1) || '-th range' ); END IF; i := i + 1; END LOOP; -- -- ELSIF (dfRec.dfNumber > 1 and dfBackupFound = TRUE#) THEN deb(DEB_IN, 'backup scn = ' || to_char(tmpScn)); -- i := 0; WHILE i < logRangeCount LOOP IF (restoreRangeTab(i).startScn <= tmpScn AND restoreRangeTab(i).highScn >= tmpScn AND restoreRangeTab(i).isValidRange = TRUE AND isActnFound(i) = FALSE) THEN deb(DEB_IN, 'backup belongs to ' || to_char(i+1) || '-th range' ); isActnFound(i) := TRUE; -- -- -- -- -- IF (tmpScn >= restoreRangeTab(i).lowScn AND (NOT (canCreateDf AND restoreRangeTab(i).startScn <= dfCreateSCN AND restoreRangeTab(i).highScn >= dfCreateSCN))) THEN restoreRangeTab(i).lowScn := tmpScn; restoreRangeTab(i).lowTime := tmpTime; restoreRangeTab(i).lowDbIncKey := tmpDbIncKey; restoreRangeTab(i).lowRlgScn := tmpRlgScn; restoreRangeTab(i).lowRlgTime := tmpRlgTime; deb(DEB_IN, 'updating lowscn to ' || to_char(tmpScn)); ELSE deb(DEB_IN, 'not updating lowscn'); END IF; IF (tmpScn < restoreRangeTab(i).rcvStartScn) THEN restoreRangeTab(i).rcvStartScn := tmpScn; restoreRangeTab(i).rcvStartTime := tmpTime; deb(DEB_IN, 'updating media rcv scn to ' || to_char(tmpScn)); ELSE deb(DEB_IN, 'not updating media rcv scn'); END IF; END IF; -- -- -- -- -- -- IF (canCreateDf AND restoreRangeTab(i).startScn <= dfCreateSCN AND restoreRangeTab(i).isValidRange = TRUE AND isActnFound(i) = FALSE) THEN deb(DEB_IN, 'creation scn belongs to ' || to_char(i+1) || '-th range. Marking the action to True'); isActnFound(i) := TRUE; IF (dfCreateSCN < restoreRangeTab(i).rcvStartScn AND restoreRangeTab(i).highScn >= dfCreateSCN) THEN restoreRangeTab(i).rcvStartScn := dfCreateSCN; restoreRangeTab(i).rcvStartTime := dfRec.dfCreationTime; deb(DEB_IN, 'updating media rcv scn to DF createscn ' || to_char(dfCreateSCN)); END IF; ELSIF ( NOT canCreateDf AND restoreRangeTab(i).highScn < dfCreateSCN AND restoreRangeTab(i).isValidRange = TRUE AND isActnFound(i) = FALSE) THEN deb(DEB_IN, 'Df non-creatable. Restore range highscn '|| restoreRangeTab(i).highScn || ' less than df' || 'creation scn ' || dfCreateSCN || '.Marking ' || to_char(i+1) || '-th range to true'); isActnFound(i) := TRUE; END IF; i := i + 1; END LOOP; -- -- ELSIF (dfCreation = TRUE#) THEN tmpScn := dfRec.dfCreationSCN; i := 0; WHILE i < logRangeCount LOOP IF (restoreRangeTab(i).startScn <= tmpScn AND restoreRangeTab(i).isValidRange = TRUE AND isActnFound(i) = FALSE) THEN deb(DEB_IN, 'creation scn belongs to ' || to_char(i+1) || '-th range' ); isActnFound(i) := TRUE; END IF; i := i + 1; END LOOP; -- -- -- ELSIF (dfRec.dfNumber > 1 and offlnRngFound = TRUE#) THEN deb(DEB_IN, 'offline range from scn = ' || to_char(rcvRec.fromSCN_act) || 'to scn = ' || to_char(rcvRec.toSCN_act)); -- i := 0; WHILE i < logRangeCount LOOP IF (restoreRangeTab(i).startScn <= rcvRec.toSCN_act AND restoreRangeTab(i).isValidRange = TRUE AND isActnFound(i) = FALSE AND rcvRec.fromSCN_act <= lastBkupScn) THEN deb(DEB_IN, 'offline range belongs to ' || to_char(i+1) || '-th range' ); isActnFound(i) := TRUE; END IF; i := i + 1; END LOOP; END IF; -- IF (dropScnExist = TRUE) THEN i := 0; WHILE i < logRangeCount LOOP IF (restoreRangeTab(i).startScn >= dropScn AND restoreRangeTab(i).isValidRange = TRUE AND isActnFound(i) = FALSE) THEN deb(DEB_IN, 'file has been dropped before ' || to_char(i+1) || '-th range' ); isActnFound(i) := TRUE; ELSIF (restoreRangeTab(i).startScn < dropScn AND restoreRangeTab(i).highScn > dropScn AND restoreRangeTab(i).isValidRange = TRUE AND isActnFound(i) = FALSE) THEN deb(DEB_IN, 'file has been dropped in ' || to_char(i+1) || '-th range' ); isActnFound(i) := TRUE; restoreRangeTab(i).lowScn := dropScn; restoreRangeTab(i).lowTime := dropTime; restoreRangeTab(i).lowDbIncKey := dropDbIncKey; restoreRangeTab(i).lowRlgScn := dropRlgScn; restoreRangeTab(i).lowRlgTime := dropRlgTime; deb(DEB_IN, 'updating media low scn to ' || dropScn); END IF; i := i + 1; END LOOP; END IF; END LOOP; -- -- i := 0; WHILE i < logRangeCount LOOP IF (isActnFound(i) = FALSE) THEN restoreRangeTab(i).isValidRange := FALSE; END IF; i := i + 1; END LOOP; -- -- ELSE i := 0; WHILE i < logRangeCount LOOP restoreRangeTab(i).isValidRange := FALSE; i := i + 1; END LOOP; EXIT; END IF; -- END LOOP; -- findControlfileBackup(FALSE, TRUE, TRUE, 0, 0); IF (getBS_status = SUCCESS) THEN LOOP EXIT WHEN getRecStackCount = 0; rcvRecPop(rcvRec); -- tmpScn := rcvRec.toSCN_act; deb(DEB_IN, 'cf backup scn = ' || to_char(tmpScn)); -- i := 0; WHILE i < logRangeCount LOOP IF (restoreRangeTab(i).startScn <= tmpScn AND restoreRangeTab(i).highScn >= tmpScn AND restoreRangeTab(i).cfBkupFound = FALSE AND restoreRangeTab(i).isValidRange = TRUE) THEN deb(DEB_IN, 'cf backup belongs to ' || to_char(i+1) || '-th range' ); restoreRangeTab(i).cfBkupFound := TRUE; -- -- IF (restoreRangeTab(i).lowScn < tmpScn) THEN restoreRangeTab(i).lowScn := tmpScn; deb(DEB_IN, 'updating lowscn to ' || to_char(tmpScn)); END IF; -- -- END IF; i := i + 1; END LOOP; END LOOP; END IF; -- -- i := 0; WHILE i < logRangeCount LOOP IF (restoreRangeTab(i).cfBkupFound = FALSE) THEN restoreRangeTab(i).isValidRange := FALSE; END IF; i := i + 1; END LOOP; resetLocalOrsSiteKey; deb(DEB_EXIT, 'with TRUE'); RETURN TRUE; EXCEPTION WHEN OTHERS THEN resetLocalOrsSiteKey; deb(DEB_EXIT, 'with FALSE'); RETURN FALSE; END getRestoreRangeSet; -- PROCEDURE sv_setSessionKey(skey IN NUMBER) IS BEGIN session_key := skey; deb(DEB_PRINT, 'Session Key Filter='|| session_key); END; FUNCTION sv_getSessionKey RETURN NUMBER IS BEGIN return session_key; END; -- PROCEDURE sv_setSessionTimeRange(fromTime IN DATE, untilTime IN DATE) IS BEGIN session_fromTime := fromTime; session_untilTime := untilTime; deb(DEB_PRINT, 'Session Time range Filter='|| to_char(session_fromTime, 'MM/DD/YYYY HH24:MI:SS') || ' To ' || to_char(session_untilTime, 'MM/DD/YYYY HH24:MI:SS')); END; FUNCTION sv_getSessionfromTimeRange RETURN DATE IS BEGIN return session_fromtime; END; FUNCTION sv_getSessionUntilTimeRange RETURN DATE IS BEGIN return session_untilTime; END; -- PROCEDURE getRetentionPolicy(recovery_window OUT number ,redundancy OUT number) IS conf_value varchar2(512); conf_name varchar2(512) := 'RETENTION POLICY'; conf# binary_integer; l1 binary_integer; l2 binary_integer; l3 binary_integer; BEGIN deb(DEB_ENTER, 'getRetentionPolicy'); recovery_window := 0; redundancy := 1; IF (findConfig_c%ISOPEN) THEN CLOSE findConfig_c; END IF; OPEN findConfig_c(conf_name, conf_value, null); FETCH findConfig_c INTO conf#, conf_name, conf_value; IF (NOT findConfig_c%NOTFOUND) THEN IF (conf_value like '%RECOVERY WINDOW%') THEN l1 := length('TO RECOVERY WINDOW OF '); l2 := length(' DAYS'); l3 := length(conf_value); recovery_window := to_number(substr(conf_value, l1, l3-l2-l1+1)); END IF; IF (conf_value like '%REDUNDANCY%') THEN l1 := length('TO REDUNDANCY '); l2 := length(conf_value); redundancy := to_number(substr(conf_value, l1, l2-l1+1)); END IF; IF (conf_value like '%NONE%') THEN -- -- redundancy := 0; recovery_window := 0; END IF; END IF; CLOSE findConfig_c; deb(DEB_IN, 'recovery window = '||recovery_window); deb(DEB_IN, 'redundancy = '||redundancy); deb(DEB_EXIT, 'getRetentionPolicy'); END getRetentionPolicy; -- PROCEDURE translateDataFileCopy( duplicates IN number ,statusMask IN binary_integer ,onlyrdf IN binary_integer ,pluginSCN IN number DEFAULT 0) IS BEGIN validateState(getDatafileCopyCursor); -- -- -- -- OPEN findDatafileBackup_c( sourcemask => imageCopy_con_t, reset_scn => this_reset_scn, reset_time => this_reset_time, statusMask => statusMask, duplicates => duplicates, onlyrdf => onlyrdf, pluginSCN => pluginSCN ); getDatafileCopyCursor := 'findDatafileBackup_c'; getDataFileCopyNoRows.error := NULL; getDataFileCopyNoRows.msg := 'Datafile copy does not exists'; getDataFileCopyDuplicates := duplicates; getDataFileCopyLast.dfNumber_obj := NULL; getDataFileCopySingleRow := FALSE; END translateDataFileCopy; -- -- -- PROCEDURE getDfBackupHistory( backedUpDev IN varchar2 ,first IN boolean ,bhistoryRec OUT NOCOPY bhistoryRec_t ,recentbackup IN boolean DEFAULT FALSE ,doingCmd IN varchar2 DEFAULT NULL ,keepTag IN varchar2 DEFAULT NULL ,toDest1 IN varchar2 DEFAULT NULL ,toDest2 IN varchar2 DEFAULT NULL ,toDest3 IN varchar2 DEFAULT NULL ,toDest4 IN varchar2 DEFAULT NULL) IS eof boolean := FALSE; local bhistoryRec_t; icount number := 0; locCreSCN number; lastCreSCN number; locRlgSCN number; lastRlgSCN number; locRlgTime date; lastRlgTime date; locCkpSCN number; lastCkpSCN number; BEGIN deb(DEB_ENTER, 'getDfBackupHistory'); IF (first) THEN getLastBackupHistory.dfNumber := NULL; IF (dfBackupHistory_c2%ISOPEN) THEN CLOSE dfBackupHistory_c2; END IF; deb(DEB_OPEN, 'dfBackupHistory_c2'); OPEN dfBackupHistory_c2(device_type => backedUpDev, cmd => doingCmd, ktag => keepTag, pattern1 => startWithPattern(toDest1), pattern2 => startWithPattern(toDest2), pattern3 => startWithPattern(toDest3), pattern4 => startWithPattern(toDest4)); END IF; IF (getLastBackupHistory.dfNumber IS NOT NULL AND (recentbackup OR getLastBackupHistory.ckp_scn = getLastBackupHistory.stop_scn)) THEN -- icount := 1; END IF; IF (getLastBackupHistory.dfNumber IS NOT NULL) THEN deb(DEB_IN, 'with file# = ' || to_char(getLastBackupHistory.dfNumber) || ' icount= ' || to_char(icount) || ' ckp_scn= ' || to_char(getLastBackupHistory.ckp_scn) || ' compTime= ' || to_char(getLastBackupHistory.compTime, 'DD-MON-RR HH24:MI:SS')); END IF; IF (NOT dfBackupHistory_c2%ISOPEN) THEN eof := TRUE; goto lastRow; END IF; <> FETCH dfBackupHistory_c2 INTO local; IF (dfBackupHistory_c2%NOTFOUND) THEN CLOSE dfBackupHistory_c2; eof := TRUE; ELSE IF (local.pluginSCN != 0) THEN locCreSCN := local.pluginSCN; locRlgSCN := local.pluginRlgSCN; locRlgTime := local.pluginRlgTime; lastCreSCN := getLastBackupHistory.pluginSCN; lastRlgSCN := getLastBackupHistory.pluginRlgSCN; lastRlgTime := getLastBackupHistory.pluginRlgTime; ELSE locCreSCN := local.create_scn; locRlgSCN := local.reset_scn; locRlgTime := local.reset_time; lastCreSCN := getLastBackupHistory.create_scn; lastRlgSCN := getLastBackupHistory.reset_scn; lastRlgTime := getLastBackupHistory.reset_time; END IF; IF (local.pluggedRonly = 1) THEN locCkpSCN := local.pluginSCN; lastCkpSCN := getLastBackupHistory.pluginSCN; ELSE locCkpSCN := local.ckp_scn; lastCkpSCN := getLastBackupHistory.ckp_scn; END IF; IF (getLastBackupHistory.dfNumber IS NULL OR (getLastBackupHistory.dfNumber = local.dfNumber AND lastCreSCN = locCreSCN AND lastRlgSCN = locRlgSCN AND lastRlgTime = locRlgTime)) THEN IF (recentbackup) THEN IF (getLastBackupHistory.dfNumber IS NULL OR locCkpSCN = lastCkpSCN) THEN -- icount := icount + 1; END IF; ELSIF (local.ckp_scn = local.stop_scn OR local.pluggedRonly = 1) THEN -- -- icount := icount + 1; -- bump the number of copies END IF; IF (getLastBackupHistory.dfNumber IS NULL) THEN getLastBackupHistory := local; -- remember the recent backup END IF; deb(DEB_IN, 'with file# = ' || to_char(local.dfNumber) || ' icount= ' || to_char(icount) || ' ckp_scn= ' || to_char(local.ckp_scn) || ' compTime= ' || to_char(local.compTime, 'DD-MON-RR HH24:MI:SS')); goto nextRow; END IF; END IF; -- -- <> IF (eof AND getLastBackupHistory.dfNumber IS NULL) THEN deb(DEB_EXIT, 'with: no_data_found'); RAISE no_data_found; END IF; -- -- bhistoryRec := getLastBackupHistory; bhistoryRec.nbackups := icount; IF (eof) THEN getLastBackupHistory.dfNumber := NULL; -- for next time to raise no_data ELSE -- getLastBackupHistory := local; END IF; deb(DEB_EXIT, 'with file# = ' || to_char(bhistoryRec.dfNumber) || ' nbackups= ' || to_char(bhistoryRec.nbackups) || ' ckp_scn= ' || to_char(bhistoryRec.ckp_scn) || ' compTime= ' || to_char(bhistoryRec.compTime, 'DD-MON-RR HH24:MI:SS')); END getDfBackupHistory; PROCEDURE getDcBackupHistory( backedUpDev IN varchar2 ,first IN boolean ,bhistoryRec OUT NOCOPY bhistoryRec_t ,doingCmd IN varchar2 DEFAULT NULL ,keepTag IN varchar2 DEFAULT NULL ,toDest1 IN varchar2 DEFAULT NULL ,toDest2 IN varchar2 DEFAULT NULL ,toDest3 IN varchar2 DEFAULT NULL ,toDest4 IN varchar2 DEFAULT NULL) IS eof boolean := FALSE; local bhistoryRec_t; icount number := 0; locCreSCN number; lastCreSCN number; locRlgSCN number; lastRlgSCN number; locRlgTime date; lastRlgTime date; locCkpSCN number; lastCkpSCN number; BEGIN deb(DEB_ENTER, 'getDcBackupHistory'); IF (first) THEN getLastBackupHistory.dfNumber := NULL; IF (dcBackupHistory_c%ISOPEN) THEN CLOSE dcBackupHistory_c; END IF; deb(DEB_OPEN, 'dcBackupHistory_c'); OPEN dcBackupHistory_c(device_type => backedUpDev, cmd => doingCmd, ktag => keepTag, pattern1 => startWithPattern(toDest1), pattern2 => startWithPattern(toDest2), pattern3 => startWithPattern(toDest3), pattern4 => startWithPattern(toDest4)); END IF; IF (getLastBackupHistory.dfNumber IS NOT NULL AND getLastBackupHistory.ckp_scn = getLastBackupHistory.stop_scn) THEN icount := 1; END IF; IF (NOT dcBackupHistory_c%ISOPEN) THEN eof := TRUE; goto lastRow; END IF; IF (getLastBackupHistory.dfNumber IS NOT NULL) THEN deb(DEB_IN, 'with file# = ' || to_char(getLastBackupHistory.dfNumber) || ' create_scn= ' || to_char(getLastBackupHistory.create_scn) || ' reset_scn= ' || to_char(getLastBackupHistory.reset_scn) || ' reset_time= ' || to_char(getLastBackupHistory.reset_time, 'DD-MON-RR HH24:MI:SS') || ' ckp_scn= ' || to_char(getLastBackupHistory.ckp_scn) || ' stop_scn= ' || to_char(getLastBackupHistory.stop_scn) || ' nbackups= ' || to_char(getLastBackupHistory.nbackups) || ' compTime= ' || to_char(getLastBackupHistory.compTime, 'DD-MON-RR HH24:MI:SS')); END IF; <> FETCH dcBackupHistory_c INTO local; IF (dcBackupHistory_c%NOTFOUND) THEN CLOSE dcBackupHistory_c; eof := TRUE; ELSE IF (local.pluginSCN != 0) THEN locCreSCN := local.pluginSCN; locRlgSCN := local.pluginRlgSCN; locRlgTime := local.pluginRlgTime; lastCreSCN := getLastBackupHistory.pluginSCN; lastRlgSCN := getLastBackupHistory.pluginRlgSCN; lastRlgTime := getLastBackupHistory.pluginRlgTime; ELSE locCreSCN := local.create_scn; locRlgSCN := local.reset_scn; locRlgTime := local.reset_time; lastCreSCN := getLastBackupHistory.create_scn; lastRlgSCN := getLastBackupHistory.reset_scn; lastRlgTime := getLastBackupHistory.reset_time; END IF; IF (getLastBackupHistory.dfNumber IS NULL OR (getLastBackupHistory.dfNumber = local.dfNumber AND lastCreSCN = locCreSCN AND getLastBackupHistory.ckp_scn = local.ckp_scn AND getLastBackupHistory.ckp_time = local.ckp_time AND getLastBackupHistory.pluggedRonly = local.pluggedRonly AND lastRlgSCN = locRlgSCN AND lastRlgTime = locRlgTime)) THEN IF (local.ckp_scn = local.stop_scn OR local.pluggedRonly = 1) THEN -- icount := icount + 1; -- bump the number of copies END IF; getLastBackupHistory := local; -- remember the last copy deb(DEB_IN, 'with file# = ' || to_char(local.dfNumber) || ' create_scn= ' || to_char(local.create_scn) || ' reset_scn= ' || to_char(local.reset_scn) || ' reset_time= ' || to_char(local.reset_time, 'DD-MON-RR HH24:MI:SS') || ' ckp_scn= ' || to_char(local.ckp_scn) || ' stop_scn= ' || to_char(local.stop_scn) || ' nbackups= ' || to_char(local.nbackups) || ' compTime= ' || to_char(local.compTime, 'DD-MON-RR HH24:MI:SS')); goto nextRow; END IF; END IF; -- -- <> IF (eof AND getLastBackupHistory.dfNumber IS NULL) THEN deb(DEB_EXIT, 'with: no_data_found'); RAISE no_data_found; END IF; -- -- bhistoryRec := getLastBackupHistory; bhistoryRec.nbackups := icount; IF (eof) THEN getLastBackupHistory.dfNumber := NULL; -- for next time to raise no_data ELSE -- getLastBackupHistory := local; END IF; deb(DEB_EXIT, 'with file# = ' || to_char(bhistoryRec.dfNumber) || ' create_scn= ' || to_char(bhistoryRec.create_scn) || ' reset_scn= ' || to_char(bhistoryRec.reset_scn) || ' reset_time= ' || to_char(bhistoryRec.reset_time, 'DD-MON-RR HH24:MI:SS') || ' ckp_scn= ' || to_char(bhistoryRec.ckp_scn) || ' stop_scn= ' || to_char(bhistoryRec.stop_scn) || ' nbackups= ' || to_char(bhistoryRec.nbackups) || ' compTime= ' || to_char(bhistoryRec.compTime, 'DD-MON-RR HH24:MI:SS')); END getDcBackupHistory; PROCEDURE getAlBackupHistory( backedUpDev IN varchar2 ,first IN boolean ,bhistoryRec OUT NOCOPY bhistoryRec_t ,doingCmd IN varchar2 DEFAULT NULL ,keepTag IN varchar2 DEFAULT NULL ,toDest1 IN varchar2 DEFAULT NULL ,toDest2 IN varchar2 DEFAULT NULL ,toDest3 IN varchar2 DEFAULT NULL ,toDest4 IN varchar2 DEFAULT NULL) IS eof boolean := FALSE; local bhistoryRec_t; icount number := 0; BEGIN deb(DEB_ENTER, 'getAlBackupHistory'); IF (first) THEN getLastBackupHistory.logThread := NULL; IF (alBackupHistory_c2%ISOPEN) THEN CLOSE alBackupHistory_c2; END IF; deb(DEB_OPEN, 'alBackupHistory_c2'); OPEN alBackupHistory_c2(device_type => backedUpDev, cmd => doingCmd, ktag => keepTag, pattern1 => startWithPattern(toDest1), pattern2 => startWithPattern(toDest2), pattern3 => startWithPattern(toDest3), pattern4 => startWithPattern(toDest4)); END IF; IF (getLastBackupHistory.logThread IS NOT NULL) THEN icount := 1; END IF; IF (NOT alBackupHistory_c2%ISOPEN) THEN eof := TRUE; goto lastRow; END IF; <> FETCH alBackupHistory_c2 INTO local; IF (alBackupHistory_c2%NOTFOUND) THEN CLOSE alBackupHistory_c2; eof := TRUE; ELSIF (getLastBackupHistory.logThread IS NULL OR (getLastBackupHistory.logThread = local.logThread AND getLastBackupHistory.logSequence = local.logSequence AND getLastBackupHistory.logTerminal = local.logTerminal AND getLastBackupHistory.next_scn = local.next_scn AND getLastBackupHistory.reset_scn = local.reset_scn AND getLastBackupHistory.reset_time = local.reset_time)) THEN icount := icount + 1; -- bump the number of copies getLastBackupHistory := local; -- remember the last copy deb(DEB_IN, 'with (reset_scn, reset_time, thread#, sequence#, terminal)=(' || to_char(local.reset_scn) || ',' || to_char(local.reset_time,'DD-MON-RR HH24:MI:SS') || ',' || to_char(local.logThread) || ',' || to_char(local.logSequence) || ',' || to_char(local.logTerminal) || ')' || ' nbackups= ' || local.nbackups|| ' compTime= ' || to_char(local.compTime, 'DD-MON-RR HH24:MI:SS')); goto nextRow; END IF; -- -- <> IF (eof AND getLastBackupHistory.logThread IS NULL) THEN deb(DEB_EXIT, 'with: no_data_found'); RAISE no_data_found; END IF; -- -- bhistoryRec := getLastBackupHistory; bhistoryRec.nbackups := icount; IF (eof) THEN getLastBackupHistory.logThread := NULL; -- for next time to raise no_data ELSE -- getLastBackupHistory := local; END IF; deb(DEB_EXIT, 'with (reset_scn, reset_time, thread#, sequence#, terminal)=(' || to_char(bhistoryRec.reset_scn) || ',' || to_char(bhistoryRec.reset_time,'DD-MON-RR HH24:MI:SS') || ',' || to_char(bhistoryRec.logThread) || ',' || to_char(bhistoryRec.logSequence) || ',' || to_char(bhistoryRec.logTerminal) || ')' || ' nbackups= ' || bhistoryRec.nbackups|| ' compTime= ' || to_char(bhistoryRec.compTime, 'DD-MON-RR HH24:MI:SS')); END getAlBackupHistory; PROCEDURE getBsBackupHistory( backedUpDev IN varchar2 ,first IN boolean ,set_stamp IN number DEFAULT NULL ,set_count IN number DEFAULT NULL ,bhistoryRec OUT NOCOPY bhistoryRec_t ,doingCmd IN varchar2 DEFAULT NULL ,keepTag IN varchar2 DEFAULT NULL ,toDest1 IN varchar2 DEFAULT NULL ,toDest2 IN varchar2 DEFAULT NULL ,toDest3 IN varchar2 DEFAULT NULL ,toDest4 IN varchar2 DEFAULT NULL) IS eof boolean := FALSE; local bhistoryRec_t; icount number := 0; bpRec bpRec_t; BEGIN deb(DEB_ENTER, 'getBsBackupHistory'); IF (set_stamp IS NOT NULL AND set_count IS NOT NULL) THEN IF (NOT first) THEN deb(DEB_EXIT, 'with: no_data_found'); RAISE no_data_found; END IF; bpRec.setStamp := set_stamp; bpRec.setCount := set_count; getBackupHistory(bpRec => bpRec, backedUpDev => backedUpDev, nbackupsFlag => 1, bscompletionFlag => 1, nbackups => bhistoryRec.nbackups, bscompletion => bhistoryRec.compTime, todest1 => toDest1, todest2 => toDest2, todest3 => todest3, todest4 => todest4); IF (bhistoryRec.nbackups = 0) THEN deb(DEB_EXIT, 'with: no_data_found'); RAISE no_data_found; END IF; bhistoryRec.setStamp := set_stamp; bhistoryRec.setCount := set_count; deb(DEB_EXIT, 'with set_stamp = ' || to_char(bhistoryRec.setStamp) || ' set_count = ' || to_char(bhistoryRec.setCount) || ' nbackups= ' || to_char(bhistoryRec.nbackups) || ' compTime= ' || to_char(bhistoryRec.compTime, 'DD-MON-RR HH24:MI:SS')); RETURN; END IF; IF (first) THEN getLastBackupHistory.setStamp := NULL; IF (bsBackupHistory_c2%ISOPEN) THEN CLOSE bsBackupHistory_c2; END IF; deb(DEB_OPEN, 'bsBackupHistory_c2'); OPEN bsBackupHistory_c2(device_type => backedUpDev, cmd => doingCmd, ktag => keepTag, pattern1 => startWithPattern(toDest1), pattern2 => startWithPattern(toDest2), pattern3 => startWithPattern(toDest3), pattern4 => startWithPattern(toDest4)); END IF; IF (getLastBackupHistory.setStamp IS NOT NULL) THEN icount := 1; END IF; IF (NOT bsBackupHistory_c2%ISOPEN) THEN eof := TRUE; goto lastRow; END IF; <> FETCH bsBackupHistory_c2 INTO local; IF (bsBackupHistory_c2%NOTFOUND) THEN CLOSE bsBackupHistory_c2; eof := TRUE; ELSIF (getLastBackupHistory.setStamp IS NULL OR (getLastBackupHistory.setStamp = local.setStamp AND getLastBackupHistory.setCount = local.setCount)) THEN icount := icount + 1; -- bump the number of copies getLastBackupHistory := local; -- remember the last copy goto nextRow; END IF; -- -- <> IF (eof AND getLastBackupHistory.setStamp IS NULL) THEN deb(DEB_EXIT, 'with: no_data_found'); RAISE no_data_found; END IF; -- -- bhistoryRec := getLastBackupHistory; bhistoryRec.nbackups := icount; IF (eof) THEN getLastBackupHistory.setStamp := NULL; -- for next time to raise no_data ELSE -- getLastBackupHistory := local; END IF; deb(DEB_EXIT, 'with set_stamp = ' || to_char(bhistoryRec.setStamp) || 'set_count = ' || to_char(bhistoryRec.setCount) || ' nbackups= ' || to_char(bhistoryRec.nbackups) || ' compTime= ' || to_char(bhistoryRec.compTime, 'DD-MON-RR HH24:MI:SS')); END getBsBackupHistory; -- -- PROCEDURE getBackupHistory( dfRec IN dfRec_t ,backedUpDev IN varchar2 ,nbackupsFlag IN number ,bscompletionFlag IN number ,nbackups OUT number ,bscompletion OUT date) IS local bhistoryRec_t; BEGIN deb(DEB_ENTER, 'getBackupHistory'); nbackups := 0; bscompletion := NULL; -- IF ((nbackupsFlag != 1 OR backedUpDev IS NULL) AND bscompletionFlag != 1) THEN deb(DEB_EXIT, 'with not interested'); RETURN; END IF; IF (dfBackupHistory_c1%ISOPEN) THEN CLOSE dfBackupHistory_c1; END IF; OPEN dfBackupHistory_c1(file# => dfRec.dfNumber ,crescn => dfRec.dfCreationSCN ,device_type => backedUpDev); <> FETCH dfBackupHistory_c1 INTO local; IF (dfBackupHistory_c1%NOTFOUND) THEN CLOSE dfBackupHistory_c1; ELSE IF (local.reset_scn = this_reset_scn AND local.reset_time = this_reset_time AND local.ckp_scn = dfRec.stopSCN) THEN nbackups := nbackups + 1; END IF; bscompletion := local.compTime; goto nextRow; END IF; deb(DEB_EXIT); END getBackupHistory; -- -- PROCEDURE getBackupHistory( alRec IN alRec_t ,backedUpDev IN varchar2 ,nbackupsFlag IN number ,bscompletionFlag IN number ,nbackups OUT number ,bscompletion OUT date) IS local bhistoryRec_t; BEGIN deb(DEB_ENTER, 'getBackupHistory'); nbackups := 0; bscompletion := NULL; -- IF ((nbackupsFlag != 1 OR backedUpDev IS NULL) AND bscompletionFlag != 1) THEN deb(DEB_EXIT, 'with not interested'); RETURN; END IF; IF (alBackupHistory_c1%ISOPEN) THEN CLOSE alBackupHistory_c1; END IF; OPEN alBackupHistory_c1(thread# => alRec.thread ,sequence# => alRec.sequence ,device_type => backedUpDev); <> FETCH alBackupHistory_c1 INTO local; IF (alBackupHistory_c1%NOTFOUND) THEN CLOSE alBackupHistory_c1; ELSE nbackups := nbackups + 1; bscompletion := local.compTime; goto nextRow; END IF; deb(DEB_EXIT); END getBackupHistory; -- PROCEDURE getBackupHistory( bpRec IN bpRec_t ,backedUpDev IN varchar2 ,nbackupsFlag IN number ,bscompletionFlag IN number ,nbackups OUT number ,bscompletion OUT date ,todest1 IN varchar2 DEFAULT NULL ,todest2 IN varchar2 DEFAULT NULL ,todest3 IN varchar2 DEFAULT NULL ,todest4 IN varchar2 DEFAULT NULL) IS local bhistoryRec_t; BEGIN deb(DEB_ENTER, 'getBackupHistory'); nbackups := 0; bscompletion := NULL; -- IF ((nbackupsFlag != 1 OR backedUpDev IS NULL) AND bscompletionFlag != 1) THEN deb(DEB_EXIT, 'with not interested'); RETURN; END IF; IF (bsBackupHistory_c1%ISOPEN) THEN CLOSE bsBackupHistory_c1; END IF; OPEN bsBackupHistory_c1(set_stamp => bpRec.setStamp ,set_count => bpRec.setCount ,device_type => backedUpDev ,pattern1 => startWithPattern(toDest1) ,pattern2 => startWithPattern(toDest2) ,pattern3 => startWithPattern(toDest3) ,pattern4 => startWithPattern(toDest4)); <> FETCH bsBackupHistory_c1 INTO local; IF (bsBackupHistory_c1%NOTFOUND) THEN CLOSE bsBackupHistory_c1; ELSE nbackups := nbackups + 1; bscompletion := local.compTime; goto nextRow; END IF; deb(DEB_EXIT); END getBackupHistory; -- -- -- -- PROCEDURE findControlfileBackup( allCopies IN boolean default FALSE, allBackups IN boolean default FALSE, allIncarnation IN boolean default FALSE, fromSCN IN number default 0, pdbId IN number default 0) IS cfrec rcvRec_t; tag varchar2(32); valRC binary_integer; validateRec validBackupSetRec_t; currentInc number; cfUntilScn number; cfRlgScn number; BEGIN deb(DEB_ENTER, 'findControlfileBackup'); validateState(null); IF (allCopies) THEN deb(DEB_IN, 'allCopies is TRUE'); ELSE deb(DEB_IN, 'allCopies is FALSE'); END IF; IF onlyStandby IS NULL THEN deb(DEB_IN, 'onlyStandby is set to NULL '); ELSIF onlyStandby = TRUE# THEN deb(DEB_IN, 'onlyStandby is set to TRUE '); ELSE deb(DEB_IN, 'onlyStandby is set to FALSE '); END IF; cfUntilScn := get_cfUntilScn(); deb(DEB_IN, 'cfUntilScn = ' || nvl(to_char(cfUntilScn), 'NULL')); IF (allIncarnations = TRUE#) THEN deb(DEB_IN, 'allIncarnations = TRUE# '); currentInc := FALSE#; -- don't care about dbinc_key cfRlgScn := getPointInTimeInc(cfUntilScn); ELSE deb(DEB_IN, 'allIncarnations <> TRUE# '); currentInc := TRUE#; cfRlgScn := this_reset_scn; END IF; deb(DEB_IN, 'cfRlgScn= ' || nvl(to_char(cfRlgScn), 'NULL')); -- OPEN findControlfileBackup_c(sourcemask => restoreSource, currentIncarnation => currentInc, tag => restoreTag, untilSCN => cfUntilScn, statusMask => BSavailable, needstby => onlyStandby, fromSCN => fromSCN); -- -- -- findControlfileBackupCursor := TRUE; -- resetthisBackupAge; getBS_status := NULL; resetrcvRecStack; LOOP valRC := NULL; FETCH findControlfileBackup_c INTO cfrec; EXIT WHEN findControlfileBackup_c%NOTFOUND ; IF (cfrec.type_con = imageCopy_con_t) THEN deb(DEB_IN, 'findControlfileBackup found a controlfilecopy:'); IF (diskDevice) THEN valRC := SUCCESS; ELSE valRC := AVAILABLE; END IF; ELSIF (cfrec.type_con = backupSet_con_t) THEN deb(DEB_IN, 'findControlfileBackup found a controlfile backup:'); valRC := validateBackupSet( backupSetRec => cfrec, tag => restoreTag, tagMatchRequired => TRUE, checkDeviceIsAllocated => TRUE, availableMask => BSavailable, validRec => validateRec); ELSIF (cfrec.type_con = proxyCopy_con_t) THEN deb(DEB_IN, 'findControlfileBackup found a controlfile proxy copy:'); IF (restoreTag is not NULL AND cfrec.tag_con != restoreTag) THEN -- -- -- deb(DEB_IN, 'tag does not match'); valRC := UNAVAILABLE; ELSIF (anyDevice = TRUE# OR isDeviceTypeAllocated(cfrec.deviceType_con) = TRUE#) THEN valRC := SUCCESS; ELSE valRC := AVAILABLE; END IF; END IF; -- -- -- -- IF (cfRlgScn != cfrec.rlgSCN_act AND valRC IS NOT NULL) THEN deb(DEB_IN, 'rlgSCN_act= ' || nvl(to_char(cfrec.rlgSCN_act), 'NULL')); valRC := NULL; IF (cfRlgScn > cfrec.rlgSCN_act AND cfRlgScn > cfrec.toSCN_act) THEN deb(DEB_IN, 'findControlfileBackup belongs to parent incarnation'); EXIT; ELSE deb(DEB_IN, 'findControlfileBackup belongs to orphan incarnation'); END IF; END IF; -- IF (valRC IS NOT NULL AND pdbId > 1) THEN IF (isPdbScnOrphan(0, cfrec.toSCN_act, 0, pdbId)) THEN deb(DEB_IN, 'findControlfileBackup in orphan pdb sub inc'); valRC := NULL; END IF; END IF; <> IF (getBS_status IS NULL AND valRC = AVAILABLE) THEN getBS_status := valRC; END IF; IF (debug) THEN printRcvRec(cfrec); END IF; IF (valRC = SUCCESS) THEN IF (thisBackupAge < rcvRecBackupAge) THEN deb(DEB_IN, 'skipping action because thisBackupAge (' || thisBackupAge || ') < rcvRecBackupAge(' || rcvRecBackupAge || ')'); thisBackupAge := thisBackupAge + 1; ELSE deb(DEB_IN, ' Added cfrec:'); IF (cfrec.type_con = backupSet_con_t) THEN cfrec.tag_con := validateRec.tag; cfrec.deviceType_con := validateRec.deviceType; cfrec.copyNumber_con := validateRec.copyNumber; END IF; rcvRecPush(cfrec); -- add record for this action getBS_status := SUCCESS; IF (allCopies and cfrec.type_con = backupSet_con_t) THEN -- -- -- valRC := validateBackupSet0( tag => restoreTag, tagMatchRequired => TRUE, checkDeviceIsAllocated => TRUE, validRec => validateRec); IF (valRC = SUCCESS) THEN GOTO addAnother; END IF; END IF; IF (allBackups = FALSE) THEN EXIT; END IF; END IF; END IF; END LOOP; CLOSE findControlfileBackup_c; IF (getBS_status = SUCCESS) THEN deb(DEB_EXIT, 'with: SUCCESS'); ELSIF (getBS_status = AVAILABLE) THEN deb(DEB_EXIT, 'with: AVAILABLE'); ELSE getBS_status := UNAVAILABLE; deb(DEB_EXIT, 'with: UNAVAILABLE'); END IF; END findControlfileBackup; -- FUNCTION getControlfileBackup( rcvRec OUT NOCOPY rcvRec_t) RETURN number IS local rcvRec_t; BEGIN deb(DEB_ENTER, 'getControlfileBackupBackup'); IF (NOT findControlfileBackupCursor) THEN -- findControlfileBackup(FALSE, FALSE, FALSE); findControlfileBackupCursor := FALSE; END IF; IF (getRecStackCount = 0) THEN IF (getBS_status = SUCCESS) THEN deb(DEB_EXIT, 'with no more records'); raise no_data_found; ELSIF (getBS_status = AVAILABLE) THEN deb(DEB_EXIT, 'with: AVAILABLE'); RETURN AVAILABLE; ELSE deb(DEB_EXIT, 'with: UNAVAILABLE'); RETURN UNAVAILABLE; END IF; END IF; rcvRecPop(local); IF (debug) THEN printRcvRec(local); END IF; rcvRec := local; deb(DEB_EXIT, 'with: SUCCESS'); RETURN SUCCESS; END getControlfileBackup; -- -- -- -- -- -- -- -- -- -- -- PROCEDURE findRangeArchivedLogBackup( minthread IN number ,minsequence IN number ,minlowSCN IN number ,maxthread IN number ,maxsequence IN number ,maxlowSCN IN number ,allCopies IN boolean default FALSE) IS lastrec rcvRec_t; brlrec rcvRec_t; validateRec validBackupSetRec_t; tapebkp rcvRecTabI_t;-- stack of tape backups valRC number; BSstatus number; -- status of current backup skipped boolean; FUNCTION dupbs(bs1 in rcvRec_t, bs2 in rcvRec_t) RETURN BOOLEAN IS BEGIN IF (bs1.type_con != backupSet_con_t OR bs2.type_con != backupSet_con_t) THEN RETURN FALSE; END IF; IF (bs1.setStamp_con != bs2.setStamp_con OR bs1.setCount_con != bs2.setCount_con) THEN RETURN FALSE; END IF; RETURN TRUE; END dupbs; FUNCTION pushTapeBackup(tapebkp in rcvRecTabI_t) RETURN BOOLEAN IS found boolean := FALSE; BEGIN deb(DEB_IN, 'looking for tape backups'); FOR i IN 1..tapebkp.count LOOP -- EXIT when (found AND NOT dupbs(tapebkp(i), tapebkp(i-1))); IF (thisBackupAge < rcvRecBackupAge) THEN deb(DEB_IN, 'skipping action because thisBackupAge (' || thisBackupAge || ') < rcvRecBackupAge(' || rcvRecBackupAge || ')'); -- IF (i = 1 OR NOT dupbs(tapebkp(i), tapebkp(i-1))) THEN thisBackupAge := thisBackupAge + 1; END IF; ELSE deb(DEB_IN, 'Added tape backup ' || i); rcvRecPush(tapebkp(i)); found := TRUE; END IF; END LOOP; RETURN found; END pushTapeBackup; BEGIN deb(DEB_ENTER, 'findRangeArchivedLogBackup'); validateState(null); lastrec.logThread_obj := 0; -- -- -- deb(DEB_OPEN, 'findRangeArcLogBackup'); OPEN findRangeArcLogBackup(sourcemask => to_number(null), minthread => minthread, minsequence => minsequence, minlowSCN => minlowSCN, maxthread => maxthread, maxsequence => maxsequence, maxlowSCN => maxlowSCN); resetrcvRecStack; tapebkp.delete; BSstatus := NULL; IF (allCopies) THEN deb(DEB_IN, 'allCopies is TRUE'); ELSE deb(DEB_IN, 'allCopies is FALSE'); END IF; LOOP <> valRC := NULL; FETCH findRangeArcLogBackup INTO brlrec; IF (findRangeArcLogBackup%NOTFOUND) THEN -- -- -- IF (BSstatus IS NULL OR BSstatus != SUCCESS) THEN IF (pushTapeBackup(tapebkp)) THEN BSstatus := SUCCESS; END IF; END IF; -- -- IF (BSstatus = AVAILABLE AND lastrec.logThread_obj != 0) THEN deb(DEB_IN, ' Added lastlrec:'); -- -- -- lastrec.status_con := '*'; rcvRecPush(lastrec); END IF; EXIT; END IF; -- -- IF (brlrec.logSequence_obj != lastrec.logSequence_obj OR brlrec.logThread_obj != lastrec.logThread_obj OR brlrec.logRlgSCN_obj != lastrec.logRlgSCN_obj OR brlrec.logRlgTime_obj != lastrec.logRlgTime_obj OR brlrec.logLowSCN_obj != lastrec.logLowSCN_obj OR brlrec.logNextSCN_obj != lastrec.logNextSCN_obj) THEN -- -- -- IF (BSstatus IS NULL OR BSstatus != SUCCESS) THEN IF (pushTapeBackup(tapebkp)) THEN BSstatus := SUCCESS; END IF; END IF; resetthisBackupAge; -- init stack, age, status variables tapebkp.delete; IF (BSstatus = AVAILABLE) THEN -- -- -- deb(DEB_IN, ' Added lastlrec:'); lastrec.status_con := '*'; rcvRecPush(lastrec); END IF; BSstatus := NULL; -- reset backup status for next record -- IF NOT isTranslatedArchivedLog( thread# => brlrec.logThread_obj ,sequence# => brlrec.logSequence_obj) THEN deb(DEB_IN, 'skip not translated brlrec' || ' thread=' || brlrec.logThread_obj || ' sequence=' || brlrec.logSequence_obj); goto nextbrlRec; END IF; -- -- lastrec := brlrec; deb(DEB_IN, 'looking backups for' || ' thread=' || brlrec.logThread_obj || ' sequence=' || brlrec.logSequence_obj); END IF; IF (BSstatus = SUCCESS) THEN deb(DEB_IN, 'skip already stacked brlrec' || ' thread=' || brlrec.logThread_obj || ' sequence=' || brlrec.logSequence_obj); goto nextbrlRec; END IF; IF (brlrec.type_con = backupSet_con_t) THEN deb(DEB_IN, 'found a backupset:'); valRC := validateBackupSet(backupSetRec => brlrec, checkDeviceIsAllocated => TRUE, tag => restoreTag, tagMatchRequired => TRUE, availableMask => BSavailable, validRec => validateRec); ELSIF (brlrec.type_con = proxyCopy_con_t) THEN deb(DEB_IN, 'found a proxy copy:'); IF (restoreTag is not NULL AND brlrec.tag_con != restoreTag) THEN -- -- -- deb(DEB_EXIT, 'tag does not match'); valRC := UNAVAILABLE; ELSIF (anyDevice = TRUE# OR isDeviceTypeAllocated(brlrec.deviceType_con) = TRUE#) THEN valRC := SUCCESS; ELSE valRC := AVAILABLE; END IF; END IF; skipped := FALSE; <> IF (BSstatus IS NULL AND valRC = AVAILABLE) THEN BSstatus := valRC; END IF; IF (debug) THEN printRcvRec(brlrec); END IF; IF (valRC = SUCCESS) THEN IF (brlrec.type_con = backupSet_con_t) THEN brlrec.tag_con := validateRec.tag; brlrec.deviceType_con := validateRec.deviceType; brlrec.copyNumber_con := validateRec.copyNumber; END IF; -- -- -- -- IF (NOT skipped AND brlrec.deviceType_con = 'DISK' AND thisBackupAge < rcvRecBackupAge) THEN deb(DEB_IN, 'skipping action because thisBackupAge (' || thisBackupAge || ') < rcvRecBackupAge(' || rcvRecBackupAge || ')'); -- -- skipped := TRUE; thisBackupAge := thisBackupAge + 1; ELSE IF (brlrec.deviceType_con = 'DISK') THEN IF (NOT skipped) THEN deb(DEB_IN, ' Added brlrec:'); rcvRecPush(brlrec); -- add record for this action BSstatus := SUCCESS; END IF; ELSE -- deb(DEB_IN, ' Added brlrec to tapebkp stack:' || to_char(tapebkp.count+1)); tapebkp(tapebkp.count+1) := brlrec; END IF; END IF; IF (allCopies AND brlrec.type_con = backupSet_con_t) THEN -- -- -- valRC := validateBackupSet0( tag => restoreTag, tagMatchRequired => TRUE, checkDeviceIsAllocated => TRUE, validRec => validateRec); IF (valRC = SUCCESS) THEN GOTO addAnother; END IF; END IF; END IF; END LOOP; CLOSE findRangeArcLogBackup; deb(DEB_EXIT); END findRangeArchivedLogBackup; -- -- PROCEDURE findArchivedLogBackup( thread IN number ,sequence IN number ,lowSCN IN number ,allCopies IN boolean default FALSE) IS local rcvRec_t; BEGIN deb(DEB_ENTER, 'findArchivedLogBackup'); -- setArchivedLogRecord(thread# => thread ,sequence# => sequence ,first => TRUE); -- -- -- findRangeArchivedLogBackup(minthread => thread, minsequence => sequence, minlowSCN => lowSCN, maxthread => thread, maxsequence => sequence, maxlowSCN => lowSCN, allCopies => allCopies); IF (getRecStackCount = 0) THEN getBS_status := NULL; deb(DEB_EXIT, 'with UNAVAILABLE'); ELSE rcvRecTop(local); -- -- IF (local.status_con = '*') THEN getBS_status := AVAILABLE; resetrcvRecStack; deb(DEB_EXIT, 'with AVAILABLE'); ELSE getBS_status := SUCCESS; deb(DEB_EXIT, 'with SUCCESS'); END IF; END IF; END findArchivedLogBackup; -- -- FUNCTION getArchivedLogBackup( rcvRec OUT NOCOPY rcvRec_t) RETURN binary_integer IS local rcvRec_t; BEGIN deb(DEB_ENTER, 'getArchivedLogBackup'); IF (getRecStackCount = 0) THEN IF (getBS_status = SUCCESS) THEN deb(DEB_EXIT, 'with no more records'); raise no_data_found; ELSIF (getBS_status = AVAILABLE) THEN deb(DEB_EXIT, 'with: AVAILABLE'); RETURN AVAILABLE; ELSE deb(DEB_EXIT, 'with: UNAVAILABLE'); RETURN UNAVAILABLE; END IF; END IF; rcvRecPop(local); IF (debug) THEN printRcvRec(local); END IF; rcvRec := local; deb(DEB_EXIT, 'with: SUCCESS'); RETURN SUCCESS; END getArchivedLogBackup; -- -- -- -- PROCEDURE findSpfileBackup( allCopies IN boolean default FALSE -- duplex copies ,redundancy IN number default NULL -- number of redundant copies ,rmanCmd IN number default unknownCmd_t) -- called for what rman command? IS scn_warn number; BEGIN findSpfileBackup(allCopies, redundancy, rmanCmd, scn_warn); END findSpfileBackup; PROCEDURE findSpfileBackup( allCopies IN boolean default FALSE -- duplex copies ,redundancy IN number default NULL -- number of redundant copies ,rmanCmd IN number default unknownCmd_t -- called for what rman command? ,scn_warn OUT number) IS bsfrec rcvRec_t; tag varchar2(32); valRC binary_integer; validateRec validBackupSetRec_t; lcopies number; findtime date; estimated boolean := TRUE; BEGIN deb(DEB_ENTER, 'findSpfileBackup'); validateState(null); -- scn_warn := 0; IF (untilScn IS NOT NULL AND untilTime IS NULL) THEN computeSpfileTime(untilScn, findtime, allIncarnations, estimated); IF estimated THEN scn_warn := 1; END IF; ELSE findtime := untilTime; END IF; -- deb(DEB_OPEN, 'findSpfileBackup_c,rmanCmd=' || rmanCmd); OPEN findSpfileBackup_c(untilTime => findTime, rmanCmd => rmanCmd); -- -- -- findSpfileBackupCursor := TRUE; -- resetthisBackupAge; getBS_status := NULL; resetrcvRecStack; IF (allCopies) THEN deb(DEB_IN, 'allCopies is TRUE'); ELSE deb(DEB_IN, 'allCopies is FALSE'); END IF; lcopies := redundancy; -- IF (rmanCmd = obsoleteCmd_t AND allCopies) THEN raise_application_error(-20999, 'internal error: findSpfileBackup_1'); END IF; LOOP valRC := NULL; FETCH findSpfileBackup_c INTO bsfrec; EXIT WHEN findSpfileBackup_c%NOTFOUND ; IF user_site_key is not null and user_db_unique_name is NOT NULL THEN user_site_key := null; deb(DEB_IN, 'Spfile backups are identified based on db_unique_name'); END IF; IF (rmanCmd = obsoleteCmd_t) THEN -- -- valRC := SUCCESS; ELSE valRC := validateBackupSet( backupSetRec => bsfrec, tag => restoreTag, tagMatchRequired => TRUE, checkDeviceIsAllocated => TRUE, availableMask => BSavailable, validRec => validateRec); END IF; <> IF (getBS_status IS NULL AND valRC = AVAILABLE) THEN getBS_status := valRC; END IF; IF (debug) THEN printRcvRec(bsfRec); END IF; IF (valRC = SUCCESS) THEN IF (thisBackupAge < rcvRecBackupAge) THEN deb(DEB_IN, 'skipping action because thisBackupAge (' || thisBackupAge || ') < rcvRecBackupAge(' || rcvRecBackupAge || ')'); thisBackupAge := thisBackupAge + 1; ELSIF (rmanCmd = obsoleteCmd_t) THEN deb(DEB_IN, ' Added bsfRec:'); rcvRecPush(bsfRec); -- add record for this action getBS_status := SUCCESS; IF (lcopies > 1) THEN lcopies := lcopies - 1; ELSE EXIT; -- we are done END IF; ELSE deb(DEB_IN, ' Added bsfRec:'); bsfrec.tag_con := validateRec.tag; bsfrec.deviceType_con := validateRec.deviceType; bsfrec.copyNumber_con := validateRec.copyNumber; rcvRecPush(bsfRec); -- add record for this action getBS_status := SUCCESS; IF (allCopies) THEN -- requested duplex copies -- -- valRC := validateBackupSet0(tag => restoreTag, tagMatchRequired => TRUE, checkDeviceIsAllocated => TRUE, validRec => validateRec); IF (valRC = SUCCESS) THEN GOTO addAnother; END IF; END IF; IF (lcopies > 1) THEN lcopies := lcopies - 1; ELSE EXIT; -- we are done END IF; END IF; END IF; END LOOP; CLOSE findSpfileBackup_c; IF (getBS_status = AVAILABLE) THEN deb(DEB_EXIT, 'with: AVAILABLE'); ELSIF (getBS_status = SUCCESS) THEN deb(DEB_EXIT, 'with: SUCCESS'); ELSE getBS_status := UNAVAILABLE; deb(DEB_EXIT, 'with: UNAVAILABLE'); END IF; END findSpfileBackup; -- FUNCTION getSpfileBackup( rcvRec OUT NOCOPY rcvRec_t ,redundancy IN number default NULL ,rmanCmd IN number default unknownCmd_t) RETURN number IS local rcvRec_t; dummy number; BEGIN deb(DEB_ENTER, 'getSpfileBackup'); IF (NOT findSpfileBackupCursor) THEN -- findSpfileBackup(allcopies => FALSE, redundancy => redundancy, rmanCmd => rmanCmd, scn_warn => dummy); END IF; IF (getRecStackCount = 0) THEN IF (getBS_status = SUCCESS) THEN deb(DEB_EXIT, 'with no more records'); raise no_data_found; ELSIF (getBS_status = AVAILABLE) THEN deb(DEB_EXIT, 'with: AVAILABLE'); RETURN AVAILABLE; ELSE deb(DEB_EXIT, 'with: UNAVAILABLE'); RETURN UNAVAILABLE; END IF; END IF; rcvRecPop(local); IF (debug) THEN printRcvRec(local); END IF; rcvRec := local; deb(DEB_EXIT, 'with: SUCCESS'); RETURN SUCCESS; END getSpfileBackup; -- PROCEDURE getCopyofDatafile( first IN boolean ,itag IN varchar2 ,fno OUT number ,crescn OUT number ,rlogscn OUT number ,rlgtime OUT date ,recid OUT binary_integer ,stamp OUT binary_integer ,name OUT varchar2 ,otag OUT varchar2 ,status OUT varchar2 ,nblocks OUT binary_integer ,bsz OUT binary_integer ,ctime OUT date ,toscn OUT number ,totime OUT date ,pluggedRonly OUT binary_integer ,pluginSCN OUT number ,pluginRlgSCN OUT number ,pluginRlgTime OUT date) IS inc_idx binary_integer; BEGIN deb(DEB_ENTER, 'getCopyofDatafile'); IF first THEN IF (getCopyofDatafile_c2%ISOPEN) THEN CLOSE getCopyofDatafile_c2; END IF; deb(DEB_PRINT, 'opening cursor'); OPEN getCopyofDatafile_c2(itag); END IF; <> FETCH getCopyofDatafile_c2 INTO fno, crescn, rlogscn, rlgtime, recid, stamp, name, otag, status, nblocks, bsz, ctime, toscn, totime, pluggedRonly, pluginSCN, pluginRlgSCN, pluginRlgTime; IF getCopyofDatafile_c2%NOTFOUND THEN deb(DEB_PRINT, 'closing cursor'); CLOSE getCopyofDatafile_c2; deb(DEB_EXIT, 'with: no data found'); RAISE no_data_found; END IF; FOR inc_idx in 0..max_inc_idx-1 LOOP IF (rlogscn = inc_list(inc_idx).resetlogs_change# AND rlgtime = inc_list(inc_idx).resetlogs_time ) THEN IF (inc_idx = 0 OR toscn <= inc_list(inc_idx-1).resetlogs_change#) THEN deb(DEB_PRINT, 'matches inc=' ||inc_idx); -- -- -- -- -- -- -- -- EXIT; -- ELSE deb(DEB_PRINT, 'inc='||inc_idx|| ',toscn='||toscn|| ' exceeds '||inc_list(inc_idx-1).resetlogs_change#); deb(DEB_PRINT, 'belongs to orphan branch of this incarnation:'); GOTO next; END IF; END IF; END LOOP; deb(DEB_EXIT, 'with: file found'); END getCopyOfDatafile; -- -- PROCEDURE getCopyofDatafile( dfnumber IN number ,itag IN varchar2 ,crescn IN OUT number ,rlogscn IN OUT number ,rlgtime IN OUT date ,recid OUT binary_integer ,stamp OUT binary_integer ,name OUT varchar2 ,otag OUT varchar2 ,status OUT varchar2 ,nblocks OUT binary_integer ,bsz OUT binary_integer ,ctime OUT date ,toscn OUT number ,totime OUT date ,pluggedRonly OUT binary_integer ,pluginSCN IN number) IS BEGIN OPEN getCopyofDatafile_c(dfnumber, itag, crescn, rlogscn, rlgtime, pluginSCN); FETCH getCopyofDatafile_c INTO recid, stamp, name, otag, status, nblocks, bsz, ctime, toscn, totime, crescn, rlogscn, rlgtime, pluggedRonly; IF getCopyofDatafile_c%NOTFOUND THEN CLOSE getCopyofDatafile_c; RAISE no_data_found; END IF; CLOSE getCopyofDatafile_c; END getCopyOfDatafile; -- PROCEDURE getCopyofDatafile( dfnumber IN number ,itag IN varchar2 ,crescn IN number ,rlogscn IN number ,rlgtime IN date ,recid OUT binary_integer ,stamp OUT binary_integer ,name OUT varchar2 ,otag OUT varchar2 ,status OUT varchar2 ,nblocks OUT binary_integer ,bsz OUT binary_integer ,ctime OUT date ,toscn OUT number ,totime OUT date) IS loc_crescn number := crescn; loc_rlogscn number := rlogscn; loc_rlgtime date := rlgtime; pluggedRonly binary_integer; pluginSCN number; BEGIN getCopyOfDatafile(dfnumber => dfnumber ,itag => itag ,crescn => loc_crescn ,rlogscn => loc_rlogscn ,rlgtime => loc_rlgtime ,recid => recid ,stamp => stamp ,name => name ,otag => otag ,status => status ,nblocks => nblocks ,bsz => bsz ,ctime => ctime ,toscn => toscn ,totime => totime ,pluggedRonly => pluggedRonly ,pluginSCN => 0); END getCopyOfDatafile; -- -- -- -- PROCEDURE setCompletedRange( after IN date ,before IN date) IS BEGIN getRA_completedAfter := after; getRA_completedBefore := before; END setCompletedRange; -- PROCEDURE setLikePattern( pattern IN varchar2) IS BEGIN getRA_likePattern := pattern; END setLikePattern; -- PROCEDURE setcanApplyAnyRedo( flag IN boolean) IS BEGIN IF (flag) THEN deb(DEB_PRINT, 'canApplyAnyRedo is set to TRUE'); canApplyAnyRedo := TRUE#; ELSE deb(DEB_PRINT, 'canApplyAnyRedo is set to FALSE'); canApplyAnyRedo := FALSE#; END IF; END setcanApplyAnyRedo; -- PROCEDURE setCanConvertCf( flag IN boolean) IS BEGIN IF (flag) THEN deb(DEB_PRINT, 'canConvert_Cf is set to TRUE'); canConvert_Cf := TRUE#; ELSE deb(DEB_PRINT, 'canConvert_Cf is set to FALSE'); canConvert_Cf := FALSE#; END IF; END setCanConvertCf; -- PROCEDURE setAllIncarnations( flag IN boolean) IS BEGIN IF (flag) THEN deb(DEB_PRINT, 'allIncarnations is set to TRUE'); allIncarnations := TRUE#; ELSE deb(DEB_PRINT, 'allIncarnations is set to FALSE'); allIncarnations := FALSE#; END IF; END setAllIncarnations; -- FUNCTION isTranslatedFno(fno IN NUMBER) RETURN NUMBER IS BEGIN IF (tc_database = TRUE# OR fno = 0 OR tc_fno.exists(fno)) THEN RETURN TRUE#; ELSE RETURN FALSE#; END IF; END isTranslatedFno; -- PROCEDURE setUntilResetlogs IS BEGIN untilSCN := this_reset_scn; untilTime := NULL; rpoint_set := FALSE; IF (this_reset_scn is NULL) THEN raise_application_error(-20020, 'Database incarnation not set'); END IF; END setUntilResetlogs; -- PROCEDURE setGuid( guid IN varchar2 DEFAULT NULL) IS BEGIN guidQualifier := guid; -- guid2pdbKeyQualifier := guidToPdbKey(guid); -- END setGuid; -- -- -- -- PROCEDURE translateTempfile IS BEGIN IF (translateTempfile_c%ISOPEN) THEN validateState('translateTempfile_c'); -- raise the error END IF; IF (pdbIdList.count = 0) THEN OPEN translateTempfile_c; getTempfileCursor := 'translateTempfile_c'; ELSIF (pdbIdList.count = 1) THEN OPEN translateTempfileOfPdbId_c(pdbIdList.first + CONST2GVAL); getTempfileCursor := 'translateTempfileOfPdbId_c'; ELSE OPEN translateTempfileOfPdbIdL_c; getTempfileCursor := 'translateTempfileOfPdbIdL_c'; END IF; END translateTempfile; -- PROCEDURE translateTempfile( fname IN varchar2) IS BEGIN IF (translateTempfileName_c%ISOPEN) THEN validateState('translateTempfileName_c'); -- raise the error END IF; OPEN translateTempfileName_c(fileName => fname); getTempfileCursor := 'translateTempfileName_c'; END translateTempfile; -- PROCEDURE translateTempfile( fno IN number) IS BEGIN IF (translateTempfileNumber_c%ISOPEN) THEN validateState('translateTempfileNumber_c'); -- raise the error END IF; OPEN translateTempfileNumber_c(fno => fno); getTempfileCursor := 'translateTempfileNumber_c'; END translateTempfile; -- PROCEDURE getTempfile( tfRec OUT NOCOPY tfRec_t) IS eof boolean := FALSE; BEGIN IF (getTempfileCursor = 'translateTempfile_c') THEN FETCH translateTempfile_c INTO tfRec; IF (translateTempfile_c%NOTFOUND) THEN CLOSE translateTempfile_c; eof := TRUE; END IF; ELSIF (getTempfileCursor = 'translateTempfileOfPdbId_c') THEN FETCH translateTempfileOfPdbId_c INTO tfRec; IF (translateTempfileOfPdbId_c%NOTFOUND) THEN CLOSE translateTempfileOfPdbId_c; eof := TRUE; END IF; ELSIF (getTempfileCursor = 'translateTempfileOfPdbIdL_c') THEN FETCH translateTempfileOfPdbIdL_c INTO tfRec; IF (translateTempfileOfPdbIdL_c%NOTFOUND) THEN CLOSE translateTempfileOfPdbIdL_c; eof := TRUE; END IF; ELSIF (getTempfileCursor = 'translateTempfileName_c') THEN FETCH translateTempfileName_c INTO tfRec; IF (translateTempfileName_c%NOTFOUND) THEN CLOSE translateTempfileName_c; eof := TRUE; END IF; ELSIF (getTempfileCursor = 'translateTempfileNumber_c') THEN FETCH translateTempfileNumber_c INTO tfRec; IF (translateTempfileNumber_c%NOTFOUND) THEN CLOSE translateTempfileNumber_c; eof := TRUE; END IF; ELSE deb(DEB_EXIT, 'with error 20204'); raise_application_error(-20204, 'Translation not started'); END IF; IF (eof) THEN getTempfileCursor := NULL; RAISE no_data_found; -- signal end-of-fetch END IF; -- -- -- IF (tfRec.pdbName IS NULL) THEN tfRec.pdbName := translatePdb2Name(tfRec.pdbid); END IF; END getTempfile; -- PROCEDURE translateDatafileCancel IS BEGIN IF (getDatafileCursor = 'translateDatafileName') THEN CLOSE translateDatafileName; ELSIF (getDatafileCursor = 'translateDatafileNumber') THEN CLOSE translateDatafileNumber; ELSIF (getDatafileCursor = 'translateDatafileCheckpoint') THEN CLOSE translateDatafileCheckpoint; END IF; getDatafileCursor := NULL; -- we closed it above getDatafileNoRows.error := NULL; -- clear for next time getDatafileLast.dfNumber := NULL; -- clear for next time END translateDatafileCancel; -- FUNCTION Num2DisplaySize(input_size IN NUMBER) return VARCHAR2 IS OneK number := 1024; OneM number := OneK * 1024; OneG number := OneM * 1024; OneT number := OneG * 1024; OneP number := OneT * 1024; BEGIN IF input_size IS NULL THEN return NULL; ELSE IF (input_size < OneM) THEN return to_char(input_size/OneK,'9990.09') ||'K'; ELSIF (input_size < OneG) THEN return to_char(input_size/OneM,'9990.09') ||'M'; ELSIF (input_size < OneT) THEN return to_char(input_size/OneG,'9990.09') ||'G'; ELSIF (input_size < OneP) THEN return to_char(input_size/OneT,'9990.09') ||'T'; ELSE return to_char(input_size/OneP,'9990.09') ||'P'; END IF; END IF; END Num2DisplaySize; -- FUNCTION Sec2DisplayTime(input_secs IN NUMBER) return VARCHAR2 IS inputsecs number ; BEGIN IF input_secs IS NULL THEN return NULL; END IF; inputsecs := round(input_secs) ; RETURN to_char(floor(inputsecs/3600),'FM09')||':'|| to_char(floor(mod(inputsecs,3600)/60),'FM09')||':'|| to_char(mod(inputsecs,60),'FM09'); END Sec2DisplayTime; -- PROCEDURE setArchivedLogRecord( thread# IN number ,sequence# IN number ,first IN boolean) IS seqTab sequenceTab_t; thrbck binary_integer; seqbck binary_integer; BEGIN IF first THEN tc_threadSeq.delete; END IF; -- IF (thread# >= CONST2GVAL) THEN thrbck := CONST2GVAL - thread#; ELSE thrbck := thread#; END IF; -- IF (sequence# >= CONST2GVAL) THEN seqbck := CONST2GVAL - sequence#; ELSE seqbck := sequence#; END IF; IF NOT tc_threadSeq.exists(thrbck) THEN tc_threadSeq(thrbck) := seqTab; END IF; tc_threadseq(thrbck)(seqbck) := TRUE; END setArchivedLogRecord; -- PROCEDURE setCanHandleTransportableTbs( flag IN boolean) IS BEGIN IF (flag) THEN deb(DEB_PRINT, 'canHandleTransportableTbs is set to TRUE'); canHandleTransportableTbs := TRUE#; ELSE deb(DEB_PRINT, 'canHandleTransportableTbs is set to FALSE'); canHandleTransportableTbs := FALSE#; END IF; END setCanHandleTransportableTbs; -- PROCEDURE getRestorePoint( name IN varchar2 ,rlgscn OUT number ,rlgtime OUT date ,scn OUT number ,guaranteed OUT number) IS clean number; out_con_id number; BEGIN getRestorePoint(name, rlgscn, rlgtime, scn, guaranteed, 0, clean, out_con_id); END getRestorePoint; PROCEDURE getRestorePoint( name IN varchar2 ,rlgscn OUT number ,rlgtime OUT date ,scn OUT number ,guaranteed OUT number ,con_id IN number ,clean OUT number ,out_con_id OUT number) IS rsp restore_point_c%ROWTYPE; rsp2 restore_point_c%ROWTYPE; BEGIN deb(DEB_ENTER, 'getRestorePoint'); IF (restore_point_c%isopen) THEN CLOSE restore_point_c; END IF; OPEN restore_point_c(con_id, name); FETCH restore_point_c INTO rsp; IF restore_point_c%NOTFOUND THEN rlgscn := NULL; rlgtime := NULL; scn := NULL; guaranteed := NULL; clean := NULL; ELSE rlgscn := rsp.reset_scn; rlgtime := rsp.reset_time; scn := rsp.scn; out_con_id := rsp.con_id; IF (rsp.clean = 'YES') THEN clean := 1; ELSE clean := 0; END IF; IF (rsp.guaranteed = 'YES') THEN guaranteed := 1; ELSE guaranteed := 0; END IF; END IF; FETCH restore_point_c INTO rsp2; -- IF ((NOT restore_point_c%NOTFOUND) AND (rsp.con_id = rsp2.con_id)) THEN deb(DEB_EXIT, 'with error 20513'); raise_application_error(-20513, 'Restore point name is ambiguous, specify the SCN instead'); END IF; CLOSE restore_point_c; deb(DEB_EXIT); END getRestorePoint; -- PROCEDURE listTranslateRestorePoint( name IN varchar2) IS BEGIN deb(DEB_ENTER, 'listTranslateRestorePoint'); IF (restore_point_c%isopen) THEN CLOSE restore_point_c; END IF; deb(DEB_OPEN, 'restore_point_c'); OPEN restore_point_c(con_id => 0, name => name); deb(DEB_EXIT); END listTranslateRestorePoint; -- PROCEDURE listGetRestorePoint( name OUT varchar2 ,scn OUT number ,rsptime OUT date ,cretime OUT date ,rsptype OUT varchar2) IS pdbname varchar2(128); BEGIN listGetRestorePoint(name, scn, rsptime, cretime, rsptype, pdbname); END listGetRestorePoint; PROCEDURE listGetRestorePoint( name OUT varchar2 ,scn OUT number ,rsptime OUT date ,cretime OUT date ,rsptype OUT varchar2 ,pdbname OUT varchar2) IS rsp restore_point_c%ROWTYPE; BEGIN deb(DEB_ENTER, 'listGetRestorePoint'); FETCH restore_point_c INTO rsp; IF (restore_point_c%NOTFOUND) THEN CLOSE restore_point_c; deb(DEB_EXIT, 'with no more records'); RAISE no_data_found; END IF; name := rsp.name; scn := rsp.scn; rsptime := rsp.restore_point_time; cretime := rsp.creation_time; -- rsptype := ' '; IF rsp.preserved = 'YES' THEN rsptype := 'PRESERVED'; END IF; -- IF rsp.guaranteed = 'YES' THEN rsptype := 'GUARANTEED'; END IF; pdbname := translatePdb2Name(rsp.con_id); deb(DEB_EXIT); END listGetRestorePoint; -- PROCEDURE setDbidTransClause(dbid IN number) IS dbidbck binary_integer; BEGIN -- IF (dbid >= CONST2GVAL) THEN dbidbck := CONST2GVAL - dbid; ELSE dbidbck := dbid; END IF; tc_dbid(dbidbck) := TRUE; END setDbidTransClause; -- FUNCTION isTranslatedDbid(dbid IN NUMBER) RETURN NUMBER IS dbidbck binary_integer; BEGIN IF (tc_anydbid = TRUE#) THEN RETURN TRUE#; ELSE -- IF (dbid >= CONST2GVAL) THEN dbidbck := CONST2GVAL - dbid; ELSE dbidbck := dbid; END IF; IF (tc_dbid.exists(dbidbck)) THEN RETURN TRUE#; END IF; END IF; RETURN FALSE#; END isTranslatedDbid; -- FUNCTION translatePdbName(pdbName IN VARCHAR2) RETURN NUMBER IS BEGIN initPdbNameList; IF (pdbNameList.exists(pdbName)) THEN RETURN pdbNameList(pdbName); ELSE RETURN NULL; END IF; END translatePdbName; -- PROCEDURE resetPdbIdList IS BEGIN pdbIdList.delete; END resetPdbIdList; -- PROCEDURE setPdbId(pdbId IN NUMBER, first IN BOOLEAN) IS BEGIN IF (first) THEN resetPdbIdList; END IF; pdbIdList(pdbId - CONST2GVAL) := TRUE; END setPdbId; -- FUNCTION isTranslatedPdbId(pdbId IN NUMBER) RETURN NUMBER IS BEGIN IF (pdbIdList.exists(pdbId - CONST2GVAL)) THEN RETURN TRUE#; END IF; RETURN FALSE#; END isTranslatedPdbId; -- FUNCTION isPdbScnOrphan(untilSCN IN NUMBER, pdbId IN NUMBER) RETURN NUMBER IS toSCN NUMBER := untilSCN - 1; BEGIN IF (isPdbScnOrphan(0, toSCN, 0, pdbId)) THEN RETURN TRUE#; ELSE RETURN FALSE#; END IF; END isPdbScnOrphan; -- FUNCTION translatePdb2Name(pdbId IN NUMBER) RETURN VARCHAR2 IS pdbname VARCHAR2(128); BEGIN -- -- IF (pdbId IS NULL) THEN RETURN NULL; END IF; IF (pdbId <= 1) THEN RETURN NULL; END IF; initPdbNameList; pdbname := pdbNameList.first; WHILE pdbname IS NOT NULL LOOP IF (pdbNameList(pdbname) = pdbId) THEN RETURN pdbname; END IF; pdbname := pdbNameList.next(pdbname); END LOOP; RETURN NULL; END translatePdb2Name; -- PROCEDURE setRestoreRangeDevTyp(typ IN VARCHAR2) IS BEGIN deb(DEB_ENTER, 'setRestoreRangeDevTyp'); restoreRangeDevTyp := typ; deb(DEB_EXIT); END setRestoreRangeDevTyp; -- PROCEDURE setSkipOfflineRangeAboveSCN(maxCheckpointSCN IN NUMBER) IS BEGIN deb(DEB_ENTER, 'setSkipOfflineRangeAboveSCN'); skipOfflineRangeAboveSCN := maxCheckpointSCN; deb(DEB_EXIT); END setSkipOfflineRangeAboveSCN; -- PROCEDURE resetRestoreRangeDevTyp IS BEGIN deb(DEB_ENTER, 'resetRestoreRangeDevTyp'); restoreRangeDevTyp := null; deb(DEB_EXIT); END resetRestoreRangeDevTyp; -- PROCEDURE translatePrePluginDf(con_id IN number) IS BEGIN deb(DEB_ENTER, 'translatePrePluginDf'); -- raise_application_error(-20999, 'Not supported in recovery catalog'); -- deb(DEB_EXIT); END translatePrePluginDf; -- FUNCTION getPrePluginDf( prePluginDfRec OUT NOCOPY prePluginDfRec_t) RETURN NUMBER IS BEGIN deb(DEB_ENTER, 'getPrePluginDf'); -- raise_application_error(-20999, 'Not supported in recovery catalog'); -- deb(DEB_EXIT, 'with FALSE#'); RETURN FALSE#; END getPrePluginDf; -- PROCEDURE setBigScnAware IS BEGIN deb(DEB_PRINT, 'Database is BIGSCN aware, higscnval set to UB8MAXVAL'); highscnval := UB8MAXVAL; END setBigScnAware; -- FUNCTION isNoBackupPdb(pdbname IN VARCHAR2) RETURN NUMBER IS nobackup NUMBER; BEGIN deb(DEB_ENTER, 'isNoBackupPdb'); IF (translateNoBackupPdb_c%ISOPEN) THEN CLOSE translateNoBackupPdb_c; END IF; OPEN translateNoBackupPdb_c(pdbname => pdbname); FETCH translateNoBackupPdb_c INTO nobackup; IF (translateNoBackupPdb_c%NOTFOUND) THEN nobackup := 0; END IF; CLOSE translateNoBackupPdb_c; deb(DEB_EXIT, 'with '||nobackup); RETURN nobackup; END isNoBackupPdb; -- -- -- -- PROCEDURE listApplicationPdbs( root_con_id IN number) IS BEGIN deb(DEB_ENTER, 'listApplicationPdbs'); -- raise_application_error(-20999, 'Not supported in recovery catalog'); -- deb(DEB_EXIT); END listApplicationPdbs; -- FUNCTION listGetAppPdb( pdb_name OUT varchar2) RETURN number IS BEGIN deb(DEB_ENTER, 'listGetAppPdb'); deb(DEB_EXIT); END listGetAppPdb; -- -- -- -- BEGIN -- -- versionList(1) := '08.00.04.00'; versionList(2) := '08.00.05.00'; versionList(3) := '08.01.03.00'; versionList(4) := '08.01.05.00'; versionList(5) := '08.01.06.00'; versionList(6) := '08.01.07.00'; versionList(7) := '09.00.00.00'; versionList(8) := '09.02.00.00'; versionList(9) := '10.01.00.00'; versionList(10):= '10.02.00.00'; versionList(11):= '10.02.00.01'; versionList(12):= '11.01.00.00'; versionList(13):= '11.01.00.01'; versionList(14):= '11.01.00.02'; versionList(15):= '11.01.00.03'; versionList(16):= '11.01.00.04'; versionList(17):= '11.01.00.05'; versionList(18):= '11.01.00.06'; versionList(19):= '11.01.00.07'; versionList(20):= '11.02.00.00'; versionList(21):= '11.02.00.01'; versionList(22):= '11.02.00.02'; versionList(23):= '12.01.00.00'; versionList(24):= '12.01.00.01'; versionList(25):= '12.01.00.02'; versionList(26):= '12.02.00.00'; versionList(27):= '12.02.00.01'; -- versionCounter := 1; versionMaxIndex := 27; -- must match highest index used above resetAll; -- init package variables to defaults END dbms_rcvman; >>> define prvtrvpc_plb <<< -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- CREATE OR REPLACE PACKAGE BODY dbms_rcvvpc AS g_catowner_uid CONSTANT user_users.username%TYPE := SYS_CONTEXT('USERENV', 'CURRENT_USERID'); FUNCTION is_ra RETURN BOOLEAN; this_is_ra CONSTANT BOOLEAN := is_ra; SUBTYPE predicate_t IS VARCHAR2(256); TYPE predicates_t IS VARRAY(14) OF predicate_t; g_p CONSTANT predicates_t := predicates_t( 'filter_user = SYS_CONTEXT(''USERENV'', ''SESSION_USER'')' -- 1 , 'db_id IN (SELECT vpc.db_id FROM vpc_databases vpc)' -- 2 , 'db_key IN (SELECT db.db_key FROM db)' -- 3 , 'pdb_key IN (SELECT pdb.pdb_key FROM pdb)' -- 4 , 'dbinc_key IN (SELECT dbinc.dbinc_key FROM dbinc)' -- 5 , 'db_key IN (SELECT db.db_key FROM db) OR db_key IS NULL' -- 6 , 'bdf_key IN (SELECT bdf.bdf_key FROM bdf)' -- 7 , 'cdf_key IN (SELECT cdf.cdf_key FROM cdf)' -- 8 , 'scr_key IN (SELECT scr.scr_key FROM scr)' -- 9 , 'EXISTS (SELECT NULL FROM vpc_databases)' -- 10 , 'df_key IN (SELECT df.df_key FROM df)' -- 11 , 'created_user = SYS_CONTEXT(''USERENV'', ''SESSION_USER'')' -- 12 , 'filter_user = SYS_CONTEXT(''USERENV'', ''SESSION_USER'')' -- 13 , 'site_key IN (SELECT node.site_key FROM node)' -- 14 ); FUNCTION is_ra RETURN BOOLEAN IS l_owner all_users.username%TYPE; BEGIN EXECUTE IMMEDIATE 'BEGIN :owner := dbms_rai_owner; END;' USING OUT l_owner; RETURN (l_owner IS NOT NULL); EXCEPTION WHEN OTHERS THEN RETURN FALSE; END is_ra; PROCEDURE p ( i_table VARCHAR2 , i_msg VARCHAR2 DEFAULT NULL ) IS BEGIN $IF FALSE $THEN sys.dbms_system.ksdwrt ( sys.dbms_system.alert_file , 'filter_client_data: ' || SYS_CONTEXT('USERENV', 'SID') || ' ' || i_table || ' ' || SYS_CONTEXT('USERENV', 'CURRENT_USER') || ' ' || SYS_CONTEXT('USERENV', 'SESSION_USER') || ' [' || i_msg || ']' ); $ELSE NULL; $END END p; FUNCTION filter_pass_all ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN NULL; END filter_pass_all; FUNCTION f_p ( i_table IN VARCHAR2 , i_predicate IN BINARY_INTEGER ) RETURN VARCHAR2 IS BEGIN -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- IF (SYS_CONTEXT('USERENV', 'SESSION_USERID') IN (g_catowner_uid, 0)) THEN p(i_table, NULL); RETURN NULL; ELSE p(i_table, g_p(i_predicate)); RETURN g_p(i_predicate) || CASE WHEN this_is_ra THEN q'{ OR SYS_CONTEXT('SYS_SESSION_ROLES','RA_CATALOG_SELECT')='TRUE'}' END || q'{ OR SYS_CONTEXT('SYS_SESSION_ROLES','RMAN_CATALOG_ACCESS')='TRUE'}'; END IF; END f_p; FUNCTION f_vpc_databases ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 1); END f_vpc_databases; FUNCTION f_db ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 2); END f_db; FUNCTION f_dbinc ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 3); END f_dbinc; FUNCTION f_bp ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 3); END f_bp; FUNCTION f_bsf ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 3); END f_bsf; FUNCTION f_bs ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 3); END f_bs; FUNCTION f_conf ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 3); END f_conf; FUNCTION f_deleted_object ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 3); END f_deleted_object; FUNCTION f_do_seq ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 3); END f_do_seq; FUNCTION f_node ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 3); END f_node; FUNCTION f_pdb ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 3); END f_pdb; FUNCTION f_rout ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 3); END f_rout; FUNCTION f_watermarks ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 3); END f_watermarks; FUNCTION f_sbt_template_db ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 3); END f_sbt_template_db; FUNCTION f_rrcache ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 3); END f_rrcache; FUNCTION f_pdbinc ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 4); END f_pdbinc; FUNCTION f_pdb_dbinc ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 4); END f_pdb_dbinc; FUNCTION f_al ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_al; FUNCTION f_bcf ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_bcf; FUNCTION f_bdf ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_bdf; FUNCTION f_brl ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_brl; FUNCTION f_ccf ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_ccf; FUNCTION f_cdf ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_cdf; FUNCTION f_ckp ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_ckp; FUNCTION f_df ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_df; FUNCTION f_fb ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_fb; FUNCTION f_grsp ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_grsp; FUNCTION f_nrsp ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_nrsp; FUNCTION f_offr ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_offr; FUNCTION f_orl ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_orl; FUNCTION f_rlh ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_rlh; FUNCTION f_rr ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_rr; FUNCTION f_rsr ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_rsr; FUNCTION f_rt ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_rt; FUNCTION f_tf ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_tf; FUNCTION f_tsatt ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_tsatt; FUNCTION f_ts ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_ts; FUNCTION f_xal ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_xal; FUNCTION f_xcf ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_xcf; FUNCTION f_xdf ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 5); END f_xdf; FUNCTION f_scr ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 6); END f_scr; FUNCTION f_bcb ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 7); END f_bcb; FUNCTION f_ccb ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 8); END f_ccb; FUNCTION f_scrl ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 9); END f_scrl; FUNCTION f_cfs ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 10); END f_cfs; FUNCTION f_config ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 10); END f_config; FUNCTION f_orsevent ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 10); END f_orsevent; FUNCTION f_rcfile ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 10); END f_rcfile; FUNCTION f_bcr ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 11); END f_bcr; FUNCTION f_xmlstore ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 12); END f_xmlstore; FUNCTION f_server ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 13); END f_server; FUNCTION f_vpc_users ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 13); END f_vpc_users; FUNCTION f_site_dfatt ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 14); END f_site_dfatt; FUNCTION f_site_tfatt ( schema_p IN VARCHAR2 , table_p IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN f_p(table_p, 14); END f_site_tfatt; END dbms_rcvvpc; >>> define create_catalog_lock1 <<< -- -- -- create or replace function get_lock_on_catalog (lock_type IN integer) return integer authid current_user is lock_handle varchar2(128); ret integer; str1 varchar2(256); str2 varchar2(100); x_mode number; s_mode number; begin -- -- -- -- -- -- -- -- -- -- str2 := 'ORA$RMAN_CATALOG_LOCK'; str1 := 'begin dbms_lock.allocate_unique(:1||dbms_catowner, :2,'|| ' 2147483647); end;'; execute immediate str1 using str2, out lock_handle; ret := -1; -- -- str1 := 'begin :1 := dbms_lock.X_MODE ; :2 := dbms_lock.S_MODE; end;'; execute immediate str1 using out x_mode, out s_mode; if (lock_type = x_mode) then -- if (user = dbms_catowner) then -- -- -- str1 := 'begin :1 := dbms_lock.convert(:2, dbms_lock.X_MODE,1); end;'; execute immediate str1 using out ret, lock_handle; -- -- -- -- -- if (ret = 4) then -- str1 := 'begin :1 := dbms_lock.request(:2, dbms_lock.X_MODE, 1, '|| ' FALSE); end;'; execute immediate str1 using out ret, lock_handle; end if; end if; elsif (lock_type = s_mode) then if (user = dbms_catowner) then -- -- str1 := 'begin :1 := dbms_lock.request(:2, dbms_lock.S_MODE, 1, '|| ' FALSE); end;'; execute immediate str1 using out ret, lock_handle; -- -- -- if (ret != 0) then str1 := 'begin :1 := dbms_lock.convert(:2, dbms_lock.S_MODE, 1);'|| ' end;'; execute immediate str1 using out ret, lock_handle; -- -- if (ret != 0) then ret := 1; end if; end if; -- else str1 := 'begin :1 := dbms_lock.request(:2, dbms_lock.S_MODE, 1,'|| ' FALSE); end;'; execute immediate str1 using OUT ret, lock_handle; end if; end if; return ret; end get_lock_on_catalog; >>> define create_catalog_lock2 <<< -- -- grant execute on get_lock_on_catalog to recovery_catalog_owner, recovery_catalog_user >>> define upgcat_1 <<< alter table ckp add (ckp_db_status VARCHAR2(7)) >>> define upgcat_2 <<< alter table ts add CONSTRAINT ts_u2 UNIQUE (dbinc_key, ts_name, create_scn) >>> define upgcat_3 <<< alter table df add (clone_fname VARCHAR2(1024)) >>> define upgcat_4 <<< alter table bdf add (completion_time date) >>> define upgcat_5 <<< alter table offr add (cf_create_time date) >>> define upgcat_6 <<< alter table offr drop constraint offr_u2 drop index >>> define upgcat_7 <<< alter table offr add constraint offr_u2 UNIQUE (dbinc_key, file#, create_scn, offline_scn, cf_create_time) >>> define upgcat_9 <<< alter table df add (stop_scn number) >>> define upgcat_10 <<< alter table df add (read_only number) >>> define upgcat_11 <<< update df set stop_scn = null, read_only = 0 where read_only is null>>> define upgcat_12 <<< alter table df modify (read_only not null) >>> define upgcat_15 <<< alter table bp add (media_pool number) >>> define upgcat_16 <<< alter table bp add (copy# number) >>> define upgcat_17 <<< update bp set copy# = 1 where copy# is null>>> define upgcat_18 <<< alter table bp modify (copy# not null) >>> define upgcat_19 <<< alter table bp drop constraint bp_c_status drop index >>> define upgcat_20 <<< alter table bp add constraint bp_c_status check (status in ('A','U','D','X')) >>> define upgcat_21 <<< alter table dbinc add (high_pc_recid number default 0) >>> define upgcat_22 <<< update dbinc set high_pc_recid = 0 >>> define upgcat_23 <<< alter table dbinc modify (high_pc_recid not null) >>> define upgcat_24 <<< alter table rlh add constraint rlh_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE >>> define upgcat_25 <<< alter table al add constraint al_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE >>> define upgcat_26 <<< alter table ccf add constraint ccf_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE >>> define upgcat_27 <<< alter table xcf add constraint xcf_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE >>> define upgcat_28 <<< alter table cdf add constraint cdf_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE >>> define upgcat_29 <<< alter table xdf add constraint xdf_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE >>> define upgcat_30 <<< alter table bs modify (bs_recid NULL) >>> define upgcat_31 <<< alter table bs modify (bs_stamp NULL) >>> define upgcat_32 <<< alter table bs modify (bck_type NULL) >>> define upgcat_33 <<< alter table bs modify (incr_level NULL) >>> define upgcat_34 <<< alter table bs modify (status NULL) >>> define upgcat_35 <<< alter table bs drop constraint bs_u1 drop index >>> define upgcat_36 <<< alter table bs modify (start_time NULL) >>> define upgcat_37 <<< alter table bs modify (completion_time NULL) >>> define upgcat_38 <<< alter table df add (stop_time date) >>> define upgcat_39 <<< alter table bcf add (controlfile_type varchar2(1) NULL) >>> define upgcat_40 <<< alter table bcf add CONSTRAINT bcf_c_cf_type CHECK (controlfile_type in ('S','B')) >>> define upgcat_41 <<< alter table bs add (controlfile_included varchar2(7) NULL) >>> define upgcat_42 <<< alter table bs add CONSTRAINT bs_c_controlfile_included CHECK (controlfile_included in ('NONE','BACKUP','STANDBY')) >>> define upgcat_43 <<< alter table ccf add (controlfile_type varchar2(1) NULL) >>> define upgcat_44 <<< alter table ccf add CONSTRAINT ccf_c_cf_type CHECK (controlfile_type in ('S','B')) >>> define upgcat_45 <<< alter table xcf add (controlfile_type varchar2(1) NULL) >>> define upgcat_46 <<< alter table xcf add CONSTRAINT xcf_c_cf_type CHECK (controlfile_type in ('S','B')) >>> define upgcat_47 <<< alter table al drop constraint al_u1 drop index >>> define upgcat_48 <<< alter table al add (is_standby varchar2(1) NULL) >>> define upgcat_49 <<< alter table al add constraint al_u1 UNIQUE (dbinc_key, al_recid, al_stamp, is_standby) >>> define upgcat_50 <<< alter table al add constraint al_c_is_standby CHECK (is_standby in ('Y','N')) >>> define upgcat_51 <<< alter table bs add (input_file_scan_only varchar2(3)) >>> define upgcat_52 <<< alter table al drop constraint al_c_status drop index >>> define upgcat_53 <<< alter table al add constraint al_c_status check (status in ('A','U','D','X')) >>> define upgcat_54 <<< alter table ccf drop constraint ccf_c_status drop index >>> define upgcat_55 <<< alter table ccf add constraint ccf_c_status check (status in ('A','U','D','X')) >>> define upgcat_58 <<< alter table db add (high_conf_recid number) >>> define upgcat_59 <<< alter table df add (rfile# number) >>> define upgcat_60 <<< alter table al add (dictionary_begin varchar2(3)) >>> define upgcat_61 <<< alter table al add (dictionary_end varchar2(3)) >>> define upgcat_62 <<< alter table ts add (included_in_database_backup varchar2(3) default 'YES') >>> define upgcat_63 <<< alter table bs add (keep_options NUMBER DEFAULT 0 NOT NULL) >>> define upgcat_64 <<< alter table bs add (keep_until DATE NULL) >>> define upgcat_65 <<< alter table xdf add (keep_options NUMBER DEFAULT 0 NOT NULL) >>> define upgcat_66 <<< alter table xdf add (keep_until DATE NULL) >>> define upgcat_67 <<< alter table xcf add (keep_options NUMBER DEFAULT 0 NOT NULL) >>> define upgcat_68 <<< alter table xcf add (keep_until DATE NULL) >>> define upgcat_69 <<< alter table cdf add (keep_options NUMBER DEFAULT 0 NOT NULL) >>> define upgcat_70 <<< alter table cdf add (keep_until DATE NULL) >>> define upgcat_71 <<< alter table ccf add (keep_options NUMBER DEFAULT 0 NOT NULL) >>> define upgcat_72 <<< alter table ccf add (keep_until DATE NULL) >>> define upgcat_73 <<< alter table bcf add (autobackup_date date) >>> define upgcat_74 <<< alter table bcf add (autobackup_sequence number) >>> define upgcat_75 <<< alter table ts add (included_in_database_backup varchar2(3) default 'YES') >>> define upgcat_76 <<< alter table bcf add (blocks number) >>> define upgcat_77 <<< alter table ckp drop constraint ckp_f2 drop index >>> define upgcat_78 <<< alter table ckp drop column prev_ckp_key >>> define upgcat_79 <<< alter table cdf add (scanned varchar2(1)) >>> define upgcat_80 <<< alter table bcb add (corruption_type varchar2(9)) >>> define upgcat_81 <<< alter table ccb add (corruption_type varchar2(9)) >>> define upgcat_82 <<< alter table db add (last_kccdivts number default 0) >>> define upgcat_99 <<< -- declare cursor broken_pieces is select bs_key, piece# from bp where copy# = 1 group by bs_key, piece# having count(piece#) > 1; cursor fix_piece(bskey number, pno number) is select bp_key from bp where bs_key = fix_piece.bskey and piece# = fix_piece.pno for update of copy#; rows_cnt number; rows_per_iteration number := 500; begin loop rows_cnt := 0; for bp in broken_pieces loop for fp in fix_piece(bp.bs_key, bp.piece#) loop rows_cnt := fix_piece%rowcount; update bp set copy# = rows_cnt where current of fix_piece; end loop; rows_cnt := broken_pieces%rowcount; exit when rows_cnt = rows_per_iteration; end loop; commit; exit when rows_cnt < rows_per_iteration; end loop; end; >>> define upgcat_100 <<< alter table dbinc add (high_bsf_recid NUMBER DEFAULT 0 NOT NULL) >>> define upgcat_101 <<< drop package dbms_rcvman >>> define upgcat_102 <<< alter table ts add (bigfile varchar2(3) default 'NO' NOT NULL) >>> define upgcat_103 <<< alter table dbinc add(dbinc_status VARCHAR2(8) DEFAULT 'ORPHAN' NOT NULL) >>> define upgcat_104 <<< alter table dbinc add constraint dbinc_status CHECK(dbinc_status in ('CURRENT', 'PARENT', 'ORPHAN')) >>> define upgcat_106 <<< alter table al add (is_recovery_dest_file VARCHAR2(3) DEFAULT 'NO' NOT NULL) >>> define upgcat_107 <<< alter table cdf add (is_recovery_dest_file VARCHAR2(3) DEFAULT 'NO' NOT NULL) >>> define upgcat_108 <<< alter table ccf add (is_recovery_dest_file VARCHAR2(3) DEFAULT 'NO' NOT NULL) >>> define upgcat_109 <<< alter table bp add (is_recovery_dest_file VARCHAR2(3) DEFAULT 'NO' NOT NULL) >>> define upgcat_110 <<< alter table bp add (bytes NUMBER DEFAULT NULL) >>> define upgcat_111 <<< alter table dbinc add (high_rsr_recid NUMBER DEFAULT 0 NOT NULL) >>> define upgcat_112 <<< alter table bp add (rsr_key number) >>> define upgcat_113 <<< alter table cdf add (rsr_key number) >>> define upgcat_114 <<< alter table ccf add (rsr_key number) >>> define upgcat_115 <<< alter table xdf add (rsr_key number) >>> define upgcat_116 <<< alter table xcf add (rsr_key number) >>> define upgcat_117 <<< update cdf set scanned='N' where scanned is null >>> define upgcat_118 <<< alter table cdf modify(scanned varchar2(1) DEFAULT 'N') >>> define upgcat_119 <<< alter table cdf modify(scanned varchar2(1) NOT NULL) >>> define upgcat_120 <<< alter table db modify(last_kccdivts NUMBER DEFAULT 0) >>> define upgcat_121 <<< update ts set included_in_database_backup='YES' where included_in_database_backup is null >>> define upgcat_122 <<< alter table ts modify(included_in_database_backup DEFAULT 'YES') >>> define upgcat_123 <<< alter table ts modify(included_in_database_backup NOT NULL) >>> define upgcat_124 <<< alter table bp add (compressed varchar2(3) DEFAULT 'NO') >>> define upgcat_125 <<< alter table al add (compressed varchar2(3) DEFAULT 'NO') >>> define upgcat_126 <<< alter table scr add (scr_comment varchar2(255)) >>> define upgcat_127 <<< alter table scr modify db_key null >>> define upgcat_128 <<< update bs set keep_options = 0 where keep_options is null >>> define upgcat_129 <<< alter table bs modify(keep_options NUMBER DEFAULT 0 NOT NULL) >>> define upgcat_130 <<< update xdf set keep_options = 0 where keep_options is null >>> define upgcat_131 <<< alter table xdf modify(keep_options NUMBER DEFAULT 0 NOT NULL) >>> define upgcat_132 <<< update xcf set keep_options = 0 where keep_options is null >>> define upgcat_133 <<< alter table xcf modify(keep_options NUMBER DEFAULT 0 NOT NULL) >>> define upgcat_134 <<< update cdf set keep_options = 0 where keep_options is null >>> define upgcat_135 <<< alter table cdf modify(keep_options NUMBER DEFAULT 0 NOT NULL) >>> define upgcat_136 <<< update ccf set keep_options = 0 where keep_options is null >>> define upgcat_137 <<< alter table ccf modify(keep_options NUMBER DEFAULT 0 NOT NULL) >>> define upgcat_138 <<< alter table conf add (db_unique_name VARCHAR2(512) DEFAULT NULL, cleanup VARCHAR2(3) DEFAULT 'YES') >>> define upgcat_139 <<< alter table conf drop constraint conf_p1 drop index >>> define upgcat_140 <<< alter table conf add constraint conf_f1 FOREIGN KEY(db_key) REFERENCES db ON DELETE CASCADE >>> define upgcat_141 <<< alter table bdf add (blocks_read number) >>> define upgcat_142 <<< update bdf set blocks_read = datafile_blocks where blocks_read is null >>> define upgcat_143 <<< alter table bdf modify(blocks_read NOT NULL) >>> define bp_i_rsr <<< CREATE INDEX bp_i_rsr on bp(rsr_key) &tablespace& >>> define cdf_i_rsr <<< CREATE INDEX cdf_i_rsr on cdf(rsr_key) &tablespace& >>> define ccf_i_rsr <<< CREATE INDEX ccf_i_rsr on ccf(rsr_key) &tablespace& >>> define xdf_i_rsr <<< CREATE INDEX xdf_i_rsr on xdf(rsr_key) &tablespace& >>> define xcf_i_rsr <<< CREATE INDEX xcf_i_rsr on xcf(rsr_key) &tablespace& >>> define xal_i_rsr <<< CREATE INDEX xal_i_rsr on xal(rsr_key) &tablespace& >>> define tsatt_i_sck <<< CREATE INDEX tsatt_i_sck on tsatt(start_ckp_key) &tablespace& >>> define tsatt_i_eck <<< CREATE INDEX tsatt_i_eck on tsatt(end_ckp_key) &tablespace& >>> define ckp_i_dbinc <<< CREATE INDEX ckp_i_dbinc on ckp(dbinc_key) &tablespace& >>> define rsr_i_dbinc <<< CREATE INDEX rsr_i_dbinc on rsr(dbinc_key) &tablespace& >>> define rsr_i_stamp <<< CREATE INDEX rsr_i_stamp on rsr(rsr_sstamp, rsr_srecid) &tablespace& >>> define rout_i_db <<< CREATE INDEX rout_i_db on rout(db_key) &tablespace& >>> define rout_i_rsr <<< CREATE INDEX rout_i_rsr on rout(rsr_key) &tablespace& >>> define rout_i_skey <<< CREATE INDEX rout_i_skey on rout(rout_skey) &tablespace& >>> define rout_i_site_key <<< CREATE INDEX rout_i_site_key on rout(site_key) &tablespace& >>> define upgcat_144 <<< alter table db add (high_ic_recid NUMBER DEFAULT 0) >>> define upgcat_145 <<< alter table bs add (block_size NUMBER DEFAULT NULL) >>> define upgcat_146 <<< -- -- -- -- -- declare cursor null_bs is select bs_key from bs where block_size is null; calblksize number; function getBSBlockSize(bs_key number) return number is blksize number := 0; begin begin select max(bdf.block_size) into blksize from bdf, bs where bdf.bs_key = bs.bs_key and bs.bs_key = getBSBlockSize.bs_key; return blksize; exception when no_data_found then null; end; begin select max(brl.block_size) into blksize from brl, bs where brl.bs_key = bs.bs_key and bs.bs_key = getBSBlockSize.bs_key; return blksize; exception when no_data_found then null; end; begin select max(bcf.block_size) into blksize from bcf, bs where bcf.bs_key = bs.bs_key and bs.bs_key = getBSBlockSize.bs_key; return blksize; exception when no_data_found then null; end; return null; end getBSBlockSize; begin for bs_rec in null_bs loop calblksize := getBSBlockSize(bs_rec.bs_key); if (calblksize != 0 and calblksize is not null) then update bs set block_size = calblksize where bs_key = bs_rec.bs_key; end if; end loop; end; >>> define upgcat_147 <<< alter table rsr add (rsr_ibytes NUMBER, rsr_obytes NUMBER, rsr_optimized VARCHAR2(3), rsr_otype VARCHAR2(80), rsr_srecid number, rsr_sstamp number, rsr_odevtype VARCHAR2(17)) >>> define upgcat_148 <<< alter table node add (high_rout_stamp NUMBER default 0, inst_startup_stamp NUMBER default 0) >>> define upgcat_149 <<< alter table ccf add (blocks NUMBER DEFAULT NULL) >>> define upgcat_150 <<< alter table xcf add (blocks NUMBER DEFAULT NULL) >>> define upgcat_151 <<< alter table cdf add (create_time DATE DEFAULT NULL, marked_corrupt NUMBER DEFAULT NULL) >>> define upgcat_152 <<< alter table bdf add (create_time DATE DEFAULT NULL, marked_corrupt NUMBER DEFAULT NULL, used_chg_track VARCHAR2(1) DEFAULT 'N', used_optim VARCHAR2(1) DEFAULT 'N') >>> define upgcat_153 <<< alter table xdf add (create_time DATE DEFAULT NULL) >>> define upgcat_154 <<< alter table fb add (oldest_flashback_time DATE DEFAULT NULL) >>> define upgcat_155 <<< alter table al add (creator VARCHAR2(7) DEFAULT NULL) >>> define upgcat_156 <<< alter table dbinc add (high_tf_recid NUMBER DEFAULT 0 NOT NULL) >>> define upgcat_157 <<< alter table ts add (temporary varchar2(3) default 'NO' NOT NULL) >>> define upgcat_158 <<< -- -- -- -- declare is_db_role number; no_conf number; cursor node_c is select db_key, count(*) no_db_unique_name from node group by db_key; cursor db_c is select db_key from db; begin select count(*) into is_db_role from user_tab_columns where table_name = 'NODE' and column_name = 'DATABASE_ROLE'; if is_db_role = 0 then for noderec in node_c loop if (noderec.no_db_unique_name > 1) then delete from node where node.db_key = noderec.db_key; delete from conf where conf.db_key = noderec.db_key; update db set db.high_conf_recid = 0 where db.db_key = noderec.db_key; end if; end loop; else -- -- -- -- for dbrec in db_c loop select count(*) into no_conf from conf where conf.db_key = dbrec.db_key; if no_conf = 0 then update node set node.high_conf_recid = 0 where node.db_key = dbrec.db_key; update db set db.high_conf_recid = 0 where db.db_key = dbrec.db_key; end if; end loop; end if; end; >>> define upgcat_159 <<< -- begin update dbinc set dbinc.db_name = upper(dbinc.db_name); update conf set conf.db_unique_name = upper(conf.db_unique_name); update node set node.db_unique_name = upper(node.db_unique_name); update fb set fb.db_unique_name = upper(fb.db_unique_name); end; >>> define upgcat_160 <<< alter table node add (database_role varchar2(7) default 'PRIMARY' NOT NULL) >>> define upgcat_161 <<< alter table node add constraint node_u1 unique(db_key, db_unique_name) >>> define upgcat_162 <<< alter table ts add (encrypt_in_backup varchar2(3)) >>> define upgcat_163 <<< alter table al add (terminal VARCHAR2(3) DEFAULT 'NO') >>> define upgcat_164 <<< alter table xal add (terminal VARCHAR2(3) DEFAULT 'NO') >>> define upgcat_165 <<< alter table brl add (terminal VARCHAR2(3) DEFAULT 'NO') >>> define upgcat_166 <<< alter table cdf drop CONSTRAINT cdf_c_status drop index >>> define upgcat_167 <<< alter table cdf add CONSTRAINT cdf_c_status CHECK (status in ('A','U','D','X','F')) >>> define upgcat_168 <<< alter table rlh drop constraint rlh_u2 drop index >>> define upgcat_add_scrl_dbkey <<< alter table scrl add (db_key NUMBER) >>> define upgcat_populate_scrl_dbkey <<< update scrl set db_key = (select db_key from scr where scr.scr_key = scrl.scr_key) >>> define upgcat_bug_4754328 <<< -- -- -- -- -- declare cursor dbinc_c is select dbinc_key from dbinc for update; tempts_cnt number; tempts_fixed number; begin select count(*) into tempts_fixed from user_procedures where object_name='DBMS_RCVCAT' and procedure_name='TEMPFILETORESYNC'; if tempts_fixed = 0 then for dbincrec in dbinc_c loop select count(*) into tempts_cnt from ts where temporary = 'YES' and drop_scn is null and dbinc_key = dbincrec.dbinc_key; if (tempts_cnt = 0) then delete from ts where temporary = 'YES' and dbinc_key = dbincrec.dbinc_key; -- end if; end loop; end if; end; >>> define upgcat_df_add_fdbid <<< alter table df add (foreign_dbid number default 0 not null) >>> define upgcat_df_add_fcrescn <<< alter table df add (foreign_create_scn number default 0 not null) >>> define upgcat_df_add_fcretim <<< alter table df add (foreign_create_time date) >>> define upgcat_df_add_pronly <<< alter table df add (plugged_readonly varchar2(3) default 'NO' not null) >>> define upgcat_df_add_plus <<< alter table df add (plugin_scn number default 0 not null) >>> define upgcat_df_add_prlgscn <<< alter table df add (plugin_reset_scn number default 0 not null) >>> define upgcat_df_add_prlgtim <<< alter table df add (plugin_reset_time date) >>> define upgcat_df_add_pfdbid <<< alter table df add (pdb_foreign_dbid number default 0 not null) >>> define upgcat_df_drop_df_p <<< alter table df drop constraint df_p drop index >>> define upgcat_bdf_add_fdbid <<< alter table bdf add (foreign_dbid number default 0 not null) >>> define upgcat_bdf_add_pronly <<< alter table bdf add (plugged_readonly varchar2(3) default 'NO' not null) >>> define upgcat_bdf_add_plus <<< alter table bdf add (plugin_scn number default 0 not null) >>> define upgcat_bdf_add_prlgscn <<< alter table bdf add (plugin_reset_scn number default 0 not null) >>> define upgcat_bdf_add_prlgtim <<< alter table bdf add (plugin_reset_time date) >>> define upgcat_bdf_add_secsize <<< alter table bdf add (section_size number) >>> define upgcat_bdf_add_sparse_backup <<< alter table bdf add (sparse_backup varchar2(3) default 'NO' not null) add CONSTRAINT bdf_c_sparse_backup CHECK (sparse_backup in ('YES', 'NO')) >>> define upgcat_cdf_add_fdbid <<< alter table cdf add (foreign_dbid number default 0 not null) >>> define upgcat_cdf_add_pronly <<< alter table cdf add (plugged_readonly varchar2(3) default 'NO' not null) >>> define upgcat_cdf_add_plus <<< alter table cdf add (plugin_scn number default 0 not null) >>> define upgcat_cdf_add_prlgscn <<< alter table cdf add (plugin_reset_scn number default 0 not null) >>> define upgcat_cdf_add_prlgtim <<< alter table cdf add (plugin_reset_time date) >>> define upgcat_cdf_add_sparse_backup <<< alter table cdf add (sparse_backup varchar2(3) default 'NO' not null) add CONSTRAINT cdf_c_sparse_backup CHECK (sparse_backup in ('YES', 'NO')) >>> define upgcat_xdf_add_fdbid <<< alter table xdf add (foreign_dbid number default 0 not null) >>> define upgcat_xdf_add_pronly <<< alter table xdf add (plugged_readonly varchar2(3) default 'NO' not null) >>> define upgcat_xdf_add_plus <<< alter table xdf add (plugin_scn number default 0 not null) >>> define upgcat_xdf_add_prlgscn <<< alter table xdf add (plugin_reset_scn number default 0 not null) >>> define upgcat_xdf_add_prlgtim <<< alter table xdf add (plugin_reset_time date) >>> define add_siteaware_columns_to_node <<< alter table node add (site_key number default 0 not null, last_kccdivts NUMBER DEFAULT 0, high_ic_recid NUMBER DEFAULT 0, cf_create_time DATE, dbinc_key NUMBER DEFAULT 0 NOT NULL, ckp_scn NUMBER DEFAULT 0 NOT NULL, full_ckp_cf_seq NUMBER DEFAULT 0 NOT NULL, job_ckp_cf_seq NUMBER DEFAULT 0 NOT NULL, high_ts_recid NUMBER, high_df_recid NUMBER, high_rt_recid NUMBER, high_orl_recid NUMBER, high_offr_recid NUMBER DEFAULT 0 NOT NULL, high_rlh_recid NUMBER DEFAULT 0 NOT NULL, high_al_recid NUMBER DEFAULT 0 NOT NULL, high_bs_recid NUMBER DEFAULT 0 NOT NULL, high_bp_recid NUMBER DEFAULT 0 NOT NULL, high_bdf_recid NUMBER DEFAULT 0 NOT NULL, high_cdf_recid NUMBER DEFAULT 0 NOT NULL, high_brl_recid NUMBER DEFAULT 0 NOT NULL, high_bcb_recid NUMBER DEFAULT 0 NOT NULL, high_ccb_recid NUMBER DEFAULT 0 NOT NULL, high_do_recid NUMBER DEFAULT 0 NOT NULL, high_pc_recid NUMBER DEFAULT 0 NOT NULL, high_bsf_recid NUMBER DEFAULT 0 NOT NULL, high_rsr_recid NUMBER DEFAULT 0 NOT NULL, high_tf_recid NUMBER DEFAULT 0 NOT NULL, high_grsp_recid NUMBER DEFAULT 0 NOT NULL, high_nrsp_recid NUMBER DEFAULT 0 NOT NULL, high_bcr_recid NUMBER DEFAULT 0 NOT NULL, low_bcr_recid NUMBER DEFAULT 0 NOT NULL, bcr_in_use VARCHAR2(3) DEFAULT 'NO' NOT NULL) >>> define update_site_key_in_node <<< declare cursor node_c is select site_key from node where site_key = 0 for update; cursor site_fromconf is select db_key, db_unique_name, count(*) over (partition by db_key) num_of_sites from (select distinct db_key, db_unique_name from conf where db_unique_name is not null and db_key not in (select db_key from node)); cursor db_not_known_c is select db_key from db where not exists (select * from node where db_key = db.db_key); last_db_key number; begin -- for noderec in node_c loop update node set site_key = rman_seq.nextval where current of node_c; end loop; -- -- for siterec in site_fromconf loop begin insert into node(db_key, db_unique_name, site_key, database_role, force_resync2cf) values (siterec.db_key, siterec.db_unique_name,rman_seq.nextval, decode(siterec.num_of_sites, 1, 'PRIMARY','STANDBY'), 'YES'); exception when dup_val_on_index then null; end; end loop; -- for dbrec in db_not_known_c loop INSERT INTO node(db_key, database_role, site_key, force_resync2cf) VALUES(dbrec.db_key, 'PRIMARY', rman_seq.nextval, 'NO'); end loop; commit; end; >>> define add_node_p_constraint <<< alter table node add CONSTRAINT node_p PRIMARY KEY (site_key) >>> define add_site_key_check_constraint <<< alter table node add CONSTRAINT check_site_key CHECK (site_key > 0) >>> define add_site_key_to_conf <<< alter table conf add (site_key number default 0 not null) >>> define assign_site_key_in_conf <<< -- -- declare cursor conf_c is select db_key, db_unique_name, site_key from conf where db_unique_name is not null for update; conf_site_key number; begin for confrec in conf_c loop select site_key into conf_site_key from node where confrec.db_unique_name = node.db_unique_name and confrec.db_key = node.db_key; update conf set site_key = conf_site_key where current of conf_c; end loop; commit; end; >>> define add_site_key_to_al <<< alter table al add (site_key number) >>> define add_al_f2_constraint <<< alter table al add CONSTRAINT al_f2 FOREIGN KEY (site_key) REFERENCES node ON DELETE CASCADE >>> define add_site_key_to_bp <<< alter table bp add (site_key number) >>> define add_encrypted_and_backed_by_osb_to_bp <<< alter table bp add (encrypted VARCHAR2(1) DEFAULT 'N', backed_by_osb VARCHAR2(1) DEFAULT 'N') >>> define add_bp_f2_constraint <<< alter table bp add CONSTRAINT bp_f2 FOREIGN KEY (site_key) REFERENCES node >>> define add_site_key_to_ccf <<< alter table ccf add (site_key number) >>> define add_ccf_f2_constraint <<< alter table ccf add CONSTRAINT ccf_f2 FOREIGN KEY (site_key) REFERENCES node >>> define add_site_key_to_xcf <<< alter table xcf add (site_key number) >>> define add_xcf_f2_constraint <<< alter table xcf add CONSTRAINT xcf_f2 FOREIGN KEY (site_key) REFERENCES node >>> define add_site_key_to_cdf <<< alter table cdf add (site_key number) >>> define add_cdf_f2_constraint <<< alter table cdf add CONSTRAINT cdf_f3 FOREIGN KEY (site_key) REFERENCES node >>> define add_site_key_to_xdf <<< alter table xdf add (site_key number) >>> define add_xdf_f2_constraint <<< alter table xdf add CONSTRAINT xdf_f3 FOREIGN KEY (site_key) REFERENCES node >>> define add_site_key_to_xal <<< alter table xal add (site_key number) >>> define add_xal_f2_constraint <<< alter table xal add CONSTRAINT xal_f2 FOREIGN KEY (site_key) REFERENCES node >>> define add_keep_to_xal <<< alter table xal add (keep_options number default 0 not null, keep_until date) >>> define add_site_key_to_rsr <<< alter table rsr add (site_key number) >>> define add_rsr_osb_allocated_to_rsr <<< alter table rsr add (rsr_osb_allocated varchar2(1)) >>> define drop_rsr_u1_constraint <<< alter table rsr drop CONSTRAINT rsr_u1 drop index >>> define add_rsr_u2_constraint <<< alter table rsr add CONSTRAINT rsr_u2 UNIQUE (dbinc_key, rsr_recid, rsr_stamp, site_key) >>> define add_rsr_f2_constraint <<< alter table rsr add CONSTRAINT rsr_f2 FOREIGN KEY (site_key) REFERENCES node ON DELETE CASCADE >>> define add_site_key_to_bs <<< alter table bs add (site_key number) >>> define add_bs_f2_constraint <<< alter table bs add CONSTRAINT bs_f2 FOREIGN KEY (site_key) REFERENCES node >>> define drop_bcf_u1_constraint <<< alter table bcf drop CONSTRAINT bcf_u1 drop index >>> define drop_bsf_u1_constraint <<< alter table bsf drop CONSTRAINT bsf_u1 drop index >>> define drop_bsf_i_bs_key_index <<< drop index bsf_i_bs_key >>> define add_bsf_u2_constraint <<< alter table bsf add CONSTRAINT bsf_u2 UNIQUE (bs_key) >>> define drop_bdf_u1_constraint <<< alter table bdf drop CONSTRAINT bdf_u1 drop index >>> define add_bdf_u2_constraint <<< alter table bdf add CONSTRAINT bdf_u2 UNIQUE (bs_key, file#) >>> define drop_brl_u1_constraint <<< alter table brl drop CONSTRAINT brl_u1 drop index >>> define add_brl_u2_constraint <<>> define drop_offr_u1_constraint <<< alter table offr drop CONSTRAINT offr_u1 drop index >>> define add_df_key_blocks_to_df <<< alter table df add (df_key NUMBER, blocks NUMBER) >>> define add_df_key_site_key_to_dfatt <<< alter table dfatt add (df_key NUMBER, site_key NUMBER) >>> define drop_dfatt_f3_constraint <<< alter table dfatt drop CONSTRAINT dfatt_f3 drop index >>> define make_df_dfatt_siteaware <<< DECLARE TYPE cur_typ IS REF CURSOR; dfatt_c cur_typ; dfattrec df%ROWTYPE; dfrec df%ROWTYPE; sql_stmt VARCHAR2(200); distinct_files NUMBER; distinct_fnames NUMBER; rid VARCHAR2(18); nextval NUMBER; BEGIN -- -- EXECUTE IMMEDIATE 'delete dfatt where end_ckp_key is not null and ' || 'end_ckp_key <> 0'; OPEN dfatt_c FOR 'SELECT dbinc_key, file#, create_scn, blocks, rowid ' || ' FROM dfatt ' || 'WHERE end_ckp_key IS NULL FOR UPDATE'; -- LOOP FETCH dfatt_c INTO dfattrec.dbinc_key, dfattrec.file#, dfattrec.create_scn, dfattrec.blocks, rid; EXIT WHEN dfatt_c%NOTFOUND; SELECT * INTO dfrec FROM df WHERE dbinc_key = dfattrec.dbinc_key AND file# = dfattrec.file# AND create_scn= dfattrec.create_scn; IF dfrec.df_key IS NULL THEN SELECT rman_seq.nextval INTO nextval FROM dual; UPDATE df SET df_key = nextval, blocks = dfattrec.blocks WHERE file# = dfrec.file# AND create_scn = dfrec.create_scn AND ts# = dfrec.ts# AND dbinc_key IN (SELECT dbinc_key FROM dbinc WHERE db_key = (SELECT db_key FROM dbinc WHERE dbinc_key = dfattrec.dbinc_key)); IF SQL%ROWCOUNT = 0 THEN RAISE_APPLICATION_ERROR(-20000,'not updated any data file'); END IF; EXECUTE IMMEDIATE 'UPDATE dfatt SET df_key = rman_seq.currval ' || 'WHERE ROWID = :1' USING rid; IF SQL%ROWCOUNT <> 1 THEN RAISE_APPLICATION_ERROR(-20001,'not updated dfatt for file'); END IF; ELSE EXECUTE IMMEDIATE 'DELETE dfatt WHERE ROWID = :1' USING rid; END IF; END LOOP; CLOSE dfatt_c; SELECT COUNT(*) INTO distinct_files FROM (SELECT DISTINCT db.db_key, file#, create_scn, ts# FROM df, dbinc, db WHERE df.dbinc_key = dbinc.dbinc_key AND dbinc.db_key = db.db_key); OPEN dfatt_c FOR 'SELECT COUNT(*) FROM dfatt'; FETCH dfatt_c INTO distinct_fnames; CLOSE dfatt_c; IF distinct_files <> distinct_fnames THEN RAISE_APPLICATION_ERROR(-20003,'distinct file count mismatch '|| distinct_files || ',' || distinct_fnames); END IF; -- EXECUTE IMMEDIATE 'UPDATE dfatt SET end_ckp_key = 0'; COMMIT; END; >>> define modify_df_key_not_null <<< alter table df modify(df_key NOT NULL) >>> define drop_dfatt_f1_constraint <<< alter table dfatt drop CONSTRAINT dfatt_f1 drop index >>> define drop_dfatt_f2_constraint <<< alter table dfatt drop CONSTRAINT dfatt_f2 drop index >>> define drop_dfatt_u1_constraint <<< alter table dfatt drop CONSTRAINT dfatt_u1 drop index >>> define drop_dbinc_key_from_dfatt <<< alter table dfatt drop column dbinc_key >>> define drop_end_ckp_key_from_dfatt <<< alter table dfatt drop column end_ckp_key >>> define drop_start_ckp_key_from_dfatt <<< alter table dfatt drop column start_ckp_key >>> define "drop_file#_from_dfatt" <<< alter table dfatt drop column file# >>> define drop_create_scn_from_dfatt <<< alter table dfatt drop column create_scn >>> define drop_blocks_from_dfatt <<< alter table dfatt drop column blocks >>> define rename_dfatt_to_site_dfatt <<< alter table dfatt rename to site_dfatt >>> define rename_ba_restore_range_cache_to_rrcache <<< alter table ba_restore_range_cache rename to rrcache >>> define modify_df_key_in_site_dfatt_not_null <<< alter table site_dfatt modify(df_key not null) >>> define add_site_dfatt_p_constraint <<< alter table site_dfatt add CONSTRAINT site_dfatt_p PRIMARY KEY (df_key, site_key) >>> define add_site_dfatt_f2_constraint <<< alter table site_dfatt add CONSTRAINT site_dfatt_f2 FOREIGN KEY (site_key) REFERENCES node ON DELETE CASCADE >>> define assign_site_key_in_site_dfatt <<< declare db_key_rec number; cursor all_dbkey_c is select db_key from db; cursor site_dfatt_c(dbkey number) is select site_dfatt.df_key, node.site_key, site_dfatt.site_key nullkey from site_dfatt, df, dbinc, node where site_dfatt.site_key is null and node.db_key = site_dfatt_c.dbkey and node.database_role = 'PRIMARY' and site_dfatt.df_key=df.df_key and df.dbinc_key = dbinc.dbinc_key and dbinc.db_key = node.db_key for update of site_dfatt.site_key; begin open all_dbkey_c; loop fetch all_dbkey_c into db_key_rec; exit when all_dbkey_c%NOTFOUND; for site_dfatt_rec in site_dfatt_c(db_key_rec) loop update site_dfatt set site_key = site_dfatt_rec.site_key where current of site_dfatt_c; end loop; commit; end loop; end; >>> define modify_site_key_in_site_dfatt_not_null <<< alter table site_dfatt modify(site_key NOT NULL) >>> define add_siteaware_columns_to_tf <<< alter table tf add (tf_key NUMBER, blocks NUMBER, autoextend VARCHAR2(3), max_size NUMBER, next_size NUMBER) >>> define add_tf_key_site_key_to_tfatt <<< alter table tfatt add (tf_key NUMBER, site_key NUMBER) >>> define drop_tfatt_f3_constraint <<< alter table tfatt drop CONSTRAINT tfatt_f3 drop index >>> define make_tf_tfatt_siteaware <<< DECLARE TYPE cur_typ IS REF CURSOR; tfatt_c cur_typ; tfattrec tf%ROWTYPE; tfrec tf%ROWTYPE; tfrec_blocks NUMBER; tfrec_autoextend VARCHAR2(3); tfrec_max_size NUMBER; tfrec_next_size NUMBER; sql_stmt VARCHAR2(200); distinct_files NUMBER; distinct_fnames NUMBER; rid VARCHAR2(18); nextval NUMBER; BEGIN -- -- EXECUTE IMMEDIATE 'delete tfatt where end_ckp_key is not null and ' || 'end_ckp_key <> 0'; OPEN tfatt_c FOR 'SELECT dbinc_key, file#, create_scn, blocks, autoextend,' || ' max_size, next_size, rowid ' || ' FROM tfatt ' || 'WHERE end_ckp_key IS NULL FOR UPDATE'; -- LOOP FETCH tfatt_c INTO tfattrec.dbinc_key, tfattrec.file#, tfattrec.create_scn, tfrec_blocks, tfrec_autoextend, tfrec_max_size, tfrec_next_size, rid; EXIT WHEN tfatt_c%NOTFOUND; SELECT * INTO tfrec FROM tf WHERE dbinc_key = tfattrec.dbinc_key AND file# = tfattrec.file# AND create_scn= tfattrec.create_scn; IF tfrec.tf_key IS NULL THEN SELECT rman_seq.nextval INTO nextval FROM dual; EXECUTE IMMEDIATE 'UPDATE tf SET tf_key = :1, ' || ' blocks = :2, ' || ' autoextend = :3, ' || ' max_size = :4, ' || ' next_size = :5 ' || 'WHERE file# = :6 ' || 'AND create_scn = :7 ' || 'AND (create_time = :8 ' || ' OR create_time IS NULL AND :9 IS NULL) ' || 'AND ts# = :10 ' || 'AND rfile# = :11 ' || 'AND dbinc_key IN ' || ' (SELECT dbinc_key FROM dbinc ' || ' WHERE db_key = (SELECT db_key FROM dbinc ' || ' WHERE dbinc_key = :12))' USING nextval, tfrec_blocks, tfrec_autoextend, tfrec_max_size, tfrec_next_size, tfrec.file#, tfrec.create_scn, tfrec.create_time, tfrec.create_time, tfrec.ts#, tfrec.rfile#, tfattrec.dbinc_key; IF SQL%ROWCOUNT = 0 THEN RAISE_APPLICATION_ERROR(-20004,'not updated any temp file'); END IF; EXECUTE IMMEDIATE 'UPDATE tfatt SET tf_key = rman_seq.currval ' || 'WHERE ROWID = :1' USING rid; IF SQL%ROWCOUNT <> 1 THEN RAISE_APPLICATION_ERROR(-20005,'not updated tfatt for file'); END IF; ELSE EXECUTE IMMEDIATE 'DELETE tfatt WHERE ROWID = :1' USING rid; END IF; END LOOP; CLOSE tfatt_c; SELECT COUNT(*) INTO distinct_files FROM (SELECT DISTINCT db.db_key, file#, create_scn, create_time, ts#, rfile# FROM tf, dbinc, db WHERE tf.dbinc_key = dbinc.dbinc_key AND dbinc.db_key = db.db_key); OPEN tfatt_c FOR 'SELECT COUNT(*) FROM tfatt'; FETCH tfatt_c INTO distinct_fnames; CLOSE tfatt_c; IF distinct_files <> distinct_fnames THEN RAISE_APPLICATION_ERROR(-20006,'distinct file count mismatch '|| distinct_files || ',' || distinct_fnames); END IF; -- EXECUTE IMMEDIATE 'UPDATE tfatt SET end_ckp_key = 0'; COMMIT; END; >>> define modify_tf_key_not_null_in_tf <<< alter table tf modify(tf_key NOT NULL) >>> define drop_tfatt_f1_constraint <<< alter table tfatt drop CONSTRAINT tfatt_f1 drop index >>> define drop_tfatt_f2_constraint <<< alter table tfatt drop CONSTRAINT tfatt_f2 drop index >>> define drop_tfatt_u1_constraint <<< alter table tfatt drop CONSTRAINT tfatt_u1 drop index >>> define drop_dbinc_key_from_tfatt <<< alter table tfatt drop column dbinc_key >>> define drop_end_ckp_key_from_tfatt <<< alter table tfatt drop column end_ckp_key >>> define drop_start_ckp_key_from_tfatt <<< alter table tfatt drop column start_ckp_key >>> define "drop_file#_from_tfatt" <<< alter table tfatt drop column file# >>> define drop_create_scn_from_tfatt <<< alter table tfatt drop column create_scn >>> define drop_blocks_from_tfatt <<< alter table tfatt drop column blocks >>> define drop_autoextend_from_tfatt <<< alter table tfatt drop column autoextend >>> define drop_max_size_from_tfatt <<< alter table tfatt drop column max_size >>> define drop_next_size_from_tfatt <<< alter table tfatt drop column next_size >>> define rename_tfatt_to_site_tfatt <<< alter table tfatt rename to site_tfatt >>> define modify_tf_key_in_site_tfatt_not_null <<< alter table site_tfatt modify(tf_key not null) >>> define add_site_tfatt_p_constraint <<< alter table site_tfatt add CONSTRAINT site_tfatt_p PRIMARY KEY (tf_key, site_key) >>> define add_site_tfatt_f2_constraint <<< alter table site_tfatt add CONSTRAINT site_tfatt_f2 FOREIGN KEY (site_key) REFERENCES node ON DELETE CASCADE >>> define assign_site_key_in_site_tfatt <<< declare cursor site_tfatt_c is select site_tfatt.tf_key, node.site_key, site_tfatt.site_key nullkey from site_tfatt, tf, dbinc, node where site_tfatt.site_key is null and node.database_role = 'PRIMARY' and site_tfatt.tf_key=tf.tf_key and tf.dbinc_key = dbinc.dbinc_key and dbinc.db_key = node.db_key for update of site_tfatt.site_key; begin for site_tfatt_rec in site_tfatt_c loop update site_tfatt set site_key = site_tfatt_rec.site_key where current of site_tfatt_c; end loop; end; >>> define modify_site_key_in_site_tfatt_not_null <<< alter table site_tfatt modify(site_key NOT NULL) >>> define add_site_key_to_ckp <<< alter table ckp add (site_key number default 0 not null) >>> define update_site_key_in_ckp <<< declare cursor ckp_c is select ckp.site_key unassigned, node.site_key from ckp, dbinc, node where ckp.site_key = 0 and ckp.dbinc_key = dbinc.dbinc_key and dbinc.db_key = node.db_key and node.database_role = 'PRIMARY' for update of ckp.site_key; begin for ckprec in ckp_c loop update ckp set site_key = ckprec.site_key where current of ckp_c; end loop; commit; end; >>> define add_ckp_f3_constraint <<< alter table ckp add constraint ckp_f3 FOREIGN KEY (site_key) REFERENCES node ON DELETE CASCADE >>> define drop_high_df_recid_from_ckp <<< alter table ckp drop column high_df_recid >>> define drop_high_conf_recid_from_db <<< alter table db drop column high_conf_recid >>> define drop_last_kccdivts_from_db <<< alter table db drop column last_kccdivts >>> define drop_high_ic_recid_from_db <<< alter table db drop column high_ic_recid >>> define drop_cf_create_time_from_dbinc <<< alter table dbinc drop column cf_create_time >>> define drop_ckp_scn_from_dbinc <<< alter table dbinc drop column ckp_scn >>> define drop_full_ckp_cf_seq_from_dbinc <<< alter table dbinc drop column full_ckp_cf_seq >>> define drop_job_ckp_cf_seq_from_dbinc <<< alter table dbinc drop column job_ckp_cf_seq >>> define drop_high_ts_recid_from_dbinc <<< alter table dbinc drop column high_ts_recid >>> define drop_high_df_recid_from_dbinc <<< alter table dbinc drop column high_df_recid >>> define drop_high_rt_recid_from_dbinc <<< alter table dbinc drop column high_rt_recid >>> define drop_high_orl_recid_from_dbinc <<< alter table dbinc drop column high_orl_recid >>> define drop_high_offr_recid_from_dbinc <<< alter table dbinc drop column high_offr_recid >>> define drop_high_rlh_recid_from_dbinc <<< alter table dbinc drop column high_rlh_recid >>> define drop_high_al_recid_from_dbinc <<< alter table dbinc drop column high_al_recid >>> define drop_high_bs_recid_from_dbinc <<< alter table dbinc drop column high_bs_recid >>> define drop_high_bp_recid_from_dbinc <<< alter table dbinc drop column high_bp_recid >>> define drop_high_bdf_recid_from_dbinc <<< alter table dbinc drop column high_bdf_recid >>> define drop_high_cdf_recid_from_dbinc <<< alter table dbinc drop column high_cdf_recid >>> define drop_high_brl_recid_from_dbinc <<< alter table dbinc drop column high_brl_recid >>> define drop_high_bcb_recid_from_dbinc <<< alter table dbinc drop column high_bcb_recid >>> define drop_high_ccb_recid_from_dbinc <<< alter table dbinc drop column high_ccb_recid >>> define drop_high_do_recid_from_dbinc <<< alter table dbinc drop column high_do_recid >>> define drop_high_pc_recid_from_dbinc <<< alter table dbinc drop column high_pc_recid >>> define drop_high_bsf_recid_from_dbinc <<< alter table dbinc drop column high_bsf_recid >>> define drop_high_rsr_recid_from_dbinc <<< alter table dbinc drop column high_rsr_recid >>> define drop_high_tf_recid_from_dbinc <<< alter table dbinc drop column high_tf_recid >>> define drop_high_grsp_recid_from_dbinc <<< alter table dbinc drop column high_grsp_recid >>> define add_ors_timezone_col_to_dbinc <<< alter table dbinc add (dbinc_timezone VARCHAR2(64)) >>> define add_type_to_orl <<< alter table orl add (type varchar2(7) default 'ONLINE') >>> define add_bytes_to_orl <<< alter table orl add (bytes number default NULL) >>> define add_site_key_to_orl <<< alter table orl add (site_key number) >>> define add_orl_f2_constraint <<< alter table orl add CONSTRAINT orl_f2 FOREIGN KEY (site_key) REFERENCES node ON DELETE CASCADE >>> define update_site_key_in_orl <<< declare cursor orl_c is select orl.site_key unassigned, node.site_key from orl, dbinc, node where orl.site_key is null and orl.dbinc_key = dbinc.dbinc_key and dbinc.db_key = node.db_key and node.database_role = 'PRIMARY' for update of orl.site_key; begin for orlrec in orl_c loop update orl set site_key = orlrec.site_key where current of orl_c; end loop; commit; end; >>> define add_db_unique_name_to_bsf <<< alter table bsf add (db_unique_name varchar2(30)) >>> define drop_site_key_from_bsf <<< alter table bsf drop column site_key >>> define upgcat_bs_multi_section <<< alter table bs add (multi_section varchar2(1)) >>> define add_site_key_to_grsp <<< alter table grsp add (site_key number) >>> define add_creation_time_to_grsp <<< alter table grsp add (creation_time date default NULL) >>> define add_rsptime_to_grsp <<< alter table grsp add (rsptime date default NULL) >>> define add_guaranteed_to_grsp <<< alter table grsp add (guaranteed varchar2(3) default 'YES') >>> define update_site_key_in_grsp <<< declare cursor grsp_c is select grsp.site_key unassigned, node.site_key from grsp, dbinc, node where grsp.site_key is null and grsp.dbinc_key = dbinc.dbinc_key and dbinc.db_key = node.db_key and node.database_role = 'PRIMARY' for update of grsp.site_key; begin for grsprec in grsp_c loop update grsp set site_key = grsprec.site_key where current of grsp_c; end loop; commit; end; >>> define check_grsp_u1_constraint <<< declare cursor grsp_c is select site_key, rspname from grsp order by site_key, rspname for update of grsp.site_key; prev_site_key number; prev_rspname grsp.rspname%type; begin delete from grsp where site_key is null; for grsprec in grsp_c loop if (prev_site_key = grsprec.site_key and prev_rspname = grsprec.rspname) then delete grsp where current of grsp_c; else prev_site_key := grsprec.site_key; prev_rspname := grsprec.rspname; end if; end loop; end; >>> define add_grsp_u1_constraint <<< alter table grsp add constraint grsp_u1 UNIQUE(site_key, rspname) >>> define add_grsp_u3_constraint <<< alter table grsp add constraint grsp_u3 FOREIGN KEY (site_key) REFERENCES node ON DELETE CASCADE >>> define upgcat_rcver_constraint <<< alter table rcver add constraint rcver_version_unique unique(version) >>> define drop_tf_u2_constraint <<< alter table tf drop CONSTRAINT tf_u2 drop index >>> define drop_df_u2_constraint <<< alter table df drop CONSTRAINT df_u2 drop index >>> define delete_dup_brl_bsf_bdf_rows <<< declare cursor brl_c is select bs_key, thread#, sequence#, lead(sequence#, 1) over (partition by bs_key, thread# order by sequence#) nextseq# from brl for update of brl.bs_key; cursor bsf_c is select bs_key, lead(bs_key, 1) over (order by bs_key) next_bs_key from bsf for update of bsf.bs_key; cursor bdf_c is select bs_key, file#, lead(file#, 1) over (partition by bs_key order by file#) nextfile# from bdf for update of bdf.bs_key; begin -- delete brl where brl_stamp = 0; -- for brlrec in brl_c loop if (brlrec.sequence# = brlrec.nextseq#) then delete brl where current of brl_c; end if; end loop; -- for bsfrec in bsf_c loop if bsfrec.bs_key = bsfrec.next_bs_key then delete bsf where current of bsf_c; end if; end loop; for bdfrec in bdf_c loop if (bdfrec.file# = bdfrec.nextfile#) then delete bdf where current of bdf_c; end if; end loop; commit; end; >>> define add_some_cols_to_site_tfatt <<< alter table site_tfatt add (drop_scn number, drop_time date , blocks number, autoextend varchar2(3), max_size number, next_size number) >>> define populate_some_cols_in_site_tfatt <<< DECLARE TYPE cur_typ IS REF CURSOR; site_tfatt_c cur_typ; site_tfatt_rec site_tfatt%ROWTYPE; site_tfatt_rid VARCHAR2(18); tf_drop_scn NUMBER; tf_drop_time DATE; tf_blocks NUMBER; tf_autoextend VARCHAR2(3); tf_max_size NUMBER; tf_next_size NUMBER; BEGIN OPEN site_tfatt_c FOR 'SELECT site_tfatt.drop_scn, site_tfatt.drop_time, ' || ' site_tfatt.blocks, site_tfatt.autoextend, ' || ' site_tfatt.max_size, site_tfatt.next_size, ' || ' tf.drop_scn tf_drop_scn, tf.drop_time tf_drop_time, ' || ' tf.blocks tf_blocks, tf.autoextend tf_autoextend, ' || ' tf.max_size tf_max_size, tf.next_size tf_next_size, ' || ' site_tfatt.ROWID site_tfatt_rowid ' || 'FROM site_tfatt, tf ' || 'WHERE site_tfatt.tf_key = tf.tf_key ' || 'FOR UPDATE OF site_tfatt.drop_scn, site_tfatt.drop_time, '|| ' site_tfatt.blocks, site_tfatt.autoextend, '|| ' site_tfatt.max_size, site_tfatt.next_size'; LOOP FETCH site_tfatt_c INTO site_tfatt_rec.drop_scn, site_tfatt_rec.drop_time, site_tfatt_rec.blocks, site_tfatt_rec.autoextend, site_tfatt_rec.max_size, site_tfatt_rec.next_size, tf_drop_scn, tf_drop_time, tf_blocks, tf_autoextend, tf_max_size, tf_next_size, site_tfatt_rid; EXIT WHEN site_tfatt_c%NOTFOUND; EXECUTE IMMEDIATE 'update site_tfatt set drop_scn = :1, drop_time = :2, ' || ' blocks = :3, autoextend = :4, max_size = :5, next_size = :6 ' || ' where ROWID = :7' USING tf_drop_scn, tf_drop_time, tf_blocks, tf_autoextend, tf_max_size, tf_next_size, site_tfatt_rid; END LOOP; COMMIT; END; >>> define drop_tf_u1 <<< alter table tf drop constraint tf_u1 drop index >>> define drop_drop_scn_from_tf <<< alter table tf drop column drop_scn >>> define drop_drop_time_from_tf <<< alter table tf drop column drop_time >>> define drop_blocks_from_tf <<< alter table tf drop column blocks >>> define drop_autoextend_from_tf <<< alter table tf drop column autoextend >>> define drop_max_size_from_tf <<< alter table tf drop column max_size >>> define drop_next_size_from_tf <<< alter table tf drop column next_size >>> define upgcat_strt_0 <<< create or replace package dbms_rcvcat authid current_user is function getPackageVersion return varchar2; function getCatalogVersion return varchar2; -- UPGRADE_COMPLETED CONSTANT number := 0; end; >>> define upgcat_strt_1 <<< create or replace package body dbms_rcvcat is function getPackageVersion return varchar2 is begin return '12.02.00.01'; end; function getCatalogVersion return varchar2 is begin return '12.02.00.01'; end; end; >>> define add_create_thread_size_to_df <<< ALTER TABLE df ADD (create_thread NUMBER, create_size NUMBER) >>> define remove_null_db_unique_name_rows_from_node <<< declare cursor db_with_null_db_unique_name_c is select db_key, db_unique_name, count(*) over (partition by db_key) num_of_sites from node where db_key in (select db_key from node where db_unique_name is null) for update of node.db_key; begin for db_with_null_db_unique_name in db_with_null_db_unique_name_c loop if db_with_null_db_unique_name.num_of_sites > 1 and db_with_null_db_unique_name.db_unique_name is null then delete node where current of db_with_null_db_unique_name_c; end if; end loop; commit; end; >>> define drop_constraint_status_rt <<< alter table rt drop CONSTRAINT rt_c_status drop index >>> define recreate_constraint_status_rt <<< alter table rt add CONSTRAINT rt_c1_status CHECK (status in ('D','E','O','I')) >>> define set_site_key_for_single_site_dbs <<< declare cursor onesite is select * from (select site_key, db_key, count(db_key) over (partition by db_key) num_sites from node where site_key > 0 and substr(nvl(db_unique_name, 'A'),1,1) <> '$') where num_sites=1; begin for onesite_row in onesite loop update ckp set site_key = onesite_row.site_key where site_key is null and ckp_key in (select ckp_key from ckp, dbinc where dbinc.dbinc_key = ckp.dbinc_key and dbinc.db_key = onesite_row.db_key); update site_dfatt set site_key = onesite_row.site_key where site_key is null and df_key in (select df_key from df, dbinc where dbinc.dbinc_key = df.dbinc_key and dbinc.db_key = onesite_row.db_key); update site_tfatt set site_key = onesite_row.site_key where site_key is null and tf_key in (select tf_key from tf, dbinc where dbinc.dbinc_key = tf.dbinc_key and dbinc.db_key = onesite_row.db_key); update orl set site_key = onesite_row.site_key where site_key is null and dbinc_key in (select dbinc_key from dbinc where db_key = onesite_row.db_key); update al set site_key = onesite_row.site_key where site_key is null and dbinc_key in (select dbinc_key from dbinc where db_key = onesite_row.db_key); update bp set site_key = onesite_row.site_key where site_key is null and bs_key in (select bs_key from bs where bs.db_key = onesite_row.db_key); update bs set site_key = onesite_row.site_key where site_key is null and db_key = onesite_row.db_key; update rout set site_key = onesite_row.site_key where site_key is null and db_key = onesite_row.db_key; update ccf set site_key = onesite_row.site_key where site_key is null and dbinc_key in (select dbinc_key from dbinc where db_key = onesite_row.db_key); update xcf set site_key = onesite_row.site_key where site_key is null and dbinc_key in (select dbinc_key from dbinc where db_key = onesite_row.db_key); update cdf set site_key = onesite_row.site_key where site_key is null and dbinc_key in (select dbinc_key from dbinc where db_key = onesite_row.db_key); update xdf set site_key = onesite_row.site_key where site_key is null and dbinc_key in (select dbinc_key from dbinc where db_key = onesite_row.db_key); update xal set site_key = onesite_row.site_key where site_key is null and dbinc_key in (select dbinc_key from dbinc where db_key = onesite_row.db_key); update rsr set site_key = onesite_row.site_key where site_key is null and dbinc_key in (select dbinc_key from dbinc where db_key = onesite_row.db_key); update grsp set site_key = onesite_row.site_key where site_key is null and dbinc_key in (select dbinc_key from dbinc where db_key = onesite_row.db_key); update nrsp set site_key = onesite_row.site_key where site_key is null and dbinc_key in (select dbinc_key from dbinc where db_key = onesite_row.db_key); update bcr set site_key = onesite_row.site_key where site_key is null and df_key in (select df_key from df, dbinc where dbinc.dbinc_key = df.dbinc_key and dbinc.db_key = onesite_row.db_key); -- -- commit; end loop; end; >>> define add_plugin_scn_to_ts <<< alter table ts add (plugin_scn number default 0 not null) >>> define add_plugin_scn_to_tsatt <<< alter table tsatt add (plugin_scn number default 0 not null) >>> define upgcat_drop_tsatt_f1 <<< alter table tsatt drop constraint tsatt_f1 drop index >>> define upgcat_drop_tf_f1 <<< alter table tf drop constraint tf_f1 drop index >>> define upgcat_drop_df_f1 <<< alter table df drop constraint df_f1 drop index >>> define upgcat_drop_df_f2 <<< alter table df drop constraint df_f2 drop index >>> define upgcat_drop_df_f3 <<< alter table df drop constraint df_f3 drop index >>> define upgcat_drop_df_f4 <<< alter table df drop constraint df_f4 drop index >>> define upgcat_drop_df_f5 <<< alter table df drop constraint df_f5 drop index >>> define upgcat_drop_ts_p <<< alter table ts drop constraint ts_p drop index >>> define upgcat_drop_ts_u1 <<< alter table ts drop constraint ts_u1 drop index >>> define upgcat_drop_ts_u2 <<< alter table ts drop constraint ts_u2 drop index >>> define upgcat_drop_tsatt_u1 <<< alter table tsatt drop constraint tsatt_u1 drop index >>> define upgcat_add_plugin_scn_to_tf <<< alter table tf add (plugin_scn number default 0 not null) >>> define upgcat_add_tf_c1_plugin_scn <<< alter table tf add CONSTRAINT tf_c1_plugin_scn CHECK (plugin_scn = 0) >>> define upgcat_fix_plugin_scn_in_ts_and_tsatt <<< begin for plugin_df_row in ( select distinct df.dbinc_key, df.ts#, df.ts_create_scn, df.ts_plugin_scn, df.drop_scn, df.pdbinc_key from df where df.ts_plugin_scn <> 0 and not exists (select 1 from ts where ts.plugin_scn = df.ts_plugin_scn and ts.dbinc_key = df.dbinc_key and ts.create_scn = df.ts_create_scn and ts.pdbinc_key = df.pdbinc_key and ts.ts# = df.ts#) order by df.drop_scn ) loop begin update ts set plugin_scn = plugin_df_row.ts_plugin_scn where ts.dbinc_key = plugin_df_row.dbinc_key and ts.ts# = plugin_df_row.ts# and ts.create_scn = plugin_df_row.ts_create_scn and ts.plugin_scn = 0 and ts.pdbinc_key = plugin_df_row.pdbinc_key and ((nvl(ts.drop_scn, -1) = nvl(plugin_df_row.drop_scn, -1)) or (ts.drop_scn <= plugin_df_row.drop_scn)); if (sql%rowcount > 1) then raise_application_error(num=>-20017, msg=>'illegal ts plugin_scn update operation'); end if; exception when dup_val_on_index then null; end; begin update tsatt set plugin_scn = plugin_df_row.ts_plugin_scn where tsatt.dbinc_key = plugin_df_row.dbinc_key and tsatt.ts# = plugin_df_row.ts# and tsatt.create_scn = plugin_df_row.ts_create_scn and tsatt.plugin_scn = 0; if (sql%rowcount > 1) then raise_application_error(num=>-20017, msg=>'illegal tsatt plugin_scn update operation'); end if; exception when dup_val_on_index then null; end; commit; end loop; end; >>> define upgcat_add_ts_pdbinc_key <<< alter table ts add (pdbinc_key number) >>> define upgcat_add_tsatt_pdbinc_key <<< alter table tsatt add (pdbinc_key number) >>> define upgcat_add_df_pdbinc_key <<< alter table df add (pdbinc_key number) >>> define upgcat_add_tf_pdb_key <<< alter table tf add (pdb_key number) >>> define upgcat_add_df_ts_pdbinc_key <<< alter table df add (ts_pdbinc_key number) >>> define upgcat_add_tf_ts_pdbinc_key <<< alter table tf add (ts_pdbinc_key number) >>> define upgcat_add_rout_site_key <<< alter table rout add (site_key NUMBER) >>> define upgcat_add_rout_f3 <<< alter table rout add CONSTRAINT rout_f3 FOREIGN KEY(site_key) REFERENCES node ON DELETE CASCADE >>> define upgcat_remove_orphan_bcf <<< delete bcf where not exists (select 1 from dbinc where dbinc.dbinc_key = bcf.dbinc_key) >>> define upgcat_add_bcf_f3 <<< alter table bcf add CONSTRAINT bcf_f3 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE >>> define add_non_cdb_to_pdb <<< declare -- cursor ncdb_c is select db.db_key, db.db_id, dbinc.dbinc_key, dbinc.reset_scn, dbinc.reset_time from db, dbinc where db.db_key = dbinc.db_key and dbinc.parent_dbinc_key is null and not exists (select 1 from pdb where pdb.db_key = db.db_key) order by db.db_key; new_pdb_key number; new_pdbinc_key number; prev_db_key number := -1; zero_guid raw(16) := HEXTORAW(RPAD('0', 32, '0')); begin for r in ncdb_c loop if (r.db_key <> prev_db_key) then prev_db_key := r.db_key; insert into pdb (pdb_key, db_key, db_id, name, con_id, create_scn, guid) values (rman_seq.nextval, r.db_key, r.db_id, NULL, 0, 1, zero_guid) returning pdb_key into new_pdb_key; update bs set pdb_key = new_pdb_key where bs.db_key = r.db_key; update bp set pdb_key = new_pdb_key where bp.db_key = r.db_key; update bsf set pdb_key = new_pdb_key where bsf.db_key = r.db_key; insert into pdbinc (pdbinc_key, pdb_key, born_dbinc_key, inc_scn, begin_reset_scn, begin_reset_time, end_reset_scn, parent_pdbinc_key, pdbinc_status) values (rman_seq.nextval, new_pdb_key, r.dbinc_key, 1, r.reset_scn, r.reset_time, 1, NULL, 'CURRENT') returning pdbinc_key into new_pdbinc_key; for r1 in (select dbinc_key from dbinc where db_key = r.db_key) loop insert into pdb_dbinc (dbinc_key, pdb_key, drop_scn, drop_time, curr_pdbinc_key) values (r1.dbinc_key, new_pdb_key, NULL, NULL, new_pdbinc_key); update ts set pdbinc_key = new_pdbinc_key where ts.dbinc_key = r1.dbinc_key; update tsatt set pdbinc_Key = new_pdbinc_key where tsatt.dbinc_key = r1.dbinc_key; update df set pdbinc_key = new_pdbinc_key, ts_pdbinc_key = new_pdbinc_key where df.dbinc_key = r1.dbinc_key; update tf set pdb_key = new_pdb_key, ts_pdbinc_key = new_pdbinc_key where tf.dbinc_key = r1.dbinc_key; update bdf set pdb_key = new_pdb_key where bdf.dbinc_key = r1.dbinc_key; update bcf set pdb_key = new_pdb_key where bcf.dbinc_key = r1.dbinc_key; update cdf set pdb_key = new_pdb_key where cdf.dbinc_key = r1.dbinc_key; update ccf set pdb_key = new_pdb_key where ccf.dbinc_key = r1.dbinc_key; update xdf set pdb_key = new_pdb_key where xdf.dbinc_key = r1.dbinc_key; update xcf set pdb_key = new_pdb_key where xcf.dbinc_key = r1.dbinc_key; end loop; end if; -- commit; end loop; end; >>> define upgcat_add_bs_pdb_key <<< alter table bs add (pdb_key number) >>> define upgcat_add_bp_pdb_key <<< alter table bp add (pdb_key number) >>> define upgcat_add_bdf_pdb_key <<< alter table bdf add (pdb_key number) >>> define upgcat_add_bcf_pdb_key <<< alter table bcf add (pdb_key number) >>> define upgcat_add_bsf_pdb_key <<< alter table bsf add (pdb_key number) >>> define upgcat_add_cdf_pdb_key <<< alter table cdf add (pdb_key number) >>> define upgcat_add_ccf_pdb_key <<< alter table ccf add (pdb_key number) >>> define upgcat_add_xdf_pdb_key <<< alter table xdf add (pdb_key number) >>> define upgcat_add_bp_template_key <<< alter table bp add (template_key number) >>> define upgcat_add_xcf_pdb_key <<< alter table xcf add (pdb_key number) >>> define modify_ts_pdbinc_key_not_null <<< alter table ts modify(pdbinc_key NOT NULL) >>> define modify_tsatt_pdbinc_key_not_null <<< alter table tsatt modify(pdbinc_key NOT NULL) >>> define modify_df_pdbinc_key_not_null <<< alter table df modify(pdbinc_key NOT NULL) >>> define modify_tf_pdb_key_not_null <<< alter table tf modify(pdb_key NOT NULL) >>> define modify_df_ts_pdbinc_key_not_null <<< alter table df modify(ts_pdbinc_key NOT NULL) >>> define modify_tf_ts_pdbinc_key_not_null <<< alter table tf modify(ts_pdbinc_key NOT NULL) >>> define modify_bs_pdb_key_not_null <<< alter table bs modify(pdb_key NOT NULL) >>> define modify_bp_pdb_key_not_null <<< alter table bp modify(pdb_key NOT NULL) >>> define modify_bdf_pdb_key_not_null <<< alter table bdf modify(pdb_key NOT NULL) >>> define modify_bcf_pdb_key_not_null <<< alter table bcf modify(pdb_key NOT NULL) >>> define modify_bsf_pdb_key_not_null <<< alter table bsf modify(pdb_key NOT NULL) >>> define modify_cdf_pdb_key_not_null <<< alter table cdf modify(pdb_key NOT NULL) >>> define modify_ccf_pdb_key_not_null <<< alter table ccf modify(pdb_key NOT NULL) >>> define modify_xdf_pdb_key_not_null <<< alter table xdf modify(pdb_key NOT NULL) >>> define modify_xcf_pdb_key_not_null <<< alter table xcf modify(pdb_key NOT NULL) >>> define upgcat_add_bs_f3 <<< alter table bs add CONSTRAINT bs_f3 FOREIGN KEY (pdb_key) REFERENCES pdb >>> define upgcat_add_bp_f4 <<< alter table bp add CONSTRAINT bp_f4 FOREIGN KEY (pdb_key) REFERENCES pdb >>> define upgcat_add_bcf_f2 <<< alter table bcf add CONSTRAINT bcf_f2 FOREIGN KEY (pdb_key) REFERENCES pdb >>> define upgcat_add_ccf_f3 <<< alter table ccf add CONSTRAINT ccf_f3 FOREIGN KEY (pdb_key) REFERENCES pdb >>> define upgcat_add_xcf_f3 <<< alter table xcf add CONSTRAINT xcf_f3 FOREIGN KEY (pdb_key) REFERENCES pdb >>> define upgcat_add_bsf_f2 <<< alter table bsf add CONSTRAINT bsf_f2 FOREIGN KEY (pdb_key) REFERENCES pdb >>> define upgcat_add_bdf_f2 <<< alter table bdf add CONSTRAINT bdf_f2 FOREIGN KEY (pdb_key) REFERENCES pdb >>> define upgcat_add_cdf_f4 <<< alter table cdf add CONSTRAINT cdf_f4 FOREIGN KEY (pdb_key) REFERENCES pdb >>> define upgcat_add_xdf_f4 <<< alter table xdf add CONSTRAINT xdf_f4 FOREIGN KEY (pdb_key) REFERENCES pdb >>> define upgcat_drop_ts_p1 <<< alter table ts drop constraint ts_p1 drop index >>> define upgcat_drop_ts_u3 <<< alter table ts drop constraint ts_u3 drop index >>> define upgcat_add_ts_p2 <<< alter table ts add CONSTRAINT ts_p2 PRIMARY KEY (dbinc_key, pdbinc_key, ts#, create_scn, plugin_scn) >>> define upgcat_add_ts_u5 <<< alter table ts add CONSTRAINT ts_u5 UNIQUE (dbinc_key, pdbinc_key, ts_name, create_scn, plugin_scn) >>> define upgcat_add_ts_u4 <<< alter table ts add CONSTRAINT ts_u4 UNIQUE (dbinc_key, pdbinc_key, ts#, drop_scn) >>> define upgcat_enable_ts_u4 <<< alter table ts enable CONSTRAINT ts_u4 >>> define upgcat_add_ts_f2 <<< alter table ts add CONSTRAINT ts_f2 FOREIGN KEY (pdbinc_key) REFERENCES pdbinc ON DELETE CASCADE >>> define upgcat_drop_tsatt_u2 <<< alter table tsatt drop constraint tsatt_u2 drop index >>> define upgcat_drop_tsatt_f4 <<< alter table tsatt drop constraint tsatt_f4 drop index >>> define upgcat_add_tsatt_u3 <<< alter table tsatt add CONSTRAINT tsatt_u3 UNIQUE (dbinc_key, pdbinc_key, ts#, create_scn, plugin_scn,end_ckp_key) >>> define upgcat_add_tsatt_f5 <<< alter table tsatt add CONSTRAINT tsatt_f5 FOREIGN KEY (dbinc_key, pdbinc_key, ts#, create_scn, plugin_scn) REFERENCES ts ON DELETE CASCADE INITIALLY DEFERRED >>> define upgcat_add_tsatt_f6 <<< alter table tsatt add CONSTRAINT tsatt_f6 FOREIGN KEY (pdbinc_key) REFERENCES pdbinc ON DELETE CASCADE >>> define upgcat_drop_df_u1 <<< alter table df drop constraint df_u1 drop index >>> define upgcat_drop_df_u3 <<< alter table df drop constraint df_u3 drop index >>> define upgcat_add_df_ts_plugin_scn <<< alter table df add (ts_plugin_scn number default 0 not null) >>> define upgcat_init_df_ts_plugin_scn <<< declare l_plugin_scn number; cursor df_c is select df.read_only, df.plugin_scn, df.plugin_reset_scn, ts.plugin_scn ts_plugin_scn from df, ts -- where df.dbinc_key = ts.dbinc_key and df.ts# = ts.ts# and df.ts_create_scn = ts.create_scn and (df.plugin_scn = ts.plugin_scn or df.plugin_scn = 0) and df.ts_plugin_scn != ts.plugin_scn for update of df.ts_plugin_scn; begin for dfrec in df_c loop -- if (dfrec.plugin_reset_scn = 0) then l_plugin_scn := 0; else l_plugin_scn := dfrec.plugin_scn; end if; -- update df set ts_plugin_scn = dfrec.ts_plugin_scn, plugin_scn = l_plugin_scn where current of df_c; end loop; commit; end; >>> define upgcat_add_df_pdb_closed <<< alter table df add (pdb_closed number default 0 not null) >>> define upgcat_add_df_p1 <<< alter table df add CONSTRAINT df_p1 PRIMARY KEY (dbinc_key, pdbinc_key, file#, create_scn, plugin_scn) >>> define upgcat_add_df_u3 <<< alter table df add CONSTRAINT df_u3 UNIQUE (dbinc_key, pdbinc_key, file#, drop_scn) >>> define upgcat_add_df_u4 <<< alter table df add CONSTRAINT df_u4 UNIQUE (dbinc_key, pdbinc_key, df_key) >>> define upgcat_add_df_f6 <<< alter table df add CONSTRAINT df_f6 FOREIGN KEY (dbinc_key, ts_pdbinc_key, ts#, ts_create_scn, ts_plugin_scn) REFERENCES ts ON DELETE CASCADE >>> define upgcat_add_df_f7 <<< alter table df add CONSTRAINT df_f7 FOREIGN KEY (pdbinc_key) REFERENCES pdbinc ON DELETE CASCADE >>> define upgcat_drop_tf_f2 <<< alter table tf drop constraint tf_f2 drop index >>> define upgcat_add_tf_f3 <<< alter table tf add CONSTRAINT tf_f3 FOREIGN KEY (dbinc_key, ts_pdbinc_key, ts#, ts_create_scn, plugin_scn) REFERENCES ts ON DELETE CASCADE >>> define upgcat_add_tf_f4 <<< alter table tf add CONSTRAINT tf_f4 FOREIGN KEY (pdb_key) REFERENCES pdb ON DELETE CASCADE >>> define pdb_i_3 <<< create unique index pdb_i_3 on pdb (decode(con_id, 0, pdb_key, 1, pdb_key), decode(con_id, 0, 0, 1, 0)) &tablespace& >>> define add_high_pdb_recid_to_node <<< alter table node add (high_pdb_recid number) >>> define add_high_pic_recid_to_node <<< alter table node add (high_pic_recid number default 0 not null) >>> define add_ors_bp_key_poll_col_to_node <<< alter table node add (bp_key_poll number default 0 not null) >>> define add_ors_timezone_col_to_node <<< alter table node add ( db_timezone VARCHAR2(64), timezone_src VARCHAR2(1)) add CONSTRAINT check_timezone_src CHECK (timezone_src IN ('A', 'P','R','S')) >>> define update_ors_col_in_bp <<< alter table bp rename column am_access to ba_access >>> define add_ors_col_to_bp <<< alter table bp add ( ct_key NUMBER, ba_access VARCHAR2(1) DEFAULT 'U', vb_key NUMBER, lib_key NUMBER, purged VARCHAR(1) DEFAULT 'U' NOT NULL) add CONSTRAINT bp_u2 UNIQUE (ct_key) add CONSTRAINT bp_c_rs CHECK (ba_access IN ('U', 'D', 'L', 'T', 'R')) add CONSTRAINT bp_c_lib_key CHECK ((lib_key IS NOT NULL AND vb_key IS NULL AND ba_access IN ('T', 'R')) OR (lib_key IS NULL AND ba_access IN ('D', 'L', 'U'))) add CONSTRAINT bp_c_purged CHECK ((purged in ('Y','N') AND status = 'D' AND ba_access != 'U') OR (purged = 'N' AND status != 'D' AND ba_access != 'U') OR (purged = 'U' AND ba_access = 'U') ) >>> define add_activation_to_brl <<< alter table brl add (activation varchar2(1)) >>> define limit_rman_seq_to_ub8 <<< ALTER SEQUENCE rman_seq MAXVALUE 18446744073709551615 CACHE 100 ORDER NOCYCLE >>> define add_issft_to_df <<< alter table df add (issft number) >>> define add_config_p_constraint <<>> define add_create_time_to_deleted_object <<< alter table deleted_object add (create_time date) >>> define delete_old_deleted_object_rec <<< begin delete deleted_object where create_time is null; commit; end; >>> define modify_deleted_object_create_time <<< alter table deleted_object modify(create_time NOT NULL) >>> define high_df_recid_update <<< declare rcver_i VARCHAR2(12); begin select max(version) into rcver_i from rcver ; IF rcver_i < '12.01.00.00' THEN update node set high_df_recid = 0 ; END IF; end; >>> define drop_bp_insert_trigger <<< drop trigger bp_insert_trigger >>> define drop_bs_insert_trigger <<< drop trigger bs_insert_trigger >>> define drop_bdf_insert_trigger <<< drop trigger bdf_insert_trigger >>> define drop_bcf_insert_trigger <<< drop trigger bcf_insert_trigger >>> define drop_bsf_insert_trigger <<< drop trigger bsf_insert_trigger >>> define drop_brl_insert_trigger <<< drop trigger brl_insert_trigger >>> define drop_do_insert_trigger <<< drop trigger do_insert_trigger >>> define recomp_invalid_objs <<< BEGIN FOR cur_rec IN (SELECT object_name, object_type, DECODE(object_type, 'PACKAGE', 1, 'PACKAGE BODY', 2, 'VIEW', 3) AS recompile_order FROM user_objects WHERE object_type IN ('PACKAGE', 'PACKAGE BODY', 'VIEW') AND status != 'VALID' AND (object_name like 'RA_%' OR object_name like 'RAI_%' OR object_name like 'DBMS_RA%' OR object_name like 'DBMS_RCV%' OR object_name like 'RCI_%' OR object_name like 'RC_%' OR object_name like '_RS_RC%') ORDER BY 3) LOOP BEGIN dbms_output.put_line('compiling ' || cur_rec.object_name); IF cur_rec.object_type in ('PACKAGE', 'VIEW') THEN EXECUTE IMMEDIATE 'ALTER ' || cur_rec.object_type || '"' || cur_rec.object_name || '" COMPILE'; ElSE EXECUTE IMMEDIATE 'ALTER PACKAGE ' || '"' || cur_rec.object_name || '" COMPILE BODY'; END IF; END; END LOOP; END; >>> define upgcat_drop_bp_f1 <<< alter table bp drop CONSTRAINT bp_f1 drop index >>> define upgcat_add_bp_f3 <<< alter table bp add CONSTRAINT bp_f3 FOREIGN KEY (bs_key) REFERENCES bs >>> define upgcat_add_bp_c_copyno <<< alter table bp ADD CONSTRAINT bp_c_copyno CHECK (copy# > 0 AND copy# <= 256) >>> define add_set_stamp_count_2_deleted_object <<< alter table deleted_object add (set_stamp NUMBER, set_count NUMBER) >>> define remove_bs_key_from_deleted_object <<< alter table deleted_object drop column bs_key >>> define upgcat_drop_server_u1_constraint <<< alter table server drop constraint server_u1 >>> define upgcat_drop_server_u2_constraint <<< alter table server drop constraint server_u2 >>> define upgcat_drop_server_http_add_column <<< alter table server drop column rs_http_add >>> define upgcat_rename_rs_proxy_port_in_server <<< alter table server rename column rs_proxy_port to proxy_port >>> define upgcat_rename_rs_proxy_url_in_server <<< alter table server rename column rs_proxy_url to proxy_url >>> define upgcat_drop_proxy_add_from_server <<< alter table server drop column proxy_add >>> define upgcat_drop_rs_http_url_from_server <<< alter table server drop column rs_http_url >>> define upgcat_add_server_host_to_server <<< alter table server add (server_host clob not null) >>> define upgcat_rename_rs_http_port_in_server <<< alter table server rename column rs_http_port to server_port >>> define upgcat_add_constr_1 <<< alter table server add CONSTRAINT server_u1 UNIQUE(filter_user, wallet_alias, wallet_path) >>> define upgcat_rename_rs_server_name_in_server <<< alter table server rename column rs_server_name to rep_server_name >>> define upgcat_rename_rs_server_key <<< alter table server rename column rs_server_key to server_key >>> define upgcat_add_constr_2 <<< alter table server add CONSTRAINT server_u2 UNIQUE(rep_server_name) >>> define upgcat_add_constr_3 <<< alter table server add CONSTRAINT server_c1 CHECK (server_port > 0) >>> define upgcat_add_constr_4 <<< alter table server add CONSTRAINT server_c2 CHECK (proxy_port > 0) >>> define upgcat_add_constr_5 <<< alter table server add CONSTRAINT server_p PRIMARY KEY (server_key) >>> define add_handle_device_type_2_deleted_object <<< alter table deleted_object add (handle varchar2(1024), device_type varchar2(255)) >>> define update_bs_stamp <<< declare rcver_i VARCHAR2(12); begin select max(version) into rcver_i from rcver ; IF rcver_i < '12.01.00.00' THEN update bs set bs_stamp = set_stamp where bs_recid = 0; END IF; end; >>> define add_check_database_role_c2_to_node <<< alter table node add constraint check_database_role_c2 CHECK ((substr(db_unique_name,1,1) = '$' AND database_role = 'RA') OR (substr(nvl(db_unique_name, 'A'),1,1) <> '$' AND database_role IN ('PRIMARY', 'STANDBY'))) >>> define upgcat_drop_deleted_object_p <<< alter table deleted_object drop CONSTRAINT deleted_object_p drop index >>> define upgcat_add_deleted_object_p1 <<< alter table deleted_object add CONSTRAINT deleted_object_p1 PRIMARY KEY (do_key, db_key) >>> define upgcat_add_deleted_object_f1 <<< alter table deleted_object add CONSTRAINT deleted_object_f1 FOREIGN KEY (db_key) REFERENCES db ON DELETE CASCADE >>> define upgcat_drop_1unwated_cols_from_watermarks <<< alter table watermarks drop (stamp_low_key, stamp_high_key, high_bp_key, high_bs_key, high_bdf_key, high_bcf_key, high_brl_key, high_bsf_key, last_bp_key, last_do_key) >>> define add_high_bp_recid_2_watermarks <<< alter table watermarks add (high_bp_recid number default 0 not null) >>> define resize_name_tempres <<< alter table tempres modify (name varchar2(1024)) >>> define resize_server_rep_server_name <<< alter table server modify (rep_server_name varchar2(128)) >>> define drop_check_database_role_c1 <<< alter table node drop constraint check_database_role_c1 >>> define rename_baschemaver_p_constraint <<< alter table baschemaver rename constraint baschemaver_p to raschemaver_p >>> define rename_baschemaver_to_raschemaver <<< alter table baschemaver rename to raschemaver >>> define resize_pdb_name <<< alter table pdb modify (name varchar2(128)) >>> define add_nrsp_add_pdb_key <<< alter table nrsp add (pdb_key number) >>> define init_nrsp_pdb_key <<< declare cursor nrsp_c is select distinct nrsp.rowid rid, dbinc.db_key db_key from nrsp, dbinc where nrsp.pdb_key is null and nrsp.dbinc_key = dbinc.dbinc_key order by dbinc.db_key; prev_db_key number := 0; local_pdb_key number; begin for r in nrsp_c loop if (r.db_key <> prev_db_key) then prev_db_key := r.db_key; select pdb_key into local_pdb_key from pdb where pdb.con_id in (1, 0) and pdb.db_key = r.db_key; end if; update nrsp set pdb_key = local_pdb_key where rowid = r.rid; end loop; end; >>> define modify_nrsp_pdb_key_not_null <<< alter table nrsp modify(pdb_key NOT NULL) >>> define add_nrsp_add_clean <<< alter table nrsp add (clean varchar(3) default 'NO') >>> define add_nrsp_u2_constraint <<< alter table nrsp add constraint nrsp_u2 UNIQUE(site_key, rspname, pdb_key) >>> define add_nrsp_f3_constraint <<< alter table nrsp add constraint nrsp_f3 FOREIGN KEY (pdb_key) REFERENCES pdb ON DELETE CASCADE >>> define add_nrsp_c1_constraint <<< alter table nrsp add constraint nrsp_c1 CHECK (clean IN ('YES','NO')) >>> define add_grsp_add_pdb_key <<< alter table grsp add (pdb_key number) >>> define init_grsp_pdb_key <<< declare cursor grsp_c is select distinct grsp.rowid rid, dbinc.db_key db_key from grsp, dbinc where grsp.pdb_key is null and grsp.dbinc_key = dbinc.dbinc_key order by dbinc.db_key; prev_db_key number := 0; local_pdb_key number; begin for r in grsp_c loop if (r.db_key <> prev_db_key) then prev_db_key := r.db_key; select pdb_key into local_pdb_key from pdb where pdb.con_id in (1, 0) and pdb.db_key = r.db_key; end if; update grsp set pdb_key = local_pdb_key where rowid = r.rid; end loop; end; >>> define modify_grsp_pdb_key_not_null <<< alter table grsp modify(pdb_key NOT NULL) >>> define add_grsp_add_clean <<< alter table grsp add (clean varchar(3) default 'NO') >>> define drop_grsp_u1_constraint <<< alter table grsp drop constraint grsp_u1 >>> define add_grsp_u4_constraint <<< alter table grsp add constraint grsp_u4 UNIQUE(site_key, rspname, pdb_key) >>> define add_grsp_f1_constraint <<< alter table grsp add constraint grsp_f1 FOREIGN KEY (pdb_key) REFERENCES pdb ON DELETE CASCADE >>> define add_grsp_c1_constraint <<< alter table grsp add constraint grsp_c1 CHECK (clean IN ('YES','NO')) >>> define add_pdb_nobackup <<< alter table pdb add (nobackup VARCHAR2(1) DEFAULT 'N' NOT NULL) >>> define add_pdb_c_nobackup_constraint <<< alter table pdb add constraint pdb_c_nobackup CHECK (nobackup in ('Y','N')) >>> define drpcat_revoke_everything <<< BEGIN FOR c IN ( SELECT NULL FROM dual WHERE EXISTS ( SELECT NULL FROM user_tables WHERE table_name = 'VPC_USERS' ) AND 2 = ( SELECT COUNT(*) FROM user_objects WHERE object_name = 'DBMS_RCVCAT' AND object_type IN ('PACKAGE', 'PACKAGE BODY') AND status = 'VALID' ) ) LOOP EXECUTE IMMEDIATE ' BEGIN FOR i IN (SELECT filter_user FROM vpc_users) LOOP BEGIN dbms_rcvcat.revoke_all(i.filter_user); EXCEPTION WHEN OTHERS THEN NULL; END; END LOOP; END; '; END LOOP; END; >>> define drpcat_1 <<< DROP SEQUENCE rman_seq >>> define drpcat_2 <<< DROP TABLE rcver >>> define drpcat_3 <<< DROP TABLE db cascade constraints >>> define drpcat_4 <<< DROP TABLE conf cascade constraints >>> define drpcat_5 <<< DROP TABLE dbinc cascade constraints >>> define drpcat_6 <<< DROP TABLE ckp cascade constraints >>> define drpcat_7 <<< DROP TABLE ts cascade constraints >>> define drpcat_8 <<< DROP TABLE tsatt cascade constraints >>> define drpcat_9 <<< DROP TABLE df cascade constraints >>> define drpcat_10 <<< DROP TABLE site_dfatt cascade constraints >>> define drpcat_11 <<< DROP TABLE offr cascade constraints >>> define drpcat_12 <<< DROP TABLE rr cascade constraints >>> define drpcat_13 <<< DROP TABLE rt cascade constraints >>> define drpcat_14 <<< DROP TABLE orl cascade constraints >>> define drpcat_15 <<< DROP TABLE rlh cascade constraints >>> define drpcat_16 <<< DROP TABLE bs cascade constraints >>> define drpcat_17 <<< DROP TABLE bp cascade constraints >>> define drpcat_18 <<< DROP TABLE bcf cascade constraints >>> define drpcat_19 <<< DROP TABLE ccf cascade constraints >>> define drpcat_20 <<< DROP TABLE xcf cascade constraints >>> define drpcat_21 <<< DROP TABLE bdf cascade constraints >>> define drpcat_22 <<< DROP TABLE cdf cascade constraints >>> define drpcat_23 <<< DROP TABLE xdf cascade constraints >>> define drpcat_24 <<< DROP TABLE brl cascade constraints >>> define drpcat_25 <<< DROP TABLE al cascade constraints >>> define drpcat_26 <<< DROP TABLE bcb cascade constraints >>> define drpcat_27 <<< DROP TABLE ccb cascade constraints >>> define drpcat_28 <<< DROP TABLE scr cascade constraints >>> define drpcat_29 <<< DROP TABLE scrl cascade constraints >>> define drpcat_30 <<< DROP VIEW rc_database >>> define drpcat_31 <<< DROP VIEW rc_database_incarnation >>> define drpcat_32 <<< DROP VIEW rc_resync >>> define drpcat_33 <<< DROP VIEW rc_checkpoint >>> define drpcat_34 <<< DROP VIEW rc_tablespace >>> define drpcat_35 <<< DROP VIEW rc_datafile >>> define drpcat_36 <<< DROP VIEW rc_redo_thread >>> define drpcat_37 <<< DROP VIEW rc_redo_log >>> define drpcat_38 <<< DROP VIEW rc_log_history >>> define drpcat_39 <<< DROP VIEW rc_archived_log >>> define drpcat_40 <<< DROP VIEW rc_backup_set >>> define drpcat_41 <<< DROP VIEW rc_backup_piece >>> define drpcat_42 <<< DROP VIEW rc_backup_datafile >>> define drpcat_43 <<< DROP VIEW rc_backup_controlfile >>> define drpcat_44 <<< DROP VIEW rc_datafile_copy >>> define drpcat_45 <<< DROP VIEW rc_controlfile_copy >>> define drpcat_46 <<< DROP VIEW rc_backup_redolog >>> define drpcat_47 <<< DROP VIEW rc_backup_corruption >>> define drpcat_48 <<< DROP VIEW rc_copy_corruption >>> define drpcat_49 <<< DROP VIEW rc_offline_range >>> define drpcat_50 <<< DROP VIEW rc_stored_script >>> define drpcat_51 <<< DROP VIEW rc_stored_script_line >>> define drpcat_52 <<< DROP VIEW rc_proxy_datafile >>> define drpcat_53 <<< DROP VIEW rc_proxy_controlfile >>> define drpcat_54 <<< DROP VIEW rc_rman_configuration >>> define drpcat_vpc <<< BEGIN BEGIN EXECUTE IMMEDIATE 'DROP PACKAGE dbms_rcvvpc'; EXCEPTION WHEN OTHERS THEN NULL; END; BEGIN EXECUTE IMMEDIATE 'DROP TRIGGER vpc_context_trg'; EXCEPTION WHEN OTHERS THEN NULL; END; END; >>> define drpcat_55 <<< DROP PACKAGE dbms_rcvcat >>> define drpcat_56 <<< DROP PACKAGE dbms_rcvman >>> define drpcat_57 <<< DROP TABLE config >>> define drpcat_58 <<< DROP TABLE sfile >>> define drpcat_59 <<< DROP VIEW rc_stored_file >>> define drpcat_60 <<< DROP VIEW rc_database_block_corruption >>> define drpcat_61 <<< DROP TABLE bsf >>> define drpcat_62 <<< DROP VIEW rc_backup_spfile >>> define drpcat_63 <<< DROP TABLE xal cascade constraints >>> define drpcat_64 <<< DROP VIEW rc_proxy_archivedlog >>> define drpcat_65 <<< DROP VIEW rc_backup_files >>> define drpcat_66 <<< DROP TABLE rsr cascade constraints >>> define drpcat_67 <<< DROP VIEW RC_RMAN_STATUS cascade constraints >>> define drpcat_68 <<< DROP TABLE fb >>> define drpcat_69 <<< DROP TABLE tf cascade constraints >>> define drpcat_70 <<< DROP TABLE site_tfatt cascade constraints >>> define drpcat_71 <<< DROP VIEW rc_tempfile >>> define drpcat_72 <<< DROP TABLE raschemaver >>> define drop_rc_restore_range <<< DROP VIEW rc_restore_range >>> define drop_rc_disk_restore_range <<< DROP VIEW rc_disk_restore_range >>> define drop_rc_sbt_restore_range <<< DROP VIEW rc_sbt_restore_range >>> define drop_dfatt <<< DROP TABLE dfatt cascade constraints >>> define drop_tfatt <<< DROP TABLE tfatt cascade constraints >>> define drop_vpc_users <<< DROP TABLE vpc_users >>> define drop_vpc_databases <<< DROP TABLE vpc_databases >>> define drop_cfs <<< DROP TABLE cfs >>> define drop_xmlstore <<< DROP TABLE xmlstore >>> define drop_node <<< DROP TABLE NODE cascade constraints >>> define drop_tempres <<< declare tempres_present number; type cur_typ is ref cursor; tempres_c cur_typ; tempres_q varchar2(256) := 'select name, data_type from tempres'; name varchar2(256); data_type varchar2(256); begin select count(*) into tempres_present from user_tab_columns where table_name = 'TEMPRES'; if (tempres_present = 0) then return; end if; open tempres_c for tempres_q; loop fetch tempres_c into name, data_type; exit when tempres_c%notfound; begin if data_type = 'TABLE' then execute immediate 'drop table ' || name; elsif data_type = 'DBLINK' then execute immediate 'drop database link ' || name; end if; exception when others then null; end; end loop; execute immediate 'drop table tempres'; end; >>> define drop_grsp <<< DROP TABLE grsp cascade constraints >>> define drop_nrsp <<< DROP TABLE nrsp >>> define drop_bcr <<< DROP TABLE bcr cascade constraints >>> define drop_pdb <<< DROP TABLE pdb cascade constraints >>> define drop_pdbinc <<< DROP TABLE pdbinc cascade constraints >>> define drop_pdb_dbinc <<< DROP TABLE pdb_dbinc cascade constraints >>> define drop_server <<< DROP TABLE server cascade constraints >>> define drop_deleted_object <<< DROP TABLE deleted_object cascade constraints >>> define drop_deleted_object_seq <<< DROP TABLE do_seq cascade constraints >>> define drop_watermarks <<< DROP TABLE watermarks cascade constraints >>> define drop_rcfile <<< DROP TABLE rcfile >>> define drop_orsevent <<< DROP TABLE orsevent >>> define drop_avm_restore_range_cache <<< DROP TABLE rrcache >>> define drop_rs_rc_get_object_list <<< DROP VIEW "_RS_RC_GET_OBJECT_LIST_" >>> define drop_rc_rcver <<< DROP VIEW RC_RCVER >>> define drop_rc_deleted_object <<< DROP VIEW RC_DELETED_OBJECT >>> define drop_rc_watermarks <<< DROP VIEW RC_WATERMARKS >>> define drop_xml_table_names_views <<< DECLARE CURSOR rs_xml_views_c IS SELECT view_name FROM user_views where view_name like '_RS_%_'; BEGIN FOR rs_xml_view IN rs_xml_views_c LOOP EXECUTE IMMEDIATE 'DROP VIEW "' || rs_xml_view.view_name || '"'; END LOOP; END; >>> define drop_rci_tempfile <<< DROP VIEW rci_tempfile >>> define drop_rci_datafile <<< DROP VIEW rci_datafile >>> define drop_rci_datafile_this_dbinc <<< DROP VIEW rci_datafile_this_dbinc >>> define drop_rci_tablespace_this_dbinc <<< DROP VIEW rci_tablespace_this_dbinc >>> define drop_rci_backup_set <<< DROP VIEW rci_backup_set >>> define drop_rci_backup_piece <<< DROP VIEW rci_backup_piece >>> define drop_rci_backup_controlfile <<< DROP VIEW rci_backup_controlfile >>> define drop_rci_backup_datafile <<< DROP VIEW rci_backup_datafile >>> define drop_rci_backup_spfile <<< DROP VIEW rci_backup_spfile >>> define drop_rci_avm_upstream_database <<< DROP VIEW rci_ra_upstream_database >>> define drop_get_lock_on_catalog <<< drop function get_lock_on_catalog >>> define abort_avm <<< begin execute immediate 'begin dbms_ra.abort_recovery_appliance; end;'; exception when others then null; end; >>> define drop_unreg_database_trigger <<< drop trigger unreg_database_trigger >>> define drop_node_insert_update <<< drop trigger node_insert_update >>> define drop_update_sbt_catalog_pieceinc <<< drop trigger update_sbt_catalog_pieceinc >>> define drop_chk_delete_sbt_catalog <<< drop trigger chk_delete_sbt_catalog >>> define drop_new_df_check <<< drop trigger new_df_check >>> define drop_rs_instance_startup_trigger <<< drop trigger ba_startup >>> define drop_rs_instance_startup_job <<< begin dbms_scheduler.drop_job('RA$TRIGGER_JOB', TRUE); end; >>> define drop_rs_instance_shutdown_trigger <<< drop trigger ba_shutdown >>> define drop_rs_sq <<< drop sequence rai_sq >>> define drop_rs_recid <<< drop sequence rai_recid >>> define drop_blocks <<< drop table blocks >>> define drop_chunks <<< drop table chunks >>> define drop_df_seq <<< drop table df_seq >>> define drop_bp_foreign_lib_key <<< alter table bp drop constraint bp_foreign_lib_key drop index >>> define drop_bp_foreign_template_key <<< alter table bp drop constraint bp_foreign_template_key drop index >>> define drop_sbt_task <<< drop table sbt_task >>> define drop_sbt_task_history <<< drop table sbt_task_history >>> define drop_sbt_template_db <<< drop table sbt_template_db >>> define drop_sbt_template_df <<< drop table sbt_template_df >>> define drop_sbt_job_template <<< drop table sbt_job_template >>> define drop_sbt_attr_set <<< drop table sbt_attr_set >>> define drop_sbt_lib_inst_rlist <<< drop table sbt_library_inst_rlist >>> define drop_sbt_lib_desc <<< drop table sbt_lib_desc >>> define drop_unreg_database <<< drop table unreg_database >>> define drop_dbsl <<< drop table dbsl >>> define drop_prvlg <<< drop table prvlg >>> define drop_rep_server <<< drop table rep_server >>> define drop_vbdf <<< drop table vbdf >>> define drop_plans_det <<< drop table plans_details >>> define drop_plans <<< drop table plans >>> define drop_sbt_session <<< drop table sbt_session >>> define drop_sbt_catalog <<< drop table sbt_catalog >>> define drop_task_chunk_cache <<< drop table task_chunk_cache >>> define drop_task <<< drop table task >>> define drop_task_history <<< drop table task_history >>> define drop_tasktypenames <<< drop table tasktypenames >>> define drop_error_log <<< drop table error_log >>> define drop_polling_history <<< drop table polling_history >>> define drop_sessions <<< drop table sessions >>> define drop_odb <<< drop table odb >>> define drop_odb_stats_cache <<< drop table odb_stats_cache >>> define drop_prot <<< drop table prot >>> define drop_poll <<< drop table poll >>> define drop_storage_histogram <<< drop table storage_histogram >>> define drop_metadata_filenames <<< drop table metadata_filenames >>> define drop_contained_filenames <<< drop table contained_filenames >>> define drop_missing_metadata_filenames <<< drop table missing_metadata_filenames >>> define drop_storage_dests <<< drop table storage_dests >>> define drop_sl <<< drop table sl >>> define drop_sl_sizing <<< drop table sl_sizing >>> define drop_rs_locks_table_type <<< drop type rai_locks_table_type >>> define drop_rs_locks_type <<< drop type rai_locks_type >>> define drop_rs_jobs_table_type <<< drop type rai_jobs_table_type >>> define drop_rs_jobs_type <<< drop type rai_jobs_type >>> define drop_timer_task <<< drop table timer_task >>> define drop_avm_pending_jobs <<< drop table rai_pending_jobs >>> define drop_bp_i_lib_key <<< drop index bp_i_lib_key >>> define drop_bp_i_template_key <<< drop index bp_i_template_key >>> define drop_host <<< drop table host >>> define drop_am_catalog_select <<< drop role ra_catalog_select >>> define drop_internal_purge_queue <<< drop view rai_purge_queue >>> define drop_internal_sbt_performance <<< drop view rai_sbt_performance >>> define drop_internal_recovery_window_space <<< drop view rai_recovery_window_space >>> define drop_rai_oldest_backup <<< drop view rai_oldest_backup >>> define drop_rai_recwingoal_scn <<< drop view rai_recwingoal_scn >>> define drop_rai_maxrecwin_stamp <<< drop view rai_maxrecwin_stamp >>> define drop_rai_unprotected_window <<< drop view rai_unprotected_window >>> define drop_rs_server <<< drop view ra_server >>> define drop_rs_storage_location <<< drop view ra_storage_location >>> define drop_rs_storage_histogram <<< drop view ra_storage_histogram >>> define drop_rs_purging_queue <<< drop view ra_purging_queue >>> define drop_rs_polling_policy <<< drop view ra_polling_policy >>> define drop_rs_db_access <<< drop view ra_db_access >>> define drop_rs_database_synonym <<< drop view ra_database_synonym >>> define drop_rs_protection_policy <<< drop view ra_protection_policy >>> define drop_rs_database <<< drop view ra_database >>> define drop_rs_database_storage_usage <<< drop view ra_database_storage_usage >>> define drop_rs_task <<< drop view ra_task >>> define drop_rs_time_usage <<< drop view ra_time_usage >>> define drop_rs_restore_range_i <<< drop view rai_restore_range >>> define drop_rs_disk_restore_range_i <<< drop view rai_disk_restore_range >>> define drop_rs_sbt_restore_range_i <<< drop view rai_sbt_restore_range >>> define drop_rs_restore_range <<< drop view ra_restore_range >>> define drop_rs_disk_restore_range <<< drop view ra_disk_restore_range >>> define drop_rs_sbt_restore_range <<< drop view ra_sbt_restore_range >>> define drop_rs_sbt_library <<< drop view ra_sbt_library >>> define drop_rs_sbt_attr_set <<< drop view ba_sbt_attr_set >>> define drop_rs_sbt_job <<< drop view ra_sbt_job >>> define drop_rs_sbt_task <<< drop view ra_sbt_task >>> define drop_rs_sbt_attribute_set <<< drop view ra_sbt_attribute_set >>> define drop_rs_config <<< drop view ra_config >>> define drop_rs_api_history <<< drop view ra_api_history >>> define drop_rs_replication_server <<< drop view ra_replication_server >>> define drop_rs_incident_log <<< drop view ra_incident_log >>> define drop_rs_incoming_backup_pieces <<< drop view ra_incoming_backup_pieces >>> define drop_am_host <<< drop view rai_host >>> define drop_avm_em_sbt_job <<< drop view ra_em_sbt_job_template >>> define create_rs_sq <<< CREATE SEQUENCE rai_sq MAXVALUE 18446744073709551615 CACHE 500 >>> define create_rs_recid <<< create sequence rai_recid start with 100000 maxvalue 4294967296 cycle >>> define create_sl <<< create table sl -- Storage Location ( sl_key number, -- primary key sl_name varchar2(128) not null, -- storage location name sl_type number not null, -- storage location type, one of: -- -- -- sl_cg_name varchar2(4000), -- name of container group (if any) sl_space number not null, -- size of storage location in bytes sl_hist_usage number, -- recent allocations for this SL -- sl_curr_hist_slot number, -- last storage histogram slot sl_freespace_goal number, -- freespace goal in bytes sl_last_check_files timestamp with time zone, -- -- sl_min_alloc number, -- allocation granule (au size) sl_needs_repair number default null, -- storage location needs to be -- sl_state varchar2(1), -- repair state: -- -- -- -- -- constraint sl_p primary key (sl_key), constraint sl_u unique (sl_name), constraint sl_alloc check ((bitand(sl_min_alloc,sl_min_alloc-1) = 0) and (sl_min_alloc >= 2*1024)), constraint sl_state check (sl_state IN ('F', 'E', 'I')) ) &tablespace& >>> define create_storage_dests <<< create table storage_dests ( sl_key number, -- storage location dest varchar2(4000) not null,-- disk group name or directory path needsize number default 0 not null, -- -- cursize number default 0 not null, -- usersize number default null, -- user's requested storage dest size -- constraint storage_dests_unique unique (sl_key, dest), constraint storage_dests_f1 foreign key (sl_key) references sl on delete cascade, constraint storage_dests_needsize check (needsize >= 0), constraint storage_dests_cursize check (cursize >= 0) ) &tablespace& >>> define create_sl_sizing <<< create table sl_sizing ( disk_group varchar2(128) not null, -- name of disk group init_ok varchar2(1) not null, -- 'Y' => ok for sl allocation sl_space number not null, -- maximum space that can be used for -- -- constraint sl_sizing_init check (init_ok IN ('Y', 'N')) ) &tablespace& >>> define create_poll <<< create table poll -- Polling Policies ( poll_key number, -- primary key poll_name varchar2(128), -- polling policy name sl_key number not null, -- storage location to poll poll_flags number, -- actions for polling code poll_freq interval day(9) to second, -- how often to poll poll_last_prune timestamp with time zone, -- time polling history last cleaned constraint poll_p primary key (poll_key), constraint poll_u unique (poll_name), constraint poll_f foreign key (sl_key) references sl ) &tablespace& >>> define create_prot <<< create table prot -- Protection Policy ( prot_key number, -- primary key prot_name varchar2(128) not null, -- policy name prot_description varchar2(128), -- description of policy sl_key number not null, -- default storage location poll_key number, -- polling area to be used prot_recovery_window_goal interval day(9) to second, -- -- -- -- prot_max_retention_window interval day(9) to second, -- -- prot_recovery_window_sbt interval day(9) to second,-- how far back from now -- -- prot_out_compression varchar2(99), -- how to compress VB during a restore -- prot_disk_cache varchar2(3), -- sl acting as cache for disk prot_unprotected_window interval day(9) to second,-- Recovery beyond this point -- -- constraint prot_p primary key (prot_key), constraint prot_u unique (prot_name), constraint prot_f foreign key (sl_key) references sl, constraint prot_p2 foreign key (poll_key) references poll, constraint prot_cache check (prot_disk_cache = 'YES' or prot_disk_cache = 'NO') ) &tablespace& >>> define create_odb <<< create table odb -- Oracle Data Base ( db_key number, -- primary key bs2_timestamp timestamp with time zone, -- -- purge_session number, -- session id of current purger purge_instance number, -- instance id of current purger prot_key number not null, -- protection policy future_prot_key number not null, -- same as prot_key or future prot. purge_scn number, -- Most recent SCN used to purge db purge_inc number, -- Most recent DBINC_KEY used to purge db sls_used number, -- Number of sls with storage for this db total_allocation number, -- Sum of allocations across all sl's not_taped number default 0 not null, -- space not written to sbt not_taped_state varchar2(1), -- Valid/Invalid/No tape/NULL wait_space number, -- null, unless waiting for cache space reserved_space number not null, -- current reserved space, in bytes base_reserved_space number not null, -- admin assigned reserved space in bytes recovery_window_goal interval day(9) to second, -- how far back from now the -- -- -- move_phase number, -- If not null, phase of move db -- sl_key number, -- storage location for new allocations sl_min_alloc number, -- allocation granule for sl_key allocated_space number, -- space allocated to sl_key for this odb used_space number, -- space in use in sl_key by this odb cumulative_usage number, -- cum. space used by foreground activity cumulative_rep_usage number, -- bytes sent to replication server cumulative_sbt_usage number, -- bytes sent to tape create_time timestamp with time zone, -- when odb row was created last_optimize timestamp with time zone, -- last time optimize was begun prev_optimize timestamp with time zone, -- previous optimize start last_validate timestamp with time zone, -- last time validate was run last_crosscheck timestamp with time zone, -- last time x-check was run last_replication timestamp with time zone, -- next_reconcile timestamp with time zone, -- next scheduled reconcile time last_reconcile timestamp with time zone, -- last time of reconcile platform_id number, -- platform id of protected database platform_name varchar2(101), -- platform name of protected database same_endian varchar2(1) default 'U', -- 'Y' => YES, 'N' => NO, 'U' => Unknown db_state number default null, -- odb state: -- pending_rep_setup varchar2(1) default NULL,-- 'Y'- need to complete repsetup -- -- -- -- -- constraint odb_p primary key (db_key), constraint odb_f2 foreign key (prot_key) references prot, constraint odb_sl foreign key (sl_key) references sl, constraint odb_c1 check (used_space >= 0), constraint odb_c2 check (allocated_space >= used_space), constraint odb_c3 check (total_allocation >= allocated_space), constraint odb_c4 check (db_state is null or db_state = 1) ) &tablespace& >>> define add_constraint_odb_f1 <<< alter table odb add constraint odb_f1 foreign key (db_key) references db on delete cascade >>> define create_odb_stats_cache <<< create table odb_stats_cache -- Cache for ra_database statistics ( db_key number, -- primary key footprint number, -- size of a full backup recovery_window_start date, -- time for first available full backup db_size number, -- size of the full database deduplication_factor number, -- deduplication factor for db minimum_recovery_start date, -- time for latest available full backup bdf1count number, -- number of backups for file #1 unprotected number, -- number of days in unprotected window nzdl_active varchar2(3), -- is dataguard shipping redo? last_refresh timestamp with time zone, -- -- constraint odb_stats_p primary key (db_key) ) &tablespace& >>> define create_prvlg <<< create table prvlg -- Privilege ( type number not null, -- type of access granted db_key number , -- database to which privilege applies user_id number not null, -- userid to whom privilege issued db_unique_name varchar2(32) , -- db_unique_name if db_key is null constraint prvlg_u unique (db_key, user_id, db_unique_name), constraint prvlg_f1 foreign key (db_key) references odb on delete cascade, constraint prvlg_c1 CHECK ((db_key is null and db_unique_name is not null) or (db_key is not null and db_unique_name is null)) ) &tablespace& >>> define create_prvlg_i1 <<< create index prvlg_i1 on prvlg(user_id, db_key, type) compress 1 &tablespace& >>> define create_prvlg_i2 <<< create index prvlg_i2 on prvlg(user_id, db_unique_name, type) compress 2 &tablespace& >>> define create_orsownerfn <<< create or replace function dbms_rai_owner return varchar2 is begin return sys.rai_schema(TRUE); end; >>> define create_orsverifierfn <<< create or replace function dbms_rai_verifier return varchar2 is u varchar2(512); begin select sys.kbrsi_icd.getVerifier into u from dual where exists (select 1 from prvlg p where p.user_id = uid); return u; exception when no_data_found then return null; end; >>> define create_am_inst_addresses <<< create or replace function dbms_rai_inst_addresses( client in varchar2 default 'BACKUP', level in number default 0, gethost in binary_integer default 0) return sys.odcivarchar2list pipelined as ip sys.odcivarchar2list; found boolean := FALSE; hostname varchar2(1024); cursor hostlst_c(hostlst in varchar2, level in number) is with table_to_parse as (select hostlst str from dual), myhost as (select upper(ltrim(rtrim(new_str))) ip_address, rownum id from table_to_parse, xmltable('r/c' passing xmltype('' || replace(str,',','') || '') columns new_str varchar2(512) path '.')) select ip_address from myhost where (id = level or level = 0); begin for r in (select case when client = 'ADMIN' then admin_ip_address when client = 'BACKUP' then backup_ip_address when client = 'REPLICATION' then nvl(replication_ip_address, backup_ip_address) end ip_address from rai_host) loop for hostRec in hostlst_c(r.ip_address, level) loop hostname := hostRec.ip_address; if (gethost > 0) then hostname := sys.rai_host_name(hostname); end if; pipe row(hostname); found := TRUE; end loop; end loop; if (not found and level <= 1) then ip := sys.rai_inst_addresses; for i in 1..ip.count loop hostname := ip(1); if (gethost > 0) then hostname := sys.rai_host_name(hostname); end if; pipe row(hostname); end loop; end if; end; >>> define create_am_sbt_parms <<< create or replace procedure dbms_rai_sbt_parms( nossl IN binary_integer, verifier OUT varchar2, ssl OUT binary_integer, port OUT number, chunk_size OUT number, dbname OUT varchar2, hostname OUT varchar2) is ip sys.odcivarchar2list; hostlst host.backup_ip_address%type; cursor hostlst_c(hostlst in varchar2, level in number) is with table_to_parse as (select hostlst str from dual), myhost as (select upper(ltrim(rtrim(new_str))) ip_address, rownum id from table_to_parse, xmltable('r/c' passing xmltype('' || replace(str,',','') || '') columns new_str varchar2(512) path '.')) select ip_address from myhost where (id = level or level = 0); begin port := 0; if (nossl <= 0) then ssl := 1; port := dbms_xdb_config.gethttpsport; end if; if (port is null or port = 0) then ssl := 0; port := dbms_xdb_config.gethttpport; end if; verifier := dbms_rai_verifier; select nvl(max(to_number(value)), 0) into chunk_size from config where name = 'network_chunksize'; dbname := upper(sys_context('USERENV', 'DB_NAME')); hostname := null; -- for i in (select 1 from rai_host where rownum = 1) loop select backup_ip_address ip_address into hostlst from rai_host h, v$instance i where h.node_name = i.host_name; for hostRec in hostlst_c(hostlst, 1) loop hostname := hostRec.ip_address; end loop; end loop; if (hostname is null) then ip := sys.rai_inst_addresses; hostname := ip(1); end if; hostname := sys.rai_host_name(hostname); end; >>> define create_am_url <<< create or replace procedure dbms_rai_url( client IN varchar2, level IN number, url OUT varchar2, hostname OUT varchar2, port OUT number) is chunk_size number; ssl binary_integer; ip sys.odcivarchar2list; sslstring varchar2(1); hostlst host.backup_ip_address%type; cursor hostlst_c(hostlst in varchar2, level in number) is with table_to_parse as (select hostlst str from dual), myhost as (select upper(ltrim(rtrim(new_str))) ip_address, rownum id from table_to_parse, xmltable('r/c' passing xmltype('' || replace(str,',','') || '') columns new_str varchar2(512) path '.')) select ip_address from myhost where (level = 0 or id = level); begin ssl := 1; port := dbms_xdb_config.gethttpsport; if (port is null or port = 0) then ssl := 0; port := dbms_xdb_config.gethttpport; end if; hostname := null; -- for i in (select 1 from rai_host where rownum = 1) loop select case when client = 'ADMIN' then admin_ip_address when client = 'BACKUP' then backup_ip_address when client = 'REPLICATION' then nvl(replication_ip_address, backup_ip_address) end ip_address into hostlst from rai_host h, v$instance i where h.node_name = i.host_name; for hostRec in hostlst_c(hostlst, level) loop hostname := hostRec.ip_address; end loop; end loop; if (hostname is null and level = 1) then ip := sys.rai_inst_addresses; hostname := ip(1); end if; if (hostname is null) then raise no_data_found; end if; hostname := sys.rai_host_name(hostname); if (ssl > 0) then sslstring := 's'; end if; url := 'http' || sslstring || '://' || hostname || ':' || port; end; >>> define create_am_wallet2url <<< create or replace procedure dbms_rai_wallet2url( wallet_loc IN varchar2, cred_alias IN varchar2, username OUT varchar2, password OUT varchar2, url OUT varchar2, client IN varchar2) is begin sys.kbrsi_icd.wallet2url( wallet_loc, cred_alias, username, password, url, client); end; >>> define create_avm_throttle_alloc <<< create or replace procedure dbms_rai_throttle_alloc( ba_job_id IN varchar2, db_unique_name IN varchar2, channels_reqd IN number, request_time IN date, wait OUT integer, error_str OUT varchar2) is l_wait boolean; begin dbms_ra_int.throttle_me_int(ba_job_id,db_unique_name, channels_reqd,request_time,l_wait,error_str); IF (l_wait) THEN wait := 1; ELSE wait := 0; END IF; end; >>> define create_ba_resync_clear_error <<< create or replace procedure dbms_rai_fix_error( error_num IN number) is begin dbms_ra_scheduler.fix_error( p_error_num => error_num, p_db_key => dbms_rcvman.getDbKey); end; >>> define populate_rsr_key <<< create or replace procedure dbms_rai_populate_rsr_key( bp_key IN number, bs_key IN number) IS begin dbms_ra_int.populate_rsr_key(bp_key, bs_key); end; >>> define create_unreg_database <<< create table unreg_database ( db_unique_name varchar2(32), sl_key number, prot_key number, reserved_space number, constraint unreg_database_p primary key (db_unique_name), constraint unreg_database_f1 foreign key (sl_key) references sl, constraint unreg_database_f2 foreign key (prot_key) references prot ) &tablespace& >>> define create_unreg_database_trigger <<< create or replace trigger unreg_database_trigger before insert or update on unreg_database for each row declare cnt number; begin select count(*) into cnt from node where db_unique_name = upper(:new.db_unique_name); if (cnt > 0) then raise dup_val_on_index; end if; end; >>> define add_constraint_node_u2 <<< alter table node add constraint node_u2 unique(db_unique_name) using index (create unique index node_u2 on node(db_unique_name) &tablespace&) >>> define drop_constraint_node_u1 <<< alter table node drop constraint node_u1 drop index >>> define create_node_insert_update <<< create or replace trigger node_insert_update before insert or update on node for each row declare db_uname varchar2(32); l_db_id number; l_cnt number; cursor unreg_db(db_uname in varchar2) is select prot_key, reserved_space from unreg_database where db_unique_name = upper(unreg_db.db_uname) for update; cnt number; begin if (UPDATING AND NVL(:old.db_unique_name, '@') = NVL(:new.db_unique_name, '@')) THEN return; end if; if substr(:new.db_unique_name, 1,1) = '$' then db_uname := substr(:new.db_unique_name, 2, instr(substr(:new.db_unique_name, 2, 32), '$') - 1); else db_uname := :new.db_unique_name; end if; -- -- for rec in unreg_db(db_uname) loop insert into odb (db_key, sls_used, total_allocation,sl_key, sl_min_alloc,allocated_space, used_space, cumulative_usage, cumulative_rep_usage, cumulative_sbt_usage, create_time, last_optimize, last_validate, last_crosscheck, prot_key, future_prot_key, pending_rep_setup, reserved_space, base_reserved_space, recovery_window_goal, not_taped, not_taped_state) (select :new.db_key, 1, 0, sl.sl_key, sl.sl_min_alloc, 0, 0, 0, 0, 0, SYSTIMESTAMP, SYSTIMESTAMP, SYSTIMESTAMP, SYSTIMESTAMP, prot.prot_key, prot.prot_key, NULL, rec.reserved_space, rec.reserved_space, prot.prot_recovery_window_goal, 1, decode(prot.prot_disk_cache, 'YES', 'I', null) from prot, sl where prot_key = rec.prot_key and prot.sl_key = sl.sl_key); -- -- -- -- select count (*) into l_cnt from rep_server, odb where odb.db_key= :new.db_key and odb.prot_key=rep_server.prot_key; if l_cnt > 0 then update odb set pending_rep_setup='Y' where db_key = :new.db_key; end if; update prvlg set db_key = :new.db_key, db_unique_name = null where db_unique_name = upper(db_uname); -- -- select db_id into l_db_id from db where db_key=:new.db_key; select count(*) into l_cnt from vpc_databases where db_id = l_db_id and reg_db_unique_name is null; if l_cnt = 0 then update vpc_databases set db_id=l_db_id, reg_db_unique_name=null where reg_db_unique_name=:new.db_unique_name and db_id = 0; else delete vpc_databases where reg_db_unique_name=:new.db_unique_name and db_id = 0; end if; delete unreg_database where current of unreg_db; update db set storage_prov = 'Y' where db_key = :new.db_key; end loop; -- select count(*) into cnt from unreg_database where db_unique_name = upper(:new.db_unique_name); if (cnt > 0) then raise dup_val_on_index; end if; end; >>> define create_dbsl <<< create table dbsl -- Storage usage for db in sl's -- ( db_key number not null, -- from db table sl_key number not null, -- from sl table dbsl_used_space number not null, -- space used in this sl for db constraint dbsl_p primary key (db_key, sl_key), constraint dbsl_f1 foreign key (db_key) references db, constraint dbsl_sl foreign key (sl_key) references sl ) &tablespace& >>> define create_chunks <<< create table chunks -- master chunk table ( df_key number, -- datafile key chunkno number, -- chunk number sl_key number not null, -- storage location key dbinc_key number not null, -- database incarnation key clean_key number, -- Key to recover not-resumable operation filesize number not null, -- size of the chunk in bytes filename varchar2(512), -- OMF name for the chunk constraint chunks_u primary key (df_key, chunkno), constraint chunks_dbinc foreign key (dbinc_key) references dbinc, constraint chunks_sl foreign key (sl_key) references sl -- -- ) organization index compress 1 initrans 2 pctfree 20 including filesize overflow &tablespace& partition by hash (df_key) partitions 1024 &tablespace& >>> define create_df_seq <<< create table df_seq -- Sequence numbers for chunks.chunkno ( df_key number, -- from df table chunkno number not null, -- next available chunk number for df constraint df_seq_p primary key (df_key) using index ( create unique index df_seq_p on df_seq(df_key) local) ) partition by hash (df_key) partitions 16 &tablespace& >>> define create_blocks <<< create table blocks -- Master block table ( dbinc_key number not null, -- Database incarnation df_key number not null, -- Data file key blockno number not null, -- Data block number ckp_id number not null, -- Backup ckp_scn (we add 1 for each read only) scn number not null, -- Data block SCN. chunkno number not null, -- Chunk number used number not null, -- size includes chunk block kcbh and tail if needed coffset number not null -- chunk offset in bytes ) pctfree 2 partition by hash (df_key) partitions 1024 &tablespace& >>> define add_index_blocks_u <<< create unique index blocks_u on blocks (df_key, blockno, scn DESC, ckp_id DESC, chunkno DESC, coffset, used, dbinc_key) local compress 2 &tablespace& >>> define add_index_blocks_c <<< create index blocks_c on blocks (df_key, chunkno, blockno) local compress 2 &tablespace& >>> define create_vbdf <<< create table vbdf ( vb_key number not null, -- Virtual Backup ID df_key number not null, -- Datafile key db_key number not null, -- Database Key pdbinc_key number, -- Pluggable Database Incarnation Key dbinc_key number not null, -- Database Incarnation Key incr_scn number, -- Incremental start SCN ckp_scn number not null, -- Checkpoint SCN abs_scn number, -- Absolute fuzzy SCN ckp_id number not null, -- Backup ckp_scn (we add 1 for each read only) unorder_id number, -- max(ckp_id) for last "unordered" block min_id number, -- Latest level 0 ckp_id file# number not null, -- Data file number blocks number not null, -- Data file size in blocks firstblk number not null, -- First block in a multi-section piece lastblk number not null, -- Last block in a multi-section piece cmpvsn number, -- Version (ph->kccfh_krbph.kccfhcvn) relfno number, -- Backup relative file# state number not null, -- See VBDF_* constants in DBMS_RA_INT package krbph_dfkey number, -- DF_KEY to which the krbph is assigned. krbph_chunkno number, -- Chunk# to find krbph, null if not current new_krbph number, -- krbph chunk# when being moved dfbytes number, -- Estimate size of the datafile (if restore) dfblocks number, -- Not size (# of logical blocks) signature number, -- Numeric signature for virtual backup srcbp_key number, -- Source bp_key vcbp_key number, -- Virtual Copy bp_key corrupt varchar2(1), -- Y if corruption in this df, null if not chunks_used number, -- Chunks freed when virtual backup is deleted constraint vbdf_u primary key (vb_key, df_key), constraint vbdf_u2 unique (dbinc_key, df_key, ckp_id), constraint vbdf_u3 unique (df_key, ckp_scn, vb_key), constraint vbdf_key check (vb_key > 0 and -- UB8MAXVAL vb_key < 18446744073709551615), constraint vbdf_min check (min_id <= ckp_id), constraint vbdf_dbinc foreign key (dbinc_key) references dbinc, constraint vbdf_db foreign key (db_key) references db -- -- -- -- ) &tablespace& >>> define create_bp_i_vbkey <<< create index bp_i_vbkey on bp (vb_key) &tablespace& >>> define create_plans <<< create table plans ( type number not null, -- Type of plan db_key number not null, -- Database Key vb_key number not null, -- Virtual Backup Key df_key number not null, -- Datafile key task_id number, -- Optional task_id for temp plans old number, -- For plans ready to be deleted blksread number, -- Total number of blocks to read maxrank number, -- For purge, duplicate blockno have rankings numchunks number, -- count of distinct chunks in plan readsize number, -- computation of buffer size to use for read needchunk number, -- Number of chunks needed to purge this vb_key freechunk number, -- Number of chunks freed by purging this vb constraint plans_u primary key (df_key, type, vb_key), constraint plans_db foreign key (db_key) references db ) &tablespace& >>> define create_plans_det <<< create table plans_details ( df_key number, -- Datafile key type number, -- Type of plan vb_key number, -- Virtual Backup ID blkrank number, -- block ranking (used in purge) blockno number, -- block number chunkno number, -- chunk number numblks number, -- number of logical blocks to copy coffset number, -- offset in chunk numbytes number, -- number of bytes to copy signature number, -- (opt) sum of all the datafile block scn values constraint plans_det_u primary key (df_key, type, vb_key, blkrank, blockno, chunkno) ) organization index compress 4 initrans 2 pctfree 2 partition by hash (df_key) partitions 1024 &tablespace& >>> define create_sbt_catalog <<< create table sbt_catalog -- Files received by SBT ( ct_key number, db_key number not null, cretime timestamp with time zone not null, handle varchar2(1024) not null, pieceinc varchar2(32) not null, endupload varchar2(1), -- 'Y', 'N', 'D' for file chunks. Otherwise, NULL. bp_key number, ftype varchar2(1) not null, -- 'F'(file piece), 'T'(tape piece), -- -- xmldoc sys.xmltype, -- sl_key number, sl_min_alloc number, filename varchar2(1024), filesize number, last_entry timestamp with time zone, completed varchar2(1), -- Y or N (storage complete) -- constraint sbt_catalog_p primary key (ct_key), constraint sbt_catalog_u1 unique (handle, pieceinc), constraint sbt_catalog_u2 unique (bp_key), constraint sbt_catalog_c1 check ((endupload in ('Y', 'N', 'D') and endupload is not null and ftype = 'F') or (endupload is null and ftype != 'F')), constraint sbt_catalog_c2 check (ftype in ('F', 'T', 'D', 'V')), constraint sbt_catalog_c3 check (ftype = 'F' or filesize is null), constraint sbt_catalog_c4 check ((completed in ('Y', 'N') and completed is not null and ftype = 'F') or (completed is null and ftype != 'F')), constraint sbt_catalog_c5 check ((ftype = 'F') or (filesize is null and ftype != 'F')), constraint sbt_catalog_c6 check ((nvl(completed, 'Y') = 'Y' and nvl(endupload, 'Y') = 'Y' and bp_key is not null and xmldoc is not null) or (bp_key is null)), constraint sbt_catalog_f1 foreign key (db_key) references db, constraint sbt_catalog_f2 foreign key (bp_key) references bp on delete cascade deferrable initially deferred ) &tablespace& xmltype xmldoc store as clob >>> define create_bp_foreign_ct_key <<< alter table bp add constraint bp_foreign_ct_key foreign key (ct_key) references sbt_catalog deferrable initially deferred >>> define create_sbt_catalog_i_1 <<< create unique index sbt_catalog_i_1 on sbt_catalog (case when (nvl(completed, 'Y') = 'Y' or bp_key is not null or endupload = 'Y') then handle else null end) &tablespace& >>> define create_sbt_catalog_i_2 <<< create unique index sbt_catalog_i_2 on sbt_catalog (case when (filesize is not null) then filename else null end) &tablespace& >>> define create_sbt_catalog_i_3 <<< create index sbt_catalog_i_3 on sbt_catalog(db_key, handle) &tablespace& >>> define create_update_sbt_catalog_pieceinc <<< create or replace trigger update_sbt_catalog_pieceinc before update on sbt_catalog for each row when (new.ct_key = old.ct_key and new.pieceinc != old.pieceinc) begin with o as (select extractValue(:old.xmldoc, '//ChunkPrefix/text()') prefix from dual), n as (select regexp_replace(o.prefix, :old.pieceinc, :new.pieceinc, instr(o.prefix, :old.pieceinc, -1 , 1)) prefix from o) select XMLQuery('copy $i := $p1 modify ((for $j in $i//Incarnation return replace value of node $j with $p2), (for $j in $i//ChunkPrefix return replace value of node $j with $p3)) return $i' passing :old.xmldoc AS "p1", :new.pieceinc AS "p2", n.prefix AS "p3" RETURNING CONTENT) into :new.xmldoc from n; end; >>> define create_chk_delete_sbt_catalog <<< create or replace trigger chk_delete_sbt_catalog after delete on sbt_catalog for each row when (old.filesize is not null) begin sys.dbms_sys_error.raise_system_error(-45113 /*E_INTERNAL_ERROR_NUM*/, 'illegal sbt_catalog delete of bp_key ' || :old.bp_key); end; >>> define create_new_df_check <<< create or replace trigger new_df_check after insert on df for each row begin dbms_ra_scheduler.newdfkey(:new.df_key,:new.dbinc_key,:new.pdbinc_key); end; >>> define create_sbt_session <<< create table sbt_session ( session_id varchar2(64), db_key number not null, cretime timestamp with time zone not null, modtime timestamp with time zone not null, constraint sbt_session_p primary key (session_id), constraint sbt_session_f1 foreign key (db_key) references db on delete cascade ) &tablespace& >>> define create_sessions <<< create table sessions ( ba_session_id number, current_task number, current_task_type number, spid varchar2(128), instance_id number, sid number, serial# number, audsid number, logon_time date, start_time timestamp with time zone, trace_file varchar2(512), last_task_start timestamp with time zone, last_config_change timestamp with time zone, last_quiesce timestamp with time zone, last_busywork_stop timestamp with time zone, purpose number, -- task_type (special task process) purpose_param1 number, -- special task param1 (or max task_type) purpose_param2 number, -- special task param2 job_name varchar2(128), constraint sessions_p primary key (ba_session_id), constraint sessions_u unique(current_task) ) &tablespace& >>> define create_task <<< create table task ( task_id number, task_type number, priority number, flags number, db_key number, sl_key number, state number, pending_interrupt number, interrupt_count number, savepoint number, param_num1 number, param_num2 number, param_num3 number, param_char1 varchar2(1000), param_char2 varchar2(1000), param varchar2(4000), ba_session_id number, execute_inst_id number, schedule_time timestamp with time zone, execute_time timestamp with time zone, last_execute_time timestamp with time zone, completion_time timestamp with time zone, last_interrupt_time timestamp with time zone, error_count number, purge_reserve number, elapsed_time interval day(9) to second(6), com_time timestamp with time zone, sbt_task_id number, creator_task_id number, creator_sid number, creator_instance number, constraint task_p primary key (task_id), constraint task_c1 check (nvl(purge_reserve,0) >= 0), /*TASK_SESSION_TIMES*/ constraint task_c2 check (flags is not null or task_type >= 2000), constraint task_c3 check (nvl(flags,0) between 0 and to_number('007f','xxxx')) ) &tablespace& >>> define create_task_i1 <<< create index task_i1 on task(task_type, param_num1) &tablespace& >>> define create_task_i2 <<< create index task_i2 on task(priority, state, task_id, task_type, execute_inst_id, sbt_task_id, pending_interrupt) &tablespace& >>> define create_task_i3 <<< create index task_i3 on task(state, db_key) &tablespace&>>> define create_task_i4 <<< create index task_i4 on task(pending_interrupt) &tablespace&>>> define create_task_i5 <<< create index task_i5 on task(sbt_task_id) &tablespace&>>> define create_task_spawn_sbt_i <<< create unique index task_spawn_sbt_i on task( case when task_type = 1 and state in (1, 2) then param_num1 end ,case when task_type = 1 and state in (1, 2) then param_num2 end) &tablespace& >>> define create_task_f1 <<< alter table task add constraint task_f1 foreign key(sbt_task_id) references sbt_task on delete set null initially deferred deferrable >>> define drop_task_f1 <<< alter table task drop constraint task_f1 >>> define create_task_history <<< create table task_history &tablespace& -- -- -- as select * from task where 1=0 >>> define create_task_chunk_cache <<< create table task_chunk_cache ( inst_id number, task_id number, chunk_cache number not null, cumulative_incr number not null, constraint tcc_u1 primary key (task_id) using index ( create unique index tcc_u1 on task_chunk_cache(task_id) global partition by hash (task_id) partitions 16), constraint tcc_f1 foreign key (task_id) references task, constraint tcc_c1 check (inst_id > 0) ) partition by range(inst_id) ( partition p001 values less than(02) , partition p002 values less than(03) , partition p003 values less than(04) , partition p004 values less than(05) , partition p005 values less than(06) , partition p006 values less than(07) , partition p007 values less than(08) , partition p008 values less than(09) , partition p009 values less than(10) , partition p010 values less than(11) , partition p011 values less than(12) , partition p012 values less than(13) , partition p013 values less than(14) , partition p014 values less than(15) , partition p015 values less than(16) , partition p016 values less than(17) , partition p256 values less than(257) ) &tablespace& >>> define create_tasktypenames <<< create table tasktypenames ( task_type number, task_type_name varchar2(30), constraint ttn_u primary key (task_type) ) organization index &tablespace& >>> define create_timer_task <<< create table timer_task ( timer_type number, timer_location number, flags number, next_execute timestamp with time zone, timer_interval interval day(9) to second(6), param_num1 number, constraint timer_task_p primary key (timer_type, timer_location) ) &tablespace& >>> define create_timer_task_t <<< create index timer_task_t on timer_task (next_execute) &tablespace& >>> define create_storage_histogram <<< create table storage_histogram ( sl_key number, slot number, usage number, constraint storage_histogram_p primary key (sl_key, slot), constraint storage_histogram_f1 foreign key (sl_key) references sl on delete cascade ) &tablespace& >>> define create_error_log <<< create table error_log ( incident# number, error_num number, sl_key number, db_key number, param_num number, param_char varchar2(1000), task_id number, status varchar2(6), component varchar2(30), severity number, error_text varchar2(4000), first_seen timestamp with time zone not null, last_seen timestamp with time zone not null, seen_count number not null, ospid varchar2(24), inst_id number, trace_file varchar2(512), call_stack varchar2(4000), final_call_stack varchar2(4000), final_backtrace_stack varchar2(4000), constraint error_log_u1 unique (error_num,sl_key,db_key,param_num,param_char), constraint error_log_c1 check (status IN ('ACTIVE', 'FIXED', 'RESET')), constraint error_log_f1 foreign key (sl_key) references sl on delete cascade, constraint error_log_f2 foreign key (db_key) references odb on delete cascade ) &tablespace& >>> define create_error_log_i1 <<< create index error_log_i1 on error_log(status, severity) &tablespace& >>> define create_polling_history <<< create table polling_history ( poll_key number, fname varchar2(512), fsize number, status varchar2(1), fail_time timestamp with time zone, -- constraint polling_history_c1 check (status in ('P', 'C', 'D', 'F', 'E', 'T', 'R')), constraint polling_history_f1 foreign key (poll_key) references poll on delete cascade ) &tablespace& >>> define create_polling_history_i1 <<< create index polling_history_i1 on polling_history (poll_key, status, fname) &tablespace& >>> define create_metadata_filenames <<< create table metadata_filenames ( sl_key number, fname varchar2(512), constraint mf_u primary key (sl_key, fname), constraint mf_f1 foreign key (sl_key) references sl on delete cascade ) organization index compress &tablespace& >>> define create_contained_filenames <<< create table contained_filenames ( sl_key number, fname varchar2(512), constraint contf_u primary key (sl_key, fname), constraint contf_f1 foreign key (sl_key) references sl on delete cascade ) organization index compress &tablespace& >>> define create_missing_metadata_filenames <<< create table missing_metadata_filenames ( sl_key number, fname varchar2(512), entered timestamp with time zone, latest timestamp with time zone, constraint mmf_u primary key (sl_key, fname), constraint mmf_f1 foreign key (sl_key) references sl on delete cascade ) organization index compress &tablespace& >>> define create_rs_jobs_type <<< create or replace type rai_jobs_type is object ( job_name varchar2(128), instance_id number, comments varchar2(240) ) >>> define create_rs_jobs_table_type <<< create or replace type rai_jobs_table_type is table of rai_jobs_type >>> define create_rs_locks_type <<< create or replace type rai_locks_type is object ( inst_id number, ba_type number, key number, lmode number, ctime number, sid number ) >>> define create_rs_locks_table_type <<< create or replace type rai_locks_table_type is table of rai_locks_type >>> define create_avm_pending_jobs <<< create table rai_pending_jobs ( ba_job_id varchar2(256), request_time date, channels_reqd number, last_ping_time date, db_unique_name varchar2(32), approval_time date, constraint rai_pending_jobs_p primary key(ba_job_id) ) organization index &tablespace& >>> define create_sbt_lib_desc <<< create table sbt_lib_desc ( lib_key number not null, -- seq generated primary key lib_name varchar2(128) not null, -- a unique library name drives number not null, -- total # of tape drives restore_drives number default 0 not null, -- drives reserved for restore parms varchar2(1024), -- sbt parms send varchar2(1024), -- sbt send command server_key number, -- Server key for rep server -- status varchar2(1), -- 'R' - Ready, 'P' - Pause -- failure_cnt number not null, -- # of contiguous failure dynamic_drives varchar2(1) not null, -- 'Y' - drives dynamically -- constraint sbt_lib_desc_p primary key (lib_key), -- primary key constraint sbt_lib_desc_u unique(lib_name), constraint sbt_lib_desc_c1 check (drives > 0), constraint sbt_lib_desc_c2 check (status in ('R', 'P', 'E')), constraint sbt_lib_desc_c3 check (dynamic_drives in ('Y', 'N')) ) &tablespace& >>> define create_sbt_lib_inst_rlist <<< create table sbt_library_inst_rlist ( lib_key number not null, instance_name varchar2(16) not null, constraint sbt_library_inst_rlist_u unique(lib_key, instance_name), constraint sbt_library_inst_rlist_f foreign key(lib_key) references sbt_lib_desc on delete cascade ) &tablespace& >>> define drop_ba_drives_sbt_lib_desc <<< alter table sbt_lib_desc drop column ba_drives >>> define create_bp_foreign_lib_key <<< alter table bp add constraint bp_foreign_lib_key foreign key (lib_key) references sbt_lib_desc >>> define create_bp_foreign_template_key <<< alter table bp add constraint bp_foreign_template_key foreign key (template_key) references sbt_job_template on delete set null initially deferred deferrable >>> define create_bp_i_lib_key <<< create index bp_i_lib_key on bp (lib_key) &tablespace& >>> define create_bp_i_template_key <<< create index bp_i_template_key on bp (template_key) &tablespace& >>> define create_sbt_attr_set <<< create table sbt_attr_set ( lib_key number not null, -- sbt_library to which this attr belongs attr_key number not null, -- sequence generated primary key attr_name varchar2(128) not null,-- unique name describing the attribute streams number, -- total # of streams used for this attr poolid number, -- pool integer passed to sbt api parms varchar2(1024), -- sbt parms; merged with sbt_library_conf send varchar2(1024), -- merged with sbt_lib_desc constraint sbt_attr_set_p primary key (attr_key), -- primary key constraint sbt_attr_set_u unique (attr_name), constraint sbt_attr_set_f foreign key (lib_key) references sbt_lib_desc on delete cascade, constraint sbt_attr_set_c1 check (streams is null or streams > 0) ) &tablespace& >>> define create_sbt_job_template <<< create table sbt_job_template ( template_key number, -- primary key template_name varchar2(128) not null, -- template name full_template_key number, -- full template key prot_key number, -- protection policy key db_key number, -- database key bck_type number not null, -- 1 -> all backup -- -- -- from_tag varchar2(32), -- tag to filter the source priority number default 100, -- priority of db to do sbt backup attr_key number, -- sbt attribute key copies number default 1 not null, -- # of duplex copies schedule_time timestamp with time zone, -- job scheduled at this timestamp window interval day to second, -- window interval for the job completion_time timestamp with time zone, -- end time of job constraint sbt_job_template_p primary key (template_key), constraint sbt_job_template_u1 unique (template_name), constraint sbt_job_template_u2 unique (template_key, attr_key), constraint sbt_job_template_u3 unique (template_key, full_template_key), constraint sbt_job_template_f1 foreign key (attr_key) references sbt_attr_set on delete cascade, constraint sbt_job_template_f2 foreign key (prot_key) references prot on delete cascade, constraint sbt_job_template_f3 foreign key (db_key) references odb on delete cascade, constraint sbt_job_template_f4 foreign key (full_template_key) references sbt_job_template(template_key), constraint sbt_job_template_c1 check (bck_type in (1,2,4,6,8,10,12,14,32)), constraint sbt_job_template_c2 check (copies between 1 and 4) ) &tablespace& >>> define create_sbt_job_template_i1 <<< create index sbt_job_template_i1 on sbt_job_template(completion_time) &tablespace& >>> define create_sbt_job_template_i2 <<< create index sbt_job_template_i2 on sbt_job_template(full_template_key) &tablespace& >>> define create_sbt_job_template_i3 <<< create index sbt_job_template_i3 on sbt_job_template(db_key) &tablespace& >>> define create_sbt_template_db_i1 <<< create index sbt_template_db_i1 on sbt_template_db(template_key) &tablespace& >>> define create_sbt_template_db_f1 <<< alter table sbt_template_db add constraint sbt_template_db_f1 foreign key (db_key) references odb on delete cascade >>> define create_sbt_template_db_f2 <<< alter table sbt_template_db add constraint sbt_template_db_f2 foreign key (template_key) references sbt_job_template on delete cascade >>> define create_sbt_template_df <<< create table sbt_template_df ( db_key number not null, template_key number not null, df_file# number, df_ts# number, df_plugin_change# number, df_foreign_dbid number, df_tablespace varchar2(30), df_creation_change# number, backup_type varchar2(30), file_type varchar2(30), bs_key number, df_checkpoint_change# number, constraint sbt_template_df_u1 unique (db_key, template_key, df_file#, df_creation_change#, df_plugin_change#), constraint sbt_template_df_f1 foreign key (db_key, template_key) references sbt_template_db on delete cascade, constraint sbt_template_df_f2 foreign key (template_key) references sbt_job_template on delete cascade ) &tablespace& >>> define create_sbt_template_df_i1 <<< create index sbt_template_df_i1 on sbt_template_df(template_key, db_key, df_file#) &tablespace& >>> define create_sbt_task <<< create table sbt_task ( task_id number, bs_key number, piece# number, template_key number, full_template_key number, attr_key number, lib_key number, copies number, rep_server_key number, failure_cnt number not null, restore varchar2(1), -- 'Y' or 'N' src_bpkey number, -- bp_key that we are copying off to sbt delete_source varchar2(1), -- 'Y' or 'N', used for archiving. Del original bp after copy format varchar2(512), -- format string for copied piece constraint sbt_task_p primary key (task_id), constraint sbt_task_u1 unique (bs_key, piece#, full_template_key), constraint sbt_task_f1 foreign key (template_key, attr_key) references sbt_job_template(template_key, attr_key) on delete cascade deferrable initially deferred, constraint sbt_task_f2 foreign key (lib_key) references sbt_lib_desc on delete cascade, constraint sbt_task_f3 foreign key (bs_key) references bs on delete cascade, constraint sbt_task_f4 foreign key (rep_server_key) references rep_server on delete cascade, constraint sbt_task_f5 foreign key(task_id) references task initially deferred deferrable, constraint sbt_task_f6 foreign key (full_template_key) references sbt_job_template on delete cascade, constraint sbt_task_c1 check (restore in ('Y', 'N')), constraint sbt_task_c2 check (delete_source in ('Y', 'N')) ) &tablespace& >>> define create_sbt_task_i1 <<< create index sbt_task_i1 on sbt_task(task_id, template_key, bs_key, piece#) &tablespace& >>> define create_sbt_task_i2 <<< create index sbt_task_i2 on sbt_task(bs_key) &tablespace& >>> define create_sbt_task_i3 <<< create index sbt_task_i3 on sbt_task(template_key, attr_key) &tablespace& >>> define create_sbt_task_history <<< create table sbt_task_history ( task_id number, bs_key number, piece# number, template_key number, full_template_key number, attr_key number, lib_key number, copies number, rep_server_key number, failure_cnt number not null, restore varchar2(1), -- 'Y' or 'N' src_bpkey number, -- bp_key that we are copying off to sbt delete_source varchar2(1), -- 'Y' or 'N', used for archiving. Del original bp after copy format varchar2(512), -- format string for copied piece constraint sbt_task_history_p primary key (task_id), -- -- -- constraint sbt_task_history_f1 foreign key (template_key) references sbt_job_template on delete set null, constraint sbt_task_history_f2 foreign key (attr_key) references sbt_attr_set on delete set null, constraint sbt_task_history_f3 foreign key (lib_key) references sbt_lib_desc on delete cascade, constraint sbt_task_history_f4 foreign key (bs_key) references bs on delete cascade, constraint sbt_task_history_f5 foreign key (rep_server_key) references rep_server on delete cascade, constraint sbt_task_history_f6 foreign key (full_template_key) references sbt_job_template on delete cascade, constraint sbt_task_history_c1 check (restore in ('Y', 'N')), constraint sbt_task_history_c2 check (delete_source in ('Y', 'N')) ) &tablespace& >>> define create_sbt_task_history_i1 <<< create index sbt_task_history_i1 on sbt_task_history(task_id, template_key, bs_key, piece#) &tablespace& >>> define create_sbt_task_history_i2 <<< create index sbt_task_history_i2 on sbt_task_history(bs_key) &tablespace& >>> define create_rep_server <<< create table rep_server -- Replication Server definition ( rep_server_key number, -- primary key server_key number, -- joinable with sbt_lib_desc or server tables prot_key number, -- protection policy(ies) using this -- status varchar2(1), -- status of replication server -- constraint rep_server_status_c1 check (status in ('A', 'C', 'D', 'T')), constraint rep_server_p primary key (rep_server_key), constraint rep_server_f1 foreign key (server_key) references server on delete cascade, constraint rep_server_f2 foreign key (prot_key) references prot ) &tablespace& >>> define create_host <<< create table host -- AM Host IP Addresses ( node_name varchar2(256) not null, -- node name with domain name admin_ip_address varchar2(4000) not null, -- admin interface backup_ip_address varchar2(4000) not null, -- client interface replication_ip_address varchar2(4000) null, -- backup interface constraint host_p primary key (backup_ip_address), constraint host_unique unique (node_name, backup_ip_address) ) &tablespace& >>> define dbmsrsi_plb <<< CREATE OR REPLACE PACKAGE dbms_ra_int IS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- TRACE_RSI CONSTANT NUMBER := 2; TRACE_RSI_MAX CONSTANT NUMBER := 4; TRACE_RSJS CONSTANT NUMBER := 8; TRACE_RCVCAT CONSTANT NUMBER := 16; TRACE_RCVCAT_MAX CONSTANT NUMBER := 32; TRACE_KRBS CONSTANT NUMBER := 64; TRACE_KRBS_SQL CONSTANT NUMBER := 128; TRACE_KRBR CONSTANT NUMBER := 256; -- INC_ARC_PREFIX CONSTANT VARCHAR2(30) := 'I_ARC$'; -- -- BIGNUM CONSTANT NUMBER := 9999999999999999999999999999999999999999; -- UB8MAXVAL CONSTANT NUMBER := 18446744073709551615; UB4MAXVAL CONSTANT NUMBER := 4294967295; -- KBRSCHKTYPE_FILE CONSTANT NUMBER := 1; /* BPs in an SL */ KBRSCHKTYPE_VIRTUAL CONSTANT NUMBER := 2; /* BPs from block pool */ KBRSCHKTYPE_TAPE CONSTANT NUMBER := 3; /* BPs on tape */ KBRSCHKTYPE_DISK CONSTANT NUMBER := 4; /* BPs on disk we do not manage */ -- BACKUP_READ CONSTANT NUMBER := 2**0; BACKUP_WRITE CONSTANT NUMBER := 2**1; RECONCILE_READ CONSTANT NUMBER := 2**2; RECONCILE_WRITE CONSTANT NUMBER := 2**3; -- -- -- -- incremental_no_fit EXCEPTION; PRAGMA EXCEPTION_INIT(incremental_no_fit, -45107); -- backup_cannot_fit EXCEPTION; PRAGMA EXCEPTION_INIT(backup_cannot_fit, -45108); -- bad_block_metadata_num CONSTANT NUMBER := -45109; bad_block_metadata EXCEPTION; PRAGMA EXCEPTION_INIT(bad_block_metadata, -45109); -- -- -- TYPE kccbs_t IS RECORD ( bsstm number, bsbss number, bsbsc number, bspct number, bstyp number, bslvl number, bskpt number, bsbsz number, bspfw number, bsplw number, bscal number, bsoid raw(16), bsste number ); -- -- -- TYPE kccbp_t IS RECORD ( bpstm number, bpbss number, bpbsc number, bpflg number, bpnum number, bptim number, bpext number, bpsz1 number, bpdev varchar2(17), bphdl varchar2(513), bpmdh varchar2(81), bpcmt varchar2(65), bptag varchar2(32), bpoid raw(16), bpsts number ); -- -- -- TYPE kccbf_t IS RECORD ( bfstm number, bfbss number, bfbsc number, bfflg number, bfdfp number, bflvl number, bfcrs number, bfcrt number, bfcps number, bfcpt number, bfrls number, bfrlc number, bfics number, bfafs number, bfncb number, bfmcb number, bflcb number, bffsz number, bfbct number, bfbsz number, bflor number, bfbrd number, bfsix number, bffdi number, bfplus number, bfprls number, bfprlt number, bfptsn number, bfssb number, bfssz number, bfoid raw(16), bfste number ); -- -- -- TYPE kccbl_t IS RECORD ( blstm number, blbss number, blbsc number, blthp number, blseq number, blrls number, blrlc number, bllos number, bllot number, blnxs number, blnxt number, blbct number, blbsz number, blsix number, blflg number, blste number ); -- -- -- TYPE kccbi_t IS RECORD ( bistm number, bibss number, bibsc number, biflg number, bifsz number, bisix number, bimdt number, bidun varchar2(30), bioid raw(16) ); -- -- -- TYPE kccal_t IS RECORD ( alstm number, alflg number, althp number, alseq number, alrls number, alrlc number, allos number, allot number, alnxs number, alnxt number, albct number, albsz number, altoa number, aldly number, alacd number, alfl2 number, aldst number, alnam varchar2(513) ); -- TYPE callstack_line IS RECORD (line NUMBER, unit VARCHAR2(128)); TYPE callstack IS TABLE OF callstack_line; TYPE error_payload IS RECORD ( dynamic_stack callstack , backtrace_stack callstack , error_depth PLS_INTEGER , action varchar2(64) , module varchar2(64)); TYPE payload_stack IS TABLE OF error_payload; s_pl_stack payload_stack := payload_stack(); -- FUNCTION stamp2date(stamp IN NUMBER) RETURN DATE; FUNCTION date2stamp(dt IN DATE) RETURN NUMBER; -- FUNCTION dbkey2name(p_dbkey IN NUMBER) RETURN VARCHAR2; -- PROCEDURE write_lock(p_type IN NUMBER, p_key IN NUMBER); FUNCTION write_lock_wait(p_type IN NUMBER, p_key IN NUMBER) RETURN BOOLEAN; FUNCTION read_lock(p_type IN NUMBER, p_key IN NUMBER) RETURN BOOLEAN; PROCEDURE unlock(p_type IN NUMBER, p_key IN NUMBER); KEY_DF CONSTANT NUMBER := 1; KEY_BP CONSTANT NUMBER := 2; KEY_AL CONSTANT NUMBER := 3; KEY_SY CONSTANT NUMBER := 4; -- sbt library object KEY_CT CONSTANT NUMBER := 5; -- sbt catalog object KEY_VB CONSTANT NUMBER := 6; -- -- AM_DEBUG_OFF CONSTANT NUMBER := 0; -- Debug off AM_DEBUG_ON CONSTANT NUMBER := 1; -- Always on, for exeptions only AM_DEBUG_LOW CONSTANT NUMBER := 2; -- Odd and rare conditions AM_DEBUG_MED CONSTANT NUMBER := 3; -- Common, but not too wordy AM_DEBUG_HIGH CONSTANT NUMBER := 4; -- Everything worth showing. -- PROCEDURE setDebug(p_level IN NUMBER, p_outtype IN NUMBER DEFAULT sys.dbms_system.trace_file); -- PROCEDURE save_error_int; -- PROCEDURE clear_error_int(reset BOOLEAN DEFAULT FALSE); -- FUNCTION get_error RETURN VARCHAR2; PROCEDURE unlock_vb(p_vbkey IN NUMBER, p_novbkey IN BOOLEAN); -- Do not unlock vbkey -- PROCEDURE validateBackupPiece(p_dbkey IN NUMBER, p_bpkey IN NUMBER); -- FUNCTION file2handle(p_fname VARCHAR2) RETURN VARCHAR2; -- PROCEDURE createSbtCatalog(p_dbid IN NUMBER, p_handle IN VARCHAR2, p_pieceinc IN VARCHAR2, p_ftype IN NUMBER, p_xmldoc IN CLOB, p_commit IN BOOLEAN, p_ct_key OUT NUMBER); -- PROCEDURE copySbtCatalog(p_handle IN VARCHAR2, p_oldpieceinc IN VARCHAR2, p_newpieceinc IN VARCHAR2); -- PROCEDURE endUploadSbtCatalog(p_handle IN VARCHAR2, p_pieceinc IN VARCHAR2, p_xmldoc IN CLOB); -- PROCEDURE finalizeSbtCatalog(p_bp_key IN NUMBER, p_ct_key IN NUMBER, p_xmldoc IN CLOB); -- PROCEDURE deleteSbtCatalog(p_handle IN VARCHAR2, p_pieceinc IN VARCHAR2); -- PROCEDURE readSbtCatalog(p_handle IN VARCHAR2, p_xmldoc OUT NOCOPY CLOB, p_affinity IN BINARY_INTEGER, p_sbtinfo2 IN BINARY_INTEGER); -- -- FUNCTION checkSbtCatalog(p_handle IN VARCHAR2, p_affinity IN BINARY_INTEGER) RETURN BINARY_INTEGER; -- -- -- PROCEDURE purgescncheck(p_dbid IN NUMBER); -- PROCEDURE tickSbtSession(p_session_id IN VARCHAR2, p_db_key IN NUMBER, p_module IN VARCHAR2, p_action IN VARCHAR2); -- PROCEDURE purgeSbtSession(p_session_id IN VARCHAR2); -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION has_privilege(user_id IN NUMBER, db_key IN NUMBER, db_uname IN VARCHAR2, operation IN VARCHAR2, accesstype IN VARCHAR2, prvlg_code IN NUMBER DEFAULT NULL) RETURN BINARY_INTEGER; -- -- -- -- TYPE savebp IS RECORD ( fuzzyscn NUMBER, nmcorrupt NUMBER, blocks_read NUMBER, complete_time DATE ); TYPE savebplst IS TABLE OF savebp INDEX BY binary_integer; s_bp_save savebplst; -- -- PROCEDURE saveBPdata(fno IN NUMBER, fuzzyScn IN NUMBER DEFAULT NULL, blocks_read IN NUMBER DEFAULT NULL, corrupt IN NUMBER DEFAULT NULL, completion_stamp IN NUMBER DEFAULT NULL, completion_time IN DATE DEFAULT NULL); -- PROCEDURE checkBackupSet(bs IN kccbs_t); -- -- FUNCTION checkBackupPiece(vbkey IN NUMBER ,lib_key IN NUMBER ,ba_access IN VARCHAR2 ,bp IN kccbp_t ,template_key IN NUMBER) RETURN NUMBER; -- PROCEDURE checkBackupDatafile(bf IN kccbf_t); -- PROCEDURE checkBackupRedolog(bl IN kccbl_t); -- PROCEDURE checkBackupSpfile(bi IN kccbi_t); -- PROCEDURE checkArchivedLog(al IN kccal_t); -- -- -- -- -- -- -- -- -- FUNCTION number2null(p_name IN VARCHAR2) RETURN NUMBER; FUNCTION varchar2null(p_name IN VARCHAR2) RETURN VARCHAR2; FUNCTION intervalnull(p_name IN VARCHAR2) RETURN DSINTERVAL_UNCONSTRAINED; FUNCTION isparamdef(p_name IN VARCHAR2) RETURN BOOLEAN; -- -- FUNCTION statBpSbt(db_key IN NUMBER, handle IN VARCHAR2, mhandle OUT NOCOPY SYS.KBRSI_ICD.NAMES$_T, single OUT BINARY_INTEGER) RETURN BINARY_INTEGER; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION dg_is_db_ok(p_dbid IN NUMBER) RETURN NUMBER; -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE dg_register_log(p_dbid IN NUMBER, p_filename IN VARCHAR2); -- -- -- -- -- -- -- -- -- FUNCTION dg_get_platform_id(p_dbid IN NUMBER) RETURN NUMBER; -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE dg_backup_log(p_dbid IN NUMBER, p_filename IN VARCHAR2, p_complete IN BOOLEAN, p_delete IN BOOLEAN DEFAULT TRUE); -- -- -- -- -- -- -- -- -- PROCEDURE RebuildBlockPool(p_dfkey IN NUMBER); -- -- -- -- -- -- FUNCTION sbt_default_drives RETURN NUMBER; -- -- -- -- -- PROCEDURE info_start(p_module VARCHAR2, p_action IN VARCHAR2); -- -- -- -- -- -- PROCEDURE info_end(p_reset BOOLEAN DEFAULT FALSE); -- -- -- -- -- -- -- PROCEDURE populate_rsr_key(p_bp_key IN NUMBER, p_bs_key IN NUMBER); -- -- -- PROCEDURE throttle_me_int(p_ba_job_id IN VARCHAR2, p_db_unique_name IN VARCHAR2, p_channels_reqd IN NUMBER, p_request_time IN DATE, p_wait OUT BOOLEAN, p_error_str OUT VARCHAR2); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE canonicalize ( name IN VARCHAR2, canon_name OUT VARCHAR2, canon_len IN BINARY_INTEGER); -- -- -- FUNCTION build_rep_tpl_name (rep_srv_name IN VARCHAR2, db_key IN NUMBER, prot_key IN NUMBER ) RETURN VARCHAR2; -- -- -- FUNCTION build_rep_lib_name ( rep_srv_name IN VARCHAR2, server_key IN NUMBER DEFAULT NULL ) RETURN VARCHAR2; -- -- -- FUNCTION build_rep_atr_name ( rep_srv_name IN VARCHAR2, server_key IN NUMBER DEFAULT NULL ) RETURN VARCHAR2; -- -- PROCEDURE replication_reconcile ( db_unique_name IN VARCHAR2 DEFAULT NULL, replication_server_name IN VARCHAR2 DEFAULT NULL); -- PROCEDURE replication_reconcile (protection_policy_name IN VARCHAR2); -- -- -- PROCEDURE replicate_one_backup(bpkey IN NUMBER, replication_server_name IN VARCHAR2 DEFAULT NULL); -- -- -- PROCEDURE replicate_backups(db_unique_name IN VARCHAR2, replication_server_name IN VARCHAR2 DEFAULT NULL); -- -- -- -- PROCEDURE replication_reconcile_reset (db_unique_name IN VARCHAR2); -- PROCEDURE lock_api_int (p_op_type IN NUMBER DEFAULT NULL, p_routine IN VARCHAR2 DEFAULT NULL, p_dbgnotes IN VARCHAR2 DEFAULT NULL); -- PROCEDURE unlock_api_int (p_routine IN VARCHAR2 DEFAULT NULL, p_dbgnotes IN VARCHAR2 DEFAULT NULL, p_the_num IN NUMBER DEFAULT 0, p_results IN BOOLEAN DEFAULT TRUE, p_docommit IN BOOLEAN DEFAULT FALSE); -- PROCEDURE verify_reserved_space ( p_slkey IN NUMBER, p_newdb IN BOOLEAN DEFAULT FALSE); -- FUNCTION is_repair_needed RETURN BOOLEAN; -- PROCEDURE testTask(taskid IN NUMBER DEFAULT NULL, tasktype IN NUMBER DEFAULT NULL, num1 IN NUMBER DEFAULT NULL, num2 IN NUMBER DEFAULT NULL, num3 IN NUMBER DEFAULT NULL, char1 IN VARCHAR2 DEFAULT NULL, char2 IN VARCHAR2 DEFAULT NULL, param IN VARCHAR2 DEFAULT NULL, slkey IN NUMBER DEFAULT NULL, dbkey IN NUMBER DEFAULT NULL, settrace IN NUMBER DEFAULT NULL, newsession IN BOOLEAN DEFAULT FALSE); -- PROCEDURE killTask(taskid IN NUMBER); FUNCTION sbt_job_backup_type_to_num(backup_type IN VARCHAR2) RETURN NUMBER; PROCEDURE create_sbt_job_template_int( template_name IN VARCHAR2, prot_name IN VARCHAR2, attr_name IN VARCHAR2, backup_type IN VARCHAR2, full_template_name IN VARCHAR2 DEFAULT NULL, from_tag IN VARCHAR2 DEFAULT NULL, priority IN NUMBER DEFAULT 100, -- SBT_PRIORITY_MEDIUM copies IN NUMBER DEFAULT 1, window IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, do_commit IN BOOLEAN DEFAULT TRUE); PROCEDURE create_sbt_job_template_int( template_name IN VARCHAR2, db_unique_name IN VARCHAR2, attr_name IN VARCHAR2, backup_type IN VARCHAR2, full_template_name IN VARCHAR2 DEFAULT NULL, from_tag IN VARCHAR2 DEFAULT NULL, priority IN NUMBER DEFAULT 100, -- SBT_PRIORITY_MEDIUM copies IN NUMBER DEFAULT 1, window IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, do_commit IN BOOLEAN DEFAULT TRUE); -- PROCEDURE wait_for_job (p_jobname VARCHAR2, p_poll_time NUMBER); -- -- PROCEDURE am_tracei (p_message IN VARCHAR2); -- -- -- FUNCTION pparmi (p_value IN VARCHAR2) RETURN VARCHAR2; FUNCTION pparmi (p_value IN NUMBER) RETURN VARCHAR2; FUNCTION pparmi (p_value IN BOOLEAN) RETURN VARCHAR2; -- -- -- -- FUNCTION b_p_i (p_varname IN VARCHAR2, p_strval IN VARCHAR2 DEFAULT NULL, p_first IN BOOLEAN DEFAULT FALSE, p_last IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2; FUNCTION b_p_i (p_varname IN VARCHAR2, p_numval IN NUMBER DEFAULT NULL, p_first IN BOOLEAN DEFAULT FALSE, p_last IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2; FUNCTION b_p_i (p_varname IN VARCHAR2, p_boolval IN BOOLEAN DEFAULT NULL, p_first IN BOOLEAN DEFAULT FALSE, p_last IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2; FUNCTION b_p_i (p_varname IN VARCHAR2, p_intval IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, p_first IN BOOLEAN DEFAULT FALSE, p_last IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2; -- FUNCTION item_not_foundi (p_obj_name IN VARCHAR2, p_obj_type IN VARCHAR2) RETURN VARCHAR2; -- PTYPE_STR CONSTANT NUMBER := 1; PTYPE_NUM CONSTANT NUMBER := 2; PTYPE_INT CONSTANT NUMBER := 3; PTYPE_BOOL CONSTANT NUMBER := 4; s_lockapi_level NUMBER := 0; -- locking depth for api locks s_lockapi_type NUMBER := 0; -- locking type for existing api locks s_lockapi_routine VARCHAR2(128); -- routine that holds current api lock s_lockapi_notes VARCHAR2(128); -- any other debugging notes for lcok -- -- -- -- -- -- -- -- -- PROCEDURE tracing_on; -- -- -- -- -- -- -- -- -- -- PROCEDURE validate_bp(bpkey IN NUMBER); END dbms_ra_int; >>> define dbmsrsjs_plb <<< CREATE OR REPLACE PACKAGE dbms_ra_scheduler AS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE init (p_instance_only IN BOOLEAN DEFAULT FALSE, p_repair IN BOOLEAN DEFAULT FALSE); -- PROCEDURE repair_rs; -- FUNCTION restart_timer_process (do_check BOOLEAN) RETURN NUMBER; -- -- PROCEDURE timer_functions; -- PROCEDURE spawn_job (p_name IN VARCHAR2, p_action IN VARCHAR2, p_instance IN NUMBER, p_comments IN VARCHAR2); -- -- -- PROCEDURE queue_spawn_sbt(p_libkey IN NUMBER, p_forpurge IN BOOLEAN, p_check_work IN BOOLEAN DEFAULT FALSE); -- -- -- -- PROCEDURE schedule (p_task_type IN NUMBER DEFAULT NULL, p_param1 IN NUMBER DEFAULT NULL, p_param2 IN NUMBER DEFAULT NULL, p_settrace IN NUMBER DEFAULT NULL); -- PROCEDURE testTask(p_taskid IN NUMBER DEFAULT NULL, p_tasktype IN NUMBER DEFAULT NULL, p_num1 IN NUMBER DEFAULT NULL, p_num2 IN NUMBER DEFAULT NULL, p_num3 IN NUMBER DEFAULT NULL, p_char1 IN VARCHAR2 DEFAULT NULL, p_char2 IN VARCHAR2 DEFAULT NULL, p_param IN VARCHAR2 DEFAULT NULL, p_slkey IN NUMBER DEFAULT NULL, p_dbkey IN NUMBER DEFAULT NULL, p_settrace IN NUMBER DEFAULT NULL, p_newsession IN BOOLEAN DEFAULT FALSE); -- PROCEDURE get_lock(p_type IN NUMBER, p_key IN NUMBER); -- PROCEDURE unlock(p_type IN NUMBER, p_key IN NUMBER); -- PROCEDURE show_locks (p_type IN NUMBER, p_key IN NUMBER); -- -- PROCEDURE get_lock_direct_waitable(p_type IN NUMBER, p_key IN NUMBER, wait_time_in_seconds IN NUMBER); -- PROCEDURE release_blocked_tasks(p_task_id IN NUMBER, p_db_key IN NUMBER DEFAULT NULL); -- PROCEDURE raise_purge_priority (p_dfkey IN NUMBER); -- PROCEDURE release_restore_wait (p_instance NUMBER DEFAULT NULL); -- -- -- PROCEDURE avoid_sl(p_type IN NUMBER, -- TASK_PURGE or TASK_INDEX_BACKUP p_slkey IN NUMBER); -- -- -- -- -- PROCEDURE avoid_db (p_db_key IN NUMBER); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE avoid_bs(p_dbkey IN NUMBER, p_bskey IN NUMBER, p_bpkey IN NUMBER); -- -- PROCEDURE new_task (task_rec IN OUT task%ROWTYPE, p_commit IN BOOLEAN DEFAULT TRUE, p_delay IN BOOLEAN DEFAULT FALSE, p_sbt_task IN BOOLEAN DEFAULT FALSE); -- PROCEDURE newdfkey (p_dfkey IN NUMBER, p_dbinckey IN NUMBER, p_pdbinckey IN NUMBER); -- FUNCTION get_savepoint RETURN NUMBER; -- FUNCTION set_blocking_purge(p_dbkey IN NUMBER, p_space IN NUMBER DEFAULT NULL) RETURN NUMBER; -- PROCEDURE log_error (p_errno NUMBER, p_param1 VARCHAR2 DEFAULT NULL, p_param2 VARCHAR2 DEFAULT NULL, p_param3 VARCHAR2 DEFAULT NULL, p_param4 VARCHAR2 DEFAULT NULL, p_keep_stack BOOLEAN DEFAULT TRUE, p_component VARCHAR2, p_severity NUMBER, p_sl_key NUMBER DEFAULT NULL, p_db_key NUMBER DEFAULT NULL, p_param_char VARCHAR2 DEFAULT NULL, p_param_num NUMBER DEFAULT NULL); -- PROCEDURE write_error (p_component VARCHAR2, p_severity NUMBER, p_sl_key NUMBER DEFAULT NULL, p_db_key NUMBER DEFAULT NULL, p_param_char VARCHAR2 DEFAULT NULL, p_param_num NUMBER DEFAULT NULL); -- PROCEDURE fix_error (p_error_num NUMBER, p_sl_key NUMBER DEFAULT NULL, p_db_key NUMBER DEFAULT NULL, p_param_char VARCHAR2 DEFAULT NULL, p_param_num NUMBER DEFAULT NULL, p_timestamp TIMESTAMP WITH TIME ZONE DEFAULT NULL); -- PROCEDURE reset_error (p_incident# NUMBER); -- PROCEDURE assert_owner; -- PROCEDURE setTracing(p_trc_on IN NUMBER, p_perf_on IN NUMBER DEFAULT 0, p_stall_on IN NUMBER DEFAULT 0, p_safe_mode IN NUMBER DEFAULT 0); -- PROCEDURE load_config; -- PROCEDURE stop_scheduler_jobs (p_stop_jobs IN NUMBER, p_instance_only IN BOOLEAN, p_db_key IN NUMBER DEFAULT NULL); -- PROCEDURE stop (p_instance_only IN BOOLEAN DEFAULT FALSE, p_quiesce_first IN BOOLEAN DEFAULT FALSE); -- PROCEDURE enqueue_timer_reload_config; -- PROCEDURE enqueue_verify_timer_task; -- PROCEDURE queue_set_reconcile_timer (p_db_key IN NUMBER); -- PROCEDURE reset_reconcile_timer; -- PROCEDURE check_for_interrupt (p_state IN NUMBER DEFAULT NULL); -- PROCEDURE purge_immediate(p_sl_key IN NUMBER, p_db_key IN NUMBER, p_allocation IN NUMBER); -- -- -- -- -- SUBTYPE interrupt_t IS BINARY_INTEGER RANGE 1..2; INTERRUPT_FOR_MOVE CONSTANT interrupt_t := 1; INTERRUPT_FOR_PURGE CONSTANT interrupt_t := 2; PROCEDURE interrupt_tasks (p_interrupt IN interrupt_t, p_task_id IN NUMBER DEFAULT NULL, p_db_key IN NUMBER DEFAULT NULL); -- PROCEDURE quiesce_rs; -- PROCEDURE unquiesce_rs; -- FUNCTION interval2secs (p_interval IN DSINTERVAL_UNCONSTRAINED) RETURN NUMBER; -- FUNCTION type2priority (p_tasktype IN NUMBER) RETURN NUMBER; -- FUNCTION tasktype2name (p_task_type NUMBER) RETURN VARCHAR2; -- FUNCTION taskstate2name (p_task_state NUMBER, p_pending_interrupt NUMBER DEFAULT 0 ) RETURN VARCHAR2; -- PROCEDURE make_amjobs (name VARCHAR2 DEFAULT 'RA$%'); -- PROCEDURE make_amlocks; -- PROCEDURE queue_sbt_backup_task(template_name IN VARCHAR2, src_bpkey IN NUMBER DEFAULT NULL, delete_source IN VARCHAR2 DEFAULT 'N', format IN VARCHAR2 DEFAULT NULL); -- PROCEDURE queue_restore_task(request_id IN NUMBER, sbt_sessionid IN VARCHAR2, handle IN VARCHAR2); -- -- FUNCTION wait_for_resource(request_id IN NUMBER, handle IN VARCHAR2) RETURN BINARY_INTEGER; -- PROCEDURE replicate_existing_backups( p_template_name IN sbt_job_template.template_name%TYPE, p_db_key IN NUMBER DEFAULT NULL, p_server_key IN NUMBER DEFAULT NULL); -- -- PROCEDURE replicate_one_bp (p_db_key IN NUMBER, p_bp_key IN NUMBER, p_server_key IN NUMBER DEFAULT NULL); -- PROCEDURE queue_replication_task(p_bp_key IN NUMBER, p_handle IN VARCHAR2, p_db_key IN NUMBER, p_bs_key IN NUMBER, p_piece_no IN NUMBER, p_rep_server_key IN NUMBER, p_sbt_template_key IN NUMBER, p_sbt_attr_set_key IN NUMBER, p_sbt_lib_key IN NUMBER); -- FUNCTION add_to_task_history_table ( task_type NUMBER, db_key NUMBER DEFAULT NULL, sl_key NUMBER DEFAULT NULL, param VARCHAR2 DEFAULT NULL, param_num1 NUMBER DEFAULT NULL, param_num2 NUMBER DEFAULT NULL, param_num3 NUMBER DEFAULT NULL, param_char1 VARCHAR2 DEFAULT NULL, param_char2 VARCHAR2 DEFAULT NULL ) RETURN NUMBER; -- PROCEDURE update_task_history_entry ( task_id NUMBER, db_key NUMBER DEFAULT NULL, sl_key NUMBER DEFAULT NULL, param VARCHAR2 DEFAULT NULL, param_num1 NUMBER DEFAULT NULL, param_num2 NUMBER DEFAULT NULL, param_num3 NUMBER DEFAULT NULL, param_char1 VARCHAR2 DEFAULT NULL, param_char2 VARCHAR2 DEFAULT NULL, do_commit IN BOOLEAN DEFAULT FALSE ); -- -- -- -- -- -- -- -- -- -- PROCEDURE copy_one_backuppiece(p_bpkey IN NUMBER, p_format IN VARCHAR2, p_deletesource IN VARCHAR2, p_template_key IN NUMBER DEFAULT NULL); -- -- -- PROCEDURE delete_one_backuppiece(p_bpkey IN NUMBER); -- -- -- -- -- -- -- FUNCTION reconcile_db (p_db_key IN NUMBER, p_server_key IN NUMBER DEFAULT NULL, p_only_active IN BOOLEAN DEFAULT TRUE, p_force_reconcile IN BOOLEAN DEFAULT FALSE, rec_cnt OUT NUMBER ) RETURN BOOLEAN; -- FUNCTION check_do_pending_rep_setup(p_db_key IN VARCHAR2) RETURN BOOLEAN; -- -- -- -- -- -- FUNCTION delete_db_task_is_benign (p_task_type IN NUMBER) RETURN NUMBER; /*-------------------------* * Package State Variables * *-------------------------*/ s_trace_file VARCHAR2(512) := NULL; -- s_current_task NUMBER := NULL; -- task executing in this session s_current_task_type NUMBER := NULL; -- type of task executing by session s_cached_storage BOOLEAN := FALSE; -- current task has storage cached -- s_polled_input BOOLEAN := FALSE; -- adding polled file into blockpool s_now_serving NUMBER := 0; -- sequence for task executions s_purging_active BOOLEAN := FALSE; -- set to TRUE if purging is active s_sysreserve_ok BOOLEAN := FALSE; -- TRUE if sys purge area can be used s_no_wait_on_allocate BOOLEAN := FALSE; -- If allocate requires purge, raise -- s_pending_interrupt NUMBER := NULL; -- task that is blocking current task s_instance NUMBER := sys_context('USERENV', 'INSTANCE'); s_last_busywork_stop TIMESTAMP WITH TIME ZONE := SYSTIMESTAMP - 365; -- s_repair_active BOOLEAN := FALSE; -- ORS repair underway in session s_amjobs rai_jobs_table_type; -- table for make_amjobs s_amlocks rai_locks_table_type; -- table for make_amlocks /*---------------------------* * Initialization Parameters * *---------------------------*/ s_alloc_increment NUMBER; -- allocation increments s_chunk_cache NUMBER; -- size of task based chunk cache s_chunkno_alloc NUMBER; -- # of chunknos to reserve at a time s_purging_reserve NUMBER; -- reserve for inline purging s_purge_wait NUMBER; -- polling wait against purger task s_purge_autoshrink NUMBER; -- automatic shrink of preallocated -- s_quiesce_wait NUMBER; -- wait before retrying quiesce s_quiesce_session_wait DSINTERVAL_UNCONSTRAINED; -- -- s_lock_refused_wait NUMBER; -- polling wait getting key locks s_interrupt_wait NUMBER; -- polling wait for interrupted tasks s_purge_threshold NUMBER; -- amount of freespace_goal to trigger -- s_scheduling_wait NUMBER; -- polling wait to look for work s_session_count NUMBER; -- # of scheduler sessions per instance s_restricted_session_count NUMBER; -- # of session for high priority work s_min_sessions_for_busywork NUMBER; -- # of free sessions before busywork s_busywork_inhibit_time DSINTERVAL_UNCONSTRAINED; -- -- -- s_timer_loop_sleep NUMBER; -- number of seconds between checks of -- s_db_stats_refresh_interval DSINTERVAL_UNCONSTRAINED; -- s_servlet_wait_seconds NUMBER; -- if client has not responded in this -- s_histogram_slot_interval DSINTERVAL_UNCONSTRAINED; -- s_histogram_cycle_slots NUMBER; -- # of slots within storage histograms s_histogram_window_slots NUMBER; -- # of slots actually considered s_histogram_goal_percentile NUMBER; -- percentile histogram bucket to use -- s_initial_freespace_ratio NUMBER; -- part of sl to use as freespace_goal -- s_min_freespace_ratio NUMBER; -- minimum part of sl to be used as -- s_task_maintenance_interval DSINTERVAL_UNCONSTRAINED; -- -- s_storage_maintenance_interval DSINTERVAL_UNCONSTRAINED; -- -- s_obsolete_sbt_interval DSINTERVAL_UNCONSTRAINED; -- s_polling_timeout_interval DSINTERVAL_UNCONSTRAINED; -- -- -- s_polling_deleted_files_check DSINTERVAL_UNCONSTRAINED; -- -- -- -- s_history_partition_interval DSINTERVAL_UNCONSTRAINED; -- -- s_history_retention NUMBER; -- -- s_rm_incomplete_files_interval DSINTERVAL_UNCONSTRAINED; -- s_expire_files_interval DSINTERVAL_UNCONSTRAINED; -- -- s_max_task_restarts NUMBER;-- max number of times to restart a task -- -- s_optimize_df_tasks NUMBER; -- -- s_crosscheck_throttle NUMBER;-- max number of crosscheck tasks -- s_late_for_warning NUMBER; -- -- s_orphan_file_wait DSINTERVAL_UNCONSTRAINED; -- -- s_reconcile_short_interval DSINTERVAL_UNCONSTRAINED; -- -- s_reconcile_long_interval DSINTERVAL_UNCONSTRAINED; -- -- s_trim_factor NUMBER; -- -- -- s_defer_delete BINARY_INTEGER; -- -- s_aggressive_delete BINARY_INTEGER; -- s_dumper_inhibit_interval DSINTERVAL_UNCONSTRAINED; -- -- s_check_sbtsched_interval DSINTERVAL_UNCONSTRAINED; -- -- s_max_sbt_failures NUMBER;-- max number of sbt failures allowed -- -- s_sbt_active_interval DSINTERVAL_UNCONSTRAINED; -- -- s_resumable_timeout NUMBER;-- expressed in seconds, specifies a -- -- s_rsrange_refresh_secs NUMBER; -- -- s_stall_when BOOLEAN; -- -- -- -- s_debug_when NUMBER; -- -- -- -- s_interrupt_when BOOLEAN; -- -- -- -- -- s_purge_opt_free NUMBER; -- -- -- s_purge_opt_pct NUMBER; -- -- -- -- s_fragmentation NUMBER; -- -- -- s_plans_maintained NUMBER; -- -- -- -- -- s_part_threshold NUMBER; -- -- -- s_part_index_style NUMBER; -- -- -- -- -- s_part_index_size NUMBER; -- -- -- s_part_parallel_degree NUMBER; -- -- -- -- -- -- -- s_alg_over_alloc BINARY_INTEGER; -- -- -- -- -- s_ra_pool_freespace_threshold NUMBER; -- Fraction of the pool tablespace that -- -- s_ra_pool_full_free_count NUMBER; -- Number of FULL_POOL waiting tasks -- -- -- -- -- -- -- -- TASK_QUIESCE_RS CONSTANT PLS_INTEGER := 00; TASK_SPAWN_SBT CONSTANT PLS_INTEGER := 01; TASK_PURGE_DF_NOW CONSTANT PLS_INTEGER := 10; TASK_REPAIR_DB CONSTANT PLS_INTEGER := 20; TASK_STORAGE_HISTOGRAM CONSTANT PLS_INTEGER := 30; TASK_RESTORE CONSTANT PLS_INTEGER := 40; --used in kbrs.c TASK_DEFERRED_DELETE CONSTANT PLS_INTEGER := 55; TASK_GCOPY_COMPUTE CONSTANT PLS_INTEGER := 57; TASK_PURGE_DUP_DF CONSTANT PLS_INTEGER := 60; TASK_PURGE_IMMEDIATE CONSTANT PLS_INTEGER := 70; TASK_PURGE_DF CONSTANT PLS_INTEGER := 80; TASK_DELETE_DB CONSTANT PLS_INTEGER := 85; TASK_TRIM_DB CONSTANT PLS_INTEGER := 90; TASK_PURGE CONSTANT PLS_INTEGER := 100; TASK_NEWDFKEY CONSTANT PLS_INTEGER := 110; TASK_BACKUP_ARCH CONSTANT PLS_INTEGER := 120; TASK_INC_ARCH CONSTANT PLS_INTEGER := 130; TASK_PLAN_SBT CONSTANT PLS_INTEGER := 135; TASK_INDEX_BACKUP CONSTANT PLS_INTEGER := 140; --used in recover2.txt TASK_POLL CONSTANT PLS_INTEGER := 150; TASK_BACKUP_SBT CONSTANT PLS_INTEGER := 160; TASK_RESTORE_SBT CONSTANT PLS_INTEGER := 170; --used in kbrs.c TASK_PURGE_SBT CONSTANT PLS_INTEGER := 180; TASK_OBSOLETE_SBT CONSTANT PLS_INTEGER := 190; TASK_RM_INCOMPLETE_FILES CONSTANT PLS_INTEGER := 200; TASK_RECONCILE CONSTANT PLS_INTEGER := 210; TASK_MOVE_DF CONSTANT PLS_INTEGER := 220; TASK_MOVE_ALL_DB CONSTANT PLS_INTEGER := 230; -- TASK_RESERVE_SBT CONSTANT PLS_INTEGER := 250; TASK_INSERT_FAULT CONSTANT PLS_INTEGER := 290; -- TASK_DB_STATS_REFRESH CONSTANT PLS_INTEGER := 300; TASK_RESTORE_RANGE_REFRESH CONSTANT PLS_INTEGER := 305; TASK_OPTIMIZE_CHUNKS_DF CONSTANT PLS_INTEGER := 310; TASK_OPTIMIZE_CHUNKS CONSTANT PLS_INTEGER := 320; TASK_REBUILD_INDEX CONSTANT PLS_INTEGER := 325; TASK_VALIDATE_DB CONSTANT PLS_INTEGER := 330; TASK_PLAN_DF CONSTANT PLS_INTEGER := 335; TASK_CHECK_FILES CONSTANT PLS_INTEGER := 340; TASK_CROSSCHECK_DB CONSTANT PLS_INTEGER := 350; -- TASK_TEST_DUMMY CONSTANT PLS_INTEGER := 410; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- TASK_SESSION_TIMES CONSTANT PLS_INTEGER := 2000; -- -- -- -- -- -- TASK_ERROR_INFO CONSTANT PLS_INTEGER := 2001; -- TASK_MIN_API CONSTANT PLS_INTEGER := 10000; TASK_API_ADD_DB CONSTANT PLS_INTEGER := 10000; TASK_API_UPD_DB CONSTANT PLS_INTEGER := 10010; TASK_API_DEL_DB CONSTANT PLS_INTEGER := 10020; TASK_API_REN_DB CONSTANT PLS_INTEGER := 10030; TASK_API_GRANT_DB CONSTANT PLS_INTEGER := 10050; TASK_API_REVOKE_DB CONSTANT PLS_INTEGER := 10060; TASK_API_ADD_SL CONSTANT PLS_INTEGER := 10070; TASK_API_UPD_SL CONSTANT PLS_INTEGER := 10080; TASK_API_DEL_SL CONSTANT PLS_INTEGER := 10090; TASK_API_ADD_PROT_POLICY CONSTANT PLS_INTEGER := 10100; TASK_API_UPD_PROT_POLICY CONSTANT PLS_INTEGER := 10110; TASK_API_DEL_PROT_POLICY CONSTANT PLS_INTEGER := 10120; TASK_API_ADD_POLL_POLICY CONSTANT PLS_INTEGER := 10130; TASK_API_UPD_POLL_POLICY CONSTANT PLS_INTEGER := 10140; TASK_API_DEL_POLL_POLICY CONSTANT PLS_INTEGER := 10150; TASK_API_ADD_SBT_LIB CONSTANT PLS_INTEGER := 10160; TASK_API_UPD_SBT_LIB CONSTANT PLS_INTEGER := 10170; TASK_API_DEL_SBT_LIB CONSTANT PLS_INTEGER := 10180; TASK_API_ADD_RESTRICT_SBT_INST CONSTANT PLS_INTEGER := 10190; TASK_API_DEL_RESTRICT_SBT_INST CONSTANT PLS_INTEGER := 10200; TASK_API_ADD_SBT_ATTR_SET CONSTANT PLS_INTEGER := 10210; TASK_API_UPD_SBT_ATTR_SET CONSTANT PLS_INTEGER := 10220; TASK_API_DEL_SBT_ATTR_SET CONSTANT PLS_INTEGER := 10230; TASK_API_ADD_SBT_JOB CONSTANT PLS_INTEGER := 10240; TASK_API_UPD_SBT_JOB CONSTANT PLS_INTEGER := 10250; TASK_API_DEL_SBT_JOB CONSTANT PLS_INTEGER := 10260; TASK_API_PAU_SBT_LIB CONSTANT PLS_INTEGER := 10270; TASK_API_RES_SBT_LIB CONSTANT PLS_INTEGER := 10280; TASK_API_ADD_REPOSITORY CONSTANT PLS_INTEGER := 10290; TASK_API_DEL_REPOSITORY CONSTANT PLS_INTEGER := 10300; TASK_API_ADD_REP_SERVER CONSTANT PLS_INTEGER := 10310; TASK_API_REM_REP_SERVER CONSTANT PLS_INTEGER := 10320; TASK_API_STARTUP CONSTANT PLS_INTEGER := 10330; TASK_API_SHUTDOWN CONSTANT PLS_INTEGER := 10340; TASK_API_ABORT CONSTANT PLS_INTEGER := 10350; TASK_API_CONFIG CONSTANT PLS_INTEGER := 10360; TASK_API_POPULATE CONSTANT PLS_INTEGER := 10370; TASK_API_MOVE_BACKUP CONSTANT PLS_INTEGER := 10380; TASK_API_COPY_BACKUP CONSTANT PLS_INTEGER := 10390; TASK_API_MOVE_BACKUP_PIECE CONSTANT PLS_INTEGER := 10400; TASK_API_COPY_BACKUP_PIECE CONSTANT PLS_INTEGER := 10410; TASK_API_REPLICATE_EXISTING CONSTANT PLS_INTEGER := 10420; TASK_API_REPLICATION_RECONCILE CONSTANT PLS_INTEGER := 10430; TASK_API_REPLICATE_ONE_PIECE CONSTANT PLS_INTEGER := 10440; TASK_API_MIGRATE_TAPE CONSTANT PLS_INTEGER := 10460; TASK_API_PAU_REP_SRV CONSTANT PLS_INTEGER := 10470; TASK_API_RES_REP_SRV CONSTANT PLS_INTEGER := 10480; TASK_API_REPAIR_SL CONSTANT PLS_INTEGER := 10490; TASK_API_TESTTASK CONSTANT PLS_INTEGER := 10500; TASK_API_CRE_REP_SERVER CONSTANT PLS_INTEGER := 10510; TASK_API_UPD_REP_SERVER CONSTANT PLS_INTEGER := 10530; TASK_API_DEL_REP_SERVER CONSTANT PLS_INTEGER := 10520; -- TASK_MAX_API CONSTANT PLS_INTEGER := 14999; -- -- PRIO_QUIESCE_RS CONSTANT PLS_INTEGER := 01; -- must be first! PRIO_SPAWN_SBT CONSTANT PLS_INTEGER := 02; -- must be second! PRIO_PURGE_DF_NOW CONSTANT PLS_INTEGER := 10; -- must be third! PRIO_REPAIR_DB CONSTANT PLS_INTEGER := 20; PRIO_STORAGE_HISTOGRAM CONSTANT PLS_INTEGER := 30; PRIO_RESTORE CONSTANT PLS_INTEGER := 40; PRIO_DEFERRED_DELETE CONSTANT PLS_INTEGER := 50; PRIO_GCOPY_COMPUTE CONSTANT PLS_INTEGER := 57; PRIO_PURGE_DUP_DF CONSTANT PLS_INTEGER := 60; -- before purge_imm PRIO_PURGE_IMMEDIATE CONSTANT PLS_INTEGER := 70; PRIO_PURGE_DF CONSTANT PLS_INTEGER := 80; PRIO_DELETE_DB CONSTANT PLS_INTEGER := 85; PRIO_TRIM_DB CONSTANT PLS_INTEGER := 90; PRIO_PURGE CONSTANT PLS_INTEGER := 100; PRIO_NEWDFKEY CONSTANT PLS_INTEGER := 110; PRIO_BACKUP_ARCH CONSTANT PLS_INTEGER := 120; PRIO_INC_ARCH CONSTANT PLS_INTEGER := 130; PRIO_PLAN_SBT CONSTANT PLS_INTEGER := 135; PRIO_INDEX_BACKUP CONSTANT PLS_INTEGER := 140; PRIO_POLL CONSTANT PLS_INTEGER := 150; PRIO_BACKUP_SBT CONSTANT PLS_INTEGER := 160; PRIO_RESTORE_SBT CONSTANT PLS_INTEGER := 170; PRIO_PURGE_SBT CONSTANT PLS_INTEGER := 180; PRIO_OBSOLETE_SBT CONSTANT PLS_INTEGER := 190; PRIO_RM_INCOMPLETE_FILES CONSTANT PLS_INTEGER := 200; PRIO_RECONCILE CONSTANT PLS_INTEGER := 210; PRIO_MOVE_DF CONSTANT PLS_INTEGER := 220; PRIO_MOVE_ALL_DB CONSTANT PLS_INTEGER := 230; PRIO_INSERT_FAULT CONSTANT PLS_INTEGER := 290; -- PRIO_MIN_BUSYWORK CONSTANT PLS_INTEGER := 299; PRIO_DB_STATS_REFRESH CONSTANT PLS_INTEGER := 300; PRIO_RESTORE_RANGE_REFRESH CONSTANT PLS_INTEGER := 305; PRIO_OPTIMIZE_CHUNKS_DF CONSTANT PLS_INTEGER := 310; PRIO_OPTIMIZE_CHUNKS CONSTANT PLS_INTEGER := 320; PRIO_REBUILD_INDEX CONSTANT PLS_INTEGER := 325; PRIO_VALIDATE_DB CONSTANT PLS_INTEGER := 330; PRIO_PLAN_DF CONSTANT PLS_INTEGER := 335; PRIO_CHECK_FILES CONSTANT PLS_INTEGER := 340; PRIO_CROSSCHECK_DB CONSTANT PLS_INTEGER := 350; -- PRIO_TEST_DUMMY CONSTANT PLS_INTEGER := 410; PRIO_MAX_BUSYWORK CONSTANT PLS_INTEGER := 999; -- -- -- -- -- -- STATE_EXECUTABLE CONSTANT PLS_INTEGER := 1; STATE_RUNNING CONSTANT PLS_INTEGER := 2; STATE_COMPLETED CONSTANT PLS_INTEGER := 3; STATE_ORDERING_WAIT CONSTANT PLS_INTEGER := 4; STATE_TASK_WAIT CONSTANT PLS_INTEGER := 5; STATE_RESTORE_WAIT CONSTANT PLS_INTEGER := 6; STATE_RETRYING CONSTANT PLS_INTEGER := 7; -- used only in views STATE_FAILED CONSTANT PLS_INTEGER := 8; -- not seen in task STATE_CANCEL CONSTANT PLS_INTEGER := 9; STATE_CANCELING CONSTANT PLS_INTEGER := 10; STATE_CANCELED CONSTANT PLS_INTEGER := 11; -- not seen in task -- -- -- TASKS_RECEIVED_BACKUP CONSTANT NUMBER := TO_NUMBER('0001','XXXX'); TASKS_BLOCKING_TASK CONSTANT NUMBER := TO_NUMBER('0002','XXXX'); TASKS_OUT_OF_ORDER CONSTANT NUMBER := TO_NUMBER('0004','XXXX'); TASKS_DELETE_INPUT CONSTANT NUMBER := TO_NUMBER('0008','XXXX'); TASKS_POLLED_INPUT CONSTANT NUMBER := TO_NUMBER('0010','XXXX'); TASKS_CHUNK_CACHE_ACTIVE CONSTANT NUMBER := TO_NUMBER('0020','XXXX'); TASKS_TOO_MANY_INTERRUPTS CONSTANT NUMBER := TO_NUMBER('0040','XXXX'); -- -- -- -- LOCK_DB_KEY CONSTANT NUMBER := 5; -- Locks for storage management LOCK_SL_KEY CONSTANT NUMBER := 6; -- Locks for storage management LOCK_COMMON CONSTANT NUMBER := 7; -- Misc locks qualified by id2 LOCK_TIMER CONSTANT NUMBER := 1; -- Timer process lock LOCK_SCHED CONSTANT NUMBER := 2; -- Serialize access to task table LOCK_API CONSTANT NUMBER := 3; -- Serialize API execution LOCK_QUIESCE CONSTANT NUMBER := 4; -- Quiesces recovery server -- -- LOCK_PURGE CONSTANT NUMBER := 8; -- Locks for purging LOCK_KEY CONSTANT NUMBER := 9; -- Locks for reading/writing -- -- -- -- -- LOCK_QUIESCE_PENDING CONSTANT NUMBER := 1; -- -- -- -- -- LOCK_DELETE_DB_UNREGISTER CONSTANT NUMBER := 2; -- -- -- SEVERITY_WARNING CONSTANT NUMBER := 1; -- warning messages SEVERITY_ERROR CONSTANT NUMBER := 10; -- non-specific error SEVERITY_INTERNAL CONSTANT NUMBER := 20; -- unhandled exception -- -- -- MOVE_PHASE_NULL CONSTANT NUMBER := NULL; -- Db is not moving MOVE_PHASE_PEND CONSTANT NUMBER := 1; -- Move is pending MOVE_PHASE_START CONSTANT NUMBER := 2; -- Waiting to move metadata MOVE_PHASE_POOL CONSTANT NUMBER := 3; -- Moving Block pool -- purge -- -- MOVE_PHASE_FILES CONSTANT NUMBER := 4; -- Moving remaining files -- -- -- -- -- -- -- -- SERVLET_PSEUDO_TASK CONSTANT NUMBER := -1; -- waiting for servlet(restore) SPACE_PSEUDO_TASK CONSTANT NUMBER := -2; -- backup_piece waiting -- OPT_DF_PSEUDO_TASK CONSTANT NUMBER := -3; -- Opt_df tasks waiting for -- TEST_PSEUDO_TASK CONSTANT NUMBER := -4; -- wait for test_task scheduler RESOURCE_PSEUDO_TASK CONSTANT NUMBER := -5; -- wait for contention on -- MAX_RESOURCE_WAIT_PROCESSES CONSTANT NUMBER := 99999; STALL_PSEUDO_TASK CONSTANT NUMBER := -6; -- _stall_when is set LIBRARY_PSEUDO_TASK CONSTANT NUMBER := -7; -- wait for stalled library -- POOL_FULL_PSEUDO_TASK CONSTANT NUMBER := -8; -- waiting for space to be -- -- -- -- POLLING_HISTORY_PROCESSING CONSTANT CHAR(1) := 'P'; POLLING_HISTORY_COMPLETED CONSTANT CHAR(1) := 'C'; POLLING_HISTORY_BAD_DBID CONSTANT CHAR(1) := 'D'; POLLING_HISTORY_BAD_FTYPE CONSTANT CHAR(1) := 'F'; POLLING_HISTORY_ERROR CONSTANT CHAR(1) := 'E'; POLLING_HISTORY_TIMED_OUT CONSTANT CHAR(1) := 'T'; POLLING_HISTORY_REMOVED CONSTANT CHAR(1) := 'R'; -- file removed -- -- -- POLL_FLAGS_DELETE_INPUT CONSTANT NUMBER := 2**0; POLL_FLAGS_UNDO_DBID_ERROR CONSTANT NUMBER := 2**1; POLL_FLAGS_UNDO_TIMEOUT_ERROR CONSTANT NUMBER := 2**2; -- -- -- FTYPE_ARCHIVELOG CONSTANT NUMBER := 4; -- skgfrfALOG FTYPE_BACKUP CONSTANT NUMBER := 9; -- skgfrfDBKUP FTYPE_INCBACKUP CONSTANT NUMBER := 10; -- skgfrfDIBKUP FTYPE_ARCHBACKUP CONSTANT NUMBER := 11; -- skgfrfABKUP FTYPE_AUTOBACKUP CONSTANT NUMBER := 20; -- skgfrfAUBKUP FTYPE_CHUNK CONSTANT NUMBER := 40; -- skgfrfCHUNK -- -- -- COPY_BA_POLL CONSTANT NUMBER := 1; -- KRBYX_ORS_POLL COPY_BA_CPMV CONSTANT NUMBER := 2; -- KRBYX_ORS_CPMV COPY_BA_XALG CONSTANT NUMBER := 3; -- KRBYX_ORS_XALG -- -- -- STOP_JOBS_ALL CONSTANT NUMBER := 1; -- Stop all jobs STOP_JOBS_DB CONSTANT NUMBER := 2; -- Stop jobs for a given db -- -- -- -- -- -- DB_STATE_IN_DELETE CONSTANT NUMBER := 1; -- Database is being deleted -- -- -- DB_TASK_IS_BENIGN CONSTANT NUMBER := 1; -- Task type is benign -- DB_TASK_IS_NOT_BENIGN CONSTANT NUMBER := 2; -- Task type is NOT benign -- -- -- -- E_RESOURCE_BUSY EXCEPTION; PRAGMA EXCEPTION_INIT (E_RESOURCE_BUSY, -54); E_ORA_600 EXCEPTION; PRAGMA EXCEPTION_INIT (E_ORA_600, -600); E_SNAPSHOT_TOO_OLD EXCEPTION; PRAGMA EXCEPTION_INIT (E_SNAPSHOT_TOO_OLD, -1555); E_TOO_MANY_ROLLBACK_EXTENTS EXCEPTION; PRAGMA EXCEPTION_INIT (E_TOO_MANY_ROLLBACK_EXTENTS, -1628); E_UNABLE_EXTEND_TEMPSEG EXCEPTION; PRAGMA EXCEPTION_INIT (E_UNABLE_EXTEND_TEMPSEG, -1652); E_TABLE_TS_FULL_NUM CONSTANT NUMBER := -1653; E_TABLE_TS_FULL EXCEPTION; PRAGMA EXCEPTION_INIT (E_TABLE_TS_FULL, -1653); E_INDEX_TS_FULL EXCEPTION; PRAGMA EXCEPTION_INIT (E_INDEX_TS_FULL, -1654); E_INDEXPART_TS_FULL EXCEPTION; PRAGMA EXCEPTION_INIT (E_INDEXPART_TS_FULL, -1683); E_TABLEPART_TS_FULL EXCEPTION; PRAGMA EXCEPTION_INIT (E_TABLEPART_TS_FULL, -1688); E_NO_LONGER_EXISTS EXCEPTION; PRAGMA EXCEPTION_INIT (E_NO_LONGER_EXISTS, -8103); E_CONSISTENT_READ EXCEPTION; PRAGMA EXCEPTION_INIT ( E_CONSISTENT_READ, -8176 ); E_CONSISTENT_READ_NUM CONSTANT NUMBER := -8176; E_PQ_FAILURE EXCEPTION; PRAGMA EXCEPTION_INIT (E_PQ_FAILURE, -12805); E_INSTANCE_UNAVAILABLE EXCEPTION; PRAGMA EXCEPTION_INIT (E_INSTANCE_UNAVAILABLE, -16639); E_BACKUP_IO_ERROR_RMAN_NUM CONSTANT NUMBER := -19624; E_BACKUP_IO_ERROR_RMAN EXCEPTION; PRAGMA EXCEPTION_INIT (E_BACKUP_IO_ERROR_RMAN, -19624); E_ERROR_ID_FILE_NUM CONSTANT NUMBER := -19625; E_ERROR_ID_FILE EXCEPTION; PRAGMA EXCEPTION_INIT (E_ERROR_ID_FILE, -19625); E_ROW_CACHE_LOCK EXCEPTION; PRAGMA EXCEPTION_INIT (E_ROW_CACHE_LOCK, -27355); E_JOB_WONT_STOP EXCEPTION; PRAGMA EXCEPTION_INIT (E_JOB_WONT_STOP, -27365); E_JOB_NOT_RUNNING EXCEPTION; PRAGMA EXCEPTION_INIT (E_JOB_NOT_RUNNING, -27366); E_JOB_NOT_FOUND EXCEPTION; PRAGMA EXCEPTION_INIT (E_JOB_NOT_FOUND, -27475); E_JOB_DOES_NOT_EXIST EXCEPTION; PRAGMA EXCEPTION_INIT (E_JOB_DOES_NOT_EXIST, -27476); E_JOB_ALREADY_EXISTS EXCEPTION; PRAGMA EXCEPTION_INIT (E_JOB_ALREADY_EXISTS, -27477); E_RESUMABLE_TIMEOUT EXCEPTION; PRAGMA EXCEPTION_INIT (E_RESUMABLE_TIMEOUT, -30032); E_CANT_EXTEND_UNDO EXCEPTION; PRAGMA EXCEPTION_INIT (E_CANT_EXTEND_UNDO, -30036); /* Below referenced from dbmsbkrs.pls */ E_CORRUPT_NUM CONSTANT NUMBER := -19599; E_CORRUPT EXCEPTION; PRAGMA EXCEPTION_INIT (E_CORRUPT, -19599); E_UCONSTRAINT_NUM CONSTANT NUMBER := -1; E_UCONSTRAINT EXCEPTION; PRAGMA EXCEPTION_INIT (E_UCONSTRAINT, -1); -- -- -- -- -- -- E_REPAIR_AVM_METADATA EXCEPTION; PRAGMA EXCEPTION_INIT ( E_REPAIR_AVM_METADATA, -45100 ); E_REPAIR_AVM_METADATA_NUM CONSTANT NUMBER := -45100; E_BAD_CHUNK_NUMBER EXCEPTION; PRAGMA EXCEPTION_INIT ( E_BAD_CHUNK_NUMBER, -45101 ); E_BAD_CHUNK_NUMBER_NUM CONSTANT NUMBER := -45101; E_NO_MORE_STORAGE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_NO_MORE_STORAGE, -45102 ); E_NO_MORE_STORAGE_NUM CONSTANT NUMBER := -45102; E_BAD_STORAGE_LOCATION EXCEPTION; PRAGMA EXCEPTION_INIT ( E_BAD_STORAGE_LOCATION, -45103 ); E_BAD_STORAGE_LOCATION_NUM CONSTANT NUMBER := -45103; E_BACKUP_NOT_FOUND EXCEPTION; PRAGMA EXCEPTION_INIT ( E_BACKUP_NOT_FOUND, -45104 ); E_BACKUP_NOT_FOUND_NUM CONSTANT NUMBER := -45104; E_NOT_IN_PURGE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_NOT_IN_PURGE, -45105 ); E_NOT_IN_PURGE_NUM CONSTANT NUMBER := -45105; E_BAD_VBID EXCEPTION; PRAGMA EXCEPTION_INIT ( E_BAD_VBID, -45106 ); E_BAD_VBID_NUM CONSTANT NUMBER := -45106; E_PENDING_INTERRUPT EXCEPTION; PRAGMA EXCEPTION_INIT ( E_PENDING_INTERRUPT, -45110 ); E_PENDING_INTERRUPT_NUM CONSTANT NUMBER := -45110; E_TOO_MANY_RESTARTS EXCEPTION; PRAGMA EXCEPTION_INIT ( E_TOO_MANY_RESTARTS, -45111 ); E_TOO_MANY_RESTARTS_NUM CONSTANT NUMBER := -45111; E_RETRY_ERROR EXCEPTION; PRAGMA EXCEPTION_INIT ( E_RETRY_ERROR, -45112 ); E_RETRY_ERROR_NUM CONSTANT NUMBER := -45112; E_INTERNAL_ERROR EXCEPTION; PRAGMA EXCEPTION_INIT ( E_INTERNAL_ERROR, -45113 ); E_INTERNAL_ERROR_NUM CONSTANT NUMBER := -45113; E_ORPHAN_FILE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_ORPHAN_FILE, -45114 ); E_ORPHAN_FILE_NUM CONSTANT NUMBER := -45114; E_TOO_BIG_TO_MOVE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_TOO_BIG_TO_MOVE, -45115 ); E_TOO_BIG_TO_MOVE_NUM CONSTANT NUMBER := -45115; E_RETRY_RESERVE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_RETRY_RESERVE, -45117 ); E_RETRY_RESERVE_NUM CONSTANT NUMBER := -45117; E_ORPHAN_BP_PIECE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_ORPHAN_BP_PIECE, -45128 ); E_ORPHAN_BP_PIECE_NUM CONSTANT NUMBER := -45128; E_BAD_ODB_USAGE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_BAD_ODB_USAGE, -45129 ); E_BAD_ODB_USAGE_NUM CONSTANT NUMBER := -45129; E_BAD_TOTAL_ALLOC EXCEPTION; PRAGMA EXCEPTION_INIT ( E_BAD_TOTAL_ALLOC, -45133 ); E_BAD_TOTAL_ALLOC_NUM CONSTANT NUMBER := -45133; E_CORRUPT_BACKUP EXCEPTION; PRAGMA EXCEPTION_INIT ( E_CORRUPT_BACKUP, -45116 ); E_CORRUPT_BACKUP_NUM CONSTANT NUMBER := -45116; E_OAM_NOT_RUNNING EXCEPTION; PRAGMA EXCEPTION_INIT ( E_OAM_NOT_RUNNING, -45164 ); E_OAM_NOT_RUNNING_NUM CONSTANT NUMBER := -45164; E_CORRUPT_BACKUPPIECE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_CORRUPT_BACKUPPIECE, -45165 ); E_CORRUPT_BACKUPPIECE_NUM CONSTANT NUMBER := -45165; E_NO_MORE_SGA EXCEPTION; PRAGMA EXCEPTION_INIT ( E_NO_MORE_SGA, -45134 ); E_NO_MORE_SGA_NUM CONSTANT NUMBER := -45134; E_CORRUPT_BLOCK EXCEPTION; PRAGMA EXCEPTION_INIT ( E_CORRUPT_BLOCK, -45132 ); E_CORRUPT_BLOCK_NUM CONSTANT NUMBER := -45132; E_TERMINATED EXCEPTION; PRAGMA EXCEPTION_INIT ( E_TERMINATED, -45135 ); E_TERMINATED_NUM CONSTANT NUMBER := -45135; E_NEED_MORE_SPACE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_NEED_MORE_SPACE, -45146 ); E_NEED_MORE_SPACE_NUM CONSTANT NUMBER := -45146; E_TOO_MANY_MOVES EXCEPTION; PRAGMA EXCEPTION_INIT ( E_TOO_MANY_MOVES, -45147 ); E_TOO_MANY_MOVES_NUM CONSTANT NUMBER := -45147; E_ERRORS_FOUND EXCEPTION; PRAGMA EXCEPTION_INIT ( E_ERRORS_FOUND, -45148 ); E_ERRORS_FOUND_NUM CONSTANT NUMBER := -45148; E_BAD_TASK_TYPE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_BAD_TASK_TYPE, -45149 ); E_BAD_TASK_TYPE_NUM CONSTANT NUMBER := -45149; E_BAD_DBID EXCEPTION; PRAGMA EXCEPTION_INIT ( E_BAD_DBID, -45150 ); E_BAD_DBID_NUM CONSTANT NUMBER := -45150; E_BAD_LOCKING_PROTOCOL EXCEPTION; PRAGMA EXCEPTION_INIT ( E_BAD_LOCKING_PROTOCOL, -45151 ); E_BAD_LOCKING_PROTOCOL_NUM CONSTANT NUMBER := -45151; E_BAD_BACKUP_PIECE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_BAD_BACKUP_PIECE, -45152 ); E_BAD_BACKUP_PIECE_NUM CONSTANT NUMBER := -45152; E_UNKNOWN_DATAFILE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_UNKNOWN_DATAFILE, -45153 ); E_UNKNOWN_DATAFILE_NUM CONSTANT NUMBER := -45153; E_UNKNOWN_FILE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_UNKNOWN_FILE, -45154 ); E_UNKNOWN_FILE_NUM CONSTANT NUMBER := -45154; E_SBT_JOB_NOTFOUND EXCEPTION; PRAGMA EXCEPTION_INIT ( E_SBT_JOB_NOTFOUND, -45156 ); E_SBT_JOB_NOTFOUND_NUM CONSTANT NUMBER := -45156; E_SBT_LIB_NOT_READY EXCEPTION; PRAGMA EXCEPTION_INIT ( E_SBT_LIB_NOT_READY, -45158 ); E_SBT_LIB_NOT_READY_NUM CONSTANT NUMBER := -45158; E_REC_WINDOW_LOST EXCEPTION; PRAGMA EXCEPTION_INIT ( E_REC_WINDOW_LOST, -45159 ); E_REC_WINDOW_LOST_NUM CONSTANT NUMBER := -45159; E_INCR_LOST EXCEPTION; PRAGMA EXCEPTION_INIT ( E_INCR_LOST, -45160 ); E_INCR_LOST_NUM CONSTANT NUMBER := -45160; E_PIECE_TOO_BIG EXCEPTION; PRAGMA EXCEPTION_INIT ( E_PIECE_TOO_BIG, -45161 ); E_PIECE_TOO_BIG_NUM CONSTANT NUMBER := -45161; E_BAD_USER EXCEPTION; PRAGMA EXCEPTION_INIT ( E_BAD_USER, -45163 ); E_BAD_USER_NUM CONSTANT NUMBER := -45163; E_BAD_FILE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_BAD_FILE, -45166 ); E_BAD_FILE_NUM CONSTANT NUMBER := -45166; E_BAD_VALIDATE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_BAD_VALIDATE, -45167 ); E_BAD_VALIDATE_NUM CONSTANT NUMBER := -45167; E_BAD_TASK EXCEPTION; PRAGMA EXCEPTION_INIT ( E_BAD_TASK, -45168 ); E_BAD_TASK_NUM CONSTANT NUMBER := -45168; E_TIMER_EXIT EXCEPTION; PRAGMA EXCEPTION_INIT ( E_TIMER_EXIT, -45169 ); E_TIMER_EXIT_NUM CONSTANT NUMBER := -45169; E_SL_FULL EXCEPTION; PRAGMA EXCEPTION_INIT ( E_SL_FULL, -45170 ); E_SL_FULL_NUM CONSTANT NUMBER := -45170; E_LATE_OPTIMIZE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_LATE_OPTIMIZE, -45171 ); E_LATE_OPTIMIZE_NUM CONSTANT NUMBER := -45171; E_LATE_VALIDATE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_LATE_VALIDATE, -45172 ); E_LATE_VALIDATE_NUM CONSTANT NUMBER := -45172; E_LATE_CHECKFILES EXCEPTION; PRAGMA EXCEPTION_INIT ( E_LATE_CHECKFILES, -45173 ); E_LATE_CHECKFILES_NUM CONSTANT NUMBER := -45173; E_REPLICATION_ERROR EXCEPTION; PRAGMA EXCEPTION_INIT ( E_REPLICATION_ERROR, -45174 ); E_REPLICATION_ERROR_NUM CONSTANT NUMBER := -45174; E_SBT_ERROR EXCEPTION; PRAGMA EXCEPTION_INIT ( E_SBT_ERROR, -45175 ); E_SBT_ERROR_NUM CONSTANT NUMBER := -45175; E_MISSING_POLL_FILE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_MISSING_POLL_FILE, -45177 ); E_MISSING_POLL_FILE_NUM CONSTANT NUMBER := -45177; E_LATE_RECONCILE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_LATE_RECONCILE, -45179 ); E_LATE_RECONCILE_NUM CONSTANT NUMBER := -45179; E_LATE_CROSSCHECK EXCEPTION; PRAGMA EXCEPTION_INIT ( E_LATE_CROSSCHECK, -45180 ); E_LATE_CROSSCHECK_NUM CONSTANT NUMBER := -45180; E_DUP_FILE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_DUP_FILE, -45181 ); E_DUP_FILE_NUM CONSTANT NUMBER := -45181; E_FAILED EXCEPTION; PRAGMA EXCEPTION_INIT ( E_FAILED, -45186 ); E_FAILED_NUM CONSTANT NUMBER := -45186; E_SL_REBUILD_FATAL_NUM CONSTANT NUMBER := -45187; E_SL_REBUILD_RECOVERABLE_NUM CONSTANT NUMBER := -45188; E_SL_RENAME_NUM CONSTANT NUMBER := -45189; E_SBT_LIB_NOT_AVAIL_NUM CONSTANT NUMBER := -45191; E_SBT_LIB_RESERV_EXISTS_NUM CONSTANT NUMBER := -45192; E_SBT_MULT_LIB_EXISTS_NUM CONSTANT NUMBER := -45193; E_BA_METADATABCK_FAIL_NUM CONSTANT NUMBER := -45194; E_SBT_LIB_RES_TIMED_OUT_NUM CONSTANT NUMBER := -45195; E_SBT_LIB_UNRES_FAILED EXCEPTION; PRAGMA EXCEPTION_INIT ( E_SBT_LIB_UNRES_FAILED, -45196 ); E_SBT_LIB_UNRES_FAILED_NUM CONSTANT NUMBER := -45196; E_SBT_LIB_RES_NOT_FOUND_NUM CONSTANT NUMBER := -45197; E_BA_TEST_RECV_FAIL_NUM CONSTANT NUMBER := -45264; E_BA_BKP_HLTH_CHCK_FAIL_NUM CONSTANT NUMBER := -45265; E_BA_DB_HLTH_CHCK_FAIL_NUM CONSTANT NUMBER := -45266; E_SHUTTING_DOWN_NUM CONSTANT NUMBER := -64700; E_SL_OUT_OF_SPACE_NUM CONSTANT NUMBER := -64701; E_CONTAINER_REBUILD_ERROR_NUM CONSTANT NUMBER := -64702; E_RESOURCE_ERROR_NUM CONSTANT NUMBER := -64703; E_NEW_INC_ERROR_NUM CONSTANT NUMBER := -64735; E_TOO_MANY_INTERRUPTS_NUM CONSTANT NUMBER := -64736; E_REC_WINDOW_LOW_NUM CONSTANT NUMBER := -64739; E_UNPROTECTED_WINDOW_LOST_NUM CONSTANT NUMBER := -64740; E_SERVLET_ERROR EXCEPTION; PRAGMA EXCEPTION_INIT ( E_SERVLET_ERROR, -45201 ); E_SERVLET_ERROR_NUM CONSTANT NUMBER := -45201; E_FULL_BACKUP_NOT_FOUND EXCEPTION; PRAGMA EXCEPTION_INIT ( E_FULL_BACKUP_NOT_FOUND, -64737 ); E_FULL_BACKUP_NOT_FOUND_NUM CONSTANT NUMBER := -64737; E_GCOPY_SUSPENDED EXCEPTION; PRAGMA EXCEPTION_INIT ( E_GCOPY_SUSPENDED, -64738 ); E_GCOPY_SUSPENDED_NUM CONSTANT NUMBER := -64738; E_COULDNT_STOP_JOB_NUM CONSTANT NUMBER := -64741; E_DELETE_DB_CHUNKS EXCEPTION; PRAGMA EXCEPTION_INIT ( E_DELETE_DB_CHUNKS, -64743 ); E_DELETE_DB_CHUNKS_NUM CONSTANT NUMBER := -64743; E_DBFS_WAIT_FAILURE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_DBFS_WAIT_FAILURE, -64750 ); E_DBFS_WAIT_FAILURE_NUM CONSTANT NUMBER := -64750; E_SBT_TASK_NOT_FOUND CONSTANT NUMBER := -45216; E_BACKUP_FAILED CONSTANT NUMBER := -64752; E_BAD_RESTORE EXCEPTION; PRAGMA EXCEPTION_INIT ( E_BAD_RESTORE, -64757 ); E_BAD_RESTORE_NUM CONSTANT NUMBER := -64757; E_POOL_FULL EXCEPTION; PRAGMA EXCEPTION_INIT ( E_POOL_FULL, -64758 ); E_POOL_FULL_NUM CONSTANT NUMBER := -64758; E_END_RESOURCE_WAIT EXCEPTION; PRAGMA EXCEPTION_INIT ( E_END_RESOURCE_WAIT, -64759 ); E_END_RESOURCE_WAIT_NUM CONSTANT NUMBER := -64759; E_ORDERING_WAIT EXCEPTION; PRAGMA EXCEPTION_INIT ( E_ORDERING_WAIT, -64760 ); E_ORDERING_WAIT_NUM CONSTANT NUMBER := -64760; E_CANCELED EXCEPTION; PRAGMA EXCEPTION_INIT ( E_CANCELED, -64756 ); E_CANCELED_NUM CONSTANT NUMBER := -64756; END dbms_ra_scheduler; >>> define dbmsrssm_plb <<< CREATE OR REPLACE PACKAGE dbms_ra_storage AS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE copy_piece(p_fname IN VARCHAR2 DEFAULT NULL, p_db_key IN NUMBER DEFAULT NULL, p_action IN NUMBER DEFAULT 0); -- PROCEDURE move_all_db; -- PROCEDURE move_database_metadata (p_db_key IN NUMBER, p_old_sl_key IN NUMBER, p_sl_key IN NUMBER); -- FUNCTION freespace (p_sl_key IN NUMBER) RETURN NUMBER; -- PROCEDURE purge_database (p_db_key IN NUMBER, p_sl_key IN NUMBER DEFAULT NULL, p_inline IN BOOLEAN DEFAULT FALSE); -- PROCEDURE allocate_backup_piece_name( p_db_id IN NUMBER, p_piecename IN VARCHAR2, p_fincarn IN VARCHAR2); -- PROCEDURE allocate_backup_piece( p_piecename IN VARCHAR2, p_fincarn IN VARCHAR2, p_filesize IN NUMBER, p_ct_key OUT NUMBER); -- PROCEDURE name_backup_piece( p_ct_key IN NUMBER, p_filename IN VARCHAR2); -- PROCEDURE finish_backup_piece( p_db_key IN NUMBER, p_handle IN VARCHAR2, p_pieceinc IN VARCHAR2, p_ct_key IN NUMBER); -- PROCEDURE finish_file(p_newfname IN VARCHAR2, p_filesize IN NUMBER, p_handle OUT VARCHAR2, p_move_bp OUT NUMBER); -- PROCEDURE swap_backup_piece(p_bpkey IN NUMBER); -- PROCEDURE free_backup_piece( p_dbkey IN NUMBER, p_piecename IN VARCHAR2, p_ftype IN NUMBER DEFAULT NULL, p_fincarn IN VARCHAR2 DEFAULT NULL, p_can_defer IN BOOLEAN DEFAULT FALSE); -- -- PROCEDURE free_backup_piece_opt( p_dbkey IN NUMBER, p_piecename IN VARCHAR2, p_db_slkey IN NUMBER, p_dbid IN NUMBER, p_currinc IN NUMBER, p_bpkey IN NUMBER, p_ftype IN NUMBER DEFAULT NULL, p_fincarn IN VARCHAR2 DEFAULT NULL, p_libkey IN NUMBER DEFAULT NULL, p_spawn_job IN BOOLEAN DEFAULT TRUE, p_notasks IN BOOLEAN DEFAULT FALSE, p_noplans IN BOOLEAN DEFAULT FALSE); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION get_chunkno( p_df_key IN NUMBER, p_count IN NUMBER DEFAULT 1) RETURN NUMBER; -- PROCEDURE preallocate_chunks( p_db_key IN NUMBER, p_count IN NUMBER, p_required IN BOOLEAN DEFAULT FALSE); -- PROCEDURE allocate_block_pool_chunk( p_db_key IN NUMBER, p_dbinc_key IN NUMBER, p_df_key IN NUMBER, p_vb_key IN NUMBER, p_chunkno OUT NUMBER); -- PROCEDURE free_block_pool_chunk( p_db_key IN NUMBER, p_dbinc_key IN NUMBER, p_df_key IN NUMBER, p_chunkno IN NUMBER); -- PROCEDURE free_block_pool_chunks( p_sl_key IN NUMBER, p_db_key IN NUMBER, p_df_key IN NUMBER, p_chunks IN dbms_sql.number_table); -- PROCEDURE free_task_storage (p_task_id NUMBER DEFAULT NULL); -- FUNCTION reserve_block_pool_space( p_db_key IN NUMBER, p_chunks IN NUMBER, p_maxchunks OUT NUMBER) RETURN NUMBER; -- PROCEDURE finish_block_pool_chunk( p_db_key IN NUMBER); -- PROCEDURE purge_storage_location (p_sl_key IN NUMBER, p_db_key IN NUMBER, p_spaceneed IN NUMBER, p_immediate IN BOOLEAN); -- PROCEDURE backupArch(p_dbkey IN NUMBER, p_fname IN VARCHAR2, p_complete IN BOOLEAN, p_delete IN BOOLEAN DEFAULT TRUE); -- PROCEDURE trim_database_for_move (p_db_key IN NUMBER, p_alloc IN NUMBER); -- PROCEDURE trim_database_as_job (p_db_key IN NUMBER, p_sl_key IN NUMBER, p_allocation IN NUMBER); -- PROCEDURE check_files (p_sl_key IN NUMBER, p_execute_time IN TIMESTAMP WITH TIME ZONE, p_savepoint IN NUMBER, p_repair IN BOOLEAN); -- PROCEDURE lock_db (p_db_key IN NUMBER); -- PROCEDURE unlock_db (p_db_key IN NUMBER); -- PROCEDURE lock_sl (p_sl_key IN NUMBER); -- PROCEDURE unlock_sl (p_sl_key IN NUMBER); -- PROCEDURE setTracing(p_trc_on IN NUMBER, p_perf_on IN NUMBER DEFAULT 0, p_stall_on IN NUMBER DEFAULT 0, p_safe_mode IN NUMBER DEFAULT 0); END dbms_ra_storage; >>> define dbmsrs_plb <<< CREATE OR REPLACE PACKAGE dbms_ra IS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- BA_STORAGE_DISK CONSTANT NUMBER := 1; BA_STORAGE_HTTP CONSTANT NUMBER := 2; BA_STORAGE_NFS_ORACLE CONSTANT NUMBER := 3; PROCEDURE startup; -- PROCEDURE startup_recovery_appliance; -- -- -- -- -- -- -- -- -- -- -- PROCEDURE shutdown; -- PROCEDURE shutdown_recovery_appliance; -- -- -- -- -- PROCEDURE abort; -- PROCEDURE abort_recovery_appliance; -- -- -- -- -- -- -- -- -- PROCEDURE create_storage_location ( storage_location_name IN VARCHAR2, storage_location_dests IN VARCHAR2); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE delete_storage_location ( storage_location_name IN VARCHAR2); -- -- -- -- -- -- -- -- PROCEDURE update_storage_location ( storage_location_name IN VARCHAR2, storage_location_dests IN VARCHAR2 DEFAULT NULL); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE add_db ( db_unique_name IN VARCHAR2, protection_policy_name IN VARCHAR2, reserved_space IN VARCHAR2); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE update_db ( db_unique_name IN VARCHAR2, protection_policy_name IN VARCHAR2 DEFAULT NULL, reserved_space IN VARCHAR2 DEFAULT NULL, db_timezone IN VARCHAR2 DEFAULT NULL, incarnations IN VARCHAR2 DEFAULT 'CURRENT'); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE delete_db ( db_unique_name IN VARCHAR2, wait IN BOOLEAN DEFAULT TRUE); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE rename_db ( db_unique_name_old IN VARCHAR2, db_unique_name_new IN VARCHAR2); -- -- -- -- -- -- -- -- -- PROCEDURE create_protection_policy ( protection_policy_name IN VARCHAR2, description IN VARCHAR2 DEFAULT NULL, storage_location_name IN VARCHAR2, polling_policy_name IN VARCHAR2 DEFAULT NULL, recovery_window_goal IN DSINTERVAL_UNCONSTRAINED, max_retention_window IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, recovery_window_sbt IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, unprotected_window IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, guaranteed_copy IN VARCHAR2 DEFAULT 'NO'); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE update_protection_policy ( protection_policy_name IN VARCHAR2, description IN VARCHAR2 DEFAULT NULL, storage_location_name IN VARCHAR2 DEFAULT NULL, polling_policy_name IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p1'), recovery_window_goal IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, max_retention_window IN DSINTERVAL_UNCONSTRAINED DEFAULT dbms_ra_int.intervalnull('p3'), recovery_window_sbt IN DSINTERVAL_UNCONSTRAINED DEFAULT dbms_ra_int.intervalnull('p2'), unprotected_window IN DSINTERVAL_UNCONSTRAINED DEFAULT dbms_ra_int.intervalnull('p4'), guaranteed_copy IN VARCHAR2 DEFAULT NULL); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE delete_protection_policy ( protection_policy_name IN VARCHAR2); -- -- -- -- PROCEDURE add_replication_server ( replication_server_name IN VARCHAR2, protection_policy_name IN VARCHAR2); -- -- -- -- -- -- -- -- -- PROCEDURE remove_replication_server ( replication_server_name IN VARCHAR2, protection_policy_name IN VARCHAR2); -- -- -- -- -- -- -- -- -- -- PROCEDURE create_polling_policy( polling_policy_name IN VARCHAR2, polling_location IN VARCHAR2, polling_frequency IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, delete_input IN BOOLEAN DEFAULT FALSE); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE update_polling_policy ( polling_policy_name IN VARCHAR2, polling_location IN VARCHAR2 DEFAULT NULL, polling_frequency IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, delete_input IN BOOLEAN DEFAULT NULL); -- -- -- -- -- -- -- -- -- -- PROCEDURE delete_polling_policy ( polling_policy_name IN VARCHAR2); -- -- -- PROCEDURE create_sbt_library ( lib_name IN VARCHAR2, drives IN NUMBER, restore_drives IN NUMBER DEFAULT 0, parms IN VARCHAR2 DEFAULT NULL, send IN VARCHAR2 DEFAULT NULL); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE update_sbt_library ( lib_name IN VARCHAR2, drives IN NUMBER DEFAULT NULL, restore_drives IN NUMBER DEFAULT NULL, parms IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p1'), send IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p2')); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE delete_sbt_library (lib_name IN VARCHAR2); -- -- -- -- -- -- PROCEDURE pause_sbt_library( lib_name IN VARCHAR2); -- -- -- -- -- -- -- -- PROCEDURE resume_sbt_library( lib_name IN VARCHAR2); -- -- -- -- -- PROCEDURE set_restrict_sbt_instance ( lib_name IN VARCHAR2, instance_name IN VARCHAR2); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE clear_restrict_sbt_instance ( lib_name IN VARCHAR2, instance_name IN VARCHAR2); -- -- -- -- -- -- -- -- -- PROCEDURE create_sbt_attribute_set( lib_name IN VARCHAR2, attribute_set_name IN VARCHAR2, streams IN NUMBER DEFAULT NULL, poolid IN NUMBER DEFAULT NULL, parms IN VARCHAR2 DEFAULT NULL, send IN VARCHAR2 DEFAULT NULL); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE update_sbt_attribute_set( attribute_set_name IN VARCHAR2, streams IN NUMBER DEFAULT dbms_ra_int.number2null('p1'), poolid IN NUMBER DEFAULT NULL, parms IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p2'), send IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p3')); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE delete_sbt_attribute_set( attribute_set_name IN VARCHAR2); -- -- -- -- SBT_PRIORITY_LOW CONSTANT NUMBER := 1000; SBT_PRIORITY_MEDIUM CONSTANT NUMBER := 100; SBT_PRIORITY_HIGH CONSTANT NUMBER := 10; SBT_PRIORITY_CRITICAL CONSTANT NUMBER := 1; PROCEDURE create_sbt_job_template ( template_name IN VARCHAR2, protection_policy_name IN VARCHAR2, attribute_set_name IN VARCHAR2, backup_type IN VARCHAR2, full_template_name IN VARCHAR2 DEFAULT NULL, from_tag IN VARCHAR2 DEFAULT NULL, priority IN NUMBER DEFAULT SBT_PRIORITY_MEDIUM, copies IN NUMBER DEFAULT 1, window IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE create_sbt_job_template ( template_name IN VARCHAR2, db_unique_name IN VARCHAR2, attribute_set_name IN VARCHAR2, backup_type IN VARCHAR2, full_template_name IN VARCHAR2 DEFAULT NULL, from_tag IN VARCHAR2 DEFAULT NULL, priority IN NUMBER DEFAULT SBT_PRIORITY_MEDIUM, copies IN NUMBER DEFAULT 1, window IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL); -- -- -- -- -- -- -- -- -- -- -- PROCEDURE update_sbt_job_template ( template_name IN VARCHAR2, attribute_set_name IN VARCHAR2 DEFAULT NULL, backup_type IN VARCHAR2 DEFAULT NULL, from_tag IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p1'), priority IN NUMBER DEFAULT NULL, copies IN NUMBER DEFAULT NULL, window IN DSINTERVAL_UNCONSTRAINED DEFAULT dbms_ra_int.intervalnull('p2')); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE delete_sbt_job_template ( template_name IN VARCHAR2); -- -- -- -- -- RESERVE_BACKUP_TYPE CONSTANT NUMBER := 32; PROCEDURE queue_sbt_backup_task( template_name IN VARCHAR2); -- -- -- -- -- -- -- PROCEDURE abort_sbt_task( task_id IN NUMBER); -- -- -- -- PROCEDURE config(p_name VARCHAR2, p_value VARCHAR2); -- -- -- -- -- PROCEDURE create_replication_server ( replication_server_name IN VARCHAR2, sbt_so_name IN VARCHAR2, sbt_parms IN VARCHAR2 DEFAULT NULL, max_streams IN NUMBER DEFAULT NULL, catalog_user_name IN VARCHAR2, wallet_alias IN VARCHAR2, wallet_path IN VARCHAR2, proxy_url IN VARCHAR2 DEFAULT NULL, proxy_port IN NUMBER DEFAULT NULL, http_timeout IN NUMBER DEFAULT NULL); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE update_replication_server ( replication_server_name IN VARCHAR2, sbt_so_name IN VARCHAR2 DEFAULT NULL, sbt_parms IN VARCHAR2 DEFAULT NULL, max_streams IN NUMBER DEFAULT dbms_ra_int.number2null('p4'), catalog_user_name IN VARCHAR2 DEFAULT NULL, wallet_alias IN VARCHAR2 DEFAULT NULL, wallet_path IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p1'), proxy_url IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p2'), proxy_port IN NUMBER DEFAULT dbms_ra_int.number2null('p3'), http_timeout IN NUMBER DEFAULT NULL); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE delete_replication_server (replication_server_name IN VARCHAR2, force IN BOOLEAN DEFAULT FALSE); -- -- -- -- -- -- -- -- -- -- -- PROCEDURE pause_replication_server (replication_server_name IN VARCHAR2); -- -- -- -- -- -- -- -- -- -- PROCEDURE resume_replication_server (replication_server_name IN VARCHAR2); -- -- -- -- PROCEDURE grant_db_access (username IN VARCHAR2, db_unique_name IN VARCHAR2); -- -- -- -- -- -- -- -- PROCEDURE revoke_db_access (username IN VARCHAR2, db_unique_name IN VARCHAR2); -- -- -- -- -- -- PROCEDURE populate_backup_piece(backup_piece_key IN NUMBER); -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE copy_backup (tag IN VARCHAR2, format IN VARCHAR2, template_name IN VARCHAR2); -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE copy_backup_piece (bp_key IN NUMBER, format IN VARCHAR2, template_name IN VARCHAR2); -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE move_backup (tag IN VARCHAR2, format IN VARCHAR2, template_name IN VARCHAR2); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE move_backup_piece (bp_key IN NUMBER, format IN VARCHAR2, template_name IN VARCHAR2); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE migrate_tape_backup(db_unique_name IN VARCHAR2, sbt_lib_name IN VARCHAR2); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE reset_error(incident# IN NUMBER); -- -- -- -- -- -- -- -- -- -- PROCEDURE repair_storage_location ( storage_location_name IN VARCHAR2, repair_type IN VARCHAR2); -- -- FUNCTION estimate_space ( db_unique_name IN VARCHAR2, target_window IN DSINTERVAL_UNCONSTRAINED) RETURN NUMBER; -- -- PROCEDURE dump (do_dpdump BOOLEAN DEFAULT FALSE); -- -- -- -- -- -- -- -- -- UNKNOWN_OPERATION_PRVLG EXCEPTION; PRAGMA EXCEPTION_INIT ( UNKNOWN_OPERATION_PRVLG, -45119 ); UNKNOWN_OPERATION_PRVLG_NUM CONSTANT NUMBER := -45119; -- SPACE_QUOTA_VIOLATION EXCEPTION; PRAGMA EXCEPTION_INIT ( SPACE_QUOTA_VIOLATION, -45120 ); SPACE_QUOTA_VIOLATION_NUM CONSTANT NUMBER := -45120; -- UNKNOWN_MANAGE_PRVLG_PARAM EXCEPTION; PRAGMA EXCEPTION_INIT ( UNKNOWN_MANAGE_PRVLG_PARAM, -45121 ); UNKNOWN_MANAGE_PRVLG_PARAM_NUM CONSTANT NUMBER := -45121; -- INVALID_SIZENUMBER EXCEPTION; PRAGMA EXCEPTION_INIT ( INVALID_SIZENUMBER, -45122 ); INVALID_SIZENUMBER_NUM CONSTANT NUMBER := -45122; -- DUP_NAME EXCEPTION; PRAGMA EXCEPTION_INIT ( DUP_NAME, -45123 ); DUP_NAME_NUM CONSTANT NUMBER := -45123; -- OBJ_IS_REFERENCED EXCEPTION; PRAGMA EXCEPTION_INIT ( OBJ_IS_REFERENCED, -45124 ); OBJ_IS_REFERENCED_NUM CONSTANT NUMBER := -45124; -- OBJ_NOT_FOUND EXCEPTION; PRAGMA EXCEPTION_INIT ( OBJ_NOT_FOUND, -45125 ); OBJ_NOT_FOUND_NUM CONSTANT NUMBER := -45125; -- CANT_DELETE_DB EXCEPTION; PRAGMA EXCEPTION_INIT ( CANT_DELETE_DB, -45126 ); CANT_DELETE_DB_NUM CONSTANT NUMBER := -45126; -- E_INTERNAL_ERROR EXCEPTION; PRAGMA EXCEPTION_INIT ( E_INTERNAL_ERROR, -45113 ); E_INTERNAL_ERROR_NUM CONSTANT NUMBER := -45113; -- MISSING_PARAM EXCEPTION; PRAGMA EXCEPTION_INIT ( MISSING_PARAM, -45127 ); MISSING_PARAM_NUM CONSTANT NUMBER := -45127; -- E_SHARED_PARAMS EXCEPTION; PRAGMA EXCEPTION_INIT ( E_SHARED_PARAMS, -45130 ); E_SHARED_PARAMS_NUM CONSTANT NUMBER := -45130; -- BAD_RECOMPR EXCEPTION; PRAGMA EXCEPTION_INIT ( BAD_RECOMPR, -45131 ); BAD_RECOMPR_NUM CONSTANT NUMBER := -45131; -- INVALID_VAL EXCEPTION; PRAGMA EXCEPTION_INIT ( INVALID_VAL, -45136 ); INVALID_VAL_NUM CONSTANT NUMBER := -45136; -- UNKNOWN_PLATFORM EXCEPTION; PRAGMA EXCEPTION_INIT ( UNKNOWN_PLATFORM, -45137 ); UNKNOWN_PLATFORM_NUM CONSTANT NUMBER := -45137; -- UNKNONW_BP EXCEPTION; PRAGMA EXCEPTION_INIT ( UNKNONW_BP, -45138 ); UNKNONW_BP_NUM CONSTANT NUMBER := -45138; -- NO_FIND_USEFUL_BP EXCEPTION; PRAGMA EXCEPTION_INIT ( NO_FIND_USEFUL_BP, -45139 ); NO_FIND_USEFUL_BP_NUM CONSTANT NUMBER := -45139; -- NO_INSERT_BP EXCEPTION; PRAGMA EXCEPTION_INIT ( NO_INSERT_BP, -45140 ); NO_INSERT_BP_NUM CONSTANT NUMBER := -45140; -- MISSING_INIT_REP_TYPE EXCEPTION; PRAGMA EXCEPTION_INIT ( MISSING_INIT_REP_TYPE, -45144 ); MISSING_INIT_REP_TYPE_NUM CONSTANT NUMBER := -45144; -- USER_NOT_FOUND EXCEPTION; PRAGMA EXCEPTION_INIT ( USER_NOT_FOUND, -45145 ); USER_NOT_FOUND_NUM CONSTANT NUMBER := -45145; -- INVALID_PARAM EXCEPTION; PRAGMA EXCEPTION_INIT ( INVALID_PARAM, -45157 ); INVALID_PARAM_NUM CONSTANT NUMBER := -45157; -- BA_NOT_RUNNING_PARAM EXCEPTION; PRAGMA EXCEPTION_INIT ( BA_NOT_RUNNING_PARAM, -45164 ); BA_NOT_RUNNING_PARAM_NUM CONSTANT NUMBER := -45164; -- REP_SRVR_RUNNING EXCEPTION; PRAGMA EXCEPTION_INIT ( REP_SRVR_RUNNING, -45176 ); REP_SRVR_RUNNING_NUM CONSTANT NUMBER := -45176; -- BAD_AU_SIZE EXCEPTION; PRAGMA EXCEPTION_INIT ( BAD_AU_SIZE, -45178 ); BAD_AU_SIZE_NUM CONSTANT NUMBER := -45178; -- NOT_OAMADMIN EXCEPTION; PRAGMA EXCEPTION_INIT ( NOT_OAMADMIN, -45182 ); NOT_OAMADMIN_NUM CONSTANT NUMBER := -45182; -- API_BLOCKED_NUM CONSTANT NUMBER := -45183; -- NOT_RA EXCEPTION; PRAGMA EXCEPTION_INIT ( NOT_RA, -45198 ); NOT_RA_NUM CONSTANT NUMBER := -45198; -- USER_NOT_EXISTS EXCEPTION; PRAGMA EXCEPTION_INIT ( USER_NOT_EXISTS, -45213 ); USER_NOT_EXISTS_NUM CONSTANT NUMBER := -45213; -- NUM_CONVERSION_ERROR EXCEPTION; PRAGMA EXCEPTION_INIT ( NUM_CONVERSION_ERROR, -45214 ); NUM_CONVERSION_ERROR_NUM CONSTANT NUMBER := -45214; -- REP_SERVER_ACTIVE EXCEPTION; PRAGMA EXCEPTION_INIT ( REP_SERVER_ACTIVE, -45215 ); REP_SERVER_ACTIVE_NUM CONSTANT NUMBER := -45215; -- SBT_TASK_NOT_FOUND EXCEPTION; PRAGMA EXCEPTION_INIT ( SBT_TASK_NOT_FOUND, -45217 ); SBT_TASK_NOT_FOUND_NUM CONSTANT NUMBER := -45217; -- CREATE_CONTAINER_FAILED EXCEPTION; PRAGMA EXCEPTION_INIT ( CREATE_CONTAINER_FAILED, -45276 ); CREATE_CONTAINER_FAILED_NUM CONSTANT NUMBER := -45276; -- UNBAL_PAREN EXCEPTION; PRAGMA EXCEPTION_INIT ( UNBAL_PAREN, -64704 ); UNBAL_PAREN_NUM CONSTANT NUMBER := -64704; -- NO_DEST EXCEPTION; PRAGMA EXCEPTION_INIT ( NO_DEST, -64705 ); NO_DEST_NUM CONSTANT NUMBER := -64705; -- BAD_STORAGE_SIZE EXCEPTION; PRAGMA EXCEPTION_INIT ( BAD_STORAGE_SIZE, -64706 ); BAD_STORAGE_SIZE_NUM CONSTANT NUMBER := -64706; -- NO_STORAGE_SIZE EXCEPTION; PRAGMA EXCEPTION_INIT ( NO_STORAGE_SIZE, -64707 ); NO_STORAGE_SIZE_NUM CONSTANT NUMBER := -64707; -- MULTIPLE_POLLING EXCEPTION; PRAGMA EXCEPTION_INIT ( MULTIPLE_POLLING, -64708 ); MULTIPLE_POLLING_NUM CONSTANT NUMBER := -64708; -- ASM_POLLING EXCEPTION; PRAGMA EXCEPTION_INIT ( ASM_POLLING, -64709 ); ASM_POLLING_NUM CONSTANT NUMBER := -64709; -- -- POLLING_SIZE EXCEPTION; PRAGMA EXCEPTION_INIT ( POLLING_SIZE, -64710 ); POLLING_SIZE_NUM CONSTANT NUMBER := -64710; -- MIXED_STORAGE_TYPES EXCEPTION; PRAGMA EXCEPTION_INIT ( MIXED_STORAGE_TYPES, -64711 ); MIXED_STORAGE_TYPES_NUM CONSTANT NUMBER := -64711; -- MULTIPLE_NON_ASM EXCEPTION; PRAGMA EXCEPTION_INIT ( MULTIPLE_NON_ASM, -64712 ); MULTIPLE_NON_ASM_NUM CONSTANT NUMBER := -64712; -- DEST_SIZE_TOO_SMALL EXCEPTION; PRAGMA EXCEPTION_INIT ( DEST_SIZE_TOO_SMALL, -64713 ); DEST_SIZE_TOO_SMALL_NUM CONSTANT NUMBER := -64713; -- DEST_SIZE_TOO_BIG EXCEPTION; PRAGMA EXCEPTION_INIT ( DEST_SIZE_TOO_BIG, -64714 ); DEST_SIZE_TOO_BIG_NUM CONSTANT NUMBER := -64714; -- REDUNDANCY_TYPE_BAD EXCEPTION; PRAGMA EXCEPTION_INIT ( REDUNDANCY_TYPE_BAD, -64715 ); REDUNDANCY_TYPE_BAD_NUM CONSTANT NUMBER := -64715; -- -- ALLOC_SIZE_DISCREPANCY EXCEPTION; PRAGMA EXCEPTION_INIT ( ALLOC_SIZE_DISCREPANCY, -64716 ); ALLOC_SIZE_DISCREPANCY_NUM CONSTANT NUMBER := -64716; -- -- NETCS_SIZE_DISCREPANCY EXCEPTION; PRAGMA EXCEPTION_INIT ( NETCS_SIZE_DISCREPANCY, -64717 ); NETCS_SIZE_DISCREPANCY_NUM CONSTANT NUMBER := -64717; -- ALLOC_SIZE_NOT_PWR_OF_2 EXCEPTION; PRAGMA EXCEPTION_INIT ( ALLOC_SIZE_NOT_PWR_OF_2, -64718 ); ALLOC_SIZE_NOT_PWR_OF_2_NUM CONSTANT NUMBER := -64718; -- ALLOC_SIZE_TOO_SMALL EXCEPTION; PRAGMA EXCEPTION_INIT ( ALLOC_SIZE_TOO_SMALL, -64719 ); ALLOC_SIZE_TOO_SMALL_NUM CONSTANT NUMBER := -64719; -- CREATED_NO_CONTAINERS EXCEPTION; PRAGMA EXCEPTION_INIT ( CREATED_NO_CONTAINERS, -64720 ); CREATED_NO_CONTAINERS_NUM CONSTANT NUMBER := -64720; -- RSRVD_SPACE_TOO_SMALL EXCEPTION; PRAGMA EXCEPTION_INIT ( RSRVD_SPACE_TOO_SMALL, -64721 ); RSRVD_SPACE_TOO_SMALL_NUM CONSTANT NUMBER := -64721; -- NUM_DRIVES_TOO_SMALL EXCEPTION; PRAGMA EXCEPTION_INIT ( NUM_DRIVES_TOO_SMALL, -64722 ); NUM_DRIVES_TOO_SMALL_NUM CONSTANT NUMBER := -64722; -- NUM_RDRIVES_TOO_SMALL EXCEPTION; PRAGMA EXCEPTION_INIT ( NUM_RDRIVES_TOO_SMALL, -64723 ); NUM_RDRIVES_TOO_SMALL_NUM CONSTANT NUMBER := -64723; -- NUM_RDRIVES_TOO_LARGE EXCEPTION; PRAGMA EXCEPTION_INIT ( NUM_RDRIVES_TOO_LARGE, -64724 ); NUM_RDRIVES_TOO_LARGE_NUM CONSTANT NUMBER := -64724; -- NUM_STREAMS_TOO_SMALL EXCEPTION; PRAGMA EXCEPTION_INIT ( NUM_STREAMS_TOO_SMALL, -64725 ); NUM_STREAMS_TOO_SMALL_NUM CONSTANT NUMBER := -64725; -- NUM_STREAMS_TOO_LARGE EXCEPTION; PRAGMA EXCEPTION_INIT ( NUM_STREAMS_TOO_LARGE, -64726 ); NUM_STREAMS_TOO_LARGE_NUM CONSTANT NUMBER := -64726; -- BAD_NUM_COPIES EXCEPTION; PRAGMA EXCEPTION_INIT ( BAD_NUM_COPIES, -64727 ); BAD_NUM_COPIES_NUM CONSTANT NUMBER := -64727; -- REP_SRVR_NM_BAD_LEN EXCEPTION; PRAGMA EXCEPTION_INIT ( REP_SRVR_NM_BAD_LEN, -64728 ); REP_SRVR_NM_BAD_LEN_NUM CONSTANT NUMBER := -64728; -- REP_SRVR_BAD_PORT EXCEPTION; PRAGMA EXCEPTION_INIT ( REP_SRVR_BAD_PORT, -64729 ); REP_SRVR_BAD_PORT_NUM CONSTANT NUMBER := -64729; -- REP_SRVR_PORT_NULL EXCEPTION; PRAGMA EXCEPTION_INIT ( REP_SRVR_PORT_NULL, -64730 ); REP_SRVR_PORT_NULL_NUM CONSTANT NUMBER := -64730; -- REP_SRVR_PROXY_NULL EXCEPTION; PRAGMA EXCEPTION_INIT ( REP_SRVR_PROXY_NULL, -64731 ); REP_SRVR_PROXY_NULL_NUM CONSTANT NUMBER := -64731; -- REP_SRVR_HOST_NOT_CONFIG EXCEPTION; PRAGMA EXCEPTION_INIT ( REP_SRVR_HOST_NOT_CONFIG, -64732 ); REP_SRVR_HOST_NOT_CONFIG_NUM CONSTANT NUMBER := -64732; -- COPY_MOVE_NOT_KEEP EXCEPTION; PRAGMA EXCEPTION_INIT ( COPY_MOVE_NOT_KEEP, -64733 ); COPY_MOVE_NOT_KEEP_NUM CONSTANT NUMBER := -64733; -- SMALL_CG_FILE_SIZE EXCEPTION; PRAGMA EXCEPTION_INIT ( SMALL_CG_FILE_SIZE, -64734 ); SMALL_CG_FILE_SIZE_NUM CONSTANT NUMBER := -64734; -- CANT_DELETE_DB_RUNNING EXCEPTION; PRAGMA EXCEPTION_INIT ( CANT_DELETE_DB_RUNNING, -64742 ); CANT_DELETE_DB_RUNNING_NUM CONSTANT NUMBER := -64742; -- REP_SETUP_ERROR EXCEPTION; PRAGMA EXCEPTION_INIT ( REP_SETUP_ERROR, -64751 ); REP_SETUP_ERROR_NUM CONSTANT NUMBER := -64751; -- API_BAD_OBJECT EXCEPTION; PRAGMA EXCEPTION_INIT ( API_BAD_OBJECT, -64753 ); API_BAD_OBJECT_NUM CONSTANT NUMBER := -64753; -- SL_REP_SBT_CONFLICT_ERROR EXCEPTION; PRAGMA EXCEPTION_INIT ( SL_REP_SBT_CONFLICT_ERROR, -64754 ); SL_REP_SBT_CONFLICT_ERROR_NUM CONSTANT NUMBER := -64754; -- CANT_DELETE_DB_DOWN EXCEPTION; PRAGMA EXCEPTION_INIT ( CANT_DELETE_DB_DOWN, -64755 ); CANT_DELETE_DB_DOWN_NUM CONSTANT NUMBER := -64755; -- DISKGROUP_NOT_USABLE_NUM CONSTANT NUMBER := -64761; -- -- -- LOCKAPI_CREATE CONSTANT NUMBER := 1; LOCKAPI_READ CONSTANT NUMBER := 2; LOCKAPI_MODIFY CONSTANT NUMBER := 3; LOCKAPI_DELETE CONSTANT NUMBER := 4; END dbms_ra; >>> define dbmsrsdmp_plb <<< CREATE OR REPLACE PACKAGE dbms_ra_dump IS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE dumper (ospid IN VARCHAR2, quiesce IN BOOLEAN DEFAULT FALSE, datapumpdump IN BOOLEAN DEFAULT TRUE); END dbms_ra_dump; >>> define dbmsrspl_plb <<< CREATE OR REPLACE PACKAGE dbms_ra_pool AS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- /*-------------------* * Package Constants * *-------------------*/ -- -- AM_DEBUG_ON CONSTANT NUMBER := 1; -- Always on, for exeptions only AM_DEBUG_LOW CONSTANT NUMBER := 2; -- Odd and rare conditions AM_DEBUG_MED CONSTANT NUMBER := 3; -- Common, but not too wordy AM_DEBUG_HIGH CONSTANT NUMBER := 4; -- Everything worth showing. AM_DEBUG_OFF CONSTANT NUMBER := 5; -- Debug off -- KBRSOPER_CLSPOST CONSTANT NUMBER := 1; -- Post read, close file KBRSOPER_POST CONSTANT NUMBER := 2; -- Post a read KBRSOPER_RELEASE CONSTANT NUMBER := 3; -- Just release (only used in C) KBRSOPER_COPY CONSTANT NUMBER := 4; -- Copy some blocks -- KBRSOPER_DEL CONSTANT NUMBER := 5; -- Needed for delete plans -- KBRSOPER_NEWFILE CONSTANT NUMBER := 6; -- New file, relative# and file# KBRSOPER_NEXT CONSTANT NUMBER := 7; -- Get Next part of restore plan KBRSOPER_DONE CONSTANT NUMBER := 8; -- All restore plan parts done -- KBRSPLBLD_PIECE CONSTANT NUMBER := 1; -- Fetch a backup piece KBRSPLBLD_PURGE CONSTANT NUMBER := 2; -- Fetch blocks for purging KBRSPLBLD_SMALLPURGE CONSTANT NUMBER := 3; -- Fetch from limitted chunks KBRSPLBLD_OPTPURGE CONSTANT NUMBER := 4; -- Fetch efficiently for purge KBRSPLBLD_ALLPURGE CONSTANT NUMBER := 5; -- Fetch nothing, delete df KBRSPLBLD_OPTIMIZE CONSTANT NUMBER := 6; -- Fetch non-contiguous blocks KBRSPLBLD_DUPPURGE CONSTANT NUMBER := 7; -- Fetch to remove old duplicates KBRSPLBLD_ORIGPIECE CONSTANT NUMBER := 8; -- Fetch an incr level 1 bp KBRSPLBLD_FULLPIECE CONSTANT NUMBER := 10; -- Mult-section support -- VBDF_COMPLETE CONSTANT NUMBER := 1; -- (Must be first) VBDF_BUILDING CONSTANT NUMBER := 2; -- Process_backup_piece working VBDF_ABORT CONSTANT NUMBER := 3; -- Purge forced abort of build VBDF_FIN_NOBP CONSTANT NUMBER := 4; -- File fin, but no bp rec VBDF_CLEANUP CONSTANT NUMBER := 5; -- Process_backup_piece cleanup VBDF_REPOPULATE CONSTANT NUMBER := 6; -- Populate_backup_piece VBDF_OBSOLETE CONSTANT NUMBER := 7; -- Essentially deleted (history) VBDF_REPAIR CONSTANT NUMBER := 8; -- Used in meta repair only stage -- -- BIGNUM CONSTANT NUMBER := 1E40; KSCNINV CONSTANT NUMBER := 281474976710655; -- CHUNK_NOT_SHARED CONSTANT NUMBER := 1; -- DBkey_inc owns not shared chunk CHUNK_OWNER CONSTANT NUMBER := 2; -- DBkey_inc owns shared chunk CHUNK_DEPENDENT CONSTANT NUMBER := 3; -- DBkey_inc shares does not own -- -- KBRS_SAVE_INFO_POOL CONSTANT NUMBER := 0; -- save name and chunk# for pool KBRS_SAVE_INFO_CFFILE CONSTANT NUMBER := 1; -- control file piece name info KBRS_SAVE_INFO_SPFILE CONSTANT NUMBER := 2; -- sp file piece name info -- -- type nolst is table of NUMBER index by binary_integer; type nmlst is table of VARCHAR2(30) index by binary_integer; -- PROCEDURE setDebug(p_level IN NUMBER, p_safemode IN NUMBER, p_outtype IN NUMBER DEFAULT sys.dbms_system.trace_file); -- FUNCTION incrLevel(p_create_scn IN NUMBER, -- bdf.create_scn p_incr_scn IN NUMBER) -- bdf.incr_scn RETURN NUMBER; PROCEDURE prep_piece_read( p_inbpkey IN NUMBER, p_loc OUT VARCHAR2, -- Storage location p_dbkey OUT NUMBER, p_db_id OUT NUMBER, p_dfkey OUT NUMBER, -- 0 if more than 1 df p_vbkey OUT NUMBER, p_blksize OUT NUMBER, p_original OUT NUMBER, -- 1 == Virtual copy p_read_bufs OUT NUMBER, p_read_size OUT NUMBER, p_read_waste OUT NUMBER); PROCEDURE prep_read( p_type IN NUMBER, /* KBRSPLBLD_% */ p_bskey IN NUMBER, /* optional */ p_vbkey IN NUMBER, p_dfkey IN NUMBER, p_blksize OUT NUMBER, p_read_bufs OUT NUMBER, p_read_size OUT NUMBER, p_read_waste OUT NUMBER); PROCEDURE dealloc_plan_bp(p_bskey NUMBER); PROCEDURE obsoletePlans(p_dfkey IN NUMBER, p_chk_krbph IN NUMBER DEFAULT 1, p_lock IN NUMBER DEFAULT 1); PROCEDURE build_read_plan( p_dbkey IN NUMBER, -- Database key p_vbkey IN NUMBER, -- Virtual backup id p_dfkey IN NUMBER, -- Datafile key p_bufsize IN NUMBER, -- size of read buffers p_type IN NUMBER, -- KBRSBLD_ type p_chunks IN NUMBER, -- Number of chunks to write. p_stored OUT NUMBER); -- Is 1 if plan was stored PROCEDURE ok4pool(p_dbkey IN NUMBER, p_bpkey IN NUMBER, p_update IN BOOLEAN, p_hasdups OUT BOOLEAN, p_nofityet OUT BOOLEAN, p_isok OUT BOOLEAN); PROCEDURE process_backup_piece(p_dbkey IN NUMBER, -- Database key p_bpkey IN NUMBER, -- BackupPiece key p_upd IN NUMBER DEFAULT 0, -- update op p_complete OUT BOOLEAN); PROCEDURE purgeDB(p_slkey IN NUMBER, -- Storage location p_dbkey IN NUMBER, -- Database key p_inline IN BOOLEAN DEFAULT FALSE); -- True when testing PROCEDURE validateDB(p_dbkey IN NUMBER); FUNCTION plannedSpace (p_slkey IN NUMBER, p_enable_dup IN NUMBER) RETURN NUMBER; FUNCTION plannedDBSpace(p_db_key IN NUMBER) -- Database key RETURN NUMBER; FUNCTION copied_to_tape(p_dbkey IN NUMBER) RETURN NUMBER; PROCEDURE optimizeDF(p_dbkey IN NUMBER, -- Database key p_dfkey IN NUMBER, -- Datafile key p_onlylost IN BOOLEAN DEFAULT FALSE); PROCEDURE purgeDupDF(p_dfkey IN NUMBER, -- Datafile key p_vbkey IN NUMBER, -- Virtual backup key p_bpkey IN NUMBER, -- (optional) bp_key for locking p_newplans IN BOOLEAN DEFAULT TRUE); -- Inhibit new plan PROCEDURE moveDF(p_dbkey IN NUMBER, -- Database key p_dfkey IN NUMBER); -- Datafile key PROCEDURE purgeDF(p_type IN NUMBER, -- Type of purge to perform p_dfkey IN NUMBER, -- Datafile key p_vbkey IN NUMBER); -- Oldest available vbkey PROCEDURE planDF(p_type IN NUMBER, -- Type of plan to build p_dfkey IN NUMBER, -- Datafile key p_vbkey IN NUMBER, -- Vbkey associated with the plan p_res IN NUMBER DEFAULT 0, -- Chunks to reserve p_locked IN BOOLEAN DEFAULT FALSE, -- Key lock already held p_must IN BOOLEAN DEFAULT FALSE, -- Guarenteed plan p_plock IN BOOLEAN DEFAULT FALSE);-- Purge lock already held PROCEDURE save_krbph(p_dfkey IN NUMBER, -- krbph df_key p_chunkno IN NUMBER, -- krbph chunk number p_name IN VARCHAR2, -- krbph chunk name p_splittype IN NUMBER ); -- splitting for block pool, -- -- -- -- PROCEDURE begin_df( p_vbkey IN OUT NUMBER, -- Virtual backup ID p_ckpid IN OUT NUMBER, -- ckp_scn --> ckp_id p_dbid IN NUMBER, -- Database ID p_fno IN NUMBER, -- Datafile number p_blocks IN NUMBER, -- (opt) Datafile size in blocks p_incrscn IN NUMBER, -- (opt) Incr_scn for backup p_crescn IN NUMBER, -- (opt) Datafile creation scn p_crestamp IN NUMBER, -- (opt) Datafile creation time p_rstscn IN NUMBER, -- (opt) reset scn p_rststamp IN NUMBER, -- (opt) reset stamp p_dfkey OUT NUMBER, -- Datafile key p_dbkey OUT NUMBER, -- Database key p_dbinckey OUT NUMBER, -- Database incarnation key p_unorderid OUT NUMBER, -- (opt) max(unorder_id) p_firstblk IN NUMBER, -- First block p_lastblk IN NUMBER); -- Last block PROCEDURE end_df( p_vbkey IN NUMBER, -- Virtual backup ID p_dfkey IN NUMBER, -- Datafile key p_relfno IN NUMBER, -- Backupset relative file num p_ckpscn IN NUMBER, -- Checkpoint scn p_absscn IN NUMBER, -- Absolute fuzzy scn p_repair IN BOOLEAN, -- True if repair in progress p_cmpvsn IN NUMBER, -- backup version# p_issft IN NUMBER, -- IS Single File Tablespace p_unorder IN NUMBER, -- 1 if gap block found p_replev IN NUMBER DEFAULT NULL); -- Repair incr level PROCEDURE repair_df(p_vbkey IN OUT NUMBER, -- Virtual backup ID p_newvb IN OUT NUMBER, -- NULL, 1 begin_df, 0 repair p_dbid IN NUMBER, -- Database ID p_fno IN NUMBER, -- Datafile number p_blocks IN NUMBER, -- Datafile size in blocks p_relfno IN NUMBER, -- Backupset relative fileno p_crescn IN NUMBER, -- Datafile creation scn p_crestamp IN NUMBER, -- Datafile creation time p_rstscn IN NUMBER, -- reset scn p_rststamp IN NUMBER, -- reset stamp p_startscn IN NUMBER, -- Incremental start scn p_ckpscn IN NUMBER, -- Checkpoint scn p_cmpvsn IN NUMBER, -- backup version# p_issft IN NUMBER, -- Single File Tablespace p_firstblk IN NUMBER, -- First block p_lastblk IN NUMBER, -- Last Block p_replev IN NUMBER); -- iLevel if invalid incrscn -- PROCEDURE deleteVB(p_slkey IN NUMBER, p_dbkey IN NUMBER, p_currinc IN NUMBER, p_bpkey IN NUMBER, p_noplans IN BOOLEAN, p_notasks IN BOOLEAN); -- PROCEDURE repairChunks(p_dbkey IN NUMBER); -- -- -- TYPE collapse_bin_t IS RECORD ( blockno NUMBER , scn NUMBER , chunkno NUMBER , used NUMBER , coffset NUMBER ); -- TYPE collapse_blocks_c IS REF CURSOR RETURN collapse_bin_t; -- TYPE collapse_b_t IS RECORD ( blockno NUMBER -- min , chunkno NUMBER , numblks NUMBER -- count , coffset NUMBER -- min , numbytes NUMBER -- sum(used) , signature NUMBER -- sum(scn) ); -- TYPE collapse_blocks_t IS TABLE OF collapse_b_t; /* The function accepts a cursor i_cur and attempts to collapse conjuncted set of blocks within a chunk. The idea here is to return the range of blocks back to the caller, so a corresponding post for read can be done. */ FUNCTION collapse ( i_cur IN collapse_blocks_c ) RETURN collapse_blocks_t PIPELINED; -- -- -- TYPE skip_last_bin_t IS RECORD ( blockno NUMBER , ckp_id NUMBER , scn NUMBER , chunkno NUMBER , used NUMBER , coffset NUMBER ); -- TYPE skip_last_blocks_c IS REF CURSOR RETURN skip_last_bin_t; -- -- TYPE skip_last_blocks_t IS TABLE OF skip_last_bin_t; /* The function accepts a cursor i_cur and removes the top most record from the result set, that's done according to the ORDER BY specification. The function is named skip_last because the eventual goal is to make blocks_u index having keys stored in the ascending order. */ FUNCTION skip_last ( i_cur IN skip_last_blocks_c ) RETURN skip_last_blocks_t PIPELINED; END dbms_ra_pool; >>> define setup_tasktypenames <<< begin insert into tasktypenames values(dbms_ra_scheduler.task_quiesce_rs, 'QUIESCE'); insert into tasktypenames values(dbms_ra_scheduler.task_spawn_sbt, 'SPAWN_SBT'); insert into tasktypenames values(dbms_ra_scheduler.task_purge_df_now, 'PURGE_DF_NOW'); insert into tasktypenames values(dbms_ra_scheduler.task_restore, 'RESTORE'); insert into tasktypenames values(dbms_ra_scheduler.task_storage_histogram, 'HISTOGRAM'); insert into tasktypenames values(dbms_ra_scheduler.task_gcopy_compute, 'GCOPY_COMPUTE'); insert into tasktypenames values(dbms_ra_scheduler.task_purge_dup_df, 'PURGE_DUP'); insert into tasktypenames values(dbms_ra_scheduler.task_deferred_delete, 'DEFERRED_DEL'); insert into tasktypenames values(dbms_ra_scheduler.task_purge_immediate, 'PURGE_IMM'); insert into tasktypenames values(dbms_ra_scheduler.task_purge_df, 'PURGE_DF'); insert into tasktypenames values(dbms_ra_scheduler.task_delete_db, 'DELETE_DB'); insert into tasktypenames values(dbms_ra_scheduler.task_trim_db, 'TRIM_DB'); insert into tasktypenames values(dbms_ra_scheduler.task_purge, 'PURGE'); insert into tasktypenames values(dbms_ra_scheduler.task_backup_arch, 'BACKUP_ARCH'); insert into tasktypenames values(dbms_ra_scheduler.task_inc_arch, 'INCOMPLETE_ARCH'); insert into tasktypenames values(dbms_ra_scheduler.task_plan_sbt, 'PLAN_SBT'); insert into tasktypenames values(dbms_ra_scheduler.task_index_backup, 'INDEX_BACKUP'); insert into tasktypenames values(dbms_ra_scheduler.task_plan_df, 'PLAN_DF'); insert into tasktypenames values(dbms_ra_scheduler.task_newdfkey, 'NEW_DFKEY'); insert into tasktypenames values(dbms_ra_scheduler.task_move_df, 'MOVE_DF'); insert into tasktypenames values(dbms_ra_scheduler.task_move_all_db, 'MOVE_ALL_DB'); insert into tasktypenames values(dbms_ra_scheduler.task_poll, 'POLL'); insert into tasktypenames values(dbms_ra_scheduler.task_restore_sbt, 'RESTORE_SBT'); insert into tasktypenames values(dbms_ra_scheduler.task_backup_sbt, 'BACKUP_SBT'); insert into tasktypenames values(dbms_ra_scheduler.task_insert_fault, 'INSERT_FAULT'); insert into tasktypenames values(dbms_ra_scheduler.task_purge_sbt, 'PURGE_SBT'); insert into tasktypenames values(dbms_ra_scheduler.task_obsolete_sbt, 'OBSOLETE_SBT'); insert into tasktypenames values(dbms_ra_scheduler.task_rm_incomplete_files,'RM_INC_FILES'); insert into tasktypenames values(dbms_ra_scheduler.task_reconcile, 'RECONCILE'); insert into tasktypenames values(dbms_ra_scheduler.task_repair_db, 'REPAIR_DB'); insert into tasktypenames values(dbms_ra_scheduler.task_db_stats_refresh, 'DB_STATS_REFRESH'); insert into tasktypenames values(dbms_ra_scheduler.task_restore_range_refresh, 'RESTORE_RANGE_REFRESH'); insert into tasktypenames values(dbms_ra_scheduler.task_optimize_chunks_df,'OPT_DF'); insert into tasktypenames values(dbms_ra_scheduler.task_optimize_chunks, 'OPTIMIZE'); insert into tasktypenames values(dbms_ra_scheduler.task_rebuild_index, 'REBUILD_INDEX'); insert into tasktypenames values(dbms_ra_scheduler.task_validate_db, 'VALIDATE'); insert into tasktypenames values(dbms_ra_scheduler.task_check_files, 'CHECK_FILES'); insert into tasktypenames values(dbms_ra_scheduler.task_crosscheck_db, 'CROSSCHECK_DB'); insert into tasktypenames values(dbms_ra_scheduler.task_session_times, 'SESSION_TIMES'); insert into tasktypenames values(dbms_ra_scheduler.task_error_info, 'ERROR_INFO'); insert into tasktypenames values(dbms_ra_scheduler.task_test_dummy, 'TEST_DUMMY'); insert into tasktypenames values(dbms_ra_scheduler.task_api_add_db, 'API_ADD_DB'); insert into tasktypenames values(dbms_ra_scheduler.task_api_upd_db, 'API_UPD_DB'); insert into tasktypenames values(dbms_ra_scheduler.task_api_del_db, 'API_DEL_DB'); insert into tasktypenames values(dbms_ra_scheduler.task_api_ren_db, 'API_REN_DB'); insert into tasktypenames values(dbms_ra_scheduler.task_api_grant_db, 'API_GRANT_DB'); insert into tasktypenames values(dbms_ra_scheduler.task_api_revoke_db, 'API_REVOKE_DB'); insert into tasktypenames values(dbms_ra_scheduler.task_api_add_sl, 'API_ADD_SL'); insert into tasktypenames values(dbms_ra_scheduler.task_api_upd_sl, 'API_UPD_SL'); insert into tasktypenames values(dbms_ra_scheduler.task_api_del_sl, 'API_DEL_SL'); insert into tasktypenames values(dbms_ra_scheduler.task_api_add_prot_policy, 'API_ADD_PROT_POLICY'); insert into tasktypenames values(dbms_ra_scheduler.task_api_upd_prot_policy, 'API_UPD_PROT_POLICY'); insert into tasktypenames values(dbms_ra_scheduler.task_api_del_prot_policy, 'API_DEL_PROT_POLICY'); insert into tasktypenames values(dbms_ra_scheduler.task_api_add_poll_policy, 'API_ADD_POLL_POLICY'); insert into tasktypenames values(dbms_ra_scheduler.task_api_upd_poll_policy, 'API_UPD_POLL_POLICY'); insert into tasktypenames values(dbms_ra_scheduler.task_api_del_poll_policy, 'API_DEL_POLL_POLICY'); insert into tasktypenames values(dbms_ra_scheduler.task_api_add_sbt_lib, 'API_ADD_SBT_LIB'); insert into tasktypenames values(dbms_ra_scheduler.task_api_upd_sbt_lib, 'API_UPD_SBT_LIB'); insert into tasktypenames values(dbms_ra_scheduler.task_api_del_sbt_lib, 'API_DEL_SBT_LIB'); insert into tasktypenames values(dbms_ra_scheduler.task_api_add_restrict_sbt_inst, 'API_ADD_RESTRICT_SBT_INST'); insert into tasktypenames values(dbms_ra_scheduler.task_api_del_restrict_sbt_inst, 'API_DEL_RESTRICT_SBT_INST'); insert into tasktypenames values(dbms_ra_scheduler.task_api_add_sbt_attr_set, 'API_ADD_SBT_ATTR_SET'); insert into tasktypenames values(dbms_ra_scheduler.task_api_upd_sbt_attr_set, 'API_UPD_SBT_ATTR_SET'); insert into tasktypenames values(dbms_ra_scheduler.task_api_del_sbt_attr_set, 'API_DEL_SBT_ATTR_SET'); insert into tasktypenames values(dbms_ra_scheduler.task_api_add_sbt_job, 'API_ADD_SBT_JOB'); insert into tasktypenames values(dbms_ra_scheduler.task_api_upd_sbt_job, 'API_UPD_SBT_JOB'); insert into tasktypenames values(dbms_ra_scheduler.task_api_del_sbt_job, 'API_DEL_SBT_JOB'); insert into tasktypenames values(dbms_ra_scheduler.task_api_pau_sbt_lib, 'API_PAU_SBT_LIB'); insert into tasktypenames values(dbms_ra_scheduler.task_api_res_sbt_lib, 'API_RES_SBT_LIB'); insert into tasktypenames values(dbms_ra_scheduler.task_api_add_repository, 'API_ADD_REPOSITORY'); insert into tasktypenames values(dbms_ra_scheduler.task_api_del_repository, 'API_DEL_REPOSITORY'); insert into tasktypenames values(dbms_ra_scheduler.task_api_add_rep_server, 'API_ADD_REP_SERVER'); insert into tasktypenames values(dbms_ra_scheduler.task_api_rem_rep_server, 'API_REM_REP_SERVER'); insert into tasktypenames values(dbms_ra_scheduler.task_api_startup, 'API_STARTUP'); insert into tasktypenames values(dbms_ra_scheduler.task_api_shutdown, 'API_SHUTDOWN'); insert into tasktypenames values(dbms_ra_scheduler.task_api_abort, 'API_ABORT'); insert into tasktypenames values(dbms_ra_scheduler.task_api_config, 'API_CONFIG'); insert into tasktypenames values(dbms_ra_scheduler.task_api_populate, 'API_POPULATE'); insert into tasktypenames values(dbms_ra_scheduler.task_api_move_backup, 'API_MOVE_BACKUP'); insert into tasktypenames values(dbms_ra_scheduler.task_api_copy_backup, 'API_COPY_BACKUP'); insert into tasktypenames values(dbms_ra_scheduler.task_api_move_backup_piece,'API_MOVE_BACKUP_PIECE'); insert into tasktypenames values(dbms_ra_scheduler.task_api_copy_backup_piece,'API_COPY_BACKUP_PIECE'); insert into tasktypenames values(dbms_ra_scheduler.task_api_replicate_existing, 'API_REPLICATE_EXISTING'); insert into tasktypenames values(dbms_ra_scheduler.task_api_replication_reconcile, 'API_REPLICATION_RECONCILE'); insert into tasktypenames values(dbms_ra_scheduler.task_api_replicate_one_piece, 'API_REPLICATE_ONE_PIECE'); insert into tasktypenames values(dbms_ra_scheduler.task_api_migrate_tape, 'API_MIGRATE_TAPE_BACKUP'); insert into tasktypenames values(dbms_ra_scheduler.task_api_pau_rep_srv, 'API_PAUSE_REPLICATION'); insert into tasktypenames values(dbms_ra_scheduler.task_api_res_rep_srv, 'API_RESUME_REPLICATION'); insert into tasktypenames values(dbms_ra_scheduler.task_api_repair_sl, 'API_REPAIR_SL'); insert into tasktypenames values(dbms_ra_scheduler.task_api_testtask, 'API_TESTTASK'); insert into tasktypenames values(dbms_ra_scheduler.task_api_cre_rep_server, 'API_CREATE_REP_SERVER'); insert into tasktypenames values(dbms_ra_scheduler.task_api_upd_rep_server, 'API_UPDATE_REP_SERVER'); insert into tasktypenames values(dbms_ra_scheduler.task_api_del_rep_server, 'API_DELETE_REP_SERVER'); commit; end; >>> define delete_old_tasktypenames_entries <<< begin DELETE FROM tasktypenames WHERE task_type_name = 'RESERVE_SBT'; -- FOR t IN (SELECT task_id FROM task WHERE task_type = dbms_ra_scheduler.TASK_RESERVE_SBT) LOOP DELETE FROM sbt_job_template jt WHERE jt.template_key IN ( SELECT st.template_key FROM sbt_task st WHERE st.task_id = t.task_id ); DELETE FROM sbt_task WHERE task_id = t.task_id; DELETE FROM task WHERE task_id = t.task_id; END LOOP; commit; end; >>> define create_taskdata_obj <<< CREATE OR REPLACE TYPE taskdata AS OBJECT ( task_state VARCHAR2(32) , task_id VARCHAR2(20) , db_uname VARCHAR2(32) , exe_time VARCHAR2(8) , task_type VARCHAR2(30) , task_param VARCHAR2(32) , client_id VARCHAR2(64) , module VARCHAR2(64) , action VARCHAR2(64) ) >>> define create_taskdata_type <<< CREATE OR REPLACE TYPE taskinfo AS TABLE OF taskdata >>> define create_taskdata_func <<< CREATE OR REPLACE FUNCTION taskdata_func RETURN taskinfo PIPELINED AS CURSOR tasklist IS SELECT t.task_id , t.db_key , t.sl_key , task_type , TO_CHAR(t.last_execute_time, 'HH24:MI:SS') EXE_TIME , (CASE WHEN t.state = dbms_ra_scheduler.STATE_TASK_WAIT THEN 'WAIT ON ' || PENDING_INTERRUPT ELSE NULL END) pending , dbms_ra_scheduler.taskstate2name( NVL(t.state, dbms_ra_scheduler.STATE_RUNNING), t.pending_interrupt) task_state , NVL2(task_type, tasktypenames.task_type_name, v.client_identifier) taskt , t.state , t.param_num1 , t.param_num2 , v.client_identifier client_id , v.module , v.action FROM task t FULL OUTER JOIN (SELECT client_identifier, module, action, to_number(decode(substr(client_identifier, 1, 4), 'RA$T', substr(client_identifier, 5, 60), NULL)) task_id FROM sys.gv_$session s WHERE (client_identifier LIKE 'RA$S%' OR client_identifier LIKE 'RA$T%')) v ON t.task_id = v.task_id JOIN tasktypenames USING (task_type) WHERE t.task_id IS NOT NULL OR v.module IS NOT NULL ORDER BY DECODE(t.state, -- most interesting stuff should be last dbms_ra_scheduler.STATE_RUNNING, 100, dbms_ra_scheduler.STATE_CANCELING, 99, dbms_ra_scheduler.STATE_CANCEL, 98, NULL, 90, t.state) , t.task_id , v.module; ids1 NUMBER; ids2 NUMBER; fail NUMBER; check_failures NUMBER; l_last_seen DATE; l_component VARCHAR2(14); l_error_text VARCHAR2(100); l_param1 VARCHAR2(100); l_param2 VARCHAR2(100); l_temp VARCHAR2(100); BEGIN -- SELECT COUNT(*) INTO fail FROM config WHERE name = '_recovery_server_state' AND value = 'OFF'; -- SELECT COUNT(*) INTO check_failures FROM config WHERE name = '_debug_flags' AND BITAND(value, 33554432) > 0; /* kbrs2.h KBRSTRC_STALL */ -- PIPE ROW(taskdata(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); PIPE ROW(taskdata('To use:', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); PIPE ROW(taskdata('SET PAGES 10000', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); PIPE ROW(taskdata('SET ARRAYSIZE 1', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); PIPE ROW(taskdata(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); FOR i IN 1 .. 10 LOOP PIPE ROW(taskdata(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); END LOOP; -- WHILE fail = 0 LOOP -- PIPE ROW(taskdata('TASK_STATE', 'TASK_ID', 'DB_UNAME', 'EXE_TIME', 'TYPE_OF_TASK', 'TASK_PARAM', 'CLIENT_ID', 'MODULE', 'ACTION')); PIPE ROW(taskdata('----------', '-------', '--------', '--------', '------------', '----------', '---------', '------', '------')); -- FOR t IN tasklist LOOP l_param1 := NULL; l_param2 := NULL; CASE WHEN t.task_type = dbms_ra_scheduler.TASK_INDEX_BACKUP THEN SELECT MAX(tag) INTO l_param1 FROM bp WHERE bp_key = t.param_num1; WHEN t.task_type = dbms_ra_scheduler.TASK_RESTORE OR t.task_type = dbms_ra_scheduler.TASK_RESTORE_SBT THEN SELECT substr(tag,1,18) INTO l_temp FROM bp WHERE bp_key = t.param_num2; SELECT MAX(file#) || ' ' || l_temp INTO l_param1 FROM bdf WHERE bs_key = (SELECT bs_key FROM bp WHERE bp_key = t.param_num2); WHEN t.task_type = dbms_ra_scheduler.TASK_PURGE_IMMEDIATE OR t.task_type = dbms_ra_scheduler.TASK_PURGE THEN IF t.db_key IS NOT NULL THEN l_param1 := 'db: ' || t.db_key; SELECT 'spc: ' || TO_CHAR(used_space/1024/1024) || 'M' INTO l_param2 FROM odb WHERE odb.db_key = t.db_key; ELSE l_param1 := 'sl: ' || t.sl_key; END IF; WHEN t.task_type = dbms_ra_scheduler.TASK_PURGE_DF THEN l_param1 := 'dfkey: ' || t.param_num1; SELECT 'spc: ' || TO_CHAR(used_space/1024/1024) || 'M' INTO l_param2 FROM odb WHERE odb.db_key = t.db_key; ELSE l_param1 := NULL; END CASE; -- PIPE ROW(taskdata( substr(t.task_state,1,32) , substr(t.task_id,1,20) , dbms_ra_int.dbkey2name(t.db_key) , t.exe_time , t.taskt , substr(l_param1,1,32) , t.client_id , t.module , t.action || t.pending )); -- IF l_param2 IS NOT NULL THEN PIPE ROW(taskdata( substr(t.task_state,1,32) , NULL , dbms_ra_int.dbkey2name(t.db_key) , NULL , NULL , NULL , NULL , NULL , substr(l_param2,1,32) )); END IF; END LOOP; -- PIPE ROW(taskdata(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); PIPE ROW(taskdata(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); PIPE ROW(taskdata(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); -- ids1 := NULL; WHILE (ids1 IS NULL OR ids1 = ids2) AND fail = 0 LOOP dbms_lock.sleep(1); -- SELECT NVL(COUNT(*) + SUM(module_hash) /* + SUM(action_hash) */, 0) INTO ids2 FROM sys.gv_$session WHERE (client_identifier LIKE 'RA$S%' OR client_identifier LIKE 'RA$T%'); -- SELECT nvl(sum(task_id) + sum(state), 0) + ids2 INTO ids2 FROM task; -- IF ids1 IS NULL THEN ids1 := ids2; END IF; -- IF check_failures > 0 AND ids1 = ids2 THEN SELECT count(*) INTO fail FROM error_log WHERE severity >= dbms_ra_scheduler.SEVERITY_ERROR AND status = 'ACTIVE' AND ROWNUM = 1; END IF; -- IF fail = 0 THEN SELECT COUNT(*) INTO fail FROM config WHERE name = '_recovery_appliance_state' AND VALUE = 'OFF'; END IF; END LOOP; END LOOP; -- IF fail > 0 THEN SELECT last_seen, substr(component, 1, 20), substr(error_text, 1, 64) INTO l_last_seen, l_component, l_error_text FROM error_log WHERE severity >= dbms_ra_scheduler.SEVERITY_ERROR AND status = 'ACTIVE' AND ROWNUM = 1; PIPE ROW(taskdata('Error:', NULL, NULL, to_char(l_last_seen, 'HH24:MI:SS'), l_component, NULL, l_error_text, l_error_text, l_error_text)); PIPE ROW(taskdata(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); END IF; RETURN; END taskdata_func; >>> define create_taskdata_view <<< CREATE OR REPLACE VIEW rai_dynamic_tasks AS SELECT * FROM TABLE(taskdata_func) t >>> define drop_taskdata_obj <<< DROP TYPE taskdata >>> define drop_taskdata_type <<< DROP TYPE taskinfo >>> define drop_taskdata_func <<< DROP FUNCTION taskdata_func >>> define drop_taskdata_view <<< DROP VIEW rai_dynamic_tasks >>> define create_active_session_view <<< create or replace view ra_active_session (inst_id, instance_name, host_name, sid, serial#, spid, db_key, db_unique_name, sbt_sid, client_identifier, module, action, sql_id, event, p1, p2, p3, wait_time, seconds_in_wait, state, task_id, task_type, priority, task_state, job_name) as with se as (select /*+PARAM('_module_action_old_length',0)*/ s.*, to_number(decode(substr(client_identifier, 1, 4), 'RA$T', substr(client_identifier, 5, 60), NULL)) task_id from gv$session s where s.client_identifier like 'RA$%') select /*+ LEADING(se proc sbt i) USE_HASH(proc sbt i) PUSH_PRED(t.t) */ i.inst_id, i.instance_name, i.host_name, se.sid, se.serial#, proc.spid, coalesce(t.db_key, sbt.db_key), coalesce(t.db_unique_name, db.reg_db_unique_name), se.client_info, se.client_identifier, se.module, se.action, se.sql_id, se.event, se.p1, se.p2, se.p3, se.wait_time, se.seconds_in_wait, se.state, t.task_id, t.task_type, t.priority, t.state, usrj.job_name from gv$process proc, gv$instance i, se left outer join sbt_session sbt on se.client_info = sbt.session_id left outer join ra_task t on t.task_id = se.task_id and t.instance_id = se.inst_id and t.archived = 'N' left outer join user_scheduler_running_jobs usrj on se.inst_id = usrj.running_instance and se.sid = usrj.session_id left outer join db on db.db_key = sbt.db_key where proc.inst_id = se.inst_id and se.inst_id = i.inst_id and se.paddr = proc.addr >>> define create_comment_active_session <<< begin execute immediate 'comment on table ra_active_session is ' || '''This view lists information about active client sessions currently ' || 'running in the Recovery Appliance.'''; execute immediate 'comment on column ra_active_session.' || 'inst_id is ' || '''The Recovery Appliance instance number where this session is running.'''; execute immediate 'comment on column ra_active_session.' || 'instance_name is ' || '''The Recovery Appliance instance name where this session is running.'''; execute immediate 'comment on column ra_active_session.' || 'host_name is ' || '''The Recovery Appliance host name where this session is running.'''; execute immediate 'comment on column ra_active_session.' || 'sid is ' || '''The session ID for the active session.'''; execute immediate 'comment on column ra_active_session.' || 'serial# is ' || '''The session serial number, which uniquely identifies ' || 'the objects in a session.'''; execute immediate 'comment on column ra_active_session.' || 'spid is ' || '''The operating system process identifier.'''; execute immediate 'comment on column ra_active_session.' || 'db_key is ' || '''The primary key for this database in the recovery catalog.'''; execute immediate 'comment on column ra_active_session.' || 'db_unique_name is' || '''The unique database name.'''; execute immediate 'comment on column ra_active_session.' || 'sbt_sid is' || '''The SBT session identifier.'''; execute immediate 'comment on column ra_active_session.' || 'client_identifier is' || '''The client Identifier of the session.'''; execute immediate 'comment on column ra_active_session.' || 'module is' || '''The name of the module that is currently executing.'''; execute immediate 'comment on column ra_active_session.' || 'action is' || '''The name of the action that is currently executing.'''; execute immediate 'comment on column ra_active_session.' || 'sql_id is' || '''The SQL identifier of the SQL statement that is ' || 'currently being executed.'''; execute immediate 'comment on column ra_active_session.' || 'event is' || '''The resource or event for which the session is waiting.'''; execute immediate 'comment on column ra_active_session.' || 'p1 is' || '''First wait event parameter'''; execute immediate 'comment on column ra_active_session.' || 'p2 is' || '''The second wait event parameter.'''; execute immediate 'comment on column ra_active_session.' || 'p3 is' || '''The third wait event parameter.'''; execute immediate 'comment on column ra_active_session.' || 'wait_time is ' || '''The wait time in hundredths of a second. ' || 'See description of ' || 'V$SESSION.WAIT_TIME ' || 'for more information.'''; execute immediate 'comment on column ra_active_session.' || 'seconds_in_wait is ' || '''The wait time (in seconds). If the session is currently waiting, ' || 'then the value is the amount of time ' || 'waited for the current wait. If the session is not in a wait, then the ' || 'value is the amount of time since the start of the most recent wait.'''; execute immediate 'comment on column ra_active_session.' || 'state is' || '''The state of the wait event: ' || 'WAITING, ' || 'WAITED UNKNOWN TIME, ' || 'WAITED SHORT TIME, ' || 'WAITED KNOWN TIME. ' || 'See description of ' || 'V$SESSION.STATE ' || 'for more information.'''; execute immediate 'comment on column ra_active_session.' || 'task_id is ' || '''The task identifier.'''; execute immediate 'comment on column ra_active_session.' || 'task_type is ' || '''The task type.'''; execute immediate 'comment on column ra_active_session.' || 'priority is ' || '''The task priority.'''; execute immediate 'comment on column ra_active_session.' || 'task_state is ' || '''The processing state for the task: EXECUTABLE, ' || 'RUNNING, ' || 'COMPLETED, ' || 'TASK_WAIT, ' || 'FAILED, ' || 'and so on.'''; execute immediate 'comment on column ra_active_session.' || 'job_name is ' || '''The DBMS_SCHEDULER job name.'''; end; >>> define drop_active_session_view <<< drop view ra_active_session >>> define create_active_session_history_view <<< create or replace view rai_active_session_history (inst_id, instance_name, host_name, sid, serial#, db_key, db_unique_name, client_identifier, module, action, sql_id, event, p1, p2, p3, state, task_id, task_type, priority, task_state) as with se as (select s.*, to_number(decode(substr(client_id, 1, 4), 'RA$T', substr(client_id, 5, 60), NULL)) task_id from gv$active_session_history s where s.client_id like 'RA$%') select i.inst_id, i.instance_name, i.host_name, se.session_id, se.session_serial#, t.db_key, t.db_unique_name, se.client_id, se.module, se.action, se.sql_id, se.event, se.p1, se.p2, se.p3, se.session_state, se.task_id, t.task_type, t.priority, t.state from gv$instance i, se left outer join ra_task t on t.task_id = se.task_id and t.instance_id = se.inst_id where se.inst_id = i.inst_id >>> define drop_active_session_history_view <<< DROP VIEW rai_active_session_history >>> define create_scheduler_error_info <<< create or replace view rai_scheduler_error_info as select task_id task_error_id , pending_interrupt task_type , interrupt_count failing_task_id , error_count task_copy_id , param_num1 ra_sched_purpose , param_num2 ra_sched_purpose_param1 , savepoint dbms_scheduler_error# , param dbms_scheduler_additional_info , param_char1 dbms_scheduler_status , param_char2 tracefile , ba_session_id sid , execute_inst_id inst_id , schedule_time sched_start_time , execute_time task_start_time , completion_time error_time from task_history where task_type = 2000 /* TASK_SESSION_TIMES */ >>> define drop_scheduler_error_info <<< DROP VIEW rai_scheduler_error_info >>> define create_internal_purge_queue <<< create or replace view rai_purge_queue (sl_key, db_key, new_retention, overspace, newsecs, goalsecs, overretentionsecs) as /* Select 3 */ select sl_key, db_key, newint, overspace, newsecs, goalsecs, decode (sign (newsecs - goalsecs), 1, (newsecs - goalsecs) / decode(goalsecs, 0, .0001, goalsecs), 0) overretentionsecs from /* Select 2 */ (select sl_key, db_key, newint, newint - goalint overint, ((extract(second from (newint))) + (extract(minute from (newint)) * 60) + (extract(hour from (newint)) * 3600) + (extract(day from (newint)) * 86400)) newsecs, ((extract(second from (goalint))) + (extract(minute from (goalint)) * 60) + (extract(hour from (goalint)) * 3600) + (extract(day from (goalint)) * 86400)) goalsecs, overspace from /* Select 1 */ (select sl_key, db_key, nvl((systimestamp - bs2_timestamp), numtodsinterval(365, 'day')) newint, recovery_window_goal goalint, (total_allocation - reserved_space) / reserved_space overspace from odb where NVL(move_phase,0) NOT IN (2,3) /*MOVE_PHASE_START,MOVE_PHASE_POOL*/)) >>> define create_internal_sbt_performance <<< create or replace view rai_sbt_performance (task_id, filename, start_time, bytes, bs_key, piece#) as with backupio as (select sid, serial, inst_id, filename, bytes from gv$backup_sync_io where type = 'OUTPUT' and filename is not null and status = 'IN PROGRESS' and device_type = 'SBT_TAPE' union all select sid, serial, inst_id, filename, bytes from gv$backup_async_io where type = 'OUTPUT' and filename is not null and status = 'IN PROGRESS' and device_type = 'SBT_TAPE' ) select t.task_id, v.filename, s.start_time, v.bytes, st.bs_key, st.piece# from backupio v, sessions s, task t, sbt_task st where s.sid = v.sid and s.serial# = v.serial and s.current_task = t.task_id and s.instance_id = v.inst_id and t.task_type in (150, 160) and t.state = 2 and st.task_id = t.task_id >>> define create_internal_recovery_window_space <<< create or replace view rai_recovery_window_space ( db_key, footprint, recwindowstart, minrectime, bdf1count ) as with bssizelist (db_key, bs_key, piecesize, filesize) as ( select /*+ QB_NAME(bssizelist) LEADING(dbinc bdf df bp bs) USE_HASH(bdf df dbinc bp bs) */ dbinc.db_key , max(bdf.bs_key) bs_key , sum(bp.bytes) keep (dense_rank last order by bdf.bs_key, bp.copy#) , max(bdf.blocks * bdf.block_size) keep (dense_rank last order by bdf.bs_key, bp.copy#) from bdf , df , dbinc , bp , bs where df.dbinc_key = bdf.dbinc_key and dbinc.dbinc_key = bdf.dbinc_key and df.file# = bdf.file# and df.create_scn = bdf.create_scn -- -- and (bdf.incr_scn = 0 or (df.create_scn >= bdf.incr_scn)) and bp.bs_key = bdf.bs_key and bp.db_key = dbinc.db_key and bp.ba_access = 'L' and bp.status <> 'D' and bs.bs_key = bp.bs_key and bs.keep_options = 0 group by dbinc.db_key, bdf.file# ) , nodupbslist (db_key, bytes, dfcount) as -- -- -- -- -- ( select /*+ QB_NAME(nodupbslist) */ bsl.db_key , least(sum(bsl.filesize), max(bsl.piecesize)) , count(*) from bssizelist bsl group by bsl.db_key, bsl.bs_key ) , dbfootprint (db_key, space) as -- -- ( select /*+ QB_NAME(dbfootprint) LEADING(odb) USE_HASH(nodupbslist) */ odb.db_key , sum(nvl(nodupbslist.bytes, 0)) + sum(dfcount) * min(odb.sl_min_alloc) *.5 from odb , nodupbslist where odb.db_key = nodupbslist.db_key group by odb.db_key ) , keepsize (db_key, space) as -- ( select /*+ QB_NAME(keepsize) LEADING(bs) USE_HASH(bp) */ bp.db_key , sum(bytes) from bp join bs using(bs_key) where bp.ba_access = 'L' and bp.status <> 'D' and bs.keep_options <> 0 group by bp.db_key ) , dbrectimes (db_key, recwindowstart, minrectime) as -- -- -- -- -- -- -- -- -- -- ( select /*+ QB_NAME(dbrectimes) */ db_key , max(recwindowstart) , min(minrectime) from (select /*+ QB_NAME(idbrectimes) LEADING(db dbinc df bdf bp bs) USE_HASH(db dbinc df bdf bp bs) */ db_key , nvl(min(bdf.ckp_time), max(df.create_time)) recwindowstart , nvl(max(bdf.ckp_time),max(df.create_time)) minrectime from (select db_key , dbinc_key , reset_scn , nvl(prior reset_scn, 1E40) next_reset_scn from dbinc start with dbinc_key = (select curr_dbinc_key from db where db.db_key = dbinc.db_key ) connect by prior parent_dbinc_key = dbinc_key ) incs join df using (dbinc_key) left outer join bdf using (file#, dbinc_key) left outer join bp using (bs_key, db_key) left outer join bs using (bs_key, db_key) where df.stop_scn is null and df.drop_scn is null and bdf.ckp_scn >= incs.reset_scn and bdf.ckp_scn < incs.next_reset_scn and bp.ba_access = 'L' and bs.keep_options = 0 group by db_key, file# ) group by db_key ) , backupf1count (db_key, bdf1count) as -- -- -- ( select /*+ QB_NAME(backupf1count) LEADING(dbinc) USE_HASH(bdf) */ dbinc.db_key , count(distinct bdf.bs_key) from bdf , dbinc where dbinc.dbinc_key = bdf.dbinc_key and bdf.file# = 1 group by dbinc.db_key ) select /*+ QB_NAME(irws) LEADING(odb dbfootprint keepsize dbrectimes backupf1count) USE_HASH(dbfootprint keepsize dbrectimes backupf1count) */ db_key , dbfootprint.space + nvl(keepsize.space, 0) footprint , recwindowstart , minrectime , bdf1count from odb left outer join dbfootprint using (db_key) left outer join keepsize using (db_key) left outer join dbrectimes using (db_key) left outer join backupf1count using (db_key) >>> define create_rai_oldest_backup <<< create or replace view rai_oldest_backup as select /*+ QB_NAME(oldestbackup) LEADING(dbinc bdf bp bs) USE_HASH(dbinc bdf bp bs) */ db_key , cast (min(bp.completion_time) as timestamp with time zone) oldest_backup from dbinc left outer join bdf using (dbinc_key) left outer join bp using (bs_key, db_key) left outer join bs using (bs_key, db_key) where bdf.file# = 1 and bp.ba_access = 'L' and bs.keep_options = 0 group by db_key >>> define create_rai_recwingoal_scn <<< create or replace view rai_recwingoal_scn (db_id, minscn) as with params(db_id, db_key, rwg_start) as (select db_id , db_key , cast((systimestamp-recovery_window_goal) at time zone db_timezone as date) from node join db using (db_key) join odb using (db_key) where node.db_unique_name not like '$%') select db_id , nvl(min(bdf.ckp_scn), 0) from (select db_key , dbinc_key , reset_scn , nvl(prior reset_scn, 1E40) next_reset_scn from dbinc start with dbinc_key = (select curr_dbinc_key from db where db.db_key = dbinc.db_key ) connect by prior parent_dbinc_key = dbinc_key ) incs join df using (dbinc_key) join params using (db_key) left outer join bdf using (file#, dbinc_key, create_scn, plugin_scn) left outer join bp using (bs_key, db_key) left outer join bs using (bs_key, db_key) where df.stop_scn is null and df.drop_scn is null and bdf.ckp_scn >= incs.reset_scn and bdf.ckp_scn < incs.next_reset_scn and bp.ba_access = 'L' and bs.keep_options = 0 and bdf.completion_time >= rwg_start group by db_id >>> define create_rai_maxrecwin_stamp <<< create or replace view rai_maxrecwin_stamp (db_id, high_time, reset_scn, reset_time) as with orderedrange as (select db_key, high_time, high_dbinc_key, row_number () over (partition by db_key order by high_time desc) as rn -- -- from rrcache -- where range_type = 'RA$DISK') , params as (select db_id, high_time, reset_scn, reset_time from db using join orderedrange using (db_key) join dbinc using (db_key) where dbinc.dbinc_key = orderedrange.high_dbinc_key and orderedrange.rn = 1) select db_id, (((((to_number(to_char(high_time, 'yyyy'))-1988)*12 + (to_number(to_char(high_time, 'mm'))-1))*31 + (to_number(to_char(high_time, 'dd'))-1))*24 + (to_number(to_char(high_time, 'hh24'))))*60 + (to_number(to_char(high_time, 'mi'))))*60 + (to_number(to_char(high_time, 'ss'))), reset_scn, (((((to_number(to_char(reset_time, 'yyyy'))-1988)*12 + (to_number(to_char(reset_time, 'mm'))-1))*31 + (to_number(to_char(reset_time, 'dd'))-1))*24 + (to_number(to_char(reset_time, 'hh24'))))*60 + (to_number(to_char(reset_time, 'mi'))))*60 + (to_number(to_char(reset_time, 'ss'))) from params >>> define create_rai_unprotected_window <<< create or replace view rai_unprotected_window (db_key, nzdl_active, unprotected) as with nodedata (db_key, odbsysdate) as ( select db_key , cast((systimestamp at time zone to_char(max(db_timezone))) as date) from node where substr(node.db_unique_name,1,1) <> '$' group by db_key ) , uw_raw (db_key, nzdl_active, nzdl_days, range_days) as ( select db_key , osc.nzdl_active , osc.unprotected , (odbsysdate-high_time) range_days from odb_stats_cache osc join nodedata using (db_key) left outer join (select db_key, max(high_time) high_time from ra_disk_restore_range group by db_key) using (db_key) ) select db_key , nzdl_active , case when (nzdl_active = 'YES') and (range_days is not null) then least(nzdl_days, range_days) else range_days end from uw_raw >>> define create_rs_server <<< create or replace view ra_server as select substr((select substr(value,1,3) from config where name = '_recovery_appliance_state'),1,5) state, substr((select value/(1024*1024) from config where name = 'network_chunksize'),1,20) network_chunksize, substr((select decode(value, '99999', 'UNLIMITED', value) from config where name = '_resource_wait_task_limit'),1,12) resource_wait_task_limit from dual >>> define create_comment_0 <<< begin execute immediate 'comment on table ra_server is ' || '''This view describes the current settings for the Recovery Appliance.'''; execute immediate 'comment on column ra_server.' || 'state is ' || '''The state of the Recovery Appliance: ON ' || 'if the Recovery Appliance is running; ' || 'OFF if it is not active.'''; execute immediate 'comment on column ra_server.network_chunksize is ' || '''The size (in MB) of network messages used by the Recovery Appliance ' || 'Backup Module to communicate with the Recovery Appliance.'''; execute immediate 'comment on column ra_server.resource_wait_task_limit is ' || '''The limitations on task concurrency caused by resource waits.'''; end; >>> define create_rs_storage_location <<< create or replace view ra_storage_location (name, sl_key, disk_groups, min_alloc, total_space, used_space, freespace, freespace_goal, last_check_files, system_purging_space) as -- with dbs (sl_key, used_space) as ( select sl_key, sum(space) used_space from ( select sl_key, used_space space from odb union all select sl_key, dbsl_used_space space from dbsl ) group by sl_key ) -- , dests (sl_key, csv) as ( select sl_key , listagg(dest, ',') within group (order by dest) csv from storage_dests group by sl_key ) -- , sps(n) as ( select to_number(value) from config where name='_purging_reserve' ) select sl.sl_name, sl.sl_key, dests.csv, sl.sl_min_alloc/(1024*1024*1024), sl.sl_space/(1024*1024*1024), NVL(dbs.used_space,0)/(1024*1024*1024), (sl.sl_space-(NVL(dbs.used_space,0)+sps.n))/(1024*1024*1024), sl.sl_freespace_goal/(1024*1024*1024), sl.sl_last_check_files, decode (sl.sl_space, 1, 1, sps.n/(1024*1024*1024)) from sl left outer join dbs on dbs.sl_key = sl.sl_key left outer join dests on dests.sl_key = sl.sl_key join sps on (1=1) where sl_space > 0 >>> define create_comment_1 <<< begin execute immediate 'comment on table ra_storage_location is ' || '''This view lists defined Recovery Appliance storage locations and their ' || 'allocations.'''; execute immediate 'comment on column ra_storage_location.' || 'name is ' || '''The Recovery Appliance storage location name.'''; execute immediate 'comment on column ra_storage_location.' || 'sl_key is ' || '''The primary key for this Recovery Appliance storage location ' || 'in the recovery catalog.'''; execute immediate 'comment on column ra_storage_location.' || 'disk_groups is ' || '''The list of names of Oracle ASM disk groups used for storage.'''; execute immediate 'comment on column ra_storage_location.' || 'min_alloc is ' || '''The minimum amount of storage (in GB) that may be allocated.'''; execute immediate 'comment on column ra_storage_location.' || 'total_space is ' || '''The maximum amount of storage (in GB) that the Recovery Appliance storage ' || 'location can use for backup data.'''; execute immediate 'comment on column ra_storage_location.' || 'used_space is ' || '''The amount of space (in GB) currently used in the ' || 'Recovery Appliance storage location.'''; execute immediate 'comment on column ra_storage_location.' || 'freespace is ' || '''The amount of space (in GB) available for immediate use.'''; execute immediate 'comment on column ra_storage_location.' || 'freespace_goal is ' || '''The expected free space requirement (in GB) based on usage history. ' || 'Purges may occur to meet this goal.'''; execute immediate 'comment on column ra_storage_location.' || 'last_check_files is ' || '''The most recent time that files were checked for consistency.'''; execute immediate 'comment on column ra_storage_location.' || 'system_purging_space is ' || '''The amount of space (in GB) reserved for purging operations.'''; end; >>> define create_rs_storage_histogram <<< create or replace view ra_storage_histogram (name, sl_key, slot, usage) as select sl.sl_name, sl_key, mod(hist.slot + numslots - (nvl(sl.sl_curr_hist_slot,0)+1), numslots), hist.usage/(1024*1024*1024) from sl join storage_histogram hist using(sl_key) cross join (select nvl(max(to_number(value)), 8*30) numslots from config where name = '_histogram_cycle_slots') where (nvl(sl.sl_space,0) != 0) >>> define create_comment_2 <<< begin execute immediate 'comment on table ra_storage_histogram is ' || '''This view describes the storage allocation history for recent time periods.'''; execute immediate 'comment on column ra_storage_histogram.' || 'name is ' || '''The name of the Recovery Appliance storage location.'''; execute immediate 'comment on column ra_storage_histogram.' || 'sl_key is ' || '''The primary key for this Recovery Appliance storage location in ' || 'the recovery catalog.'''; execute immediate 'comment on column ra_storage_histogram.' || 'slot is ' || '''The slot (ordered by sampling time period) in the histogram.'''; execute immediate 'comment on column ra_storage_histogram.' || 'usage is ' || '''The amount of space (in GB) that was allocated during the ' || 'histogram slot.'''; end; >>> define create_rs_purging_queue <<< create or replace view ra_purging_queue (sl_name, sl_key, db_unique_name, db_key, purge_order, new_recovery_window, new_pct_recovery, pct_storage) as select sl.sl_name, sl_key, db.reg_db_unique_name, db_key, row_number() over (partition by sl_key order by ipq.overretentionsecs desc, ipq.overspace desc), nvl2(odb.bs2_timestamp,ipq.new_retention,null), nvl2(odb.bs2_timestamp,(ipq.newsecs/ipq.goalsecs)*100,null), (1+ipq.overspace)*100 from rai_purge_queue ipq join sl using(sl_key) join odb using (sl_key, db_key) left outer join db using (db_key) >>> define create_comment_3 <<< begin execute immediate 'comment on table ra_purging_queue is ' || '''This view describes the order in which protected databases will have their oldest backups deleted when space is low.'''; execute immediate 'comment on column ra_purging_queue.' || 'sl_name is ' || '''The Recovery Appliance storage location name.'''; execute immediate 'comment on column ra_purging_queue.' || 'sl_key is ' || '''The primary key for this Recovery Appliance storage location in the recovery ' || 'catalog.'''; execute immediate 'comment on column ra_purging_queue.' || 'db_unique_name is ' || '''The unique name of the protected database whose backups the Recovery ' || 'Appliance will purge.'''; execute immediate 'comment on column ra_purging_queue.' || 'db_key is ' || '''The primary key for the protected database whose backups ' || 'the Recovery Appliance will purge.'''; execute immediate 'comment on column ra_purging_queue.' || 'purge_order is ' || '''The order in which this protected database is eligible for purging.'''; execute immediate 'comment on column ra_purging_queue.' || 'new_recovery_window is ' || '''The recovery window goal for this protected database after a purge.'''; execute immediate 'comment on column ra_purging_queue.' || 'new_pct_recovery is ' || '''The percentage of the recovery window goal remaining for ' || 'this protected database after a purge.'''; execute immediate 'comment on column ra_purging_queue.' || 'pct_storage is ' || '''The percentage of reserved space being consumed by this ' || 'protected database.'''; end; >>> define create_rs_polling_policy <<< create or replace view ra_polling_policy (polling_name, polling_key, dest, frequency, delete_input) as select poll.poll_name, poll.poll_key, sd.dest, poll.poll_freq, DECODE (BITAND(poll.poll_flags,1), 0, 'FALSE', 'TRUE') from sl join storage_dests sd using(sl_key) join poll using(sl_key) where (nvl(sl.sl_space, 0) = 0) >>> define create_comment_4 <<< begin execute immediate 'comment on table ra_polling_policy is ' || '''This view lists the defined backup polling policies.'''; execute immediate 'comment on column ra_polling_policy.' || 'polling_name is ' || '''The name of this backup polling policy.'''; execute immediate 'comment on column ra_polling_policy.' || 'polling_key is ' || '''The primary key for this backup polling policy in the recovery catalog.'''; execute immediate 'comment on column ra_polling_policy.' || 'dest is ' || '''The file system directory corresponding to the backup polling location.'''; execute immediate 'comment on column ra_polling_policy.' || 'frequency is ' || '''The interval at which the Recovery Appliance scans the backup polling ' || 'location for new files.'''; execute immediate 'comment on column ra_polling_policy.' || 'delete_input is ' || '''The deletion policy for the polling location: ' || 'TRUE to delete files ' || 'as they are accepted; FALSE ' || 'to keep all files.'''; end; >>> define create_rs_db_access <<< create or replace view ra_db_access (username, db_unique_name, db_key) as select username, substr(decode(prvlg.db_key, null, db_unique_name, db.reg_db_unique_name),1,32), prvlg.db_key from prvlg left outer join db on db.db_key = prvlg.db_key, all_users au where prvlg.user_id = au.user_id >>> define create_comment_5 <<< begin execute immediate 'comment on table ra_db_access is ' || '''This view describes which Recovery Appliance user accounts have access to which protected databases.'''; execute immediate 'comment on column ra_db_access.' || 'username is ' || '''The name of the Recovery Appliance user account.'''; execute immediate 'comment on column ra_db_access.' || 'db_unique_name is ' || '''The unique name of the protected database accessed by the ' || 'Recovery Appliance user account.'''; execute immediate 'comment on column ra_db_access.' || 'db_key is ' || '''The primary key for the protected database accessed by the ' || 'Recovery Appliance user account.'''; end; >>> define create_rs_database_synonym <<< create or replace view ra_database_synonym (db_unique_name, dbid) as select node.db_unique_name, db.db_id from node join db using(db_key) where node.db_unique_name not like '%$%' union all select db_unique_name, null db_id from unreg_database >>> define create_comment_6 <<< begin execute immediate 'comment on table ra_database_synonym is ' || '''This view lists the protected databases and their equivalent names.'''; execute immediate 'comment on column ra_database_synonym.' || 'db_unique_name is '|| '''The unique name of the protected database.'''; execute immediate 'comment on column ra_database_synonym.' || 'dbid is ' || '''The DBID for all protected databases that are equivalent to this database.'''; end; >>> define create_rs_protection_policy <<< create or replace view ra_protection_policy (policy_name, description, prot_key, sl_name, sl_key, polling_name, recovery_window_goal, max_retention_window, recovery_window_sbt, unprotected_window, guaranteed_copy, replication_server_list) as select prot.prot_name, prot.prot_description, prot.prot_key, sl.sl_name, sl.sl_key, poll.poll_name, prot.prot_recovery_window_goal, prot.prot_max_retention_window, prot.prot_recovery_window_sbt, prot.prot_unprotected_window, prot.prot_disk_cache, (SELECT listagg(server.rep_server_name, ',') within GROUP (ORDER BY server.rep_server_name) FROM server, rep_server WHERE prot.prot_key=rep_server.prot_key AND rep_server.server_key = server.server_key) replication_server_list from prot join sl on prot.sl_key = sl.sl_key left outer join poll on prot.poll_key = poll.poll_key >>> define create_comment_7 <<< begin execute immediate 'comment on table ra_protection_policy is '|| '''This view lists the protection policies defined for this Recovery Appliance.'''; execute immediate 'comment on column ra_protection_policy.' || 'policy_name is '|| '''The user-created name of the protection policy.'''; execute immediate 'comment on column ra_protection_policy.' || 'description is '|| '''The protection policy description.'''; execute immediate 'comment on column ra_protection_policy.' || 'prot_key is '|| '''The primary key for this protection policy in the Recovery Appliance metadata database.'''; execute immediate 'comment on column ra_protection_policy.' || 'sl_name is '|| '''The name of the Recovery Appliance storage location used by this protection policy.'''; execute immediate 'comment on column ra_protection_policy.' || 'sl_key is '|| '''The primary key of the Recovery Appliance storage location used by this protection policy.'''; execute immediate 'comment on column ra_protection_policy.' || 'polling_name is '|| '''The name of the backup polling policy assigned to this protection policy.'''; execute immediate 'comment on column ra_protection_policy.' || 'recovery_window_goal is '|| '''The recovery window goal for restoring backups stored on disk.'''; execute immediate 'comment on column ra_protection_policy.' || 'max_retention_window is '|| '''The maximum amount of time that the Recovery Appliance must retain disk backups.'''; execute immediate 'comment on column ra_protection_policy.' || 'recovery_window_sbt is '|| '''The recovery window for restoring backups stored on tape.'''; execute immediate 'comment on column ra_protection_policy.' || 'guaranteed_copy is '|| '''The status of the guaranteed copy setting: ' || 'YES means that ' || 'the Recovery Appliance replicates backups or copies them to tape before deleting them; ' || 'NO means that ' || 'the Recovery Appliance accepts new backups even if old backups ' || 'must be purged because free space is low.'''; execute immediate 'comment on column ra_protection_policy.' || 'unprotected_window is '|| '''The point beyond which recovery is not possible unless additional redo is available.'''; execute immediate 'comment on column ra_protection_policy.' || 'replication_server_list is '|| '''The list of replication server configurations associated with this protection policy.'''; end; >>> define create_rs_database <<< create or replace view ra_database as with nodedata (db_key, db_timezone, odbsysdate) as ( select db_key , max(db_timezone) , cast((systimestamp at time zone to_char(max(db_timezone))) as date) from node where substr(node.db_unique_name,1,1) <> '$' group by db_key ) , rgd(db_key, recovery_goal_days) as ( select db_key, to_number(extract(day from recovery_window_goal)) + to_number(extract(hour from recovery_window_goal)) / (24) + to_number(extract(minute from recovery_window_goal)) / (24*60) FROM odb ) , rws (db_key, recovery_window_space) as ( -- -- select db_key, case when osc.recovery_window_start is null or osc.bdf1count < 3 or (odbsysdate - osc.recovery_window_start) <= 0 then odb.reserved_space else ceil( ( ( (odb.total_allocation - osc.footprint) * rgd.recovery_goal_days / (odbsysdate - osc.recovery_window_start) ) + osc.footprint ) / odb.sl_min_alloc ) * odb.sl_min_alloc end from odb join rgd using (db_key) join nodedata using (db_key) left outer join odb_stats_cache osc using (db_key) ) -- , lo (db_key, task_exists) as -- -- ( select db_key, nvl2(task_id, 1, 0) from odb left outer join task using (db_key) where nvl(task_type, 310) = 310 /*task_optimize_chunks_df*/ and rownum = 1 ) select db.reg_db_unique_name db_unique_name, db_key, DECODE(db_state, NULL, 'NO', 1, 'YES', 'UNKNOWN') deleting, db_id dbid, create_time creation_time, prot_name policy_name, sl_name storage_location, recovery_window_goal, prot_max_retention_window max_retention_window, prot_recovery_window_sbt recovery_window_sbt, db_timezone timezone, total_allocation/(1024*1024*1024) space_usage, reserved_space/(1024*1024*1024) disk_reserved_space, prot_disk_cache guaranteed_copy, cumulative_usage/(1024*1024*1024) cumulative_usage, cumulative_rep_usage/(1024*1024*1024) replication_usage, cumulative_sbt_usage/(1024*1024*1024) sbt_usage, DECODE(odb.pending_rep_setup, NULL, NULL, 'Y', 'PENDING', 'N', 'SUCCESS', 'UNKNOWN') replication_setup_status, case when lo.task_exists = 0 then last_optimize else prev_optimize end last_optimize, last_validate last_validate, last_crosscheck last_crosscheck, sls_used storage_location_count, DECODE(odb.move_phase, NULL, 'NOT MOVING', 1, 'PENDING MOVE', 2, 'STARTING MOVE', 3, 'MOVING BLOCK POOLS', 4, 'MOVING FILES', 'UNKNOWN') storage_movement_phase, osc.db_size/(1024*1024*1024) size_estimate, rws.recovery_window_space/(1024*1024*1024) recovery_window_space, osc.deduplication_factor, (odbsysdate - osc.minimum_recovery_start) * to_dsinterval('1 0:0:0') minimum_recovery_needed, prot_unprotected_window unprotected_window_threshold, numtodsinterval(ruw.unprotected, 'day') unprotected_window, ruw.nzdl_active from odb join db using(db_key) join prot on (odb.future_prot_key = prot.prot_key) join rgd using (db_key) join sl ON odb.sl_key = sl.sl_key join nodedata using (db_key) join rai_unprotected_window ruw using(db_key) left outer join odb_stats_cache osc using(db_key) left outer join rws using(db_key) left outer join lo using(db_key) union all select db_unique_name, NULL db_key, 'NO' deleting, NULL db_id, NULL creation_time, prot.prot_name policy_name, sl_name storage_location, prot_recovery_window_goal recovery_window_goal, prot_max_retention_window max_retention_window, prot_recovery_window_sbt recovery_window_sbt, NULL timezone, 0 space_usage, reserved_space/(1024*1024*1024) disk_reserved_space, prot_disk_cache guaranteed_copy, 0 cumulative_usage, 0 replication_usage, 0 sbt_usage, null replication_status, null last_optimize, null last_validate, null last_crosscheck, 1 storage_location_count, 'NOT MOVING' storage_movement_phase, NULL size_estimate, NULL recovery_window_space, NULL deduplication_factor, NULL minimum_recovery_needed, prot_unprotected_window unprotected_window_threshold, NULL unprotected_window, 'NO' nzdl_active from unreg_database u join prot using(prot_key) join sl ON u.sl_key = sl.sl_key >>> define create_comment_8 <<< begin execute immediate 'comment on table ra_database is ' || '''This view lists the databases protected by this Recovery Appliance.'''; execute immediate 'comment on column ra_database.' || 'db_unique_name is '|| '''The unique name of this protected database.'''; execute immediate 'comment on column ra_database.' || 'db_key is '|| '''The primary key for this database in the Recovery Appliance metadata database.'''; execute immediate 'comment on column ra_database.' || 'deleting is '|| '''YES if this ' || 'database is currently being deleted.'''; execute immediate 'comment on column ra_database.' || 'dbid is '|| '''The DBID for this protected database.'''; execute immediate 'comment on column ra_database.' || 'creation_time is '|| '''The time when this database was added to the Recovery Appliance.'''; execute immediate 'comment on column ra_database.' || 'policy_name is '|| '''The name of the protection policy used by this database.'''; execute immediate 'comment on column ra_database.' || 'storage_location is '|| '''The name of the Recovery Appliance storage location used by this protected database.'''; execute immediate 'comment on column ra_database.' || 'recovery_window_goal is '|| '''The recovery window goal for backups on disk, as specified in the protection policy.'''; execute immediate 'comment on column ra_database.' || 'max_retention_window is '|| '''The maximum amount of time to retain disk backups. The Recovery Appliance deletes ' || 'disk backups when they are older than this window. However, backups may be retained ' || 'longer if deleting them would negatively affect the ' || 'recovery_window_goal requirement.'''; execute immediate 'comment on column ra_database.' || 'recovery_window_sbt is '|| '''The recovery window for backups on tape, as specified in the protection policy.'''; execute immediate 'comment on column ra_database.' || 'timezone is '|| '''The time zone offset of the protected database.'''; execute immediate 'comment on column ra_database.' || 'space_usage is '|| '''The amount of disk space (in GB) currently used by this protected database.'''; execute immediate 'comment on column ra_database.' || 'disk_reserved_space is '|| '''The amount of disk space (in GB) reserved for the exclusive use of this database'''; execute immediate 'comment on column ra_database.' || 'guaranteed_copy is '|| '''The status of the guaranteed copy setting: ' || 'YES means that ' || 'the Recovery Appliance replicates backups or copies them to tape before deleting them; ' || 'NO means that ' || 'the Recovery Appliance accepts new backups even if old backups ' || 'must be purged because free space is low.'''; execute immediate 'comment on column ra_database.' || 'cumulative_usage is '|| '''The cumulative amount of disk space (in GB) allocated for ' || 'all backups received for this database.'''; execute immediate 'comment on column ra_database.' || 'replication_usage is '|| '''The cumulative amount of disk space (in GB) replicated ' || 'for this protected database.'''; execute immediate 'comment on column ra_database.' || 'sbt_usage is '|| '''The cumulative amount of disk space (in GB) sent to SBT from this ' || 'protected database.'''; execute immediate 'comment on column ra_database.' || 'replication_setup_status is '|| '''The status of the setup for the downstream replication appliance for this database.'''; execute immediate 'comment on column ra_database.' || 'last_optimize is '|| '''The time when the most recent data placement optimization was completed.'''; execute immediate 'comment on column ra_database.' || 'last_validate is '|| '''The time when the most recent validation of backup data was completed.'''; execute immediate 'comment on column ra_database.' || 'last_crosscheck is '|| '''The time when the most recent crosscheck of backup data was completed.'''; execute immediate 'comment on column ra_database.' || 'storage_location_count is '|| '''The number of storage locations used by this database. If greater than ' || 'one, then a storage location movement operation is in progress for this database.'''; execute immediate 'comment on column ra_database.' || 'storage_movement_phase is '|| '''The phase of the storage location movement operation for this protected database.'''; execute immediate 'comment on column ra_database.' || 'size_estimate is '|| '''The estimated space (in GB) consumed by the entire protected database.'''; execute immediate 'comment on column ra_database.' || 'recovery_window_space is '|| '''The estimated space (in GB) that is needed to meet the recovery window goal.'''; execute immediate 'comment on column ra_database.' || 'deduplication_factor is '|| '''The ratio of the total size of backups to the consumed space.'''; execute immediate 'comment on column ra_database.' || 'minimum_recovery_needed is '|| '''The minimum interval needed to restore the protected database to ' || 'the present.'''; execute immediate 'comment on column ra_database.' || 'unprotected_window_threshold is '|| '''The user-specified maximum amount of data loss for protected databases ' || 'that are subject to a protection policy. The Recovery Appliance generates ' || 'an alert if the unprotected window of this database exceeds this value.'''; execute immediate 'comment on column ra_database.' || 'unprotected_window is '|| '''The point beyond which recovery is impossible unless additional redo is available.'''; execute immediate 'comment on column ra_database.' || 'nzdl_active is '|| '''YES if real-time redo transport is ' || 'active. NO if redo has ' || 'not recently been received.'''; end; >>> define create_rs_database_storage <<< create or replace view ra_database_storage_usage as select db.reg_db_unique_name db_unique_name, o.db_key, sl.sl_name storage_location, o.used_space /(1024*1024*1024) used_space from (select db_key, sl_key, used_space from odb union all select db_key, sl_key, dbsl_used_space used_space from dbsl) o join sl ON o.sl_key = sl.sl_key left outer join db on db.db_key = o.db_key >>> define create_comment_8a <<< begin execute immediate 'comment on table ra_database_storage_usage is '|| '''This view lists the storage usage for each protected database.'''; execute immediate 'comment on column ra_database_storage_usage.' || 'db_unique_name is '|| '''The unique name of the protected database.'''; execute immediate 'comment on column ra_database_storage_usage.' || 'db_key is '|| '''The primary key for this protected database in the ' || 'Recovery Appliance metadata database.'''; execute immediate 'comment on column ra_database_storage_usage.' || 'storage_location is '|| '''The name of the Recovery Appliance storage location used by this protected database.'''; execute immediate 'comment on column ra_database_storage_usage.' || 'used_space is ' || '''The amount of space (in GB) used by this database in its ' || 'Recovery Appliance storage locations. Backups for a protected database ' || 'typically reside in only one storage location, but can reside ' || 'in two locations when a movement operation is in progress.'''; end; >>> define create_rs_task <<< create or replace view ra_task (task_id, task_type, priority, state, waiting_on, creation_time, completion_time, elapsed_seconds, error_count, interrupt_count, last_interrupt_time, execute_instance_id, last_execute_time, db_unique_name, db_key, sl_name, sl_key, ospid, instance_id, archived) as select t.task_id, tasktypenames.task_type_name, priority, state, waiting_on, t.creation_time, t.completion_time, ((extract(second from (t.elapsed_time))) + (extract(minute from (t.elapsed_time)) * 60) + (extract(hour from (t.elapsed_time)) * 3600) + (extract(day from (t.elapsed_time)) * 86400)), nvl(t.error_count,0), nvl(t.interrupt_count,0), last_interrupt_time, t.execute_inst_id, last_execute_time, db.reg_db_unique_name, t.db_key, sl.sl_name, t.sl_key, t.ospid, t.instance_id, archived from (select task_id, task_type, priority, (case state when 1 then 'EXECUTABLE' when 2 then NVL2(a.sid, 'RUNNING', 'RETRYING') when 3 then 'COMPLETED' when 4 then 'ORDERING_WAIT' when 5 then (case pending_interrupt when -1 then 'SERVLET_WAIT' when -2 then 'SPACE_WAIT' when -3 then 'OPT_DF_WAIT' when -4 then 'TEST_WAIT' when -5 then 'RESOURCE_WAIT' when -6 then 'STALL_WHEN_WAIT' when -7 then 'LIBRARY_WAIT' when -8 then 'POOL_FULL_WAIT' else 'TASK_WAIT' end) when 6 then 'RESTORE_WAIT' when 8 then 'FAILED' when 9 then 'CANCEL' when 10 then 'CANCELING' when 11 then 'CANCELED' else 'UNKNOWN' end) state, (case when pending_interrupt < 0 then null else pending_interrupt end) waiting_on, schedule_time creation_time, completion_time, (case when s.ba_session_id is not null then (elapsed_time + (systimestamp - s.last_task_start)) else elapsed_time end) elapsed_time, error_count, interrupt_count, last_interrupt_time, execute_inst_id, last_execute_time, db_key, sl_key, s.spid ospid, s.instance_id, 'N' archived from task left outer join sessions s on (s.current_task = task.task_id) left outer join sys.rai_active_sessions a on ( a.inst_id = s.instance_id and a.audsid = s.audsid and a.sid = s.sid and a.serial# = s.serial# and a.logon_time = s.logon_time) union all select task_id, task_type, priority, DECODE(state, 3, 'COMPLETED', 8, 'FAILED', 11, 'CANCELED', 'UNKNOWN' || state) state, NULL waiting_on, schedule_time, completion_time, elapsed_time, error_count, interrupt_count, last_interrupt_time, execute_inst_id, last_execute_time, db_key, th.sl_key, NULL ospid, NULL instance_id, 'Y' archived from task_history th where (th.task_type < 2000 /*dbms_ra_scheduler.task_session_times*/)) t left outer join sl on sl.sl_key = t.sl_key join tasktypenames using (task_type) left outer join db on db.db_key = t.db_key >>> define create_comment_9 <<< begin execute immediate 'comment on table ra_task is '|| '''This view lists queued background tasks and their run statuses.'''; execute immediate 'comment on column ra_task.' || 'task_id is '|| '''The ID for the task.'''; execute immediate 'comment on column ra_task.' || 'task_type is '|| '''The type of processing performed by the task.'''; execute immediate 'comment on column ra_task.' || 'priority is '|| '''The run priority for the task.'''; execute immediate 'comment on column ra_task.' || 'state is '|| '''The processing state for the task: ' || 'EXECUTABLE, ' || 'RUNNING, ' || 'COMPLETED, ' || 'TASK_WAIT, ' || 'FAILED, ' || 'and so on.'''; execute immediate 'comment on column ra_task.' || 'waiting_on is '|| '''The ID of the task that is blocking this task when its state ' || 'is TASK_WAIT.'''; execute immediate 'comment on column ra_task.' || 'creation_time is '|| '''The time of task creation.'''; execute immediate 'comment on column ra_task.' || 'completion_time is '|| '''The timestamp for task completion. The column is null ' || 'if the task is not complete.'''; execute immediate 'comment on column ra_task.' || 'elapsed_seconds is '|| '''The elapsed run time (in seconds) for the task.'''; execute immediate 'comment on column ra_task.' || 'error_count is '|| '''Number of times that the task had errors'''; execute immediate 'comment on column ra_task.' || 'interrupt_count is '|| '''The number of times that the task was interrupted.'''; execute immediate 'comment on column ra_task.' || 'last_interrupt_time is '|| '''The most recent time that the task was interrupted.'''; execute immediate 'comment on column ra_task.' || 'execute_instance_id is '|| '''The ID of the database instance on which the task must run. ' || 'The column is null if the task can run on any instance.'''; execute immediate 'comment on column ra_task.' || 'last_execute_time is '|| '''The most recent time that the task was restarted.'''; execute immediate 'comment on column ra_task.' || 'db_unique_name is '|| '''The unique name of the protected database for which the task is running.'''; execute immediate 'comment on column ra_task.' || 'db_key is '|| '''The primary key of the protected database for which the task is running.'''; execute immediate 'comment on column ra_task.' || 'sl_name is '|| '''The name of the Recovery Appliance storage location used by the task.'''; execute immediate 'comment on column ra_task.' || 'sl_key is '|| '''The primary key of the Recovery Appliance storage location used by the task.'''; execute immediate 'comment on column ra_task.' || 'ospid is '|| '''The platform-specific ID of the process in which the task is current running.'''; execute immediate 'comment on column ra_task.' || 'instance_id is '|| '''The ID of the database instance on which the task is currently running.'''; execute immediate 'comment on column ra_task.' || 'archived is '|| '''The archive status of the task: ' || 'Y ' || 'if it has moved to the archive; otherwise, N.'''; end; >>> define create_rs_time_usage <<< create or replace view ra_time_usage (total_time, idle_time) as select elapsed, elapsed - used from (select sum((extract(second from (elapsed))) + (extract(minute from (elapsed)) * 60) + (extract(hour from (elapsed)) * 3600) + (extract(day from (elapsed)) * 86400)) elapsed /* Elapsed time for active sessions */ from (select (nvl(last_task_start, systimestamp) - start_time) elapsed from sessions union all /* Elapsed time for dead sessions */ select elapsed_time elapsed from task_history join tasktypenames using (task_type) where tasktypenames.task_type_name = 'SESSION_TIMES' and elapsed_time is not null)), (select sum((extract(second from (used))) + (extract(minute from (used)) * 60) + (extract(hour from (used)) * 3600) + (extract(day from (used)) * 86400)) used /* Used time from completed tasks */ from (select elapsed_time used from task_history join tasktypenames using (task_type) where tasktypenames.task_type_name != 'SESSION_TIMES' and elapsed_time is not null union all /* Used time from active tasks */ select elapsed_time used from task where elapsed_time is not null)) >>> define create_comment_10 <<< begin execute immediate 'comment on table ra_time_usage is '|| '''This view describes the Recovery Appliance elapsed and idle time ' || 'for the last 30 days.'''; execute immediate 'comment on column ra_time_usage.' || 'total_time is '|| '''The sum of the elapsed times (in seconds) across all sessions.'''; execute immediate 'comment on column ra_time_usage.' || 'idle_time is '|| '''The sum of the idle times (in seconds) across all sessions.'''; end; >>> define create_rs_restore_range_i <<< create or replace view rai_restore_range as select db_key, low_time, high_time, low_scn, high_scn, low_dbinc_key, high_dbinc_key from TABLE(rc_listRsRangePipe('RA$ANY')) >>> define create_rs_disk_restore_range_i <<< create or replace view rai_disk_restore_range as select db_key, low_time, high_time, low_scn, high_scn, low_dbinc_key, high_dbinc_key from TABLE(rc_listRsRangePipe('RA$DISK')) >>> define create_rs_sbt_restore_range_i <<< create or replace view rai_sbt_restore_range as select db_key, low_time, high_time, low_scn, high_scn, low_dbinc_key, high_dbinc_key from TABLE(rc_listRsRangePipe('RA$SBT')) >>> define create_rs_restore_range <<< create or replace view ra_restore_range as select db_key, low_time, high_time, low_scn, high_scn, low_dbinc_key, high_dbinc_key, last_updated from rrcache where range_type = 'RA$ANY' >>> define create_rs_disk_restore_range <<< create or replace view ra_disk_restore_range as select db_key, low_time, high_time, low_scn, high_scn, low_dbinc_key, high_dbinc_key, last_updated from rrcache where range_type = 'RA$DISK' >>> define create_rs_sbt_restore_range <<< create or replace view ra_sbt_restore_range as select db_key, low_time, high_time, low_scn, high_scn, low_dbinc_key, high_dbinc_key, last_updated from rrcache where range_type = 'RA$SBT' >>> define create_comment_rs_restore_range <<< begin execute immediate 'comment on table ra_restore_range is ' || '''This view describes the restore range of each protected database ' || 'from all backups on this Recovery Appliance.'''; execute immediate 'comment on column ra_restore_range.' || 'db_key is ' || '''The primary key of the protected database.'''; execute immediate 'comment on column ra_restore_range.' || 'low_time is ' || '''The earliest time to which the protected database can be restored.'''; execute immediate 'comment on column ra_restore_range.' || 'high_time is ' || '''The latest time to which the protected database can be restored.'''; execute immediate 'comment on column ra_restore_range.' || 'low_scn is ' || '''The lowest SCN to which the database can be restored.'''; execute immediate 'comment on column ra_restore_range.' || 'high_scn is ' || '''The highest SCN to which the protected database can be restored.'''; execute immediate 'comment on column ra_restore_range.' || 'low_dbinc_key is ' || '''The primary key for the incarnation of the target database to which the low SCN belongs.'''; execute immediate 'comment on column ra_restore_range.' || 'high_dbinc_key is ' || '''The primary key for the incarnation of the target database to which the high SCN belongs.'''; execute immediate 'comment on column ra_restore_range.' || 'last_updated is ' || '''The time that the restore range for this database was updated.'''; end; >>> define create_comment_rs_disk_restore_range <<< begin execute immediate 'comment on table ra_disk_restore_range is ' || '''The restore range of each protected database from disk backups ' || 'on this Recovery Appliance.'''; execute immediate 'comment on column ra_disk_restore_range.' || 'db_key is ' || '''The primary key of the protected database.'''; execute immediate 'comment on column ra_disk_restore_range.' || 'low_time is ' || '''The earliest time to which the protected database can be restored.'''; execute immediate 'comment on column ra_disk_restore_range.' || 'high_time is ' || '''The latest time to which the protected database can be restored.'''; execute immediate 'comment on column ra_disk_restore_range.' || 'low_scn is ' || '''The lowest SCN to which the protected database can be restored.'''; execute immediate 'comment on column ra_disk_restore_range.' || 'high_scn is ' || '''The highest SCN to which the protected database can be restored.'''; execute immediate 'comment on column ra_disk_restore_range.' || 'low_dbinc_key is ' || '''The primary key for the incarnation of the target database to which ' || 'LOW_SCN belongs.'''; execute immediate 'comment on column ra_disk_restore_range.' || 'high_dbinc_key is ' || '''The primary key for the incarnation of the target database to which ' || 'HIGH_SCN belongs.'''; execute immediate 'comment on column ra_disk_restore_range.' || 'last_updated is ' || '''The time that the restore range for this protected database was updated.'''; end; >>> define create_comment_rs_sbt_restore_range <<< begin execute immediate 'comment on table ra_sbt_restore_range is ' || '''This view describes the restore range of each database from SBT backups on the Recovery Appliance.'''; execute immediate 'comment on column ra_sbt_restore_range.' || 'db_key is ' || '''The primary key of the protected database.'''; execute immediate 'comment on column ra_sbt_restore_range.' || 'low_time is ' || '''The earliest time to which the database can be restored.'''; execute immediate 'comment on column ra_sbt_restore_range.' || 'high_time is ' || '''The latest time to which the database can be restored.'''; execute immediate 'comment on column ra_sbt_restore_range.' || 'low_scn is ' || '''The lowest SCN to which the database can be restored.'''; execute immediate 'comment on column ra_sbt_restore_range.' || 'high_scn is ' || '''The highest SCN to which the database can be restored.'''; execute immediate 'comment on column ra_sbt_restore_range.' || 'low_dbinc_key is ' || '''The primary key for the incarnation of the target database to which the low SCN belongs.'''; execute immediate 'comment on column ra_sbt_restore_range.' || 'high_dbinc_key is ' || '''The primary key for the incarnation of the target database to which the high SCN belongs.'''; execute immediate 'comment on column ra_sbt_restore_range.' || 'last_updated is ' || '''The time that the restore range for this protected database was last updated.'''; end; >>> define create_rs_sbt_library <<< create or replace view ra_sbt_library (lib_key, lib_name, drives, restore_drives, parms, send, status, last_error_text) as with errsbt as (select lib_key, min(error_text) keep( dense_rank last order by task_id nulls first) error_text from (select e.error_text, s.lib_key, s.task_id from sbt_task_history s, error_log e where e.task_id = s.task_id and e.status = 'ACTIVE' union all select e.error_text, s.lib_key, s.task_id from sbt_task s, error_log e where e.task_id = s.task_id and e.status = 'ACTIVE') group by lib_key) select lib.lib_key, lib.lib_name, lib.drives, lib.restore_drives, lib.parms, lib.send, decode(lib.status, 'R', 'READY', 'P', 'PAUSE', 'E', 'ERROR', NULL), errsbt.error_text from sbt_lib_desc lib left outer join errsbt on errsbt.lib_key = lib.lib_key >>> define create_comment_rs_sbt_library <<< begin execute immediate 'comment on table ra_sbt_library is ' || '''This view lists the defined SBT libraries.'''; execute immediate 'comment on column ra_sbt_library.' || 'lib_key is '|| '''The key of this SBT library in the Recovery Appliance metadata database.'''; execute immediate 'comment on column ra_sbt_library.' || 'lib_name is ' || '''The SBT library name.'''; execute immediate 'comment on column ra_sbt_library.' || 'drives is ' || '''The number of drives available for use by this SBT library.'''; execute immediate 'comment on column ra_sbt_library.' || 'restore_drives is ' || '''The number of drives reserved for restore operations.'''; execute immediate 'comment on column ra_sbt_library.' || 'parms is ' || '''The SBT parameters passed while allocating an RMAN channel.'''; execute immediate 'comment on column ra_sbt_library.' || 'send is ' || '''The SEND command string ' || 'passed to the allocated channel.'''; execute immediate 'comment on column ra_sbt_library.' || 'status is ' || '''The SBT library status: READY, '|| 'PAUSE, ' || 'ERROR, or null.'''; execute immediate 'comment on column ra_sbt_library.' || 'last_error_text is '|| '''The most recent error text of the task that failed.'''; end; >>> define create_rs_sbt_attr_set <<< create or replace view ra_sbt_attribute_set (attribute_set_key, attribute_set_name, lib_name, streams, poolid, parms, send) as select attr.attr_key, attr.attr_name, lib.lib_name, attr.streams, attr.poolid, attr.parms, attr.send from sbt_lib_desc lib, sbt_attr_set attr where lib.lib_key = attr.lib_key >>> define create_comment_rs_sbt_attr_set <<< begin execute immediate 'comment on table ra_sbt_attribute_set is ' || '''This view describes the defined SBT attribute set.'''; execute immediate 'comment on column ra_sbt_attribute_set.' || 'attribute_set_key is '|| '''The key of this SBT attribute set in the Recovery Appliance metadata database.'''; execute immediate 'comment on column ra_sbt_attribute_set.' || 'attribute_set_name is '|| '''The SBT attribute set name.'''; execute immediate 'comment on column ra_sbt_attribute_set.' || 'lib_name is '|| '''The name of the SBT library object with which this attribute set is associated.'''; execute immediate 'comment on column ra_sbt_attribute_set.' || 'streams is ' || '''The number of parallel streams available for jobs that run with this attribute set.'''; execute immediate 'comment on column ra_sbt_attribute_set.' || 'poolid is ' || '''The media pool identifier.'''; execute immediate 'comment on column ra_sbt_attribute_set.' || 'parms is ' || '''The SBT parameters passed while allocating the RMAN channel.'''; execute immediate 'comment on column ra_sbt_attribute_set.' || 'send is ' || '''The SEND command string passed' || ' to the allocated channel.'''; end; >>> define create_rs_sbt_job <<< create or replace view ra_sbt_job (template_key, template_name, attribute_set_name, lib_name, policy_name, db_key, db_unique_name, backup_type, from_tag, priority, copies, last_schedule_time, window) as select job.template_key, job.template_name, attr.attr_name, lib.lib_name, prot.prot_name, job.db_key, case when job.db_key is not null then db.reg_db_unique_name else null end, case job.bck_type when 1 then 'ALL' when 2 then 'FULL' when 4 then 'INCR' when 6 then 'FULL, INCR' when 8 then 'ARCH' when 10 then 'FULL, ARCH' when 12 then 'INCR, ARCH' when 14 then 'FULL, INCR, ARCH' when 32 then 'TAPE RESERVE' else '?' end bck_type, job.from_tag, job.priority, job.copies, job.schedule_time, job.window from sbt_lib_desc lib, sbt_attr_set attr, sbt_job_template job left outer join prot on prot.prot_key = job.prot_key left outer join db on db.db_key = job.db_key where ((lib.lib_key = attr.lib_key and job.attr_key = attr.attr_key) or (job.bck_type = 32)) >>> define create_comment_rs_sbt_job <<< begin execute immediate 'comment on table ra_sbt_job is ' || '''This view describes the defined SBT job templates.'''; execute immediate 'comment on column ra_sbt_job.' || 'template_key is ' || '''The key of this SBT job template in the Recovery Appliance metadata database.'''; execute immediate 'comment on column ra_sbt_job.' || 'template_name is ' || '''The SBT job template name.'''; execute immediate 'comment on column ra_sbt_job.' || 'attribute_set_name is ' || '''The SBT attribute set name.'''; execute immediate 'comment on column ra_sbt_job.' || 'lib_name is ' || '''The SBT library name.'''; execute immediate 'comment on column ra_sbt_job.' || 'policy_name is ' || '''The protection policy specifying databases whose backups ' || 'the Recovery Appliance considers eligible for copying to tape.'''; execute immediate 'comment on column ra_sbt_job.' || 'db_key is ' || '''The primary key of the protected database whose backups ' || 'the Recovery Appliance considers eligible for copying to tape.'''; execute immediate 'comment on column ra_sbt_job.' || 'db_unique_name is ' || '''The unique name of the protected database whose backups ' || 'the Recovery Appliance considers eligible for copying to tape.'''; execute immediate 'comment on column ra_sbt_job.' || 'backup_type is ' || '''The types of backups to be copied to tape by this job: ' || 'ALL, ' || 'FULL, ' || 'INCR, ' || 'ARCH, or ' || 'TAPE_RESERVE.'''; execute immediate 'comment on column ra_sbt_job.' || 'from_tag is ' || '''The backups with the specified tag to be copied to tape by this job.'''; execute immediate 'comment on column ra_sbt_job.' || 'priority is ' || '''The priority for scheduling this job.'''; execute immediate 'comment on column ra_sbt_job.' || 'copies is ' || '''The number of copies to be created on tape.'''; execute immediate 'comment on column ra_sbt_job.' || 'last_schedule_time is ' || '''The last time at which this SBT job was scheduled to run.'''; execute immediate 'comment on column ra_sbt_job.' || 'window is ' || '''The time allotted for copy tasks to start for this job.'''; end; >>> define create_rs_sbt_task <<< create or replace view ra_sbt_task (task_id, state, completion_time, elapsed_seconds, execute_instance_id, error_count, error_text, db_unique_name, db_key, restore_task, bs_key, piece#, copies, template_name, attribute_set_name, lib_name, replication, filename, start_time, bytes, total) as with bpnew as (select bs_key, piece#, max(bytes) total from bp where bp.ba_access != 'U' and bp.status != 'D' group by bs_key, piece#) select st.task_id, t.state, t.completion_time, t.elapsed_seconds, t.execute_instance_id, t.error_count, e.error_text, t.db_unique_name, t.db_key, decode(st.restore, 'Y', 'YES', 'NO'), st.bs_key, st.piece#, st.copies, job.template_name, attr.attr_name, lib.lib_name, NVL2(lib.server_key, 'YES', 'NO'), isp.filename, isp.start_time, decode(t.state, 'COMPLETED', bpnew.total, isp.bytes), bpnew.total from ra_task t, sbt_lib_desc lib, (select task_id, restore, bs_key, piece#, copies, lib_key, attr_key, template_key from sbt_task st union all select task_id, restore, bs_key, piece#, copies, lib_key, attr_key, template_key from sbt_task_history sth) st left outer join error_log e on st.task_id = e.task_id and e.status = 'ACTIVE' left outer join sbt_attr_set attr on st.attr_key = attr.attr_key left outer join sbt_job_template job on st.template_key = job.template_key left outer join rai_sbt_performance isp on st.task_id = isp.task_id and st.piece# = isp.piece# and st.bs_key = isp.bs_key left outer join bpnew on st.piece# = bpnew.piece# and st.bs_key = bpnew.bs_key where st.task_id = t.task_id and st.lib_key = lib.lib_key >>> define create_comment_rs_sbt_task <<< begin execute immediate 'comment on table ra_sbt_task is ' || '''This view lists the queued background SBT tasks and their run statuses.'''; execute immediate 'comment on column ra_sbt_task.' || 'task_id is ' || '''The ID for the task.'''; execute immediate 'comment on column ra_sbt_task.' || 'state is ' || '''The processing state for the task: ' || 'EXECUTABLE, ' || 'RUNNING, ' || 'COMPLETED, ' || 'TASK_WAIT, ' || 'FAILED, ' || 'and so on.'''; execute immediate 'comment on column ra_sbt_task.' || 'completion_time is ' || '''The timestamp for task completion. The column is null '|| 'if the task is not complete.'''; execute immediate 'comment on column ra_sbt_task.' || 'elapsed_seconds is ' || '''The elapsed run time (in seconds) for the task.'''; execute immediate 'comment on column ra_sbt_task.' || 'execute_instance_id is ' || '''The ID of the database instance ID on which the task must run. ' || 'The column is null if the task can run on any instance.'''; execute immediate 'comment on column ra_sbt_task.' || 'error_count is '|| '''The number of times that the task had errors.'''; execute immediate 'comment on column ra_sbt_task.' || 'error_text is '|| '''The error text for the task that failed.'''; execute immediate 'comment on column ra_sbt_task.' || 'db_unique_name is ' || '''The unique name of the protected database for which the task is running.'''; execute immediate 'comment on column ra_sbt_task.' || 'db_key is ' || '''The primary key of the protected database for which the task is running.'''; execute immediate 'comment on column ra_sbt_task.' || 'restore_task is ' || '''The type of task: YES if this ' || 'is a restore task; NO if this ' || 'is a backup task.'''; execute immediate 'comment on column ra_sbt_task.' || 'bs_key is ' || '''The key of the backup set that is accessed by this task.'''; execute immediate 'comment on column ra_sbt_task.' || 'piece# is ' || '''The number of the backup piece that is accessed by this task.'''; execute immediate 'comment on column ra_sbt_task.' || 'copies is ' || '''The number of copies created by this task.'''; execute immediate 'comment on column ra_sbt_task.' || 'template_name is ' || '''The SBT job template to which this task belongs.'''; execute immediate 'comment on column ra_sbt_task.' || 'attribute_set_name is ' || '''The name of the SBT attribute set to which this task belongs.'''; execute immediate 'comment on column ra_sbt_task.' || 'lib_name is ' || '''The name of the SBT library used by this task.'''; execute immediate 'comment on column ra_sbt_task.' || 'replication is ' || '''The type of task: YES ' || 'if this is a replication task; ' || 'NO ' || 'if this is an SBT task.'''; execute immediate 'comment on column ra_sbt_task.' || 'filename is ' || '''The name of the backup file being read or written.'''; execute immediate 'comment on column ra_sbt_task.' || 'start_time is ' || '''The start time of this task.'''; execute immediate 'comment on column ra_sbt_task.' || 'bytes is ' || '''The number of bytes read or written so far.'''; execute immediate 'comment on column ra_sbt_task.' || 'total is '|| '''The total number of bytes to be read or written.'''; end; >>> define create_rs_api_history <<< create or replace view ra_api_history as select th.param_char2 results, th.execute_time, tasktypenames.task_type_name task_name, th.param command_issued, ((extract(second from (th.elapsed_time))) + (extract(minute from (th.elapsed_time)) * 60) + (extract(hour from (th.elapsed_time)) * 3600) + (extract(day from (th.elapsed_time)) * 86400) ) elapsed_seconds from task_history th join tasktypenames using (task_type) join (select min(task_type) low, max(task_type) high from tasktypenames where task_type_name like 'API_%') limits ON(1=1) where (task_type between limits.low and limits.high) order by th.execute_time >>> define create_comment_rs_api_history <<< begin execute immediate 'comment on table ra_api_history is ' || '''This view describes the history of user-issued API commands.'''; execute immediate 'comment on column ra_api_history.' || 'results is ' || '''The results from running this command: ' || 'SUCCESS ' || 'or FAIL.'''; execute immediate 'comment on column ra_api_history.' || 'execute_time is ' || '''The time at which the command started.'''; execute immediate 'comment on column ra_api_history.' || 'task_name is ' || '''The name of the task.'''; execute immediate 'comment on column ra_api_history.' || 'command_issued is ' || '''The full command as submitted by the user.'''; execute immediate 'comment on column ra_api_history.' || 'elapsed_seconds is '|| '''The elapsed run time (in seconds) for the task.'''; end; >>> define create_rs_config <<< create or replace view ra_config (name, value) as select config.name, config.value from config where name not like '\_%' escape '\' and name <> 'compatible' order by config.name >>> define create_comment_rs_config <<< begin execute immediate 'comment on table ra_config is ' || '''This view lists the user configuration settings.'''; execute immediate 'comment on column ra_config.' || 'name is ' || '''The name of the configuration variable.'''; execute immediate 'comment on column ra_config.' || 'value is ' || '''The value of the configuration variable'''; end; >>> define create_rs_replication_server <<< create or replace view ra_replication_server (replication_server_name, replication_server_state, protection_policy, rep_server_connect_name, proxy_http_address, proxy_timeout, sbt_library_name, sbt_library_parms, attribute_name, attribute_parms, wallet_path, wallet_alias, server_host) as select s.rep_server_name, decode(r.status, 'C', 'CREATING', 'D', 'DELETING', 'T', 'TESTING COMMUNICATION', 'A', decode(l.status, 'R', 'RUNNING', 'P', 'PAUSED', 'E', 'ERROR', NULL), NULL), p.prot_name, s.filter_user, NVL2(s.proxy_port, s.proxy_url || ':' || TO_CHAR(s.proxy_port, 'FM99999'), s.proxy_url), s.timeout_secs, l.lib_name, l.parms, a.attr_name, a.parms, s.wallet_path, s.wallet_alias, s.server_host from server s join sbt_lib_desc l on l.server_key=s.server_key join sbt_attr_set a on a.lib_key=l.lib_key left outer join rep_server r on s.server_key=r.server_key left outer join prot p on r.prot_key = p.prot_key order by p.prot_name, s.rep_server_name >>> define create_comment_rs_replication_server <<< begin execute immediate 'comment on table ra_replication_server is ' || '''This view lists the replication server configurations.'''; execute immediate 'comment on column ra_replication_server.' || 'replication_server_name is ' || '''The user-assigned name of the replication server configuration.'''; execute immediate 'comment on column ra_replication_server.' || 'replication_server_state is ' || '''The replication status of the downstream Recovery Appliance: ' || 'AVAILABLE, ' || 'CREATING, ' || 'DELETING, ' || 'TESTING COMMUNICATION, ' || 'or null.'''; execute immediate 'comment on column ra_replication_server.' || 'protection_policy is ' || '''The protection policy associated with this replication server' || ' configuration.'''; execute immediate 'comment on column ra_replication_server.' || 'rep_server_connect_name is ' || '''The user name used to connect to the downstream Recovery Appliance.'''; execute immediate 'comment on column ra_replication_server.' || 'proxy_http_address is ' || '''The address of the proxy server in the form ' || 'proxy_server_http_address:port_' || 'of_proxy_server.'''; execute immediate 'comment on column ra_replication_server.' || 'proxy_timeout is ' || '''The timeout period for the proxy server connection.'''; execute immediate 'comment on column ra_replication_server.' || 'sbt_library_name is ' || '''The name of the SBT library with which this replication server ' || 'configuration is associated.'''; execute immediate 'comment on column ra_replication_server.' || 'sbt_library_parms is ' || '''The SBT library parameters.'''; execute immediate 'comment on column ra_replication_server.' || 'attribute_name is '|| '''The SBT attribute set name.'''; execute immediate 'comment on column ra_replication_server.' || 'attribute_parms is ' || '''The SBT parameters passed while allocating the RMAN channel.'''; execute immediate 'comment on column ra_replication_server.' || 'wallet_path is ' || '''The path to the local Oracle wallet (excluding the wallet file name).'''; execute immediate 'comment on column ra_replication_server.' || 'wallet_alias is ' || '''The alias that identifies the Oracle wallet credentials ' || 'that this Recovery Appliance uses to log in to the downstream Recovery Appliance.'''; execute immediate 'comment on column ra_replication_server.' || 'server_host is ' || '''The server name or address of the downstream Recovery Appliance.'''; end; >>> define create_rs_incident_log <<< create or replace view ra_incident_log (incident_id, error_code, parameter, error_text, sl_key, sl_name, db_key, db_unique_name, task_id, status, component, severity, first_seen, last_seen, seen_count) as select incident#, error_num, NVL(param_char, TO_CHAR(param_num)), error_text, sl.sl_key, sl.sl_name, error_log.db_key, db.reg_db_unique_name, task_id, status, component, DECODE (severity, 1, 'WARNING', 10, 'ERROR', 20, 'INTERNAL', 'INVALID' || TO_CHAR(severity)), first_seen, last_seen, seen_count from error_log left outer join sl on error_log.sl_key = sl.sl_key left outer join db on db.db_key = error_log.db_key >>> define create_comment_rs_incident_log <<< begin execute immediate 'comment on table ra_incident_log is ' || '''This view describes the Recovery Appliance incidents.'''; execute immediate 'comment on column ra_incident_log.' || 'incident_id is ' || '''The unique ID for the incident.'''; execute immediate 'comment on column ra_incident_log.' || 'error_code is ' || '''The Oracle error code for the message describing the incident.'''; execute immediate 'comment on column ra_incident_log.' || 'parameter is ' || '''The parameter qualifying the scope of the error code.'''; execute immediate 'comment on column ra_incident_log.' || 'error_text is ' || '''The text of the message for the last detection of this error condition.'''; execute immediate 'comment on column ra_incident_log.' || 'sl_key is ' || '''Primary key of the storage location (if any) involved in this incident'''; execute immediate 'comment on column ra_incident_log.' || 'sl_name is ' || '''The primary key of the Recovery Appliance storage location (if any) ' || 'involved in this incident.'''; execute immediate 'comment on column ra_incident_log.' || 'db_key is ' || '''The primary key of the protected database (if any) involved in this incident.'''; execute immediate 'comment on column ra_incident_log.' || 'db_unique_name is ' || '''The unique name of the protected database (if any) involved in this incident.'''; execute immediate 'comment on column ra_incident_log.' || 'task_id is ' || '''The ID for the task (if any) in which this incident was detected.'''; execute immediate 'comment on column ra_incident_log.' || 'status is ' || '''The status of this incident: ACTIVE, ' || 'FIXED, or ' || 'RESET.'''; execute immediate 'comment on column ra_incident_log.' || 'component is ' || '''The component of the Recovery Appliance detecting this incident.'''; execute immediate 'comment on column ra_incident_log.' || 'severity is ' || '''The importance of this incident to the smooth operation of the ' || 'Recovery Appliance.'''; execute immediate 'comment on column ra_incident_log.' || 'first_seen is ' || '''The timestamp when the Recovery Appliance first detected the incident.'''; execute immediate 'comment on column ra_incident_log.' || 'last_seen is ' || '''The timestamp when the Recovery Appliance most recently detected the incident.'''; execute immediate 'comment on column ra_incident_log.' || 'seen_count is ' || '''The number of times that the Recovery Appliance detected the incident.'''; end; >>> define create_rs_incoming_backup_pieces <<< create or replace view ra_incoming_backup_pieces (sl_key, sl_name, db_key, db_unique_name, handle, current_size, last_update) as select sl.sl_key, sl.sl_name, sbt_catalog.db_key, db.reg_db_unique_name, handle, filesize/(1024*1024*1024), last_entry from sbt_catalog left outer join sl on sbt_catalog.sl_key = sl.sl_key left outer join db on db.db_key = sbt_catalog.db_key where completed = 'N' union all /* Polling pieces */ select sl.sl_key, sl.sl_name, task.db_key, db.reg_db_unique_name, bp.handle, bp.bytes/(1024*1024*1024), nvl(task.last_execute_time,task.schedule_time) from task left outer join db on db.db_key = task.db_key, bp, odb, sl where task.task_type = 140 /* task_index_backup */ and bitand(task.flags,16) = 16 /* tasks_polled_input */ and task.param_num1 = bp.bp_key and task.db_key = odb.db_key and odb.sl_key = sl.sl_key >>> define create_comment_rs_incoming_backup_pieces <<< begin execute immediate 'comment on table ra_incoming_backup_pieces is ' || '''This view describes the backup pieces being received by the Recovery Appliance.'''; execute immediate 'comment on column ra_incoming_backup_pieces.' || 'sl_key is ' || '''The primary key of the Recovery Appliance storage location storing this ' || 'backup piece.'''; execute immediate 'comment on column ra_incoming_backup_pieces.' || 'sl_name is ' || '''The name of the Recovery Appliance storage location storing this backup piece.'''; execute immediate 'comment on column ra_incoming_backup_pieces.' || 'db_key is ' || '''The primary key of the protected database creating this backup piece.'''; execute immediate 'comment on column ra_incoming_backup_pieces.' || 'db_unique_name is ' || '''The unique name of the protected database creating this backup piece.'''; execute immediate 'comment on column ra_incoming_backup_pieces.' || 'handle is ' || '''The handle assigned to this backup piece.'''; execute immediate 'comment on column ra_incoming_backup_pieces.' || 'current_size is ' || '''The size (in GB) currently allocated for this backup piece.'''; execute immediate 'comment on column ra_incoming_backup_pieces.' || 'last_update is ' || '''The time when the backup piece was completely received.'''; end; >>> define create_avm_em_sbt_job <<< CREATE OR REPLACE VIEW ra_em_sbt_job_template AS WITH j AS ( SELECT /*+ LEADING(l a j h p) */ j.template_key , j.template_name , h.template_name full_template_name , a.attr_name , l.lib_name , p.prot_name , j.db_key , j.bck_type , j.from_tag , j.priority , j.copies , j.window , l.status lib_status FROM sbt_lib_desc l , sbt_attr_set a , sbt_job_template j , sbt_job_template h , prot p WHERE l.lib_key = a.lib_key AND j.attr_key = a.attr_key AND l.server_key IS NULL AND j.full_template_key = h.template_key AND p.prot_key(+) = j.prot_key ) , backupio AS ( SELECT sid, serial, inst_id, bytes FROM gv$backup_sync_io WHERE type = 'OUTPUT' AND filename is not null AND status = 'IN PROGRESS' AND device_type = 'SBT_TAPE' UNION ALL SELECT sid, serial, inst_id, bytes FROM gv$backup_async_io WHERE type = 'OUTPUT' AND filename is not null AND status = 'IN PROGRESS' AND device_type = 'SBT_TAPE' ) , isp AS ( SELECT s.current_task task_id, v.bytes bytes FROM backupio v , sessions s WHERE s.sid = v.sid AND s.serial# = v.serial AND s.instance_id = v.inst_id ) , ct AS ( SELECT template_key , MIN(error_text) KEEP ( DENSE_RANK LAST ORDER BY last_seen NULLS FIRST ) error_text , MAX(last_seen) error_last_seen , COUNT(executable) executable , COUNT(running) running , COUNT(completed) completed , MAX(ct) completion_time , SUM(bytes) bytes FROM ( SELECT /*+ LEADING(l st t e) USE_HASH(st) USE_HASH(t) USE_HASH(e) USE_HASH(isp) */ template_key , completion_time ct , DECODE(state, 1, 1) executable , DECODE(state, 2, 1) running , DECODE(state, 3, 1) completed , error_text , last_seen , bytes FROM sbt_lib_desc l , sbt_task st , task t LEFT OUTER JOIN error_log e ON e.task_id = t.task_id AND e.status = 'ACTIVE' LEFT OUTER JOIN isp ON t.task_id = isp.task_id WHERE l.server_key IS NULL AND l.lib_key = st.lib_key AND st.task_id = t.task_id UNION ALL SELECT /*+ LEADING(l st t e) USE_HASH(st) USE_HASH(t) USE_HASH(e) */ template_key , completion_time , NULL , NULL , DECODE(state , 8, CAST(NULL AS NUMBER) , 1 ) completed , error_text , last_seen , 0 FROM sbt_lib_desc l , sbt_task_history st , task_history t LEFT OUTER JOIN error_log e ON e.task_id = t.task_id AND e.status = 'ACTIVE' WHERE l.server_key IS NULL AND l.lib_key = st.lib_key AND st.task_id = t.task_id AND t.task_type < 2000 AND completion_time >= SYSTIMESTAMP - INTERVAL '24' HOUR ) GROUP BY template_key ) , t AS ( SELECT /*+ LEADING(j) USE_HASH(ct) */ template_name , full_template_name , prot_name , db_key , attr_name , lib_name , bck_type , priority , copies , window , from_tag , error_text , error_last_seen , executable , running , completed , completion_time , lib_status , bytes FROM j , ct WHERE ct.template_key(+) = j.template_key ) , d AS ( SELECT /*+ PUSH_PRED */ db_key , db_unique_name , ROW_NUMBER() OVER ( PARTITION BY db_key ORDER BY database_role , db_unique_name ) rn FROM node WHERE db_unique_name NOT LIKE '%$%' ) SELECT template_name , full_template_name , prot_name policy_name , db_unique_name , attr_name attribute_set_name , lib_name , CASE bck_type WHEN 1 THEN 'ALL' WHEN 2 THEN 'FULL' WHEN 4 THEN 'INCR' WHEN 6 THEN 'FULL, INCR' WHEN 8 THEN 'ARCH' WHEN 10 THEN 'FULL, ARCH' WHEN 12 THEN 'INCR, ARCH' WHEN 14 THEN 'FULL, INCR, ARCH' WHEN 32 THEN 'TAPE RESERVE' ELSE '?' END backup_type , priority , copies , window , from_tag , error_text , error_last_seen , executable , running , completed , completion_time , DECODE(lib_status , 'R', 'READY' , 'P', 'PAUSE' , 'E', 'ERROR' ) status , bytes FROM t , d WHERE d.db_key(+) = t.db_key AND d.rn(+) = 1 >>> define create_comment_avm_em_sbt_job <<< begin execute immediate 'comment on table ra_em_sbt_job_template is ' || '''This view lists defined SBT jobs and their statuses for ' || 'Oracle Enterprise Manager.'''; execute immediate 'comment on column ra_em_sbt_job_template.' || 'template_name is ' || '''The name of the SBT job template.'''; execute immediate 'comment on column ra_em_sbt_job_template.' || 'full_template_name is ' || '''The full name of the SBT job template.'''; execute immediate 'comment on column ra_em_sbt_job_template.' || 'policy_name is ' || '''The protection policy specifying the protected databases whose ' || 'backups the Recovery Appliance considers eligible for copying.'''; execute immediate 'comment on column ra_em_sbt_job_template.' || 'db_unique_name is ' || '''The unique name of the protected database whose ' || 'backups the Recovery Appliance considers eligible for copying.'''; execute immediate 'comment on column ra_em_sbt_job_template.' || 'attribute_set_name is ' || '''The name of the SBT attribute set.'''; execute immediate 'comment on column ra_em_sbt_job_template.' || 'lib_name is ' || '''The name of the SBT library.'''; execute immediate 'comment on column ra_em_sbt_job_template.' || 'backup_type is ' || '''The types of backups to be copied to tape by this job: ' || 'ALL, ' || 'FULL, ' || 'INCR, ' || 'ARCH, or ' || 'TAPE_RESERVE.'''; execute immediate 'comment on column ra_em_sbt_job_template.' || 'priority is ' || '''The priority for scheduling this job.'''; execute immediate 'comment on column ra_em_sbt_job_template.' || 'copies is ' || '''The number of copies to be created on tape.'''; execute immediate 'comment on column ra_em_sbt_job_template.' || 'window is ' || '''The time allotted for copy tasks to start for this job.'''; execute immediate 'comment on column ra_em_sbt_job_template.' || 'from_tag is ' || '''The tag for the backup to be copied to tape by this job.'''; execute immediate 'comment on column ra_em_sbt_job_template.' || 'error_text is '|| '''The error text for the task that failed.'''; execute immediate 'comment on column ra_em_sbt_job_template.' || 'error_last_seen is ' || '''The timestamp when the Recovery Appliance most recently detected the error.'''; execute immediate 'comment on column ra_em_sbt_job_template.' || 'executable is ' || '''The number of tasks in an executable state.'''; execute immediate 'comment on column ra_em_sbt_job_template.' || 'running is ' || '''The number of tasks that are running or retrying.'''; execute immediate 'comment on column ra_em_sbt_job_template.' || 'completed is ' || '''The number of completed tasks.'''; execute immediate 'comment on column ra_em_sbt_job_template.' || 'completion_time is ' || '''The time of the most recent completed task.'''; execute immediate 'comment on column ra_em_sbt_job_template.' || 'status is ' || '''The status of the SBT library: ' || 'READY, ' || 'PAUSE, or ' || 'ERROR.'''; execute immediate 'comment on column ra_em_sbt_job_template.' || 'bytes is ' || '''The number of bytes read or written so far.'''; end; >>> define create_am_catalog_select <<< DECLARE l_role CONSTANT VARCHAR2(128) := 'RA_CATALOG_SELECT'; l_privileges CONSTANT VARCHAR2(128) := 'SELECT'; l_user CONSTANT VARCHAR2(128) := 'DBSNMP'; e_role_already_exist EXCEPTION; PRAGMA EXCEPTION_INIT(e_role_already_exist, -1921); e_user_or_role_doesnt_exist EXCEPTION; PRAGMA EXCEPTION_INIT(e_user_or_role_doesnt_exist, -1917); e_insufficient_privileges EXCEPTION; PRAGMA EXCEPTION_INIT(e_insufficient_privileges, -1031); BEGIN BEGIN EXECUTE IMMEDIATE 'CREATE ROLE ' || l_role; EXCEPTION WHEN e_role_already_exist THEN NULL; END; -- -- -- FOR i IN ( SELECT view_name FROM user_views WHERE view_name LIKE 'RA\_%' ESCAPE '\' OR view_name LIKE 'RC\_%' ESCAPE '\' OR view_name = 'RAI_RECWINGOAL_SCN' OR view_name = 'RAI_MAXRECWIN_STAMP' ) LOOP EXECUTE IMMEDIATE 'CREATE OR REPLACE PUBLIC SYNONYM ' || i.view_name || ' FOR ' || i.view_name; EXECUTE IMMEDIATE 'GRANT ' || l_privileges || ' ON ' || i.view_name || ' TO ' || l_role; END LOOP; BEGIN EXECUTE IMMEDIATE 'GRANT ' || l_role || ' TO ' || l_user; EXCEPTION WHEN e_user_or_role_doesnt_exist THEN NULL; WHEN e_insufficient_privileges THEN NULL; END; -- EXECUTE IMMEDIATE 'GRANT select ON rai_recwingoal_scn TO public'; EXECUTE IMMEDIATE 'GRANT select ON rai_maxrecwin_stamp TO public'; -- EXECUTE IMMEDIATE 'GRANT select ON ra_server TO public'; END; >>> define create_am_host <<< create or replace view rai_host (node_name, admin_ip_address, backup_ip_address, replication_ip_address) as select node_name, admin_ip_address, backup_ip_address, replication_ip_address from host >>> define drop_rai_FullRecSet_t <<< drop type rai_FullRecSet_t >>> define drop_rai_FullRec_t <<< drop type rai_FullRec_t >>> define rai_FullRec_t <<< create or replace type rai_FullRec_t authid current_user as object ( db_key NUMBER, df_file# NUMBER, df_ts# NUMBER, df_plugin_change# NUMBER, df_foreign_dbid NUMBER, df_tablespace VARCHAR2(30), df_creation_change# NUMBER, backup_type VARCHAR2(32), file_type VARCHAR2(32), bs_key NUMBER, df_checkpoint_change# NUMBER ) >>> define rai_FullRecSet_t <<< create or replace type rai_FullRecSet_t as table of rai_FullRec_t >>> define drop_rai_FullRecSetImpl_t <<< drop type rai_FullRecSetImpl_t >>> define rai_FullRecSetImpl_t <<< create or replace type rai_FullRecSetImpl_t authid current_user as object ( curval number, -- current rownum done number, -- done with the query needobsolete number, -- user interested in obsolete col static function ODCITableStart(sctx IN OUT rai_FullRecSetImpl_t) return number, member function ODCITableFetch(self IN OUT rai_FullRecSetImpl_t, nrows IN number, objSet OUT rai_FullRecSet_t) return number, member function ODCITableClose(self IN rai_FullRecSetImpl_t) return number ) >>> define bai_FullRecSetImplbody_t <<< create or replace type body rai_FullRecSetImpl_t is -- -- -- static function ODCITableStart(sctx IN OUT rai_FullRecSetImpl_t) return number is begin -- sctx:=rai_FullRecSetImpl_t(0, 0, 1); return SYS.ODCIConst.Success; end ODCITableStart; -- -- -- -- member function ODCITableFetch(self IN OUT rai_FullRecSetImpl_t, nrows IN number, objSet OUT rai_FullRecSet_t) return number is n number := 0; firstCall boolean := TRUE; ret boolean := TRUE; redundancy number; baseline_cap number := 0; lbRec dbms_rcvman.lbrec_t; lbCursor dbms_rcvman.lbCursor_t; lbState dbms_rcvman.lbState_t; begin objSet := rai_FullRecSet_t(); -- dbms_rcvman.setAllIncarnations(TRUE); select GREATEST(nvl(max(value), 0), 0) into baseline_cap from config where name = '_baseline_cap'; -- if (baseline_cap > 0) then dbms_rcvman.setUntilTime(SYSDATE - baseline_cap); end if; dbms_rcvman.setFirstFullBckScopeAttributes(baseline_cap); while ret and self.done = 0 loop ret := dbms_rcvman.listBackup(lbRec, firstCall, FALSE, redundancy, TRUE, lbCursor, lbState, null); if (lbRec.df_file# is not null) then objSet.extend; n := n + 1; objSet(n):= rai_FullRec_t( to_char(null), -- db_key to_number(null), -- df_file# to_number(null), -- df_ts# to_number(null), -- df_plugin_change# to_number(null), -- df_foreign_dbid to_char(null), -- df_tablespace to_number(null), -- df_creation_change# to_char(null), -- backup_type to_char(null), -- file_type to_number(null), -- bs_key to_number(null)); -- df_checkpoint_change# objSet(n).db_key := dbms_rcvman.getDbKey; objSet(n).df_file# := lbRec.df_file#; objSet(n).df_ts# := lbRec.df_ts#; objSet(n).df_plugin_change# := lbRec.df_plugin_change#; objSet(n).df_foreign_dbid := lbRec.df_foreign_dbid; objSet(n).df_tablespace := lbRec.df_tablespace; objSet(n).df_creation_change# := lbRec.df_creation_change#; objSet(n).backup_type := lbRec.backup_type; objSet(n).file_type := lbRec.file_type; objSet(n).bs_key := lbRec.bs_key; objSet(n).df_checkpoint_change# := lbRec.df_checkpoint_change#; end if; firstCall := false; self.curval:=self.curval+1; if not ret then self.done := 1; end if; end loop; dbms_rcvman.setFirstFullBckScopeAttributes(null); return SYS.ODCIConst.Success; end ODCITableFetch; member function ODCITableClose(self IN rai_FullRecSetImpl_t) return number is begin return SYS.ODCIConst.Success; end ODCITableClose; end; >>> define drop_bai_listFullBackupPipe <<< drop function bai_listFullBackupPipe >>> define bai_listFullBackupPipe <<< CREATE OR REPLACE FUNCTION bai_listFullBackupPipe RETURN rai_FullRecSet_t AUTHID DEFINER PIPELINED using rai_FullRecSetImpl_t; >>> define grant_bai_listFullBackupPipe <<< grant execute on bai_listFullBackupPipe to public >>> define create_rai_full_backup_files <<< create or replace view rai_full_backup_files as select db_key, df_file#, df_ts#, df_plugin_change#, df_foreign_dbid, df_tablespace, df_creation_change#, backup_type, file_type, bs_key, df_checkpoint_change# from TABLE(bai_listFullBackupPipe) >>> define create_ra_sbt_template_mdf <<< create or replace view ra_sbt_template_mdf as select stf.template_key, stf.db_key, d.reg_db_unique_name db_unique_name, stf.df_file#, stf.df_ts#, stf.df_plugin_change#, stf.df_foreign_dbid, stf.df_tablespace, stf.df_creation_change# from sbt_template_df stf, db d where d.db_key = stf.db_key and stf.bs_key IS NULL >>> define create_comment_ra_sbt_template_mdf <<< begin execute immediate 'comment on table ra_sbt_template_mdf is ' || '''This view lists missing level 0 data file backups for each SBT template.'''; execute immediate 'comment on column ra_sbt_template_mdf.' || 'template_key is ' || '''The key identifying the SBT template.'''; execute immediate 'comment on column ra_sbt_template_mdf.' || 'db_key is ' || '''The key for the protected database that contains the missing file.'''; execute immediate 'comment on column ra_sbt_template_mdf.' || 'db_unique_name is ' || '''The unique name of the database that contains the missing data file.'''; execute immediate 'comment on column ra_sbt_template_mdf.' || 'df_file# is ' || '''The number of the missing data file.'''; execute immediate 'comment on column ra_sbt_template_mdf.' || 'df_ts# is ' || '''The tablespace number of the missing data file.'''; execute immediate 'comment on column ra_sbt_template_mdf.' || 'df_plugin_change# is ' || '''The plugin SCN for the missing data file.'''; execute immediate 'comment on column ra_sbt_template_mdf.' || 'df_foreign_dbid is ' || '''The foreign DBID for the database that contains the missing data file.'''; execute immediate 'comment on column ra_sbt_template_mdf.' || 'df_tablespace is ' || '''The tablespace that contains the missing data file.'''; execute immediate 'comment on column ra_sbt_template_mdf.' || 'df_creation_change# is ' || '''The creation SCN for the missing data file.'''; end; >>> define drop_rai_full_backup_files <<< DROP VIEW rai_full_backup_files >>> define drop_ra_sbt_template_mdf <<< DROP VIEW ra_sbt_template_mdf >>> define delete_from_config <<< begin delete from config where name <> 'compatible'; commit; end; >>> define setup_ors_defaults <<< declare procedure ra_config_insert(name in config.name%TYPE, value in config.value%TYPE ) is begin merge into config using dual on (name = ra_config_insert.name) when not matched then insert (name, value) values (ra_config_insert.name, ra_config_insert.value); end; begin ra_config_insert('_enable_populate_rsr_key', 1); ra_config_insert('_waitfordbfs', NULL); ra_config_insert('_dbfs_time_out_days', 5*1/24/60); ra_config_insert('_last_incarnation', NULL); ra_config_insert('_def_contfilesize', '2t'); ra_config_insert('_spare_asm_disks', '2'); ra_config_insert('_compress', 'YES'); ra_config_insert('_alg_over_alloc', 125); ra_config_insert('_piece_affinity', 'YES'); ra_config_insert('_recovery_appliance_state', 'OFF'); ra_config_insert('_def_min_alloc', 4 * 1024 * 1024); ra_config_insert('_chunk_cache', 512); ra_config_insert('_chunkno_alloc', 1024); ra_config_insert('network_chunksize', 128 * 1024 * 1024); ra_config_insert('_alloc_increment', 4.0 * 1024 * 1024 * 1024); ra_config_insert('_purging_reserve', 4 * 1024 * 1024 * 100); ra_config_insert('_purge_wait', 15); ra_config_insert('_purge_autoshrink', .1); ra_config_insert('_quiesce_wait', 15); ra_config_insert('_quiesce_session_wait_days', 5/24/60); ra_config_insert('_interrupt_wait', 20); ra_config_insert('_lock_refused_wait', 5); ra_config_insert('_purge_threshold', .9); ra_config_insert('_scheduling_wait', 5); ra_config_insert('_sched_run_wait', 5); ra_config_insert('_sched_sleep_wait', 5); ra_config_insert('_sched_icd_wait', 5*60); ra_config_insert('_sched_max_locktime', 5*60); ra_config_insert('_timer_loop_sleep_seconds', 15); ra_config_insert('_histogram_slot_days', 1/24*3); ra_config_insert('_histogram_cycle_slots', 365*24/3); ra_config_insert('_histogram_window_slots', 30*24/3); ra_config_insert('_histogram_goal_percentile', .95); ra_config_insert('_initial_freespace_ratio', .05); ra_config_insert('_min_freespace_ratio', .01); ra_config_insert('_task_maintenance_days', 1/24/60 * 5); ra_config_insert('_storage_maintenance_days', 1/24/60 * 60); ra_config_insert('_obsolete_sbt_days', 1); ra_config_insert('_default_poll_frequency_days', 1/24); ra_config_insert('_polling_timeout_days', 1/24/60 * 90); ra_config_insert('_polling_del_files_check_days', 1); ra_config_insert('_history_partition_days', 1); ra_config_insert('_history_retention', 30); ra_config_insert('_rm_incomplete_files_days', 10 * 1/24/60); ra_config_insert('_expire_files_days', 1/24/60 * 90); ra_config_insert('_max_task_restarts', 10); ra_config_insert('_interrupt_max', 300); ra_config_insert('_busy_interrupt_max', 500); ra_config_insert('optimize_chunks_days', 7); ra_config_insert('_optimize_space_limit', 1/10); ra_config_insert('validate_db_days', 14); ra_config_insert('check_files_days', 14); ra_config_insert('percent_late_for_warning', 50); ra_config_insert('_orphan_file_wait_days', 1/24/60 * 5); ra_config_insert('_restricted_session_count', 5); ra_config_insert('_min_sessions_for_busywork', 4); ra_config_insert('_busywork_inhibit_time', 5*1/24/60); ra_config_insert('_fragmentation', 10); ra_config_insert('_reconcile_short_delay_days', 1/24 * 1); ra_config_insert('_reconcile_long_delay_days', 1); ra_config_insert('_trim_factor', 2); ra_config_insert('_defer_delete', 'NO'); ra_config_insert('_trace_file_days', 3/24); ra_config_insert('_dumper_last_dump_timestamp', to_char(systimestamp-365, 'dd-mm-rr hh24:mi:ss')); ra_config_insert('_dumper_inhibit_days', 1); ra_config_insert('_dumper_params', 'NODATAPUMP,NOBLOCKS,NOCHUNKS'); ra_config_insert('_dumper_file_ext', '.dat'); ra_config_insert('_check_sbtsched_days',1/24/60*30); ra_config_insert('_max_sbt_failures', 25); ra_config_insert('crosscheck_db_days', 1); ra_config_insert('_crosscheck_throttle', 5); ra_config_insert('_servlet_wait_seconds', 512); ra_config_insert('_replication_streams_per_node', 4); ra_config_insert('_replication_min_streams', 4); ra_config_insert('_replication_max_streams', 64); ra_config_insert('_api_lock_wait_seconds', 30); ra_config_insert('_db_stats_refresh_days', 10/24/60); ra_config_insert('_throttle_max_channels', 1000); ra_config_insert('_throttle_threshold_channels', 872); ra_config_insert('_throttle_wait_aft_apprvl_secs', 300); ra_config_insert('_throttle_wait_for_crash_secs', 1800); ra_config_insert('_throttle_sbt_active_hours', 12); ra_config_insert('_throttle_max_single_chan_req', 128); ra_config_insert('_throttle_wait_repeat_req_secs', 300); ra_config_insert('_incident_alert_threshold', dbms_ra_scheduler.severity_error); ra_config_insert('_incident_dump_threshold', dbms_ra_scheduler.severity_internal); ra_config_insert('_resumable_timeout', 86400); ra_config_insert('_baseline_cap', 14); ra_config_insert('_resource_wait_timeout_days', 15*1/24/60); ra_config_insert('_resource_wait_relax_rate', 150/100); ra_config_insert('_resource_wait_task_limit', dbms_ra_scheduler.max_resource_wait_processes); ra_config_insert('_aggressive_delete' , 'YES'); ra_config_insert('_stall_when' , 'OFF'); ra_config_insert('_debug_when' , 0); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ra_config_insert('_debug_error', TO_NUMBER('F0047CE6','XXXXXXXX')); ra_config_insert('_purge_opt_free' , 4); ra_config_insert('_purge_opt_pct' , 0.5); ra_config_insert('_plans_maintained' , 5); ra_config_insert('_part_threshold' , 0.40); ra_config_insert('_part_index_style' , 1); ra_config_insert('_part_index_size' , 1.5 * 1024 * 1024 * 1024); ra_config_insert('_nzdl_is_alive_days', 10 *1/24/60); ra_config_insert('_sbt_library_home', '?/lib'); ra_config_insert('_c2t_optimization', 'ON'); ra_config_insert('_ra_pool_freespace_threshold', .01); ra_config_insert('_ra_pool_full_free_count', 10); ra_config_insert('_ordering_wait_timeout_days', 2); commit; end; >>> define delete_old_config_entries <<< begin delete from config where name IN ('_reserve_backup_drives', '_drive_reserve_minutes', '_drive_wait_minutes' ); commit; end; >>> define upg_task_interval <<< alter table task modify (elapsed_time interval day(9) to second(6)) >>> define upg_task_sessions <<< alter table task add constraint task_f2 foreign key(ba_session_id) references sessions >>> define upg_task_history_interval <<< alter table task_history modify (elapsed_time interval day(9) to second(6)) >>> define upg_timer_task_interval <<< alter table timer_task modify (timer_interval interval day(9) to second(6)) >>> define upg_ors_defaults <<< begin -- update config set value = case upper(value) when 'ON' then '1' -- Force KBRSTRC_ERROR when 'OFF' then '0' else value end where name = '_debug_when'; commit; end; >>> define upg_odb_stats_cache_nzdl <<< alter table odb_stats_cache add (nzdl_active varchar2(3)) >>> define upg_task_creator <<< alter table task add (creator_task_id number, creator_sid number, creator_instance number) >>> define upg_task_history_creator <<< alter table task_history add (creator_task_id number, creator_sid number, creator_instance number) >>> define prvtrsi_plb <<< CREATE OR REPLACE PACKAGE BODY dbms_ra_int IS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- /*-------------------------* * v$ table definition * *-------------------------*/ type backup_set_t is record ( RECID NUMBER , STAMP NUMBER , SET_STAMP NUMBER , SET_COUNT NUMBER , BACKUP_TYPE VARCHAR2(1) , CONTROLFILE_INCLUDED VARCHAR2(3) , INCREMENTAL_LEVEL NUMBER , PIECES NUMBER , START_TIME DATE , COMPLETION_TIME DATE , ELAPSED_SECONDS NUMBER , BLOCK_SIZE NUMBER , INPUT_FILE_SCAN_ONLY VARCHAR2(3) , KEEP VARCHAR2(3) , KEEP_UNTIL DATE , KEEP_OPTIONS VARCHAR2(13) , MULTI_SECTION VARCHAR2(3) , GUID RAW(16) ); type backup_piece_t is record ( RECID NUMBER, STAMP NUMBER, SET_STAMP NUMBER, SET_COUNT NUMBER, PIECE# NUMBER, COPY# NUMBER, DEVICE_TYPE VARCHAR2(17), HANDLE VARCHAR2(513), COMMENTS VARCHAR2(81), MEDIA VARCHAR2(65), MEDIA_POOL NUMBER, CONCUR VARCHAR2(3), TAG VARCHAR2(32), STATUS VARCHAR2(1), DELETED VARCHAR2(3), START_TIME DATE, COMPLETION_TIME DATE, ELAPSED_SECONDS NUMBER, BYTES NUMBER, IS_RECOVERY_DEST_FILE VARCHAR2(3), RMAN_STATUS_RECID NUMBER, RMAN_STATUS_STAMP NUMBER, COMPRESSED VARCHAR2(3), BACKED_BY_VSS VARCHAR2(3), ENCRYPTED VARCHAR2(3), BACKED_BY_OSB VARCHAR2(3), GUID RAW(16) ); type backup_datafile_t is record ( RECID NUMBER, STAMP NUMBER, SET_STAMP NUMBER, SET_COUNT NUMBER, FILE# NUMBER, CREATION_CHANGE# NUMBER, CREATION_TIME DATE, RESETLOGS_CHANGE# NUMBER, RESETLOGS_TIME DATE, INCREMENTAL_LEVEL NUMBER, INCREMENTAL_CHANGE# NUMBER, CHECKPOINT_CHANGE# NUMBER, CHECKPOINT_TIME DATE, ABSOLUTE_FUZZY_CHANGE# NUMBER, MARKED_CORRUPT NUMBER, MEDIA_CORRUPT NUMBER, LOGICALLY_CORRUPT NUMBER, DATAFILE_BLOCKS NUMBER, BLOCKS NUMBER, BLOCK_SIZE NUMBER, OLDEST_OFFLINE_RANGE NUMBER, COMPLETION_TIME DATE, CONTROLFILE_TYPE VARCHAR2(1), USED_CHANGE_TRACKING VARCHAR2(3), BLOCKS_READ NUMBER, USED_OPTIMIZATION VARCHAR2(3), FOREIGN_DBID NUMBER, PLUGGED_READONLY VARCHAR2(3), PLUGIN_CHANGE# NUMBER, PLUGIN_RESETLOGS_CHANGE# NUMBER, PLUGIN_RESETLOGS_TIME DATE, SECTION_SIZE NUMBER, UNDO_OPTIMIZED VARCHAR2(3), BLOCKS_SKIPPED_IN_CELL NUMBER, GUID RAW(16) ); type backup_redolog_t is record ( RECID NUMBER, STAMP NUMBER, SET_STAMP NUMBER, SET_COUNT NUMBER, THREAD# NUMBER, SEQUENCE# NUMBER, RESETLOGS_CHANGE# NUMBER, RESETLOGS_TIME DATE, FIRST_CHANGE# NUMBER, FIRST_TIME DATE, NEXT_CHANGE# NUMBER, NEXT_TIME DATE, BLOCKS NUMBER, BLOCK_SIZE NUMBER, TERMINAL VARCHAR2(3), ACTIVATION VARCHAR2(1) ); type backup_spfile_t is record ( RECID NUMBER, STAMP NUMBER, SET_STAMP NUMBER, SET_COUNT NUMBER, MODIFICATION_TIME DATE, BYTES NUMBER, COMPLETION_TIME DATE, DB_UNIQUE_NAME node.db_unique_name%TYPE, GUID RAW(16) ); type archived_log_t is record ( RECID NUMBER, STAMP NUMBER, NAME VARCHAR2(513), DEST_ID NUMBER, THREAD# NUMBER, SEQUENCE# NUMBER, RESETLOGS_CHANGE# NUMBER, RESETLOGS_TIME DATE, RESETLOGS_ID NUMBER, FIRST_CHANGE# NUMBER, FIRST_TIME DATE, NEXT_CHANGE# NUMBER, NEXT_TIME DATE, BLOCKS NUMBER, BLOCK_SIZE NUMBER, CREATOR VARCHAR2(7), REGISTRAR VARCHAR2(7), STANDBY_DEST VARCHAR2(3), ARCHIVED VARCHAR2(3), APPLIED VARCHAR2(9), DELETED VARCHAR2(3), STATUS VARCHAR2(1), COMPLETION_TIME DATE, DICTIONARY_BEGIN VARCHAR2(3), DICTIONARY_END VARCHAR2(3), END_OF_REDO VARCHAR2(3), BACKUP_COUNT NUMBER, ARCHIVAL_THREAD# NUMBER, ACTIVATION# NUMBER, IS_RECOVERY_DEST_FILE VARCHAR2(3), COMPRESSED VARCHAR2(3), FAL VARCHAR2(3), END_OF_REDO_TYPE VARCHAR2(10), BACKED_BY_VSS VARCHAR2(3) ); -- type paramdef_t is table of boolean index by varchar2(2); paramtab paramdef_t; /*-------------------------* * Private constants * *-------------------------*/ -- TRUE# CONSTANT NUMBER := 1; FALSE# CONSTANT NUMBER := 0; /*----------------------------------------* * Session scoped Package State Variables * *----------------------------------------*/ -- debug NUMBER := AM_DEBUG_HIGH; --AM_DEBUG_ON; debug_outtype NUMBER := sys.dbms_system.trace_file; -- -- -- -- s_purgescn NUMBER := NULL; -- type chrlst is table of VARCHAR(64) index by binary_integer; s_info_module chrlst; s_info_action chrlst; -- -- s_last_throttled DATE; PROCEDURE replication_reconcile_int (p_db_key IN NUMBER DEFAULT NULL, p_server_key IN NUMBER DEFAULT NULL); /*------------------* * Local Procedures * *------------------*/ -- PROCEDURE deb(p_line IN varchar2, p_level IN NUMBER DEFAULT AM_DEBUG_HIGH) IS BEGIN IF debug >= p_level and p_level > AM_DEBUG_OFF THEN -- -- -- -- -- -- sys.kbrsi_icd.rsTrace('RSI: ' || p_line); END IF; END deb; PROCEDURE save_error IS BEGIN save_error_int; END save_error; -- PROCEDURE clear_error(reset BOOLEAN DEFAULT FALSE) IS BEGIN dbms_ra_int.clear_error_int(reset); END clear_error; FUNCTION print (p_value IN BOOLEAN) RETURN VARCHAR2 IS BEGIN IF p_value THEN RETURN 'TRUE'; ELSIF p_value IS NULL THEN RETURN 'NULL'; ELSE RETURN 'FALSE'; END IF; END print; -- FUNCTION stamp2date(stamp IN NUMBER) RETURN DATE IS x NUMBER; dt VARCHAR2(19); BEGIN x := stamp; IF (stamp = 0) THEN RETURN NULL; END IF; dt := TO_CHAR(MOD(x,60), 'FM09'); -- seconds x := FLOOR(x/60); dt := TO_CHAR(MOD(x,60), 'FM09') || ':' || dt; -- minutes x := FLOOR(x/60); dt := TO_CHAR(MOD(x,24), 'FM09') || ':' || dt; -- hours x := FLOOR(x/24); dt := TO_CHAR(MOD(x,31)+1, 'FM09') || ' ' || dt; -- days x := FLOOR(x/31); dt := TO_CHAR(MOD(x,12)+1, 'FM09') || '/' || dt; -- months dt := TO_CHAR(FLOOR(x/12)+1988) || '/' || dt; return TO_DATE(dt, 'YYYY/MM/DD HH24:MI:SS', 'NLS_CALENDAR=Gregorian'); END stamp2date; FUNCTION date2stamp(dt IN DATE) RETURN NUMBER IS stamp NUMBER; BEGIN stamp := (((((TO_NUMBER(TO_CHAR(dt, 'YYYY'))-1988)*12 + (TO_NUMBER(TO_CHAR(dt, 'MM'))-1))*31 + (TO_NUMBER(TO_CHAR(dt, 'DD'))-1))*24 + (TO_NUMBER(TO_CHAR(dt, 'HH24'))))*60 + (TO_NUMBER(TO_CHAR(dt, 'MI'))))*60 + (TO_NUMBER(TO_CHAR(dt, 'SS'))); RETURN stamp; END date2stamp; -- FUNCTION dbkey2name(p_dbkey IN NUMBER) RETURN VARCHAR2 IS l_dbname VARCHAR(512); BEGIN -- -- -- -- SELECT max(reg_db_unique_name) INTO l_dbname FROM db WHERE db.db_key = p_dbkey; RETURN l_dbname; END dbkey2name; -- FUNCTION keylockstr(p_type IN NUMBER) RETURN VARCHAR2 IS l_typstr VARCHAR2(10); BEGIN CASE p_type WHEN KEY_BP THEN l_typstr := 'bpkey '; WHEN KEY_DF THEN l_typstr := 'dfkey '; WHEN KEY_AL THEN l_typstr := 'alkey '; WHEN KEY_SY THEN l_typstr := 'lib_key '; WHEN KEY_CT THEN l_typstr := 'ctkey '; WHEN KEY_VB THEN l_typstr := 'vbkey '; ELSE SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'keylockstr: unknown type ' || p_type); END CASE; RETURN l_typstr; END keylockstr; -- -- -- -- -- -- PROCEDURE write_lock(p_type IN NUMBER, p_key IN NUMBER) IS l_exists NUMBER; l_typstr VARCHAR2(10) := keylockstr(p_type); BEGIN -- dbms_ra_scheduler.get_lock(dbms_ra_scheduler.LOCK_KEY, p_key); deb('write_lock ' || l_typstr || p_key || ', got - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON); -- CASE p_type WHEN KEY_BP THEN SELECT COUNT(*) INTO l_exists FROM bp WHERE bp_key = p_key; /* @@RG: doing this break FREE AND status != 'D'; */ WHEN KEY_DF THEN l_exists := 1; -- Datafiles never go away, no need to check. WHEN KEY_AL THEN SELECT COUNT(*) INTO l_exists FROM al WHERE al_key = p_key; WHEN KEY_SY THEN SELECT COUNT(*) INTO l_exists FROM sbt_lib_desc WHERE lib_key = p_key; WHEN KEY_CT THEN SELECT COUNT(*) INTO l_exists FROM sbt_catalog WHERE ct_key = p_key; WHEN KEY_VB THEN SELECT COUNT(*) INTO l_exists FROM vbdf WHERE vb_key = p_key; ELSE -- dbms_ra_scheduler.unlock(dbms_ra_scheduler.LOCK_KEY, p_key); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'WRITE_LOCK: lock ' || p_key || ' has unknown type ' || p_type); END CASE; IF l_exists = 0 THEN -- dbms_ra_scheduler.unlock(dbms_ra_scheduler.LOCK_KEY, p_key); -- -- RAISE dbms_ra_scheduler.e_retry_error; END IF; END write_lock; -- -- -- -- -- -- FUNCTION write_lock_wait(p_type IN NUMBER, p_key IN NUMBER) RETURN BOOLEAN IS l_dummy BOOLEAN; l_typstr VARCHAR2(10) := keylockstr(p_type); l_exists NUMBER; BEGIN -- deb('write_lock ' || l_typstr || p_key || ', start - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON); l_dummy := sys.kbrsi_icd.rsKeyWriteLock(p_key, TRUE); deb('write_lock ' || l_typstr || p_key || ', got - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON); -- CASE p_type WHEN KEY_BP THEN SELECT COUNT(*) INTO l_exists FROM bp WHERE bp_key = p_key AND status != 'D'; WHEN KEY_DF THEN l_exists := 1; -- Datafiles never go away, no need to check. WHEN KEY_AL THEN SELECT COUNT(*) INTO l_exists FROM al WHERE al_key = p_key; WHEN KEY_SY THEN SELECT COUNT(*) INTO l_exists FROM sbt_lib_desc WHERE lib_key = p_key; WHEN KEY_CT THEN SELECT COUNT(*) INTO l_exists FROM sbt_catalog WHERE ct_key = p_key; WHEN KEY_VB THEN SELECT COUNT(*) INTO l_exists FROM vbdf WHERE vb_key = p_key; ELSE -- dbms_ra_scheduler.unlock(dbms_ra_scheduler.LOCK_KEY, p_key); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'WRITE_LOCK_WAIT: lock ' || p_key || ' has unknown type ' || p_type); END CASE; IF l_exists = 0 THEN dbms_ra_scheduler.show_locks(dbms_ra_scheduler.LOCK_KEY, p_key); dbms_ra_scheduler.unlock(dbms_ra_scheduler.LOCK_KEY, p_key); RETURN FALSE; ELSE RETURN TRUE; END IF; END write_lock_wait; -- -- -- -- -- FUNCTION read_lock(p_type IN NUMBER, p_key IN NUMBER) RETURN BOOLEAN IS l_lockstate BOOLEAN; l_exists NUMBER; l_typstr VARCHAR2(10) := keylockstr(p_type); BEGIN -- deb('read_lock ' || l_typstr || p_key || ', start - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON); l_lockstate := sys.kbrsi_icd.rsKeyReadLock(p_key, TRUE); deb('read_lock ' || l_typstr || p_key || ', got - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON); -- CASE p_type WHEN KEY_BP THEN SELECT COUNT(*) INTO l_exists FROM bp WHERE bp_key = p_key AND ba_access != 'U' AND purged = 'N'; WHEN KEY_DF THEN l_exists := 1; -- Datafiles never go away, no need to check. WHEN KEY_AL THEN SELECT COUNT(*) INTO l_exists FROM al WHERE al_key = p_key; WHEN KEY_SY THEN SELECT COUNT(*) INTO l_exists FROM sbt_lib_desc WHERE lib_key = p_key; WHEN KEY_CT THEN SELECT COUNT(*) INTO l_exists FROM sbt_catalog WHERE ct_key = p_key; WHEN KEY_VB THEN SELECT COUNT(*) INTO l_exists FROM vbdf WHERE vb_key = p_key; ELSE -- dbms_ra_scheduler.unlock(dbms_ra_scheduler.LOCK_KEY, p_key); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'READ_LOCK: lock ' || p_key || ' has unknown type ' || p_type); END CASE; IF l_exists = 0 THEN dbms_ra_scheduler.unlock(dbms_ra_scheduler.LOCK_KEY, p_key); RETURN FALSE; ELSE RETURN TRUE; END IF; END read_lock; -- -- -- PROCEDURE unlock(p_type IN NUMBER, p_key IN NUMBER) IS BEGIN dbms_ra_scheduler.unlock(dbms_ra_scheduler.LOCK_KEY, p_key); CASE p_type WHEN KEY_BP THEN deb('unlock bpkey ' || p_key || ' - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON); WHEN KEY_DF THEN deb('unlock dfkey ' || p_key || ' - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON); WHEN KEY_AL THEN deb('unlock alkey ' || p_key || ' - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON); WHEN KEY_CT THEN deb('unlock ctkey ' || p_key || ' - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON); WHEN KEY_SY THEN deb('unlock lib_key ' || p_key || ' - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON); WHEN KEY_VB THEN deb('unlock vbkey ' || p_key || ' - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON); ELSE deb('unlock unknown key ' || p_key || ' - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON); END CASE; END unlock; -- -- FUNCTION pieceAffinity(handle IN VARCHAR2, db_key OUT NUMBER, lib_key OUT NUMBER) RETURN NUMBER IS not_found BOOLEAN := FALSE; l_ct_key NUMBER; l_bp_key NUMBER; l_status bp.status%TYPE; bs_key NUMBER; bpno NUMBER; l_endupload sbt_catalog.endupload%TYPE; CURSOR bpQ(bs_key IN NUMBER, bpno IN NUMBER) IS SELECT ct.ct_key, ct.db_key, bp.lib_key FROM sbt_catalog ct, bp WHERE bp.bp_key = ct.bp_key AND bp.bs_key = bpQ.bs_key AND bp.status = 'A' AND bp.ba_access != 'U' AND bp.piece# = bpQ.bpno ORDER BY decode(ba_access, 'R', 3, 'T', 2, nvl2(vb_key, 1, 0)), bp.copy# desc; CURSOR ctQ(handle IN VARCHAR2) IS SELECT ct.ct_key, ct.db_key, ct.bp_key, bp.status, bp.lib_key, ct.endupload, bp.bs_key, bp.piece# FROM sbt_catalog ct LEFT OUTER JOIN bp ON ct.bp_key = bp.bp_key AND bp.ba_access != 'U' WHERE ct.handle = ctQ.handle ORDER by ct.bp_key nulls last, decode(ct.endupload, 'Y', 0, 1); BEGIN -- -- -- OPEN ctQ(handle); FETCH ctQ INTO l_ct_key, db_key, l_bp_key, l_status, lib_key, l_endupload, bs_key, bpno; IF (ctQ%NOTFOUND) THEN CLOSE ctQ; RAISE no_data_found; END IF; CLOSE ctQ; IF (l_status != 'D') THEN RETURN l_ct_key; END IF; -- -- IF (l_endupload = 'Y' and l_bp_key IS NULL) THEN RETURN l_ct_key; END IF; -- IF (l_bp_key IS NULL) THEN deb('pieceAffinity: bp_key not found', AM_DEBUG_MED); not_found := TRUE; ELSE -- complete piece but it is purged. Look for alternate piece OPEN bpQ(bs_key, bpno); FETCH bpQ INTO l_ct_key, db_key, lib_key; IF (bpQ%NOTFOUND) THEN deb('pieceAffinity: no alternate piece found', AM_DEBUG_MED); not_found := TRUE; END IF; CLOSE bpQ; END IF; IF (not_found) THEN RAISE no_data_found; END IF; RETURN l_ct_key; END pieceAffinity; /*-------------------* * Global Procedures * *-------------------*/ -- -- -- PROCEDURE setDebug(p_level IN NUMBER, p_outtype IN NUMBER DEFAULT sys.dbms_system.trace_file) IS BEGIN debug := p_level; debug_outtype := p_outtype; END setDebug; -- PROCEDURE save_error_int IS l_error_depth PLS_INTEGER := utl_call_stack.error_depth; l_newds callstack := callstack(); l_newbt callstack := callstack(); BEGIN deb('save_error_int at depth=' || l_error_depth); -- -- IF s_pl_stack.COUNT > 0 THEN IF l_error_depth <= s_pl_stack(s_pl_stack.LAST).error_depth THEN RETURN; END IF; END IF; -- s_pl_stack.EXTEND; -- -- FOR l_line IN 3..utl_call_stack.dynamic_depth LOOP l_newds.EXTEND; l_newds(l_newds.LAST).line := utl_call_stack.unit_line(l_line); l_newds(l_newds.LAST).unit := utl_call_stack.concatenate_subprogram(utl_call_stack.subprogram(l_line)); END LOOP; -- -- FOR l_line IN REVERSE 1..utl_call_stack.backtrace_depth LOOP l_newbt.EXTEND; l_newbt(l_newbt.LAST).line := utl_call_stack.backtrace_line(l_line); l_newbt(l_newbt.LAST).unit := utl_call_stack.backtrace_unit(l_line); END LOOP; s_pl_stack(s_pl_stack.LAST).dynamic_stack := l_newds; s_pl_stack(s_pl_stack.LAST).backtrace_stack := l_newbt; s_pl_stack(s_pl_stack.LAST).error_depth := l_error_depth; s_pl_stack(s_pl_stack.LAST).action := SYS_CONTEXT('USERENV', 'ACTION'); s_pl_stack(s_pl_stack.LAST).module := SYS_CONTEXT('USERENV', 'MODULE'); EXCEPTION WHEN OTHERS THEN deb('save_error_int failed with: ' || SQLERRM); deb(' at line ' || utl_call_stack.backtrace_line(1)); RAISE; END save_error_int; -- PROCEDURE clear_error_int(reset BOOLEAN DEFAULT FALSE) IS l_error_depth PLS_INTEGER := utl_call_stack.error_depth; BEGIN deb('save_error_int at depth=' || l_error_depth); IF reset THEN s_pl_stack.DELETE; ELSE -- -- FOR f IN REVERSE 1..s_pl_stack.COUNT LOOP IF l_error_depth <= s_pl_stack(f).error_depth THEN s_pl_stack.TRIM; ELSE -- RETURN; END IF; END LOOP; END IF; EXCEPTION WHEN OTHERS THEN deb('clear_error_int failed with: ' || SQLERRM); deb(' at line ' || utl_call_stack.backtrace_line(1)); RAISE; END clear_error_int; -- FUNCTION get_error RETURN VARCHAR2 IS NEWLN CONSTANT CHAR(1) := CHR(10); l_errormsg VARCHAR2(32000); l_payload error_payload; l_nextbt callstack; l_nextds callstack; l_unit VARCHAR2(128); E_STRING_ERROR EXCEPTION; PRAGMA EXCEPTION_INIT ( E_STRING_ERROR, -6502 ); E_STRING_ERROR_NUM CONSTANT NUMBER := -6502; BEGIN IF s_pl_stack.COUNT = 0 THEN RETURN 'No Call Stack Saved'; END IF; l_errormsg := ''; FOR l_frame IN 1..s_pl_stack.COUNT LOOP -- IF s_pl_stack.COUNT > 1 THEN l_errormsg := l_errormsg || NEWLN || NEWLN || 'Error frame ' || l_frame; ELSE l_errormsg := 'Error stack:'; END IF; -- l_payload := s_pl_stack(l_frame); l_nextbt := l_payload.backtrace_stack; l_nextds := l_payload.dynamic_stack; -- l_errormsg := l_errormsg || NEWLN || RPAD('Backtrace unit',40) || LPAD('Line', 10); FOR l_line IN 1..l_nextbt.COUNT LOOP l_unit := l_nextbt(l_line).unit; IF LENGTH(l_unit) > 40 THEN -- l_unit := SUBSTR(l_unit,-40); END IF; l_errormsg := l_errormsg || NEWLN || RPAD(l_unit, 40) || LPAD(l_nextbt(l_line).line, 10); END LOOP; -- l_errormsg := l_errormsg || NEWLN || NEWLN || RPAD('Call stack unit',40) || LPAD('Line', 10); FOR l_line IN 1..l_nextds.COUNT LOOP l_unit := l_nextds(l_line).unit; IF LENGTH(l_unit) > 40 THEN -- l_unit := SUBSTR(l_unit,-40); END IF; l_errormsg := l_errormsg || NEWLN || RPAD(l_unit, 40) || LPAD(l_nextds(l_line).line, 10); END LOOP; END LOOP; RETURN l_errormsg; EXCEPTION WHEN E_STRING_ERROR THEN deb('return what we have so far...'); RETURN SUBSTR(l_errormsg, 1, 31995) || '...'; WHEN OTHERS THEN deb('get_error failed with: ' || SQLERRM); deb(' at line ' || utl_call_stack.backtrace_line(1)); RAISE; END get_error; -- -- -- PROCEDURE unlock_vb(p_vbkey IN NUMBER, p_novbkey IN BOOLEAN) -- Do not unlock vbkey IS CURSOR dfnums(in_vbkey number) IS SELECT db_key, vb_key, df_key FROM vbdf WHERE vb_key = in_vbkey; CURSOR bpnums(in_vbkey number) IS SELECT bp_key FROM bp WHERE vb_key = in_vbkey; BEGIN -- FOR l IN dfnums(p_vbkey) LOOP unlock(KEY_DF, l.df_key); END LOOP; -- IF NOT p_novbkey THEN FOR l IN bpnums(p_vbkey) LOOP unlock(KEY_BP, l.bp_key); END LOOP; END IF; END unlock_vb; -- -- -- PROCEDURE validateBackupPiece(p_dbkey IN NUMBER, p_bpkey IN NUMBER) IS l_blksize NUMBER := 0; l_sameendian NUMBER := 0; l_fname VARCHAR2(1024):= NULL; l_msection NUMBER; l_pieces NUMBER; BEGIN deb(' validateBackupPiece, db_key:' || p_dbkey || ' : bp_key: ' || p_bpkey, AM_DEBUG_MED); -- SELECT block_size INTO l_blksize FROM bp, bs WHERE bp.bs_key=bs.bs_key AND vb_key IS NULL AND bp_key = p_bpkey; SELECT DECODE(multi_section, 'Y', 1, 0), pieces INTO l_msection, l_pieces FROM bs WHERE bs_key = (SELECT bs_key from bp where bp_key = p_bpkey) ; deb(' validateBackupPiece, bp_key:' || p_bpkey || ' blksize: ' || l_blksize || ' l_msection ' || l_msection || ' pieces: ' || l_pieces, AM_DEBUG_MED); BEGIN -- -- IF (l_pieces = 1 OR l_msection = 1) THEN SELECT filename INTO l_fname FROM sbt_catalog WHERE bp_key = p_bpkey; sys.kbrsi_icd.validatePiece(filename => l_fname, blksize => l_blksize); END IF; EXCEPTION WHEN OTHERS THEN save_error; SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_CORRUPT_BACKUPPIECE_NUM, p_bpkey); END; END validateBackupPiece; -- FUNCTION file2handle(p_fname VARCHAR2) RETURN VARCHAR2 IS l_handle VARCHAR2(512); BEGIN IF dbms_ra_scheduler.s_current_task_type = dbms_ra_scheduler.TASK_INC_ARCH THEN l_handle := INC_ARC_PREFIX || substr(p_fname,1,512); ELSE l_handle := '$' || substr(p_fname,1,511); END IF; RETURN l_handle; END file2handle; -- PROCEDURE createSbtCatalog(p_dbid IN NUMBER, p_handle IN VARCHAR2, p_pieceinc IN VARCHAR2, p_ftype IN NUMBER, p_xmldoc IN CLOB, p_commit IN BOOLEAN, p_ct_key OUT NUMBER) IS db_key NUMBER; ftypestr VARCHAR2(1); l_completed sbt_catalog.completed%TYPE := NULL; l_endupload sbt_catalog.endupload%TYPE := NULL; l_filename sbt_catalog.filename%TYPE := NULL; BEGIN BEGIN SELECT db_key INTO db_key FROM db WHERE db_id = p_dbid; EXCEPTION WHEN no_data_found THEN save_error; raise_application_error(-20001, 'Database not found'); END; CASE p_ftype WHEN DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL THEN ftypestr := 'V'; WHEN DBMS_RA_INT.KBRSCHKTYPE_TAPE THEN ftypestr := 'T'; WHEN DBMS_RA_INT.KBRSCHKTYPE_FILE THEN ftypestr := 'F'; l_completed := 'N'; l_endupload := 'N'; WHEN DBMS_RA_INT.KBRSCHKTYPE_DISK THEN ftypestr := 'D'; l_filename := p_handle; ELSE SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'unknown_ftype'); END CASE; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- BEGIN INSERT INTO sbt_catalog (ct_key, db_key, cretime, handle, pieceinc, endupload, ftype, xmldoc, completed, filename) VALUES (rman_seq.nextval, db_key, systimestamp, p_handle, p_pieceinc, l_endupload, ftypestr, sys.xmltype.createxml(p_xmldoc), l_completed, l_filename) RETURNING ct_key INTO p_ct_key; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN save_error; clear_error; SELECT ct_key INTO p_ct_key FROM sbt_catalog s WHERE s.db_key = createSbtCatalog.db_key AND handle = p_handle AND pieceinc = p_pieceinc; END; IF (p_commit) THEN COMMIT; END IF; END createSbtCatalog; -- PROCEDURE copySbtCatalog(p_handle IN VARCHAR2, p_oldpieceinc IN VARCHAR2, p_newpieceinc IN VARCHAR2) IS l_entry sbt_catalog%ROWTYPE; l_newchunkprefix varchar2(1024); BEGIN -- SELECT * INTO l_entry FROM sbt_catalog WHERE handle = p_handle AND pieceinc = p_oldpieceinc; -- SELECT sl_key INTO l_entry.sl_key FROM odb, bp WHERE odb.db_key = bp.db_key AND bp.bp_key = l_entry.bp_key; l_entry.ct_key := rman_seq.nextval; l_entry.pieceinc := p_newpieceinc; l_entry.bp_key := NULL; -- Needed to avoid constraint violation -- SELECT regexp_replace(prefix, p_oldpieceinc, p_newpieceinc, instr(prefix, p_oldpieceinc, -1 , 1)) INTO l_newchunkprefix FROM (SELECT extractValue(l_entry.xmldoc, '//ChunkPrefix/text()') prefix FROM dual); -- -- -- -- -- SELECT XMLQuery('copy $i := $p1 modify ((for $j in $i//Incarnation return replace value of node $j with $p2), (for $j in $i//ChunkPrefix return replace value of node $j with $p3)) return $i' PASSING l_entry.xmldoc AS "p1", p_newpieceinc AS "p2", l_newchunkprefix AS "p3" RETURNING CONTENT) INTO l_entry.xmldoc FROM dual; -- IF (l_entry.endupload IS NOT NULL) THEN l_entry.endupload := 'N'; END IF; IF (l_entry.completed IS NOT NULL) THEN l_entry.completed := 'N'; END IF; l_entry.filename := NULL; l_entry.filesize := NULL; l_entry.last_entry := SYSTIMESTAMP; -- INSERT INTO sbt_catalog VALUES l_entry; END copySbtCatalog; -- PROCEDURE endUploadSbtCatalog(p_handle IN VARCHAR2, p_pieceinc IN VARCHAR2, p_xmldoc IN CLOB) IS l_ct_key NUMBER; BEGIN SELECT ct.ct_key INTO l_ct_key FROM sbt_catalog ct WHERE ct.handle = p_handle AND ct.pieceinc = p_pieceinc AND ct.bp_key IS NULL; UPDATE sbt_catalog ct SET ct.endupload = 'Y' ,ct.xmldoc = sys.xmltype.createxml(p_xmldoc) WHERE ct.ct_key = l_ct_key; COMMIT; END endUploadSbtCatalog; -- PROCEDURE finalizeSbtCatalog(p_bp_key IN NUMBER, p_ct_key IN NUMBER, p_xmldoc IN CLOB) IS l_ftype sbt_catalog.ftype%TYPE; l_bskey NUMBER; BEGIN IF debug >= AM_DEBUG_HIGH AND p_xmldoc IS NOT NULL THEN deb('finalizeSbtCatalog xmldoc = '); deb(dbms_lob.substr(p_xmldoc, 4000, 1)); END IF; SELECT bs_key into l_bskey from bs WHERE bs.bs_key = (SELECT bs_key from bp WHERE bp.bp_key = p_bp_key) FOR UPDATE of bs.bs_key; IF debug >= AM_DEBUG_HIGH THEN deb('finalizeSbtCatalog locked bs_key = ' || l_bskey); END IF; UPDATE sbt_catalog ct SET ct.bp_key = p_bp_key ,ct.completed = nvl2(ct.completed, 'Y', null) ,ct.endupload = nvl2(ct.endupload, 'Y', null) ,ct.xmldoc = case when ct.xmldoc is null then sys.xmltype.createxml(p_xmldoc) else ct.xmldoc end WHERE ct_key = p_ct_key RETURNING ct.ftype INTO l_ftype; UPDATE bp SET bp.ct_key = p_ct_key WHERE bp.bp_key = p_bp_key; IF (l_ftype = 'V') THEN UPDATE vbdf v SET state = DBMS_RA_POOL.VBDF_COMPLETE WHERE state = DBMS_RA_POOL.VBDF_FIN_NOBP AND EXISTS (SELECT 1 FROM bp p, bdf d WHERE p.bs_key = d.bs_key AND p.bp_key = p_bp_key AND p.vb_key = v.vb_key AND d.file# = v.file#); END IF; END finalizeSbtCatalog; -- PROCEDURE deleteSbtCatalog(p_handle IN VARCHAR2, p_pieceinc IN VARCHAR2) IS l_ct_key NUMBER; l_bp_key NUMBER; bp_key NUMBER; BEGIN IF (p_pieceinc IS NOT NULL) THEN SELECT ct.ct_key, ct.bp_key INTO l_ct_key, l_bp_key FROM sbt_catalog ct WHERE ct.handle = p_handle AND ct.pieceinc = p_pieceinc; ELSE SELECT ct.ct_key, ct.bp_key INTO l_ct_key, l_bp_key FROM sbt_catalog ct, bp WHERE ct.handle = p_handle AND bp.status != 'D' AND bp.bp_key = ct.bp_key AND bp.ct_key = ct.ct_key; END IF; IF (l_bp_key IS NULL) THEN -- -- UPDATE sbt_catalog ct SET ct.endupload = 'D' WHERE ct.ct_key = l_ct_key; ELSE -- -- -- deb('deleteSbtCatalog piece complete; handle = ' || p_handle || ' ;leave it to rsDeleteBackupPiece'); END IF; COMMIT; EXCEPTION WHEN no_data_found THEN save_error; deb('deleteSbtCatalog no_data_found: handle= ' || p_handle); clear_error; END deleteSbtCatalog; -- PROCEDURE readSbtCatalog(p_handle IN VARCHAR2, p_xmldoc OUT NOCOPY CLOB, p_affinity IN BINARY_INTEGER, p_sbtinfo2 IN BINARY_INTEGER) IS l_ct_ftype sbt_catalog.ftype%TYPE; l_ct_key NUMBER; l_lib_key NUMBER; l_db_key NUMBER; l_mclob CLOB; l_status BINARY_INTEGER; l_mhandle SYS.KBRSI_ICD.NAMES$_T; l_single BINARY_INTEGER; l_network_chunksize NUMBER; l_ct_endupload sbt_catalog.endupload%TYPE; l_ct_completed sbt_catalog.completed%TYPE; l_ct_pieceinc sbt_catalog.pieceinc%TYPE; l_bp_key NUMBER; l_chunks NUMBER; l_filesize NUMBER; l_call_finish_bp BOOLEAN := FALSE; BEGIN -- IF (p_affinity > 0) THEN l_ct_key := pieceAffinity(p_handle, l_db_key, l_lib_key); ELSE SELECT ct.ct_key, ct.db_key, bp.lib_key INTO l_ct_key, l_db_key, l_lib_key FROM sbt_catalog ct, bp WHERE ct.handle = p_handle AND ct.bp_key = bp.bp_key AND bp.status != 'D'; END IF; IF (p_sbtinfo2 > 0) THEN SELECT bp.lib_key, ct.db_key, ct.endupload, ct.completed, ct.pieceinc, ct.ftype, bp.bp_key INTO l_lib_key, l_db_key, l_ct_endupload, l_ct_completed, l_ct_pieceinc, l_ct_ftype, l_bp_key FROM sbt_catalog ct LEFT OUTER JOIN bp ON ct.bp_key = bp.bp_key AND bp.status != 'D' WHERE ct.ct_key = l_ct_key; -- -- -- -- -- -- IF (l_ct_completed = 'N' AND l_ct_endupload = 'Y' AND l_ct_ftype = 'F' AND l_bp_key IS NULL) THEN l_call_finish_bp := TRUE; END IF; END IF; -- IF (l_lib_key IS NOT NULL) THEN l_status := dbms_ra_int.statBpSbt( db_key => l_db_key, handle => p_handle, mhandle => l_mhandle, single => l_single); IF (l_status = 0) THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(DBMS_RA.OBJ_NOT_FOUND_NUM, p_handle, 'tape file', FALSE); END IF; END IF; SELECT nvl(max(to_number(value)), 0) INTO l_network_chunksize FROM config WHERE name = 'network_chunksize'; IF (l_mhandle.count > 0) THEN l_mclob := ''; FOR i in 0..l_mhandle.count-1 LOOP IF (l_mhandle(i) IS NOT NULL) THEN l_mclob := l_mclob || '' || l_mhandle(i)||''; END IF; END LOOP; IF (l_single > 0) THEN l_mclob := l_mclob || 'TRUE'; ELSE l_mclob := l_mclob || 'FALSE'; END IF; l_mclob := l_mclob || ''; -- -- -- -- SELECT XMLQuery('copy $i := $p1 modify (for $j in $i//MediaInfo return replace node $j with $p2) return $i' PASSING ct.xmldoc AS "p1", XMLType(l_mclob) AS "p2" RETURNING CONTENT).getClobVal(), filesize INTO p_xmldoc, l_filesize FROM sbt_catalog ct WHERE ct.ct_key = l_ct_key; ELSE SELECT ct.xmldoc.getClobVal(), filesize INTO p_xmldoc, l_filesize FROM sbt_catalog ct WHERE ct.ct_key = l_ct_key; END IF; IF (l_network_chunksize != 0) THEN -- -- -- -- -- -- -- -- IF (l_filesize IS NULL) THEN l_chunks := dbms_ra_int.UB8MAXVAL; ELSE l_chunks := ceil(l_filesize/l_network_chunksize); END IF; -- -- -- -- -- SELECT XMLQuery('copy $i := $p1 modify ((for $j in $i//ChunkSize return replace value of node $j with $p2), (for $j in $i//Chunks return replace value of node $j with $p3)) return $i' PASSING XMLType(p_xmldoc) AS "p1", to_char(l_network_chunksize) AS "p2", to_char(l_chunks) AS "p3" RETURNING CONTENT).getClobVal() INTO p_xmldoc FROM dual; END IF; -- -- -- -- IF (l_call_finish_bp) THEN dbms_ra_storage.finish_backup_piece( p_db_key => l_db_key, p_handle => p_handle, p_pieceinc => l_ct_pieceinc, p_ct_key => l_ct_key); END IF; END readSbtCatalog; -- -- FUNCTION checkSbtCatalog(p_handle IN VARCHAR2, p_affinity IN BINARY_INTEGER) RETURN BINARY_INTEGER IS l_ct_key NUMBER; l_db_key NUMBER; l_lib_key NUMBER; BEGIN -- IF (p_affinity > 0) THEN l_ct_key := pieceAffinity(p_handle, l_db_key, l_lib_key); ELSE SELECT ct.ct_key INTO l_ct_key FROM sbt_catalog ct, bp WHERE ct.handle = p_handle AND ct.bp_key = bp.bp_key AND bp.status != 'D'; END IF; RETURN 1; EXCEPTION WHEN no_data_found THEN save_error; clear_error; RETURN 0; END checkSbtCatalog; -- -- -- PROCEDURE purgescncheck(p_dbid IN NUMBER) IS l_purgescn NUMBER; l_dbkey NUMBER; BEGIN -- -- -- -- -- -- -- -- IF NVL(s_purgescn, 0) > 0 THEN SELECT odb.db_key, purge_scn INTO l_dbkey, l_purgescn FROM odb, db WHERE odb.db_key = db.db_key AND db_id = p_dbid; -- -- IF l_purgescn > s_purgescn THEN UPDATE odb SET purge_scn = NULL, purge_inc = NULL, bs2_timestamp = NULL WHERE db_key = l_dbkey; COMMIT; END IF; s_purgescn := NULL; END IF; END purgescncheck; -- PROCEDURE tickSbtSession(p_session_id IN VARCHAR2, p_db_key IN NUMBER, p_module IN VARCHAR2, p_action IN VARCHAR2) IS l_rowid rowid; l_modtime timestamp; l_currtime timestamp := systimestamp; BEGIN sys.dbms_application_info.set_client_info(p_session_id); sys.dbms_application_info.set_module(p_module, p_action); SELECT se.modtime, ROWID INTO l_modtime, l_rowid FROM sbt_session se WHERE se.session_id = p_session_id; -- IF (l_currtime > (l_modtime + dbms_ra_scheduler.s_sbt_active_interval/4)) THEN UPDATE sbt_session se SET se.modtime = l_currtime WHERE ROWID = l_rowid; COMMIT; END IF; EXCEPTION WHEN no_data_found THEN save_error; INSERT INTO sbt_session(session_id, db_key, cretime, modtime) VALUES (p_session_id, p_db_key, l_currtime, l_currtime); COMMIT; clear_error; END tickSbtSession; -- PROCEDURE purgeSbtSession(p_session_id IN VARCHAR2) IS BEGIN DELETE sbt_session se WHERE se.session_id = p_session_id; COMMIT; END purgeSbtSession; -- -- FUNCTION get_prvlg_code(operation IN VARCHAR2, accesstype IN VARCHAR2) RETURN NUMBER IS writeop BOOLEAN := FALSE; BEGIN IF (accesstype = 'READ') THEN writeop := FALSE; ELSIF (accesstype = 'WRITE') THEN writeop := TRUE; ELSE SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA.INVALID_VAL_NUM, 'accesstype'); END IF; -- IF (operation = 'BACKUP') THEN IF (writeop) THEN RETURN BACKUP_READ; ELSE RETURN BACKUP_WRITE; END IF; ELSIF (operation = 'RECONCILE') THEN IF (writeop) THEN RETURN RECONCILE_READ; ELSE RETURN RECONCILE_WRITE; END IF; ELSE SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA.INVALID_VAL_NUM, 'operation'); END IF; RETURN NULL; END get_prvlg_code; -- -- FUNCTION has_privilege_int(user_id IN NUMBER, db_key IN NUMBER, db_uname IN VARCHAR2, prvlg_code IN NUMBER) RETURN BINARY_INTEGER IS has_prvlg BINARY_INTEGER := 0; BEGIN IF (has_privilege_int.db_key IS NOT NULL) THEN SELECT /*+ INDEX(pv prvlg(user_id db_key type)) */ 1d INTO has_prvlg FROM prvlg pv WHERE pv.user_id = has_privilege_int.user_id AND pv.db_key = has_privilege_int.db_key AND bitand(pv.type, prvlg_code) = prvlg_code AND ROWNUM = 1; ELSE SELECT /*+ INDEX(pv prvlg(user_id db_unique_name type)) */ 1d INTO has_prvlg FROM prvlg pv WHERE pv.user_id = has_privilege_int.user_id AND pv.db_unique_name = has_privilege_int.db_uname AND bitand(pv.type, prvlg_code) = prvlg_code AND ROWNUM = 1; END IF; RETURN has_prvlg; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; clear_error; RETURN 0; END has_privilege_int; -- FUNCTION has_privilege(user_id IN NUMBER, db_key IN NUMBER, db_uname IN VARCHAR2, operation IN VARCHAR2, accesstype IN VARCHAR2, prvlg_code IN NUMBER DEFAULT NULL) RETURN BINARY_INTEGER IS l_prvlg_code NUMBER := prvlg_code; BEGIN IF (l_prvlg_code IS NULL) THEN l_prvlg_code := get_prvlg_code(upper(operation), upper(accesstype)); END IF; RETURN has_privilege_int(user_id, db_key, upper(db_uname), l_prvlg_code); END has_privilege; -- -- -- -- -- -- PROCEDURE saveBPdata(fno IN NUMBER, fuzzyScn IN NUMBER DEFAULT NULL, blocks_read IN NUMBER DEFAULT NULL, corrupt IN NUMBER DEFAULT NULL, completion_stamp IN NUMBER DEFAULT NULL, completion_time IN DATE DEFAULT NULL) IS i BINARY_INTEGER := fno; BEGIN -- IF fuzzyScn IS NOT NULL THEN s_bp_save(i).fuzzyscn := fuzzyScn; END IF; IF blocks_read IS NOT NULL THEN s_bp_save(i).blocks_read := blocks_read; END IF; IF corrupt IS NOT NULL THEN s_bp_save(i).nmcorrupt := corrupt; END IF; IF completion_stamp IS NOT NULL THEN s_bp_save(i).complete_time := stamp2date(completion_stamp); END IF; IF completion_time IS NOT NULL THEN s_bp_save(i).complete_time := completion_time; END IF; END saveBPdata; -- PROCEDURE checkBackupSet(bs IN kccbs_t) IS local backup_set_t; keep_options NUMBER; l_completion_time DATE := NULL; BEGIN -- IF s_bp_save.EXISTS(s_bp_save.LAST) THEN l_completion_time := s_bp_save(s_bp_save.LAST).complete_time; END IF; -- -- SELECT rai_recid.nextval, bs.bsstm, bs.bsbss, bs.bsbsc, decode(bitand(bs.bstyp, 11), 1, 'D', 2, 'I', 8, 'L'), decode(bitand(bs.bstyp, 4 + 64), 4, 'YES', 68, 'SBY', 'NO'), decode(bitand(bs.bstyp, 16 + 8192), 16, bs.bslvl, NULL), bs.bspct, stamp2date(bs.bsbss), nvl(l_completion_time, stamp2date(bs.bsste)), /* KCCBSCAT is true */ abs(nvl(l_completion_time, stamp2date(bs.bsste)) - stamp2date(bs.bsbss)) * 86400, bs.bsbsz, decode(bitand(bs.bstyp,128),128,'YES','NO'), decode(bitand(bs.bstyp, 1792), 0, 'NO', 'YES'), stamp2date(bs.bskpt), decode(bitand(bs.bstyp, 1792), 256, 'LOGS', 512, 'NOLOGS', 1024, 'BACKUP_LOGS', NULL), decode(bitand(bs.bstyp, 16384), 16384, 'YES', 'NO'), bs.bsoid INTO local FROM dual WHERE bitand(bs.bstyp,32) != 32; -- -- SELECT decode(local.keep_options, 'LOGS', 256, 'NOLOGS', 512, 'BACKUP_LOGS', 1024, 0) INTO keep_options FROM dual; -- dbms_rcvcat.checkBackupSet( local.recid, local.stamp, local.set_stamp, local.set_count, local.backup_type, local.incremental_level, local.pieces, local.start_time, local.completion_time, local.controlfile_included, local.input_file_scan_only, keep_options, local.keep_until, local.block_size, local.multi_section, FALSE, local.guid); END checkBackupSet; -- FUNCTION checkBackupPiece(vbkey IN NUMBER ,lib_key IN NUMBER ,ba_access IN VARCHAR2 ,bp IN kccbp_t ,template_key IN NUMBER) RETURN NUMBER IS local backup_piece_t; bp_key NUMBER; l_completion_time DATE := NULL; BEGIN -- IF s_bp_save.EXISTS(s_bp_save.LAST) THEN l_completion_time := s_bp_save(s_bp_save.LAST).complete_time; END IF; -- -- SELECT 0, -- want catalog to create bp_recid in strictly increasing order bp.bpstm, bp.bpbss, bp.bpbsc, bp.bpnum, NULL, /* copy# no longer in use */ bp.bpdev, bp.bphdl, bp.bpcmt, bp.bpmdh, bitand(bp.bpflg, 4080) / 16, decode(bitand(bp.bpflg, 2), 1,'YES','NO'), bp.bptag, decode(bitand(bp.bpflg, 1 + 4096 + 8192), 0, 'A', 1, 'D', 4096, 'X',8192,'U','?'), decode(bitand(bp.bpflg, 1), 1, 'YES','NO'), stamp2date(bp.bpsts), nvl(l_completion_time, stamp2date(bp.bptim)), abs(nvl(l_completion_time, stamp2date(bp.bptim)) - stamp2date(bp.bpsts)) * 86400, ((floor(bp.bpext/512) * 4294967296) + bp.bpsz1) * 512, decode(bitand(bp.bpflg, 16384), 0, 'NO', 'YES'), 0, -- rman_status_recid unknown 0, -- rman_status_stamp unknown decode(bitand(bp.bpext, 64), 64, 'YES', 'NO'), decode(bitand(bp.bpflg, 16384), 0,'NO', decode(bitand(bp.bpext, 256), 0, 'NO', 'YES')), decode(bitand(bp.bpext, 128), 128, 'YES', 'NO'), decode(bitand(bp.bpflg, 16384), 16384, 'NO', decode(bitand(bp.bpext,256), 0, 'NO', 'YES')), bp.bpoid INTO local FROM dual; -- IF ba_access <> 'L' OR vbkey IS NOT NULL THEN s_purgescn := 0; END IF; -- bp_key := dbms_rcvcat.checkBackupPiece( local.recid, local.stamp, local.set_stamp, local.set_count, local.piece#, local.tag, local.device_type, local.handle, local.comments, local.media, local.concur, local.start_time, local.completion_time, local.status, local.copy#, local.media_pool, local.bytes, local.is_recovery_dest_file, local.rman_status_recid, local.rman_status_stamp, local.compressed, local.encrypted, local.backed_by_osb, ba_access, vbkey, FALSE, lib_key, local.guid, template_key); RETURN bp_key; END checkBackupPiece; -- PROCEDURE checkBackupDatafile(bf IN kccbf_t) IS local backup_datafile_t; l_purgescn NUMBER; l_dbkey NUMBER; i BINARY_INTEGER := bf.bfdfp; l_fuzzyscn NUMBER := NULL; l_nmcorrupt NUMBER := NULL; l_blocks_read NUMBER := NULL; l_complete_time DATE := NULL; l_bs_key NUMBER := NULL; l_isVirtual VARCHAR2(1); BEGIN -- -- IF s_bp_save.EXISTS(i) THEN l_fuzzyscn := s_bp_save(i).fuzzyscn; l_nmcorrupt := s_bp_save(i).nmcorrupt; l_blocks_read := s_bp_save(i).blocks_read; l_complete_time := s_bp_save(i).complete_time; deb('checkBackupDatafile ' || i || ', fuzzy ' || l_fuzzyscn || ', corr ' || l_nmcorrupt || ', blks ' || l_blocks_read || ', time ' || l_complete_time, AM_DEBUG_MED); END IF; -- -- SELECT rai_recid.nextval, bf.bfstm, bf.bfbss, bf.bfbsc, bf.bfdfp, to_number(bf.bfcrs), stamp2date(bf.bfcrt), to_number(bf.bfrls), stamp2date(bf.bfrlc), decode(bitand(bf.bfflg, 1 + 8), 1, bf.bflvl, NULL), to_number(bf.bfics), to_number(bf.bfcps), stamp2date(bf.bfcpt), nvl(l_fuzzyscn, to_number(bf.bfafs)), nvl(l_nmcorrupt, bf.bfncb), bf.bfmcb, bf.bflcb, bf.bffsz, bf.bfbct, bf.bfbsz, bf.bflor, nvl(l_complete_time, stamp2date(bf.bfste)), decode(bf.bfdfp, 0, decode(bitand(bf.bfflg, 2), 2, 'S', 'B'), NULL), decode(bitand(bf.bfflg, 4), 4, 'YES', 'NO'), nvl(l_blocks_read, bf.bfbrd), decode(bitand(bf.bfflg, 16), 16, 'YES', 'NO'), bf.bffdi, decode(bitand(bf.bfflg, 32), 0, 'NO', 'YES'), bf.bfplus, bf.bfprls, stamp2date(bf.bfprlt), bf.bfssz, decode(bitand(bf.bfflg, 128), 0, 'NO', 'YES'), bf.bfssb, bf.bfoid INTO local FROM dual WHERE bitand(bf.bfflg, 64) != 64; SELECT CASE MIN(NVL(vb_key, 0)) WHEN 0 THEN 'F' ELSE 'T' END INTO l_isVirtual FROM bs, bp WHERE bs.bs_key = bp.bs_key AND bs.db_key = dbms_rcvcat.this_db_key AND bs.set_stamp = local.set_stamp AND bs.set_count = local.set_count; -- s_purgescn := LEAST(NVL(s_purgescn, BIGNUM), local.checkpoint_change#); -- dbms_rcvcat.checkBackupDataFile( local.recid, local.stamp, local.set_stamp, local.set_count, local.file#, local.creation_change#, local.creation_time, local.resetlogs_change#, local.resetlogs_time, local.incremental_level, local.incremental_change#, local.checkpoint_change#, local.checkpoint_time, local.absolute_fuzzy_change#, local.datafile_blocks, local.blocks, local.block_size, local.oldest_offline_range, local.completion_time, local.controlfile_type, local.marked_corrupt, local.media_corrupt, local.logically_corrupt, FALSE, local.blocks_read, local.used_change_tracking, local.used_optimization, local.foreign_dbid, local.plugged_readonly, local.plugin_change#, local.plugin_resetlogs_change#, local.plugin_resetlogs_time, local.section_size, local.guid, 'NO' /* sparse backup */, FALSE, CASE l_isVirtual WHEN 'F' THEN FALSE ELSE TRUE END); -- -- -- IF local.section_size <> 0 THEN SELECT bs_key INTO l_bs_key FROM bs WHERE db_key = dbms_rcvcat.this_db_key AND bs.set_stamp = local.set_stamp AND bs.set_count = local.set_count; deb('dbms_rs_int:checkBackupDataFile msection bs_key' || l_bs_key); deb('dbms_rs_int:checkBackupDataFile db_key' || dbms_rcvcat.this_db_key); -- -- -- -- UPDATE vbdf SET ckp_scn = (SELECT ckp_scn FROM bdf WHERE bs_key = l_bs_key AND file# = local.file# ) WHERE vb_key IN (SELECT bp.vb_key FROM bp JOIN vbdf ON bp.vb_key = vbdf.vb_key WHERE bp.bs_key = l_bs_key AND bp.vb_key IS NOT NULL AND vbdf.ckp_scn > (SELECT ckp_scn FROM bdf WHERE bs_key = l_bs_key AND file# = local.file# ) AND vbdf.state = DBMS_RA_POOL.VBDF_COMPLETE); deb('dbms_rs_int:checkBackupDataFile UPDATED vbdfs' || l_bs_key); END IF; END checkBackupDatafile; -- PROCEDURE checkBackupRedolog(bl IN kccbl_t) IS local backup_redolog_t; BEGIN -- -- SELECT rai_recid.nextval, bl.blstm, bl.blbss, bl.blbsc, bl.blthp, bl.blseq, to_number(bl.blrls), stamp2date(bl.blrlc), to_number(bl.bllos), stamp2date(bl.bllot), to_number(bl.blnxs), stamp2date(bl.blnxt), bl.blbct, bl.blbsz, decode(bitand(bl.blflg, 1), 1, 'YES', 'NO'), decode(bitand(bl.blflg, 4), 4, 'Y', null) INTO local FROM dual WHERE bitand(bl.blflg, 2) != 2; -- dbms_rcvcat.checkBackupRedoLog( local.recid, local.stamp, local.set_stamp, local.set_count, local.thread#, local.sequence#, local.resetlogs_change#, local.resetlogs_time, local.first_change#, local.first_time, local.next_change#, local.next_time, local.blocks, local.block_size, FALSE, local.terminal, local.activation); END checkBackupRedolog; -- PROCEDURE checkBackupSpfile(bi IN kccbi_t) IS local backup_spfile_t; BEGIN -- -- SELECT rai_recid.nextval, bi.bistm, bi.bibss, bi.bibsc, stamp2date(bi.bimdt), bi.bifsz, stamp2date(bi.bistm), bi.bidun, bi.bioid INTO local FROM dual WHERE bitand(bi.biflg, 1) != 1; -- dbms_rcvcat.checkBackupSpFile( local.recid, local.stamp, local.set_stamp, local.set_count, local.modification_time, local.bytes, FALSE, local.db_unique_name, local.guid); END checkBackupSpfile; -- PROCEDURE checkArchivedLog(al IN kccal_t) IS local archived_log_t; l_archived varchar2(10); l_is_standby varchar2(1); l_terminal varchar2(3); BEGIN -- -- SELECT rai_recid.nextval, al.alstm, al.alnam, al.aldst, al.althp, al.alseq, al.alrls, stamp2date(al.alrlc), al.alrlc, al.allos, stamp2date(al.allot), al.alnxs, stamp2date(al.alnxt), al.albct, al.albsz, decode(bitand(al.alflg, 16+32+64+128+256), 16, 'ARCH', 32, 'FGRD', 64, 'RMAN', 128,'SRMN', 256,'LGWR', 'UNKNOWN'), decode(bitand(al.alflg, 4), 4, 'RFS', decode(bitand(al.alflg, 16+32+64+128+256), 16, 'ARCH', 32, 'FGRD', 64, 'RMAN', 128,'SRMN', 256,'LGWR', 'UNKNOWN')), decode(bitand(al.alflg, 8),0,'NO','YES'), decode(bitand(al.alflg, 2),0,'NO','YES'), decode(bitand(al.alflg, 1024),0, (decode(bitand(al.alfl2, 16384),0,'NO','IN-MEMORY')),'YES'), decode(bitand(al.alflg, 1),0,'NO','YES'), decode(bitand(al.alflg, 1+2048+4096), 0, 'A', 1, 'D', 2048,'X', 4096,'U', '?'), stamp2date(al.alstm), decode(bitand(al.alflg,8192),0,'NO','YES'), decode(bitand(al.alflg,16384),0,'NO','YES'), decode(bitand(al.alflg,32768),0,'NO','YES'), to_number(bitand(al.alfl2,15)), al.altoa, al.alacd, decode(bitand(al.alfl2,64),0,'NO','YES'), decode(bitand(al.alfl2,128),0,'NO','YES'), decode(bitand(al.alflg,512),0,'NO','YES'), decode(bitand(al.alfl2,256+512+1024), 256, 'TERMINAL', 512, 'ACTIVATION', 1024, 'RESETLOGS', decode(bitand(al.alflg,32768),0,'','SWITCHOVER')), decode(bitand(al.alfl2,4096), 0, null, 'Y') INTO local FROM dual; -- -- -- SELECT decode(local.archived, 'YES', 'Y', 'NO', 'N', 'UNKNOWN'), decode(local.registrar, 'RFS', 'Y', 'SRMN', 'Y', 'N'), decode (local.end_of_redo_type, 'TERMINAL', 'YES', 'NO') INTO l_archived, l_is_standby, l_terminal FROM dual; dbms_rcvcat.checkArchivedLog( local.recid, local.stamp, local.thread#, local.sequence#, local.resetlogs_change#, local.resetlogs_time, local.first_change#, local.first_time, local.next_change#, local.next_time, local.blocks, local.block_size, local.name, l_archived, local.completion_time, local.status, l_is_standby, null, null, local.is_recovery_dest_file, local.compressed, local.creator, l_terminal, FALSE); END checkArchivedLog; -- FUNCTION number2null(p_name IN VARCHAR2) RETURN NUMBER IS BEGIN paramtab(p_name) := TRUE; return NULL; END number2null; FUNCTION varchar2null(p_name IN VARCHAR2) RETURN VARCHAR2 IS BEGIN paramtab(p_name) := TRUE; return NULL; END varchar2null; FUNCTION intervalnull(p_name IN VARCHAR2) RETURN DSINTERVAL_UNCONSTRAINED IS BEGIN paramtab(p_name) := TRUE; return NULL; END intervalnull; FUNCTION isparamdef(p_name IN VARCHAR2) RETURN BOOLEAN IS loc boolean := FALSE; BEGIN if (paramtab.exists(p_name)) then loc := paramtab(p_name); paramtab(p_name) := FALSE; end if; return loc; END isparamdef; -- FUNCTION statBpSbt(db_key IN NUMBER, handle IN VARCHAR2, mhandle OUT NOCOPY SYS.KBRSI_ICD.NAMES$_T, single OUT BINARY_INTEGER) RETURN BINARY_INTEGER IS status BINARY_INTEGER; parms VARCHAR2(1024); node VARCHAR2(512); devtype VARCHAR2(512); l_lib_key NUMBER; l_lib_name sbt_lib_desc.lib_name%TYPE; l_lib_status sbt_lib_desc.status%TYPE; BEGIN deb('statBpSbt: handle= ' || handle); -- SELECT lib.parms, lib.status, lib.lib_name, lib.lib_key INTO parms, l_lib_status, l_lib_name, l_lib_key FROM sbt_lib_desc lib, bp WHERE bp.lib_key = lib.lib_key AND bp.handle = statBpSbt.handle AND bp.db_key = statBpSbt.db_key; -- IF (l_lib_status != 'R') THEN deb('statBpSbt: library not ready'); RETURN 1; END IF; -- devtype := sys.dbms_backup_restore.deviceAllocate( ident => 'RA$SBT', node => node, type => 'SBT_TAPE', params => parms, dupcnt => 1, allowmts => TRUE, ors_lib_key => l_lib_key, db_name => NULL, platform_id => 0); -- status := sys.kbrsi_icd.statBpSbt( handle => handle, mhandle => mhandle, single => single); -- sys.dbms_backup_restore.deviceDeallocate; RETURN status; EXCEPTION WHEN others THEN save_error; -- IF (devtype IS NOT NULL) THEN sys.dbms_backup_restore.deviceDeallocate; END IF; sys.kbrsi_icd.rsClearErr; clear_error; deb('statBpSbt: failed ' || sqlerrm); RETURN 0; END statBpSbt; -- FUNCTION dg_is_db_ok(p_dbid IN NUMBER) RETURN NUMBER IS l_answer NUMBER; l_dbkey NUMBER; l_slkey NUMBER; l_state NUMBER; l_repair NUMBER; BEGIN -- IF NOT sys.kbrsi_icd.isorsalive THEN deb('dg_is_db_ok: BA is DOWN'); RETURN FALSE#; END IF; -- -- -- BEGIN SELECT db.db_key, odb.sl_key INTO l_dbkey, l_slkey FROM db, odb, sl WHERE db.db_id = p_dbid AND db.db_key = odb.db_key AND odb.sl_key = sl.sl_key AND odb.db_state IS NULL AND sl.sl_needs_repair IS NULL; l_answer := TRUE#; EXCEPTION WHEN no_data_found THEN save_error; BEGIN SELECT odb.db_state, sl.sl_needs_repair INTO l_state, l_repair FROM db, odb, sl WHERE db.db_id = p_dbid AND db.db_key = odb.db_key AND odb.sl_key = sl.sl_key; deb('dg_is_db_ok: NO DATA FOUND, db_state: ' || TO_CHAR(l_state) || ', needs_repair: ' || TO_CHAR(l_repair)); EXCEPTION WHEN OTHERS THEN save_error; deb('dg_is_db_ok: no_data_found debugging query failed: ' || SQLCODE || ' ' || SQLERRM); clear_error; END; l_answer := FALSE#; clear_error; END; -- RETURN l_answer; END dg_is_db_ok; -- FUNCTION dg_get_platform_id(p_dbid IN NUMBER) RETURN NUMBER IS l_platid NUMBER; BEGIN deb('dg_get_platform_id: For dbid ' || to_char(p_dbid)); SELECT odb.platform_id INTO l_platid FROM db, odb WHERE db.db_id = p_dbid AND db.db_key = odb.db_key; deb('dg_get_platform_id: return ' || to_char(l_platid)); RETURN l_platid; END dg_get_platform_id; -- PROCEDURE dg_register_log(p_dbid IN NUMBER, p_filename IN VARCHAR2) IS task_rec task%ROWTYPE; BEGIN deb('dg_register_log: ' || p_filename, AM_DEBUG_MED); /* THIS CAN BE RETIRED */ END dg_register_log; -- PROCEDURE dg_backup_log(p_dbid IN NUMBER, p_filename IN VARCHAR2, p_complete IN BOOLEAN, p_delete IN BOOLEAN DEFAULT TRUE) IS task_rec task%ROWTYPE; BEGIN deb('dg_backup_log: ' || p_filename, AM_DEBUG_MED); -- -- -- SELECT db_key INTO task_rec.db_key FROM db WHERE db_id = p_dbid; IF p_complete THEN task_rec.task_type := dbms_ra_scheduler.TASK_BACKUP_ARCH; ELSE task_rec.task_type := dbms_ra_scheduler.TASK_INC_ARCH; END IF; -- -- -- task_rec.param := p_filename; task_rec.param_num1 := p_dbid; IF p_delete THEN task_rec.param_num2 := 1; ELSE task_rec.param_num2 := 0; END IF; dbms_ra_scheduler.new_task (task_rec); END dg_backup_log; -- -- -- PROCEDURE RebuildBlockPool(p_dfkey IN NUMBER) IS BEGIN deb('RebuildBlockPool for df ' || p_dfkey, AM_DEBUG_MED); -- dbms_ra_scheduler.stop (p_quiesce_first => FALSE); -- -- -- UPDATE config SET value = '.9994' WHERE name = '_last_incarnation'; -- DELETE vbdf WHERE vbdf.df_key = p_dfkey; deb('RebuildBlockPool: Deleted ' || SQL%ROWCOUNT || ' vbdfs', AM_DEBUG_MED); -- DELETE blocks WHERE df_key = p_dfkey; deb('RebuildBlockPool: Deleted ' || SQL%ROWCOUNT || ' blocks', AM_DEBUG_MED); -- DELETE chunks WHERE chunks.df_key = p_dfkey; deb('RebuildBlockPool: Deleted ' || SQL%ROWCOUNT || ' chunks', AM_DEBUG_MED); COMMIT; -- dbms_ra_scheduler.init (p_repair => TRUE); deb('RebuildBlockPool: Completed ', AM_DEBUG_MED); END RebuildBlockPool; -- -- -- FUNCTION sbt_default_drives RETURN NUMBER IS l_drives_per_node NUMBER; l_min_drives NUMBER; l_max_drives NUMBER; l_instances NUMBER; l_drives NUMBER; BEGIN SELECT nvl(max(to_number(value)), 4) INTO l_drives_per_node FROM config WHERE name = '_replication_streams_per_node'; SELECT nvl(max(to_number(value)), 4) INTO l_min_drives FROM config WHERE name = '_replication_min_streams'; SELECT nvl(max(to_number(value)), 64) INTO l_max_drives FROM config WHERE name = '_replication_max_streams'; SELECT count(*) INTO l_instances FROM sys.rai_active_instances; l_drives := l_drives_per_node * l_instances; IF l_drives < l_min_drives THEN l_drives := l_min_drives; END IF; IF l_drives > l_max_drives THEN l_drives := l_max_drives; END IF; RETURN l_drives; END sbt_default_drives; -- -- -- -- -- PROCEDURE info_start(p_module VARCHAR2, p_action IN VARCHAR2) IS c BINARY_INTEGER := s_info_module.COUNT; BEGIN s_info_module(c) := p_module; s_info_action(c) := p_action; dbms_application_info.set_module(p_module, p_action); deb('info_start ' || s_info_module.COUNT, AM_DEBUG_MED); END info_start; -- -- -- -- -- -- PROCEDURE info_end(p_reset BOOLEAN DEFAULT FALSE) IS BEGIN deb('info_end ' || s_info_module.COUNT, AM_DEBUG_MED); -- IF s_info_module.COUNT = 0 AND NOT p_reset THEN -- IF debug >= AM_DEBUG_MED THEN sys.dbms_sys_error.raise_system_error( dbms_ra_scheduler.E_INTERNAL_ERROR_NUM, 'Missing info_start call'); ELSE deb('info_end: Missing info_start, count is ' || s_info_module.COUNT, AM_DEBUG_ON); s_info_module(0) := 'ILLEGAL INDEX'; s_info_action(0) := 'ILLEGAL INDEX'; END IF; END IF; -- IF p_reset THEN IF s_info_module.COUNT > 1 THEN deb('info_end reset done, count ' || s_info_module.COUNT); END IF; -- WHILE (s_info_module.COUNT > 1) LOOP s_info_module.DELETE(s_info_module.LAST); s_info_action.DELETE(s_info_action.LAST); END LOOP; ELSE IF s_info_module.COUNT > 1 THEN s_info_module.DELETE(s_info_module.LAST); s_info_action.DELETE(s_info_action.LAST); ELSE s_info_module(0) := NULL; s_info_action(0) := NULL; END IF; END IF; dbms_application_info.set_module(s_info_module(s_info_module.LAST), s_info_action(s_info_action.LAST)); END info_end; -- -- -- -- -- -- PROCEDURE populate_rsr_key(p_bp_key IN NUMBER, p_bs_key IN NUMBER) IS l_rsr_key NUMBER; l_vb_key NUMBER; l_rsr NUMBER; l_srcbp_key NUMBER; l_ba_access bp.ba_access%TYPE; l_device_type bp.device_type%TYPE; BEGIN deb('populate_rsr_key : Entered p_bp_key = ' || p_bp_key || ' p_bs_key = ' || p_bs_key); SELECT vb_key, rsr_key, ba_access, device_type INTO l_vb_key, l_rsr_key, l_ba_access, l_device_type FROM bp WHERE bp_key = p_bp_key; -- IF l_vb_key IS NULL THEN IF l_rsr_key IS NULL THEN -- -- -- BEGIN SELECT rsr_key INTO l_rsr FROM bp WHERE bs_key = p_bs_key AND rsr_key IS NOT NULL AND rownum = 1; EXCEPTION WHEN no_data_found THEN deb('populate_rsr_key : No bp rows with bs_key = '|| p_bs_key || ' has rsr_key. Resync is yet to happen.'); RETURN; END; UPDATE bp SET rsr_key = l_rsr WHERE bp_key = p_bp_key AND rsr_key IS NULL; deb('populate_rsr_key : Updated ' || SQL%ROWCOUNT || ' rows in bp '|| 'with rsr_key = ' || l_rsr || ' ;copy2tape/replication bkps'); ELSE -- -- -- -- BEGIN SELECT vb_key INTO l_vb_key FROM vbdf WHERE srcbp_key = p_bp_key AND rownum = 1; EXCEPTION WHEN no_data_found THEN -- IF l_ba_access = 'U' AND l_device_type = 'DISK' THEN -- -- -- UPDATE bp SET rsr_key = l_rsr_key WHERE (bs_key IN (SELECT bs_key FROM bp WHERE vb_key IN (SELECT vb_key FROM vbdf WHERE srcbp_key IN (SELECT bp_key FROM bp WHERE bs_key = p_bs_key))) OR bs_key = p_bs_key) AND rsr_key IS NULL; deb('populate_rsr_key : Updated ' || SQL%ROWCOUNT || ' rows in bp with rsr_key = ' || l_rsr_key || ' ;polling bkps'); ELSE -- -- -- UPDATE bp SET rsr_key = l_rsr_key WHERE bs_key = p_bs_key; deb('populate_rsr_key : Updated ' || SQL%ROWCOUNT || ' rows in bp with rsr_key = ' || l_rsr_key || ' ;resync - ' || ' non-datafiles copy2tape/replication '); END IF; RETURN; END; UPDATE bp SET rsr_key = l_rsr_key WHERE bs_key IN (SELECT bs_key FROM bp WHERE vb_key = l_vb_key) AND rsr_key IS NULL; deb('populate_rsr_key : Updated ' || SQL%ROWCOUNT || ' rows in bp with rsr_key = ' || l_rsr_key || ' ;resync -' || 'virtual bkps and their copy2tape and replication bkps'); END IF; ELSE -- -- -- BEGIN SELECT srcbp_key INTO l_srcbp_key FROM vbdf WHERE vb_key = l_vb_key AND rownum = 1; IF l_srcbp_key IS NOT NULL THEN SELECT rsr_key INTO l_rsr FROM bp WHERE bp_key = l_srcbp_key; END IF; EXCEPTION WHEN no_data_found THEN deb('populate_rsr_key : no parent bp row available' || 'for vb_key= ' || l_vb_key); RETURN; END; IF l_rsr IS NOT NULL THEN UPDATE bp SET rsr_key = l_rsr WHERE bp_key = p_bp_key AND rsr_key IS NULL; deb('populate_rsr_key : Updated ' || SQL%ROWCOUNT || ' rows in bp with rsr_key = ' || l_rsr || '; virtual backups'); END IF; END IF; END populate_rsr_key; /*---------------------------------------------------------------------------- * This is for avm front end congestion control. If the requirement for a new * backup job exceeds the system bottleneck the job will have to wait. * * This is a co-operative throttling algorithm, where there will be many RMAN * jobs simultaneously requesting for AvM resources. Each RMAN client will * ping AvM at regular intervals (set to 1 min currently) until it gets a green * signal from the AvM side. AvM decides this based on the currently active * backup streams (channels) and the maximum allowable number of channels. AvM * will serve the clients in a first come first served manner. Once a client * gets approval it can go ahead with all its channel allocation. * * The algorithm uses the following four config parameters, viz, * _throttle_max_channels : * This denotes the maximum number of channels allowed in AvM. In * other words, this is the maximum limit after which we assume all * AvM resources will be used up and no further allocation is * possible until some of the previous jobs are done. If it is not * set (or set to 0), we assume that resource control is not enabled. * _throttle_threshold_channels (default, _throttle_max_channels -(minus) * _throttle_max_single_chan_req ) : * There is really no point throttling when the current allocation * is way too less than the maximum allowable. This parameter * specifies the value after which we force each job to go * through the throttling logic. * _throttle_wait_aft_apprvl_secs (default, 180 secs) : * This specifies the time for which the next job will have to wait * after the previous job is approved. This is basically a heuristic * to guess the time interval between the approval of a job and the * actual channel allocations by that job. When a job is approved, * it'll need some time to actually allocate the channels and for * this short duration the current allocation count will be in a * transient state. So, we are assuming that by this time the * previous job will be done allocating all its channels and the * current allocation count will be stable and the next job can go * ahead with its request. * _throttle_wait_for_crash_secs (default, 30 mins) : * There can be cases where an RMAN job is crashed after requesting * channel resources. There should be some mechanism to remove the * crashed jobs from the waiting queue. This time is used for this * purpose. If there is no ping from the client for this much time * we assume that the job is killed and we remove the job from the * waiting queue. * _throttle_sbt_active_hours (default, 12 hours) : * BA will clear up the active sessions which are older than this * time * _throttle_max_single_chan_req (default, 128) : * This specifies the maximum channels that can be requested in * one request * _throttle_wait_repeat_req_secs (default, 300 secs) : * This specifies the minimum time for which the client has to wait * before requesting for channels again * * Following is the high-level overview of the algorithm used: * * Inputs: * p_ba_job_id : unique identifier for the client requesting resources. * p_channels_reqd: number of channels required by the client. * p_request_time: time when the request is made. * Outputs: * p_wait : boolean output indicating wheather the client nedds to wait * more. if p_wait = false, its a green signal from AvM and the * client can go ahead with the allocation, otherwise the client * will have to wait and re-ping after some time. * p_error_str: indicates if there is any error condition. * * Algorithm: * 0. All the parameters that control the congestion algorithm will be * read only once per RMAN client. * 1. We allow the job to allocate required_channels if any of the * following is true - * a) If number of currently allocated channels/active SBT streams * (currently_active_channels) is less than _throttle_threshold_channels * b) required_channels + currently_active_channels < * _threshold_max_channels and this is the first job in the queue. * 2. We remove a job from the queue in the following two cases - * a) When it is given go ahead with channel allocation and current * time is past throttle_waitsecs_after_approval * b) When there is no ping from an RMAN client beyond * _threshold_waitsecs_for_crash * 3. In all other cases, job from top of queue is approved when required * number of SBT streams are freed up at AvM. *---------------------------------------------------------------------------*/ PROCEDURE throttle_me_int(p_ba_job_id IN VARCHAR2, p_db_unique_name IN VARCHAR2, p_channels_reqd IN NUMBER, p_request_time IN DATE, p_wait OUT BOOLEAN, p_error_str OUT VARCHAR2) IS l_min_request_time DATE; l_active_sbt_sessions NUMBER; l_rowids dbms_sql.urowid_table; l_max_channel NUMBER; l_wait_after_approve NUMBER; l_wait_for_crash NUMBER; l_threshold_channels NUMBER; l_ba_job_id VARCHAR2(256); l_max_single_req NUMBER; l_wait_for_repeat_req NUMBER; l_approved_sessions NUMBER; type avmlst is table of VARCHAR2(256) index by binary_integer; l_ba_job_ids avmlst; type sbtlst is table of VARCHAR2(32) index by binary_integer; l_sbt_sessions sbtlst; l_lock_retval NUMBER; l_lock_handle VARCHAR2(200); l_is_locked BOOLEAN := FALSE; l_ba_job_id_dbunq VARCHAR2(256); PROCEDURE release_lock IS BEGIN IF l_is_locked THEN l_lock_retval := dbms_lock.release(l_lock_handle); END IF; END; BEGIN p_wait := true; p_error_str := null; -- -- l_ba_job_id_dbunq := p_ba_job_id || p_db_unique_name; -- -- IF sys.kbrsi_icd.rskeyreadlock (dbms_ra_scheduler.lock_quiesce_pending, FALSE) THEN -- SYS.KBRSI_ICD.RSKEYUNLOCK(DBMS_RA_SCHEDULER.LOCK_QUIESCE_PENDING); ELSE deb('Throttle: Quiesce is pending. Go away.'); RETURN; END IF; deb('Throttle: throttling for db: ' || p_db_unique_name); -- SELECT /*+ RESULT_CACHE */ NVL(MAX(DECODE(name, '_throttle_max_channels', value)), 1000) mc, NVL(MAX(DECODE(name, '_throttle_threshold_channels', value)), 872) tc, NVL(MAX(DECODE(name, '_throttle_wait_aft_apprvl_secs', value)), 300) wap, NVL(MAX(DECODE(name, '_throttle_wait_for_crash_secs', value)), 1800) wfc, NVL(MAX(DECODE(name, '_throttle_max_single_chan_req', value)), 128) mscr, NVL(MAX(DECODE(name, '_throttle_wait_repeat_req_secs', value)), 300) wrr INTO l_max_channel, l_threshold_channels, l_wait_after_approve, l_wait_for_crash, l_max_single_req, l_wait_for_repeat_req FROM config WHERE name IN ( '_throttle_max_channels', '_throttle_threshold_channels', '_throttle_wait_aft_apprvl_secs', '_throttle_wait_for_crash_secs', '_throttle_max_single_chan_req', '_throttle_wait_repeat_req_secs' ); -- -- -- IF (((SYSDATE - s_last_throttled) * 86400) <= l_wait_for_repeat_req) THEN p_wait := TRUE; RETURN; END IF; -- -- IF p_channels_reqd > l_max_single_req THEN p_error_str := 'client can request only max of ' || l_max_single_req || ' channels'; RETURN; END IF; -- IF l_max_channel > 0 THEN -- -- -- -- BEGIN SELECT rowid, ba_job_id BULK COLLECT INTO l_rowids, l_ba_job_ids FROM rai_pending_jobs WHERE ((sysdate - approval_time) * 86400) >= l_wait_after_approve OR ((sysdate - last_ping_time) * 86400) >= l_wait_for_crash FOR UPDATE SKIP LOCKED; FOR i IN 1 .. l_rowids.COUNT LOOP DELETE rai_pending_jobs WHERE ROWID = l_rowids(i); deb('Throttle: Deleting entry ' || l_ba_job_ids(i) || ' from rai_pending_jobs'); END LOOP; END; -- -- BEGIN SELECT rowid, session_id BULK COLLECT INTO l_rowids, l_sbt_sessions FROM sbt_session WHERE systimestamp > (modtime + dbms_ra_scheduler.s_sbt_active_interval) FOR UPDATE SKIP LOCKED; FOR i IN 1 .. l_rowids.COUNT LOOP DELETE sbt_session WHERE ROWID = l_rowids(i); deb('Throttle: Deleting entry ' || l_sbt_sessions(i) || ' from sbt_active_sessions'); END LOOP; END; -- -- BEGIN INSERT INTO rai_pending_jobs (ba_job_id, request_time, channels_reqd, db_unique_name, last_ping_time) VALUES (l_ba_job_id_dbunq, p_request_time, p_channels_reqd, p_db_unique_name, sysdate); COMMIT; deb('Throttle: New RMAN job ' || l_ba_job_id_dbunq); EXCEPTION WHEN dup_val_on_index THEN save_error; UPDATE rai_pending_jobs SET last_ping_time = sysdate WHERE ba_job_id = l_ba_job_id_dbunq; COMMIT; clear_error; END; BEGIN -- -- -- dbms_lock.allocate_unique('ORA$ZDLRA_SBT_CHANNEL_THROTTLE', l_lock_handle); l_lock_retval := dbms_lock.request(l_lock_handle); IF l_lock_retval <> 0 THEN deb('Throttle:Unable to get lock ORA$ZDLRA_SBT_CHANNEL_THROTTLE err = ' || l_lock_retval); sys.dbms_sys_error.raise_system_error( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Throttle:Unable to get lock for throttling. Error=' || l_lock_retval); END IF; l_is_locked := TRUE; -- SELECT COUNT(*) INTO l_active_sbt_sessions FROM sbt_session; deb('Throttle: Active backup/restore sessions=' || l_active_sbt_sessions); SELECT nvl(sum(channels_reqd), 0) INTO l_approved_sessions FROM rai_pending_jobs WHERE (approval_time IS NOT NULL AND ((sysdate - approval_time) * 86400) <= l_wait_after_approve); deb('Throttle: Allowed connections=' || l_approved_sessions); -- IF (l_active_sbt_sessions + l_approved_sessions >= l_threshold_channels) THEN -- -- -- IF (l_active_sbt_sessions + p_channels_reqd + l_approved_sessions <= l_max_channel) THEN -- -- BEGIN SELECT request_time, ba_job_id INTO l_min_request_time, l_ba_job_id FROM ( SELECT request_time, ba_job_id FROM ra_database ad, rai_pending_jobs ap WHERE ad.db_unique_name = ap.db_unique_name AND approval_time IS NULL AND (((sysdate - last_ping_time) * 86400) <= (0.2 * l_wait_for_crash)) ORDER BY recovery_window_goal DESC, request_time) WHERE ROWNUM = 1; deb('Throttle: Selected job is: ' || l_ba_job_id || ' request time is: ' || l_min_request_time); deb('Throttle: Current job request time is: ' || p_request_time); IF l_min_request_time = p_request_time AND l_ba_job_id = l_ba_job_id_dbunq THEN p_wait := false; -- -- -- -- s_last_throttled := SYSDATE; ELSE deb('Throttle: need to wait'); END IF; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; NULL; clear_error; END; END IF; ELSE -- p_wait := FALSE; END IF; EXCEPTION WHEN OTHERS THEN -- release_lock; RAISE; END; ELSE -- p_wait := FALSE; END IF; BEGIN IF p_wait = FALSE THEN UPDATE rai_pending_jobs SET approval_time = sysdate WHERE ba_job_id = l_ba_job_id_dbunq AND approval_time IS NULL; IF SQL%ROWCOUNT = 1 THEN deb('Throttle: setting wait to false'); COMMIT; ELSE -- -- deb('Throttle: Unexpected, rai_pending_jobs rows updated ' || sql%rowcount); ROLLBACK; END IF; END IF; -- release_lock; EXCEPTION WHEN OTHERS THEN -- release_lock; RAISE; END; END throttle_me_int; /*---------------------------------------------------------------------------- * This routine is DBLRA specific but mimics the dbms_utility.canonicalize(). * see $ORACLE_HOME/rdbms/admin/dbmsutil.sql The interface is kept the same, * although the functionality is tailored to support longer identifiers as * well as restrict the number of supported characters to avoid customers * specifying cryptic names. * * Neither dbms_utility.canonicalize nor dbms_assert.enquote_name nor this * implementation does use a generic_m NLS sorting. I.e. e.g. customers from * Germany should not anticipate to see the conversion of Eszett symbol to * double S -- see http://en.wikipedia.org/wiki/German_alphabet. For * illustration purposes review this script: * * -- setenv NLS_LANG AMERICAN_AMERICA.UTF8 * -- export NLS_LANG=AMERICAN_AMERICA.UTF8 * SET SERVEROUTPUT ON * DECLARE * l_e VARCHAR2(1 CHAR) := UNISTR('\00DF'); * l_canon VARCHAR2(1 CHAR); * l_length BINARY_INTEGER := 1; * PROCEDURE p(s VARCHAR) IS BEGIN dbms_output.put_line(s); END; * BEGIN * p('original=[' || l_e || ']'); * p('upper=[' || UPPER(l_e) || ']'); * p('nls_upper=[' || NLS_UPPER(l_e) || ']'); * -- http://en.wikipedia.org/wiki/German_alphabet * -- "Eszett is sorted as though it were ss." * p('nls_upper_gen_m=[' || NLS_UPPER(l_e, 'NLS_SORT=GENERIC_M') || ']'); * p('enquote_name=[' || dbms_assert.enquote_name(l_e) || ']'); * p('enquote_name w/o capitalization=[' * || dbms_assert.enquote_name(l_e, FALSE) || ']'); * dbms_utility.canonicalize(l_e, l_canon, l_length); * p('dbms_utility.canonicalize=[' || l_canon || ']'); * dbms_ra_int.canonicalize(l_e, l_canon, l_length); * p('dbms_ra_int.canonicalize=[' || l_canon || ']'); * END; * / * * If this implementation is changed one must correct the corresponding * unit test tkrmrsapi.sql script *---------------------------------------------------------------------------*/ PROCEDURE canonicalize ( name IN VARCHAR2 , canon_name OUT VARCHAR2 , canon_len IN BINARY_INTEGER ) IS -- -- lc_length_limit CONSTANT BINARY_INTEGER := 1000; -- -- -- -- -- -- -- -- lc_allowed_re CONSTANT VARCHAR2(128) := '-_:#[:alnum:]'; lc_not_allowed_re CONSTANT VARCHAR2(128) := CASE WHEN lc_allowed_re IS NOT NULL THEN '[^' || lc_allowed_re || ']' END; -- -- -- -- -- -- lc_leading_restricted_chars_re CONSTANT VARCHAR2(128) := '^[-_:#[:digit:]]'; -- l_name VARCHAR2(32767 BYTE); -- l_bad_char_pos BINARY_INTEGER; BEGIN -- IF (name IS NULL) THEN RETURN; END IF; -- IF (canon_len IS NULL OR canon_len < 1) THEN sys.dbms_sys_error.raise_system_error(-64744, 'canon_len', FALSE); END IF; -- IF (LENGTH(name) > lc_length_limit OR canon_len > lc_length_limit) THEN sys.dbms_sys_error.raise_system_error( -64745, TO_CHAR(lc_length_limit), FALSE ); END IF; -- -- -- BEGIN l_name := TRIM(BOTH '"' FROM dbms_assert.enquote_name(str => name)); EXCEPTION WHEN VALUE_ERROR OR dbms_assert.INVALID_SQL_NAME THEN sys.dbms_sys_error.raise_system_error(-64746, FALSE); END; -- l_bad_char_pos := GREATEST( REGEXP_INSTR(l_name, lc_not_allowed_re) , REGEXP_INSTR(l_name, lc_leading_restricted_chars_re) ); IF (l_bad_char_pos > 0) THEN sys.dbms_sys_error.raise_system_error( -64747, SUBSTR(l_name, l_bad_char_pos, 1), TO_CHAR(l_bad_char_pos), FALSE ); END IF; -- canon_name := SUBSTR(l_name, 1, canon_len); END canonicalize; -- -- -- -- -- -- -- FUNCTION build_rep_tpl_name ( rep_srv_name IN VARCHAR2, db_key IN NUMBER, prot_key IN NUMBER) RETURN VARCHAR2 IS tmp_name VARCHAR2(1024); l_server_key NUMBER; l_rep_srv_key NUMBER; BEGIN SELECT server_key INTO l_server_key FROM server WHERE rep_server_name=build_rep_tpl_name.rep_srv_name; SELECT rep_server_key INTO l_rep_srv_key FROM rep_server WHERE server_key = l_server_key AND prot_key = build_rep_tpl_name.prot_key; -- -- -- tmp_name := 'REP$TPL_' || l_rep_srv_key || '_' || db_key || '_' || rep_srv_name; RETURN substr(tmp_name, 1, 128); EXCEPTION WHEN NO_DATA_FOUND THEN -- -- -- save_error; -- am_tracei('BUILD_REP_TPL_NAME: Did not find needed info.' || ', rep server=' || rep_srv_name || ', db_key=' || db_key || ', l_server_key=' || l_server_key || ', l_prot_key=' || prot_key || ', l_rep_srv_key=' || l_rep_srv_key); sys.dbms_sys_error.raise_system_error( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'BUILD_REP_TPL_NAME: Did not find needed info.' || ', rep server=' || rep_srv_name || ', db_key=' || db_key || ', l_server_key=' || l_server_key || ', l_prot_key=' || prot_key || ', l_rep_srv_key=' || l_rep_srv_key, FALSE); END build_rep_tpl_name; -- -- -- -- -- -- -- FUNCTION build_rep_lib_name (rep_srv_name IN VARCHAR2, server_key IN NUMBER DEFAULT NULL ) RETURN VARCHAR2 IS tmp_name VARCHAR2(1024); l_skey VARCHAR2(128) := to_char(server_key); BEGIN IF server_key IS NULL THEN SELECT to_char(server_key) INTO l_skey FROM server WHERE rep_server_name=rep_srv_name; END IF; tmp_name := 'REP$LIB_' || l_skey || '_' || rep_srv_name; RETURN substr(tmp_name, 1, 128); EXCEPTION WHEN NO_DATA_FOUND THEN -- -- -- save_error; -- am_tracei('BUILD_REP_LIB_NAME: Did not find rep server ' || rep_srv_name); sys.dbms_sys_error.raise_system_error( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'BUILD_REP_LIB_NAME: Did not find rep server ' || rep_srv_name, FALSE); END build_rep_lib_name; -- -- -- -- -- FUNCTION build_rep_atr_name (rep_srv_name IN VARCHAR2, server_key IN NUMBER DEFAULT NULL) RETURN VARCHAR2 IS tmp_name VARCHAR2(1024); l_skey VARCHAR2(128) := to_char(server_key); BEGIN IF server_key IS NULL THEN SELECT to_char(server_key) INTO l_skey FROM server WHERE rep_server_name=rep_srv_name; END IF; tmp_name := 'REP$ATR_' || l_skey || '_' || rep_srv_name; RETURN substr(tmp_name, 1, 128); EXCEPTION WHEN NO_DATA_FOUND THEN -- -- -- save_error; -- am_tracei('BUILD_REP_ATR_NAME: Did not find rep server ' || rep_srv_name); sys.dbms_sys_error.raise_system_error( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'BUILD_REP_ATR_NAME: Did not find rep server ' || rep_srv_name, FALSE); END build_rep_atr_name; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE lock_api_int (p_op_type IN NUMBER DEFAULT NULL, p_routine IN VARCHAR2 DEFAULT NULL, p_dbgnotes IN VARCHAR2 DEFAULT NULL) IS CURSOR existing_locks IS SELECT ba_type, key FROM sys.rai_js_locks WHERE sid = SYS_CONTEXT('USERENV', 'SID') AND (ba_type IN (DBMS_RA_SCHEDULER.LOCK_KEY, DBMS_RA_SCHEDULER.LOCK_PURGE, DBMS_RA_SCHEDULER.LOCK_SL_KEY, DBMS_RA_SCHEDULER.LOCK_DB_KEY) OR (ba_type = DBMS_RA_SCHEDULER.LOCK_COMMON AND key = DBMS_RA_SCHEDULER.LOCK_API)); l_sid NUMBER; l_instance NUMBER; l_existing_locks NUMBER; l_api_lock_wait NUMBER; BEGIN am_tracei ('LOCK_API_INT for: ' || p_routine || ', lock type: ' || p_op_type || ', with dbg notes:' || p_dbgnotes); -- -- -- SELECT COUNT(*) INTO l_existing_locks FROM sys.rai_js_locks WHERE sid = SYS_CONTEXT('USERENV', 'SID') AND (ba_type IN (DBMS_RA_SCHEDULER.LOCK_KEY, DBMS_RA_SCHEDULER.LOCK_PURGE, DBMS_RA_SCHEDULER.LOCK_SL_KEY, DBMS_RA_SCHEDULER.LOCK_DB_KEY) OR (ba_type = DBMS_RA_SCHEDULER.LOCK_COMMON AND key = DBMS_RA_SCHEDULER.LOCK_API)); -- -- -- -- -- -- -- -- IF (s_lockapi_level <> 0) OR (l_existing_locks <> 0) THEN -- SELECT SYS_CONTEXT('USERENV', 'SID') INTO l_sid FROM dual; SELECT sys_context('USERENV', 'INSTANCE') INTO l_instance FROM dual; am_tracei('LOCK_API_INT: ERROR - API lock exists for this session: ' || ' existing_lock_cnt=' || l_existing_locks || ' s_lockapi_level=' || s_lockapi_level || ' l_instance=' || l_instance || ' l_sid=' || l_sid); END IF; IF (l_existing_locks <> 0) THEN am_tracei('LOCK_API_INT: Releasing all API locks help by this session'); -- FOR l IN existing_locks LOOP am_tracei('LOCK_API_INT: Releasing API lock due to ctrl-c: ' || ' Lock type:' || l.ba_type || ', Lock key:' || l.key ); CASE l.ba_type WHEN DBMS_RA_SCHEDULER.LOCK_DB_KEY THEN dbms_ra_storage.unlock_db(l.key); WHEN DBMS_RA_SCHEDULER.LOCK_SL_KEY THEN dbms_ra_storage.unlock_sl(l.key); WHEN DBMS_RA_SCHEDULER.LOCK_PURGE THEN sys.kbrsi_icd.rspurgeunlock(l.key); WHEN DBMS_RA_SCHEDULER.LOCK_KEY THEN sys.kbrsi_icd.rskeyunlock(l.key); WHEN DBMS_RA_SCHEDULER.LOCK_COMMON THEN unlock_api_int(p_results=>FALSE, p_docommit=>FALSE); END CASE; END LOOP; -- ROLLBACK; -- s_lockapi_level := 0; END IF; -- -- s_lockapi_routine := p_routine; s_lockapi_notes := p_dbgnotes; s_lockapi_type := p_op_type; -- SELECT value INTO l_api_lock_wait FROM config WHERE name = '_api_lock_wait_seconds'; -- WHILE NOT sys.kbrsi_icd.rsapilock LOOP BEGIN -- IF l_api_lock_wait > 0 THEN l_api_lock_wait := l_api_lock_wait - 1; dbms_lock.sleep(1); CONTINUE; END IF; -- SELECT inst_id, sid INTO l_instance, l_sid FROM sys.rai_js_gvlocks WHERE ba_type = dbms_ra_scheduler.lock_common AND key = dbms_ra_scheduler.lock_api AND lmode = 6; -- =KSQMX (exclusive mode) sys.dbms_sys_error.raise_system_error(DBMS_RA.API_BLOCKED_NUM, l_sid, l_instance, FALSE); EXCEPTION WHEN NO_DATA_FOUND THEN dbms_lock.sleep(1); CONTINUE; END; END LOOP; s_lockapi_level := s_lockapi_level + 1; EXCEPTION WHEN OTHERS THEN am_tracei ('LOCK_API_INT EXCEPTION: ' || SQLERRM); RAISE; END lock_api_int; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE unlock_api_int (p_routine IN VARCHAR2 DEFAULT NULL, p_dbgnotes IN VARCHAR2 DEFAULT NULL, p_the_num IN NUMBER DEFAULT 0, p_results IN BOOLEAN DEFAULT TRUE, p_docommit IN BOOLEAN DEFAULT FALSE) IS BEGIN am_tracei ('UNLOCK_API_INT for ' || p_routine || '()' || p_dbgnotes); -- IF (p_the_num > 0) THEN dbms_ra_scheduler.update_task_history_entry ( task_id => p_the_num , param_char2 => CASE WHEN p_results THEN 'SUCCESS' ELSE 'FAIL' END , do_commit => p_docommit ); END IF; -- -- -- SELECT COUNT(*) INTO s_lockapi_level FROM sys.rai_js_locks WHERE sid = SYS_CONTEXT('USERENV', 'SID') AND ba_type = DBMS_RA_SCHEDULER.LOCK_COMMON AND key = DBMS_RA_SCHEDULER.LOCK_API; IF (s_lockapi_level > 0) THEN s_lockapi_routine := NULL; s_lockapi_notes := NULL; s_lockapi_type := NULL; -- sys.kbrsi_icd.rsapiunlock; s_lockapi_level := s_lockapi_level - 1; END IF; EXCEPTION WHEN OTHERS THEN am_tracei ('UNLOCK_API_INT EXCEPTION: ' || SQLERRM); RAISE; END unlock_api_int; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION build_parameter (p_paramtype IN NUMBER, p_varname IN VARCHAR2, p_strval IN VARCHAR2 DEFAULT NULL, p_numval IN NUMBER DEFAULT NULL, p_boolval IN BOOLEAN DEFAULT NULL, p_intval IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, p_first IN BOOLEAN DEFAULT FALSE, p_last IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2 IS l_str VARCHAR2(4000); BEGIN IF p_first THEN l_str := l_str || '('; END IF; IF NOT p_first THEN l_str := l_str || ', '; END IF; l_str := l_str || p_varname || '=>'; CASE p_paramtype WHEN PTYPE_STR THEN IF p_strval IS NULL THEN l_str := l_str || 'NULL'; ELSE l_str := l_str || '''' || p_strval || ''''; END IF; WHEN PTYPE_NUM THEN IF p_numval IS NULL THEN l_str := l_str || 'NULL'; ELSE l_str := l_str || p_numval; END IF; WHEN PTYPE_BOOL THEN IF p_boolval IS NULL THEN l_str := l_str || 'NULL'; ELSIF p_boolval THEN l_str := l_str || 'TRUE'; ELSE l_str := l_str || 'FALSE'; END IF; WHEN PTYPE_INT THEN IF p_intval IS NULL THEN l_str := l_str || 'NULL'; ELSE -- l_str := l_str || p_intval; END IF; ELSE l_str := l_str || ''; END CASE; IF p_last THEN l_str := l_str || ')'; END IF; RETURN l_str; END build_parameter; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION b_p_i (p_varname IN VARCHAR2, p_strval IN VARCHAR2 DEFAULT NULL, p_first IN BOOLEAN DEFAULT FALSE, p_last IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2 IS BEGIN RETURN build_parameter (p_paramtype => PTYPE_STR, p_varname => p_varname, p_strval => p_strval, p_first => p_first, p_last => p_last); END b_p_i; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION b_p_i (p_varname IN VARCHAR2, p_numval IN NUMBER DEFAULT NULL, p_first IN BOOLEAN DEFAULT FALSE, p_last IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2 IS BEGIN RETURN build_parameter (p_paramtype => PTYPE_NUM, p_varname => p_varname, p_numval => p_numval, p_first => p_first, p_last => p_last); END b_p_i; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION b_p_i (p_varname IN VARCHAR2, p_boolval IN BOOLEAN DEFAULT NULL, p_first IN BOOLEAN DEFAULT FALSE, p_last IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2 IS BEGIN RETURN build_parameter (p_paramtype => PTYPE_BOOL, p_varname => p_varname, p_boolval => p_boolval, p_first => p_first, p_last => p_last); END b_p_i; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION b_p_i (p_varname IN VARCHAR2, p_intval IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, p_first IN BOOLEAN DEFAULT FALSE, p_last IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2 IS BEGIN RETURN build_parameter (p_paramtype => PTYPE_INT, p_varname => p_varname, p_intval => p_intval, p_first => p_first, p_last => p_last); END b_p_i; -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE am_tracei (p_message IN VARCHAR2) IS BEGIN -- sys.kbrsi_icd.rsTrace('BA: ' || p_message); -- END am_tracei; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION item_not_foundi (p_obj_name IN VARCHAR2, p_obj_type IN VARCHAR2) RETURN VARCHAR2 IS BEGIN RETURN 'item not found: ' || p_obj_name ||' (' || p_obj_type || ')'; END item_not_foundi; -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE replication_reconcile_reset (db_unique_name IN VARCHAR2) IS BEGIN NULL; -- END; -- -- -- -- -- -- PROCEDURE rep_rec_by_prot_int (p_prot_key IN NUMBER) IS l_cnt NUMBER; l_db_key NUMBER; l_rep_server_key NUMBER; l_all_reconciled BOOLEAN := TRUE; -- CURSOR toreconcile_cursor(pp_key IN NUMBER) IS select rep_server_key rep_server_key, o.db_key db_key, rs.server_key from rep_server rs, odb o where rs.prot_key = pp_key and rs.status = 'A' and o.prot_key = rs.prot_key and o.db_state is NULL; BEGIN am_tracei('reconcile by prot prot_key=' || p_prot_key); -- IF p_prot_key IS NULL THEN am_tracei('replication_reconcile_prot_int NULL prot_key'); sys.dbms_sys_error.raise_system_error (DBMS_RA.INVALID_VAL_NUM, 'replication_reconcile_prot_int NULL prot_key', FALSE); END IF; -- -- -- FOR r IN toreconcile_cursor(p_prot_key) LOOP am_tracei('reconcile by prot prot_key=' || p_prot_key || ', r.db_key=' || r.db_key || ', r.rep_server_key=' || r.rep_server_key || ', r.server_key=' || r.server_key) ; replication_reconcile_int (r.db_key, r.server_key); END LOOP; am_tracei('reconcile by prot SUCCESS - prot_key=' || p_prot_key); END rep_rec_by_prot_int; -- -- -- -- -- -- PROCEDURE replication_reconcile_int (p_db_key IN NUMBER DEFAULT NULL, p_server_key IN NUMBER DEFAULT NULL) IS l_cnt NUMBER; l_success BOOLEAN; l_exp_cnt NUMBER; BEGIN -- IF p_db_key IS NULL THEN am_tracei('replication_reconcile_int NULL db_key'); sys.dbms_sys_error.raise_system_error (DBMS_RA.INVALID_VAL_NUM, 'replication_reconcile_int NULL db_key', FALSE); END IF; IF p_server_key IS NOT NULL THEN l_exp_cnt := 1; ELSE SELECT count(*) INTO l_exp_cnt FROM rep_server rs WHERE rs.prot_key = (SELECT prot_key FROM odb WHERE db_key=p_db_key and db_state is NULL); END IF; -- l_success := dbms_ra_scheduler.reconcile_db ( p_db_key => p_db_key, p_server_key => p_server_key, p_only_active => FALSE, p_force_reconcile => TRUE, rec_cnt => l_cnt); IF NOT l_success OR l_cnt <> l_exp_cnt THEN dbms_ra_scheduler.log_error(p_errno => dbms_ra.REP_SETUP_ERROR_NUM, p_db_key => p_db_key, p_param1 => 'reconcile_db', p_param2 => 'USER_REC_SRV_KEY=p_server_key', p_param3 => dbms_ra_int.dbkey2name(p_db_key), P_keep_stack => FALSE, p_component =>'REPLICATION_RECONCILE', p_severity => dbms_ra_scheduler.SEVERITY_ERROR, p_param_char => 'RECONCILE'); ELSE dbms_ra_scheduler.fix_error (p_error_num => dbms_ra.REP_SETUP_ERROR_NUM, p_db_key => p_db_key, p_param_char => 'RECONCILE'); END IF; END replication_reconcile_int; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE replication_reconcile ( db_unique_name IN VARCHAR2 DEFAULT NULL, replication_server_name IN VARCHAR2 DEFAULT NULL) IS l_the NUMBER; l_db_key NUMBER := NULL; l_rep_server_key NUMBER := NULL; l_server_key NUMBER := NULL; l_cnt NUMBER; l_obj_type VARCHAR2(128); l_obj_name VARCHAR2(128); c_db_unique_name VARCHAR2(128); c_rep_server_name VARCHAR2(128); locked BOOLEAN := FALSE; -- -- CURSOR prot_list IS select prot.prot_name, prot.prot_key from prot where prot.prot_key in (select prot_key from rep_server where status = 'A'); -- CURSOR repserv_by_name_cursor(repsrvr_name IN VARCHAR2) IS select rs.rep_server_key, rs.prot_key, rs.server_key from rep_server rs, server s where s.rep_server_name = repsrvr_name and rs.server_key = s.server_key and rs.status = 'A'; -- CURSOR repserv_by_dbs_prot(odb_db_key in NUMBER) IS select rs.rep_server_key, rs.server_key from rep_server rs, odb o, server s where o.db_key = odb_db_key and o.db_state is NULL and rs.prot_key = o.prot_key and s.server_key = rs.server_key and rs.status = 'A'; BEGIN am_tracei('reconcile db_unique_name=' || db_unique_name || ', replication_server_name=' || replication_server_name); lock_api_int(DBMS_RA.LOCKAPI_MODIFY, 'replication_reconcile'); locked := TRUE; dbms_ra_int.canonicalize(db_unique_name, c_db_unique_name, 128); dbms_ra_int.canonicalize(replication_server_name, c_rep_server_name, 128); -- IF c_db_unique_name IS NOT NULL THEN BEGIN SELECT db_key INTO l_db_key FROM node WHERE node.db_unique_name = c_db_unique_name; EXCEPTION WHEN NO_DATA_FOUND THEN l_obj_type := 'db unique name'; l_obj_name := c_db_unique_name; RAISE DBMS_RA.OBJ_NOT_FOUND; END; END IF; l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_REPLICATION_RECONCILE, param => 'replication_reconcile' || b_p_i('db_unique_name', c_db_unique_name, p_first=>TRUE) || b_p_i('replication_server_name', c_rep_server_name, p_last=>TRUE)); IF c_db_unique_name IS NULL THEN -- IF c_rep_server_name IS NULL THEN -- -- -- FOR p IN prot_list LOOP am_tracei ('replication_reconcile (1): prot_key=' || p.prot_key); rep_rec_by_prot_int (p.prot_key); END LOOP; ELSE -- -- -- FOR r IN repserv_by_name_cursor(c_rep_server_name) LOOP am_tracei ('replication_reconcile (2): prot_key=' || r.prot_key); rep_rec_by_prot_int (r.prot_key); END LOOP; END IF; ELSE -- db_unique is not NULL - IE db name was specified -- IF c_rep_server_name IS NULL THEN -- -- -- am_tracei ('replication_reconcile (3b): l_db_key=' || l_db_key); FOR r IN repserv_by_dbs_prot(l_db_key) LOOP am_tracei ('replication_reconcile (3c): l_db_key=' || l_db_key || ', l_rep_server_key=' || r.rep_server_key); replication_reconcile_int (l_db_key, r.server_key); END LOOP; ELSE -- -- -- BEGIN am_tracei ('replication_reconcile (4b): rs_name=' || c_rep_server_name); -- -- SELECT rs.rep_server_key, rs.server_key INTO l_rep_server_key, l_server_key FROM rep_server rs, server s, odb o WHERE s.rep_server_name = c_rep_server_name AND s.server_key = rs.server_key AND rs.status = 'A' AND o.db_key = l_db_key AND o.db_state is NULL AND rs.prot_key = o.prot_key; EXCEPTION WHEN NO_DATA_FOUND THEN -- -- l_obj_type := 'rep server name'; l_obj_name := c_rep_server_name; RAISE DBMS_RA.OBJ_NOT_FOUND; END; am_tracei ('replication_reconcile (4c): l_db_key=' || l_db_key || ', l_rep_server_key=' || l_rep_server_key || ', l_server_key=' || l_server_key); replication_reconcile_int (l_db_key, l_server_key); END IF; END IF; unlock_api_int(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); locked := FALSE; EXCEPTION WHEN DBMS_RA.OBJ_NOT_FOUND THEN -- IF locked THEN unlock_api_int(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); locked := FALSE; END IF; -- IF l_obj_type IS NOT NULL THEN am_tracei ('replication_reconcile fail: ' || item_not_foundi(l_obj_name, l_obj_type)); sys.dbms_sys_error.raise_system_error(DBMS_RA.OBJ_NOT_FOUND_NUM, l_obj_name, l_obj_type, FALSE); ELSE RAISE; END IF; WHEN OTHERS THEN IF locked THEN unlock_api_int(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); locked := FALSE; END IF; am_tracei ('replication_reconcile fail: sqlcode=' || sqlcode || ', sqlerrm=' || SQLERRM); RAISE; END replication_reconcile; -- PROCEDURE replication_reconcile (protection_policy_name IN VARCHAR2) IS l_the NUMBER; l_cnt NUMBER; l_obj_type VARCHAR2(128); l_obj_name VARCHAR2(128); l_prot_key NUMBER := NULL; c_protection_policy_name VARCHAR2(128); locked BOOLEAN := FALSE; BEGIN am_tracei('reconcile by prot prot_name=' || protection_policy_name); lock_api_int(DBMS_RA.LOCKAPI_MODIFY, 'replication_reconcile'); locked := TRUE; dbms_ra_int.canonicalize(protection_policy_name, c_protection_policy_name, 128); BEGIN SELECT prot_key INTO l_prot_key FROM prot WHERE prot.prot_name = c_protection_policy_name; EXCEPTION WHEN NO_DATA_FOUND THEN l_obj_type := 'protection policy name'; l_obj_name := protection_policy_name; RAISE DBMS_RA.OBJ_NOT_FOUND; END; l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_REPLICATION_RECONCILE, param => 'replication_reconcile' || b_p_i('protection_policy_name', protection_policy_name, p_first=>TRUE, p_last=>TRUE)); rep_rec_by_prot_int (l_prot_key); unlock_api_int(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); locked := FALSE; EXCEPTION WHEN DBMS_RA.OBJ_NOT_FOUND THEN -- IF locked THEN unlock_api_int(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); locked := FALSE; END IF; -- IF l_obj_type IS NOT NULL THEN am_tracei ('replication_reconcile: ' || item_not_foundi(l_obj_name, l_obj_type)); sys.dbms_sys_error.raise_system_error(DBMS_RA.OBJ_NOT_FOUND_NUM, l_obj_name, l_obj_type, FALSE); ELSE RAISE; END IF; WHEN OTHERS THEN IF locked THEN unlock_api_int(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); locked := FALSE; END IF; am_tracei ('replication_reconcile fail: sqlcode=' || sqlcode || ', sqlerrm=' || SQLERRM); RAISE; END replication_reconcile; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE replicate_one_backup(bpkey IN NUMBER, replication_server_name IN VARCHAR2 DEFAULT NULL) IS l_db_key NUMBER; l_rep_server_key NUMBER := NULL; l_server_key NUMBER := NULL; l_repcnt NUMBER; l_obj_type VARCHAR2(128); l_obj_name VARCHAR2(128); c_rep_server_name VARCHAR2(128); BEGIN am_tracei ('replicate_one_backup: bp_key=' || bpkey || ' ,replication_server_name=' || replication_server_name); dbms_ra_int.canonicalize(replication_server_name, c_rep_server_name, 128); -- -- -- -- -- -- -- -- l_obj_type := 'replicate one backup piece'; l_obj_name := 'bp_key=' || bpkey; SELECT db_key INTO l_db_key FROM bp WHERE bp_key=bp_key AND status = 'A' AND ba_access = 'L'; -- -- -- IF replication_server_name IS NULL THEN -- -- -- SELECT count(*) INTO l_repcnt FROM odb o, rep_server rs WHERE o.prot_key = rs.prot_key AND o.db_key = l_db_key AND o.db_state is NULL AND rs.status = 'A'; IF l_repcnt = 0 THEN l_obj_type := 'replication_server'; l_obj_name := 'bp_key=' || bpkey; RAISE NO_DATA_FOUND; END IF; ELSE l_obj_type := 'replication_server'; l_obj_name := 'bp_key=' || bpkey || ', rs_name=' || replication_server_name; -- -- SELECT rep_server_key, rs.server_key INTO l_rep_server_key, l_server_key FROM odb o, rep_server rs, server s WHERE o.prot_key = rs.prot_key AND o.db_key = l_db_key AND o.db_state is NULL AND rs.server_key = s.server_key AND s.rep_server_name = c_rep_server_name AND rs.status = 'A'; l_repcnt := 1; END IF; IF l_repcnt > 0 THEN am_tracei ('replicate_one_backup: creating replication tasks db_key=' || l_db_key || ', bp_key=' || bpkey || ', rep_server_key=' || l_rep_server_key || ', server_key=' || l_server_key || ', rep_cnt=' || l_repcnt); dbms_ra_scheduler.replicate_one_bp (p_db_key => l_db_key, p_bp_key => bpkey, p_server_key => l_server_key); END IF; EXCEPTION WHEN NO_DATA_FOUND THEN am_tracei ('replicate_one_backup: ' || item_not_foundi(l_obj_name, l_obj_type)); sys.dbms_sys_error.raise_system_error(DBMS_RA.OBJ_NOT_FOUND_NUM, l_obj_name, l_obj_type, FALSE); END; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE replicate_backups_int (p_db_unique_name IN VARCHAR2, p_rep_serv_name IN VARCHAR2 DEFAULT NULL) IS l_repsrv_key NUMBER := NULL; l_prot_name prot.prot_name%TYPE; l_prot_key NUMBER := NULL; l_db_key NUMBER := NULL; l_server_key NUMBER := NULL; l_obj_type VARCHAR2(128); l_obj_name VARCHAR2(128); l_cnt NUMBER; l_lib_key NUMBER; l_template_name sbt_job_template.template_name%TYPE; l_backup_type VARCHAR2(128); l_invalid_val VARCHAR2(128); l_success BOOLEAN; l_exp_cnt NUMBER; l_num_rec NUMBER; l_pending_rep_setup odb.pending_rep_setup%type := NULL; l_rep_atr_name sbt_attr_set.attr_name%TYPE; BEGIN -- -- BEGIN SELECT node.db_key, odb.prot_key INTO l_db_key, l_prot_key FROM node, odb WHERE node.db_unique_name = p_db_unique_name AND node.db_key=odb.db_key AND odb.db_state is NULL; EXCEPTION WHEN NO_DATA_FOUND THEN l_obj_type := 'db unique name'; l_obj_name := p_db_unique_name; RAISE DBMS_RA.OBJ_NOT_FOUND; END; -- -- -- SELECT COUNT(*) INTO l_cnt FROM rep_server WHERE prot_key=l_prot_key AND status = 'A'; IF (l_cnt = 0) THEN l_obj_type := 'replication server'; l_obj_name := 'none found'; RAISE DBMS_RA.OBJ_NOT_FOUND; END IF; -- IF p_rep_serv_name IS NOT NULL THEN l_obj_type := 'replication server'; l_obj_name := p_rep_serv_name; -- -- SELECT rs.server_key INTO l_server_key FROM odb o, rep_server rs, server s WHERE o.prot_key = rs.prot_key AND o.db_key = l_db_key AND o.db_state is NULL AND s.rep_server_name = p_rep_serv_name AND rs.status = 'A'; END IF; SELECT pending_rep_setup INTO l_pending_rep_setup FROM odb WHERE odb.db_key=l_db_key; IF l_pending_rep_setup = 'Y' THEN IF NOT dbms_ra_scheduler.check_do_pending_rep_setup(l_db_key) THEN am_tracei ('REPLICATE_BACKUPS: Unable to complete replication ' || 'setup for database ' || dbms_ra_int.dbkey2name(l_db_key)); sys.dbms_sys_error.raise_system_error(dbms_ra.REP_SETUP_ERROR_NUM, 'complete_rep_setup', 'USER_BACKUP_EXISTING', dbms_ra_int.dbkey2name(l_db_key), FALSE); ELSE -- -- -- -- -- -- -- am_tracei('REPLICATE_BACKUPS: Exit. pending_rep_setup=' || l_pending_rep_setup); RETURN; END IF; END IF; IF (l_pending_rep_setup IS NULL) OR (l_pending_rep_setup <> 'N') THEN am_tracei('REPLICATE_BACKUPS: Rep server not yet setup'); RETURN; END IF; -- SELECT prot_name INTO l_prot_name FROM prot WHERE prot_key = l_prot_key; -- FOR s IN (SELECT server.server_key, rep_server_name FROM rep_server, server, odb WHERE rep_server.prot_key=l_prot_key AND rep_server.status = 'A' AND server.server_key = rep_server.server_key AND odb.db_key = l_db_key AND odb.db_state is NULL AND odb.prot_key = rep_server.prot_key) LOOP BEGIN -- IF p_rep_serv_name IS NOT NULL THEN IF upper(s.rep_server_name) <> upper(p_rep_serv_name) THEN CONTINUE; END IF; END IF; -- SELECT lib_key INTO l_lib_key FROM sbt_lib_desc WHERE server_key = s.server_key; -- l_success := dbms_ra_scheduler.reconcile_db ( p_db_key => l_db_key, p_server_key => s.server_key, p_only_active => FALSE, p_force_reconcile => TRUE, rec_cnt => l_num_rec); IF NOT l_success OR l_num_rec <> 1 THEN dbms_ra_scheduler.log_error(p_errno => dbms_ra.REP_SETUP_ERROR_NUM, p_db_key => l_db_key, p_param1 => 'user_backup_existing', p_param2 => s.rep_server_name, p_param3 => p_db_unique_name, P_keep_stack => FALSE, p_component =>'REPLICATION_RECONCILE', p_severity => dbms_ra_scheduler.SEVERITY_ERROR, p_param_char => 'RECONCILE'); ELSE -- -- -- dbms_ra_scheduler.fix_error(p_error_num => dbms_ra.REP_SETUP_ERROR_NUM, p_db_key => l_db_key, p_param_char => 'RECONCILE'); -- -- -- dbms_ra_scheduler.queue_set_reconcile_timer (l_db_key); -- -- l_template_name := dbms_ra_int.build_rep_tpl_name ( rep_srv_name => s.rep_server_name, db_key => l_db_key, prot_key => l_prot_key); -- -- -- -- BEGIN l_rep_atr_name := dbms_ra_int.build_rep_atr_name(s.rep_server_name); dbms_ra_int.create_sbt_job_template_int( template_name => l_template_name, db_unique_name => p_db_unique_name, attr_name => l_rep_atr_name, backup_type => 'ALL', do_commit => TRUE); EXCEPTION WHEN DBMS_RA.DUP_NAME THEN -- NULL; END; dbms_ra_scheduler.replicate_existing_backups( p_template_name => l_template_name); END IF; EXCEPTION WHEN OTHERS THEN -- -- UPDATE sbt_lib_desc SET status = (CASE WHEN failure_cnt + 1 < dbms_ra_scheduler.s_max_sbt_failures THEN 'R' ELSE 'E' END), failure_cnt = failure_cnt + 1 WHERE status = 'R' AND lib_key = l_lib_key; COMMIT; RAISE; END; END LOOP; EXCEPTION WHEN DBMS_RA.OBJ_NOT_FOUND THEN -- IF l_obj_type IS NOT NULL THEN am_tracei ('replicate_backups: ' || item_not_foundi(l_obj_name, l_obj_type)); sys.dbms_sys_error.raise_system_error(DBMS_RA.OBJ_NOT_FOUND_NUM, l_obj_name, l_obj_type, FALSE); ELSE RAISE; END IF; WHEN DBMS_RA.MISSING_INIT_REP_TYPE THEN -- am_tracei ('replicate_backups: required intial_replication ' || 'parameter not defined'); RAISE; WHEN DBMS_RA.INVALID_VAL THEN IF l_invalid_val IS NOT NULL THEN am_tracei ('replicate_backups: Invalid value for initial_replication - ' || l_invalid_val); sys.dbms_sys_error.raise_system_error(DBMS_RA.INVALID_VAL_NUM, l_invalid_val, FALSE); ELSE RAISE; END IF; WHEN OTHERS THEN ROLLBACK; am_tracei ('replicate_backups exception: ' || ' db_unique_name:' || p_db_unique_name || ', err:' || SQLERRM); RAISE; END replicate_backups_int; -- PROCEDURE replicate_backups (db_unique_name IN VARCHAR2, replication_server_name IN VARCHAR2 DEFAULT NULL) IS l_the NUMBER; BEGIN lock_api_int(DBMS_RA.LOCKAPI_MODIFY, 'replicate_backups'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_REPLICATE_EXISTING, param => 'replicate_backups' || b_p_i('db_unique_name', db_unique_name, p_first=>TRUE, p_last=>TRUE)); replicate_backups_int (upper(db_unique_name), upper(replication_server_name)); unlock_api_int(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api_int(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END replicate_backups; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE verify_reserved_space (p_slkey IN NUMBER, p_newdb IN BOOLEAN DEFAULT FALSE) IS l_sl_space NUMBER; l_curr_res NUMBER; l_future_res NUMBER; l_bigdb NUMBER; l_count NUMBER; l_nospace BOOLEAN; l_moving_space NUMBER; l_padding_space NUMBER := 20 * 1024 * 1024; /* retain some unclaimed space */ BEGIN -- -- -- -- -- IF is_repair_needed THEN am_tracei('verify_reserved_space: Repair is needed'); RETURN; END IF; -- SELECT sl_space INTO l_sl_space FROM sl WHERE sl_key = p_slkey; SELECT l_sl_space - nvl(VALUE, 0) INTO l_sl_space FROM config WHERE name = '_purging_reserve'; -- IF p_newdb THEN SELECT NVL(MAX(d.base_reserved_space), 0) INTO l_bigdb FROM prot p, odb d WHERE (d.prot_key = p.prot_key OR d.future_prot_key = p.prot_key) AND (d.sl_key = p_slkey OR p.sl_key = p_slkey) AND d.move_phase IS NOT NULL; -- -- SELECT (NVL(TO_NUMBER(MIN(VALUE)), 2) * l_bigdb) - l_bigdb INTO l_padding_space FROM config WHERE name = '_trim_factor'; END IF; -- -- -- SELECT SUM(reserved_space) INTO l_future_res FROM (SELECT d.base_reserved_space reserved_space FROM prot p, odb d WHERE p.sl_key = p_slkey AND d.future_prot_key = p.prot_key UNION ALL SELECT d.reserved_space FROM prot p, unreg_database d WHERE p.sl_key = p_slkey AND d.prot_key = p.prot_key); -- SELECT SUM(reserved_space) INTO l_curr_res FROM (SELECT reserved_space FROM odb WHERE sl_key = p_slkey UNION ALL SELECT reserved_space FROM prot p, unreg_database d WHERE p.sl_key = p_slkey AND d.prot_key = p.prot_key UNION ALL SELECT dbsl_used_space reserved_space FROM dbsl WHERE sl_key = p_slkey AND sl_key NOT IN (SELECT sl_key FROM odb WHERE move_phase > dbms_ra_scheduler.MOVE_PHASE_PEND)); -- IF (l_sl_space - l_padding_space) < l_future_res OR (l_sl_space - l_padding_space) < l_curr_res THEN ROLLBACK; RAISE DBMS_RA.SPACE_QUOTA_VIOLATION; END IF; -- -- -- -- IF NOT p_newdb THEN -- -- SELECT MAX(base_reserved_space) INTO l_future_res FROM odb d, prot p WHERE p.prot_key = d.future_prot_key AND p.sl_key = p_slkey AND d.sl_key <> p.sl_key AND d.move_phase > dbms_ra_scheduler.MOVE_PHASE_PEND; IF l_future_res IS NOT NULL THEN /* check current reservations */ -- -- SELECT NVL(SUM(reserved_space), 0) INTO l_curr_res FROM (SELECT reserved_space reserved_space FROM odb d WHERE d.sl_key = p_slkey UNION ALL SELECT d.reserved_space FROM prot p, unreg_database d WHERE p.sl_key = p_slkey AND d.prot_key = p.prot_key); IF (l_sl_space - l_padding_space) < (l_curr_res + l_future_res) THEN ROLLBACK; RAISE DBMS_RA.SPACE_QUOTA_VIOLATION; END IF; END IF; END IF; -- -- FOR x IN (SELECT db_key, used_space, base_reserved_space, not_taped, not_taped_state FROM odb d, prot p WHERE d.prot_key = p.prot_key AND d.not_taped > d.base_reserved_space AND p.prot_disk_cache = 'YES') LOOP -- -- -- CASE WHEN x.not_taped_state = 'V' THEN /* Valid */ l_nospace := (x.base_reserved_space < x.not_taped); WHEN x.not_taped_state = 'N' THEN /* No Tape */ l_nospace := (x.base_reserved_space < x.used_space); WHEN x.not_taped_state IS NULL THEN /* feature Disabled */ l_nospace := FALSE; WHEN x.not_taped_state = 'C' THEN /* Computing new value */ l_nospace := FALSE; WHEN x.not_taped_state = 'B' THEN /* Broken, computed val is too high */ -- UPDATE odb SET not_taped_state = 'C' WHERE db_key = x.db_key; l_nospace := FALSE; WHEN x.not_taped_state = 'I' THEN /* Invalid value */ IF x.base_reserved_space < x.not_taped THEN -- UPDATE odb SET not_taped_state = 'C' WHERE db_key = x.db_key; END IF; l_nospace := FALSE; ELSE sys.dbms_sys_error.raise_system_error( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Bad not_taped_state value: ' || x.not_taped_state, FALSE); END CASE; IF l_nospace THEN ROLLBACK; RAISE DBMS_RA.SPACE_QUOTA_VIOLATION; END IF; END LOOP; END; -- -- -- -- -- -- -- -- -- FUNCTION is_repair_needed RETURN BOOLEAN IS l_current_incarn NUMBER; l_last_incarn NUMBER; BEGIN SELECT incarnation# INTO l_current_incarn FROM sys.v_$database_incarnation WHERE status='CURRENT'; SELECT NVL(MIN(value), l_current_incarn) INTO l_last_incarn FROM config WHERE name = '_last_incarnation'; IF l_current_incarn <> l_last_incarn THEN am_tracei ('is_repair_needed: Old incarn: ' || l_last_incarn || '; New incarn: ' || l_current_incarn); RETURN TRUE; END IF; RETURN FALSE; END; -- -- -- -- -- -- -- -- -- -- FUNCTION pparmi (p_value IN VARCHAR2) RETURN VARCHAR2 IS BEGIN IF p_value IS NULL THEN RETURN 'NULL'; ELSE RETURN '''' || p_value || ''''; END IF; END pparmi; FUNCTION pparmi (p_value IN NUMBER) RETURN VARCHAR2 IS BEGIN RETURN pparmi(TO_CHAR(p_value)); END pparmi; FUNCTION pparmi (p_value IN BOOLEAN) RETURN VARCHAR2 IS BEGIN IF p_value IS NULL THEN RETURN 'NULL'; ELSIF p_value THEN RETURN 'TRUE'; ELSE RETURN 'FALSE'; END IF; END pparmi; -- -- -- -- -- -- -- -- -- -- PROCEDURE wait_for_job (p_jobname VARCHAR2, p_poll_time NUMBER) IS KBRSTRC_STALL CONSTANT NUMBER := TO_NUMBER('2000000', 'XXXXXXXX'); l_debug_flags NUMBER; l_error_count NUMBER; BEGIN LOOP -- dbms_ra_scheduler.make_amjobs(p_jobname); EXIT WHEN dbms_ra_scheduler.s_amjobs.COUNT = 0; -- SELECT NVL(MIN(value),0) INTO l_debug_flags FROM config WHERE name = '_debug_flags'; IF BITAND (l_debug_flags, KBRSTRC_STALL) <> 0 THEN SELECT COUNT(*) INTO l_error_count FROM error_log WHERE severity >= DBMS_RA_SCHEDULER.SEVERITY_ERROR AND status = 'ACTIVE' AND ROWNUM = 1; am_tracei('wait_for_job: ' || p_jobname || ' error_count =' || l_error_count); EXIT WHEN l_error_count > 0; END IF; dbms_lock.sleep(p_poll_time); END LOOP; END wait_for_job; -- -- -- FUNCTION sbt_job_backup_type_to_num(backup_type IN VARCHAR2) RETURN NUMBER IS l_bck_type NUMBER := 0; CURSOR backup_type_c(btype IN VARCHAR2) IS WITH table_to_parse as (select btype str from dual) SELECT DISTINCT upper(ltrim(rtrim(new_str))) new_str FROM table_to_parse, xmltable('r/c' passing xmltype('' || replace(str,',','') || '') columns new_str varchar2(512) path '.'); btypeRec backup_type_c%ROWTYPE; BEGIN FOR btypeRec IN backup_type_c(backup_type) LOOP CASE btypeRec.new_str WHEN 'ALL' THEN l_bck_type := l_bck_type + 1; WHEN 'FULL' THEN l_bck_type := l_bck_type + 2; WHEN 'INCR' THEN l_bck_type := l_bck_type + 4; WHEN 'ARCH' THEN l_bck_type := l_bck_type + 8; ELSE sys.dbms_sys_error.raise_system_error (DBMS_RA.INVALID_PARAM_NUM, btyperec.new_str, 'backup type', FALSE); END CASE; END LOOP; IF (l_bck_type = 0) THEN sys.dbms_sys_error.raise_system_error (DBMS_RA.INVALID_PARAM_NUM, '', 'backup type', FALSE); END IF; -- IF (bitand(l_bck_type, 1) = 1) THEN -- all l_bck_type := 1; ELSIF (bitand(l_bck_type, 2 + 4 + 8) = 14) THEN -- same as all l_bck_type := 1; END IF; RETURN l_bck_type; END sbt_job_backup_type_to_num; -- PROCEDURE create_sbt_job_template_int( template_name IN VARCHAR2, prot_name IN VARCHAR2, attr_name IN VARCHAR2, backup_type IN VARCHAR2, full_template_name IN VARCHAR2 DEFAULT NULL, from_tag IN VARCHAR2 DEFAULT NULL, priority IN NUMBER DEFAULT 100, -- dbms_ra.SBT_PRIORITY_MEDIUM copies IN NUMBER DEFAULT 1, window IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, do_commit IN BOOLEAN DEFAULT TRUE) IS l_attr_key NUMBER; l_prot_key NUMBER; l_bck_type NUMBER; l_invalid_val VARCHAR(128); l_full_template_key NUMBER := NULL; l_template_key NUMBER; BEGIN IF (copies IS NULL OR copies < 1 OR copies > 4) THEN am_tracei('create_sbt_job w/ prot policy: num copies invalid: ' || pparmi(copies)); sys.dbms_sys_error.raise_system_error(DBMS_RA.BAD_NUM_COPIES_NUM, pparmi(copies), FALSE); END IF; -- SELECT attr.attr_key INTO l_attr_key FROM sbt_attr_set attr WHERE attr.attr_name = create_sbt_job_template_int.attr_name; -- SELECT prot.prot_key INTO l_prot_key FROM prot WHERE prot.prot_name = create_sbt_job_template_int.prot_name; l_bck_type := sbt_job_backup_type_to_num(backup_type); l_template_key := rman_seq.nextval; -- -- -- IF ((bitand(l_bck_type, 1) <> 0) OR (bitand(l_bck_type, 2) <> 0)) THEN IF ((full_template_name IS NOT NULL) AND (full_template_name <> template_name)) THEN l_invalid_val := 'full_template_name should be same as template_name'; RAISE DBMS_RA.INVALID_VAL; ELSE l_full_template_key := l_template_key; END IF; ELSIF (full_template_name IS NULL) THEN SELECT job.template_key INTO l_full_template_key FROM sbt_job_template job WHERE job.prot_key = l_prot_key AND (create_sbt_job_template_int.from_tag IS NULL OR job.from_tag = create_sbt_job_template_int.from_tag) AND (bitand(job.bck_type,1) = 1 OR bitand(job.bck_type,2) = 2); ELSE -- -- -- SELECT job.template_key INTO l_full_template_key FROM sbt_job_template job WHERE job.template_name = create_sbt_job_template_int.full_template_name AND job.prot_key = l_prot_key AND (bitand(job.bck_type,1) = 1 OR bitand(job.bck_type,2) = 2); END IF; -- INSERT INTO sbt_job_template job (template_key, template_name, full_template_key, prot_key, db_key, bck_type, from_tag, priority, attr_key, copies, window) VALUES (l_template_key, template_name, l_full_template_key, l_prot_key, NULL, l_bck_type, from_tag, priority, l_attr_key, copies, window); IF do_commit THEN -- COMMIT; END IF; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN sys.dbms_sys_error.raise_system_error (DBMS_RA.DUP_NAME_NUM, template_name, 'Sbt Job Template', FALSE); WHEN DBMS_RA.INVALID_VAL THEN IF l_invalid_val IS NOT NULL THEN am_tracei('create_sbt_job_template_int raising invalid value: ' || l_invalid_val); sys.dbms_sys_error.raise_system_error (DBMS_RA.INVALID_VAL_NUM, l_invalid_val, FALSE); ELSE RAISE; END IF; WHEN NO_DATA_FOUND THEN IF (l_attr_key IS NULL) THEN am_tracei('create_sbt_job w/prot policy: ' || item_not_foundi(attr_name, 'sbt attribute set')); sys.dbms_sys_error.raise_system_error (DBMS_RA.OBJ_NOT_FOUND_NUM, attr_name, 'sbt attribute set', FALSE); ELSIF (l_prot_key IS NULL) THEN am_tracei('create_sbt_job w/prot policy: ' || item_not_foundi(prot_name, 'protection policy')); sys.dbms_sys_error.raise_system_error (DBMS_RA.OBJ_NOT_FOUND_NUM, prot_name, 'protection policy', FALSE); ELSIF (full_template_name IS NULL) THEN sys.dbms_sys_error.raise_system_error (DBMS_RA.OBJ_NOT_FOUND_NUM, template_name,'full template name', FALSE); ELSE am_tracei('create_sbt_job w/prot policy: ' || item_not_foundi(full_template_name, 'full template name')); sys.dbms_sys_error.raise_system_error (DBMS_RA.OBJ_NOT_FOUND_NUM, full_template_name,'full template name', FALSE); END IF; WHEN TOO_MANY_ROWS THEN sys.dbms_sys_error.raise_system_error (DBMS_RA.OBJ_NOT_FOUND_NUM, template_name, 'full template name', FALSE); END create_sbt_job_template_int; -- PROCEDURE create_sbt_job_template_int( template_name IN VARCHAR2, db_unique_name IN VARCHAR2, attr_name IN VARCHAR2, backup_type IN VARCHAR2, full_template_name IN VARCHAR2 DEFAULT NULL, from_tag IN VARCHAR2 DEFAULT NULL, priority IN NUMBER DEFAULT 100, -- dbms_ra.SBT_PRIORITY_MEDIUM copies IN NUMBER DEFAULT 1, window IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, do_commit IN BOOLEAN DEFAULT TRUE) IS l_attr_key NUMBER; l_db_key NUMBER; l_bck_type NUMBER; l_invalid_val VARCHAR(128); l_full_template_key NUMBER := NULL; l_template_key NUMBER; BEGIN IF (copies IS NULL OR copies < 1 OR copies > 4) THEN am_tracei('create_sbt_job: num copies invalid: ' || pparmi(copies)); sys.dbms_sys_error.raise_system_error(DBMS_RA.BAD_NUM_COPIES_NUM, pparmi(copies), FALSE); END IF; -- SELECT attr.attr_key INTO l_attr_key FROM sbt_attr_set attr WHERE attr.attr_name = create_sbt_job_template_int.attr_name; -- SELECT db_key INTO l_db_key FROM node WHERE node.db_unique_name = create_sbt_job_template_int.db_unique_name -- -- AND NOT EXISTS (SELECT db_state FROM odb WHERE odb.db_key = node.db_key AND db_state IS NOT NULL); l_bck_type := sbt_job_backup_type_to_num(backup_type); l_template_key := rman_seq.nextval; -- -- -- IF ((bitand(l_bck_type, 1) <> 0) OR (bitand(l_bck_type, 2) <> 0)) THEN IF ((full_template_name IS NOT NULL) AND (full_template_name <> template_name)) THEN l_invalid_val := 'full_template_name should be same as template_name'; RAISE DBMS_RA.INVALID_VAL; ELSE l_full_template_key := l_template_key; END IF; ELSIF (full_template_name IS NULL) THEN -- SELECT job.template_key INTO l_full_template_key FROM sbt_job_template job WHERE job.db_key = l_db_key AND (create_sbt_job_template_int.from_tag IS NULL OR job.from_tag = create_sbt_job_template_int.from_tag) AND (bitand(job.bck_type,1) = 1 OR bitand(job.bck_type,2) = 2); ELSE -- -- -- SELECT job.template_key INTO l_full_template_key FROM sbt_job_template job WHERE job.template_name = create_sbt_job_template_int.full_template_name AND job.db_key = l_db_key AND (bitand(bck_type,1) = 1 OR bitand(bck_type,2) = 2); END IF; -- INSERT INTO sbt_job_template job (template_key, template_name, full_template_key, prot_key, db_key, bck_type, from_tag, priority, attr_key, copies, window) VALUES (l_template_key, template_name, l_full_template_key, NULL, l_db_key, l_bck_type, from_tag, priority, l_attr_key, copies, window); IF do_commit THEN -- COMMIT; END IF; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN sys.dbms_sys_error.raise_system_error (DBMS_RA.DUP_NAME_NUM, template_name, 'Sbt Job Template', FALSE); WHEN DBMS_RA.INVALID_VAL THEN IF l_invalid_val IS NOT NULL THEN am_tracei('create_sbt_job_template_int raising invalid value: ' || l_invalid_val); sys.dbms_sys_error.raise_system_error (DBMS_RA.INVALID_VAL_NUM, l_invalid_val, FALSE); ELSE RAISE; END IF; WHEN NO_DATA_FOUND THEN IF (l_attr_key IS NULL) THEN am_tracei('create_sbt_job w/db name: ' || item_not_foundi(attr_name, 'sbt attribute set')); sys.dbms_sys_error.raise_system_error (DBMS_RA.OBJ_NOT_FOUND_NUM, attr_name, 'sbt attribute set', FALSE); ELSIF (l_db_key IS NULL) THEN am_tracei('create_sbt_job w/db name: ' || item_not_foundi(db_unique_name, 'db unique name')); sys.dbms_sys_error.raise_system_error (DBMS_RA.OBJ_NOT_FOUND_NUM, db_unique_name, 'db unique name',FALSE); ELSIF (full_template_name IS NULL) THEN sys.dbms_sys_error.raise_system_error (DBMS_RA.OBJ_NOT_FOUND_NUM, template_name,'full template name', FALSE); ELSE am_tracei('create_sbt_job w/prot policy: ' || item_not_foundi(full_template_name, 'full template name')); sys.dbms_sys_error.raise_system_error (DBMS_RA.OBJ_NOT_FOUND_NUM, full_template_name,'full template name', FALSE); END IF; WHEN TOO_MANY_ROWS THEN sys.dbms_sys_error.raise_system_error (DBMS_RA.OBJ_NOT_FOUND_NUM, template_name, 'full template name', FALSE); END create_sbt_job_template_int; -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE testTask(taskid IN NUMBER DEFAULT NULL, tasktype IN NUMBER DEFAULT NULL, num1 IN NUMBER DEFAULT NULL, num2 IN NUMBER DEFAULT NULL, num3 IN NUMBER DEFAULT NULL, char1 IN VARCHAR2 DEFAULT NULL, char2 IN VARCHAR2 DEFAULT NULL, param IN VARCHAR2 DEFAULT NULL, slkey IN NUMBER DEFAULT NULL, dbkey IN NUMBER DEFAULT NULL, settrace IN NUMBER DEFAULT NULL, newsession IN BOOLEAN DEFAULT FALSE) IS l_the NUMBER; BEGIN l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_TESTTASK, param => 'testtask' || b_p_i('taskid', taskid, p_first=>TRUE) || b_p_i('tasktype', tasktype) || b_p_i('num1', num1) || b_p_i('num2', num2) || b_p_i('num3', num3) || b_p_i('char1', char1) || b_p_i('char2', char2) || b_p_i('param', param) || b_p_i('slkey', slkey) || b_p_i('dbkey', dbkey) || b_p_i('settrace', settrace) || b_p_i('newsession', newsession, p_last=>TRUE)); dbms_ra_scheduler.testtask( p_taskid => taskid , p_tasktype => tasktype , p_num1 => num1 , p_num2 => num2 , p_num3 => num3 , p_char1 => char1 , p_char2 => char2 , p_param => param , p_slkey => slkey , p_dbkey => dbkey , p_settrace => settrace , p_newsession => newsession); unlock_api_int(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN unlock_api_int(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END; -- -- -- -- -- -- -- -- -- -- PROCEDURE killTask(taskid IN NUMBER) IS l_rowcount NUMBER; BEGIN -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); -- UPDATE task SET state = DBMS_RA_SCHEDULER.STATE_CANCEL WHERE task_id = taskid AND state NOT IN (DBMS_RA_SCHEDULER.STATE_RUNNING, DBMS_RA_SCHEDULER.STATE_CANCELING); l_rowcount := SQL%ROWCOUNT; COMMIT; IF l_rowcount = 0 THEN sys.dbms_sys_error.raise_system_error( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Task ' || taskid || ' is either running or no longer exists', FALSE); END IF; -- SYS.KBRSI_ICD.RSSCHEDUNLOCK; EXCEPTION WHEN OTHERS THEN -- SYS.KBRSI_ICD.RSSCHEDUNLOCK; RAISE; END; -- -- -- -- -- -- -- PROCEDURE tracing_on IS BEGIN -- -- dbms_ra_scheduler.load_config; -- sys.kbrsi_icd.rsSetTrace(0,1); -- -- -- -- END tracing_on; -- -- -- -- -- -- -- -- -- -- -- PROCEDURE validate_bp(bpkey IN NUMBER) IS l_dbkey NUMBER; l_vbkey NUMBER; BEGIN -- SELECT db_key, vb_key INTO l_dbkey, l_vbkey FROM bp WHERE bp_key = bpkey; -- tracing_on; -- IF l_vbkey IS NULL THEN -- dbms_ra_int.validateBackupPiece(l_dbkey, bpkey); ELSE -- sys.kbrsi_icd.validateTask(bpkey => bpkey); END IF; EXCEPTION WHEN no_data_found THEN RAISE dbms_ra_scheduler.E_BACKUP_NOT_FOUND; END validate_bp; -- END dbms_ra_int; >>> define prvtrsjs_plb <<< CREATE OR REPLACE PACKAGE BODY dbms_ra_scheduler AS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- /*-------------------------* * Package State Variables * *-------------------------*/ s_debug_flags NUMBER := NULL; s_debug_error NUMBER := 1; s_trace_file_days NUMBER; s_trace_file_open DATE := SYSDATE-365; s_tracing_on BOOLEAN := FALSE; s_perf_on BOOLEAN := FALSE; s_safe_mode BOOLEAN := FALSE; s_ba_session_id NUMBER := NULL; -- id for this scheduler s_current_sid NUMBER := NULL; -- sid of this scheduler session s_config_time TIMESTAMP WITH TIME ZONE; -- Time config vars were set s_init_done BOOLEAN := FALSE; -- true if packages vars initialized s_inst_name VARCHAR2(32) := sys_context('USERENV', 'INSTANCE_NAME'); -- s_timer_process_instance -- for timer processes, the instance NUMBER := NULL; -- upon which they are running s_libkey NUMBER := NULL; -- device type allocated in this -- s_enable_dup NUMBER := 1; -- When space runs out only normal -- -- s_next_dead_scheduler_check TIMESTAMP WITH TIME ZONE := SYSTIMESTAMP; -- -- s_resource_wait_timeout NUMBER := 1; -- -- -- s_resource_wait_active BOOLEAN := FALSE; s_resource_wait_last_alter TIMESTAMP WITH TIME ZONE; -- -- s_resource_wait_relax_rate NUMBER; -- Multiplier for resource_wait_task_limit -- -- s_optimize_space_limit NUMBER; -- Fraction of reserved space that can be -- s_setup_next_reconcile BOOLEAN := TRUE; s_interrupt_max NUMBER; -- # of interrupts of regular task -- s_busy_interrupt_max NUMBER; -- # of interrupts of busywork task -- s_ordering_wait_timeout NUMBER; -- # of days until we warn about -- -- s_pool_tablespace user_tablespaces.tablespace_name%TYPE; -- s_tasktype2name DBMS_SQL.VARCHAR2A; -- s_c2t_optimization NUMBER := 1; s_baseline_cap NUMBER := 0; -- -- -- PROCEDURE wait_for_repair (p_sl_key IN NUMBER, p_db_key IN NUMBER); PROCEDURE exec_timer_storage_maintenance; PROCEDURE exec_timer_task_maintenance; PROCEDURE verify_timer_tasks; PROCEDURE timer_task_upsert (p_type IN NUMBER, p_interval IN DSINTERVAL_UNCONSTRAINED); PROCEDURE cleanup_dead_schedulers (p_restart BOOLEAN); PROCEDURE execute_quiesce; PROCEDURE execute_spawn_sbt(p_task_rec IN OUT NOCOPY task%ROWTYPE); PROCEDURE execute_restore (p_task_rec IN OUT NOCOPY task%ROWTYPE); PROCEDURE execute_backup_arch (p_task_rec IN OUT NOCOPY task%ROWTYPE); PROCEDURE execute_inc_arch (p_task_rec IN OUT NOCOPY task%ROWTYPE); PROCEDURE execute_index_backup (p_task_rec IN OUT NOCOPY task%ROWTYPE); PROCEDURE execute_newdfkey (p_task_rec IN OUT NOCOPY task%ROWTYPE); PROCEDURE release_ordering_wait (p_dbkey IN NUMBER); PROCEDURE execute_deferred_delete(p_task_rec IN OUT NOCOPY task%ROWTYPE); PROCEDURE execute_gcopy_compute(p_task_rec IN OUT NOCOPY task%ROWTYPE); PROCEDURE execute_purge (p_task_rec IN OUT NOCOPY task%ROWTYPE); PROCEDURE execute_poll (p_task_rec IN OUT NOCOPY task%ROWTYPE); PROCEDURE execute_rm_incomplete_files (sbtonly IN BOOLEAN DEFAULT FALSE); PROCEDURE execute_purge_df (p_task_rec IN OUT NOCOPY task%ROWTYPE); PROCEDURE execute_purge_dup_df (p_task_rec IN OUT NOCOPY task%ROWTYPE); PROCEDURE execute_plan_df (p_task_rec IN OUT NOCOPY task%ROWTYPE); PROCEDURE execute_storage_histogram; PROCEDURE execute_db_stats_refresh; PROCEDURE execute_restore_range_refresh (p_task_rec IN task%ROWTYPE); PROCEDURE execute_optimize_chunks_df (p_task_rec IN task%ROWTYPE); PROCEDURE execute_optimize_chunks (p_task_rec IN task%ROWTYPE); PROCEDURE execute_rebuild_index (p_task_rec IN task%ROWTYPE); PROCEDURE execute_validate_db (p_task_rec IN task%ROWTYPE); PROCEDURE execute_delete_db (p_task_rec IN task%ROWTYPE); PROCEDURE execute_check_files (p_task_rec IN task%ROWTYPE); PROCEDURE execute_crosscheck_db (p_task_rec IN task%ROWTYPE); PROCEDURE execute_trim_db (p_task_rec IN task%ROWTYPE); PROCEDURE execute_move_all_db; PROCEDURE execute_move_df (p_task_rec IN task%ROWTYPE); PROCEDURE execute_backup_sbt (p_task_rec IN task%ROWTYPE); PROCEDURE execute_restore_sbt (p_task_rec IN task%ROWTYPE); PROCEDURE execute_purge_sbt (p_task_rec IN task%ROWTYPE); PROCEDURE execute_obsolete_sbt(p_task_rec IN task%ROWTYPE); PROCEDURE execute_reconcile(p_task_rec IN task%ROWTYPE); PROCEDURE execute_repair_db(p_task_rec IN task%ROWTYPE); PROCEDURE execute_insert_fault (p_task_rec IN task%ROWTYPE); PROCEDURE complete_task (p_action IN VARCHAR2, p_taskname IN VARCHAR2, p_current_execution_time TIMESTAMP WITH TIME ZONE, p_final_state NUMBER); PROCEDURE suspend_task (p_newstate IN NUMBER, p_current_execution_time TIMESTAMP WITH TIME ZONE); PROCEDURE trace_task (p_action VARCHAR2, p_taskname IN VARCHAR2); FUNCTION define_task (task_rec IN OUT NOCOPY task%ROWTYPE, p_sbt_task IN BOOLEAN DEFAULT FALSE) RETURN NUMBER; -- PROCEDURE copy_sbt (p_task_rec IN task%ROWTYPE); PROCEDURE log_sbt_error(p_db_key IN NUMBER, p_lib_key IN NUMBER, p_failure_cnt IN NUMBER, p_retry IN BOOLEAN); PROCEDURE log_sbt_task_error(p_db_key IN NUMBER, p_bs_key IN NUMBER, p_bp_key IN NUMBER, p_template_key IN NUMBER, p_lib_key IN NUMBER); PROCEDURE restore_sbt (p_task_rec IN task%ROWTYPE); PROCEDURE cleanup_task (p_task_type IN NUMBER); PROCEDURE crosscheck_db(p_db_key IN NUMBER); PROCEDURE purge_obsolete_sbt( p_dbkey IN NUMBER, p_libkey IN NUMBER, p_sbt_ret IN DSINTERVAL_UNCONSTRAINED); PROCEDURE spawn_sbt_job(p_libkey IN NUMBER); PROCEDURE spawn_purge_sbt_job(p_libkey IN NUMBER); PROCEDURE set_reconcile_timer(p_db_key IN NUMBER); PROCEDURE set_resumable_timeout; PROCEDURE setDatabase(p_dbkey IN NUMBER, p_dbid OUT NUMBER, p_currinc OUT NUMBER, p_db_slkey OUT NUMBER); PROCEDURE wait_for_dbfs; -- -- -- FUNCTION print (p_value IN BOOLEAN) RETURN VARCHAR2; FUNCTION print (p_value IN NUMBER) RETURN VARCHAR2; FUNCTION print (p_value IN DSINTERVAL_UNCONSTRAINED) RETURN VARCHAR2; FUNCTION print (p_value IN VARCHAR2) RETURN VARCHAR2; FUNCTION print (p_value IN TIMESTAMP WITH TIME ZONE) RETURN VARCHAR2; FUNCTION print (p_value IN DATE) RETURN VARCHAR2; FUNCTION bittst (p_mask IN NUMBER, p_bit IN NUMBER) RETURN BOOLEAN; FUNCTION bitclr (p_mask IN NUMBER, p_bit IN NUMBER) RETURN NUMBER; FUNCTION bitset (p_mask IN NUMBER, p_bit IN NUMBER) RETURN NUMBER; PROCEDURE tracex (message IN VARCHAR2); PROCEDURE trace1 (message IN VARCHAR2); FUNCTION check_when (p_view IN VARCHAR2, p_task_id IN NUMBER) RETURN BOOLEAN; PROCEDURE avoid_delete_db(p_dbkey IN NUMBER DEFAULT NULL); FUNCTION delete_db_disruptive_running RETURN NUMBER; -- PROCEDURE delete_db_remove_remaining (p_dbkey IN NUMBER); -- -- -- -- -- PROCEDURE inValidateBaseLevelBcks (p_db_key IN NUMBER, p_currinc IN NUMBER, p_template_key IN NUMBER, p_baseline_scn IN OUT NUMBER); -- PROCEDURE baselineTimezone(p_db_key IN NUMBER, p_baseline_time OUT NOCOPY DATE, p_baseline_untscn OUT NOCOPY NUMBER, p_recovery_window_sbt OUT NOCOPY DATE); -- PROCEDURE queueBaseLevelBcks(p_db_key IN NUMBER, p_dbid OUT NUMBER, p_currinc IN OUT NUMBER, p_db_slkey IN OUT NUMBER, p_from_tag IN VARCHAR2, p_template_key IN NUMBER, p_baseline_scn IN OUT NUMBER, p_lib_key IN NUMBER, p_attr_key IN NUMBER, p_copies IN NUMBER, p_delete_source IN VARCHAR2, p_format IN VARCHAR2, p_last_bp_key IN NUMBER, p_max_bp_key IN NUMBER, p_server_key IN NUMBER); -- PROCEDURE queueMissingDFBcks(p_db_key IN NUMBER, p_from_tag IN VARCHAR2, p_template_key IN NUMBER, p_baseline_scn IN NUMBER, p_lib_key IN NUMBER, p_attr_key IN NUMBER, p_copies IN NUMBER, p_delete_source IN VARCHAR2, p_format IN VARCHAR2, p_last_bp_key IN NUMBER, p_server_key IN NUMBER); -- PROCEDURE logMissingDfBcksError(p_db_key IN NUMBER, p_currinc IN NUMBER, p_template_key IN NUMBER); -- PROCEDURE queueIncrementalBcks(p_db_key IN NUMBER, p_from_tag IN VARCHAR2, p_template_key IN NUMBER, p_full_template_key IN NUMBER, p_baseline_scn IN NUMBER, p_lib_key IN NUMBER, p_attr_key IN NUMBER, p_copies IN NUMBER, p_delete_source IN VARCHAR2, p_format IN VARCHAR2, p_init_cf_bs_key IN NUMBER, p_last_bp_key IN NUMBER, p_server_key IN NUMBER); -- PROCEDURE queueArchivedLogBcks(p_db_key IN NUMBER, p_from_tag IN VARCHAR2, p_template_key IN NUMBER, p_full_template_key IN NUMBER, p_baseline_scn IN NUMBER, p_lib_key IN NUMBER, p_attr_key IN NUMBER, p_copies IN NUMBER, p_delete_source IN VARCHAR2, p_format IN VARCHAR2, p_init_cf_bs_key IN NUMBER, p_last_bp_key IN NUMBER, p_server_key IN NUMBER); -- PROCEDURE queueKeepBcks (p_db_key IN NUMBER, p_from_tag IN VARCHAR2, p_template_key IN NUMBER, p_baseline_scn IN NUMBER, p_lib_key IN NUMBER, p_attr_key IN NUMBER, p_copies IN NUMBER, p_delete_source IN VARCHAR2, p_format IN VARCHAR2, p_last_bp_key IN NUMBER, p_server_key IN NUMBER); -- PROCEDURE create_replication_tasks(p_db_key IN NUMBER, p_bp_key IN NUMBER DEFAULT NULL, p_bs_key IN NUMBER DEFAULT NULL, p_piece_no IN NUMBER DEFAULT NULL, p_server_key IN NUMBER DEFAULT NULL, p_lib_key IN NUMBER DEFAULT NULL); -- -- -- -- -- -- TIMER_RELOAD_CONFIG CONSTANT NUMBER := 0; TIMER_VERIFY CONSTANT NUMBER := 1; TIMER_POLLING CONSTANT NUMBER := 2; TIMER_HISTORY_PRUNE CONSTANT NUMBER := 3; TIMER_RM_INCOMPLETE_FILES CONSTANT NUMBER := 4; TIMER_STORAGE_HISTOGRAM CONSTANT NUMBER := 5; TIMER_STORAGE_MAINTENANCE CONSTANT NUMBER := 6; TIMER_TASK_MAINTENANCE CONSTANT NUMBER := 7; TIMER_OBSOLETE_SBT CONSTANT NUMBER := 8; TIMER_RECONCILE CONSTANT NUMBER := 9; TIMER_SPAWN_SBT CONSTANT NUMBER := 10; TIMER_SET_RECONCILE_TIMER CONSTANT NUMBER := 11; TIMER_DB_STATS_REFRESH CONSTANT NUMBER := 12; -- -- TIMER_RM_SBT_SESSION CONSTANT NUMBER := 15; -- COPIED_TO_TAPE CONSTANT NUMBER := 1; NOT_COPIED_TO_TAPE CONSTANT NUMBER := 0; -- -- PROCEDURE save_error IS BEGIN DBMS_RA_INT.SAVE_ERROR_INT; END save_error; -- -- PROCEDURE clear_error(reset BOOLEAN DEFAULT FALSE) IS BEGIN DBMS_RA_INT.CLEAR_ERROR_INT(reset); END clear_error; -- -- PROCEDURE init (p_instance_only IN BOOLEAN DEFAULT FALSE, p_repair IN BOOLEAN DEFAULT FALSE) IS l_alert_text VARCHAR2(100); l_current_incarnation NUMBER; l_last_incarnation NUMBER; l_state VARCHAR2(3); l_waitcount NUMBER := 0; l_debug_flags NUMBER := 0; l_num NUMBER; BEGIN /* Config overrides init.ora value, if set */ /* Get value from config and set the debug flags - Start */ BEGIN SELECT NVL(MAX(TO_NUMBER(value)), 0) INTO l_debug_flags FROM config WHERE name = '_debug_flags'; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; clear_error; END; -- -- IF SYS.rai_schema <> ('"' || USER || '"') THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(e_bad_user_num, SYS.rai_schema); END IF; sys.kbrsi_icd.rsSetDebugFlags(l_debug_flags); /* Get value from config and set the debug flags - End */ sys.kbrsi_icd.rsSetTrace(1); s_current_task_type := 0; -- Just to make the trace work out. trace_task('INIT_JOB_SCHED', 'INIT'); trace1 ('INIT: instance_only=' || print(p_instance_only) || '; repair=' || print(p_repair) || '; user=' || USER); -- -- -- SELECT value into l_state FROM config WHERE name = '_recovery_appliance_state'; -- -- -- IF p_instance_only AND l_state <> 'ON' THEN trace1 ('INIT: Exiting since recovery appliance wasnt manually started'); RETURN; END IF; -- -- -- SYS.DBMS_SYSTEM.KSDWRT(SYS.DBMS_SYSTEM.ALERT_FILE, 'Startup of ZDLRA at ' || SYSTIMESTAMP || CASE p_instance_only WHEN TRUE THEN ' for instance ' || s_inst_name END || CASE l_debug_flags WHEN 0 THEN NULL ELSE ' with _debug flags = ' || l_debug_flags || '(' || TO_CHAR(l_debug_flags, 'FMXXXXXXXXXXXXXXXX') || ')' END); -- -- -- DBMS_RA_INT.LOCK_API_INT(DBMS_RA.LOCKAPI_CREATE, 'start recovery appliance'); -- -- -- SELECT incarnation# INTO l_current_incarnation FROM sys.v_$database_incarnation WHERE status='CURRENT'; SELECT TO_NUMBER(NVL(MIN(value),-1)) INTO l_last_incarnation FROM config WHERE name = '_last_incarnation'; trace1 ('INIT: Old incarn: ' || l_last_incarnation || '; New incarn: ' || l_current_incarnation); IF l_current_incarnation <> l_last_incarnation THEN -- -- -- -- IF l_last_incarnation <> -1 THEN BEGIN IF p_repair THEN trace1 ('INIT: Need to fix up bad ors metadata.'); -- -- -- -- -- fix_error (p_error_num => E_REPAIR_AVM_METADATA_NUM); COMMIT; repair_rs; ELSE trace1 ('INIT: Turn off recovery appliance state'); -- UPDATE config SET value = 'OFF' WHERE name = '_recovery_appliance_state'; COMMIT; SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(e_repair_avm_metadata_num, l_last_incarnation, l_current_incarnation); END IF; EXCEPTION WHEN OTHERS THEN save_error; write_error (p_component => 'REPAIR', p_severity => SEVERITY_ERROR); DBMS_RA_INT.UNLOCK_API_INT (p_the_num=>0, p_results=>FALSE, p_docommit=>FALSE); RAISE; END; END IF; -- -- -- UPDATE config SET value = TO_CHAR(l_current_incarnation) WHERE name = '_last_incarnation'; COMMIT; -- -- -- -- -- fix_error (p_error_num => E_REPAIR_AVM_METADATA_NUM); COMMIT; END IF; -- -- -- -- -- -- -- IF SYS.KBRSI_ICD.RSTIMERCHECK THEN UPDATE poll SET poll_flags = poll_flags - BITAND(poll_flags, POLL_FLAGS_UNDO_TIMEOUT_ERROR) + POLL_FLAGS_UNDO_TIMEOUT_ERROR; -- -- -- UPDATE config SET value = MAX_RESOURCE_WAIT_PROCESSES WHERE name = '_resource_wait_task_limit'; UPDATE task SET state = STATE_EXECUTABLE, pending_interrupt = NULL WHERE state = STATE_TASK_WAIT AND pending_interrupt = RESOURCE_PSEUDO_TASK; trace1('INIT: Cleared ' || SQL%ROWCOUNT || ' resource wait tasks'); COMMIT; END IF; -- -- -- IF NOT p_instance_only THEN trace1 ('INIT: Turn on recovery appliance state'); UPDATE config SET value = 'ON' WHERE name = '_recovery_appliance_state'; COMMIT; -- -- -- fix_error(p_error_num => E_SHUTTING_DOWN_NUM); -- -- -- fix_error(p_error_num => E_COULDNT_STOP_JOB_NUM); COMMIT; END IF; -- -- -- -- trace1 ('INIT: Starting timer session'); -- -- -- BEGIN DBMS_SCHEDULER.DROP_JOB( job_name => 'RA$_TIMER_' || TO_CHAR(s_instance), force => TRUE); trace1 ('INIT: Stopped RA$_TIMER_' || TO_CHAR(s_instance)); EXCEPTION WHEN E_JOB_NOT_RUNNING OR E_JOB_NOT_FOUND OR E_JOB_DOES_NOT_EXIST THEN save_error; clear_error; END; l_num := restart_timer_process (FALSE); -- -- -- DBMS_RA_INT.UNLOCK_API_INT (p_the_num=>0, p_results=>FALSE, p_docommit=>FALSE); trace1 ('INIT: Up and running'); EXCEPTION WHEN OTHERS THEN save_error; DBMS_RA_INT.UNLOCK_API_INT (p_the_num=>0, p_results=>FALSE, p_docommit=>FALSE); RAISE; END init; -- -- -- -- -- -- -- PROCEDURE display_cf_errors (p_amrvkey NUMBER, p_sl_name VARCHAR2, p_sl_key NUMBER) IS BEGIN FOR m IN (SELECT msg FROM sys.amrv$msg WHERE amrv_key = p_amrvkey AND (msgcode IN (202, 203, 200) -- -- -- OR msgcode BETWEEN 1000 AND 1999) -- ORDER BY msgtime) LOOP log_error (p_errno => E_CONTAINER_REBUILD_ERROR_NUM, p_param1 => p_sl_name, p_param2 => m.msg, p_component => 'REPAIR', p_sl_key => p_sl_key, p_severity => SEVERITY_ERROR); END LOOP; END display_cf_errors; -- -- -- -- -- -- -- PROCEDURE repair_rs IS CURSOR bp_cursor IS SELECT ct.ct_key, bs.keep_options, ct.db_key, bs.bs_key, bp.bp_key FROM sbt_catalog ct, bp, bs, (SELECT bdf.bs_key, MAX(bdf.ckp_time) ckp_time FROM bdf GROUP BY bs_key) bdf WHERE ct.pieceinc = 'NEEDS_REPAIR' AND ct.bp_key = bp.bp_key AND ct.completed = 'Y' AND bp.status != 'D' AND bp.bs_key = bs.bs_key AND bdf.bs_key = bs.bs_key ORDER BY bdf.ckp_time; CURSOR odb_cursor IS SELECT o.db_key, NVL(d.sls_used,0)+1 sls_used, d.dbsl_used_space, p.prot_recovery_window_goal, o.prot_key, o.future_prot_key, fp.sl_key future_sl_key, o.sl_key, o.allocated_space, d.dbsl_sl_key FROM odb o JOIN prot p ON (o.prot_key = p.prot_key) JOIN prot fp ON (o.future_prot_key = fp.prot_key) LEFT OUTER JOIN (SELECT db_key, SUM(dbsl_used_space) dbsl_used_space, COUNT(*) sls_used, MIN(sl_key) dbsl_sl_key FROM dbsl GROUP BY db_key) d ON (d.db_key = o.db_key); l_start_time TIMESTAMP WITH TIME ZONE := SYSTIMESTAMP; l_destlist VARCHAR2(4000); l_bad_sls NUMBER := 0; l_gname VARCHAR2(31); l_amrvkey NUMBER; l_sl_space NUMBER; l_freespace NUMBER; l_lastdb dbinc.db_name%TYPE; l_task_rec task%ROWTYPE; l_count NUMBER; BEGIN trace1 ('REPAIR_RS'); s_repair_active := TRUE; -- -- -- -- DELETE FROM sbt_catalog WHERE completed = 'N'; trace1('REPAIR_RS: Deleted ' || SQL%ROWCOUNT || ' incomplete backup pieces'); UPDATE task SET state = CASE state WHEN STATE_RUNNING THEN STATE_EXECUTABLE WHEN STATE_CANCELING THEN STATE_CANCEL END WHERE state IN (STATE_RUNNING, STATE_CANCELING); trace1('REPAIR_RS: Modified ' || SQL%ROWCOUNT || ' tasks'); UPDATE sessions SET current_task=NULL, current_task_type=NULL WHERE current_task IS NOT NULL; trace1('REPAIR_RS: Modified ' || SQL%ROWCOUNT || ' sessions'); COMMIT; -- -- -- quiesce_rs (); -- -- -- UPDATE sl SET sl_needs_repair = 1 WHERE sl_space > 0; trace1('REPAIR_RS: Marked ' || SQL%ROWCOUNT || ' storage locations'); COMMIT; -- -- -- -- UPDATE task SET state = STATE_CANCEL WHERE task_type = TASK_DELETE_DB; COMMIT; -- -- -- -- -- DELETE FROM task_chunk_cache; trace1('REPAIR_RS: Deleted ' || SQL%ROWCOUNT || ' task_chunk_cache rows'); DELETE FROM task WHERE task_type IN (TASK_PURGE_DF_NOW, TASK_PURGE_DUP_DF, TASK_PURGE_DF, TASK_TRIM_DB, TASK_PURGE, TASK_MOVE_DF, TASK_MOVE_ALL_DB); trace1('REPAIR_RS: Deleted ' || SQL%ROWCOUNT || ' task rows'); UPDATE task SET state=STATE_EXECUTABLE, pending_interrupt=NULL, interrupt_count=0, savepoint=NULL, ba_session_id=NULL, purge_reserve=NULL, flags = flags - BITAND(flags, TASKS_CHUNK_CACHE_ACTIVE); trace1('REPAIR_RS: Updated ' || SQL%ROWCOUNT || ' task rows'); COMMIT; -- -- -- -- cleanup_dead_schedulers (p_restart => FALSE); -- -- -- EXECUTE IMMEDIATE 'TRUNCATE TABLE plans_details'; EXECUTE IMMEDIATE 'TRUNCATE TABLE plans'; trace1 ('REPAIR_RS: tasks and plans are gone'); -- -- -- -- DELETE FROM sbt_catalog WHERE completed = 'N'; trace1('REPAIR_RS: Deleted ' || SQL%ROWCOUNT || ' sbt_catalog rows'); -- -- -- UPDATE odb SET db_state = NULL; COMMIT; -- -- -- -- FOR s IN (SELECT sl_key, sl_name, sl_cg_name, sl_state FROM sl WHERE sl_space > 0) LOOP trace1('REPAIR_RS: Repairing sl_key=' || s.sl_key || '; cgname=' || s.sl_cg_name || '; state=' || s.sl_state); -- -- -- -- SELECT SUBSTR (SYS_CONNECT_BY_PATH (dest, ','), 2) INTO l_destlist FROM (SELECT ROWNUM rn, dest, COUNT (*) OVER () cnt FROM storage_dests WHERE sl_key = s.sl_key) WHERE rn = cnt START with rn = 1 CONNECT by rn = prior rn + 1; -- -- -- IF s.sl_state = 'I' THEN l_gname := s.sl_name; IF sys.kbrsi_icd.repair_container_group(gname => s.sl_name, amrvkey => l_amrvkey) = 0 THEN log_error(p_errno => E_SL_REBUILD_RECOVERABLE_NUM, p_param1 => s.sl_name, p_param2 => l_amrvkey, p_component => 'REPAIR', p_sl_key => s.sl_key, p_severity => SEVERITY_ERROR); -- display_cf_errors (l_amrvkey, s.sl_name, s.sl_key); -- l_bad_sls := l_bad_sls + 1; UPDATE sl SET sl_state = 'E' WHERE sl_key = s.sl_key; COMMIT; CONTINUE; END IF; ELSE -- User did not request repair... -- -- -- SYS.KBRSI_ICD.DROP_CONTAINER_GROUP(gname => s.sl_name, force => 1, keep_container => 1); trace1('REPAIR_RS: Container metadata has been cleared'); IF sys.kbrsi_icd.rebuild_container_group(pathlist => l_destlist, gname => l_gname, amrvkey => l_amrvkey) = 0 THEN trace1('REPAIR_RS: Error seen on container group=' || l_gname || '; amrvkey=' || l_amrvkey); -- -- -- IF l_gname IS NULL THEN log_error(p_errno => E_SL_REBUILD_FATAL_NUM, p_param1 => s.sl_name, p_param2 => l_amrvkey, p_component => 'REPAIR', p_sl_key => s.sl_key, p_severity => SEVERITY_ERROR); -- display_cf_errors (l_amrvkey, s.sl_name, s.sl_key); -- UPDATE sl SET sl_state = 'F' WHERE sl_key = s.sl_key; COMMIT; ELSE log_error(p_errno => E_SL_REBUILD_RECOVERABLE_NUM, p_param1 => s.sl_name, p_param2 => l_amrvkey, p_component => 'REPAIR', p_sl_key => s.sl_key, p_severity => SEVERITY_ERROR); -- display_cf_errors (l_amrvkey, s.sl_name, s.sl_key); -- UPDATE sl SET sl_state = 'E' WHERE sl_key = s.sl_key; COMMIT; END IF; -- -- -- l_bad_sls := l_bad_sls + 1; CONTINUE; END IF; END IF; -- -- -- trace1('REPAIR_RS: Container metadata is good.'); UPDATE sl SET sl_state = NULL WHERE sl_key = s.sl_key; COMMIT; -- -- -- IF s.sl_name <> l_gname THEN log_error(p_errno => E_SL_RENAME_NUM, p_param1 => l_gname, p_param2 => s.sl_name, p_component => 'REPAIR', p_sl_key => s.sl_key, p_severity => SEVERITY_ERROR); l_bad_sls := l_bad_sls + 1; CONTINUE; END IF; -- -- -- UPDATE sl SET sl_space = (SELECT total_space FROM sys.am$container_group WHERE group_name = s.sl_name) WHERE sl_key = s.sl_key RETURNING sl_space INTO l_sl_space; COMMIT; trace1('REPAIR_RS: Container rebuild of ' || s.sl_cg_name || ' succeeded with a size of ' || l_sl_space/(1024*1024*1024) || 'GB'); -- -- -- BEGIN DBMS_RA_INT.VERIFY_RESERVED_SPACE (s.sl_key, FALSE); EXCEPTION WHEN DBMS_RA.SPACE_QUOTA_VIOLATION THEN save_error; log_error(p_errno => E_SL_OUT_OF_SPACE_NUM, p_param1 => s.sl_name, p_component => 'REPAIR', p_sl_key => s.sl_key, p_severity => SEVERITY_ERROR); l_bad_sls := l_bad_sls + 1; clear_error; CONTINUE; END; -- -- -- -- testTask(p_tasktype => TASK_CHECK_FILES, p_slkey => s.sl_key, p_num1 => 1); DELETE FROM sessions WHERE purpose = TASK_CHECK_FILES; COMMIT; END LOOP; trace1('REPAIR_RS: Files are repaired'); -- -- -- IF l_bad_sls > 0 THEN unquiesce_rs(); s_repair_active := FALSE; trace1('REPAIR_RS: Bad container termination.'); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_ERRORS_FOUND_NUM, l_bad_sls); END IF; -- -- -- -- -- FOR b IN bp_cursor LOOP UPDATE sbt_catalog SET pieceinc = 'REPAIRED' WHERE ct_key = b.ct_key; -- -- -- -- IF b.keep_options = 0 THEN l_task_rec.task_type := DBMS_RA_SCHEDULER.TASK_INDEX_BACKUP; l_task_rec.flags := DBMS_RA_SCHEDULER.TASKS_RECEIVED_BACKUP; l_task_rec.db_key := b.db_key; l_task_rec.param_num1 := b.bp_key; DBMS_RA_SCHEDULER.NEW_TASK (task_rec => l_task_rec); ELSE COMMIT; END IF; END LOOP; trace1('REPAIR_RS: Backups are queued'); -- -- -- FOR o IN odb_cursor LOOP -- -- -- -- trace1('REPAIR_RS: Repairing db_key=' || o.db_key); UPDATE odb SET purge_session = NULL, purge_instance = NULL, sls_used = o.sls_used, total_allocation = used_space + NVL(o.dbsl_used_space,0), not_taped = used_space + NVL(o.dbsl_used_space,0), wait_space = NULL, reserved_space = base_reserved_space, recovery_window_goal = o.prot_recovery_window_goal, move_phase = DECODE (o.sls_used, 1, MOVE_PHASE_NULL, MOVE_PHASE_PEND), allocated_space = used_space WHERE db_key = o.db_key; -- -- -- -- IF (o.sls_used = 2) AND (o.allocated_space = 0) AND (o.dbsl_sl_key = o.future_sl_key) THEN trace1('Move has completed for db_key=' || o.db_key); DBMS_RA_STORAGE.MOVE_DATABASE_METADATA( o.db_key, o.sl_key, o.future_sl_key); UPDATE odb SET move_phase = MOVE_PHASE_NULL, sls_used = 1 WHERE db_key = o.db_key; END IF; COMMIT; END LOOP; trace1('REPAIR_RS: ODB rows have been updated'); -- -- -- -- -- FOR s IN (SELECT sl_key, sl_name, sl_space FROM sl WHERE sl_space > 0) LOOP l_freespace := DBMS_RA_STORAGE.FREESPACE(s.sl_key); IF l_freespace < 0 THEN trace1 ('REPAIR_RS: Storage location ' || s.sl_name || ' needs ' || l_freespace || ' more storage'); log_error (p_errno => E_NEED_MORE_SPACE_NUM, p_param1 => s.sl_name, p_param2 => -l_freespace, p_component => 'REPAIR', p_severity => SEVERITY_ERROR); END IF; END LOOP; trace1('REPAIR_RS: Unreasonable storage location check is complete.'); -- -- -- -- -- -- -- -- -- -- l_lastdb := NULL; FOR o IN (SELECT odb.sls_used, dbinc.db_name FROM odb JOIN db ON odb.db_key = db.db_key JOIN dbinc ON (db.db_key = dbinc.db_key) AND (db.curr_dbinc_key = dbinc.dbinc_key) WHERE odb.sls_used > 1) LOOP IF l_lastdb IS NULL THEN trace1(o.db_name || ' is in the middle of a move'); l_lastdb := o.db_name; ELSE trace1 ('REPAIR_RS: ' || l_lastdb || ' and ' || o.db_name || ' are both in more than one storage location.'); log_error (p_errno => E_TOO_MANY_MOVES_NUM, p_param1 => l_lastdb, p_param2 => o.db_name, p_component => 'REPAIR', p_severity => SEVERITY_ERROR); END IF; END LOOP; trace1('REPAIR_RS: Movement check completed.'); -- -- -- -- l_task_rec.task_type := TASK_MOVE_ALL_DB; l_task_rec.flags := 0; new_task(l_task_rec); -- -- -- FOR d IN (SELECT db_key, sl_key FROM odb) LOOP l_task_rec.task_type := TASK_REPAIR_DB; l_task_rec.db_key := d.db_key; l_task_rec.sl_key := d.sl_key; l_task_rec.flags := 0; new_task(l_task_rec); END LOOP; trace1('REPAIR_RS: Pool repair tasks submitted.'); -- -- -- SELECT COUNT(*) INTO l_count FROM error_log WHERE last_seen > l_start_time AND severity >= SEVERITY_ERROR AND ROWNUM = 1; IF l_count > 0 THEN trace1 ('REPAIR_RS: ' || l_count || ' errors need to be fixed before restarting the recovery appliance'); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_ERRORS_FOUND_NUM, l_count); END IF; -- -- -- -- fix_error (p_error_num => E_NEED_MORE_SPACE_NUM, p_timestamp => l_start_time); fix_error (p_error_num => E_TOO_MANY_MOVES_NUM, p_timestamp => l_start_time); fix_error (p_error_num => E_SL_REBUILD_RECOVERABLE_NUM, p_timestamp => l_start_time); fix_error (p_error_num => E_SL_REBUILD_FATAL_NUM, p_timestamp => l_start_time); fix_error (p_error_num => E_SL_REBUILD_RECOVERABLE_NUM, p_timestamp => l_start_time); fix_error (p_error_num => E_SL_RENAME_NUM, p_timestamp => l_start_time); fix_error (p_error_num => E_SL_OUT_OF_SPACE_NUM, p_timestamp => l_start_time); fix_error (p_error_num => E_CONTAINER_REBUILD_ERROR_NUM, p_timestamp => l_start_time); COMMIT; -- -- -- unquiesce_rs(); s_repair_active := FALSE; trace1('REPAIR_RS: Completed'); EXCEPTION WHEN OTHERS THEN save_error; unquiesce_rs(); s_repair_active := FALSE; RAISE; END repair_rs; -- -- -- -- -- -- -- -- -- PROCEDURE wait_for_repair (p_sl_key IN NUMBER, p_db_key IN NUMBER) IS l_id NUMBER; BEGIN -- -- -- -- SELECT MAX(task_id) INTO l_id FROM task WHERE task_type = TASK_REPAIR_DB; IF l_id IS NOT NULL THEN trace1('WAIT_FOR_REPAIR: Waiting for task ' || l_id); s_pending_interrupt := l_id; RAISE E_RETRY_ERROR; END IF; trace1('WAIT_FOR_REPAIR: Nothing to wait for '); RETURN; END wait_for_repair; -- -- -- -- -- -- -- -- FUNCTION restart_timer_process (do_check BOOLEAN) RETURN NUMBER IS l_retval NUMBER :=1; BEGIN trace1('RESTART_TIMER_PROCESS do_check=' || print(do_check)); IF do_check THEN SELECT COUNT(*) INTO l_retval FROM config WHERE name = '_recovery_appliance_state' AND value = 'ON'; END IF; IF l_retval = 1 THEN BEGIN spawn_job ('RA$_TIMER_' || TO_CHAR(s_instance), 'dbms_ra_scheduler.timer_functions;', s_instance, NULL); EXCEPTION WHEN E_JOB_ALREADY_EXISTS THEN save_error; trace1('RESTART_TIMER_PROCESS: Timer session already active'); clear_error; END; END IF; trace1('RESTART_TIMER_PROCESS: Retval=' || l_retval); RETURN l_retval; END restart_timer_process; -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE spawn_job (p_name IN VARCHAR2, p_action IN VARCHAR2, p_instance IN NUMBER, p_comments IN VARCHAR2) IS sts VARCHAR2(3); BEGIN trace1('SPAWN_JOB: ' || p_name); -- -- -- SELECT shutdown_pending INTO sts FROM v$instance; IF sts = 'YES' THEN trace1('SPAWN_JOB: No dice. Instance shutting down'); RETURN; END IF; -- -- -- SELECT value INTO sts FROM config WHERE name = '_recovery_appliance_state'; IF sts = 'OFF' THEN trace1('SPAWN_JOB: No dice. recovery appliance is not running'); RETURN; END IF; -- -- -- DBMS_SCHEDULER.CREATE_JOB( job_name => p_name ,job_type => 'plsql_block' ,job_action => p_action ,enabled => FALSE ,auto_drop => TRUE ,comments => p_comments); IF dbms_utility.is_cluster_database AND p_instance IS NOT NULL THEN trace1('SPAWN_JOB: On instance ' || p_instance); DBMS_SCHEDULER.SET_ATTRIBUTE ( name => p_name ,attribute => 'instance_id' ,value => p_instance); END IF; DBMS_SCHEDULER.ENABLE (name => p_name); END spawn_job; -- -- -- -- -- PROCEDURE spawn_purge_sbt_job(p_libkey IN NUMBER) IS -- -- -- PURGE_SCHEDULER_PER_INST CONSTANT NUMBER := 3; CURSOR missing_schedulers IS WITH rs AS -- running schedulers (SELECT NVL(instance_id, 1) instance_id, COUNT(*) session_count FROM TABLE(CAST(s_amjobs AS rai_jobs_table_type)) WHERE comments = TO_CHAR(p_libkey) AND job_name LIKE 'RA$_PURGE_SBT%' GROUP BY instance_id) SELECT i.inst_number, NVL(rs.session_count, 0) session_count FROM sys.rai_active_instances i LEFT OUTER JOIN rs ON i.inst_number = rs.instance_id WHERE NVL(rs.session_count, 0) < PURGE_SCHEDULER_PER_INST; BEGIN -- make_amjobs (name => 'RA$_PURGE_SBT%'); FOR ms IN missing_schedulers LOOP FOR i IN ms.session_count..PURGE_SCHEDULER_PER_INST-1 LOOP spawn_job (dbms_scheduler.generate_job_name('RA$_PURGE_SBT_'), 'dbms_ra_scheduler.schedule(' || ' p_task_type => dbms_ra_scheduler.TASK_PURGE_SBT,' || ' p_param1 => ' || TO_CHAR(p_libkey) || ');', ms.inst_number, TO_CHAR(p_libkey)); END LOOP; END LOOP; END spawn_purge_sbt_job; -- -- -- -- -- PROCEDURE spawn_sbt_job(p_libkey IN NUMBER) IS TYPE msRecord_t IS RECORD ( inst_number NUMBER, session_count NUMBER ); TYPE msTable_t IS TABLE OF msRecord_t INDEX BY BINARY_INTEGER; CURSOR missing_schedulers IS WITH rs AS -- running schedulers (SELECT NVL(instance_id, 1) instance_id, COUNT(*) session_count FROM TABLE(CAST(s_amjobs AS rai_jobs_table_type)) WHERE comments = TO_CHAR(p_libkey) AND job_name LIKE 'RA$_BKRS_SBT%' GROUP BY instance_id) SELECT i.inst_number, NVL(rs.session_count, 0) session_count FROM sys.rai_active_instances i LEFT OUTER JOIN rs ON i.inst_number = rs.instance_id -- ORDER BY 2, 1; drives_inuse NUMBER; l_proc NUMBER; l_drives NUMBER; first BOOLEAN; min_job_cnt NUMBER; mslist msTable_t; BEGIN make_amjobs (name => 'RA$_BKRS_SBT%'); -- -- OPEN missing_schedulers; FETCH missing_schedulers BULK COLLECT INTO mslist; CLOSE missing_schedulers; SELECT count(*) INTO drives_inuse FROM TABLE(CAST(s_amjobs AS rai_jobs_table_type)) WHERE comments = TO_CHAR(p_libkey); BEGIN SELECT l.drives, (l.drives - drives_inuse) INTO l_drives, l_proc FROM sbt_lib_desc l WHERE l.lib_key = p_libkey; EXCEPTION WHEN no_data_found THEN save_error; trace1('SPAWN_SBT_JOB: Library/Replication server has been deleted.'); -- -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); UPDATE task SET state = STATE_CANCEL WHERE task_type IN (TASK_BACKUP_SBT, TASK_PURGE_SBT, TASK_OBSOLETE_SBT, TASK_RESTORE_SBT) AND EXISTS (SELECT 1 FROM sbt_task st WHERE st.task_id = task.task_id AND st.lib_key = p_libkey) AND state NOT IN (STATE_RUNNING, STATE_CANCELING); trace1('SPAWN_SBT_JOB: Killed ' || SQL%ROWCOUNT || ' task(s).'); COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK; END; trace1('SPAWN_SBT_JOB: drives_inuse=' || drives_inuse || ', proc=' || l_proc); -- WHILE (l_proc > 0) LOOP first := TRUE; FOR i in 1..mslist.count LOOP IF (first) THEN min_job_cnt := mslist(i).session_count; first := FALSE; ELSE EXIT WHEN (mslist(i).session_count > min_job_cnt); END IF; spawn_job (dbms_scheduler.generate_job_name('RA$_BKRS_SBT_'), 'dbms_ra_scheduler.schedule(' || ' p_task_type => dbms_ra_scheduler.TASK_BACKUP_SBT,' || ' p_param1 => ' || TO_CHAR(p_libkey) || ');', mslist(i).inst_number, TO_CHAR(p_libkey)); mslist(i).session_count := mslist(i).session_count + 1; l_proc := l_proc - 1; EXIT WHEN l_proc = 0; END LOOP; END LOOP; END spawn_sbt_job; -- -- -- -- -- PROCEDURE queue_spawn_sbt(p_libkey IN NUMBER, p_forpurge IN BOOLEAN, p_check_work IN BOOLEAN DEFAULT FALSE) IS l_tasks NUMBER; l_forpurge NUMBER; new_task_rec task%ROWTYPE; l_task_work NUMBER; l_drives NUMBER; l_new_drives NUMBER; l_dynamic_drives sbt_lib_desc.dynamic_drives%TYPE; -- -- -- -- CURSOR spawn_sbt_tasks(l_forpurge IN NUMBER) IS WITH rs AS -- running schedulers (SELECT param_num2 forpurge FROM task WHERE task_type = TASK_SPAWN_SBT AND state IN (STATE_EXECUTABLE, STATE_RUNNING) AND param_num1 = p_libkey AND param_num2 = nvl(l_forpurge, param_num2) GROUP BY param_num2), ds AS -- dead schedulers (SELECT 1 forpurge FROM dual WHERE nvl(l_forpurge, 1) = 1 UNION SELECT 0 forpurge FROM dual WHERE nvl(l_forpurge, 0) = 0) SELECT ds.forpurge FROM ds WHERE NOT EXISTS (SELECT 1 FROM rs WHERE rs.forpurge = ds.forpurge); BEGIN -- IF (p_forpurge IS NULL) THEN l_forpurge := NULL; ELSIF (p_forpurge) THEN l_forpurge := 1; ELSE l_forpurge := 0; END IF; trace1('QUEUE_SPAWN_SBT: called for lib_key=' || p_libkey || '; forpurge=' || nvl(to_char(l_forpurge), 'NULL')); BEGIN SELECT /*+ RESULT_CACHE */ l.dynamic_drives, l.drives INTO l_dynamic_drives, l_drives FROM sbt_lib_desc l WHERE l.lib_key = p_libkey; EXCEPTION WHEN no_data_found THEN save_error; trace1('QUEUE_SPAWN_SBT: library not found'); clear_error; RETURN; END; IF (l_dynamic_drives = 'Y') THEN l_new_drives := dbms_ra_int.sbt_default_drives; IF (l_new_drives != l_drives) THEN UPDATE sbt_lib_desc l SET l.drives = l_new_drives WHERE l.lib_key = p_libkey; COMMIT; END IF; END IF; FOR spt IN spawn_sbt_tasks(l_forpurge) LOOP IF (p_check_work) THEN trace1('QUEUE_SPAWN_SBT: scheduler checking for work'); IF (spt.forpurge = 1) THEN SELECT COUNT(*) INTO l_task_work FROM task t, sbt_lib_desc l WHERE t.state = STATE_EXECUTABLE AND t.task_type = TASK_PURGE_SBT AND t.param_num1 = l.lib_key AND t.param_num1 = p_libkey AND l.status = 'R' -- filter ready libs AND rownum = 1; ELSE SELECT COUNT(*) INTO l_task_work FROM task t, sbt_lib_desc l, sbt_task st LEFT OUTER JOIN sbt_job_template j ON j.template_key = st.template_key AND st.restore = 'N' -- backup jobs AND (j.completion_time IS NULL OR SYSTIMESTAMP < j.completion_time) WHERE t.state = STATE_EXECUTABLE AND t.task_id = st.task_id AND t.task_type IN (TASK_BACKUP_SBT, TASK_RESTORE_SBT) AND (j.template_key IS NOT NULL OR st.restore = 'Y') AND st.lib_key = l.lib_key AND l.status = 'R' -- filter ready libs AND st.lib_key = p_libkey AND rownum = 1; END IF; ELSE l_task_work := 1; END IF; IF (l_task_work != 0) THEN trace1('QUEUE_SPAWN_SBT: adding spawn sbt task for lib_key=' || p_libkey || '; forpurge=' || spt.forpurge); BEGIN new_task_rec.task_type := TASK_SPAWN_SBT; new_task_rec.flags := 0; new_task_rec.param_num1 := p_libkey; new_task_rec.param_num2 := spt.forpurge; new_task (new_task_rec); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN save_error; -- -- IF (SQLERRM NOT LIKE '%TASK_SPAWN_SBT_I%') THEN RAISE; END IF; clear_error; END; END IF; END LOOP; END queue_spawn_sbt; -- -- -- -- -- PROCEDURE timer_functions IS l_debug_flags NUMBER := 0; l_next_timer timer_task%ROWTYPE; l_sts VARCHAR2(10); l_seq NUMBER; new_task_rec task%ROWTYPE; l_count NUMBER; l_active_schedulers NUMBER; -- -- CURSOR timer_cursor IS SELECT i.inst_name, i.inst_number FROM sys.rai_active_instances i WHERE NOT EXISTS (SELECT 1 FROM TABLE(CAST(s_amlocks AS rai_locks_table_type)) l WHERE i.inst_number = l.inst_id AND key = LOCK_TIMER); -- CURSOR reconcile_cursor IS SELECT db_key FROM odb WHERE NVL(next_reconcile, SYSTIMESTAMP + 1) <= SYSTIMESTAMP AND db_state IS NULL AND NOT EXISTS (SELECT 1 FROM task WHERE task_type = TASK_RECONCILE AND task.db_key = odb.db_key) ORDER BY next_reconcile DESC; -- -- CURSOR sbt_spawn_cursor IS SELECT SUM(CASE WHEN t.state = STATE_RUNNING THEN 1 ELSE 0 END), st.lib_key FROM task t, sbt_lib_desc l, sbt_task st LEFT OUTER JOIN sbt_job_template j ON j.template_key = st.template_key AND st.restore = 'N' -- backup jobs AND (j.completion_time IS NULL OR SYSTIMESTAMP < j.completion_time) WHERE t.state IN (STATE_RUNNING, STATE_EXECUTABLE) AND t.task_id = st.task_id AND t.task_type IN (TASK_BACKUP_SBT, TASK_RESTORE_SBT) AND (j.template_key IS NOT NULL OR st.restore = 'Y') AND st.lib_key = l.lib_key AND l.status = 'R' -- filter ready libs GROUP BY st.lib_key; -- -- CURSOR sbt_purge_cursor IS SELECT SUM(CASE WHEN t.state = STATE_RUNNING THEN 1 ELSE 0 END), t.param_num1 FROM task t LEFT OUTER JOIN sbt_lib_desc l ON t.param_num1 = l.lib_key WHERE t.state IN (STATE_RUNNING, STATE_EXECUTABLE) AND t.task_type = TASK_PURGE_SBT AND (l.status = 'R' OR l.status IS NULL) -- filter ready libs GROUP BY t.param_num1; -- lib_key l_db_key NUMBER; l_rec_bp_key NUMBER; l_libkey NUMBER; l_cnt NUMBER := 0; BEGIN -- assert_owner; /* User timer process to set debug flags as each RAC instance starts */ /* Get value from config and set the debug flags - Start */ BEGIN SELECT NVL(MAX(TO_NUMBER(value)), 0) INTO l_debug_flags FROM config WHERE name = '_debug_flags'; SYS.KBRSI_ICD.RSSETDEBUGFLAGS(l_debug_flags); EXCEPTION WHEN NO_DATA_FOUND THEN save_error; clear_error; END; /* Get value from config and set the debug flags - End */ -- sys.kbrsi_icd.rsSetTrace; trace1('TIMER activated as user ' || SYS_CONTEXT('USERENV','SESSION_USER')); trace1('TIMER activated as login user ' || USER); trace1('TIMER schema set to ' || SYS_CONTEXT('USERENV','CURRENT_SCHEMA')); -- -- -- wait_for_dbfs; -- -- -- set_resumable_timeout; -- -- -- SYS.KBRSI_ICD.RSTIMERLOCK; trace1('TIMER locked out other timer jobs'); -- -- -- -- s_timer_process_instance := s_instance; -- -- -- -- enqueue_timer_reload_config; -- -- -- dbms_session.set_identifier('RA$ACTIVE_TIMER'); WHILE TRUE LOOP clear_error(reset => TRUE); new_task_rec := NULL; dbms_application_info.set_module('TIMER_FUNCTIONS', NULL); -- -- -- -- IF ((s_trace_file_open + s_trace_file_days) < SYSDATE) THEN trace1('TIMER_FUNCTIONS: Ending tracefile'); s_trace_file := NULL; s_trace_file_open := SYSDATE; EXECUTE IMMEDIATE 'ALTER SESSION SET tracefile_identifier="ra_' || TO_CHAR(s_trace_file_open, 'YYYYMMDDHH24MI') || '"'; END IF; -- -- -- SELECT * INTO l_next_timer FROM timer_task WHERE next_execute = (SELECT MIN(next_execute) FROM timer_task) AND ROWNUM = 1; -- -- -- -- IF (l_next_timer.next_execute > SYSTIMESTAMP) THEN DBMS_LOCK.SLEEP(s_timer_loop_sleep); -- sys.kbrsi_icd.rsSetTrace; -- -- -- SELECT /*+ RESULT_CACHE */ value INTO l_sts FROM config WHERE (name = '_recovery_appliance_state'); IF l_sts = 'OFF' THEN trace1('TIMER_FUNCTIONS: Exiting because recovery appliance shut down.'); SYS.KBRSI_ICD.RSRUNSCHED; -- wake up other schedulers. RETURN; END IF; -- -- -- -- -- -- -- IF s_next_dead_scheduler_check <= SYSTIMESTAMP THEN s_next_dead_scheduler_check := SYSTIMESTAMP + NUMTODSINTERVAL(5, 'MINUTE'); cleanup_dead_schedulers (p_restart => TRUE); -- -- -- make_amlocks(); FOR t IN timer_cursor LOOP trace1('TIMER_FUNCTIONS: Starting timer process on instance ' || t.inst_name); BEGIN spawn_job ('RA$_TIMER_' || t.inst_number, 'dbms_ra_scheduler.timer_functions;', t.inst_number, NULL); EXCEPTION WHEN E_JOB_ALREADY_EXISTS THEN save_error; trace1 ('TIMER_FUNCTIONS: Timer session already active ' || 'for instance ' || t.inst_number); clear_error; END; END LOOP; END IF; CONTINUE; END IF; -- -- -- trace1('TIMER_FUNCTIONS: Current timer is: ' || l_next_timer.timer_type); dbms_application_info.set_module('TIMER_FUNCTIONS', l_next_timer.timer_type); CASE l_next_timer.timer_type -- -- WHEN TIMER_RELOAD_CONFIG THEN load_config; set_resumable_timeout; verify_timer_tasks; -- -- WHEN TIMER_VERIFY THEN verify_timer_tasks; -- -- WHEN TIMER_POLLING THEN -- -- -- SELECT COUNT(*) INTO l_count FROM task WHERE task_type = TASK_POLL AND param_num1 = l_next_timer.timer_location AND ROWNUM = 1; IF l_count = 0 THEN new_task_rec.task_type := TASK_POLL; new_task_rec.flags := 0; new_task_rec.param_num1 := l_next_timer.timer_location; new_task (new_task_rec); END IF; -- -- WHEN TIMER_HISTORY_PRUNE THEN -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- DELETE FROM task_history WHERE completion_time < (SYSTIMESTAMP-(s_history_partition_interval*s_history_retention)); COMMIT; trace1('TIMER_FUNCTIONS: Deleted ' || SQL%ROWCOUNT || ' history rows'); DELETE FROM error_log WHERE last_seen < (SYSTIMESTAMP - (s_history_partition_interval*s_history_retention)); COMMIT; trace1('TIMER_FUNCTIONS: Deleted ' || SQL%ROWCOUNT || ' error rows'); -- -- DELETE FROM sbt_task_history sth WHERE (sth.failure_cnt > 0 OR sth.restore = 'Y') AND NOT EXISTS (SELECT 1 FROM task_history th WHERE th.task_id = sth.task_id); COMMIT; -- -- WHEN TIMER_RM_INCOMPLETE_FILES THEN -- -- -- SELECT COUNT(*) INTO l_count FROM task WHERE task_type = TASK_RM_INCOMPLETE_FILES AND ROWNUM = 1; IF l_count = 0 THEN new_task_rec.task_type := TASK_RM_INCOMPLETE_FILES; new_task_rec.flags := 0; new_task (new_task_rec); END IF; -- -- WHEN TIMER_STORAGE_HISTOGRAM THEN -- -- -- SELECT COUNT(*) INTO l_count FROM task WHERE task_type = TASK_STORAGE_HISTOGRAM AND ROWNUM = 1; IF l_count = 0 THEN new_task_rec.task_type := TASK_STORAGE_HISTOGRAM; new_task_rec.flags := 0; new_task (new_task_rec); END IF; -- -- WHEN TIMER_STORAGE_MAINTENANCE THEN exec_timer_storage_maintenance; -- -- WHEN TIMER_TASK_MAINTENANCE THEN exec_timer_task_maintenance; -- -- WHEN TIMER_OBSOLETE_SBT THEN -- -- -- SELECT COUNT(*) INTO l_count FROM task WHERE task_type = TASK_OBSOLETE_SBT AND ROWNUM = 1; IF l_count = 0 THEN new_task_rec.task_type := TASK_OBSOLETE_SBT; new_task_rec.flags := 0; new_task (new_task_rec); END IF; -- -- WHEN TIMER_SET_RECONCILE_TIMER THEN -- -- trace1 ('TIMER_FUNCTIONS_SET_RECONCILE_TIMER: dbkey=' || l_next_timer.param_num1); IF l_next_timer.param_num1 IS NULL THEN timer_task_upsert (TIMER_RECONCILE, NULL); ELSE set_reconcile_timer (l_next_timer.param_num1); END IF; -- -- WHEN TIMER_RECONCILE THEN -- -- -- BEGIN trace1 ('TIMER_FUNCTIONS_RECONCILE: Finding reconciles...'); OPEN reconcile_cursor; LOOP FETCH reconcile_cursor INTO l_db_key; EXIT WHEN reconcile_cursor%NOTFOUND; trace1 ('TIMER_FUNCTIONS_RECONCILE: create TASK_RECONCILE ' || ' l_db_key=' || l_db_key); new_task_rec.task_type := TASK_RECONCILE; new_task_rec.db_key := l_db_key; new_task_rec.flags := 0; new_task (new_task_rec); l_cnt := l_cnt + 1; END LOOP; CLOSE reconcile_cursor; EXCEPTION WHEN OTHERS THEN trace1 ('TIMER_FUNCTIONS_RECONCILE: EXCEPTION: sqlcode=' || SQLCODE); IF l_cnt = 0 THEN NULL; -- -- -- END IF; save_error; CLOSE reconcile_cursor; RAISE; END; IF l_cnt = 0 THEN -- -- -- -- -- -- -- -- NULL; END IF; -- -- -- -- SELECT MAX(db_key) INTO l_db_key FROM odb WHERE (next_reconcile IS NOT NULL) AND ((SYSTIMESTAMP - next_reconcile) > (s_late_for_warning * s_reconcile_long_interval)); IF l_db_key IS NULL THEN fix_error (p_error_num => E_LATE_RECONCILE_NUM); ELSE log_error (p_errno => E_LATE_RECONCILE_NUM, p_param1 => DBMS_RA_INT.DBKEY2NAME(l_db_key), p_component => 'RECONCILE', p_severity => SEVERITY_WARNING); END IF; -- -- WHEN TIMER_SPAWN_SBT THEN BEGIN OPEN sbt_spawn_cursor; LOOP FETCH sbt_spawn_cursor INTO l_count, l_libkey; EXIT WHEN sbt_spawn_cursor%NOTFOUND; IF (l_count = 0) THEN new_task_rec.task_type := TASK_SPAWN_SBT; new_task_rec.flags := 0; new_task_rec.param_num1 := l_libkey; new_task_rec.param_num2 := 0; -- forpurge new_task (new_task_rec); END IF; END LOOP; CLOSE sbt_spawn_cursor; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN save_error; CLOSE sbt_spawn_cursor; -- -- IF (SQLERRM NOT LIKE '%TASK_SPAWN_SBT_I%') THEN RAISE; END IF; clear_error; WHEN OTHERS THEN save_error; CLOSE sbt_spawn_cursor; RAISE; END; BEGIN OPEN sbt_purge_cursor; LOOP FETCH sbt_purge_cursor INTO l_count, l_libkey; EXIT WHEN sbt_purge_cursor%NOTFOUND; IF (l_count = 0) THEN new_task_rec.task_type := TASK_SPAWN_SBT; new_task_rec.flags := 0; new_task_rec.param_num1 := l_libkey; new_task_rec.param_num2 := 1; -- forpurge new_task (new_task_rec); END IF; END LOOP; CLOSE sbt_purge_cursor; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN save_error; CLOSE sbt_purge_cursor; -- -- IF (SQLERRM NOT LIKE '%TASK_SPAWN_SBT_I%') THEN RAISE; END IF; clear_error; WHEN OTHERS THEN save_error; CLOSE sbt_purge_cursor; RAISE; END; -- -- WHEN TIMER_DB_STATS_REFRESH THEN -- -- -- -- SELECT COUNT(*) INTO l_count FROM task WHERE task_type = TASK_DB_STATS_REFRESH AND ROWNUM = 1; IF l_count = 0 THEN new_task_rec.task_type := TASK_DB_STATS_REFRESH; new_task_rec.flags := 0; new_task (new_task_rec); END IF; -- -- WHEN TIMER_RM_SBT_SESSION THEN DELETE FROM sbt_session WHERE systimestamp > (modtime + s_sbt_active_interval); -- -- ELSE trace1('TIMER_FUNCTIONS: Unknown Timer function : Type - ' || l_next_timer.timer_type); log_error (p_errno => E_BAD_TASK_TYPE_NUM, p_param1 => 'TIMER TASK ' || print(l_next_timer.timer_type), p_component => 'TIMER', p_severity => SEVERITY_WARNING); END CASE; -- -- -- IF l_next_timer.timer_interval IS NULL THEN trace1('TIMER_FUNCTIONS: Deleting timer row location=' || l_next_timer.timer_location || ', type=' || l_next_timer.timer_type); DELETE FROM timer_task WHERE timer_type = l_next_timer.timer_type AND timer_location = l_next_timer.timer_location; ELSE trace1('TIMER_FUNCTIONS: Rescheduling timer row'); UPDATE timer_task SET next_execute = SYSTIMESTAMP + timer_interval WHERE timer_type = l_next_timer.timer_type AND timer_location = l_next_timer.timer_location; END IF; COMMIT; END LOOP; EXCEPTION WHEN E_ORA_600 THEN save_error; -- -- -- write_error (p_component => 'TIMER', p_severity => SEVERITY_INTERNAL); RAISE; WHEN OTHERS THEN save_error; -- -- log_error (p_errno => E_TIMER_EXIT_NUM, p_component => 'TIMER', p_severity => SEVERITY_INTERNAL); RAISE; END timer_functions; -- -- -- -- -- PROCEDURE exec_timer_storage_maintenance IS l_count NUMBER; l_freespace NUMBER; l_sl_name sl.sl_name%TYPE; l_db_key NUMBER; new_task_rec task%ROWTYPE; l_resource_wait_task_limit NUMBER; l_last_optimize TIMESTAMP WITH TIME ZONE; l_optimize_chunks_days NUMBER; l_optimize_chunks_interval DSINTERVAL_UNCONSTRAINED; l_optimize_late DSINTERVAL_UNCONSTRAINED; l_validate_db_days NUMBER; l_validate_db_interval DSINTERVAL_UNCONSTRAINED; l_check_files_days NUMBER; l_check_files_interval DSINTERVAL_UNCONSTRAINED; l_crosscheck_db_days NUMBER; l_crosscheck_db_interval DSINTERVAL_UNCONSTRAINED; BEGIN -- -- -- SELECT MAX(DECODE(name, '_resource_wait_task_limit', TO_NUMBER(value))) , MAX(DECODE(name, 'optimize_chunks_days', TO_NUMBER(value))) , MAX(DECODE(name, 'validate_db_days', TO_NUMBER(value))) , MAX(DECODE(name, 'check_files_days', TO_NUMBER(value))) , MAX(DECODE(name, 'crosscheck_db_days', TO_NUMBER(value))) INTO l_resource_wait_task_limit, l_optimize_chunks_days, l_validate_db_days, l_check_files_days, l_crosscheck_db_days FROM config WHERE name IN ('_resource_wait_task_limit', 'optimize_chunks_days', 'validate_db_days', 'check_files_days','crosscheck_db_days'); -- -- -- -- -- -- -- IF l_resource_wait_task_limit < MAX_RESOURCE_WAIT_PROCESSES THEN trace1('EXEC_TIMER_STORAGE_MAINTENANCE: ' || 'No busy work when we are resource constrained'); RETURN; END IF; -- -- -- -- -- -- -- -- -- -- -- FOR sl IN (SELECT sl_key, sl_freespace_goal FROM sl WHERE sl_hist_usage IS NOT NULL AND sl_space <> 0) LOOP -- l_freespace := DBMS_RA_STORAGE.FREESPACE(sl.sl_key) + s_purging_reserve; trace1('TIMER_STORAGE_MAINTENANCE for sl ' || sl.sl_key || ' goal is ' || sl.sl_freespace_goal || ' freespace is ' || l_freespace); -- IF l_freespace < (sl.sl_freespace_goal * s_purge_threshold) THEN -- SELECT COUNT(*) INTO l_count FROM task WHERE (task_type = TASK_PURGE) AND (sl_key = sl.sl_key) AND ROWNUM = 1; IF l_count = 0 THEN -- new_task_rec.task_type := TASK_PURGE; new_task_rec.sl_key := sl.sl_key; new_task_rec.db_key := NULL; new_task_rec.flags := 0; new_task (new_task_rec); END IF; END IF; END LOOP; -- -- -- -- -- -- l_optimize_chunks_interval := NUMTODSINTERVAL(l_optimize_chunks_days, 'day'); trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_OPTIMIZE: checking schedule' || ' optimize_chunks_days=' || l_optimize_chunks_days || ' optimize_chunks_interval=' || interval2secs(l_optimize_chunks_interval)); FOR d IN ( SELECT db_key FROM odb WHERE NVL(( last_optimize + l_optimize_chunks_interval) , SYSTIMESTAMP) <= SYSTIMESTAMP AND db_key NOT IN ( SELECT db_key FROM task WHERE task_type IN ( TASK_OPTIMIZE_CHUNKS_DF , TASK_OPTIMIZE_CHUNKS ) ) ) LOOP new_task_rec := NULL; new_task_rec.task_type := TASK_OPTIMIZE_CHUNKS; new_task_rec.flags := 0; new_task_rec.db_key := d.db_key; new_task (new_task_rec); END LOOP; -- -- -- -- -- -- -- l_optimize_late := s_late_for_warning * l_optimize_chunks_interval; SELECT MAX(db_key) INTO l_db_key FROM odb WHERE (last_optimize + l_optimize_late < SYSTIMESTAMP) OR ( NVL(prev_optimize,last_optimize)+l_optimize_late < last_optimize AND db_key IN (SELECT db_key FROM task WHERE task_type = TASK_OPTIMIZE_CHUNKS_DF ) ); IF l_db_key IS NULL THEN trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_OPTIMIZE: ' || 'fixing E_LATE_OPTIMIZE_NUM'); fix_error (p_error_num => E_LATE_OPTIMIZE_NUM); ELSE trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_OPTIMIZE: ' || 'logging E_LATE_OPTIMIZE_NUM'); log_error (p_errno => E_LATE_OPTIMIZE_NUM, p_component => 'OPTIMIZE', p_severity => SEVERITY_WARNING); END IF; -- -- -- -- -- l_validate_db_interval := NUMTODSINTERVAL(l_validate_db_days,'day'); trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_VALIDATE: checking schedule' || ' validate_db_days=' || l_validate_db_days || ' validate_db_interval=' || interval2secs(l_validate_db_interval)); FOR v IN (SELECT o.db_key, task_id, NVL(last_validate, SYSTIMESTAMP - l_validate_db_interval) last_time FROM odb o LEFT OUTER JOIN task t ON (o.db_key = t.db_key) AND (task_type = TASK_VALIDATE_DB) WHERE ((NVL(last_validate, SYSTIMESTAMP - l_validate_db_interval) + l_validate_db_interval) <= SYSTIMESTAMP) ORDER BY NVL(last_validate,SYSTIMESTAMP)) LOOP trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_VALIDATE:' || ' v.db_key=' || v.db_key || ' v.task_id=' || v.task_id || ' v.last_time=' || TO_CHAR(v.last_time) || ' SYSTIMESTAMP=' || TO_CHAR(SYSTIMESTAMP)); IF v.task_id IS NULL THEN -- trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE: running TASK_VALIDATE_DB'); new_task_rec := NULL; new_task_rec.task_type := TASK_VALIDATE_DB; new_task_rec.db_key := v.db_key; new_task_rec.flags := 0; new_task (new_task_rec); ELSE trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_VALIDATE: ' || 'not running new TASK_VALIDATE_DB for odb ' || DBMS_RA_INT.DBKEY2NAME(v.db_key)); END IF; END LOOP; -- -- -- -- SELECT MAX(db_key) INTO l_db_key FROM odb WHERE last_validate + (s_late_for_warning * l_validate_db_interval) <= SYSTIMESTAMP; IF l_db_key IS NULL THEN trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE: fixing E_LATE_VALIDATE_NUM'); fix_error (p_error_num => E_LATE_VALIDATE_NUM); ELSE trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE: logging E_LATE_VALIDATE_NUM'); log_error (p_errno => E_LATE_VALIDATE_NUM, p_component => 'VALIDATE', p_severity => SEVERITY_WARNING); END IF; -- -- -- -- -- l_check_files_interval := NUMTODSINTERVAL(l_check_files_days,'day'); trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_CHECKFILE: checking schedule' || ' check_files_days=' || l_check_files_days || ' check_files_interval=' || interval2secs(l_check_files_interval)); FOR c IN (SELECT s.sl_key, sl_name, task_id, NVL(sl_last_check_files, SYSTIMESTAMP - l_check_files_interval) FROM sl s LEFT OUTER JOIN task t ON (s.sl_key = t.sl_key) AND (task_type = TASK_CHECK_FILES) WHERE ((NVL(sl_last_check_files, SYSTIMESTAMP - l_check_files_interval) + l_check_files_interval) <= SYSTIMESTAMP) AND NVL(sl_space, 0) <> 0 AND NOT EXISTS (SELECT 1 FROM config WHERE name = 'disable_check_files') ORDER BY NVL(sl_last_check_files,SYSTIMESTAMP)) LOOP IF c.task_id IS NULL THEN -- trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_CHECKFILE: ' || 'running TASK_CHECK_FILES for sl ' || TO_CHAR(c.sl_key)); new_task_rec := NULL; new_task_rec.task_type := TASK_CHECK_FILES; new_task_rec.sl_key := c.sl_key; new_task_rec.flags := 0; new_task_rec.param_num1 := 0; new_task (new_task_rec); ELSE trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_CHECKFILE: ' || 'not running new TASK_CHECK_FILES for sl ' || TO_CHAR(c.sl_key)); END IF; END LOOP; -- -- -- -- SELECT MAX(sl_name) INTO l_sl_name FROM sl WHERE sl_space > 0 AND sl_last_check_files + (s_late_for_warning * l_check_files_interval) <= SYSTIMESTAMP; IF l_sl_name IS NULL THEN trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE: fixing E_LATE_CHECKFILES_NUM'); fix_error (p_error_num => E_LATE_CHECKFILES_NUM); ELSE trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE: logging E_LATE_CHECKFILES_NUM'); log_error (p_errno => E_LATE_CHECKFILES_NUM, p_component => 'CHECK_FILES', p_severity => SEVERITY_WARNING); END IF; -- -- -- -- -- l_crosscheck_db_interval := NUMTODSINTERVAL(l_crosscheck_db_days, 'day'); trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_CROSSCHECK: checking schedule' || ' crosscheck_db_days=' || l_crosscheck_db_days || ' crosscheck_db_interval=' || interval2secs(l_crosscheck_db_interval)); FOR cc IN (SELECT db_key, last_crosscheck FROM odb WHERE ((NVL(last_crosscheck, SYSTIMESTAMP - l_crosscheck_db_interval) + l_crosscheck_db_interval) <= SYSTIMESTAMP) AND NOT EXISTS (SELECT 1 FROM task WHERE task_type = TASK_CROSSCHECK_DB AND task.db_key = odb.db_key) ORDER BY last_crosscheck DESC) LOOP trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_CROSSCHECK: ' || 'running TASK_CROSSCHECK_DB cc.db_key=' || cc.db_key || ' cc.last_crosscheck=' || TO_CHAR(cc.last_crosscheck,'DD-MM-YYYY HH:MI:SS') || ' SYSTIMESTAMP=' || TO_CHAR(SYSTIMESTAMP,'DD-MM-YYYY HH:MI:SS')); new_task_rec.task_type := TASK_CROSSCHECK_DB; new_task_rec.db_key := cc.db_key; new_task_rec.flags := 0; new_task (new_task_rec); END LOOP; -- -- -- -- SELECT MAX(db_key) INTO l_db_key FROM odb WHERE last_crosscheck + (s_late_for_warning * l_crosscheck_db_interval) <= SYSTIMESTAMP; IF l_db_key IS NULL THEN trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE: fixing E_LATE_CROSSCHECK_NUM'); fix_error (p_error_num => E_LATE_CROSSCHECK_NUM); ELSE trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE: logging E_LATE_CROSSCHECK_NUM'); log_error (p_errno => E_LATE_CROSSCHECK_NUM, p_component => 'CROSSCHECK', p_severity => SEVERITY_WARNING); END IF; END exec_timer_storage_maintenance; -- -- -- -- -- -- -- PROCEDURE exec_timer_task_maintenance IS l_count NUMBER; l_last_interrupt TIMESTAMP WITH TIME ZONE; l_last_year TIMESTAMP WITH TIME ZONE := SYSTIMESTAMP - NUMTODSINTERVAL(365,'DAY'); l_concurrent_tasks NUMBER; l_max_concurrent_tasks NUMBER; l_status BINARY_INTEGER; l_message VARCHAR2(256); l_timestamp TIMESTAMP WITH TIME ZONE; BEGIN -- -- -- -- -- -- -- FOR d IN (SELECT db_key, wait_space FROM odb p WHERE (wait_space > used_space OR wait_space IS NULL) AND EXISTS (SELECT 1 FROM task t WHERE t.db_key = p.db_key AND pending_interrupt = SPACE_PSEUDO_TASK)) LOOP -- IF d.wait_space IS NOT NULL THEN BEGIN DBMS_RA_STORAGE.LOCK_DB (d.db_key); UPDATE odb SET wait_space = NULL WHERE db_key = d.db_key; COMMIT; DBMS_RA_STORAGE.UNLOCK_DB (d.db_key); EXCEPTION WHEN OTHERS THEN save_error; DBMS_RA_STORAGE.UNLOCK_DB (d.db_key); RAISE; END; END IF; release_blocked_tasks(SPACE_PSEUDO_TASK, d.db_key); END LOOP; -- -- -- -- -- -- -- release_blocked_tasks(OPT_DF_PSEUDO_TASK); -- -- -- -- -- -- -- release_blocked_tasks(SERVLET_PSEUDO_TASK); -- -- -- -- -- -- -- SELECT COUNT(*) INTO l_count FROM sbt_lib_desc WHERE status = 'R'; IF l_count > 0 THEN release_blocked_tasks(LIBRARY_PSEUDO_TASK); END IF; -- -- -- -- -- -- -- -- SELECT NVL(MAX(last_interrupt_time), l_last_year), COUNT(*) INTO l_last_interrupt, l_count FROM task WHERE state = STATE_TASK_WAIT AND pending_interrupt = RESOURCE_PSEUDO_TASK; trace1('EXEC_TIMER_TASK_MAINTENANCE: RESOURCE ' || ' count=' || l_count || ' last_interrupt=' || l_last_interrupt); IF l_count <> 0 THEN -- -- -- -- -- IF NOT s_resource_wait_active THEN trace1('EXEC_TIMER_TASK_MAINTENANCE: Entering resource wait state'); s_resource_wait_active := TRUE; -- -- -- -- -- s_resource_wait_last_alter := l_last_interrupt; -- -- -- -- -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); UPDATE task SET pending_interrupt = RESOURCE_PSEUDO_TASK, state = CASE state WHEN STATE_EXECUTABLE THEN STATE_TASK_WAIT ELSE state END WHERE priority > PRIO_MIN_BUSYWORK; COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK; trace1('EXEC_TIMER_TASK_MAINTENANCE: Stuck it to ' || SQL%ROWCOUNT || ' busywork tasks.'); ELSE s_resource_wait_last_alter := GREATEST (s_resource_wait_last_alter, l_last_interrupt); END IF; -- -- -- -- IF (SYSTIMESTAMP - s_resource_wait_last_alter) > NUMTODSINTERVAL(s_resource_wait_timeout, 'day') THEN UPDATE config SET value = ROUND(value * s_resource_wait_relax_rate) WHERE name = '_resource_wait_task_limit'; COMMIT; s_resource_wait_last_alter := SYSTIMESTAMP; END IF; -- -- -- -- SELECT COUNT(*) INTO l_concurrent_tasks FROM sessions WHERE current_task IS NOT NULL; SELECT TO_NUMBER(value) INTO l_max_concurrent_tasks FROM config WHERE name = '_resource_wait_task_limit'; trace1('EXEC_TIMER_TASK_MAINTENANCE: ' || ' l_concurrent_tasks=' || l_concurrent_tasks || '; l_max_concurrent_tasks=' || l_max_concurrent_tasks); -- -- -- -- -- -- IF ((SYSTIMESTAMP - l_last_interrupt) > NUMTODSINTERVAL(s_resource_wait_timeout, 'DAY')) AND (l_max_concurrent_tasks > l_concurrent_tasks) THEN SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); BEGIN FOR t IN (SELECT task_id FROM task WHERE state = STATE_TASK_WAIT AND pending_interrupt = RESOURCE_PSEUDO_TASK ORDER BY priority, task_id) LOOP EXIT WHEN l_concurrent_tasks >= l_max_concurrent_tasks; -- -- -- UPDATE task SET pending_interrupt = NULL, state = STATE_EXECUTABLE WHERE task_id = t.task_id; l_concurrent_tasks := l_concurrent_tasks + 1; trace1('EXEC_TIMER_TASK_MAINTENANCE: ' || 'Released resource waiting task_id ' || t.task_id); END LOOP; EXCEPTION WHEN OTHERS THEN save_error; COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0); RAISE; END; COMMIT; -- -- -- -- IF (l_max_concurrent_tasks > l_concurrent_tasks) THEN trace1('EXEC_TIMER_TASK_MAINTENANCE: Leaving Resource Wait State'); -- -- -- l_status := UTL_LMS.GET_MESSAGE(errnum => -E_END_RESOURCE_WAIT_NUM, product => 'rdbms', facility => 'ora', language => NULL, message => l_message); IF l_status = 0 THEN SYS.DBMS_SYSTEM.KSDWRT(SYS.DBMS_SYSTEM.ALERT_FILE, l_message); END IF; UPDATE config SET value = MAX_RESOURCE_WAIT_PROCESSES WHERE name = '_resource_wait_task_limit'; COMMIT; fix_error (p_error_num => E_RESOURCE_ERROR_NUM); s_resource_wait_active := FALSE; END IF; SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0); END IF; END IF; -- -- -- -- -- -- SELECT COUNT(*) INTO l_count FROM task WHERE state = STATE_TASK_WAIT AND pending_interrupt = POOL_FULL_PSEUDO_TASK; trace1('EXEC_TIMER_TASK_MAINTENANCE: POOL_FULL ' || ' count=' || l_count); IF l_count = 0 THEN fix_error (p_error_num => E_POOL_FULL_NUM); COMMIT; ELSE -- -- -- IF s_pool_tablespace IS NULL THEN SELECT tablespace_name into s_pool_tablespace FROM user_segments WHERE segment_name IN ('PLANS', 'PLANS_DETAILS', 'CHUNKS', 'BLOCKS') AND tablespace_name IS NOT NULL AND ROWNUM = 1; END IF; IF s_pool_tablespace IS NOT NULL THEN -- -- -- -- FOR r in ( SELECT fs.freespace/ts.totalspace freespace_ratio FROM (SELECT SUM(bytes) totalspace FROM dba_data_files WHERE tablespace_name = s_pool_tablespace GROUP BY tablespace_name) ts, (SELECT NVL(SUM(bytes), 0) freespace FROM dba_free_space WHERE tablespace_name = s_pool_tablespace) fs) LOOP -- -- -- -- -- -- -- -- -- -- IF r.freespace_ratio > s_ra_pool_freespace_threshold THEN l_count := s_ra_pool_full_free_count; ELSE l_count := 1; END IF; trace1('EXEC_TIMER_TASK_MAINTENANCE: FULL_POOL_PSEUDO_TASK' || ': freespace_ratio=' || r.freespace_ratio || '; count=' || l_count); END LOOP; -- -- -- -- -- -- FOR t IN (SELECT task_id FROM task WHERE state = STATE_TASK_WAIT AND pending_interrupt = POOL_FULL_PSEUDO_TASK ORDER BY priority, task_id) LOOP -- -- -- UPDATE task SET pending_interrupt = NULL, state = STATE_EXECUTABLE WHERE task_id = t.task_id; trace1('EXEC_TIMER_TASK_MAINTENANCE: ' || 'Released pool waiting task_id ' || t.task_id); l_count := l_count - 1; EXIT WHEN l_count <= 0; END LOOP; COMMIT; END IF; END IF; -- -- -- -- -- -- l_timestamp := SYSTIMESTAMP; FOR o in (SELECT db_key FROM task WHERE task_type = TASK_INDEX_BACKUP AND state = STATE_ORDERING_WAIT AND (SYSTIMESTAMP - last_execute_time) > NUMTODSINTERVAL(s_ordering_wait_timeout, 'DAY') GROUP BY db_key) LOOP trace1('EXEC_TIMER_TASK_MAINTENANCE: Ordering wait timeout on db: ' || o.db_key); log_error (p_errno => E_ORDERING_WAIT_NUM, p_param1 => DBMS_RA_INT.DBKEY2NAME(o.db_key), p_param2 => s_ordering_wait_timeout, p_component => 'INDEX_BACKUP', p_severity => SEVERITY_WARNING, p_db_key => o.db_key); END LOOP; -- -- -- fix_error (p_error_num => E_ORDERING_WAIT_NUM, p_timestamp => l_timestamp); -- -- -- -- -- -- -- -- -- -- -- -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); UPDATE task SET state = STATE_CANCEL WHERE execute_inst_id IS NOT NULL AND task_type IN (TASK_RESTORE, TASK_RESTORE_SBT) AND state NOT IN (STATE_RUNNING, STATE_CANCELING) AND NOT EXISTS (SELECT 1 FROM sys.rai_active_instances i WHERE task.execute_inst_id = i.inst_number); trace1('EXEC_TIMER_TASK_MAINTENANCE: Canceled ' || SQL%ROWCOUNT || ' task(s).'); COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK; END exec_timer_task_maintenance; -- -- -- -- -- -- -- -- -- -- PROCEDURE queue_set_reconcile_timer (p_db_key IN NUMBER) IS l_timer_task timer_task%ROWTYPE; BEGIN trace1 ('QUEUE_SET_RECONCILE_TIMER: p_db_key=' || p_db_key); -- -- -- -- -- trace1 ('QUEUE_SET_RECONCILE_TIMER_TASK'); l_timer_task.timer_type := TIMER_SET_RECONCILE_TIMER; l_timer_task.timer_location := rai_sq.nextval; l_timer_task.flags := 0; l_timer_task.param_num1 := p_db_key; l_timer_task.next_execute := SYSTIMESTAMP-100; l_timer_task.timer_interval := NULL; INSERT INTO timer_task VALUES l_timer_task; COMMIT; END queue_set_reconcile_timer; -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE set_reconcile_timer (p_db_key IN NUMBER) IS l_timer_task timer_task%ROWTYPE; l_count NUMBER; l_last_bp_key NUMBER; l_base_time timestamp; -- Start time to base reconcile on l_next_run_time_this_odb timestamp; -- new next run time for this odb l_next_run_time_all_odbs timestamp; -- new next run time for all odb's l_next_reconcile_time timestamp; -- next scheduled time. l_last_reconcile_time timestamp; -- last reconciled time. l_last_rep_time timestamp; -- finish time of last replication l_set_long_interval BOOLEAN := FALSE; l_set_now_reconcile BOOLEAN := FALSE; l_task_rec task%ROWTYPE; -- used for doing initial replication l_success BOOLEAN; l_num_rec NUMBER; l_exp_rec_cnt NUMBER; BEGIN trace1 ('SET_RECONCILE_TIMER: p_db_key=' || p_db_key); -- -- -- -- IF p_db_key IS NOT NULL THEN SELECT count(*) INTO l_count FROM odb where db_key = p_db_key AND db_state IS NULL; IF l_count = 0 THEN trace1('SET_RECONCILE_TIMER: Completing reconcile_timer. odb no ' || ' longer exists or is being deleted p_db_key=' || p_db_key); queue_set_reconcile_timer(NULL); RETURN; END IF; END IF; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- SELECT last_replication, next_reconcile, last_reconcile INTO l_last_rep_time, l_next_reconcile_time, l_last_reconcile_time FROM odb WHERE db_key = p_db_key; l_base_time := SYSTIMESTAMP; IF l_last_reconcile_time IS NULL THEN -- l_set_now_reconcile := TRUE; ELSIF l_last_rep_time = 0 THEN -- l_set_long_interval := TRUE; ELSE -- -- -- -- IF l_last_rep_time <= (l_base_time - (2*s_reconcile_short_interval)) THEN l_set_long_interval := TRUE; ELSE IF l_next_reconcile_time <= (l_last_rep_time + (2 * s_reconcile_short_interval)) THEN l_base_time := l_last_rep_time + s_reconcile_short_interval; ELSE l_base_time := l_last_rep_time; END IF; l_set_long_interval := FALSE; END IF; END IF; -- -- -- -- -- -- -- IF l_set_now_reconcile = TRUE THEN l_next_run_time_this_odb := SYSTIMESTAMP - 10; ELSIF l_set_long_interval = TRUE THEN IF s_reconcile_long_interval = 0 THEN l_next_run_time_this_odb := NULL; ELSE l_next_run_time_this_odb := l_base_time + s_reconcile_long_interval; END IF; ELSE IF s_reconcile_short_interval = 0 THEN l_next_run_time_this_odb := NULL; ELSE l_next_run_time_this_odb := l_base_time + s_reconcile_short_interval; END IF; END IF; -- -- -- IF l_next_run_time_this_odb IS NOT NULL AND l_next_reconcile_time IS NOT NULL AND l_next_reconcile_time < l_next_run_time_this_odb AND l_next_reconcile_time > l_last_reconcile_time THEN l_next_run_time_this_odb := l_next_reconcile_time; trace1 ('SET_RECONCILE_TIMER: Modifying next run time to ' || l_next_run_time_this_odb); END IF; trace1 ('SET_RECONCILE_TIMER: ' || ' l_base_time=' || l_base_time || ', l_next_run_time=' || l_next_run_time_this_odb || ', l_last_replication_time=' || l_last_rep_time || ', pre-existing_reconcile_time=' || l_next_reconcile_time); -- -- -- -- -- -- -- -- SELECT count(*) INTO l_count FROM timer_task WHERE timer_type = TIMER_RECONCILE; -- -- -- trace1 ('SET_RECONCILE_TIMER: ' || ' Update next_reconcile to =' || l_next_run_time_this_odb); UPDATE odb SET next_reconcile = l_next_run_time_this_odb WHERE db_key = p_db_key; -- -- SELECT MIN(next_reconcile) INTO l_next_run_time_all_odbs FROM odb; -- -- IF l_next_run_time_all_odbs IS NOT NULL THEN IF l_count = 0 THEN -- -- -- -- l_timer_task.timer_type := TIMER_RECONCILE; l_timer_task.timer_location := rai_sq.nextval; l_timer_task.flags := 0; l_timer_task.next_execute := l_next_run_time_all_odbs; l_timer_task.timer_interval := NULL; INSERT INTO timer_task VALUES l_timer_task; trace1 ('SET_RECONCILE_TIMER: add new reconcile timer. ' || ' timer_location=' || l_timer_task.timer_location || ', next_run_time=' || l_timer_task.next_execute); ELSE -- -- SELECT * INTO l_timer_task FROM timer_task WHERE timer_type = TIMER_RECONCILE; -- -- trace1 ('SET_RECONCILE_TIMER: updating reconcile timer. ' || ' next_run_time=' || l_timer_task.next_execute); UPDATE timer_task SET timer_interval = NULL, flags = 0, next_execute = l_next_run_time_all_odbs, timer_location = rai_sq.nextval WHERE timer_type = TIMER_RECONCILE; END IF; ELSE -- -- trace1('SET_RECONCILE_TIMER: Deleting reconcile timer. No replicating db'); DELETE FROM timer_task WHERE timer_type = TIMER_RECONCILE; END IF; COMMIT; EXCEPTION WHEN OTHERS THEN trace1 ('SET_RECONCILE_TIMER: EXCEPTION - Skipping timer setup - sqlcode='|| SQLCODE); save_error; -- s_setup_next_reconcile := TRUE; COMMIT; RAISE; END set_reconcile_timer; -- -- -- -- PROCEDURE reset_reconcile_timer IS BEGIN queue_set_reconcile_timer (NULL); END reset_reconcile_timer; -- -- -- -- -- -- PROCEDURE enqueue_timer_reload_config IS l_timer_task timer_task%ROWTYPE; BEGIN -- -- -- -- trace1 ('ENQUEUE_TIMER_RELOAD_CONFIG'); l_timer_task.timer_type := TIMER_RELOAD_CONFIG; l_timer_task.timer_location := rai_sq.nextval; l_timer_task.flags := 0; l_timer_task.next_execute := SYSTIMESTAMP-101; l_timer_task.timer_interval := NULL; INSERT INTO timer_task VALUES l_timer_task; COMMIT; END enqueue_timer_reload_config; -- -- -- -- -- -- -- -- PROCEDURE enqueue_verify_timer_task IS PRAGMA AUTONOMOUS_TRANSACTION; l_timer_task timer_task%ROWTYPE; BEGIN -- -- -- -- trace1 ('ENQUEUE_VERIFY_TIMER_TASK'); l_timer_task.timer_type := TIMER_VERIFY; l_timer_task.timer_location := rai_sq.nextval; l_timer_task.flags := 0; l_timer_task.next_execute := SYSTIMESTAMP-100; l_timer_task.timer_interval := NULL; INSERT INTO timer_task VALUES l_timer_task; COMMIT; END enqueue_verify_timer_task; -- -- -- -- -- -- PROCEDURE verify_timer_tasks IS CURSOR polling_areas IS SELECT NVL(tt.timer_location,-1), p.poll_key, p.poll_freq FROM poll p LEFT OUTER JOIN timer_task tt ON (tt.timer_type = TIMER_POLLING) AND (tt.timer_location = p.poll_key) WHERE ((tt.timer_location IS NULL) OR (p.poll_freq != tt.timer_interval)); l_newrowflag NUMBER; l_timer_location NUMBER; l_timer_interval DSINTERVAL_UNCONSTRAINED; BEGIN trace1('VERIFY_TIMER_TASKS'); -- -- -- FOR t IN (SELECT tt.timer_location poll_key FROM timer_task tt WHERE (tt.timer_type = TIMER_POLLING) AND NOT EXISTS (SELECT 1 FROM poll p WHERE tt.timer_location = p.poll_key) AND NOT EXISTS (SELECT 1 FROM task WHERE task.task_type = TASK_POLL AND tt.timer_location = task.param_num1)) LOOP trace1 ('VERIFY_TIMER_TASKS: deleting old poll ' || t.poll_key); DELETE polling_history WHERE poll_key = t.poll_key; DELETE timer_task tt WHERE tt.timer_location = t.poll_key; COMMIT; END LOOP; -- -- -- OPEN polling_areas; LOOP FETCH polling_areas INTO l_newrowflag, l_timer_location, l_timer_interval; EXIT WHEN polling_areas%NOTFOUND; -- -- l_timer_interval := LEAST (l_timer_interval, NUMTODSINTERVAL(99, 'day')); IF (l_newrowflag = -1) THEN trace1('VERIFY_TIMER_TASKS: new polling location ' || l_timer_location); INSERT INTO timer_task (timer_type, timer_location, flags, next_execute, timer_interval) VALUES (TIMER_POLLING, l_timer_location, 0, SYSTIMESTAMP, l_timer_interval); ELSE trace1('VERIFY_TIMER_TASKS: polling location changed ' || l_timer_location); UPDATE timer_task SET next_execute = CASE WHEN l_timer_interval < timer_interval THEN SYSTIMESTAMP ELSE next_execute END, timer_interval = l_timer_interval WHERE (timer_type = TIMER_POLLING) AND (timer_location = l_timer_location); END IF; END LOOP; CLOSE polling_areas; -- -- -- timer_task_upsert (TIMER_HISTORY_PRUNE, s_history_partition_interval/2); -- -- -- timer_task_upsert(TIMER_RM_INCOMPLETE_FILES, s_rm_incomplete_files_interval); -- -- -- timer_task_upsert(TIMER_STORAGE_HISTOGRAM, s_histogram_slot_interval); -- -- -- timer_task_upsert(TIMER_STORAGE_MAINTENANCE, s_storage_maintenance_interval); -- -- -- -- timer_task_upsert(TIMER_TASK_MAINTENANCE, s_task_maintenance_interval); -- -- -- -- timer_task_upsert(TIMER_OBSOLETE_SBT, s_obsolete_sbt_interval); -- -- -- -- reset_reconcile_timer(); -- -- -- timer_task_upsert(TIMER_SPAWN_SBT, s_check_sbtsched_interval); -- -- -- timer_task_upsert(TIMER_DB_STATS_REFRESH, s_db_stats_refresh_interval); -- -- -- timer_task_upsert(TIMER_RM_SBT_SESSION, s_sbt_active_interval/2); COMMIT; END verify_timer_tasks; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE timer_task_upsert (p_type IN NUMBER, p_interval IN DSINTERVAL_UNCONSTRAINED) IS BEGIN trace1('TIMER_TASK_UPSERT: Type=' || p_type || '; new interval=' || p_interval); -- -- -- -- MERGE INTO timer_task USING dual ON (timer_type = p_type) WHEN NOT MATCHED THEN INSERT (timer_type, timer_location, flags, next_execute, timer_interval) VALUES (p_type, 0, NULL, SYSTIMESTAMP, p_interval) WHEN MATCHED THEN UPDATE SET next_execute = CASE WHEN p_interval < timer_interval THEN SYSTIMESTAMP ELSE next_execute END, timer_interval = p_interval; END timer_task_upsert; -- -- -- -- -- -- -- -- PROCEDURE cleanup_dead_schedulers (p_restart BOOLEAN) IS CURSOR dead_schedulers IS SELECT * FROM sessions s WHERE NOT EXISTS (SELECT 1 FROM sys.rai_active_sessions a WHERE a.inst_id = s.instance_id AND a.audsid = s.audsid AND a.sid = s.sid AND a.serial# = s.serial# AND a.logon_time = s.logon_time); CURSOR dead_sbt_schedulers IS SELECT s.purpose, s.purpose_param1 FROM sessions s WHERE NOT EXISTS (SELECT 1 FROM sys.rai_active_sessions a WHERE a.inst_id = s.instance_id AND a.audsid = s.audsid AND a.sid = s.sid AND a.serial# = s.serial# AND a.logon_time = s.logon_time) AND s.purpose IN (TASK_BACKUP_SBT, TASK_PURGE_SBT) AND s.current_task IS NOT NULL GROUP BY s.purpose, s.purpose_param1; type numTab_t is table of number index by binary_integer; sbt_purpose numTab_t; sbt_lib_key numTab_t; -- -- -- -- -- CURSOR missing_schedulers IS SELECT i.inst_number, NVL(sc.all_session_count,0) all_session_count, NVL(sc.restricted_session_count,0) restricted_session_count FROM sys.rai_active_instances i LEFT OUTER JOIN (SELECT NVL(jobs.instance_id,1) instance_id, COUNT(*) all_session_count, COUNT(se.purpose_param1) restricted_session_count FROM TABLE(CAST(s_amjobs AS rai_jobs_table_type)) jobs LEFT OUTER JOIN sessions se ON (se.instance_id = jobs.instance_id AND se.job_name = jobs.job_name) GROUP BY jobs.instance_id) sc ON i.inst_number = sc.instance_id; l_task_rec task%ROWTYPE; l_flags NUMBER; l_error_count NUMBER; l_purge_reserve NUMBER; l_db_key NUMBER; l_session_info_id NUMBER; l_restrictions NUMBER; l_sched_error# NUMBER; l_sched_log_id NUMBER; l_sched_additional_info VARCHAR2(4000); l_sched_status VARCHAR2(30); l_sched_log_date TIMESTAMP WITH TIME ZONE; l_new_sessions NUMBER; BEGIN trace1('CLEANUP_DEAD_SCHEDULERS'); -- -- -- OPEN dead_sbt_schedulers; FETCH dead_sbt_schedulers BULK COLLECT INTO sbt_purpose, sbt_lib_key; CLOSE dead_sbt_schedulers; -- -- -- FOR ds IN dead_schedulers LOOP l_session_info_id := CASE WHEN ds.current_task IS NULL THEN NULL ELSE rai_sq.nextval END; IF (ds.purpose IS NOT NULL) AND (ds.current_task IS NULL) THEN trace1('CLEANUP_DEAD_SCHEDULERS: Scheduler ' || ds.serial# || '.' || ds.ba_session_id || ' of type ' || tasktype2name(ds.purpose) || ' exited normally'); ELSE trace1('CLEANUP_DEAD_SCHEDULERS: Scheduler ' || ds.serial# || '.' || ds.ba_session_id || ' with OS PID ' || ds.spid || ' died while processing task id ' || print(ds.current_task)); -- -- -- -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); -- -- -- -- -- BEGIN SELECT * INTO l_task_rec FROM task WHERE task_id = ds.current_task AND ba_session_id = ds.ba_session_id; EXCEPTION WHEN NO_DATA_FOUND THEN l_task_rec := NULL; END; -- -- -- IF l_task_rec.task_id IS NOT NULL THEN -- -- -- -- IF l_task_rec.task_type IN (TASK_RESTORE, TASK_RESTORE_SBT) THEN release_restore_wait (ds.instance_id); END IF; -- -- -- -- -- -- -- SELECT flags INTO l_flags FROM task WHERE task_id = ds.current_task; IF BITAND (l_flags, TASKS_CHUNK_CACHE_ACTIVE) <> 0 THEN DBMS_RA_STORAGE.FREE_TASK_STORAGE (ds.current_task); END IF; -- -- -- -- -- UPDATE task SET ba_session_id = NULL, state = CASE l_task_rec.state WHEN STATE_CANCELING THEN STATE_CANCEL ELSE STATE_EXECUTABLE END, error_count = NVL(error_count,0) + 1 WHERE task_id = ds.current_task RETURNING flags, error_count, purge_reserve, db_key INTO l_flags, l_error_count, l_purge_reserve, l_db_key; trace1 ('CLEANUP_DEAD_SCHEDULERS: Task ' || ds.current_task || ' has now restarted ' || l_error_count || ' times.'); -- -- -- IF bittst (l_flags, TASKS_BLOCKING_TASK) THEN UPDATE task SET pending_interrupt = NULL, state = (CASE state WHEN STATE_RUNNING THEN STATE_RUNNING WHEN STATE_CANCEL THEN STATE_CANCEL WHEN STATE_CANCELING THEN STATE_CANCELING ELSE STATE_EXECUTABLE END) WHERE pending_interrupt = ds.current_task; END IF; -- -- -- -- IF (ds.current_task_type IN (TASK_PURGE_DF, TASK_PURGE_DF_NOW)) AND (l_purge_reserve IS NOT NULL) THEN trace1 ('CLEANUP_DEAD_SCHEDULERS: Boosting priority of task'); UPDATE task SET task_type = TASK_PURGE_DF_NOW, priority = PRIO_PURGE_DF_NOW, error_count = 0 WHERE task_id = ds.current_task; END IF; -- -- -- -- IF ds.purpose = TASK_PURGE_IMMEDIATE AND ds.current_task_type = TASK_PURGE_IMMEDIATE THEN UPDATE task SET task_type = TASK_PURGE WHERE task_id = ds.current_task; trace1 ('CLEANUP_DEAD_SCHEDULERS: Reset task_type to TASK_PURGE'); END IF; IF ds.purpose = TASK_TRIM_DB AND ds.current_task_type = TASK_TRIM_DB THEN DELETE task WHERE task_id = ds.current_task; trace1 ('CLEANUP_DEAD_SCHEDULERS: Delete TRIM_DB task'); END IF; -- -- -- l_task_rec.task_id := l_session_info_id; l_task_rec.task_type := TASK_ERROR_INFO; INSERT INTO task_history VALUES l_task_rec; END IF; -- ds.current task is not null END IF; -- (ds.purpose IS NOT NULL) AND (ds.current_task IS NULL) -- -- -- -- -- l_sched_error# := NULL; l_sched_log_id := NULL; l_sched_additional_info:= NULL; l_sched_status := NULL; l_sched_log_date := SYSTIMESTAMP; FOR i IN (SELECT error#, log_id, additional_info, status, log_date FROM user_scheduler_job_run_details WHERE instance_id = ds.instance_id AND job_name = ds.job_name ORDER BY NVL2(additional_info,2,1)) LOOP l_sched_error# := i.error#; l_sched_log_id := i.log_id; l_sched_additional_info := i.additional_info; l_sched_status := i.status; l_sched_log_date := i.log_date; END LOOP; -- -- -- INSERT INTO task_history (task_id, task_type, flags, pending_interrupt, interrupt_count, savepoint, param_num1, param_num2, param_num3, param, param_char1, param_char2, ba_session_id, execute_inst_id, schedule_time, execute_time, completion_time, elapsed_time, error_count) VALUES (ds.ba_session_id, TASK_SESSION_TIMES, 0, ds.current_task_type, ds.current_task, l_sched_error#, ds.purpose, ds.purpose_param1, l_sched_log_id, l_sched_additional_info, l_sched_status, ds.trace_file, ds.sid, ds.instance_id, ds.start_time, NVL(ds.last_task_start,ds.start_time), l_sched_log_date, NVL(ds.last_task_start,ds.start_time) - ds.start_time, l_session_info_id); DELETE FROM sessions WHERE ba_session_id = ds.ba_session_id; COMMIT; -- SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0); END LOOP; trace1('CLEANUP_DEAD_SCHEDULERS: No more dead schedulers'); IF p_restart THEN -- -- -- -- IF s_session_count IS NULL THEN BEGIN SELECT TO_NUMBER(value) * 2 INTO s_session_count FROM sys.v_$parameter WHERE name = 'cpu_count'; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; s_session_count := 2; clear_error; END; IF s_session_count < 2 THEN s_session_count := 2; END IF; trace1 ('CLEANUP_DEAD_SCHEDULERS: ' || s_session_count || ' schedulers per instance.'); END IF; -- -- -- -- -- -- -- -- -- make_amjobs (name => 'RA$_SCHED%'); FOR ms IN missing_schedulers LOOP trace1('CLEANUP_DEAD_SCHEDULERS: Instance ' || ms.inst_number || ' has ' || print(ms.all_session_count) || ' sessions active and ' || print(ms.restricted_session_count) || ' restricted sessions.'); IF NVL(ms.all_session_count, 0) < s_session_count THEN l_new_sessions := CEIL((s_session_count - NVL(ms.all_session_count, 0)) / 2); FOR i IN 0 .. l_new_sessions - 1 LOOP -- -- -- -- IF ms.restricted_session_count + i < s_restricted_session_count THEN l_restrictions := PRIO_INDEX_BACKUP - 1; ELSE l_restrictions := NULL; END IF; trace1('CLEANUP_DEAD_SCHEDULERS: Restarting session ' || TO_CHAR(ms.all_session_count+1+i) || ' of ' || TO_CHAR(s_session_count) || ' with maximum priority of ' || print(l_restrictions) || ' on instance ' || ms.inst_number); spawn_job ('RA$_SCHED_' || TO_CHAR(rai_sq.nextval), 'dbms_ra_scheduler.schedule(' || 'p_param1 => ' || print(l_restrictions) || ');', ms.inst_number, NULL); -- -- -- -- -- -- -- s_next_dead_scheduler_check := SYSTIMESTAMP; END LOOP; END IF; END LOOP; FOR i in 1..sbt_purpose.count LOOP IF (sbt_purpose(i) = TASK_BACKUP_SBT) THEN trace1('CLEANUP_DEAD_SCHEDULERS: Restarting sbt schedulers ' || 'task_type TASK_BACKUP_SBT lib_key= ' || sbt_lib_key(i)); spawn_sbt_job(p_libkey => sbt_lib_key(i)); ELSIF (sbt_purpose(i) = TASK_PURGE_SBT) THEN trace1('CLEANUP_DEAD_SCHEDULERS: Restarting sbt schedulers ' || 'task_type TASK_PURGE_SBT lib_key= ' || sbt_lib_key(i)); spawn_purge_sbt_job(p_libkey => sbt_lib_key(i)); END IF; END LOOP; -- -- -- SYS.KBRSI_ICD.RSRUNSCHED; END IF; EXCEPTION WHEN E_PQ_FAILURE THEN save_error; -- -- trace1('CLEANUP_DEAD_SCHEDULERS: Instance failure...try again later'); clear_error; RETURN; END cleanup_dead_schedulers; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE schedule (p_task_type IN NUMBER DEFAULT NULL, p_param1 IN NUMBER DEFAULT NULL, p_param2 IN NUMBER DEFAULT NULL, p_settrace IN NUMBER DEFAULT NULL) IS -- l_serial# NUMBER; l_audsid NUMBER; l_logon_time DATE; l_spid VARCHAR2(128); l_job_name DBMS_ID; l_task_rec task%ROWTYPE; l_sts VARCHAR2(10); l_exit_scheduler BOOLEAN := FALSE; l_count NUMBER; l_active_count NUMBER; l_failing BOOLEAN; l_canceling BOOLEAN; l_idle_count NUMBER; l_timing NUMBER; -- centisecond counter l_taskstr VARCHAR2(30); l_end_str VARCHAR2(30); l_task_work NUMBER := NULL; l_dummy_bool BOOLEAN; l_flags NUMBER; l_key NUMBER; l_ba_type NUMBER; l_other_work NUMBER; l_dbkey NUMBER; l_current_execution_time TIMESTAMP WITH TIME ZONE; l_max_task_prio NUMBER := NVL(p_param1, PRIO_MAX_BUSYWORK); l_curr_max_prio NUMBER; l_new_config_time TIMESTAMP WITH TIME ZONE; l_last_quiesce TIMESTAMP WITH TIME ZONE; l_dbok NUMBER; CURSOR task_locks IS /* key and purging locks */ SELECT key, ba_type FROM sys.rai_js_locks WHERE sid = SYS_CONTEXT('USERENV', 'SID') AND ba_type IN (LOCK_DB_KEY, LOCK_SL_KEY, LOCK_PURGE, LOCK_KEY); -- CURSOR sbt_task_cursor IS WITH sbt_task_int AS (SELECT /*+ LEADING(t) USE_HASH(st) */ t.*, st.lib_key, st.copies, st.restore, st.failure_cnt, st.template_key, SUM(CASE WHEN (t.state = STATE_RUNNING AND st.template_key IS NOT NULL AND st.attr_key IS NOT NULL) THEN st.copies ELSE 0 END) OVER (PARTITION BY st.template_key) inuse_streams, SUM(CASE WHEN (t.state = STATE_RUNNING AND t.task_type = TASK_BACKUP_SBT AND st.restore = 'N') THEN st.copies ELSE 0 END) OVER (PARTITION BY st.lib_key) backup_drives_inuse, SUM(CASE WHEN (t.state = STATE_RUNNING AND st.restore = 'R') THEN st.copies ELSE 0 END) OVER (PARTITION BY st.lib_key) restore_drives_inuse FROM sbt_task st, task t WHERE st.task_id = t.task_id AND t.state IN (STATE_RUNNING, STATE_EXECUTABLE) AND t.task_type IN (TASK_BACKUP_SBT, TASK_RESTORE_SBT) AND st.lib_key = schedule.p_param1), sbt_job_attr AS (SELECT /*+ NO_PUSH_PRED NO_MERGE USE_HASH(j) */ a.streams, j.template_key, j.priority, j.attr_key FROM sbt_job_template j LEFT OUTER JOIN sbt_attr_set a -- -- ON a.lib_key = schedule.p_param1 AND j.attr_key = a.attr_key WHERE (j.completion_time IS NULL OR SYSTIMESTAMP < j.completion_time) AND ((a.attr_key IS NULL AND j.bck_type = dbms_ra.RESERVE_BACKUP_TYPE) OR (a.attr_key IS NOT NULL AND j.bck_type != dbms_ra.RESERVE_BACKUP_TYPE))) SELECT /*+ LEADING(st) USE_HASH(j) USE_HASH(l) */ st.task_id, -- all task table rows (task.*) st.task_type, st.priority, st.flags, st.db_key, st.sl_key, st.state, st.pending_interrupt, st.interrupt_count, st.savepoint, st.param_num1, st.param_num2, st.param_num3, st.param_char1, st.param_char2, st.param, st.ba_session_id, st.execute_inst_id, st.schedule_time, st.execute_time, st.last_execute_time, st.completion_time, st.last_interrupt_time, st.error_count, st.purge_reserve, st.elapsed_time, st.com_time, st.sbt_task_id, st.creator_task_id, st.creator_sid, st.creator_instance FROM sbt_lib_desc l, sbt_task_int st LEFT OUTER JOIN sbt_job_attr j ON j.template_key = st.template_key AND st.restore = 'N' -- backup jobs WHERE st.state = STATE_EXECUTABLE AND (st.execute_inst_id IS NULL OR -- -- -- -- st.task_type != TASK_RESTORE_SBT OR st.execute_inst_id = s_instance) AND l.lib_key = st.lib_key AND l.status = 'R' -- filter ready libs AND (j.streams IS NULL OR st.copies <= (j.streams - nvl(st.inuse_streams, 0))) AND ((j.template_key IS NOT NULL AND -- backup task st.copies <= (l.drives - l.restore_drives - nvl(st.backup_drives_inuse, 0) - nvl(st.restore_drives_inuse, 0))) OR (st.restore = 'Y' AND -- restore task st.copies <= (l.drives - nvl(st.backup_drives_inuse, 0) - nvl(st.restore_drives_inuse, 0)))) -- ORDER BY st.restore desc, j.priority, nvl(st.error_count, 0), st.failure_cnt, st.task_id; -- CURSOR sbt_purge_cursor IS SELECT * FROM (SELECT t.* FROM task t LEFT OUTER JOIN sbt_lib_desc l ON t.param_num1 = l.lib_key WHERE t.state = STATE_EXECUTABLE AND t.task_type = TASK_PURGE_SBT AND t.param_num1 = schedule.p_param1 AND (l.status = 'R' OR l.status IS NULL) -- filter ready libs UNION ALL SELECT t.* FROM task t WHERE t.state = STATE_EXECUTABLE AND t.task_type = TASK_QUIESCE_RS) t -- ORDER BY t.task_type, NVL(t.param_num1,0), t.task_id; BEGIN sys.kbrsi_icd.rsSetTrace; -- -- -- assert_owner; dbms_session.set_identifier('RA$'); IF p_task_type IS NULL THEN dbms_ra_int.info_start('SCHEDULE', NULL); ELSE dbms_ra_int.info_start('SCHEDULE', tasktype2name(p_task_type)); END IF; -- SELECT spid, sid, serial#, audsid, logon_time INTO l_spid,s_current_sid, l_serial#, l_audsid, l_logon_time FROM sys.rai_my_ospid; SELECT MAX(job_name) INTO l_job_name FROM user_scheduler_running_jobs WHERE session_id = s_current_sid AND running_instance = s_instance; trace1('SCHEDULE: SID=' || s_current_sid || ', SERIAL#=' || l_serial# || ', audsid=' || l_audsid || ', INST_ID=' || s_instance || ', OS/PID=' || l_spid || ', current_schema=' || SYS_CONTEXT ('USERENV', 'CURRENT_SCHEMA') || ', user=' || USER || ', session_user=' || SYS_CONTEXT ('USERENV', 'SESSION_USER') || ', type=' || print(p_task_type) || ', job_name=' || print(l_job_name) || ', param1=' || print(p_param1) || ', param2=' || print(p_param2)); -- -- -- set_resumable_timeout; -- -- -- -- -- -- -- -- -- IF (p_task_type IS NULL) THEN l_dummy_bool := SYS.KBRSI_ICD.RSQUIESCECHECK (wait=>TRUE); SYS.KBRSI_ICD.RSQUIESCEUNLOCK; END IF; INSERT INTO sessions (ba_session_id, current_task, current_task_type, spid, instance_id, sid, serial#, audsid, logon_time, start_time, trace_file, purpose, purpose_param1, purpose_param2, job_name, last_config_change) VALUES (rai_sq.nextval, NULL, NULL, l_spid, s_instance, s_current_sid, l_serial#, l_audsid, l_logon_time, SYSTIMESTAMP, NULL, p_task_type, p_param1, p_param2, l_job_name, s_config_time) RETURNING ba_session_id INTO s_ba_session_id; COMMIT; -- -- -- wait_for_dbfs; -- WHILE (l_task_work IS NULL OR l_task_work>0) AND (NOT l_exit_scheduler) LOOP -- sys.kbrsi_icd.rsSetTrace; -- -- -- -- IF (NVL(p_task_type,0) <> TASK_TEST_DUMMY) AND SYS.KBRSI_ICD.RSTIMERCHECK THEN -- -- -- -- SELECT value INTO l_sts FROM config WHERE (name = '_recovery_appliance_state'); IF l_sts = 'OFF' THEN trace1('SCHEDULE: Exiting because recovery appliance has been stopped.'); SYS.KBRSI_ICD.RSRUNSCHED; -- wake up other schedulers. EXIT; END IF; trace1 ('SCHEDULE: Starting timer session'); BEGIN spawn_job ('RA$_TIMER_' || s_instance, 'dbms_ra_scheduler.timer_functions;', s_instance, NULL); EXCEPTION WHEN E_JOB_ALREADY_EXISTS THEN save_error; trace1 ('SCHEDULE: Timer session already active for instance ' || s_instance); clear_error; END; END IF; l_failing := FALSE; l_canceling := FALSE; -- -- -- -- -- -- -- -- -- -- IF p_task_type IS NULL THEN SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 1); ELSE SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); END IF; BEGIN -- -- -- IF (p_task_type = TASK_PURGE_IMMEDIATE) THEN -- SELECT * INTO l_task_rec FROM (SELECT * FROM task WHERE (state = STATE_EXECUTABLE) AND (task_type IN (TASK_QUIESCE_RS, TASK_PURGE_DF, TASK_PURGE_DUP_DF * s_enable_dup, TASK_PURGE_DF_NOW, TASK_PURGE_IMMEDIATE)) AND sl_key = p_param1 ORDER BY task_type, task_id) WHERE ROWNUM = 1; ELSIF (p_task_type = TASK_TRIM_DB) THEN -- SELECT * INTO l_task_rec FROM (SELECT * FROM task WHERE (state = STATE_EXECUTABLE) AND (task_type IN (TASK_QUIESCE_RS, TASK_PURGE_DF, TASK_PURGE_DF_NOW, TASK_PURGE_DUP_DF, TASK_TRIM_DB)) AND sl_key = p_param1 AND db_key = p_param2 ORDER BY task_type, task_id) WHERE ROWNUM = 1; ELSIF (p_task_type = TASK_RESTORE) THEN -- SELECT * INTO l_task_rec FROM (SELECT * FROM task WHERE state = STATE_EXECUTABLE AND task_type IN (TASK_QUIESCE_RS, TASK_RESTORE) AND execute_inst_id = s_instance ORDER BY task_type, task_id) WHERE ROWNUM = 1; ELSIF (p_task_type = TASK_TEST_DUMMY) THEN -- SELECT * INTO l_task_rec FROM (SELECT * FROM task WHERE (task_id = p_param1) -- ORDER BY task_type, task_id) WHERE ROWNUM = 1; IF (l_task_rec.task_type <> TASK_QUIESCE_RS) AND (l_task_rec.state <> STATE_TASK_WAIT) AND (l_task_rec.pending_interrupt <> TEST_PSEUDO_TASK) THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM, 'cannot schedule testtask on a live task'); END IF; -- l_task_work := 0; /* One chance to get the desired task */ ELSIF (p_task_type = TASK_BACKUP_SBT) THEN -- -- -- -- -- BEGIN SELECT * INTO l_task_rec FROM (SELECT * FROM task WHERE (task_type = TASK_QUIESCE_RS) AND (state = STATE_EXECUTABLE) ORDER BY task_type, task_id) WHERE ROWNUM = 1; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; l_task_rec := NULL; clear_error; END; IF l_task_rec.task_id IS NULL THEN OPEN sbt_task_cursor; FETCH sbt_task_cursor INTO l_task_rec; IF (sbt_task_cursor%NOTFOUND) THEN CLOSE sbt_task_cursor; RAISE no_data_found; END IF; CLOSE sbt_task_cursor; END IF; ELSIF (p_task_type = TASK_PURGE_SBT) THEN OPEN sbt_purge_cursor; FETCH sbt_purge_cursor INTO l_task_rec; IF (sbt_purge_cursor%NOTFOUND) THEN CLOSE sbt_purge_cursor; RAISE no_data_found; END IF; CLOSE sbt_purge_cursor; ELSE -- -- -- IF SYSTIMESTAMP > (s_last_busywork_stop + s_busywork_inhibit_time) THEN l_curr_max_prio := LEAST(l_max_task_prio, PRIO_MAX_BUSYWORK); ELSE l_curr_max_prio := LEAST(l_max_task_prio, PRIO_MIN_BUSYWORK); END IF; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- SELECT * INTO l_task_rec FROM (SELECT * FROM task WHERE ( state = STATE_EXECUTABLE AND task_type != TASK_PURGE_SBT AND sbt_task_id IS NULL AND (task_type != TASK_RESTORE OR NVL(execute_inst_id, s_instance) = s_instance) AND priority < l_curr_max_prio) OR state = STATE_CANCEL ORDER BY priority, state, task_id) WHERE ROWNUM = 1; l_canceling := (l_task_rec.state = STATE_CANCEL); IF NOT l_canceling THEN -- -- IF type2priority(l_task_rec.task_type) >= PRIO_MIN_BUSYWORK THEN SELECT COUNT(*), COUNT(current_task) INTO l_count, l_active_count FROM sessions; l_idle_count := l_count - l_active_count; IF (l_idle_count < s_min_sessions_for_busywork) THEN trace1 ('SCHEDULE: Too busy for busywork.' || ' Total sessions=' || l_count || ' Active sessions=' || l_active_count || ' Minimum sessions needed=' || s_min_sessions_for_busywork || ' Task id=' || l_task_rec.task_id); -- -- -- -- s_last_busywork_stop := SYSTIMESTAMP; -- -- -- UPDATE sessions SET last_busywork_stop = s_last_busywork_stop WHERE ba_session_id = s_ba_session_id; COMMIT; l_task_rec := NULL; END IF; END IF; END IF; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; l_task_rec := NULL; clear_error; END; IF l_task_rec.task_id IS NOT NULL THEN s_current_task := l_task_rec.task_id; s_current_task_type := l_task_rec.task_type; s_cached_storage := BITAND(l_task_rec.flags, TASKS_CHUNK_CACHE_ACTIVE) <> 0; s_purging_active := (NVL(l_task_rec.purge_reserve,0) <> 0); s_now_serving := s_now_serving + 1; s_pending_interrupt := NULL; -- clear_error(reset => TRUE); l_end_str := NULL; -- l_current_execution_time := SYSTIMESTAMP; l_timing := dbms_utility.get_time; -- -- -- -- -- -- UPDATE task SET state = CASE l_task_rec.state WHEN STATE_CANCEL THEN STATE_CANCELING ELSE STATE_RUNNING END, ba_session_id = s_ba_session_id, execute_inst_id = s_instance, execute_time = NVL(execute_time, l_current_execution_time), last_execute_time = l_current_execution_time, elapsed_time = NVL(elapsed_time,INTERVAL '0' MINUTE), pending_interrupt = NULL WHERE (task_id = s_current_task) RETURNING execute_time INTO l_task_rec.execute_time; UPDATE sessions SET current_task = s_current_task, current_task_type = s_current_task_type, last_task_start = SYSTIMESTAMP WHERE ba_session_id = s_ba_session_id RETURNING last_config_change, last_quiesce INTO l_new_config_time, l_last_quiesce; -- -- -- -- -- -- IF l_last_quiesce IS NOT NULL AND l_last_quiesce + s_quiesce_session_wait > SYSTIMESTAMP AND l_task_rec.priority > PRIO_PURGE AND NOT l_canceling THEN -- -- -- trace1('SCHEDULE: Due to Quiesce, skipping task id ' || s_current_task); ROLLBACK; s_current_task := NULL; l_task_rec := NULL; END IF; -- -- -- COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK; -- -- -- trace1 ('SCHEDULE: config_time new ' || print(l_new_config_time) || ' vs old ' || print(s_config_time)); IF l_new_config_time > s_config_time THEN load_config(); set_resumable_timeout; END IF; -- -- -- -- IF ((s_trace_file_open + s_trace_file_days) < SYSDATE) THEN trace1('SCHEDULE: Ending tracefile'); s_trace_file_open := SYSDATE; EXECUTE IMMEDIATE 'ALTER SESSION SET tracefile_identifier="ra_' || TO_CHAR(s_trace_file_open, 'YYYYMMDDHH24MI') || '"'; -- -- -- BEGIN SELECT value INTO s_trace_file FROM v$diag_info WHERE name = 'Default Trace File'; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; s_trace_file := 'Unknown trace file'; clear_error; END; UPDATE sessions SET trace_file = s_trace_file WHERE ba_session_id = s_ba_session_id; COMMIT; END IF; -- -- -- -- IF s_current_task IS NULL THEN DBMS_LOCK.SLEEP(60); CONTINUE; END IF; -- -- -- -- IF s_cached_storage THEN DBMS_RA_STORAGE.FREE_TASK_STORAGE; END IF; -- -- -- BEGIN -- -- -- IF p_settrace IS NOT NULL THEN sys.kbrsi_icd.rsSetTrace(0, p_settrace); -- used by testtask ELSIF ( (NVL(s_debug_when, 0) <> 0) AND check_when('RAI_DEBUG_WHEN', l_task_rec.task_id)) THEN sys.kbrsi_icd.rsSetTrace(0, s_debug_when); -- Trace this task only END IF; -- -- -- IF (l_task_rec.error_count >= s_max_task_restarts - 1) AND NOT l_canceling THEN IF l_task_rec.error_count >= s_max_task_restarts THEN trace1 ('SCHEDULE: ' || 'Failed on restarts = ' || l_task_rec.error_count || '; p_task_id = ' || print(s_current_task)); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(e_too_many_restarts_num, l_task_rec.task_id, l_task_rec.error_count); END IF; -- sys.kbrsi_icd.rsSetTrace(0, s_debug_error); trace1 ('SCHEDULE: Last chance execute!'); END IF; -- -- -- l_taskstr := tasktype2name(l_task_rec.task_type); l_end_str := NULL; IF l_canceling THEN trace_task('Cancel_Task', l_taskstr); RAISE E_CANCELED; END IF; -- trace_task('Begin_Task', l_taskstr); IF s_perf_on THEN sys.kbrsi_icd.rsStartStats(l_taskstr); END IF; dbms_session.set_identifier('RA$T' || l_task_rec.task_id); dbms_ra_int.info_start(l_taskstr, NULL); -- -- -- IF s_stall_when AND check_when('RAI_STALL_WHEN', l_task_rec.task_id) AND (NVL(p_task_type,0) <> TASK_TEST_DUMMY) THEN s_pending_interrupt := STALL_PSEUDO_TASK; RAISE e_retry_error; END IF; -- IF l_task_rec.db_key IS NOT NULL THEN -- -- -- IF delete_db_task_is_benign( l_task_rec.task_type) = DB_TASK_IS_NOT_BENIGN THEN -- -- -- SELECT COUNT(*) INTO l_dbok FROM odb o WHERE o.db_key = l_task_rec.db_key AND o.db_state IS NULL; IF l_dbok = 0 THEN -- RAISE E_FAILED; END IF; END IF; END IF; -- -- -- CASE l_task_rec.task_type WHEN TASK_QUIESCE_RS THEN execute_quiesce; WHEN TASK_SPAWN_SBT THEN execute_spawn_sbt (l_task_rec); WHEN TASK_PURGE_DF_NOW THEN execute_purge_df (l_task_rec); WHEN TASK_RESTORE THEN execute_restore (l_task_rec); WHEN TASK_STORAGE_HISTOGRAM THEN execute_storage_histogram; WHEN TASK_DEFERRED_DELETE THEN execute_deferred_delete(l_task_rec); WHEN TASK_GCOPY_COMPUTE THEN execute_gcopy_compute (l_task_rec); WHEN TASK_PURGE_IMMEDIATE THEN execute_purge (l_task_rec); WHEN TASK_PURGE_DF THEN execute_purge_df (l_task_rec); WHEN TASK_PURGE_DUP_DF THEN execute_purge_dup_df (l_task_rec); WHEN TASK_TRIM_DB THEN execute_trim_db (l_task_rec); WHEN TASK_PLAN_SBT THEN execute_plan_df (l_task_rec); WHEN TASK_INDEX_BACKUP THEN execute_index_backup (l_task_rec); WHEN TASK_BACKUP_ARCH THEN execute_backup_arch (l_task_rec); WHEN TASK_INC_ARCH THEN execute_inc_arch (l_task_rec); WHEN TASK_NEWDFKEY THEN execute_newdfkey (l_task_rec); WHEN TASK_PURGE THEN execute_purge (l_task_rec); WHEN TASK_PLAN_DF THEN execute_plan_df (l_task_rec); WHEN TASK_MOVE_DF THEN execute_move_df (l_task_rec); WHEN TASK_MOVE_ALL_DB THEN execute_move_all_db; WHEN TASK_POLL THEN execute_poll (l_task_rec); WHEN TASK_BACKUP_SBT THEN execute_backup_sbt (l_task_rec); WHEN TASK_RESTORE_SBT THEN execute_restore_sbt (l_task_rec); WHEN TASK_PURGE_SBT THEN execute_purge_sbt (l_task_rec); WHEN TASK_OBSOLETE_SBT THEN execute_obsolete_sbt (l_task_rec); WHEN TASK_RM_INCOMPLETE_FILES THEN execute_rm_incomplete_files; WHEN TASK_DB_STATS_REFRESH THEN execute_db_stats_refresh; WHEN TASK_RESTORE_RANGE_REFRESH THEN execute_restore_range_refresh (l_task_rec); WHEN TASK_OPTIMIZE_CHUNKS_DF THEN execute_optimize_chunks_df (l_task_rec); WHEN TASK_OPTIMIZE_CHUNKS THEN execute_optimize_chunks(l_task_rec); WHEN TASK_REBUILD_INDEX THEN execute_rebuild_index (l_task_rec); WHEN TASK_VALIDATE_DB THEN execute_validate_db (l_task_rec); WHEN TASK_DELETE_DB THEN execute_delete_db (l_task_rec); WHEN TASK_CHECK_FILES THEN execute_check_files (l_task_rec); WHEN TASK_CROSSCHECK_DB THEN execute_crosscheck_db (l_task_rec); WHEN TASK_RECONCILE THEN execute_reconcile (l_task_rec); WHEN TASK_REPAIR_DB THEN execute_repair_db (l_task_rec); WHEN TASK_INSERT_FAULT THEN execute_insert_fault (l_task_rec); ELSE /*NF_START*/ trace1 ('SCHEDULE: unknown task type: ' || l_task_rec.task_type); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_BAD_TASK_TYPE_NUM, l_task_rec.task_type); END CASE; EXCEPTION WHEN E_PENDING_INTERRUPT OR E_RETRY_ERROR OR E_RETRY_RESERVE THEN save_error; trace1 ('SCHEDULE: Waiting for task id ' || print(s_pending_interrupt)); -- -- -- -- IF SQLCODE = E_RETRY_RESERVE_NUM THEN s_enable_dup := 0; END IF; -- -- -- -- -- IF s_pending_interrupt = SPACE_PSEUDO_TASK THEN SELECT db_key INTO l_dbkey FROM task WHERE task_id = s_current_task; BEGIN DBMS_RA_STORAGE.LOCK_DB (l_dbkey); UPDATE odb SET wait_space = used_space WHERE db_key = l_dbkey; COMMIT; DBMS_RA_STORAGE.UNLOCK_DB (l_dbkey); EXCEPTION WHEN OTHERS THEN save_error; DBMS_RA_STORAGE.UNLOCK_DB (l_dbkey); RAISE; END; END IF; IF s_pending_interrupt <> 0 THEN -- -- -- suspend_task (STATE_TASK_WAIT, l_current_execution_time); l_end_str := 'Waiting_Task'; ELSE -- -- -- suspend_task (STATE_EXECUTABLE, l_current_execution_time); l_end_str := 'Interrupt_Task'; END IF; -- -- -- l_task_rec.task_id := NULL; clear_error; WHEN E_NO_MORE_SGA THEN save_error; trace1 ('SCHEDULE: NO_MORE_SGA'); suspend_task (STATE_RESTORE_WAIT, l_current_execution_time); l_end_str := 'Interrupt_Task'; -- -- -- l_task_rec.task_id := NULL; clear_error; WHEN E_SNAPSHOT_TOO_OLD OR E_UNABLE_EXTEND_TEMPSEG OR E_TOO_MANY_ROLLBACK_EXTENTS OR E_CANT_EXTEND_UNDO THEN save_error; ROLLBACK; -- -- -- log_error (p_errno => E_RESOURCE_ERROR_NUM, p_keep_stack => TRUE, p_component => 'SCHEDULER', p_severity => SEVERITY_WARNING, p_param_num => SQLCODE); -- -- -- -- -- SELECT FLOOR(COUNT(*)*.9) INTO l_count FROM sessions WHERE current_task IS NOT NULL; trace1 ('SCHEDULE: Try to reset resource restrictions to ' || l_count); -- -- -- -- UPDATE config SET value = GREATEST(LEAST(value, l_count),3) WHERE name = '_resource_wait_task_limit' RETURNING value INTO l_count; trace1 ('SCHEDULE: Resource restrictions set to ' || l_count); COMMIT; -- -- -- -- s_pending_interrupt := RESOURCE_PSEUDO_TASK; suspend_task (STATE_TASK_WAIT, l_current_execution_time); l_end_str := 'Waiting_Task'; -- -- -- l_task_rec.task_id := NULL; -- -- -- -- l_exit_scheduler := TRUE; clear_error; WHEN E_TABLE_TS_FULL OR E_INDEX_TS_FULL OR E_INDEXPART_TS_FULL OR E_TABLEPART_TS_FULL OR E_RESUMABLE_TIMEOUT THEN -- save_error; -- IF s_pool_tablespace IS NULL THEN SELECT tablespace_name INTO s_pool_tablespace FROM user_segments WHERE segment_name IN ('PLANS', 'PLANS_DETAILS', 'CHUNKS', 'BLOCKS') AND ROWNUM = 1; END IF; trace1('SCHEDULE: Tablespace ' || s_pool_tablespace || ' is full'); IF INSTR(SYS.DBMS_UTILITY.FORMAT_ERROR_STACK, s_pool_tablespace) = 0 THEN RAISE; END IF; ROLLBACK; -- -- -- log_error (p_errno => E_POOL_FULL_NUM, p_param1 => s_pool_tablespace, p_keep_stack => TRUE, p_component => 'SCHEDULER', p_severity => SEVERITY_ERROR); -- -- -- -- s_pending_interrupt := POOL_FULL_PSEUDO_TASK; suspend_task (STATE_TASK_WAIT, l_current_execution_time); l_end_str := 'Waiting_Task'; -- -- -- l_task_rec.task_id := NULL; WHEN E_TOO_MANY_RESTARTS THEN save_error; -- write_error (p_component => 'SCHEDULER', p_severity => SEVERITY_INTERNAL, p_param_num => l_task_rec.task_id); l_failing := TRUE; clear_error; WHEN E_TERMINATED THEN save_error; -- -- -- trace1 ('SCHEDULE: E_TERMINATED handled.'); clear_error; WHEN E_FAILED THEN save_error; -- trace1 ('SCHEDULE: E_FAILED handled.'); l_end_str := 'Failed_Task'; l_failing := TRUE; clear_error; WHEN E_CANCELED THEN save_error; -- trace1 ('SCHEDULE: E_CANCELED handled.'); l_end_str := 'Canceled_Task'; clear_error; END; -- -- -- IF l_task_rec.task_id IS NULL THEN FOR l IN task_locks LOOP CASE l.ba_type WHEN LOCK_DB_KEY THEN DBMS_RA_STORAGE.UNLOCK_DB(l.key); WHEN LOCK_SL_KEY THEN DBMS_RA_STORAGE.UNLOCK_SL(l.key); WHEN LOCK_PURGE THEN SYS.KBRSI_ICD.RSPURGEUNLOCK(l.key); WHEN LOCK_KEY THEN SYS.KBRSI_ICD.RSKEYUNLOCK(l.key); END CASE; END LOOP; END IF; sys.kbrsi_icd.rsStopStats; dbms_ra_int.info_end(TRUE); dbms_session.set_identifier('RA$'); -- -- -- IF l_task_rec.task_id IS NOT NULL THEN -- -- -- l_timing := dbms_utility.get_time - l_timing; trace1 ('SCHEDULE: Execution time was ' || l_timing); -- -- -- complete_task (NVL(l_end_str,'End_task'), l_taskstr, l_current_execution_time, CASE WHEN l_failing THEN STATE_FAILED WHEN l_canceling THEN STATE_CANCELED ELSE STATE_COMPLETED END); ELSE -- -- -- -- trace_task(NVL(l_end_str,'Nulled_task'), l_taskstr); END IF; l_taskstr := NULL; -- We are done that operation -- -- s_sysreserve_ok := FALSE; s_no_wait_on_allocate := FALSE; s_current_task := NULL; s_current_task_type := NULL; UPDATE sessions SET current_task = NULL, current_task_type = NULL WHERE ba_session_id = s_ba_session_id; COMMIT; ELSE -- -- -- -- -- IF p_task_type = TASK_PURGE_IMMEDIATE THEN -- SELECT COUNT(*) INTO l_task_work FROM task WHERE (task_type IN (TASK_PURGE_IMMEDIATE, TASK_PURGE_DF, TASK_PURGE_DUP_DF, TASK_PURGE_DF_NOW)) AND sl_key = p_param1 AND (pending_interrupt IS NULL OR task_type != TASK_PURGE_DUP_DF); s_enable_dup := 1; -- ELSIF p_task_type = TASK_TRIM_DB THEN -- SELECT COUNT(*) INTO l_task_work FROM task WHERE (task_type IN (TASK_TRIM_DB, TASK_PURGE_DF, TASK_PURGE_DF_NOW)) AND sl_key = p_param1 AND db_key = p_param2; ELSIF p_task_type = TASK_RESTORE THEN -- SELECT COUNT(*) INTO l_task_work FROM task WHERE task_type = TASK_RESTORE AND state = STATE_EXECUTABLE AND execute_inst_id = s_instance; -- ELSIF (p_task_type = TASK_BACKUP_SBT) THEN -- SELECT COUNT(*) INTO l_task_work FROM task t, sbt_lib_desc l, sbt_task st LEFT OUTER JOIN sbt_job_template j ON j.template_key = st.template_key AND st.restore = 'N' -- backup or reserve jobs AND (j.completion_time IS NULL OR SYSTIMESTAMP < j.completion_time) WHERE t.state = STATE_EXECUTABLE AND t.task_id = st.task_id AND t.task_type IN (TASK_BACKUP_SBT, TASK_RESTORE_SBT) AND (j.template_key IS NOT NULL OR st.restore = 'Y') AND st.lib_key = l.lib_key AND l.status = 'R' -- filter ready libs AND st.lib_key = schedule.p_param1; ELSIF p_task_type = TASK_PURGE_SBT THEN -- SELECT COUNT(*) INTO l_task_work FROM task t, sbt_lib_desc l WHERE t.state = STATE_EXECUTABLE AND t.task_type = TASK_PURGE_SBT AND l.status = 'R' -- filter ready libs AND t.param_num1 = l.lib_key AND t.param_num1 = schedule.p_param1; ELSE /* Normal scheduler */ -- -- -- -- -- SELECT COUNT(*) INTO l_other_work FROM DUAL WHERE EXISTS (SELECT 1 FROM task WHERE ( state = STATE_EXECUTABLE AND task_type != TASK_PURGE_SBT AND sbt_task_id IS NULL) OR state = STATE_CANCEL); END IF; -- IF l_task_work = 0 THEN SYS.KBRSI_ICD.RSSCHEDUNLOCK; cleanup_task(p_task_type); ELSE -- -- -- -- -- -- -- trace1 ('SCHEDULE: No work to be done. Going to sleep'); IF (p_task_type IS NULL) AND (l_other_work = 0) THEN SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 1); ELSE -- -- -- -- -- -- -- -- SYS.KBRSI_ICD.RSSCHEDUNLOCK; DBMS_LOCK.SLEEP(s_scheduling_wait); END IF; END IF; END IF; /* Found a task to execute */ -- IF s_safe_mode THEN BEGIN SELECT key, ba_type INTO l_key, l_ba_type FROM (SELECT key, ba_type FROM sys.rai_js_locks WHERE sid = SYS_CONTEXT('USERENV', 'SID') AND ba_type IN (LOCK_DB_KEY, LOCK_SL_KEY, LOCK_PURGE, LOCK_KEY) -- AND NOT ((ba_type = LOCK_KEY) AND (key = LOCK_QUIESCE_PENDING)) ORDER BY ba_type, key) WHERE ROWNUM = 1; s_tracing_on := TRUE; SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM, 'SCHEDULE: ba_type ' || l_ba_type || ', lock ' || l_key || ' held illegally'); EXCEPTION WHEN no_data_found THEN save_error; clear_error; /* no locks is a good thing */ END; END IF; END LOOP; -- -- -- UPDATE sessions SET last_task_start = SYSTIMESTAMP WHERE ba_session_id = s_ba_session_id; COMMIT; dbms_application_info.set_module(NULL, NULL); dbms_session.set_identifier(NULL); EXCEPTION WHEN E_ORA_600 THEN -- -- save_error; IF s_current_task_type IS NULL THEN l_taskstr := 'SCHEDULER'; ELSE l_taskstr := tasktype2name(s_current_task_type); END IF; write_error (p_component => l_taskstr, p_severity => SEVERITY_INTERNAL, p_param_num => s_current_task, p_param_char => l_spid); RAISE; WHEN OTHERS THEN save_error; -- sys.kbrsi_icd.rsStopStats; -- -- -- -- IF (p_task_type = TASK_PURGE_SBT OR p_task_type = TASK_BACKUP_SBT) THEN l_spid := NULL; END IF; IF s_current_task_type IS NULL THEN l_taskstr := 'SCHEDULER'; ELSE l_taskstr := tasktype2name(s_current_task_type); END IF; log_error (p_errno => E_BAD_TASK_NUM, p_param1 => print(l_task_rec.task_id), p_param2 => (CASE WHEN s_current_task_type IS NOT NULL THEN l_taskstr ELSE 'NONE' END), p_component => l_taskstr, p_severity => SEVERITY_INTERNAL, p_param_num => l_task_rec.task_id, p_param_char => l_spid); SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0); cleanup_task(p_task_type); -- trace_task('Fail_Task', l_taskstr); dbms_application_info.set_module(NULL, NULL); dbms_session.set_identifier(NULL); RAISE; END schedule; -- -- -- -- -- -- -- -- -- PROCEDURE testTask(p_taskid IN NUMBER DEFAULT NULL, p_tasktype IN NUMBER DEFAULT NULL, p_num1 IN NUMBER DEFAULT NULL, p_num2 IN NUMBER DEFAULT NULL, p_num3 IN NUMBER DEFAULT NULL, p_char1 IN VARCHAR2 DEFAULT NULL, p_char2 IN VARCHAR2 DEFAULT NULL, p_param IN VARCHAR2 DEFAULT NULL, p_slkey IN NUMBER DEFAULT NULL, p_dbkey IN NUMBER DEFAULT NULL, p_settrace IN NUMBER DEFAULT NULL, p_newsession IN BOOLEAN DEFAULT FALSE) IS l_value VARCHAR2(3); l_count NUMBER; l_task_rec task%ROWTYPE; l_task_id NUMBER; l_needtask BOOLEAN := TRUE; l_jobname DBMS_ID; l_action VARCHAR2(200); BEGIN -- IF p_taskid IS NOT NULL THEN trace1 ('testTask retry task id ' || p_taskid); -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); BEGIN SELECT COUNT(*) INTO l_count FROM task WHERE task_id = p_taskid; -- -- IF l_count > 0 THEN -- SELECT * INTO l_task_rec FROM task WHERE task_id = p_taskid; -- IF l_task_rec.state IN (STATE_RUNNING, STATE_CANCELING) THEN -- SELECT value into l_value FROM config WHERE name = '_recovery_appliance_state'; IF l_value = 'ON' THEN -- SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM, 'Appliance is on: cannot testtask a running task'); END IF; -- IF BITAND (l_task_rec.flags, TASKS_CHUNK_CACHE_ACTIVE) <> 0 THEN DBMS_RA_STORAGE.FREE_TASK_STORAGE (p_taskid); END IF; -- -- UPDATE sessions SET current_task = NULL, current_task_type = NULL WHERE current_task = p_taskid; END IF; -- UPDATE task SET ba_session_id = NULL, state = STATE_TASK_WAIT, pending_interrupt = TEST_PSEUDO_TASK, error_count = 1 WHERE task_id = p_taskid; COMMIT; l_needtask := FALSE; -- ELSE BEGIN SELECT * INTO l_task_rec FROM task_history WHERE task_id = p_taskid; DELETE FROM task_history WHERE task_id = p_taskid; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM, 'testtask taskid not found'); END; END IF; l_task_rec.pending_interrupt := NULL; l_task_rec.error_count := 1; /* Ensure it runs again. */ COMMIT; /* commit the deletes before releasing schedlock */ SYS.KBRSI_ICD.RSSCHEDUNLOCK; EXCEPTION WHEN OTHERS THEN save_error; SYS.KBRSI_ICD.RSSCHEDUNLOCK; RAISE; END; ELSIF p_tasktype IS NULL THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM, 'cannot testtask without a taskid or type'); ELSE -- l_task_rec.task_id := rai_sq.nextval; l_task_rec.task_type := p_tasktype; l_task_rec.priority := type2priority(p_tasktype); l_task_rec.param_num1 := p_num1; l_task_rec.param_num2 := p_num2; l_task_rec.param_num3 := p_num3; l_task_rec.param_char1 := p_char1; l_task_rec.param_char2 := p_char2; l_task_rec.param := p_param; l_task_rec.sl_key := p_slkey; l_task_rec.db_key := p_dbkey; l_task_rec.flags := 0; END IF; -- trace1 ('testTask type: ' || tasktype2name(l_task_rec.task_type) || ', num1: ' || print(l_task_rec.param_num1) || ', num2: ' || print(l_task_rec.param_num2) || ', num3: ' || print(l_task_rec.param_num3) || ', char1: ' || print(l_task_rec.param_char1) || ', char2: ' || print(l_task_rec.param_char2) || ', param: ' || print(l_task_rec.param) || ', slkey: ' || print(l_task_rec.sl_key) || ', dbkey: ' || print(l_task_rec.db_key)); -- -- IF l_needtask THEN l_task_id := define_task (task_rec => l_task_rec); END IF; UPDATE task -- SET state = STATE_TASK_WAIT, pending_interrupt = TEST_PSEUDO_TASK WHERE task_id = l_task_id; COMMIT; -- -- -- -- IF p_newsession THEN l_jobname := 'RA$TESTTASK_' || rai_sq.nextval; l_action := 'DBMS_RA_SCHEDULER.SCHEDULE(' || ' p_task_type => ' || TASK_TEST_DUMMY || ', p_param1 => ' || l_task_rec.task_id || ', p_settrace => ' || print(p_settrace) || ');'; trace1 ('TESTTASK: spawning ' || l_jobname || ' for ' || l_action); spawn_job (l_jobname, l_action, s_instance, NULL); DBMS_RA_INT.WAIT_FOR_JOB (l_jobname, 5); ELSE trace1 ('testTask local session start'); schedule(p_task_type => TASK_TEST_DUMMY , p_param1 => l_task_rec.task_id , p_settrace => p_settrace); END IF; trace1 ('testTask complete'); END testTask; -- -- -- PROCEDURE get_lock(p_type IN NUMBER, p_key IN NUMBER) IS l_locked BOOLEAN := FALSE; l_blocking_sid NUMBER := NULL; BEGIN tracex ('GET_LOCK: for type ' || p_type || ' for key ' || p_key); -- -- WHILE NOT l_locked AND l_blocking_sid IS NULL LOOP CASE p_type WHEN LOCK_KEY THEN l_locked := sys.kbrsi_icd.rsKeyWriteLock(p_key,FALSE); WHEN LOCK_PURGE THEN l_locked := sys.kbrsi_icd.rsPurgeLock(p_key); ELSE SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM, 'Lock on unknown lock type=' || p_type); END CASE; -- -- -- IF NOT l_locked THEN <> BEGIN SELECT MIN(jsl.sid), NVL(MIN(s.current_task), SERVLET_PSEUDO_TASK) INTO l_blocking_sid, s_pending_interrupt FROM sys.rai_js_gvlocks jsl LEFT OUTER JOIN sessions s ON (jsl.sid = s.sid AND jsl.inst_id = s.instance_id) WHERE jsl.ba_type = p_type AND jsl.key = MOD(p_key, POWER(2,32)); EXCEPTION WHEN E_PQ_FAILURE THEN save_error; clear_error; -- GOTO try_try_again; END; END IF; END LOOP; -- IF NOT l_locked THEN tracex ('GET_LOCK not locked: type ' || p_type || ' for key ' || p_key); show_locks(p_type, p_key); RAISE E_RETRY_ERROR; END IF; END get_lock; -- -- -- PROCEDURE unlock(p_type IN NUMBER, p_key IN NUMBER) IS BEGIN CASE p_type WHEN LOCK_KEY THEN sys.kbrsi_icd.rsKeyUnlock(p_key); WHEN LOCK_PURGE THEN sys.kbrsi_icd.rsPurgeUnlock(p_key); ELSE SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM, 'Unlock on unknown lock type=' || p_type); END CASE; END unlock; -- -- -- PROCEDURE show_locks (p_type IN NUMBER, p_key IN NUMBER) IS CURSOR locks (in_type IN NUMBER, in_key IN NUMBER) IS SELECT l.sid, s.current_task, s.current_task_type FROM TABLE(CAST(s_amlocks AS rai_locks_table_type)) l LEFT OUTER JOIN sessions s ON (l.sid = s.sid AND l.inst_id = s.instance_id) WHERE l.ba_type = in_type AND l.key = mod(in_key, power(2,32)); BEGIN IF s_safe_mode THEN make_amlocks(); FOR l IN locks (p_type, p_key) LOOP trace1 ('SHOW_LOCKS: type ' || p_type || ', key ' || p_key || ', SID ' || l.sid || ', task id ' || NVL(TO_CHAR(l.current_task),'**Servlet**') || ', task_type ' || tasktype2name(l.current_task_type)); END LOOP; END IF; END show_locks; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE get_lock_direct_waitable(p_type IN NUMBER, p_key IN NUMBER, wait_time_in_seconds IN NUMBER) IS l_exit_loop NUMBER := 0; l_start_time DATE; l_current_time DATE; l_end_time DATE; l_max_time DATE; l_max NUMBER; l_got_lock BOOLEAN := FALSE; BEGIN trace1('Acquiring lock for key=' || p_key || ' type=' || p_type || ' retry=' || wait_time_in_seconds); l_current_time := SYSDATE; l_start_time := l_current_time; l_end_time := l_start_time + ((1/24/60/60) * wait_time_in_seconds); -- l_max := ((1/24/60) * 10); IF wait_time_in_seconds > l_max THEN l_max := wait_time_in_seconds; END IF; l_max_time := l_start_time + l_max; WHILE l_exit_loop = 0 LOOP CASE p_type WHEN LOCK_KEY THEN l_got_lock := sys.kbrsi_icd.rsKeyWriteLock(p_key,FALSE); WHEN LOCK_PURGE THEN l_got_lock := sys.kbrsi_icd.rsPurgeLock(p_key); ELSE SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM, 'GET_LOCK_DIRECT_WRITABLE on unknown_lock_type= ' || p_type); END CASE; IF l_got_lock = FALSE THEN IF wait_time_in_seconds > 0 THEN l_current_time := SYSDATE; IF (l_current_time > l_end_time) OR (l_current_time > l_max_time) THEN l_exit_loop := 1; ELSE dbms_lock.sleep(s_lock_refused_wait); -- 5 seconds END IF; ELSIF wait_time_in_seconds = 0 THEN l_exit_loop := 1; END IF; ELSE l_exit_loop := 1; END IF; END LOOP; IF l_got_lock = FALSE THEN trace1('Unable to get write_lock for key=' || p_key); END IF; END get_lock_direct_waitable; -- -- -- PROCEDURE release_blocked_tasks(p_task_id IN NUMBER, p_db_key IN NUMBER DEFAULT NULL) IS l_max_vb_key NUMBER; l_retention_time TIMESTAMP; l_max_vb_key2 NUMBER; BEGIN -- -- -- -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); -- -- -- UPDATE task SET pending_interrupt = NULL, state = (CASE state WHEN STATE_RUNNING THEN STATE_RUNNING WHEN STATE_CANCEL THEN STATE_CANCEL WHEN STATE_CANCELING THEN STATE_CANCELING ELSE STATE_EXECUTABLE END), ba_session_id = NULL WHERE pending_interrupt = p_task_id AND (p_db_key IS NULL OR db_key = p_db_key); trace1('RELEASE_BLOCKED_TASKS: Released ' || SQL%ROWCOUNT || ' tasks.'); COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0); EXCEPTION WHEN OTHERS THEN save_error; trace1('RELEASE_BLOCKED_TASKS: Exeception raised ' || SQLERRM); SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0); RAISE; END release_blocked_tasks; -- -- -- -- -- -- -- -- -- -- PROCEDURE raise_purge_priority (p_dfkey IN NUMBER) IS BEGIN trace1('RAISE_PURGE_PRIORITY on df_key ' || p_dfkey); -- -- -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); UPDATE task SET task_type = TASK_PURGE_DF_NOW, priority = PRIO_PURGE_DF_NOW WHERE task_type = TASK_PURGE_DF AND param_num1 = p_dfkey AND state IN (STATE_RUNNING, STATE_EXECUTABLE); trace1('RAISE_PURGE_PRIORITY: Accelerated ' || SQL%ROWCOUNT || ' tasks.'); COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0); EXCEPTION WHEN OTHERS THEN save_error; trace1('RAISE_PURGE_PRIORITY: Exeception raised ' || SQLERRM); SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0); RAISE; END raise_purge_priority; -- -- -- -- PROCEDURE avoid_sl(p_type IN NUMBER, -- TASK_PURGE or TASK_INDEX_BACKUP p_slkey IN NUMBER) IS l_taskid NUMBER; l_space NUMBER; BEGIN -- CASE p_type WHEN TASK_PURGE THEN -- -- -- -- SELECT MIN(task_id) INTO l_taskid FROM task WHERE task_type IN (TASK_PURGE, TASK_PURGE_IMMEDIATE, DECODE(s_current_task_type, TASK_INDEX_BACKUP, 0, TASK_PURGE_DF), DECODE(s_current_task_type, TASK_INDEX_BACKUP, 0, TASK_PURGE_DUP_DF), TASK_PURGE_DF_NOW, TASK_REPAIR_DB, TASK_REBUILD_INDEX) AND task_id != s_current_task AND (sl_key = p_slkey OR (task_type = TASK_REBUILD_INDEX AND state = STATE_RUNNING)); WHEN TASK_INDEX_BACKUP THEN -- -- -- -- SELECT SUM(bytes)+MAX(bytes)+MAX(bytes) INTO l_space FROM task t, odb d, bp p WHERE state = STATE_RUNNING AND t.db_key = d.db_key AND d.sl_key = p_slkey AND t.param_num1 = p.bp_key AND t.task_type = TASK_INDEX_BACKUP AND BITAND (t.flags, TASKS_CHUNK_CACHE_ACTIVE) = 0; -- l_taskid := NULL; IF dbms_ra_storage.freespace(p_slkey) < l_space THEN BEGIN -- -- SELECT MIN(rand_task) INTO l_taskid FROM (SELECT FIRST_VALUE(task_id) OVER (ORDER BY dbms_random.VALUE) rand_task FROM task t, odb d WHERE state = STATE_RUNNING AND t.db_key = d.db_key AND d.sl_key = p_slkey AND t.task_type IN (TASK_INDEX_BACKUP, TASK_PURGE_DF, TASK_PURGE_DUP_DF) AND t.task_id <> s_current_task); EXCEPTION WHEN no_data_found THEN save_error; clear_error; -- OK, this is the only task, so just do it. END; END IF; trace1('AVOID_SL: task ' || l_taskid || ', space ' || l_space); ELSE SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM, 'bad avoid_sl task'); END CASE; -- IF l_taskid IS NOT NULL THEN trace1('AVOID_SL: throwing retry for sl_key ' || p_slkey); s_pending_interrupt := l_taskid; RAISE E_RETRY_ERROR; END IF; END avoid_sl; -- -- -- -- -- -- PROCEDURE avoid_db (p_db_key IN NUMBER) IS l_task_id NUMBER; BEGIN -- -- -- IF type2priority(NVL(s_current_task_type,0)) < PRIO_MIN_BUSYWORK THEN RETURN; END IF; -- -- -- -- SELECT task_id INTO l_task_id FROM task WHERE db_key = p_db_key AND priority < PRIO_MIN_BUSYWORK AND state != STATE_ORDERING_WAIT AND task_type NOT IN (TASK_BACKUP_SBT, TASK_RESTORE_SBT, TASK_PURGE_SBT, TASK_OBSOLETE_SBT, TASK_PLAN_SBT) AND ROWNUM = 1; -- trace1('AVOID_DB: throwing retry for db_key ' || p_db_key); s_pending_interrupt := l_task_id; RAISE E_RETRY_ERROR; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; clear_error; END avoid_db; -- -- -- -- -- -- -- PROCEDURE avoid_bs(p_dbkey IN NUMBER, p_bskey IN NUMBER, p_bpkey IN NUMBER) IS l_taskid NUMBER; BEGIN -- -- -- -- -- -- -- -- -- SELECT MIN(task_id) INTO l_taskid FROM task t, odb p, bp b, bdf d, (SELECT * FROM bdf WHERE bdf.bs_key = p_bskey) a WHERE t.state = STATE_RUNNING AND t.db_key = p.db_key AND t.db_key = p_dbkey AND t.task_type = TASK_INDEX_BACKUP AND t.task_id != s_current_task AND t.param_num1 = b.bp_key AND b.bs_key = d.bs_key AND d.file# = a.file# AND b.piece# = (SELECT piece# FROM bp WHERE bp_key = p_bpkey); -- IF l_taskid IS NOT NULL THEN trace1('AVOID_BS: throwing retry for bs_key ' || p_bskey); s_pending_interrupt := l_taskid; RAISE E_RETRY_ERROR; END IF; END avoid_bs; -- -- -- -- -- PROCEDURE avoid_delete_db(p_dbkey IN NUMBER DEFAULT NULL) IS BEGIN -- -- -- -- SELECT MAX(task_id) INTO s_pending_interrupt FROM task WHERE task_type = TASK_DELETE_DB AND state = STATE_RUNNING AND db_key = NVL(p_dbkey, db_key); -- IF s_pending_interrupt IS NOT NULL THEN trace1('AVOID_DELETE_DB: Waiting for task ' || s_pending_interrupt); RAISE E_RETRY_ERROR; END IF; END avoid_delete_db; -- -- -- PROCEDURE execute_backup_arch (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS l_delete BOOLEAN; BEGIN trace1('EXECUTE_BACKUP_ARCH: Performing Backup arch Task ' || s_current_task); tracex('EXECUTE_BACKUP_ARCH: DB: ' || p_task_rec.db_key || ' filename: ' || p_task_rec.param); wait_for_repair (NULL, p_task_rec.db_key); -- -- -- -- SELECT MIN(task_id) INTO s_pending_interrupt FROM task WHERE db_key = p_task_rec.db_key AND param = p_task_rec.param AND task_type IN (TASK_INC_ARCH, TASK_BACKUP_ARCH) AND (state = STATE_RUNNING OR task_type = TASK_INC_ARCH) AND task_id != s_current_task; IF s_pending_interrupt IS NOT NULL THEN trace1('EXECUTE_BACKUP_ARCH: Avoiding TASK_INC_ARCH'); RAISE E_RETRY_ERROR; END IF; -- -- l_delete := (p_task_rec.param_num2 = 1); dbms_ra_storage.backupArch(p_task_rec.db_key, p_task_rec.param, TRUE, l_delete); END execute_backup_arch; -- -- -- -- -- -- PROCEDURE execute_inc_arch (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS l_delete BOOLEAN; BEGIN trace1('EXECUTE_INC_ARCH: Performing backup of incomplete arch'); tracex('EXECUTE_INC_ARCH: DB: ' || p_task_rec.db_key || ' db_id: ' || p_task_rec.param_num1 || ' filename: ' || p_task_rec.param); wait_for_repair (NULL, p_task_rec.db_key); -- -- -- SELECT MIN(task_id) INTO s_pending_interrupt FROM task WHERE db_key = p_task_rec.db_key AND param = p_task_rec.param AND task_type IN (TASK_INC_ARCH, TASK_BACKUP_ARCH) AND state = STATE_RUNNING AND task_id != s_current_task; IF s_pending_interrupt IS NOT NULL THEN trace1('EXECUTE_INC_ARCH: Avoiding other backup task'); RAISE E_RETRY_ERROR; END IF; -- -- l_delete := (p_task_rec.param_num2 = 1); dbms_ra_storage.backupArch(p_task_rec.db_key, p_task_rec.param, FALSE, l_delete); END execute_inc_arch; -- -- -- PROCEDURE execute_index_backup (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS l_resource_wait_count NUMBER; l_max_vb_key NUMBER; l_max_vb_key2 NUMBER; l_processed BOOLEAN; l_flags NUMBER; l_bpkey NUMBER := NULL; l_count NUMBER; l_df_key NUMBER; l_size NUMBER; l_complete BOOLEAN; l_ftype NUMBER; l_dbid NUMBER; new_task_rec task%ROWTYPE; l_sameendian BINARY_INTEGER; l_repcnt NUMBER; l_vcbp NUMBER; BEGIN trace1('EXECUTE_INDEX_BACKUP: Performing Backup Task ' || s_current_task); tracex('EXECUTE_INDEX_BACKUP: DB: ' || p_task_rec.db_key || ' bpkey: ' || p_task_rec.param_num1 || ' update: ' || p_task_rec.param_num2 || 'polling key: ' || p_task_rec.param_num3 || ' polling filename: ' || p_task_rec.param); -- -- -- wait_for_repair (NULL, p_task_rec.db_key); -- -- -- -- -- IF bittst(p_task_rec.flags, TASKS_OUT_OF_ORDER) THEN SELECT MAX(vb_key)INTO l_max_vb_key FROM vbdf WHERE db_key = p_task_rec.db_key; END IF; -- -- -- BEGIN -- -- -- -- -- s_polled_input := bittst(p_task_rec.flags, TASKS_POLLED_INPUT); DBMS_RA_POOL.PROCESS_BACKUP_PIECE(p_task_rec.db_key, p_task_rec.param_num1, NVL(p_task_rec.param_num2, 0), l_processed); s_polled_input := FALSE; EXCEPTION WHEN OTHERS THEN save_error; -- -- IF s_polled_input THEN s_polled_input := FALSE; sys.kbrsi_icd.rsIsComplete(fname => p_task_rec.param, filesize => l_size, complete => l_complete, ftype => l_ftype, same_endian => l_sameendian, dbid => l_dbid); IF NOT l_complete THEN trace1('EXECUTE_INDEX_BACKUP: disappearing file ' || p_task_rec.param); ROLLBACK; UPDATE polling_history SET fail_time = SYSTIMESTAMP, status = POLLING_HISTORY_PROCESSING WHERE fname = p_task_rec.param; COMMIT; DBMS_RA_SCHEDULER.LOG_ERROR ( p_errno => DBMS_RA_SCHEDULER.E_MISSING_POLL_FILE_NUM, p_param1 => p_task_rec.param, p_component => 'INDEX_BACKUP', p_severity => DBMS_RA_SCHEDULER.SEVERITY_WARNING, p_db_key => p_task_rec.db_key); clear_error; sys.kbrsi_icd.rsClearErr; RETURN; ELSE RAISE; END IF; ELSE RAISE; END IF; END; IF l_processed THEN -- -- -- IF NOT bittst(p_task_rec.flags, TASKS_DELETE_INPUT) AND s_aggressive_delete > 0 THEN FOR x IN (SELECT handle, pieceinc FROM sbt_catalog WHERE bp_key = p_task_rec.param_num1 AND ftype = 'F' AND db_key = p_task_rec.db_key) LOOP -- new_task_rec.task_type := DBMS_RA_SCHEDULER.TASK_DEFERRED_DELETE; new_task_rec.flags := 0; new_task_rec.db_key := p_task_rec.db_key; new_task_rec.param_char1 := x.handle; new_task_rec.param_num1 := DBMS_RA_INT.KBRSCHKTYPE_FILE; new_task_rec.param_num2 := p_task_rec.param_num1; new_task_rec.param_char2 := x.pieceinc; trace1 ('EXECUTE_INDEX_BACKUP: Defer task queued ' || x.handle); -- -- DBMS_RA_SCHEDULER.NEW_TASK (task_rec => new_task_rec, p_commit => FALSE); COMMIT; END LOOP; END IF; -- -- -- fix_error(p_error_num => E_CORRUPT_BLOCK_NUM, p_db_key => p_task_rec.db_key); -- -- -- -- -- -- -- -- -- SELECT COUNT(*) INTO l_count FROM error_log WHERE error_num = E_INCR_LOST_NUM AND db_key = p_task_rec.db_key; IF l_count > 0 THEN -- -- -- SELECT MAX(v1.df_key) INTO l_df_key FROM vbdf v1, df WHERE db_key = p_task_rec.db_key AND v1.df_key = df.df_key AND df.drop_scn IS NULL AND NOT EXISTS (SELECT 1 FROM vbdf v2 WHERE v1.db_key = v2.db_key AND v1.df_key = v2.df_key AND v2.state = DBMS_RA_POOL.VBDF_COMPLETE); trace1('EXECUTE_INDEX_BACKUP: Missing pool for df ' || print(l_df_key)); IF l_df_key IS NULL THEN fix_error (p_error_num => E_INCR_LOST_NUM, p_db_key => p_task_rec.db_key); COMMIT; END IF; END IF; END IF; -- -- -- -- -- IF NOT l_processed AND p_task_rec.param IS NOT NULL AND NVL(p_task_rec.param_num2, 0) = 0 /* not populating pool */ THEN trace1('EXECUTE_INDEX_BACKUP - Polled backup being copied'); -- l_bpkey := p_task_rec.param_num1; IF NOT DBMS_RA_INT.READ_LOCK(DBMS_RA_INT.KEY_BP, l_bpkey) THEN trace1('EXECUTE_INDEX_BACKUP - Polled backup no longer exists'); RETURN; END IF; BEGIN DBMS_RA_STORAGE.COPY_PIECE(p_task_rec.param, p_task_rec.db_key); EXCEPTION WHEN OTHERS THEN save_error; DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_BP, l_bpkey); RAISE; END; DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_BP, l_bpkey); END IF; trace1('EXECUTE_INDEX_BACKUP - BACKUP TASK FINISHED'); -- -- IF l_processed AND p_task_rec.param IS NOT NULL THEN -- -- -- SELECT count(*) INTO l_repcnt FROM odb o, rep_server rs WHERE o.prot_key = rs.prot_key AND o.db_key = p_task_rec.db_key AND rs.status = 'A'; IF l_repcnt > 0 THEN SELECT MAX(vcbp_key) INTO l_vcbp FROM vbdf WHERE db_key = p_task_rec.db_key AND srcbp_key = p_task_rec.param_num1; trace1 ('EXECUTE_INDEX_BACKUP: Creating replication tasks for origbp=' || p_task_rec.param_num1 || ', newbp=' || l_vcbp); IF l_vcbp IS NOT NULL THEN -- -- -- replicate_one_bp (p_db_key => p_task_rec.db_key, p_bp_key => l_vcbp); trace1('EXECUTE_INDEX_BACKUP - Replication queued'); END IF; END IF; END IF; IF bittst(p_task_rec.flags, TASKS_DELETE_INPUT) THEN -- -- -- -- -- -- -- -- sys.kbrsi_icd.rsDeleteFile(p_task_rec.param); -- -- -- DBMS_RA_STORAGE.FREE_BACKUP_PIECE( p_dbkey => p_task_rec.db_key, p_piecename => p_task_rec.param, p_ftype => DBMS_RA_INT.KBRSCHKTYPE_FILE); -- -- -- COMMIT; UPDATE polling_history SET status = POLLING_HISTORY_REMOVED WHERE poll_key = p_task_rec.param_num3 AND status = POLLING_HISTORY_COMPLETED AND fname = p_task_rec.param; COMMIT; END IF; -- -- -- release_ordering_wait(p_task_rec.db_key); EXCEPTION WHEN dbms_ra_int.incremental_no_fit THEN save_error; -- -- -- trace1 ('EXECUTE_INDEX_BACKUP: Out of order backup piece: ' || p_task_rec.db_key || ' ' || p_task_rec.param_num1); -- -- -- -- -- -- -- -- -- -- -- -- IF s_cached_storage THEN DBMS_RA_STORAGE.FREE_TASK_STORAGE; END IF; SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); -- -- -- SELECT MAX(vb_key)INTO l_max_vb_key2 FROM vbdf WHERE db_key = p_task_rec.db_key; trace1 ('EXECUTE_INDEX_BACKUP: new vb_key=' || print(l_max_vb_key2) || '; old vb_key=' || print(l_max_vb_key) || '; flags =' || print(p_task_rec.flags)); -- -- -- -- IF bittst(p_task_rec.flags, TASKS_OUT_OF_ORDER) AND (NVL(l_max_vb_key,0) = NVL(l_max_vb_key2,0)) THEN UPDATE task SET state = STATE_ORDERING_WAIT, ba_session_id = NULL WHERE (task_id = s_current_task) RETURNING BITAND(flags,TASKS_BLOCKING_TASK) INTO l_flags; ELSE -- -- -- -- -- -- UPDATE task SET state = STATE_EXECUTABLE, ba_session_id = NULL, flags = flags - BITAND(flags, TASKS_OUT_OF_ORDER) + TASKS_OUT_OF_ORDER WHERE (task_id = s_current_task) RETURNING BITAND(flags,TASKS_BLOCKING_TASK) INTO l_flags; END IF; -- -- -- IF l_flags <> 0 THEN UPDATE task SET pending_interrupt = NULL, state = (CASE state WHEN STATE_RUNNING THEN STATE_RUNNING WHEN STATE_CANCEL THEN STATE_CANCEL WHEN STATE_CANCELING THEN STATE_CANCELING ELSE STATE_EXECUTABLE END), ba_session_id = NULL WHERE pending_interrupt = s_current_task; END IF; -- -- -- -- UPDATE sessions SET current_task = NULL, current_task_type = NULL WHERE ba_session_id = s_ba_session_id; -- -- -- p_task_rec := NULL; COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0); clear_error; WHEN E_RETRY_ERROR THEN -- Expected interruption save_error; RAISE; WHEN E_RETRY_RESERVE THEN -- Expected interruption save_error; RAISE; WHEN OTHERS THEN save_error; trace1 ('EXECUTE_INDEX_BACKUP: Unloved backup piece: db ' || p_task_rec.db_key || ', backupset key ' || p_task_rec.param_num1); trace1 ('EXECUTE_INDEX_BACKUP: Error returned is ' || SQLERRM); RAISE; -- More info recorded in scheduler exception handler END execute_index_backup; -- -- -- PROCEDURE execute_newdfkey (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS l_count NUMBER; l_dbkey NUMBER; BEGIN trace1('EXECUTE_NEWDFKEY: Handling a new datafile ' || s_current_task); tracex('EXECUTE_NEWDFKEY: dfkey: ' || p_task_rec.param_num1 || ' dbinc_key: ' || p_task_rec.param_num2 || ' ;pdbinc_key: ' || p_task_rec.param_num3); -- SELECT MAX(db_key) INTO l_dbkey FROM dbinc WHERE dbinc_key = p_task_rec.param_num2; -- SELECT COUNT(*) INTO l_count FROM task WHERE state = STATE_ORDERING_WAIT AND db_key = l_dbkey; IF l_count = 0 THEN RETURN; END IF; -- SELECT COUNT(*) INTO l_count FROM df WHERE df_key = p_task_rec.param_num1 AND dbinc_key = p_task_rec.param_num2 AND pdbinc_key = p_task_rec.param_num3; IF l_count = 0 THEN -- IF sysdate - (1/24) > p_task_rec.schedule_time THEN RETURN; -- We give up ELSE RAISE E_RETRY_ERROR; -- Try again later END IF; END IF; -- release_ordering_wait(l_dbkey); END execute_newdfkey; -- -- -- -- PROCEDURE release_ordering_wait (p_dbkey IN NUMBER) IS l_rcount NUMBER := 0; BEGIN trace1('release_ordering_wait ' || p_dbkey); -- -- -- -- -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); UPDATE task SET state = STATE_EXECUTABLE WHERE (state = STATE_ORDERING_WAIT) AND (db_key = p_dbkey); l_rcount := SQL%ROWCOUNT; COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0); -- -- -- IF l_rcount > 0 THEN SYS.KBRSI_ICD.RSRUNSCHED; END IF; EXCEPTION WHEN OTHERS THEN save_error; SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0); RAISE; END release_ordering_wait; -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE release_restore_wait (p_instance NUMBER DEFAULT NULL) IS l_rcount NUMBER := 0; BEGIN -- -- -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); UPDATE task SET state = STATE_EXECUTABLE WHERE task_id = (SELECT MIN(task_id) FROM task WHERE state = STATE_RESTORE_WAIT AND execute_inst_id = NVL(p_instance, s_instance)); l_rcount := SQL%ROWCOUNT; COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0); trace1 ('RELEASE_RESTORE_WAIT: Tasks released=' || l_rcount); -- -- -- IF l_rcount > 0 THEN SYS.KBRSI_ICD.RSRUNSCHED; END IF; EXCEPTION WHEN OTHERS THEN save_error; SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0); RAISE; END release_restore_wait; -- -- -- -- -- -- -- PROCEDURE execute_quiesce IS l_dummy_bool BOOLEAN; BEGIN tracex ('EXECUTE_QUIESCE'); l_dummy_bool := SYS.KBRSI_ICD.RSQUIESCECHECK (wait=>TRUE); SYS.KBRSI_ICD.RSQUIESCEUNLOCK; END execute_quiesce; -- -- -- -- -- -- -- PROCEDURE execute_spawn_sbt(p_task_rec IN OUT NOCOPY task%ROWTYPE) IS BEGIN tracex ('EXECUTE_SPAWN_SBT : Performing spawn sbt ' || s_current_task || ' lib_key=' || p_task_rec.param_num1 || ';purge=' || p_task_rec.param_num2); IF (p_task_rec.param_num2 = 1) THEN -- forpurge? spawn_purge_sbt_job(p_libkey => p_task_rec.param_num1); ELSE spawn_sbt_job(p_libkey => p_task_rec.param_num1); END IF; END execute_spawn_sbt; -- -- -- PROCEDURE execute_restore (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS l_skip BOOLEAN := FALSE; BEGIN tracex ('EXECUTE_RESTORE: Performing Restore task ' || s_current_task || '; sessionid=' || p_task_rec.param_char1); tracex ('EXECUTE_RESTORE: ' || 'handle=' || p_task_rec.param_char2); tracex ('EXECUTE_RESTORE: ' || 'reqid=' || p_task_rec.param_num1 || '; bpkey=' || p_task_rec.param_num2); IF (get_savepoint IS NOT NULL) THEN trace1('EXECUTE_RESTORE: Cannot restart this task'); l_skip := TRUE; END IF; IF (p_task_rec.com_time + (1/24/60/60 * s_servlet_wait_seconds)) < sysdate THEN trace1('EXECUTE_RESTORE: Servlet com_time is too old'); l_skip := TRUE; END IF; -- -- -- IF NOT l_skip THEN sys.kbrsi_icd.restoreVbTask(reqid => p_task_rec.param_num1, bpkey => p_task_rec.param_num2); END IF; -- release_restore_wait; EXCEPTION WHEN E_NO_MORE_SGA THEN save_error; RAISE; WHEN dbms_ra_int.bad_block_metadata THEN save_error; SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(dbms_ra_scheduler.e_bad_restore_num, p_task_rec.param_num2); WHEN OTHERS THEN save_error; release_restore_wait; RAISE; END execute_restore; /* dbms_ra_scheduler.execute_restore */ -- -- -- PROCEDURE execute_poll (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS l_poll_flags NUMBER; l_delete_input BOOLEAN; l_task_flags NUMBER; l_polling_directory storage_dests.dest%TYPE; l_polling_name poll.poll_name%TYPE; l_omf_namespace VARCHAR2(1) := NULL; -- CURSOR file_cursor IS SELECT fname_krbmsft FROM sys.rai_js_search_file WHERE (fname_krbmsft NOT IN (SELECT fname FROM polling_history ph WHERE (poll_key = p_task_rec.param_num1) AND (ph.status NOT IN (POLLING_HISTORY_PROCESSING, POLLING_HISTORY_REMOVED)))); l_fname VARCHAR2(513); l_ftype NUMBER; l_dbid NUMBER; l_size NUMBER; l_old_size NUMBER; l_complete BOOLEAN; l_backuppiece_id NUMBER; l_db_key NUMBER; l_delete_this_file BOOLEAN; l_newfname VARCHAR2(513); task_rec task%ROWTYPE; l_count NUMBER; l_odb_sameendian NUMBER; l_piece_sameendian NUMBER; l_outfname VARCHAR2(1024); l_pstatus VARCHAR2(1); BEGIN tracex ('EXECUTE_POLL: Performing Poll task ' || s_current_task || '; poll_key=' || p_task_rec.param_num1); -- -- -- -- -- -- -- -- -- SELECT poll.poll_name, poll.poll_flags, sd.dest INTO l_polling_name, l_poll_flags, l_polling_directory FROM poll, sl, storage_dests sd WHERE poll.sl_key = sl.sl_key AND poll.poll_key = p_task_rec.param_num1 AND poll.sl_key = sd.sl_key; l_delete_input := bittst(l_poll_flags, POLL_FLAGS_DELETE_INPUT); trace1 ('EXECUTE_POLL: Delete_input =' || print(l_delete_input) || '; directory=' || l_polling_directory || '; flags=' || l_poll_flags); -- -- -- -- IF bittst(l_poll_flags, POLL_FLAGS_UNDO_DBID_ERROR) THEN UPDATE polling_history SET fail_time = SYSTIMESTAMP, status = POLLING_HISTORY_PROCESSING WHERE (poll_key = p_task_rec.param_num1) AND (status = POLLING_HISTORY_BAD_DBID); trace1 ('EXECUTE_POLL: Reprocessing ' || SQL%ROWCOUNT || ' bad dbid files'); COMMIT; END IF; -- -- -- IF bittst(l_poll_flags,POLL_FLAGS_UNDO_TIMEOUT_ERROR) THEN UPDATE polling_history SET fail_time = SYSTIMESTAMP, status = POLLING_HISTORY_PROCESSING WHERE (poll_key = p_task_rec.param_num1) AND (status = POLLING_HISTORY_TIMED_OUT); trace1 ('EXECUTE_POLL: Reprocessing ' || SQL%ROWCOUNT || ' timed out files'); COMMIT; END IF; -- -- -- l_poll_flags := BITAND(l_poll_flags, POLL_FLAGS_UNDO_DBID_ERROR + POLL_FLAGS_UNDO_TIMEOUT_ERROR); IF l_poll_flags <> 0 THEN l_poll_flags := bitclr(l_poll_flags, POLL_FLAGS_UNDO_DBID_ERROR+POLL_FLAGS_UNDO_TIMEOUT_ERROR); UPDATE poll SET poll_flags = poll_flags - BITAND (poll_flags, l_poll_flags) WHERE poll.poll_key = p_task_rec.param_num1; COMMIT; END IF; -- -- -- -- UPDATE polling_history SET fail_time = NULL, status = POLLING_HISTORY_TIMED_OUT WHERE (poll_key = p_task_rec.param_num1) AND (status = POLLING_HISTORY_PROCESSING) AND ((SYSTIMESTAMP - fail_time) > s_polling_timeout_interval); trace1 ('EXECUTE_POLL: Timed out ' || SQL%ROWCOUNT || ' files'); COMMIT; -- -- -- sys.dbms_backup_restore.searchFiles(pattern => l_polling_directory, ns => l_omf_namespace, ccf => FALSE, omf => FALSE, ftype => NULL, onlyfnm => TRUE, normfnm => FALSE); trace1 ('EXECUTE_POLL: File list created'); -- -- -- OPEN file_cursor; LOOP -- -- -- -- -- -- -- FETCH file_cursor INTO l_fname; EXIT WHEN file_cursor%NOTFOUND; trace1 ('EXECUTE_POLL: name=' || l_fname); -- -- -- sys.kbrsi_icd.rsIsComplete(fname => l_fname, filesize => l_size, complete => l_complete, ftype => l_ftype, same_endian => l_piece_sameendian, dbid => l_dbid); IF l_complete THEN trace1 ('EXECUTE_POLL: completed=' || print(l_complete) || ',dbid=' || l_dbid || ', ftype ' || l_ftype || ', size ' || l_size || ', same_endian ' || l_piece_sameendian || ', name ' || l_fname); -- IF l_piece_sameendian = 0 THEN -- archivelog xtt SELECT DECODE(odb.same_endian, 'N', 0, 'Y', 1, -1) INTO l_piece_sameendian FROM odb WHERE db_key = (SELECT db_key FROM db WHERE db_id = l_dbid); IF l_piece_sameendian != 0 THEN /* Update db about this */ UPDATE odb SET same_endian='N' WHERE db_key = (SELECT db_key FROM db WHERE db_id = l_dbid); COMMIT; END IF; END IF; ELSE trace1 ('EXECUTE_POLL: Found incomplete ' || l_fname || ' size ' || l_size); END IF; -- -- -- -- SELECT MIN(NVL(fsize,0)) INTO l_old_size FROM polling_history WHERE (poll_key=p_task_rec.param_num1) AND (fname = l_fname); IF l_old_size IS NULL THEN -- -- -- INSERT INTO polling_history (fname, fail_time, fsize, status, poll_key) VALUES (l_fname, SYSTIMESTAMP, l_size, POLLING_HISTORY_PROCESSING, p_task_rec.param_num1); ELSIF (l_old_size < l_size) THEN -- -- -- UPDATE polling_history SET fail_time = SYSTIMESTAMP, fsize = l_size WHERE (poll_key=p_task_rec.param_num1) AND (fname = l_fname); END IF; -- -- -- -- IF (l_complete) THEN BEGIN SELECT db.db_key, DECODE(odb.same_endian, 'N', 0, 'Y', 1, -1) INTO l_db_key, l_odb_sameendian FROM db, odb, prot WHERE db_id = l_dbid AND db.db_key = odb.db_key -- AND odb.db_state IS NULL AND odb.prot_key = prot.prot_key AND prot.poll_key = p_task_rec.param_num1; trace1 ('EXECUTE_POLL: db_key=' || l_db_key || ' sameendian=' || l_odb_sameendian); EXCEPTION WHEN NO_DATA_FOUND THEN save_error; trace1 ('EXECUTE_POLL: Ignoring unknown dbid: ' || l_dbid || ' for polling policy ' || l_polling_name); -- -- -- -- -- UPDATE polling_history SET fail_time = NULL, status = POLLING_HISTORY_BAD_DBID WHERE (poll_key=p_task_rec.param_num1) AND (fname = l_fname); COMMIT; clear_error; CONTINUE; END; ELSE -- -- -- COMMIT; CONTINUE; END IF; -- -- -- -- -- -- -- -- BEGIN SELECT 1 INTO l_count FROM bp WHERE handle = dbms_ra_int.file2handle(l_fname); -- log_error (p_errno => E_DUP_FILE_NUM, p_param1 => l_fname, p_component => 'POLLING', p_severity => SEVERITY_WARNING, p_param_num => p_task_rec.param_num1, p_param_char => l_fname); trace1('EXECUTE_POLL: duplicate file ' || l_fname || ' of type ' || l_ftype); -- UPDATE polling_history SET fail_time = NULL, status = POLLING_HISTORY_COMPLETED WHERE ((poll_key=p_task_rec.param_num1) AND (fname = l_fname)); COMMIT; CONTINUE; EXCEPTION WHEN no_data_found THEN save_error; NULL; /* The expected result */ clear_error; END; -- -- -- -- CASE WHEN (l_ftype IN (FTYPE_ARCHIVELOG,FTYPE_ARCHBACKUP,FTYPE_AUTOBACKUP)) THEN BEGIN IF l_ftype = FTYPE_ARCHIVELOG THEN -- -- -- trace1 ('EXECUTE_POLL: Archivelog'); l_size := l_size + (4 * 32 * 1024); -- max block size 32k ELSE trace1 ('EXECUTE_POLL: Archbackup or Autopbackup'); END IF; -- DBMS_RA_STORAGE.COPY_PIECE(l_fname, l_db_key); l_delete_this_file := l_delete_input; fix_error (p_error_num => E_BACKUP_FAILED, p_db_key => l_db_key); EXCEPTION WHEN E_BACKUP_IO_ERROR_RMAN THEN save_error; -- -- -- log_error (p_errno => E_BAD_FILE_NUM, p_param1 => l_fname, p_component => 'POLLING', p_severity => SEVERITY_ERROR, p_param_num => p_task_rec.param_num1, p_param_char => l_fname); UPDATE polling_history SET fail_time = NULL, status = POLLING_HISTORY_ERROR WHERE ((poll_key=p_task_rec.param_num1) AND (fname = l_fname)); COMMIT; clear_error; CONTINUE; WHEN E_NO_MORE_STORAGE OR E_PIECE_TOO_BIG THEN save_error; log_error (p_errno => E_BACKUP_FAILED, p_component => 'POLLING', p_severity => SEVERITY_ERROR, p_db_key => l_db_key, p_param1 => DBMS_RA_INT.DBKEY2NAME(l_db_key)); UPDATE polling_history SET fail_time = NULL, status = POLLING_HISTORY_ERROR WHERE ((poll_key=p_task_rec.param_num1) AND (fname = l_fname)); COMMIT; clear_error; CONTINUE; END; WHEN (l_ftype IN (FTYPE_BACKUP,FTYPE_INCBACKUP)) THEN BEGIN IF l_odb_sameendian = 0 OR l_piece_sameendian = 0 THEN -- -- -- IF l_odb_sameendian != 0 AND l_piece_sameendian = 0 THEN /* Update db about this */ UPDATE odb SET same_endian='N' WHERE db_key = l_db_key; COMMIT; END IF; -- -- trace1 ('EXECUTE_POLL: same endian from db : ' || l_odb_sameendian || ' same endian inferred from piece ' || l_piece_sameendian); BEGIN DBMS_RA_STORAGE.COPY_PIECE(l_fname, l_db_key, COPY_BA_POLL /*KRBYX_ORS_POLL*/); fix_error (p_error_num => E_BACKUP_FAILED, p_db_key => l_db_key); EXCEPTION WHEN E_NO_MORE_STORAGE OR E_PIECE_TOO_BIG THEN save_error; log_error (p_errno => E_BACKUP_FAILED, p_component => 'POLLING', p_severity => SEVERITY_ERROR, p_db_key => l_db_key, p_param1 => DBMS_RA_INT.DBKEY2NAME(l_db_key)); UPDATE polling_history SET fail_time = NULL, status = POLLING_HISTORY_ERROR WHERE ((poll_key=p_task_rec.param_num1) AND (fname = l_fname)); COMMIT; clear_error; CONTINUE; END; l_outfname := dbms_ra_int.file2handle(l_fname); -- -- -- -- -- SELECT MIN(bp.bp_key) into l_backuppiece_id FROM bp,bdf WHERE handle = l_outfname AND bdf.bs_key = bp.bs_key; l_delete_this_file := l_delete_input; task_rec.param := NULL; l_task_flags := 0; ELSE -- -- -- -- -- sys.kbrsi_icd.rsInspectBackupPiece( handle => l_fname, vbkey => null, bpsize => l_size, chktype => DBMS_RA_INT.KBRSCHKTYPE_DISK, fno => null, lib_key => null,/* local disk */ ct_key => null, bpkey => l_backuppiece_id, template_key => null); l_delete_this_file := FALSE; l_task_flags := TASKS_POLLED_INPUT; IF l_delete_input THEN l_task_flags := TASKS_POLLED_INPUT+TASKS_DELETE_INPUT; END IF; task_rec.param := l_fname; END IF; trace1 ('EXECUTE_POLL: db_key: ' || l_db_key || ', bpkey: ' || l_backuppiece_id); -- -- -- -- IF (l_backuppiece_id IS NOT NULL) THEN task_rec.task_type := TASK_INDEX_BACKUP; task_rec.flags := l_task_flags; task_rec.db_key := l_db_key; task_rec.param_num1 := l_backuppiece_id; task_rec.param_num3 := p_task_rec.param_num1; -- poll_key new_task (task_rec, FALSE); -- nocommit END IF; EXCEPTION WHEN OTHERS THEN save_error; trace1 ('EXECUTE_POLL: Processing datafile backup returned: ' || SQLERRM); UPDATE polling_history SET fail_time = NULL, status = POLLING_HISTORY_ERROR WHERE ((poll_key=p_task_rec.param_num1) AND (fname = l_fname)); COMMIT; -- sys.kbrsi_icd.rsClearErr; clear_error; CONTINUE; END; ELSE trace1('EXECUTE_POLL: Unknown file ' || l_fname || ' of type ' || l_ftype); UPDATE polling_history SET fail_time = NULL, status = POLLING_HISTORY_BAD_FTYPE WHERE ((poll_key=p_task_rec.param_num1) AND (fname = l_fname)); COMMIT; CONTINUE; END CASE; -- -- -- l_pstatus := POLLING_HISTORY_COMPLETED; IF l_delete_this_file THEN sys.kbrsi_icd.rsDeleteFile(l_fname); l_pstatus := POLLING_HISTORY_REMOVED; END IF; -- -- -- UPDATE polling_history SET fail_time = NULL, status = l_pstatus WHERE ((poll_key=p_task_rec.param_num1) AND (fname = l_fname)); COMMIT; END LOOP; CLOSE file_cursor; -- -- -- -- SELECT COUNT(*) INTO l_count FROM poll WHERE (poll_key = p_task_rec.param_num1) AND (poll_last_prune + s_polling_deleted_files_check < SYSTIMESTAMP); trace1('EXECUTE_POLL: prune check is ' || l_count); IF l_count > 0 THEN DELETE FROM polling_history WHERE (poll_key = p_task_rec.param_num1) AND NOT EXISTS (SELECT 1 FROM sys.rai_js_search_file sf WHERE sf.fname_krbmsft = fname); trace1('EXECUTE_POLL: prune check deleted ' || SQL%ROWCOUNT || ' row(s)'); -- -- -- FOR x IN (SELECT param_char, error_num FROM error_log WHERE error_num IN (E_BAD_FILE_NUM, E_DUP_FILE_NUM) AND param_num = p_task_rec.param_num1 AND NOT EXISTS (SELECT 1 FROM polling_history WHERE poll_key = p_task_rec.param_num1 AND fname=param_char)) LOOP fix_error (p_error_num => x.error_num, p_param_num => p_task_rec.param_num1, p_param_char => x.param_char); END LOOP; UPDATE poll SET poll_last_prune = SYSTIMESTAMP WHERE (poll_key = p_task_rec.param_num1); COMMIT; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; -- -- -- -- -- trace1('EXECUTE_POLL: detected NO_DATA_FOUND'); enqueue_verify_timer_task; clear_error; RETURN; END execute_poll; -- -- -- -- PROCEDURE execute_deferred_delete(p_task_rec IN OUT NOCOPY task%ROWTYPE) IS BEGIN tracex ('EXECUTE_DEFERRED_DELETE: Performing execute_deferred_delete ' || 'dbkey ' || p_task_rec.db_key || ', bpkey ' || p_task_rec.param_num2 || ', handle ' || p_task_rec.param_char1 || ', fincarn ' || p_task_rec.param_char2 || ', ftype ' || p_task_rec.param_num1); -- -- IF p_task_rec.param_num2 IS NOT NULL THEN DBMS_RA_STORAGE.SWAP_BACKUP_PIECE(p_task_rec.param_num2); END IF; DBMS_RA_STORAGE.FREE_BACKUP_PIECE( p_dbkey => p_task_rec.db_key, p_piecename => p_task_rec.param_char1, p_ftype => p_task_rec.param_num1, p_fincarn => p_task_rec.param_char2, p_can_defer => FALSE); END execute_deferred_delete; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE execute_gcopy_compute (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS l_ontape NUMBER; l_used NUMBER; l_count NUMBER; l_task NUMBER; l_not_taped_state VARCHAR2(1); BEGIN tracex ('EXECUTE_GCOPY_COMPUTE: Compute odb.not_taped value for ' || 'dbkey ' || p_task_rec.db_key); -- -- -- SELECT MIN(task_id) INTO l_task FROM task WHERE task_type = TASK_GCOPY_COMPUTE AND state = STATE_RUNNING AND db_key = p_task_rec.db_key AND task_id <> s_current_task; IF l_task IS NOT NULL THEN s_pending_interrupt := l_task; RAISE e_retry_error; END IF; -- -- -- SELECT used_space, not_taped_state INTO l_used, l_not_taped_state FROM odb WHERE db_key = p_task_rec.db_key; -- IF l_not_taped_state IN ('V', 'N') OR l_not_taped_state IS NULL THEN RETURN; END IF; l_not_taped_state := 'V'; -- -- -- -- -- l_ontape := dbms_ra_pool.copied_to_tape(p_task_rec.db_key); -- IF l_ontape = 0 THEN SELECT COUNT(*) INTO l_count FROM bp WHERE db_key = p_task_rec.db_key AND lib_key IS NOT NULL AND ROWNUM = 1; IF l_count = 0 THEN l_not_taped_state := 'N'; END IF; END IF; -- -- -- -- -- UPDATE odb SET not_taped = l_used - l_ontape, not_taped_state = (CASE WHEN not_taped_state IN ('C', 'B') AND base_reserved_space < (l_used - l_ontape) THEN 'B' ELSE l_not_taped_state END) WHERE db_key = p_task_rec.db_key RETURNING not_taped_state INTO l_not_taped_state; COMMIT; trace1 ('EXECUTE_GCOPY_COMPUTE: not_taped_state ' || l_not_taped_state || 'dbkey ' || p_task_rec.db_key); -- -- -- IF l_not_taped_state <> 'B' THEN fix_error (p_error_num => E_GCOPY_SUSPENDED_NUM, p_db_key => p_task_rec.db_key); END IF; END execute_gcopy_compute; -- -- -- -- -- -- PROCEDURE execute_purge (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS l_immediate BOOLEAN := (s_current_task_type = TASK_PURGE_IMMEDIATE); l_neededspace NUMBER; BEGIN tracex ('EXECUTE_PURGE: Performing Purge task ' || s_current_task || '; sl_key=' || p_task_rec.sl_key || '; db_key=' || p_task_rec.db_key || '; needed space ' || p_task_rec.param_num1); wait_for_repair (p_task_rec.sl_key, NULL); -- -- -- IF l_immediate THEN l_neededspace := NVL(p_task_rec.param_num1, s_alloc_increment); ELSE SELECT sl_freespace_goal INTO l_neededspace FROM sl WHERE sl_key = p_task_rec.sl_key; END IF; -- -- -- DBMS_RA_STORAGE.PURGE_STORAGE_LOCATION (p_task_rec.sl_key, p_task_rec.db_key, l_neededspace, l_immediate); END execute_purge; -- -- -- PROCEDURE execute_rm_incomplete_files (sbtonly IN BOOLEAN DEFAULT FALSE) IS -- -- -- CURSOR sbt_file_cursor IS SELECT db_key, sc.handle, sc.pieceinc FROM sbt_catalog sc JOIN odb o USING (db_key) WHERE sc.ftype = 'F' -- filter file chunks AND sc.bp_key IS NULL -- filter un-inspected pieces AND ((sc.last_entry IS NULL AND ((sc.cretime+s_expire_files_interval) < SYSTIMESTAMP)) OR ((sc.completed = 'N') AND ((sc.last_entry+s_expire_files_interval) < SYSTIMESTAMP)) OR (sc.endupload = 'D') OR (o.db_state = DB_STATE_IN_DELETE)); l_db_key NUMBER; l_handle VARCHAR2(512); l_pieceinc VARCHAR2(32); l_filename VARCHAR2(512); l_retry_seen BOOLEAN := FALSE; BEGIN trace1 ('EXECUTE_RM_INCOMPLETE_FILES: Performing RM_Incomplete_Files ' || s_current_task); -- -- -- trace1 ('EXECUTE_RM_INCOMPLETE_FILES: SBT File Cleanup'); OPEN sbt_file_cursor; LOOP FETCH sbt_file_cursor INTO l_db_key, l_handle, l_pieceinc; EXIT WHEN sbt_file_cursor%NOTFOUND; trace1 ('EXECUTE_RM_INCOMPLETE_FILES: db=' || l_db_key || '; handle=' || l_handle || '; pieceinc ' || l_pieceinc); -- -- -- BEGIN DBMS_RA_STORAGE.FREE_BACKUP_PIECE(p_dbkey => l_db_key, p_piecename => l_handle, p_fincarn => l_pieceinc); EXCEPTION WHEN E_RETRY_ERROR THEN save_error; -- -- -- trace1('EXECUTE_RM_COMPLETE_FILES: ' || l_handle || ' is locked.'); l_retry_seen := TRUE; clear_error; CONTINUE; END; END LOOP; CLOSE sbt_file_cursor; -- -- -- IF l_retry_seen THEN RAISE E_RETRY_ERROR; END IF; trace1 ('EXECUTE_RM_INCOMPLETE_FILES: Done'); END execute_rm_incomplete_files; -- -- -- -- -- -- -- PROCEDURE execute_purge_df (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS BEGIN tracex ('EXECUTE_PURGE_DF on' || ' db_key=' || p_task_rec.db_key || '; sl_key=' || p_task_rec.sl_key || '; vb_key=' || p_task_rec.param_num2 || '; df_key=' || p_task_rec.param_num1 || '; type=' || p_task_rec.param_num3); -- -- -- -- -- s_purging_active := TRUE; s_no_wait_on_allocate := TRUE; -- -- -- -- IF NVL(p_task_rec.purge_reserve,0) > 0 THEN DBMS_RA_STORAGE.FINISH_BLOCK_POOL_CHUNK (p_task_rec.db_key); END IF; -- -- -- dbms_ra_pool.purgeDF(p_task_rec.param_num3, -- Type of purge p_task_rec.param_num1, -- df_key p_task_rec.param_num2); -- vb_key EXCEPTION WHEN OTHERS THEN save_error; trace1('EXECUTE_PURGE_DF: Exiting on error: ' || SQLERRM); -- -- -- DBMS_RA_STORAGE.FINISH_BLOCK_POOL_CHUNK (p_task_rec.db_key); RAISE; END execute_purge_df; -- -- -- -- -- -- PROCEDURE execute_purge_dup_df (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS BEGIN tracex ('EXECUTE_PURGE_DUP_DF on' || ' db_key=' || p_task_rec.db_key || '; vb_key=' || p_task_rec.param_num2 || '; df_key=' || p_task_rec.param_num1 || '; keylock='|| p_task_rec.param_num3); -- -- -- -- -- -- s_purging_active := FALSE; s_no_wait_on_allocate := TRUE; -- -- -- dbms_ra_pool.purgeDupDF(p_task_rec.param_num1, -- df_key p_task_rec.param_num2, -- vb_key p_task_rec.param_num3); -- key lock END execute_purge_dup_df; -- -- -- -- -- -- PROCEDURE execute_plan_df (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS l_count NUMBER; l_libstat sbt_lib_desc.status%TYPE; l_libkey NUMBER; BEGIN tracex ('EXECUTE_PLAN_DF on' || ' db_key=' || p_task_rec.db_key || '; sl_key=' || p_task_rec.sl_key || '; vb_key=' || p_task_rec.param_num2 || '; df_key=' || p_task_rec.param_num1 || '; type=' || p_task_rec.param_num3 || '; bs_key=' || p_task_rec.param); -- -- -- -- IF s_current_task_type = TASK_PLAN_SBT THEN SELECT MAX(l.status), MAX(l.lib_key) INTO l_libstat, l_libkey FROM sbt_task s, task t, sbt_lib_desc l WHERE s.task_id = t.sbt_task_id AND s.lib_key = l.lib_key AND s.bs_key = TO_NUMBER(p_task_rec.param) AND t.task_type = TASK_BACKUP_SBT AND t.state NOT IN (STATE_RUNNING, STATE_CANCEL, STATE_CANCELING); IF l_libstat IS NULL THEN -- No task left, bail quietly. trace1 ('EXECUTE_PLAN_DF can find no SBT for ' || '; bs_key=' || p_task_rec.param); RETURN; END IF; -- IF l_libstat <> 'R' THEN -- s_pending_interrupt := LIBRARY_PSEUDO_TASK; trace1 ('EXECUTE_PLAN_DF has stalled library'); RAISE e_retry_error; END IF; END IF; -- -- -- dbms_ra_pool.planDF(p_task_rec.param_num3, -- Type of plan p_task_rec.param_num1, -- df_key p_task_rec.param_num2); -- vb_key END execute_plan_df; -- -- -- -- PROCEDURE execute_storage_histogram IS -- CURSOR sl_cursor IS SELECT sl_key FROM sl WHERE sl_hist_usage IS NOT NULL AND sl_space <> 0; l_sl_key NUMBER; l_sl_hist_usage NUMBER; l_sl_curr_hist_slot NUMBER; l_sl_space NUMBER; l_next_slot NUMBER; l_wrap_slot NUMBER; l_freespace_goal NUMBER; l_count NUMBER; new_task_rec task%ROWTYPE; BEGIN tracex ('EXECUTE_STORAGE_HISTOGRAM'); -- -- -- OPEN sl_cursor; LOOP FETCH sl_cursor INTO l_sl_key; EXIT WHEN sl_cursor%NOTFOUND; BEGIN -- -- -- DBMS_RA_STORAGE.LOCK_SL (l_sl_key); -- -- -- SELECT sl_hist_usage, NVL(sl_curr_hist_slot,-1), sl_space INTO l_sl_hist_usage, l_sl_curr_hist_slot, l_sl_space FROM sl WHERE sl_key = l_sl_key; -- -- -- l_next_slot := MOD(l_sl_curr_hist_slot+1, s_histogram_cycle_slots); MERGE INTO storage_histogram USING dual ON (sl_key = l_sl_key AND slot = l_next_slot) WHEN NOT MATCHED THEN INSERT (sl_key, slot, usage) VALUES (l_sl_key, l_next_slot, l_sl_hist_usage) WHEN MATCHED THEN UPDATE SET usage = l_sl_hist_usage; -- -- -- -- -- -- -- -- IF (l_next_slot+1) - s_histogram_window_slots < 0 THEN l_wrap_slot := s_histogram_cycle_slots - (s_histogram_window_slots - (l_next_slot+1)); ELSE l_wrap_slot := s_histogram_cycle_slots; END IF; -- -- -- -- SELECT PERCENTILE_CONT(s_histogram_goal_percentile) WITHIN GROUP (ORDER BY usage ASC), COUNT(*) INTO l_freespace_goal, l_count FROM storage_histogram WHERE sl_key = l_sl_key AND ((slot BETWEEN l_next_slot+1 - s_histogram_window_slots AND l_next_slot) OR (slot BETWEEN l_wrap_slot AND (s_histogram_cycle_slots-1))); trace1('EXECUTE_STORAGE_HISTOGRAM slot count=' || l_count || '; histogram_goal=' || l_freespace_goal/(1024*124*1024)); -- -- -- IF l_count < 10 THEN l_freespace_goal := s_initial_freespace_ratio * l_sl_space; END IF; -- -- -- -- -- l_freespace_goal := GREATEST(l_freespace_goal, s_min_freespace_ratio * l_sl_space, (s_alloc_increment*3)); trace1 ('EXECUTE_STORAGE_HISTOGRAM for sl ' || l_sl_key || ', slot ' || l_next_slot || ', usage ' || l_sl_hist_usage || ', newgoal ' || l_freespace_goal); -- -- -- UPDATE sl SET sl_hist_usage = 0, sl_curr_hist_slot = l_next_slot, sl_freespace_goal = l_freespace_goal WHERE sl_key = l_sl_key; COMMIT; DBMS_RA_STORAGE.UNLOCK_SL (l_sl_key); EXCEPTION WHEN OTHERS THEN save_error; DBMS_RA_STORAGE.UNLOCK_SL (l_sl_key); trace1 ('EXECUTE_STORAGE_HISTOGRAM error: ' || SQLERRM); RAISE; END; -- -- -- SELECT COUNT(*) INTO l_count FROM odb JOIN prot USING(prot_key) JOIN rai_oldest_backup rob USING(db_key) WHERE odb.sl_key = l_sl_key -- AND odb.db_state IS NULL AND odb.move_phase IS NULL AND odb.used_space > 0 AND NVL(odb.purge_scn,0) <> DBMS_RA_POOL.BIGNUM AND prot.prot_max_retention_window IS NOT NULL -- AND (odb.bs2_timestamp IS NULL OR ((SYSTIMESTAMP - odb.bs2_timestamp) > odb.recovery_window_goal)) -- AND (rob.oldest_backup < (SYSTIMESTAMP - prot.prot_max_retention_window)) AND ROWNUM = 1; IF l_count > 0 THEN -- SELECT COUNT(*) INTO l_count FROM task WHERE (task_type = TASK_PURGE) AND (sl_key = l_sl_key) AND ROWNUM = 1; IF l_count = 0 THEN -- new_task_rec.task_type := TASK_PURGE; new_task_rec.sl_key := l_sl_key; new_task_rec.db_key := NULL; new_task_rec.flags := 0; new_task (new_task_rec); END IF; END IF; END LOOP; CLOSE sl_cursor; EXCEPTION WHEN OTHERS THEN save_error; CLOSE sl_cursor; RAISE; END execute_storage_histogram; -- -- -- PROCEDURE execute_db_stats_refresh IS new_task_rec task%ROWTYPE; BEGIN DELETE odb_stats_cache; INSERT /*+ OPT_PARAM('optimizer_dynamic_sampling' 0) OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false') OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none') OPT_PARAM('_optimizer_use_feedback' 'false') */ INTO odb_stats_cache ( db_key , footprint , recovery_window_start , db_size , deduplication_factor , minimum_recovery_start , bdf1count , unprotected , nzdl_active , last_refresh ) WITH db_size (db_key, space) AS -- -- ( SELECT /*+ QB_NAME(db_size) NO_PUSH_PRED NO_MERGE LEADING(dbinc) USE_HASH(df) FULL(dbinc) FULL(df) */ dbinc.db_key , SUM(df.block_size * df.blocks) FROM dbinc , df WHERE df.drop_scn IS NULL AND dbinc.dbinc_key = df.dbinc_key AND dbinc.dbinc_status = 'CURRENT' GROUP BY dbinc.db_key ) , all_backups (db_key, space) AS -- -- ( SELECT --+ QB_NAME(all_backups) NO_PUSH_PRED NO_MERGE db_key , SUM(fsize) FROM ( -- SELECT /*+ QB_NAME(dfiles) LEADING(bdf) USE_HASH(bp) NO_SWAP_JOIN_INPUTS(bp) */ db_key , SUM(datafile_blocks * block_size) KEEP (DENSE_RANK LAST ORDER BY bdf_key) fsize FROM bp , bdf WHERE bp.ba_access = 'L' AND bdf.bs_key = bp.bs_key GROUP BY db_key , ckp_scn , create_scn , dbinc_key , file# , NVL2(bp.vb_key, -1, -2) UNION ALL SELECT /*+ QB_NAME(ofiles) LEADING(bp bsf bcf brl) USE_HASH(bsf) USE_HASH(bcf) USE_HASH(brl) NO_SWAP_JOIN_INPUTS(bsf) NO_SWAP_JOIN_INPUTS(bcf) NO_SWAP_JOIN_INPUTS(brl) */ bp.db_key , SUM(NVL(bsf.bytes, 0)) -- spfiles + SUM(NVL(bcf.block_size * bcf.blocks, 0)) -- control files + SUM(NVL(brl.block_size * brl.blocks, 0)) -- archive logs FROM bp LEFT OUTER JOIN bsf USING (bs_key) LEFT OUTER JOIN bcf USING (bs_key) LEFT OUTER JOIN brl USING (bs_key) WHERE bp.ba_access = 'L' GROUP BY bp.db_key ) GROUP BY db_key ) , dedup (db_key, deduplication_factor) AS -- -- -- ( SELECT /*+ QB_NAME(dedup) LEADING(odb sc ab) NO_PUSH_PRED NO_MERGE USE_HASH(ab) USE_HASH(sc) */ db_key , ab.space / GREATEST(odb.total_allocation - NVL(sc.incs, 0), 1) FROM odb JOIN all_backups ab USING (db_key) LEFT OUTER JOIN ( SELECT /*+ QB_NAME(sc) NO_MERGE NO_PUSH_PRED FULL(sc) */ db_key , SUM(filesize) incs FROM sbt_catalog sc WHERE filesize IS NOT NULL AND completed <> 'Y' GROUP BY db_key ) sc USING (db_key) ) , dg_raw (db_key, datum_days, value_interval) as -- ( SELECT /*+ LEADING(ds db odb) */ db_key , SYSDATE - TO_DATE(MAX(datum_time), 'MM/DD/YYYY HH24:MI:SS') , TO_DSINTERVAL(MAX(value)) FROM odb JOIN db USING (db_key) LEFT OUTER JOIN v$dataguard_stats ds ON (db_id = ds.source_dbid AND ds.name = 'transport lag') -- GROUP BY db_key ) , dg_stats (db_key, nzdl_active, unprotected) as -- ( SELECT db_key , CASE WHEN datum_days < config.value THEN 'YES' ELSE 'NO' END , extract(day from value_interval) + extract(hour from value_interval) / 24 + extract(minute from value_interval) / (24*60) + extract(second from value_interval) / (24*60*60) FROM dg_raw JOIN config ON (name = '_nzdl_is_alive_days') ) SELECT /*+ QB_NAME(osc) LEADING(odb irws db_size dedup) USE_HASH(irws) USE_HASH(db_size) USE_HASH(dedup) NO_PUSH_PRED(irws.dbfootprint) NO_PUSH_PRED(irws.keepsize) NO_PUSH_PRED(irws.dbrectimes) NO_PUSH_PRED(irws.backupf1count) */ db_key , irws.footprint , irws.recwindowstart , db_size.space , dedup.deduplication_factor , irws.minrectime , irws.bdf1count , dgs.unprotected , dgs.nzdl_active , SYSTIMESTAMP FROM odb LEFT OUTER JOIN rai_recovery_window_space irws USING (db_key) LEFT OUTER JOIN db_size USING (db_key) LEFT OUTER JOIN dedup USING (db_key) LEFT OUTER JOIN dg_stats dgs USING (db_key) -- WHERE odb.db_state IS NULL ; trace1('EXECUTE_DB_STATS_REFRESH: Dbs computed = ' || SQL%ROWCOUNT); COMMIT; -- -- -- -- -- -- -- -- -- -- -- FOR rrrt IN (SELECT db_key FROM odb WHERE NOT EXISTS (SELECT 1 FROM task WHERE task_type = TASK_RESTORE_RANGE_REFRESH AND odb.db_key = task.db_key)) LOOP new_task_rec.task_type := TASK_RESTORE_RANGE_REFRESH; new_task_rec.flags := 0; new_task_rec.db_key := rrrt.db_key; new_task (task_rec => new_task_rec, p_commit => FALSE); END LOOP; COMMIT; SYS.KBRSI_ICD.RSRUNSCHED; END execute_db_stats_refresh; -- -- -- PROCEDURE execute_restore_range_refresh (p_task_rec IN task%ROWTYPE) IS l_db_key NUMBER := p_task_rec.db_key; l_currinc NUMBER; l_db_id NUMBER; l_dbid NUMBER; l_reset_scn NUMBER; l_reset_time DATE; l_db_name dbinc.db_name%TYPE; l_db_slkey NUMBER; l_highscn NUMBER; l_count NUMBER; l_current_days NUMBER; l_current_range INTERVAL DAY(9) TO SECOND; l_goal_range INTERVAL DAY(9) TO SECOND; l_high_time DATE; l_low_time DATE; l_unprot_win INTERVAL DAY(9) TO SECOND; l_timestamp DATE; l_temp NUMBER; l_unprotected NUMBER; l_create_time TIMESTAMP WITH TIME ZONE; l_create_date DATE; BEGIN tracex('EXECUTE_RESTORE_RANGE_REFRESH: db_key: ' || l_db_key); -- -- -- SELECT db.db_id, reset_scn, reset_time, dbinc.db_name INTO l_db_id, l_reset_scn, l_reset_time, l_db_name FROM db, dbinc WHERE db.curr_dbinc_key = dbinc.dbinc_key AND dbinc.db_key = db.db_key AND db.db_key = l_db_key; trace1('EXECUTE_RESTORE_RANGE_REFRESH: DBNAME: ' || l_db_name || '; db_id: ' || l_db_id || '; reset_scn: ' || l_reset_scn || '; reset_time: ' || l_reset_time); -- -- -- setDatabase(l_db_key, l_dbid, l_currinc, l_db_slkey); -- SELECT MAX(high_scn) INTO l_highscn FROM rai_restore_range; SELECT MAX(high_scn) INTO l_highscn FROM rai_disk_restore_range; SELECT MAX(high_scn) INTO l_highscn FROM rai_sbt_restore_range; trace1 ('EXECUTE_RESTORE_RANGE_REFRESH: restore range refreshed for db ' || l_db_name); -- -- -- SELECT create_time, prot_recovery_window_goal, prot_unprotected_window INTO l_create_time, l_goal_range, l_unprot_win FROM odb JOIN prot USING( prot_key ) WHERE db_key = p_task_rec.db_key; -- -- -- -- -- BEGIN SELECT high_time, low_time INTO l_high_time, l_low_time FROM (SELECT high_time, low_time FROM ra_restore_range WHERE db_key = p_task_rec.db_key ORDER BY high_time DESC) WHERE ROWNUM = 1; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; l_high_time := NULL; l_low_time := NULL; clear_error; END; -- -- -- -- -- -- -- -- SELECT unprotected INTO l_unprotected FROM odb_stats_cache WHERE db_key = l_db_key; -- -- -- SELECT CAST(( SYSTIMESTAMP AT TIME ZONE TO_CHAR(db_timezone)) AS DATE), CAST(( l_create_time AT TIME ZONE TO_CHAR(db_timezone)) AS DATE) INTO l_timestamp, l_create_date FROM node WHERE db_key = p_task_rec.db_key AND database_role = 'PRIMARY' AND ROWNUM = 1; -- -- -- -- -- -- IF (NUMTODSINTERVAL(l_timestamp - l_create_date,'day') > l_goal_range) THEN l_temp := l_timestamp - l_low_time ; IF (l_low_time IS NULL OR NUMTODSINTERVAL(l_temp,'day') < l_goal_range) THEN log_error( p_errno => E_REC_WINDOW_LOW_NUM, p_param1 => DBMS_RA_INT.DBKEY2NAME(l_db_key), p_component => 'RESTORE_RANGE_REFRESH', p_severity => SEVERITY_WARNING, p_db_key => l_db_key); ELSE fix_error( p_error_num => E_REC_WINDOW_LOW_NUM, p_db_key => l_db_key); COMMIT; END IF; END IF; -- -- -- -- -- -- -- IF (NUMTODSINTERVAL(l_timestamp - l_create_date,'day') > l_unprot_win) THEN IF l_high_time IS NULL OR NUMTODSINTERVAL(l_unprotected,'day') > l_unprot_win THEN trace1('EXECUTE_RESTORE_RANGE_REFRESH: ' || 'Current unprotected window is ' || NUMTODSINTERVAL(l_unprotected,'day') || '; Unprotected_window goal is ' || l_unprot_win); log_error( p_errno => E_UNPROTECTED_WINDOW_LOST_NUM, p_param1 => DBMS_RA_INT.DBKEY2NAME(l_db_key), p_component => 'RESTORE_RANGE_REFRESH', p_severity => SEVERITY_WARNING, p_db_key => l_db_key); ELSE fix_error( p_error_num => E_UNPROTECTED_WINDOW_LOST_NUM, p_db_key => l_db_key); COMMIT; END IF; ELSE -- -- -- fix_error( p_error_num => E_UNPROTECTED_WINDOW_LOST_NUM, p_db_key => l_db_key); COMMIT; END IF; -- -- -- SELECT COUNT(*) INTO l_count FROM error_log WHERE error_num = E_REC_WINDOW_LOST_NUM AND db_key = p_task_rec.db_key AND ROWNUM=1; IF l_count > 0 THEN -- -- -- -- -- BEGIN SELECT high_time - low_time INTO l_current_days FROM (SELECT high_time, low_time FROM ra_disk_restore_range WHERE db_key = p_task_rec.db_key ORDER BY high_time DESC) WHERE ROWNUM=1; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; l_current_days := NULL; clear_error; END; l_current_range := NUMTODSINTERVAL(l_current_days, 'day'); trace1('EXECUTE_RESTORE_RANGE_REFRESH: ' || 'Current Range is ' || l_current_range || '; Goal is ' || l_goal_range); IF l_current_range >= l_goal_range THEN fix_error (p_error_num => E_REC_WINDOW_LOST_NUM, p_db_key => p_task_rec.db_key); COMMIT; END IF; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; trace1 ('EXECUTE_RESTORE_RANGE_REFRESH: Database not found'); clear_error; WHEN OTHERS THEN save_error; trace1 ('EXECUTE_RESTORE_RANGE_REFRESH: Some error occurred'); RAISE; END execute_restore_range_refresh; -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE execute_optimize_chunks (p_task_rec IN task%ROWTYPE) IS CURSOR optdf_cursor IS SELECT df_key, MAX(f.blocks)*MAX(f.block_size) filesize FROM df f, dbinc i WHERE i.dbinc_key = f.dbinc_key AND i.db_key = p_task_rec.db_key GROUP BY f.df_key; l_db_key NUMBER := p_task_rec.db_key; l_last_optimize TIMESTAMP WITH TIME ZONE; l_sl_min_alloc NUMBER; new_task_rec task%ROWTYPE; BEGIN tracex ('EXECUTE_OPTIMIZE_CHUNKS for db_key=' || l_db_key); -- -- -- SELECT last_optimize, sl_min_alloc INTO l_last_optimize, l_sl_min_alloc FROM odb WHERE db_key = l_db_key; -- -- -- -- -- wait_for_repair (NULL, l_db_key); FOR t IN optdf_cursor LOOP -- -- new_task_rec.task_type := TASK_OPTIMIZE_CHUNKS_DF; new_task_rec.flags := 0; new_task_rec.db_key := l_db_key; new_task_rec.param_num1 := t.df_key; new_task_rec.param_num2 := GREATEST (t.filesize, l_sl_min_alloc); new_task(new_task_rec, p_commit => FALSE); END LOOP; -- -- -- -- -- -- UPDATE odb SET last_optimize = SYSTIMESTAMP, prev_optimize = l_last_optimize WHERE db_key = l_db_key; COMMIT; SYS.KBRSI_ICD.RSRUNSCHED; END execute_optimize_chunks; -- -- -- PROCEDURE execute_optimize_chunks_df (p_task_rec IN task%ROWTYPE) IS l_space_so_far NUMBER; l_db_reserved_space NUMBER; l_count NUMBER; l_taskid NUMBER; l_hash NUMBER; l_task_rec task%ROWTYPE; BEGIN tracex ('EXECUTE_OPTIMIZE_CHUNKS_DF ' || '; db_key=' || p_task_rec.db_key || '; df_key=' || p_task_rec.param_num1 || '; bpsize(MB)=' || p_task_rec.param_num2/1024/1024 || '; alloc(MB)=' || print(p_task_rec.param_num3/1024/1024)); wait_for_repair (NULL, p_task_rec.db_key); avoid_db (p_task_rec.db_key); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- IF p_task_rec.param_num3 IS NULL THEN -- -- -- -- -- BEGIN SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); SELECT NVL(SUM(param_num3),0), MIN(task_id) INTO l_space_so_far, s_pending_interrupt FROM task WHERE task_type = TASK_OPTIMIZE_CHUNKS_DF AND task_id <> p_task_rec.task_id AND db_key = p_task_rec.db_key AND param_num3 IS NOT NULL; SELECT base_reserved_space INTO l_db_reserved_space FROM odb WHERE db_key = p_task_rec.db_key; trace1('EXECUTE_OPTIMIZE_CHUNKS_DF' || ': Usage(MB)=' || l_space_so_far/1024/1024 || '; Space(MB)=' || l_db_reserved_space/1024/1024 || '; Wait on task id ' || print(s_pending_interrupt)); IF ((l_space_so_far + p_task_rec.param_num2) > (s_optimize_space_limit * l_db_reserved_space)) AND (s_pending_interrupt IS NOT NULL) THEN -- -- -- -- -- -- UPDATE task SET pending_interrupt = s_pending_interrupt, state = STATE_TASK_WAIT WHERE task_type = TASK_OPTIMIZE_CHUNKS_DF AND db_key = p_task_rec.db_key AND state = STATE_EXECUTABLE AND task_id <> s_pending_interrupt AND param_num3 IS NULL AND param_num2 >= p_task_rec.param_num2; l_count := SQL%ROWCOUNT; trace1('EXECUTE_OPTIMIZE_CHUNKS_DF: Put to sleep ' || l_count || ' other tasks'); -- -- -- IF l_count > 0 THEN UPDATE task SET flags = NVL(flags,0) - BITAND(NVL(flags,0), TASKS_BLOCKING_TASK) + TASKS_BLOCKING_TASK WHERE task_id = s_pending_interrupt; END IF; COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK; -- -- -- RAISE E_PENDING_INTERRUPT; END IF; EXCEPTION WHEN OTHERS THEN save_error; SYS.KBRSI_ICD.RSSCHEDUNLOCK; RAISE; END; -- -- -- UPDATE task SET param_num3=NVL(param_num2,0) WHERE task_id = s_current_task; COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK; s_pending_interrupt := NULL; trace1('EXECUTE_OPTIMIZE_CHUNKS_DF: Enough space to optimize'); END IF; -- -- -- -- s_no_wait_on_allocate := TRUE; -- -- -- dbms_ra_pool.optimizeDF(p_task_rec.db_key, p_task_rec.param_num1); -- -- -- -- SELECT ORA_HASH(p_task_rec.param_num1, 1023, 0) + 1 INTO l_hash FROM dual; SELECT MIN(task_id) INTO l_taskid FROM task WHERE task_type = TASK_REBUILD_INDEX AND param_num1 = l_hash; IF l_taskid IS NULL THEN trace1('EXECUTE_OPTIMIZE_CHUNKS_DF: Rebuild blocks partition ' || l_hash); l_task_rec.task_type := TASK_REBUILD_INDEX; l_task_rec.param_num1 := l_hash; l_task_rec.flags := 0; new_task(l_task_rec); END IF; -- -- -- -- -- -- -- -- END execute_optimize_chunks_df; -- -- -- -- PROCEDURE execute_rebuild_index (p_task_rec IN task%ROWTYPE) IS l_partition_name user_tab_partitions.partition_name%TYPE; l_tablespace_name user_tab_partitions.tablespace_name%TYPE; l_table_name user_tables.table_name%TYPE := 'BLOCKS'; l_index_name user_indexes.index_name%TYPE := 'BLOCKS_U'; l_ddl VARCHAR2(2048); BEGIN tracex ('EXECUTE_REBUILD_INDEX on' || ' df_hash=' || p_task_rec.param_num1); -- get_lock(dbms_ra_scheduler.LOCK_PURGE, p_task_rec.param_num1); -- -- -- -- -- SELECT MAX(task_id) INTO s_pending_interrupt FROM task t, bp p, bdf d, df f WHERE t.param_num1 = p.bp_key AND p.bs_key = d.bs_key AND d.dbinc_key = f.dbinc_key AND d.create_scn = f.create_scn AND d.file# = f.file# AND state IN (STATE_RUNNING, STATE_EXECUTABLE) AND task_type IN (TASK_INDEX_BACKUP, TASK_CHECK_FILES) AND (p_task_rec.param_num1 = ORA_HASH(f.df_key, 1023, 0) + 1 OR (task_type = TASK_CHECK_FILES AND state = STATE_RUNNING)); IF s_pending_interrupt IS NOT NULL THEN RAISE e_retry_error; END IF; /* See if the size of the partition exceeds the threshold */ BEGIN SELECT --+ LEADING(t st i si) i.partition_name, i.tablespace_name INTO l_partition_name, l_tablespace_name FROM user_tab_partitions t, user_segments st, user_ind_partitions i, user_segments si WHERE t.table_name = l_table_name AND st.segment_name = t.table_name AND t.partition_name = st.partition_name AND t.partition_position = p_task_rec.param_num1 AND i.index_name = l_index_name AND si.segment_name = i.index_name AND i.partition_name = si.partition_name AND i.partition_position = t.partition_position AND si.bytes > s_part_index_size AND si.blocks / st.blocks > (s_part_threshold + 1); EXCEPTION WHEN NO_DATA_FOUND THEN -- save_error; unlock(dbms_ra_scheduler.LOCK_PURGE, p_task_rec.param_num1); trace1 ('EXECUTE_REBUILD_INDEX nothing to shrink for' || ' df_hash=' || p_task_rec.param_num1); clear_error; RETURN; END; -- IF s_part_index_style = 1 THEN l_ddl := 'ALTER INDEX ' || dbms_assert.enquote_name(l_index_name) || ' REBUILD PARTITION ' || dbms_assert.enquote_name(l_partition_name) || CASE WHEN s_part_parallel_degree IS NOT NULL THEN ' PARALLEL ' || CASE WHEN s_part_parallel_degree = 0 THEN '(DEGREE DEFAULT)' ELSE TO_CHAR(s_part_parallel_degree) END END || ' TABLESPACE ' || dbms_assert.enquote_name(l_tablespace_name) || ' ONLINE'; ELSE l_ddl := 'ALTER INDEX ' || dbms_assert.enquote_name(l_index_name) || ' MODIFY PARTITION ' || dbms_assert.enquote_name(l_partition_name) || ' SHRINK SPACE'; END IF; -- trace1('EXECUTE_REBUILD_INDEX: ' || l_ddl); -- EXECUTE IMMEDIATE l_ddl; unlock(dbms_ra_scheduler.LOCK_PURGE, p_task_rec.param_num1); EXCEPTION WHEN OTHERS THEN save_error; unlock(dbms_ra_scheduler.LOCK_PURGE, p_task_rec.param_num1); RAISE; END execute_rebuild_index; -- -- -- -- -- -- -- PROCEDURE execute_validate_db (p_task_rec IN task%ROWTYPE) IS l_db_key NUMBER := p_task_rec.db_key; l_execute_time TIMESTAMP WITH TIME ZONE := p_task_rec.execute_time; BEGIN tracex ('EXECUTE_VALIDATE_DB: db_key=' || l_db_key); wait_for_repair (NULL, l_db_key); avoid_db (l_db_key); -- -- -- dbms_ra_pool.validateDB(l_db_key); -- -- -- fix_error (p_error_num => E_BAD_VALIDATE_NUM, p_db_key => l_db_key, p_timestamp => l_execute_time); -- -- -- -- FOR x IN (SELECT param_num FROM error_log e WHERE error_num = E_CORRUPT_BLOCK_NUM AND db_key = p_task_rec.db_key AND NOT EXISTS (SELECT 1 FROM bp WHERE bp_key=e.param_num)) LOOP fix_error (p_error_num => E_CORRUPT_BLOCK_NUM, p_db_key => p_task_rec.db_key, p_param_num => x.param_num); END LOOP; -- -- -- UPDATE odb SET last_validate = SYSTIMESTAMP WHERE db_key = p_task_rec.db_key; COMMIT; END execute_validate_db; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION delete_db_disruptive_running RETURN NUMBER IS l_taskid NUMBER := NULL; BEGIN SELECT MAX(task_id) INTO l_taskid FROM task t WHERE t.state = STATE_RUNNING -- AND (t.task_type IN (TASK_RECONCILE, TASK_CHECK_FILES) OR (t.task_type = TASK_MOVE_ALL_DB AND EXISTS (SELECT move_phase FROM odb WHERE odb.db_key = t.db_key AND odb.move_phase IS NOT NULL))); RETURN l_taskid; END delete_db_disruptive_running; -- -- -- -- -- -- FUNCTION delete_db_task_is_benign (p_task_type IN NUMBER) RETURN NUMBER IS BEGIN IF p_task_type IN (TASK_DELETE_DB, TASK_PURGE, TASK_PURGE_IMMEDIATE, TASK_PURGE_DF, TASK_PURGE_DF_NOW, TASK_DEFERRED_DELETE, TASK_RM_INCOMPLETE_FILES, TASK_RECONCILE) THEN RETURN DB_TASK_IS_BENIGN; ELSE RETURN DB_TASK_IS_NOT_BENIGN; END IF; END; -- -- -- -- PROCEDURE delete_db_remove_remaining (p_dbkey IN NUMBER) IS BEGIN -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); -- -- UPDATE task SET state = STATE_CANCEL WHERE db_key = p_dbkey AND state NOT IN (STATE_RUNNING, STATE_CANCELING) AND delete_db_task_is_benign(task_type) = DB_TASK_IS_NOT_BENIGN; trace1('DELETE_DB_REMOVE_REMAINING: Canceled ' || SQL%ROWCOUNT || ' task(s).'); COMMIT; -- SYS.KBRSI_ICD.RSSCHEDUNLOCK; EXCEPTION WHEN OTHERS THEN save_error; -- SYS.KBRSI_ICD.RSSCHEDUNLOCK; RAISE; END delete_db_remove_remaining; -- -- -- -- -- -- -- -- -- -- -- PROCEDURE execute_delete_db (p_task_rec IN task%ROWTYPE) IS DELETE_DB_SVPNT_START CONSTANT NUMBER := 0; DELETE_DB_SVPNT_WAIT_DISRUPTIV CONSTANT NUMBER := 1; DELETE_DB_SVPNT_SUBMIT_DELETES CONSTANT NUMBER := 2; DELETE_DB_SVPNT_WAIT_DELETES CONSTANT NUMBER := 3; DELETE_DB_SVPNT_FREEBP CONSTANT NUMBER := 4; DELETE_DB_SVPNT_DELFILES CONSTANT NUMBER := 5; DELETE_DB_SVPNT_METADATA CONSTANT NUMBER := 6; DELETE_DB_SVPNT_UNREGISTER CONSTANT NUMBER := 7; l_db_key NUMBER := p_task_rec.db_key; l_db_id NUMBER := p_task_rec.param_num1; l_db_unique_name VARCHAR2(1000) := p_task_rec.param_char1; l_savepoint NUMBER := NVL(p_task_rec.savepoint, DELETE_DB_SVPNT_START); l_isdown NUMBER; l_chunkcnt NUMBER; l_task_rec task%ROWTYPE; l_task_id NUMBER; l_task_type NUMBER; l_sl_key NUMBER; l_tcount NUMBER; l_count NUMBER; l_more_data BOOLEAN := FALSE; l_krsperr BINARY_INTEGER; l_lockstate BOOLEAN; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- CURSOR fils IS SELECT db_key, df_key, MAX(vb_key) vb_key FROM vbdf WHERE vbdf.db_key = l_db_key GROUP BY db_key, df_key; -- CURSOR bss IS SELECT 1 ord, p.sl_key, p.db_key, bp_key, handle, NULL pieceinc, NULL ftype FROM bp b, odb p WHERE b.db_key = l_db_key AND b.db_key = p.db_key AND purged = 'N' AND lib_key IS NULL /* Only backups on disk */ AND b.ba_access = 'L' UNION ALL SELECT 2 ord, p.sl_key, p.db_key, bp_key, handle, pieceinc, DECODE(ftype, 'F', DBMS_RA_INT.KBRSCHKTYPE_FILE, 'V', DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL, 'T', DBMS_RA_INT.KBRSCHKTYPE_TAPE, NULL) ftype FROM sbt_catalog c, odb p WHERE c.db_key = l_db_key AND c.db_key = p.db_key AND c.completed = 'N' AND c.filesize IS NOT NULL /* Only local storage backups */ ORDER BY ord, db_key, bp_key DESC; -- CURSOR rep_server_cursor IS SELECT s.rep_server_name, p.prot_name FROM rep_server r, prot p, odb o, server s WHERE p.prot_key = r.prot_key AND s.server_key = r.server_key AND o.prot_key = p.prot_key AND o.db_key = l_db_key; BEGIN -- -- -- -- -- IF l_savepoint = DELETE_DB_SVPNT_START THEN trace1 ('EXECUTE_DELETE_DB: ' || print(l_db_unique_name) || '; db_id=' || print(l_db_id) || '; db_key=' || print(l_db_key) || '; savepoint=' || print(l_savepoint)); -- -- -- -- -- -- -- -- -- -- -- -- -- stop_scheduler_jobs (STOP_JOBS_DB, FALSE, l_db_key); trace1 ('delete_db: ' || print(l_db_unique_name) || ': stop_scheduler_jobs() complete'); -- -- -- -- delete_db_remove_remaining(l_db_key); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- trace1 ('delete_db: ' || print(l_db_unique_name) || ': database quiet complete'); check_for_interrupt (DELETE_DB_SVPNT_WAIT_DISRUPTIV); l_savepoint := DELETE_DB_SVPNT_WAIT_DISRUPTIV; END IF; -- DELETE_DB_SVPNT_START -- -- -- -- -- -- -- -- -- -- delete_db_remove_remaining(l_db_key); -- -- -- -- -- IF l_savepoint = DELETE_DB_SVPNT_WAIT_DISRUPTIV THEN trace1 ('delete_db: ' || print(l_db_unique_name) || ': at savepoint ' || print(l_savepoint) || ': wait disruptive'); -- s_pending_interrupt := delete_db_disruptive_running; -- IF s_pending_interrupt IS NOT NULL THEN IF s_tracing_on THEN trace1 ('delete_db: ' || print(l_db_unique_name) || ': waiting on disruptive task id ' || s_pending_interrupt); END IF; RAISE E_RETRY_ERROR; END IF; trace1 ('delete_db: ' || print(l_db_unique_name) || ': wait disruptive complete'); check_for_interrupt (DELETE_DB_SVPNT_SUBMIT_DELETES); l_savepoint := DELETE_DB_SVPNT_SUBMIT_DELETES; END IF; -- -- -- -- -- IF l_savepoint = DELETE_DB_SVPNT_SUBMIT_DELETES THEN trace1 ('delete_db: ' || print(l_db_unique_name) || ': at savepoint ' || print(l_savepoint) || ': submit tasks'); -- -- -- -- -- -- FOR d IN (SELECT c.handle, c.pieceinc, DECODE(ftype, 'F', DBMS_RA_INT.KBRSCHKTYPE_FILE, 'V', DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL, 'T', DBMS_RA_INT.KBRSCHKTYPE_TAPE, 'D', DBMS_RA_INT.KBRSCHKTYPE_DISK, NULL) ftype FROM sbt_catalog c LEFT OUTER JOIN bp USING (bp_key) WHERE c.db_key = l_db_key AND NVL(bp.status, 'A') = 'A' AND NVL(bp.ba_access, 'L') = 'L' AND bp.lib_key IS NULL /* Only backups on disk */ ORDER BY c.ct_key DESC) LOOP l_task_rec.task_type := task_deferred_delete; l_task_rec.flags := 0; l_task_rec.db_key := l_db_key; l_task_rec.param_char1 := d.handle; l_task_rec.param_char2 := d.pieceinc; l_task_rec.param_num1 := d.ftype; new_task (task_rec => l_task_rec, p_commit => FALSE); trace1 ('delete_db: ' || print(l_db_unique_name) || ': deferred_delete task queued ' || print(d.handle)); END LOOP; -- -- -- -- -- -- -- -- -- l_task_rec.task_type := task_rm_incomplete_files; l_task_rec.flags := 0; l_task_rec.db_key := l_db_key; new_task (task_rec => l_task_rec, p_commit => TRUE); trace1 ('delete_db: ' || print(l_db_unique_name) || ': submit tasks complete'); -- check_for_interrupt (DELETE_DB_SVPNT_WAIT_DELETES); l_savepoint := DELETE_DB_SVPNT_WAIT_DELETES; END IF; -- -- -- -- -- IF l_savepoint = DELETE_DB_SVPNT_WAIT_DELETES THEN trace1 ('delete_db: ' || print(l_db_unique_name) || ': at savepoint ' || print(l_savepoint) || ': submitted tasks wait'); -- SELECT MAX(task_id) INTO s_pending_interrupt FROM task WHERE db_key = l_db_key AND task_type <> TASK_DELETE_DB; IF s_pending_interrupt IS NOT NULL THEN IF s_tracing_on THEN BEGIN SELECT task_type INTO l_task_type FROM task WHERE task_id = s_pending_interrupt; trace1 ('delete_db: ' || print(l_db_unique_name) || ': waiting on ' || tasktype2name(l_task_type)); EXCEPTION -- WHEN NO_DATA_FOUND THEN NULL; END; END IF; RAISE E_RETRY_ERROR; END IF; trace1 ('delete_db: ' || print(l_db_unique_name) || ': submitted tasks complete'); check_for_interrupt (DELETE_DB_SVPNT_FREEBP); l_savepoint := DELETE_DB_SVPNT_FREEBP; END IF; -- -- -- -- -- IF l_savepoint = DELETE_DB_SVPNT_FREEBP THEN trace1 ('delete_db: ' || print(l_db_unique_name) || ': at savepoint ' || print(l_savepoint) || ': free_backup_pieces'); -- -- l_more_data := TRUE; WHILE l_more_data LOOP l_more_data := FALSE; FOR b IN bss LOOP l_more_data := TRUE; trace1('delete_db: ' || print(l_db_unique_name) || ': free_backup_piece_opt() deleting ' || print(b.handle)); dbms_ra_storage.free_backup_piece_opt( p_dbkey => b.db_key, p_piecename => b.handle, p_db_slkey => b.sl_key, p_dbid => l_db_id, p_currinc => NULL, /* Not in use with noplans/notasks */ p_bpkey => b.bp_key, p_ftype => b.ftype, p_fincarn => b.pieceinc, p_libkey => NULL, /* Only local disk backups deleted */ p_noplans => TRUE, p_notasks => TRUE); END LOOP; END LOOP; COMMIT; trace1 ('delete_db: ' || print(l_db_unique_name) || ': free_backup_pieces complete'); check_for_interrupt (DELETE_DB_SVPNT_DELFILES); l_savepoint := DELETE_DB_SVPNT_DELFILES; END IF; -- -- -- -- -- IF l_savepoint = DELETE_DB_SVPNT_DELFILES THEN trace1 ('delete_db: ' || print(l_db_unique_name) || ': at savepoint ' || print(l_savepoint) || ': deleting files'); -- -- -- -- trace1('delete_db: ' || print(l_db_unique_name) || ': deleting files'); l_more_data := TRUE; WHILE l_more_data LOOP l_more_data := FALSE; FOR f IN fils LOOP l_more_data := TRUE; dbms_ra_pool.purgeDF(dbms_ra_pool.KBRSPLBLD_ALLPURGE, f.df_key, f.vb_key); -- dbms_ra_pool.optimizeDF(l_db_key, f.df_key, TRUE); DELETE FROM vbdf WHERE df_key = f.df_key AND NOT EXISTS (SELECT 1 FROM chunks WHERE df_key = f.df_key); IF SQL%ROWCOUNT = 0 THEN trace1('delete_db: ' || print(l_db_unique_name) || ': failed to delete files, df_key ' || f.df_key); sys.dbms_sys_error.raise_system_error(E_INTERNAL_ERROR_NUM, 'delete_db: ' || print(l_db_unique_name) || ': failed to delete files, df_key ' || f.df_key, FALSE); END IF; COMMIT; END LOOP; END LOOP; trace1('delete_db: ' || print(l_db_unique_name) || ': deleting files complete'); -- SELECT count(*) INTO l_chunkcnt FROM chunks, df, dbinc WHERE chunks.df_key = df.df_key AND df.dbinc_key = dbinc.dbinc_key AND dbinc.db_key = l_db_key AND ROWNUM =1; IF (l_chunkcnt > 0) THEN RAISE E_DELETE_DB_CHUNKS; END IF; check_for_interrupt (DELETE_DB_SVPNT_METADATA); l_savepoint := DELETE_DB_SVPNT_METADATA; END IF; -- -- -- -- -- IF l_savepoint = DELETE_DB_SVPNT_METADATA THEN trace1 ('delete_db: ' || print(l_db_unique_name) || ': at savepoint ' || print(l_savepoint) || ': deleting db metadata'); -- -- -- trace1('delete_db: ' || print(l_db_unique_name) || ': plans cleanup'); FOR p IN (SELECT df_key, vb_key, type FROM plans WHERE db_key = l_db_key) LOOP DELETE plans_details WHERE df_key = p.df_key AND vb_key = p.vb_key AND type = p.type; COMMIT; END LOOP; DELETE FROM plans WHERE db_key = l_db_key; COMMIT; trace1('delete_db: ' || print(l_db_unique_name) || ': plans cleanup complete'); -- trace1('delete_db: ' || print(l_db_unique_name) || ': calling rsKRSPDeleteDB()'); l_krsperr := sys.kbrsi_icd.rsKRSPDeleteDB(l_db_id); IF l_krsperr != 0 THEN sys.dbms_sys_error.raise_system_error(E_INTERNAL_ERROR_NUM, 'associated Data Guard metadata delete failed ' || l_krsperr, FALSE); END IF; trace1('delete_db: ' || print(l_db_unique_name) || ': rsKRSPDeleteDB() complete'); -- trace1('delete_db: ' || print(l_db_unique_name) || ': db_key cleanup'); DELETE FROM df_seq WHERE df_key IN (SELECT df.df_key FROM df, dbinc WHERE df.dbinc_key = dbinc.dbinc_key AND dbinc.db_key = l_db_key); trace1('delete_db: ' || print(l_db_unique_name) || ': df_seq cleanup complete'); -- UPDATE db SET storage_prov = 'N' WHERE db_key=l_db_key; -- -- -- -- -- -- -- -- -- -- -- -- -- COMMIT; trace1('delete_db: ' || print(l_db_unique_name) || ': db_key cleanup complete'); trace1('delete_db: ' || print(l_db_unique_name) || ': deleting db metadata complete'); check_for_interrupt (DELETE_DB_SVPNT_UNREGISTER); l_savepoint := DELETE_DB_SVPNT_UNREGISTER; END IF; -- -- -- -- -- IF l_savepoint = DELETE_DB_SVPNT_UNREGISTER THEN trace1 ('delete_db: ' || print(l_db_unique_name) || ': at savepoint ' || print(l_savepoint) || ': dbms_rcvcat.unregisterDatabase()'); -- -- -- -- -- -- -- -- get_lock(LOCK_KEY, LOCK_DELETE_DB_UNREGISTER); -- dbms_rcvcat.unregisterDatabase(l_db_key, l_db_id); unlock(LOCK_KEY, LOCK_DELETE_DB_UNREGISTER); trace1('delete_db: ' || print(l_db_unique_name) || ': dbms_rcvcat.unregisterDatabase() complete'); END IF; trace1('delete_db: ' || print(l_db_unique_name) || ': complete'); EXCEPTION WHEN OTHERS THEN save_error; -- IF l_savepoint = DELETE_DB_SVPNT_UNREGISTER THEN sys.kbrsi_icd.rsKeyUnlock(LOCK_DELETE_DB_UNREGISTER); ROLLBACK; END IF; -- -- RAISE; END execute_delete_db; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE execute_check_files (p_task_rec IN task%ROWTYPE) IS l_sl_key NUMBER := p_task_rec.sl_key; l_savepoint NUMBER := NVL(p_task_rec.savepoint,0); l_repair BOOLEAN := (p_task_rec.param_num1 <> 0); l_execute_time TIMESTAMP WITH TIME ZONE := p_task_rec.execute_time; BEGIN tracex ('EXECUTE_CHECK_FILES: sl_key=' || l_sl_key || '; task_start=' || l_execute_time || '; savepoint=' || print(l_savepoint) || '; repair=' || print(l_repair)); -- avoid_delete_db(); DBMS_RA_STORAGE.CHECK_FILES(l_sl_key, l_execute_time,l_savepoint, l_repair); EXCEPTION WHEN e_consistent_read THEN save_error; -- -- -- SELECT MAX(task_id) INTO s_pending_interrupt FROM task WHERE state = STATE_RUNNING AND task_type = TASK_REBUILD_INDEX; RAISE e_retry_error; END execute_check_files; -- -- -- -- -- PROCEDURE execute_crosscheck_db (p_task_rec IN task%ROWTYPE) IS l_db_key NUMBER := p_task_rec.db_key; l_runcount NUMBER; BEGIN tracex ('EXECUTE_CROSSCHECK_DB: db_key=' || l_db_key); -- -- -- wait_for_repair (NULL, l_db_key); avoid_db (l_db_key); IF p_task_rec.param_num2 IS NULL THEN BEGIN SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); -- -- -- -- -- SELECT COUNT(*), MIN(task_id) INTO l_runcount, s_pending_interrupt FROM task WHERE task_type = TASK_CROSSCHECK_DB AND param_num2 IS NOT NULL AND task_id <> p_task_rec.task_id; trace1('EXECUTE_CROSSCHECK' || ': Run count=' || l_runcount || '; Wait on task id ' || print(s_pending_interrupt)); IF l_runcount > s_crosscheck_throttle THEN -- -- -- -- RAISE E_PENDING_INTERRUPT; ELSE -- -- -- -- UPDATE task SET param_num2=1 WHERE task_id = s_current_task; COMMIT; END IF; SYS.KBRSI_ICD.RSSCHEDUNLOCK; EXCEPTION WHEN OTHERS THEN save_error; SYS.KBRSI_ICD.RSSCHEDUNLOCK; RAISE; END; END IF; -- -- -- crosscheck_db(l_db_key); -- -- -- UPDATE odb SET last_crosscheck = SYSTIMESTAMP WHERE db_key = l_db_key; COMMIT; END execute_crosscheck_db; -- -- -- PROCEDURE setDatabase(p_dbkey IN NUMBER, p_dbid OUT NUMBER, p_currinc OUT NUMBER, p_db_slkey OUT NUMBER) IS l_currinc NUMBER; l_dbid NUMBER; l_db_slkey NUMBER; l_dbname VARCHAR2(30); l_rlgscn NUMBER; l_rlgtime DATE; l_dbun VARCHAR2(30); BEGIN -- SELECT db.curr_dbinc_key, db.db_id, reset_scn, reset_time, dbinc.db_name, odb.sl_key INTO l_currinc, l_dbid, l_rlgscn, l_rlgtime, l_dbname, l_db_slkey FROM db, dbinc, odb WHERE db.curr_dbinc_key = dbinc.dbinc_key AND dbinc.db_key = db.db_key AND db.db_key = odb.db_key AND db.db_key = p_dbkey; -- select rtrim(ltrim(value)) into l_dbun from sys.v_$parameter where lower(name)='db_unique_name'; dbms_rcvman.resetAll; dbms_rcvcat.setDatabase(db_name => l_dbname, reset_scn => l_rlgscn, reset_time => l_rlgtime, db_id => l_dbid, db_unique_name => l_dbun, site_aware => TRUE, cf_type => 0, -- this value is overridden -- dummy_instance => FALSE, ors_instance => TRUE); dbms_rcvman.setArchiveFileScopeAttributes(logs_shared => 1); dbms_rcvman.setBackupFileScopeAttributes( disk_backups_shared => 0, tape_backups_shared => 1); p_dbid := l_dbid; p_currinc := l_currinc; p_db_slkey := l_db_slkey; END setDatabase; -- -- -- -- -- -- -- PROCEDURE wait_for_dbfs IS l_filename config.value%TYPE; l_dbfs_time_out number; BEGIN -- -- -- SELECT TO_NUMBER(value)*24*60*60 INTO l_dbfs_time_out FROM config WHERE name = '_dbfs_time_out_days'; trace1('WAIT_FOR_DBFS: wait time is ' || print(l_dbfs_time_out)); -- -- -- FOR i in 1..l_dbfs_time_out LOOP SELECT MIN(value) INTO l_filename FROM config WHERE name = '_waitfordbfs'; IF MOD(i,60) = 1 THEN trace1('WAIT_FOR_DBFS: filename is ' || print(l_filename)); END IF; IF l_filename IS NULL THEN -- -- -- fix_error (p_error_num => E_DBFS_WAIT_FAILURE_NUM, p_param_num => s_instance); COMMIT; RETURN; END IF; IF sys.kbrsi_icd.fileexists(l_filename) = 1 THEN -- -- -- fix_error (p_error_num => E_DBFS_WAIT_FAILURE_NUM, p_param_num => s_instance); COMMIT; RETURN; END IF; -- -- -- dbms_lock.sleep(1); END LOOP; -- -- -- SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_DBFS_WAIT_FAILURE_NUM, s_instance, l_filename); EXCEPTION WHEN E_DBFS_WAIT_FAILURE THEN save_error; write_error (p_component => 'INITIALIZE', p_severity => SEVERITY_ERROR, p_param_num => s_instance); RAISE; END wait_for_dbfs; -- -- -- -- -- -- PROCEDURE crosscheck_db (p_db_key IN NUMBER) IS devtype VARCHAR2(512) := NULL; l_set_count NUMBER; l_set_stamp NUMBER; l_pieceno binary_integer; l_recid NUMBER; l_stamp NUMBER; l_handle VARCHAR2(1024); l_bpkey NUMBER; l_lastlibkey NUMBER := 0; l_thislibkey NUMBER; l_parms VARCHAR2(1028); l_node VARCHAR2(512); file_in_use BOOLEAN := FALSE; rc NUMBER; rc_in_use NUMBER; found BOOLEAN; l_new_status VARCHAR2(1); l_old_status VARCHAR2(1); l_dbinc_key NUMBER; CURSOR bp_cursor(c_db_key IN NUMBER) IS SELECT bp.handle, bs.set_stamp, bs.set_count, bp.bp_key, bp.lib_key, bp.bp_recid, bp.bp_stamp, bp.piece#, bp.status FROM bp, bs, sbt_lib_desc lib WHERE bp.db_key = c_db_key AND bs.bs_key = bp.bs_key AND bp.status != 'D' AND bp.ba_access IN ('T', 'R') AND bp.lib_key = lib.lib_key AND lib.status = 'R' -- filter ready jobs AND bp.lib_key IS NOT NULL ORDER BY bp.lib_key; l_dbid NUMBER; l_currinc NUMBER; l_db_slkey NUMBER; BEGIN trace1 ('CROSSCHECK_DB: Performing auto crosscheck for db_key=' || p_db_key); -- BEGIN SELECT curr_dbinc_key INTO l_dbinc_key FROM db WHERE db_key=p_db_key; EXCEPTION WHEN no_data_found THEN -- Database has been deleted. Just go away. save_error; clear_error; RETURN; END; setDatabase(p_db_key, l_dbid, l_currinc, l_db_slkey); -- -- OPEN bp_cursor(p_db_key); LOOP FETCH bp_cursor INTO l_handle, l_set_stamp, l_set_count, l_bpkey, l_thislibkey, l_recid, l_stamp, l_pieceno, l_old_status; EXIT WHEN bp_cursor%NOTFOUND; trace1 ('CROSSCHECK_DB: handle=' || l_handle || ', set_stamp=' || l_set_stamp || ', set_count=' || l_set_count || ', bp_key=' || l_bpkey || ', libkey=' || l_thislibkey || ', start_status=' || l_old_status); -- -- IF l_thislibkey != l_lastlibkey THEN -- -- IF (devtype IS NOT NULL) THEN sys.dbms_backup_restore.deviceDeallocate; devtype := NULL; END IF; -- -- SELECT lib.parms INTO l_parms FROM sbt_lib_desc lib WHERE lib.lib_key = l_thislibkey; -- devtype := sys.dbms_backup_restore.deviceAllocate( ident => 'RA$SBT', node => l_node, type => 'SBT_TAPE', params => l_parms, dupcnt => 1, allowmts => TRUE, ors_lib_key => l_thislibkey, db_name => NULL, platform_id => 0); l_lastlibkey := l_thislibkey; END IF; -- BEGIN file_in_use := FALSE; found := FALSE; rc_in_use := 0; rc := sys.dbms_backup_restore.validateBackupPiece( recid => l_recid, stamp => l_stamp, handle => l_handle, set_stamp => l_set_stamp, set_count => l_set_count, pieceno => l_pieceno, hdl_isdisk => 0); EXCEPTION WHEN OTHERS THEN save_error; rc := sys.dbms_backup_restore.validate_file_different; sys.kbrsi_icd.rsClearErr; clear_error; END; trace1 ('CROSSCHECK_DB: After validate for bp_key=' || l_bpkey || ', rc=' || rc); rc_in_use := bitand(rc, sys.dbms_backup_restore.validate_in_use); rc := bitand(rc, sys.dbms_backup_restore.validate_file_different); IF rc = 0 AND rc_in_use = 0 THEN found := TRUE; END IF; -- IF found THEN l_new_status := 'A'; ELSE l_new_status := 'X'; END IF; trace1 ('CROSSCHECK_DB: After validate for bp_key=' || l_bpkey || ', modified_rc=' || rc || ', rc_in_use=' || rc_in_use || ', new_status=' || l_new_status || ', old_status=' || l_old_status); -- IF (l_old_status != l_new_status) THEN trace1 ('CROSSCHECK_DB: Changing status of handle=' || l_handle || ', bp_key=' || l_bpkey || ' to ' || l_new_status); dbms_rcvcat.changeBackupPiece( bp_recid => l_recid, bp_stamp => l_stamp, status => l_new_status, set_stamp => l_set_stamp, set_count => l_set_count); END IF; END LOOP; CLOSE bp_cursor; IF (devtype IS NOT NULL) THEN sys.dbms_backup_restore.deviceDeallocate; devtype := NULL; END IF; EXCEPTION WHEN others THEN save_error; -- IF (devtype IS NOT NULL) THEN sys.dbms_backup_restore.deviceDeallocate; END IF; IF (bp_cursor%ISOPEN) THEN CLOSE bp_cursor; END IF; RAISE; END crosscheck_db; -- -- -- -- PROCEDURE execute_insert_fault(p_task_rec IN task%ROWTYPE) IS l_param_num1 NUMBER := NVL(p_task_rec.param_num1,1); E_NO_SYNONYM EXCEPTION; PRAGMA EXCEPTION_INIT (E_NO_SYNONYM, -980); BEGIN trace1('EXECUTE_INSERT_FAULT: Fault is ' || p_task_rec.param); -- $IF $$RSJS_INSERT_FAULT IS NOT NULL $THEN -- CASE p_task_rec.param WHEN 'RESOURCE_ERROR' THEN trace1('EXECUTE_INSERT_FAULT: Step is ' || l_param_num1); -- UPDATE task set param_num1 = l_param_num1 + 1 WHERE task_id = s_current_task; COMMIT; DBMS_LOCK.SLEEP(1); CASE l_param_num1 WHEN 1 THEN RAISE E_RETRY_ERROR; WHEN 2 THEN RAISE E_SNAPSHOT_TOO_OLD; WHEN 3 THEN RAISE E_UNABLE_EXTEND_TEMPSEG; WHEN 4 THEN RAISE E_CANT_EXTEND_UNDO; WHEN 5 THEN RETURN; END CASE; WHEN 'POOL_FULL' THEN trace1('EXECUTE_INSERT_FAULT: POOL_FULL'); BEGIN FOR i in 1..1000 LOOP EXECUTE IMMEDIATE q'{INSERT INTO JUNK_LAST VALUES (RPAD('A', 1000, 'A'))}'; COMMIT; END LOOP; EXCEPTION WHEN E_NO_SYNONYM THEN trace1('EXECUTE_INSERT_FAULT: junk_last was dropped.'); END; WHEN 'SLEEP' THEN trace1('EXECUTE_INSERT_FAULT: Sleep time is ' || l_param_num1); DBMS_LOCK.SLEEP (p_task_rec.param_num1); WHEN 'ORA-600' THEN trace1('EXECUTE_INSERT_FAULT: ORA-600'); IF NVL(p_task_rec.error_count,0) = 0 THEN RAISE E_ORA_600; END IF; ELSE SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM, 'Unknown fault: ' || p_task_rec.param); END CASE; $END END execute_insert_fault; -- -- -- -- PROCEDURE execute_backup_sbt (p_task_rec IN task%ROWTYPE) IS restore sbt_task.restore%TYPE; BEGIN BEGIN SELECT restore INTO restore FROM sbt_task WHERE task_id = s_current_task; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; log_sbt_task_error( p_db_key => p_task_rec.db_key, p_bs_key => p_task_rec.param_num1, p_bp_key => NULL, p_template_key => p_task_rec.param_num2, p_lib_key => NULL); RAISE E_FAILED; END; IF (restore != 'Y') THEN copy_sbt(p_task_rec); release_blocked_tasks(SPACE_PSEUDO_TASK, p_task_rec.db_key); END IF; END execute_backup_sbt; /* dbms_ra_scheduler.execute_backup_sbt */ -- -- -- -- PROCEDURE execute_restore_sbt (p_task_rec IN task%ROWTYPE) IS restore sbt_task.restore%TYPE; l_skip BOOLEAN := FALSE; BEGIN BEGIN SELECT restore INTO restore FROM sbt_task WHERE task_id = s_current_task; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; log_sbt_task_error( p_db_key => p_task_rec.db_key, p_bs_key => NULL, p_bp_key => p_task_rec.param_num2, p_template_key => NULL, p_lib_key => p_task_rec.param_num3); RAISE E_FAILED; END; IF (restore = 'Y') THEN IF (get_savepoint IS NOT NULL) THEN tracex('EXECUTE_RESTORE_SBT: Cannot restart this task'); l_skip := TRUE; END IF; IF p_task_rec.com_time + (1/24/60/60 * s_servlet_wait_seconds) < sysdate THEN tracex('EXECUTE_RESTORE_SBT: Servlet com_time is too old'); l_skip := TRUE; END IF; -- -- -- IF NOT l_skip THEN restore_sbt(p_task_rec); END IF; -- release_restore_wait; END IF; EXCEPTION WHEN E_NO_MORE_SGA THEN save_error; RAISE; WHEN OTHERS THEN save_error; release_restore_wait; RAISE; END execute_restore_sbt; /* dbms_ra_scheduler.execute_restore_sbt */ -- PROCEDURE invalidateTemplateBackup(p_bs_key IN NUMBER, p_bp_key IN NUMBER, p_db_key IN NUMBER, p_template_key IN NUMBER); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE copy_sbt(p_task_rec IN task%ROWTYPE) IS -- CURSOR bp_cursor(bskey IN NUMBER, pno IN NUMBER) IS SELECT bp.handle, bs.set_stamp, bs.set_count, bp.bp_key FROM bp, bs WHERE bs.bs_key = bp.bs_key AND bp.bs_key = bp_cursor.bskey AND bp.piece# = bp_cursor.pno AND bp.status != 'D' AND bp.ba_access != 'U' AND bp.lib_key is null AND bp.template_key is null ORDER BY bs.set_stamp, bs.set_count, bp.piece#, bp.copy# DESC; l_task_rec task%ROWTYPE; set_count NUMBER; set_stamp NUMBER; out_recid NUMBER; out_stamp NUMBER; concur BOOLEAN; newfilename VARCHAR2(1024); newfilename1 VARCHAR2(1024); srcfilename VARCHAR2(1024); handle VARCHAR2(1024); comment VARCHAR2(80); media VARCHAR2(80); lyear VARCHAR2(4); lday VARCHAR2(2); lmonth VARCHAR2(2); lcfaudate VARCHAR2(512); devtype VARCHAR2(512); node VARCHAR2(255); bpsize NUMBER; l_maxcopy NUMBER; l_copynum NUMBER; bpkey NUMBER; template_key NUMBER; bskey NUMBER; pno NUMBER; attr_key NUMBER; l_lib_key NUMBER; dupcnt NUMBER; server_key NUMBER; l_bp_key NUMBER; format_str VARCHAR2(512); l_src_bpkey NUMBER; l_delete_src VARCHAR2(1); parms VARCHAR2(2048); l_lparms VARCHAR2(1024); l_pparms VARCHAR2(1024); l_count NUMBER; l_failure_cnt NUMBER; l_dbname dbinc.db_name%TYPE; l_platform_id NUMBER; l_send sbt_attr_set.send%type; l_rep_srvr_status rep_server.status%TYPE; l_rep_server_key NUMBER; l_level NUMBER; l_taped NUMBER; l_not_taped_state VARCHAR2(1); l_not_taped NUMBER; l_reserved NUMBER; -- l_dbkey NUMBER := p_task_rec.db_key; BEGIN trace1 ('COPY_SBT'); -- SELECT template_key, bs_key, piece#, attr_key, copies, src_bpkey, delete_source, format, lib_key, failure_cnt, rep_server_key INTO template_key, bskey, pno, attr_key, dupcnt, l_src_bpkey, l_delete_src, format_str, l_lib_key, l_failure_cnt, l_rep_server_key FROM sbt_task WHERE task_id = s_current_task; -- SELECT attr.parms, lib.parms, server_key, attr.send INTO l_lparms, l_pparms, server_key, l_send FROM sbt_lib_desc lib, sbt_attr_set attr WHERE attr.lib_key = lib.lib_key AND attr.attr_key = copy_sbt.attr_key; -- IF l_rep_server_key IS NOT NULL THEN BEGIN SELECT status INTO l_rep_srvr_status FROM rep_server WHERE rep_server_key = l_rep_server_key; IF l_rep_srvr_status != 'A' THEN RAISE no_data_found; END IF; EXCEPTION WHEN no_data_found THEN save_error; trace1('COPY_SBT: Replication Server not available. ' || ' l_rep_server_key=' || l_rep_server_key); clear_error; RETURN; END; END IF; -- -- IF (l_pparms IS NOT NULL) AND (l_lparms IS NOT NULL) THEN parms := l_pparms || ', ' || l_lparms; ELSIF l_pparms IS NOT NULL THEN parms := l_pparms; ELSE parms := l_lparms; END IF; BEGIN IF l_src_bpkey IS NULL THEN -- OPEN bp_cursor(bskey, pno); FETCH bp_cursor INTO srcfilename, set_stamp, set_count, l_bp_key; IF (bp_cursor%NOTFOUND) THEN CLOSE bp_cursor; RAISE no_data_found; END IF; CLOSE bp_cursor; ELSE l_bp_key := l_src_bpkey; SELECT handle, bs_key INTO srcfilename, bskey FROM bp WHERE bp_key = l_src_bpkey AND status != 'D'; SELECT set_stamp, set_count INTO set_stamp, set_count FROM bs WHERE bs_key = bskey; END IF; EXCEPTION WHEN no_data_found THEN save_error; trace1 ('COPY_SBT: backup piece not found' || ', bs_key=' || bskey || ', piece#=' || pno || ', bp_key=' || l_src_bpkey); RAISE DBMS_RA_SCHEDULER.E_BACKUP_NOT_FOUND; END; IF NOT DBMS_RA_INT.READ_LOCK(DBMS_RA_INT.KEY_BP, l_bp_key) THEN trace1 ('COPY_SBT: Unable to get read_lock on bp_key=' || l_bp_key); -- -- RAISE dbms_ra_scheduler.e_retry_error; END IF; SELECT db_name INTO l_dbname FROM dbinc WHERE db_key = l_dbkey AND dbinc_status = 'CURRENT'; SELECT platform_id INTO l_platform_id FROM odb WHERE db_key = l_dbkey; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- IF format_str IS NULL THEN format_str := 'RA_SBT_' || template_key || '_%U_' || bskey; IF (l_failure_cnt > 0) THEN format_str := format_str || '_' || ceil(dbms_random.value(1,100)); END IF; trace1 ('COPY_SBT: format_str=' || format_str); END IF; -- SELECT NVL(MAX(copy#), 0) INTO l_maxcopy FROM bp WHERE bs_key = bskey; -- dbms_ra_int.s_bp_save.DELETE; -- devtype := sys.dbms_backup_restore.deviceAllocate( ident => 'RA$SBT', node => node, type => 'SBT_TAPE', params => parms, dupcnt => dupcnt, allowmts => TRUE, ors_lib_key => l_lib_key, db_name => l_dbname, platform_id => l_platform_id); -- if (l_send is not null) then sys.dbms_backup_restore.deviceCommand(cmd => l_send); end if; l_copynum := 0; while (l_copynum < dupcnt) loop newfilename := sys.dbms_backup_restore.genPieceName( pno => pno, set_count => set_count, set_stamp => set_stamp, format => format_str, copyno => l_copynum + l_maxcopy + 1, devtype => 'SBT_TAPE', year => 0, month => 0, day => 0, dbid => null, -- computed in server if required ndbname => null, -- computed in server if required pdbname => null, -- computed in server if required cfseq => null); if (l_copynum > 0) then sys.dbms_backup_restore.backupPieceCrtDupSet(l_copynum, newfilename); else newfilename1 := newfilename; end if; l_copynum := l_copynum + 1; end loop; -- trace1('COPY_SBT: copying '|| srcfilename || ' to ' || newfilename1); sys.dbms_backup_restore.backupBackupPiece( bpname => srcfilename, fname => newfilename1, handle => handle, comment => comment, media => media, concur => concur, recid => out_recid, stamp => out_stamp, check_logical=> FALSE, params => NULL, reuse => FALSE, deffmt => 0, copy_recid => null, copy_stamp => null, -- -- copyno => 0, npieces => pno, dest => 0, pltfrmfr => null, ors => TRUE, bpsize => bpsize, template_key => template_key); -- sys.dbms_backup_restore.deviceDeallocate; devtype := NULL; -- dbms_ra_int.s_bp_save.DELETE; DBMS_RA_INT.unlock(DBMS_RA_INT.KEY_BP, l_bp_key); -- IF l_delete_src = 'Y' THEN delete_one_backuppiece(l_bp_key); END IF; -- -- IF l_delete_src = 'Y' THEN l_taped := 0; ELSE -- SELECT NVL2(MAX(copy#), 0, bpsize) INTO l_taped FROM bp WHERE bs_key = bskey AND piece# = pno AND lib_key IS NOT NULL AND bp_key <> l_bp_key; -- IF l_taped > 0 THEN SELECT MIN(dbms_ra_pool.incrLevel(create_scn, incr_scn)) INTO l_level FROM bdf WHERE bs_key = bskey; IF l_level = 0 THEN l_taped := 1; END IF; END IF; END IF; -- DBMS_RA_STORAGE.LOCK_DB(l_dbkey); IF server_key IS NOT NULL AND server_key > 0 THEN UPDATE odb SET wait_space = NULL, cumulative_rep_usage = cumulative_rep_usage + bpsize, not_taped = not_taped - l_taped, not_taped_state = (CASE WHEN not_taped_state = 'B' THEN 'C' WHEN not_taped_state = 'N' THEN 'I' WHEN not_taped_state = 'V' AND l_taped = 1 THEN 'I' ELSE not_taped_state END) WHERE db_key = l_dbkey RETURNING not_taped_state, not_taped, base_reserved_space INTO l_not_taped_state, l_not_taped, l_reserved; ELSE UPDATE odb SET wait_space = NULL, cumulative_sbt_usage = cumulative_sbt_usage + bpsize, not_taped = not_taped - l_taped, not_taped_state = (CASE WHEN not_taped_state = 'B' THEN 'C' WHEN not_taped_state = 'N' THEN 'I' WHEN not_taped_state = 'V' AND l_taped = 1 THEN 'I' ELSE not_taped_state END) WHERE db_key = l_dbkey RETURNING not_taped_state, not_taped, base_reserved_space INTO l_not_taped_state, l_not_taped, l_reserved; END IF; COMMIT; trace1('COPY_SBT: not_taped_state ' || l_not_taped_state || ', not_taped ' || l_not_taped); DBMS_RA_STORAGE.UNLOCK_DB(l_dbkey); -- -- IF server_key IS NOT NULL AND server_key > 0 THEN -- -- DBMS_RA_STORAGE.LOCK_DB(l_dbkey); UPDATE odb SET last_replication = SYSTIMESTAMP WHERE db_key = l_dbkey; COMMIT; DBMS_RA_STORAGE.UNLOCK_DB(l_dbkey); -- -- queue_set_reconcile_timer (p_db_key => l_dbkey); END IF; -- UPDATE sbt_lib_desc SET failure_cnt = 0 WHERE lib_key = l_lib_key; UPDATE sbt_task SET failure_cnt = 0 WHERE task_id = s_current_task; -- fix_error (p_error_num => (CASE WHEN server_key IS NOT NULL THEN E_REPLICATION_ERROR_NUM ELSE E_SBT_ERROR_NUM END), p_db_key => l_dbkey, p_param_num => l_lib_key); -- COMMIT; -- -- -- IF l_not_taped_state = 'C' OR (l_not_taped_state = 'I' AND l_not_taped + bpsize > l_reserved) THEN SELECT COUNT(*) INTO l_count FROM task WHERE task_type = TASK_GCOPY_COMPUTE AND db_key = l_dbkey AND ROWNUM = 1; IF l_count = 0 THEN l_task_rec.task_type := TASK_GCOPY_COMPUTE; l_task_rec.db_key := l_dbkey; l_task_rec.flags := 0; DBMS_RA_SCHEDULER.NEW_TASK(l_task_rec); END IF; END IF; -- dbms_ra_pool.dealloc_plan_bp(bskey); EXCEPTION -- -- -- WHEN E_BACKUP_NOT_FOUND THEN save_error; -- UPDATE sbt_lib_desc SET failure_cnt = 0 WHERE lib_key = l_lib_key; UPDATE sbt_task SET failure_cnt = 0 WHERE task_id = s_current_task; -- invalidateTemplateBackup(bskey, l_bp_key, l_dbkey, template_key); COMMIT; clear_error; WHEN OTHERS THEN save_error; DBMS_RA_STORAGE.UNLOCK_DB(l_dbkey); DBMS_RA_INT.unlock(DBMS_RA_INT.KEY_BP, l_bp_key); ROLLBACK; UPDATE sbt_task SET failure_cnt = failure_cnt + 1 WHERE task_id = s_current_task RETURNING failure_cnt INTO l_failure_cnt; IF (l_failure_cnt >= s_max_sbt_failures) THEN invalidateTemplateBackup(bskey, l_bp_key, l_dbkey, template_key); END IF; COMMIT; -- dbms_ra_int.s_bp_save.DELETE; BEGIN -- -- log_sbt_error (l_dbkey, l_lib_key, l_failure_cnt, TRUE); RAISE; EXCEPTION WHEN OTHERS THEN save_error; -- IF (devtype IS NOT NULL) THEN -- sys.dbms_backup_restore.deviceDeallocate; END IF; RAISE; END; END copy_sbt; -- -- -- -- PROCEDURE log_sbt_error(p_db_key IN NUMBER, p_lib_key IN NUMBER, p_failure_cnt IN NUMBER, p_retry IN BOOLEAN) IS l_lib_name sbt_lib_desc.lib_name%TYPE; l_rep_server_name server.rep_server_name%TYPE; BEGIN trace1('LOG_SBT_ERROR: On ' || SQLERRM); -- -- -- -- IF SQLCODE IN (E_NO_MORE_SGA_NUM, E_PENDING_INTERRUPT_NUM, E_RETRY_ERROR_NUM, E_RETRY_RESERVE_NUM) THEN trace1('LOG_SBT_ERROR: Exiting on expected error'); RETURN; END IF; UPDATE sbt_lib_desc SET status = (CASE WHEN failure_cnt + 1 < s_max_sbt_failures THEN 'R' ELSE 'E' END), failure_cnt = failure_cnt + 1 WHERE status = 'R' AND lib_key = p_lib_key; COMMIT; -- -- -- IF s_current_task IS NOT NULL THEN SELECT lib_name, rep_server_name INTO l_lib_name, l_rep_server_name FROM sbt_lib_desc lib LEFT OUTER JOIN server ON (lib.server_key=server.server_key) WHERE lib.lib_key = p_lib_key; -- -- -- log_error (p_errno => (CASE WHEN l_rep_server_name IS NOT NULL THEN E_REPLICATION_ERROR_NUM ELSE E_SBT_ERROR_NUM END), p_param1 => NVL(l_rep_server_name, l_lib_name), p_component => (CASE WHEN l_rep_server_name IS NOT NULL THEN 'REPLICATION' ELSE 'SBT' END), p_severity => SEVERITY_ERROR, p_db_key => p_db_key, p_param_num => p_lib_key, p_param_char => NVL(l_rep_server_name, l_lib_name)); -- -- -- SYS.KBRSI_ICD.RSCLEARERR; IF (NOT p_retry) THEN trace1('LOG_SBT_ERROR: raising failed error'); RAISE E_FAILED; -- -- -- -- -- -- -- -- -- -- ELSIF l_rep_server_name IS NOT NULL THEN -- -- UPDATE sbt_task SET failure_cnt = 0 WHERE task_id = s_current_task; COMMIT; trace1('LOG_SBT_ERROR: raising retryable replication error'); RAISE E_RETRY_ERROR; ELSIF (p_failure_cnt >= s_max_sbt_failures) THEN trace1('LOG_SBT_ERROR: raising failed error'); RAISE E_FAILED; ELSE trace1('LOG_SBT_ERROR: raising retryable error'); RAISE E_RETRY_ERROR; END IF; END IF; END log_sbt_error; -- -- -- -- PROCEDURE log_sbt_task_error( p_db_key IN NUMBER, p_bs_key IN NUMBER, p_bp_key IN NUMBER, p_template_key IN NUMBER, p_lib_key IN NUMBER) IS cnt NUMBER; l_dbname dbinc.db_name%TYPE; BEGIN IF (p_db_key IS NOT NULL) THEN SELECT db_name INTO l_dbname FROM dbinc WHERE db_key = p_db_key AND dbinc_status = 'CURRENT'; ELSE l_dbname := ''; END IF; IF (p_bp_key IS NOT NULL) THEN SELECT count(*) INTO cnt FROM bp WHERE bp.bs_key = p_bp_key AND bp.status = 'A'; IF (cnt = 0) THEN trace1('log_sbt_task_error: bp_key ' || p_bp_key || ' has been purged'); -- -- -- -- -- -- RETURN; END IF; END IF; IF (p_bs_key IS NOT NULL) THEN SELECT count(*) INTO cnt FROM bs WHERE bs.bs_key = p_bs_key AND bs.status = 'A'; IF (cnt = 0) THEN trace1('log_sbt_task_error: bs_key ' || p_bs_key || 'has been purged.'); -- -- -- -- -- -- RETURN; END IF; END IF; IF (p_template_key IS NOT NULL) THEN SELECT count(*) INTO cnt FROM sbt_job_template j WHERE j.template_key = p_template_key; IF (cnt = 0) THEN trace1('log_sbt_task_error: template_key ' || p_template_key || ' has been purged'); -- -- -- -- -- -- RETURN; END IF; END IF; IF (p_lib_key IS NOT NULL) THEN SELECT count(*) INTO cnt FROM sbt_lib_desc lib WHERE lib.lib_key = p_lib_key; IF (cnt = 0) THEN trace1('log_sbt_task_error: sbt_lib_key ' || p_lib_key || ' has been purged'); -- -- -- -- -- -- RETURN; END IF; END IF; -- -- -- -- trace1('log_sbt_task_error: usable backup piece has been purged'); log_error(p_errno => E_SBT_TASK_NOT_FOUND, p_component => 'SBT_TASK', p_param1 => 'BACKUP SET', p_param2 => print(p_bs_key), p_param3 => l_dbname, p_severity => SEVERITY_WARNING); END log_sbt_task_error; -- -- -- PROCEDURE restore_sbt (p_task_rec IN task%ROWTYPE) IS handle VARCHAR2(1024); parms VARCHAR2(1028); node VARCHAR2(512); devtype VARCHAR2(512); l_lib_key NUMBER; l_db_key NUMBER; l_server_key NUMBER; l_dbname dbinc.db_name%TYPE; l_platform_id NUMBER; BEGIN trace1 ('RESTORE_SBT: Performing sbt backup restore'); -- SELECT bp.handle, lib.parms, bp.lib_key, bp.db_key, lib.server_key INTO handle, parms, l_lib_key, l_db_key, l_server_key FROM sbt_lib_desc lib, bp WHERE bp.lib_key = lib.lib_key AND bp.bp_key = p_task_rec.param_num2; SELECT db_name INTO l_dbname FROM dbinc WHERE db_key = l_db_key AND dbinc_status = 'CURRENT'; SELECT platform_id INTO l_platform_id FROM odb WHERE db_key = l_db_key; -- devtype := sys.dbms_backup_restore.deviceAllocate( ident => 'RA$SBT', node => node, type => 'SBT_TAPE', params => parms, dupcnt => 1, allowmts => TRUE, ors_lib_key => l_lib_key, db_name => l_dbname, platform_id => l_platform_id); -- sys.kbrsi_icd.restoreSbtTask(reqid => p_task_rec.param_num1, handle => handle); -- sys.dbms_backup_restore.deviceDeallocate; devtype := NULL; -- UPDATE sbt_lib_desc SET failure_cnt = 0 WHERE lib_key = l_lib_key; fix_error (p_error_num => (CASE WHEN l_server_key IS NOT NULL THEN E_REPLICATION_ERROR_NUM ELSE E_SBT_ERROR_NUM END), p_db_key => l_db_key, p_param_num => l_lib_key); -- COMMIT; EXCEPTION WHEN others THEN save_error; ROLLBACK; BEGIN -- -- log_sbt_error (l_db_key, l_lib_key, 0, FALSE); RAISE; EXCEPTION WHEN OTHERS THEN save_error; -- IF (devtype IS NOT NULL) THEN -- sys.dbms_backup_restore.deviceDeallocate; END IF; RAISE; END; END restore_sbt; -- -- -- PROCEDURE cleanup_task(p_task_type IN NUMBER) IS BEGIN IF (p_task_type = TASK_PURGE_SBT) THEN IF (s_libkey IS NOT NULL) THEN s_libkey := NULL; sys.dbms_backup_restore.deviceDeallocate; END IF; END IF; END cleanup_task; -- -- -- -- PROCEDURE execute_purge_sbt(p_task_rec IN task%ROWTYPE) IS parms VARCHAR2(1028); node VARCHAR2(512); devtype VARCHAR2(512); l_lib_key NUMBER; BEGIN -- IF (p_task_rec.param_num1 != nvl(s_libkey, -1)) THEN -- IF (s_libkey IS NOT NULL) THEN s_libkey := NULL; sys.dbms_backup_restore.deviceDeallocate; END IF; -- BEGIN SELECT lib.parms INTO parms FROM sbt_lib_desc lib WHERE lib.lib_key = p_task_rec.param_num1; EXCEPTION WHEN no_data_found THEN save_error; trace1('EXECUTE_PURGE_SBT: Library/Rep server has been deleted.'); clear_error; RETURN; END; -- devtype := sys.dbms_backup_restore.deviceAllocate( ident => 'RA$SBT', node => node, type => 'SBT_TAPE', params => parms, dupcnt => 1, allowmts => TRUE, ors_lib_key => l_lib_key, db_name => NULL, platform_id => 0); s_libkey := p_task_rec.param_num1; END IF; -- trace1 ('EXECUTE_PURGE_SBT: Purge backuppiece ' || p_task_rec.param_char1); sys.kbrsi_icd.deleteBpSbt(handle => p_task_rec.param_char1); EXCEPTION WHEN no_data_found THEN -- library doesn't exists anymore save_error; NULL; clear_error; END execute_purge_sbt; /* dbms_ra_scheduler.execute_purge_sbt */ -- -- -- PROCEDURE execute_trim_db (p_task_rec IN task%ROWTYPE) IS BEGIN tracex ('EXECUTE_TRIM_DB' || ' sl_key=' || p_task_rec.sl_key || '; db_key=' || p_task_rec.db_key); -- -- -- DBMS_RA_STORAGE.TRIM_DATABASE_FOR_MOVE (p_task_rec.db_key, p_task_rec.param_num1); END execute_trim_db; -- -- -- -- -- -- -- -- -- -- PROCEDURE execute_move_all_db IS BEGIN -- avoid_delete_db(); DBMS_RA_STORAGE.MOVE_ALL_DB; END execute_move_all_db; -- -- -- PROCEDURE execute_move_df (p_task_rec IN task%ROWTYPE) IS l_sl_key NUMBER; l_old_sl_key NUMBER; l_chunks NUMBER; BEGIN tracex ('EXECUTE_MOVE_DF on database ' || p_task_rec.db_key || '; df_key= ' || p_task_rec.param_num1); -- -- -- s_no_wait_on_allocate := TRUE; -- -- -- -- dbms_ra_pool.moveDF(p_task_rec.db_key, p_task_rec.param_num1); END execute_move_df; -- -- -- -- -- -- PROCEDURE execute_repair_db (p_task_rec IN task%ROWTYPE) IS l_count NUMBER; BEGIN tracex ('EXECUTE_REPAIR_DB on database ' || print(p_task_rec.db_key) || '; sl_key= ' || p_task_rec.sl_key); -- -- -- IF p_task_rec.db_key IS NOT NULL THEN dbms_ra_pool.repairChunks(p_task_rec.db_key); END IF; -- -- -- UPDATE task SET db_key = NULL WHERE task_id = s_current_task; COMMIT; -- -- -- FOR i IN 1..360 LOOP SELECT COUNT(*) INTO l_count FROM config WHERE name = '_testwait' AND LOWER(value) = 'repair'; EXIT WHEN l_count = 0; trace1 ('EXECUTE_REPAIR_DB: Waiting for test'); DBMS_LOCK.SLEEP(10); END LOOP; -- -- -- -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); SELECT COUNT(*) INTO l_count FROM task WHERE (task_type = TASK_REPAIR_DB) AND (db_key IS NOT NULL); trace1 ('EXECUTE_REPAIR_DB: ' || l_count || ' repair tasks still active'); -- -- -- -- -- IF l_count = 0 THEN UPDATE sl SET sl_needs_repair = NULL, sl_state = NULL WHERE sl_space <> 0; COMMIT; END IF; SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0); EXCEPTION WHEN OTHERS THEN save_error; SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0); RAISE; END execute_repair_db; -- -- -- -- -- -- PROCEDURE complete_task (p_action VARCHAR2, p_taskname IN VARCHAR2, p_current_execution_time TIMESTAMP WITH TIME ZONE, p_final_state NUMBER) IS l_flags NUMBER; l_purge_reserve NUMBER := NULL; l_db_key NUMBER; l_unlock_needed BOOLEAN := FALSE; l_error_count NUMBER; l_template_name sbt_job_template.template_name%TYPE := NULL; l_task_type NUMBER; BEGIN -- -- -- IF s_cached_storage THEN DBMS_RA_STORAGE.FREE_TASK_STORAGE (s_current_task); END IF; -- -- -- IF s_purging_active THEN SELECT purge_reserve, db_key INTO l_purge_reserve, l_db_key FROM task WHERE task_id = s_current_task; END IF; -- -- -- -- IF NVL(l_purge_reserve, 0) > 0 THEN trace1 ('COMPLETE_TASK: Freeing reserved chunks ' || l_purge_reserve); l_unlock_needed := TRUE; DBMS_RA_STORAGE.LOCK_DB (l_db_key); UPDATE odb SET used_space = used_space - (l_purge_reserve * sl_min_alloc) WHERE db_key = l_db_key; UPDATE task SET purge_reserve = 0 WHERE task_id = s_current_task; COMMIT; DBMS_RA_STORAGE.UNLOCK_DB (l_db_key); l_unlock_needed := FALSE; END IF; -- -- -- -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); UPDATE task SET state = p_final_state, completion_time = SYSTIMESTAMP, elapsed_time = elapsed_time + (SYSTIMESTAMP - p_current_execution_time) WHERE task_id = s_current_task RETURNING db_key, error_count, task_type INTO l_db_key, l_error_count, l_task_type; trace1('COMPLETE_TASK: Copying to task_history'); INSERT INTO task_history (SELECT * FROM task WHERE task_id = s_current_task); IF (l_task_type IN (TASK_BACKUP_SBT, TASK_RESTORE_SBT)) THEN INSERT INTO sbt_task_history (SELECT * FROM sbt_task WHERE task_id = s_current_task); DELETE FROM sbt_task WHERE task_id = s_current_task; END IF; -- sbt task -- -- -- DELETE FROM task WHERE task_id = s_current_task RETURNING flags, purge_reserve INTO l_flags, l_purge_reserve; IF NVL(l_purge_reserve,0) <> 0 THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( E_INTERNAL_ERROR_NUM, 'unclaimed purge_reserve=' || l_purge_reserve); END IF; IF BITAND (l_flags, TASKS_CHUNK_CACHE_ACTIVE) <> 0 THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( E_INTERNAL_ERROR_NUM, 'unclaimed chunk_cache'); END IF; -- -- -- UPDATE sessions SET current_task = NULL, current_task_type = NULL WHERE ba_session_id = s_ba_session_id; IF BITAND(l_flags,TASKS_BLOCKING_TASK) <> 0 THEN -- -- -- -- -- UPDATE task SET pending_interrupt = NULL, state = (CASE state WHEN STATE_RUNNING THEN STATE_RUNNING WHEN STATE_CANCELING THEN STATE_CANCELING WHEN STATE_CANCEL THEN STATE_CANCEL ELSE STATE_EXECUTABLE END) WHERE pending_interrupt = s_current_task; trace1 ('COMPLETE_TASK: Releasing ' || SQL%ROWCOUNT || ' waiting tasks'); COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0); ELSE COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK; END IF; -- -- -- IF BITAND (l_flags, TASKS_TOO_MANY_INTERRUPTS) <> 0 THEN fix_error (p_error_num => E_TOO_MANY_INTERRUPTS_NUM, p_param_num => s_current_task); END IF; trace_task(p_action, p_taskname); EXCEPTION WHEN OTHERS THEN save_error; trace1('COMPLETE_TASK: Error seen is ' || SQLERRM); IF l_unlock_needed THEN DBMS_RA_STORAGE.UNLOCK_DB (l_db_key); END IF; SYS.KBRSI_ICD.RSSCHEDUNLOCK; RAISE; END complete_task; -- -- -- PROCEDURE suspend_task (p_newstate IN NUMBER, p_current_execution_time TIMESTAMP WITH TIME ZONE) IS l_newstate NUMBER := p_newstate; l_flags NUMBER; l_interrupting_type NUMBER; l_dfkey NUMBER; l_vbkey NUMBER; l_ptype NUMBER; l_priority NUMBER; l_interrupt_count NUMBER; BEGIN trace1 ('SUSPEND_TASK: newstate=' || p_newstate || '; pending_interrupt=' || print(s_pending_interrupt)); -- -- -- IF s_cached_storage THEN DBMS_RA_STORAGE.FREE_TASK_STORAGE; END IF; -- -- -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); IF NVL(s_pending_interrupt,0) > 0 THEN -- -- -- -- -- -- -- -- -- trace1 ('SUSPEND_TASK: Waiting for task'); UPDATE task SET flags = NVL(flags,0) - BITAND(NVL(flags,0), TASKS_BLOCKING_TASK) + TASKS_BLOCKING_TASK WHERE task_id = s_pending_interrupt AND state <> STATE_ORDERING_WAIT AND NOT (task_type IN (TASK_BACKUP_SBT, TASK_RESTORE_SBT, TASK_OBSOLETE_SBT) AND state <> STATE_RUNNING) RETURNING task_type, param_num1, param_num2, param_num3 INTO l_interrupting_type, l_dfkey, l_vbkey, l_ptype; IF SQL%ROWCOUNT = 0 THEN trace1 ('SUSPEND_TASK: Interrupting task no longer is around'); l_newstate := STATE_EXECUTABLE; s_pending_interrupt := NULL; ELSIF s_current_task_type IN (TASK_PURGE_DF, TASK_PURGE_DF_NOW) AND l_interrupting_type IN (TASK_PURGE_DF, TASK_PURGE_DF_NOW) THEN -- -- -- -- -- -- -- -- -- -- UPDATE task SET pending_interrupt = 0 WHERE task_id = s_pending_interrupt AND state = STATE_RUNNING AND EXISTS (SELECT 1 FROM task WHERE task_id = s_current_task AND param_num1 = l_dfkey AND param_num2 > l_vbkey AND param_num3 = l_ptype AND nvl(savepoint, 0) = 0); IF SQL%ROWCOUNT > 0 THEN trace1 ('SUSPEND_TASK: Interrupting task is an obsolete purge.'); END IF; END IF; END IF; -- -- -- UPDATE task SET state = l_newstate, pending_interrupt = s_pending_interrupt, last_interrupt_time = SYSTIMESTAMP, interrupt_count = NVL(interrupt_count,0) + 1, elapsed_time = elapsed_time + (SYSTIMESTAMP - p_current_execution_time), ba_session_id = NULL WHERE task_id = s_current_task RETURNING BITAND(flags,TASKS_BLOCKING_TASK), priority, interrupt_count INTO l_flags, l_priority, l_interrupt_count; -- -- IF ((l_prioritys_interrupt_max)) OR (l_interrupt_count>s_busy_interrupt_max) THEN log_error (p_errno => E_TOO_MANY_INTERRUPTS_NUM, p_param1 => TO_CHAR(s_current_task), p_param2 => tasktype2name(s_current_task_type), p_param3 => TO_CHAR(l_interrupt_count), p_component => tasktype2name(s_current_task_type), p_severity => SEVERITY_WARNING, p_param_num => s_current_task); l_flags := bitset (l_flags, TASKS_TOO_MANY_INTERRUPTS); UPDATE task SET flags = l_flags WHERE task_id = s_current_task; END IF; -- -- -- -- UPDATE sessions SET current_task = NULL, current_task_type = NULL WHERE ba_session_id = s_ba_session_id; -- -- -- IF BITAND(l_flags,TASKS_BLOCKING_TASK) <> 0 THEN UPDATE task SET pending_interrupt = NULL, state = (CASE state WHEN STATE_RUNNING THEN STATE_RUNNING WHEN STATE_CANCELING THEN STATE_CANCELING WHEN STATE_CANCEL THEN STATE_CANCEL ELSE STATE_EXECUTABLE END), ba_session_id = NULL WHERE pending_interrupt = s_current_task; COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0); ELSE COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK; END IF; END suspend_task; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE interrupt_tasks (p_interrupt IN interrupt_t, p_task_id IN NUMBER DEFAULT NULL, p_db_key IN NUMBER DEFAULT NULL) IS l_updated_restore_tasks dbms_sql.number_table; l_wait_on_task_id NUMBER := NVL (p_task_id, s_current_task); l_min NUMBER; l_count NUMBER; BEGIN trace1 ('INTERRUPT_TASKS: interrupt type is: ' || p_interrupt); -- -- -- LOOP -- -- -- -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); -- -- -- UPDATE task SET flags = NVL(flags,0) - BITAND(NVL(flags,0), TASKS_BLOCKING_TASK) + TASKS_BLOCKING_TASK WHERE task_id = l_wait_on_task_id; IF SQL%ROWCOUNT = 0 THEN trace1 ('INTERRUPT_TASKS: Waiting-on task is missing: ' || l_wait_on_task_id); SYS.KBRSI_ICD.RSSCHEDUNLOCK; EXIT; END IF; -- -- -- IF (p_interrupt = INTERRUPT_FOR_MOVE) THEN UPDATE task SET pending_interrupt = l_wait_on_task_id WHERE task_type IN (TASK_MOVE_ALL_DB, TASK_MOVE_DF) AND pending_interrupt IS NULL AND task_id != l_wait_on_task_id; COMMIT; ELSIF (p_interrupt = INTERRUPT_FOR_PURGE) THEN UPDATE task SET pending_interrupt = l_wait_on_task_id WHERE task_type IN (TASK_RESTORE, TASK_INDEX_BACKUP) AND pending_interrupt IS NULL AND task_id != l_wait_on_task_id AND db_key = p_db_key RETURNING DECODE(task_type, TASK_RESTORE, param_num1) BULK COLLECT INTO l_updated_restore_tasks; COMMIT; FOR i IN 1..l_updated_restore_tasks.COUNT LOOP IF (l_updated_restore_tasks(i) IS NOT NULL) THEN SYS.KBRSI_ICD.RESTORESTOPTASK(l_updated_restore_tasks(i)); END IF; END LOOP; END IF; SYS.KBRSI_ICD.RSSCHEDUNLOCK; IF (p_interrupt = INTERRUPT_FOR_MOVE) THEN SELECT MIN(task_id), COUNT(*) INTO l_min, l_count FROM task WHERE task_type IN (TASK_MOVE_ALL_DB, TASK_MOVE_DF) AND pending_interrupt IS NULL AND task_id != l_wait_on_task_id; ELSIF (p_interrupt = INTERRUPT_FOR_PURGE) THEN SELECT MIN(task_id), COUNT(*) INTO l_min, l_count FROM task WHERE task_type IN (TASK_RESTORE, TASK_INDEX_BACKUP) AND pending_interrupt IS NULL AND task_id != l_wait_on_task_id AND db_key = p_db_key; END IF; trace1('INTERRUPT_TASKS: shows ' || l_count || ' tasks running starting with task id ' || l_min); EXIT WHEN l_count = 0; dbms_lock.sleep(s_interrupt_wait); END LOOP; END interrupt_tasks; -- -- -- PROCEDURE trace_task (p_action VARCHAR2, p_taskname IN VARCHAR2) IS BEGIN -- IF s_tracing_on THEN sys.kbrsi_icd.rsTrace('########## ' || TO_CHAR(SYSTIMESTAMP, 'MM/DD/YYYY HH24:MI:SS.FF3') || ' ' || rpad(p_action, 15) || rpad(p_taskname,11) || ' id ' || rpad(s_current_task || ' ', 14, '#')); ELSE -- sys.kbrsi_icd.rsTrace( '#### ' || p_action || ': ' || p_taskname || ' id ' || s_current_task); END IF; END trace_task; -- -- -- FUNCTION define_task (task_rec IN OUT NOCOPY task%ROWTYPE, p_sbt_task IN BOOLEAN DEFAULT FALSE) RETURN NUMBER IS l_resource_wait_process_count NUMBER; BEGIN trace1 ('DEFINE_TASK'); -- -- task_rec.task_id := rai_sq.nextval; IF (p_sbt_task) THEN task_rec.sbt_task_id := task_rec.task_id; ELSE task_rec.sbt_task_id := NULL; END IF; task_rec.priority := type2priority(task_rec.task_type); task_rec.flags := NVL(task_rec.flags, 0); task_rec.state := STATE_EXECUTABLE; task_rec.schedule_time := SYSTIMESTAMP; task_rec.creator_task_id := NVL(s_current_task, s_timer_process_instance); task_rec.creator_sid := TO_NUMBER(SYS_CONTEXT('USERENV', 'SID')); task_rec.creator_instance := s_instance; -- -- -- -- IF (task_rec.task_type = TASK_INDEX_BACKUP) OR (task_rec.priority >= PRIO_MIN_BUSYWORK) THEN SELECT TO_NUMBER(value) INTO l_resource_wait_process_count FROM config WHERE name = '_resource_wait_task_limit'; IF l_resource_wait_process_count <> MAX_RESOURCE_WAIT_PROCESSES THEN trace1 ('DEFINE_TASK: Cannot do busywork if resource wait is on.' || ' RW process count=' || l_resource_wait_process_count || ' Task id=' || task_rec.task_id); task_rec.state := STATE_TASK_WAIT; task_rec.pending_interrupt := RESOURCE_PSEUDO_TASK; END IF; END IF; -- -- -- IF task_rec.task_type IN (TASK_RESTORE, TASK_RESTORE_SBT) THEN task_rec.execute_inst_id := s_instance; ELSE task_rec.execute_inst_id := NULL; END IF; INSERT INTO task VALUES task_rec; IF s_tracing_on THEN trace1 ('DEFINE_TASK: Assign task_type ' || tasktype2name(task_rec.task_type) || ' (' || task_rec.task_type || '); task_id ' || task_rec.task_id); END IF; RETURN task_rec.task_id; END define_task; -- -- -- PROCEDURE new_task (task_rec IN OUT NOCOPY task%ROWTYPE, p_commit IN BOOLEAN DEFAULT TRUE, p_delay IN BOOLEAN DEFAULT FALSE, p_sbt_task IN BOOLEAN DEFAULT FALSE) IS l_task_id NUMBER; BEGIN -- -- -- IF p_delay THEN task_rec.pending_interrupt := s_current_task; UPDATE task SET flags = NVL(flags,0) - BITAND(NVL(flags,0), TASKS_BLOCKING_TASK) + TASKS_BLOCKING_TASK WHERE task_id = s_current_task; COMMIT; END IF; -- -- -- l_task_id := define_task (task_rec => task_rec, p_sbt_task => p_sbt_task); IF p_commit THEN COMMIT; END IF; IF p_commit AND NOT p_delay THEN -- -- -- SYS.KBRSI_ICD.RSRUNSCHED; END IF; END new_task; -- -- -- PROCEDURE newdfkey (p_dfkey IN NUMBER,p_dbinckey IN NUMBER, p_pdbinckey IN NUMBER) IS PRAGMA AUTONOMOUS_TRANSACTION; task_rec task%ROWTYPE; l_count NUMBER; BEGIN -- SELECT COUNT(*) INTO l_count FROM task WHERE state = STATE_ORDERING_WAIT; IF l_count = 0 THEN RETURN; END IF; task_rec.task_type := TASK_NEWDFKEY; task_rec.param_num1 := p_dfkey; task_rec.param_num2 := p_dbinckey; task_rec.param_num3 := p_pdbinckey; -- -- new_task (task_rec, false); COMMIT; END newdfkey; -- -- -- FUNCTION get_savepoint RETURN NUMBER IS l_answer NUMBER; BEGIN -- -- -- SELECT MIN(savepoint) INTO l_answer FROM task WHERE task_id = s_current_task; RETURN l_answer; END get_savepoint; -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION set_blocking_purge(p_dbkey IN NUMBER, p_space IN NUMBER DEFAULT NULL) RETURN NUMBER IS l_slkey NUMBER; l_not_taped_state VARCHAR(1); l_task_rec task%ROWTYPE; BEGIN trace1('SET_BLOCKING_PURGE: dbkey' || p_dbkey || ', needed space ' || print(p_space)); -- -- -- SELECT sl_key, not_taped_state INTO l_slkey, l_not_taped_state FROM odb WHERE db_key = p_dbkey; -- -- -- SELECT min(task_id) INTO s_pending_interrupt FROM task WHERE task_type IN (TASK_PURGE_DF_NOW, TASK_PURGE, TASK_PURGE_IMMEDIATE, TASK_TRIM_DB) AND task_id <> NVL(s_current_task,0) AND sl_key = l_slkey; -- -- -- -- IF s_pending_interrupt IS NULL THEN SELECT min(task_id) INTO s_pending_interrupt FROM task WHERE task_type IN (TASK_PURGE_DF_NOW, TASK_PURGE, TASK_PURGE_IMMEDIATE, TASK_PURGE_DUP_DF, TASK_TRIM_DB) AND task_id <> NVL(s_current_task,0) AND sl_key = l_slkey; END IF; -- -- -- -- -- -- IF s_pending_interrupt IS NULL AND s_current_task IS NOT NULL AND p_space IS NOT NULL THEN IF l_not_taped_state IS NOT NULL THEN s_pending_interrupt := SPACE_PSEUDO_TASK; ELSE -- Make space trace1('SET_BLOCKING_PURGE: make space'); l_task_rec.task_type := TASK_PURGE_IMMEDIATE; l_task_rec.db_key := p_dbkey; l_task_rec.sl_key := l_slkey; l_task_rec.param_num1 := p_space; l_task_rec.flags := 0; -- -- -- -- -- new_task(l_task_rec); s_pending_interrupt := l_task_rec.task_id; END IF; END IF; trace1('SET_BLOCKING_PURGE: Waiting for task -- ' || print(s_pending_interrupt)); RETURN s_pending_interrupt; END set_blocking_purge; -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE check_for_interrupt (p_state IN NUMBER DEFAULT NULL) IS l_session_count NUMBER; l_active_count NUMBER; l_waiting_task NUMBER; BEGIN trace1 ('CHECK_FOR_INTERRUPT'); -- -- -- IF s_current_task IS NULL THEN trace1 ('CHECK_FOR_INTERRUPT: No active task!'); RETURN; END IF; IF s_repair_active THEN trace1 ('CHECK_FOR_INTERRUPT: Repair is underway!'); RETURN; END IF; -- -- -- IF (p_state IS NOT NULL) THEN UPDATE task SET savepoint = p_state WHERE task_id = s_current_task; COMMIT; trace1 ('CHECK_FOR_INTERRUPT: savepoint set to ' || p_state); END IF; -- IF s_interrupt_when AND check_when('RAI_INTERRUPT_WHEN', s_current_task) AND (NVL(s_current_task_type, 0) <> TASK_TEST_DUMMY) THEN RAISE E_PENDING_INTERRUPT; END IF; -- -- -- -- IF type2priority(s_current_task_type) >= PRIO_MIN_BUSYWORK THEN -- -- -- SELECT COUNT(*), COUNT (current_task) INTO l_session_count, l_active_count FROM sessions WHERE purpose IS NULL; IF (l_session_count = l_active_count) THEN SELECT COUNT(*) INTO l_waiting_task FROM task WHERE state = STATE_EXECUTABLE AND ba_session_id IS NULL AND priority < PRIO_MIN_BUSYWORK AND task_type NOT IN (TASK_BACKUP_SBT, TASK_RESTORE_SBT, TASK_PURGE_SBT) AND (task_type != TASK_RESTORE OR NVL(execute_inst_id, s_instance) = s_instance) AND ROWNUM = 1; IF (l_waiting_task > 0) THEN -- -- -- -- trace1 ('CHECK_FOR_INTERRUPT: interrupting with' || ' sessions=' || l_session_count || ' actives=' || l_active_count); s_last_busywork_stop := SYSTIMESTAMP; UPDATE sessions SET last_busywork_stop = s_last_busywork_stop WHERE ba_session_id = s_ba_session_id; COMMIT; RAISE E_PENDING_INTERRUPT; END IF; END IF; -- -- -- SELECT MIN(task_id) INTO s_pending_interrupt FROM task WHERE pending_interrupt = s_current_task AND priority < type2priority(s_current_task_type); IF s_pending_interrupt IS NOT NULL THEN trace1 ('CHECK_FOR_INTERRUPT: interrupting because blocking task id ' || s_pending_interrupt); RAISE E_PENDING_INTERRUPT; END IF; END IF; -- -- -- SELECT MAX(pending_interrupt) INTO s_pending_interrupt FROM task WHERE task_id = s_current_task; IF s_pending_interrupt IS NOT NULL THEN trace1 ('CHECK_FOR_INTERRUPT: Pending interrupt from task id ' || s_pending_interrupt); RAISE E_PENDING_INTERRUPT; END IF; END check_for_interrupt; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE log_error (p_errno NUMBER, p_param1 VARCHAR2 DEFAULT NULL, p_param2 VARCHAR2 DEFAULT NULL, p_param3 VARCHAR2 DEFAULT NULL, p_param4 VARCHAR2 DEFAULT NULL, p_keep_stack BOOLEAN DEFAULT TRUE, p_component VARCHAR2, p_severity NUMBER, p_sl_key NUMBER DEFAULT NULL, p_db_key NUMBER DEFAULT NULL, p_param_char VARCHAR2 DEFAULT NULL, p_param_num NUMBER DEFAULT NULL) IS BEGIN IF p_param4 IS NOT NULL THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(p_errno, p_param1, p_param2, p_param3, p_param4, p_keep_stack); ELSIF p_param3 IS NOT NULL THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(p_errno, p_param1, p_param2, p_param3, p_keep_stack); ELSIF p_param2 IS NOT NULL THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(p_errno, p_param1, p_param2, p_keep_stack); ELSIF p_param1 IS NOT NULL THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(p_errno, p_param1, p_keep_stack); ELSE SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(p_errno, p_keep_stack); END IF; EXCEPTION WHEN OTHERS THEN -- -- -- IF SQLCODE = p_errno THEN write_error (p_component => p_component, p_severity => p_severity, p_sl_key => p_sl_key, p_db_key => p_db_key, p_param_char => p_param_char, p_param_num => p_param_num); -- ELSE RAISE; END IF; END log_error; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE write_error (p_component VARCHAR2, p_severity NUMBER, p_sl_key NUMBER DEFAULT NULL, p_db_key NUMBER DEFAULT NULL, p_param_char VARCHAR2 DEFAULT NULL, p_param_num NUMBER DEFAULT NULL) IS PRAGMA AUTONOMOUS_TRANSACTION; l_call_stack VARCHAR2(4000); l_final_backtrace_stack VARCHAR2(4000); l_final_call_stack VARCHAR2(4000); l_error_stack VARCHAR2(4000); l_sqlcode NUMBER := sqlcode; l_ospid VARCHAR2(24); l_severity NUMBER := p_severity; l_save_tracing BOOLEAN; l_count NUMBER; l_next_dumptime TIMESTAMP; l_job_name VARCHAR2(100); l_seen_count NUMBER; l_incident_alert NUMBER; l_incident_dump NUMBER; DUMPTIME_FORMAT CONSTANT VARCHAR2(19) := 'DD-MM-RR HH24:MI:SS'; BEGIN -- -- -- l_call_stack := SUBSTR(DBMS_RA_INT.GET_ERROR,1,4000); l_error_stack := SUBSTR(SYS.DBMS_UTILITY.FORMAT_ERROR_STACK,1,4000); l_final_backtrace_stack := SUBSTR(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE,1,4000); l_final_call_stack := SUBSTR(SYS.DBMS_UTILITY.FORMAT_CALL_STACK,1,4000); -- -- -- SELECT spid INTO l_ospid FROM sys.rai_my_ospid WHERE ROWNUM=1; -- -- -- IF s_trace_file IS NULL THEN BEGIN SELECT value INTO s_trace_file FROM v$diag_info WHERE name = 'Default Trace File'; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; s_trace_file := 'Unknown trace file'; clear_error; END; END IF; -- -- -- -- -- -- -- FOR i IN 1..100 LOOP BEGIN MERGE INTO error_log USING dual ON (error_num = l_sqlcode AND NVL(sl_key, -1) = NVL(p_sl_key, -1) AND NVL(db_key, -1) = NVL(p_db_key, -1) AND NVL(param_char, '?') = NVL(p_param_char, '?') AND NVL(param_num, -1) = NVL(p_param_num, -1)) WHEN NOT MATCHED THEN INSERT (incident#, error_num, sl_key, db_key, param_char, param_num, status, component, severity, error_text, first_seen, last_seen, seen_count, ospid, inst_id, task_id, trace_file, call_stack, final_call_stack, final_backtrace_stack) VALUES (rai_sq.nextval, l_sqlcode, p_sl_key, p_db_key, p_param_char, p_param_num, 'ACTIVE', p_component, p_severity, l_error_stack, SYSTIMESTAMP, SYSTIMESTAMP, 1, l_ospid, s_instance, s_current_task, s_trace_file, l_call_stack, l_final_call_stack, l_final_backtrace_stack) WHEN MATCHED THEN -- UPDATE SET status = 'ACTIVE', component = p_component, severity = p_severity, error_text = l_error_stack, last_seen = SYSTIMESTAMP, seen_count = seen_count + 1, ospid = l_ospid, inst_id = s_instance, task_id = s_current_task, trace_file = s_trace_file, call_stack = l_call_stack, final_call_stack = l_final_call_stack, final_backtrace_stack = l_final_backtrace_stack; -- SELECT seen_count, alert.value, dump.value INTO l_seen_count, l_incident_alert, l_incident_dump FROM error_log, config alert, config dump WHERE (error_num = l_sqlcode AND NVL(sl_key, -1) = NVL(p_sl_key, -1) AND NVL(db_key, -1) = NVL(p_db_key, -1) AND NVL(param_char, '?') = NVL(p_param_char, '?') AND NVL(param_num, -1) = NVL(p_param_num, -1)) AND alert.name = '_incident_alert_threshold' AND dump.name = '_incident_dump_threshold'; COMMIT; EXIT; EXCEPTION WHEN DUP_VAL_ON_INDEX OR E_NO_LONGER_EXISTS THEN save_error; trace1('WRITE_ERROR: Retrying after ' || SQLERRM); DBMS_LOCK.SLEEP(1); clear_error; CONTINUE; END; END LOOP; -- -- -- IF (l_severity >= l_incident_alert) AND (l_seen_count = 1) THEN l_save_tracing := s_tracing_on; s_tracing_on := TRUE; -- -- -- SYS.DBMS_SYSTEM.KSDWRT(SYS.DBMS_SYSTEM.ALERT_FILE, 'Recovery Appliance failure on ospid: ' || l_ospid || '; Errors: ' || l_error_stack); trace1 ('WRITE_ERROR: Recovery Appliance failure on ospid: ' || l_ospid || '; Errors: ' || l_error_stack); trace1 ('WRITE_ERROR saved call stack(s):'); trace1 (l_call_stack); trace1 ('WRITE_ERROR final call stack:'); trace1 (l_final_call_stack); trace1 ('WRITE_ERROR final backtrace: '); trace1 (l_final_backtrace_stack); s_tracing_on := l_save_tracing; ELSE trace1 ('BA warning: ' || l_error_stack); END IF; -- -- -- -- -- -- IF (p_severity >= l_incident_dump) AND (l_seen_count = 1) THEN -- -- -- BEGIN SELECT TO_TIMESTAMP(value, DUMPTIME_FORMAT) INTO l_next_dumptime FROM config WHERE (name = '_dumper_last_dump_timestamp') FOR UPDATE NOWAIT; EXCEPTION WHEN E_RESOURCE_BUSY THEN save_error; -- l_next_dumptime := SYSTIMESTAMP; clear_error; WHEN NO_DATA_FOUND THEN save_error; l_next_dumptime := NULL; clear_error; END; trace1 ('WRITE_ERROR: previous dump time was ' || NVL(TO_CHAR(l_next_dumptime), 'NULL')); IF (l_next_dumptime IS NULL) OR ((l_next_dumptime + s_dumper_inhibit_interval) <= SYSTIMESTAMP) THEN -- -- -- UPDATE config SET value = TO_CHAR(SYSTIMESTAMP, DUMPTIME_FORMAT) WHERE name = '_dumper_last_dump_timestamp'; COMMIT; l_job_name := 'RA_DUMPER_' || rai_sq.nextval; trace1 ('WRITE_ERROR dumping job: ' || l_job_name); -- -- -- DBMS_SCHEDULER.CREATE_JOB( job_name => l_job_name ,job_type => 'plsql_block' ,job_action => 'dbms_ra_dump.dumper(' || l_ospid || ',FALSE,TRUE);' ,enabled => TRUE ,auto_drop => TRUE); -- -- -- sys.kbrsi_icd.rsOAMDump; -- -- -- FOR l_x IN 1..360 LOOP DBMS_LOCK.SLEEP(10); make_amjobs (name => l_job_name); EXIT WHEN s_amjobs.COUNT = 0; END LOOP; trace1 ('WRITE_ERROR dump completed'); ELSE ROLLBACK; -- Unlock row in config table if we aren't going to dump. END IF; END IF; END write_error; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE fix_error (p_error_num NUMBER, p_sl_key NUMBER DEFAULT NULL, p_db_key NUMBER DEFAULT NULL, p_param_char VARCHAR2 DEFAULT NULL, p_param_num NUMBER DEFAULT NULL, p_timestamp TIMESTAMP WITH TIME ZONE DEFAULT NULL) IS BEGIN UPDATE error_log SET status = 'FIXED' WHERE error_num = p_error_num AND (p_sl_key IS NULL OR sl_key = p_sl_key) AND (p_db_key IS NULL OR db_key = p_db_key) AND (p_param_char IS NULL OR param_char = p_param_char) AND (p_param_num IS NULL OR param_num = p_param_num) AND (p_timestamp IS NULL OR last_seen < p_timestamp); trace1('FIX_ERROR: Cleared ' || SQL%ROWCOUNT || ' errors for ' || 'error_num=' || p_error_num || '; sl_key=' || print(p_sl_key) || '; db_key=' || print(p_db_key) || '; param_char=' || print(p_param_char) || '; param_num=' || print(p_param_num) || '; timestamp=' || print(TO_CHAR(p_timestamp)) ); END fix_error; -- -- -- -- -- -- -- -- PROCEDURE reset_error (p_incident# NUMBER) IS BEGIN UPDATE error_log SET status = 'RESET' WHERE incident# = p_incident#; trace1('RESET_ERROR: Cleared ' || SQL%ROWCOUNT || ' errors for incident# ' || p_incident#); COMMIT; END reset_error; -- -- -- -- -- PROCEDURE assert_owner IS BEGIN IF SYS.rai_schema(TRUE) <> SYS_CONTEXT('USERENV','SESSION_USER') THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_BAD_USER_NUM, SYS.rai_schema); END IF; END assert_owner; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE purge_immediate(p_sl_key IN NUMBER, p_db_key IN NUMBER, p_allocation IN NUMBER) IS l_task_rec task%ROWTYPE; BEGIN -- trace1 ('PURGE_IMMEDIATE for ' || ' p_sl_key=' || p_sl_key || ', p_db_key=' || p_db_key || ', p_allocation=' || print(p_allocation)); -- -- -- l_task_rec.task_type := TASK_PURGE_IMMEDIATE; l_task_rec.db_key := p_db_key; l_task_rec.sl_key := p_sl_key; -- Used to query task queue. l_task_rec.param_num1 := p_allocation; l_task_rec.flags := 0; new_task(l_task_rec); -- -- -- schedule(p_task_type => TASK_PURGE_IMMEDIATE, p_param1 => p_sl_key); trace1 ('PURGE_IMMEDIATE complete'); END purge_immediate; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE quiesce_rs IS l_lockflag BOOLEAN; l_session_count NUMBER := 1; l_task_rec task%ROWTYPE; l_sessions NUMBER := 1; l_tasks NUMBER; l_backup_pieces NUMBER := 1; l_session_rowids DBMS_SQL.UROWID_TABLE; BEGIN trace1 ('QUIESCE_RS'); -- -- -- -- -- -- -- -- l_lockflag := SYS.KBRSI_ICD.RSKEYWRITELOCK (LOCK_QUIESCE_PENDING, TRUE); trace1 ('QUIESCE_RS: Locking out new backup pieces'); SYS.KBRSI_ICD.RSQUIESCELOCK; trace1 ('QUIESCE_RS: Locking out further activity'); -- -- LOOP -- -- -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); UPDATE task SET pending_interrupt = 0 WHERE (state = STATE_RUNNING) AND (priority >= PRIO_MIN_BUSYWORK) AND pending_interrupt IS NULL; trace1 ('QUIESCE_RS: Requested interrupts for ' || SQL%ROWCOUNT || ' tasks'); COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK; -- -- -- -- -- SELECT COUNT(*) INTO l_tasks FROM task WHERE task_type = TASK_QUIESCE_RS AND state = STATE_EXECUTABLE AND ROWNUM = 1; IF l_tasks = 0 THEN SELECT COUNT(*) INTO l_session_count FROM sessions; FOR i IN 1..l_session_count+1 LOOP l_task_rec.task_type := TASK_QUIESCE_RS; l_task_rec.flags := 0; new_task (task_rec => l_task_rec, p_commit=> FALSE); END LOOP; COMMIT; trace1 ('QUIESCE_RS: Created ' || (l_session_count+1) || ' more quiesce tasks'); -- -- -- SYS.KBRSI_ICD.RSRUNSCHED; END IF; -- -- -- -- -- -- -- -- -- -- BEGIN SELECT COUNT(*) INTO l_sessions FROM sessions s WHERE current_task_type <> TASK_QUIESCE_RS AND current_task <> NVL(s_current_task,-1) AND EXISTS (SELECT 1 FROM sys.rai_active_sessions a WHERE a.inst_id = s.instance_id AND a.audsid = s.audsid AND a.sid = s.sid AND a.serial# = s.serial# AND a.logon_time = s.logon_time); trace1 ('QUIESCE_RS: Waiting for ' || l_sessions || ' sessions'); EXCEPTION WHEN E_PQ_FAILURE THEN save_error; -- trace1 ('QUIESCE_RS: E_PQ_FAILURE'); DBMS_LOCK.SLEEP(1); clear_error; CONTINUE; END; -- -- -- SELECT COUNT(*) INTO l_backup_pieces FROM sbt_catalog WHERE completed = 'N' AND filesize IS NOT NULL; trace1 ('QUIESCE_RS: Waiting for ' || l_backup_pieces || ' b/u pieces'); -- -- -- EXIT WHEN (l_sessions = 0) AND (l_backup_pieces = 0); -- -- -- -- IF (l_backup_pieces <> 0) THEN BEGIN execute_rm_incomplete_files (sbtonly => TRUE); EXCEPTION -- -- -- WHEN E_RETRY_ERROR THEN save_error; clear_error; END; -- -- -- -- -- -- -- -- -- -- -- -- -- -- SELECT ROWID BULK COLLECT INTO l_session_rowids FROM sessions ORDER BY ROWID; FORALL i IN l_session_rowids.FIRST..l_session_rowids.LAST UPDATE sessions SET last_quiesce = SYSTIMESTAMP WHERE ROWID = l_session_rowids(i); COMMIT; SYS.KBRSI_ICD.RSQUIESCEUNLOCK; END IF; -- -- -- IF s_tracing_on THEN FOR sc IN (SELECT ct_key, db_key, handle, pieceinc, filesize, last_entry FROM sbt_catalog WHERE completed = 'N' AND filesize IS NOT NULL) LOOP trace1 ('QUIESCE_RS: Incomplete piece=' || sc.ct_key || ' for db=' || sc.db_key || ' lastentry=' || sc.last_entry || ' filesize=' || sc.filesize); trace1 ('QUIESCE_RS: Handle=' || sc.handle || ' Pieceinc=' || sc.pieceinc); END LOOP; FOR sess IN (SELECT current_task FROM sessions s WHERE current_task_type <> TASK_QUIESCE_RS AND current_task <> NVL(s_current_task,-1)) LOOP trace1 ('QUIESCE_RS: Blocking task=' || sess.current_task); END LOOP; END IF; -- -- -- DBMS_LOCK.SLEEP(s_quiesce_wait); IF (l_backup_pieces <> 0) THEN -- -- -- SYS.KBRSI_ICD.RSQUIESCELOCK; END IF; END LOOP; -- -- -- -- SELECT ROWID BULK COLLECT INTO l_session_rowids FROM sessions ORDER BY ROWID; FORALL i IN l_session_rowids.FIRST..l_session_rowids.LAST UPDATE sessions SET last_quiesce = NULL WHERE ROWID = l_session_rowids(i); COMMIT; trace1 ('QUIESCE_RS: We have quiet.'); END quiesce_rs; -- -- -- -- -- -- PROCEDURE unquiesce_rs IS BEGIN trace1 ('UNQUIESCE_RS'); -- -- -- SYS.KBRSI_ICD.RSQUIESCEUNLOCK; trace1 ('QUIESCE_RS: We no longer have quiet.'); -- -- -- SYS.KBRSI_ICD.RSRUNSCHED; -- -- -- SYS.KBRSI_ICD.RSKEYUNLOCK(LOCK_QUIESCE_PENDING); END unquiesce_rs; -- -- -- -- -- -- -- -- -- -- -- FUNCTION print (p_value IN BOOLEAN) RETURN VARCHAR2 IS BEGIN IF p_value THEN RETURN 'TRUE'; ELSIF p_value IS NULL THEN RETURN 'NULL'; ELSE RETURN 'FALSE'; END IF; END print; FUNCTION print (p_value IN NUMBER) RETURN VARCHAR2 IS BEGIN RETURN NVL(TO_CHAR(p_value),'NULL'); END print; FUNCTION print (p_value IN DSINTERVAL_UNCONSTRAINED) RETURN VARCHAR2 IS BEGIN RETURN NVL(TO_CHAR(p_value),'NULL'); END print; FUNCTION print (p_value IN VARCHAR2) RETURN VARCHAR2 IS BEGIN RETURN NVL(p_value,'***NULL***'); END print; FUNCTION print (p_value IN TIMESTAMP WITH TIME ZONE) RETURN VARCHAR2 IS BEGIN IF p_value IS NULL THEN RETURN '***NULL***'; ELSE RETURN TO_CHAR(p_value, 'DD-MON-YY HH24:MI:SS.FF3'); END IF; END print; FUNCTION print (p_value IN DATE) RETURN VARCHAR2 IS BEGIN IF p_value IS NULL THEN RETURN '***NULL***'; ELSE RETURN TO_CHAR(p_value, 'DD-MON-YY HH24:MI:SS'); END IF; END print; -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION bittst (p_mask IN NUMBER, p_bit IN NUMBER) RETURN BOOLEAN IS BEGIN IF BITAND (p_mask, p_bit) <> 0 THEN RETURN TRUE; ELSE RETURN FALSE; END IF; END bittst; -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION bitclr (p_mask IN NUMBER, p_bit IN NUMBER) RETURN NUMBER IS BEGIN RETURN p_mask - BITAND (p_mask, p_bit); END bitclr; -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION bitset (p_mask IN NUMBER, p_bit IN NUMBER) RETURN NUMBER IS BEGIN RETURN bitclr(p_mask, p_bit) + p_bit; END bitset; -- -- -- -- -- -- -- -- -- -- FUNCTION interval2secs (p_interval IN DSINTERVAL_UNCONSTRAINED) RETURN NUMBER IS l_seconds NUMBER; BEGIN l_seconds := to_number(extract(second from p_interval)) + to_number(extract(minute from p_interval)) * 60 + to_number(extract(hour from p_interval)) * 60 * 60 + to_number(extract(day from p_interval)) * 60 * 60 * 24; RETURN l_seconds; END interval2secs; -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION check_when (p_view IN VARCHAR2, p_task_id IN NUMBER) RETURN BOOLEAN IS l_tmp NUMBER; l_answer BOOLEAN; BEGIN BEGIN IF p_view = 'RAI_STALL_WHEN' THEN EXECUTE IMMEDIATE 'SELECT 1 FROM RAI_STALL_WHEN WHERE TASK_ID = :task' INTO l_tmp USING p_task_id; ELSIF p_view = 'RAI_DEBUG_WHEN' THEN EXECUTE IMMEDIATE 'SELECT 1 FROM RAI_DEBUG_WHEN WHERE TASK_ID = :task' INTO l_tmp USING p_task_id; ELSIF p_view = 'RAI_INTERRUPT_WHEN' THEN EXECUTE IMMEDIATE 'SELECT 1 FROM RAI_INTERRUPT_WHEN WHERE TASK_ID = :task' INTO l_tmp USING p_task_id; ELSE SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Check_when unknown view ' || p_view); END IF; l_answer := TRUE; EXCEPTION WHEN no_data_found THEN save_error; l_answer := FALSE; clear_error; WHEN OTHERS THEN save_error; -- trace1 ('CHECK_WHEN: Error seen is ' || SQLERRM); SYS.KBRSI_ICD.RSCLEARERR; clear_error; END; trace1('check_when: ' || p_view || ' id ' || p_task_id || ' is ' || print(l_answer)); RETURN l_answer; END check_when; -- -- -- -- -- -- -- -- -- -- FUNCTION type2priority (p_tasktype IN NUMBER) RETURN NUMBER IS retval NUMBER; BEGIN retval := CASE p_tasktype WHEN TASK_QUIESCE_RS THEN PRIO_QUIESCE_RS WHEN TASK_SPAWN_SBT THEN PRIO_SPAWN_SBT WHEN TASK_PURGE_DF_NOW THEN PRIO_PURGE_DF_NOW WHEN TASK_RESTORE THEN PRIO_RESTORE WHEN TASK_STORAGE_HISTOGRAM THEN PRIO_STORAGE_HISTOGRAM WHEN TASK_DEFERRED_DELETE THEN PRIO_DEFERRED_DELETE WHEN TASK_GCOPY_COMPUTE THEN PRIO_GCOPY_COMPUTE WHEN TASK_PURGE_IMMEDIATE THEN PRIO_PURGE_IMMEDIATE WHEN TASK_PURGE_DF THEN PRIO_PURGE_DF WHEN TASK_PURGE_DUP_DF THEN PRIO_PURGE_DUP_DF WHEN TASK_TRIM_DB THEN PRIO_TRIM_DB WHEN TASK_DELETE_DB THEN PRIO_DELETE_DB WHEN TASK_BACKUP_ARCH THEN PRIO_BACKUP_ARCH WHEN TASK_INC_ARCH THEN PRIO_INC_ARCH WHEN TASK_PLAN_SBT THEN PRIO_PLAN_SBT WHEN TASK_INDEX_BACKUP THEN PRIO_INDEX_BACKUP WHEN TASK_NEWDFKEY THEN PRIO_NEWDFKEY WHEN TASK_PURGE THEN PRIO_PURGE WHEN TASK_PLAN_DF THEN PRIO_PLAN_DF WHEN TASK_INSERT_FAULT THEN PRIO_INSERT_FAULT WHEN TASK_MOVE_DF THEN PRIO_MOVE_DF WHEN TASK_MOVE_ALL_DB THEN PRIO_MOVE_ALL_DB WHEN TASK_POLL THEN PRIO_POLL WHEN TASK_BACKUP_SBT THEN PRIO_BACKUP_SBT WHEN TASK_RESTORE_SBT THEN PRIO_RESTORE_SBT WHEN TASK_PURGE_SBT THEN PRIO_PURGE_SBT WHEN TASK_OBSOLETE_SBT THEN PRIO_OBSOLETE_SBT WHEN TASK_RM_INCOMPLETE_FILES THEN PRIO_RM_INCOMPLETE_FILES WHEN TASK_DB_STATS_REFRESH THEN PRIO_DB_STATS_REFRESH WHEN TASK_RESTORE_RANGE_REFRESH THEN PRIO_RESTORE_RANGE_REFRESH WHEN TASK_OPTIMIZE_CHUNKS_DF THEN PRIO_OPTIMIZE_CHUNKS_DF WHEN TASK_OPTIMIZE_CHUNKS THEN PRIO_OPTIMIZE_CHUNKS WHEN TASK_REBUILD_INDEX THEN PRIO_REBUILD_INDEX WHEN TASK_VALIDATE_DB THEN PRIO_VALIDATE_DB WHEN TASK_CHECK_FILES THEN PRIO_CHECK_FILES WHEN TASK_CROSSCHECK_DB THEN PRIO_CROSSCHECK_DB WHEN TASK_RECONCILE THEN PRIO_RECONCILE WHEN TASK_REPAIR_DB THEN PRIO_REPAIR_DB ELSE 99999 -- pseudo tasks don't get priorities END; trace1 ('TYPE2PRIORITY: Priority is ' || retval); IF s_safe_mode AND (retval = 99999) THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Task type ' || p_tasktype || ' has no priority'); END IF; RETURN retval; END type2priority; -- -- -- -- -- -- -- -- -- -- FUNCTION tasktype2name (p_task_type NUMBER) RETURN VARCHAR2 IS BEGIN IF p_task_type IS NULL THEN RETURN 'NULL'; END IF; -- -- -- IF NOT s_tasktype2name.EXISTS(p_task_type) THEN FOR tt IN (SELECT task_type, task_type_name FROM tasktypenames) LOOP s_tasktype2name(tt.task_type) := tt.task_type_name; END LOOP; END IF; RETURN s_tasktype2name(p_task_type); EXCEPTION WHEN no_data_found THEN save_error; clear_error; RETURN ('ILLEGAL_' || TO_CHAR(p_task_type)); END tasktype2name; -- -- -- -- -- -- -- -- -- -- FUNCTION taskstate2name (p_task_state NUMBER, p_pending_interrupt NUMBER DEFAULT 0 ) RETURN VARCHAR2 IS l_statestr VARCHAR2(30); BEGIN CASE p_task_state WHEN STATE_EXECUTABLE THEN l_statestr := 'EXECUTABLE'; WHEN STATE_RUNNING THEN l_statestr := 'RUNNING'; WHEN STATE_COMPLETED THEN l_statestr := 'COMPLETED'; WHEN STATE_ORDERING_WAIT THEN l_statestr := 'ORDERING_WAIT'; WHEN STATE_TASK_WAIT THEN CASE p_pending_interrupt WHEN SERVLET_PSEUDO_TASK THEN l_statestr := 'SERVLET_WAIT'; WHEN SPACE_PSEUDO_TASK THEN l_statestr := 'SPACE_WAIT'; WHEN OPT_DF_PSEUDO_TASK THEN l_statestr := 'OPT_DF_WAIT'; WHEN TEST_PSEUDO_TASK THEN l_statestr := 'TEST_WAIT'; WHEN RESOURCE_PSEUDO_TASK THEN l_statestr := 'RESOURCE_WAIT'; WHEN STALL_PSEUDO_TASK THEN l_statestr := 'STALL_WHEN_WAIT'; WHEN LIBRARY_PSEUDO_TASK THEN l_statestr := 'LIBRARY_WAIT'; WHEN POOL_FULL_PSEUDO_TASK THEN l_statestr := 'POOL_FULL_WAIT'; ELSE l_statestr := 'TASK_WAIT'; END CASE; WHEN STATE_RESTORE_WAIT THEN l_statestr := 'RESTORE_WAIT'; WHEN STATE_RETRYING THEN l_statestr := 'RETRYING'; WHEN STATE_FAILED THEN l_statestr := 'FAILED'; WHEN STATE_CANCEL THEN l_statestr := 'CANCEL'; WHEN STATE_CANCELING THEN l_statestr := 'CANCELING'; WHEN STATE_CANCELED THEN l_statestr := 'CANCELED'; ELSE l_statestr := 'ILLEGAL_' || TO_CHAR(p_task_state); /*NF_START*/ END CASE; RETURN l_statestr; END taskstate2name; -- -- -- -- -- -- -- -- -- -- -- PROCEDURE make_amjobs (name VARCHAR2 DEFAULT 'RA$%') IS l_done BOOLEAN := FALSE; BEGIN WHILE NOT l_done LOOP BEGIN SELECT rai_jobs_type(job_name, NVL(instance_id, s_instance), comments) BULK COLLECT INTO s_amjobs FROM user_scheduler_jobs WHERE job_name LIKE name AND enabled = 'TRUE' AND state IN ('RUNNING', 'SCHEDULED'); trace1 ('MAKE_AMJOBS: Rows copied=' || SQL%ROWCOUNT); l_done := TRUE; EXCEPTION WHEN E_PQ_FAILURE THEN save_error; trace1 ('MAKE_AMJOBS: E_PQ_FAILURE'); DBMS_LOCK.SLEEP(1); clear_error; CONTINUE; END; END LOOP; END make_amjobs; -- -- -- -- -- -- -- -- -- PROCEDURE make_amlocks IS l_done BOOLEAN := FALSE; BEGIN WHILE NOT l_done LOOP BEGIN SELECT rai_locks_type(inst_id, ba_type, key, lmode, ctime, sid) BULK COLLECT INTO s_amlocks FROM sys.rai_js_gvlocks; trace1 ('MAKE_AMLOCKS: Rows copied=' || SQL%ROWCOUNT); l_done := TRUE; EXCEPTION WHEN E_PQ_FAILURE THEN save_error; trace1 ('MAKE_AMLOCKS: E_PQ_FAILURE'); DBMS_LOCK.SLEEP(1); clear_error; CONTINUE; END; END LOOP; END make_amlocks; -- -- -- -- -- -- PROCEDURE load_config IS TYPE names_tab IS TABLE OF config.name%TYPE; l_names names_tab; TYPE values_tab IS TABLE OF config.value%TYPE; l_values values_tab; BEGIN IF NOT s_init_done THEN sys.kbrsi_icd.rsSetTrace(1); /* Set up tracing for a new session */ END IF; -- -- -- s_config_time := SYSTIMESTAMP; SELECT name, value BULK COLLECT INTO l_names, l_values FROM config; -- -- -- IF l_names.FIRST IS NULL THEN sys.dbms_sys_error.raise_system_error( E_INTERNAL_ERROR_NUM, 'Config table not initialized'); END IF; -- -- -- FOR i IN l_names.FIRST..l_names.LAST LOOP CASE l_names(i) WHEN '_debug_flags' THEN s_debug_flags := TO_NUMBER(l_values(i)); WHEN '_debug_error' THEN s_debug_error := TO_NUMBER(l_values(i)); WHEN '_trace_file_days' THEN s_trace_file_days := TO_NUMBER(l_values(i)); WHEN '_alloc_increment' THEN s_alloc_increment := TO_NUMBER(l_values(i)); WHEN '_chunk_cache' THEN s_chunk_cache := TO_NUMBER(l_values(i)); WHEN '_chunkno_alloc' THEN s_chunkno_alloc := TO_NUMBER(l_values(i)); WHEN '_purging_reserve' THEN s_purging_reserve := TO_NUMBER(l_values(i)); WHEN '_purge_wait' THEN s_purge_wait := TO_NUMBER(l_values(i)); WHEN '_purge_autoshrink' THEN s_purge_autoshrink := TO_NUMBER(l_values(i)); WHEN '_quiesce_wait' THEN s_quiesce_wait := TO_NUMBER(l_values(i)); WHEN '_quiesce_session_wait_days' THEN s_quiesce_session_wait := NUMTODSINTERVAL(l_values(i), 'DAY'); WHEN '_lock_refused_wait' THEN s_lock_refused_wait := TO_NUMBER(l_values(i)); WHEN '_interrupt_wait' THEN s_interrupt_wait := TO_NUMBER(l_values(i)); WHEN '_purge_threshold' THEN s_purge_threshold := TO_NUMBER(l_values(i)); WHEN '_scheduling_wait' THEN s_scheduling_wait := TO_NUMBER(l_values(i)); WHEN '_session_count' THEN s_session_count := TO_NUMBER(l_values(i)); WHEN '_timer_loop_sleep_seconds' THEN s_timer_loop_sleep := TO_NUMBER(l_values(i)); WHEN '_servlet_wait_seconds' THEN s_servlet_wait_seconds := TO_NUMBER(l_values(i)); WHEN '_db_stats_refresh_days' THEN s_db_stats_refresh_interval := NUMTODSINTERVAL(l_values(i), 'DAY'); WHEN '_histogram_slot_days' THEN s_histogram_slot_interval := NUMTODSINTERVAL(l_values(i), 'DAY'); WHEN '_histogram_cycle_slots' THEN s_histogram_cycle_slots := TO_NUMBER(l_values(i)); WHEN '_histogram_window_slots' THEN s_histogram_window_slots := TO_NUMBER(l_values(i)); WHEN '_histogram_goal_percentile' THEN s_histogram_goal_percentile := TO_NUMBER(l_values(i)); WHEN '_initial_freespace_ratio' THEN s_initial_freespace_ratio := TO_NUMBER(l_values(i)); WHEN '_min_freespace_ratio' THEN s_min_freespace_ratio := TO_NUMBER(l_values(i)); WHEN '_task_maintenance_days' THEN s_task_maintenance_interval := NUMTODSINTERVAL(l_values(i),'DAY'); WHEN '_storage_maintenance_days' THEN s_storage_maintenance_interval := NUMTODSINTERVAL(l_values(i),'DAY'); WHEN '_obsolete_sbt_days' THEN s_obsolete_sbt_interval := NUMTODSINTERVAL(l_values(i), 'DAY'); WHEN '_polling_timeout_days' THEN s_polling_timeout_interval := NUMTODSINTERVAL(l_values(i), 'DAY'); WHEN '_polling_del_files_check_days' THEN s_polling_deleted_files_check := NUMTODSINTERVAL(l_values(i), 'DAY'); WHEN '_history_partition_days' THEN s_history_partition_interval := NUMTODSINTERVAL(l_values(i), 'DAY'); WHEN '_history_retention' THEN s_history_retention := TO_NUMBER(l_values(i)); WHEN '_rm_incomplete_files_days' THEN s_rm_incomplete_files_interval := NUMTODSINTERVAL(l_values(i), 'DAY'); WHEN '_expire_files_days' THEN s_expire_files_interval := NUMTODSINTERVAL(l_values(i), 'DAY'); WHEN '_max_task_restarts' THEN s_max_task_restarts := TO_NUMBER(l_values(i)); WHEN '_interrupt_max' THEN s_interrupt_max := TO_NUMBER(l_values(i)); WHEN '_busy_interrupt_max' THEN s_busy_interrupt_max := TO_NUMBER(l_values(i)); WHEN '_ordering_wait_timeout_days' THEN s_ordering_wait_timeout := TO_NUMBER(l_values(i)); WHEN '_crosscheck_throttle' THEN s_crosscheck_throttle := TO_NUMBER(l_values(i)); WHEN '_optimize_space_limit' THEN s_optimize_space_limit := TO_NUMBER(l_values(i)); WHEN 'percent_late_for_warning' THEN s_late_for_warning := (100 + TO_NUMBER(l_values(i)))/100; WHEN '_orphan_file_wait_days' THEN s_orphan_file_wait := NUMTODSINTERVAL(l_values(i), 'DAY'); WHEN '_restricted_session_count' THEN s_restricted_session_count := TO_NUMBER(l_values(i)); WHEN '_min_sessions_for_busywork' THEN s_min_sessions_for_busywork := TO_NUMBER(l_values(i)); WHEN '_reconcile_short_delay_days' THEN s_reconcile_short_interval := NUMTODSINTERVAL(l_values(i), 'DAY'); WHEN '_reconcile_long_delay_days' THEN s_reconcile_long_interval := NUMTODSINTERVAL(l_values(i), 'DAY'); WHEN '_trim_factor' THEN s_trim_factor := TO_NUMBER(l_values(i)); WHEN '_defer_delete' THEN IF l_values(i) = 'YES' THEN s_defer_delete := 1; ELSE s_defer_delete := 0; END IF; WHEN '_aggressive_delete' THEN IF l_values(i) = 'YES' THEN s_aggressive_delete := 1; ELSE s_aggressive_delete := 0; END IF; WHEN '_dumper_inhibit_days' THEN s_dumper_inhibit_interval := NUMTODSINTERVAL(l_values(i), 'DAY'); WHEN '_check_sbtsched_days' THEN s_check_sbtsched_interval := NUMTODSINTERVAL(l_values(i), 'DAY'); WHEN '_max_sbt_failures' THEN s_max_sbt_failures := TO_NUMBER(l_values(i)); WHEN '_throttle_sbt_active_hours' THEN s_sbt_active_interval := NUMTODSINTERVAL(l_values(i), 'HOUR'); WHEN '_resumable_timeout' THEN -- s_resumable_timeout := GREATEST(NVL(TO_NUMBER(l_values(i)), 0), 0); WHEN '_resource_wait_timeout_days' THEN s_resource_wait_timeout := TO_NUMBER(l_values(i)); WHEN '_resource_wait_relax_rate' THEN s_resource_wait_relax_rate := TO_NUMBER(l_values(i)); WHEN '_busywork_inhibit_time' THEN s_busywork_inhibit_time := NUMTODSINTERVAL(l_values(i), 'DAY'); WHEN '_part_threshold' THEN s_part_threshold := LEAST(TO_NUMBER(l_values(i)), 0.99); WHEN '_part_index_style' THEN s_part_index_style := TO_NUMBER(l_values(i)); WHEN '_part_index_size' THEN s_part_index_size := TO_NUMBER(l_values(i)); WHEN '_part_parallel_degree' THEN s_part_parallel_degree := GREATEST(NVL(TO_NUMBER(l_values(i)), 0), 0); WHEN '_stall_when' THEN IF UPPER(l_values(i)) = 'ON' THEN s_stall_when := TRUE; ELSE s_stall_when := FALSE; END IF; WHEN '_interrupt_when' THEN IF l_values(i) = 'ON' THEN s_interrupt_when := TRUE; ELSE s_interrupt_when := FALSE; END IF; WHEN '_debug_when' THEN s_debug_when := TO_NUMBER(l_values(i)); WHEN '_purge_opt_free' THEN s_purge_opt_free := TO_NUMBER(l_values(i)); WHEN '_purge_opt_pct' THEN s_purge_opt_pct := LEAST(TO_NUMBER(l_values(i)), 0.9); WHEN '_fragmentation' THEN s_fragmentation := TO_NUMBER(l_values(i)); WHEN '_plans_maintained' THEN s_plans_maintained := TO_NUMBER(l_values(i)); WHEN '_baseline_cap' THEN s_baseline_cap := TO_NUMBER(l_values(i)); WHEN '_c2t_optimization' THEN IF l_values(i) = 'ON' THEN s_c2t_optimization := 1; ELSE s_c2t_optimization := 0; END IF; WHEN '_alg_over_alloc' THEN s_alg_over_alloc := TO_NUMBER(l_values(i)); WHEN '_ra_pool_freespace_threshold' THEN s_ra_pool_freespace_threshold := TO_NUMBER(l_values(i)); WHEN '_ra_pool_full_free_count' THEN s_ra_pool_full_free_count := TO_NUMBER(l_values(i)); ELSE NULL; END CASE; END LOOP; -- s_init_done := TRUE; IF s_tracing_on THEN trace1 ('_debug_flags=' || s_debug_flags); trace1 ('_debug_error=' || s_debug_error); trace1 ('_trace_file_days=' || s_trace_file_days); trace1 ('late_for_warning=' || s_late_for_warning); trace1 ('_instance=' || s_instance); trace1 ('_alloc_increment=' || s_alloc_increment); trace1 ('_chunk_cache=' || s_chunk_cache); trace1 ('_chunkno_alloc=' || s_chunkno_alloc); trace1 ('_purging_reserve=' || s_purging_reserve); trace1 ('_purge_wait=' || s_purge_wait); trace1 ('_purge_autoshrink=' || s_purge_autoshrink); trace1 ('_quiesce_wait=' || s_quiesce_wait); trace1 ('_quiesce_session_wait=' || s_quiesce_session_wait); trace1 ('_lock_refused_wait=' || s_lock_refused_wait); trace1 ('_interrupt_wait=' || s_interrupt_wait); trace1 ('_scheduling_wait=' || s_scheduling_wait); trace1 ('_session_count=' || s_session_count); trace1 ('_restricted_session_count =' || s_restricted_session_count); trace1 ('_min_sessions_for_busywork=' || s_min_sessions_for_busywork); trace1 ('_busywork_inhibit_time=' || s_busywork_inhibit_time); trace1 ('_timer_loop_sleep_seconds=' || s_timer_loop_sleep); trace1 ('_db_stats_refresh_interval=' || s_db_stats_refresh_interval); trace1 ('_histogram_slot_days=' || s_histogram_slot_interval); trace1 ('_histogram_cycle_slots=' || s_histogram_cycle_slots); trace1 ('_histogram_window_slots=' || s_histogram_window_slots); trace1 ('_histogram_goal_percentile=' || s_histogram_goal_percentile); trace1 ('_initial_freespace_ratio=' || s_initial_freespace_ratio); trace1 ('_min_freespace_ratio=' || s_min_freespace_ratio); trace1 ('_task_maintenance_days=' || s_task_maintenance_interval); trace1 ('_storage_maintenance_days=' || s_storage_maintenance_interval); trace1 ('_obsolete_sbt_days=' || s_obsolete_sbt_interval); trace1 ('_polling_timeout_days=' || s_polling_timeout_interval); trace1 ('_polling_del_files_check_days=' || s_polling_deleted_files_check); trace1 ('_history_partition_days=' || s_history_partition_interval); trace1 ('_history_retention=' || s_history_retention); trace1 ('_rm_incomplete_files_days=' || s_rm_incomplete_files_interval); trace1 ('_max_task_restarts=' || s_max_task_restarts); trace1 ('_interrupt_max=' || s_interrupt_max); trace1 ('_busy_interrupt_max=' || s_busy_interrupt_max); trace1 ('_busy_interrupt_max=' || s_busy_interrupt_max); trace1 ('_ordering_wait_timeout_days=' || s_ordering_wait_timeout); trace1 ('_crosscheck_throttle=' || s_crosscheck_throttle); trace1 ('_optimize_space_limit=' || s_optimize_space_limit); trace1 ('_expire_files_days=' || s_expire_files_interval); trace1 ('_orphan_file_wait_days=' || s_orphan_file_wait); trace1 ('_reconcile_short_delay_days=' || s_reconcile_short_interval); trace1 ('_reconcile_long_delay_days=' || s_reconcile_long_interval); trace1 ('_trim_factor=' || s_trim_factor); trace1 ('_defer_delete= ' || s_defer_delete); trace1 ('_aggressive_delete=' || s_aggressive_delete); trace1 ('_dumper_inhibit_interval=' || s_dumper_inhibit_interval); trace1 ('_check_sbtsched_days=' || s_check_sbtsched_interval); trace1 ('_max_sbt_failures=' || s_max_sbt_failures); trace1 ('_throttle_sbt_active_hours=' || s_sbt_active_interval); trace1 ('_resumable_timeout=' || s_resumable_timeout); trace1 ('_resource_wait_timeout=' || s_resource_wait_timeout); trace1 ('_resource_wait_relax_rate=' || s_resource_wait_relax_rate); trace1 ('_purge_opt_free=' || s_purge_opt_free); trace1 ('_purge_opt_pct=' || s_purge_opt_pct); trace1 ('_fragmentation=' || s_fragmentation); trace1 ('_plans_maintained=' || s_plans_maintained); trace1 ('_part_threshold=' || s_part_threshold); trace1 ('_part_index_style=' || s_part_index_style); trace1 ('_part_index_size=' || s_part_index_size); trace1 ('_part_parallel_degree=' || s_part_parallel_degree); trace1 ('_stall_when=' || print(s_stall_when)); trace1 ('_interrupt_when=' || print(s_interrupt_when)); trace1 ('_debug_when=' || print(s_debug_when)); trace1 ('_c2t_optimization=' || print(s_c2t_optimization)); trace1 ('_baseline_cap=' || print(s_baseline_cap)); trace1 ('_alg_over_alloc=' || s_alg_over_alloc); trace1 ('_ra_pool_freespace_threshold=' || s_ra_pool_freespace_threshold); trace1 ('_ra_pool_full_free_count=' || s_ra_pool_full_free_count); END IF; EXCEPTION WHEN OTHERS THEN save_error; SYS.DBMS_SYSTEM.KSDWRT(SYS.DBMS_SYSTEM.TRACE_FILE, 'LOAD_CONFIG failed with ' || SQLERRM); RAISE; END load_config; -- -- -- -- -- -- -- -- -- -- PROCEDURE tracex (message IN VARCHAR2) IS l_pos NUMBER := 1; l_hdr VARCHAR2(100); BEGIN -- -- -- IF NOT s_init_done THEN load_config; s_init_done := TRUE; END IF; -- IF s_tracing_on THEN l_hdr := TO_CHAR(SYSTIMESTAMP, 'HH24:MI:SS.FF3') || ' RSJS:'; ELSE l_hdr := 'RSJS:'; END IF; -- -- -- LOOP sys.kbrsi_icd.rsTrace(l_hdr || SUBSTR(message, l_pos, 1000)); l_pos := l_pos+1000; EXIT WHEN l_pos > LENGTH(message); END LOOP; END tracex; -- -- -- -- -- -- -- -- PROCEDURE trace1 (message IN VARCHAR2) IS C_LINELEN CONSTANT PLS_INTEGER := 200-18; C_NEWLINE CONSTANT CHAR(1) := CHR(10); --linefeed l_msglen PLS_INTEGER := LENGTH(message); l_nextbuf VARCHAR2(200); l_pos PLS_INTEGER := 1; l_endpos PLS_INTEGER; l_offset PLS_INTEGER; BEGIN -- -- -- IF NOT s_init_done THEN load_config; s_init_done := TRUE; END IF; -- -- -- -- -- -- -- -- IF s_tracing_on THEN WHILE l_msglen >= l_pos LOOP l_offset := 0; l_nextbuf := SUBSTR(message,l_pos,C_LINELEN); IF INSTR(l_nextbuf, C_NEWLINE) > 0 THEN l_endpos := INSTR(l_nextbuf,C_NEWLINE); l_offset := -1; ELSIF l_msglen + 1 - l_pos <= C_LINELEN THEN l_endpos := C_LINELEN; ELSIF INSTR(l_nextbuf, ' ', -1) > 0 THEN l_endpos := INSTR(l_nextbuf, ' ', -1); l_offset := -1; ELSE l_endpos := C_LINELEN; END IF; SYS.KBRSI_ICD.RSTRACE('RSJS:' || SUBSTR(l_nextbuf, 1, l_endpos+l_offset)); l_pos := l_pos + l_endpos; END LOOP; END IF; END trace1; -- -- PROCEDURE setTracing(p_trc_on IN NUMBER, p_perf_on IN NUMBER DEFAULT 0, p_stall_on IN NUMBER DEFAULT 0, p_safe_mode IN NUMBER DEFAULT 0) IS BEGIN s_tracing_on := (p_trc_on > 0); s_perf_on := (p_perf_on > 0); s_safe_mode := (p_safe_mode > 0); END setTracing; -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE stop_scheduler_jobs (p_stop_jobs IN NUMBER, p_instance_only IN BOOLEAN, p_db_key IN NUMBER DEFAULT NULL) IS -- TYPE sched_jobs_record_t IS RECORD ( job_name DBMS_ID, ord NUMBER, instance_id NUMBER, current_task NUMBER, current_task_type NUMBER ); -- TYPE sched_jobs_cursor_t IS REF CURSOR RETURN sched_jobs_record_t; l_instance NUMBER := NULL; l_all_gone BOOLEAN; l_jobs_cursor sched_jobs_cursor_t; l_jobs_rec sched_jobs_record_t; l_timers_gone BOOLEAN; l_debug_flags NUMBER; KBRSTRC_STALL CONSTANT NUMBER := TO_NUMBER('02000000','XXXXXXXX'); l_stall_on_error BOOLEAN; BEGIN -- IF p_stop_jobs = STOP_JOBS_ALL THEN NULL; ELSIF p_stop_jobs = STOP_JOBS_DB THEN IF p_db_key IS NULL THEN sys.dbms_sys_error.raise_system_error(E_INTERNAL_ERROR_NUM, 'STOP_SCHEDULER_JOBS: STOP_JOBS_DB: NULL p_db_key'); END IF; IF p_instance_only THEN sys.dbms_sys_error.raise_system_error(E_INTERNAL_ERROR_NUM, 'STOP_SCHEDULER_JOBS: STOP_JOBS_DB: p_instance_only is TRUE'); END IF; ELSE sys.dbms_sys_error.raise_system_error(E_INTERNAL_ERROR_NUM, 'STOP_SCHEDULER_JOBS: invalid p_stop_jobs'); END IF; IF p_instance_only THEN -- -- -- l_instance := s_instance; END IF; -- -- -- -- -- FOR i in 1..600 LOOP -- -- -- trace1 ('STOP_SCHEDULER_JOBS: Loop ' || i); l_all_gone := TRUE; l_timers_gone := FALSE; BEGIN -- SELECT NVL(MAX(TO_NUMBER(value)), 0) INTO l_debug_flags FROM config WHERE name = '_debug_flags'; -- l_stall_on_error := (BITAND(l_debug_flags, KBRSTRC_STALL) <> 0); make_amjobs; -- IF p_stop_jobs = STOP_JOBS_ALL THEN -- OPEN l_jobs_cursor FOR -- -- -- SELECT job_name, ord, instance_id, current_task, current_task_type FROM (SELECT job_name, DECODE(SUBSTR(job_name,1,9), 'RA$_TIMER', 1, NVL2(current_task,2,3)) ord, amjobs.instance_id, current_task, current_task_type FROM TABLE(CAST(s_amjobs AS rai_jobs_table_type)) amjobs LEFT OUTER JOIN sessions USING (job_name) WHERE job_name LIKE 'RA$%' AND job_name NOT LIKE 'RA$TRIG%' AND amjobs.instance_id = NVL(l_instance,amjobs.instance_id)) ORDER BY ord; ELSE -- OPEN l_jobs_cursor FOR SELECT j.job_name, 2, j.instance_id, s.current_task, s.current_task_type FROM TABLE(CAST(dbms_ra_scheduler.s_amjobs AS rai_jobs_table_type)) j, sessions s, task t WHERE j.job_name = s.job_name AND j.instance_id = s.instance_id AND s.ba_session_id = t.ba_session_id AND t.db_key = p_db_key AND delete_db_task_is_benign(t.task_type) = DB_TASK_IS_NOT_BENIGN; END IF; -- LOOP FETCH l_jobs_cursor INTO l_jobs_rec; EXIT WHEN l_jobs_cursor%NOTFOUND; IF p_stop_jobs = STOP_JOBS_ALL AND NOT l_timers_gone AND l_jobs_rec.ord > 1 THEN -- -- -- IF NOT l_stall_on_error THEN SYS.KBRSI_ICD.RSRUNSCHED; END IF; l_timers_gone := TRUE; END IF; BEGIN trace1 ('STOP_SCHEDULER_JOBS: Killing ' || l_jobs_rec.job_name || ' on instance ' || l_jobs_rec.instance_id); DBMS_SCHEDULER.STOP_JOB(job_name => l_jobs_rec.job_name, force => TRUE); EXCEPTION WHEN OTHERS THEN save_error; -- -- -- -- trace1 ('STOP_SCHEDULER_JOBS: Error seen is ' || SQLERRM); SYS.KBRSI_ICD.RSCLEARERR; l_all_gone := FALSE; -- -- -- -- IF (i >= 10) AND (l_jobs_rec.ord > 1) THEN log_error (p_errno => E_COULDNT_STOP_JOB_NUM, p_param1 => l_jobs_rec.job_name, p_param2 => print(l_jobs_rec.current_task), p_param3 => tasktype2name(l_jobs_rec.current_task_type), p_param4 => i, p_keep_stack => TRUE, p_component => 'SHUTDOWN', p_severity => SEVERITY_WARNING, p_param_char => l_jobs_rec.job_name); END IF; clear_error; CONTINUE; END; END LOOP; EXCEPTION WHEN E_ROW_CACHE_LOCK THEN save_error; trace1 ('STOP_SCHEDULER_JOBS: Row cache lock problem'); DBMS_LOCK.SLEEP(6); l_all_gone := FALSE; clear_error; CONTINUE; WHEN E_PQ_FAILURE THEN save_error; trace1 ('STOP_SCHEDULER_JOBS: E_PQ_FAILURE'); l_all_gone := FALSE; clear_error; CONTINUE; END; -- IF l_all_gone THEN EXIT; END IF; DBMS_LOCK.SLEEP(1); END LOOP; END stop_scheduler_jobs; -- -- -- -- -- -- -- -- -- -- -- PROCEDURE stop (p_instance_only IN BOOLEAN DEFAULT FALSE, p_quiesce_first IN BOOLEAN DEFAULT FALSE) IS l_instance NUMBER := NULL; l_schema all_tables.owner%TYPE; l_ddl VARCHAR2(200); l_all_gone BOOLEAN; l_need_unquiesce BOOLEAN := FALSE; BEGIN -- -- sys.kbrsi_icd.rsSetTrace; trace1 ('STOP: p_instance_only=' || print(p_instance_only) || ', p_quiesce_first=' || print(p_quiesce_first)); trace1 ('STOP: For schema ' || SYS_CONTEXT('USERENV', 'SESSION_USER')); -- -- -- l_schema := SYS_CONTEXT('USERENV', 'SESSION_USER'); IF l_schema = 'SYS' THEN -- -- -- l_schema := SYS.rai_schema; l_ddl := 'ALTER SESSION SET CURRENT_SCHEMA =' || l_schema; EXECUTE IMMEDIATE l_ddl; trace1 ('STOP: Schema set to ' || l_schema); END IF; IF NOT p_instance_only THEN IF p_quiesce_first THEN -- -- -- DBMS_RA_INT.LOCK_API_INT(DBMS_RA.LOCKAPI_DELETE, 'stop recovery appliance'); -- -- -- -- l_need_unquiesce := TRUE; quiesce_rs (); END IF; -- -- -- trace1 ('STOP: Turn off recovery appliance state'); UPDATE config SET value = 'OFF' WHERE (name = '_recovery_appliance_state'); COMMIT; END IF; -- -- -- stop_scheduler_jobs (STOP_JOBS_ALL, p_instance_only); -- -- -- IF l_need_unquiesce THEN unquiesce_rs; l_need_unquiesce := FALSE; END IF; -- -- -- fix_error(p_error_num => E_SHUTTING_DOWN_NUM); COMMIT; -- -- -- IF p_quiesce_first THEN DBMS_RA_INT.UNLOCK_API_INT (p_the_num=>0, p_results=>FALSE, p_docommit=>FALSE); END IF; EXCEPTION WHEN e_bad_user THEN save_error; RAISE; WHEN OTHERS THEN save_error; IF l_need_unquiesce THEN unquiesce_rs; END IF; -- -- -- IF p_quiesce_first THEN DBMS_RA_INT.UNLOCK_API_INT (p_the_num=>0, p_results=>FALSE, p_docommit=>FALSE); END IF; trace1 ('STOP: Exception for ' || SQLERRM); -- -- -- log_error(p_errno => E_INTERNAL_ERROR_NUM, p_param1 => 'failure during shutdown or abort', p_component => 'SHUTDOWN', p_severity => SEVERITY_INTERNAL); RAISE; END stop; -- -- -- -- FUNCTION queue_one_sbt_backup_task( p_db_key IN NUMBER, p_bs_key IN NUMBER, p_piece_no IN NUMBER, p_template_key IN NUMBER, p_full_template_key IN NUMBER, p_attr_set_key IN NUMBER, p_lib_key IN NUMBER, p_copies IN NUMBER, p_src_bpkey IN NUMBER DEFAULT NULL, p_delete_source IN VARCHAR2 DEFAULT 'N', p_format IN VARCHAR2 DEFAULT NULL, p_rep_server_key IN NUMBER DEFAULT NULL ) RETURN BOOLEAN IS new_task_rec task%ROWTYPE; l_spawn_job BOOLEAN; l_count NUMBER; l_rep_srvr_status rep_server.status%TYPE; BEGIN -- new_task_rec.task_type := TASK_BACKUP_SBT; new_task_rec.flags := 0; new_task_rec.db_key := p_db_key; new_task_rec.param_num1 := p_bs_key; new_task_rec.param_num2 := p_template_key; new_task (task_rec => new_task_rec, p_commit => FALSE, p_sbt_task => TRUE); trace1('QUEUE_ONE_SBT_BACKUP_TASK - add task: ' || ' p_db_key=' || p_db_key || ', p_bs_key=' || p_bs_key || ', p_piece_no=' || p_piece_no || ', p_src_bp_key=' || p_src_bpkey || ', p_template_key=' || p_template_key || ', p_attr_set_key=' || p_attr_set_key || ', p_lib_key=' || p_lib_key || ', p_copies=' || p_copies || ', p_delete_source=' || p_delete_source || ', p_format=' || p_format || ', p_rep_server_key=' || p_rep_server_key || ', new_task_rec.task_id=' || new_task_rec.task_id); INSERT INTO sbt_task (task_id, bs_key, piece#, rep_server_key, template_key, full_template_key, attr_key, lib_key, copies, failure_cnt, restore, src_bpkey, delete_source, format) VALUES (new_task_rec.task_id, p_bs_key, p_piece_no, p_rep_server_key, p_template_key, p_full_template_key, p_attr_set_key, p_lib_key, p_copies, 0, 'N', p_src_bpkey, p_delete_source, p_format); -- COMMIT; -- l_spawn_job := TRUE; -- -- new_task_rec := NULL; new_task_rec.task_type := TASK_PLAN_SBT; new_task_rec.flags := 0; new_task_rec.db_key := p_db_key; new_task_rec.param := p_bs_key; -- -- -- -- SELECT MAX(dbms_ra_pool.incrLevel(d.create_scn, d.incr_scn)) + COUNT(*) INTO l_count FROM bdf d WHERE bs_key = p_bs_key; -- IF l_count = 1 THEN new_task_rec.param_num3 := dbms_ra_pool.KBRSPLBLD_PIECE; ELSE new_task_rec.param_num3 := dbms_ra_pool.KBRSPLBLD_ORIGPIECE; END IF; -- -- FOR i IN (SELECT df_key, vb_key FROM bp JOIN bdf USING (bs_key) JOIN df USING (dbinc_key, create_scn, file#) WHERE bs_key = p_bs_key AND piece# = p_piece_no AND status != 'D' AND vb_key IS NOT NULL) LOOP new_task_rec.param_num1 := i.df_key; new_task_rec.param_num2 := i.vb_key; new_task (task_rec => new_task_rec, p_commit => FALSE); END LOOP; COMMIT; -- -- -- SYS.KBRSI_ICD.RSRUNSCHED; trace1('QUEUE_ONE_SBT_BACKUP_TASK: completed'); RETURN l_spawn_job; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN ROLLBACK; save_error; -- -- IF (SQLERRM NOT LIKE '%SBT_TASK_U1%') THEN trace1 ('QUEUE_ONE_SBT_BACKUP_TASK: dup_val error - ' || SQLERRM); RAISE; END IF; trace1 ('QUEUE_ONE_SBT_BACKUP_TASK: Skipping existing sbt_task'); clear_error; RETURN FALSE; WHEN OTHERS THEN save_error; trace1 ('QUEUE_ONE_SBT_BACKUP_TASK: error - ' || SQLERRM); RAISE; END queue_one_sbt_backup_task; -- -- -- -- PROCEDURE queue_sbt_backup_task(template_name IN VARCHAR2, src_bpkey IN NUMBER DEFAULT NULL, delete_source IN VARCHAR2 DEFAULT 'N', format IN VARCHAR2 DEFAULT NULL) IS -- CURSOR odb_cursor(template_key IN NUMBER) IS SELECT odb.db_key, job.bck_type, job.full_template_key FROM odb, sbt_job_template job WHERE odb.prot_key = nvl(job.prot_key, odb.prot_key) AND odb.db_key = nvl(job.db_key, odb.db_key) AND job.template_key = odb_cursor.template_key ORDER BY 1; l_last_bp_key NUMBER; l_max_bp_key NUMBER; l_locked BOOLEAN := FALSE; l_spawn_job BOOLEAN := FALSE; l_db_key NUMBER; l_bck_type NUMBER; l_template_key NUMBER; l_full_template_key NUMBER; l_full_attr_key NUMBER; l_full_lib_key NUMBER; l_attr_key NUMBER; l_lib_key NUMBER; l_bs_key NUMBER; l_piece_no NUMBER; l_copies NUMBER; job_exists NUMBER; l_lib_status sbt_lib_desc.status%TYPE; l_sbt_task NUMBER; l_dbid NUMBER; l_currinc NUMBER; l_db_slkey NUMBER; l_is_dest_repserver NUMBER; l_baseline_scn NUMBER; l_init_cf_bs_key NUMBER; l_all_bck_type BOOLEAN := FALSE; l_from_tag sbt_job_template.from_tag%TYPE; l_prot_key sbt_job_template.prot_key%TYPE; l_server_key NUMBER; l_rep_srvr_status rep_server.status%TYPE; l_rep_bp_cnt NUMBER; BEGIN trace1 ('QUEUE_SBT_BACKUP_TASK: ' || template_name || '; src_bpkey=' || src_bpkey); -- SELECT job.template_key, job.attr_key, job.copies, attr.lib_key, lib.status, job.from_tag, job.prot_key INTO l_template_key, l_attr_key, l_copies, l_lib_key, l_lib_status, l_from_tag, l_prot_key FROM sbt_job_template job, sbt_attr_set attr, sbt_lib_desc lib WHERE job.template_name = queue_sbt_backup_task.template_name AND job.attr_key = attr.attr_key AND attr.lib_key = lib.lib_key; trace1 ('QUEUE_SBT_BACKUP_TASK: l_attr_key=' || l_attr_key || ',l_template_key=' || l_template_key || ',l_lib_key=' || l_lib_key); -- -- -- -- -- -- -- -- IF src_bpkey IS NULL THEN -- -- IF (NOT dbms_ra_int.write_lock_wait(DBMS_RA_INT.KEY_SY, l_lib_key)) THEN RAISE no_data_found; END IF; l_locked := TRUE; -- OPEN odb_cursor(l_template_key); LOOP <> FETCH odb_cursor INTO l_db_key, l_bck_type, l_full_template_key; EXIT WHEN odb_cursor%NOTFOUND; -- IF l_full_template_key IS NOT NULL THEN SELECT job.attr_key, attr.lib_key INTO l_full_attr_key, l_full_lib_key FROM sbt_job_template job, sbt_attr_set attr, sbt_lib_desc lib WHERE job.template_key = l_full_template_key AND job.attr_key = attr.attr_key AND attr.lib_key = lib.lib_key; trace1 ('QUEUE_SBT_BACKUP_TASK: ' || 'l_full_attr_key=' || l_full_attr_key || ',l_full_template_key=' || l_full_template_key || ',l_full_lib_key=' || l_full_lib_key); END IF; l_all_bck_type := (bitand(l_bck_type, 1) = 1); SELECT curr_dbinc_key INTO l_currinc FROM DB WHERE db_key = l_db_key; -- -- -- SELECT nvl(max(baseline_scn), 0) INTO l_baseline_scn FROM sbt_template_db WHERE db_key = l_db_key AND template_key = l_full_template_key; SELECT nvl(max(last_bp_key), 0) INTO l_last_bp_key FROM sbt_template_db WHERE db_key = l_db_key AND template_key = l_template_key; -- -- IF s_c2t_optimization = 0 THEN l_last_bp_key := 0; l_baseline_scn := 0; END IF; -- BEGIN SELECT rs.server_key, rs.status INTO l_server_key , l_rep_srvr_status FROM odb o, rep_server rs, sbt_job_template j, sbt_lib_desc l, sbt_attr_set a WHERE o.db_key=l_db_key AND j.template_key=l_template_key AND l.lib_key=l_lib_key AND a.attr_key=l_attr_key AND l.lib_key=a.lib_key AND a.attr_key=j.attr_key AND o.prot_key=rs.prot_key AND rs.server_key=l.server_key; IF l_rep_srvr_status != 'A' THEN trace1('QUEUE_SBT_BACKUP_TASK: not active rep server'); RETURN; END IF; SELECT COUNT(*) INTO l_rep_bp_cnt FROM bp WHERE bp.db_key = l_db_key AND bp.vb_key IS NOT NULL AND bp.status = 'A' AND ROWNUM = 1; -- IF l_rep_bp_cnt = 0 THEN trace1('QUEUE_SBT_BACKUP_TASK: no DB backup for replication ' || ' l_db_key=' || l_db_key || ' l_template_key=' || l_template_key); CONTINUE; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN l_server_key := NULL; END; trace1('QUEUE_SBT_BACKUP_TASK: is server_key= ' || l_server_key ); -- -- SELECT NVL(MAX(bp_key), 0) INTO l_max_bp_key FROM bp; -- -- -- -- IF (l_all_bck_type OR (bitand(l_bck_type, 2) = 2)) THEN -- -- -- trace1('QUEUE_SBT_BACKUP_TASK: validate base level backup'); inValidateBaseLevelBcks (l_db_key, l_currinc, l_template_key, l_baseline_scn); trace1('QUEUE_SBT_BACKUP_TASK: queue level 0 full backups'); queueBaseLevelBcks(p_db_key => l_db_key, p_dbid => l_dbid, p_currinc => l_currinc, p_db_slkey => l_db_slkey, p_from_tag => l_from_tag, p_template_key => l_template_key, p_baseline_scn => l_baseline_scn, p_lib_key => l_lib_key, p_attr_key => l_attr_key, p_copies => l_copies, p_delete_source => delete_source, p_format => format, p_last_bp_key => l_last_bp_key, p_max_bp_key => l_max_bp_key, p_server_key => l_server_key ); logMissingDfBcksError(p_db_key => l_db_key, p_currinc => l_currinc, p_template_key => l_template_key); END IF; -- -- IF l_baseline_scn = 0 and ((bitand(l_bck_type, 4) = 4) or (bitand(l_bck_type, 8) = 8)) THEN trace1 ('QUEUE_SBT_BACKUP_TASK initial base full backup not sent'); END IF; IF l_baseline_scn > 0 THEN SELECT COUNT(*) INTO l_init_cf_bs_key FROM sbt_template_df WHERE template_key = l_template_key AND db_key = l_db_key AND df_file# <= 0 AND bs_key IS NULL; END IF; -- IF ((l_baseline_scn > 0) AND (l_all_bck_type OR (bitand(l_bck_type, 4) = 4))) THEN IF (NOT l_all_bck_type) THEN trace1('QUEUE_SBT_BACKUP_TASK: queue level 0 missing DF backups'); queueMissingDFBcks(p_db_key => l_db_key, p_from_tag => l_from_tag, p_template_key => l_full_template_key, p_baseline_scn => l_baseline_scn, p_lib_key => l_full_lib_key, p_attr_key => l_full_attr_key, p_copies => l_copies, p_delete_source => delete_source, p_format => format, p_last_bp_key => l_last_bp_key, p_server_key => l_server_key ); logMissingDfBcksError(p_db_key => l_db_key, p_currinc => l_currinc, p_template_key => l_full_template_key); END IF; trace1('QUEUE_SBT_BACKUP_TASK: queue incremental backups'); queueIncrementalBcks(p_db_key => l_db_key, p_from_tag => l_from_tag, p_template_key => l_template_key, p_full_template_key => l_full_template_key, p_baseline_scn => l_baseline_scn, p_lib_key => l_lib_key, p_attr_key => l_attr_key, p_copies => l_copies, p_delete_source => delete_source, p_format => format, p_init_cf_bs_key => l_init_cf_bs_key, p_last_bp_key => l_last_bp_key, p_server_key => l_server_key ); END IF; -- IF ((l_baseline_scn > 0) AND (l_all_bck_type OR (bitand(l_bck_type, 8) = 8))) THEN trace1('QUEUE_SBT_BACKUP_TASK: queue archived log backups'); queueArchivedLogBcks(p_db_key => l_db_key, p_from_tag => l_from_tag, p_template_key => l_template_key, p_full_template_key => l_full_template_key, p_baseline_scn => l_baseline_scn, p_lib_key => l_lib_key, p_attr_key => l_attr_key, p_copies => l_copies, p_delete_source => delete_source, p_format => format, p_init_cf_bs_key => l_init_cf_bs_key, p_last_bp_key => l_last_bp_key, p_server_key => l_server_key ); END IF; -- IF ((l_baseline_scn > 0) AND (l_server_key > 0)) THEN trace1('QUEUE_SBT_BACKUP_TASK: queue keep backups'); queueKeepBcks(p_db_key => l_db_key, p_from_tag => l_from_tag, p_template_key => l_template_key, p_baseline_scn => l_baseline_scn, p_lib_key => l_lib_key, p_attr_key => l_attr_key, p_copies => l_copies, p_delete_source => delete_source, p_format => format, p_last_bp_key => l_last_bp_key, p_server_key => l_server_key ); END IF; -- IF (l_baseline_scn > 0 AND s_c2t_optimization = 1) THEN BEGIN INSERT INTO sbt_template_db (db_key, template_key, baseline_scn, last_bp_key, curr_dbinc_key) VALUES (l_db_key, l_template_key, l_baseline_scn, l_max_bp_key, l_currinc); trace1('QUEUE_SBT_BACKUP_TASK row inserted to sbt_template_db' || ' l_db_key=' || l_db_key || ' l_template_key=' || l_template_key); EXCEPTION WHEN dup_val_on_index THEN save_error; -- UPDATE sbt_template_db SET last_bp_key = l_max_bp_key WHERE template_key = l_template_key AND db_key = l_db_key AND last_bp_key < l_max_bp_key; trace1('QUEUE_SBT_BACKUP_TASK: updated sbt_template_db' || ' l_template_key=' || l_template_key || ' l_db_key=' || l_db_key || ' l_max_bp_key=' || l_max_bp_key || ' rows updated=' || SQL%ROWCOUNT); clear_error; END; COMMIT; END IF; END LOOP; CLOSE odb_cursor; -- dbms_ra_int.unlock(DBMS_RA_INT.KEY_SY, l_lib_key); l_locked := FALSE; ELSE -- -- -- SELECT full_template_key INTO l_full_template_key FROM sbt_job_template WHERE template_key=l_template_key; SELECT bs_key, piece#, db_key INTO l_bs_key, l_piece_no, l_db_key FROM bp WHERE bp_key=src_bpkey; l_spawn_job := queue_one_sbt_backup_task( p_db_key => l_db_key, p_bs_key => l_bs_key, p_piece_no => l_piece_no, p_template_key => l_template_key, p_full_template_key => l_full_template_key, p_attr_set_key => l_attr_key, p_lib_key => l_lib_key, p_copies => l_copies, p_src_bpkey => src_bpkey, p_delete_source => delete_source, p_format => format ); END IF; UPDATE sbt_job_template job SET job.schedule_time = SYSTIMESTAMP, job.completion_time = nvl2(job.window, job.window + SYSTIMESTAMP, null) WHERE job.template_key = l_template_key; COMMIT; IF (NOT l_spawn_job) THEN trace1 ('QUEUE_SBT_BACKUP_TASK complete with no job'); -- SELECT count(*) INTO l_sbt_task FROM sbt_task t WHERE t.restore = 'N' AND t.template_key = l_template_key AND ROWNUM = 1; IF (l_sbt_task = 0) THEN trace1 ('QUEUE_SBT_BACKUP_TASK no sbt_task queued'); RETURN; END IF; END IF; IF (l_lib_status != 'R') THEN trace1 ('QUEUE_SBT_BACKUP_TASK complete as library is not ready'); RETURN; END IF; queue_spawn_sbt(p_libkey => l_lib_key, p_forpurge => FALSE); trace1 ('QUEUE_SBT_BACKUP_TASK complete'); EXCEPTION WHEN no_data_found THEN save_error; trace1 ('QUEUE_SBT_BACKUP_TASK handling no_data_found'); -- IF (l_locked) THEN dbms_ra_int.unlock(DBMS_RA_INT.KEY_SY, l_lib_key); END IF; -- SELECT count(*) INTO job_exists FROM sbt_job_template job WHERE job.template_name = queue_sbt_backup_task.template_name; -- IF (job_exists = 0) THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( E_SBT_JOB_NOTFOUND_NUM, template_name); ELSE RAISE; END IF; WHEN OTHERS THEN save_error; -- IF (l_locked) THEN dbms_ra_int.unlock(DBMS_RA_INT.KEY_SY, l_lib_key); END IF; RAISE; END queue_sbt_backup_task; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION reconcile_it (p_db_key IN NUMBER, p_lib_key IN NUMBER, p_server_key IN NUMBER, p_force_reconcile IN BOOLEAN DEFAULT FALSE) RETURN BOOLEAN IS l_status sbt_lib_desc.status%TYPE; l_cnt NUMBER; l_err_cnt NUMBER := 0; DB_INC_NOT_CURRENT EXCEPTION; DB_INC_NOT_FOUND EXCEPTION; PRAGMA EXCEPTION_INIT(DB_INC_NOT_CURRENT, -20011); PRAGMA EXCEPTION_INIT(DB_INC_NOT_FOUND, -20003); BEGIN trace1 ('RECONCILE_IT: replication cursor ' || ' p_db_key=' || p_db_key || ', p_lib_key=' || p_lib_key || ', p_server_key=' || p_server_key); SELECT count(*) INTO l_cnt FROM sbt_lib_desc WHERE lib_key = p_lib_key; IF l_cnt = 0 THEN -- trace1 ('RECONCILE_IT: Replication Server Library no longer exists (' || p_lib_key || ') - returning '); RETURN FALSE; END IF; -- -- -- -- IF NOT DBMS_RA_INT.READ_LOCK(DBMS_RA_INT.KEY_SY, p_lib_key) THEN trace1 ('RECONCILE_IT: Replication Server Library (' || p_lib_key || ') - returning - unable to get lock'); RETURN FALSE; END IF; SELECT status INTO l_status FROM sbt_lib_desc WHERE lib_key = p_lib_key; IF NOT p_force_reconcile AND (l_status = 'P') THEN -- -- -- DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_SY, p_lib_key); trace1 ('RECONCILE_IT: User paused lib_key=' || p_lib_key); RETURN FALSE; END IF; IF NOT p_force_reconcile AND (l_status = 'E') THEN -- -- -- DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_SY, p_lib_key); trace1 ('RECONCILE_IT: Library is in "E"rror condition lib_key=' || p_lib_key); RETURN FALSE; END IF; BEGIN dbms_rcvcat.doReplicationReconcile(p_db_key => p_db_key, p_lib_key => p_lib_key, p_server_key => p_server_key); -- -- UPDATE sbt_lib_desc SET status = (CASE WHEN status = 'E' THEN 'R' ELSE status END), failure_cnt = 0 WHERE lib_key = p_lib_key; -- fix_error (p_error_num => E_REPLICATION_ERROR_NUM, p_db_key => p_db_key, p_param_num => p_lib_key); -- COMMIT; EXCEPTION -- -- WHEN DB_INC_NOT_CURRENT OR DB_INC_NOT_FOUND THEN save_error; -- -- -- sys.kbrsi_icd.rsClearErr; clear_error; -- WHEN OTHERS THEN l_err_cnt := l_err_cnt + 1; save_error; -- -- log_sbt_error(p_db_key, p_lib_key, 0, FALSE); sys.kbrsi_icd.rsClearErr; clear_error; -- END; -- -- -- DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_SY, p_lib_key); RETURN (l_err_cnt = 0); EXCEPTION WHEN OTHERS THEN save_error; DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_SY, p_lib_key); RAISE; END reconcile_it; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION reconcile_db (p_db_key IN NUMBER, p_server_key IN NUMBER DEFAULT NULL, p_only_active IN BOOLEAN DEFAULT TRUE, p_force_reconcile IN BOOLEAN DEFAULT FALSE, rec_cnt OUT NUMBER ) RETURN BOOLEAN IS CURSOR rep_server_cursor (in_db_key IN NUMBER) IS SELECT l.lib_key, rs.server_key, rs.status FROM odb o, rep_server rs, sbt_lib_desc l WHERE o.db_key=in_db_key AND o.prot_key=rs.prot_key AND rs.server_key=l.server_key; l_lib_key NUMBER; l_template_key NUMBER; l_server_key NUMBER; l_rep_srvr_status rep_server.status%TYPE; l_suc_cnt NUMBER := 0; l_err_cnt NUMBER := 0; l_cnt NUMBER := 0; l_rv BOOLEAN; l_rec_time timestamp; BEGIN trace1 ('RECONCILE_DB p_db_key=' || p_db_key || ', p_server_key=' || p_server_key || ', p_only_active=' || print(p_only_active)); l_suc_cnt := 0; l_err_cnt := 0; rec_cnt := 0; IF p_db_key IS NULL THEN trace1 ('RECONCILE_DB: required db_key missing.'); RETURN FALSE; END IF; IF p_server_key IS NOT NULL THEN BEGIN SELECT l.lib_key, r.status INTO l_lib_key, l_rep_srvr_status FROM odb o, sbt_lib_desc l, rep_server r WHERE o.db_key=p_db_key AND l.server_key = p_server_key AND l.server_key = r.server_key AND o.prot_key=r.prot_key; EXCEPTION WHEN no_data_found THEN save_error; trace1('RECONCILE_DB: Replication Server not available.'); clear_error; -- -- RETURN TRUE; END; IF l_rep_srvr_status != 'A' THEN IF p_only_active THEN trace1 ('RECONCILE_DB1: skipping inactive replication server. ' || 'server_key=' || p_server_key || ', rep_srvr_status=' || l_rep_srvr_status); RETURN TRUE; END IF; END IF; -- -- l_rv := reconcile_it (p_db_key => reconcile_db.p_db_key, p_lib_key => l_lib_key, p_server_key => reconcile_db.p_server_key, p_force_reconcile => reconcile_db.p_force_reconcile); IF l_rv THEN l_suc_cnt := l_suc_cnt + 1; UPDATE odb SET last_reconcile = SYSTIMESTAMP WHERE db_key = p_db_key RETURNING last_reconcile INTO l_rec_time; COMMIT; trace1('RECONCILE_DB: update last_reconcile_time for ' || ' db_key=' || p_db_key || ', to ' || l_rec_time); ELSE l_err_cnt := l_err_cnt + 1; END IF; ELSE BEGIN OPEN rep_server_cursor(p_db_key); LOOP FETCH rep_server_cursor INTO l_lib_key, l_server_key, l_rep_srvr_status; EXIT WHEN rep_server_cursor%NOTFOUND; IF l_rep_srvr_status != 'A' THEN IF p_only_active THEN trace1 ('RECONCILE_DB: skipping inactive replication server. ' || 'server_key=' || l_server_key); CONTINUE; END IF; END IF; l_rv := reconcile_it (p_db_key => p_db_key, p_lib_key => l_lib_key, p_server_key => l_server_key, p_force_reconcile => reconcile_db.p_force_reconcile); IF l_rv THEN l_suc_cnt := l_suc_cnt + 1; UPDATE odb SET last_reconcile = SYSTIMESTAMP WHERE db_key = p_db_key RETURNING last_reconcile INTO l_rec_time; COMMIT; trace1('RECONCILE_DB: update last_reconcile_time for ' || ' db_key=' || p_db_key || ', to ' || l_rec_time); ELSE l_err_cnt := l_err_cnt + 1; END IF; END LOOP; CLOSE rep_server_cursor; END; END IF; rec_cnt := l_suc_cnt; RETURN (l_err_cnt = 0); EXCEPTION WHEN OTHERS THEN save_error; trace1 ('RECONCILE_DB: error - ' || SQLERRM); RAISE; END reconcile_db; -- -- -- -- -- PROCEDURE execute_reconcile(p_task_rec IN task%ROWTYPE) IS l_db_key NUMBER; l_rv BOOLEAN; l_rec_cnt NUMBER; -- num we reconciled against l_exp_rec_cnt NUMBER; -- num we expected to reconcile against BEGIN l_db_key := p_task_rec.db_key; tracex('EXECUTE_RECONCILE: db_key=' || l_db_key); wait_for_repair (NULL, l_db_key); avoid_delete_db (l_db_key); SELECT count(*) INTO l_exp_rec_cnt FROM rep_server rs WHERE rs.prot_key = (SELECT prot_key FROM odb WHERE db_key=l_db_key -- AND db_state IS NULL); IF l_exp_rec_cnt > 0 THEN l_rv := reconcile_db (p_db_key => l_db_key, p_server_key => NULL, p_only_active => TRUE, p_force_reconcile => FALSE, rec_cnt => l_rec_cnt); IF l_rv AND l_rec_cnt > 0 AND l_rec_cnt = l_exp_rec_cnt THEN fix_error (p_error_num => dbms_ra.REP_SETUP_ERROR_NUM, p_db_key => l_db_key, p_param_char => 'RECONCILE'); END IF; trace1('EXECUTE_RECONCILE: reconcile complete. rv=' || print(l_rv) || ' actual_reconcile count=' || l_rec_cnt || ', expected_reconcile=' || l_exp_rec_cnt); IF l_rec_cnt = 0 THEN trace1('EXECUTE_RECONCILE: no active replication servers. Aborting task'); END IF; ELSE -- trace1('EXECUTE_RECONCILE: Nothing to reconcile. Aborting task'); END IF; -- -- -- IF s_setup_next_reconcile THEN trace1('EXECUTE_RECONCILE: setup new reconcile timer.' || ' db_key=' || l_db_key); queue_set_reconcile_timer(l_db_key); END IF; EXCEPTION WHEN OTHERS THEN save_error; trace1 ('execute_reconcile: error - ' || SQLERRM); RAISE; END execute_reconcile; -- -- -- -- -- PROCEDURE queue_replication_task(p_bp_key IN NUMBER, p_handle IN VARCHAR2, p_db_key IN NUMBER, p_bs_key IN NUMBER, p_piece_no IN NUMBER, p_rep_server_key IN NUMBER, p_sbt_template_key IN NUMBER, p_sbt_attr_set_key IN NUMBER, p_sbt_lib_key IN NUMBER) IS l_spawn_job BOOLEAN := FALSE; new_task_rec task%ROWTYPE; l_db_key NUMBER; l_bs_key NUMBER; l_piece_no NUMBER; l_rep_server_key NUMBER; l_sbt_template_key NUMBER; l_sbt_job_attr_key NUMBER; l_sbt_lib_key NUMBER; l_copies NUMBER; l_cnt NUMBER; l_rep_srvr_status rep_server.status%TYPE; BEGIN trace1 ('QUEUE_REPLICATION_TASK:' || ' p_db_key= ' || p_db_key || ', p_bs_key= ' || p_bs_key || ', p_piece_no= ' || p_piece_no || ', p_bp_key= ' || p_bp_key || ', p_rep_server_key= ' || p_rep_server_key || ', p_sbt_template_key= ' || p_sbt_template_key || ', p_sbt_attr_set_key= ' || p_sbt_attr_set_key || ', p_sbt_lib_key= ' || p_sbt_lib_key || ', p_handle= ' || p_handle); l_db_key := p_db_key; l_bs_key := p_bs_key; l_piece_no := p_piece_no; l_sbt_template_key := p_sbt_template_key; l_sbt_job_attr_key := p_sbt_attr_set_key; l_sbt_lib_key := p_sbt_lib_key; l_rep_server_key := p_rep_server_key; l_copies := 1; -- SELECT count(*) INTO l_cnt FROM sbt_lib_desc WHERE lib_key = l_sbt_lib_key; IF l_cnt = 0 THEN trace1('QUEUE_REPLICATION_TASK: Library for Replication Server has ' || ' been deleted.'); RETURN; END IF; -- BEGIN SELECT status INTO l_rep_srvr_status FROM rep_server WHERE rep_server_key = l_rep_server_key; IF l_rep_srvr_status != 'A' THEN RAISE no_data_found; END IF; EXCEPTION WHEN no_data_found THEN save_error; trace1('QUEUE_REPLICATION_TASK: Replication Server not available. ' || ' l_rep_server_key=' || l_rep_server_key); clear_error; RETURN; END; -- l_spawn_job := queue_one_sbt_backup_task( p_db_key => l_db_key, p_bs_key => l_bs_key, p_piece_no => l_piece_no, p_src_bpkey => p_bp_key, p_template_key => l_sbt_template_key, p_full_template_key => l_sbt_template_key, p_attr_set_key => l_sbt_job_attr_key, p_lib_key => l_sbt_lib_key, p_rep_server_key => l_rep_server_key, p_copies => l_copies); UPDATE sbt_job_template job SET job.schedule_time = SYSTIMESTAMP, job.completion_time = nvl2(job.window, job.window + SYSTIMESTAMP, null) WHERE job.template_key = l_sbt_template_key; -- COMMIT; IF (NOT l_spawn_job) THEN trace1 ('QUEUE_REPLICATION_TASK: no job queued for ' || ' l_sbt_template_key=' || l_sbt_template_key || ' l_bs_key=' || l_bs_key || ' l_piece_no=' || l_piece_no); RETURN; END IF; queue_spawn_sbt(p_libkey => l_sbt_lib_key, p_forpurge => FALSE); EXCEPTION WHEN OTHERS THEN save_error; trace1 ('QUEUE_REPLICATION_TASK: error - ' || SQLERRM); RAISE; END queue_replication_task; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE replicate_existing_backups( p_template_name IN sbt_job_template.template_name%TYPE, p_db_key IN NUMBER DEFAULT NULL, p_server_key IN NUMBER DEFAULT NULL ) IS l_cnt NUMBER; BEGIN IF p_db_key IS NOT NULL THEN SELECT count(*) INTO l_cnt FROM bp WHERE db_key=p_db_key AND status = 'A' AND ROWNUM=1 AND vb_key IS NOT NULL; ELSIF p_template_name IS NOT NULL THEN SELECT count(*) INTO l_cnt FROM bp WHERE status = 'A' AND ROWNUM=1 AND vb_key IS NOT NULL AND db_key = (SELECT db_key FROM sbt_job_template WHERE template_name=p_template_name); END IF; trace1('replicate_existing_backups by p_db_key= ' || p_db_key || ' rssrvr_key=' || p_server_key || ' template_name=' || p_template_name || ' existing_bu_cnt=' || l_cnt); IF l_cnt > 0 THEN dbms_ra_scheduler.queue_sbt_backup_task(template_name => p_template_name); END IF; END replicate_existing_backups; -- -- -- -- -- -- -- -- -- -- PROCEDURE create_replication_tasks(p_db_key IN NUMBER, p_bp_key IN NUMBER DEFAULT NULL, p_bs_key IN NUMBER DEFAULT NULL, p_piece_no IN NUMBER DEFAULT NULL, p_server_key IN NUMBER DEFAULT NULL, p_lib_key IN NUMBER DEFAULT NULL ) IS CURSOR rep_server_cursor (in_db_key IN NUMBER) IS SELECT l.lib_key,a.attr_key,j.template_key, rs.server_key,rs.rep_server_key, rs.status FROM odb o, rep_server rs, sbt_job_template j, sbt_lib_desc l, sbt_attr_set a WHERE o.db_key=in_db_key AND o.prot_key=rs.prot_key AND rs.server_key=l.server_key AND l.lib_key=a.lib_key AND a.attr_key=j.attr_key AND o.db_key=j.db_key; l_handle VARCHAR2(512) := NULL; l_db_key NUMBER; l_bs_key NUMBER; l_piece_no NUMBER; l_sbt_template_key NUMBER; l_sbt_attr_key NUMBER; l_lib_key NUMBER; l_server_key NUMBER; l_rep_server_key NUMBER; l_rep_srvr_status rep_server.status%TYPE; BEGIN trace1 ('CREATE_REPLICATION_TASKS:' || ' p_db_key = ' || p_db_key || ' p_bp_key = ' || p_bp_key || ' p_ba_srv = ' || p_server_key || ' p_lib_key = ' || p_lib_key ); l_db_key := p_db_key; l_bs_key := p_bs_key; l_piece_no := p_piece_no; IF l_db_key IS NULL THEN trace1 ('CREATE_REPLICATION_TASKS: required db_key missing.'); RETURN; END IF; IF (p_bs_key IS NULL OR p_piece_no IS NULL) THEN IF p_bp_key IS NULL THEN trace1 ('CREATE_REPLICATION_TASKS: required bp_key missing.'); RETURN; END IF; SELECT bs_key, db_key, handle, piece# INTO l_bs_key, l_db_key, l_handle, l_piece_no FROM bp WHERE bp.bp_key = p_bp_key AND bp.status != 'D'; END IF; BEGIN OPEN rep_server_cursor(l_db_key); LOOP FETCH rep_server_cursor INTO l_lib_key, l_sbt_attr_key, l_sbt_template_key, l_server_key, l_rep_server_key, l_rep_srvr_status; EXIT WHEN rep_server_cursor%NOTFOUND; trace1 ('CREATE_REPLICATION_TASKS: replication cursor ' || ' l_db_key=' || l_db_key || ', p_bp_key=' || p_bp_key || ', l_bs_key=' || l_bs_key || ', l_piece_no=' || l_piece_no || ', template_key=' || l_sbt_template_key || ', lib_key=' || l_lib_key || ', rep_server_key=' || l_rep_server_key || ', attr_key=' || l_sbt_attr_key || ', server_key=' || l_server_key || ', p_server_key=' || p_server_key || ', rep_srvr_status=' || l_rep_srvr_status); IF (l_lib_key IS NOT NULL) AND ((p_lib_key is NOT NULL AND p_lib_key=l_lib_key) OR (p_lib_key is NULL)) AND ((p_server_key IS NULL) OR (p_server_key IS NOT NULL AND p_server_key = l_server_key)) AND (l_rep_srvr_status = 'A') THEN queue_replication_task(p_bp_key => p_bp_key , p_handle => l_handle , p_db_key => l_db_key , p_bs_key => l_bs_key , p_piece_no => l_piece_no , p_rep_server_key => l_rep_server_key , p_sbt_template_key => l_sbt_template_key , p_sbt_attr_set_key => l_sbt_attr_key , p_sbt_lib_key => l_lib_key ); END IF; END LOOP; CLOSE rep_server_cursor; EXCEPTION WHEN OTHERS THEN save_error; CLOSE rep_server_cursor; RAISE; END; EXCEPTION WHEN OTHERS THEN save_error; trace1 ('CREATE_REPLICATION_TASKS: error - ' || SQLERRM); RAISE; END create_replication_tasks; -- -- -- -- PROCEDURE queue_restore_task(request_id IN NUMBER, sbt_sessionid IN VARCHAR2, handle IN VARCHAR2) IS new_task_rec task%ROWTYPE; l_db_key NUMBER; l_lib_key NUMBER; l_bs_key NUMBER; l_bp_key NUMBER; l_piece_no NUMBER; l_count NUMBER; l_status sbt_lib_desc.status%TYPE; l_lib_name sbt_lib_desc.lib_name%TYPE; l_rep_srvr_status rep_server.status%TYPE; l_rep_srvr_key NUMBER; l_rs_srvr_key NUMBER; BEGIN trace1 ('QUEUE_RESTORE_TASK:' || ' request_id = ' || request_id || ' sbt_sessionid = ' || sbt_sessionid || ' handle = ' || handle); SELECT bp.db_key, bp.bp_key, bp.bs_key, bp.piece#, bp.lib_key INTO l_db_key, l_bp_key, l_bs_key, l_piece_no, l_lib_key FROM bp WHERE bp.handle = queue_restore_task.handle AND bp.status != 'D' AND bp.ba_access != 'U'; IF (l_lib_key IS NOT NULL) THEN SELECT lib.status, lib.lib_name, lib.server_key INTO l_status, l_lib_name, l_rs_srvr_key FROM sbt_lib_desc lib WHERE lib.lib_key = l_lib_key; IF (l_status != 'R') THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( E_SBT_LIB_NOT_READY_NUM, l_lib_name); END IF; -- -- -- -- -- -- -- IF l_rs_srvr_key IS NOT NULL THEN -- BEGIN SELECT rs.status, rs.rep_server_key INTO l_rep_srvr_status, l_rep_srvr_key FROM odb o, rep_server rs, sbt_lib_desc l WHERE o.db_key=l_db_key AND o.prot_key=rs.prot_key AND rs.server_key=l.server_key AND l.lib_key=l_lib_key; IF l_rep_srvr_status != 'A' THEN -- SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( E_SBT_LIB_NOT_READY_NUM, l_lib_name); END IF; EXCEPTION WHEN no_data_found THEN save_error; -- clear_error; END; END IF; END IF; -- IF (l_lib_key IS NOT NULL) THEN new_task_rec.task_type := TASK_RESTORE_SBT; ELSE new_task_rec.task_type := TASK_RESTORE; END IF; new_task_rec.flags := 0; new_task_rec.db_key := l_db_key; new_task_rec.param_char1 := sbt_sessionid; new_task_rec.param_char2 := handle; new_task_rec.param_num1 := request_id; new_task_rec.param_num2 := l_bp_key; new_task_rec.param_num3 := l_lib_key; new_task_rec.com_time := sysdate; IF (l_lib_key IS NOT NULL) THEN new_task (task_rec => new_task_rec, p_commit => FALSE, p_sbt_task => TRUE); INSERT INTO sbt_task (task_id, bs_key, piece#, rep_server_key, template_key, attr_key, lib_key, copies, failure_cnt, restore) VALUES (new_task_rec.task_id, l_bs_key, l_piece_no, l_rep_srvr_key, NULL, NULL, l_lib_key, 1, 0, 'Y'); ELSE new_task (task_rec => new_task_rec, p_commit => FALSE); END IF; -- COMMIT; -- -- -- SYS.KBRSI_ICD.RSRUNSCHED; IF (l_lib_key IS NOT NULL) THEN -- sbt restore task queue_spawn_sbt(p_libkey => l_lib_key, p_forpurge => FALSE); ELSE -- Virtual restore -- -- SELECT COUNT(*) INTO l_count FROM task WHERE state = STATE_RESTORE_WAIT AND execute_inst_id = s_instance; IF l_count = 0 THEN spawn_job('RA$_REST_' || rai_sq.nextval, 'dbms_ra_scheduler.schedule(' || ' p_task_type => dbms_ra_scheduler.TASK_RESTORE);', s_instance, NULL); END IF; END IF; trace1 ('QUEUE_RESTORE_TASK complete'); END queue_restore_task; -- -- -- -- FUNCTION wait_for_resource(request_id IN NUMBER, handle IN VARCHAR2) RETURN BINARY_INTEGER IS l_busy BINARY_INTEGER := 0; maxtries NUMBER := 100; l_state NUMBER; l_task_type NUMBER; BEGIN trace1 ('WAIT_FOR_RESOURCE:' || ' request_id = ' || request_id || ' handle = ' || handle); -- BEGIN SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); SELECT t.state, t.task_type INTO l_state, l_task_type FROM task t LEFT OUTER JOIN sbt_task st ON st.task_id = t.task_id AND st.restore = 'Y' -- restore jobs WHERE t.param_num1 = request_id AND ((t.task_type = TASK_RESTORE_SBT AND st.task_id IS NOT NULL) OR (t.task_type = TASK_RESTORE)); UPDATE task SET com_time = sysdate WHERE param_num1 = request_id; COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK; EXCEPTION WHEN no_data_found THEN save_error; SYS.KBRSI_ICD.RSSCHEDUNLOCK; trace1('WAIT_FOR_RESOURCE: could not locate task'); clear_error; RETURN l_busy; END; IF (l_state = STATE_RUNNING OR l_state = STATE_COMPLETED) THEN RETURN l_busy; END IF; IF (l_task_type IN (TASK_RESTORE, TASK_RESTORE_SBT)) THEN IF (l_state NOT IN (STATE_RUNNING, STATE_CANCELING, STATE_CANCEL)) THEN l_busy := 1; END IF; ELSE sys.dbms_sys_error.raise_system_error( E_INTERNAL_ERROR_NUM, 'unknown task_type ' || nvl(l_task_type, '')); END IF; RETURN l_busy; END wait_for_resource; -- -- -- -- PROCEDURE execute_obsolete_sbt(p_task_rec IN task%ROWTYPE) IS -- CURSOR sbt_cursor IS SELECT bp.db_key, bp.lib_key, odb.sbt_ret FROM (SELECT DISTINCT bp.db_key, bp.lib_key FROM bp WHERE bp.lib_key IS NOT NULL AND bp.status != 'D' AND bp.ba_access != 'U') bp, (SELECT odb.db_key, prot.prot_recovery_window_sbt sbt_ret FROM prot, odb WHERE prot.prot_key = odb.prot_key) odb WHERE bp.db_key = odb.db_key -- -- ORDER BY 1, 3; BEGIN -- FOR i in sbt_cursor LOOP trace1 ('EXECUTE_OBSOLETE_SBT: db_key=' || i.db_key || ' lib_key=' || i.lib_key); IF (i.sbt_ret IS NOT NULL) THEN purge_obsolete_sbt(p_dbkey => i.db_key, p_libkey => i.lib_key, p_sbt_ret => i.sbt_ret); END IF; END LOOP; END execute_obsolete_sbt; -- -- -- -- -- PROCEDURE purge_obsolete_sbt( p_dbkey IN NUMBER, p_libkey IN NUMBER, p_sbt_ret IN DSINTERVAL_UNCONSTRAINED) IS l_spawn_job BOOLEAN; l_untilTime DATE; l_status BOOLEAN; l_firstcall BOOLEAN; lbRec dbms_rcvman.lbRec_t; lbCursor dbms_rcvman.lbCursor_t; l_dbid NUMBER; l_currinc NUMBER; l_db_slkey NUMBER; BEGIN IF (p_sbt_ret IS NULL) THEN RETURN; -- no retention set END IF; l_untilTime := SYSDATE - p_sbt_ret; trace1 ('PURGE_OBSOLTE_SBT: db_key=' || p_dbkey || ' lib_key=' || p_libkey || ' untilTime=' || l_untilTime); setDatabase(p_dbkey, l_dbid, l_currinc, l_db_slkey); -- BEGIN dbms_rcvman.setUntilTime(l_untilTime); EXCEPTION WHEN OTHERS THEN save_error; trace1 ('PURGE_OBSOLETE_SBT EXCEPTION: (setUntilTime)' || SQLERRM); sys.kbrsi_icd.rsClearErr; clear_error; RETURN; END; dbms_rcvman.setDeviceType('SBT_TAPE'); dbms_rcvman.setOrsFile(localOnly => FALSE, libKey => p_libkey); dbms_rcvman.setNeedObsoleteData(TRUE); -- l_status := TRUE; l_firstcall := TRUE; l_spawn_job := FALSE; WHILE (l_status) LOOP l_status := dbms_rcvman.listBackup( lbRecOut => lbRec, firstcall => l_firstcall, only_obsolete => TRUE, redundancy => 1, piped_call => FALSE, lbCursor => lbCursor, lbState => dbms_rcvman.lbStatePck); l_firstcall := FALSE; IF (lbRec.pkey IS NOT NULL AND lbRec.file_type = dbms_rcvman.piece_txt AND (lbRec.status = dbms_rcvman.available_txt OR lbRec.status = dbms_rcvman.expired_txt OR lbRec.status = dbms_rcvman.unavailable_txt)) THEN DBMS_RA_STORAGE.FREE_BACKUP_PIECE_OPT( p_dbkey => p_dbkey, p_piecename => lbRec.fname, p_db_slkey => l_db_slkey, p_dbid => l_dbid, p_currinc => l_currinc, p_bpkey => lbRec.pkey, p_ftype => DBMS_RA_INT.KBRSCHKTYPE_TAPE, p_libkey => p_libkey, p_spawn_job => FALSE); -- l_spawn_job := TRUE; END IF; END LOOP; IF (NOT l_spawn_job) THEN RETURN; END IF; -- queue_spawn_sbt(p_libkey => p_libkey, p_forpurge => TRUE); EXCEPTION WHEN OTHERS THEN save_error; trace1 ('PURGE_OBSOLETE_SBT EXCEPTION: ' || SQLERRM); RAISE; END purge_obsolete_sbt; -- -- -- -- FUNCTION add_to_task_history_table ( task_type NUMBER, db_key NUMBER DEFAULT NULL, sl_key NUMBER DEFAULT NULL, param VARCHAR2 DEFAULT NULL, param_num1 NUMBER DEFAULT NULL, param_num2 NUMBER DEFAULT NULL, param_num3 NUMBER DEFAULT NULL, param_char1 VARCHAR2 DEFAULT NULL, param_char2 VARCHAR2 DEFAULT NULL ) RETURN NUMBER IS PRAGMA AUTONOMOUS_TRANSACTION; l_task_id NUMBER := 0; BEGIN tracex('#### ' || param); l_task_id := rai_sq.nextval; -- -- -- INSERT INTO TASK_HISTORY (task_id, task_type, flags, db_key, sl_key, param, param_num1, param_num2, param_num3, param_char1, param_char2, execute_time, completion_time, execute_inst_id, state) VALUES (l_task_id, task_type, 0, db_key, sl_key, SUBSTR(param, 1, 4000), param_num1, param_num2, param_num3, param_char1, param_char2, SYSTIMESTAMP, SYSTIMESTAMP, s_instance, STATE_COMPLETED); COMMIT; RETURN l_task_id; EXCEPTION WHEN OTHERS THEN save_error; trace1 ('ADD_TO_TASK_HISTORY_TABLE EXCEPTION: ' || SQLERRM); RAISE; END add_to_task_history_table; -- -- -- -- PROCEDURE update_task_history_entry ( task_id NUMBER, db_key NUMBER DEFAULT NULL, sl_key NUMBER DEFAULT NULL, param VARCHAR2 DEFAULT NULL, param_num1 NUMBER DEFAULT NULL, param_num2 NUMBER DEFAULT NULL, param_num3 NUMBER DEFAULT NULL, param_char1 VARCHAR2 DEFAULT NULL, param_char2 VARCHAR2 DEFAULT NULL, do_commit IN BOOLEAN DEFAULT FALSE ) IS BEGIN IF db_key IS NOT NULL THEN UPDATE task_history SET db_key=update_task_history_entry.db_key WHERE task_id = update_task_history_entry.task_id; END IF; IF sl_key IS NOT NULL THEN UPDATE task_history SET sl_key=update_task_history_entry.sl_key WHERE task_id = update_task_history_entry.task_id; END IF; IF param IS NOT NULL THEN UPDATE task_history SET param=SUBSTR(param, 1, 4000) WHERE task_id = update_task_history_entry.task_id; END IF; IF param_num1 IS NOT NULL THEN UPDATE task_history SET param_num1=update_task_history_entry.param_num1 WHERE task_id = update_task_history_entry.task_id; END IF; IF param_num2 IS NOT NULL THEN UPDATE task_history SET param_num2=update_task_history_entry.param_num2 WHERE task_id = update_task_history_entry.task_id; END IF; IF param_num3 IS NOT NULL THEN UPDATE task_history SET param_num3=update_task_history_entry.param_num3 WHERE task_id = update_task_history_entry.task_id; END IF; IF param_char1 IS NOT NULL THEN UPDATE task_history SET param_char1=update_task_history_entry.param_char1 WHERE task_id = update_task_history_entry.task_id; END IF; IF param_char2 IS NOT NULL THEN UPDATE task_history SET param_char2=update_task_history_entry.param_char2 WHERE task_id = update_task_history_entry.task_id; END IF; -- -- IF do_commit THEN COMMIT; END IF; END update_task_history_entry; -- -- -- -- -- -- -- -- -- -- PROCEDURE copy_one_backuppiece(p_bpkey IN NUMBER, p_format IN VARCHAR2, p_deletesource IN VARCHAR2, p_template_key IN NUMBER DEFAULT NULL) AS start_time timestamp; end_time timestamp; howlong interval day(3) to second(3); set_count NUMBER; set_stamp NUMBER; recid NUMBER; stamp NUMBER; out_recid NUMBER; out_stamp NUMBER; concur BOOLEAN; newfilename varchar2(1024); srcfilename varchar2(1024); handle varchar2(512); comment varchar2(80); media varchar2(80); lyear varchar2(4); lday varchar2(2); lmonth varchar2(2); lcfaudate varchar2(512); devtype varchar2(512); node varchar2(255); thetag varchar2(255); bpsize number; dbkey NUMBER; vbkey NUMBER; pstr VARCHAR2(4000); piecenum NUMBER; l_bskey NUMBER; l_maxcopy NUMBER; l_template_name sbt_job_template.template_name%TYPE; BEGIN trace1 ('copy_one_backuppiece: bp_key=' || p_bpkey || ' ,template_key=' || p_template_key || ' ,deletesource = ' || p_deletesource || ' ,format=' || p_format); -- SELECT bp.handle, bp.bp_recid, bp.bp_stamp, bp.tag, bp.db_key, bp.vb_key, piece#, bs_key INTO srcfilename, recid, stamp, thetag, dbkey, vbkey, piecenum, l_bskey FROM bp WHERE bp.bp_key = p_bpkey; -- SELECT set_stamp, set_count INTO set_stamp, set_count FROM bs WHERE bs_key=l_bskey; -- IF (p_template_key IS NOT NULL) THEN -- -- SELECT template_name INTO l_template_name FROM sbt_job_template WHERE template_key = p_template_key; -- dbms_ra_scheduler.queue_sbt_backup_task(template_name => l_template_name, src_bpkey => p_bpkey, delete_source => p_deletesource, format => p_format); ELSE -- -- start_time := systimestamp; devtype := sys.dbms_backup_restore.deviceAllocate( ident => 'ORA_DISK_1', node => node, type => NULL, params => NULL, dupcnt => 1, allowmts => TRUE, ors_lib_key => NULL); -- lcfaudate := NULL; SELECT to_char(nvl(to_date(lcfaudate), sysdate), 'YYYY', 'NLS_CALENDAR=Gregorian'), to_char(nvl(to_date(lcfaudate), sysdate), 'MM', 'NLS_CALENDAR=Gregorian'), to_char(nvl(to_date(lcfaudate), sysdate), 'DD', 'NLS_CALENDAR=Gregorian') INTO lyear, lmonth, lday FROM dual; -- SELECT NVL(MAX(copy#), 0) INTO l_maxcopy FROM bp WHERE bs_key = l_bskey; newfilename := sys.dbms_backup_restore.genPieceName( pno => piecenum, set_count => set_count, set_stamp => set_stamp, format => p_format, copyno => l_maxcopy + 1, devtype => 'DISK', year => lyear, month => lmonth, day => lday, dbid => NULL, -- computed in server if required ndbname => NULL, -- computed in server if required pdbname => NULL, -- computed in server if required cfseq => NULL); sys.dbms_backup_restore.backupBackupPiece( bpname => srcfilename, fname => newfilename, handle => handle, comment => comment, media => media, concur => concur, recid => out_recid, stamp => out_stamp, check_logical=> FALSE, tag => thetag, params => null, reuse => false, deffmt => 0, copy_recid => recid, copy_stamp => stamp, -- -- copyno => 0, npieces => 1, dest => 0, pltfrmfr => null, ors => TRUE, template_key => NULL, bpsize => bpsize); -- sys.dbms_backup_restore.backupCancel; sys.dbms_backup_restore.restoreCancel(TRUE); sys.dbms_backup_restore.cfileUseCurrent(TRUE); -- release enqueue sys.dbms_backup_restore.deviceDeallocate; sys.dbms_backup_restore.set_client_info(''); sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0); -- end_time := systimestamp; howlong := end_time - start_time; trace1('copy_one_backuppiece took ' || howlong || ' seconds'); END IF; EXCEPTION WHEN OTHERS THEN save_error; IF (p_template_key IS NULL) THEN sys.dbms_backup_restore.backupCancel; sys.dbms_backup_restore.restoreCancel(TRUE); sys.dbms_backup_restore.cfileUseCurrent(TRUE); -- release enqueue sys.dbms_backup_restore.deviceDeallocate; sys.dbms_backup_restore.set_client_info(''); sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0); ROLLBACK; END IF; RAISE; END copy_one_backuppiece; -- -- -- -- -- -- PROCEDURE delete_one_backuppiece(p_bpkey IN NUMBER) AS BEGIN DECLARE l_dbkey sbt_catalog.db_key%type; l_piecename sbt_catalog.handle%type; l_ftype sbt_catalog.ftype%type; l_fincarn sbt_catalog.pieceinc%type; l_status VARCHAR2(1); l_ba_access VARCHAR2(1); BEGIN trace1('delete_one_backuppiece - bp_key=' || p_bpkey); SELECT status, ba_access INTO l_status, l_ba_access FROM bp WHERE bp_key=p_bpkey; IF l_ba_access NOT IN ('L', 'D') OR l_status != 'A' THEN trace1('delete_one_backuppiece - nothing to delete - status=' || l_status || ', ba_access=' || l_ba_access); RETURN; END IF; SELECT db_key, handle, ftype, pieceinc INTO l_dbkey, l_piecename, l_ftype, l_fincarn FROM sbt_catalog WHERE bp_key = p_bpkey; trace1('delete_backuppiece - l_dbkey=' || l_dbkey || ' l_piecename=' || l_piecename || ' l_fincarn=' || l_fincarn); -- FOR l_x IN 1..300 LOOP BEGIN dbms_ra_storage.free_backup_piece(p_dbkey => l_dbkey, p_piecename => l_piecename, p_fincarn => l_fincarn); EXIT; EXCEPTION WHEN E_RETRY_ERROR THEN save_error; trace1('delete_backuppiece attempt ' || l_x || 'at getting lock - l_dbkey=' || l_dbkey || ' l_piecename=' || l_piecename || ' l_fincarn=' || l_fincarn); DBMS_LOCK.SLEEP(1); clear_error; WHEN OTHERS THEN save_error; RAISE; END; END LOOP; END; END delete_one_backuppiece; PROCEDURE set_resumable_timeout IS BEGIN IF (s_resumable_timeout = 0 OR s_resumable_timeout IS NULL) THEN EXECUTE IMMEDIATE 'ALTER SESSION DISABLE RESUMABLE'; ELSE EXECUTE IMMEDIATE 'ALTER SESSION ENABLE RESUMABLE TIMEOUT ' || s_resumable_timeout; END IF; END set_resumable_timeout; -- -- -- PROCEDURE inValidateBaseLevelBcks (p_db_key IN NUMBER, p_currinc IN NUMBER, p_template_key IN NUMBER, p_baseline_scn IN OUT NUMBER) IS CURSOR invalid_bcks_cursor(p_db_key IN NUMBER, p_currinc IN NUMBER, p_template_key IN NUMBER) IS WITH my_dbinc AS (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc START WITH dbinc_key = p_currinc CONNECT BY PRIOR parent_dbinc_key=dbinc_key ANd db_key = p_db_key ), my_stf AS (SELECT stf.bs_key, stf.df_file#, stf.template_key, bdf.abs_fuzzy_scn, bdf.ckp_scn, bdf.dbinc_key, stf.db_key FROM bdf, sbt_template_df stf WHERE stf.db_key = p_db_key AND stf.template_key = p_template_key AND stf.df_file# = bdf.file# AND stf.bs_key = bdf.bs_key) SELECT my_stf.bs_key, my_stf.df_file#, my_stf.template_key, my_stf.db_key FROM my_stf, my_dbinc WHERE my_stf.dbinc_key = my_dbinc.dbinc_key AND greatest(abs_fuzzy_scn, ckp_scn) >= my_dbinc.next_reset_scn UNION SELECT my_stf.bs_key, my_stf.df_file#, my_stf.template_key, my_stf.db_key FROM my_stf WHERE my_stf.dbinc_key NOT IN (SELECT dbinc_key FROM my_dbinc) ORDER BY 1; -- to avoid deadlocks for parallel updates l_values invalid_bcks_cursor%ROWTYPE; l_curr_dbinc_key NUMBER; l_valid_backups NUMBER; BEGIN trace1('inValidateBaseLevelBcks: db_key=' || p_db_key || ',currdbinc_key=' || p_currinc || ',template_key=' || p_template_key); BEGIN SELECT curr_dbinc_key INTO l_curr_dbinc_key FROM sbt_template_db WHERE db_key = p_db_key AND template_key = p_template_key; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; trace1('inValidateBaseLevelBcks: no sbt_template_db found'); clear_error; RETURN; END; IF l_curr_dbinc_key = p_currinc THEN trace1('inValidateBaseLevelBcks: currinc not changed, nothing to do'); RETURN; END IF; OPEN invalid_bcks_cursor(p_db_key, p_currinc, p_template_key); LOOP FETCH invalid_bcks_cursor INTO l_values; EXIT WHEN invalid_bcks_cursor%NOTFOUND; UPDATE sbt_template_df SET bs_key = null, df_checkpoint_change# = null WHERE db_key = p_db_key AND template_key = p_template_key AND df_file# = l_values.df_file# AND bs_key = l_values.bs_key; END LOOP; CLOSE invalid_bcks_cursor; -- -- SELECT COUNT(*) INTO l_valid_backups FROM sbt_template_df WHERE db_key = p_db_key AND template_key = p_template_key AND df_file# > 0 AND bs_key IS NOT NULL; IF (l_valid_backups = 0) THEN UPDATE sbt_template_db SET baseline_scn = null WHERE db_key = p_db_key AND template_key = p_template_key AND s_c2t_optimization = 1; UPDATE sbt_template_df SET bs_key = null, df_checkpoint_change# = null WHERE db_key = p_db_key AND template_key = p_template_key AND df_file# <= 0; p_baseline_scn := 0; trace1('inValidateBaseLevelBcks: baseline_scn set to NULL'); ELSE trace1('inValidateBaseLevelBcks: Valid backup count=' || l_valid_backups); END IF; -- -- UPDATE sbt_template_db SET curr_dbinc_key = p_currinc WHERE db_key = p_db_key AND template_key = p_template_key AND s_c2t_optimization = 1; COMMIT; END inValidateBaseLevelBcks; -- -- PROCEDURE baselineTimezone(p_db_key IN NUMBER, p_baseline_time OUT NOCOPY DATE, p_baseline_untscn OUT NOCOPY NUMBER, p_recovery_window_sbt OUT NOCOPY DATE) IS l_db_timezone VARCHAR2(64); l_currtime DATE; l_dbid NUMBER; l_currinc NUMBER; l_db_slkey NUMBER; BEGIN setDatabase(p_db_key, l_dbid, l_currinc, l_db_slkey); -- dbms_rcvman.setAllIncarnations(TRUE); SELECT MIN(db_timezone) INTO l_db_timezone FROM node WHERE db_key = p_db_key AND database_role = 'PRIMARY'; -- IF (l_db_timezone IS NULL) THEN l_currtime := SYSDATE; ELSE SELECT CAST((SYSTIMESTAMP AT TIME ZONE TO_CHAR(l_db_timezone)) as DATE) INTO l_currtime FROM dual; END IF; p_baseline_time := l_currtime - s_baseline_cap; -- dbms_rcvman.setUntilTime(p_baseline_time); p_baseline_untscn := NVL(dbms_rcvman.getUntilScn, 0); BEGIN SELECT l_currtime - prot_recovery_window_sbt INTO p_recovery_window_sbt FROM prot, odb WHERE odb.prot_key = prot.prot_key AND odb.db_key = p_db_key; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; clear_error; p_recovery_window_sbt := NULL; trace1('baselineTimezone: No Rec window SBT for db_key=' || p_db_key); END; trace1('baselineTimezone: baseline_cap=' || print(s_baseline_cap) || ',l_currtime=' || print(l_currtime) || ',p_baseline_time=' || print(p_baseline_time) || ',l_db_timezone=' || print(l_db_timezone) || ',p_recovery_window_sbt=' || print(p_recovery_window_sbt) || ',p_baseline_untscn=' || print(p_baseline_untscn)); END baselineTimezone; -- -- PROCEDURE queueBaseLevelBcks(p_db_key IN NUMBER, p_dbid OUT NUMBER, p_currinc IN OUT NUMBER, p_db_slkey IN OUT NUMBER, p_from_tag IN VARCHAR2, p_template_key IN NUMBER, p_baseline_scn IN OUT NUMBER, p_lib_key IN NUMBER, p_attr_key IN NUMBER, p_copies IN NUMBER, p_delete_source IN VARCHAR2, p_format IN VARCHAR2, p_last_bp_key IN NUMBER, p_max_bp_key IN NUMBER, p_server_key IN NUMBER) IS -- -- CURSOR bp_last_full_cursor(c_baseline_untscn IN NUMBER) IS WITH my_dbinc AS (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc START WITH dbinc_key = (SELECT curr_dbinc_key from db where db_key=p_db_key) CONNECT BY PRIOR parent_dbinc_key = dbinc_key), bp_list AS -- -- (SELECT /*+ MATERIALIZE */ bp.* FROM bp, sbt_template_df stf WHERE bp.bs_key = stf.bs_key AND stf.template_key = p_template_key AND stf.db_key = p_db_key AND bp.lib_key IS NULL AND bp.ba_access IN ('D', 'L') AND bp.status != 'D' AND bp.bp_key <= p_last_bp_key UNION ALL SELECT bp.* FROM bp WHERE bp.db_key = p_db_key AND bp.lib_key IS NULL AND bp.ba_access IN ('D', 'L') AND bp.status != 'D' AND (p_from_tag IS NULL OR bp.tag = p_from_tag) AND bp.bp_key > p_last_bp_key), df_backup AS -- latest datafile backups (SELECT * FROM (SELECT RANK() OVER (PARTITION BY file#, create_scn, plugin_scn ORDER BY ckp_scn DESC, bdf_key DESC) rank, bdf.file#, bdf.create_scn, bdf.plugin_scn, bdf.ckp_scn, bdf.ckp_time, bp.bs_key, bp.bp_key, bp.piece# FROM bp_list bp, bdf, my_dbinc WHERE bp.bs_key = bdf.bs_key -- -- -- -- AND bp.vb_key IS NOT NULL AND bdf.incr_scn <= bdf.create_scn AND bdf.dbinc_key = my_dbinc.dbinc_key AND bdf.ckp_scn >= c_baseline_untscn AND (decode(bdf.abs_fuzzy_scn, 0, bdf.ckp_scn, bdf.abs_fuzzy_scn) < my_dbinc.next_reset_scn OR my_dbinc.next_reset_scn IS NULL)) WHERE rank = 1), cf_backup AS -- latest controlfile backup (SELECT * FROM (SELECT RANK() over (ORDER BY ckp_scn DESC, bcf_key DESC) rank, bp.bs_key, bp.bp_key, bp.piece#, bcf.ckp_scn, bcf.ckp_time FROM bp_list bp, bcf, my_dbinc WHERE bp.bs_key = bcf.bs_key AND bcf.dbinc_key = my_dbinc.dbinc_key AND bcf.ckp_scn >= c_baseline_untscn AND (bcf.ckp_scn < my_dbinc.next_reset_scn OR my_dbinc.next_reset_scn IS NULL)) WHERE rank=1), sf_backup AS -- latest spfile backup (SELECT * FROM (SELECT RANK() over (ORDER BY modification_time DESC, bsf_key DESC) rank, bp.bs_key, bp.bp_key, bp.piece#, bsf.modification_time FROM bp_list bp, bsf WHERE bp.bs_key = bsf.bs_key AND bsf.db_key = p_db_key) WHERE rank=1), df_list AS -- list of all datafiles relevant to baseline_cap days (SELECT * FROM (SELECT RANK() OVER (PARTITION BY df.file#, df.create_scn, df.plugin_scn ORDER BY df.dbinc_key DESC) rank, df.file#, df.ts#, df.plugin_scn, df.foreign_dbid, df.create_scn, df.dbinc_key, df.read_only, df.stop_scn FROM df, dbinc WHERE dbinc.db_key = p_db_key AND df.dbinc_key = dbinc.dbinc_key AND dbinc.dbinc_status != 'ORPHAN' AND (drop_scn IS NULL or drop_scn > c_baseline_untscn)) WHERE rank = 1), last_offr_df AS -- (SELECT * FROM (SELECT RANK() OVER (PARTITION BY offr.file#, create_scn -- no plugin_scn ORDER BY offr.dbinc_key DESC) rank, offr.file#, offr.create_scn, offr.offline_scn, offr.online_scn, offr.dbinc_key FROM offr, dbinc WHERE dbinc.db_key = p_db_key AND offr.dbinc_key = dbinc.dbinc_key AND dbinc.dbinc_status != 'ORPHAN' AND offr.online_scn >= c_baseline_untscn) WHERE rank = 1), df_attributes AS -- (SELECT dl.file#, dl.ts#, dl.create_scn, dl.foreign_dbid, dl.plugin_scn, dl.dbinc_key, dl.read_only, dl.stop_scn, lod.offline_scn, lod.online_scn FROM df_list dl LEFT OUTER JOIN last_offr_df lod ON dl.file# = lod.file# AND dl.create_scn = lod.create_scn AND dl.dbinc_key = lod.dbinc_key), lf_backup AS -- latest level 0 backup set for datafiles/cf/spfile (SELECT bs_key, bp_key, piece#, df_attributes.file#, df_attributes.create_scn, df_attributes.plugin_scn, df_attributes.foreign_dbid, df_attributes.read_only, df_attributes.stop_scn, df_attributes.offline_scn, df_attributes.online_scn, df_backup.ckp_scn, df_backup.ckp_time FROM df_attributes LEFT OUTER JOIN df_backup ON df_attributes.file# = df_backup.file# AND df_attributes.create_scn = df_backup.create_scn AND df_attributes.plugin_scn = df_backup.plugin_scn UNION ALL SELECT bs_key, bp_key, piece#, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ckp_scn, ckp_time FROM cf_backup UNION ALL SELECT bs_key, bp_key, piece#, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, modification_time ckp_time FROM sf_backup) -- SELECT lf.bs_key, lf.piece#, lf.bp_key, lf.file#, lf.create_scn, lf.plugin_scn, lf.foreign_dbid, lf.read_only, lf.stop_scn, lf.offline_scn, lf.online_scn, lf.ckp_scn, lf.ckp_time, CASE WHEN (s_c2t_optimization = 0) THEN NOT_COPIED_TO_TAPE WHEN EXISTS (SELECT 1 FROM sbt_task_history t WHERE t.failure_cnt = 0 AND t.restore = 'N' AND t.full_template_key = p_template_key AND t.bs_key = lf.bs_key AND t.piece# = lf.piece#) THEN COPIED_TO_TAPE WHEN EXISTS (SELECT 1 FROM sbt_task t WHERE t.restore = 'N' AND t.full_template_key = p_template_key AND t.bs_key = lf.bs_key AND t.piece# = lf.piece#) THEN COPIED_TO_TAPE ELSE NOT_COPIED_TO_TAPE END AS bs_copied2tape FROM lf_backup lf ORDER BY 1, 2; l_bs_key NUMBER; l_piece_no NUMBER; l_bp_key NUMBER; l_file# NUMBER; l_create_scn NUMBER; l_plugin_scn NUMBER; l_foreign_dbid NUMBER; l_read_only NUMBER; l_stop_scn NUMBER; l_offline_scn NUMBER; l_online_scn NUMBER; l_ckp_scn NUMBER; l_ckp_time DATE; l_spawn_job BOOLEAN; l_baseline_time DATE; l_baseline_untscn NUMBER := 0; l_queued_bs_key NUMBER; l_queued_piece_no NUMBER; l_baseline_scn NUMBER; l_effective_ckp_scn NUMBER; l_spfile_selected BOOLEAN := FALSE; l_cffile_selected BOOLEAN := FALSE; l_bs_copied2tape NUMBER; l_cleanup_std BOOLEAN := TRUE; l_recovery_window_sbt DATE; l_bp_start_time DATE; BEGIN trace1 ('queueBaseLevelBcks:Sending new baseline, template_key='|| p_template_key || ' from_tag=' || p_from_tag || ' db_key=' || p_db_key); -- baselineTimezone(p_db_key, l_baseline_time, l_baseline_untscn, l_recovery_window_sbt); BEGIN INSERT INTO sbt_template_db (db_key, template_key) VALUES(p_db_key, p_template_key); EXCEPTION WHEN dup_val_on_index THEN save_error; clear_error; END; OPEN bp_last_full_cursor(l_baseline_untscn); LOOP FETCH bp_last_full_cursor INTO l_bs_key, l_piece_no, l_bp_key, l_file#, l_create_scn, l_plugin_scn, l_foreign_dbid, l_read_only, l_stop_scn, l_offline_scn, l_online_scn, l_ckp_scn, l_ckp_time, l_bs_copied2tape; EXIT WHEN bp_last_full_cursor%NOTFOUND; trace1 ('queueBaseLevelBcks: Found l_bs_key=' || l_bs_key || ' l_piece_no=' || l_piece_no || ' l_bp_key=' || l_bp_key || ' l_file#=' || l_file# || ' l_create_scn=' || l_create_scn || ' l_plugin_scn=' || l_plugin_scn || ' l_foreign_dbid=' || l_foreign_dbid || ' l_read_only=' || l_read_only || ' l_stop_scn=' || l_stop_scn || ' l_offline_scn=' || l_offline_scn || ' l_online_scn=' || l_online_scn || ' l_ckp_scn=' || l_ckp_scn || ' l_ckp_time=' || l_ckp_time || ' l_bs_copied2tape=' || l_bs_copied2tape || ' l_queued_bs_key=' || l_queued_bs_key || ' l_queued_piece_no#=' || l_queued_piece_no); -- IF (l_cleanup_std) THEN DELETE sbt_template_df WHERE db_key = p_db_key AND template_key = p_template_key; trace1 ('queueBaseLevelBcks:deleted old rows=' || SQL%ROWCOUNT); l_cleanup_std := FALSE; END IF; BEGIN INSERT INTO sbt_template_df( template_key, db_key, df_file#, df_plugin_change#, df_foreign_dbid, df_creation_change#, bs_key, df_checkpoint_change#) VALUES (p_template_key, p_db_key, l_file#, l_plugin_scn, l_foreign_dbid, l_create_scn, l_bs_key, l_ckp_scn); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN NULL; END; IF l_file# = 0 THEN l_cffile_selected := TRUE; END IF; IF l_file# = -1 THEN l_spfile_selected := TRUE; END IF; IF l_bs_key IS NULL THEN trace1 ('queueBaseLevelBcks: no backup found for file' || l_file#); CONTINUE; END IF; IF p_baseline_scn = 0 AND l_read_only = 0 THEN IF (l_offline_scn < l_baseline_untscn AND l_online_scn > l_baseline_untscn AND l_offline_scn = l_ckp_scn) THEN l_effective_ckp_scn := l_online_scn; ELSE l_effective_ckp_scn := l_ckp_scn; END IF; IF (l_baseline_scn IS NULL OR l_effective_ckp_scn < l_baseline_scn) THEN l_baseline_scn := l_effective_ckp_scn; trace1('queueBaseLevelBcks: computed l_baseline_scn moved to ' || l_baseline_scn); END IF; END IF; -- -- -- IF s_c2t_optimization = 1 AND l_bs_copied2tape = COPIED_TO_TAPE AND l_read_only = 1 AND l_recovery_window_sbt IS NOT NULL THEN trace1('queueBaseLevelBcks: Read-only file l_bs_key=' || l_bs_key || ' l_piece_no=' || l_piece_no); IF (l_queued_bs_key IS NULL OR (l_queued_bs_key <> l_bs_key AND l_piece_no = 1)) THEN BEGIN -- -- SELECT max(start_time) INTO l_bp_start_time FROM bp WHERE bp.bs_key = l_bs_key AND bp.piece# = 1 AND bp.template_key = p_template_key; trace1('queueBaseLevelBcks: Tape backup written time=' || l_bp_start_time); IF l_bp_start_time IS NULL THEN l_bp_start_time := l_recovery_window_sbt; trace1('queueBaseLevelBcks: set completion time to SBT window'); END IF; END; END IF; IF l_bp_start_time <= l_recovery_window_sbt THEN l_bs_copied2tape := NOT_COPIED_TO_TAPE; trace1('queueBaseLevelBcks: copy again, piece outside SBT window'); ELSE trace1('queueBaseLevelBcks: no copy, piece within SBT window'); END IF; END IF; -- IF ((l_bs_copied2tape = NOT_COPIED_TO_TAPE) AND (l_queued_bs_key IS NULL OR ((l_queued_bs_key = l_bs_key AND l_queued_piece_no <> l_piece_no) OR l_queued_bs_key <> l_bs_key))) THEN trace1('queueBaseLevelBcks: Queuing l_bs_key=' || l_bs_key || ' l_piece_no=' || l_piece_no); IF p_server_key IS NOT NULL THEN create_replication_tasks(p_db_key => p_db_key, p_bs_key => l_bs_key, p_piece_no => l_piece_no, p_bp_key => l_bp_key, p_server_key => p_server_key ); ELSE l_spawn_job := queue_one_sbt_backup_task( p_db_key => p_db_key, p_bs_key => l_bs_key, p_piece_no => l_piece_no, p_template_key => p_template_key, p_full_template_key => p_template_key, p_attr_set_key => p_attr_key, p_lib_key => p_lib_key, p_copies => p_copies, p_src_bpkey => l_bp_key, p_delete_source => p_delete_source, p_format => p_format); END IF; l_queued_bs_key := l_bs_key; l_queued_piece_no := l_piece_no; END IF; END LOOP; CLOSE bp_last_full_cursor; IF p_baseline_scn = 0 THEN p_baseline_scn := l_baseline_scn; UPDATE sbt_template_db SET baseline_scn = p_baseline_scn WHERE db_key = p_db_key AND template_key = p_template_key AND s_c2t_optimization = 1; IF SQL%ROWCOUNT > 0 THEN trace1 ('queueBaseLevelBcks Re-setting baseline_scn to ' || p_baseline_scn); END IF; END IF; trace1 ('queueBaseLevelBcks p_baseline_scn=' || p_baseline_scn); -- UPDATE sbt_template_db SET last_bp_key = p_max_bp_key, curr_dbinc_key = p_currinc WHERE db_key = p_db_key AND template_key = p_template_key AND s_c2t_optimization = 1; IF SQL%ROWCOUNT > 0 THEN trace1 ('queueBaseLevelBcks setting last_bp_key to ' || p_max_bp_key); END IF; trace1 ('queueBaseLevelBcks: updated sbt_template_db ' || SQL%ROWCOUNT); IF NOT l_cffile_selected THEN INSERT INTO sbt_template_df(template_key, db_key, df_file#) VALUES (p_template_key, p_db_key, 0); END IF; IF NOT l_spfile_selected THEN INSERT INTO sbt_template_df(template_key, db_key, df_file#) VALUES (p_template_key, p_db_key, -1); END IF; COMMIT; END queueBaseLevelBcks; -- -- PROCEDURE queueMissingDFBcks(p_db_key IN NUMBER, p_from_tag IN VARCHAR2, p_template_key IN NUMBER, p_baseline_scn IN NUMBER, p_lib_key IN NUMBER, p_attr_key IN NUMBER, p_copies IN NUMBER, p_delete_source IN VARCHAR2, p_format IN VARCHAR2, p_last_bp_key IN NUMBER, p_server_key IN NUMBER) IS l_bs_key NUMBER; l_piece_no NUMBER; l_bp_key NUMBER; l_queued_bs_key NUMBER; l_queued_piece_no NUMBER; l_spawn_job BOOLEAN; l_df_file# NUMBER; l_df_ckpscn# NUMBER; l_df_crescn# NUMBER; l_df_pc# NUMBER; l_df_is_offline_cln NUMBER; l_count NUMBER; -- -- CURSOR bp_ndf_full_cursor IS WITH my_dbinc AS (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn FROM dbinc START WITH dbinc_key = (SELECT curr_dbinc_key from db where db_key=p_db_key) CONNECT BY PRIOR parent_dbinc_key = dbinc_key), df_backup AS -- datafile backups (SELECT * FROM (SELECT RANK() over (PARTITION BY file#, create_scn, plugin_scn ORDER BY ckp_scn DESC, bdf_key DESC) rank, bp.bs_key, bp.bp_key, bp.piece#, bdf.ckp_scn df_checkpoint_change#, stf.df_file#, stf.df_creation_change#, stf.df_plugin_change# FROM bp, bdf, my_dbinc, sbt_template_df stf WHERE bp.bp_key > p_last_bp_key AND bp.bs_key = bdf.bs_key AND bdf.file# = stf.df_file# AND bdf.create_scn = stf.df_creation_change# AND bdf.plugin_scn = stf.df_plugin_change# AND bdf.foreign_dbid = stf.df_foreign_dbid AND stf.template_key = p_template_key AND stf.db_key = p_db_key AND bp.db_key = p_db_key AND (stf.bs_key IS NULL OR stf.bs_key = -1) AND bp.lib_key IS NULL AND (p_from_tag IS NULL OR bp.tag = p_from_tag) AND bp.template_key IS NULL AND bp.ba_access IN ('D', 'L') AND bp.status != 'D' -- -- -- -- AND bp.vb_key IS NOT NULL AND bdf.incr_scn <= bdf.create_scn AND bdf.dbinc_key = my_dbinc.dbinc_key AND (decode(bdf.abs_fuzzy_scn, 0, bdf.ckp_scn, bdf.abs_fuzzy_scn) < my_dbinc.next_reset_scn OR my_dbinc.next_reset_scn IS NULL)) WHERE rank = 1), cf_backup AS -- latest controlfile backup (SELECT * FROM (SELECT RANK() over (ORDER BY ckp_scn DESC, bcf_key DESC) rank, bp.bs_key, bp.bp_key, bp.piece#, bcf.ckp_scn, bcf.ckp_time FROM bp, bcf, my_dbinc, sbt_template_df stf WHERE bp.bs_key = bcf.bs_key AND bp.lib_key IS NULL AND bp.bp_key > p_last_bp_key AND stf.df_file# = 0 AND stf.template_key = p_template_key AND stf.db_key = p_db_key AND bp.db_key = p_db_key AND (stf.bs_key IS NULL OR stf.bs_key = -1) AND bp.ba_access IN ('D', 'L') AND bp.status != 'D' AND (p_from_tag IS NULL OR bp.tag = p_from_tag) AND bcf.dbinc_key = my_dbinc.dbinc_key AND (bcf.ckp_scn < my_dbinc.next_reset_scn OR my_dbinc.next_reset_scn IS NULL)) WHERE rank=1), sf_backup AS -- latest spfile backup (SELECT * FROM (SELECT RANK() over (ORDER BY modification_time DESC) rank, bp.bs_key, bp.bp_key, bp.piece#, bsf.modification_time FROM bp, bsf, sbt_template_df stf WHERE bp.bs_key = bsf.bs_key AND bp.lib_key IS NULL AND bp.bp_key > p_last_bp_key AND stf.df_file# = -1 AND stf.template_key = p_template_key AND stf.db_key = p_db_key AND bp.db_key = p_db_key AND (stf.bs_key IS NULL OR stf.bs_key = -1) AND bp.ba_access IN ('D', 'L') AND bp.status != 'D' AND (p_from_tag IS NULL OR bp.tag = p_from_tag) AND bsf.db_key = p_db_key) WHERE rank=1), ndf_backup AS -- latest backup for all missing files (SELECT bs_key, piece#, bp_key, df_file#, df_creation_change#, df_plugin_change#, df_checkpoint_change# FROM df_backup UNION ALL SELECT bs_key, piece#, bp_key, 0, NULL, NULL, ckp_scn FROM cf_backup UNION ALL SELECT bs_key, piece#, bp_key, -1, NULL, NULL, NULL FROM sf_backup) SELECT ndf.bs_key, ndf.piece#, ndf.bp_key, ndf.df_file#, ndf.df_creation_change#, ndf.df_plugin_change#, ndf.df_checkpoint_change# FROM ndf_backup ndf WHERE ((s_c2t_optimization = 0) OR (s_c2t_optimization = 1 AND NOT EXISTS (SELECT 1 FROM sbt_task_history t WHERE t.failure_cnt = 0 AND t.restore = 'N' AND t.full_template_key = p_template_key AND t.bs_key = ndf.bs_key AND t.piece# = ndf.piece#) AND NOT EXISTS (SELECT 1 FROM sbt_task t WHERE t.restore = 'N' AND t.full_template_key = p_template_key AND t.bs_key = ndf.bs_key AND t.piece# = ndf.piece#))) ORDER BY 1, 2; BEGIN trace1 ('queueMissingDFBcks: Sending missing bcks, template_key=' || p_template_key || ' from_tag=' || p_from_tag || ' db_key=' || p_db_key); -- MERGE INTO sbt_template_df a USING (SELECT DISTINCT p_db_key db_key, file#, ts#, plugin_scn, foreign_dbid, create_scn FROM df WHERE decode(foreign_dbid, 0, create_scn, plugin_scn) > p_baseline_scn AND dbinc_key in (select dbinc_key from dbinc where db_key = p_db_key and dbinc_status <> 'ORPHAN')) b ON (a.db_key = b.db_key AND a.template_key = p_template_key AND a.df_file# = b.file# AND a.df_plugin_change# = b.plugin_scn AND a.df_foreign_dbid = b.foreign_dbid AND a.df_creation_change# = b.create_scn) WHEN NOT MATCHED THEN INSERT (a.db_key, a.df_file#, a.df_ts#, a.df_plugin_change#, a.df_foreign_dbid, a.df_creation_change#, a.template_key) VALUES (b.db_key, b.file#, b.ts#, b.plugin_scn, b.foreign_dbid, b.create_scn, p_template_key); IF SQL%ROWCOUNT > 0 THEN COMMIT; trace1 ('queueMissingDFBcks: row mergred =' || SQL%ROWCOUNT); END IF; -- -- OPEN bp_ndf_full_cursor; LOOP FETCH bp_ndf_full_cursor INTO l_bs_key, l_piece_no, l_bp_key, l_df_file#, l_df_crescn#, l_df_pc#, l_df_ckpscn#; EXIT WHEN bp_ndf_full_cursor%NOTFOUND; -- IF l_df_ckpscn# < p_baseline_scn THEN SELECT COUNT(*) INTO l_df_is_offline_cln FROM DF WHERE dbinc_key = (SELECT curr_dbinc_key FROM db WHERE db_key = p_db_key) AND drop_scn IS NOT NULL AND stop_scn IS NOT NULL AND file# = l_df_file# AND create_scn = l_df_crescn# AND plugin_scn = l_df_pc#; IF l_df_is_offline_cln = 0 THEN CONTINUE; END IF; END IF; trace1 ('queueMissingDFBcks: Found l_bs_key=' || l_bs_key || ' l_piece_no=' || l_piece_no || ' l_df_file#=' || l_df_file# || ' l_df_crescn#=' || l_df_crescn# || ' l_df_pc#=' || l_df_pc# || ' l_queued_bs_key=' || l_queued_bs_key || ' l_queued_piece_no#=' || l_queued_piece_no || ' l_df_ckpscn#=' || l_df_ckpscn#); IF (l_queued_bs_key IS NULL OR ((l_queued_bs_key = l_bs_key AND l_queued_piece_no <> l_piece_no) OR l_queued_bs_key <> l_bs_key)) THEN trace1('queueMissingDFBcks: Queuing l_bs_key=' || l_bs_key || ' l_piece_no=' || l_piece_no); IF p_server_key IS NOT NULL THEN create_replication_tasks(p_db_key => p_db_key, p_bs_key => l_bs_key, p_piece_no => l_piece_no, p_bp_key => l_bp_key, p_server_key => p_server_key ); ELSE l_spawn_job := queue_one_sbt_backup_task( p_db_key => p_db_key, p_bs_key => l_bs_key, p_piece_no => l_piece_no, p_template_key => p_template_key, p_full_template_key => p_template_key, p_attr_set_key => p_attr_key, p_lib_key => p_lib_key, p_copies => p_copies, p_src_bpkey => l_bp_key, p_delete_source => p_delete_source, p_format => p_format); END IF; l_queued_bs_key := l_bs_key; l_queued_piece_no := l_piece_no; END IF; -- UPDATE sbt_template_df SET bs_key = l_bs_key, df_checkpoint_change# = l_df_ckpscn# WHERE db_key = p_db_key AND df_file# = l_df_file# AND (df_creation_change# = l_df_crescn# OR l_df_file# <= 0) AND (df_plugin_change# = l_df_pc# OR l_df_file# <= 0) AND (bs_key IS NULL or bs_key = -1) AND template_key = p_template_key; IF SQL%ROWCOUNT = 1 THEN trace1 ('queueMissingDFBcks: setting bs_key=' || l_bs_key || 'for datafile '|| l_df_file#); ELSE SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM, 'queueMissingDFBcks ' || SQL%ROWCOUNT || ' for datafile '|| l_df_file#); END IF; END LOOP; CLOSE bp_ndf_full_cursor; COMMIT; END queueMissingDFBcks; -- -- PROCEDURE logMissingDfBcksError(p_db_key IN NUMBER, p_currinc IN NUMBER, p_template_key IN NUMBER) IS l_cnt_mdf NUMBER; BEGIN -- -- -- -- -- -- UPDATE sbt_template_df SET bs_key = -1 WHERE bs_key IS NULL AND db_key = p_db_key AND template_key = p_template_key AND NOT EXISTS (SELECT 1 FROM df WHERE df.dbinc_key = p_currinc AND df.drop_scn is null AND df.file# = df_file# AND df.create_scn = df_creation_change# AND df.plugin_scn = df_plugin_change# AND df.foreign_dbid = df_foreign_dbid) AND sbt_template_df.df_file# <> 0; IF SQL%ROWCOUNT > 0 THEN trace1 ('logMissingDfBcksError: dropped sbt_template_df count=' || SQL%ROWCOUNT); COMMIT; END IF; SELECT count(*) INTO l_cnt_mdf FROM sbt_template_df WHERE db_key = p_db_key AND template_key = p_template_key AND df_file# <> -1 -- tolerate non-existence of SPFile Bck AND bs_key IS NULL; -- IF (l_cnt_mdf = 0) THEN fix_error(p_error_num => E_FULL_BACKUP_NOT_FOUND_NUM, p_db_key => p_db_key); trace1('logMissingDfBcksError: fixing E_FULL_BACKUP_NOT_FOUND_NUM'); ELSE log_error(p_errno => E_FULL_BACKUP_NOT_FOUND_NUM, p_db_key => p_db_key, p_param1 => dbms_ra_int.dbkey2name(p_db_key), p_component => 'SBT_FULL_BACKUP', p_severity => SEVERITY_WARNING); trace1 ('logMissingDfBcksError: datafile files missing backup'); END IF; END logMissingDfBcksError; -- -- PROCEDURE queueIncrementalBcks(p_db_key IN NUMBER, p_from_tag IN VARCHAR2, p_template_key IN NUMBER, p_full_template_key IN NUMBER, p_baseline_scn IN NUMBER, p_lib_key IN NUMBER, p_attr_key IN NUMBER, p_copies IN NUMBER, p_delete_source IN VARCHAR2, p_format IN VARCHAR2, p_init_cf_bs_key IN NUMBER, p_last_bp_key IN NUMBER, p_server_key IN NUMBER) IS -- -- CURSOR bp_incr_cursor IS WITH new_bp AS (SELECT bp.bs_key, bp.piece#, bp.bp_key, bp.vb_key FROM bp, bs WHERE bp.db_key = p_db_key AND bp.bp_key > p_last_bp_key AND bp.bs_key = bs.bs_key AND (p_from_tag IS NULL OR bp.tag = p_from_tag) AND bp.lib_key IS NULL AND bp.template_key IS NULL AND bp.ba_access IN ('D', 'L') AND bp.status != 'D' AND bs.bck_type IN ('I', 'D') AND bs.keep_options = 0 ), sf_backup AS -- latest spfile backup, when p_last_bp_key=0 (SELECT * FROM (SELECT RANK() over (ORDER BY modification_time DESC, bsf_key DESC) rank, bp.bs_key, bp.bp_key, bp.piece#, bsf.modification_time FROM bp, bsf WHERE bp.bs_key = bsf.bs_key AND p_last_bp_key = 0 AND bp.bp_key > p_last_bp_key AND bp.lib_key IS NULL AND bp.ba_access IN ('D', 'L') AND bp.status != 'D' AND (p_from_tag IS NULL OR bp.tag = p_from_tag) AND bsf.db_key = p_db_key) WHERE rank=1), incr_backup AS (SELECT new_bp.bs_key, new_bp.piece#, new_bp.bp_key FROM new_bp, bdf WHERE bdf.bs_key = new_bp.bs_key -- -- -- -- AND new_bp.vb_key IS NOT NULL AND bdf.incr_scn > bdf.create_scn AND bdf.incr_scn >= p_baseline_scn UNION ALL SELECT new_bp.bs_key, new_bp.piece#, new_bp.bp_key FROM new_bp, bcf WHERE bcf.bs_key = new_bp.bs_key AND bcf.ckp_scn >= p_baseline_scn UNION ALL SELECT new_bp.bs_key, new_bp.piece#, new_bp.bp_key FROM new_bp, bsf WHERE bsf.bs_key = new_bp.bs_key AND p_last_bp_key > 0 -- -- -- -- UNION ALL SELECT bs_key, piece#, bp_key FROM sf_backup) -- SELECT ib.bs_key, ib.piece#, ib.bp_key FROM incr_backup ib WHERE ((s_c2t_optimization = 0) OR (s_c2t_optimization = 1 AND NOT EXISTS (SELECT 1 FROM sbt_task_history t WHERE t.failure_cnt = 0 AND t.restore = 'N' AND t.full_template_key = p_full_template_key AND t.bs_key = ib.bs_key AND t.piece# = ib.piece#) AND NOT EXISTS (SELECT 1 FROM sbt_task t WHERE t.restore = 'N' AND t.full_template_key = p_full_template_key AND t.bs_key = ib.bs_key AND t.piece# = ib.piece#))) ORDER BY 1, 2; l_bs_key NUMBER; l_piece_no NUMBER; l_bp_key NUMBER; l_spawn_job BOOLEAN; l_queued_bs_key NUMBER; l_queued_piece_no NUMBER; BEGIN trace1('queueIncrementalBcks: Sending Incrementals, template_key='|| p_template_key || ' from_tag=' || p_from_tag || ' db_key=' || p_db_key); OPEN bp_incr_cursor; LOOP FETCH bp_incr_cursor INTO l_bs_key, l_piece_no, l_bp_key; EXIT WHEN bp_incr_cursor%NOTFOUND; trace1('queueIncrementalBcks: l_bs_key=' || l_bs_key || ' l_piece_no=' || l_piece_no || ' l_bp_key=' || l_bp_key || ' l_queued_bs_key=' || l_queued_bs_key || ' l_queued_piece_no#=' || l_queued_piece_no); IF (l_queued_bs_key IS NULL OR ((l_queued_bs_key = l_bs_key AND l_queued_piece_no <> l_piece_no) OR l_queued_bs_key <> l_bs_key)) THEN trace1('queueIncrementalBcks: Queuing l_bs_key=' || l_bs_key || ' l_piece_no=' || l_piece_no); IF p_server_key IS NOT NULL THEN create_replication_tasks(p_db_key => p_db_key, p_bs_key => l_bs_key, p_piece_no => l_piece_no, p_bp_key => l_bp_key, p_server_key => p_server_key ); ELSE l_spawn_job := queue_one_sbt_backup_task( p_db_key => p_db_key, p_bs_key => l_bs_key, p_piece_no => l_piece_no, p_template_key => p_template_key, p_full_template_key => p_full_template_key, p_attr_set_key => p_attr_key, p_lib_key => p_lib_key, p_copies => p_copies, p_src_bpkey => l_bp_key, p_delete_source => p_delete_source, p_format => p_format); END IF; l_queued_bs_key := l_bs_key; l_queued_piece_no := l_piece_no; END IF; IF p_init_cf_bs_key > 0 THEN UPDATE sbt_template_df SET bs_key = l_bs_key WHERE template_key = p_template_key AND db_key = p_db_key AND df_file# = 0 AND bs_key IS NULL AND EXISTS (SELECT bcf.bcf_key FROM bcf WHERE bs_key = l_bs_key); UPDATE sbt_template_df SET bs_key = l_bs_key WHERE template_key = p_template_key AND db_key = p_db_key AND df_file# = -1 AND bs_key IS NULL AND EXISTS (SELECT bsf.bsf_key FROM bsf WHERE bs_key = l_bs_key); COMMIT; END IF; END LOOP; CLOSE bp_incr_cursor; END queueIncrementalBcks; -- -- PROCEDURE queueArchivedLogBcks(p_db_key IN NUMBER, p_from_tag IN VARCHAR2, p_template_key IN NUMBER, p_full_template_key IN NUMBER, p_baseline_scn IN NUMBER, p_lib_key IN NUMBER, p_attr_key IN NUMBER, p_copies IN NUMBER, p_delete_source IN VARCHAR2, p_format IN VARCHAR2, p_init_cf_bs_key IN NUMBER, p_last_bp_key IN NUMBER, p_server_key IN NUMBER) IS -- -- CURSOR bp_arch_cursor IS WITH new_bp AS (SELECT bp.bs_key, bp.piece#, bp.bp_key FROM bp, bs WHERE bp.db_key = p_db_key AND bp.bp_key > p_last_bp_key AND bp.bs_key = bs.bs_key AND (p_from_tag IS NULL OR bp.tag = p_from_tag) AND bp.lib_key IS NULL AND bp.ba_access IN ('D', 'L') AND bp.status != 'D' AND bs.keep_options = 0 ), arch_backup AS (SELECT new_bp.bs_key, new_bp.piece#, new_bp.bp_key FROM new_bp, brl WHERE brl.bs_key = new_bp.bs_key AND brl.next_scn >= p_baseline_scn UNION ALL SELECT new_bp.bs_key, new_bp.piece#, new_bp.bp_key FROM new_bp, bcf WHERE bcf.bs_key = new_bp.bs_key AND bcf.ckp_scn >= p_baseline_scn UNION ALL SELECT new_bp.bs_key, new_bp.piece#, new_bp.bp_key FROM new_bp, bsf WHERE bsf.bs_key = new_bp.bs_key) -- SELECT ab.bs_key, ab.piece#, ab.bp_key FROM arch_backup ab WHERE ((s_c2t_optimization = 0) OR (s_c2t_optimization = 1 AND NOT EXISTS (SELECT 1 FROM sbt_task_history t WHERE t.failure_cnt = 0 AND t.restore = 'N' AND t.full_template_key = p_full_template_key AND t.bs_key = ab.bs_key AND t.piece# = ab.piece#) AND NOT EXISTS (SELECT 1 FROM sbt_task t WHERE t.restore = 'N' AND t.full_template_key = p_full_template_key AND t.bs_key = ab.bs_key AND t.piece# = ab.piece#))) ORDER BY 1, 2; l_bs_key NUMBER; l_piece_no NUMBER; l_bp_key NUMBER; l_spawn_job BOOLEAN; l_queued_bs_key NUMBER; l_queued_piece_no NUMBER; BEGIN trace1('queueArchivedLogBcks: Sending archivelog bcks, template_key='|| p_template_key || ' from_tag=' || p_from_tag || ' db_key=' || p_db_key); OPEN bp_arch_cursor; LOOP FETCH bp_arch_cursor INTO l_bs_key, l_piece_no, l_bp_key; EXIT WHEN bp_arch_cursor%NOTFOUND; trace1('queueArchivedLogBcks: l_bs_key=' || l_bs_key || ' l_piece_no=' || l_piece_no || ' l_bp_key=' || l_bp_key || ' l_queued_bs_key=' || l_queued_bs_key || ' l_queued_piece_no#=' || l_queued_piece_no); IF (l_queued_bs_key IS NULL OR ((l_queued_bs_key = l_bs_key AND l_queued_piece_no <> l_piece_no) OR l_queued_bs_key <> l_bs_key)) THEN trace1('queueBaseLevelBcks: Queuing l_bs_key=' || l_bs_key || ' l_piece_no=' || l_piece_no); IF p_server_key IS NOT NULL THEN create_replication_tasks(p_db_key => p_db_key, p_bs_key => l_bs_key, p_piece_no => l_piece_no, p_bp_key => l_bp_key, p_server_key => p_server_key ); ELSE l_spawn_job := queue_one_sbt_backup_task( p_db_key => p_db_key, p_bs_key => l_bs_key, p_piece_no => l_piece_no, p_template_key => p_template_key, p_full_template_key => p_full_template_key, p_attr_set_key => p_attr_key, p_lib_key => p_lib_key, p_copies => p_copies, p_src_bpkey => l_bp_key, p_delete_source => p_delete_source, p_format => p_format); END IF; l_queued_bs_key := l_bs_key; l_queued_piece_no := l_piece_no; END IF; IF p_init_cf_bs_key > 0 THEN UPDATE sbt_template_df SET bs_key = l_bs_key WHERE template_key = p_template_key AND db_key = p_db_key AND df_file# = 0 AND bs_key IS NULL AND EXISTS (SELECT bcf.bcf_key FROM bcf WHERE bs_key = l_bs_key); UPDATE sbt_template_df SET bs_key = l_bs_key WHERE template_key = p_template_key AND db_key = p_db_key AND df_file# = -1 AND bs_key IS NULL AND EXISTS (SELECT bsf.bsf_key FROM bsf WHERE bs_key = l_bs_key); COMMIT; END IF; END LOOP; CLOSE bp_arch_cursor; END queueArchivedLogBcks; -- -- PROCEDURE queueKeepBcks (p_db_key IN NUMBER, p_from_tag IN VARCHAR2, p_template_key IN NUMBER, p_baseline_scn IN NUMBER, p_lib_key IN NUMBER, p_attr_key IN NUMBER, p_copies IN NUMBER, p_delete_source IN VARCHAR2, p_format IN VARCHAR2, p_last_bp_key IN NUMBER, p_server_key IN NUMBER) IS l_bs_key NUMBER; l_piece_no NUMBER; l_spawn_job BOOLEAN; l_baseline_untscn NUMBER; l_baseline_time DATE; l_recovery_window_sbt DATE; -- -- CURSOR bp_all_keep_cursor IS SELECT DISTINCT bp.bs_key, bp.piece# FROM bp, bs WHERE bp.db_key = p_db_key AND bp.bs_key = bs.bs_key AND bp.template_key IS NULL AND bp.lib_key IS NULL AND bp.ba_access IN ('D', 'L') AND bp.status != 'D' AND ((p_last_bp_key = 0 AND bp.completion_time > l_baseline_time) OR (p_last_bp_key > 0 AND bp.bp_key > p_last_bp_key)) AND bs.keep_options > 0 AND (p_from_tag IS NULL OR bp.tag = p_from_tag) AND ((s_c2t_optimization = 0) OR (s_c2t_optimization = 1 AND NOT EXISTS (SELECT 1 FROM sbt_task_history t WHERE t.failure_cnt = 0 AND t.restore = 'N' AND t.full_template_key = p_template_key AND t.bs_key = bp.bs_key AND t.piece# = bp.piece#) AND NOT EXISTS (SELECT 1 FROM sbt_task t WHERE t.restore = 'N' AND t.full_template_key = p_template_key AND t.bs_key = bp.bs_key AND t.piece# = bp.piece#))) ORDER BY 1, 2; BEGIN IF (p_server_key IS NULL) THEN trace1('queueKeepBcks : returning as server_key is null'); RETURN; END IF; trace1('queueKeepBcks : Sending KEEP backups, template_key='|| p_template_key || ' from_tag=' || p_from_tag || ' db_key=' || p_db_key); -- baselineTimezone(p_db_key, l_baseline_time, l_baseline_untscn, l_recovery_window_sbt); OPEN bp_all_keep_cursor; LOOP FETCH bp_all_keep_cursor INTO l_bs_key, l_piece_no; EXIT WHEN bp_all_keep_cursor%NOTFOUND; trace1('queueKeepBcks: l_bs_key=' || l_bs_key || ' l_piece_no=' || l_piece_no); create_replication_tasks(p_db_key => p_db_key, p_bs_key => l_bs_key, p_piece_no => l_piece_no, p_server_key => p_server_key ); END LOOP; CLOSE bp_all_keep_cursor; END queueKeepBcks; PROCEDURE invalidateTemplateBackup(p_bs_key IN NUMBER, p_bp_key IN NUMBER, p_db_key IN NUMBER, p_template_key IN NUMBER) IS BEGIN -- UPDATE sbt_template_df stf SET bs_key = NULL, df_checkpoint_change# = NULL WHERE stf.db_key = p_db_key AND stf.template_key = p_template_key AND stf.bs_key = p_bs_key; IF SQL%ROWCOUNT > 0 THEN trace1 ('invalidateTemplateBackup: updated sbt_template_df' || SQL%ROWCOUNT); log_error(p_errno => E_FULL_BACKUP_NOT_FOUND_NUM, p_db_key => p_db_key, p_param1 => dbms_ra_int.dbkey2name(p_db_key), p_component => 'SBT_FULL_BACKUP', p_severity => SEVERITY_WARNING); trace1 ('invalidateTemplateBackup: bs_key ' || p_bs_key || ' db_key ' || p_db_key || ' bp_key ' || p_bp_key || ' template_key ' || p_template_key || ' not copied to tape'); END IF; -- -- UPDATE sbt_template_db std SET std.last_bp_key = p_bp_key - 1 WHERE std.db_key = p_db_key AND std.template_key = p_template_key AND std.last_bp_key >= p_bp_key AND s_c2t_optimization = 1; IF SQL%ROWCOUNT = 1 THEN trace1 ('invalidateTemplateBackup: updated one sbt_template_db row'); END IF; END invalidateTemplateBackup; -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION check_do_pending_rep_setup(p_db_key IN VARCHAR2) RETURN BOOLEAN IS l_db_key NUMBER; l_prot_key NUMBER; l_ckpt NUMBER; l_template_name sbt_job_template.template_name%TYPE; l_prot_name prot.prot_name%TYPE; l_lib_key NUMBER; l_pending_rep_setup VARCHAR2(1); l_obj_type VARCHAR2(128); l_obj_name VARCHAR2(128); l_rv BOOLEAN := FALSE; l_all_reconciled BOOLEAN := TRUE; l_all_replicated BOOLEAN := TRUE; l_db_unique_name node.db_unique_name%TYPE; l_lockflag BOOLEAN; l_rec_cnt NUMBER; -- num we reconciled against l_exp_rec_cnt NUMBER; -- num we expected to reconcile against l_rep_atr_name sbt_attr_set.attr_name%TYPE; BEGIN IF p_db_key IS NULL THEN trace1 ('CHECK_DO_PENDING_REP_SETUP: required db_key missing.'); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM, 'cannot complete rep setup without a dbkey'); END IF; l_db_key := p_db_key; l_db_unique_name := dbms_ra_int.dbkey2name(l_db_key); -- -- -- -- -- -- -- l_lockflag := SYS.KBRSI_ICD.RSKEYWRITELOCK (l_db_key, TRUE); SELECT pending_rep_setup, prot_key INTO l_pending_rep_setup, l_prot_key FROM odb o WHERE o.db_key = l_db_key; trace1 ('CHECK_DO_PENDING_REP_SETUP: write lock on db_key=' || l_db_key || ', pending_rep_setup=' || l_pending_rep_setup || ', got_lock=' || print(l_lockflag)); -- IF l_pending_rep_setup <> 'Y' THEN IF l_lockflag THEN SYS.KBRSI_ICD.RSKEYUNLOCK(l_db_key); END IF; RETURN TRUE; END IF; trace1 ('CHECK_DO_PENDING_REP_SETUP: Completing rep setup for ' || l_db_unique_name || '(' || l_db_key || ')'); SELECT prot_name INTO l_prot_name FROM prot WHERE prot_key=l_prot_key; SELECT count(*) INTO l_exp_rec_cnt FROM rep_server rs, odb o WHERE rs.prot_key = l_prot_key AND o.prot_key = rs.prot_key AND o.db_key = l_db_key; IF l_exp_rec_cnt > 0 THEN trace1 ('CHECK_DO_PENDING_REP_SETUP: Expecting to reconcile ' || l_exp_rec_cnt || ' replication servers'); FOR f IN (SELECT rs.server_key, s.rep_server_name FROM rep_server rs, server s WHERE prot_key=l_prot_key AND s.server_key = rs.server_key) LOOP BEGIN l_rv := reconcile_db (p_db_key => l_db_key, p_server_key => f.server_key, p_only_active => FALSE, p_force_reconcile => TRUE, rec_cnt => l_rec_cnt); trace1('CHECK_DO_PENDING_REP_SETUP: reconcile complete. rv='|| print(l_rv) || ' actual_reconcile count=' || l_rec_cnt || ', expected_reconcile=' || l_exp_rec_cnt); IF NOT l_rv OR l_rec_cnt = 0 THEN trace1('CHECK_DO_PENDING_REP_SETUP: not all reconciled'); l_all_reconciled := FALSE; dbms_ra_scheduler.log_error(p_errno => dbms_ra.REP_SETUP_ERROR_NUM, p_db_key => l_db_key, p_param1 => 'complete_setup_reconcile_' || l_rec_cnt, p_param2 => f.rep_server_name, p_param3 => l_db_unique_name, P_keep_stack => FALSE, p_component =>'REPLICATION_RECONCILE', p_severity => dbms_ra_scheduler.SEVERITY_ERROR, p_param_char => 'RECONCILE'); END IF; END; END LOOP; IF l_all_reconciled AND l_rec_cnt = l_exp_rec_cnt THEN fix_error (p_error_num => dbms_ra.REP_SETUP_ERROR_NUM, p_db_key => l_db_key, p_param_char => 'RECONCILE'); END IF; ELSE l_all_reconciled := FALSE; trace1('CHECK_DO_PENDING_REP_SETUP: No dbs to reconcile.' || 'Aborting completion of replication setup'); END IF; -- IF l_all_reconciled THEN -- -- UPDATE odb SET pending_rep_setup = 'N' WHERE db_key = l_db_key; COMMIT; FOR f IN (SELECT rs.server_key, s.rep_server_name FROM rep_server rs, server s WHERE prot_key=l_prot_key AND s.server_key = rs.server_key) LOOP BEGIN l_ckpt := 4; -- dbms_ra_scheduler.queue_set_reconcile_timer (l_db_key); l_ckpt := 5; -- -- -- l_template_name := dbms_ra_int.build_rep_tpl_name ( rep_srv_name => f.rep_server_name, db_key => l_db_key, prot_key => l_prot_key); trace1 ('CHECK_DO_PENDING_REP_SETUP: Creating template ' || l_template_name); BEGIN l_rep_atr_name := dbms_ra_int.build_rep_atr_name(f.rep_server_name); dbms_ra_int.create_sbt_job_template_int(template_name =>l_template_name, db_unique_name => l_db_unique_name, attr_name => l_rep_atr_name, backup_type => 'ALL', do_commit => TRUE); EXCEPTION WHEN DBMS_RA.DUP_NAME THEN -- save_error; clear_error; END; trace1 ('CHECK_DO_PENDING_REP_SETUP: Queueing replicate_existing '|| 'for db=' ||l_db_unique_name || ', rep_srvr=' || f.rep_server_name); dbms_ra_scheduler.replicate_existing_backups( p_template_name => l_template_name); EXCEPTION WHEN OTHERS THEN l_all_replicated := FALSE; -- -- dbms_ra_scheduler.log_error (p_errno => dbms_ra.REP_SETUP_ERROR_NUM, p_db_key => l_db_key, p_param1 => 'complete_setup_initrep_' || l_ckpt, p_param2 => f.rep_server_name, p_param3 => l_db_unique_name, P_keep_stack => FALSE, p_component => 'REPLICATION_INITIAL_REP', p_severity => dbms_ra_scheduler.SEVERITY_ERROR, p_param_char => 'INITIAL_REPLICATION'); END; END LOOP; IF l_all_replicated THEN fix_error (p_error_num => dbms_ra.REP_SETUP_ERROR_NUM, p_db_key => l_db_key, p_param_char => 'INITIAL_REPLICATION'); END IF; END IF; IF l_all_replicated AND l_all_reconciled THEN trace1 ('CHECK_DO_PENDING_REP_SETUP: Replication setup completed for ' || l_db_unique_name); l_rv := TRUE; END IF; IF l_lockflag THEN SYS.KBRSI_ICD.RSKEYUNLOCK(l_db_key); END IF; RETURN l_rv; EXCEPTION WHEN OTHERS THEN save_error; IF l_lockflag THEN SYS.KBRSI_ICD.RSKEYUNLOCK(l_db_key); END IF; clear_error; RAISE; END check_do_pending_rep_setup; -- -- -- -- -- -- -- -- -- PROCEDURE replicate_one_bp (p_db_key IN NUMBER, p_bp_key IN NUMBER, p_server_key IN NUMBER DEFAULT NULL) IS l_pending_rep_setup odb.pending_rep_setup%TYPE; l_db_key NUMBER := p_db_key; l_bp_key NUMBER := p_bp_key; l_repcnt NUMBER; BEGIN IF l_db_key IS NULL THEN trace1 ('REPLICATE_ONE_BP: required db_key missing.'); RETURN; END IF; IF l_bp_key IS NULL THEN trace1 ('REPLICATE_ONE_BP: required bp_key missing.'); RETURN; END IF; -- -- -- -- -- -- -- -- SELECT pending_rep_setup INTO l_pending_rep_setup FROM odb WHERE odb.db_key=l_db_key; IF l_pending_rep_setup = 'Y' THEN IF NOT check_do_pending_rep_setup(l_db_key) THEN trace1 ('REPLICATE_ONE_BP: Unable to complete replication ' || 'setup for database ' || dbms_ra_int.dbkey2name(l_db_key)); RETURN; END IF; END IF; -- SELECT count(*) INTO l_repcnt FROM odb o, rep_server rs WHERE o.prot_key = rs.prot_key AND o.db_key = l_db_key AND rs.server_key = NVL(p_server_key, rs.server_key) AND rs.status = 'A'; IF l_repcnt > 0 THEN DBMS_RA_SCHEDULER.CREATE_REPLICATION_TASKS(p_db_key => l_db_key, p_bp_key => l_bp_key, p_server_key => p_server_key); END IF; END replicate_one_bp; -- END dbms_ra_scheduler; >>> define prvtrssm_plb <<< CREATE OR REPLACE PACKAGE BODY dbms_ra_storage AS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- /*-------------------------* * Package State Variables * *-------------------------*/ s_tracing_on BOOLEAN := FALSE; s_perf_on BOOLEAN := FALSE; s_stall_on BOOLEAN := FALSE; s_safe_mode BOOLEAN := FALSE; s_db_level BINARY_INTEGER := 0; -- locking depth for database alloc s_sl_level BINARY_INTEGER := 0; -- locking depth for storage locs s_enable_dup NUMBER := 1; -- When space runs out only normal -- -- -- -- -- PROCEDURE repair_orphan_file (p_sl_key NUMBER, p_fname VARCHAR2); PROCEDURE repair_fileless_metadata (p_fname VARCHAR2); FUNCTION allocate_db_space ( p_sl_key IN OUT NUMBER, p_db_key IN NUMBER, p_size IN NUMBER DEFAULT NULL, p_movepurge IN BOOLEAN DEFAULT FALSE) RETURN BOOLEAN; PROCEDURE check_tape_limit(p_db_key IN NUMBER, p_reserved IN NUMBER, p_used_space IN NUMBER, p_not_taped IN NUMBER, p_not_taped_state IN VARCHAR2, p_move_phase IN NUMBER, p_allocation IN NUMBER); PROCEDURE return_space (p_size IN NUMBER, p_db_key IN NUMBER, p_sl_key IN NUMBER, p_db_sl_key IN NUMBER); FUNCTION available_bs(p_sl_key IN NUMBER, p_db_key IN NUMBER, p_alloc IN NUMBER) RETURN BOOLEAN; PROCEDURE move_db (p_db_key IN NUMBER); PROCEDURE used_space_check (p_db_key IN NUMBER, p_sl_key IN NUMBER, p_check_files IN BOOLEAN DEFAULT FALSE, p_repair_sl_key IN NUMBER DEFAULT NULL); -- -- -- FUNCTION print (p_value IN BOOLEAN) RETURN VARCHAR2; FUNCTION print (p_value IN NUMBER) RETURN VARCHAR2; FUNCTION print (p_value IN DSINTERVAL_UNCONSTRAINED) RETURN VARCHAR2; FUNCTION print (p_value IN VARCHAR2) RETURN VARCHAR2; PROCEDURE tracex (message IN VARCHAR2); PROCEDURE trace1 (message IN VARCHAR2); -- -- -- s_init_done BOOLEAN := FALSE; -- true if packages vars initialized sf_chunksize NUMBER := NULL; -- Chunk size from current db sf_curr_db NUMBER := 0; -- Remembering curr_db optimizes chunksize get -- -- -- -- -- -- s_chunkno_cache_execution NUMBER := -1; TYPE numtab IS TABLE OF NUMBER INDEX BY VARCHAR2(16); s_chunkno_cache_first numtab; s_chunkno_cache_next numtab; -- -- -- -- -- -- s_sl_info_cache_execution NUMBER := -1; s_sl_info_key NUMBER; s_sl_info_chunksize NUMBER; -- -- -- TRUE# CONSTANT NUMBER := 1; FALSE# CONSTANT NUMBER := 0; -- -- PROCEDURE save_error IS BEGIN DBMS_RA_INT.SAVE_ERROR_INT; END save_error; -- -- PROCEDURE clear_error IS BEGIN DBMS_RA_INT.CLEAR_ERROR_INT; END clear_error; -- -- -- -- -- -- FUNCTION f_chunksize(p_dbkey IN NUMBER) RETURN NUMBER IS BEGIN -- IF sf_curr_db != p_dbkey THEN SELECT sl_min_alloc INTO sf_chunksize FROM odb WHERE db_key = p_dbkey; sf_curr_db := p_dbkey; END IF; RETURN sf_chunksize; END f_chunksize; -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE copy_piece(p_fname IN VARCHAR2 DEFAULT NULL, p_db_key IN NUMBER DEFAULT NULL, p_action IN NUMBER DEFAULT 0) IS l_newfname VARCHAR2(513) := NULL; l_sldir VARCHAR2(513); l_fsize NUMBER; l_bp_key NUMBER; l_alg_over_alloc NUMBER; BEGIN -- -- -- SELECT sl_cg_name INTO l_sldir FROM sl, odb WHERE odb.sl_key = sl.sl_key AND odb.db_key = p_db_key; -- -- -- -- trace1 ('COPY_PIECE: File to be copied from ' || p_fname || ' to ' || l_sldir); trace1 ('COPY_PIECE: p_action value ' || p_action); -- dbms_ra_int.s_bp_save.DELETE; l_alg_over_alloc := DBMS_RA_SCHEDULER.S_ALG_OVER_ALLOC; SYS.KBRSI_ICD.RSCOPYFILE (p_fname, l_newfname, l_fsize, l_sldir, p_action, l_alg_over_alloc); -- dbms_ra_int.s_bp_save.DELETE; -- SELECT bp_key INTO l_bp_key FROM sbt_catalog WHERE filename = l_newfname AND filesize IS NOT NULL; dbms_ra_scheduler.replicate_one_bp (p_db_key => p_db_key, p_bp_key => l_bp_key); EXCEPTION WHEN OTHERS THEN save_error; -- dbms_ra_int.s_bp_save.DELETE; RAISE; END copy_piece; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE check_files (p_sl_key IN NUMBER, p_execute_time IN TIMESTAMP WITH TIME ZONE, p_savepoint IN NUMBER, p_repair IN BOOLEAN) IS l_sl_count NUMBER; l_savepoint NUMBER := p_savepoint; l_storage_directory sl.sl_cg_name%TYPE; l_sl_name sl.sl_name%TYPE; l_omf_namespace VARCHAR2(1) := NULL; l_scn NUMBER; l_repair_sl_key NUMBER; l_blockpool_usage NUMBER; l_sbtpiece_usage NUMBER; l_task_chunk_cache NUMBER; l_task_purge_reserve NUMBER; l_used_space NUMBER; l_dbsl_used NUMBER; l_total_allocation NUMBER; l_computed_allocation NUMBER; BEGIN trace1 ('CHECK_FILES: sl_key=' || p_sl_key || '; savepoint ' || p_savepoint || '; execute_time ' || p_execute_time); -- -- -- -- -- -- SELECT COUNT(*) INTO l_sl_count FROM sl WHERE sl_space > 0 AND ROWNUM <= 2; -- -- -- -- -- -- -- LOOP DELETE contained_filenames WHERE sl_key = p_sl_key AND ROWNUM < 50000; EXIT WHEN SQL%ROWCOUNT = 0; COMMIT; END LOOP; LOOP DELETE metadata_filenames WHERE sl_key = p_sl_key AND ROWNUM < 50000; EXIT WHEN SQL%ROWCOUNT = 0; COMMIT; END LOOP; COMMIT; -- IF l_savepoint = 0 THEN -- -- -- -- -- -- -- -- SELECT MIN(sl_cg_name), MIN(sl_name) INTO l_storage_directory, l_sl_name FROM sl WHERE sl_key = p_sl_key; IF l_storage_directory IS NULL THEN trace1 ('CHECK_FILES: Storage location is no more.'); RETURN; END IF; trace1 ('CHECK_FILES: Storage is at: ' || l_storage_directory); -- -- -- -- INSERT INTO contained_filenames (fname, sl_key) (SELECT filename, p_sl_key FROM sys.am$file f, sl s WHERE s.sl_cg_name = f.params AND s.sl_key = p_sl_key); COMMIT; trace1 ('CHECK_FILES: File list is created.'); -- -- -- -- -- -- -- INSERT INTO metadata_filenames (fname, sl_key) (SELECT filename, p_sl_key FROM chunks, sl, dbinc, db WHERE chunks.sl_key = p_sl_key AND chunks.sl_key = sl.sl_key AND chunks.dbinc_key = dbinc.dbinc_key AND dbinc.db_key = db.db_key AND chunks.filename IS NOT NULL); trace1('CHECK_FILES: Assembled filenames for ' || SQL%ROWCOUNT || ' block pool chunks.'); COMMIT; INSERT INTO metadata_filenames (fname, sl_key) (SELECT sc.filename, p_sl_key FROM sbt_catalog sc WHERE sc.sl_key = p_sl_key AND sc.ftype = 'F' AND sc.filesize IS NOT NULL AND sc.filename IS NOT NULL); trace1('CHECK_FILES: Assembled filenames for ' || SQL%ROWCOUNT || ' sbt received files.'); COMMIT; -- -- -- -- IF p_repair THEN FOR f IN (SELECT mf.fname fname FROM metadata_filenames mf WHERE mf.sl_key = p_sl_key MINUS SELECT cf.fname FROM contained_filenames cf WHERE cf.sl_key = p_sl_key) LOOP trace1 ('CHECK_FILES: Fileless metadata for ' || f.fname); repair_fileless_metadata (f.fname); END LOOP; END IF; -- -- -- FOR f IN (SELECT fname FROM contained_filenames cf WHERE sl_key = p_sl_key AND NOT EXISTS (SELECT 1 FROM metadata_filenames tmf WHERE cf.fname = tmf.fname AND sl_key = p_sl_key) ) LOOP IF p_repair THEN -- -- -- repair_orphan_file(p_sl_key, f.fname); ELSE -- -- -- -- -- -- -- MERGE INTO missing_metadata_filenames mmf USING dual ON ((mmf.sl_key = p_sl_key) AND (mmf.fname = f.fname)) WHEN NOT MATCHED THEN INSERT ( sl_key, fname, entered, latest) VALUES (p_sl_key, f.fname, SYSTIMESTAMP, SYSTIMESTAMP) WHEN MATCHED THEN UPDATE SET latest = SYSTIMESTAMP; trace1 ('CHECK_FILES: Potential orphan file -- ' || f.fname); END IF; END LOOP; -- -- -- DELETE contained_filenames WHERE sl_key = p_sl_key; COMMIT; IF NOT p_repair THEN -- -- -- -- DELETE FROM missing_metadata_filenames WHERE sl_key = p_sl_key AND latest < p_execute_time; trace1 ('CHECK_FILES: ' || SQL%ROWCOUNT || ' files left the orphanage'); COMMIT; -- -- -- FOR f IN (SELECT fname FROM missing_metadata_filenames WHERE sl_key = p_sl_key AND entered < (p_execute_time - DBMS_RA_SCHEDULER.S_ORPHAN_FILE_WAIT)) LOOP trace1 ('CHECK_FILES: Reportable orphan file -- ' || f.fname); DBMS_RA_SCHEDULER.LOG_ERROR ( p_errno => DBMS_RA_SCHEDULER.E_ORPHAN_FILE_NUM, p_param1 => f.fname, p_param2 => l_sl_name, p_component => 'CHECK_FILES', p_severity => DBMS_RA_SCHEDULER.SEVERITY_ERROR, p_sl_key => p_sl_key, p_param_char => f.fname); END LOOP; -- -- -- trace1 ('CHECK_FILES: Clear corrected orphan_file errors'); DBMS_RA_SCHEDULER.FIX_ERROR( p_error_num => DBMS_RA_SCHEDULER.E_ORPHAN_FILE_NUM, p_sl_key => p_sl_key, p_timestamp => p_execute_time); END IF; trace1 ('CHECK_FILES: File check complete.'); END IF; -- -- -- -- -- -- IF p_repair THEN UPDATE task SET flags = flags - BITAND (flags, DBMS_RA_SCHEDULER.TASKS_CHUNK_CACHE_ACTIVE); DELETE task_chunk_cache; COMMIT; END IF; -- -- -- DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT(1); -- -- -- -- -- -- IF (l_savepoint <= 1) AND (NOT p_repair) THEN -- -- -- FOR f IN (SELECT sc.handle, DBMS_RA_INT.DBKEY2NAME(sc.db_key) db_unique_name FROM sbt_catalog sc WHERE sc.sl_key = p_sl_key AND sc.completed = 'Y' AND sc.filesize IS NOT NULL AND NOT EXISTS (SELECT 1 FROM bp WHERE bp.db_key = sc.db_key AND bp.handle = sc.handle AND bp.vb_key IS NULL) ) LOOP trace1 ('CHECK_FILES: Orphan sbt piece -- ' || f.handle); DBMS_RA_SCHEDULER.LOG_ERROR ( p_errno => DBMS_RA_SCHEDULER.E_ORPHAN_BP_PIECE_NUM, p_param1 => f.handle, p_param2 => f.db_unique_name, p_component => 'CHECK_FILES', p_severity => DBMS_RA_SCHEDULER.SEVERITY_ERROR, p_sl_key => p_sl_key, p_param_char => f.handle); END LOOP; trace1 ('CHECK_FILES: Finished SBT piece check.'); -- -- -- trace1 ('CHECK_FILES: Clear corrected orphan_bp_piece errors'); DBMS_RA_SCHEDULER.FIX_ERROR( p_error_num => DBMS_RA_SCHEDULER.E_ORPHAN_BP_PIECE_NUM, p_sl_key => p_sl_key, p_timestamp => p_execute_time); COMMIT; END IF; -- -- -- DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT(2); -- -- -- -- -- -- IF l_savepoint <= 2 THEN IF p_repair THEN l_repair_sl_key := p_sl_key; ELSE l_repair_sl_key := NULL; END IF; FOR u IN (SELECT odb.db_key, odb.sl_key, odb.sl_min_alloc chunksize FROM odb LEFT OUTER JOIN dbsl ON ((odb.db_key = dbsl.db_key) AND (dbsl.sl_key = p_sl_key)) WHERE (odb.sl_key = p_sl_key OR dbsl.sl_key = p_sl_key) ) LOOP -- -- -- -- -- -- used_space_check (u.db_key, p_sl_key, TRUE, l_repair_sl_key); IF NOT p_repair THEN trace1 ('CHECK_FILES: Clear corrected bad usage errors'); DBMS_RA_SCHEDULER.FIX_ERROR( p_error_num => DBMS_RA_SCHEDULER.E_BAD_ODB_USAGE_NUM, p_db_key => u.db_key, p_timestamp => p_execute_time); trace1 ('CHECK_FILES: Clear corrected bad total allocation errors'); DBMS_RA_SCHEDULER.FIX_ERROR( p_error_num => DBMS_RA_SCHEDULER.E_BAD_TOTAL_ALLOC_NUM, p_db_key => u.db_key, p_timestamp => p_execute_time); END IF; END LOOP; -- -- -- IF p_repair THEN trace1 ('CHECK_FILES: Clear corrected bad dbid errors'); DBMS_RA_SCHEDULER.FIX_ERROR( p_error_num => DBMS_RA_SCHEDULER.E_BAD_DBID_NUM, p_sl_key => p_sl_key, p_timestamp => p_execute_time); trace1 ('CHECK_FILES: Clear corrected bad backuppiece errors'); DBMS_RA_SCHEDULER.FIX_ERROR( p_error_num => DBMS_RA_SCHEDULER.E_BAD_BACKUP_PIECE_NUM, p_sl_key => p_sl_key, p_timestamp => p_execute_time); trace1 ('CHECK_FILES: Clear corrected unknown datafile errors'); DBMS_RA_SCHEDULER.FIX_ERROR( p_error_num => DBMS_RA_SCHEDULER.E_UNKNOWN_DATAFILE_NUM, p_sl_key => p_sl_key, p_timestamp => p_execute_time); trace1 ('CHECK_FILES: Clear corrected unknown file type errors'); DBMS_RA_SCHEDULER.FIX_ERROR( p_error_num => DBMS_RA_SCHEDULER.E_UNKNOWN_FILE_NUM, p_sl_key => p_sl_key, p_timestamp => p_execute_time); END IF; END IF; COMMIT; trace1 ('CHECK_FILES: Finished used_space check.'); -- -- -- DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT(3); -- -- -- UPDATE sl SET sl_last_check_files = SYSTIMESTAMP WHERE sl_key = p_sl_key; COMMIT; END check_files; -- -- -- -- -- -- -- -- -- -- -- PROCEDURE repair_orphan_file (p_sl_key NUMBER, p_fname VARCHAR2) IS l_size NUMBER; l_complete BOOLEAN; l_backuppiece_id NUMBER; l_ftype NUMBER; l_dbid NUMBER; l_db_key NUMBER; l_dbsl_key NUMBER; l_sl_min_alloc NUMBER; l_allocsize NUMBER; l_newctkey NUMBER; -- -- l_backupset_id NUMBER; l_task_rec task%ROWTYPE; l_repcnt NUMBER; l_dbinc_key NUMBER; l_df_key NUMBER; l_chunkno NUMBER; l_newfincarn sbt_catalog.pieceinc%TYPE := 'NEEDS_REPAIR'; l_sameendian BINARY_INTEGER; BEGIN trace1 ('REPAIR_ORPHAN_FILE for ' || p_fname); -- -- -- SYS.KBRSI_ICD.RSISCOMPLETE(fname => p_fname, filesize => l_size, complete => l_complete, ftype => l_ftype, same_endian => l_sameendian, dbid => l_dbid); IF l_complete THEN trace1 ('REPAIR_ORPHAN_FILE: completed=' || print(l_complete) || ', dbid=' || l_dbid || ', ftype ' || l_ftype || ', size ' || l_size); ELSE trace1 ('REPAIR_ORPHAN_FILE: Found incomplete. Size=' || l_size); SYS.KBRSI_ICD.RSDELETEFILE(p_fname); RETURN; END IF; -- -- -- BEGIN SELECT db.db_key, odb.sl_key INTO l_db_key, l_dbsl_key FROM db, odb WHERE db.db_key = odb.db_key AND db_id = l_dbid; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; trace1 ('REPAIR_ORPHAN_FILE: File %s references an unknown dbid: ' || l_dbid); DBMS_RA_SCHEDULER.LOG_ERROR ( p_errno => DBMS_RA_SCHEDULER.E_BAD_DBID_NUM, p_param1 => p_fname, p_param2 => l_dbid, p_keep_stack=> FALSE, p_component => 'REPAIR', p_severity => DBMS_RA_SCHEDULER.SEVERITY_ERROR, p_sl_key => p_sl_key, p_param_char => p_fname); clear_error; END; CASE WHEN (l_ftype IN (DBMS_RA_SCHEDULER.FTYPE_ARCHBACKUP, DBMS_RA_SCHEDULER.FTYPE_AUTOBACKUP, DBMS_RA_SCHEDULER.FTYPE_BACKUP, DBMS_RA_SCHEDULER.FTYPE_INCBACKUP)) THEN -- -- -- SELECT sl_min_alloc INTO l_sl_min_alloc FROM sl WHERE sl_key = p_sl_key; l_allocsize := CEIL(l_size/l_sl_min_alloc) * l_sl_min_alloc; trace1 ('REPAIR_ORPHAN_FILE: min_alloc= ' || l_sl_min_alloc || '; allocsize= ' || l_allocsize); -- -- -- -- l_newctkey := rman_seq.NEXTVAL; INSERT INTO sbt_catalog (ct_key, db_key, cretime, handle, pieceinc, endupload, bp_key, ftype, sl_key, sl_min_alloc, filename, filesize, last_entry, completed) VALUES (l_newctkey, l_db_key, SYSTIMESTAMP, p_fname, l_newfincarn, 'Y', NULL, 'F', p_sl_key, l_sl_min_alloc, p_fname, l_allocsize, SYSTIMESTAMP, 'N'); -- -- -- -- -- -- -- IF p_sl_key <> l_dbsl_key THEN trace1 ('REPAIR_ORPHAN_FILE: sl_key=' || p_sl_key || '; dbsl_key=' || l_dbsl_key); MERGE INTO dbsl USING dual ON ((dbsl.db_key = l_db_key) AND (dbsl.sl_key = p_sl_key)) WHEN NOT MATCHED THEN INSERT ( db_key, sl_key, dbsl_used_space) VALUES (l_db_key, p_sl_key, l_allocsize); END IF; COMMIT; -- -- -- BEGIN SYS.KBRSI_ICD.RSINSPECTBACKUPPIECE( handle => p_fname, vbkey => null, bpsize => l_size, chktype => DBMS_RA_INT.KBRSCHKTYPE_FILE, fno => null, lib_key => null,/* local disk */ ct_key => l_newctkey, bpkey => l_backuppiece_id, template_key => null); EXCEPTION WHEN OTHERS THEN save_error; trace1 ('REPAIR_ORPHAN_FILE: Processing backup returned: ' || SQLERRM); DBMS_RA_SCHEDULER.LOG_ERROR ( p_errno => DBMS_RA_SCHEDULER.E_BAD_BACKUP_PIECE_NUM, p_param1 => p_fname, p_component => 'REPAIR', p_severity => DBMS_RA_SCHEDULER.SEVERITY_ERROR, p_sl_key => p_sl_key, p_param_char => p_fname); sys.kbrsi_icd.rsClearErr; free_backup_piece(p_dbkey => l_db_key ,p_piecename => p_fname ,p_fincarn => l_newfincarn ,p_ftype => DBMS_RA_INT.KBRSCHKTYPE_FILE); COMMIT; clear_error; END; -- -- -- dbms_ra_scheduler.replicate_one_bp (p_db_key => l_db_key, p_bp_key => l_backuppiece_id); -- -- -- COMMIT; WHEN (l_ftype IN (DBMS_RA_SCHEDULER.FTYPE_CHUNK)) THEN -- -- -- -- -- BEGIN SELECT df.dbinc_key, df.df_key INTO l_dbinc_key, l_df_key FROM dbinc, df WHERE dbinc.dbinc_key = df.dbinc_key AND dbinc.db_key = l_db_key AND ROWNUM=1; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; trace1 ('REPAIR_ORPHAN_FILE: Unknown Datafile for dbid ' || l_dbid); DBMS_RA_SCHEDULER.LOG_ERROR ( p_errno => DBMS_RA_SCHEDULER.E_UNKNOWN_DATAFILE_NUM, p_param1 => p_fname, p_param2 => l_dbid, p_keep_stack=> FALSE, p_component => 'REPAIR', p_severity => DBMS_RA_SCHEDULER.SEVERITY_ERROR, p_sl_key => p_sl_key, p_param_char => p_fname); clear_error; END; -- -- -- -- -- -- -- IF p_sl_key <> l_dbsl_key THEN trace1 ('REPAIR_ORPHAN_FILE: sl_key=' || p_sl_key || '; dbsl_key=' || l_dbsl_key); MERGE INTO dbsl USING dual ON ((dbsl.db_key = l_db_key) AND (dbsl.sl_key = p_sl_key)) WHEN NOT MATCHED THEN INSERT ( db_key, sl_key, dbsl_used_space) VALUES (l_db_key, p_sl_key, 1); END IF; -- -- -- -- -- l_chunkno := get_chunkno (l_df_key); trace1 ('REPAIR_ORPHAN_FILE: Inserting chunkno=' || l_chunkno || '; df_key=' || l_df_key || '; dbinc_key=' || l_dbinc_key); INSERT INTO chunks ( sl_key, dbinc_key, df_key, chunkno, filename, filesize, clean_key) VALUES (p_sl_key, l_dbinc_key, l_df_key, l_chunkno, p_fname, 1, -1); COMMIT; ELSE trace1('REPAIR_ORPHAN_FILE: ' || p_fname || ' is not a valid recovery appliance file'); DBMS_RA_SCHEDULER.LOG_ERROR ( p_errno => DBMS_RA_SCHEDULER.E_UNKNOWN_FILE_NUM, p_param1 => p_fname, p_component => 'REPAIR', p_severity => DBMS_RA_SCHEDULER.SEVERITY_ERROR, p_sl_key => p_sl_key, p_param_char => p_fname); END CASE; END repair_orphan_file; -- -- -- -- -- -- -- -- -- -- -- PROCEDURE repair_fileless_metadata (p_fname VARCHAR2) IS l_ct_key NUMBER; l_db_key NUMBER; l_handle sbt_catalog.handle%TYPE; l_dbid NUMBER; l_currinc_key NUMBER; l_dbsl_key NUMBER; l_bp_key NUMBER; l_dbinc_key NUMBER; l_df_key NUMBER; l_chunkno NUMBER; CURSOR find_chunks IS SELECT db.db_key, c.df_key, c.dbinc_key, db.db_id, db.curr_dbinc_key, c.chunkno, bp.bp_key, odb.sl_key, bp.handle FROM chunks c JOIN dbinc ON c.dbinc_key = dbinc.dbinc_key JOIN db ON dbinc.db_key = db.db_key JOIN odb ON db.db_key = odb.db_key LEFT OUTER JOIN vbdf ON vbdf.krbph_dfkey = c.df_key AND vbdf.krbph_chunkno = c.chunkno LEFT OUTER JOIN bp USING (vb_key) WHERE c.filename = p_fname; BEGIN trace1('REPAIR_FILELESS_METADATA for ' || p_fname); BEGIN -- -- -- SELECT db_key, s.handle, s.bp_key, db.db_id, db.curr_dbinc_key, odb.sl_key INTO l_db_key, l_handle, l_bp_key, l_dbid, l_currinc_key, l_dbsl_key FROM sbt_catalog s JOIN db USING (db_key) JOIN odb USING (db_key) WHERE s.filename = p_fname; free_backup_piece_opt (p_dbkey => l_db_key ,p_piecename => l_handle ,p_db_slkey => l_dbsl_key ,p_dbid => l_dbid ,p_currinc => l_currinc_key ,p_bpkey => l_bp_key ,p_spawn_job => FALSE ,p_notasks => TRUE ,p_noplans => TRUE); trace1('REPAIR_FILELESS_METADATA: Piece deleted from sbt_catalog'); RETURN; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; trace1('REPAIR_FILELESS_METADATA: Not in sbt_catalog'); clear_error; END; -- -- -- -- FOR c IN find_chunks LOOP trace1('REPAIR_FILELESS_METADATA: bp_key found is ' || print(c.bp_key)); IF c.bp_key IS NOT NULL THEN -- -- -- free_backup_piece_opt (p_dbkey => c.db_key ,p_piecename => c.handle ,p_db_slkey => c.sl_key ,p_dbid => c.db_id ,p_currinc => c.curr_dbinc_key ,p_bpkey => c.bp_key ,p_ftype => NULL ,p_fincarn => NULL ,p_libkey => NULL ,p_spawn_job => FALSE ,p_notasks => TRUE ,p_noplans => TRUE); END IF; l_db_key := c.db_key; l_dbinc_key := c.dbinc_key; l_df_key := c.df_key; l_chunkno := c.chunkno; END LOOP; -- -- -- DELETE FROM blocks WHERE df_key = l_df_key AND chunkno = l_chunkno; trace1('REPAIR_FILELESS_METADATA: Deleting ' || SQL%ROWCOUNT || ' rows in blocks table'); -- -- -- free_block_pool_chunk (l_db_key, l_dbinc_key, l_df_key, l_chunkno); COMMIT; END repair_fileless_metadata; -- -- -- -- -- -- -- -- -- -- PROCEDURE move_all_db IS l_saved NUMBER; l_count NUMBER; l_dbkey NUMBER; l_old_slkey NUMBER; l_new_slkey NUMBER; BEGIN trace1 ('MOVE_ALL_DB'); -- -- -- l_saved := DBMS_RA_SCHEDULER.GET_SAVEPOINT; IF l_saved IS NULL THEN /* verify some other move is not in progress */ BEGIN -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); -- SELECT MAX(task_id) INTO DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT FROM task WHERE task_type = DBMS_RA_SCHEDULER.TASK_MOVE_ALL_DB AND task_id != DBMS_RA_SCHEDULER.S_CURRENT_TASK AND savepoint IS NOT NULL; -- IF DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT IS NULL THEN DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT(0); -- We are now the mover l_saved := 0; -- Indicate we are the mover -- ELSE -- SELECT COUNT(*) INTO l_count FROM task WHERE task_type = DBMS_RA_SCHEDULER.TASK_MOVE_ALL_DB AND state = DBMS_RA_SCHEDULER.STATE_TASK_WAIT; IF l_count = 0 THEN -- No one else is waiting, let us wait RAISE DBMS_RA_SCHEDULER.E_RETRY_ERROR; END IF; END IF; SYS.KBRSI_ICD.RSSCHEDUNLOCK; EXCEPTION WHEN OTHERS THEN save_error; SYS.KBRSI_ICD.RSSCHEDUNLOCK; RAISE; END; IF l_saved IS NULL THEN -- We are not the mover RETURN; END IF; END IF; -- -- -- SELECT MAX(task_id) INTO DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT FROM task WHERE task_type = DBMS_RA_SCHEDULER.TASK_MOVE_DF; IF DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT IS NOT NULL THEN RAISE DBMS_RA_SCHEDULER.E_RETRY_ERROR; END IF; -- -- -- LOOP -- Until we have no more databases to move -- SELECT MIN(db_key) INTO l_dbkey FROM odb WHERE move_phase > DBMS_RA_SCHEDULER.MOVE_PHASE_PEND -- AND db_state IS NULL; -- IF l_dbkey IS NULL THEN -- -- SELECT MIN(db_key) INTO l_dbkey FROM (SELECT db_key, (unclaimed - reserved_space) space FROM /* Unreserved space for each storage location */ (SELECT sl_key, (sl_space - SUM(reserved_space)) unclaimed FROM (SELECT s.sl_key, sl_space, d.reserved_space FROM odb d, prot p, sl s WHERE p.sl_key = s.sl_key AND p.prot_key = d.future_prot_key -- AND d.db_state IS NULL UNION SELECT s.sl_key, sl_space, d.reserved_space FROM unreg_database d, prot p, sl s WHERE p.sl_key = s.sl_key AND p.prot_key = d.prot_key) GROUP BY sl_key, sl_space) a, /* Future reserved space for each moving db */ (SELECT db_key, prot.sl_key, reserved_space FROM odb, prot WHERE odb.future_prot_key = prot.prot_key AND move_phase IS NOT NULL -- AND db_state IS NULL) b WHERE a.sl_key = b.sl_key ORDER BY space) WHERE ROWNUM = 1; IF l_dbkey IS NULL THEN trace1 ('MOVE_ALL_DB: Completed'); RETURN; -- We are all done moving. END IF; END IF; -- SELECT COUNT(*) INTO l_count FROM odb WHERE db_key = l_dbkey AND move_phase = DBMS_RA_SCHEDULER.MOVE_PHASE_PEND; IF l_count > 0 THEN -- We still need to move this database metadata -- -- -- -- trim_database_for_move(l_dbkey, 0); DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT(0); -- SELECT d.sl_key, p.sl_key INTO l_old_slkey, l_new_slkey FROM odb d, prot p WHERE d.future_prot_key = p.prot_key AND d.db_key = l_dbkey; trace1('MOVE_ALL_DB: Moving from ' || l_old_slkey || ' to ' || l_new_slkey); -- -- dbms_ra_scheduler.avoid_sl(DBMS_RA_SCHEDULER.TASK_PURGE, l_old_slkey); BEGIN -- -- DBMS_RA_SCHEDULER.QUIESCE_RS (); DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT(NULL); -- -- -- -- FOR c IN (SELECT task_id FROM task JOIN task_chunk_cache USING (task_id) WHERE db_key = l_dbkey) LOOP free_task_storage (c.task_id); END LOOP; -- move_database_metadata (l_dbkey, l_old_slkey, l_new_slkey); -- DBMS_RA_SCHEDULER.UNQUIESCE_RS (); EXCEPTION WHEN OTHERS THEN save_error; ROLLBACK; DBMS_RA_SCHEDULER.UNQUIESCE_RS (); RAISE; END; -- -- trim_database_for_move(l_dbkey, 0); END IF; -- move_db(l_dbkey); END LOOP; END move_all_db; -- -- -- -- -- -- -- -- -- -- PROCEDURE move_db (p_db_key IN NUMBER) IS l_sl_key NUMBER; l_db_id NUMBER; l_found_work BOOLEAN := FALSE; l_bpkey NUMBER; l_status VARCHAR2(1); l_got_lock BOOLEAN; CURSOR move_block_pool IS SELECT DISTINCT chunks.df_key FROM chunks, df, dbinc WHERE chunks.df_key = df.df_key AND df.dbinc_key = dbinc.dbinc_key AND dbinc.db_key = p_db_key AND chunks.sl_key <> l_sl_key; l_df_key NUMBER; l_count NUMBER; l_newtask_rec task%ROWTYPE; l_bp_key NUMBER; l_bs_key NUMBER; CURSOR move_backup_pieces IS SELECT ct.filename, ct.handle, ct.pieceinc, ct.filesize, ct.bp_key FROM sbt_catalog ct, bp WHERE ct.db_key = p_db_key AND bp.bp_key = ct.bp_key AND ct.sl_key <> l_sl_key AND ct.completed = 'Y' AND bp.status <> 'D'; l_fname VARCHAR2(512); l_handle VARCHAR2(512); l_fincarn VARCHAR2(512); l_fsize NUMBER; l_newfname VARCHAR2(512); l_sldir VARCHAR2(512); l_sls_used NUMBER; l_currinc NUMBER; BEGIN trace1 ('MOVE_DB on database ' || p_db_key); -- -- -- DBMS_RA_SCHEDULER.S_NO_WAIT_ON_ALLOCATE := TRUE; -- -- -- SELECT odb.sl_key, db.db_id, db.curr_dbinc_key INTO l_sl_key, l_db_id, l_currinc FROM odb, db WHERE odb.db_key = p_db_key AND odb.db_key = db.db_key; OPEN move_block_pool; LOOP FETCH move_block_pool INTO l_df_key; EXIT WHEN move_block_pool%NOTFOUND; l_found_work := TRUE; -- -- -- SELECT COUNT(*) INTO l_count FROM task WHERE task_type = DBMS_RA_SCHEDULER.TASK_MOVE_DF AND db_key = p_db_key AND param_num1 = l_df_key; trace1 ('MOVE_DB for df_key=' || l_df_key || '; count=' || l_count ); IF l_count = 0 THEN l_newtask_rec.task_type := DBMS_RA_SCHEDULER.TASK_MOVE_DF; l_newtask_rec.flags := 0; l_newtask_rec.db_key := p_db_key; l_newtask_rec.sl_key := l_sl_key; l_newtask_rec.param_num1 := l_df_key; DBMS_RA_SCHEDULER.NEW_TASK (l_newtask_rec); END IF; END LOOP; CLOSE move_block_pool; DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT(NULL); -- -- -- -- SELECT MAX(task_id) INTO DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT FROM task WHERE task_type = DBMS_RA_SCHEDULER.TASK_MOVE_DF AND db_key = p_db_key; IF DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT IS NOT NULL THEN trace1 ('MOVE_DB: Blocking task is ' || DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT); -- -- -- -- RAISE DBMS_RA_SCHEDULER.E_PENDING_INTERRUPT; END IF; -- -- -- -- -- -- -- -- -- -- BEGIN lock_db (p_db_key); UPDATE odb SET move_phase = DBMS_RA_SCHEDULER.MOVE_PHASE_FILES WHERE db_key = p_db_key; COMMIT; unlock_db (p_db_key); trace1 ('MOVE_DB: Finished moving block pools.'); EXCEPTION WHEN OTHERS THEN save_error; unlock_db (p_db_key); RAISE; END; -- -- -- SELECT sl_cg_name INTO l_sldir FROM sl WHERE sl_key = l_sl_key; -- -- -- OPEN move_backup_pieces; LOOP FETCH move_backup_pieces INTO l_fname, l_handle, l_fincarn, l_fsize, l_bp_key; EXIT WHEN move_backup_pieces%NOTFOUND; trace1 ('MOVE_DB for dbfile= ' || l_handle); l_found_work := TRUE; l_newfname := NULL; l_got_lock := FALSE; -- -- -- -- -- -- -- -- -- -- -- -- -- -- BEGIN DBMS_RA_INT.WRITE_LOCK(DBMS_RA_INT.KEY_BP, l_bp_key); l_got_lock := TRUE; -- -- -- -- SYS.KBRSI_ICD.RSCOPYFILE (l_fname, l_newfname, l_fsize, l_sldir, DBMS_RA_SCHEDULER.COPY_BA_CPMV /*KRBYX_ORS_CPMV*/); trace1 ('MOVE_DB: File copied from ' || l_fname || ' to ' || l_newfname); -- -- -- DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_BP, l_bp_key); -- -- -- free_backup_piece_opt(p_dbkey => p_db_key, p_piecename => l_handle, p_db_slkey => l_sl_key, p_dbid => l_db_id, p_currinc => l_currinc, p_fincarn => l_fincarn, p_ftype => DBMS_RA_INT.KBRSCHKTYPE_FILE, p_bpkey => NULL); EXCEPTION WHEN OTHERS THEN save_error; IF NOT l_got_lock AND SQLCODE = DBMS_RA_SCHEDULER.E_RETRY_ERROR_NUM THEN trace1 ('MOVE_DB: Skipping copy of bp_key ' || l_bp_key); clear_error; CONTINUE; END IF; IF l_bp_key IS NOT NULL AND l_got_lock THEN DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_BP, l_bp_key); END IF; trace1 ('MOVE_DB: Bad copied file: ' || SQLERRM); RAISE; END; -- -- -- DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT(NULL); END LOOP; CLOSE move_backup_pieces; -- -- -- -- IF l_found_work THEN DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT := NULL; RAISE DBMS_RA_SCHEDULER.E_PENDING_INTERRUPT; END IF; -- -- -- -- UPDATE odb SET move_phase = NULL, reserved_space = base_reserved_space WHERE db_key = p_db_key RETURN sls_used INTO l_sls_used; -- DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT(NULL); COMMIT; -- -- -- -- -- trace1 ('MOVE_DB: sls_used is ' || l_sls_used); END move_db; -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE allocate_backup_piece_name( p_db_id IN NUMBER, p_piecename IN VARCHAR2, p_fincarn IN VARCHAR2) IS l_bool BOOLEAN := FALSE; l_db_sl_key NUMBER; l_sl_min_alloc NUMBER; l_count NUMBER; l_db_id NUMBER; l_old_filename sbt_catalog.filename%TYPE; l_old_filesize NUMBER; l_old_sl_min_alloc NUMBER; l_new_fincarn sbt_catalog.pieceinc%TYPE; l_new_ct_key NUMBER; BEGIN trace1 ('ALLOCATE_BACKUP_PIECE_NAME: dbid ' || p_db_id || ', handle ' || p_piecename); -- -- -- -- -- -- -- IF DBMS_RA_SCHEDULER.S_CURRENT_TASK IS NULL THEN l_bool := SYS.KBRSI_ICD.RSKEYREADLOCK (DBMS_RA_SCHEDULER.LOCK_QUIESCE_PENDING, FALSE); -- -- -- -- IF NOT l_bool THEN RAISE DBMS_RA_SCHEDULER.E_RETRY_ERROR; END IF; END IF; -- -- -- BEGIN SELECT odb.sl_key, odb.sl_min_alloc INTO l_db_sl_key, l_sl_min_alloc FROM db, odb WHERE db.db_id = p_db_id AND db.db_key = odb.db_key; EXCEPTION WHEN OTHERS THEN save_error; SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Allocate_backup_piece_name cannot find sl', TRUE); END; -- UPDATE sbt_catalog SET sl_key = l_db_sl_key , sl_min_alloc = l_sl_min_alloc , filesize = 0 , last_entry = SYSTIMESTAMP , completed = 'N' WHERE handle = p_piecename AND pieceinc = p_fincarn AND filesize IS NULL; IF SQL%ROWCOUNT <> 1 THEN -- -- -- -- BEGIN SELECT db_id, filename, filesize, sl_min_alloc INTO l_db_id, l_old_filename, l_old_filesize, l_old_sl_min_alloc FROM sbt_catalog JOIN db USING (db_key) WHERE handle = p_piecename AND pieceinc = p_fincarn; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; trace1 ('ALLOCATE_BACKUP_PIECE_NAME: No catalog entry found'); RAISE DBMS_RA_SCHEDULER.E_TERMINATED; END; -- -- -- -- -- -- trace1 ('ALLOCATE_BACKUP_PIECE_NAME: piece previously allocated'); -- -- -- SYS.KBRSI_ICD.RSGENFINCARN (l_new_fincarn); -- -- -- UPDATE sbt_catalog SET sl_key = l_db_sl_key , sl_min_alloc = l_sl_min_alloc , filename = NULL , filesize = 0 , last_entry = SYSTIMESTAMP , completed = 'N' WHERE handle = p_piecename AND pieceinc = p_fincarn; -- -- -- -- DBMS_RA_INT.CREATESBTCATALOG ( p_dbid => l_db_id , p_handle => p_piecename , p_pieceinc => l_new_fincarn , p_ftype => DBMS_RA_INT.KBRSCHKTYPE_FILE , p_xmldoc => NULL , p_commit => FALSE , p_ct_key => l_new_ct_key); trace1 ('NAME_BACKUP_PIECE: new ctkey=' || l_new_ct_key || '; new fincarn=' || l_new_fincarn); -- -- -- UPDATE sbt_catalog SET filename = l_old_filename , filesize = l_old_filesize , sl_key = l_db_sl_key , sl_min_alloc = l_sl_min_alloc , last_entry = SYSTIMESTAMP - NUMTODSINTERVAL(365, 'day') , completed = 'N' WHERE ct_key = l_new_ct_key; END IF; COMMIT; -- IF DBMS_RA_SCHEDULER.S_CURRENT_TASK IS NULL THEN SYS.KBRSI_ICD.RSKEYUNLOCK(DBMS_RA_SCHEDULER.LOCK_QUIESCE_PENDING); END IF; EXCEPTION WHEN OTHERS THEN save_error; IF l_bool THEN SYS.KBRSI_ICD.RSKEYUNLOCK(DBMS_RA_SCHEDULER.LOCK_QUIESCE_PENDING); END IF; RAISE; END allocate_backup_piece_name; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE allocate_backup_piece( p_piecename IN VARCHAR2, p_fincarn IN VARCHAR2, p_filesize IN NUMBER, p_ct_key OUT NUMBER) IS PRAGMA AUTONOMOUS_TRANSACTION; l_db_key NUMBER := NULL; l_count NUMBER; l_sl_key NUMBER; l_sl_min_alloc NUMBER; l_filesize NUMBER; l_totfsize NUMBER; l_allocsize NUMBER; l_used NUMBER; l_needsize NUMBER; l_move_phase NUMBER; l_not_taped NUMBER; l_not_taped_state VARCHAR2(1); l_reserved NUMBER; l_ct_rowid UROWID; l_odb_rowid UROWID; E_INVALID_ROWID EXCEPTION; l_cumulative_incr NUMBER; l_retcode BINARY_INTEGER := 0; l_allocate_ok BOOLEAN; PRAGMA EXCEPTION_INIT(E_INVALID_ROWID, -1410); BEGIN trace1 ('ALLOCATE_BACKUP_PIECE for' || ' handle ' || p_piecename || ', pieceinc ' || p_fincarn || ', filesize ' || p_filesize); -- BEGIN SELECT ROWID, ct_key, db_key, filesize, sl_min_alloc INTO l_ct_rowid, p_ct_key, l_db_key, l_filesize, l_sl_min_alloc FROM sbt_catalog WHERE handle = p_piecename AND pieceinc = p_fincarn AND completed = 'N'; EXCEPTION WHEN OTHERS THEN save_error; SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Allocate_backup_piece cannot find ct_key', TRUE); END; BEGIN l_retcode := SYS.KBRSI_ICD.CONTAINER_BDAPI_GTFB(p_filesize, l_sl_min_alloc, l_totfsize); trace1 ('ALLOCATE_BACKUP_PIECE filesize ' || p_filesize || 'total_filesize ' || l_totfsize); EXCEPTION WHEN OTHERS THEN save_error; SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Allocate_backup_piece: gtfb failure', TRUE); END; IF (l_retcode != 0) THEN trace1 ('ALLOCATE_BACKUP_PIECE error retrieving total filesize for ' || ' handle ' || p_piecename || ', pieceinc ' || p_fincarn || ', retcode=' || l_retcode); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'bad bdapi_gtfb ret ' || l_retcode); END IF; -- IF (l_filesize >= l_totfsize) THEN RETURN; END IF; -- -- -- -- -- -- lock_db(l_db_key); -- -- -- -- LOOP -- -- -- BEGIN -- SELECT filesize, sl_key, sl_min_alloc INTO l_filesize, l_sl_key, l_sl_min_alloc FROM sbt_catalog WHERE ROWID = l_ct_rowid AND handle = p_piecename AND pieceinc = p_fincarn AND completed = 'N'; EXCEPTION -- WHEN e_invalid_rowid OR NO_DATA_FOUND THEN save_error; -- -- -- -- BEGIN SELECT ROWID, filesize, sl_key, sl_min_alloc INTO l_ct_rowid, l_filesize, l_sl_key, l_sl_min_alloc FROM sbt_catalog WHERE handle = p_piecename AND pieceinc = p_fincarn AND completed = 'N'; EXCEPTION WHEN e_invalid_rowid OR NO_DATA_FOUND THEN save_error; -- -- trace1('ALLOCATE_BACKUP_PIECE: cannot find ct_key on refetch'); RAISE DBMS_RA_SCHEDULER.E_RETRY_ERROR; WHEN OTHERS THEN save_error; SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Allocate_backup_piece: cannot find ct_key on refetch', TRUE); END; clear_error; WHEN OTHERS THEN save_error; SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Allocate_backup_piece: cannot find ct_key2', TRUE); END; trace1 ('ALLOCATE_BACKUP_PIECE: sl_key = ' || l_sl_key); -- -- -- IF l_filesize >= l_totfsize THEN trace1 ('ALLOCATE_BACKUP_PIECE: Space was already allocated.'); unlock_db (l_db_key); RETURN; END IF; -- -- -- l_needsize := CEIL((l_totfsize - l_filesize)/l_sl_min_alloc) * l_sl_min_alloc; trace1 ('ALLOCATE_BACKUP_PIECE: l_needsize = ' || l_needsize); -- -- -- IF (l_odb_rowid IS NULL) THEN BEGIN SELECT ROWID, allocated_space, used_space INTO l_odb_rowid, l_allocsize, l_used FROM odb WHERE db_key = l_db_key; EXCEPTION WHEN OTHERS THEN save_error; SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Allocate_backup_piece: cannot find odb', TRUE); END; ELSE BEGIN SELECT allocated_space, used_space INTO l_allocsize, l_used FROM odb WHERE ROWID = l_odb_rowid AND db_key = l_db_key; EXCEPTION WHEN e_invalid_rowid OR NO_DATA_FOUND THEN save_error; SELECT ROWID, allocated_space, used_space INTO l_odb_rowid, l_allocsize, l_used FROM odb WHERE db_key = l_db_key; clear_error; WHEN OTHERS THEN save_error; SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Allocate_backup_piece: cannot find odb2', TRUE); END; END IF; trace1 ('ALLOCATE_BACKUP_PIECE: Allocated = ' || l_allocsize || ', Used = ' || l_used); IF (l_used + l_needsize <= l_allocsize) THEN -- -- -- IF NVL(DBMS_RA_SCHEDULER.S_CURRENT_TASK_type,-1) IN ( DBMS_RA_SCHEDULER.TASK_MOVE_ALL_DB, DBMS_RA_SCHEDULER.TASK_REPAIR_DB) THEN l_cumulative_incr := 0; ELSE l_cumulative_incr := l_needsize; END IF; -- -- -- -- UPDATE odb SET used_space = used_space + l_needsize, not_taped = not_taped + l_needsize, cumulative_usage = cumulative_usage + l_cumulative_incr WHERE ROWID = l_odb_rowid RETURNING base_reserved_space, used_space, not_taped, not_taped_state, move_phase INTO l_reserved, l_used, l_not_taped, l_not_taped_state, l_move_phase; UPDATE sbt_catalog SET filesize = filesize + l_needsize, last_entry = SYSTIMESTAMP WHERE ROWID = l_ct_rowid RETURNING filesize INTO l_filesize; IF l_filesize > l_reserved THEN ROLLBACK; RAISE DBMS_RA_SCHEDULER.E_PIECE_TOO_BIG; END IF; check_tape_limit(l_db_key, l_reserved, l_used, l_not_taped, l_not_taped_state, l_move_phase, l_needsize); trace1 ('ALLOCATE_BACKUP_PIECE: allocation granted'); COMMIT; EXIT; END IF; -- -- -- BEGIN l_allocate_ok := allocate_db_space(l_sl_key, l_db_key, l_needsize); EXCEPTION WHEN DBMS_RA_SCHEDULER.E_RETRY_RESERVE OR DBMS_RA_SCHEDULER.E_RETRY_ERROR OR DBMS_RA_SCHEDULER.E_PENDING_INTERRUPT THEN save_error; RAISE; WHEN OTHERS THEN save_error; SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Allocate_backup_piece: allocate_db_space failure', TRUE); END; IF NOT l_allocate_ok THEN ROLLBACK; trace1 ('ALLOCATE_BACKUP_PIECE: No storage space found!'); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_NO_MORE_STORAGE_NUM, DBMS_RA_SCHEDULER.S_ALLOC_INCREMENT); END IF; END LOOP; unlock_db (l_db_key); -- BEGIN used_space_check (l_db_key, l_sl_key); EXCEPTION WHEN OTHERS THEN save_error; SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Allocate_backup_piece: used_space_check failure', TRUE); END; trace1 ('ALLOCATE_BACKUP_PIECE: Completed.'); EXCEPTION WHEN OTHERS THEN save_error; ROLLBACK; IF l_db_key IS NOT NULL THEN -- -- -- -- -- UPDATE sbt_catalog SET last_entry = SYSTIMESTAMP WHERE ROWID = l_ct_rowid; COMMIT; unlock_db (l_db_key); END IF; RAISE; END allocate_backup_piece; -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE name_backup_piece( p_ct_key IN NUMBER, p_filename IN VARCHAR2) IS l_db_key NUMBER; l_filename sbt_catalog.filename%TYPE; l_filesize NUMBER; BEGIN trace1 ('NAME_BACKUP_PIECE for ' || 'ctkey ' || p_ct_key || ' fname ' || p_filename); -- -- -- UPDATE sbt_catalog SET filename = p_filename WHERE ct_key = p_ct_key; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- IF SQL%ROWCOUNT = 0 THEN trace1 ('NAME_BACKUP_PIECE: no unallocated backup found'); -- -- -- SELECT filename, filesize INTO l_filename, l_filesize FROM sbt_catalog WHERE ct_key = p_ct_key; SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Attempt to name a backup up piece that was already named: ' || 'Old name=' || l_filename || '; Old size=' || l_filesize || '; New name=' || p_filename, FALSE); END IF; COMMIT; EXCEPTION WHEN NO_DATA_FOUND THEN -- -- -- save_error; trace1 ('NAME_BACKUP_PIECE: backup not found'); RAISE DBMS_RA_SCHEDULER.E_BACKUP_NOT_FOUND; END name_backup_piece; -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE finish_backup_piece( p_db_key IN NUMBER, p_handle IN VARCHAR2, p_pieceinc IN VARCHAR2, p_ct_key IN NUMBER) IS l_filesize NUMBER; l_backuppiece_id NUMBER; l_backupset_id NUMBER; l_incr_level NUMBER; task_rec task%ROWTYPE; l_files NUMBER; l_piecename VARCHAR2(513); l_cnt NUMBER; BEGIN trace1 ('FINISH_BACKUP_PIECE for' || ' db_key ' || p_db_key || ', handle ' || p_handle || ', pieceinc ' || p_pieceinc); -- -- -- -- BEGIN SELECT filesize INTO l_filesize FROM sbt_catalog WHERE db_key = p_db_key AND handle = p_handle AND pieceinc = p_pieceinc AND ct_key = p_ct_key; EXCEPTION WHEN no_data_found THEN save_error; SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'file piece is not right'); WHEN OTHERS THEN save_error; RAISE; END; trace1 ('FINISH_BACKUP_PIECE: handle= "' || p_handle || '" l_filesize=' || l_filesize); -- -- -- BEGIN sys.kbrsi_icd.rsInspectBackupPiece( handle => p_handle, vbkey => null, bpsize => l_filesize, chktype => DBMS_RA_INT.KBRSCHKTYPE_FILE, fno => null, lib_key => null, /* local disk file */ ct_key => p_ct_key, bpkey => l_backuppiece_id, template_key => null); -- SELECT bs_key INTO l_backupset_id FROM bp WHERE bp.bp_key = l_backuppiece_id AND bp.status != 'D'; -- -- -- dbms_ra_scheduler.replicate_one_bp (p_db_key => p_db_key, p_bp_key => l_backuppiece_id); EXCEPTION WHEN OTHERS THEN save_error; trace1 ('FINISH_BACKUP_PIECE: Backup piece returned:' || SQLERRM); RAISE; END; trace1 ('FINISH_BACKUP_PIECE: rsInspectBackupPiece returned ' || ' dbkey=' || p_db_key || ' bskey=' || l_backupset_id || ' bpkey=' || l_backuppiece_id); -- SELECT COUNT(*) INTO l_cnt FROM bdf WHERE bs_key = l_backupset_id AND (incr_level IS NOT NULL OR incr_scn > 0); IF (l_cnt > 0) THEN task_rec.task_type := DBMS_RA_SCHEDULER.TASK_INDEX_BACKUP; task_rec.flags := DBMS_RA_SCHEDULER.TASKS_RECEIVED_BACKUP; task_rec.db_key := p_db_key; task_rec.param_num1 := l_backupset_id; task_rec.param_num1 := l_backuppiece_id; DBMS_RA_SCHEDULER.NEW_TASK (task_rec); END IF; COMMIT; trace1 ('FINISH_BACKUP_PIECE: Fin.'); END finish_backup_piece; -- -- -- -- -- -- -- -- -- -- PROCEDURE swap_backup_piece(p_bpkey IN NUMBER) IS l_task NUMBER; BEGIN -- -- FOR srcb IN (SELECT bs_key, bp_key, piece#, v.vcbp_key, v.vb_key FROM bp p JOIN sbt_task t USING (bs_key, piece#) JOIN vbdf v ON p.db_key = v.db_key AND p.bp_key = v.srcbp_key WHERE bp_key = p_bpkey AND v.relfno = 1) LOOP -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); -- -- SELECT MAX(task_id) INTO l_task FROM task JOIN sbt_task USING (task_id) WHERE bs_key = srcb.bs_key AND piece# = srcb.piece# AND (state = DBMS_RA_SCHEDULER.STATE_RUNNING OR failure_cnt > 0); -- IF l_task IS NULL THEN UPDATE sbt_task SET bs_key = (SELECT bs_key FROM bp WHERE bp_key = srcb.vcbp_key AND status != 'D'), src_bpkey = nvl2(src_bpkey, srcb.vcbp_key, NULL) WHERE bs_key = srcb.bs_key AND piece# = srcb.piece#; IF SQL%ROWCOUNT > 0 THEN trace1 ('SWAP_BACKUP_PIECE swap srcbpkey ' || srcb.bp_key || ' with bpkey ' || srcb.vcbp_key); END IF; -- UPDATE vbdf SET srcbp_key = NULL WHERE vb_key = srcb.vb_key AND srcbp_key = p_bpkey; COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK; ELSE -- trace1('SWAP_BACKUP_PIECE: throwing retry for bpkey ' || srcb.bp_key); DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT := l_task; RAISE DBMS_RA_SCHEDULER.E_RETRY_ERROR; END IF; END LOOP; END swap_backup_piece; -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE free_backup_piece(p_dbkey IN NUMBER, p_piecename IN VARCHAR2, p_ftype IN NUMBER DEFAULT NULL, p_fincarn IN VARCHAR2 DEFAULT NULL, p_can_defer IN BOOLEAN DEFAULT FALSE) IS l_dbid NUMBER; l_db_slkey NUMBER; -- current sl for database l_fincarn sbt_catalog.pieceinc%type; l_bpkey NUMBER; l_ftype NUMBER; l_currinc NUMBER; new_task_rec task%ROWTYPE; BEGIN trace1 ('FREE_BACKUP_PIECE for ' || ' db_key ' || p_dbkey || ' ,piecename ' || p_piecename); -- IF (p_can_defer AND DBMS_RA_SCHEDULER.S_DEFER_DELETE > 0) THEN SELECT MAX(bp_key) INTO l_bpkey FROM bp WHERE handle = p_piecename; IF (l_bpkey IS NOT NULL) THEN trace1 ('FREE_BACKUP_PIECE: Test Defer Delete bp_key = ' || l_bpkey); dbms_rcvcat.rsDeleteBackupPiece(l_bpkey, 'N'); END IF; RAISE DBMS_RA_SCHEDULER.E_RETRY_ERROR; END IF; -- SELECT db.db_id, odb.sl_key, db.curr_dbinc_key INTO l_dbid, l_db_slkey, l_currinc FROM db, odb WHERE db.db_key = p_dbkey AND db.db_key = odb.db_key; -- IF (p_fincarn IS NULL) THEN SELECT MIN(pieceinc), MIN(bp_key), DECODE(MIN(ftype), 'F', DBMS_RA_INT.KBRSCHKTYPE_FILE, 'V', DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL, 'T', DBMS_RA_INT.KBRSCHKTYPE_TAPE, NULL) INTO l_fincarn, l_bpkey, l_ftype FROM sbt_catalog ct WHERE ct.handle = p_piecename AND ct.bp_key IS NOT NULL; ELSE l_fincarn := p_fincarn; SELECT min(bp_key), DECODE(MIN(ftype), 'F', DBMS_RA_INT.KBRSCHKTYPE_FILE, 'V', DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL, 'T', DBMS_RA_INT.KBRSCHKTYPE_TAPE, NULL) INTO l_bpkey, l_ftype FROM sbt_catalog ct WHERE ct.pieceinc = l_fincarn AND ct.handle = p_piecename; END IF; -- IF (p_ftype IS NOT NULL) THEN IF (p_ftype != nvl(l_ftype, p_ftype)) THEN sys.dbms_sys_error.raise_system_error (DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'mismatched ftype'); END IF; l_ftype := p_ftype; END IF; free_backup_piece_opt( p_dbkey => p_dbkey, p_piecename => p_piecename, p_db_slkey => l_db_slkey, p_dbid => l_dbid, p_currinc => l_currinc, p_bpkey => l_bpkey, p_ftype => l_ftype, p_fincarn => l_fincarn); EXCEPTION WHEN NO_DATA_FOUND THEN save_error; ROLLBACK; -- SELECT MAX(bp_key) INTO l_bpkey FROM sbt_catalog WHERE handle = p_piecename AND (pieceinc = p_fincarn OR p_fincarn IS NULL) AND (bp_key IS NOT NULL OR p_fincarn IS NOT NULL); IF l_bpkey IS NULL THEN tracex ('FREE_BACKUP_PIECE: already deleted'); clear_error; ELSE RAISE; END IF; WHEN DBMS_RA_SCHEDULER.E_RETRY_ERROR THEN save_error; ROLLBACK; trace1 ('FREE_BACKUP_PIECE: retry error'); IF (NOT p_can_defer) THEN RAISE; END IF; IF (l_bpkey IS NOT NULL) THEN trace1 ('FREE_BACKUP_PIECE: Defer Delete bp_key = ' || l_bpkey); dbms_rcvcat.rsDeleteBackupPiece(l_bpkey, 'N'); END IF; -- new_task_rec.task_type := DBMS_RA_SCHEDULER.TASK_DEFERRED_DELETE; new_task_rec.flags := 0; new_task_rec.db_key := p_dbkey; new_task_rec.param_char1 := p_piecename; new_task_rec.param_num1 := p_ftype; new_task_rec.param_char2 := p_fincarn; trace1 ('FREE_BACKUP_PIECE: Defer task queued ' || p_piecename); DBMS_RA_SCHEDULER.NEW_TASK (task_rec => new_task_rec, p_commit => FALSE); -- COMMIT; clear_error; WHEN OTHERS THEN save_error; ROLLBACK; RAISE; END free_backup_piece; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE free_backup_piece_opt( p_dbkey IN NUMBER, p_piecename IN VARCHAR2, p_db_slkey IN NUMBER, p_dbid IN NUMBER, p_currinc IN NUMBER, p_bpkey IN NUMBER, p_ftype IN NUMBER DEFAULT NULL, p_fincarn IN VARCHAR2 DEFAULT NULL, p_libkey IN NUMBER DEFAULT NULL, p_spawn_job IN BOOLEAN DEFAULT TRUE, p_notasks IN BOOLEAN DEFAULT FALSE, p_noplans IN BOOLEAN DEFAULT FALSE) IS l_slkey NUMBER; l_filesize NUMBER; new_task_rec task%ROWTYPE; l_fincarn sbt_catalog.pieceinc%type := p_fincarn; l_ftype NUMBER := p_ftype; l_libkey NUMBER := p_libkey; l_bpkey NUMBER := p_bpkey; l_ctkey NUMBER; l_rsaccess VARCHAR2(1); l_filename VARCHAR2(512); l_db_locked BOOLEAN := FALSE; BEGIN tracex('FREE_BACKUP_PIECE_OPT for' || ' db_key=' || p_dbkey || ', piecename=' || p_piecename || ', dbslkey=' || print(p_db_slkey) || ', dbid=' || print(p_dbid) || ', currinc=' || print(p_currinc) || ', bpkey=' || print(p_bpkey) || ', ftype=' || print(p_ftype) || ', fincarn=' || print(p_fincarn)); -- IF (l_bpkey IS NOT NULL AND (p_fincarn IS NULL OR p_ftype IS NULL)) THEN BEGIN SELECT pieceinc, DECODE(ftype, 'F', DBMS_RA_INT.KBRSCHKTYPE_FILE, 'V', DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL, 'T', DBMS_RA_INT.KBRSCHKTYPE_TAPE, 'D', DBMS_RA_INT.KBRSCHKTYPE_DISK, NULL) INTO l_fincarn, l_ftype FROM sbt_catalog ct WHERE ct.bp_key = l_bpkey; EXCEPTION WHEN no_data_found THEN save_error; clear_error; RETURN; -- No backup piece, nothing to do END; END IF; IF l_ftype IS NULL THEN trace1('FREE_BACKUP_PIECE_OPT ' || p_piecename || ' already deleted'); IF p_bpkey IS NOT NULL THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'already deleted'); END IF; RETURN; END IF; -- IF (l_bpkey IS NOT NULL) THEN dbms_ra_int.write_lock(DBMS_RA_INT.KEY_BP, l_bpkey); ELSIF (l_ftype = DBMS_RA_INT.KBRSCHKTYPE_FILE) THEN SELECT ct_key INTO l_ctkey FROM sbt_catalog WHERE handle = p_piecename AND pieceinc = l_fincarn; dbms_ra_int.write_lock(DBMS_RA_INT.KEY_CT, l_ctkey); END IF; -- IF (l_ftype = DBMS_RA_INT.KBRSCHKTYPE_TAPE) THEN IF (l_libkey IS NULL) THEN SELECT bp.lib_key INTO l_libkey FROM bp WHERE bp.handle = p_piecename AND bp.db_key = p_dbkey; END IF; END IF; CASE l_ftype WHEN DBMS_RA_INT.KBRSCHKTYPE_FILE THEN trace1 ('FREE_BACKUP_PIECE_OPT: file piece'); -- -- -- l_db_locked := TRUE; lock_db (p_dbkey); -- -- -- SELECT MIN(sl_key), MIN(filesize), MIN(filename) INTO l_slkey, l_filesize, l_filename FROM sbt_catalog WHERE pieceinc = l_fincarn AND handle = p_piecename; trace1 ('FREE_BACKUP_PIECE_OPT: filesize=' || print(l_filesize) || ', fname ' || l_filename); -- -- -- IF l_filesize IS NOT NULL THEN -- -- -- -- -- -- -- l_rsaccess := 'L'; IF p_bpkey IS NOT NULL AND p_fincarn IS NULL THEN SELECT ba_access INTO l_rsaccess FROM bp WHERE bp_key = p_bpkey; END IF; IF l_rsaccess = 'L' AND l_filename IS NOT NULL THEN SYS.KBRSI_ICD.rsDeleteFile(l_filename); END IF; -- -- -- UPDATE sbt_catalog SET sl_key = NULL, filesize = NULL, last_entry = NULL WHERE handle = p_piecename AND pieceinc = l_fincarn; -- -- -- return_space(l_filesize, p_dbkey, l_slkey, p_db_slkey); END IF; -- -- -- COMMIT; unlock_db(p_dbkey); l_db_locked := FALSE; -- IF l_filesize IS NOT NULL THEN used_space_check (p_dbkey, l_slkey); END IF; IF (l_bpkey IS NULL) THEN -- trace1 ('FREE_BACKUP_PIECE_OPT: Deleting sbt_catalog entry'); DELETE FROM sbt_catalog WHERE handle = p_piecename AND pieceinc = l_fincarn; END IF; WHEN DBMS_RA_INT.KBRSCHKTYPE_TAPE THEN trace1 ('FREE_BACKUP_PIECE_OPT: tape chunk'); WHEN DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL THEN trace1 ('FREE_BACKUP_PIECE_OPT: virtual chunk'); -- -- IF p_noplans AND p_notasks THEN trace1('FREE_BACKUP_PIECE_OPT: Skipping deleteVB'); ELSE dbms_ra_pool.deleteVB(p_slkey => p_db_slkey, p_dbkey => p_dbkey, p_currinc => p_currinc, p_bpkey => l_bpkey, p_noplans => p_noplans, p_notasks => p_notasks); END IF; WHEN DBMS_RA_INT.KBRSCHKTYPE_DISK THEN trace1 ('FREE_BACKUP_PIECE_OPT: disk chunk'); ELSE sys.dbms_sys_error.raise_system_error( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'unknown ftype'); END CASE; IF (l_bpkey IS NOT NULL) THEN -- trace1 ('FREE_BACKUP_PIECE_OPT: Deleting bp_key = ' || l_bpkey); dbms_rcvcat.rsDeleteBackupPiece(l_bpkey, 'Y'); END IF; IF (l_ftype = DBMS_RA_INT.KBRSCHKTYPE_TAPE) AND (NOT p_notasks) THEN -- new_task_rec.task_type := DBMS_RA_SCHEDULER.TASK_PURGE_SBT; new_task_rec.flags := 0; new_task_rec.db_key := p_dbkey; new_task_rec.param_num1 := l_libkey; new_task_rec.param_char1 := p_piecename; DBMS_RA_SCHEDULER.NEW_TASK (task_rec => new_task_rec, p_commit => FALSE); END IF; -- COMMIT; -- IF (l_bpkey IS NOT NULL) THEN dbms_ra_int.unlock(DBMS_RA_INT.KEY_BP, l_bpkey); l_bpkey := NULL; END IF; IF (l_ctkey IS NOT NULL) THEN dbms_ra_int.unlock(DBMS_RA_INT.KEY_CT, l_ctkey); l_ctkey := NULL; END IF; IF (l_ftype = DBMS_RA_INT.KBRSCHKTYPE_TAPE) THEN -- IF (p_spawn_job) THEN dbms_ra_scheduler.queue_spawn_sbt( p_libkey => l_libkey, p_forpurge => TRUE); END IF; END IF; DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT; trace1 ('FREE_BACKUP_PIECE_OPT: Done.'); EXCEPTION WHEN NO_DATA_FOUND THEN save_error; trace1 ('FREE_BACKUP_PIECE_OPT: no row found'); ROLLBACK; IF l_db_locked THEN unlock_db(p_dbkey); END IF; IF (l_bpkey IS NOT NULL) THEN dbms_ra_int.unlock(DBMS_RA_INT.KEY_BP, l_bpkey); END IF; IF (l_ctkey IS NOT NULL) THEN dbms_ra_int.unlock(DBMS_RA_INT.KEY_CT, l_ctkey); END IF; clear_error; WHEN OTHERS THEN save_error; ROLLBACK; IF l_db_locked THEN unlock_db(p_dbkey); END IF; IF (l_bpkey IS NOT NULL) THEN dbms_ra_int.unlock(DBMS_RA_INT.KEY_BP, l_bpkey); END IF; IF (l_ctkey IS NOT NULL) THEN dbms_ra_int.unlock(DBMS_RA_INT.KEY_CT, l_ctkey); END IF; RAISE; END free_backup_piece_opt; -- -- -- -- -- -- -- -- -- -- -- PROCEDURE finish_file(p_newfname IN VARCHAR2, p_filesize IN NUMBER, p_handle OUT VARCHAR2, p_move_bp OUT NUMBER) IS l_allocsize NUMBER; l_sl_min_alloc NUMBER; l_needsize NUMBER; l_sl_key NUMBER; l_db_key NUMBER; l_old_ct_key NUMBER; l_new_ct_key NUMBER; l_repcnt NUMBER; BEGIN trace1 ('FINISH_FILE for' || ' newfname ' || p_newfname || ', filesize ' || p_filesize); -- -- -- SELECT db_key INTO l_db_key FROM sbt_catalog WHERE filename = p_newfname AND filesize IS NOT NULL; lock_db(l_db_key); -- -- -- SELECT filesize, sl_key, handle, ct_key INTO l_allocsize, l_sl_key, p_handle, l_new_ct_key FROM sbt_catalog WHERE filename = p_newfname AND filesize IS NOT NULL; -- -- -- BEGIN SELECT sl_min_alloc INTO l_sl_min_alloc FROM sl WHERE sl_key = l_sl_key; -- -- -- l_needsize := CEIL(p_filesize / l_sl_min_alloc) * l_sl_min_alloc; trace1 ('FINISH_FILE: Old allocation was: ' || l_allocsize || '; New allocation is: ' || l_needsize); IF l_allocsize < 0 THEN -- Something went horribly wrong. SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Bad filesize, difference is ' || l_allocsize); END IF; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; trace1 ('FINISH_FILE: Copied file not found'); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Cannot find ' || p_newfname); END; IF l_allocsize < l_needsize THEN trace1 ('FINISH_FILE: Copied filesize cannot grow'); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Filesize cannot grow ' || l_allocsize); END IF; -- -- -- -- IF DBMS_RA_SCHEDULER.S_CURRENT_TASK_TYPE IN (DBMS_RA_SCHEDULER.TASK_MOVE_ALL_DB,DBMS_RA_SCHEDULER.TASK_MOVE_DF) THEN SELECT bp.bp_key, ct.ct_key INTO p_move_bp, l_old_ct_key FROM sbt_catalog ct, bp WHERE ct.bp_key = bp.bp_key AND ct.handle = p_handle AND bp.status != 'D'; trace1 ('FINISH_FILE: p_move_bp=' || print(p_move_bp)); -- UPDATE sbt_catalog ct SET ct.completed = nvl2(ct.completed, 'N', null) ,ct.endupload = nvl2(ct.endupload, 'D', null) ,ct.bp_key = null WHERE ct.ct_key = l_old_ct_key; -- -- -- dbms_ra_int.finalizeSbtCatalog(p_bp_key => p_move_bp ,p_ct_key => l_new_ct_key ,p_xmldoc => NULL); END IF; -- -- -- UPDATE sbt_catalog SET filesize = l_needsize WHERE db_key = l_db_key AND ct_key = l_new_ct_key; -- -- -- return_space ((l_allocsize - l_needsize), l_db_key, l_sl_key, NULL); COMMIT; unlock_db (l_db_key); -- used_space_check (l_db_key, l_sl_key); trace1 ('FINISH_FILE: Completed.'); EXCEPTION WHEN OTHERS THEN save_error; ROLLBACK; unlock_db (l_db_key); RAISE; END finish_file; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE preallocate_chunks( p_db_key IN NUMBER, p_count IN NUMBER, p_required IN BOOLEAN DEFAULT FALSE) IS l_used NUMBER; l_sl_key NUMBER; l_allocsize NUMBER; l_count NUMBER := p_count; l_chunksize NUMBER; l_reserved NUMBER; l_not_taped NUMBER; l_not_taped_state VARCHAR2(1); l_move_phase NUMBER; l_cachescn NUMBER; BEGIN trace1 ('PREALLOCATE_CHUNKS for ' || 'db_key ' || p_db_key || ', count ' || p_count); -- -- -- IF DBMS_RA_SCHEDULER.S_CURRENT_TASK IS NULL THEN sys.dbms_sys_error.raise_system_error( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'cannot preallocate without a task'); END IF; -- -- -- lock_db(p_db_key); -- -- -- LOOP -- -- -- SELECT allocated_space, used_space, odb.sl_key, odb.sl_min_alloc INTO l_allocsize, l_used, l_sl_key, l_chunksize FROM odb, sl WHERE db_key = p_db_key AND odb.sl_key = sl.sl_key; trace1('PREALLOCATE_CHUNKS: Allocated_space=' || l_allocsize || ', Used_space=' || l_used); IF l_used + (l_count * l_chunksize) <= l_allocsize THEN -- -- -- UPDATE odb SET used_space = used_space + (l_count * l_chunksize), not_taped = not_taped + (l_count * l_chunksize) WHERE db_key = p_db_key RETURNING base_reserved_space, used_space, not_taped, not_taped_state, move_phase INTO l_reserved, l_used, l_not_taped, l_not_taped_state, l_move_phase; DBMS_RA_SCHEDULER.S_CACHED_STORAGE := TRUE; UPDATE task_chunk_cache SET chunk_cache = chunk_cache + l_count WHERE inst_id = DBMS_RA_SCHEDULER.S_INSTANCE AND task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK; IF SQL%ROWCOUNT = 0 THEN -- INSERT INTO task_chunk_cache (inst_id, task_id, chunk_cache, cumulative_incr) VALUES (DBMS_RA_SCHEDULER.S_INSTANCE, DBMS_RA_SCHEDULER.S_CURRENT_TASK, l_count, 0); UPDATE task SET flags = flags - BITAND (flags, DBMS_RA_SCHEDULER.TASKS_CHUNK_CACHE_ACTIVE) + DBMS_RA_SCHEDULER.TASKS_CHUNK_CACHE_ACTIVE WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK; END IF; -- -- -- -- IF DBMS_RA_SCHEDULER.S_CURRENT_TASK_TYPE = DBMS_RA_SCHEDULER.TASK_INDEX_BACKUP THEN check_tape_limit(p_db_key, l_reserved, l_used, l_not_taped, l_not_taped_state, l_move_phase, (l_count * l_chunksize)); END IF; COMMIT; EXIT; END IF; -- -- -- trace1 ('PREALLOCATE_CHUNKS: Need more disk space'); IF NOT allocate_db_space(l_sl_key, p_db_key, l_count*l_chunksize) THEN ROLLBACK; SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_NO_MORE_STORAGE_NUM, DBMS_RA_SCHEDULER.S_ALLOC_INCREMENT); END IF; END LOOP; unlock_db (p_db_key); -- used_space_check (p_db_key, l_sl_key); trace1 ('PREALLOCATE_CHUNKS: Completed.'); EXCEPTION WHEN DBMS_RA_SCHEDULER.E_RETRY_RESERVE THEN save_error; ROLLBACK; trace1 ('PREALLOCATE_CHUNKS: Forcing a retry'); unlock_db (p_db_key); RAISE; WHEN OTHERS THEN save_error; trace1 ('PREALLOCATE_CHUNKS: Unexpected exception: ' || SQLERRM); ROLLBACK; unlock_db (p_db_key); RAISE; END preallocate_chunks; -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION get_chunkno( p_df_key IN NUMBER, p_count IN NUMBER DEFAULT 1) RETURN NUMBER IS PRAGMA AUTONOMOUS_TRANSACTION; l_usable_cache BOOLEAN; l_df_char VARCHAR2(16) := TO_CHAR(p_df_key,'FMXXXXXXXXXXXXXXXX'); l_allocation NUMBER := GREATEST(p_count, DBMS_RA_SCHEDULER.S_CHUNKNO_ALLOC); BEGIN -- -- -- IF (s_chunkno_cache_execution <> DBMS_RA_SCHEDULER.S_NOW_SERVING) THEN s_chunkno_cache_first.DELETE; s_chunkno_cache_next.DELETE; s_chunkno_cache_execution := DBMS_RA_SCHEDULER.S_NOW_SERVING; END IF; -- -- -- -- l_usable_cache := s_chunkno_cache_first.EXISTS(l_df_char); IF l_usable_cache THEN l_usable_cache := (s_chunkno_cache_next(l_df_char) >= (s_chunkno_cache_first(l_df_char) + p_count)); END IF; IF NOT l_usable_cache THEN -- -- -- -- FOR i IN 1..100 LOOP BEGIN UPDATE df_seq SET chunkno = chunkno + l_allocation WHERE df_key = p_df_key RETURNING chunkno INTO s_chunkno_cache_next(l_df_char); -- -- -- IF SQL%ROWCOUNT = 0 THEN s_chunkno_cache_next(l_df_char) := l_allocation + 1; INSERT INTO df_seq(df_key, chunkno) VALUES (p_df_key, s_chunkno_cache_next(l_df_char)); END IF; COMMIT; EXIT; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN save_error; trace1('GET_CHUNKNO: Retrying after constraint violation seen'); DBMS_LOCK.SLEEP(1); clear_error; CONTINUE; END; END LOOP; s_chunkno_cache_first(l_df_char) := s_chunkno_cache_next(l_df_char) - l_allocation; trace1('GET_CHUNKNO: Allocated ids from ' || s_chunkno_cache_first(l_df_char) || 'through ' || print(s_chunkno_cache_next(l_df_char)-1)); END IF; -- -- -- s_chunkno_cache_first(l_df_char) := s_chunkno_cache_first(l_df_char) + p_count; -- -- -- RETURN s_chunkno_cache_first(l_df_char) - p_count; END get_chunkno; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE allocate_block_pool_chunk( p_db_key IN NUMBER, p_dbinc_key IN NUMBER, p_df_key IN NUMBER, p_vb_key IN NUMBER, p_chunkno OUT NUMBER) IS PRAGMA AUTONOMOUS_TRANSACTION; l_allocsize NUMBER; l_cumulative_incr NUMBER; l_used NUMBER; l_task_purge_reserve NUMBER; l_task_chunk_cache NUMBER; l_allocdone BOOLEAN := FALSE; l_chunksize NUMBER; BEGIN trace1 ('ALLOCATE_BLOCK_POOL_CHUNK for ' || 'db_key ' || p_db_key || ', df_key ' || p_df_key); -- -- -- IF (s_sl_info_cache_execution <> DBMS_RA_SCHEDULER.S_NOW_SERVING) THEN -- -- -- BEGIN SELECT odb.sl_key, sl.sl_min_alloc INTO s_sl_info_key, s_sl_info_chunksize FROM odb, sl WHERE odb.db_key = p_db_key AND odb.sl_key = sl.sl_key; s_sl_info_cache_execution := DBMS_RA_SCHEDULER.S_NOW_SERVING; trace1 ('ALLOCATE_BLOCK_POOL_CHUNK: sl_key is: ' || s_sl_info_key); EXCEPTION WHEN NO_DATA_FOUND THEN save_error; trace1 ('ALLOCATE_BLOCK_POOL_CHUNK: No storage location found'); RAISE DBMS_RA_SCHEDULER.E_BAD_STORAGE_LOCATION; END; END IF; -- -- -- SELECT purge_reserve, NVL(chunk_cache,0) INTO l_task_purge_reserve, l_task_chunk_cache FROM task LEFT OUTER JOIN task_chunk_cache USING (task_id) WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK; -- -- -- -- IF DBMS_RA_SCHEDULER.S_PURGING_ACTIVE AND l_task_purge_reserve > 0 THEN -- -- -- -- DBMS_RA_SCHEDULER.S_CACHED_STORAGE := TRUE; UPDATE task SET purge_reserve = purge_reserve - 1 WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK; trace1 ('ALLOCATE_BLOCK_POOL_CHUNK: Allocated from reserve. Remaining=' || TO_CHAR(l_task_purge_reserve-1)); ELSE -- -- -- -- -- IF l_task_chunk_cache < 1 THEN preallocate_chunks (p_db_key, DBMS_RA_SCHEDULER.S_CHUNK_CACHE); END IF; -- -- -- -- IF DBMS_RA_SCHEDULER.S_POLLED_INPUT THEN l_cumulative_incr := s_sl_info_chunksize; ELSE l_cumulative_incr := 0; END IF; DBMS_RA_SCHEDULER.S_CACHED_STORAGE := TRUE; UPDATE task_chunk_cache SET chunk_cache = chunk_cache - 1, cumulative_incr = cumulative_incr + l_cumulative_incr WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK; END IF; -- -- -- p_chunkno := get_chunkno (p_df_key); INSERT INTO chunks ( sl_key, dbinc_key, df_key, chunkno, filesize, clean_key) VALUES (s_sl_info_key, p_dbinc_key, p_df_key, p_chunkno, 0, p_vb_key) RETURNING chunkno INTO p_chunkno; COMMIT; trace1 ('ALLOCATE_BLOCK_POOL_CHUNK chunkno ' || p_chunkno); -- used_space_check (p_db_key, s_sl_info_key); trace1 ('ALLOCATE_BLOCK_POOL_CHUNK: Completed.'); EXCEPTION WHEN OTHERS THEN save_error; trace1 ('ALLOCATE_BLOCK_POOL_CHUNK: Exception seen: ' || SQLERRM); RAISE; END allocate_block_pool_chunk; -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE free_block_pool_chunk( p_db_key IN NUMBER, p_dbinc_key IN NUMBER, p_df_key IN NUMBER, p_chunkno IN NUMBER) IS PRAGMA AUTONOMOUS_TRANSACTION; l_sl_key NUMBER; l_move_phase NUMBER; l_chunksize NUMBER; l_task_chunk_cache NUMBER; BEGIN trace1 ('FREE_BLOCK_POOL_CHUNK for ' || ', db_key ' || p_db_key || ', dbinc_key ' || p_dbinc_key || ', df_key ' || p_df_key || ', chunkno ' || p_chunkno); -- -- -- DELETE FROM chunks WHERE dbinc_key = p_dbinc_key AND df_key = p_df_key AND chunkno = p_chunkno RETURNING sl_key INTO l_sl_key; IF SQL%ROWCOUNT = 0 THEN trace1 ('FREE_BLOCK_POOL_CHUNK: Chunk not found'); RETURN; END IF; trace1 ('FREE_BLOCK_POOL_CHUNK dbinc_key ' || p_dbinc_key || ' chunkno ' || p_chunkno || ' was deleted'); -- -- -- -- -- -- SELECT move_phase, sl_min_alloc INTO l_move_phase, l_chunksize FROM odb WHERE db_key = p_db_key; IF (l_move_phase IS NOT NULL) OR (DBMS_RA_SCHEDULER.S_CURRENT_TASK IS NULL) THEN trace1 ('FREE_BLOCK_POOL_CHUNK: DB is in motion or no active task'); -- -- BEGIN lock_db(p_db_key); return_space(l_chunksize, p_db_key, l_sl_key, NULL); COMMIT; unlock_db(p_db_key); -- used_space_check (p_db_key, l_sl_key); EXCEPTION WHEN OTHERS THEN save_error; trace1 ('FREE_BLOCK_POOL_CHUNK: Exception seen: ' || SQLERRM); unlock_db(p_db_key); RAISE; END; ELSE -- -- -- DBMS_RA_SCHEDULER.S_CACHED_STORAGE := TRUE; UPDATE task_chunk_cache SET chunk_cache = chunk_cache + 1 WHERE inst_id = DBMS_RA_SCHEDULER.S_INSTANCE AND task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK RETURNING chunk_cache INTO l_task_chunk_cache; IF SQL%ROWCOUNT = 0 THEN -- INSERT INTO task_chunk_cache (inst_id, task_id, chunk_cache, cumulative_incr) VALUES (DBMS_RA_SCHEDULER.S_INSTANCE, DBMS_RA_SCHEDULER.S_CURRENT_TASK, 1, 0); l_task_chunk_cache := 1; UPDATE task SET flags = flags - BITAND (flags, DBMS_RA_SCHEDULER.TASKS_CHUNK_CACHE_ACTIVE) + DBMS_RA_SCHEDULER.TASKS_CHUNK_CACHE_ACTIVE WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK; END IF; -- -- -- -- COMMIT; -- -- -- IF l_task_chunk_cache >= DBMS_RA_SCHEDULER.S_CHUNK_CACHE THEN -- -- -- -- BEGIN lock_db(p_db_key); return_space(l_chunksize * l_task_chunk_cache, p_db_key, l_sl_key, NULL); UPDATE task_chunk_cache SET chunk_cache = 0 WHERE inst_id = DBMS_RA_SCHEDULER.S_INSTANCE AND task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK; COMMIT; unlock_db(p_db_key); -- used_space_check (p_db_key, l_sl_key); EXCEPTION WHEN OTHERS THEN save_error; trace1 ('FREE_BLOCK_POOL_CHUNK: Exception seen: ' || SQLERRM); unlock_db(p_db_key); RAISE; END; END IF; END IF; trace1 ('FREE_BLOCK_POOL_CHUNK: Fin.'); END free_block_pool_chunk; -- -- -- -- -- -- -- -- -- -- -- PROCEDURE free_block_pool_chunks( p_sl_key IN NUMBER, p_db_key IN NUMBER, p_df_key IN NUMBER, p_chunks IN dbms_sql.number_table) IS l_freed NUMBER; BEGIN trace1('FREE_BLOCK_POOL_CHUNKS: Chunkcount=' || p_chunks.COUNT || ', sl_key=' || p_sl_key || ', db_key=' || p_db_key || ', df_key=' || p_df_key); -- IF p_chunks.COUNT = 0 THEN RETURN; END IF; lock_db(p_db_key); -- FORALL i IN 1 .. p_chunks.COUNT DELETE FROM chunks WHERE df_key = p_df_key AND chunkno = p_chunks(i); l_freed := SQL%ROWCOUNT; IF l_freed <> p_chunks.COUNT THEN trace1('FREE_BLOCK_POOL_CHUNKS: Alert - cnt ' || p_chunks.COUNT || ', freed ' || SQL%ROWCOUNT); sys.dbms_sys_error.raise_system_error( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Bad free chunks: ' || l_freed || ' vs ' || p_chunks.COUNT); ELSE trace1('FREE_BLOCK_POOL_CHUNKS: freed ' || p_chunks.COUNT); END IF; return_space((f_chunksize(p_db_key) * l_freed), p_db_key, p_sl_key, NULL); COMMIT; unlock_db(p_db_key); -- dbms_ra_storage.used_space_check (p_db_key, p_sl_key); EXCEPTION WHEN OTHERS THEN save_error; trace1 ('FREE_BLOCK_POOL_CHUNKS: Exception seen: ' || SQLERRM); unlock_db(p_db_key); RAISE; END free_block_pool_chunks; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE free_task_storage (p_task_id NUMBER DEFAULT NULL) IS l_task_id NUMBER := NVL(p_task_id, DBMS_RA_SCHEDULER.S_CURRENT_TASK); l_db_key NUMBER; l_chunk_cache NUMBER; l_cumulative_incr NUMBER; BEGIN trace1 ('FREE_TASK_STORAGE id ' || l_task_id); -- -- -- -- -- BEGIN SELECT db_key, chunk_cache, cumulative_incr INTO l_db_key, l_chunk_cache, l_cumulative_incr FROM task JOIN task_chunk_cache USING (task_id) WHERE task_id = l_task_id; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; trace1 ('FREE_TASK_STORAGE: No chunk cache row.'); clear_error; RETURN; END; -- -- -- -- lock_db (l_db_key); -- -- -- DELETE FROM task_chunk_cache WHERE task_id = l_task_id; UPDATE task SET flags = flags - BITAND (flags, DBMS_RA_SCHEDULER.TASKS_CHUNK_CACHE_ACTIVE) WHERE task_id = l_task_id; -- -- -- -- IF (l_db_key IS NOT NULL) THEN UPDATE odb SET used_space = used_space - (l_chunk_cache * sl_min_alloc), cumulative_usage = cumulative_usage + l_cumulative_incr WHERE db_key = l_db_key; END IF; -- -- -- COMMIT; unlock_db (l_db_key); IF p_task_id IS NULL THEN DBMS_RA_SCHEDULER.S_CACHED_STORAGE := FALSE; END IF; trace1 ('FREE_TASK_STORAGE: transferred chunks=' || l_chunk_cache || '; cumulative_incr=' || l_cumulative_incr); EXCEPTION WHEN OTHERS THEN save_error; trace1 ('FREE_TASK_STORAGE: Error is ' || SQLERRM); unlock_db (l_db_key); RAISE; END free_task_storage; -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE return_space (p_size IN NUMBER, p_db_key IN NUMBER, p_sl_key IN NUMBER, p_db_sl_key IN NUMBER) IS l_db_sl_key NUMBER; l_updated_used_space NUMBER; l_total_usage NUMBER; l_blockpool_usage NUMBER; l_sbtpiece_usage NUMBER; l_move_phase NUMBER; BEGIN trace1 ('RETURN_SPACE: size=' || p_size || ', db_key=' || p_db_key || ', sl_key=' || p_sl_key || ', db_sl_key=' || print(p_db_sl_key)); -- -- -- IF p_db_sl_key IS NOT NULL THEN l_db_sl_key := p_db_sl_key; ELSE SELECT sl_key INTO l_db_sl_key FROM odb WHERE db_key = p_db_key; END IF; trace1 ('RETURN_SPACE: using db_sl_key=' || l_db_sl_key); IF l_db_sl_key = p_sl_key THEN -- -- -- UPDATE odb SET used_space = used_space - NVL(p_size, 0) WHERE db_key = p_db_key; ELSE -- -- -- -- UPDATE odb SET total_allocation = total_allocation - NVL(p_size, 0) WHERE db_key = p_db_key; UPDATE dbsl SET dbsl_used_space = dbsl_used_space - NVL(p_size, 0) WHERE db_key = p_db_key AND sl_key = p_sl_key RETURNING dbsl_used_space INTO l_updated_used_space; IF l_updated_used_space = 0 THEN trace1 ('RETURN_SPACE: dbsl row is now empty'); DELETE dbsl WHERE db_key = p_db_key AND sl_key = p_sl_key; UPDATE odb SET sls_used = sls_used - 1 WHERE db_key = p_db_key; END IF; END IF; END return_space; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION reserve_block_pool_space( p_db_key IN NUMBER, p_chunks IN NUMBER, p_maxchunks OUT NUMBER) RETURN NUMBER IS l_sl_key NUMBER; l_move_phase NUMBER; l_allocated NUMBER; l_used NUMBER; l_freechunks NUMBER; l_availablechunks NUMBER; l_purge_reserve NUMBER; l_reservation NUMBER; l_total_allocation NUMBER; l_chunksize NUMBER; BEGIN trace1 ('RESERVE_BLOCK_POOL_SPACE for ' || ' db_key ' || p_db_key || ', chunks ' || p_chunks); -- l_chunksize := f_chunksize(p_db_key); -- -- -- IF p_chunks IS NULL THEN sys.kbrsi_icd.rsTrace('RESERVE_BLOCK_POOL_SPACE illegal null input'); sys.dbms_sys_error.raise_system_error( DBMS_RA_SCHEDULER.E_BAD_CHUNK_NUMBER_NUM, 'value','NULL'); END IF; -- -- -- -- IF NOT DBMS_RA_SCHEDULER.S_PURGING_ACTIVE THEN trace1 ('RESERVE_BLOCK_POOL_SPACE: Not purging!'); RAISE DBMS_RA_SCHEDULER.E_NOT_IN_PURGE; END IF; p_maxchunks := DBMS_RA_SCHEDULER.S_PURGING_RESERVE / l_chunksize; lock_db(p_db_key); <> NULL; -- -- -- BEGIN SELECT odb.sl_key, NVL(odb.move_phase,0), odb.allocated_space, odb.used_space INTO l_sl_key, l_move_phase, l_allocated, l_used FROM odb WHERE odb.db_key = p_db_key; trace1('RESERVE_BLOCK_POOL_SPACE: Storage location key is: ' || l_sl_key); EXCEPTION WHEN NO_DATA_FOUND THEN save_error; trace1 ('RESERVE_BLOCK_POOL_SPACE: Bad storage location'); unlock_db(p_db_key); RAISE DBMS_RA_SCHEDULER.E_BAD_STORAGE_LOCATION; END; -- -- -- IF l_move_phase != DBMS_RA_SCHEDULER.MOVE_PHASE_POOL THEN BEGIN DBMS_RA_SCHEDULER.S_SYSRESERVE_OK := TRUE; lock_sl(l_sl_key); -- -- -- -- l_freechunks := freespace(l_sl_key) / l_chunksize; trace1('RESERVE_BLOCK_POOL_SPACE freechunks=' || l_freechunks || ' ; allocated=' || l_allocated || ' ; used=' || l_used || ' ; chunksize=' || l_chunksize); l_availablechunks := l_freechunks + ((l_allocated-l_used) / l_chunksize); l_availablechunks := FLOOR(l_availablechunks); trace1 ('RESERVE_BLOCK_POOL_SPACE Chunks available = ' || l_availablechunks); IF l_availablechunks < p_chunks THEN l_purge_reserve := l_availablechunks; ELSE l_purge_reserve := p_chunks; END IF; trace1('RESERVE_BLOCK_POOL_SPACE: purge_reserve = ' || l_purge_reserve); -- -- -- -- -- -- UPDATE odb SET used_space = l_used + (l_purge_reserve * l_chunksize), not_taped = not_taped + (l_purge_reserve * l_chunksize), allocated_space = l_used + (l_purge_reserve * l_chunksize), total_allocation = total_allocation - l_allocated + l_used + (l_purge_reserve * l_chunksize) WHERE db_key = p_db_key; UPDATE task SET purge_reserve = l_purge_reserve WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK; COMMIT; unlock_sl(l_sl_key); EXCEPTION WHEN OTHERS THEN save_error; unlock_sl(l_sl_key); DBMS_RA_SCHEDULER.S_SYSRESERVE_OK := FALSE; RAISE; END; ELSE -- -- -- -- -- -- -- -- -- SELECT reserved_space, odb.total_allocation INTO l_reservation, l_total_allocation FROM odb WHERE db_key = p_db_key; l_freechunks := (l_reservation - l_total_allocation) / l_chunksize; l_availablechunks := l_freechunks + ((l_allocated - l_used) /l_chunksize); trace1 ('RESERVE_BLOCK_POOL_SPACE (move) Chunks available = ' || l_availablechunks); -- -- -- -- -- -- -- -- IF l_availablechunks < 2 THEN l_availablechunks := 2; END IF; -- -- -- IF l_availablechunks < p_chunks THEN l_purge_reserve := l_availablechunks; ELSE l_purge_reserve := p_chunks; END IF; -- -- -- IF ((l_allocated - l_used) >= (l_purge_reserve * l_chunksize)) THEN UPDATE odb SET used_space = l_used + (l_purge_reserve * l_chunksize), not_taped = not_taped + (l_purge_reserve * l_chunksize) WHERE db_key = p_db_key; UPDATE task SET purge_reserve = l_purge_reserve WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK; COMMIT; ELSE -- -- -- IF NOT allocate_db_space (l_sl_key, p_db_key, (l_purge_reserve * l_chunksize), TRUE) THEN -- trace1 ('RESERVE_SPACE: No storage space found!'); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_NO_MORE_STORAGE_NUM, DBMS_RA_SCHEDULER.S_ALLOC_INCREMENT); END IF; -- -- -- -- -- -- trace1('RESERVE_BLOCK_POOL_SPACE: Looping after allocation'); GOTO do_reserve; END IF; END IF; unlock_db(p_db_key); trace1 ('RESERVE_BLOCK_POOL_SPACE: Reserved chunks = ' || l_purge_reserve); RETURN l_purge_reserve; EXCEPTION WHEN OTHERS THEN save_error; unlock_db(p_db_key); RAISE; END reserve_block_pool_space; -- -- -- -- -- -- -- -- -- -- -- PROCEDURE finish_block_pool_chunk(p_db_key IN NUMBER) IS PRAGMA AUTONOMOUS_TRANSACTION; l_unused_chunks NUMBER; BEGIN trace1 ('FINISH_BLOCK_POOL_CHUNK for db_key = ' || p_db_key); -- -- -- lock_db(p_db_key); SELECT NVL(purge_reserve,0) INTO l_unused_chunks FROM task WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK; IF l_unused_chunks > 0 THEN UPDATE odb SET used_space = used_space - (l_unused_chunks * sl_min_alloc) WHERE db_key = p_db_key; -- -- -- -- -- -- UPDATE task SET purge_reserve = NULL, task_type = DECODE (task_type, DBMS_RA_SCHEDULER.TASK_PURGE_DF_NOW, DBMS_RA_SCHEDULER.TASK_PURGE_DF, task_type) WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK; COMMIT; trace1 ('FINISH_BLOCK_POOL_CHUNK: Fin.'); END IF; unlock_db (p_db_key); trace1 ('FINISH_BLOCK_POOL_CHUNK: Fin.'); EXCEPTION WHEN OTHERS THEN save_error; unlock_db (p_db_key); RAISE; END finish_block_pool_chunk; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION allocate_db_space ( p_sl_key IN OUT NUMBER, p_db_key IN NUMBER, p_size IN NUMBER DEFAULT NULL, p_movepurge IN BOOLEAN DEFAULT FALSE) RETURN BOOLEAN IS l_alloc_size NUMBER := NVL (p_size, DBMS_RA_SCHEDULER.S_ALLOC_INCREMENT); l_allocated_space NUMBER; l_preallocated_space NUMBER; l_move_phase NUMBER; l_needs_repair NUMBER; l_reserved_space NUMBER; new_task_rec task%ROWTYPE; l_freespace NUMBER; l_program VARCHAR2(300); l_count NUMBER; l_job_name user_scheduler_jobs.job_name%TYPE; BEGIN -- -- -- IF (l_alloc_size < DBMS_RA_SCHEDULER.S_ALLOC_INCREMENT) AND NOT p_movepurge THEN l_alloc_size := DBMS_RA_SCHEDULER.S_ALLOC_INCREMENT; END IF; trace1 ('ALLOCATE_DB_SPACE for ' || ' sl_key=' || p_sl_key || ', db_key=' || p_db_key || ', size=' || print(p_size) || ', allocsize=' || l_alloc_size || ', movepurge=' || print(p_movepurge)); -- -- -- -- LOOP -- -- -- BEGIN SELECT allocated_space, allocated_space-used_space, move_phase, sl_key INTO l_allocated_space, l_preallocated_space, l_move_phase, p_sl_key FROM odb WHERE db_key = p_db_key; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; trace1 ('ALLOCATE_DB_SPACE: No space for DB'); clear_error; RETURN FALSE; END; trace1 ('ALLOCATE_DB_SPACE: DB allocation is ' || l_allocated_space || '; preallocation is ' || l_preallocated_space || '; used_space is ' || TO_NUMBER(l_allocated_space - l_preallocated_space) || '; move_phase is ' || l_move_phase); -- -- -- SELECT sl_needs_repair INTO l_needs_repair FROM sl WHERE sl_key = p_sl_key; IF l_needs_repair IS NOT NULL THEN trace1 ('ALLOCATE_DB_SPACE: SL under repair'); RETURN FALSE; END IF; -- -- -- -- -- -- IF (l_move_phase = DBMS_RA_SCHEDULER.MOVE_PHASE_POOL) AND NOT p_movepurge THEN -- -- -- -- -- -- -- -- SELECT reserved_space INTO l_reserved_space FROM odb WHERE odb.db_key = p_db_key; -- -- -- -- IF l_reserved_space - (l_allocated_space - l_preallocated_space) < l_alloc_size THEN -- -- -- l_job_name := 'RA$_PURDB_' || TO_CHAR(p_db_key); l_program := 'dbms_ra_storage.trim_database_as_job(' || ' p_db_key=>' || TO_CHAR(p_db_key) || ', p_sl_key=>' || TO_CHAR(p_sl_key) || ', p_allocation=>' || TO_CHAR(l_alloc_size) || ');'; trace1('ALLOCATE_DB_SPACE: Spawning: ' || l_program); BEGIN DBMS_RA_SCHEDULER.SPAWN_JOB (l_job_name, l_program, NULL, NULL); EXCEPTION WHEN DBMS_RA_SCHEDULER.E_JOB_ALREADY_EXISTS THEN save_error; trace1 ('ALLOCATE_DB_SPACE: Purging job already exists'); clear_error; WHEN OTHERS THEN save_error; trace1 ('ALLOCATE_DB_SPACE: Spawning exited with: ' || SQLERRM); RAISE; END; -- -- -- -- IF DBMS_RA_SCHEDULER.S_NO_WAIT_ON_ALLOCATE THEN DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT := DBMS_RA_SCHEDULER.SET_BLOCKING_PURGE (p_db_key, p_size); RAISE DBMS_RA_SCHEDULER.E_RETRY_RESERVE; END IF; -- -- -- -- unlock_db(p_db_key); -- -- -- -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); UPDATE task SET pending_interrupt = NULL, state = (CASE WHEN state = DBMS_RA_SCHEDULER.STATE_RUNNING THEN DBMS_RA_SCHEDULER.STATE_RUNNING WHEN state = DBMS_RA_SCHEDULER.STATE_CANCEL THEN DBMS_RA_SCHEDULER.STATE_CANCEL WHEN state = DBMS_RA_SCHEDULER.STATE_CANCELING THEN DBMS_RA_SCHEDULER.STATE_CANCELING ELSE DBMS_RA_SCHEDULER.STATE_EXECUTABLE END) WHERE pending_interrupt = DBMS_RA_SCHEDULER.S_CURRENT_TASK; trace1 ('ALLOCATE_DB_SPACE: releasing ' || SQL%ROWCOUNT || ' tasks'); COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0); -- -- -- -- -- IF s_safe_mode THEN SELECT min(key) INTO l_count FROM sys.rai_js_locks WHERE sid = SYS_CONTEXT('USERENV', 'SID') AND ba_type = DBMS_RA_SCHEDULER.LOCK_KEY AND key NOT IN (SELECT MOD(param_num1, POWER(2,32)) FROM task WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK AND task_type = DBMS_RA_SCHEDULER.TASK_INDEX_BACKUP); IF l_count IS NOT NULL THEN trace1('ALLOCATE_DB_SPACE: (DB) Key lock ' || l_count || ' held illegally'); sys.dbms_sys_error.raise_system_error( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'bad key lock'); END IF; END IF; -- -- -- -- IF DBMS_RA_SCHEDULER.S_CURRENT_TASK IS NULL THEN trace1 ('ALLOCATE_DB_SPACE: Retry exception for servlet wait'); RAISE DBMS_RA_SCHEDULER.E_RETRY_ERROR; END IF; trace1 ('ALLOCATE_DB_SPACE: ...waiting for db purge...'); DBMS_LOCK.SLEEP(DBMS_RA_SCHEDULER.S_PURGE_WAIT); lock_db(p_db_key); -- -- -- -- -- CONTINUE; END IF; END IF; -- -- -- -- -- lock_sl (p_sl_key); l_freespace := freespace(p_sl_key); trace1 ('ALLOCATE_DB_SPACE (COMMON CODEPATH): freespace ' || l_freespace); IF l_freespace >= (l_alloc_size - l_preallocated_space) THEN -- -- -- UPDATE odb SET allocated_space = allocated_space + (l_alloc_size - l_preallocated_space), total_allocation = total_allocation + (l_alloc_size - l_preallocated_space) WHERE db_key = p_db_key; -- -- -- -- -- -- -- IF NVL(DBMS_RA_SCHEDULER.S_CURRENT_TASK_type,-1) NOT IN (DBMS_RA_SCHEDULER.TASK_MOVE_DF, DBMS_RA_SCHEDULER.TASK_MOVE_ALL_DB, DBMS_RA_SCHEDULER.TASK_PURGE_IMMEDIATE, DBMS_RA_SCHEDULER.TASK_PURGE_DF_NOW, DBMS_RA_SCHEDULER.TASK_OPTIMIZE_CHUNKS_DF, DBMS_RA_SCHEDULER.TASK_REPAIR_DB) THEN UPDATE sl SET sl_hist_usage = NVL(sl_hist_usage,0) + (l_alloc_size - l_preallocated_space) WHERE sl_key = p_sl_key; END IF; COMMIT; unlock_sl(p_sl_key); trace1 ('ALLOCATE_DB_SPACE: Allocation is granted'); RETURN TRUE; END IF; -- -- -- IF NOT available_bs(p_sl_key, p_db_key, l_alloc_size - l_preallocated_space) THEN trace1 ('ALLOCATE_DB_SPACE: No available space'); unlock_sl(p_sl_key); EXIT; END IF; -- -- -- -- -- unlock_sl(p_sl_key); unlock_db(p_db_key); -- -- -- -- -- -- -- -- -- IF (DBMS_RA_SCHEDULER.S_CURRENT_TASK IS NULL) OR (DBMS_RA_SCHEDULER.TYPE2PRIORITY(DBMS_RA_SCHEDULER.S_CURRENT_TASK_TYPE) < DBMS_RA_SCHEDULER.PRIO_MIN_BUSYWORK) THEN -- -- -- l_job_name := 'RA$_PURGE_' || TO_CHAR(p_sl_key); l_program := 'dbms_ra_scheduler.purge_immediate(' || ' p_sl_key=>' || TO_CHAR(p_sl_key) || ', p_db_key=>' || TO_CHAR(p_db_key) || ', p_allocation=>' || TO_CHAR(l_alloc_size) || ');'; trace1('ALLOCATE_DB_SPACE: Spawning: ' || l_program); BEGIN DBMS_RA_SCHEDULER.SPAWN_JOB (L_JOB_NAME, L_PROGRAM, NULL, NULL); EXCEPTION WHEN DBMS_RA_SCHEDULER.E_JOB_ALREADY_EXISTS THEN save_error; trace1 ('ALLOCATE_DB_SPACE: Purging job already exists'); clear_error; WHEN OTHERS THEN save_error; trace1 ('ALLOCATE_DB_SPACE: Spawning exited with: ' || SQLERRM); lock_db(p_db_key); RAISE; END; ELSE -- -- -- -- SELECT COUNT(*) INTO l_count FROM task WHERE task_type IN (DBMS_RA_SCHEDULER.TASK_PURGE, DBMS_RA_SCHEDULER.TASK_PURGE_IMMEDIATE) AND sl_key = p_sl_key; IF l_count = 0 THEN new_task_rec.task_type := DBMS_RA_SCHEDULER.TASK_PURGE; new_task_rec.sl_key := p_sl_key; new_task_rec.db_key := p_db_key; new_task_rec.flags := 0; new_task_rec.param_num1 := l_alloc_size; DBMS_RA_SCHEDULER.NEW_TASK (new_task_rec); END IF; END IF; -- -- -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); UPDATE task SET pending_interrupt = NULL, state = (CASE WHEN state = DBMS_RA_SCHEDULER.STATE_RUNNING THEN DBMS_RA_SCHEDULER.STATE_RUNNING WHEN state = DBMS_RA_SCHEDULER.STATE_CANCEL THEN DBMS_RA_SCHEDULER.STATE_CANCEL WHEN state = DBMS_RA_SCHEDULER.STATE_CANCELING THEN DBMS_RA_SCHEDULER.STATE_CANCELING ELSE DBMS_RA_SCHEDULER.STATE_EXECUTABLE END) WHERE pending_interrupt = DBMS_RA_SCHEDULER.S_CURRENT_TASK; trace1 ('ALLOCATE_DB_SPACE: releasing ' || SQL%ROWCOUNT || ' tasks'); COMMIT; SYS.KBRSI_ICD.RSSCHEDUNLOCK; -- -- -- -- IF DBMS_RA_SCHEDULER.S_NO_WAIT_ON_ALLOCATE THEN DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT := CASE DBMS_RA_SCHEDULER.S_CURRENT_TASK_TYPE WHEN DBMS_RA_SCHEDULER.TASK_OPTIMIZE_CHUNKS_DF THEN DBMS_RA_SCHEDULER.OPT_DF_PSEUDO_TASK ELSE DBMS_RA_SCHEDULER.SET_BLOCKING_PURGE (p_db_key, p_size) END; lock_db(p_db_key); RAISE DBMS_RA_SCHEDULER.E_RETRY_RESERVE; END IF; -- -- -- -- -- IF s_safe_mode THEN SELECT min(key) INTO l_count FROM sys.rai_js_locks WHERE sid = SYS_CONTEXT('USERENV', 'SID') AND ba_type = DBMS_RA_SCHEDULER.LOCK_KEY AND key NOT IN (SELECT MOD(param_num1, POWER(2,32)) FROM task WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK AND task_type = DBMS_RA_SCHEDULER.TASK_INDEX_BACKUP); IF l_count IS NOT NULL THEN tracex('ALLOCATE_DB_SPACE: Key lock ' || l_count || ' held illegally'); sys.dbms_sys_error.raise_system_error( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'bad key lock'); END IF; END IF; -- -- -- -- LOOP -- -- -- -- IF DBMS_RA_SCHEDULER.S_CURRENT_TASK IS NULL THEN trace1 ('ALLOCATE_DB_SPACE: Retry exception for servlet wait'); RAISE DBMS_RA_SCHEDULER.E_RETRY_ERROR; END IF; trace1 ('ALLOCATE_DB_SPACE: ...waiting for purge...'); -- -- DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT; DBMS_LOCK.SLEEP(DBMS_RA_SCHEDULER.S_PURGE_WAIT); -- -- -- -- SELECT sl_key INTO p_sl_key FROM odb WHERE db_key = p_db_key; l_freespace := freespace(p_sl_key); EXIT WHEN l_freespace > (l_alloc_size - l_preallocated_space); dbms_ra_scheduler.make_amjobs(name => l_job_name); SELECT COUNT(*) INTO l_count FROM TABLE(CAST(DBMS_RA_SCHEDULER.S_AMJOBS AS rai_jobs_table_type)); EXIT WHEN l_count = 0; END LOOP; trace1 ('ALLOCATE_DB_SPACE: ... Done waiting'); -- -- -- -- lock_db(p_db_key); END LOOP; -- -- -- trace1 ('ALLOCATE_DB_SPACE: Allocation is refused'); RETURN FALSE; END allocate_db_space; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE check_tape_limit(p_db_key IN NUMBER, p_reserved IN NUMBER, p_used_space IN NUMBER, p_not_taped IN NUMBER, p_not_taped_state IN VARCHAR2, p_move_phase IN NUMBER, p_allocation IN NUMBER) IS l_not_taped NUMBER; l_count NUMBER; l_task_rec task%ROWTYPE; BEGIN trace1 ('CHECK_TAPE_LIMIT: dbkey ' || p_db_key); -- IF p_not_taped_state IS NULL THEN RETURN; END IF; -- IF p_not_taped < p_reserved THEN RETURN; END IF; -- IF p_not_taped_state IN ('N', 'B') AND p_used_space < p_reserved THEN RETURN; END IF; -- ROLLBACK; -- IF p_not_taped_state IN ('I', 'C') THEN SELECT COUNT(*) INTO l_count FROM task WHERE task_type = DBMS_RA_SCHEDULER.TASK_GCOPY_COMPUTE AND db_key = p_db_key AND ROWNUM = 1; -- IF l_count = 0 THEN l_task_rec.task_type := DBMS_RA_SCHEDULER.TASK_GCOPY_COMPUTE; l_task_rec.db_key := p_db_key; l_task_rec.flags := 0; DBMS_RA_SCHEDULER.NEW_TASK(l_task_rec); END IF; RAISE DBMS_RA_SCHEDULER.E_RETRY_RESERVE; END IF; -- trace1 ('CHECK_TAPE_LIMIT: space denied for dbkey ' || p_db_key); IF DBMS_RA_SCHEDULER.S_CURRENT_TASK IS NULL THEN -- SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_NO_MORE_STORAGE_NUM, p_allocation); ELSE -- DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT := DBMS_RA_SCHEDULER.SET_BLOCKING_PURGE (p_db_key, p_allocation); RAISE DBMS_RA_SCHEDULER.E_RETRY_RESERVE; END IF; END check_tape_limit; -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE purge_storage_location ( p_sl_key IN NUMBER, p_db_key IN NUMBER, p_spaceneed IN NUMBER, p_immediate IN BOOLEAN) IS CURSOR purgedb_cursor IS SELECT db_key, overretentionsecs, overspace, newsecs, goalsecs FROM rai_purge_queue WHERE sl_key = p_sl_key ORDER BY overretentionsecs DESC, overspace DESC; -- -- -- -- -- -- CURSOR copies_of_vb IS SELECT DISTINCT p.db_key, p.bp_key, p.handle, t.piece# sbt FROM odb o JOIN bp p ON o.db_key = p.db_key JOIN vbdf v ON p.db_key = v.db_key AND p.bp_key = v.srcbp_key LEFT OUTER JOIN sbt_task t USING (bs_key) WHERE p.vb_key IS NULL AND p.status != 'D' AND p.ba_access = 'L' AND o.sl_key = p_sl_key AND nvl(t.failure_cnt,0) = 0 AND v.df_key = v.krbph_dfkey AND v.state = DBMS_RA_POOL.VBDF_COMPLETE; l_bs2_timestamp TIMESTAMP WITH TIME ZONE; l_purge_scn NUMBER; l_oldest_backup TIMESTAMP WITH TIME ZONE; i BINARY_INTEGER; l_freespace NUMBER; l_original_freespace NUMBER; l_shrinkage NUMBER; l_planned_space NUMBER := 0; l_preallocated NUMBER; l_db_key NUMBER; l_overretention NUMBER; l_overspace NUMBER; l_newsecs NUMBER; l_goalsecs NUMBER; l_purgedb NUMBER := NULL; l_count NUMBER; l_1 NUMBER; l_2 NUMBER; l_chunksize NUMBER; l_resume NUMBER; TYPE t_dbkey_list IS TABLE OF NUMBER; l_skipped_dbkeys t_dbkey_list := t_dbkey_list(); l_list_ptr NUMBER; l_warned_dbkeys t_dbkey_list := t_dbkey_list(); l_last_free NUMBER := 0; l_slname sl.sl_name%TYPE; l_excess NUMBER; l_extra NUMBER; l_bskey NUMBER; c_autoshrink CONSTANT NUMBER := DBMS_RA_SCHEDULER.S_PURGE_AUTOSHRINK; c_alloc_incr CONSTANT NUMBER := DBMS_RA_SCHEDULER.S_ALLOC_INCREMENT; ONE_MEG CONSTANT NUMBER := 1024*1024; BEGIN trace1 ('PURGE_STORAGE_LOCATION for ' || ' p_sl_key=' || p_sl_key || ', p_db_key=' || print(p_db_key) || ', p_immediate=' || print(p_immediate)); -- -- -- -- FOR srcb IN copies_of_vb LOOP -- IF srcb.sbt IS NOT NULL THEN BEGIN swap_backup_piece(srcb.bp_key); free_backup_piece(srcb.db_key, srcb.handle, DBMS_RA_INT.KBRSCHKTYPE_FILE); EXCEPTION WHEN DBMS_RA_SCHEDULER.E_RETRY_ERROR THEN save_error; DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT := NULL; trace1 ('PURGE_STORAGE_LOCATION: skip bpkey ' || srcb.bp_key); clear_error; END; END IF; END LOOP; -- -- -- -- -- -- -- -- -- FOR trim IN (SELECT db_key FROM odb WHERE sl_key = p_sl_key AND db_key <> NVL(p_db_key, 0) AND (allocated_space - used_space) > GREATEST(c_autoshrink * reserved_space, c_alloc_incr)) LOOP lock_db(trim.db_key); -- -- -- -- -- -- -- -- -- SELECT LEAST ((allocated_space - used_space), GREATEST(c_autoshrink * reserved_space, c_alloc_incr)) INTO l_shrinkage FROM odb WHERE db_key=trim.db_key; UPDATE odb SET allocated_space = allocated_space - l_shrinkage, total_allocation = total_allocation - l_shrinkage WHERE db_key=trim.db_key; COMMIT; trace1('PURGE_STORAGE_LOCATION: Shrunk db_key=' || trim.db_key || ' by megs=' || l_shrinkage/ONE_MEG); unlock_db(trim.db_key); END LOOP; -- DBMS_RA_SCHEDULER.GET_LOCK (DBMS_RA_SCHEDULER.LOCK_PURGE, p_sl_key); -- -- FOR db IN (SELECT db_key, prot_max_retention_window, odb.recovery_window_goal, bs2_timestamp, purge_scn, rob.oldest_backup FROM odb JOIN prot USING(prot_key) JOIN rai_oldest_backup rob USING(db_key) WHERE odb.sl_key = p_sl_key AND odb.move_phase IS NULL AND odb.used_space > 0 AND NVL(odb.purge_scn,0) <> DBMS_RA_POOL.BIGNUM AND prot.prot_max_retention_window IS NOT NULL -- AND (odb.bs2_timestamp IS NULL OR ((SYSTIMESTAMP - odb.bs2_timestamp) > odb.recovery_window_goal)) -- AND (rob.oldest_backup < (SYSTIMESTAMP - prot.prot_max_retention_window))) LOOP trace1('PURGE_STORAGE_LOCATION: for db_key ' || db.db_key || '; max_retention_window is ' || db.prot_max_retention_window); -- -- -- -- l_bs2_timestamp := db.bs2_timestamp; l_purge_scn := db.purge_scn; l_oldest_backup := db.oldest_backup; -- -- -- -- -- WHILE ((l_oldest_backup <= (SYSTIMESTAMP - db.prot_max_retention_window)) AND (NVL(l_purge_scn,0) <> DBMS_RA_POOL.BIGNUM) -- AND (l_bs2_timestamp IS NULL OR ((SYSTIMESTAMP - l_bs2_timestamp) > db.recovery_window_goal))) LOOP -- -- -- -- -- -- -- -- -- trace1 ('PURGE_STORAGE_LOCATION: bs2_timestamp=' || l_bs2_timestamp || '; bs2_timestamp is ' || l_bs2_timestamp || '; purge_scn is ' || l_purge_scn || '; oldest_backup is ' || l_oldest_backup); purge_database (db.db_key, p_sl_key, FALSE); -- -- -- DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT; -- -- -- SELECT bs2_timestamp, purge_scn, oldest_backup INTO l_bs2_timestamp, l_purge_scn, l_oldest_backup FROM odb JOIN rai_oldest_backup rob USING(db_key) WHERE db_key = db.db_key; END LOOP; END LOOP; -- l_resume := NVL(dbms_ra_scheduler.get_savepoint, 0); IF l_resume > 0 AND l_db_key IS NOT NULL THEN SELECT db_key INTO l_db_key FROM task WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK; trace1 ('PURGE_STORAGE_LOCATION: Resume Purging on ' || l_db_key); purge_database (l_db_key, p_sl_key, FALSE); END IF; -- l_original_freespace := freespace(p_sl_key); l_freespace := l_original_freespace; -- -- -- LOOP -- -- -- IF p_immediate THEN -- -- -- -- SELECT allocated_space - used_space INTO l_preallocated FROM odb WHERE db_key = p_db_key; ELSE l_preallocated := 0; END IF; tracex ('PURGE_STORAGE_LOCATION: freespace=' || l_freespace/ONE_MEG || '+ planned=' || l_planned_space/ONE_MEG || '+ preallocated=' || l_preallocated/ONE_MEG || '> spaceneed' || p_spaceneed/ONE_MEG); -- -- -- EXIT WHEN (l_freespace + l_planned_space + l_preallocated) > p_spaceneed; -- -- -- IF s_stall_on THEN SELECT COUNT(*) INTO l_count FROM error_log WHERE severity >= DBMS_RA_SCHEDULER.SEVERITY_ERROR AND status = 'ACTIVE'; IF l_count > 0 THEN -- SYS.KBRSI_ICD.RSRUNSCHED; END IF; END IF; -- -- -- IF s_safe_mode THEN l_db_key := NULL; OPEN purgedb_cursor; LOOP FETCH purgedb_cursor INTO l_db_key, l_overretention, l_overspace, l_newsecs, l_goalsecs; EXIT WHEN purgedb_cursor%NOTFOUND; SELECT used_space, allocated_space, sl_min_alloc INTO l_1, l_2, l_chunksize FROM odb WHERE db_key = l_db_key; -- -- -- -- -- -- -- trace1('PURGE_STORAGE_LOCATION stats' || ' db_key=' || lpad(l_db_key,4) || ', %% of time=' || round(l_overretention*100,2) || ', %% over allocated space= ' || round(l_overspace*100,2) || '; used chunks ' || l_1/l_chunksize || '; allocated chunks ' || round(l_2/l_chunksize) || '; (newsecs ' || round(l_newsecs) || ', goalsecs ' || l_goalsecs || ')'); END LOOP; CLOSE purgedb_cursor; -- -- -- -- -- IF l_db_key IS NULL THEN trace1('PURGE_STORAGE_LOCATION: No databases in purge queue!'); DBMS_RA_SCHEDULER.UNLOCK (DBMS_RA_SCHEDULER.LOCK_PURGE, p_sl_key); RETURN; END IF; END IF; OPEN purgedb_cursor; l_purgedb := NULL; LOOP BEGIN FETCH purgedb_cursor INTO l_db_key, l_overretention, l_overspace, l_newsecs, l_goalsecs; IF purgedb_cursor%NOTFOUND THEN -- bail EXIT; END IF; -- -- -- -- IF l_db_key MEMBER OF l_skipped_dbkeys THEN trace1('PURGE_STORAGE_LOCATION: skipping db_key=' || l_db_key); CONTINUE; END IF; -- -- -- IF l_overretention = 0 AND NOT l_db_key MEMBER OF l_warned_dbkeys THEN DBMS_RA_SCHEDULER.LOG_ERROR ( p_errno => DBMS_RA_SCHEDULER.E_REC_WINDOW_LOST_NUM, p_param1 => DBMS_RA_INT.DBKEY2NAME(l_db_key), p_component => 'PURGE', p_severity => DBMS_RA_SCHEDULER.SEVERITY_WARNING, p_db_key => l_db_key); l_warned_dbkeys.EXTEND; l_list_ptr := l_warned_dbkeys.LAST; l_warned_dbkeys(l_list_ptr) := l_db_key; END IF; -- -- -- -- IF (l_overretention <= 0) AND (l_skipped_dbkeys.FIRST IS NOT NULL) THEN EXIT; END IF; -- -- -- -- -- -- -- -- -- -- IF (l_overretention > 0) OR (l_overspace > 0) THEN -- -- -- l_purgedb := l_db_key; EXIT; END IF; EXCEPTION WHEN OTHERS THEN save_error; CLOSE purgedb_cursor; RAISE; END; END LOOP; CLOSE purgedb_cursor; -- -- -- IF l_purgedb IS NULL THEN trace1 ('PURGE_STORAGE_LOCATION: No database found to purge (yet)!'); -- -- -- -- IF (l_skipped_dbkeys.FIRST IS NOT NULL) AND p_immediate THEN -- -- -- -- FOR i IN l_skipped_dbkeys.FIRST..l_skipped_dbkeys.LAST LOOP l_purgedb := l_skipped_dbkeys(i); SELECT overretentionsecs, overspace, newsecs, goalsecs INTO l_overretention, l_overspace, l_newsecs, l_goalsecs FROM rai_purge_queue WHERE db_key = l_purgedb; IF l_overretention > 0 THEN -- -- -- l_skipped_dbkeys.DELETE(i); -- -- -- EXIT; END IF; -- -- -- l_purgedb := NULL; END LOOP; -- -- -- -- -- IF l_purgedb IS NULL THEN l_list_ptr := l_skipped_dbkeys.FIRST; l_purgedb := l_skipped_dbkeys(l_list_ptr); l_skipped_dbkeys.DELETE(l_list_ptr); trace1 ('PURGE_STORAGE_LOCATION: Plan C has chosen dbkey=' || l_purgedb); SELECT overretentionsecs, overspace, newsecs, goalsecs INTO l_overretention, l_overspace, l_newsecs, l_goalsecs FROM rai_purge_queue WHERE db_key = l_purgedb; END IF; IF l_purgedb IS NOT NULL THEN -- -- -- -- trace1 ('PURGE_STORAGE_LOCATION: Killing tasks for dbkey=' || l_purgedb); dbms_ra_scheduler.interrupt_tasks( p_interrupt => dbms_ra_scheduler.INTERRUPT_FOR_PURGE , p_db_key => l_purgedb ); END IF; END IF; -- IF (l_skipped_dbkeys.FIRST IS NOT NULL) ... END IF; -- IF l_purgedb IS NULL ... -- -- -- -- -- -- -- IF (l_purgedb IS NULL) AND p_immediate AND (p_db_key IS NOT NULL) THEN SELECT (allocated_space + NVL(p_spaceneed,0)) - reserved_space INTO l_excess FROM odb WHERE db_key = p_db_key; trace1('PURGE_STORAGE_LOCATION: Purge the greedy db'); IF l_excess > 0 THEN SELECT overretentionsecs, overspace, newsecs, goalsecs INTO l_overretention, l_overspace, l_newsecs, l_goalsecs FROM rai_purge_queue WHERE sl_key = p_sl_key AND db_key = p_db_key; l_purgedb := p_db_key; END IF; END IF; -- -- -- -- IF l_purgedb IS NULL THEN trace1 ('PURGE_STORAGE_LOCATION: No database found to purge!'); EXIT; END IF; -- -- -- -- IF (l_newsecs < l_goalsecs) THEN SELECT sl_name INTO l_slname FROM sl WHERE sl_key = p_sl_key; DBMS_RA_SCHEDULER.LOG_ERROR ( p_errno => DBMS_RA_SCHEDULER.E_SL_FULL_NUM, p_param1 => l_slname, p_component => 'PURGE', p_severity => DBMS_RA_SCHEDULER.SEVERITY_WARNING, p_sl_key => p_sl_key); -- -- -- -- -- -- IF ((NOT p_immediate) OR ((l_original_freespace + DBMS_RA_SCHEDULER.S_ALLOC_INCREMENT) < (l_freespace + l_planned_space))) THEN trace1 ('PURGE_STORAGE_LOCATION: purgedb is below retention goal: ' || l_purgedb); EXIT; END IF; ELSE -- -- -- -- DBMS_RA_SCHEDULER.FIX_ERROR( p_error_num => DBMS_RA_SCHEDULER.E_SL_FULL_NUM, p_sl_key => p_sl_key); COMMIT; END IF; BEGIN -- -- -- DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT; -- l_last_free := l_freespace + l_planned_space; trace1('PURGE_STORAGE_LOCATION: purging' || ' db_key=' || lpad(l_db_key,4)); -- -- -- -- UPDATE task SET pending_interrupt = NULL, db_key = l_purgedb WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK; COMMIT; -- -- -- purge_database (l_purgedb, p_sl_key, FALSE); l_planned_space := f_chunksize(l_purgedb) * dbms_ra_pool.plannedSpace(p_sl_key, s_enable_dup); -- -- -- -- -- l_skipped_dbkeys := t_dbkey_list(); EXCEPTION WHEN DBMS_RA_SCHEDULER.E_RETRY_ERROR THEN save_error; -- -- -- -- -- l_skipped_dbkeys.EXTEND; l_list_ptr := l_skipped_dbkeys.LAST; l_skipped_dbkeys(l_list_ptr) := l_purgedb; trace1 ('PURGE_STORAGE_LOCATION: Added dbkey=' || l_purgedb || ' to skipped db list'); clear_error; WHEN OTHERS THEN save_error; ROLLBACK; -- lock_db (l_purgedb); UPDATE odb SET total_allocation = total_allocation - (allocated_space - used_space), allocated_space = used_space WHERE db_key = l_purgedb RETURNING used_space INTO l_count; COMMIT; unlock_db (l_purgedb); trace1 ('PURGE_STORAGE_LOCATION: ODB allocation (mbs) trimmed to: ' || l_count/ONE_MEG); RAISE; END; -- -- -- -- -- lock_db (l_purgedb); IF p_immediate AND (l_purgedb = NVL(p_db_key,-1)) THEN SELECT LEAST(allocated_space - used_space, NVL(p_spaceneed,0)) INTO l_extra FROM odb WHERE db_key = l_purgedb; ELSE l_extra := 0; END IF; UPDATE odb SET total_allocation = total_allocation - (allocated_space - (used_space + l_extra)), allocated_space = used_space + l_extra WHERE db_key = l_purgedb RETURNING used_space INTO l_count; COMMIT; unlock_db (l_purgedb); -- -- -- UPDATE task SET pending_interrupt = NULL, db_key = NULL WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK; COMMIT; l_purgedb := NULL; l_freespace := freespace(p_sl_key); trace1 ('PURGE_STORAGE_LOCATION: ODB allocation trimmed to: ' || l_count || ' freespace(mbs)=' || l_freespace/ONE_MEG); END LOOP; -- DBMS_RA_SCHEDULER.UNLOCK (DBMS_RA_SCHEDULER.LOCK_PURGE, p_sl_key); EXCEPTION WHEN OTHERS THEN save_error; ROLLBACK; DBMS_RA_SCHEDULER.UNLOCK (DBMS_RA_SCHEDULER.LOCK_PURGE, p_sl_key); trace1 ('PURGE_STORAGE_LOCATION: Failed with: ' || SQLERRM); RAISE; END purge_storage_location; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION available_bs(p_sl_key IN NUMBER, p_db_key IN NUMBER, p_alloc IN NUMBER) RETURN BOOLEAN IS l_count NUMBER; l_ret BOOLEAN := TRUE; BEGIN -- SELECT COUNT(*) INTO l_count FROM odb WHERE db_key = p_db_key AND used_space + p_alloc >= reserved_space; -- IF l_count > 0 THEN SELECT COUNT(*) INTO l_count FROM dual WHERE EXISTS (SELECT 1 FROM bp WHERE db_key = p_db_key AND lib_key IS NULL /* Only backups on disk */ AND status = 'A' AND ba_access = 'L'); IF l_count = 0 THEN trace1('AVAILABLE_BS has nothing to delete for db_key ' || p_db_key); -- l_ret := FALSE; END IF; END IF; RETURN l_ret; END available_bs; -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE purge_database (p_db_key IN NUMBER, p_sl_key IN NUMBER DEFAULT NULL, p_inline IN BOOLEAN DEFAULT FALSE) IS l_sl_key NUMBER := p_sl_key; l_count NUMBER; BEGIN trace1 ('PURGE_DATABASE: db_key=' || p_db_key || ', sl_key=' || print(p_sl_key) || ', inline=' || print(p_inline) ); IF l_sl_key IS NULL THEN SELECT sl_key INTO l_sl_key FROM odb WHERE db_key = p_db_key; trace1 ('PURGE_DATABASE: sl_key=' || l_sl_key); END IF; -- -- -- DBMS_RA_SCHEDULER.S_PURGING_ACTIVE := TRUE; dbms_ra_pool.purgeDB(l_sl_key, p_db_key, p_inline); DBMS_RA_SCHEDULER.S_PURGING_ACTIVE := FALSE; trace1 ('PURGE_DATABASE: ... Done Purging'); -- -- -- SELECT COUNT(*) INTO l_count FROM odb WHERE wait_space > used_space AND db_key = p_db_key; IF l_count > 0 THEN DBMS_RA_SCHEDULER.RELEASE_BLOCKED_TASKS ( DBMS_RA_SCHEDULER.SPACE_PSEUDO_TASK, p_db_key); lock_db (p_db_key); UPDATE odb SET wait_space = NULL WHERE db_key = p_db_key; COMMIT; unlock_db (p_db_key); END IF; EXCEPTION WHEN OTHERS THEN save_error; trace1 ('PURGE_DATABASE: Exception: ' || SQLERRM); DBMS_RA_SCHEDULER.S_PURGING_ACTIVE := FALSE; RAISE; END purge_database; -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE backupArch(p_dbkey IN NUMBER, p_fname IN VARCHAR2, p_complete IN BOOLEAN, p_delete IN BOOLEAN DEFAULT TRUE) IS KRSP_SUCCESS CONSTANT NUMBER := 0; -- As defined in krsp.h KRSP_REFETCH CONSTANT NUMBER := 1; -- As defined in krsp.h KRSP_GIVEUP CONSTANT NUMBER := 2; -- As defined in krsp.h l_ftype NUMBER; l_dbid NUMBER; l_size NUMBER; l_count NUMBER; l_iscomplete BOOLEAN; l_dbinckey NUMBER; l_lowscn NUMBER; l_handle bp.handle%TYPE; l_inchandle bp.handle%TYPE; l_arcwhole NUMBER; l_action NUMBER := 0; l_sameendian NUMBER; BEGIN trace1('backupArch: dbkey ' || p_dbkey || ', name ' || p_fname); -- IF p_complete THEN l_arcwhole := TRUE#; ELSE l_arcwhole := FALSE#; END IF; -- -- -- sys.kbrsi_icd.rsIsComplete(fname => p_fname, filesize => l_size, complete => l_iscomplete, ftype => l_ftype, same_endian => l_sameendian, dbid => l_dbid); IF NOT l_iscomplete THEN -- There is some issue with the source file. trace1('backupArch: Archived Log ' || p_fname || ' cannot be backed up'); -- -- -- IF p_delete THEN SYS.KBRSI_ICD.RSDELETEFILE(p_fname); END IF; -- -- -- SELECT db_id INTO l_dbid FROM db WHERE db_key = p_dbkey; -- SYS.KBRSI_ICD.DG_BACKEDUP(l_dbid, p_fname, l_arcwhole, KRSP_REFETCH); COMMIT; RETURN; END IF; -- -- -- -- -- -- BEGIN SELECT 1 INTO l_count FROM db WHERE db_key = p_dbkey AND db_id = l_dbid; EXCEPTION WHEN no_data_found THEN save_error; tracex('backupArch: Archived Log ' || p_fname || ' has a bad dbid ' || l_dbid); sys.dbms_sys_error.raise_system_error( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'arc log with bad dbid ' || l_dbid); END; -- IF l_size IS NULL OR l_size < 1 THEN tracex('backupArch: Archived Log ' || p_fname || ' has a bad size ' || l_size); sys.dbms_sys_error.raise_system_error( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'arc log with bad size ' || l_size); END IF; -- IF l_sameendian /* skgfrfALGCVT */ = 0 THEN -- archivelog xtt l_action := DBMS_RA_SCHEDULER.COPY_BA_XALG /*KRBYX_ORS_XALG*/; SELECT DECODE(odb.same_endian, 'N', 0, 'Y', 1, -1) INTO l_sameendian FROM odb WHERE db_key = p_dbkey; IF l_sameendian != 0 THEN /* Update db about this */ UPDATE odb SET same_endian='N' WHERE db_key = p_dbkey; COMMIT; END IF; END IF; -- -- -- BEGIN l_handle := dbms_ra_int.file2handle(p_fname); copy_piece(p_fname, p_dbkey, l_action); DBMS_RA_SCHEDULER.fix_error ( p_error_num => DBMS_RA_SCHEDULER.E_BACKUP_FAILED, p_db_key => p_dbkey); EXCEPTION WHEN dbms_ra_scheduler.E_SERVLET_ERROR OR DUP_VAL_ON_INDEX THEN save_error; SELECT COUNT(*) INTO l_count FROM sbt_catalog WHERE handle = l_handle; IF l_count = 0 THEN -- Handle is not already present RAISE; -- we do not know what is wrong. END IF; tracex('backupArch: File already backed up'); clear_error; WHEN DBMS_RA_SCHEDULER.E_NO_MORE_STORAGE OR DBMS_RA_SCHEDULER.E_PIECE_TOO_BIG THEN save_error; DBMS_RA_SCHEDULER.log_error ( p_errno => DBMS_RA_SCHEDULER.E_BACKUP_FAILED, p_component => 'NZDL', p_severity => DBMS_RA_SCHEDULER.SEVERITY_ERROR, p_db_key => p_dbkey, p_param1 => DBMS_RA_INT.DBKEY2NAME(p_dbkey)); clear_error; IF p_delete THEN SYS.KBRSI_ICD.RSDELETEFILE(p_fname); END IF; SYS.KBRSI_ICD.DG_BACKEDUP(l_dbid, p_fname, l_arcwhole, KRSP_GIVEUP); RETURN; END; -- -- -- IF DBMS_RA_SCHEDULER.S_CURRENT_TASK_TYPE = DBMS_RA_SCHEDULER.TASK_BACKUP_ARCH THEN SELECT dbinc_key, low_scn INTO l_dbinckey, l_lowscn FROM bp p, brl r WHERE p.bs_key = r.bs_key AND p.handle = l_handle; SELECT MIN(p.handle) INTO l_inchandle FROM bp p, brl r WHERE p.bs_key = r.bs_key AND r.dbinc_key = l_dbinckey AND r.low_scn = l_lowscn AND p.handle LIKE DBMS_RA_INT.INC_ARC_PREFIX || '%'; IF l_inchandle IS NOT NULL THEN free_backup_piece(p_dbkey, l_inchandle); END IF; END IF; -- -- -- IF p_delete THEN SYS.KBRSI_ICD.RSDELETEFILE(p_fname); END IF; -- -- -- SYS.KBRSI_ICD.DG_BACKEDUP(l_dbid, p_fname, l_arcwhole, KRSP_SUCCESS); COMMIT; EXCEPTION WHEN OTHERS THEN save_error; trace1('backupArch: failure on ' || p_fname); -- -- SELECT COUNT(*) INTO l_count FROM task WHERE error_count >= dbms_ra_scheduler.s_max_task_restarts - 1 AND task_id = dbms_ra_scheduler.s_current_task; IF l_count > 0 THEN trace1('backupArch: Archived Log ' || p_fname || ' not backed up'); -- IF p_delete THEN SYS.KBRSI_ICD.RSDELETEFILE(p_fname); END IF; -- SELECT COUNT(*) INTO l_count FROM db WHERE db_id = l_dbid; IF l_count > 0 THEN trace1('backupArch: dbid ' || l_dbid); SYS.KBRSI_ICD.DG_BACKEDUP(l_dbid, p_fname, l_arcwhole, KRSP_GIVEUP); END IF; COMMIT; END IF; RAISE; END backupArch; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE move_database_metadata (p_db_key IN NUMBER, p_old_sl_key IN NUMBER, p_sl_key IN NUMBER) IS l_sls_used NUMBER; l_old_sl_allocated NUMBER; l_old_sl_used NUMBER; l_new_sl_used NUMBER; l_new_purge_reserve NUMBER; l_prot_key NUMBER; l_prot_recovery_window_goal prot.prot_recovery_window_goal%TYPE; l_sl_min_alloc NUMBER; l_chunksize NUMBER; l_task_rec task%ROWTYPE; BEGIN trace1 ('MOVE_DATABASE_METADATA: db_key=' || p_db_key || ', old_sl_key=' || p_old_sl_key || ', sl_key=' || p_sl_key); -- -- -- IF p_sl_key = p_old_sl_key THEN trace1 ('MOVE_DATABASE_METADATA: Nothing to move'); RETURN; END IF; -- -- -- SELECT allocated_space, used_space, sls_used, prot_key, sl_min_alloc INTO l_old_sl_allocated, l_old_sl_used, l_sls_used, l_prot_key, l_chunksize FROM odb WHERE db_key = p_db_key; trace1 ('MOVE_DATABASE_METADATA: old_sl_allocated=' || l_old_sl_allocated || ', old_sl_used=' || l_old_sl_used || ', sls_used=' || l_sls_used); -- -- -- -- IF l_old_sl_used > 0 THEN INSERT INTO dbsl ( db_key, sl_key, dbsl_used_space) VALUES (p_db_key, p_old_sl_key, l_old_sl_used); l_sls_used := l_sls_used + 1; END IF; -- -- -- -- SELECT MIN(dbsl_used_space) INTO l_new_sl_used FROM dbsl WHERE db_key = p_db_key AND sl_key = p_sl_key; IF l_new_sl_used IS NULL THEN l_new_sl_used := 0; ELSE DELETE dbsl WHERE db_key = p_db_key AND sl_key = p_sl_key; l_sls_used := l_sls_used - 1; END IF; -- -- -- SELECT sl_min_alloc INTO l_sl_min_alloc FROM sl WHERE sl_key = p_sl_key; -- -- -- SELECT prot_recovery_window_goal INTO l_prot_recovery_window_goal FROM prot WHERE prot_key = l_prot_key; -- -- -- -- UPDATE odb SET sl_key = p_sl_key, sl_min_alloc = l_sl_min_alloc, total_allocation = total_allocation - (l_old_sl_allocated - l_old_sl_used), sls_used = l_sls_used, allocated_space = l_new_sl_used, used_space = l_new_sl_used, move_phase = DBMS_RA_SCHEDULER.MOVE_PHASE_POOL, prot_key = future_prot_key, recovery_window_goal = l_prot_recovery_window_goal WHERE db_key = p_db_key; COMMIT; used_space_check (p_db_key, p_sl_key); EXCEPTION WHEN OTHERS THEN save_error; ROLLBACK; RAISE; END move_database_metadata; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE trim_database_for_move (p_db_key IN NUMBER, p_alloc IN NUMBER) IS l_alloc NUMBER := NVL(p_alloc, 0); l_api_lock_wait NUMBER; l_total_allocation NUMBER; l_planned_purges NUMBER; l_sl_key NUMBER; l_unclaimed NUMBER; l_reservation NUMBER; l_base_res NUMBER; l_new_res NUMBER; l_used_space NUMBER; l_phase NUMBER; l_newsecs NUMBER; l_goalsecs NUMBER; CURSOR bp_cursor IS SELECT MIN(bp_key) bp_key, vb_key, SUBSTR(MIN(tag),1,15) tag, TO_CHAR(MIN(start_time), ' HH:MI:SS') start_time, COUNT(*) bps FROM bp WHERE vb_key IS NOT NULL AND tag LIKE 'LOT_%' AND status != 'D' GROUP BY vb_key ORDER by vb_key; BEGIN trace1 ('TRIM_DATABASE_FOR_MOVE db_key=' || p_db_key); -- -- -- -- -- -- -- -- -- -- -- SELECT value INTO l_api_lock_wait FROM config WHERE name = '_api_lock_wait_seconds'; WHILE NOT SYS.KBRSI_ICD.RSAPILOCK LOOP l_api_lock_wait := l_api_lock_wait - 1; IF l_api_lock_wait = 0 THEN RAISE DBMS_RA_SCHEDULER.E_RETRY_ERROR; END IF; DBMS_LOCK.SLEEP(1); END LOOP; -- -- -- SELECT sl_key, reserved_space, base_reserved_space, used_space, move_phase INTO l_sl_key, l_reservation, l_base_res, l_used_space, l_phase FROM odb WHERE db_key = p_db_key; -- -- -- -- -- SELECT MIN(sl_space - DECODE(sl_key, l_sl_key, space - l_reservation, space) - DBMS_RA_SCHEDULER.S_PURGING_RESERVE * 2) INTO l_unclaimed FROM /* List of sl_keys and the claimed space */ (SELECT sl.sl_key, SUM(reserved_space) space, sl_space FROM sl, (SELECT reserved_space, sl_key FROM odb UNION ALL SELECT u.reserved_space, p.sl_key FROM unreg_database u, prot p WHERE u.prot_key = p.prot_key) d WHERE d.sl_key = sl.sl_key GROUP BY sl.sl_key, sl_space) s WHERE sl_key = l_sl_key OR /* list of related sl_keys */ sl_key IN (SELECT prot.sl_key FROM prot, odb WHERE odb.db_key = p_db_key AND (prot.prot_key = odb.prot_key OR prot.prot_key = odb.future_prot_key)); -- -- -- -- -- -- -- -- IF l_phase = DBMS_RA_SCHEDULER.MOVE_PHASE_PEND THEN l_new_res := l_reservation; ELSE l_new_res := LEAST(l_unclaimed, GREATEST(DBMS_RA_SCHEDULER.S_TRIM_FACTOR * l_base_res, l_used_space + l_alloc) ); END IF; trace1 ('TRIM_DATABASE: new reservation is ' || l_new_res); -- -- -- -- -- lock_db (p_db_key); UPDATE odb SET reserved_space = l_new_res WHERE db_key = p_db_key; COMMIT; unlock_db (p_db_key); -- -- SYS.KBRSI_ICD.RSAPIUNLOCK; -- -- -- LOOP -- -- -- lock_db (p_db_key); UPDATE odb SET total_allocation = total_allocation - (allocated_space - used_space), allocated_space = used_space WHERE db_key = p_db_key RETURNING total_allocation INTO l_total_allocation; COMMIT; unlock_db (p_db_key); -- -- -- -- l_planned_purges := f_chunksize(p_db_key) * dbms_ra_pool.plannedDBSpace(p_db_key); trace1 ('TRIM_DATABASE: planned_purges ' || l_planned_purges || ', allocation ' || l_total_allocation || ', l_alloc ' || l_alloc); EXIT WHEN (l_alloc + l_total_allocation - l_planned_purges) < l_new_res; -- -- -- -- IF l_phase = DBMS_RA_SCHEDULER.MOVE_PHASE_PEND AND (l_alloc + l_total_allocation - l_planned_purges) < l_unclaimed THEN -- SELECT newsecs, goalsecs INTO l_newsecs, l_goalsecs FROM rai_purge_queue WHERE db_key = p_db_key; EXIT WHEN (l_newsecs < l_goalsecs); END IF; IF s_tracing_on THEN FOR t IN bp_cursor LOOP trace1(LPAD(t.vb_key, 6) || LPAD(t.bps, 4) || ' ' || t.tag || t.start_time); END LOOP; END IF; -- -- -- BEGIN DBMS_RA_SCHEDULER.GET_LOCK (DBMS_RA_SCHEDULER.LOCK_PURGE, l_sl_key); purge_database (p_db_key, NULL, FALSE); DBMS_RA_SCHEDULER.UNLOCK(DBMS_RA_SCHEDULER.LOCK_PURGE, l_sl_key); EXCEPTION -- WHEN DBMS_RA_SCHEDULER.E_RETRY_ERROR OR DBMS_RA_SCHEDULER.E_RETRY_RESERVE THEN save_error; trace1 ('TRIM_DB: Locking Error...Retry in a bit'); DBMS_RA_SCHEDULER.UNLOCK (DBMS_RA_SCHEDULER.LOCK_PURGE, l_sl_key); SYS.KBRSI_ICD.RSAPIUNLOCK; DBMS_LOCK.SLEEP(DBMS_RA_SCHEDULER.S_LOCK_REFUSED_WAIT); clear_error; CONTINUE; WHEN OTHERS THEN save_error; trace1 ('TRIM_DB: Purge failed with: ' || SQLERRM); DBMS_RA_SCHEDULER.UNLOCK (DBMS_RA_SCHEDULER.LOCK_PURGE, l_sl_key); SYS.KBRSI_ICD.RSAPIUNLOCK; RAISE; END; END LOOP; END trim_database_for_move; -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE trim_database_as_job (p_db_key IN NUMBER, p_sl_key IN NUMBER, p_allocation IN NUMBER) IS l_task_rec task%ROWTYPE; BEGIN trace1 ('TRIM_DATABASE_AS_JOB: db_key=' || p_db_key || ', sl_key=' || p_sl_key || ', allocation=' || p_allocation); -- -- -- l_task_rec.task_type := DBMS_RA_SCHEDULER.TASK_TRIM_DB; l_task_rec.db_key := p_db_key; l_task_rec.sl_key := p_sl_key; -- Used to query task queue. l_task_rec.param_num1 := p_allocation; l_task_rec.flags := 0; DBMS_RA_SCHEDULER.NEW_TASK(l_task_rec); -- -- -- DBMS_RA_SCHEDULER.SCHEDULE (p_task_type => DBMS_RA_SCHEDULER.TASK_TRIM_DB, p_param1 => p_sl_key, p_param2 => p_db_key); trace1 ('TRIM_DATABASE_AS_JOB complete'); END trim_database_as_job; -- -- -- -- -- -- -- -- -- -- FUNCTION freespace (p_sl_key IN NUMBER) RETURN NUMBER IS l_allocsize NUMBER; l_slsize NUMBER; l_purgereserve NUMBER; l_free NUMBER; BEGIN trace1 ('FREESPACE: sl_key = ' || p_sl_key); -- -- -- SELECT ((SELECT NVL(SUM(allocated_space),0) FROM odb WHERE (odb.sl_key = p_sl_key)) + (SELECT NVL(SUM(dbsl_used_space),0) FROM dbsl WHERE (dbsl.sl_key = p_sl_key))), sl_space INTO l_allocsize, l_slsize FROM sl WHERE sl_key = p_sl_key; trace1 ('FREESPACE: l_allocsize = ' || l_allocsize || ', l_slsize = ' || l_slsize); -- -- -- IF DBMS_RA_SCHEDULER.S_SYSRESERVE_OK THEN l_purgereserve := 0; ELSE l_purgereserve := DBMS_RA_SCHEDULER.S_PURGING_RESERVE; END IF; l_free := (l_slsize - l_purgereserve) - l_allocsize; trace1 ('FREESPACE: sl_key = ' || p_sl_key || '; l_free = ' || l_free); RETURN l_free; EXCEPTION WHEN NO_DATA_FOUND THEN save_error; trace1 ('FREESPACE: No space in storage location'); RAISE; END freespace; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE used_space_check (p_db_key IN NUMBER, p_sl_key IN NUMBER, p_check_files IN BOOLEAN DEFAULT FALSE, p_repair_sl_key IN NUMBER DEFAULT NULL) IS l_chunksize NUMBER; l_used_space NUMBER; l_move_phase NUMBER; l_total NUMBER; l_allocated NUMBER; l_dbsl_used NUMBER; l_task_purge_reserve NUMBER; l_task_chunk_cache NUMBER; l_blockpool_usage NUMBER; l_sbtpiece_usage NUMBER; BEGIN IF s_safe_mode OR p_check_files THEN trace1 ('USED_SPACE_CHECK for db_key=' || p_db_key || '; db_sl_key=' || p_sl_key || '; check_files=' || print(p_check_files) || '; repair_sl_key=' || print(p_repair_sl_key)); l_chunksize := f_chunksize(p_db_key); -- -- -- -- WITH bp_usage AS ( SELECT /*+ USE_NL_WITH_INDEX(c) LEADING(dbinc df) INDEX(df) NO_INDEX_FFS(c) INDEX_RS_ASC(c) */ p_db_key db_key , COUNT(*) * l_chunksize blockpool_usage FROM chunks c -- , df , dbinc WHERE c.df_key = df.df_key AND c.dbinc_key = dbinc.dbinc_key AND df.dbinc_key = dbinc.dbinc_key AND dbinc.db_key = p_db_key AND c.sl_key = NVL(p_repair_sl_key, c.sl_key) ) , sbt_usage AS ( SELECT p_db_key db_key , SUM(filesize) sbtpiece_usage FROM sbt_catalog WHERE db_key = p_db_key AND sbt_catalog.sl_key = NVL(p_repair_sl_key, sbt_catalog.sl_key) ) , tasks_usage AS ( SELECT p_db_key db_key , SUM(t.purge_reserve) * l_chunksize task_purge_reserve , SUM(tcc.chunk_cache) * l_chunksize task_chunk_cache FROM task t LEFT OUTER JOIN task_chunk_cache tcc USING (task_id) WHERE t.db_key = p_db_key AND p_sl_key = NVL (p_repair_sl_key, p_sl_key) ) , dbsl_usage AS ( SELECT p_db_key db_key , SUM(dbsl_used_space) dbsl_used FROM dbsl WHERE dbsl.db_key = p_db_key AND dbsl.sl_key = NVL(p_repair_sl_key, dbsl.sl_key) ) , odb_usage AS ( SELECT p_db_key db_key , odb.used_space used_space , odb.move_phase move_phase , total_allocation total , allocated_space allocated FROM odb WHERE odb.db_key = p_db_key ) SELECT /*+ OPT_PARAM('optimizer_dynamic_sampling' 0) OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false') OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none') OPT_PARAM('_optimizer_use_feedback' 'false') LEADING(odb_usage dbsl_usage task_usage sbt_usage bp_usage) */ NVL(MIN(used_space), 0) , NVL(MIN(move_phase), 0) , NVL(MIN(total), 0) , NVL(MIN(allocated), 0) , NVL(MIN(dbsl_used), 0) , NVL(MIN(task_purge_reserve), 0) , NVL(MIN(task_chunk_cache), 0) , NVL(MIN(sbtpiece_usage), 0) , NVL(MIN(blockpool_usage), 0) INTO l_used_space , l_move_phase , l_total , l_allocated , l_dbsl_used , l_task_purge_reserve , l_task_chunk_cache , l_sbtpiece_usage , l_blockpool_usage FROM odb_usage LEFT OUTER JOIN dbsl_usage USING (db_key) LEFT OUTER JOIN tasks_usage USING (db_key) LEFT OUTER JOIN sbt_usage USING (db_key) LEFT OUTER JOIN bp_usage USING (db_key); trace1 ('USED_SPACE_CHECK: move phase=' || l_move_phase || '; odb usage=' || l_used_space || '; dbsl usage=' || l_dbsl_used || '; pool usage=' || l_blockpool_usage || '; pieceusage=' || l_sbtpiece_usage || '; chunk_cache=' || l_task_chunk_cache || '; purge_reserve=' || l_task_purge_reserve || '; chunk_size=' || l_chunksize || '; db_key=' || p_db_key); IF p_repair_sl_key IS NOT NULL THEN -- -- -- -- -- -- -- IF l_dbsl_used = 0 THEN UPDATE odb SET used_space = (l_blockpool_usage + l_sbtpiece_usage), allocated_space = (l_blockpool_usage + l_sbtpiece_usage), total_allocation = (l_blockpool_usage + l_sbtpiece_usage) WHERE db_key = p_db_key; ELSE UPDATE dbsl SET dbsl_used_space = (l_blockpool_usage + l_sbtpiece_usage + l_task_chunk_cache + l_task_purge_reserve) WHERE db_key = p_db_key AND sl_key = p_repair_sl_key; END IF; ELSIF (NOT DBMS_RA_SCHEDULER.S_REPAIR_ACTIVE) AND ((l_blockpool_usage + l_sbtpiece_usage + l_task_chunk_cache + l_task_purge_reserve) <> (l_used_space + l_dbsl_used)) THEN trace1 ('USED_SPACE_CHECK: Check failed...'); DBMS_RA_SCHEDULER.LOG_ERROR ( p_errno => DBMS_RA_SCHEDULER.E_BAD_ODB_USAGE_NUM, p_param1 => l_used_space+l_dbsl_used, p_param2 => DBMS_RA_INT.DBKEY2NAME(p_db_key), -- p_param3 => 'sl_key=' || TO_CHAR(p_sl_key), p_param4 => (l_blockpool_usage + l_sbtpiece_usage + l_task_chunk_cache + l_task_purge_reserve), p_component => 'CHECK_FILES', p_severity => DBMS_RA_SCHEDULER.SEVERITY_ERROR, p_db_key => p_db_key); END IF; trace1 ('USED_SPACE_CHECK: total_allocation is ' || l_total || '; allocation=' || l_allocated || '; dbsl_used=' || l_dbsl_used || '; db_key=' || p_db_key); IF (l_total <> (l_allocated + l_dbsl_used)) AND (NOT DBMS_RA_SCHEDULER.S_REPAIR_ACTIVE) THEN DBMS_RA_SCHEDULER.LOG_ERROR ( p_errno => DBMS_RA_SCHEDULER.E_BAD_TOTAL_ALLOC_NUM, p_param1 => l_total, p_param2 => DBMS_RA_INT.DBKEY2NAME(p_db_key), p_param3 => l_allocated+l_dbsl_used, p_component => 'CHECK_FILES', p_severity => DBMS_RA_SCHEDULER.SEVERITY_ERROR, p_db_key => p_db_key); END IF; END IF; EXCEPTION WHEN DBMS_RA_SCHEDULER.E_SNAPSHOT_TOO_OLD OR DBMS_RA_SCHEDULER.E_CONSISTENT_READ THEN save_error; IF p_check_files THEN RAISE; ELSE -- trace1 ('USED_SPACE_CHECK: Ignoring check due to -- ' || SQLERRM); clear_error; END IF; END used_space_check; -- -- -- -- -- -- -- -- -- -- -- PROCEDURE lock_db ( p_db_key IN NUMBER) IS l_return NUMBER; BEGIN tracex ('LOCK_DB for db_key ' || p_db_key); IF (s_db_level <> 0) OR (s_sl_level <> 0) THEN tracex('LOCK_DB: Bad locking protocol: ' || s_db_level || ',' || s_sl_level); -- -- -- -- ELSE SYS.KBRSI_ICD.RSDBLOCK (p_db_key); s_db_level := s_db_level + 1; END IF; EXCEPTION WHEN OTHERS THEN save_error; tracex ('LOCK_DB EXCEPTION: ' || SQLERRM); RAISE; END lock_db; -- -- -- -- -- -- -- -- -- PROCEDURE unlock_db ( p_db_key IN NUMBER) IS l_return NUMBER; BEGIN tracex ('UNLOCK_DB for db_key ' || p_db_key); IF (s_sl_level <> 0) THEN tracex('UNLOCK_DB: Bad locking protocol: ' || s_db_level || ',' || s_sl_level); -- -- -- -- ELSIF (s_db_level > 0) THEN SYS.KBRSI_ICD.RSDBUNLOCK (p_db_key); s_db_level := s_db_level - 1; END IF; END unlock_db; -- -- -- -- -- -- -- -- -- -- -- PROCEDURE lock_sl (p_sl_key IN NUMBER) IS l_return NUMBER; BEGIN tracex ('LOCK_SL for sl_key ' || p_sl_key); IF (s_sl_level <> 0) THEN tracex('LOCK_SL: Bad locking protocol: ' || s_db_level || ',' || s_sl_level); -- -- -- -- ELSE SYS.KBRSI_ICD.RSSLLOCK (p_sl_key); s_sl_level := s_sl_level + 1; END IF; EXCEPTION WHEN OTHERS THEN save_error; tracex ('LOCK_SL EXCEPTION: ' || SQLERRM); RAISE; END lock_sl; -- -- -- -- -- -- -- -- -- PROCEDURE unlock_sl ( p_sl_key IN NUMBER) IS l_return NUMBER; BEGIN tracex ('UNLOCK_SL for sl_key ' || p_sl_key); IF (s_sl_level > 0) THEN SYS.KBRSI_ICD.RSSLUNLOCK (p_sl_key); s_sl_level := s_sl_level - 1; END IF; END unlock_sl; -- -- -- -- -- -- -- -- -- -- -- FUNCTION print (p_value IN BOOLEAN) RETURN VARCHAR2 IS BEGIN IF p_value THEN RETURN 'TRUE'; ELSIF p_value IS NULL THEN RETURN 'NULL'; ELSE RETURN 'FALSE'; END IF; END print; FUNCTION print (p_value IN NUMBER) RETURN VARCHAR2 IS BEGIN RETURN NVL(TO_CHAR(p_value),'NULL'); END print; FUNCTION print (p_value IN DSINTERVAL_UNCONSTRAINED) RETURN VARCHAR2 IS BEGIN RETURN NVL(TO_CHAR(p_value),'NULL'); END print; FUNCTION print (p_value IN VARCHAR2) RETURN VARCHAR2 IS BEGIN RETURN NVL(p_value,'***NULL***'); END print; -- -- -- -- -- -- -- -- -- -- PROCEDURE tracex (message IN VARCHAR2) IS l_pos NUMBER := 1; BEGIN -- -- -- IF NOT s_init_done THEN DBMS_RA_SCHEDULER.LOAD_CONFIG; s_init_done := TRUE; END IF; -- -- -- LOOP sys.kbrsi_icd.rsTrace('RSSM:' || SUBSTR(message, l_pos, 1000)); l_pos := l_pos+1000; EXIT WHEN l_pos > LENGTH(message); END LOOP; END tracex; -- -- -- -- -- -- -- -- PROCEDURE trace1 (message IN VARCHAR2) IS l_pos NUMBER := 1; BEGIN -- -- -- IF NOT s_init_done THEN DBMS_RA_SCHEDULER.LOAD_CONFIG; s_init_done := TRUE; END IF; -- -- -- IF s_tracing_on THEN LOOP sys.kbrsi_icd.rsTrace('RSSM:' || SUBSTR(message, l_pos, 1000)); l_pos := l_pos+1000; EXIT WHEN l_pos > LENGTH(message); END LOOP; END IF; END trace1; -- -- PROCEDURE setTracing(p_trc_on IN NUMBER, p_perf_on IN NUMBER DEFAULT 0, p_stall_on IN NUMBER DEFAULT 0, p_safe_mode IN NUMBER DEFAULT 0) IS BEGIN s_tracing_on := (p_trc_on > 0); s_perf_on := (p_perf_on > 0); s_stall_on := (p_stall_on > 0); s_safe_mode := (p_safe_mode > 0); END setTracing; END dbms_ra_storage; >>> define prvtrs_plb <<< CREATE OR REPLACE PACKAGE BODY dbms_ra IS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- CCCHK_ALL_APIS CONSTANT NUMBER := 1; CCCHK_CREDEL_REP_SERVER CONSTANT NUMBER := 2; -- -- -- -- AM_SEC_OPERATION_GRANT CONSTANT NUMBER := 1; AM_SEC_OPERATION_REVOKE CONSTANT NUMBER := 2; -- AM_SEC_PRIVTYPE_BACKUP CONSTANT NUMBER := 10; AM_SEC_PRIVTYPE_RECONCILE CONSTANT NUMBER := 11; AM_SEC_PRIVTYPE_ALL CONSTANT NUMBER := 12; -- AM_SEC_ACCESSTYPE_READ CONSTANT NUMBER := 20; AM_SEC_ACCESSTYPE_WRITE CONSTANT NUMBER := 21; AM_SEC_ACCESSTYPE_ALL CONSTANT NUMBER := 22; -- ONEMEG CONSTANT NUMBER := 1024 * 1024; /* Just a handy reference */ FOURMEG CONSTANT NUMBER := 4 * ONEMEG; /* Default _def_min_alloc */ MIN_CG_FILE_SIZE CONSTANT NUMBER := 40 * ONEMEG; /* Hard code 40 meg min */ MIN_CG_FILE_SIZE_NUMSTR CONSTANT VARCHAR2(3) := '40M';/* used in error msg */ -- MIN_RESERVATION CONSTANT NUMBER := 10 * ONEMEG; -- TYPE destRecord_t IS RECORD ( name_dest VARCHAR2(4000), size_dest NUMBER ); TYPE destList_t IS TABLE OF destRecord_t INDEX BY BINARY_INTEGER; -- FUNCTION item_not_found (p_obj_name IN VARCHAR2, p_obj_type IN VARCHAR2 ) RETURN VARCHAR2; FUNCTION numstring_to_num (p_numstr IN VARCHAR2, p_allow0 IN BOOLEAN DEFAULT FALSE ) RETURN NUMBER; FUNCTION add_repository(catalog_user_name VARCHAR2, new_server_key NUMBER, am_server_name VARCHAR2, wallet_alias VARCHAR2, wallet_path VARCHAR2, proxy_url VARCHAR2 DEFAULT NULL, proxy_port NUMBER DEFAULT NULL, http_timeout NUMBER DEFAULT NULL ) RETURN NUMBER; PROCEDURE grant_network_acl_ace(catalog_user_name VARCHAR2, wallet_alias VARCHAR2, wallet_path VARCHAR2); PROCEDURE revoke_network_acl_ace(catalog_user_name IN VARCHAR2, wallet_alias IN VARCHAR2, wallet_path IN VARCHAR2); PROCEDURE delete_replication_server_int(p_rep_server_name IN VARCHAR2, p_force IN BOOLEAN DEFAULT FALSE); PROCEDURE remove_rep_from_prot_int (p_replication_server_name IN VARCHAR2, p_protection_policy_name IN VARCHAR2, do_commit IN BOOLEAN DEFAULT TRUE); PROCEDURE delete_sbt_job_template_int(template_name IN VARCHAR2, do_commit IN BOOLEAN DEFAULT TRUE); PROCEDURE ctrl_c_check(check_what IN NUMBER); FUNCTION is_ba_running RETURN BOOLEAN; PROCEDURE create_containers ( p_slkey IN NUMBER, p_create IN BOOLEAN, p_reformat IN BOOLEAN DEFAULT FALSE); FUNCTION parse_dests (p_storage_dests IN VARCHAR2, p_storage_for_poll IN BOOLEAN DEFAULT FALSE ) RETURN destList_t; PROCEDURE lock_api (p_op_type IN NUMBER DEFAULT NULL, p_routine IN VARCHAR2 DEFAULT NULL, p_dbgnotes IN VARCHAR2 DEFAULT NULL); PROCEDURE unlock_api (p_routine IN VARCHAR2 DEFAULT NULL, p_dbgnotes IN VARCHAR2 DEFAULT NULL, p_the_num IN NUMBER DEFAULT 0, p_results IN BOOLEAN DEFAULT TRUE, p_docommit IN BOOLEAN DEFAULT FALSE); PROCEDURE upsert_config_parm(p_name VARCHAR2, p_value VARCHAR2); FUNCTION is_rep_server(name IN VARCHAR2) RETURN BOOLEAN; FUNCTION is_sysgen_obj(name IN VARCHAR2) RETURN BOOLEAN; PROCEDURE remove_rep_tasks(p_db_key IN NUMBER, p_template in VARCHAR2); PROCEDURE delete_replicated_backups(p_db_key IN NUMBER, p_sbt_lib_key IN NUMBER, p_force_del IN BOOLEAN DEFAULT FALSE); PROCEDURE revoke_db_access_int (p_username IN VARCHAR2, p_db_unique_name IN VARCHAR2); -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION numstring_to_num (p_numstr IN VARCHAR2, p_allow0 IN BOOLEAN DEFAULT FALSE ) RETURN NUMBER IS OneK NUMBER := 1024; -- Kilobyte OneM NUMBER := OneK * 1024; -- Megabyte OneG NUMBER := OneM * 1024; -- Gigabyte OneT NUMBER := OneG * 1024; -- Terabyte OneP NUMBER := OneT * 1024; -- Petabyte OneE NUMBER := OneP * 1024; -- Exabyte OneZ NUMBER := OneE * 1024; -- Zetabyte OneY NUMBER := OneZ * 1024; -- Yottabyte sizeunit CHAR; newsize NUMBER; space NUMBER; -- Return value in bytes BEGIN -- -- -- IF (p_numstr IS NULL) THEN RAISE INVALID_SIZENUMBER; END IF; sizeunit := upper(substr(p_numstr, -1, 1)); newsize := to_number(substr(p_numstr, 1, length(p_numstr) - 1)); CASE sizeunit WHEN 'K' THEN space := newsize * OneK; WHEN 'M' THEN space := newsize * OneM; WHEN 'G' THEN space := newsize * OneG; WHEN 'T' THEN space := newsize * OneT; WHEN 'P' THEN space := newsize * oneP; WHEN 'E' THEN space := newsize * oneE; WHEN 'Z' THEN space := newsize * OneZ; WHEN 'Y' THEN space := newsize * OneY; ELSE -- space := to_number(p_numstr); END CASE; IF space=0 AND NOT p_allow0 THEN RAISE INVALID_SIZENUMBER; END IF; RETURN space; END numstring_to_num; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION item_not_found (p_obj_name IN VARCHAR2, p_obj_type IN VARCHAR2) RETURN VARCHAR2 IS BEGIN RETURN dbms_ra_int.item_not_foundi(p_obj_name => p_obj_name, p_obj_type => p_obj_type); END item_not_found; -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE am_trace (p_message IN VARCHAR2) IS BEGIN -- dbms_ra_int.am_tracei(p_message); END am_trace; -- -- -- -- -- -- -- -- -- -- FUNCTION pparm (p_value IN VARCHAR2) RETURN VARCHAR2 IS BEGIN RETURN dbms_ra_int.pparmi(p_value); END pparm; FUNCTION pparm (p_value IN NUMBER) RETURN VARCHAR2 IS BEGIN RETURN dbms_ra_int.pparmi(p_value); END pparm; FUNCTION pparm (p_value IN BOOLEAN) RETURN VARCHAR2 IS BEGIN RETURN dbms_ra_int.pparmi(p_value); END pparm; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION b_p (p_varname IN VARCHAR2, p_strval IN VARCHAR2 DEFAULT NULL, p_first IN BOOLEAN DEFAULT FALSE, p_last IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2 IS BEGIN RETURN dbms_ra_int.b_p_i(p_varname => p_varname, p_strval => p_strval, p_first => p_first, p_last => p_last); END b_p; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION b_p (p_varname IN VARCHAR2, p_numval IN NUMBER DEFAULT NULL, p_first IN BOOLEAN DEFAULT FALSE, p_last IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2 IS BEGIN RETURN dbms_ra_int.b_p_i(p_varname => p_varname, p_numval => p_numval, p_first => p_first, p_last => p_last); END b_p; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION b_p (p_varname IN VARCHAR2, p_boolval IN BOOLEAN DEFAULT NULL, p_first IN BOOLEAN DEFAULT FALSE, p_last IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2 IS BEGIN RETURN dbms_ra_int.b_p_i(p_varname => p_varname, p_boolval => p_boolval, p_first => p_first, p_last => p_last); END b_p; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION b_p (p_varname IN VARCHAR2, p_intval IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, p_first IN BOOLEAN DEFAULT FALSE, p_last IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2 IS BEGIN RETURN dbms_ra_int.b_p_i(p_varname => p_varname, p_intval => p_intval, p_first => p_first, p_last => p_last); END b_p; -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE upsert_config_parm(p_name VARCHAR2, p_value VARCHAR2) IS BEGIN -- IF p_name = '_def_sl_size' THEN sys.dbms_sys_error.raise_system_error(E_INTERNAL_ERROR_NUM, '_def_sl_size is no longer supported', FALSE); END IF; MERGE INTO config USING (SELECT p_name sq_name, p_value sq_value FROM dual) ON (sq_name=name) WHEN matched THEN UPDATE SET value=sq_value WHEN NOT matched THEN INSERT VALUES(sq_name, sq_value); -- -- dbms_ra_scheduler.load_config; COMMIT; END; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE lock_api (p_op_type IN NUMBER DEFAULT NULL, p_routine IN VARCHAR2 DEFAULT NULL, p_dbgnotes IN VARCHAR2 DEFAULT NULL) IS BEGIN dbms_ra_int.lock_api_int(p_op_type, p_routine, p_dbgnotes); END lock_api; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE unlock_api (p_routine IN VARCHAR2 DEFAULT NULL, p_dbgnotes IN VARCHAR2 DEFAULT NULL, p_the_num IN NUMBER DEFAULT 0, p_results IN BOOLEAN DEFAULT TRUE, p_docommit IN BOOLEAN DEFAULT FALSE) IS BEGIN dbms_ra_int.unlock_api_int(p_routine, p_dbgnotes, p_the_num, p_results, p_docommit); END unlock_api; -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE config(p_name VARCHAR2, p_value VARCHAR2) IS l_the NUMBER; KBRSTRC_TO_DISK CONSTANT NUMBER := 2; TRACING_ACTIVE_NUM CONSTANT NUMBER := -64748; l_session_rowids dbms_sql.urowid_table; l_name VARCHAR2(100) := LOWER(p_name); BEGIN l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_CONFIG, param => 'config' || b_p('p_name', p_name, p_first=>TRUE ) || b_p('p_value', p_value, p_last=>TRUE)); -- BEGIN CASE WHEN l_name = 'network_chunksize' THEN IF TO_NUMBER (p_value) < 1024*1024 THEN RAISE INVALID_VAL; END IF; WHEN l_name IN ('optimize_chunks_days' , 'validate_db_days' , 'check_files_days' , 'crosscheck_db_days') THEN IF TO_NUMBER (p_value) < 1/24/60/60 THEN RAISE INVALID_VAL; END IF; WHEN l_name = 'percent_late_for_warning' THEN IF TO_NUMBER (p_value) < 0 THEN RAISE INVALID_VAL; END IF; ELSE NULL; END CASE; EXCEPTION WHEN INVALID_VAL THEN rollback; sys.dbms_sys_error.raise_system_error(INVALID_VAL_NUM, 'value', FALSE); WHEN OTHERS THEN rollback; sys.dbms_sys_error.raise_system_error(INVALID_VAL_NUM, 'value', TRUE); END; -- upsert_config_parm(l_name, UPPER(p_value)); IF l_name = '_debug_flags' THEN sys.kbrsi_icd.rsSetDebugFlags(p_value); IF BITAND(NVL(TO_NUMBER(p_value),0), KBRSTRC_TO_DISK) <> 0 THEN dbms_ra_scheduler.log_error ( p_errno => TRACING_ACTIVE_NUM, p_param1 => '_debug_flags', p_component => 'API', p_severity => dbms_ra_scheduler.severity_warning, p_param_char => '_debug_flags'); ELSE dbms_ra_scheduler.fix_error ( p_error_num => TRACING_ACTIVE_NUM, p_param_char => '_debug_flags'); END IF; END IF; IF l_name = '_debug_when' THEN IF TO_NUMBER(p_value) <> 0 THEN dbms_ra_scheduler.log_error ( p_errno => TRACING_ACTIVE_NUM, p_param1 => '_debug_when', p_component => 'API', p_severity => dbms_ra_scheduler.severity_warning, p_param_char => '_debug_when'); ELSE dbms_ra_scheduler.fix_error ( p_error_num => TRACING_ACTIVE_NUM, p_param_char => '_debug_when'); END IF; END IF; IF l_name = '_stall_when' AND UPPER(p_value) = 'OFF' THEN dbms_ra_scheduler.release_blocked_tasks( dbms_ra_scheduler.STALL_PSEUDO_TASK); END IF; -- -- SELECT ROWID BULK COLLECT INTO l_session_rowids FROM sessions ORDER BY ROWID; FORALL i IN l_session_rowids.FIRST..l_session_rowids.LAST UPDATE sessions SET last_config_change = SYSTIMESTAMP WHERE ROWID = l_session_rowids(i); COMMIT; -- dbms_ra_scheduler.enqueue_timer_reload_config; dbms_ra_scheduler.update_task_history_entry(task_id => l_the, param_char2 => 'SUCCESS', do_commit => TRUE); EXCEPTION WHEN OTHERS THEN rollback; dbms_ra_scheduler.update_task_history_entry(task_id => l_the, param_char2 => 'FAIL', do_commit => TRUE); RAISE; END; -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE reset_error (incident# NUMBER) IS BEGIN dbms_ra_scheduler.reset_error(p_incident# => incident#); END; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE move_commit (p_slkey IN NUMBER, p_protkey IN NUMBER DEFAULT NULL, p_dbkey IN NUMBER DEFAULT NULL) IS l_task_rec task%ROWTYPE; l_interrupt NUMBER; BEGIN -- SELECT COUNT(*) INTO l_interrupt FROM odb d, prot p WHERE p.prot_key = d.future_prot_key AND ((p.sl_key = p_slkey AND p_protkey IS NULL AND p_dbkey IS NULL) OR p.prot_key = p_protkey OR d.db_key = p_dbkey) AND d.sl_key <> p.sl_key AND d.move_phase > dbms_ra_scheduler.MOVE_PHASE_PEND; -- -- -- IF l_interrupt > 0 OR p_protkey IS NOT NULL OR p_dbkey IS NOT NULL THEN l_task_rec.task_type := dbms_ra_scheduler.TASK_MOVE_ALL_DB; l_task_rec.sl_key := p_slkey; l_task_rec.flags := 0; dbms_ra_scheduler.new_task(l_task_rec, FALSE); END IF; -- IF l_interrupt > 0 THEN dbms_ra_scheduler.interrupt_tasks( p_interrupt => dbms_ra_scheduler.INTERRUPT_FOR_MOVE , p_task_id => l_task_rec.task_id ); ELSE COMMIT; END IF; END; -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE repair_storage_location ( storage_location_name IN VARCHAR2, repair_type IN VARCHAR2) IS l_the NUMBER; l_count NUMBER; l_storage_location_name DBMS_ID; l_sl_key NUMBER; l_state sl.sl_state%TYPE; l_return BINARY_INTEGER; l_amrvkey BINARY_INTEGER; no_container_group EXCEPTION; PRAGMA EXCEPTION_INIT(no_container_group, -45279); BEGIN l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_REPAIR_SL, param => 'repair_storage_location' || b_p('storage_location_name',storage_location_name, p_first=>TRUE) || b_p('repair_type', repair_type, p_last=>TRUE)); -- -- -- SELECT COUNT(*) INTO l_count FROM config WHERE config.name = '_recovery_appliance_state' AND config.value = 'ON'; IF l_count <> 0 THEN sys.dbms_sys_error.raise_system_error(E_INTERNAL_ERROR_NUM, 'recovery appliance is running', FALSE); END IF; dbms_ra_int.canonicalize(storage_location_name, l_storage_location_name, 128); BEGIN SELECT sl_key, NVL(sl_state,' ') INTO l_sl_key, l_state FROM sl WHERE sl_name = l_storage_location_name; EXCEPTION WHEN NO_DATA_FOUND THEN am_trace ('repair_storage_location: ' || item_not_found( l_storage_location_name, 'storage location')); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, l_storage_location_name, 'storage location', FALSE); END; CASE UPPER(repair_type) -- WHEN 'IGNORE_MISSING_DATA' THEN IF l_state = 'E' THEN UPDATE sl SET sl_state = 'I' WHERE sl_key = l_sl_key; COMMIT; ELSE am_trace ('repair_storage_location: bad repair value'); sys.dbms_sys_error.raise_system_error(INVALID_VAL_NUM, 'IGNORE_MISSING_DATA', FALSE); END IF; -- WHEN 'REFORMAT' THEN -- IF l_state != 'F' THEN am_trace ('repair_storage_location: bad repair value'); sys.dbms_sys_error.raise_system_error(INVALID_VAL_NUM, 'REFORMAT', FALSE); END IF; -- -- BEGIN am_trace ('repair_storage_location: drop container'); sys.kbrsi_icd.drop_container_group(gname => l_storage_location_name, force => 1, keep_container => 0); EXCEPTION WHEN no_container_group THEN am_trace ('repair_storage_location ignored: ' || SQLERRM); END; -- FOR i IN (SELECT dest FROM storage_dests WHERE sl_key = l_sl_key) LOOP am_trace ('repair_storage_location: remove container -- ' || i.dest); IF sys.kbrsi_icd.remove_containers (pathlist => i.dest, gname => l_storage_location_name, amrvkey => l_amrvkey) = 0 THEN sys.dbms_sys_error.raise_system_error( dbms_ra_scheduler.e_sl_rebuild_fatal_num, l_storage_location_name, l_amrvkey); END IF; END LOOP; -- -- UPDATE storage_dests SET cursize = 0, needsize = 0 WHERE sl_key = l_sl_key; -- am_trace ('repair_storage_location: recreate container group'); create_containers(l_sl_key, TRUE, TRUE); -- UPDATE sl SET sl_state = NULL WHERE sl_key = l_sl_key; COMMIT; ELSE sys.dbms_sys_error.raise_system_error(INVALID_VAL_NUM, repair_type, FALSE); END CASE; dbms_ra_scheduler.update_task_history_entry(task_id => l_the, param_char2 => 'SUCCESS', do_commit => TRUE); EXCEPTION WHEN OTHERS THEN dbms_ra_scheduler.update_task_history_entry(task_id => l_the, param_char2 => 'FAIL', do_commit => TRUE); RAISE; END; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION estimate_space ( db_unique_name IN VARCHAR2, target_window IN DSINTERVAL_UNCONSTRAINED) RETURN NUMBER IS l_db_unique_name node.db_unique_name%TYPE := db_unique_name; l_unregistered_db NUMBER; l_db_key NUMBER; l_total_allocation NUMBER; l_footprint NUMBER; l_current_window NUMBER; l_bdf1count NUMBER; l_min_alloc NUMBER; l_target_days NUMBER; l_ratio NUMBER; l_space NUMBER; BEGIN SELECT COUNT(*) INTO l_unregistered_db FROM unreg_database WHERE db_unique_name = l_db_unique_name; -- IF l_unregistered_db > 0 THEN RETURN NULL; END IF; -- -- -- BEGIN SELECT db_key, total_allocation, sl_min_alloc, footprint, odbsysdate-recwindowstart, bdf1count INTO l_db_key, l_total_allocation, l_min_alloc, l_footprint, l_current_window, l_bdf1count FROM (SELECT db_key , CAST((SYSTIMESTAMP AT TIME ZONE TO_CHAR(db_timezone)) AS DATE) odbsysdate FROM node WHERE db_unique_name = l_db_unique_name AND ROWNUM = 1) JOIN odb USING (db_key) LEFT OUTER JOIN rai_recovery_window_space USING (db_key) WHERE db_unique_name = l_db_unique_name -- AND db_state IS NULL; EXCEPTION WHEN no_data_found THEN am_trace ('estimate_space: ' || item_not_found(db_unique_name, 'db unique name')); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, l_db_unique_name, 'db unique name', FALSE); END; -- -- -- -- IF target_window IS NULL OR l_footprint IS NULL OR NVL(l_current_window, 0) <= 0 OR NVL(l_bdf1count, 0) < 3 THEN RETURN NULL; END IF; -- -- -- -- l_target_days := TO_NUMBER(EXTRACT(DAY FROM target_window)) + TO_NUMBER(EXTRACT(HOUR FROM target_window))/(24) + TO_NUMBER(EXTRACT(MINUTE FROM target_window))/(24*60); -- l_ratio := l_target_days / l_current_window; -- -- -- l_space := (l_total_allocation - l_footprint) * l_ratio; l_space := l_space + l_footprint; -- l_space := CEIL(l_space/l_min_alloc) * l_min_alloc; -- l_space := l_space/(1024*1024*1024); RETURN l_space; END; -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE dump (do_dpdump BOOLEAN DEFAULT FALSE) IS BEGIN dbms_ra_dump.dumper('API', FALSE, do_dpdump); END; -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION canStartAVMServices RETURN BOOLEAN IS l_is_avm VARCHAR2(16); BEGIN SELECT UPPER(TRIM(' ' FROM NVL(is_avm,'FALSE'))) INTO l_is_avm FROM XMLTable('/ORACLE_CLUSTER/PAGE0' PASSING XMLTYPE( BFILENAME('DBM_XMLDIR', 'databasemachine.xml') , NLS_CHARSET_ID('AL32UTF8') ) COLUMNS is_avm VARCHAR2(32) PATH 'BACKUP_APPLIANCE' ); RETURN (l_is_avm = 'TRUE'); EXCEPTION WHEN OTHERS THEN RETURN FALSE; END canStartAVMServices; -- -- -- -- -- -- PROCEDURE startup IS BEGIN -- -- -- -- -- dbms_ra.startup_recovery_appliance; END startup; PROCEDURE startup_recovery_appliance IS l_the NUMBER; BEGIN -- sys.kbrsi_icd.ba_enabled; IF dbms_ra.canStartAVMServices = FALSE THEN sys.dbms_sys_error.raise_system_error(NOT_RA_NUM); END IF; l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_STARTUP, param => 'startup_recovery_appliance()'); dbms_ra_scheduler.init (p_repair => TRUE); dbms_ra_scheduler.update_task_history_entry(task_id => l_the, param_char2 => 'SUCCESS', do_commit => TRUE); EXCEPTION WHEN OTHERS THEN dbms_ra_scheduler.update_task_history_entry(task_id => l_the, param_char2 => 'FAIL', do_commit => TRUE); RAISE; END startup_recovery_appliance; -- -- -- -- -- -- -- PROCEDURE shutdown IS BEGIN -- -- -- -- -- dbms_ra.shutdown_recovery_appliance; END shutdown; PROCEDURE shutdown_recovery_appliance IS l_the NUMBER; l_jobname sessions.job_name%type; l_action VARCHAR2(200); l_value VARCHAR2(10); BEGIN -- dbms_ra_scheduler.assert_owner; l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_SHUTDOWN, param => 'shutdown_recovery_appliance()'); dbms_ra_scheduler.log_error( p_errno => dbms_ra_scheduler.e_shutting_down_num, P_keep_stack => FALSE, p_component => 'SHUTDOWN', p_severity => dbms_ra_scheduler.severity_warning); -- -- -- -- l_jobname := 'RA$SHUTDOWN_' || rai_sq.nextval; l_action := 'dbms_ra_scheduler.stop (p_quiesce_first => TRUE);'; am_trace('shutdown: spawning ' || l_jobname || ' for ' || l_action); dbms_scheduler.create_job( job_name => l_jobname ,job_type => 'plsql_block' ,job_action => l_action ,enabled => TRUE ,auto_drop => TRUE); -- dbms_ra_int.wait_for_job (l_jobname, 1); SELECT DECODE(value, 'OFF', 'SUCCESS', 'FAIL') INTO l_value FROM config WHERE name = '_recovery_appliance_state'; dbms_ra_scheduler.update_task_history_entry(task_id => l_the, param_char2 => l_value, do_commit => TRUE); EXCEPTION WHEN dbms_ra_scheduler.e_bad_user THEN RAISE; WHEN OTHERS THEN dbms_ra_scheduler.update_task_history_entry(task_id => l_the, param_char2 => 'FAIL', do_commit => TRUE); RAISE; END shutdown_recovery_appliance; -- -- -- -- -- -- -- PROCEDURE abort IS BEGIN -- -- -- -- -- dbms_ra.abort_recovery_appliance; END abort; PROCEDURE abort_recovery_appliance IS l_the NUMBER; l_value VARCHAR2(10); BEGIN -- dbms_ra_scheduler.assert_owner; l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_ABORT, param => 'abort_recovery_appliance()'); dbms_ra_scheduler.log_error( p_errno => dbms_ra_scheduler.e_shutting_down_num, P_keep_stack => FALSE, p_component => 'ABORT', p_severity => dbms_ra_scheduler.severity_warning); dbms_ra_scheduler.stop (p_quiesce_first => FALSE); SELECT DECODE(value, 'OFF', 'SUCCESS', 'FAIL') INTO l_value FROM config WHERE name = '_recovery_appliance_state'; dbms_ra_scheduler.update_task_history_entry(task_id => l_the, param_char2 => l_value, do_commit => TRUE); EXCEPTION WHEN dbms_ra_scheduler.e_bad_user THEN RAISE; WHEN OTHERS THEN dbms_ra_scheduler.update_task_history_entry(task_id => l_the, param_char2 => 'FAIL', do_commit => TRUE); RAISE; END abort_recovery_appliance; -- -- -- -- -- -- PROCEDURE clean_old_uids IS BEGIN delete from prvlg where user_id not in (select user_id from all_users); -- -- END clean_old_uids; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE grant_privilege_int (p_username IN VARCHAR2, p_db_unique_name IN VARCHAR2, p_privilege_type IN VARCHAR2 DEFAULT NULL, p_accesstype IN VARCHAR2 DEFAULT NULL) IS l_read_access BOOLEAN := FALSE; l_write_access BOOLEAN := FALSE; l_backup_op BOOLEAN := FALSE; l_reconcile_op BOOLEAN := FALSE; l_req_prvlg NUMBER := 0; l_db_key NUMBER := NULL; l_unregistered_db NUMBER := 0; l_db_unique_name node.db_unique_name%TYPE := p_db_unique_name; l_user_id NUMBER; BEGIN clean_old_uids; SELECT COUNT (*) INTO l_unregistered_db FROM unreg_database WHERE db_unique_name = p_db_unique_name; -- IF l_unregistered_db = 0 THEN BEGIN SELECT db_key INTO l_db_key FROM node WHERE node.db_unique_name = p_db_unique_name -- -- AND NOT EXISTS (SELECT db_state FROM odb WHERE odb.db_key = node.db_key AND db_state IS NOT NULL); l_db_unique_name := NULL; EXCEPTION WHEN NO_DATA_FOUND THEN RAISE OBJ_NOT_FOUND; END; END IF; -- BEGIN SELECT user_id INTO l_user_id FROM all_users u where u.username = p_username; EXCEPTION WHEN NO_DATA_FOUND THEN am_trace ('grant_privilege: user not found' || p_username); sys.dbms_sys_error.raise_system_error(USER_NOT_FOUND_NUM, p_username, FALSE); END; -- IF (p_privilege_type = 'BACKUP') THEN l_backup_op := TRUE; ELSIF (p_privilege_type = 'RECONCILE') THEN l_reconcile_op := TRUE; ELSIF (p_privilege_type IS NULL) THEN l_backup_op := TRUE; l_reconcile_op := TRUE; ELSE RAISE UNKNOWN_OPERATION_PRVLG; END IF; IF (p_accesstype = 'READ') THEN l_read_access := TRUE; ELSIF (p_accesstype = 'WRITE') THEN l_write_access := TRUE; ELSIF (p_accesstype IS NULL) THEN l_read_access := TRUE; l_write_access := TRUE; ELSE RAISE UNKNOWN_OPERATION_PRVLG; END IF; -- -- IF (l_backup_op) THEN IF (l_read_access) THEN l_req_prvlg := l_req_prvlg + DBMS_RA_INT.BACKUP_READ; END IF; IF (l_write_access) THEN l_req_prvlg := l_req_prvlg + DBMS_RA_INT.BACKUP_WRITE; END IF; END IF; IF (l_reconcile_op) THEN IF (l_read_access) THEN l_req_prvlg := l_req_prvlg + DBMS_RA_INT.RECONCILE_READ; END IF; IF (l_write_access) THEN l_req_prvlg := l_req_prvlg + DBMS_RA_INT.RECONCILE_WRITE; END IF; END IF; -- MERGE INTO prvlg USING dual ON ( user_id = l_user_id AND ((db_key = l_db_key) OR (l_db_key is null AND db_key is null AND db_unique_name = l_db_unique_name) ) ) WHEN MATCHED THEN UPDATE SET type = (l_req_prvlg + type - bitand (l_req_prvlg, type)) WHEN NOT MATCHED THEN INSERT VALUES (l_req_prvlg, l_db_key, l_user_id, l_db_unique_name); COMMIT; EXCEPTION WHEN OBJ_NOT_FOUND THEN am_trace ('grant_privilege: ' || item_not_found(p_db_unique_name, 'db unique name')); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, p_db_unique_name, 'db unique name', FALSE); WHEN OTHERS THEN ROLLBACK; am_trace ('grant_privilege exception:'||p_db_unique_name || ',' || p_username || ',' || p_privilege_type ||',' || p_accesstype || ', err:' || SQLERRM); RAISE; END grant_privilege_int; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE revoke_privilege_int (p_username IN VARCHAR2, p_db_unique_name IN VARCHAR2, p_privilege_type IN VARCHAR2 DEFAULT NULL, p_accesstype IN VARCHAR2 DEFAULT NULL) IS l_read_access BOOLEAN := FALSE; l_write_access BOOLEAN := FALSE; l_backup_op BOOLEAN := FALSE; l_reconcile_op BOOLEAN := FALSE; l_req_prvlg NUMBER := 0; l_has_prvlg NUMBER := 0; l_db_key NUMBER := NULL; l_unregistered_db NUMBER := 0; l_db_unique_name node.db_unique_name%TYPE := p_db_unique_name; l_user_id NUMBER; BEGIN clean_old_uids; SELECT COUNT (*) INTO l_unregistered_db FROM unreg_database WHERE db_unique_name = p_db_unique_name; -- IF l_unregistered_db = 0 THEN BEGIN SELECT db_key INTO l_db_key FROM node WHERE node.db_unique_name = p_db_unique_name -- -- AND NOT EXISTS (SELECT db_state FROM odb WHERE odb.db_key = node.db_key AND db_state IS NOT NULL); l_db_unique_name := NULL; EXCEPTION WHEN NO_DATA_FOUND THEN RAISE OBJ_NOT_FOUND; END; END IF; -- BEGIN SELECT user_id INTO l_user_id FROM all_users u where u.username = p_username; EXCEPTION WHEN NO_DATA_FOUND THEN am_trace ('revoke_privilege: user not found' || p_username); sys.dbms_sys_error.raise_system_error(USER_NOT_FOUND_NUM, p_username, FALSE); END; -- IF (p_privilege_type = 'BACKUP') THEN l_backup_op := TRUE; ELSIF (p_privilege_type = 'RECONCILE') THEN l_reconcile_op := TRUE; ELSIF (p_privilege_type IS NULL) THEN l_backup_op := TRUE; l_reconcile_op := TRUE; ELSE RAISE UNKNOWN_OPERATION_PRVLG; END IF; IF (p_accesstype = 'READ') THEN l_read_access := TRUE; ELSIF (p_accesstype = 'WRITE') THEN l_write_access := TRUE; ELSIF (p_accesstype IS NULL) THEN l_read_access := TRUE; l_write_access := TRUE; ELSE RAISE UNKNOWN_OPERATION_PRVLG; END IF; -- IF (l_backup_op) THEN IF (l_read_access) THEN l_req_prvlg := l_req_prvlg + DBMS_RA_INT.BACKUP_READ; END IF; IF (l_write_access) THEN l_req_prvlg := l_req_prvlg + DBMS_RA_INT.BACKUP_WRITE; END IF; END IF; IF (l_reconcile_op) THEN IF (l_read_access) THEN l_req_prvlg := l_req_prvlg + DBMS_RA_INT.RECONCILE_READ; END IF; IF (l_write_access) THEN l_req_prvlg := l_req_prvlg + DBMS_RA_INT.RECONCILE_WRITE; END IF; END IF; MERGE INTO prvlg USING dual ON ( user_id = l_user_id AND ((db_key = l_db_key) OR (l_db_key is null AND db_key is null AND db_unique_name = l_db_unique_name) ) ) WHEN MATCHED THEN UPDATE SET type = (type - bitand(l_req_prvlg, type)); -- DELETE prvlg WHERE type = 0 AND ( user_id = l_user_id AND ((db_key = l_db_key) OR (l_db_key is null AND db_key is null AND db_unique_name = l_db_unique_name) ) ); COMMIT; EXCEPTION WHEN OBJ_NOT_FOUND THEN am_trace ('revoke_privilege: ' || item_not_found(p_db_unique_name, 'db unique name')); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, p_db_unique_name, 'db unique name', FALSE); WHEN OTHERS THEN ROLLBACK; am_trace ('revoke_privilege exception:' || p_db_unique_name|| ',' || p_username || ',' || p_privilege_type || ',' || p_accesstype || ', err:' || SQLERRM); RAISE; END revoke_privilege_int; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE manage_privilege_int (p_db_unique_name IN VARCHAR2, p_operation IN NUMBER, p_privilege_type IN NUMBER DEFAULT NULL, p_access_type IN NUMBER DEFAULT NULL, p_username IN VARCHAR2 DEFAULT NULL) IS l_privilege_type VARCHAR2(32); l_accesstype VARCHAR2(32); BEGIN -- IF p_privilege_type = AM_SEC_PRIVTYPE_BACKUP THEN l_privilege_type := 'BACKUP'; ELSIF p_privilege_type = AM_SEC_PRIVTYPE_RECONCILE THEN l_privilege_type := 'RECONCILE'; ELSIF p_privilege_type = AM_SEC_PRIVTYPE_ALL THEN l_privilege_type := NULL; ELSIF p_privilege_type IS NULL THEN l_privilege_type := NULL; ELSE RAISE UNKNOWN_MANAGE_PRVLG_PARAM; END IF; -- IF p_access_type = AM_SEC_ACCESSTYPE_READ THEN l_accesstype := 'READ'; ELSIF p_access_type = AM_SEC_ACCESSTYPE_WRITE THEN l_accesstype := 'WRITE'; ELSIF p_access_type = AM_SEC_ACCESSTYPE_ALL THEN l_accesstype := NULL; ELSIF p_access_type IS NULL THEN l_accesstype := NULL; ELSE RAISE UNKNOWN_MANAGE_PRVLG_PARAM; END IF; -- IF p_operation = AM_SEC_OPERATION_GRANT THEN grant_privilege_int(p_username, p_db_unique_name, l_privilege_type, l_accesstype); ELSIF p_operation = AM_SEC_OPERATION_REVOKE THEN revoke_privilege_int(p_username, p_db_unique_name, l_privilege_type, l_accesstype); ELSE RAISE UNKNOWN_MANAGE_PRVLG_PARAM; END IF; EXCEPTION WHEN OTHERS THEN ROLLBACK; am_trace ('manage_privilege exception: '|| p_db_unique_name || ',' || p_username || ',' || p_operation || ',' || p_privilege_type || ',' || p_access_type || ', err:' || SQLERRM); RAISE; END manage_privilege_int; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE fake_sl_sizing (p_diskgroup IN VARCHAR2) IS PRAGMA AUTONOMOUS_TRANSACTION; l_count NUMBER; l_totalspace NUMBER; l_asm_group NUMBER; l_redundancy NUMBER; l_disksize NUMBER; l_sparedisks NUMBER; BEGIN -- SELECT COUNT(*) INTO l_count FROM sl_sizing WHERE disk_group = p_diskgroup; IF l_count <> 0 THEN RETURN; END IF; -- BEGIN SELECT group_number, total_mb * ONEMEG, CASE type WHEN 'NORMAL' THEN 2 WHEN 'HIGH' THEN 3 WHEN 'EXTERN' THEN 1 ELSE 0 END INTO l_asm_group, l_totalspace, l_redundancy FROM sys.v_$asm_diskgroup WHERE name = p_diskgroup; EXCEPTION WHEN no_data_found THEN am_trace('fake_sl_sizing: ' || item_not_found(p_diskgroup, 'storage destination')); RETURN; END; -- BEGIN SELECT MAX(total_mb) * ONEMEG INTO l_disksize FROM sys.v_$asm_disk WHERE group_number = l_asm_group; EXCEPTION WHEN no_data_found THEN am_trace('fake_sl_sizing: ' || item_not_found(p_diskgroup, 'storage destination smallest disk')); RETURN; END; -- SELECT NVL(MAX(TO_NUMBER(value)), 2) INTO l_sparedisks FROM config WHERE name = '_spare_asm_disks'; am_trace('fake_sl_sizing: totalspace=' || TO_CHAR(l_totalspace) || '; redundancy=' || TO_CHAR(l_redundancy) || '; disksize=' || TO_CHAR(l_disksize) || '; sparedisks=' || TO_CHAR(l_sparedisks)); -- -- -- -- -- -- IF l_redundancy > 1 THEN l_totalspace := (l_totalspace - (l_sparedisks * l_disksize)) / l_redundancy; ELSE -- l_totalspace := .85 * l_totalspace; END IF; -- am_trace('fake_sl_sizing: usable totalspace before FLOOR 0=' || TO_CHAR(l_totalspace)); l_totalspace := GREATEST(l_totalspace, 0); am_trace('fake_sl_sizing: usable totalspace=' || TO_CHAR(l_totalspace)); -- INSERT INTO sl_sizing (disk_group, init_ok, sl_space) VALUES (p_diskgroup, 'Y', l_totalspace); COMMIT; END fake_sl_sizing; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE create_containers (p_slkey IN NUMBER, p_create IN BOOLEAN, p_reformat IN BOOLEAN DEFAULT FALSE) IS l_min_alloc NUMBER; l_invalid_val VARCHAR2(128); l_net_chunksize NUMBER; l_cg_name sl.sl_name%TYPE; l_newcg BOOLEAN := FALSE; l_params VARCHAR2(100); l_cont_size NUMBER; l_this_cont_size NUMBER; l_au_size NUMBER := NULL; l_asm_group NUMBER; l_asm_group_name DBMS_ID; l_init_ok VARCHAR2(1); l_max_diskgroup NUMBER; l_used_diskgroup NUMBER; l_freespace NUMBER; l_needsize NUMBER; l_asm_count PLS_INTEGER := 0; l_nonasm_count PLS_INTEGER := 0; l_def_cont_size VARCHAR2(50); l_size NUMBER; l_new_cursize NUMBER; l_newcontainer BOOLEAN := FALSE; TWO_TERABYTE CONSTANT NUMBER := 2*ONEMEG*1024*1024; BEGIN am_trace('create_containers: start'); -- SELECT sl_name, sl_min_alloc INTO l_cg_name, l_min_alloc FROM sl WHERE sl_key = p_slkey; am_trace('create_containers: sl_name: ' || l_cg_name || ', sl_min_alloc: ' || pparm(l_min_alloc)); -- -- -- -- -- SELECT MAX(DECODE(name, 'network_chunksize', TO_NUMBER(value))), MAX(DECODE(name, '_def_contfilesize', value)) INTO l_net_chunksize, l_def_cont_size FROM config WHERE name IN ('network_chunksize', '_def_contfilesize'); am_trace('create_containers: network_chunksize: ' || l_net_chunksize || ', _def_contfilesize: ' || l_def_cont_size); -- -- -- -- FOR i IN (SELECT dest, rowid, cursize, usersize, rownum FROM storage_dests WHERE sl_key = p_slkey) LOOP am_trace('create_containers: verifying destination ' || i.dest); am_trace('create_containers: usersize=' || pparm(i.usersize)); -- -- -- IF SUBSTR(i.dest, 1, 1) = '+' THEN IF l_nonasm_count > 0 THEN RAISE MIXED_STORAGE_TYPES; END IF; l_asm_count := l_asm_count + 1; -- BEGIN SELECT group_number, name, allocation_unit_size INTO l_asm_group, l_asm_group_name, l_au_size FROM sys.v_$asm_diskgroup WHERE '+' || name || '/' = i.dest; EXCEPTION WHEN no_data_found THEN am_trace('create_containers: ' || item_not_found(i.dest, 'storage destination')); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, i.dest, 'storage destination', FALSE); END; -- -- -- fake_sl_sizing (l_asm_group_name); -- BEGIN SELECT init_ok, sl_space INTO l_init_ok, l_max_diskgroup FROM sl_sizing WHERE disk_group = l_asm_group_name; EXCEPTION WHEN NO_DATA_FOUND THEN l_init_ok := 'N'; END; IF l_init_ok = 'N' THEN sys.dbms_sys_error.raise_system_error(DISKGROUP_NOT_USABLE_NUM, i.dest, FALSE); END IF; -- -- SELECT NVL(SUM(fsize),0) INTO l_used_diskgroup FROM sys.amcont$ WHERE fname LIKE i.dest || '%'; -- l_freespace := l_max_diskgroup - l_used_diskgroup; am_trace('create_containers: freespace=' || TO_CHAR(l_freespace)); -- am_trace('create_containers: usable freespace before FLOOR 0=' || TO_CHAR(l_freespace)); l_freespace := GREATEST(l_freespace, 0); am_trace('create_containers: usable freespace=' || TO_CHAR(l_freespace)); -- l_needsize := l_freespace; -- -- IF i.usersize IS NOT NULL THEN -- IF i.usersize < i.cursize THEN -- sys.dbms_sys_error.raise_system_error(DEST_SIZE_TOO_SMALL_NUM, i.usersize, i.dest, i.cursize, FALSE); END IF; IF i.usersize > i.cursize + l_freespace THEN -- sys.dbms_sys_error.raise_system_error(DEST_SIZE_TOO_BIG_NUM, i.usersize, i.dest, i.cursize + l_freespace, FALSE); END IF; -- -- -- -- l_needsize := i.usersize - i.cursize; am_trace('create_containers: granted needsize=' || l_needsize); END IF; -- end ASM storage destination -- -- -- ELSE IF l_asm_count > 0 THEN RAISE MIXED_STORAGE_TYPES; END IF; l_nonasm_count := l_nonasm_count + 1; -- IF i.rownum > 1 THEN RAISE MULTIPLE_NON_ASM; END IF; -- IF i.usersize = NULL THEN l_invalid_val := 'container ' || i.dest || ' size;' || ' a size is required for file-based containers'; RAISE INVALID_VAL; END IF; -- SELECT NVL(value, FOURMEG) INTO l_au_size FROM config WHERE name = '_def_min_alloc'; -- -- IF p_reformat THEN i.cursize := 0; END IF; am_trace('create_containers: i.cursize=' || i.cursize); -- -- -- l_needsize := i.usersize - i.cursize; am_trace('create_containers: granted needsize=' || l_needsize); am_trace('create_containers: min alloc=' || TO_CHAR(l_au_size) || '; usersize=' || TO_CHAR(i.usersize) || '; cursize=' || TO_CHAR(i.cursize) || '; needsize=' || TO_CHAR(l_needsize)); -- -- IF l_needsize < 0 THEN l_invalid_val := 'container ' || i.dest || ' size;' || ' requested size ' || i.usersize || ' is smaller than existing size ' || i.cursize; RAISE INVALID_VAL; END IF; END IF; -- end non-ASM (file-based) storage destination -- -- -- -- -- -- l_min_alloc := NVL(l_min_alloc, l_au_size); am_trace('create_containers: l_min_alloc: ' || pparm(l_min_alloc)); -- IF (l_min_alloc <> l_au_size) THEN sys.dbms_sys_error.raise_system_error(ALLOC_SIZE_DISCREPANCY_NUM, l_cg_name, TO_CHAR(l_min_alloc), i.dest, TO_CHAR(l_au_size), FALSE); END IF; -- -- IF (MOD(l_net_chunksize, l_au_size) <> 0) THEN sys.dbms_sys_error.raise_system_error(NETCS_SIZE_DISCREPANCY_NUM, TO_CHAR(l_net_chunksize), i.dest, TO_CHAR(l_au_size), FALSE); RAISE INVALID_VAL; END IF; -- IF (BITAND(l_au_size, l_au_size-1) <> 0) THEN sys.dbms_sys_error.raise_system_error(ALLOC_SIZE_NOT_PWR_OF_2_NUM, i.dest, TO_CHAR(l_au_size), FALSE); END IF; -- IF (l_au_size < 2*ONEMEG) THEN sys.dbms_sys_error.raise_system_error(ALLOC_SIZE_TOO_SMALL_NUM, i.dest, TO_CHAR(l_au_size), TO_CHAR(2*ONEMEG), FALSE); END IF; -- -- -- am_trace('create_containers: updating ' || i.dest || ' for needsise ' || l_needsize); UPDATE storage_dests SET needsize = l_needsize WHERE rowid = i.rowid; am_trace('create_containers: verified destination ' || i.dest); END LOOP; -- end all storage destination size change calculations -- -- -- -- -- -- -- -- l_cont_size := numstring_to_num(l_def_cont_size); IF l_cont_size > (TWO_TERABYTE - 512) THEN l_cont_size := TWO_TERABYTE - 512; END IF; IF p_create THEN -- UPDATE sl SET sl_cg_name = '/:' || sl_name, sl_min_alloc = l_au_size, sl_space = 1 WHERE sl_key = p_slkey RETURNING sl_name INTO l_cg_name; -- am_trace('create_containers: creating container group ' || l_cg_name); sys.kbrsi_icd.create_container_group(l_cg_name); l_newcg := TRUE; am_trace('create_containers: created container group ' || l_cg_name); END IF; -- -- -- -- -- -- -- -- -- -- -- -- -- COMMIT; -- -- IF dbms_ra_int.is_repair_needed AND NOT p_reformat THEN am_trace('create_containers: repairing, but not reformatting'); RETURN; END IF; -- l_newcontainer := FALSE; FOR i IN (SELECT dest, cursize, needsize, rowid FROM storage_dests WHERE sl_key = p_slkey AND needsize >= MIN_CG_FILE_SIZE) LOOP -- l_size := i.needsize; am_trace('create_containers: creating containers for ' || i.dest || '; unused space is ' || l_size); -- WHILE l_size >= MIN_CG_FILE_SIZE LOOP -- -- -- IF l_size > l_cont_size THEN l_this_cont_size := l_cont_size; ELSE l_this_cont_size := TRUNC(l_size / l_au_size) * l_au_size; END IF; am_trace('create_containers: creating container file of size ' || l_this_cont_size); BEGIN sys.kbrsi_icd.create_container(l_cg_name, l_this_cont_size, i.dest); l_newcontainer := TRUE; EXCEPTION WHEN CREATE_CONTAINER_FAILED THEN am_trace('create_containers: Create error: container ''' || i.dest || ''', SQL error ''' || SQLERRM || ''''); -- -- -- IF l_asm_count > 0 THEN -- l_size := LEAST((l_this_cont_size - (100 * ONEMEG)), ROUND(l_this_cont_size*.9)); CONTINUE; END IF; RAISE; END; am_trace('create_containers: created container file of size ' || l_this_cont_size); l_size := l_size - l_this_cont_size; am_trace('create_containers: remaining size ' || l_size); END LOOP; -- -- -- -- -- l_new_cursize := i.cursize + i.needsize - l_size; UPDATE storage_dests SET cursize = l_new_cursize WHERE rowid = i.rowid; am_trace('create_containers: storage dest: ' || i.dest || ', new cursize: ' || l_new_cursize); END LOOP; -- IF p_create AND NOT l_newcontainer THEN sys.dbms_sys_error.raise_system_error(CREATED_NO_CONTAINERS_NUM, l_cg_name, FALSE); END IF; -- SELECT total_space INTO l_size FROM sys.am$container_group WHERE group_name = l_cg_name; -- -- -- -- -- -- IF NOT p_create THEN dbms_ra_storage.lock_sl(p_slkey); END IF; UPDATE sl SET sl_space = l_size WHERE sl_key = p_slkey; COMMIT; IF NOT p_create THEN dbms_ra_storage.unlock_sl(p_slkey); END IF; am_trace('create_containers: total usable size for ' || l_cg_name || ' is ' || TO_CHAR(l_size)); am_trace('create_containers: end'); EXCEPTION WHEN OTHERS THEN -- dbms_ra_storage.unlock_sl(p_slkey); ROLLBACK; -- IF SQLCODE = MIXED_STORAGE_TYPES_NUM OR SQLCODE = MULTIPLE_NON_ASM_NUM THEN am_trace('create_containers: raising ' || SQLERRM); RAISE; END IF; -- IF p_create AND l_newcg THEN am_trace('create_containers exception: dropping container group ' || l_cg_name); sys.kbrsi_icd.drop_container_group(gname => l_cg_name, force => 1, keep_container => 0); DELETE FROM sl WHERE sl_key = p_slkey; COMMIT; END IF; IF SQLCODE = INVALID_VAL_NUM AND l_invalid_val IS NOT NULL THEN am_trace ('create_containers exception: INVALID_VAL: ' || l_invalid_val); sys.dbms_sys_error.raise_system_error(INVALID_VAL_NUM, l_invalid_val, FALSE); END IF; RAISE; END create_containers; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION parse_dests (p_storage_dests IN VARCHAR2, p_storage_for_poll IN BOOLEAN DEFAULT FALSE ) RETURN destList_t IS i PLS_INTEGER := 0; l_dest_list destList_t; l_dests VARCHAR2(4000); l_dests_len BINARY_INTEGER; l_pos BINARY_INTEGER := 1; l_spec VARCHAR2(4000); l_lparen_col NUMBER; l_rparen_col NUMBER; l_synerr_col NUMBER; l_name VARCHAR2(4000); l_isasm BOOLEAN := FALSE; l_sl_key NUMBER; l_size_spec VARCHAR2(4000); l_size NUMBER; l_dup_name_type VARCHAR2(256) := NULL; l_dup_name VARCHAR2(256) := NULL; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- l_spec_list_pat VARCHAR2(128) := '[^,]*,?'; -- -- -- -- -- -- -- -- -- l_spec_item_pat VARCHAR2(128) := '^([^,()]+)?(\(([^)]*)\))?,?$'; -- -- -- -- -- -- -- l_size_spec_pat VARCHAR2(128) := '^[0-9]+[KkMmGgTtPpEeZzYy]?$'; BEGIN am_trace('parse_dests: p_storage_for_poll: ' || pparm(p_storage_for_poll)); -- IF p_storage_dests IS NULL THEN am_trace('parse_dests: p_storage_dests IS NULL'); RETURN l_dest_list; END IF; -- -- -- -- -- -- -- -- -- -- l_dests := REPLACE(p_storage_dests,' ',''); -- l_dests_len := LENGTH(l_dests); -- WHILE TRUE LOOP -- l_spec := REGEXP_SUBSTR(l_dests,l_spec_list_pat,l_pos,1); -- -- -- EXIT WHEN l_pos > l_dests_len; -- -- l_synerr_col := 0; l_lparen_col := INSTR(l_spec,'('); l_rparen_col := INSTR(l_spec,')'); IF l_lparen_col != 0 AND l_rparen_col = 0 THEN l_synerr_col := l_lparen_col; ELSIF l_lparen_col = 0 AND l_rparen_col != 0 THEN l_synerr_col := l_rparen_col; ELSIF l_lparen_col > l_rparen_col THEN l_synerr_col := l_rparen_col; END IF; IF l_synerr_col > 0 THEN sys.dbms_sys_error.raise_system_error(UNBAL_PAREN_NUM, l_dests, TO_CHAR(l_pos + l_synerr_col - 1), FALSE); END IF; -- -- l_name := REGEXP_SUBSTR(l_spec,l_spec_item_pat,1,1,'',1); IF l_name IS NULL THEN sys.dbms_sys_error.raise_system_error(NO_DEST_NUM, l_dests, TO_CHAR(l_pos), FALSE); END IF; -- l_isasm := SUBSTR(l_name,1,1) = '+'; -- -- -- IF p_storage_for_poll AND l_dest_list.COUNT = 1 THEN sys.dbms_sys_error.raise_system_error(MULTIPLE_POLLING_NUM, l_dests, TO_CHAR(l_pos), FALSE); END IF; -- IF l_isasm AND p_storage_for_poll THEN sys.dbms_sys_error.raise_system_error(ASM_POLLING_NUM, l_dests, TO_CHAR(l_pos), FALSE); END IF; -- IF SUBSTR(l_name, -1, 1) != '/' THEN l_name := l_name || '/'; END IF; -- -- l_size_spec := REGEXP_SUBSTR(l_spec,l_spec_item_pat,1,1,'',3); -- IF l_size_spec IS NOT NULL THEN -- IF p_storage_for_poll THEN sys.dbms_sys_error.raise_system_error(POLLING_SIZE_NUM, l_dests, TO_CHAR(l_pos + l_lparen_col - 1), FALSE); END IF; -- l_size_spec := REGEXP_SUBSTR(l_size_spec,l_size_spec_pat,1,1); IF l_size_spec IS NULL THEN sys.dbms_sys_error.raise_system_error(BAD_STORAGE_SIZE_NUM, l_dests, TO_CHAR(l_pos + l_lparen_col - 1), FALSE); END IF; END IF; -- -- -- -- IF (NOT l_isasm) AND (l_size_spec IS NULL) AND (NOT p_storage_for_poll) THEN sys.dbms_sys_error.raise_system_error(NO_STORAGE_SIZE_NUM, l_dests, TO_CHAR(l_pos), FALSE); END IF; -- l_size := NULL; IF l_size_spec IS NOT NULL THEN BEGIN -- l_size := numstring_to_num(l_size_spec,TRUE); -- IF l_size < MIN_CG_FILE_SIZE THEN sys.dbms_sys_error.raise_system_error(SMALL_CG_FILE_SIZE_NUM, MIN_CG_FILE_SIZE_NUMSTR, l_dests, TO_CHAR(l_pos), FALSE); END IF; EXCEPTION WHEN INVALID_SIZENUMBER THEN -- sys.dbms_sys_error.raise_system_error(BAD_STORAGE_SIZE_NUM, l_dests, TO_CHAR(l_pos + l_lparen_col - 1), FALSE); WHEN OTHERS THEN RAISE; END; END IF; -- i := i + 1; IF l_isasm THEN l_dest_list(i).name_dest := UPPER(l_name); ELSE l_dest_list(i).name_dest := l_name; END IF; l_dest_list(i).size_dest := l_size; am_trace('parse_dests: inserted into dest_list(' || TO_CHAR(i) || '): ' || 'name: ' || l_dest_list(i).name_dest || ', size: ' || TO_CHAR(l_dest_list(i).size_dest)); -- l_pos := l_pos + LENGTH(l_spec); END LOOP; RETURN l_dest_list; END parse_dests; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE create_storage_location_int ( p_storage_name IN VARCHAR2, p_storage_dests IN VARCHAR2, p_storage_for_poll IN BOOLEAN DEFAULT FALSE) IS l_numrows NUMBER; l_dest_list destList_t; l_sl_key NUMBER; l_sl_name sl.sl_name%TYPE; l_dup_name_type VARCHAR2(256) := NULL; l_dup_name VARCHAR2(256) := NULL; BEGIN -- -- SELECT count(*) INTO l_numrows FROM sl WHERE sl.sl_name = p_storage_name; IF l_numrows != 0 THEN l_dup_name_type := 'storage location'; l_dup_name := p_storage_name; RAISE DUP_VAL_ON_INDEX; END IF ; -- IF p_storage_dests IS NULL THEN am_trace ('create_storage_location: required parameter missing:' || ' storage destination'); sys.dbms_sys_error.raise_system_error(MISSING_PARAM_NUM, 'storage destination', FALSE); END IF; -- -- am_trace('create_storage_location: parse_dests'); l_dest_list := parse_dests(p_storage_dests,p_storage_for_poll); am_trace('create_storage_location: parse_dests OK'); -- am_trace('create_storage_location: create SL row'); INSERT INTO sl (sl_key, sl_name, sl_type, sl_space, sl_last_check_files, sl_min_alloc) VALUES (rman_seq.nextval, p_storage_name, BA_STORAGE_DISK, 0, SYSTIMESTAMP, NULL) RETURNING sl_key into l_sl_key; am_trace('create_storage_location: create SL row OK'); -- FOR i IN l_dest_list.FIRST..l_dest_list.LAST LOOP -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- am_trace('create_storage_location: show existing dests'); FOR d IN (SELECT dest FROM storage_dests ORDER BY dest) LOOP am_trace('create_storage_location: existing dest: ' || d.dest); END LOOP; am_trace('create_storage_location: show existing dests OK'); am_trace('create_storage_location: name reuse query'); -- SELECT MIN(sl_name) INTO l_sl_name FROM sl JOIN storage_dests sd USING (sl_key) WHERE sd.dest = SUBSTR(l_dest_list(i).name_dest, 1, LENGTH(sd.dest)) OR l_dest_list(i).name_dest = SUBSTR(sd.dest, 1, LENGTH(l_dest_list(i).name_dest)); am_trace('create_storage_location: name reuse query OK'); am_trace('create_storage_location: signal SHARED_PARAMS?'); IF l_sl_name IS NOT NULL THEN am_trace('create_storage_location: signalling SHARED_PARAMS'); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_SHARED_PARAMS_NUM, l_sl_name); END IF; am_trace('create_storage_location: signal SHARED_PARAMS OK'); am_trace('create_storage_location: trace creating dests'); am_trace('create_storage_location: creating dest ' || l_dest_list(i).name_dest || ', size ' || l_dest_list(i).size_dest); am_trace('create_storage_location: trace creating dests OK'); am_trace('create_storage_location: insert'); INSERT INTO storage_dests (sl_key, dest, needsize, cursize, usersize) VALUES (l_sl_key, l_dest_list(i).name_dest, 0, 0, l_dest_list(i).size_dest); am_trace('create_storage_location: insert complete'); END LOOP; -- -- -- IF NOT p_storage_for_poll THEN am_trace('create_storage_location: calling create_containers'); create_containers(l_sl_key, TRUE); am_trace('create_storage_location: create_containers OK'); END IF; COMMIT; -- dbms_ra_scheduler.enqueue_verify_timer_task; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN ROLLBACK; IF l_dup_name IS NOT NULL THEN -- sys.dbms_sys_error.raise_system_error(DUP_NAME_NUM, l_dup_name, l_dup_name_type, FALSE); ELSE -- RAISE; END IF; -- WHEN -- MISSING_PARAM OR E_SHARED_PARAMS OR -- UNBAL_PAREN OR NO_DEST OR MULTIPLE_POLLING OR ASM_POLLING OR POLLING_SIZE OR BAD_STORAGE_SIZE OR NO_STORAGE_SIZE OR SMALL_CG_FILE_SIZE OR -- CREATE_CONTAINER_FAILED OR MIXED_STORAGE_TYPES OR OBJ_NOT_FOUND OR REDUNDANCY_TYPE_BAD OR DEST_SIZE_TOO_SMALL OR DEST_SIZE_TOO_BIG OR MIXED_STORAGE_TYPES OR MULTIPLE_NON_ASM OR INVALID_VAL OR ALLOC_SIZE_DISCREPANCY OR NETCS_SIZE_DISCREPANCY OR ALLOC_SIZE_NOT_PWR_OF_2 OR ALLOC_SIZE_TOO_SMALL OR CREATED_NO_CONTAINERS THEN ROLLBACK; RAISE; -- WHEN OTHERS THEN ROLLBACK; am_trace ('create_storage_location exception: ' || ' local key: ' || l_sl_key || ' storage_name: ' || p_storage_name || ' storage_dest: ' || p_storage_dests || ' err:' || SQLERRM); RAISE; END create_storage_location_int; -- PROCEDURE create_storage_location ( storage_location_name IN VARCHAR2, storage_location_dests IN VARCHAR2) IS l_the NUMBER; c_storage_location_name sl.sl_name%TYPE; BEGIN lock_api(LOCKAPI_CREATE, 'create_storage_location'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_ADD_SL, param => 'create_storage_location' || b_p('storage_location_name', storage_location_name, p_first=>TRUE) || b_p('storage_location_dests', storage_location_dests, p_last=>TRUE)); dbms_ra_int.canonicalize(storage_location_name,c_storage_location_name, 128); create_storage_location_int (c_storage_location_name, storage_location_dests); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END create_storage_location; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE delete_storage_location_int (p_storage_name IN VARCHAR2) IS l_sl_key NUMBER := NULL; l_sl_cnt NUMBER := NULL; l_cg_name sl.sl_name%TYPE; l_space NUMBER; BEGIN -- BEGIN SELECT sl_key, DECODE(sl_space, 0, NULL, sl_name), sl_space INTO l_sl_key, l_cg_name, l_space FROM sl WHERE sl_name = p_storage_name; EXCEPTION WHEN NO_DATA_FOUND THEN RAISE OBJ_NOT_FOUND; END; dbms_ra_storage.lock_sl(l_sl_key); SELECT count(*) INTO l_sl_cnt FROM prot WHERE prot.sl_key = l_sl_key ; IF l_sl_cnt = 0 THEN -- SELECT count(*) INTO l_sl_cnt FROM dbsl WHERE dbsl.sl_key = l_sl_key ; END IF; IF l_sl_cnt = 0 THEN -- -- -- DELETE FROM error_log WHERE sl_key = l_sl_key; -- DELETE FROM poll WHERE sl_key = l_sl_key; -- IF SQL%ROWCOUNT > 0 THEN COMMIT; dbms_ra_scheduler.enqueue_verify_timer_task; END IF; -- DELETE FROM unreg_database WHERE sl_key = l_sl_key; -- DELETE FROM sl WHERE sl_name = p_storage_name; ELSE am_trace ('delete_storage_location: cannot delete storage location ' || 'that has protection policies or databases or ' || 'polling locations referencing it.' || ' storage_name:' || p_storage_name); RAISE OBJ_IS_REFERENCED; END IF; -- IF (l_cg_name IS NOT NULL) AND (NOT dbms_ra_int.is_repair_needed) THEN sys.kbrsi_icd.drop_container_group(gname => l_cg_name, force => 1, keep_container => 0); END IF; COMMIT; dbms_ra_storage.unlock_sl(l_sl_key); l_sl_key := NULL; EXCEPTION WHEN OBJ_IS_REFERENCED THEN dbms_ra_storage.unlock_sl(l_sl_key); am_trace ('delete_storage_location: item in use' || p_storage_name); sys.dbms_sys_error.raise_system_error(OBJ_IS_REFERENCED_NUM, p_storage_name, 'storage location', FALSE); WHEN OBJ_NOT_FOUND THEN dbms_ra_storage.unlock_sl(l_sl_key); am_trace ('delete_storage_location: ' || item_not_found( p_storage_name, 'storage location')); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, p_storage_name, 'storage location', FALSE); WHEN OTHERS THEN ROLLBACK; am_trace ('delete_storage_location exception:' || ' storage_name:' || p_storage_name || ' err:' || SQLERRM); IF l_sl_key IS NOT NULL THEN dbms_ra_storage.unlock_sl(l_sl_key); l_sl_key := NULL; END IF; RAISE; END delete_storage_location_int; -- PROCEDURE delete_storage_location (storage_location_name IN VARCHAR2) IS l_the NUMBER; c_storage_location_name sl.sl_name%TYPE; BEGIN lock_api(LOCKAPI_DELETE, 'delete_storage_location'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_DEL_SL, param => 'delete_storage_location' || b_p('storage_location_name', storage_location_name, p_first=>TRUE, p_last=>TRUE)); dbms_ra_int.canonicalize(storage_location_name,c_storage_location_name, 128); delete_storage_location_int (c_storage_location_name); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END delete_storage_location; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE update_storage_location_int (p_storage_name IN VARCHAR2, p_storage_dests IN VARCHAR2 DEFAULT NULL) IS l_dest_list destList_t; l_sl_key NUMBER := NULL; l_sl_name sl.sl_name%TYPE; BEGIN -- BEGIN SELECT sl.sl_key INTO l_sl_key FROM sl WHERE sl_name = p_storage_name; EXCEPTION WHEN NO_DATA_FOUND THEN RAISE OBJ_NOT_FOUND; END; -- -- l_dest_list := parse_dests(p_storage_dests => p_storage_dests); -- -- IF l_dest_list.COUNT > 0 THEN FOR i IN l_dest_list.FIRST..l_dest_list.LAST LOOP am_trace('update_storage_location: show existing dests'); FOR d IN (SELECT dest FROM storage_dests ORDER BY dest) LOOP am_trace('update_storage_location: existing dest: ' || d.dest); END LOOP; am_trace('update_storage_location: show existing dests OK'); am_trace('update_storage_location: name reuse query'); -- SELECT MIN(sl_name) INTO l_sl_name FROM sl JOIN storage_dests sd USING (sl_key) WHERE (sd.dest = SUBSTR(l_dest_list(i).name_dest, 1, LENGTH(sd.dest)) OR l_dest_list(i).name_dest = SUBSTR(sd.dest, 1, LENGTH(l_dest_list(i).name_dest))) AND NOT (sd.dest = l_dest_list(i).name_dest AND sl_name = p_storage_name); am_trace('update_storage_location: name reuse query OK'); am_trace('update_storage_location: signal SHARED_PARAMS?'); IF l_sl_name IS NOT NULL THEN am_trace('update_storage_location: signalling SHARED_PARAMS'); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_SHARED_PARAMS_NUM, l_sl_name); END IF; am_trace('update_storage_location: signal SHARED_PARAMS OK'); -- MERGE INTO storage_dests USING dual ON (sl_key = l_sl_key AND dest = l_dest_list(i).name_dest) WHEN MATCHED THEN UPDATE SET usersize = l_dest_list(i).size_dest WHEN NOT MATCHED THEN INSERT (sl_key, dest, needsize, cursize, usersize) VALUES (l_sl_key, l_dest_list(i).name_dest, 0, 0, l_dest_list(i).size_dest); END LOOP; END IF; -- am_trace('update_storage_location: calling create_containers'); create_containers(l_sl_key, FALSE); am_trace('update_storage_location: create_containers OK'); -- dbms_ra_scheduler.fix_error( p_error_num => dbms_ra_scheduler.e_sl_full_num, p_sl_key => l_sl_key); commit; EXCEPTION WHEN OBJ_NOT_FOUND THEN IF l_sl_key IS NULL THEN -- exception happened here am_trace('update_storage_location: ' || item_not_found(p_storage_name,'storage location')); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, p_storage_name, 'storage location', FALSE); ELSE -- dbms_ra_storage.unlock_sl(l_sl_key); l_sl_key := NULL; RAISE; -- exception happened in a callee END IF; -- WHEN -- MISSING_PARAM OR -- UNBAL_PAREN OR NO_DEST OR MULTIPLE_POLLING OR ASM_POLLING OR POLLING_SIZE OR BAD_STORAGE_SIZE OR NO_STORAGE_SIZE OR SMALL_CG_FILE_SIZE OR -- CREATE_CONTAINER_FAILED OR MIXED_STORAGE_TYPES OR REDUNDANCY_TYPE_BAD OR DEST_SIZE_TOO_SMALL OR DEST_SIZE_TOO_BIG OR MIXED_STORAGE_TYPES OR MULTIPLE_NON_ASM OR INVALID_VAL OR ALLOC_SIZE_DISCREPANCY OR NETCS_SIZE_DISCREPANCY OR ALLOC_SIZE_NOT_PWR_OF_2 OR ALLOC_SIZE_TOO_SMALL OR CREATED_NO_CONTAINERS THEN ROLLBACK; -- IF l_sl_key IS NOT NULL THEN dbms_ra_storage.unlock_sl(l_sl_key); l_sl_key := NULL; END IF; RAISE; WHEN OTHERS THEN ROLLBACK; am_trace ('update_storage_location exception: ' || ' storage_name:' || p_storage_name || ' storage_dests:' || p_storage_dests || ' err:' || SQLERRM); RAISE; END update_storage_location_int; -- PROCEDURE update_storage_location ( storage_location_name IN VARCHAR2, storage_location_dests IN VARCHAR2 DEFAULT NULL) IS l_the NUMBER; c_storage_location_name sl.sl_name%TYPE; BEGIN lock_api(LOCKAPI_MODIFY, 'update_storage_location'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_UPD_SL, param => 'update_storage_location' || b_p('storage_location_name', storage_location_name, p_first=>TRUE ) || b_p('storage_location_dests', storage_location_dests , p_last=>TRUE)); dbms_ra_int.canonicalize(storage_location_name,c_storage_location_name, 128); update_storage_location_int (c_storage_location_name, storage_location_dests); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END update_storage_location; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE add_db_int (p_db_unique_name IN VARCHAR2, p_protection_policy_name IN VARCHAR2, p_reserved_space IN VARCHAR2) IS l_prot_key NUMBER; l_db_key NUMBER; l_deleting NUMBER; l_sl_key NUMBER := NULL; l_poll_key NUMBER; l_missing_param VARCHAR2(128); l_space NUMBER; l_cnt NUMBER; l_pending_rep_setup odb.pending_rep_setup%type := NULL; BEGIN -- IF p_db_unique_name IS NULL THEN l_missing_param := 'db_unique_name'; RAISE MISSING_PARAM; END IF; -- BEGIN IF p_protection_policy_name IS NOT NULL THEN SELECT prot_key, prot.sl_key, prot.poll_key INTO l_prot_key, l_sl_key, l_poll_key FROM prot WHERE prot_name = p_protection_policy_name; ELSE l_missing_param := 'protection_policy_name'; RAISE MISSING_PARAM; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN RAISE OBJ_NOT_FOUND; END; -- l_space := numstring_to_num(NVL(p_reserved_space,0)); IF l_space < MIN_RESERVATION THEN am_trace('add_db: reserved_space ' || TO_CHAR(l_space) || ' less than MIN_RESERVATION ' || TO_CHAR(MIN_RESERVATION)); sys.dbms_sys_error.raise_system_error(RSRVD_SPACE_TOO_SMALL_NUM, TO_CHAR(l_space), TO_CHAR(MIN_RESERVATION), FALSE); END IF; -- -- BEGIN SELECT db_key into l_db_key from node WHERE db_unique_name = p_db_unique_name; -- SELECT COUNT(*) INTO l_deleting FROM odb WHERE db_key = l_db_key AND db_state IS NOT NULL; IF l_deleting > 0 THEN sys.dbms_sys_error.raise_system_error(CANT_DELETE_DB_RUNNING_NUM, p_db_unique_name, FALSE); END IF; -- -- SELECT count (*) INTO l_cnt FROM rep_server WHERE prot_key=l_prot_key; IF l_cnt > 0 THEN l_pending_rep_setup := 'Y'; END IF; INSERT INTO odb (db_key, sls_used, total_allocation,sl_key,sl_min_alloc, allocated_space, used_space, cumulative_usage, cumulative_rep_usage, cumulative_sbt_usage, create_time, last_optimize, last_validate, prot_key, future_prot_key, base_reserved_space, reserved_space, recovery_window_goal, not_taped, not_taped_state, pending_rep_setup) (SELECT l_db_key, 1, 0, sl.sl_key, sl.sl_min_alloc, 0, 0, 0, 0, 0, SYSTIMESTAMP, SYSTIMESTAMP, SYSTIMESTAMP, prot.prot_key, prot.prot_key, l_space, l_space, prot.prot_recovery_window_goal, 1, decode(prot.prot_disk_cache, 'YES', 'I', null), l_pending_rep_setup FROM prot, sl WHERE prot_key = l_prot_key AND prot.sl_key = sl.sl_key); EXCEPTION WHEN NO_DATA_FOUND THEN -- INSERT INTO unreg_database (db_unique_name, sl_key, prot_key, reserved_space) VALUES (p_db_unique_name, l_sl_key, l_prot_key, l_space); END; -- IF l_poll_key IS NOT NULL THEN UPDATE poll SET poll_flags = poll_flags - BITAND(poll_flags, DBMS_RA_SCHEDULER.POLL_FLAGS_UNDO_DBID_ERROR) + DBMS_RA_SCHEDULER.POLL_FLAGS_UNDO_DBID_ERROR WHERE poll_key = l_poll_key; END IF; -- dbms_ra_int.verify_reserved_space(l_sl_key, TRUE); -- move_commit(l_sl_key); -- dbms_ra_scheduler.enqueue_verify_timer_task; EXCEPTION WHEN MISSING_PARAM THEN IF l_missing_param IS NOT NULL THEN am_trace ('add_db: required parameter missing' || l_missing_param); sys.dbms_sys_error.raise_system_error(MISSING_PARAM_NUM, l_missing_param, FALSE); ELSE RAISE; END IF; WHEN OBJ_NOT_FOUND THEN ROLLBACK; am_trace ('add_db: ' || item_not_found(p_protection_policy_name, 'protection policy')); sys.dbms_sys_error.raise_system_error (OBJ_NOT_FOUND_NUM, p_protection_policy_name, 'protection policy', FALSE); WHEN DUP_VAL_ON_INDEX THEN ROLLBACK; sys.dbms_sys_error.raise_system_error(DUP_NAME_NUM, p_db_unique_name, 'db unique name', FALSE); WHEN OTHERS THEN ROLLBACK; am_trace ('add_db exception: ' || ' db_unique_name:' || p_db_unique_name || ' policy_name:' || p_protection_policy_name || ' sl_key:' || l_sl_key || ' err:' || SQLERRM); RAISE; END add_db_int; -- PROCEDURE add_db (db_unique_name IN VARCHAR2, protection_policy_name IN VARCHAR2, reserved_space IN VARCHAR2) IS l_the NUMBER; c_protection_policy_name prot.prot_name%TYPE; NUM_CONVERSION_ERROR_NATIVE EXCEPTION; PRAGMA EXCEPTION_INIT ( NUM_CONVERSION_ERROR_NATIVE, -06502 ); BEGIN lock_api(LOCKAPI_CREATE, 'add_db'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_ADD_DB, param => 'add_db' || b_p('db_unique_name', db_unique_name, p_first=>TRUE) || b_p('protection_policy_name', protection_policy_name) || b_p('reserved_space', reserved_space, p_last=>TRUE)); dbms_ra_int.canonicalize(protection_policy_name, c_protection_policy_name, 128); add_db_int (upper(db_unique_name), c_protection_policy_name, reserved_space); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN NUM_CONVERSION_ERROR_NATIVE THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); sys.dbms_sys_error.raise_system_error(NUM_CONVERSION_ERROR_NUM, reserved_space); WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END add_db; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE update_db_int (p_db_unique_name IN VARCHAR2, p_protection_policy_name IN VARCHAR2 DEFAULT NULL, p_reserved_space IN VARCHAR2 DEFAULT NULL, p_db_timezone IN VARCHAR2 DEFAULT NULL, p_incarnations IN VARCHAR2 DEFAULT 'CURRENT') IS l_old_prot_key NUMBER; l_prot_key NUMBER; l_new_rep_srv_cnt NUMBER; l_lib_key NUMBER; l_tmp_lib_key NUMBER; l_db_key NUMBER := NULL; l_old_sl_key NUMBER := NULL; l_sl_key NUMBER := NULL; l_rsvn NUMBER := 0; l_old_rsvn NUMBER; l_move_phase NUMBER := NULL; l_old_poll_key NUMBER; l_poll_key NUMBER; l_old_alloc NUMBER; l_alloc NUMBER; l_recovery_window_goal DSINTERVAL_UNCONSTRAINED; l_obj_type VARCHAR2(128); l_obj_name VARCHAR2(128); l_quota_name VARCHAR2(128); l_unregistered_db NUMBER := 0; l_not_taped_state VARCHAR2(1); l_gcopy VARCHAR2(3) := NULL; -- Guaranteed Copy YES/NO/same l_disk_cache VARCHAR2(3); l_invalid_val VARCHAR2(256); l_rep_srv_name server.rep_server_name%TYPE; l_db_unique_name node.db_unique_name%TYPE; l_template_name sbt_job_template.template_name%TYPE; l_prot_name prot.prot_name%TYPE; l_prot_name_old prot.prot_name%TYPE; l_task_rec task%ROWTYPE; l_all_reconciled BOOLEAN := TRUE; l_success BOOLEAN; l_num_rec NUMBER; l_rep_atr_name sbt_attr_set.attr_name%TYPE; l_cnt NUMBER; -- l_tmz_err EXCEPTION; PRAGMA EXCEPTION_INIT(l_tmz_err, -20244); BEGIN SELECT COUNT(*) INTO l_unregistered_db FROM unreg_database WHERE db_unique_name = p_db_unique_name; IF l_unregistered_db = 0 THEN l_quota_name := NULL; l_obj_type := 'db unique name'; l_obj_name := p_db_unique_name; BEGIN SELECT db_key INTO l_db_key FROM node WHERE db_unique_name = p_db_unique_name -- -- AND NOT EXISTS (SELECT db_state FROM odb WHERE odb.db_key = node.db_key AND db_state IS NOT NULL); EXCEPTION WHEN no_data_found THEN RAISE OBJ_NOT_FOUND; END; SELECT prot_key INTO l_old_prot_key FROM odb WHERE db_key = l_db_key; -- SELECT prot.sl_key, odb.base_reserved_space, odb.move_phase, prot.poll_key, sl_min_alloc, prot.prot_disk_cache, odb.not_taped_state INTO l_old_sl_key, l_rsvn, l_move_phase, l_old_poll_key, l_old_alloc, l_disk_cache, l_not_taped_state FROM odb JOIN prot USING (prot_key) WHERE odb.db_key = l_db_key; ELSE l_quota_name := p_db_unique_name; SELECT prot_key, prot.sl_key, u.reserved_space, prot.poll_key INTO l_old_prot_key, l_old_sl_key, l_rsvn, l_old_poll_key FROM unreg_database u JOIN prot USING (prot_key) WHERE u.db_unique_name = p_db_unique_name AND ROWNUM=1; END IF; -- IF p_protection_policy_name IS NOT NULL THEN -- l_obj_type := 'protection policy'; l_obj_name := p_protection_policy_name; l_prot_name := p_protection_policy_name; BEGIN SELECT prot_key, sl_key, poll_key, prot_recovery_window_goal, prot_disk_cache INTO l_prot_key, l_sl_key, l_poll_key, l_recovery_window_goal, l_disk_cache FROM prot WHERE prot_name = p_protection_policy_name; EXCEPTION WHEN NO_DATA_FOUND THEN RAISE OBJ_NOT_FOUND; END; ELSE SELECT prot_key, prot_name, sl_key, poll_key, prot_recovery_window_goal, prot_disk_cache INTO l_prot_key, l_prot_name, l_sl_key, l_poll_key, l_recovery_window_goal, l_disk_cache FROM prot WHERE prot_key = l_old_prot_key; END IF; -- l_old_rsvn := l_rsvn; IF p_reserved_space IS NOT NULL THEN l_rsvn := numstring_to_num(p_reserved_space); IF l_rsvn < MIN_RESERVATION THEN am_trace('update_db: reserved_space ' || TO_CHAR(l_rsvn) || ' less than MIN_RESERVATION ' || TO_CHAR(MIN_RESERVATION)); sys.dbms_sys_error.raise_system_error(RSRVD_SPACE_TOO_SMALL_NUM, TO_CHAR(l_rsvn), TO_CHAR(MIN_RESERVATION), FALSE); END IF; END IF; -- -- -- -- -- -- -- -- IF (l_old_prot_key <> l_prot_key) AND (l_sl_key <>l_old_sl_key) THEN -- -- SELECT count(*) INTO l_cnt FROM sbt_job_template j, sbt_attr_set a, sbt_lib_desc l WHERE j.db_key = l_db_key AND j.attr_key = a.attr_key AND a.lib_key = l.lib_key AND l.server_key IS NULL; IF l_cnt > 0 THEN am_trace('update_db: aborting - existing tape jobs'); RAISE SL_REP_SBT_CONFLICT_ERROR; END IF; -- -- SELECT COUNT (*) INTO l_cnt FROM (SELECT server_key FROM rep_server WHERE prot_key=l_old_prot_key MINUS SELECT server_key FROM rep_server WHERE prot_key=l_prot_key); IF l_cnt > 0 THEN am_trace('update_db: aborting - rep srvs in old not in new'); RAISE SL_REP_SBT_CONFLICT_ERROR; END IF; -- -- SELECT COUNT (*) INTO l_cnt FROM (SELECT server_key FROM rep_server WHERE prot_key=l_prot_key MINUS SELECT server_key FROM rep_server WHERE prot_key=l_old_prot_key); IF l_cnt > 0 THEN am_trace('update_db: aborting - rep srvs in new not in old'); RAISE SL_REP_SBT_CONFLICT_ERROR; END IF; END IF; IF l_unregistered_db = 1 THEN UPDATE unreg_database SET prot_key = l_prot_key, reserved_space = l_rsvn WHERE db_unique_name=p_db_unique_name; -- dbms_ra_int.verify_reserved_space(l_sl_key); COMMIT; ELSE -- SELECT sl_min_alloc INTO l_alloc FROM sl WHERE sl_key = l_sl_key; -- IF l_alloc != l_old_alloc THEN RAISE BAD_AU_SIZE; END IF; -- IF (l_not_taped_state IS NULL AND l_disk_cache = 'YES') THEN l_gcopy := 'YES'; END IF; -- IF (l_not_taped_state IS NOT NULL AND l_disk_cache = 'NO') THEN l_gcopy := 'NO'; END IF; -- IF (l_poll_key IS NOT NULL) AND (l_poll_key <> l_old_poll_key) THEN UPDATE poll SET poll_flags = poll_flags - BITAND(poll_flags, DBMS_RA_SCHEDULER.POLL_FLAGS_UNDO_DBID_ERROR) + DBMS_RA_SCHEDULER.POLL_FLAGS_UNDO_DBID_ERROR WHERE poll_key = l_poll_key; END IF; -- -- IF (l_sl_key = l_old_sl_key) AND ((l_move_phase IS NULL) OR (l_move_phase = dbms_ra_scheduler.MOVE_PHASE_PEND)) THEN UPDATE odb SET prot_key = l_prot_key, future_prot_key = l_prot_key, reserved_space = l_rsvn, base_reserved_space = l_rsvn, not_taped = DECODE(l_gcopy, 'YES', used_space, -- If turned on set to used not_taped), not_taped_state = DECODE(l_gcopy, 'YES', 'I', -- If turned on, Invalid 'NO', NULL, -- If turned off, null not_taped_state), recovery_window_goal = l_recovery_window_goal WHERE db_key = l_db_key; -- IF l_rsvn <> l_old_rsvn THEN dbms_ra_int.verify_reserved_space(l_sl_key); END IF; COMMIT; ELSE -- -- -- -- -- UPDATE odb SET future_prot_key = l_prot_key, move_phase = NVL(move_phase,dbms_ra_scheduler.MOVE_PHASE_PEND), reserved_space = l_rsvn, base_reserved_space = l_rsvn, not_taped = DECODE(l_gcopy, 'YES', used_space, -- If turned on set to used not_taped), not_taped_state = DECODE(l_gcopy, 'YES', 'I', -- If turned on, Invalid 'NO', NULL, -- If turned off, null not_taped_state), recovery_window_goal = l_recovery_window_goal WHERE db_key = l_db_key; -- dbms_ra_int.verify_reserved_space(l_sl_key); -- move_commit(l_sl_key, NULL, l_db_key); END IF; -- IF l_gcopy = 'YES' THEN l_task_rec.task_type := DBMS_RA_SCHEDULER.TASK_GCOPY_COMPUTE; l_task_rec.db_key := l_db_key; l_task_rec.flags := 0; DBMS_RA_SCHEDULER.NEW_TASK(l_task_rec); END IF; -- IF l_gcopy = 'NO' THEN dbms_ra_scheduler.release_blocked_tasks( dbms_ra_scheduler.SPACE_PSEUDO_TASK, l_db_key); dbms_ra_scheduler.fix_error ( p_error_num => DBMS_RA_SCHEDULER.E_GCOPY_SUSPENDED_NUM, p_db_key => l_db_key); END IF; -- -- IF l_old_prot_key != l_prot_key THEN -- -- UPDATE odb SET last_replication = NULL, next_reconcile = NULL, last_reconcile = NULL, pending_rep_setup = NULL WHERE db_key = l_db_key; COMMIT; -- SELECT prot_name INTO l_prot_name_old FROM prot WHERE prot_key = l_old_prot_key; -- FOR s IN (SELECT rs.server_key, srv.rep_server_name FROM rep_server rs, server srv WHERE prot_key=l_old_prot_key AND srv.server_key = rs.server_key) LOOP l_template_name := dbms_ra_int.build_rep_tpl_name ( rep_srv_name => s.rep_server_name, db_key => l_db_key, prot_key => l_old_prot_key); BEGIN remove_rep_tasks(p_db_key => l_db_key, p_template => l_template_name); delete_sbt_job_template_int(template_name => l_template_name, do_commit => FALSE); EXCEPTION WHEN OBJ_NOT_FOUND THEN -- NULL; END; END LOOP; COMMIT; -- -- FOR rslst IN (SELECT server_key FROM rep_server WHERE prot_key=l_old_prot_key MINUS SELECT server_key FROM rep_server WHERE prot_key=l_prot_key) LOOP SELECT l.lib_key INTO l_tmp_lib_key FROM sbt_lib_desc l, server s WHERE l.server_key = s.server_key AND s.server_key = rslst.server_key; am_trace ('UPDATE_DB: Deleting backup piece records' || ' for ' || dbms_ra_int.dbkey2name(l_db_key)); delete_replicated_backups(p_db_key => l_db_key, p_sbt_lib_key => l_tmp_lib_key, p_force_del => TRUE); END LOOP; -- -- SELECT COUNT(*) INTO l_new_rep_srv_cnt FROM (SELECT server_key FROM rep_server WHERE prot_key=l_prot_key MINUS SELECT server_key FROM rep_server WHERE prot_key=l_old_prot_key); -- -- -- -- UPDATE odb SET pending_rep_setup = 'Y' WHERE db_key = l_db_key; COMMIT; -- FOR s IN (SELECT server_key FROM rep_server WHERE prot_key=l_prot_key) LOOP SELECT rep_server_name INTO l_rep_srv_name FROM server WHERE server.server_key = s.server_key; -- -- -- SELECT lib_key INTO l_lib_key FROM sbt_lib_desc WHERE server_key = s.server_key; l_success := dbms_ra_scheduler.reconcile_db ( p_db_key => l_db_key, p_server_key => s.server_key, p_only_active => FALSE, p_force_reconcile => TRUE, rec_cnt => l_num_rec); IF NOT l_success OR l_num_rec <> 1 THEN l_all_reconciled := FALSE; dbms_ra_scheduler.log_error(p_errno => dbms_ra.REP_SETUP_ERROR_NUM, p_db_key => l_db_key, p_param1 => 'update_db_reconcile-' || l_prot_name, p_param2 => l_rep_srv_name, p_param3 => p_db_unique_name, P_keep_stack => FALSE, p_component =>'REPLICATION_RECONCILE', p_severity => dbms_ra_scheduler.SEVERITY_ERROR, p_param_char => 'RECONCILE'); ELSE -- -- dbms_ra_scheduler.fix_error ( p_error_num => dbms_ra.REP_SETUP_ERROR_NUM, p_db_key => l_db_key, p_param_char => 'RECONCILE'); -- -- l_db_unique_name := dbms_ra_int.dbkey2name(l_db_key); -- dbms_ra_scheduler.queue_set_reconcile_timer (l_db_key); -- -- l_template_name := dbms_ra_int.build_rep_tpl_name ( rep_srv_name => l_rep_srv_name, db_key => l_db_key, prot_key => l_prot_key); BEGIN l_rep_atr_name := dbms_ra_int.build_rep_atr_name(l_rep_srv_name); dbms_ra_int.create_sbt_job_template_int( template_name => l_template_name, db_unique_name => l_db_unique_name, attr_name => l_rep_atr_name, backup_type => 'ALL', do_commit => TRUE); EXCEPTION WHEN DUP_NAME THEN -- NULL; END; -- UPDATE odb SET pending_rep_setup = 'N' WHERE db_key = l_db_key; COMMIT; -- IF l_new_rep_srv_cnt != 0 THEN dbms_ra_scheduler.replicate_existing_backups( p_template_name => l_template_name); END IF; END IF; END LOOP; COMMIT; END IF; -- IF l_disk_cache = 'NO' THEN dbms_ra_scheduler.release_blocked_tasks( dbms_ra_scheduler.SPACE_PSEUDO_TASK, l_db_key); END IF; END IF; -- IF l_unregistered_db = 1 -- IF (p_db_timezone IS NOT NULL) THEN dbms_rcvcat.addTimeZone(p_db_unique_name, p_db_timezone, 'A', p_incarnations); END IF; EXCEPTION WHEN l_tmz_err THEN l_invalid_val := SUBSTR(SQLERRM, 1, 256); am_trace('update_db: raising INVALID_VAL ' || l_invalid_val); l_invalid_val := SUBSTR(l_invalid_val, instr(l_invalid_val, ':')); sys.dbms_sys_error.raise_system_error(INVALID_VAL_NUM, l_invalid_val, FALSE); WHEN MISSING_INIT_REP_TYPE THEN -- am_trace ('update_db: intial replication parameter not defined'); RAISE; WHEN OBJ_NOT_FOUND THEN -- IF l_obj_type IS NOT NULL THEN am_trace('update_db: ' || item_not_found(l_obj_name,l_obj_type)); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, l_obj_name, l_obj_type, FALSE); ELSE RAISE; END IF; WHEN OTHERS THEN ROLLBACK; am_trace ('update_db exception: ' || p_db_unique_name || ',' || p_protection_policy_name || ', err:' || SQLERRM); RAISE; END update_db_int; -- PROCEDURE update_db (db_unique_name IN VARCHAR2, protection_policy_name IN VARCHAR2 DEFAULT NULL, reserved_space IN VARCHAR2 DEFAULT NULL, db_timezone IN VARCHAR2 DEFAULT NULL, incarnations IN VARCHAR2 DEFAULT 'CURRENT') IS l_the NUMBER; c_protection_policy_name prot.prot_name%TYPE; BEGIN lock_api(LOCKAPI_MODIFY, 'update_db'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_UPD_DB, param => 'update_db' || b_p('db_unique_name', db_unique_name, p_first=>TRUE) || b_p('protection_policy_name', protection_policy_name) || b_p('reserved_space', reserved_space, p_last=>TRUE)); dbms_ra_int.canonicalize(protection_policy_name, c_protection_policy_name, 128); update_db_int (upper(db_unique_name), c_protection_policy_name, reserved_space, upper(db_timezone), incarnations); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END update_db; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE delete_db_int (p_db_unique_name IN VARCHAR2, p_wait IN BOOLEAN) IS l_unreg_db VARCHAR2(30); l_db_id NUMBER := 0; l_db_key NUMBER := NULL; l_obj_type VARCHAR2(128); l_obj_name VARCHAR2(128); l_task_rec task%ROWTYPE; l_texists NUMBER; l_count NUMBER; l_error_num NUMBER; l_waiting BOOLEAN := FALSE; BEGIN -- -- BEGIN SELECT db_unique_name INTO l_unreg_db FROM unreg_database WHERE db_unique_name = p_db_unique_name FOR UPDATE OF db_unique_name; EXCEPTION WHEN NO_DATA_FOUND THEN l_unreg_db := NULL; END; IF l_unreg_db IS NOT NULL THEN -- -- -- revoke_db_access_int (NULL, p_db_unique_name); DELETE unreg_database WHERE db_unique_name=p_db_unique_name; COMMIT; RETURN; ELSE -- BEGIN l_obj_type := 'db unique name'; l_obj_name := p_db_unique_name; SELECT db_key, db_id INTO l_db_key, l_db_id FROM db WHERE reg_db_unique_name = p_db_unique_name; EXCEPTION WHEN NO_DATA_FOUND THEN RAISE OBJ_NOT_FOUND; END; END IF; -- SELECT COUNT(*) INTO l_count FROM config WHERE config.name = '_recovery_appliance_state' AND config.value = 'OFF'; IF l_count > 0 THEN -- RAISE CANT_DELETE_DB_DOWN; END IF; -- SELECT COUNT(*) INTO l_count FROM task t WHERE t.task_type = DBMS_RA_SCHEDULER.TASK_DELETE_DB AND db_key = l_db_key; IF l_count > 0 THEN -- sys.dbms_sys_error.raise_system_error(CANT_DELETE_DB_RUNNING_NUM, p_db_unique_name, FALSE); END IF; -- BEGIN dbms_ra_storage.lock_db (l_db_key); -- -- -- -- -- revoke_db_access_int (NULL, p_db_unique_name); -- -- -- -- -- -- -- -- UPDATE odb SET db_state = DBMS_RA_SCHEDULER.DB_STATE_IN_DELETE WHERE db_key = l_db_key; COMMIT; dbms_ra_storage.unlock_db (l_db_key); am_trace ('delete_db: ' || p_db_unique_name || ': database marked for delete'); EXCEPTION WHEN OTHERS THEN -- dbms_ra_storage.unlock_db (l_db_key); -- am_trace('delete_db: ' || p_db_unique_name || ': failed to mark database for delete'); sys.dbms_sys_error.raise_system_error(E_INTERNAL_ERROR_NUM, 'delete_db: ' || p_db_unique_name || ': failed to mark database for delete', FALSE); END; -- l_task_rec.task_type := DBMS_RA_SCHEDULER.TASK_DELETE_DB; l_task_rec.db_key := l_db_key; l_task_rec.param_num1 := l_db_id; l_task_rec.param_char1 := p_db_unique_name; l_task_rec.flags := 0; dbms_ra_scheduler.new_task(l_task_rec); -- IF p_wait THEN -- -- -- -- dbms_ra_int.info_start('DELETE_DB', p_db_unique_name || ': waiting for completion'); l_waiting := TRUE; LOOP SELECT COUNT(*) INTO l_texists FROM task WHERE task_id = l_task_rec.task_id; EXIT WHEN l_texists = 0; -- SELECT COUNT(*) INTO l_count FROM config WHERE config.name = '_recovery_appliance_state' AND config.value = 'OFF'; IF l_count > 0 THEN -- RAISE CANT_DELETE_DB_DOWN; END IF; -- DBMS_LOCK.SLEEP(10); END LOOP; dbms_ra_int.info_end; l_waiting := FALSE; -- -- SELECT COUNT(*), MAX(error_num) INTO l_count, l_error_num FROM error_log WHERE task_id = l_task_rec.task_id; am_trace('delete_db: ' || p_db_unique_name || ': Found errors=' || l_count || ', ' || pparm(l_error_num)); IF l_count > 0 THEN sys.dbms_sys_error.raise_system_error(l_error_num, p_db_unique_name, FALSE); END IF; -- -- SELECT COUNT(*) INTO l_count FROM db WHERE db_key = l_db_key; IF l_count > 0 THEN am_trace('delete_db: ' || p_db_unique_name || ': database has not been deleted,' || ' delete task ' || l_task_rec.task_id); -- sys.dbms_sys_error.raise_system_error(CANT_DELETE_DB_NUM, p_db_unique_name, FALSE); END IF; END IF; EXCEPTION WHEN OBJ_NOT_FOUND THEN IF l_waiting THEN dbms_ra_int.info_end; END IF; -- IF l_obj_type IS NOT NULL THEN am_trace('delete_db: ' || p_db_unique_name || ': ' || item_not_found(l_obj_name,l_obj_type)); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, l_obj_name, l_obj_type, FALSE); ELSE RAISE; END IF; WHEN OTHERS THEN IF l_waiting THEN dbms_ra_int.info_end; END IF; am_trace ('delete_db exception: ' || p_db_unique_name || ': err: ' ||SQLERRM); RAISE; END delete_db_int; -- PROCEDURE delete_db (db_unique_name IN VARCHAR2, wait IN BOOLEAN DEFAULT TRUE) IS l_the NUMBER; BEGIN lock_api(LOCKAPI_DELETE, 'delete_db'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_DEL_DB, param => 'delete_db' || b_p('db_unique_name', db_unique_name, p_first=>TRUE) || b_p('wait', wait, p_last=>TRUE)); delete_db_int (upper(db_unique_name), wait); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END delete_db; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE rename_db_int (p_db_unique_name_old IN VARCHAR2, p_db_unique_name_new IN VARCHAR2) IS l_obj_type VARCHAR2(128); l_obj_name VARCHAR2(128); l_count NUMBER; BEGIN UPDATE unreg_database SET db_unique_name = p_db_unique_name_new WHERE db_unique_name = p_db_unique_name_old; -- IF SQL%ROWCOUNT = 0 THEN l_obj_type := 'db unique name'; l_obj_name := p_db_unique_name_old; BEGIN -- SELECT COUNT(*) INTO l_count FROM node WHERE db_unique_name = p_db_unique_name_old -- -- AND NOT EXISTS (SELECT db_state FROM odb WHERE odb.db_key = node.db_key AND db_state IS NOT NULL); IF l_count = 0 THEN RAISE OBJ_NOT_FOUND; END IF; END; dbms_rcvcat.renameSite(p_db_unique_name_old, p_db_unique_name_new); END IF; COMMIT; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN am_trace ('rename_db: object with name already exists' || p_db_unique_name_new); sys.dbms_sys_error.raise_system_error(DUP_NAME_NUM, p_db_unique_name_new, 'db unique name', FALSE); WHEN OBJ_NOT_FOUND THEN -- IF l_obj_type IS NOT NULL THEN am_trace('update_db: ' || item_not_found(l_obj_name,l_obj_type)); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, l_obj_name, l_obj_type, FALSE); ELSE RAISE; END IF; WHEN OTHERS THEN ROLLBACK; am_trace('rename_db exception: ' || p_db_unique_name_old || ', ' || p_db_unique_name_new || ', err:' || SQLERRM); RAISE; END rename_db_int; -- PROCEDURE rename_db (db_unique_name_old IN VARCHAR2, db_unique_name_new IN VARCHAR2) IS l_the NUMBER; BEGIN lock_api(LOCKAPI_MODIFY, 'rename_db'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_REN_DB, param => 'rename_db' || b_p('db_unique_name_old', db_unique_name_old, p_first=>TRUE) || b_p('db_unique_name_new', db_unique_name_new, p_last=>TRUE)); rename_db_int (upper(db_unique_name_old), upper(db_unique_name_new)); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END rename_db; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE create_protection_policy_int ( p_protection_policy_name IN VARCHAR2, p_description IN VARCHAR2 DEFAULT NULL, p_storage_location_name IN VARCHAR2 DEFAULT NULL, p_polling_policy_name IN VARCHAR2 DEFAULT NULL, p_recovery_window_goal IN DSINTERVAL_UNCONSTRAINED, p_max_retention_window IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, p_recovery_window_sbt IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, p_unprotected_window IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, p_guaranteed_copy IN VARCHAR2 DEFAULT NULL) IS l_sl_key NUMBER; l_poll_key NUMBER; l_prot_key NUMBER; l_numrows NUMBER; l_restore_compression VARCHAR2(100); l_obj_name VARCHAR2(128); l_obj_type VARCHAR2(128); l_missing_param VARCHAR2(128); l_invalid_val VARCHAR2(128); l_algnm VARCHAR2(64) := NULL; l_cnt NUMBER; BEGIN -- -- SELECT count(*) INTO l_numrows FROM prot WHERE prot.prot_name = p_protection_policy_name; IF l_numrows != 0 THEN RAISE DUP_VAL_ON_INDEX; END IF ; -- -- BEGIN IF p_storage_location_name IS NOT NULL THEN -- -- l_obj_name := p_storage_location_name; SELECT sl_key INTO l_sl_key FROM sl WHERE sl.sl_name = p_storage_location_name; ELSE l_missing_param := 'storage_location_name'; RAISE MISSING_PARAM; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN l_obj_type := 'storage location'; RAISE OBJ_NOT_FOUND; END; -- -- BEGIN IF p_polling_policy_name IS NOT NULL THEN -- -- SELECT poll_key INTO l_poll_key FROM poll WHERE poll.poll_name = p_polling_policy_name; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN l_obj_name := p_polling_policy_name; l_obj_type := 'polling policy'; RAISE OBJ_NOT_FOUND; END; -- -- -- -- SELECT MIN(value) INTO l_restore_compression FROM config WHERE name = '_restore_compression'; IF l_restore_compression IS NOT NULL AND l_restore_compression != 'OFF' THEN SELECT max(algorithm_name) INTO l_algnm FROM sys.v_$rman_compression_algorithm WHERE algorithm_name = DECODE(l_restore_compression, 'BZIP2', 'BASIC', 'ZLIB', 'MEDIUM', l_restore_compression) AND is_valid = 'YES'; IF l_algnm IS NULL THEN RAISE BAD_RECOMPR; END IF; END IF; -- -- IF p_max_retention_window IS NOT NULL AND p_max_retention_window < p_recovery_window_goal THEN l_invalid_val := 'max_retention_window'; RAISE INVALID_VAL; END IF; -- -- IF p_guaranteed_copy != 'YES' AND p_guaranteed_copy != 'NO' THEN l_invalid_val := 'guaranteed_copy'; RAISE INVALID_VAL; END IF; -- l_prot_key := rman_seq.nextval; INSERT INTO prot (prot_key, prot_name, prot_description, sl_key, poll_key, prot_recovery_window_goal, prot_max_retention_window, prot_recovery_window_sbt, prot_unprotected_window, prot_out_compression, prot_disk_cache) VALUES (l_prot_key, p_protection_policy_name, SUBSTR(p_description,1,128), l_sl_key, l_poll_key, p_recovery_window_goal, p_max_retention_window, p_recovery_window_sbt, p_unprotected_window, l_algnm, p_guaranteed_copy); COMMIT; EXCEPTION WHEN MISSING_PARAM THEN IF l_missing_param IS NOT NULL THEN am_trace ('create_protection_policy: required parameter missing ' || l_missing_param); sys.dbms_sys_error.raise_system_error(MISSING_PARAM_NUM, l_missing_param, FALSE); ELSE RAISE; END IF; WHEN INVALID_VAL THEN IF l_invalid_val IS NOT NULL THEN am_trace ('create_protection_policy: parameter value is invalid ' || l_invalid_val); sys.dbms_sys_error.raise_system_error(INVALID_VAL_NUM, l_invalid_val, FALSE); ELSE RAISE; END IF; WHEN OBJ_NOT_FOUND THEN -- IF l_obj_type IS NOT NULL THEN am_trace ('create_protection_policy: ' || item_not_found(l_obj_name, l_obj_type)); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, l_obj_name, l_obj_type, FALSE); ELSE RAISE; END IF; WHEN DUP_VAL_ON_INDEX THEN am_trace ('create_protection_policy: object with name already exists ' || p_protection_policy_name); sys.dbms_sys_error.raise_system_error(DUP_NAME_NUM, p_protection_policy_name, 'protection policy', FALSE); WHEN OTHERS THEN ROLLBACK; am_trace ('create_protection_policy exception: ' || ' prot_key:' || l_prot_key || ', protection_policy_name:' || p_protection_policy_name || ', description:' || p_description || ', storage_loc_key:' || l_sl_key || ', polling policy key:' || l_poll_key || ', p_recovery_window_goal:' || p_recovery_window_goal || ', p_max_retention_window:' || p_max_retention_window || ', recovery_window_sbt:' || p_recovery_window_sbt || ', unprotected_window:' || p_unprotected_window || ', err:' || SQLERRM); RAISE; END create_protection_policy_int; -- PROCEDURE create_protection_policy ( protection_policy_name IN VARCHAR2, description IN VARCHAR2 DEFAULT NULL, storage_location_name IN VARCHAR2, polling_policy_name IN VARCHAR2 DEFAULT NULL, recovery_window_goal IN DSINTERVAL_UNCONSTRAINED, max_retention_window IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, recovery_window_sbt IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, unprotected_window IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, guaranteed_copy IN VARCHAR2 DEFAULT 'NO') IS l_the NUMBER; c_protection_policy_name prot.prot_name%TYPE; c_polling_policy_name poll.poll_name%TYPE; c_storage_location_name sl.sl_name%TYPE; BEGIN lock_api(LOCKAPI_CREATE, 'create_protection_policy'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_ADD_PROT_POLICY, param => 'create_protection_policy' || b_p('protection_policy_name', protection_policy_name, p_first=>TRUE) || b_p('description', description) || b_p('storage_location_name', storage_location_name) || b_p('polling_policy_name', polling_policy_name ) || b_p('recovery_window_goal', recovery_window_goal ) || b_p('max_retention_window', max_retention_window ) || b_p('recovery_window_sbt', recovery_window_sbt) || b_p('unprotected_window', unprotected_window) || b_p('guaranteed_copy', guaranteed_copy, p_last=>TRUE)); dbms_ra_int.canonicalize(protection_policy_name, c_protection_policy_name, 128); dbms_ra_int.canonicalize(storage_location_name, c_storage_location_name, 128); dbms_ra_int.canonicalize(polling_policy_name, c_polling_policy_name, 128); create_protection_policy_int (c_protection_policy_name, description, c_storage_location_name, c_polling_policy_name, recovery_window_goal, max_retention_window, recovery_window_sbt, unprotected_window, upper(guaranteed_copy)); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END create_protection_policy; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE update_protection_policy_int ( p_protection_policy_name IN VARCHAR2, p_description IN VARCHAR2 DEFAULT NULL, p_storage_location_name IN VARCHAR2 DEFAULT NULL, p_polling_policy_name IN VARCHAR2, p_recovery_window_goal IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, p_max_retention_window IN DSINTERVAL_UNCONSTRAINED, p_recovery_window_sbt IN DSINTERVAL_UNCONSTRAINED, p_unprotected_window IN DSINTERVAL_UNCONSTRAINED, p_guaranteed_copy IN VARCHAR2 DEFAULT NULL) IS l_needmove BOOLEAN := FALSE; l_prot_key NUMBER; l_old_sl_key NUMBER; l_sl_key NUMBER; l_poll_key NUMBER; l_old_alloc NUMBER; l_alloc NUMBER; l_recovery_window_goal DSINTERVAL_UNCONSTRAINED; l_max_retention_window DSINTERVAL_UNCONSTRAINED; l_obj_type VARCHAR2(128); l_obj_name VARCHAR2(128); l_invalid_val VARCHAR2(128); l_polling_retdef BOOLEAN := dbms_ra_int.isparamdef('p1'); l_maxret_retdef BOOLEAN := dbms_ra_int.isparamdef('p3'); l_sbt_retdef BOOLEAN := dbms_ra_int.isparamdef('p2'); l_unprotected_window BOOLEAN := dbms_ra_int.isparamdef('p4'); l_restore_compression VARCHAR2(100); l_algnm VARCHAR2(64) := NULL; l_cache_scn NUMBER; l_cnt NUMBER; update_sbt_ret VARCHAR2(1) := 'Y'; update_polling_ret VARCHAR2(1) := 'Y'; update_unprot_win VARCHAR2(1) := 'Y'; l_task_rec task%ROWTYPE; CURSOR odbcur IS SELECT db_key FROM odb WHERE odb.prot_key = l_prot_key; BEGIN -- BEGIN SELECT prot.prot_key, prot.sl_key, prot.prot_recovery_window_goal, prot.prot_max_retention_window INTO l_prot_key, l_old_sl_key, l_recovery_window_goal, l_max_retention_window FROM prot WHERE prot_name = p_protection_policy_name; EXCEPTION WHEN NO_DATA_FOUND THEN l_obj_type := 'protection policy'; l_obj_name := p_protection_policy_name; RAISE OBJ_NOT_FOUND; END; -- IF p_storage_location_name IS NOT NULL THEN BEGIN SELECT sl_key, sl_min_alloc INTO l_sl_key, l_alloc FROM sl WHERE sl.sl_name = p_storage_location_name; SELECT sl_min_alloc INTO l_old_alloc FROM sl WHERE sl_key = l_old_sl_key; -- IF l_alloc != l_old_alloc THEN RAISE BAD_AU_SIZE; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN l_obj_type := 'storage location'; l_obj_name := p_storage_location_name; RAISE OBJ_NOT_FOUND; END; ELSE l_sl_key := l_old_sl_key; END IF; -- IF p_polling_policy_name IS NOT NULL THEN -- BEGIN SELECT poll_key INTO l_poll_key FROM poll WHERE poll.poll_name = p_polling_policy_name; EXCEPTION WHEN NO_DATA_FOUND THEN l_obj_type := 'polling policy'; l_obj_name := p_polling_policy_name; RAISE OBJ_NOT_FOUND; END; ELSIF l_polling_retdef THEN -- update_polling_ret := NULL; END IF; -- IF p_recovery_window_goal IS NOT NULL THEN l_recovery_window_goal := p_recovery_window_goal; END IF; -- IF NOT l_maxret_retdef THEN l_max_retention_window := p_max_retention_window; END IF; -- -- IF l_max_retention_window IS NOT NULL AND l_max_retention_window < l_recovery_window_goal THEN IF p_max_retention_window IS NOT NULL THEN l_invalid_val := 'max_retention_window'; ELSE l_invalid_val := 'recovery_window_goal'; END IF; RAISE INVALID_VAL; END IF; -- IF l_sbt_retdef THEN update_sbt_ret := NULL; END IF; -- IF l_unprotected_window THEN update_unprot_win := NULL; END IF; -- -- -- -- SELECT MIN(value) INTO l_restore_compression FROM config WHERE name = '_restore_compression'; IF l_restore_compression IS NULL THEN -- Get original value SELECT prot_out_compression INTO l_algnm FROM prot WHERE prot.prot_name = p_protection_policy_name; COMMIT; ELSE -- Verify provided value IF l_restore_compression = 'OFF' THEN l_algnm := NULL; ELSE SELECT max(algorithm_name) INTO l_algnm FROM sys.v_$rman_compression_algorithm WHERE algorithm_name = DECODE(l_restore_compression, 'BZIP2', 'BASIC', 'ZLIB', 'MEDIUM', l_restore_compression) AND is_valid = 'YES'; IF l_algnm IS NULL THEN RAISE BAD_RECOMPR; END IF; END IF; END IF; -- -- IF p_guaranteed_copy IS NOT NULL AND p_guaranteed_copy != 'YES' AND p_guaranteed_copy != 'NO' THEN l_invalid_val := 'guaranteed_copy'; RAISE INVALID_VAL; END IF; -- -- UPDATE prot SET prot.prot_description = NVL(SUBSTR(p_description,1,128), prot_description), prot.sl_key = l_sl_key, prot.poll_key = nvl2(update_polling_ret, l_poll_key, prot.poll_key), prot.prot_recovery_window_goal = l_recovery_window_goal, prot.prot_max_retention_window = l_max_retention_window, prot.prot_recovery_window_sbt = nvl2(update_sbt_ret, p_recovery_window_sbt, prot.prot_recovery_window_sbt), prot.prot_unprotected_window= nvl2(update_unprot_win, p_unprotected_window, prot.prot_unprotected_window), prot.prot_out_compression = l_algnm, prot.prot_disk_cache = nvl(p_guaranteed_copy, prot.prot_disk_cache) WHERE prot.prot_name = p_protection_policy_name; -- -- IF p_guaranteed_copy IS NOT NULL THEN -- UPDATE odb SET not_taped = DECODE(p_guaranteed_copy, 'YES', -- Turn it on DECODE(not_taped_state, 'V', not_taped, 'I', not_taped, used_space), not_taped), not_taped_state = DECODE(p_guaranteed_copy, 'YES', -- Turn it on DECODE(not_taped_state, 'V', 'V', 'N', 'N', 'C'), 'NO', NULL, -- Turn it off not_taped_state) WHERE future_prot_key = l_prot_key; END IF; -- -- IF l_sl_key != l_old_sl_key THEN UPDATE odb SET move_phase = dbms_ra_scheduler.MOVE_PHASE_PEND WHERE future_prot_key = l_prot_key AND move_phase IS NULL; l_needmove := TRUE; END IF; -- dbms_ra_int.verify_reserved_space(l_sl_key); -- IF p_polling_policy_name IS NOT NULL THEN UPDATE poll SET poll_flags = poll_flags - BITAND(poll_flags, DBMS_RA_SCHEDULER.POLL_FLAGS_UNDO_DBID_ERROR) + DBMS_RA_SCHEDULER.POLL_FLAGS_UNDO_DBID_ERROR WHERE poll_key = l_poll_key; END IF; -- IF p_recovery_window_goal IS NOT NULL THEN UPDATE odb SET recovery_window_goal = p_recovery_window_goal WHERE prot_key = l_prot_key; END IF; -- IF l_needmove THEN move_commit(l_sl_key, l_prot_key); ELSE COMMIT; END IF; -- IF p_guaranteed_copy IS NOT NULL THEN FOR x IN (SELECT db_key, not_taped_state FROM odb WHERE prot_key = l_prot_key) LOOP -- IF p_guaranteed_copy = 'YES' AND x.not_taped_state IN ('I','C') THEN l_task_rec.task_type := DBMS_RA_SCHEDULER.TASK_GCOPY_COMPUTE; l_task_rec.db_key := x.db_key; l_task_rec.flags := 0; DBMS_RA_SCHEDULER.NEW_TASK(l_task_rec); -- IF x.not_taped_state = 'C' THEN dbms_ra_scheduler.log_error ( p_errno => DBMS_RA_SCHEDULER.E_GCOPY_SUSPENDED_NUM, p_param1 => dbms_ra_int.dbkey2name(x.db_key), p_db_key => x.db_key, p_keep_stack => FALSE, p_component => 'UPDATE_POLICY', p_severity => DBMS_RA_SCHEDULER.SEVERITY_WARNING); END IF; -- ELSIF p_guaranteed_copy = 'NO' AND x.not_taped_state IS NULL THEN dbms_ra_scheduler.release_blocked_tasks( dbms_ra_scheduler.SPACE_PSEUDO_TASK, x.db_key); dbms_ra_scheduler.fix_error ( p_error_num => DBMS_RA_SCHEDULER.E_GCOPY_SUSPENDED_NUM, p_db_key => x.db_key); END IF; END LOOP; END IF; EXCEPTION WHEN OBJ_NOT_FOUND THEN ROLLBACK; IF l_obj_type IS NOT NULL THEN am_trace('update_protection_policy: ' || item_not_found(l_obj_name,l_obj_type)); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, l_obj_name, l_obj_type, FALSE); ELSE RAISE; END IF; WHEN INVALID_VAL THEN IF l_invalid_val IS NOT NULL then am_trace ('update_protection_policy: parameter value is invalid' || l_invalid_val); sys.dbms_sys_error.raise_system_error(INVALID_VAL_NUM, l_invalid_val, FALSE); ELSE RAISE; END IF; WHEN INVALID_SIZENUMBER THEN ROLLBACK; am_trace ('update_protection_policy: Invalid size number' || ' protection_policy_name:' || p_protection_policy_name ); RAISE; WHEN BAD_RECOMPR THEN ROLLBACK; am_trace ('update_protection_policy: Invalid' || ' restore_compression: ' || l_restore_compression); RAISE; WHEN OTHERS THEN ROLLBACK; am_trace ('update_protection_policy exception:' || ' prot_key:' || l_prot_key || ', protection_policy_name:' || p_protection_policy_name || ', description:' || p_description || ', storage_loc_name:' || p_storage_location_name || ', polling_policy_name:' || p_polling_policy_name || ', recovery_window_goal:' || p_recovery_window_goal || ', max_retention_window:' || p_max_retention_window || ', recovery_window_sbt:' || p_recovery_window_sbt || ', unprotected_window:' || p_unprotected_window || ', err:' || SQLERRM); RAISE; END update_protection_policy_int; -- PROCEDURE update_protection_policy ( protection_policy_name IN VARCHAR2, description IN VARCHAR2 DEFAULT NULL, storage_location_name IN VARCHAR2 DEFAULT NULL, polling_policy_name IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p1'), recovery_window_goal IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, max_retention_window IN DSINTERVAL_UNCONSTRAINED DEFAULT dbms_ra_int.intervalnull('p3'), recovery_window_sbt IN DSINTERVAL_UNCONSTRAINED DEFAULT dbms_ra_int.intervalnull('p2'), unprotected_window IN DSINTERVAL_UNCONSTRAINED DEFAULT dbms_ra_int.intervalnull('p4'), guaranteed_copy IN VARCHAR2 DEFAULT NULL) IS l_the NUMBER; c_protection_policy_name prot.prot_name%TYPE; c_polling_policy_name poll.poll_name%TYPE; c_storage_location_name sl.sl_name%TYPE; BEGIN lock_api(LOCKAPI_MODIFY, 'update_protection_policy'); -- l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_UPD_PROT_POLICY, param => 'update_protection_policy' || b_p('protection_policy_name', protection_policy_name, p_first=>TRUE) || b_p('description', description) || b_p('storage_location_name', storage_location_name) || b_p('polling_policy_name', polling_policy_name ) || b_p('recovery_window_goal', recovery_window_goal ) || b_p('max_retention_window', max_retention_window ) || b_p('recovery_window_sbt', recovery_window_sbt ) || b_p('unprotected_window', unprotected_window ) || b_p('guaranteed_copy', guaranteed_copy, p_last=>TRUE)); dbms_ra_int.canonicalize(protection_policy_name, c_protection_policy_name, 128); dbms_ra_int.canonicalize(storage_location_name, c_storage_location_name, 128); dbms_ra_int.canonicalize(polling_policy_name, c_polling_policy_name, 128); update_protection_policy_int (c_protection_policy_name, description, c_storage_location_name, c_polling_policy_name, recovery_window_goal, max_retention_window, recovery_window_sbt, unprotected_window, upper(guaranteed_copy)); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END update_protection_policy; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE delete_protection_policy_int (p_protection_policy_name IN VARCHAR2) IS l_prot_key NUMBER := NULL; l_prot_cnt NUMBER := NULL; l_odb_key NUMBER := NULL; l_odb_cnt NUMBER := NULL; CURSOR rep_server_cursor IS SELECT s.rep_server_name rep_server_name, p.prot_name prot_name FROM rep_server r, prot p, server s WHERE r.prot_key = l_prot_key AND s.server_key = r.server_key; BEGIN -- BEGIN SELECT prot.prot_key INTO l_prot_key FROM prot WHERE prot_name = p_protection_policy_name; EXCEPTION WHEN NO_DATA_FOUND THEN RAISE OBJ_NOT_FOUND; END; -- SELECT count(*) INTO l_prot_cnt FROM odb WHERE odb.prot_key = l_prot_key ; IF l_prot_cnt = 0 THEN -- FOR f IN rep_server_cursor LOOP BEGIN remove_rep_from_prot_int(f.rep_server_name, f.prot_name, FALSE); EXCEPTION WHEN OBJ_NOT_FOUND THEN -- NULL; END; END LOOP; DELETE FROM prot WHERE prot_name = p_protection_policy_name; ELSE RAISE OBJ_IS_REFERENCED; END IF; COMMIT; EXCEPTION WHEN OBJ_NOT_FOUND THEN -- am_trace ('delete_protection_policy: ' || item_not_found( p_protection_policy_name, 'protection policy')); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, p_protection_policy_name, 'protection policy', FALSE); WHEN OBJ_IS_REFERENCED THEN -- am_trace ('delete_protection_policy: protection policy is referenced' || ' protection_policy_name:' || p_protection_policy_name); sys.dbms_sys_error.raise_system_error(OBJ_IS_REFERENCED_NUM, p_protection_policy_name, 'protection policy', FALSE); WHEN OTHERS THEN ROLLBACK; am_trace ('delete_protection_policy exception: ' || ' protection_policy_name:' || p_protection_policy_name || ' err:' || SQLERRM); RAISE; END delete_protection_policy_int; -- PROCEDURE delete_protection_policy (protection_policy_name IN VARCHAR2) IS l_the NUMBER; c_protection_policy_name prot.prot_name%TYPE; BEGIN lock_api(LOCKAPI_DELETE, 'delete_protection_policy'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_DEL_PROT_POLICY, param => 'delete_protection_policy' || b_p('protection_policy_name', protection_policy_name, p_first=>TRUE, p_last=>TRUE)); dbms_ra_int.canonicalize(protection_policy_name, c_protection_policy_name, 128); delete_protection_policy_int (c_protection_policy_name); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END delete_protection_policy; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE create_polling_policy_int (p_polling_policy_name IN VARCHAR2, p_polling_location IN VARCHAR2, p_polling_frequency DSINTERVAL_UNCONSTRAINED DEFAULT NULL, p_delete_input BOOLEAN) IS l_pol_key NUMBER; l_sl_key NUMBER; l_numrows NUMBER; l_polling_frequency DSINTERVAL_UNCONSTRAINED; l_poll_flags NUMBER := 0; l_delete_input VARCHAR2(5); l_storage_location_name sl.sl_name%TYPE; BEGIN -- -- SELECT count(*) INTO l_numrows FROM poll WHERE poll.poll_name = p_polling_policy_name; IF l_numrows != 0 THEN RAISE DUP_VAL_ON_INDEX; END IF ; -- l_storage_location_name := 'AMPOLL$' || rman_seq.nextval; -- -- create_storage_location_int( p_storage_name => l_storage_location_name, p_storage_dests => p_polling_location, p_storage_for_poll => TRUE); -- -- BEGIN SELECT sl_key INTO l_sl_key FROM sl WHERE sl.sl_name = l_storage_location_name OR sl.sl_name = l_storage_location_name || '/'; EXCEPTION WHEN NO_DATA_FOUND THEN raise OBJ_NOT_FOUND; END; IF p_polling_frequency IS NOT NULL THEN l_polling_frequency := p_polling_frequency; ELSE SELECT numtodsinterval(value, 'day') INTO l_polling_frequency FROM config WHERE name = '_default_poll_frequency_days'; END IF; IF p_delete_input THEN l_poll_flags := l_poll_flags + DBMS_RA_SCHEDULER.POLL_FLAGS_DELETE_INPUT; l_delete_input := 'TRUE'; ELSIF p_delete_input IS NULL THEN l_delete_input := 'NULL'; ELSE l_delete_input := 'FALSE'; END IF; -- l_pol_key := rman_seq.nextval; INSERT INTO poll (poll_key, poll_name, sl_key, poll_flags, poll_freq, poll_last_prune) VALUES (l_pol_key, p_polling_policy_name, l_sl_key, l_poll_flags, l_polling_frequency, SYSTIMESTAMP); -- dbms_ra_scheduler.enqueue_verify_timer_task; COMMIT; EXCEPTION WHEN OBJ_NOT_FOUND THEN -- am_trace ('create_polling_policy: ' || item_not_found( l_storage_location_name, 'polling location')); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, l_storage_location_name, 'polling location', FALSE); WHEN DUP_VAL_ON_INDEX THEN am_trace ('create_polling_policy: object with name already exists' || p_polling_policy_name); sys.dbms_sys_error.raise_system_error(DUP_NAME_NUM, p_polling_policy_name, 'polling policy', FALSE); WHEN OTHERS THEN ROLLBACK; am_trace ('create_polling_policy exception: ' || rman_seq.currval || ', ' || p_polling_policy_name || ', ' || l_storage_location_name || ', ' || l_polling_frequency || ', ' || l_delete_input || ', ' || ' err:' || SQLERRM); RAISE; END create_polling_policy_int; -- PROCEDURE create_polling_policy ( polling_policy_name IN VARCHAR2, polling_location IN VARCHAR2, polling_frequency DSINTERVAL_UNCONSTRAINED DEFAULT NULL, delete_input BOOLEAN DEFAULT FALSE) IS l_the NUMBER; c_polling_policy_name poll.poll_name%TYPE; BEGIN lock_api(LOCKAPI_CREATE, 'create_polling_policy'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_ADD_POLL_POLICY, param => 'create_polling_policy' || b_p('polling_policy_name', polling_policy_name, p_first=>TRUE) || b_p('polling_location', polling_location) || b_p('polling_frequency', polling_frequency ) || b_p('delete_input', delete_input , p_last=>TRUE)); dbms_ra_int.canonicalize(polling_policy_name, c_polling_policy_name, 128); create_polling_policy_int (c_polling_policy_name, polling_location, polling_frequency, delete_input); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END create_polling_policy; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE update_polling_policy_int ( p_polling_policy_name IN VARCHAR2, p_polling_location IN VARCHAR2 DEFAULT NULL, p_polling_frequency DSINTERVAL_UNCONSTRAINED DEFAULT NULL, p_delete_input BOOLEAN DEFAULT NULL) IS l_sl_key NUMBER := NULL; l_poll_flags NUMBER := 0; l_numrows NUMBER := 0; l_changes BOOLEAN := FALSE; l_obj_type VARCHAR2(128); l_obj_name VARCHAR2(128); l_delete_input VARCHAR2(5); l_storage_location_name sl.sl_name%TYPE; l_polling_location storage_dests.dest%TYPE; l_sl_name sl.sl_name%TYPE; BEGIN -- BEGIN SELECT poll_key, poll_flags, sl_key INTO l_numrows, l_poll_flags, l_sl_key FROM poll WHERE poll.poll_name = p_polling_policy_name; EXCEPTION WHEN NO_DATA_FOUND THEN l_obj_type := 'polling policy'; l_obj_name := p_polling_policy_name; RAISE OBJ_NOT_FOUND; END; -- IF p_polling_location IS NOT NULL THEN -- l_polling_location := p_polling_location; IF SUBSTR(p_polling_location, -1, 1) != '/' THEN l_polling_location := l_polling_location || '/'; END IF; -- SELECT MIN(sl_name) INTO l_sl_name FROM sl JOIN storage_dests sd USING (sl_key) WHERE (sd.dest = SUBSTR(l_polling_location, 1, LENGTH(sd.dest)) OR l_polling_location = SUBSTR(sd.dest, 1, LENGTH(l_polling_location))) AND sl_key <> l_sl_key; IF l_sl_name IS NOT NULL THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_SHARED_PARAMS_NUM, l_sl_name); END IF; UPDATE storage_dests SET dest = l_polling_location WHERE sl_key = l_sl_key; l_changes := TRUE; END IF; -- IF p_polling_frequency IS NOT NULL THEN UPDATE poll SET poll.poll_freq = p_polling_frequency WHERE poll.poll_name = p_polling_policy_name; l_changes := TRUE; END IF; -- IF p_delete_input IS NOT NULL THEN l_poll_flags := l_poll_flags - BITAND(l_poll_flags, DBMS_RA_SCHEDULER.POLL_FLAGS_DELETE_INPUT); IF p_delete_input THEN l_poll_flags := l_poll_flags + DBMS_RA_SCHEDULER.POLL_FLAGS_DELETE_INPUT; l_delete_input := 'TRUE'; ELSE l_delete_input := 'FALSE'; END IF; UPDATE poll SET poll.poll_flags = l_poll_flags WHERE poll.poll_name = p_polling_policy_name; l_changes := TRUE; ELSE l_delete_input := 'NULL'; END IF; -- IF l_changes = TRUE THEN -- dbms_ra_scheduler.enqueue_verify_timer_task; COMMIT; END IF; EXCEPTION WHEN OBJ_NOT_FOUND THEN -- IF l_obj_type IS NOT NULL THEN am_trace('update_polling_policy: ' || item_not_found(l_obj_name,l_obj_type)); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, l_obj_name, l_obj_type, FALSE); ELSE RAISE; END IF; WHEN OTHERS THEN ROLLBACK; am_trace ('update_polling_policy exception: ' || p_polling_policy_name || ', ' || p_polling_location || ', ' || p_polling_frequency || ', ' || l_delete_input || ', ' || ' err:' || SQLERRM); RAISE; END update_polling_policy_int; -- PROCEDURE update_polling_policy ( polling_policy_name IN VARCHAR2, polling_location IN VARCHAR2, polling_frequency IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL, delete_input IN BOOLEAN DEFAULT NULL) IS l_the NUMBER; c_polling_policy_name poll.poll_name%TYPE; BEGIN lock_api(LOCKAPI_MODIFY, 'update_polling_policy'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_UPD_POLL_POLICY, param => 'update_polling_policy' || b_p('polling_policy_name', polling_policy_name, p_first=>TRUE) || b_p('polling_location ', polling_location ) || b_p('polling_frequency', polling_frequency ) || b_p('delete_input', delete_input, p_last=>TRUE)); dbms_ra_int.canonicalize(polling_policy_name, c_polling_policy_name, 128); update_polling_policy_int (c_polling_policy_name, polling_location, polling_frequency, delete_input); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END update_polling_policy; -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE delete_polling_policy_int (p_polling_policy_name IN VARCHAR2) IS l_poll_key NUMBER := 0; l_storage_location_name sl.sl_name%TYPE; BEGIN -- BEGIN SELECT poll_key INTO l_poll_key FROM poll WHERE poll.poll_name = p_polling_policy_name; EXCEPTION WHEN NO_DATA_FOUND THEN RAISE OBJ_NOT_FOUND; END; -- SELECT sl.sl_name INTO l_storage_location_name FROM sl, poll WHERE poll.poll_name = p_polling_policy_name AND poll.sl_key = sl.sl_key; -- UPDATE prot SET poll_key = NULL WHERE poll_key = l_poll_key; -- DELETE FROM error_log WHERE error_num IN (DBMS_RA_SCHEDULER.E_BAD_FILE_NUM) AND param_num = l_poll_key; -- DELETE FROM poll WHERE poll_name = p_polling_policy_name; -- delete_storage_location_int(l_storage_location_name); -- -- dbms_ra_scheduler.enqueue_verify_timer_task; COMMIT; EXCEPTION WHEN OBJ_NOT_FOUND THEN am_trace('delete_polling_policy: ' || item_not_found(p_polling_policy_name,'polling policy')); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, p_polling_policy_name, 'polling policy', FALSE); WHEN OTHERS THEN ROLLBACK; am_trace ('delete_polling_policy exception: ' || ' poll_name:' || p_polling_policy_name || ' err:' || SQLERRM); RAISE; END delete_polling_policy_int; -- PROCEDURE delete_polling_policy (polling_policy_name IN VARCHAR2) IS l_the NUMBER; c_polling_policy_name poll.poll_name%TYPE; BEGIN lock_api(LOCKAPI_DELETE, 'delete_polling_policy'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_DEL_POLL_POLICY, param => 'delete_polling_policy' || b_p('polling_policy_name', polling_policy_name, p_first=>TRUE, p_last=>TRUE)); dbms_ra_int.canonicalize(polling_policy_name, c_polling_policy_name, 128); delete_polling_policy_int (c_polling_policy_name); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END delete_polling_policy; -- -- -- -- -- -- -- -- PROCEDURE create_sbt_library_int( lib_name IN VARCHAR2, drives IN NUMBER, restore_drives IN NUMBER DEFAULT 0, parms IN VARCHAR2 DEFAULT NULL, send IN VARCHAR2 DEFAULT NULL, server_key IN NUMBER DEFAULT NULL, p_status IN VARCHAR2 DEFAULT 'R', do_commit IN BOOLEAN DEFAULT TRUE) IS l_drives NUMBER := drives; l_dynamic_drives VARCHAR2(1) := 'N'; BEGIN IF (server_key IS NOT NULL AND l_drives IS NULL) THEN l_dynamic_drives := 'Y'; l_drives := dbms_ra_int.sbt_default_drives; END IF; IF (l_drives <= 0 OR l_drives IS NULL) THEN am_trace('create_sbt_library: num drives too small: ' || TO_CHAR(l_drives)); sys.dbms_sys_error.raise_system_error(NUM_DRIVES_TOO_SMALL_NUM, FALSE); END IF; IF (restore_drives < 0 OR restore_drives IS NULL) THEN am_trace('create_sbt_library: num restore drives too small: ' || TO_CHAR(restore_drives)); sys.dbms_sys_error.raise_system_error(NUM_RDRIVES_TOO_SMALL_NUM, FALSE); END IF; IF (restore_drives >= l_drives) THEN am_trace('create_sbt_library: num restore drives ' || TO_CHAR(restore_drives) || ' >= total num drives ' || TO_CHAR(l_drives)); sys.dbms_sys_error.raise_system_error(NUM_RDRIVES_TOO_LARGE_NUM, TO_CHAR(restore_drives), TO_CHAR(l_drives), FALSE); END IF; -- INSERT INTO sbt_lib_desc (lib_key, lib_name, drives, restore_drives, parms, send, server_key, status, failure_cnt, dynamic_drives) VALUES (rman_seq.nextval, lib_name, l_drives, restore_drives, parms, send, server_key, p_status, 0, l_dynamic_drives); IF do_commit THEN COMMIT; END IF; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN sys.dbms_sys_error.raise_system_error (DUP_NAME_NUM, lib_name, 'sbt library', FALSE); END create_sbt_library_int; -- PROCEDURE create_sbt_library( lib_name IN VARCHAR2, drives IN NUMBER, restore_drives IN NUMBER DEFAULT 0, parms IN VARCHAR2 DEFAULT NULL, send IN VARCHAR2 DEFAULT NULL) IS l_the NUMBER; c_lib_name sbt_lib_desc.lib_name%TYPE; BEGIN lock_api(LOCKAPI_CREATE, 'create_sbt_library'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_ADD_SBT_LIB, param => 'create_sbt_library' || b_p('lib_name', lib_name, p_first=>TRUE) || b_p('drives', drives ) || b_p('restore_drives', restore_drives ) || b_p('parms', parms ) || b_p('send', send , p_last=>TRUE )); dbms_ra_int.canonicalize(lib_name, c_lib_name, 128); create_sbt_library_int( c_lib_name, drives, restore_drives, parms, send); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END create_sbt_library; -- PROCEDURE update_sbt_library_int( lib_name IN VARCHAR2, drives IN NUMBER DEFAULT NULL, restore_drives IN NUMBER DEFAULT NULL, parms IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p1'), send IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p2'), dynamic_drives IN VARCHAR2 DEFAULT 'N') IS parmsdef BOOLEAN := dbms_ra_int.isparamdef('p1'); senddef BOOLEAN := dbms_ra_int.isparamdef('p2'); l_drives_in NUMBER := drives; update_parms VARCHAR2(1):= 'Y'; update_send VARCHAR2(1):= 'Y'; l_lib_key NUMBER; l_restore_drives NUMBER; l_streams NUMBER; l_drives_out NUMBER; BEGIN IF (parmsdef) THEN update_parms := NULL; END IF; IF (senddef) THEN update_send := NULL; END IF; IF (dynamic_drives = 'Y') THEN l_drives_in := dbms_ra_int.sbt_default_drives; END IF; IF (l_drives_in IS NOT NULL AND l_drives_in <= 0) THEN am_trace('update_sbt_library: num drives too small: ' || TO_CHAR(l_drives_in)); sys.dbms_sys_error.raise_system_error(NUM_DRIVES_TOO_SMALL_NUM, FALSE); END IF; IF (restore_drives < 0) THEN am_trace('update_sbt_library: num restore drives too small: ' || TO_CHAR(restore_drives)); sys.dbms_sys_error.raise_system_error(NUM_RDRIVES_TOO_SMALL_NUM, FALSE); END IF; UPDATE sbt_lib_desc lib SET lib.drives = nvl(update_sbt_library_int.l_drives_in, lib.drives), lib.restore_drives = nvl(update_sbt_library_int.restore_drives, lib.restore_drives), lib.parms = nvl2(update_parms, update_sbt_library_int.parms, lib.parms), lib.send = nvl2(update_send, update_sbt_library_int.send, lib.send), lib.dynamic_drives = update_sbt_library_int.dynamic_drives WHERE lib.lib_name = update_sbt_library_int.lib_name RETURNING lib_key, drives, restore_drives INTO l_lib_key, l_drives_out, l_restore_drives; -- IF (sql%rowcount = 0) THEN am_trace('update_sbt_library: ' || item_not_found(lib_name, 'sbt library')); sys.dbms_sys_error.raise_system_error (OBJ_NOT_FOUND_NUM, lib_name, 'sbt library', FALSE); END IF; SELECT max(streams) INTO l_streams FROM sbt_attr_set WHERE lib_key = l_lib_key; IF (l_streams > l_drives_out) THEN am_trace('update_sbt_library: num streams ' || TO_CHAR(l_streams) || ' > num drives ' || TO_CHAR(l_drives_out)); sys.dbms_sys_error.raise_system_error(NUM_STREAMS_TOO_LARGE_NUM, TO_CHAR(l_streams), TO_CHAR(l_drives_out), FALSE); END IF; IF (l_restore_drives >= l_drives_out) THEN am_trace('update_sbt_library: num restore drives ' || TO_CHAR(l_restore_drives) || ' >= total num drives ' || TO_CHAR(l_drives_out)); sys.dbms_sys_error.raise_system_error(NUM_RDRIVES_TOO_LARGE_NUM, TO_CHAR(l_restore_drives), TO_CHAR(l_drives_out), FALSE); END IF; END update_sbt_library_int; -- PROCEDURE update_sbt_library( lib_name IN VARCHAR2, drives IN NUMBER DEFAULT NULL, restore_drives IN NUMBER DEFAULT NULL, parms IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p1'), send IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p2')) IS l_the NUMBER; c_lib_name sbt_lib_desc.lib_name%TYPE; BEGIN lock_api(LOCKAPI_MODIFY, 'update_sbt_library'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_UPD_SBT_LIB, param => 'update_sbt_library' || b_p('lib_name', lib_name, p_first=>TRUE) || b_p('drives', drives ) || b_p('restore_drives', restore_drives ) || b_p('parms', parms ) || b_p('send', send , p_last=>TRUE)); dbms_ra_int.canonicalize(lib_name, c_lib_name, 128); update_sbt_library_int( c_lib_name, drives, restore_drives, parms, send, 'N'); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END update_sbt_library; -- -- PROCEDURE update_bps_for_delete_lib_int(p_db_key IN NUMBER, p_lib_key IN VARCHAR2) IS l_dbid NUMBER; CURSOR bp_c (p_db_key IN NUMBER) IS SELECT bp.rowid bp_rowid, bp.bp_key, bs.bs_key FROM bp, bs WHERE bp.db_key = bp_c.p_db_key AND bp.bs_key = bs.bs_key AND bp.lib_key = p_lib_key FOR UPDATE OF bp.bp_key, bs.bs_key ORDER BY BS.BS_KEY; bpRec bp_c%ROWTYPE; BEGIN -- -- -- -- -- am_trace('update_bps_for_delete: locking db_key: ' || p_db_key); SELECT db_id INTO l_dbid FROM db WHERE db_key = p_db_key FOR UPDATE OF db.db_key; -- OPEN bp_c(p_db_key); FETCH bp_c into bpRec; -- DELETE FROM sbt_catalog ct WHERE ct.bp_key IS NOT NULL AND ct.ftype = 'T' AND ct.db_key = p_db_key AND EXISTS (SELECT 1 FROM bp WHERE bp.bp_key = ct.bp_key AND bp.lib_key = p_lib_key AND bp.db_key = p_db_key AND bp.lib_key IS NOT NULL); am_trace('update_bps_for_delete: deleted sbt_catalog rows: ' || sql%rowcount); -- -- UPDATE bp SET ba_access = 'U' ,lib_key = NULL ,ct_key = NULL ,purged = 'U' WHERE lib_key = p_lib_key AND bp.db_key = p_db_key; am_trace('update_bps_for_delete: updated bp rows: ' || sql%rowcount); CLOSE bp_c; END; -- PROCEDURE delete_sbt_library_int(lib_name IN VARCHAR2, do_commit IN BOOLEAN DEFAULT TRUE) IS l_lib_key NUMBER; l_not_taped_state VARCHAR2(1); BEGIN SELECT lib.lib_key INTO l_lib_key FROM sbt_lib_desc lib WHERE lib.lib_name = delete_sbt_library_int.lib_name; FOR dbrec IN (SELECT DISTINCT db_key FROM sbt_catalog ct WHERE ct.bp_key IS NOT NULL AND ct.ftype = 'T' AND EXISTS (SELECT 1 FROM bp WHERE bp.bp_key = ct.bp_key AND bp.lib_key = l_lib_key AND bp.lib_key IS NOT NULL) ORDER BY db_key) LOOP -- update_bps_for_delete_lib_int(p_db_key => dbrec.db_key, p_lib_key => l_lib_key); -- -- SELECT not_taped_state INTO l_not_taped_state FROM odb WHERE db_key = dbrec.db_key; IF l_not_taped_state IS NOT NULL THEN UPDATE odb SET not_taped_state = 'C' WHERE db_key = dbrec.db_key; dbms_ra_scheduler.log_error ( p_errno => DBMS_RA_SCHEDULER.E_GCOPY_SUSPENDED_NUM, p_param1 => dbms_ra_int.dbkey2name(dbrec.db_key), p_db_key => dbrec.db_key, p_keep_stack => FALSE, p_component => 'UPDATE_POLICY', p_severity => DBMS_RA_SCHEDULER.SEVERITY_WARNING); END IF; END LOOP; -- DELETE FROM sbt_lib_desc lib WHERE lib.lib_key = l_lib_key; -- IF do_commit THEN COMMIT; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN am_trace('delete_sbt_library: ' || item_not_found(lib_name, 'sbt library')); sys.dbms_sys_error.raise_system_error (OBJ_NOT_FOUND_NUM, lib_name, 'sbt library', FALSE); END delete_sbt_library_int; -- PROCEDURE delete_sbt_library(lib_name IN VARCHAR2) IS l_the NUMBER; c_lib_name sbt_lib_desc.lib_name%TYPE; BEGIN dbms_ra_int.canonicalize(lib_name, c_lib_name, 128); IF is_rep_server(c_lib_name) THEN sys.dbms_sys_error.raise_system_error (API_BAD_OBJECT_NUM, 'replication server', 'sbt library', FALSE); END IF; lock_api(LOCKAPI_DELETE, 'delete_sbt_library'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_DEL_SBT_LIB, param => 'delete_sbt_library' || b_p('lib_name', lib_name, p_first=>TRUE, p_last=>TRUE)); delete_sbt_library_int(c_lib_name); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END delete_sbt_library; -- PROCEDURE pause_sbt_library_int(lib_name IN VARCHAR2) IS BEGIN UPDATE sbt_lib_desc lib SET lib.status = 'P', lib.failure_cnt = 0 WHERE lib.lib_name = pause_sbt_library_int.lib_name; -- IF (sql%rowcount = 0) THEN am_trace('pause_sbt_library: ' || item_not_found(lib_name, 'sbt library')); sys.dbms_sys_error.raise_system_error (OBJ_NOT_FOUND_NUM, lib_name, 'sbt library', FALSE); END IF; -- COMMIT; END pause_sbt_library_int; -- PROCEDURE pause_sbt_library(lib_name IN VARCHAR2) IS l_the NUMBER; c_lib_name sbt_lib_desc.lib_name%TYPE; BEGIN dbms_ra_int.canonicalize(lib_name, c_lib_name, 128); IF is_rep_server(c_lib_name) THEN sys.dbms_sys_error.raise_system_error (API_BAD_OBJECT_NUM, 'replication server', 'sbt library', FALSE); END IF; lock_api(LOCKAPI_MODIFY, 'pause_sbt_library'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_PAU_SBT_LIB, param => 'pause_sbt_library' || b_p('lib_name', lib_name, p_first=>TRUE, p_last=>TRUE)); pause_sbt_library_int(c_lib_name); unlock_api(); EXCEPTION WHEN OTHERS THEN unlock_api(); RAISE; END pause_sbt_library; -- PROCEDURE resume_sbt_library_int(lib_name IN VARCHAR2) IS l_lib_key NUMBER; l_server_key NUMBER; BEGIN UPDATE sbt_lib_desc lib SET lib.status = 'R', lib.failure_cnt = 0 WHERE lib.lib_name = resume_sbt_library_int.lib_name RETURNING lib_key, server_key INTO l_lib_key, l_server_key; -- IF (sql%rowcount = 0) THEN am_trace('resume_sbt_library: ' || item_not_found(lib_name, 'sbt library')); sys.dbms_sys_error.raise_system_error (OBJ_NOT_FOUND_NUM, lib_name, 'sbt library', FALSE); END IF; -- -- -- dbms_ra_scheduler.queue_spawn_sbt( p_libkey => l_lib_key, p_forpurge => NULL, p_check_work => TRUE); IF (l_server_key IS NOT NULL) THEN dbms_ra_scheduler.reset_reconcile_timer; END IF; -- COMMIT; -- -- -- -- dbms_ra_scheduler.release_blocked_tasks( dbms_ra_scheduler.LIBRARY_PSEUDO_TASK); END resume_sbt_library_int; -- PROCEDURE resume_sbt_library(lib_name IN VARCHAR2) IS l_the NUMBER; c_lib_name sbt_lib_desc.lib_name%TYPE; BEGIN dbms_ra_int.canonicalize(lib_name, c_lib_name, 128); IF is_rep_server(c_lib_name) THEN sys.dbms_sys_error.raise_system_error (API_BAD_OBJECT_NUM, 'replication server', 'sbt library', FALSE); END IF; lock_api(LOCKAPI_MODIFY, 'resume_sbt_library'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_RES_SBT_LIB, param => 'resume_sbt_library' || b_p('lib_name', lib_name, p_first=>TRUE, p_last=>TRUE)); dbms_ra_int.canonicalize(lib_name, c_lib_name, 128); resume_sbt_library_int(c_lib_name); unlock_api(); EXCEPTION WHEN OTHERS THEN unlock_api(); RAISE; END resume_sbt_library; -- PROCEDURE set_restrict_sbt_instance_int(lib_name IN VARCHAR2, instance_name IN VARCHAR2) IS l_lib_key NUMBER; doexists NUMBER; upper_inst sbt_library_inst_rlist.instance_name%TYPE; BEGIN SELECT lib.lib_key INTO l_lib_key FROM sbt_lib_desc lib WHERE lib.lib_name = set_restrict_sbt_instance_int.lib_name; -- upper_inst := upper(instance_name); MERGE INTO sbt_library_inst_rlist rlist USING dual ON ( rlist.lib_key = l_lib_key AND rlist.instance_name = upper_inst ) WHEN NOT MATCHED THEN INSERT (lib_key, instance_name) VALUES (l_lib_key, upper_inst); -- COMMIT; EXCEPTION WHEN NO_DATA_FOUND THEN am_trace('set_restrict_sbt_instance: ' || item_not_found(lib_name, 'sbt library')); sys.dbms_sys_error.raise_system_error (OBJ_NOT_FOUND_NUM, lib_name, 'sbt library', FALSE); END set_restrict_sbt_instance_int; -- PROCEDURE set_restrict_sbt_instance(lib_name IN VARCHAR2, instance_name IN VARCHAR2) IS l_the NUMBER; c_lib_name sbt_lib_desc.lib_name%TYPE; BEGIN dbms_ra_int.canonicalize(lib_name, c_lib_name, 128); IF is_rep_server(c_lib_name) THEN sys.dbms_sys_error.raise_system_error (API_BAD_OBJECT_NUM, 'replication server', 'sbt library', FALSE); END IF; lock_api(LOCKAPI_CREATE, 'set_restrict_sbt_instance'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_ADD_RESTRICT_SBT_INST, param => 'set_restrict_sbt_instance' || b_p('lib_name', lib_name, p_first=>TRUE) || b_p('instance_name', instance_name , p_last=>TRUE)); set_restrict_sbt_instance_int(c_lib_name, instance_name); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END set_restrict_sbt_instance; -- -- -- PROCEDURE clear_restrict_sbt_inst_int(lib_name IN VARCHAR2, instance_name IN VARCHAR2) IS l_lib_key NUMBER; upper_inst sbt_library_inst_rlist.instance_name%TYPE; BEGIN SELECT lib.lib_key INTO l_lib_key FROM sbt_lib_desc lib WHERE lib.lib_name = clear_restrict_sbt_inst_int.lib_name; -- upper_inst := upper(instance_name); DELETE FROM sbt_library_inst_rlist rlist WHERE rlist.lib_key = l_lib_key AND rlist.instance_name = upper_inst; -- IF (sql%rowcount = 0) THEN am_trace('clear_restrict_sbt_instance: ' || item_not_found(upper_inst, 'instance name')); sys.dbms_sys_error.raise_system_error (OBJ_NOT_FOUND_NUM, upper_inst, 'instance name', FALSE); END IF; -- COMMIT; EXCEPTION WHEN NO_DATA_FOUND THEN am_trace('clear_restrict_sbt_instance: ' || item_not_found(lib_name, 'sbt library')); sys.dbms_sys_error.raise_system_error (OBJ_NOT_FOUND_NUM, lib_name, 'sbt library', FALSE); END clear_restrict_sbt_inst_int; -- PROCEDURE clear_restrict_sbt_instance(lib_name IN VARCHAR2, instance_name IN VARCHAR2) IS l_lib_key NUMBER; upper_inst sbt_library_inst_rlist.instance_name%TYPE; l_the NUMBER; c_lib_name sbt_lib_desc.lib_name%TYPE; BEGIN dbms_ra_int.canonicalize(lib_name, c_lib_name, 128); IF is_rep_server(c_lib_name) THEN sys.dbms_sys_error.raise_system_error (API_BAD_OBJECT_NUM, 'replication server', 'sbt library', FALSE); END IF; lock_api(LOCKAPI_DELETE, 'clear_restrict_sbt_instance'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_DEL_RESTRICT_SBT_INST, param => 'clear_restrict_sbt_instance' || b_p('lib_name', lib_name, p_first=>TRUE) || b_p('instance_name', instance_name , p_last=>TRUE)); clear_restrict_sbt_inst_int(c_lib_name, instance_name); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END clear_restrict_sbt_instance; -- PROCEDURE create_sbt_attr_set_int( lib_name IN VARCHAR2, attr_name IN VARCHAR2, streams IN NUMBER DEFAULT NULL, poolid IN NUMBER DEFAULT NULL, parms IN VARCHAR2 DEFAULT NULL, send IN VARCHAR2 DEFAULT NULL, do_commit IN BOOLEAN DEFAULT TRUE) IS l_lib_key NUMBER; l_drives NUMBER; BEGIN SELECT lib.lib_key, lib.drives INTO l_lib_key, l_drives FROM sbt_lib_desc lib WHERE lib.lib_name = create_sbt_attr_set_int.lib_name; IF (streams <= 0) THEN am_trace('create_sbt_attr_set: num streams too small: ' || TO_CHAR(streams)); sys.dbms_sys_error.raise_system_error(NUM_STREAMS_TOO_SMALL_NUM, FALSE); END IF; IF (streams > l_drives) THEN am_trace('create_sbt_attr_set: num streams ' || TO_CHAR(streams) || ' larger than num drives ' || TO_CHAR(l_drives)); sys.dbms_sys_error.raise_system_error(NUM_STREAMS_TOO_LARGE_NUM, TO_CHAR(streams), TO_CHAR(l_drives), FALSE); END IF; -- INSERT INTO sbt_attr_set (lib_key, attr_key, attr_name, streams, poolid, parms, send) VALUES (l_lib_key, rman_seq.nextval, attr_name, streams, poolid, parms, send); IF do_commit THEN -- COMMIT; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN am_trace('create_sbt_attr_set: ' || item_not_found(lib_name, 'sbt library')); sys.dbms_sys_error.raise_system_error (OBJ_NOT_FOUND_NUM, lib_name, 'sbt library', FALSE); WHEN DUP_VAL_ON_INDEX THEN sys.dbms_sys_error.raise_system_error (DUP_NAME_NUM, attr_name, 'sbt attribute set', FALSE); END create_sbt_attr_set_int; -- PROCEDURE create_sbt_attribute_set( lib_name IN VARCHAR2, attribute_set_name IN VARCHAR2, streams IN NUMBER DEFAULT NULL, poolid IN NUMBER DEFAULT NULL, parms IN VARCHAR2 DEFAULT NULL, send IN VARCHAR2 DEFAULT NULL) IS l_the NUMBER; c_lib_name sbt_lib_desc.lib_name%TYPE; c_attr_name sbt_attr_set.attr_name%TYPE; BEGIN dbms_ra_int.canonicalize(lib_name, c_lib_name, 128); IF is_rep_server(c_lib_name) THEN sys.dbms_sys_error.raise_system_error (API_BAD_OBJECT_NUM, 'replication server', 'sbt library', FALSE); END IF; lock_api(LOCKAPI_CREATE, 'create_sbt_attribute_set'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_ADD_SBT_ATTR_SET, param => 'create_sbt_attribute_set' || b_p('lib_name', lib_name, p_first=>TRUE) || b_p('attribute_set_name', attribute_set_name ) || b_p('streams', streams ) || b_p('poolid', poolid ) || b_p('parms', parms ) || b_p('send', send, p_last=>TRUE)); dbms_ra_int.canonicalize(attribute_set_name, c_attr_name, 128); create_sbt_attr_set_int( c_lib_name, c_attr_name, streams, poolid, parms, send); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END create_sbt_attribute_set; -- PROCEDURE update_sbt_attr_set_int( attr_name IN VARCHAR2, streams IN NUMBER DEFAULT dbms_ra_int.number2null('p1'), poolid IN NUMBER DEFAULT NULL, parms IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p2'), send IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p3')) IS streamsdef BOOLEAN := dbms_ra_int.isparamdef('p1'); parmsdef BOOLEAN := dbms_ra_int.isparamdef('p2'); senddef BOOLEAN := dbms_ra_int.isparamdef('p3'); update_streams VARCHAR2(1) := 'Y'; update_parms VARCHAR2(1) := 'Y'; update_send VARCHAR2(1) := 'Y'; l_streams NUMBER; l_drives NUMBER; l_lib_key NUMBER; BEGIN IF (streamsdef) THEN update_streams := NULL; END IF; IF (parmsdef) THEN update_parms := NULL; END IF; IF (senddef IS NULL) THEN update_send := NULL; END IF; IF (streams <= 0) THEN am_trace('update_sbt_attr_set: num streams too small: ' || TO_CHAR(streams)); sys.dbms_sys_error.raise_system_error(NUM_STREAMS_TOO_SMALL_NUM, FALSE); END IF; UPDATE sbt_attr_set attr SET attr.streams = nvl2(update_streams, update_sbt_attr_set_int.streams, attr.streams), attr.poolid = nvl(update_sbt_attr_set_int.poolid, attr.poolid), attr.parms = nvl2(update_parms, update_sbt_attr_set_int.parms, attr.parms), attr.send = nvl2(update_send, update_sbt_attr_set_int.send, attr.send) WHERE attr.attr_name = update_sbt_attr_set_int.attr_name RETURNING streams, lib_key INTO l_streams, l_lib_key; -- IF (sql%rowcount = 0) THEN am_trace('update_sbt_attr_set: ' || item_not_found(attr_name, 'sbt attribute set')); sys.dbms_sys_error.raise_system_error (OBJ_NOT_FOUND_NUM, attr_name, 'sbt attribute set', FALSE); END IF; SELECT lib.drives INTO l_drives FROM sbt_lib_desc lib WHERE lib.lib_key = l_lib_key; IF (l_streams > l_drives) THEN am_trace('update_sbt_attr: num streams ' || TO_CHAR(l_streams) || ' larger than num drives ' || TO_CHAR(l_drives)); sys.dbms_sys_error.raise_system_error(NUM_STREAMS_TOO_LARGE_NUM, TO_CHAR(l_streams), TO_CHAR(l_drives), FALSE); END IF; -- COMMIT; END update_sbt_attr_set_int; -- PROCEDURE update_sbt_attribute_set( attribute_set_name IN VARCHAR2, streams IN NUMBER DEFAULT dbms_ra_int.number2null('p1'), poolid IN NUMBER DEFAULT NULL, parms IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p2'), send IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p3')) IS l_the NUMBER; c_attr_name sbt_attr_set.attr_name%TYPE; BEGIN lock_api(LOCKAPI_MODIFY, 'update_sbt_attribute_set'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_UPD_SBT_ATTR_SET, param => 'update_sbt_attribute_set' || b_p('attribute_set_name', attribute_set_name, p_first=>TRUE) || b_p('streams', streams ) || b_p('poolid', poolid ) || b_p('parms', parms ) || b_p('send', send , p_last=>TRUE)); dbms_ra_int.canonicalize(attribute_set_name, c_attr_name, 128); update_sbt_attr_set_int( c_attr_name, streams, poolid, parms, send); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END update_sbt_attribute_set; -- PROCEDURE delete_sbt_attr_set_int(attr_name IN VARCHAR2, do_commit IN BOOLEAN DEFAULT TRUE) IS BEGIN DELETE FROM sbt_attr_set attr WHERE attr.attr_name = delete_sbt_attr_set_int.attr_name; -- IF (sql%rowcount = 0) THEN am_trace('delete_sbt_attr_set: ' || item_not_found(attr_name, 'sbt attribute set')); sys.dbms_sys_error.raise_system_error (OBJ_NOT_FOUND_NUM, attr_name, 'sbt attribute set', FALSE); END IF; IF do_commit THEN -- COMMIT; END IF; END delete_sbt_attr_set_int; -- PROCEDURE delete_sbt_attribute_set(attribute_set_name IN VARCHAR2) IS l_the NUMBER; c_attr_name sbt_attr_set.attr_name%TYPE; BEGIN dbms_ra_int.canonicalize(attribute_set_name, c_attr_name, 128); IF is_rep_server(c_attr_name) THEN sys.dbms_sys_error.raise_system_error (API_BAD_OBJECT_NUM, 'replication server', 'sbt attribute', FALSE); END IF; lock_api(LOCKAPI_DELETE, 'delete_sbt_attribute_set'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_DEL_SBT_ATTR_SET, param => 'delete_sbt_library' || b_p('attribute_set_name', attribute_set_name, p_first=>TRUE, p_last=>TRUE)); delete_sbt_attr_set_int(c_attr_name); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END delete_sbt_attribute_set; -- PROCEDURE create_sbt_job_template( template_name IN VARCHAR2, protection_policy_name IN VARCHAR2, attribute_set_name IN VARCHAR2, backup_type IN VARCHAR2, full_template_name IN VARCHAR2 DEFAULT NULL, from_tag IN VARCHAR2 DEFAULT NULL, priority IN NUMBER DEFAULT SBT_PRIORITY_MEDIUM, copies IN NUMBER DEFAULT 1, window IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL) IS l_the NUMBER; c_attr_name sbt_attr_set.attr_name%TYPE; c_prot_name prot.prot_name%TYPE; c_template_name sbt_job_template.template_name%TYPE; c_full_template_name sbt_job_template.template_name%TYPE; c_from_tag sbt_job_template.from_tag%TYPE; BEGIN dbms_ra_int.canonicalize(attribute_set_name, c_attr_name, 128); IF is_rep_server(c_attr_name) THEN sys.dbms_sys_error.raise_system_error (API_BAD_OBJECT_NUM, 'replication server', 'sbt job template', FALSE); END IF; lock_api(LOCKAPI_CREATE, 'create_sbt_job_template'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_ADD_SBT_JOB, param => 'create_sbt_job_template' || b_p('template_name', template_name, p_first=>TRUE) || b_p('protection_policy_name', protection_policy_name) || b_p('attribute_set_name', attribute_set_name) || b_p('backup_type', backup_type ) || b_p('full_template_name', full_template_name) || b_p('from_tag', from_tag ) || b_p('priority', priority ) || b_p('copies', copies ) || b_p('window', window, p_last=>TRUE)); dbms_ra_int.canonicalize(protection_policy_name, c_prot_name, 128); dbms_ra_int.canonicalize(template_name, c_template_name, 128); dbms_ra_int.canonicalize(full_template_name, c_full_template_name, 128); dbms_ra_int.canonicalize(from_tag, c_from_tag, 32); dbms_ra_int.create_sbt_job_template_int( template_name => c_template_name, prot_name => c_prot_name, attr_name => c_attr_name, backup_type => upper(backup_type), full_template_name => c_full_template_name, from_tag => c_from_tag, priority => priority, copies => copies, window => window); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END create_sbt_job_template; -- PROCEDURE create_sbt_job_template( template_name IN VARCHAR2, db_unique_name IN VARCHAR2, attribute_set_name IN VARCHAR2, backup_type IN VARCHAR2, full_template_name IN VARCHAR2 DEFAULT NULL, from_tag IN VARCHAR2 DEFAULT NULL, priority IN NUMBER DEFAULT SBT_PRIORITY_MEDIUM, copies IN NUMBER DEFAULT 1, window IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL) IS l_the NUMBER; c_attr_name sbt_attr_set.attr_name%TYPE; c_template_name sbt_job_template.template_name%TYPE; c_full_template_name sbt_job_template.template_name%TYPE; c_from_tag sbt_job_template.from_tag%TYPE; BEGIN dbms_ra_int.canonicalize(attribute_set_name, c_attr_name, 128); IF is_rep_server(c_attr_name) THEN sys.dbms_sys_error.raise_system_error (API_BAD_OBJECT_NUM, 'replication server', 'sbt job template', FALSE); END IF; lock_api(LOCKAPI_CREATE, 'create_sbt_job_template'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_ADD_SBT_JOB, param => 'create_sbt_job_template' || b_p('template_name', template_name, p_first=>TRUE ) || b_p('db_unique_name', db_unique_name ) || b_p('attribute_set_name', attribute_set_name ) || b_p('backup_type', backup_type ) || b_p('full_template_name', full_template_name ) || b_p('from_tag', from_tag ) || b_p('priority', priority ) || b_p('copies', copies ) || b_p('window', window , p_last=>TRUE)); dbms_ra_int.canonicalize(template_name, c_template_name, 128); dbms_ra_int.canonicalize(full_template_name, c_full_template_name, 128); dbms_ra_int.canonicalize(from_tag, c_from_tag, 32); dbms_ra_int.create_sbt_job_template_int( template_name => c_template_name, db_unique_name => upper(db_unique_name), attr_name => c_attr_name, backup_type => upper(backup_type), full_template_name => c_full_template_name, from_tag => c_from_tag, priority => priority, copies => copies, window => window); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END create_sbt_job_template; -- PROCEDURE update_sbt_job_template_int( template_name IN VARCHAR2, attr_name IN VARCHAR2 DEFAULT NULL, backup_type IN VARCHAR2 DEFAULT NULL, from_tag IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p1'), priority IN NUMBER DEFAULT NULL, copies IN NUMBER DEFAULT NULL, window IN DSINTERVAL_UNCONSTRAINED DEFAULT dbms_ra_int.intervalnull('p2')) IS CURSOR sbt_task_c(l_template_key IN NUMBER, old_attr_key IN NUMBER) IS SELECT rowid FROM sbt_task st WHERE st.template_key = l_template_key AND st.attr_key = old_attr_key ORDER BY st.task_id; l_rowids dbms_sql.urowid_table; fromtagdef BOOLEAN := dbms_ra_int.isparamdef('p1'); update_fromtag VARCHAR2(1) := 'Y'; windowdef BOOLEAN := dbms_ra_int.isparamdef('p2'); update_window VARCHAR2(1) := 'Y'; l_attr_key NUMBER := NULL; l_bck_type NUMBER := NULL; l_t_btype NUMBER := NULL; l_invalid_val VARCHAR(128); l_template_key NUMBER; old_attr_key NUMBER; BEGIN IF (copies < 1 OR copies > 4) THEN am_trace('update_sbt_job: num copies invalid: ' || pparm(copies)); sys.dbms_sys_error.raise_system_error(BAD_NUM_COPIES_NUM, pparm(copies), FALSE); END IF; IF (attr_name IS NOT NULL) THEN -- BEGIN SELECT attr.attr_key INTO l_attr_key FROM sbt_attr_set attr WHERE attr.attr_name = update_sbt_job_template_int.attr_name; EXCEPTION WHEN NO_DATA_FOUND THEN am_trace('update_sbt_job: ' || item_not_found(attr_name, 'sbt attribute set')); sys.dbms_sys_error.raise_system_error (OBJ_NOT_FOUND_NUM, attr_name, 'sbt attribute set', FALSE); END; END IF; IF (fromtagdef) THEN update_fromtag := NULL; END IF; IF (windowdef) THEN update_window := NULL; END IF; IF (backup_type IS NOT NULL) THEN l_bck_type := dbms_ra_int.sbt_job_backup_type_to_num(backup_type); SELECT job.bck_type INTO l_t_btype FROM sbt_job_template job WHERE job.template_name = update_sbt_job_template_int.template_name; -- IF (l_t_btype != l_bck_type) THEN sys.dbms_sys_error.raise_system_error (INVALID_PARAM_NUM, backup_type, 'for given template', FALSE); END IF; END IF; IF (l_attr_key IS NOT NULL) THEN SELECT job.attr_key, job.template_key INTO old_attr_key, l_template_key FROM sbt_job_template job WHERE job.template_name = update_sbt_job_template_int.template_name FOR UPDATE; OPEN sbt_task_c(l_template_key, old_attr_key); LOOP FETCH sbt_task_c BULK COLLECT INTO l_rowids LIMIT 1000; EXIT WHEN l_rowids.COUNT = 0; FORALL i IN 1..l_rowids.COUNT UPDATE sbt_task SET attr_key = l_attr_key WHERE rowid = l_rowids(i); END LOOP; CLOSE sbt_task_c; END IF; UPDATE sbt_job_template job SET job.attr_key = nvl(l_attr_key, job.attr_key), job.bck_type = nvl(l_bck_type, job.bck_type), job.from_tag = nvl2(update_fromtag, update_sbt_job_template_int.from_tag, job.from_tag), job.priority = nvl(update_sbt_job_template_int.priority, job.priority), job.copies = nvl(update_sbt_job_template_int.copies, job.copies), job.window = nvl2(update_window, update_sbt_job_template_int.window, job.window) WHERE job.template_name = update_sbt_job_template_int.template_name; -- IF (sql%rowcount = 0) THEN am_trace('update_sbt_job: ' || item_not_found(template_name, 'sbt job template')); sys.dbms_sys_error.raise_system_error (OBJ_NOT_FOUND_NUM, template_name, 'Sbt Job Template', FALSE); END IF; -- COMMIT; EXCEPTION WHEN INVALID_VAL THEN IF l_invalid_val IS NOT NULL THEN am_trace('update_sbt_job_template_int raising invalid value: ' || l_invalid_val); sys.dbms_sys_error.raise_system_error (INVALID_VAL_NUM, l_invalid_val, FALSE); ELSE RAISE; END IF; END update_sbt_job_template_int; -- PROCEDURE update_sbt_job_template( template_name IN VARCHAR2, attribute_set_name IN VARCHAR2 DEFAULT NULL, backup_type IN VARCHAR2 DEFAULT NULL, from_tag IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p1'), priority IN NUMBER DEFAULT NULL, copies IN NUMBER DEFAULT NULL, window IN DSINTERVAL_UNCONSTRAINED DEFAULT dbms_ra_int.intervalnull('p2')) IS l_the NUMBER; c_attr_name sbt_attr_set.attr_name%TYPE; c_template_name sbt_job_template.template_name%TYPE; c_from_tag sbt_job_template.from_tag%TYPE; BEGIN dbms_ra_int.canonicalize(template_name, c_template_name, 128); IF is_rep_server(c_template_name) THEN sys.dbms_sys_error.raise_system_error (API_BAD_OBJECT_NUM, 'replication server', 'sbt job template', FALSE); END IF; dbms_ra_int.canonicalize(attribute_set_name, c_attr_name, 128); IF is_rep_server(c_attr_name) THEN sys.dbms_sys_error.raise_system_error (API_BAD_OBJECT_NUM, 'replication server', 'sbt job template', FALSE); END IF; lock_api(LOCKAPI_MODIFY, 'update_sbt_job_template'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_UPD_SBT_JOB, param => 'update_sbt_job_template' || b_p('template_name', template_name, p_first=>TRUE ) || b_p('attribute_set_name', attribute_set_name ) || b_p('backup_type', backup_type ) || b_p('priority', priority ) || b_p('window', window ) || b_p('copies', copies , p_last=>TRUE)); dbms_ra_int.canonicalize(from_tag, c_from_tag, 32); update_sbt_job_template_int( c_template_name, c_attr_name, upper(backup_type), c_from_tag, priority, copies, window); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END update_sbt_job_template; -- PROCEDURE delete_sbt_job_template_int(template_name IN VARCHAR2, do_commit IN BOOLEAN DEFAULT TRUE) IS l_cnt NUMBER; BEGIN SELECT /*+ OPT_PARAM('_optimizer_join_elimination_enabled' 'false') */ COUNT(*) INTO l_cnt FROM sbt_job_template a WHERE EXISTS (SELECT 1 FROM sbt_job_template b WHERE b.template_key = a.full_template_key AND b.template_name = delete_sbt_job_template_int.template_name); IF l_cnt > 1 THEN RAISE OBJ_IS_REFERENCED; END IF; DELETE FROM sbt_job_template job WHERE job.template_name = delete_sbt_job_template_int.template_name; -- IF (sql%rowcount = 0) THEN am_trace('delete_sbt_job: ' || item_not_found(template_name, 'sbt job template')); sys.dbms_sys_error.raise_system_error (OBJ_NOT_FOUND_NUM, template_name, 'Sbt Job Template', FALSE); END IF; -- COMMIT; EXCEPTION WHEN OBJ_IS_REFERENCED THEN am_trace('Reference INCR/ARCH job template exists for a given' || ' FULL template ' || template_name); sys.dbms_sys_error.raise_system_error (OBJ_IS_REFERENCED_NUM, 'Sbt Template Job', template_name, FALSE); RAISE; END delete_sbt_job_template_int; -- PROCEDURE delete_sbt_job_template(template_name IN VARCHAR2) IS l_the NUMBER; c_template_name sbt_job_template.template_name%TYPE; BEGIN dbms_ra_int.canonicalize(template_name, c_template_name, 128); IF is_rep_server(c_template_name) THEN sys.dbms_sys_error.raise_system_error (API_BAD_OBJECT_NUM, 'replication server', 'sbt job template', FALSE); END IF; lock_api(LOCKAPI_DELETE, 'delete_sbt_job'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_DEL_SBT_JOB, param => 'delete_sbt_job_template' || b_p('template_name', template_name, p_first=>TRUE, p_last=>TRUE)); delete_sbt_job_template_int(c_template_name); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END delete_sbt_job_template; -- -- -- PROCEDURE queue_sbt_backup_task(template_name IN VARCHAR2) IS c_template_name sbt_job_template.template_name%TYPE; BEGIN dbms_ra_int.canonicalize(template_name, c_template_name, 128); IF is_rep_server(c_template_name) THEN sys.dbms_sys_error.raise_system_error (API_BAD_OBJECT_NUM, 'replication server', 'sbt job template', FALSE); END IF; dbms_ra_scheduler.queue_sbt_backup_task(c_template_name); END queue_sbt_backup_task; -- -- PROCEDURE abort_sbt_task(task_id IN NUMBER) IS l_job_name sessions.job_name%type; BEGIN SELECT s.job_name INTO l_job_name FROM sessions s WHERE s.current_task = abort_sbt_task.task_id AND s.current_task_type IN (dbms_ra_scheduler.TASK_BACKUP_SBT, dbms_ra_scheduler.TASK_RESTORE_SBT, dbms_ra_scheduler.TASK_PURGE_SBT); dbms_scheduler.stop_job(job_name => l_job_name, force => TRUE); EXCEPTION WHEN no_data_found THEN sys.dbms_sys_error.raise_system_error(SBT_TASK_NOT_FOUND_NUM, TO_CHAR(task_id), FALSE); END abort_sbt_task; -- FUNCTION extract_host_name(input_url IN varchar2) RETURN varchar2 IS host_name varchar2(512) := regexp_substr( input_url, '^(https?://)?([^:/]*)', 1, 1, 'i', 2); BEGIN am_trace('extract_host_name host_name=' || host_name); RETURN host_name; END extract_host_name; -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE grant_network_acl_ace(catalog_user_name VARCHAR2, wallet_alias VARCHAR2, wallet_path VARCHAR2) IS r_avm_server server%ROWTYPE; l_owner user_users.username%TYPE; CURSOR hostlst_c(hostlst IN VARCHAR2) IS WITH table_to_parse as (select hostlst str from dual) SELECT DISTINCT upper(ltrim(rtrim(new_str))) new_str FROM table_to_parse, xmltable('r/c' passing xmltype('' || replace(str,',','') || '') columns new_str varchar2(512) path '.'); BEGIN l_owner := SYS.rai_schema(TRUE); SELECT * INTO r_avm_server FROM server WHERE wallet_alias = grant_network_acl_ace.wallet_alias AND nvl(wallet_path,'') = nvl(grant_network_acl_ace.wallet_path, '') AND filter_user = catalog_user_name; IF (r_avm_server.wallet_path IS NOT NULL) THEN am_trace ('grant_network_acl_ace wallet: ' || r_avm_server.wallet_path || ' catalog_user_name=' || catalog_user_name || ' acl_owner_name=' || l_owner); sys.dbms_network_acl_admin.append_wallet_ace( wallet_path => r_avm_server.wallet_path, ace => xs$ace_type(privilege_list => xs$name_list('use_passwords'), principal_name => l_owner, principal_type => xs_acl.ptype_db)); END IF; FOR hostRec IN hostlst_c(r_avm_server.server_host) LOOP am_trace ('grant_network_acl_ace host: ' || extract_host_name(hostRec.new_str) || ' server_port=' || r_avm_server.server_port || ' catalog_user_name=' || catalog_user_name || ' acl_owner_name=' || l_owner); sys.dbms_network_acl_admin.append_host_ace( host => extract_host_name(hostRec.new_str), lower_port => r_avm_server.server_port, ace => xs$ace_type(privilege_list => xs$name_list('connect'), principal_name => l_owner, principal_type => xs_acl.ptype_db)); END LOOP; IF r_avm_server.proxy_url IS NOT NULL THEN am_trace ('grant_network_acl_ace proxy: ' || extract_host_name(r_avm_server.proxy_url) || ' port=' || r_avm_server.proxy_port || ' catalog_user_name=' || catalog_user_name || ' acl_owner_name=' || l_owner); sys.dbms_network_acl_admin.append_host_ace( host => extract_host_name(r_avm_server.proxy_url), lower_port => r_avm_server.proxy_port, ace => xs$ace_type(privilege_list => xs$name_list('connect'), principal_name => l_owner, principal_type => xs_acl.ptype_db)); END IF; EXCEPTION WHEN OTHERS THEN rollback; am_trace ('grant_network_acl_ace exception: ' || ' catalog_user_name: ' || catalog_user_name || ' wallet_alias: ' || wallet_alias || ' wallet_path: ' || wallet_path || ' err: ' || SQLERRM); revoke_network_acl_ace(catalog_user_name, wallet_alias, wallet_path); RAISE; END grant_network_acl_ace; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION add_repository(catalog_user_name VARCHAR2, new_server_key NUMBER, am_server_name VARCHAR2, wallet_alias VARCHAR2, wallet_path VARCHAR2, proxy_url VARCHAR2 DEFAULT NULL, proxy_port NUMBER DEFAULT NULL, http_timeout NUMBER DEFAULT NULL ) RETURN NUMBER IS l_server_key NUMBER; l_the NUMBER; l_port NUMBER; l_ssl BOOLEAN; l_hostlst VARCHAR2(8192); BEGIN l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_ADD_REPOSITORY, param => 'add_repository' || b_p('catalog_user_name', catalog_user_name, p_first=>TRUE) || b_p('new_server_key',new_server_key ) || b_p('am_server_name',am_server_name ) || b_p('wallet_alias', wallet_alias ) || b_p('wallet_path', wallet_path ) || b_p('proxy_url', proxy_url ) || b_p('proxy_port', proxy_port ) || b_p('http_timeout', http_timeout , p_last=>TRUE)); sys.kbrsi_icd.wallet2hostlst( wallet_loc => wallet_path, cred_alias => wallet_alias, hostlst => l_hostlst, port => l_port, ssl => l_ssl, client => 'REPLICATION'); IF (l_port IS NULL OR l_port <= 0) THEN am_trace('add_repository raising invalid value: ' || 'HTTP server not configured at replication host'); sys.dbms_sys_error.raise_system_error (INVALID_VAL_NUM, 'HTTP server not configured at replication host', FALSE); END IF; INSERT INTO server (server_key, filter_user, server_host, server_port, wallet_alias, wallet_path, proxy_url, proxy_port, timeout_secs, rep_server_name) VALUES (add_repository.new_server_key, add_repository.catalog_user_name, l_hostlst, l_port, add_repository.wallet_alias, add_repository.wallet_path, add_repository.proxy_url, add_repository.proxy_port, add_repository.http_timeout, add_repository.am_server_name); grant_network_acl_ace(catalog_user_name, wallet_alias, wallet_path); RETURN new_server_key; END add_repository; -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE revoke_network_acl_ace(catalog_user_name IN VARCHAR2, wallet_alias IN VARCHAR2, wallet_path IN VARCHAR2) IS r_avm_server server%ROWTYPE; l_owner user_users.username%TYPE; CURSOR hostlst_c(hostlst IN VARCHAR2) IS WITH table_to_parse as (select hostlst str from dual) SELECT DISTINCT upper(ltrim(rtrim(new_str))) new_str FROM table_to_parse, xmltable('r/c' passing xmltype('' || replace(str,',','') || '') columns new_str varchar2(512) path '.'); E_COULD_NOT_REVOKE EXCEPTION; PRAGMA EXCEPTION_INIT (E_COULD_NOT_REVOKE, -1927); BEGIN l_owner := SYS.rai_schema(TRUE); SELECT * INTO r_avm_server FROM server WHERE wallet_alias = revoke_network_acl_ace.wallet_alias AND nvl(wallet_path,'') = nvl(revoke_network_acl_ace.wallet_path, '') AND filter_user = catalog_user_name; FOR hostRec IN hostlst_c(r_avm_server.server_host) LOOP BEGIN dbms_network_acl_admin.remove_host_ace( host => extract_host_name(hostRec.new_str), lower_port => r_avm_server.server_port, ace => xs$ace_type(privilege_list => xs$name_list('connect'), principal_name => l_owner, granted => true, principal_type => xs_acl.ptype_db)); EXCEPTION WHEN E_COULD_NOT_REVOKE THEN am_trace ('revoke_network_acl no_revoke: remove_host_ace: ' || ' catalog_user_name: ' || catalog_user_name || ' acl_owner_name=' || l_owner || ' wallet_alias: ' || wallet_alias || ' wallet_path: ' || wallet_path || ' host: ' || extract_host_name(hostRec.new_str) || ' err: ' || SQLERRM); WHEN OTHERS THEN am_trace ('revoke_network_acl exception: ' || ' catalog_user_name: ' || catalog_user_name || ' acl_owner_name=' || l_owner || ' wallet_alias: ' || wallet_alias || ' wallet_path: ' || wallet_path || ' host: ' || extract_host_name(hostRec.new_str) || ' err: ' || SQLERRM); END; END LOOP; IF (r_avm_server.wallet_path IS NOT NULL) THEN BEGIN dbms_network_acl_admin.remove_wallet_ace( wallet_path => r_avm_server.wallet_path, ace => xs$ace_type(privilege_list => xs$name_list('use_passwords'), principal_name => l_owner, granted => true, principal_type => xs_acl.ptype_db)); EXCEPTION WHEN OTHERS THEN am_trace ('revoke_network_acl exception: remove_wallet_ace: ' || ' catalog_user_name: ' || catalog_user_name || ' acl_owner_name=' || l_owner || ' wallet_alias: ' || wallet_alias || ' wallet_path: ' || wallet_path || ' err: ' || SQLERRM); END; END IF; IF r_avm_server.proxy_url IS NOT NULL THEN BEGIN dbms_network_acl_admin.remove_host_ace( host => r_avm_server.proxy_url, lower_port => r_avm_server.proxy_port, ace => xs$ace_type(privilege_list => xs$name_list('connect'), principal_name => l_owner, granted => true, principal_type => xs_acl.ptype_db)); EXCEPTION WHEN OTHERS THEN am_trace ('revoke_network_acl exception: remove_host_ace: ' || ' catalog_user_name: ' || catalog_user_name || ' acl_owner_name=' || l_owner || ' wallet_alias: ' || wallet_alias || ' wallet_path: ' || wallet_path || ' proxy host: ' || r_avm_server.proxy_url || ' err: ' || SQLERRM); END; END IF; END revoke_network_acl_ace; -- -- -- -- -- -- -- -- PROCEDURE delete_repository(catalog_user_name IN VARCHAR2, wallet_alias IN VARCHAR2, wallet_path IN VARCHAR2) IS l_the NUMBER; BEGIN l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_DEL_REPOSITORY, param => 'delete_repository' || b_p('catalog_user_name', catalog_user_name, p_first=>TRUE) || b_p('wallet_alias', wallet_alias) || b_p('wallet_path', wallet_path , p_last=>TRUE)); revoke_network_acl_ace(catalog_user_name, wallet_alias, wallet_path); DELETE server WHERE wallet_alias = delete_repository.wallet_alias AND wallet_path = delete_repository.wallet_path AND filter_user = catalog_user_name; END delete_repository; -- -- -- -- -- -- FUNCTION build_parms_for_rep (p_user_parms IN VARCHAR2, p_wallet_path IN VARCHAR2, p_wallet_alias IN VARCHAR2, p_proxy_url IN VARCHAR2, p_proxy_port IN NUMBER, p_sbt_so_name IN VARCHAR2) RETURN VARCHAR2 IS l_sbt_parms sbt_lib_desc.parms%TYPE; l_port_str VARCHAR2(7); BEGIN l_sbt_parms := 'SBT_PARMS=('; IF p_user_parms IS NOT NULL THEN l_sbt_parms := l_sbt_parms || p_user_parms || ', '; END IF; l_sbt_parms := l_sbt_parms || 'RA_WALLET="'; IF p_wallet_path IS NOT NULL THEN l_sbt_parms := l_sbt_parms || 'LOCATION=' || p_wallet_path || ' '; END IF; l_sbt_parms := l_sbt_parms || 'CREDENTIAL_ALIAS=' || p_wallet_alias || '"'; IF p_proxy_url IS NOT NULL THEN l_port_str := NULL; IF p_proxy_port IS NOT NULL THEN l_port_str := ':' || p_proxy_port; END IF; l_sbt_parms := l_sbt_parms || ', RA_PROXY=' || p_proxy_url || l_port_str; END IF; l_sbt_parms := l_sbt_parms || ', RA_REPLICATION=TRUE'; l_sbt_parms := l_sbt_parms || ')'; RETURN 'SBT_LIBRARY=' || p_sbt_so_name || ', ' || l_sbt_parms; END build_parms_for_rep; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE create_replication_server_int ( replication_server_name IN VARCHAR2, sbt_so_name IN VARCHAR2, sbt_parms IN VARCHAR2 DEFAULT NULL, max_streams IN NUMBER DEFAULT NULL, catalog_user_name IN VARCHAR2, wallet_alias IN VARCHAR2, wallet_path IN VARCHAR2, proxy_url IN VARCHAR2 DEFAULT NULL, proxy_port IN NUMBER DEFAULT NULL, http_timeout IN NUMBER DEFAULT NULL) IS num_of NUMBER; l_obj_type VARCHAR2(128); l_obj_name VARCHAR2(128); l_server_key NUMBER; l_missing_param VARCHAR2(128); l_sbt_parms sbt_lib_desc.parms%TYPE; l_addrepos_done BOOLEAN := FALSE; l_rep_lib_name sbt_lib_desc.lib_name%TYPE; l_rep_atr_name sbt_attr_set.attr_name%TYPE; BEGIN -- IF length(replication_server_name) > 128 THEN am_trace('create_replication_server:' || ' replication_server_name too long: ' || TO_CHAR(length(replication_server_name)) || ', "' || replication_server_name || '"'); sys.dbms_sys_error.raise_system_error( REP_SRVR_NM_BAD_LEN_NUM, TO_CHAR(length(replication_server_name)), FALSE); END IF; IF proxy_port <= 0 THEN am_trace('create_replication_server: proxy port <= 0: ' || TO_CHAR(proxy_port)); sys.dbms_sys_error.raise_system_error(REP_SRVR_BAD_PORT_NUM, TO_CHAR(proxy_port), FALSE); END IF; IF (proxy_url IS NOT NULL AND proxy_port IS NULL) THEN am_trace('create_replication_server:' || ' Proxy Port: NULL, Proxy URL: ' || proxy_url); sys.dbms_sys_error.raise_system_error(REP_SRVR_PORT_NULL_NUM, FALSE); END IF; IF (proxy_url IS NULL AND proxy_port IS NOT NULL) THEN am_trace('create_replication_server:' || ' Proxy Port: ' || TO_CHAR(proxy_port) || ', Proxy URL: NULL'); sys.dbms_sys_error.raise_system_error(REP_SRVR_PROXY_NULL_NUM, FALSE); END IF; IF replication_server_name IS NULL THEN l_missing_param := 'replication_server_name'; RAISE MISSING_PARAM; END IF; IF sbt_so_name IS NULL THEN l_missing_param := 'sbt_so_name'; RAISE MISSING_PARAM; END IF; -- -- SELECT count(*) INTO num_of FROM server WHERE rep_server_name=replication_server_name; IF num_of > 0 THEN -- l_obj_type := 'replication server already exists'; l_obj_name := replication_server_name; RAISE DUP_VAL_ON_INDEX; END IF; -- l_server_key := rman_seq.nextval; l_rep_lib_name := dbms_ra_int.build_rep_lib_name(replication_server_name, l_server_key); l_rep_atr_name := dbms_ra_int.build_rep_atr_name(replication_server_name, l_server_key); -- -- -- -- SELECT count(*) INTO num_of FROM sbt_lib_desc WHERE sbt_lib_desc.lib_name=l_rep_lib_name; IF num_of > 0 THEN -- l_obj_type := 'replication server has an existing sbt lib description'; l_obj_name := replication_server_name; RAISE DUP_VAL_ON_INDEX; END IF; -- -- SELECT count(*) INTO num_of FROM sbt_attr_set WHERE sbt_attr_set.attr_name=l_rep_atr_name; IF num_of > 0 THEN -- l_obj_type := 'replication server has an existing sbt attribute set name'; l_obj_name := replication_server_name; RAISE DUP_VAL_ON_INDEX; END IF; am_trace('CREATE_REPLICATION_SERVER: ' || 'replication_server_name=' || replication_server_name || 'rep_server_lib_name=' || l_rep_lib_name || 'rep_server_atr_name=' || l_rep_atr_name || ', sbt_so_name=' || sbt_so_name || ', sbt_parms=' || sbt_parms); -- -- l_server_key := add_repository( catalog_user_name => create_replication_server_int.catalog_user_name, new_server_key => l_server_key, am_server_name => create_replication_server_int.replication_server_name, wallet_alias => create_replication_server_int.wallet_alias, wallet_path => create_replication_server_int.wallet_path, proxy_url => create_replication_server_int.proxy_url, proxy_port => create_replication_server_int.proxy_port, http_timeout => create_replication_server_int.http_timeout); l_addrepos_done := TRUE; -- -- l_sbt_parms := build_parms_for_rep ( p_user_parms => create_replication_server_int.sbt_parms, p_wallet_path => create_replication_server_int.wallet_path , p_wallet_alias => create_replication_server_int.wallet_alias, p_proxy_url => create_replication_server_int.proxy_url , p_proxy_port => create_replication_server_int.proxy_port , p_sbt_so_name => create_replication_server_int.sbt_so_name); am_trace('CREATE_REPLICATION_SERVER: l_parms=' || l_sbt_parms); -- -- -- -- -- create_sbt_library_int( lib_name => l_rep_lib_name, drives => max_streams, parms => l_sbt_parms, server_key => l_server_key, p_status => 'P', do_commit => FALSE); create_sbt_attr_set_int( lib_name => l_rep_lib_name, attr_name => l_rep_atr_name, do_commit => FALSE); COMMIT; EXCEPTION WHEN REP_SRVR_NM_BAD_LEN OR REP_SRVR_BAD_PORT OR REP_SRVR_PORT_NULL OR REP_SRVR_PROXY_NULL THEN IF l_addrepos_done THEN delete_repository(create_replication_server_int.catalog_user_name, create_replication_server_int.wallet_alias, create_replication_server_int.wallet_path); END IF; ROLLBACK; RAISE; WHEN DUP_VAL_ON_INDEX THEN IF l_addrepos_done THEN delete_repository(create_replication_server_int.catalog_user_name, create_replication_server_int.wallet_alias, create_replication_server_int.wallet_path); END IF; ROLLBACK; IF l_obj_type IS NOT NULL THEN sys.dbms_sys_error.raise_system_error(DUP_NAME_NUM, l_obj_name, l_obj_type, FALSE); ELSE RAISE; END IF; WHEN MISSING_PARAM THEN IF l_addrepos_done THEN delete_repository(create_replication_server_int.catalog_user_name, create_replication_server_int.wallet_alias, create_replication_server_int.wallet_path); END IF; ROLLBACK; IF l_missing_param IS NOT NULL THEN am_trace ('create_replication_server: required parameter missing' || l_missing_param); sys.dbms_sys_error.raise_system_error(MISSING_PARAM_NUM, l_missing_param, FALSE); ELSE RAISE; END IF; WHEN OTHERS THEN IF l_addrepos_done THEN delete_repository(create_replication_server_int.catalog_user_name, create_replication_server_int.wallet_alias, create_replication_server_int.wallet_path); END IF; ROLLBACK; am_trace ('create_replication_server: EXCEPTION: ' || SQLERRM); RAISE; END create_replication_server_int; -- PROCEDURE create_replication_server ( replication_server_name IN VARCHAR2, sbt_so_name IN VARCHAR2, sbt_parms IN VARCHAR2 DEFAULT NULL, max_streams IN NUMBER DEFAULT NULL, catalog_user_name IN VARCHAR2, wallet_alias IN VARCHAR2, wallet_path IN VARCHAR2, proxy_url IN VARCHAR2 DEFAULT NULL, proxy_port IN NUMBER DEFAULT NULL, http_timeout IN NUMBER DEFAULT NULL) IS l_the NUMBER; c_rep_srv_name server.rep_server_name%TYPE; u_catalog_user_name server.filter_user%TYPE; BEGIN dbms_ra_int.canonicalize(replication_server_name, c_rep_srv_name, 128); IF is_sysgen_obj(c_rep_srv_name) THEN sys.dbms_sys_error.raise_system_error (API_BAD_OBJECT_NUM, 'replication server', 'system object', FALSE); END IF; lock_api(LOCKAPI_CREATE, 'create_replication_server'); u_catalog_user_name := upper(catalog_user_name); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_CRE_REP_SERVER, param => 'create_replication_server' || b_p('replication_server_name', replication_server_name, p_first=>TRUE) || b_p('sbt_so_name', sbt_so_name ) || b_p('sbt_parms', sbt_parms ) || b_p('max_streams', max_streams ) || b_p('catalog_user_name', u_catalog_user_name ) || b_p('wallet_alias', wallet_alias ) || b_p('wallet_path', wallet_path ) || b_p('proxy_url', proxy_url ) || b_p('proxy_port', proxy_port ) || b_p('http_timeout', http_timeout , p_last=>TRUE)); -- -- -- -- ctrl_c_check(CCCHK_CREDEL_REP_SERVER); create_replication_server_int (c_rep_srv_name, sbt_so_name, sbt_parms, max_streams, u_catalog_user_name, wallet_alias, wallet_path, proxy_url, proxy_port, http_timeout); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END create_replication_server; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE update_replication_server_int ( replication_server_name IN VARCHAR2, sbt_so_name IN VARCHAR2 DEFAULT NULL, sbt_parms IN VARCHAR2 DEFAULT NULL, max_streams IN NUMBER DEFAULT dbms_ra_int.number2null('p4'), catalog_user_name IN VARCHAR2 DEFAULT NULL, wallet_alias IN VARCHAR2 DEFAULT NULL, wallet_path IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p1'), proxy_url IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p2'), proxy_port IN NUMBER DEFAULT dbms_ra_int.number2null('p3'), http_timeout IN NUMBER DEFAULT NULL) IS num_of NUMBER; l_repsrv_status VARCHAR2(1); l_obj_type VARCHAR2(128); l_obj_name VARCHAR2(128); l_parms VARCHAR2(2048); l_old_parms VARCHAR2(2048); l_lib_name sbt_lib_desc.lib_name%TYPE; l_dynamic_drives sbt_lib_desc.dynamic_drives%TYPE; l_missing_param VARCHAR2(128); l_old_server server%ROWTYPE; l_new_server server%ROWTYPE; l_sbt_parms sbt_lib_desc.parms%TYPE; l_sbt_so_name sbt_lib_desc.parms%TYPE; l_streamsdef BOOLEAN := dbms_ra_int.isparamdef('p4'); l_port NUMBER; l_ssl BOOLEAN; l_hostlst VARCHAR2(8192); l_walpath_def BOOLEAN := dbms_ra_int.isparamdef('p1'); l_pxy_def BOOLEAN := dbms_ra_int.isparamdef('p2'); l_pxyport_def BOOLEAN := dbms_ra_int.isparamdef('p3'); l_grant_network BOOLEAN := FALSE; l_rep_lib_name sbt_lib_desc.lib_name%TYPE; l_wallet_path server.wallet_path%TYPE; l_wallet_alias server.wallet_alias%TYPE; BEGIN am_trace('UPDATE_REPLICATION_SERVER: replication_server_name=' || replication_server_name || ', sbt_so_name=' || sbt_so_name || ', sbt_parms=' || sbt_parms || ', max_streams=' || max_streams || ', catalog_user_name=' || catalog_user_name || ', wallet_alias=' || wallet_alias || ', wallet_path=' || wallet_path || ', proxy_url=' || proxy_url || ', proxy_port=' || proxy_port || ', http_timeout=' || http_timeout); -- BEGIN SELECT * INTO l_old_server FROM server WHERE server.rep_server_name=replication_server_name; EXCEPTION WHEN NO_DATA_FOUND THEN l_obj_type := 'replication server'; l_obj_name := replication_server_name; RAISE OBJ_NOT_FOUND; END; BEGIN SELECT lib_name, status INTO l_lib_name, l_repsrv_status FROM sbt_lib_desc WHERE server_key = l_old_server.server_key; EXCEPTION WHEN NO_DATA_FOUND THEN l_obj_type := 'replication server has an existing sbt lib description'; l_obj_name := replication_server_name; RAISE OBJ_NOT_FOUND; END; -- IF (NOT l_streamsdef) THEN IF (max_streams IS NULL) THEN l_dynamic_drives := 'Y'; ELSE l_dynamic_drives := 'N'; END IF; update_sbt_library_int(lib_name => l_lib_name, drives => max_streams, dynamic_drives => l_dynamic_drives); END IF; -- -- IF l_repsrv_status = 'R' AND (sbt_so_name IS NOT NULL OR sbt_parms IS NOT NULL OR catalog_user_name IS NOT NULL OR wallet_alias IS NOT NULL OR NOT l_walpath_def OR NOT l_pxy_def OR NOT l_pxyport_def OR http_timeout IS NOT NULL) THEN RAISE REP_SRVR_RUNNING; END IF; l_new_server := l_old_server; -- IF (NOT l_pxyport_def OR NOT l_pxy_def OR NOT l_walpath_def OR wallet_alias IS NOT NULL) THEN revoke_network_acl_ace(l_old_server.filter_user, l_old_server.wallet_alias, l_old_server.wallet_path); l_grant_network := TRUE; END IF; -- IF wallet_alias IS NOT NULL THEN l_wallet_alias := wallet_alias; ELSE l_wallet_alias := l_old_server.wallet_alias; END IF; IF wallet_path IS NOT NULL THEN l_wallet_path := wallet_path; ELSE l_wallet_path := l_old_server.wallet_path; END IF; sys.kbrsi_icd.wallet2hostlst(wallet_loc => l_wallet_path, cred_alias => l_wallet_alias, hostlst => l_hostlst, port => l_port, ssl => l_ssl, client => 'REPLICATION'); IF (l_port IS NULL OR l_port <= 0) THEN am_trace('update_replication_server_int:' || ' HTTP server not configured at replication host'); sys.dbms_sys_error.raise_system_error(REP_SRVR_HOST_NOT_CONFIG_NUM, FALSE); END IF; l_new_server.server_host := l_hostlst; l_new_server.server_port := l_port; UPDATE server SET server_host = l_new_server.server_host, server_port = l_new_server.server_port WHERE server_key = l_old_server.server_key; IF proxy_port <= 0 THEN am_trace('update_replication_server: proxy port <= 0: ' || TO_CHAR(proxy_port)); sys.dbms_sys_error.raise_system_error(REP_SRVR_BAD_PORT_NUM, TO_CHAR(proxy_port), FALSE); END IF; IF (proxy_url IS NOT NULL AND proxy_port IS NULL) THEN am_trace('update_replication_server:' || ' Proxy Port: NULL, Proxy URL: ' || proxy_url); sys.dbms_sys_error.raise_system_error(REP_SRVR_PORT_NULL_NUM, FALSE); END IF; IF (proxy_url IS NULL AND proxy_port IS NOT NULL) THEN am_trace('update_replication_server:' || ' Proxy Port: ' || TO_CHAR(proxy_port) || ', Proxy URL: NULL'); sys.dbms_sys_error.raise_system_error(REP_SRVR_PROXY_NULL_NUM, FALSE); END IF; -- IF NOT l_pxyport_def THEN l_new_server.proxy_port := proxy_port; UPDATE server SET proxy_port = l_new_server.proxy_port WHERE server_key = l_old_server.server_key; END IF; -- IF NOT l_pxy_def THEN l_new_server.proxy_url := proxy_url; UPDATE server SET proxy_url = l_new_server.proxy_url WHERE server_key = l_old_server.server_key; END IF; -- IF http_timeout IS NOT NULL THEN l_new_server.timeout_secs := http_timeout; UPDATE server SET server.timeout_secs = l_new_server.timeout_secs WHERE server_key = l_old_server.server_key; END IF; -- IF wallet_alias IS NOT NULL THEN l_new_server.wallet_alias := wallet_alias; UPDATE server SET server.wallet_alias = l_new_server.wallet_alias WHERE server_key = l_old_server.server_key; END IF; -- IF NOT l_walpath_def THEN l_new_server.wallet_path := wallet_path; UPDATE server SET server.wallet_path = l_new_server.wallet_path WHERE server_key = l_old_server.server_key; END IF; -- IF catalog_user_name IS NOT NULL THEN l_new_server.filter_user := catalog_user_name; UPDATE server SET filter_user = l_new_server.filter_user WHERE server_key = l_old_server.server_key; END IF; -- -- -- -- IF sbt_so_name IS NOT NULL THEN l_sbt_so_name := sbt_so_name; ELSE SELECT parms INTO l_old_parms FROM sbt_lib_desc WHERE server_key = l_old_server.server_key; -- l_sbt_so_name := regexp_substr(l_old_parms, '(.*)(SBT_LIBRARY=)([^,]*)', 1, 1, 'i', 3); END IF; -- -- l_parms := build_parms_for_rep( p_user_parms => sbt_parms, p_wallet_path => l_new_server.wallet_path, p_wallet_alias => l_new_server.wallet_alias, p_proxy_url => l_new_server.proxy_url, p_proxy_port => l_new_server.proxy_port, p_sbt_so_name => l_sbt_so_name); am_trace('UPDATE_REPLICATION_SERVER: replication_server_name=' || replication_server_name || ', sbt_parms=' || l_sbt_parms || ', l_parms=' || l_parms || ', l_sbt_so_name=' || l_sbt_so_name); -- IF l_parms IS NOT NULL THEN UPDATE sbt_lib_desc SET sbt_lib_desc.parms = l_parms WHERE server_key = l_old_server.server_key; END IF; IF l_grant_network THEN grant_network_acl_ace( l_new_server.filter_user, l_new_server.wallet_alias, l_new_server.wallet_path); END IF; COMMIT; EXCEPTION WHEN OBJ_NOT_FOUND THEN ROLLBACK; IF l_obj_type IS NOT NULL THEN am_trace('update_replication_server: ' || item_not_found(l_obj_name, l_obj_type)); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, l_obj_name, l_obj_type, FALSE); ELSE RAISE; END IF; WHEN DUP_VAL_ON_INDEX THEN IF l_obj_type IS NOT NULL THEN sys.dbms_sys_error.raise_system_error(DUP_NAME_NUM, l_obj_name, l_obj_type, FALSE); ELSE RAISE; END IF; WHEN REP_SRVR_HOST_NOT_CONFIG OR REP_SRVR_BAD_PORT OR REP_SRVR_PORT_NULL OR REP_SRVR_PROXY_NULL THEN ROLLBACK; am_trace ('update_replication_server: Max length of ' || ' replication_server_name is 128 chars: ' || replication_server_name); RAISE; WHEN REP_SRVR_RUNNING THEN ROLLBACK; am_trace('update_replication_server: Attempt to update a non-paused ' || ' replication_server=' || replication_server_name); sys.dbms_sys_error.raise_system_error(REP_SRVR_RUNNING_NUM, replication_server_name, FALSE); WHEN OTHERS THEN ROLLBACK; am_trace ('update_replication_server exception: ' || replication_server_name || ' err:' || SQLERRM); IF (l_grant_network) THEN grant_network_acl_ace(l_old_server.filter_user, l_old_server.wallet_alias, l_old_server.wallet_path); END IF; RAISE; END update_replication_server_int; -- PROCEDURE update_replication_server ( replication_server_name IN VARCHAR2, sbt_so_name IN VARCHAR2 DEFAULT NULL, sbt_parms IN VARCHAR2 DEFAULT NULL, max_streams IN NUMBER DEFAULT dbms_ra_int.number2null('p4'), catalog_user_name IN VARCHAR2 DEFAULT NULL, wallet_alias IN VARCHAR2 DEFAULT NULL, wallet_path IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p1'), proxy_url IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p2'), proxy_port IN NUMBER DEFAULT dbms_ra_int.number2null('p3'), http_timeout IN NUMBER DEFAULT NULL) IS l_the NUMBER; c_rep_srv_name server.rep_server_name%TYPE; u_catalog_user_name server.filter_user%TYPE; BEGIN dbms_ra_int.canonicalize(replication_server_name, c_rep_srv_name, 128); IF is_sysgen_obj(c_rep_srv_name) THEN sys.dbms_sys_error.raise_system_error (API_BAD_OBJECT_NUM, 'replication server', 'system object', FALSE); END IF; u_catalog_user_name := upper(catalog_user_name); lock_api(LOCKAPI_MODIFY, 'update_replication_server'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_UPD_REP_SERVER, param => 'update_replication_server' || b_p('replication_server_name', replication_server_name, p_first=>TRUE) || b_p('sbt_so_name', sbt_so_name ) || b_p('sbt_parms', sbt_parms ) || b_p('max_streams', max_streams ) || b_p('catalog_user_name', u_catalog_user_name ) || b_p('wallet_alias', wallet_alias ) || b_p('wallet_path', wallet_path ) || b_p('proxy_url', proxy_url ) || b_p('proxy_port', proxy_port ) || b_p('http_timeout', http_timeout , p_last=>TRUE)); update_replication_server_int (c_rep_srv_name, sbt_so_name, sbt_parms, max_streams, u_catalog_user_name, wallet_alias, wallet_path, proxy_url, proxy_port, http_timeout); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END update_replication_server; -- -- -- -- -- -- -- PROCEDURE delete_replicated_backups(p_db_key IN NUMBER, p_sbt_lib_key IN NUMBER, p_force_del IN BOOLEAN DEFAULT FALSE) IS l_skip_cnt NUMBER := 0; l_dbid NUMBER; l_currinc NUMBER; BEGIN IF p_db_key IS NULL OR p_sbt_lib_key IS NULL THEN -- SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM, 'missing db/sbt_lib key'); END IF; -- -- FOR d IN (SELECT bp_key, c.handle, c.pieceinc, bp.db_key FROM sbt_catalog c LEFT OUTER JOIN bp USING (bp_key) WHERE bp.lib_key = p_sbt_lib_key AND bp.status NOT in ('D', 'X') AND bp.db_key = p_db_key AND c.db_key = p_db_key ) LOOP -- SELECT db.db_id, db.curr_dbinc_key INTO l_dbid, l_currinc FROM db WHERE db.db_key = d.db_key; BEGIN DBMS_RA_STORAGE.FREE_BACKUP_PIECE_OPT( p_dbkey => d.db_key, p_piecename => d.handle, p_db_slkey => NULL, p_dbid => l_dbid, p_currinc => l_currinc, p_bpkey => d.bp_key, p_ftype => DBMS_RA_INT.KBRSCHKTYPE_TAPE, p_libkey => p_sbt_lib_key, p_spawn_job => FALSE, p_notasks => TRUE); am_trace ('DELETE_REPLICATED_BACKUPS: Delete replicated bp record ' || d.handle || ' bpkey ' || d.bp_key); EXCEPTION WHEN dbms_ra_scheduler.e_retry_error THEN -- -- -- am_trace ('DELETE_REPLICATED_BACKUPS: Unable to delete locked bp ' || 'record ' || d.handle || ' bpkey ' || d.bp_key); l_skip_cnt := l_skip_cnt + 1; END; END LOOP; -- IF p_force_del AND l_skip_cnt > 0 THEN update_bps_for_delete_lib_int(p_db_key, p_sbt_lib_key); END IF; END; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE delete_replication_server_int (p_rep_server_name IN VARCHAR2, p_force IN BOOLEAN DEFAULT FALSE) IS l_sbt_lib_name sbt_lib_desc.lib_name%TYPE; l_sbt_lib_key NUMBER; l_server_key NUMBER; r_server server%ROWTYPE; r_sbt_lib_desc sbt_lib_desc%ROWTYPE; l_cnt NUMBER; l_restorecnt NUMBER; l_errors BOOLEAN:=FALSE; l_gotlock BOOLEAN := FALSE; l_bpkey NUMBER; l_task_rec task%ROWTYPE; l_sbt_lib_found BOOLEAN := FALSE; l_dbid NUMBER; l_currinc NUMBER; l_rep_lib_name sbt_lib_desc.lib_name%TYPE; CURSOR rep_server_cursor IS SELECT prot_name FROM prot, rep_server WHERE prot.prot_key = rep_server.prot_key AND rep_server.server_key = l_server_key; BEGIN am_trace('DELETE_REPLICATION_SERVER: replication_server_name=' || p_rep_server_name); -- -- SELECT COUNT(*) INTO l_cnt FROM server WHERE server.rep_server_name=p_rep_server_name; IF l_cnt = 0 THEN am_trace('DELETE_REPLICATION_SERVER: replication_server_name=' || p_rep_server_name || ' was not found.'); RAISE NO_DATA_FOUND; END IF; -- SELECT s.server_key INTO l_server_key FROM server s WHERE s.rep_server_name = p_rep_server_name; -- SELECT COUNT(*) INTO l_cnt FROM rep_server WHERE rep_server.server_key=l_server_key; IF l_cnt != 0 AND p_force = FALSE THEN -- am_trace('DELETE_REPLICATION_SERVER: replication_server_name=' || p_rep_server_name || ' - attempted to delete while ' || 'still associated with a protection policy. Either ' || 'remove_replication_server or use force==TRUE option.'); RAISE OBJ_IS_REFERENCED; END IF; -- -- -- -- UPDATE rep_server SET status = 'D' WHERE server_key = l_server_key; IF SQL%ROWCOUNT = 0 THEN am_trace ('DELETE_REPLICATION_SERVER: RS ' || p_rep_server_name || ' unable to find associated rep_server entry'); END IF; COMMIT; -- l_sbt_lib_found := TRUE; BEGIN SELECT l.lib_key, l.lib_name, s.filter_user, s.wallet_alias, s.wallet_path INTO l_sbt_lib_key, l_sbt_lib_name, r_server.filter_user, r_server.wallet_alias, r_server.wallet_path FROM sbt_lib_desc l, server s WHERE s.server_key = l_server_key AND l.server_key = s.server_key; EXCEPTION WHEN NO_DATA_FOUND THEN am_trace ('DELETE_REPLICATION_SERVER: RS ' || p_rep_server_name || ' unable to find associated sbt_library'); l_sbt_lib_found := FALSE; END; am_trace('DELETE_REPLICATION_SERVER: Deleting: replication_server_name=' || p_rep_server_name || ', l_sbt_lib_key =' || l_sbt_lib_key || ', l_server_key=' || l_server_key); -- IF l_sbt_lib_found THEN l_rep_lib_name := dbms_ra_int.build_rep_lib_name(p_rep_server_name); pause_sbt_library_int(l_rep_lib_name); END IF; -- -- -- -- -- -- IF l_sbt_lib_found THEN SELECT COUNT(*) INTO l_restorecnt FROM config c, task t, sbt_task st WHERE t.task_type = DBMS_RA_SCHEDULER.TASK_RESTORE_SBT AND t.state = DBMS_RA_SCHEDULER.STATE_RUNNING AND st.task_id = t.task_id AND st.lib_key = l_sbt_lib_key AND c.name = '_recovery_appliance_state' AND c.value = 'ON'; IF l_restorecnt != 0 THEN am_trace('DELETE_REPLICATION_SERVER: Aborting - found ' || l_restorecnt|| 'running restore tasks'); sys.dbms_sys_error.raise_system_error(REP_SERVER_ACTIVE_NUM, FALSE); END IF; END IF; -- -- -- -- -- -- -- -- IF l_sbt_lib_found THEN LOOP am_trace('DELETE_REPLICATION_SERVER: Waiting on running reconcile tasks'); SELECT COUNT(*) INTO l_cnt FROM config c, odb o, rep_server r, task t WHERE task_type = DBMS_RA_SCHEDULER.TASK_RECONCILE AND r.server_key = l_server_key AND r.prot_key = o.prot_key AND o.db_key = t.db_key AND c.name = '_recovery_appliance_state' AND c.value = 'ON' AND ROWNUM = 1; EXIT WHEN l_cnt = 0; DBMS_LOCK.SLEEP(10); END LOOP; END IF; -- -- -- IF l_sbt_lib_found THEN am_trace ('DELETE_REPLICATION_SERVER: Deleting backup piece records ' || 'l_server_key = ' || l_server_key); FOR dbrec IN (SELECT o.db_key FROM odb o, rep_server rs WHERE rs.server_key = l_server_key AND o.prot_key = rs.prot_key ORDER BY db_key) LOOP am_trace ('DELETE_REPLICATION_SERVER: Deleting backup piece records' || ' for ' || dbms_ra_int.dbkey2name(dbrec.db_key)); delete_replicated_backups(p_db_key => dbrec.db_key, p_sbt_lib_key => l_sbt_lib_key, p_force_del => FALSE); END LOOP; END IF; -- IF l_cnt != 0 AND p_force = TRUE THEN FOR f IN rep_server_cursor LOOP BEGIN am_trace ('DELETE_REPLICATION_SERVER: Removing rep from prot'); remove_rep_from_prot_int(p_rep_server_name, f.prot_name, FALSE); EXCEPTION WHEN OBJ_NOT_FOUND THEN am_trace ('DELETE_REPLICATION_SERVER: RS ' || p_rep_server_name || ' rep_server entry not found for protection policy ' || f.prot_name); -- NULL; END; END LOOP; END IF; -- BEGIN delete_repository(r_server.filter_user, r_server.wallet_alias, r_server.wallet_path); EXCEPTION WHEN NO_DATA_FOUND THEN -- am_trace ('DELETE_REPLICATION_SERVER: RS ' || p_rep_server_name || ' delete_repository data not found '); NULL; END; -- -- -- COMMIT; BEGIN if l_sbt_lib_key IS NOT NULL THEN -- IF NOT DBMS_RA_INT.WRITE_LOCK_WAIT(DBMS_RA_INT.KEY_SY,l_sbt_lib_key) THEN am_trace ('DELETE_REPLICATION_SERVER: SBT lib entry no longer exists'); -- -- -- END IF; l_gotlock := TRUE; END IF; -- -- delete_sbt_library_int(l_sbt_lib_name, FALSE); EXCEPTION WHEN OBJ_NOT_FOUND THEN -- am_trace ('DELETE_REPLICATION_SERVER: RS ' || p_rep_server_name || ' delete_sbt_library_int data not found '); NULL; END; -- COMMIT; -- IF l_gotlock THEN DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_SY, l_sbt_lib_key); l_gotlock := FALSE; END IF; EXCEPTION WHEN OBJ_IS_REFERENCED THEN IF l_gotlock THEN DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_SY, l_sbt_lib_key); END IF; am_trace ('DELETE_REPLICATION_SERVER: RS ' || p_rep_server_name || ' is currently associated with protection policy use force' || ' option or call remove_replication_server' ); sys.dbms_sys_error.raise_system_error(OBJ_IS_REFERENCED_NUM, p_rep_server_name, 'replication server has an existing protection policy', FALSE); WHEN NO_DATA_FOUND THEN IF l_gotlock THEN DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_SY, l_sbt_lib_key); END IF; am_trace('DELETE_REPLICATION_SERVER: ' || item_not_found(p_rep_server_name,'replication server name')); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, p_rep_server_name, 'replication server name', FALSE); WHEN OTHERS THEN IF l_gotlock THEN DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_SY, l_sbt_lib_key); END IF; am_trace ('delete_replication_server exception: RS ' || p_rep_server_name || ' err:' || SQLERRM); sys.dbms_sys_error.raise_system_error(OBJ_IS_REFERENCED_NUM, p_rep_server_name, 'replication server encountered an exception', TRUE); END delete_replication_server_int; -- PROCEDURE delete_replication_server (replication_server_name IN VARCHAR2, force IN BOOLEAN DEFAULT FALSE) IS l_the NUMBER; c_rep_srv_name server.rep_server_name%TYPE; BEGIN dbms_ra_int.canonicalize(replication_server_name, c_rep_srv_name, 128); IF is_sysgen_obj(c_rep_srv_name) THEN sys.dbms_sys_error.raise_system_error (API_BAD_OBJECT_NUM, 'replication server', 'system object', FALSE); END IF; lock_api(LOCKAPI_DELETE, 'delete_replication_server'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_DEL_REP_SERVER, param => 'delete_replication_server' || b_p('replication_server_name', replication_server_name, p_first=>TRUE) || b_p('force', force, p_last=>TRUE)); -- -- -- -- ctrl_c_check(CCCHK_CREDEL_REP_SERVER); delete_replication_server_int (c_rep_srv_name, force); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN -- -- -- COMMIT; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END delete_replication_server; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE add_rep_to_prot_int (p_replication_server_name IN VARCHAR2, p_protection_policy_name IN VARCHAR2) IS l_repsrv_key NUMBER := NULL; l_prot_key NUMBER := NULL; l_server_key NUMBER := NULL; l_obj_type VARCHAR2(128); l_obj_name VARCHAR2(128); l_cnt NUMBER; l_lib_key NUMBER; l_template_name sbt_job_template.template_name%TYPE; l_db_unique_name node.db_unique_name%TYPE; l_all_reconciled BOOLEAN := TRUE; l_invalid_val VARCHAR2(128); l_msg VARCHAR2(128); l_ckpt NUMBER := 0; l_success BOOLEAN; l_num_rec NUMBER; l_tot_rec NUMBER := 0; l_last_rec timestamp; l_rep_atr_name sbt_attr_set.attr_name%TYPE; CURSOR odbcur IS SELECT db_key FROM odb WHERE odb.prot_key = l_prot_key -- AND odb.db_state IS NULL; BEGIN -- BEGIN SELECT prot_key INTO l_prot_key FROM prot WHERE prot.prot_name = p_protection_policy_name; EXCEPTION WHEN NO_DATA_FOUND THEN l_obj_type := 'protection policy'; l_obj_name := p_protection_policy_name; RAISE OBJ_NOT_FOUND; END; -- BEGIN SELECT server_key INTO l_server_key FROM server WHERE server.rep_server_name = p_replication_server_name; EXCEPTION WHEN NO_DATA_FOUND THEN l_obj_type := 'replication server'; l_obj_name := p_replication_server_name; RAISE OBJ_NOT_FOUND; END; -- -- SELECT COUNT(*) INTO l_cnt FROM rep_server WHERE server_key=l_server_key AND prot_key=l_prot_key; IF (l_cnt > 0) THEN RETURN; END IF; -- l_repsrv_key := rman_seq.nextval; INSERT INTO rep_server (rep_server_key, server_key, prot_key, status) VALUES (l_repsrv_key, l_server_key, l_prot_key, 'C'); COMMIT; -- -- -- -- -- -- -- SELECT lib_key INTO l_lib_key FROM sbt_lib_desc WHERE server_key = l_server_key; FOR f IN odbcur LOOP -- UPDATE odb SET pending_rep_setup = 'Y', last_reconcile = NULL, next_reconcile = NULL, last_replication = NULL WHERE db_key = f.db_key; COMMIT; -- -- l_success := dbms_ra_scheduler.reconcile_db ( p_db_key => f.db_key, p_server_key => l_server_key, p_only_active => FALSE, p_force_reconcile => TRUE, rec_cnt => l_num_rec); IF NOT l_success OR l_num_rec <> 1 THEN l_all_reconciled := FALSE; l_msg := 'REP_REC CKPT=' || l_ckpt; dbms_ra_scheduler.log_error (p_errno => REP_SETUP_ERROR_NUM, p_param1 => 'reconcile', p_param2 => p_replication_server_name, p_param3 => dbms_ra_int.dbkey2name(f.db_key), P_keep_stack => FALSE, p_component => 'REPLICATION_SETUP', p_severity => dbms_ra_scheduler.SEVERITY_ERROR, p_param_char => l_msg, p_param_num => f.db_key); ELSE -- -- dbms_ra_scheduler.fix_error ( p_error_num => dbms_ra.REP_SETUP_ERROR_NUM, p_db_key => f.db_key, p_param_char => 'RECONCILE'); l_tot_rec := l_tot_rec + 1; END IF; END LOOP; -- -- -- -- -- UPDATE rep_server SET status = 'A' WHERE rep_server_key = l_repsrv_key; UPDATE sbt_lib_desc SET status = 'R' WHERE lib_key = l_lib_key; -- -- COMMIT; -- -- IF l_tot_rec > 0 THEN FOR f IN odbcur LOOP BEGIN SELECT last_reconcile INTO l_last_rec FROM odb WHERE db_key = f.db_key; IF l_last_rec = 0 OR l_last_rec IS NULL THEN -- CONTINUE; END IF; l_ckpt := 1; l_db_unique_name := dbms_ra_int.dbkey2name(f.db_key); l_ckpt := 2; -- dbms_ra_scheduler.queue_set_reconcile_timer (f.db_key); l_ckpt := 3; -- -- l_template_name := dbms_ra_int.build_rep_tpl_name ( rep_srv_name => p_replication_server_name, db_key => f.db_key, prot_key => l_prot_key); l_ckpt := 4; BEGIN l_rep_atr_name := dbms_ra_int.build_rep_atr_name(p_replication_server_name); dbms_ra_int.create_sbt_job_template_int( template_name => l_template_name, db_unique_name => l_db_unique_name, attr_name => l_rep_atr_name, backup_type => 'ALL', do_commit => TRUE); EXCEPTION WHEN DUP_NAME THEN -- NULL; END; UPDATE odb SET pending_rep_setup = 'N' WHERE db_key = f.db_key; COMMIT; -- l_ckpt := 5; dbms_ra_scheduler.replicate_existing_backups( p_template_name => l_template_name); EXCEPTION WHEN OTHERS THEN -- -- -- -- l_msg := 'REP_INIT CKPT=' || l_ckpt; dbms_ra_scheduler.log_error (p_errno => REP_SETUP_ERROR_NUM, p_param1 => 'initial replication', p_param2 => p_replication_server_name, p_param3 => l_db_unique_name, P_keep_stack => FALSE, p_component => 'REPLICATION_INITREP', p_severity => dbms_ra_scheduler.SEVERITY_ERROR, p_param_char => l_msg, p_param_num => f.db_key); ROLLBACK; -- -- UPDATE sbt_lib_desc SET status = (CASE WHEN failure_cnt + 1 < dbms_ra_scheduler.s_max_sbt_failures THEN 'R' ELSE 'E' END), failure_cnt = failure_cnt + 1 WHERE status = 'R' AND lib_key = l_lib_key; COMMIT; RAISE; END; END LOOP; END IF; EXCEPTION WHEN MISSING_INIT_REP_TYPE THEN -- am_trace ('add_replication_server: required intial_replication ' || 'parameter not defined'); RAISE; WHEN OBJ_NOT_FOUND THEN -- IF l_obj_type IS NOT NULL THEN am_trace ('add_replication_server: ' || item_not_found(l_obj_name, l_obj_type)); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, l_obj_name, l_obj_type, FALSE); ELSE RAISE; END IF; WHEN OTHERS THEN ROLLBACK; am_trace ('add_replication_server exception: ' || ' replication_server_name:' || p_replication_server_name || ', protection_policy_name:' || p_protection_policy_name || ', err:' || SQLERRM); RAISE; END add_rep_to_prot_int; -- PROCEDURE add_replication_server (replication_server_name IN VARCHAR2, protection_policy_name IN VARCHAR2) IS l_the NUMBER; c_rep_srv_name server.rep_server_name%TYPE; c_protection_policy_name prot.prot_name%TYPE; BEGIN dbms_ra_int.canonicalize(replication_server_name, c_rep_srv_name, 128); IF is_sysgen_obj(c_rep_srv_name) THEN sys.dbms_sys_error.raise_system_error (API_BAD_OBJECT_NUM, 'replication server', 'system object', FALSE); END IF; lock_api(LOCKAPI_CREATE, 'add_replication_server'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_ADD_REP_SERVER, param => 'add_replication_server' || b_p('replication_server_name', replication_server_name, p_first=>TRUE) || b_p('protection_policy_name', protection_policy_name, p_last=>TRUE)); dbms_ra_int.canonicalize(protection_policy_name, c_protection_policy_name, 128); add_rep_to_prot_int (c_rep_srv_name, c_protection_policy_name); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END add_replication_server; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE remove_rep_from_prot_int (p_replication_server_name IN VARCHAR2, p_protection_policy_name IN VARCHAR2, do_commit IN BOOLEAN DEFAULT TRUE) IS l_repsrv_key NUMBER := NULL; l_prot_key NUMBER := NULL; l_db_key NUMBER := NULL; l_server_key NUMBER := NULL; l_lib_key NUMBER := NULL; l_obj_type VARCHAR2(128); l_obj_name VARCHAR2(128); l_cnt NUMBER; l_template_name sbt_job_template.template_name%TYPE; l_db_unique_name node.db_unique_name%TYPE; CURSOR odbcur IS SELECT db_key FROM odb WHERE odb.prot_key = l_prot_key -- AND odb.db_state IS NULL; BEGIN -- BEGIN SELECT prot_key INTO l_prot_key FROM prot WHERE prot.prot_name = p_protection_policy_name; EXCEPTION WHEN NO_DATA_FOUND THEN l_obj_type := 'protection policy'; l_obj_name := p_protection_policy_name; RAISE OBJ_NOT_FOUND; END; -- BEGIN SELECT server_key INTO l_server_key FROM server WHERE server.rep_server_name = p_replication_server_name; EXCEPTION WHEN NO_DATA_FOUND THEN l_obj_type := 'replication server'; l_obj_name := p_replication_server_name; RAISE OBJ_NOT_FOUND; END; -- -- -- UPDATE rep_server SET status = 'D' WHERE server_key = l_server_key AND prot_key = l_prot_key; COMMIT; -- FOR f IN odbcur LOOP BEGIN l_db_unique_name := dbms_ra_int.dbkey2name(f.db_key); l_template_name := dbms_ra_int.build_rep_tpl_name ( rep_srv_name => p_replication_server_name, db_key => f.db_key, prot_key => l_prot_key); remove_rep_tasks(p_db_key => f.db_key, p_template => l_template_name); delete_sbt_job_template_int(template_name => l_template_name, do_commit => FALSE); EXCEPTION WHEN OBJ_NOT_FOUND THEN am_trace ('remove_replication_server: ' || ' skipping removal of sbt_job_template: ' || ' replication_server_name:' || p_replication_server_name || ', protection_policy_name:' || p_protection_policy_name); NULL; WHEN OTHERS THEN ROLLBACK; am_trace ('remove_replication_server: ' || 'unable to remove sbt_job_template' || SQLERRM || ' replication_server_name:' || p_replication_server_name || ', protection_policy_name:' || p_protection_policy_name); RAISE; END; END LOOP; -- DELETE FROM rep_server WHERE rep_server.server_key = l_server_key AND rep_server.prot_key = l_prot_key; -- -- SELECT count(*) INTO l_cnt FROM rep_server WHERE prot_key = l_prot_key AND status <> 'D'; -- IF l_cnt = 0 THEN UPDATE odb SET pending_rep_setup = NULL, next_reconcile = NULL, last_reconcile = NULL, last_replication = NULL WHERE prot_key = l_prot_key; END IF; IF do_commit THEN COMMIT; END IF; EXCEPTION WHEN OBJ_NOT_FOUND THEN -- IF l_obj_type IS NOT NULL THEN am_trace ('remove_replication_server: ' || item_not_found(l_obj_name, l_obj_type)); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, l_obj_name, l_obj_type, FALSE); ELSE RAISE; END IF; WHEN OTHERS THEN ROLLBACK; am_trace ('remove_replication_server exception: ' || ' replication_server_name:' || p_replication_server_name || ', protection_policy_name:' || p_protection_policy_name || ', err:' || SQLERRM); RAISE; END remove_rep_from_prot_int; -- PROCEDURE remove_replication_server (replication_server_name IN VARCHAR2, protection_policy_name IN VARCHAR2) IS l_the NUMBER; c_rep_srv_name server.rep_server_name%TYPE; c_protection_policy_name prot.prot_name%TYPE; BEGIN dbms_ra_int.canonicalize(replication_server_name, c_rep_srv_name, 128); IF is_sysgen_obj(c_rep_srv_name) THEN sys.dbms_sys_error.raise_system_error (API_BAD_OBJECT_NUM, 'replication server', 'system object', FALSE); END IF; lock_api(LOCKAPI_DELETE, 'remove_replication_server'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_REM_REP_SERVER, param => 'remove_replication_server' || b_p('replication_server_name', replication_server_name, p_first=>TRUE) || b_p('protection_policy_name', protection_policy_name, p_last=>TRUE)); dbms_ra_int.canonicalize(protection_policy_name, c_protection_policy_name, 128); remove_rep_from_prot_int (c_rep_srv_name, c_protection_policy_name, TRUE); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END remove_replication_server; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE pause_replication_server (replication_server_name IN VARCHAR2) IS l_the NUMBER; c_rep_srv_name server.rep_server_name%TYPE; l_rep_lib_name sbt_lib_desc.lib_name%TYPE; BEGIN dbms_ra_int.canonicalize(replication_server_name, c_rep_srv_name, 128); IF is_sysgen_obj(c_rep_srv_name) THEN sys.dbms_sys_error.raise_system_error (API_BAD_OBJECT_NUM, 'replication server', 'system object', FALSE); END IF; l_rep_lib_name := dbms_ra_int.build_rep_lib_name(c_rep_srv_name); lock_api(LOCKAPI_MODIFY, 'pause_replication_server'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_PAU_REP_SRV, param => 'pause_replication_server' || b_p('replication_server_name', replication_server_name, p_first=>TRUE, p_last=>TRUE)); pause_sbt_library_int(l_rep_lib_name); unlock_api(); EXCEPTION WHEN OTHERS THEN unlock_api(); RAISE; END pause_replication_server; -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE resume_replication_server (replication_server_name IN VARCHAR2) IS l_the NUMBER; c_rep_srv_name server.rep_server_name%TYPE; l_rep_lib_name sbt_lib_desc.lib_name%TYPE; BEGIN dbms_ra_int.canonicalize(replication_server_name, c_rep_srv_name, 128); IF is_sysgen_obj(c_rep_srv_name) THEN sys.dbms_sys_error.raise_system_error (API_BAD_OBJECT_NUM, 'replication server', 'system object', FALSE); END IF; l_rep_lib_name := dbms_ra_int.build_rep_lib_name(c_rep_srv_name); lock_api(LOCKAPI_MODIFY, 'resume_replication_server'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_RES_REP_SRV, param => 'resume_replication_server' || b_p('replication_server_name', replication_server_name, p_first=>TRUE, p_last=>TRUE)); resume_sbt_library_int(l_rep_lib_name); unlock_api(); EXCEPTION WHEN OTHERS THEN unlock_api(); RAISE; END resume_replication_server; -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE manage_user_int (create_vpc IN BOOLEAN, username IN VARCHAR2, db_unique_name IN VARCHAR2) IS l_db_key NUMBER := NULL; l_dbid NUMBER := NULL; l_user_id NUMBER; BEGIN begin select db.db_key, db.db_id into l_db_key, l_dbid from node, db where db_unique_name = upper(manage_user_int.db_unique_name) and node.db_key = db.db_key -- -- and not exists (select db_state from odb where odb.db_key = node.db_key and db_state is not null); exception when no_data_found then l_dbid := 0; end; IF create_vpc THEN -- dbms_rcvcat.grant_catalog(username, l_dbid, db_unique_name); am_trace('grant_register suceeded for ' || username || ' and db ' || db_unique_name); ELSE -- dbms_rcvcat.revoke_catalog(username, l_dbid, db_unique_name); am_trace('revoke_register suceeded for ' || username || ' and db ' || db_unique_name); END IF; END manage_user_int; PROCEDURE grant_db_access (username IN VARCHAR2, db_unique_name IN VARCHAR2) IS canon_username DBMS_QUOTED_ID; l_the NUMBER; l_db_unique_name VARCHAR2(128); l_db_key NUMBER; USER_NOT_EXISTS_NATIVE EXCEPTION; PRAGMA EXCEPTION_INIT ( USER_NOT_EXISTS_NATIVE, -01917 ); BEGIN IF (upper(username)='SYS') THEN RAISE NOT_OAMADMIN; END IF; lock_api(LOCKAPI_CREATE, 'grant_db_access'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_GRANT_DB, param => 'grant_db_access' || b_p('db_unique_name', db_unique_name, p_first=>TRUE) || b_p('username', username, p_last=>TRUE)); dbms_ra_int.canonicalize(username, canon_username, 130); -- IF '"' || canon_username || '"' = sys.rai_schema THEN RAISE NOT_OAMADMIN; END IF; manage_user_int(TRUE, canon_username, upper(db_unique_name)); manage_privilege_int(upper(db_unique_name), AM_SEC_OPERATION_GRANT, AM_SEC_PRIVTYPE_ALL, AM_SEC_ACCESSTYPE_ALL, canon_username); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN USER_NOT_EXISTS_NATIVE THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); sys.dbms_sys_error.raise_system_error(USER_NOT_EXISTS_NUM,username); WHEN OBJ_NOT_FOUND THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); sys.dbms_sys_error.raise_system_error (OBJ_NOT_FOUND_NUM, db_unique_name, 'db unique name', FALSE); WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END grant_db_access; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE revoke_db_access_int (p_username IN VARCHAR2, p_db_unique_name IN VARCHAR2) IS l_db_unique_name VARCHAR2(128); l_db_key NUMBER; CURSOR username_cursor IS SELECT username FROM ra_db_access WHERE db_unique_name = l_db_unique_name; BEGIN l_db_unique_name := upper(p_db_unique_name); IF p_username IS NOT NULL THEN -- am_trace ('revoke_db_access_int: Removing ' || p_username || ' from ' || l_db_unique_name); manage_privilege_int(l_db_unique_name, AM_SEC_OPERATION_REVOKE, AM_SEC_PRIVTYPE_ALL, AM_SEC_ACCESSTYPE_ALL, p_username); manage_user_int(FALSE, p_username, l_db_unique_name); ELSE -- FOR u IN username_cursor LOOP BEGIN am_trace ('revoke_db_access_int: Removing ' || u.username || ' from ' || l_db_unique_name); manage_privilege_int(l_db_unique_name, AM_SEC_OPERATION_REVOKE, AM_SEC_PRIVTYPE_ALL, AM_SEC_ACCESSTYPE_ALL, u.username); manage_user_int(FALSE, u.username, l_db_unique_name); END; END LOOP; END IF; END; -- PROCEDURE revoke_db_access (username IN VARCHAR2, db_unique_name IN VARCHAR2) IS canon_username DBMS_QUOTED_ID; l_the NUMBER; BEGIN lock_api(LOCKAPI_CREATE, 'revoke_db_access'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_REVOKE_DB, param => 'revoke_db_access' || b_p('db_unique_name', db_unique_name, p_first=>TRUE) || b_p('username', username, p_last=>TRUE)); dbms_ra_int.canonicalize(username, canon_username, 130); -- IF '"' || canon_username || '"' = sys.rai_schema THEN RAISE NOT_OAMADMIN; END IF; revoke_db_access_int (canon_username, db_unique_name); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OBJ_NOT_FOUND THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); sys.dbms_sys_error.raise_system_error (OBJ_NOT_FOUND_NUM, db_unique_name, 'db unique name', FALSE); WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END revoke_db_access; -- -- -- -- -- PROCEDURE populate_backup_piece_int(p_bpkey IN NUMBER) IS l_dbkey NUMBER := NULL; l_vbkey NUMBER := NULL; l_slkey NUMBER; l_update NUMBER := 0; -- 1 => Disk, 2 => Tape l_bskey NUMBER; l_bpkey NUMBER; l_count NUMBER; l_ckpscn NUMBER; l_hasdups BOOLEAN; l_nofit BOOLEAN; l_isok BOOLEAN; task_rec task%ROWTYPE; BEGIN am_trace('Populate_backup_piece - p_bpkey ' || p_bpkey); -- SELECT MIN(vb_key), MIN(db_key) INTO l_vbkey, l_dbkey FROM bp WHERE status != 'D' AND ba_access != 'U' AND bp_key = p_bpkey; IF l_dbkey IS NULL THEN am_trace('Populate_backup_piece: Missing specified backup ' || p_bpkey); RAISE UNKNONW_BP; END IF; -- SELECT COUNT(*) INTO l_count FROM odb d, bp p WHERE d.db_key = p.db_key AND d.same_endian = 'U' AND p.bp_key = p_bpkey; IF l_count > 0 THEN am_trace('Populate_backup_piece: Unknown same_endian for db'); RAISE UNKNOWN_PLATFORM; END IF; -- IF l_vbkey IS NOT NULL THEN -- SELECT MAX(ckp_scn) INTO l_ckpscn FROM vbdf WHERE vb_key = l_vbkey; -- SELECT bp_key INTO l_bpkey FROM (SELECT bp_key, d.file#, d.incr_scn, d.ckp_scn FROM vbdf v, bdf d, bp p WHERE v.dbinc_key = d.dbinc_key AND v.file# = d.file# AND p.bs_key = d.bs_key AND p.vb_key IS NULL AND p.status != 'D' AND p.ba_access != 'U' AND d.ckp_scn <= l_ckpscn ORDER BY ckp_scn DESC, incr_scn DESC, bp_key) WHERE ROWNUM = 1; -- IF l_bpkey IS NULL THEN am_trace('Populate_backup_piece: Can not find useful backup.'); RAISE NO_FIND_USEFUL_BP; END IF; ELSE l_bpkey := p_bpkey; END IF; -- SELECT bs_key INTO l_bskey FROM bp WHERE bp_key = l_bpkey; -- dbms_ra_pool.ok4pool(l_dbkey, l_bpkey, TRUE, l_hasdups, l_nofit, l_isok); IF l_nofit THEN dbms_ra_pool.ok4pool(l_dbkey, l_bpkey, FALSE, l_hasdups, l_nofit, l_isok); END IF; IF NOT l_isok THEN am_trace('Populate_backup_piece: Can not use this backup.'); RAISE NO_INSERT_BP; END IF; -- SELECT COUNT(*) INTO l_count FROM vbdf v, bdf d WHERE v.dbinc_key = d.dbinc_key AND v.file# = d.file# AND bs_key = l_bskey AND d.ckp_scn <= v.ckp_scn; IF l_count = 0 THEN l_update := 0; ELSE l_update := 1; END IF; am_trace('Populate_backup_piece: Source bpkey ' || l_bpkey || ', bskey -- ' || l_bskey || ', update -- ' || l_update); -- SELECT sl_key INTO l_slkey FROM odb WHERE db_key = l_dbkey; -- task_rec.task_type := dbms_ra_scheduler.TASK_INDEX_BACKUP; task_rec.flags := 1; -- TASKS_RECEIVED_BACKUP task_rec.db_key := l_dbkey; task_rec.param_num1 := l_bpkey; task_rec.param_num2 := l_update; -- dbms_ra_scheduler.new_task(task_rec); END populate_backup_piece_int; -- -- -- -- -- -- -- -- -- -- -- PROCEDURE populate_backup_piece(backup_piece_key IN NUMBER) IS l_the NUMBER; BEGIN lock_api(LOCKAPI_MODIFY, 'populate_backup_piece'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_POPULATE, param => 'populate_backup_piece' || b_p('backup_piece_key', backup_piece_key, p_first=>TRUE, p_last=>TRUE)); populate_backup_piece_int(backup_piece_key); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END populate_backup_piece; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE copy_move_int(p_tag IN VARCHAR2 DEFAULT NULL, p_bpkey IN NUMBER DEFAULT NULL, p_format IN VARCHAR2 DEFAULT NULL, p_template_name IN VARCHAR2 DEFAULT NULL, p_deleteit IN BOOLEAN DEFAULT FALSE ) IS CURSOR bps_To_Move(c_tag IN VARCHAR2) IS select MIN(bp.bp_key) bp_key from bp where tag=c_tag AND status = 'A' AND ba_access = 'L' AND bp.bs_key in (select bs_key from bs where keep_options > 0) GROUP BY bs_key, piece#; CURSOR bps_To_Copy(c_tag IN VARCHAR2) IS select MIN(bp.bp_key) bp_key from bp where tag=c_tag AND status = 'A' AND ba_access = 'L' AND bp.bs_key in (select bs_key from bs) GROUP BY bs_key, piece#; l_missing_param VARCHAR2(128); l_deletesource VARCHAR2(1); l_template_key NUMBER DEFAULT NULL; l_keepoptions NUMBER := 0; l_cnt NUMBER := 0; c_template_name sbt_job_template.template_name%TYPE; BEGIN IF p_format IS NULL THEN l_missing_param := 'format'; RAISE MISSING_PARAM; END IF; IF p_tag IS NULL AND p_bpkey IS NULL THEN l_missing_param := 'tag and/or bpkey (neither supplied)'; RAISE MISSING_PARAM; END IF; IF p_template_name IS NOT NULL THEN BEGIN dbms_ra_int.canonicalize(p_template_name, c_template_name, 128); SELECT job.template_key INTO l_template_key FROM sbt_job_template job WHERE job.template_name = c_template_name; EXCEPTION WHEN NO_DATA_FOUND THEN RAISE OBJ_NOT_FOUND; END; END IF; IF p_deleteit THEN l_deletesource := 'Y'; ELSE l_deletesource := 'N'; END IF; IF p_bpkey IS NULL THEN IF p_deleteit THEN FOR b IN bps_To_Move(p_tag) LOOP l_cnt := l_cnt + 1; am_trace ('copy_move_int: BP_KEY being moved is: ' || b.bp_key); dbms_ra_scheduler.copy_one_backuppiece(p_bpkey => b.bp_key, p_format => p_format, p_deletesource => l_deletesource, p_template_key => l_template_key); -- -- IF p_template_name IS NULL THEN dbms_ra_scheduler.delete_one_backuppiece(b.bp_key); END IF; END LOOP; ELSE FOR b IN bps_To_Copy(p_tag) LOOP l_cnt := l_cnt + 1; am_trace ('copy_move_int: BP_KEY being copied is: ' || b.bp_key); dbms_ra_scheduler.copy_one_backuppiece(p_bpkey => b.bp_key, p_format => p_format, p_deletesource => l_deletesource, p_template_key => l_template_key); END LOOP; END IF; IF l_cnt = 0 THEN am_trace ('copy_move_int: No eligible backup pieces found for tag ' || p_tag); RAISE UNKNONW_BP; END IF; ELSE -- IF p_deleteit THEN SELECT keep_options INTO l_keepoptions FROM bs WHERE bs_key=(SELECT bs_key FROM bp WHERE bp_key=p_bpkey); IF l_keepoptions = 0 THEN am_trace('copy_move_int: bp_key ' || TO_CHAR(p_bpkey) || ' is not part of a KEEP backup'); sys.dbms_sys_error.raise_system_error(COPY_MOVE_NOT_KEEP_NUM, TO_CHAR(p_bpkey), FALSE); END IF; END IF; dbms_ra_scheduler.copy_one_backuppiece(p_bpkey => p_bpkey, p_format => p_format, p_deletesource => l_deletesource, p_template_key => l_template_key); -- -- IF p_deleteit=TRUE AND p_template_name IS NULL THEN dbms_ra_scheduler.delete_one_backuppiece(p_bpkey); END IF; END IF; EXCEPTION WHEN COPY_MOVE_NOT_KEEP THEN RAISE; WHEN MISSING_PARAM THEN IF l_missing_param IS NOT NULL THEN am_trace ('copy_move_int: required parameter missing: ' || l_missing_param); sys.dbms_sys_error.raise_system_error(MISSING_PARAM_NUM, l_missing_param, FALSE); ELSE RAISE; END IF; WHEN OBJ_NOT_FOUND THEN am_trace('copy_move_int: ' || item_not_found(p_template_name,'sbt job template')); sys.dbms_sys_error.raise_system_error (OBJ_NOT_FOUND_NUM, p_template_name, 'sbt job template', FALSE); WHEN OTHERS THEN am_trace ('copy_move_int exception: ' || ' err:' || SQLERRM); RAISE; END copy_move_int; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE move_backup_piece (bp_key IN NUMBER, format IN VARCHAR2, template_name IN VARCHAR2) IS l_the NUMBER; c_template_name sbt_job_template.template_name%TYPE; BEGIN am_trace('move_backup_piece: bp_key=' || bp_key || ' ,format=' || format || ' ,template_name=' || template_name); lock_api(LOCKAPI_CREATE, 'move_backup_piece'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_MOVE_BACKUP_PIECE, param => 'move_backup_piece' || b_p('bp_key', bp_key, p_first=>TRUE) || b_p('format', format) || b_p('template_name', template_name, p_last=>TRUE)); dbms_ra_int.canonicalize(template_name, c_template_name, 128); copy_move_int(p_tag => NULL, p_bpkey => bp_key, p_format => format, p_template_name => c_template_name, p_deleteit => TRUE); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END move_backup_piece; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE move_backup (tag IN VARCHAR2, format IN VARCHAR2, template_name IN VARCHAR2) IS l_the NUMBER; c_template_name sbt_job_template.template_name%TYPE; BEGIN am_trace('move_backup: tag=' || tag || ' ,format=' || format || ' ,template_name=' || template_name); lock_api(LOCKAPI_CREATE, 'move_backup'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_MOVE_BACKUP, param => 'move_backup' || b_p('tag', tag, p_first=>TRUE) || b_p('format', format) || b_p('template_name', template_name, p_last=>TRUE)); dbms_ra_int.canonicalize(template_name, c_template_name, 128); copy_move_int(p_tag => tag, p_bpkey => NULL, p_format => format, p_template_name => c_template_name, p_deleteit => TRUE); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END move_backup; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE copy_backup_piece (bp_key IN NUMBER, format IN VARCHAR2, template_name IN VARCHAR2) IS l_the NUMBER; c_template_name sbt_job_template.template_name%TYPE; BEGIN am_trace('copy_backup_piece: bp_key=' || bp_key || ' ,format=' || format || ' ,template_name=' || template_name); lock_api(LOCKAPI_CREATE, 'copy_backup_piece'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_COPY_BACKUP_PIECE, param => 'copy_backup_piece' || b_p('bp_key', bp_key, p_first=>TRUE) || b_p('format', format) || b_p('template_name', template_name, p_last=>TRUE)); dbms_ra_int.canonicalize(template_name, c_template_name, 128); copy_move_int(p_tag => NULL, p_bpkey => bp_key, p_format => format, p_template_name => c_template_name, p_deleteit => FALSE); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END copy_backup_piece; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE copy_backup (tag IN VARCHAR2, format IN VARCHAR2, template_name IN VARCHAR2) IS l_the NUMBER; c_template_name sbt_job_template.template_name%TYPE; BEGIN am_trace('copy_backup: tag=' || tag || ' ,format=' || format || ' ,template_name=' || template_name); lock_api(LOCKAPI_CREATE, 'copy_backup'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_COPY_BACKUP, param => 'copy_backup' || b_p('tag', tag, p_first=>TRUE) || b_p('format', format) || b_p('template_name', template_name, p_last=>TRUE)); dbms_ra_int.canonicalize(template_name, c_template_name, 128); copy_move_int(p_tag => tag, p_bpkey => NULL, p_format => format, p_template_name => c_template_name, p_deleteit => FALSE); unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE); EXCEPTION WHEN OTHERS THEN rollback; unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE); RAISE; END copy_backup; -- -- -- -- -- -- PROCEDURE migrate_tape_backup_int( db_unique_name IN VARCHAR2, sbt_lib_name IN VARCHAR2) IS CURSOR dbuniq_c(db_unique_name IN VARCHAR2) IS WITH table_to_parse as (select db_unique_name str from dual) SELECT DISTINCT ltrim(rtrim(new_str)) new_str FROM table_to_parse, xmltable('r/c' passing xmltype('' || replace(str,',','') || '') columns new_str varchar2(512) path '.'); -- -- CURSOR bp_c(db_key IN NUMBER) IS SELECT bp.rowid bp_rowid, bp.bp_key, bp.handle, bp.tag, bp.status, bp.piece#, bp.encrypted, bp.compressed, bs.bck_type, bs.set_stamp, bs.set_count, bs.block_size, bs.controlfile_included, nvl2(bsf.bsf_key, 1, 0) spfile_included FROM bp, bs LEFT OUTER JOIN bsf ON bs.bs_key = bsf.bs_key WHERE bp.bs_key = bs.bs_key AND bp.db_key = bp_c.db_key AND bp.status != 'D' AND bp.ba_access = 'U' -- non-AM backups AND bp.device_type != 'DISK' -- tape backups AND rownum <= 500 -- limit commit size by 500 rows FOR UPDATE OF bp.lib_key, bs.bs_key ORDER BY bs.bs_key, bp.bp_key; dbuniqRec dbuniq_c%ROWTYPE; bpRec bp_c%ROWTYPE; l_db_key NUMBER; l_dbid NUMBER; l_lib_key NUMBER; xmldoc CLOB; eoc BOOLEAN; l_ba_access VARCHAR2(1); l_db_name dbinc.db_name%TYPE; l_bstyp NUMBER; BEGIN -- BEGIN SELECT lib.lib_key, nvl2(lib.server_key, 'R', 'T') INTO l_lib_key, l_ba_access FROM sbt_lib_desc lib WHERE lib.lib_name = migrate_tape_backup_int.sbt_lib_name; EXCEPTION WHEN NO_DATA_FOUND THEN am_trace('migrate_tape_backup: ' || item_not_found(sbt_lib_name, 'sbt library')); sys.dbms_sys_error.raise_system_error (OBJ_NOT_FOUND_NUM, sbt_lib_name, 'sbt library', FALSE); END; am_trace ('MIGRATE_TAPE_BACKUP l_lib_key: ' || l_lib_key); am_trace ('MIGRATE_TAPE_BACKUP l_ba_access: ' || l_ba_access); FOR dbuniqRec IN dbuniq_c(db_unique_name) LOOP am_trace ('MIGRATE_TAPE_BACKUP for: ' || dbuniqRec.new_str); BEGIN SELECT db.db_key, db.db_id INTO l_db_key, l_dbid FROM node, db WHERE node.db_unique_name = dbuniqRec.new_str AND node.db_key = db.db_key -- -- AND NOT EXISTS (SELECT db_state FROM odb WHERE odb.db_key = node.db_key AND db_state IS NOT NULL) FOR UPDATE OF db.db_key; SELECT db_name INTO l_db_name FROM dbinc WHERE db_key = l_db_key AND dbinc_status = 'CURRENT'; EXCEPTION WHEN no_data_found THEN am_trace('migrate_tape_backup: ' || item_not_found(dbuniqRec.new_str, 'db unique name')); sys.dbms_sys_error.raise_system_error (OBJ_NOT_FOUND_NUM, dbuniqRec.new_str, 'db unique name', FALSE); END; eoc := FALSE; WHILE (not eoc) LOOP eoc := TRUE; -- -- FOR bpRec IN bp_c(l_db_key) LOOP am_trace ('MIGRATE_TAPE_BACKUP handle: ' || bpRec.handle); eoc:= FALSE; -- -- CASE bpRec.bck_type WHEN 'D' THEN l_bstyp := 4; WHEN 'I' THEN l_bstyp := 16; WHEN 'L' THEN l_bstyp := 8; ELSE l_bstyp := 0; END CASE; IF (bpRec.controlfile_included != 'NONE') THEN l_bstyp := l_bstyp + 1; END IF; IF (bpRec.spfile_included > 0) THEN l_bstyp := l_bstyp + 2; END IF; IF bprec.compressed = 'YES' THEN l_bstyp := l_bstyp + 32; END IF; IF bprec.encrypted = 'Y' THEN l_bstyp := l_bstyp + 64; END IF; -- -- am_trace ('MIGRATE_TAPE_BACKUP adding sbt catalog entry'); sys.kbrsi_icd.rsAddToSbtCatalog( bpkey => bpRec.bp_key, dbver => 0, dbname => l_db_name, dbid => l_dbid, handle => bpRec.handle, setstamp => bpRec.set_stamp, setcount => bpRec.set_count, pieceblksize => bpRec.block_size, pieceno => bpRec.piece#, tag => bpRec.tag, bstyp => l_bstyp); -- UPDATE bp SET status = bpRec.status, ba_access = l_ba_access, lib_key = l_lib_key, purged = 'N' WHERE rowid = bpRec.bp_rowid; am_trace ('MIGRATE_TAPE_BACKUP updated bp rows ' || SQL%ROWCOUNT); END LOOP; IF (not eoc) THEN COMMIT; ELSE am_trace ('MIGRATE_TAPE_BACKUP complete: ' || dbuniqRec.new_str); END IF; END LOOP; END LOOP; END migrate_tape_backup_int; PROCEDURE migrate_tape_backup( db_unique_name IN VARCHAR2, sbt_lib_name IN VARCHAR2) IS l_the NUMBER; c_sbt_lib_name sbt_lib_desc.lib_name%TYPE; BEGIN lock_api(LOCKAPI_CREATE, 'migrate_tape_backup'); l_the := dbms_ra_scheduler.add_to_task_history_table ( task_type => dbms_ra_scheduler.TASK_API_MIGRATE_TAPE, param => 'migrate_tape_backup' || b_p('db_unique_name', db_unique_name, p_first=>TRUE) || b_p('sbt_lib_name', sbt_lib_name, p_last=>TRUE)); dbms_ra_int.canonicalize(sbt_lib_name, c_sbt_lib_name, 128); migrate_tape_backup_int(upper(db_unique_name), c_sbt_lib_name); unlock_api(); EXCEPTION WHEN OTHERS THEN unlock_api(); RAISE; END migrate_tape_backup; -- -- -- -- -- -- -- -- PROCEDURE remove_rep_tasks(p_db_key IN NUMBER, p_template in VARCHAR2) IS l_template_key NUMBER; BEGIN BEGIN SELECT job.template_key INTO l_template_key FROM sbt_job_template job WHERE job.template_name = p_template; EXCEPTION WHEN NO_DATA_FOUND THEN -- am_trace ('rempove_rep_tasks: ' || item_not_found( p_template, 'replication template')); sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM, p_template, 'remreptasks-template', FALSE); END; -- SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0); -- -- UPDATE task t SET state = DBMS_RA_SCHEDULER.STATE_CANCEL WHERE t.db_key = p_db_key AND t.param_num2 = l_template_key AND t.state NOT IN (DBMS_RA_SCHEDULER.STATE_RUNNING, DBMS_RA_SCHEDULER.STATE_CANCELING) AND t.task_type IN (DBMS_RA_SCHEDULER.TASK_BACKUP_SBT, DBMS_RA_SCHEDULER.TASK_PURGE_SBT, DBMS_RA_SCHEDULER.TASK_OBSOLETE_SBT, DBMS_RA_SCHEDULER.TASK_RESTORE_SBT); COMMIT; -- SYS.KBRSI_ICD.RSSCHEDUNLOCK; EXCEPTION WHEN OTHERS THEN -- SYS.KBRSI_ICD.RSSCHEDUNLOCK; RAISE; END; -- -- -- -- -- -- PROCEDURE ctrl_c_check(check_what IN NUMBER) IS BEGIN -- IF (check_what = CCCHK_CREDEL_REP_SERVER OR check_what = CCCHK_ALL_APIS) THEN FOR x IN (SELECT rep_server_name FROM server s, rep_server r WHERE s.server_key = r.server_key AND status != 'A') LOOP delete_replication_server_int (x.rep_server_name, TRUE); END LOOP; END IF; END; -- -- -- -- -- -- FUNCTION is_ba_running RETURN BOOLEAN IS l_count NUMBER; BEGIN -- -- -- SELECT COUNT(*) INTO l_count FROM config WHERE config.name = '_recovery_appliance_state' AND config.value = 'ON'; IF l_count <> 0 THEN RETURN TRUE; ELSE RETURN FALSE; END IF; END; -- -- -- -- -- -- FUNCTION is_sysgen_obj(name IN VARCHAR2) RETURN BOOLEAN IS l_cnt NUMBER; BEGIN -- -- -- -- IF INSTR(name, '$') > 0 THEN RETURN TRUE; END IF; RETURN FALSE; END; -- -- -- -- -- -- FUNCTION is_rep_server(name IN VARCHAR2) RETURN BOOLEAN IS l_cnt NUMBER; BEGIN -- -- -- SELECT count(*) INTO l_cnt FROM server WHERE rep_server_name = name; -- IF l_cnt > 0 THEN RETURN TRUE; END IF; -- IF INSTR(name, 'REP$', 1) > 0 THEN RETURN TRUE; END IF; RETURN FALSE; END; -- END dbms_ra; >>> define prvtrsdmp_plb <<< CREATE OR REPLACE PACKAGE BODY dbms_ra_dump IS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- s_tracedump BOOLEAN := TRUE; -- add dump info to trace file s_filedump BOOLEAN := FALSE; -- add dump info to dir file s_file utl_file.file_type; -- handle for dir dump file s_datapump BOOLEAN := TRUE; -- produce a datapump dump s_blocks BOOLEAN := FALSE; -- including blocks table s_chunks BOOLEAN := FALSE; -- including chunks table s_start_history TIMESTAMP; -- start of recent history. s_file_ext VARCHAR2(4) := '.dat'; -- file extensions for files. -- WIDTH CONSTANT NUMBER := 132; -- page width SEPARATOR CONSTANT VARCHAR2(1) := '*'; -- header char RECENT_INTERVAL CONSTANT DSINTERVAL_UNCONSTRAINED := TO_DSINTERVAL('0 0:30:00'); -- recent times DUMP_DIR CONSTANT VARCHAR2(8) := 'RA_DUMP'; -- directory object for -- E_OBJECT_NO_LONGER_EXISTS EXCEPTION; PRAGMA EXCEPTION_INIT (E_OBJECT_NO_LONGER_EXISTS, -8103); -- PROCEDURE dumpOpen (filename VARCHAR2) IS BEGIN IF s_filedump THEN s_file := UTL_FILE.FOPEN (DUMP_DIR, filename || s_file_ext, 'A'); END IF; END dumpOpen; -- PROCEDURE dumpClose IS BEGIN IF s_filedump THEN UTL_FILE.FCLOSE (s_file); END IF; END dumpClose; -- PROCEDURE dumpLine (text VARCHAR2) IS BEGIN IF s_tracedump THEN -- sys.kbrsi_icd.rsTrace(REPLACE(text,'%','%%')); END IF; IF s_filedump THEN UTL_FILE.PUT_LINE (s_file, text); END IF; END dumpLine; -- PROCEDURE dumpHeader (text VARCHAR2) IS textpos NUMBER; BEGIN dumpLine(' '); dumpLine(LPAD(SEPARATOR, WIDTH, SEPARATOR)); -- textpos := (WIDTH - (LENGTH(text)+2))/ 2; dumpLine(RPAD(LPAD(SEPARATOR, textpos-1, SEPARATOR) || ' ' || text || ' ', WIDTH, SEPARATOR)); dumpLine(LPAD(SEPARATOR, WIDTH, SEPARATOR)); END dumpHeader; -- FUNCTION dumpPad (text VARCHAR2, len NUMBER) RETURN VARCHAR2 IS BEGIN RETURN RPAD(NVL(text, '*NULL*'), len, ' '); END; -- FUNCTION dumpPad (num NUMBER, len NUMBER) RETURN VARCHAR2 IS BEGIN IF num IS NULL THEN RETURN dumpPad (' ', len); ELSE RETURN SUBSTR(TO_CHAR(num, RPAD('9',len,'9')),2); END IF; END; FUNCTION dumpMB (num NUMBER, len NUMBER) RETURN VARCHAR2 IS BEGIN IF num IS NULL THEN RETURN dumpPad (' ', len); ELSE RETURN SUBSTR(TO_CHAR(num, RPAD('9',len-5,'9') || '.99'),2) || 'MB'; END IF; END; FUNCTION dumpGB (num NUMBER, len NUMBER) RETURN VARCHAR2 IS BEGIN IF num IS NULL THEN RETURN dumpPad (' ', len); ELSE RETURN SUBSTR(TO_CHAR(num, RPAD('9',len-5,'9') || '.99'),2) || 'GB'; END IF; END; FUNCTION dumpPct (num NUMBER) RETURN VARCHAR2 IS BEGIN IF num IS NULL THEN RETURN dumpPad (' ', 10); ELSE RETURN SUBSTR(TO_CHAR(num, '999999.99') || '%',2); END IF; END; FUNCTION dumpPad (ts TIMESTAMP WITH TIME ZONE, len NUMBER) RETURN VARCHAR2 IS BEGIN RETURN dumpPad(TO_CHAR(ts, 'DD-MM-YYYY HH24:MI:SS'), len); END; -- FUNCTION dumpPad (ts TIMESTAMP, len NUMBER) RETURN VARCHAR2 IS BEGIN RETURN dumpPad(TO_CHAR(ts, 'DD-MM-YYYY HH24:MI:SS'), len); END; FUNCTION dumpPad (ts DATE, len NUMBER) RETURN VARCHAR2 IS BEGIN RETURN dumpPad(TO_CHAR(ts, 'DD-MM-YYYY HH24:MI:SS'), len); END; FUNCTION dumpInt (thisint dsinterval_unconstrained, len NUMBER) RETURN VARCHAR2 IS temp VARCHAR2(200); BEGIN temp := SUBSTR(TO_CHAR(thisint),2); RETURN dumpPad(temp, len); END; -- PROCEDURE dumpBig (message VARCHAR2) IS C_NEWLINE CONSTANT CHAR(1) := CHR(10); --linefeed l_msglen PLS_INTEGER := LENGTH(message); l_nextbuf VARCHAR2(200); l_pos PLS_INTEGER := 1; l_endpos PLS_INTEGER; BEGIN WHILE l_msglen >= l_pos LOOP l_nextbuf := SUBSTR(message,l_pos,WIDTH); IF INSTR(l_nextbuf, C_NEWLINE) > 0 THEN l_endpos := INSTR(l_nextbuf,C_NEWLINE) - 1; ELSIF l_msglen + 1 - l_pos <= WIDTH THEN l_endpos := WIDTH; ELSIF INSTR(l_nextbuf, ' ', -1) > 0 THEN l_endpos := INSTR(l_nextbuf, ' ', -1) - 1; ELSE l_endpos := WIDTH; END IF; IF l_endpos > 0 THEN dumpLine (SUBSTR(l_nextbuf, 1, l_endpos)); IF SUBSTR(l_nextbuf,l_endpos,1) IN (C_NEWLINE, ' ') THEN l_endpos := l_endpos + 1; END IF; ELSE l_endpos := 1; END IF; l_pos := l_pos + l_endpos; END LOOP; END; -- PROCEDURE dumpStatus IS CURSOR log_entries IS SELECT incident#, last_seen, seen_count, status, SUBSTR(component,1,10) component, ospid, inst_id, task_id, DECODE(severity, 0, 'INFORMATION', 1, 'WARNING', 10, 'ERROR', 20, 'INTERNAL', TO_CHAR(severity)) severity, trace_file, error_text, DECODE(severity, 20, call_stack, NULL) call_stack FROM error_log ORDER BY status, severity, last_seen DESC; CURSOR recent_apis IS SELECT execute_time, task_type_name, db_key, sl_key, param FROM task_history LEFT OUTER JOIN tasktypenames USING (task_type) WHERE task_type >= dbms_ra_scheduler.task_min_api ORDER BY execute_time DESC; CURSOR ba_locks IS SELECT l.inst_id, SUBSTR(ras.spid, 1, 12) spid, ttn.task_type_name, DECODE(l.ba_type, 5, 'PDB ' || LPAD(l.key, 26-4), 6, 'SL ' || LPAD(l.key, 26-3), 7, DECODE(l.key, 1, 'TIMER', 2, 'SCHEDULING', 3, 'API EXECUTION', 4, 'QUIESCE RA', '7 ' || TO_CHAR(l.key)), 8, 'PURGE ' || LPAD(l.key, 26-6), 9, 'KEY ' || LPAD(l.key, 26-4), TO_CHAR(l.ba_type)) lock_type, DECODE(l.lmode, 1, 'NULL', -- other modes shouldnt be seen 2, 'SUB-SHARE', 4, 'SHARE', 6, 'EXCLUSIVE', TO_CHAR(l.lmode)) lock_mode, l.ctime FROM TABLE(CAST(dbms_ra_scheduler.s_amlocks AS rai_locks_table_type)) l JOIN sys.rai_active_sessions ras ON (l.sid = ras.sid) AND (l.inst_id = ras.inst_id) LEFT OUTER JOIN sessions s ON (l.sid = s.sid) AND (l.inst_id = s.instance_id) LEFT OUTER JOIN tasktypenames ttn ON (s.current_task_type = ttn.task_type) ORDER BY l.inst_id, l.sid; CURSOR configs IS SELECT name, value FROM config ORDER BY name; firstrow BOOLEAN := TRUE; BEGIN FOR c IN log_entries LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('Error Log Contents'); dumpLine (dumpPad('Incident#', 22) || dumpPad('Last seen', 22) || dumpPad('Count', 6) || dumpPad('Status', 7) || dumpPad('Component', 12) || dumpPad('OS pid', 13) || dumpPad('Inst id', 8) || dumpPad('Task id', 21) || 'Severity'); dumpLine (RPAD('-', 21, '-') || RPAD(' ', 22, '-') || RPAD(' ', 6, '-') || RPAD(' ', 7, '-') || RPAD(' ', 12, '-') || RPAD(' ', 13, '-') || RPAD(' ', 8, '-') || RPAD(' ', 21, '-') || RPAD(' ', 12, '-')); dumpLine ('Trace file'); dumpLine ('Error Message'); dumpLine ('Backtrace and Call Stack(s)'); END IF; dumpLine (dumpPad(c.incident#, 21) || ' ' || dumpPad(c.last_seen, 21) || ' ' || dumpPad(c.seen_count, 5) || ' ' || dumpPad(c.status, 6) || ' ' || dumpPad(c.component, 11) || ' ' || dumpPad(c.ospid,12) || ' ' || dumpPad(c.inst_id,7) || ' ' || dumpPad(c.task_id,20) || ' ' || dumpPad(c.severity,11)); dumpBig (c.trace_file); dumpBig (c.error_text); IF c.call_stack IS NOT NULL THEN dumpBig (c.call_stack); END IF; END LOOP; <> BEGIN firstrow := TRUE; FOR c IN recent_apis LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('Recent APIs'); dumpLine (dumpPad('Execute Time', 20) || 'Type'); dumpLine ('Param'); dumpLine (RPAD('-', 19, '-') || RPAD(' ', 20, '-')); END IF; dumpLine (dumpPad(c.execute_time, 19) || ' ' || dumpPad(c.task_type_name,19)); dumpBig (c.param); END LOOP; EXCEPTION WHEN E_OBJECT_NO_LONGER_EXISTS THEN -- GOTO RETRY_TASK_HISTORY; END; <> BEGIN firstrow := TRUE; DBMS_RA_SCHEDULER.MAKE_AMLOCKS(); FOR c IN ba_locks LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('recovery appliance Locks'); dumpLine (dumpPad('Instid', 7) || dumpPad('OS pid', 13) || dumpPad('Task type', 12) || dumpPad('Lock type', 27) || dumpPad('Lock mode', 10) || 'Secs Holding'); dumpLine (RPAD('-', 6, '-') || RPAD(' ', 13, '-') || RPAD(' ', 12, '-') || RPAD(' ', 27, '-') || RPAD(' ', 10, '-') || RPAD(' ', 13, '-')); END IF; dumpLine (dumpPad(c.inst_id, 6) || ' ' || dumpPad(c.spid, 12) || ' ' || dumpPad(c.task_type_name,11) || ' ' || dumpPad(c.lock_type,26) || ' ' || dumpPad(c.lock_mode,9) || ' ' || dumpPad(c.ctime,12)); END LOOP; EXCEPTION WHEN DBMS_RA_SCHEDULER.E_PQ_FAILURE THEN -- GOTO TRY_TRY_AGAIN; END; firstrow := TRUE; FOR c IN configs LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('CONFIG settings'); dumpLine (dumpPad('Name', 31) || 'Value'); dumpLine (RPAD('-', 30, '-') || RPAD(' ', 100, '-')); END IF; dumpLine (dumpPad(c.name, 30) || ' ' || c.value); END LOOP; END dumpStatus; -- PROCEDURE dumpSessions IS CURSOR active_sessions IS SELECT SUBSTR(usj.job_name,1,20) job_name, usj.running_instance, usj.slave_os_process_id, s.audsid, s.current_task, ctt.task_type_name current_task_type, p.task_type_name purpose FROM user_scheduler_running_jobs usj LEFT OUTER JOIN sessions s ON (usj.session_id = s.sid AND usj.running_instance = s.instance_id) LEFT OUTER JOIN tasktypenames ctt ON (s.current_task_type = ctt.task_type) LEFT OUTER JOIN tasktypenames p ON (s.purpose = ctt.task_type) WHERE usj.job_name LIKE 'RA$_%' ORDER BY usj.job_name, usj.running_instance; CURSOR dead_sessions IS SELECT s.instance_id, s.spid, s.audsid, s.current_task, ctt.task_type_name current_task_type, p.task_type_name purpose FROM sessions s LEFT OUTER JOIN tasktypenames ctt ON (s.current_task_type = ctt.task_type) LEFT OUTER JOIN tasktypenames p ON (s.purpose = ctt.task_type) WHERE NOT EXISTS (SELECT 1 FROM user_scheduler_running_jobs usj WHERE usj.job_name LIKE 'RA$_%' AND usj.session_id = s.sid AND usj.running_instance = NVL(s.instance_id,usj.running_instance)) ORDER BY instance_id, ba_session_id; l_done BOOLEAN := FALSE; firstrow BOOLEAN := TRUE; BEGIN WHILE NOT l_done LOOP BEGIN FOR c IN active_sessions LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('Active Sessions'); dumpLine (dumpPad('Job Name', 21) || dumpPad('Instid', 7) || dumpPad('OS pid', 13) || dumpPad('Audsid', 13) || dumpPad('Session type', 13) || dumpPad('Task ID', 21) || 'Task type'); dumpLine (RPAD('-', 20, '-') || RPAD(' ', 7, '-') || RPAD(' ', 13, '-') || RPAD(' ', 13, '-') || RPAD(' ', 13, '-') || RPAD(' ', 21, '-') || RPAD(' ', 13, '-')); END IF; dumpLine (dumpPad(c.job_name, 20) || ' ' || dumpPad(c.running_instance, 6) || ' ' || dumpPad(c.slave_os_process_id,12) || ' ' || dumpPad(c.audsid,12) || ' ' || dumpPad(c.purpose,12) || ' ' || dumpPad(c.current_task,20) || ' ' || c.current_task_type); END LOOP; l_done := TRUE; EXCEPTION WHEN dbms_ra_scheduler.e_pq_failure THEN dbms_lock.sleep(1); CONTINUE; END; END LOOP; l_done := FALSE; firstrow := TRUE; WHILE NOT l_done LOOP BEGIN FOR c IN dead_sessions LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('Dead Sessions'); dumpLine (dumpPad('Instid', 7) || dumpPad('OS pid', 13) || dumpPad('Audsid', 13) || dumpPad('Session type', 13) || dumpPad('CurTask ID', 21) || 'CurTask type'); dumpLine (RPAD('-', 6, '-') || RPAD(' ', 13, '-') || RPAD(' ', 13, '-') || RPAD(' ', 13, '-') || RPAD(' ', 21, '-') || RPAD(' ', 13, '-')); END IF; dumpLine (dumpPad(c.instance_id, 6) || ' ' || dumpPad(c.spid,12) || ' ' || dumpPad(c.audsid,12) || ' ' || dumpPad(c.purpose,12) || ' ' || dumpPad(c.current_task,20) || ' ' || c.current_task_type); END LOOP; l_done := TRUE; EXCEPTION WHEN dbms_ra_scheduler.e_pq_failure THEN dbms_lock.sleep(1); CONTINUE; END; END LOOP; END dumpSessions; -- PROCEDURE dumpTasks IS CURSOR current_tasks IS SELECT task_id, task_type_name, state, interrupt_count, pending_interrupt, savepoint, param_num1, db_key, sl_key, elapsed_time, param FROM task LEFT OUTER JOIN tasktypenames USING (task_type) ORDER BY task_id; CURSOR finished_tasks IS SELECT * FROM (SELECT task_id, task_type_name, param_num1, db_key, sl_key, elapsed_time, completion_time, param FROM task_history LEFT OUTER JOIN tasktypenames USING (task_type) WHERE task_type < 200 -- don't include API tasks or session fake tasks AND completion_time > s_start_history) ORDER BY completion_time desc; CURSOR sbt_tasks IS SELECT task_id, bs_key, attr_key, lib_key, failure_cnt, restore FROM sbt_task ORDER BY task_id; CURSOR timer_tasks IS SELECT DECODE (timer_type, 1, 'VERIFY', 2, 'POLLING', 3, 'HISTORY PRUNE', 4, 'REMOVE INCOMPLETE FILES', 5, 'STORAGE HISTOGRAM', 6, 'STORAGE MAINTENANCE', 7, 'TASK MAINTENANCE', 8, 'OBSOLETE SBT', 9, 'RECONCILE', 10, 'CROSSCHECK', 11, 'SPAWN SBT', 12, 'SET RECONCILE TIMER', 13, 'UNRESERVE DRIVES', 14, 'REMOVE UNRESERVE DRIVES', 15, 'REMOVE SBT SESSIONS', '***UNKNOWN*** ' || TO_CHAR(timer_type)) type, timer_location, next_execute, timer_interval FROM timer_task ORDER BY next_execute; firstrow BOOLEAN := TRUE; printint VARCHAR2(200); BEGIN FOR c IN current_tasks LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('Current tasks'); dumpLine (dumpPad('Task Id', 21) || dumpPad('Type', 15) || dumpPad('State', 14) || dumpPad('Interrupts', 11) || dumpPad('Waiting on', 21) || dumpPad('Savepoint', 10) || dumpPad('Param_num1', 21) || dumpPad('Dbkey', 21) || dumpPad('Slkey', 21) || 'Time used'); dumpLine ('Param'); dumpLine (RPAD('-', 20, '-') || RPAD(' ', 15, '-') || RPAD(' ', 14, '-') || RPAD(' ', 11, '-') || RPAD(' ', 21, '-') || RPAD(' ', 10, '-') || RPAD(' ', 21, '-') || RPAD(' ', 21, '-') || RPAD(' ', 21, '-') || RPAD(' ', 20, '-')); END IF; dumpLine (dumpPad(c.task_id, 20) || ' ' || dumpPad(c.task_type_name, 14) || ' ' || dumpPad(dbms_ra_scheduler.taskstate2name(c.state, c.pending_interrupt),13) || ' ' || dumpPad(c.interrupt_count,10) || ' ' || dumpPad(CASE WHEN c.pending_interrupt < 0 THEN NULL ELSE c.pending_interrupt END,20) || ' ' || dumpPad(c.savepoint,9) || ' ' || dumpPad(c.param_num1,20) || ' ' || dumpPad(c.db_key,20) || ' ' || dumpPad(c.sl_key,20) || ' ' || dumpPad(c.elapsed_time,19)); IF c.param IS NOT NULL THEN dumpBig(c.param); END IF; END LOOP; <> BEGIN firstrow := TRUE; FOR c IN finished_tasks LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('Completed tasks from last 30 minutes'); dumpLine (dumpPad('Task Id', 21) || dumpPad('Type', 15) || dumpPad('Param_num1', 10) || dumpPad('Dbkey', 21) || dumpPad('Slkey', 21) || dumpPad('Time used', 20) || 'Completion time'); dumpLine ('Param'); dumpLine (RPAD('-', 20, '-') || RPAD(' ', 15, '-') || RPAD(' ', 10, '-') || RPAD(' ', 21, '-') || RPAD(' ', 21, '-') || RPAD(' ', 20, '-') || RPAD(' ', 20, '-')); END IF; printint := dumpInt(c.elapsed_time,19); dumpLine (dumpPad(c.task_id, 20) || ' ' || dumpPad(c.task_type_name, 14) || ' ' || dumpPad(c.param_num1, 9) || ' ' || dumpPad(c.db_key,20) || ' ' || dumpPad(c.sl_key,20) || ' ' || dumpPad(printint,19) || ' ' || dumpPad(c.completion_time,19)); dumpBig(c.param); END LOOP; EXCEPTION WHEN E_OBJECT_NO_LONGER_EXISTS THEN -- -- dumpLine ('*** EXCEPTION: E_OBJECT_NO_LONGER_EXISTS'); END; firstrow := TRUE; FOR c IN sbt_tasks LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('SBT Tasks'); dumpLine (dumpPad('Task Id', 21) || dumpPad('BS key', 10) || dumpPad('Attr key', 10) || dumpPad('Lib Key', 10) || dumpPad('Failed', 7) || 'Restore'); dumpLine (RPAD('-', 20, '-') || RPAD(' ', 21, '-') || RPAD(' ', 21, '-') || RPAD(' ', 21, '-') || RPAD(' ', 7, '-') || RPAD(' ', 8, '-')); END IF; dumpLine (dumpPad(c.task_id, 20) || ' ' || dumpPad(c.bs_key,20) || ' ' || dumpPad(c.attr_key,20) || ' ' || dumpPad(c.lib_key,20) || ' ' || dumpPad(c.failure_cnt,20) || ' ' || c.restore); END LOOP; firstrow := TRUE; FOR c IN timer_tasks LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('Timer Tasks'); dumpLine (dumpPad('Timer type', 25) || dumpPad('Location', 10) || dumpPad('Next Execute', 20) || 'Interval'); dumpLine (RPAD('-', 24, '-') || RPAD(' ', 10, '-') || RPAD(' ', 20, '-') || RPAD(' ', 20, '-')); END IF; printint := dumpInt(c.timer_interval,19); dumpLine (dumpPad(c.type, 24) || ' ' || dumpPad(c.timer_location,9) || ' ' || dumpPad(c.next_execute,19) || ' ' || dumpPad(printint,19)); END LOOP; END dumpTasks; -- -- PROCEDURE dumpSls IS CURSOR sls IS SELECT SUBSTR(name,1,19) name, sl_key, min_alloc, total_space, dbms_ra_storage.freespace(sl_key)/(1024*1024*1024) freespace, freespace_goal, system_purging_space, disk_groups FROM ra_storage_location WHERE total_space > 0 ORDER BY name; CURSOR purge_queue IS SELECT SUBSTR(sl_name,1, 19) sl_name, sl_key, SUBSTR(db_unique_name,1, 19) db_name, db_key, purge_order, TO_CHAR(new_recovery_window) new_recovery, new_pct_recovery, pct_storage FROM ra_purging_queue ORDER BY sl_name, purge_order; CURSOR polling IS SELECT SUBSTR(polling_name,1, 19) polling_name, polling_key, frequency, dest FROM ra_polling_policy ORDER BY polling_name; firstrow BOOLEAN; printint VARCHAR2(200); BEGIN firstrow := TRUE; FOR c IN sls LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('Storage Locations'); dumpLine (dumpPad('Name', 20) || dumpPad('Sl_key', 21) || dumpPad('Min_alloc', 16) || dumpPad('Total Size', 16) || dumpPad('Freespace', 16) || dumpPad('Freespace goal', 16) || 'SysPurgeSpace'); dumpLine ('Disk Groups'); dumpLine (RPAD('-', 19, '-') || RPAD(' ', 21, '-') || RPAD(' ', 16, '-') || RPAD(' ', 16, '-') || RPAD(' ', 16, '-') || RPAD(' ', 16, '-') || RPAD(' ', 16, '-')); END IF; dumpLine (dumpPad(c.name, 19) || ' ' || dumpPad(c.sl_key, 20) || ' ' || dumpMB(c.min_alloc*1024, 15) || ' ' || dumpGB(c.total_space, 15) || ' ' || dumpGB(c.freespace, 15) || ' ' || dumpGB(c.freespace_goal, 15) || ' ' || dumpGB(c.system_purging_space, 15)); dumpBig(c.disk_groups); END LOOP; firstrow := TRUE; FOR c IN purge_queue LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('Purge queues'); dumpLine (dumpPad('Sl name', 20) || dumpPad('Sl_key', 21) || dumpPad('Db name', 20) || dumpPad('Db_key', 21) || dumpPad('Purge Order', 12) || dumpPad('New Recovery', 20) || dumpPad('% of Goal', 11) || '% of Reserve'); dumpLine (RPAD('-', 19, '-') || RPAD(' ', 21, '-') || RPAD(' ', 20, '-') || RPAD(' ', 21, '-') || RPAD(' ', 12, '-') || RPAD(' ', 20, '-') || RPAD(' ', 11, '-') || RPAD(' ', 11, '-')); END IF; dumpLine (dumpPad(c.sl_name, 19) || ' ' || dumpPad(c.sl_key,20) || ' ' || dumpPad(c.db_name, 19) || ' ' || dumpPad(c.db_key,20) || ' ' || dumpPad(c.purge_order,11) || ' ' || -- dumpPad(c.new_recovery,19) || ' ' || dumpPct(c.new_pct_recovery) || ' ' || dumpPct(c.pct_storage)); END LOOP; firstrow := TRUE; FOR c IN polling LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('Polling Policies'); dumpLine (dumpPad('Name', 20) || dumpPad('Poll_key', 21) || 'Frequency'); dumpLine ('Param'); dumpLine (RPAD('-', 19, '-') || RPAD(' ', 21, '-') || RPAD(' ', 20, '-')); END IF; printint := dumpInt(c.frequency, 19); dumpLine (dumpPad(c.polling_name, 19) || ' ' || dumpPad(c.polling_key, 20) || ' ' || dumpPad(printint, 19)); dumpBig(c.dest); END LOOP; END dumpSls; -- -- PROCEDURE dumpPdbs IS CURSOR pdbs IS SELECT SUBSTR(db_unique_name,1,19) name, db_key, deleting, dbid, SUBSTR(storage_location,1, 19) sl_name, space_usage, disk_reserved_space, recovery_window_goal, recovery_window_sbt FROM ra_database ORDER BY db_unique_name; CURSOR pdb_movement IS SELECT SUBSTR(db_unique_name,1,19) name, db_key, storage_movement_phase, storage_location_count FROM ra_database WHERE storage_movement_phase <> 'NOT MOVING' ORDER BY db_unique_name; CURSOR db_access IS SELECT SUBSTR(db_unique_name,1,19) db_name, db_key, SUBSTR(username, 1, 19) username FROM ra_db_access ORDER BY db_unique_name, username; firstrow BOOLEAN; printint VARCHAR2(200); printint2 VARCHAR2(200); BEGIN firstrow := TRUE; FOR c IN pdbs LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('Protected Databases'); dumpLine (dumpPad('Name', 20) || dumpPad('Db_key', 21) || dumpPad('Deleting', 9) || dumpPad('Dbid', 11) || dumpPad('SL Name', 20) || dumpPad('Space Usage', 16) || dumpPad('Reserved Space', 16) || dumpPad('Recovery Goal', 20) || 'SBT Recovery Goal'); dumpLine (RPAD('-', 19, '-') || RPAD(' ', 21, '-') || RPAD(' ', 09, '-') || RPAD(' ', 11, '-') || RPAD(' ', 20, '-') || RPAD(' ', 16, '-') || RPAD(' ', 16, '-') || RPAD(' ', 20, '-') || RPAD(' ', 20, '-')); END IF; printint := dumpInt(c.recovery_window_goal,19); printint2 := dumpInt(c.recovery_window_sbt,19); dumpLine (dumpPad(c.name, 19) || ' ' || dumpPad(c.db_key, 20) || ' ' || dumpPad(c.deleting, 8) || ' ' || dumpPad(c.dbid, 10) || ' ' || dumpPad(c.sl_name, 19) || ' ' || dumpGB(c.space_usage, 15) || ' ' || dumpGB(c.disk_reserved_space, 15) || ' ' || dumpPad(printint, 19) || ' ' || dumpPad(printint2, 19)); END LOOP; firstrow := TRUE; FOR c IN db_access LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('Database access'); dumpLine (dumpPad('Name', 20) || dumpPad('Db_key', 21) || 'Username'); dumpLine (RPAD('-', 19, '-') || RPAD(' ', 21, '-') || RPAD(' ', 20, '-')); END IF; dumpLine (dumpPad(c.db_name, 19) || ' ' || dumpPad(c.db_key, 20) || ' ' || dumpPad(c.username, 19)); END LOOP; firstrow := TRUE; FOR c IN pdb_movement LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('Moving Protected DataBases'); dumpLine (dumpPad('Name', 20) || dumpPad('Db_key', 21) || dumpPad('Move phase', 19) || 'SL Count'); dumpLine (RPAD('-', 19, '-') || RPAD(' ', 21, '-') || RPAD(' ', 19, '-') || RPAD(' ', 10, '-')); END IF; dumpLine (dumpPad(c.name, 19) || ' ' || dumpPad(c.db_key, 20) || ' ' || dumpPad(c.storage_movement_phase, 18) || ' ' || dumpPad(c.storage_location_count, 9)); END LOOP; END dumpPdbs; -- PROCEDURE dumpBps IS CURSOR bps IS SELECT s.db_key, s.ct_key, s.bp_key, s.sl_key, DECODE(s.ftype, 'F','FILE', 'T','TAPE', 'P','POLL', 'V','VIRT', '????') type, s.endupload, bp.bp_recid, bp.bp_stamp, bp.vb_key, bp.lib_key, s.completed, s.filesize/(1024*1024) filesize, s.cretime, s.last_entry, DECODE(s.pieceinc, 'unknown', ' ', s.pieceinc) pieceinc, s.handle FROM sbt_catalog s LEFT OUTER JOIN bp ON (s.bp_key = bp.bp_key) ORDER BY s.db_key, s.cretime; firstrow BOOLEAN; BEGIN firstrow := TRUE; FOR c IN bps LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('Backup Pieces'); dumpLine (dumpPad('Db_key', 21) || dumpPad('Ct_key', 21) || dumpPad('Bp_key', 21) || dumpPad('Sl_key', 21) || dumpPad('Type', 5) || dumpPad('EndLoad', 8) || dumpPad('Recid', 10) || 'Stamp'); dumpLine (RPAD('-', 20, '-') || RPAD(' ', 21, '-') || RPAD(' ', 21, '-') || RPAD(' ', 21, '-') || RPAD(' ', 5, '-') || RPAD(' ', 8, '-') || RPAD(' ', 10, '-') || RPAD(' ', 10, '-')); dumpLine (dumpPad('Vb_key', 21) || dumpPad('Lib_key',21) || dumpPad('Done', 5) || dumpPad('Filesize', 16) || dumpPad('Create Time', 20) || dumpPad('Last update', 20) || 'File Incarnation'); dumpLine (RPAD('-', 20, '-') || RPAD(' ', 21, '-') || RPAD(' ', 5, '-') || RPAD(' ', 16, '-') || RPAD(' ', 20, '-') || RPAD(' ', 20, '-') || RPAD(' ', 17, '-')); dumpLine ('Handle'); dumpLine (RPAD(' ', 120, '-')); END IF; dumpLine (dumpPad(c.db_key, 20) || ' ' || dumpPad(c.ct_key, 20) || ' ' || dumpPad(c.bp_key, 20) || ' ' || dumpPad(c.sl_key, 20) || ' ' || dumpPad(c.type, 4) || ' ' || dumpPad(c.endupload, 7) || ' ' || dumpPad(c.bp_recid, 9) || ' ' || dumpPad(c.bp_stamp, 9)); dumpLine (dumpPad(c.vb_key, 20) || ' ' || dumpPad(c.lib_key, 20) || ' ' || dumpPad(NVL(c.completed,'Y'), 4) || ' ' || dumpMB(c.filesize, 15) || ' ' || dumpPad(c.cretime, 19) || ' ' || dumpPad(c.last_entry, 19) || ' ' || dumpPad(c.pieceinc,16)); dumpBig(c.handle); END LOOP; END dumpBps; -- PROCEDURE dumpCFinfo IS CURSOR grps IS SELECT SUBSTR(g.gname,1,30) gname, g.gid gid, g.ausize ausize, to_char(g.gvfld1, 'xxxxxxxx') gvfld1, to_char(g.gvfld2, 'xxxxxxxx') gvfld2 FROM sys.amgrp$ g ORDER BY gid; CURSOR conts IS SELECT SUBSTR(g.gname,1,30) gname, g.gid gid, c.cid cid, c.crid crid, to_char(c.cvfld, 'xxxxxxxx') cvfld , c.state state, c.fsize cont_fsize, c.fname cont_fname FROM sys.amcont$ c JOIN sys.amgrp$ g ON (c.gid = g.gid) ORDER BY cid; CURSOR rvs IS SELECT SUBSTR(a.gname,1,30) gname, a.amrv_key amrv_key, DECODE(a.opstate, 'R','REBUILD', 'V','VALIDATE', '????') operation, DECODE(a.phase, 'I','INIT', 'S','STRUCTURE R/V', 'F','CONTAINED FILE R/V', 'Z','FINALIZING', 'C','COMPLETED', '????') phase, DECODE(a.step, 'B','PHASE_STARTED', 'A','PHASE_ABORTED_FATAL', 'E','PHASE_COMPLETED_WITH_ERRORS', 'C','PHASE_COMPLETED_NO_ERRORS', '????') execution_step, DECODE(a.error, 'E','FINSIHED WITH ERRORS', 'N','FINSIHED NO ERRORS', 'A','R/V ABORTED', 'a','ROW FOUND ABANDONDED', '????') results, pct_done, starttime, finishtime, doneid FROM sys.amrv$ a ORDER BY amrv_key; CURSOR rvmsgs IS SELECT SUBSTR(a.gname,1,30) gname, m.amrv_key amrv_key, m.amrvmsg_key amrvmsg_key, msgtime, msgphase, msgcode, NVL(fname, '') fname, NVL(msg, '') msg FROM sys.amrv$msg m LEFT OUTER JOIN sys.amrv$ a ON (a.amrv_key = m.amrv_key) WHERE msgcode NOT IN (101,102,103) ORDER BY m.amrv_key, m.amrvmsg_key; firstrow BOOLEAN; BEGIN firstrow := TRUE; FOR c IN grps LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('Container Groups'); dumpLine (dumpPad('Name', 31) || dumpPad('GID', 21) || dumpPad('AU Size', 12) || dumpPad('gvfld1', 11) || dumpPad('gvfld2', 11)); dumpLine (RPAD('-', 30, '-') || RPAD(' ', 21, '-') || RPAD(' ', 12, '-') || RPAD(' ', 11, '-') || RPAD(' ', 11, '-')); END IF; dumpLine (dumpPad(c.gname, 30) || ' ' || dumpPad(c.gid, 20) || ' ' || dumpPad(c.ausize, 11) || ' ' || dumpPad(c.gvfld1, 10) || ' ' || dumpPad(c.gvfld2, 10)); END LOOP; firstrow := TRUE; FOR c IN conts LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('Container Files'); dumpLine (dumpPad('Name', 31) || dumpPad('GID', 21) || dumpPad('CID', 21) || dumpPad('CRID', 21) || dumpPad('cvfld', 11) || dumpPad('state', 10) || dumpPad('fsize', 10)); dumpLine (RPAD('-', 30, '-') || RPAD(' ', 21, '-') || RPAD(' ', 21, '-') || RPAD(' ', 21, '-') || RPAD(' ', 11, '-') || RPAD(' ', 10, '-') || RPAD(' ', 10, '-')); dumpLine ('Container Filename'); dumpLine (RPAD('-', 127, '-')); END IF; dumpLine (dumpPad(c.gname, 30) || ' ' || dumpPad(c.gid, 20) || ' ' || dumpPad(c.cid, 20) || ' ' || dumpPad(c.crid, 20) || ' ' || dumpPad(c.cvfld, 10) || ' ' || dumpPad(c.state, 9) || ' ' || dumpGB (c.cont_fsize, 9)); dumpLine(dumpPad(c.cont_fname, 127)); END LOOP; firstrow := TRUE; FOR c IN rvs LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('Rebuild/Validate Executions'); dumpLine (dumpPad('Name', 31) || dumpPad('amrv_key', 21) || dumpPad('Operation', 10) || dumpPad('Phase', 20) || dumpPad('Execution Step', 27)); dumpLine (RPAD('-', 30, '-') || RPAD(' ', 21, '-') || RPAD(' ', 10, '-') || RPAD(' ', 20, '-') || RPAD(' ', 27, '-')); dumpLine (dumpPad('Results', 25) || dumpPad('Pct', 6) || dumpPad('Start', 21) || dumpPad('End', 21) || dumpPad('doneid', 10)); dumpLine (RPAD('-', 24, '-') || RPAD(' ', 6, '-') || RPAD(' ', 21, '-') || RPAD(' ', 21, '-') || RPAD(' ', 10, '-')); END IF; dumpLine (dumpPad(c.gname, 30) || ' ' || dumpPad(c.amrv_key, 20) || ' ' || dumpPad(c.operation, 9) || ' ' || dumpPad(c.phase, 19) || ' ' || dumpPad(c.execution_step, 26)); dumpLine( dumpPad(c.results, 24) || ' ' || dumpPad(c.pct_done, 5) || ' ' || dumpPad(c.starttime, 20) || ' ' || dumpPad(c.finishtime, 20) || ' ' || dumpPad(c.doneid, 9)); END LOOP; firstrow := TRUE; FOR c IN rvmsgs LOOP IF firstrow THEN firstrow := FALSE; dumpHeader('Rebuild/Validate Messages'); dumpLine (dumpPad('Name', 31) || dumpPad('amrv_key', 21) || dumpPad('amrvmsg_key', 21) || dumpPad('Message Time', 21) || dumpPad('Phase', 6) || dumpPad('Code', 10)); dumpLine (RPAD('-', 30, '-') || RPAD(' ', 21, '-') || RPAD(' ', 21, '-') || RPAD(' ', 21, '-') || RPAD(' ', 6, '-') || RPAD(' ', 10, '-')); dumpLine('Filename'); dumpLine (RPAD('-', 127, '-')); dumpLine('Message'); dumpLine (RPAD('-', 127, '-')); END IF; dumpLine (dumpPad(c.gname, 30) || ' ' || dumpPad(c.amrv_key, 20) || ' ' || dumpPad(c.amrvmsg_key, 20) || ' ' || dumpPad(c.msgtime, 20) || ' ' || dumpPad(c.msgphase, 5) || ' ' || dumpPad(c.msgcode, 9)); dumpBig(c.fname); dumpBig(c.msg); END LOOP; END dumpCFinfo; -- PROCEDURE dumpDataPump (filename VARCHAR2) IS l_md_filter VARCHAR2(200); -- tables to exclude h1 NUMBER; -- Data Pump job handle job_state VARCHAR2(30); -- To keep track of job state sts ku$_Status; ind NUMBER; -- Loop index spos NUMBER; -- String starting position slen NUMBER; -- String length for output le ku$_LogEntry; -- For WIP and error messages BEGIN IF NOT s_filedump THEN dumpHeader('No DataPump dump since directory was not found'); ELSE dumpHeader('DataPump dumpfile will be saved at ' || DUMP_DIR || ':' || filename || '_dp' || s_file_ext); -- h1 := dbms_datapump.open('EXPORT','SCHEMA',NULL,'DUMPJOB' || rai_sq.NEXTVAL); -- dbms_datapump.add_file(h1,filename || '_DATAPUMPlog' || s_file_ext, DUMP_DIR, NULL, dbms_datapump.ku$_file_type_log_file, NULL); -- dbms_datapump.set_parameter(h1, 'COMPRESSION', 'ALL'); dbms_datapump.set_parameter(h1, 'COMPRESSION_ALGORITHM', 'MEDIUM'); -- dbms_datapump.add_file(h1,filename || '_DATAPUMP' || s_file_ext, DUMP_DIR, NULL, dbms_datapump.ku$_file_type_dump_file, NULL); -- IF NOT (s_blocks AND s_chunks) THEN IF (NOT s_blocks) AND (NOT s_chunks) THEN l_md_filter := 'IN (''BLOCKS'',''PLANS_DETAILS'',''CHUNKS'')'; ELSIF (NOT s_blocks) THEN l_md_filter := 'IN (''BLOCKS'',''PLANS_DETAILS'')'; ELSE l_md_filter := 'IN (''CHUNKS'')'; END IF; dbms_datapump.metadata_filter(h1, 'EXCLUDE_NAME_EXPR', l_md_filter, 'TABLE'); END IF; -- dbms_datapump.start_job(h1); -- job_state := 'UNDEFINED'; WHILE (job_state != 'COMPLETED') AND (job_state != 'COMPLETING') AND (job_state != 'STOPPED') LOOP -- dbms_datapump.get_status(h1,0,0,job_state,sts); dbms_lock.sleep(2); END LOOP; END IF; dumpHeader('DataPump dumpfile has been saved.'); -- EXCEPTION WHEN OTHERS THEN dumpLine('Exception in Data Pump job'); dumpLine(SQLERRM); dumpLine('Data Pump errors:'); dbms_datapump.get_status(h1,dbms_datapump.ku$_status_job_error,0, job_state,sts); IF (BITAND(sts.mask,dbms_datapump.ku$_status_job_error) != 0) THEN le := sts.error; IF le IS NOT NULL THEN ind := le.FIRST; WHILE ind IS NOT NULL LOOP spos := 1; slen := LENGTH(le(ind).LogText); IF slen > 255 THEN slen := 255; END IF; WHILE slen > 0 LOOP dumpLine(substr(le(ind).LogText,spos,slen)); spos := spos + 255; slen := length(le(ind).LogText) + 1 - spos; END LOOP; ind := le.NEXT(ind); END LOOP; END IF; END IF; END dumpDataPump; -- PROCEDURE dumper (ospid IN VARCHAR2, quiesce IN BOOLEAN DEFAULT FALSE, datapumpdump IN BOOLEAN DEFAULT TRUE) IS l_dumper_params VARCHAR2(512); l_pos NUMBER := 1; l_pos2 NUMBER; l_keyword VARCHAR2(100); counter NUMBER; l_filename VARCHAR2(100); l_backtrace_stack VARCHAR2(4000); l_call_stack VARCHAR2(4000); l_error_stack VARCHAR2(4000); l_ospid VARCHAR2(24); BEGIN -- DBMS_RA_SCHEDULER.ASSERT_OWNER; IF quiesce THEN DBMS_RA_SCHEDULER.QUIESCE_RS(); END IF; -- SELECT MAX(DECODE(name, '_dumper_params', value)) , MAX(DECODE(name, '_dumper_file_ext', LOWER(value))) INTO l_dumper_params, s_file_ext FROM config WHERE name IN ('_dumper_params', '_dumper_file_ext'); LOOP l_pos2 := INSTR (l_dumper_params, ',', l_pos); IF l_pos2 = 0 THEN l_keyword := SUBSTR(l_dumper_params, l_pos); ELSE l_keyword := SUBSTR(l_dumper_params, l_pos, l_pos2-l_pos); END IF; CASE UPPER(l_keyword) WHEN 'DATAPUMP' THEN s_datapump := TRUE; WHEN 'NODATAPUMP' THEN s_datapump := FALSE; WHEN 'BLOCKS' THEN s_blocks := TRUE; WHEN 'NOBLOCKS' THEN s_blocks := FALSE; WHEN 'CHUNKS' THEN s_chunks := TRUE; WHEN 'NOCHUNKS' THEN s_chunks := FALSE; ELSE NULL; END CASE; -- EXIT WHEN l_pos2 = 0; -- l_pos := l_pos2 + 1; END LOOP; -- IF l_ospid IS NULL THEN SELECT spid INTO l_ospid FROM sys.rai_my_ospid WHERE ROWNUM=1; END IF; -- l_filename := 'radump_time_' || TO_CHAR(SYSTIMESTAMP , 'HH24MISS') || '__ospid_' || TRIM(l_ospid); -- s_start_history := (SYSTIMESTAMP - RECENT_INTERVAL); -- SELECT COUNT(*) INTO counter FROM all_directories WHERE directory_name = DUMP_DIR; IF counter = 0 THEN s_tracedump := TRUE; s_filedump := FALSE; ELSE s_tracedump := FALSE; s_filedump := TRUE; END IF; -- dumpOpen(l_filename || '_RADUMP'); dumpHeader('Recovery Appliance state dump for pid ' || l_ospid || ' at ' || TO_CHAR(SYSTIMESTAMP, 'DD-MM-YYYY HH24:MI:SS')); dumpStatus; -- error log, recent apis, and locks dumpSessions; -- active sessions, dead sessions dumpTasks; -- current tasks, recent tasks, sbt tasks, timer tasks dumpSls; -- storage locations, purge queues and polling locs dumpPdbs; -- pdbs, privs dumpBps; -- sbt_catalog table dumpCFinfo; -- container file info, amgrp$, amcont$, amrv$, amrv$msg IF s_datapump AND datapumpdump THEN dumpDataPump (l_filename); -- END IF; dumpHeader('End of recovery appliance state dump at ' || TO_CHAR(SYSTIMESTAMP, 'DD-MM-YYYY HH24:MI:SS')); -- dumpClose; IF quiesce THEN DBMS_RA_SCHEDULER.UNQUIESCE_RS(); END IF; EXCEPTION WHEN OTHERS THEN l_backtrace_stack := SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE(); l_call_stack := SYS.DBMS_UTILITY.FORMAT_CALL_STACK(); dumpLine (l_call_stack); dumpLine (l_backtrace_stack); dumpClose; IF quiesce THEN DBMS_RA_SCHEDULER.UNQUIESCE_RS(); END IF; RAISE; END dumper; END dbms_ra_dump; >>> define prvtrspl_plb <<< CREATE OR REPLACE PACKAGE BODY dbms_ra_pool IS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- /*---------------------------------------------------------------------------* * PRIVATE TYPES AND CONSTANTS * *---------------------------------------------------------------------------*/ /*----------------------------------------* * Session scoped Package State Variables * *----------------------------------------*/ -- debug NUMBER := AM_DEBUG_HIGH; --AM_DEBUG_ON; debug_outtype NUMBER := sys.dbms_system.trace_file; s_safemode BOOLEAN := FALSE; -- -- -- saved_vbkey NUMBER; -- Backup processing: remember the vbkey saved_krbphdf NUMBER; -- Backup processing: remember dfkey for krbph saved_krbph NUMBER; -- Backup processing: remember chunk# for krbph saved_krbph_name VARCHAR2(513); -- Name of saved_krbph chunk. saved_krbph_cfname VARCHAR2(513); -- Name of saved_krbph cf piece file chunk. saved_krbph_spname VARCHAR2(513); -- Name of saved_krbph sp piece file chunk. -- -- -- s_purge_dbinc NUMBER; -- s_purgeknows NUMBER; -- TRUE# CONSTANT NUMBER := 1; FALSE# CONSTANT NUMBER := 0; SPACING CONSTANT NUMBER := 10; -- Sequence space, allow for post recs MAXCHUNKSIZE CONSTANT NUMBER := (32 * 1024 * 1024); MAXDELCHUNKS CONSTANT NUMBER := 100; -- Guestimate: See purge_pool for usage -- -- -- -- -- TOTBLKPRCHNKS CONSTANT NUMBER := 1000000; MIN_READ_BUFS CONSTANT NUMBER := 10; -- Minimum read buffers. DEF_READ_BUFS CONSTANT NUMBER := 128; -- Default read buffers. DEF_READ_SIZE CONSTANT NUMBER := 12 * 32 * 1024; -- Default 384k read buf size -- MBLK_SIZE CONSTANT NUMBER := 84; /* sizeof(kbrscb) + sizeof(krbpmd) */ -- -- -- -- -- -- -- -- RESTART_PURGE_OBSOLETEP CONSTANT NUMBER := 11; -- We Started obsolete plans RESTART_PURGE_DEL_BLOCKS CONSTANT NUMBER := 12; -- We started deleting blocks RESTART_PURGE_VBDF CONSTANT NUMBER := 14; -- We started purge vbdf RESTART_PURGE_ALL_RETRY1 CONSTANT NUMBER := 15; -- Purge_all needs retry RESTART_PURGE_ALL_RETRY2 CONSTANT NUMBER := 16; -- Purge_all needs retry RESTART_PURGE_ALL_RETRY3 CONSTANT NUMBER := 17; -- Purge_all needs retry /*--------------------------------------------------* * Function/State variables * * These are config values that do not change value * *--------------------------------------------------*/ sf_chunksize NUMBER := NULL; sf_curr_db NUMBER := 0; sf_pooloff BOOLEAN := NULL; -- FUNCTION f_chunksize(p_dbkey IN NUMBER) RETURN NUMBER IS BEGIN -- IF sf_curr_db != p_dbkey THEN SELECT sl_min_alloc INTO sf_chunksize FROM odb WHERE db_key = p_dbkey; sf_curr_db := p_dbkey; END IF; RETURN sf_chunksize; END f_chunksize; -- FUNCTION f_pooloff RETURN BOOLEAN IS l_pooloff config.value%TYPE; BEGIN IF sf_pooloff IS NULL THEN SELECT NVL(UPPER(MAX(value)), 'NO') INTO l_pooloff FROM config WHERE name = '_pooloff'; sf_pooloff := (l_pooloff = 'YES'); END IF; RETURN sf_pooloff; END f_pooloff; /*---------------------------------------------------------------------------* * PRIVATE FUNCTION DECLARATIONS * *---------------------------------------------------------------------------*/ PROCEDURE deb(p_line IN varchar2, p_level IN NUMBER DEFAULT AM_DEBUG_ON); PROCEDURE purge_lock(p_key IN NUMBER); PROCEDURE purge_unlock(p_key IN NUMBER); PROCEDURE debugdf(p_dfkey IN NUMBER); PROCEDURE save_error; PROCEDURE clear_error; FUNCTION print (p_value IN BOOLEAN) RETURN VARCHAR2; PROCEDURE raise_bad_metadata(p_dfkey IN NUMBER); PROCEDURE working_ckpid(p_dbkey IN NUMBER, p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_orphans IN BOOLEAN, -- orphan backups p_dbinckey IN OUT NUMBER, -- in backup dbinc p_ckpid IN OUT NUMBER, -- in backup ckpid p_deadinc OUT NUMBER, -- orphan inc we no need p_orphaninc OUT NUMBER); -- orphan blocks inc PROCEDURE alloc_plan(p_dbkey IN NUMBER, p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_qtype IN NUMBER); PROCEDURE dealloc_plan(p_dfkey IN NUMBER, p_vbkey IN NUMBER DEFAULT NULL, p_qtype IN NUMBER DEFAULT NULL, p_lock IN BOOLEAN DEFAULT TRUE); PROCEDURE trim_plan(p_dfkey IN NUMBER); FUNCTION fragmentation(p_dbkey IN NUMBER, p_dfkey IN NUMBER, p_vbkey IN NUMBER) RETURN NUMBER; PROCEDURE show_plan(p_vbkey IN NUMBER, -- Virtual backup id p_dfkey IN NUMBER, -- Datafile key p_krbph_dfkey IN NUMBER, -- Datafile key for krbph p_qtype IN NUMBER); -- KBRSPLBLD_ type stored in plan PROCEDURE plan_blocks(p_vbkey IN NUMBER, -- Virtual backup id p_dfkey IN NUMBER, -- Datafile key p_chunksize IN NUMBER, -- size of chunk p_bufsize IN NUMBER, -- size of read buffers p_blksize IN NUMBER, -- size of each block p_type IN NUMBER, -- KBRSPLBLD_ type p_totalsize OUT NUMBER, -- backup size of df p_totalblocks OUT NUMBER, -- blocks in datafile p_totalchunks OUT NUMBER, -- distinct chunks in plan p_signature OUT NUMBER, -- signature 4 restore p_maxrank OUT NUMBER); -- block ranking in plan PROCEDURE restore_plan_blocks(p_type IN NUMBER, -- KBRSPLBLD_ type p_dfkey IN NUMBER, -- Datafile key p_vbkey IN NUMBER, -- Virtual backup id p_blksize IN NUMBER);-- size of each block PROCEDURE old_chunks(p_type IN NUMBER, p_dfkey IN NUMBER, p_vbkey IN NUMBER); PROCEDURE restricted_purge(p_dfkey IN NUMBER, -- Datafile key p_vbkey IN NUMBER, -- Virtual backup id p_type IN NUMBER, -- plan type p_dbkey IN NUMBER, p_chunks IN NUMBER); PROCEDURE optimize_blocks(p_dfkey IN NUMBER, p_vbkey IN NUMBER, -- Virtual backup id p_type IN NUMBER, -- plan type p_stored OUT NUMBER, p_needs OUT NUMBER); PROCEDURE purge_pool(p_dbkey IN NUMBER, p_type IN NUMBER, p_qtype IN NUMBER, p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_dflocked IN BOOLEAN DEFAULT FALSE); PROCEDURE purge_vbdf(p_dbkey IN NUMBER, p_type IN NUMBER, p_dfkey IN NUMBER, p_vbkey IN NUMBER); PROCEDURE reorderDF(p_type IN NUMBER, -- Type of KBRSPLBLD_% to perform p_dfkey IN NUMBER, p_vbkey IN NUMBER); PROCEDURE purgeRes(p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_savepoint IN NUMBER, p_small OUT BOOLEAN); PROCEDURE set_next_retention(p_dbkey IN NUMBER, p_currinc IN NUMBER, p_outscn OUT NUMBER); PROCEDURE purgeObsolete(p_slkey IN NUMBER, p_dbkey IN NUMBER, p_notasks IN BOOLEAN); PROCEDURE process_allfiles (p_dbkey IN NUMBER, p_bskey IN NUMBER, p_bpkey IN NUMBER, p_toname IN VARCHAR2, p_hasdups IN BOOLEAN, p_update IN BOOLEAN); PROCEDURE cleanup(p_vbkey IN NUMBER); FUNCTION isTaped(p_dbkey IN NUMBER, p_bpkey IN NUMBER, p_bskey IN NUMBER) RETURN BOOLEAN; PROCEDURE new_plans (p_dbkey IN NUMBER, p_dfkey IN NUMBER, p_nopurge IN BOOLEAN DEFAULT FALSE); FUNCTION orphans (p_dbkey IN NUMBER, p_dfkey IN NUMBER, p_currinc IN NUMBER DEFAULT NULL) RETURN BOOLEAN; FUNCTION orphan_bp(p_dbkey IN NUMBER, p_dfkey IN NUMBER, p_currinc IN NUMBER) RETURN BOOLEAN; FUNCTION orphan_blocks(p_dbkey IN NUMBER, p_dfkey IN NUMBER) RETURN BOOLEAN; PROCEDURE orphan_safe(p_dbkey IN NUMBER, p_dfkey IN NUMBER, p_currinc IN NUMBER, o_vbkey OUT NUMBER, o_scn OUT NUMBER); PROCEDURE orphan_common(p_dbinc_a IN NUMBER, p_dbinc_b IN NUMBER, p_dfkey IN NUMBER, o_ckpid OUT NUMBER, o_ckpscn OUT NUMBER); PROCEDURE q_restore_fast(p_type IN NUMBER, -- KBRSPLBLD_ type p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_incrscn IN NUMBER, p_ckpscn IN NUMBER, p_absscn IN NUMBER, p_ckpid IN NUMBER, p_minckpid IN NUMBER, p_maxckpid IN NUMBER, p_dbinc_key IN NUMBER, p_firstblk IN NUMBER, p_lastblk IN NUMBER); PROCEDURE q_restore_incs(p_type IN NUMBER, -- KBRSPLBLD_ type p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_incrscn IN NUMBER, p_ckpscn IN NUMBER, p_absscn IN NUMBER, p_ckpid IN NUMBER, p_minckpid IN NUMBER, p_maxckpid IN NUMBER, p_dbinc_key IN NUMBER, p_deadinc IN NUMBER, p_orphaninc IN NUMBER, p_maxorphscn IN NUMBER, p_firstblk IN NUMBER, p_lastblk IN NUMBER); PROCEDURE q_restore_cdb(p_type IN NUMBER, -- KBRSPLBLD_ type p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_incrscn IN NUMBER, p_ckpscn IN NUMBER, p_absscn IN NUMBER, p_ckpid IN NUMBER, p_minckpid IN NUMBER, p_maxckpid IN NUMBER, p_pdbinc_key IN NUMBER, p_dbinc_key IN NUMBER, p_deadinc IN NUMBER, p_orphaninc IN NUMBER, p_maxorphscn IN NUMBER, p_firstblk IN NUMBER, p_lastblk IN NUMBER, p_orphans IN BOOLEAN); PROCEDURE q_purge_basic(p_type IN NUMBER, -- KBRSPLBLD_ type p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_dbkey IN NUMBER, p_currinc IN NUMBER, p_ckpscn IN NUMBER, p_absscn IN NUMBER, p_ckpid IN NUMBER, p_minckpid IN NUMBER); PROCEDURE q_purge_orphan(p_type IN NUMBER, -- KBRSPLBLD_ type p_dbkey IN NUMBER, p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_ckpscn IN NUMBER, p_absscn IN NUMBER, p_ckpid IN NUMBER, p_minckpid IN NUMBER, p_maxckpid IN NUMBER, p_dbinc_key IN NUMBER, p_deadinc IN NUMBER, -- Orphan inc we no need p_orphaninc IN NUMBER); -- Orphan block inc PROCEDURE q_purge_dup(p_type IN NUMBER, p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_dbkey IN NUMBER, p_currinc IN NUMBER, p_fuzdif IN NUMBER, p_minscn IN NUMBER); PROCEDURE q_purge_all(p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_dbkey IN NUMBER); /*---------------------------------------------------------------------------* * EXPORT FUNCTIONS * *---------------------------------------------------------------------------*/ -- -- -- -- -- -- -- -- -- PROCEDURE setDebug(p_level IN NUMBER, p_safemode IN NUMBER, p_outtype IN NUMBER DEFAULT sys.dbms_system.trace_file) IS BEGIN debug := p_level; s_safemode := (p_safemode = 1); debug_outtype := p_outtype; END setDebug; -- -- -- -- -- -- -- -- FUNCTION incrLevel(p_create_scn IN NUMBER, -- bdf.create_scn p_incr_scn IN NUMBER) -- bdf.incr_scn RETURN NUMBER IS l_level NUMBER; BEGIN -- -- -- -- -- -- -- -- IF p_incr_scn = 0 OR (p_incr_scn <= p_create_scn) THEN l_level := 0; ELSE l_level := 1; END IF; RETURN l_level; END incrLevel; -- -- -- -- -- -- -- PROCEDURE prep_piece_read(p_inbpkey IN NUMBER, p_loc OUT VARCHAR2, -- Storage location p_dbkey OUT NUMBER, p_db_id OUT NUMBER, p_dfkey OUT NUMBER, -- 0 if more than 1 df p_vbkey OUT NUMBER, p_blksize OUT NUMBER, p_original OUT NUMBER, -- 1 == Virtual copy p_read_bufs OUT NUMBER, p_read_size OUT NUMBER, p_read_waste OUT NUMBER) IS -- CURSOR fPlans(c_bskey NUMBER, c_vbkey NUMBER, c_type NUMBER) IS SELECT df_key FROM vbdf v, bdf d WHERE v.dbinc_key = d.dbinc_key AND v.ckp_scn = d.ckp_scn AND v.file# = d.file# AND d.bs_key = c_bskey AND v.vb_key = c_vbkey MINUS SELECT /*+ INDEX(p) */ df_key FROM plans p WHERE p.type = c_type AND p.vb_key = c_vbkey AND p.df_key IN ( SELECT v.df_key FROM vbdf v WHERE v.vb_key = c_vbkey ) AND p.blksread IS NOT NULL; -- CURSOR fnos(c_bskey NUMBER, c_vbkey NUMBER) IS SELECT v.db_key, v.vb_key, v.df_key, v.vcbp_key FROM vbdf v, bdf d WHERE v.dbinc_key = d.dbinc_key AND v.ckp_scn = d.ckp_scn AND v.file# = d.file# AND v.vb_key = c_vbkey AND d.bs_key = c_bskey; l_dfkey NUMBER; l_numdf NUMBER := 0; l_vcbpkey NUMBER; l_type NUMBER := NULL; l_bskey NUMBER; l_count NUMBER; l_handle VARCHAR2(1024); l_done BOOLEAN; BEGIN deb('prep_piece_read: bpkey ' || p_inbpkey || ', ' || systimestamp, AM_DEBUG_MED); -- -- IF NOT dbms_ra_int.read_lock(dbms_ra_int.KEY_BP, p_inbpkey) THEN -- -- -- RAISE dbms_ra_scheduler.e_retry_error; END IF; -- SELECT bp.db_key, bp.vb_key, bp.bs_key, bp.handle INTO p_dbkey, p_vbkey, l_bskey, l_handle FROM bp, bs WHERE bp.bs_key = bs.bs_key AND bp.status != 'D' AND bp.ba_access != 'U' AND bp_key = p_inbpkey; -- FOR f IN fnos(l_bskey, p_vbkey) LOOP IF NOT dbms_ra_int.read_lock(dbms_ra_int.KEY_DF, f.df_key) THEN RAISE dbms_ra_scheduler.e_retry_error; -- Not possible, so give up. END IF; l_dfkey := f.df_key; -- Any dfkey will do. l_vcbpkey := f.vcbp_key; -- Should all be the same. l_numdf := l_numdf + 1; -- Counting the datafiles. END LOOP; -- IF p_inbpkey = l_vcbpkey THEN l_type := KBRSPLBLD_ORIGPIECE; p_original := 1; IF l_numdf > 1 THEN -- We only provide a dfkey if there is one. p_dfkey := 0; ELSE p_dfkey := l_dfkey; END IF; ELSE l_type := KBRSPLBLD_PIECE; p_original := 0; p_dfkey := l_dfkey; END IF; -- FOR f IN fPlans(l_bskey, p_vbkey, l_type) LOOP l_done := FALSE; WHILE NOT l_done LOOP BEGIN planDF(l_type, f.df_key, p_vbkey, 0, TRUE, TRUE); l_done := TRUE; EXCEPTION WHEN dbms_ra_scheduler.e_snapshot_too_old THEN save_error; -- -- dbms_lock.sleep(5); clear_error; WHEN dbms_ra_scheduler.e_no_longer_exists THEN -- -- -- save_error; clear_error; END; END LOOP; -- BEGIN SELECT 1 INTO l_count FROM plans WHERE type = l_type AND vb_key = p_vbkey AND df_key = f.df_key AND blksread IS NOT NULL; EXCEPTION WHEN no_data_found THEN save_error; SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Plan broken for bpkey ' || p_inbpkey || ', dfkey ' || f.df_key || ', vbkey ' || p_vbkey); END; END LOOP; -- SELECT db_id INTO p_db_id FROM db WHERE db_key = p_dbkey; -- SELECT sl_cg_name INTO p_loc FROM vbdf v, odb o, sl s WHERE v.vb_key = p_vbkey AND v.relfno = 1 AND o.db_key = v.db_key AND s.sl_key = o.sl_key; -- prep_read(l_type, l_bskey, p_vbkey, l_dfkey, p_blksize, p_read_bufs, p_read_size, p_read_waste); END prep_piece_read; -- -- -- -- -- -- -- PROCEDURE prep_read(p_type IN NUMBER, /* KBRSPLBLD_% */ p_bskey IN NUMBER, /* optional */ p_vbkey IN NUMBER, p_dfkey IN NUMBER, p_blksize OUT NUMBER, p_read_bufs OUT NUMBER, p_read_size OUT NUMBER, p_read_waste OUT NUMBER) IS l_all NUMBER; BEGIN deb('prep_read: type ' || p_type || ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey, AM_DEBUG_MED); -- SELECT /*+ RESULT_CACHE */ NVL(MAX(DECODE(name, '_read_bufs', value)), DEF_READ_BUFS), NVL(MAX(DECODE(name, '_read_size', value)), DEF_READ_SIZE), NVL(MAX(DECODE(name, '_read_waste', value)), 0) INTO p_read_bufs, p_read_size, p_read_waste FROM config WHERE name IN ('_read_bufs', '_read_size', '_read_waste' ); -- SELECT max(block_size) INTO p_blksize FROM df WHERE df_key = p_dfkey; -- IF p_read_bufs IS NULL OR p_type IN (KBRSPLBLD_PURGE, KBRSPLBLD_OPTPURGE, KBRSPLBLD_SMALLPURGE, KBRSPLBLD_DUPPURGE) THEN -- IF p_bskey IS NOT NULL THEN -- -- SELECT GREATEST(LEAST(MAX(numchunks) + 1, NVL(p_read_bufs, DEF_READ_BUFS)), MIN_READ_BUFS) INTO p_read_bufs FROM vbdf v, bdf d, plans p WHERE v.dbinc_key = d.dbinc_key AND v.ckp_scn = d.ckp_scn AND v.file# = d.file# AND p.type = p_type AND v.vb_key = p.vb_key AND v.df_key = p.df_key AND d.bs_key = p_bskey; ELSE -- SELECT GREATEST(LEAST(MAX(numchunks) + 1, NVL(p_read_bufs, DEF_READ_BUFS)), MIN_READ_BUFS) INTO p_read_bufs FROM plans WHERE type = p_type AND vb_key = p_vbkey AND df_key = p_dfkey; END IF; END IF; -- IF p_read_bufs IS NULL THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Maxfiles bad for bskey ' || p_bskey || ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey); END IF; END prep_read; -- -- -- -- -- -- -- PROCEDURE dealloc_plan_bp(p_bskey NUMBER) IS l_count NUMBER; l_rnk NUMBER; l_dflst NOLST; l_vblst NOLST; l_lvlst NOLST; l_type NUMBER; BEGIN deb('dealloc_plan_bp bskey ' || p_bskey, AM_DEBUG_MED); -- SELECT COUNT(*) INTO l_count FROM sbt_task WHERE bs_key = p_bskey AND task_id <> dbms_ra_scheduler.s_current_task AND ROWNUM = 1; IF l_count > 0 THEN deb('dealloc_plan_bp in use, bskey ' || p_bskey, AM_DEBUG_MED); RETURN; END IF; -- -- -- SELECT df_key, vb_key, incrLevel(create_scn, incr_scn) lvl BULK COLLECT INTO l_dflst, l_vblst, l_lvlst FROM bp JOIN bdf USING (bs_key) JOIN df USING (dbinc_key, create_scn, file#) WHERE bs_key = p_bskey AND vb_key IS NOT NULL; -- IF l_dflst.COUNT = 0 THEN deb('dealloc_plan_bp not a vb, bskey ' || p_bskey, AM_DEBUG_MED); RETURN; END IF; -- IF l_dflst.COUNT > 1 OR l_lvlst(1) > 0 THEN l_type := KBRSPLBLD_ORIGPIECE; ELSE l_type := KBRSPLBLD_PIECE; -- SELECT rnk INTO l_rnk FROM (SELECT vb_key, DENSE_RANK() OVER (ORDER BY vb_key DESC) rnk FROM vbdf WHERE df_key = l_dflst(1)) WHERE vb_key = l_vblst(1); IF l_rnk <= dbms_ra_scheduler.s_plans_maintained THEN RETURN; END IF; END IF; -- FOR i IN 1 .. l_dflst.COUNT LOOP dealloc_plan(l_dflst(i), l_vblst(i), l_type); END LOOP; END dealloc_plan_bp; -- -- -- -- -- -- -- -- -- -- PROCEDURE obsoletePlans(p_dfkey IN NUMBER, p_chk_krbph IN NUMBER DEFAULT 1, p_lock IN NUMBER DEFAULT 1) IS l_vbkey NUMBER; l_count NUMBER; l_vblst NOLST; l_typlst NOLST; BEGIN -- -- -- -- -- -- IF (p_lock = TRUE#) THEN dbms_ra_int.write_lock(dbms_ra_int.KEY_DF, p_dfkey); END IF; deb('obsoletePlans: for dfkey ' || p_dfkey); dbms_ra_int.info_start('obsoletePlans', 'dfkey ' || p_dfkey); -- -- SELECT vb_key, type BULK COLLECT INTO l_vblst, l_typlst FROM plans WHERE df_key = p_dfkey AND type != KBRSPLBLD_PURGE; FOR i IN 1 .. l_vblst.COUNT LOOP dealloc_plan(p_dfkey, l_vblst(i), l_typlst(i), FALSE); END LOOP; deb('obsoletePlans: for dfkey ' || p_dfkey || ' at - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_MED); -- IF (p_lock = TRUE#) THEN dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey); END IF; -- IF p_chk_krbph = TRUE# THEN FOR p IN (SELECT df_key, new_krbph FROM vbdf WHERE krbph_dfkey = p_dfkey AND new_krbph IS NOT NULL) LOOP -- IF (p_lock = TRUE#) THEN dbms_ra_int.write_lock(dbms_ra_int.KEY_DF, p.df_key); END IF; -- UPDATE vbdf SET krbph_chunkno = p.new_krbph, new_krbph = NULL WHERE df_key = p.df_key AND krbph_dfkey = p_dfkey AND new_krbph = p.new_krbph RETURNING vb_key INTO l_vbkey; -- -- IF l_vbkey IS NOT NULL THEN dealloc_plan(p.df_key, l_vbkey, KBRSPLBLD_ORIGPIECE, FALSE); dealloc_plan(p.df_key, l_vbkey, KBRSPLBLD_PIECE, FALSE); deb('obsoletePlans: dfkey ' || p.df_key || ', vbkey ' || l_vbkey, AM_DEBUG_MED); END IF; -- IF (p_lock = TRUE#) THEN dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p.df_key); END IF; END LOOP; IF s_safemode THEN SELECT COUNT(*) INTO l_count FROM vbdf WHERE vb_key = l_vbkey AND new_krbph IS NOT NULL; IF l_count > 0 THEN deb('obsoletePlans: not all krbph_chunkno were fixed up for vbkey ' || l_vbkey); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'missed krbph_chunkno'); END IF; END IF; END IF; dbms_ra_int.info_end; END obsoletePlans; -- -- -- -- -- -- -- PROCEDURE build_read_plan(p_dbkey IN NUMBER, -- Database key p_vbkey IN NUMBER, -- Virtual backup key p_dfkey IN NUMBER, -- Datafile key p_bufsize IN NUMBER, -- size of read buffers p_type IN NUMBER, -- KBRSPLBLD_ type p_chunks IN NUMBER, -- Number of chunks to write. p_stored OUT NUMBER) -- Is 1 if plan was stored IS l_blksize NUMBER; l_vfound NUMBER; -- Virtual backup found l_qtype NUMBER; -- query type to execute l_dfbytes NUMBER; -- size of db in bytes l_dfblocks NUMBER; -- number of blocks in DF l_chunks NUMBER; -- number of distinct chunks in plan l_signature NUMBER; -- numeric signature for this restore l_maxrank NUMBER; -- block ranking used in purges l_needs NUMBER; -- chunks that are needed l_frees NUMBER; -- chunks that will be freed in a purge l_fno NUMBER; -- file# for error reporting l_dbname node.db_unique_name%TYPE; -- db_unique_name for error reporting BEGIN -- IF p_type = KBRSPLBLD_PURGE OR p_type = KBRSPLBLD_OPTPURGE OR p_type = KBRSPLBLD_SMALLPURGE OR p_type = KBRSPLBLD_ALLPURGE OR p_type = KBRSPLBLD_DUPPURGE THEN l_qtype := KBRSPLBLD_PURGE; ELSE l_qtype := p_type; END IF; -- -- p_stored := NULL; BEGIN alloc_plan(p_dbkey, p_dfkey, p_vbkey, l_qtype); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN save_error; deb('build_read_plan plan already exists', AM_DEBUG_LOW); clear_error; RETURN; -- Caller checks to see it was built END; -- p_stored := 1; -- -- SELECT max(block_size) INTO l_blksize FROM df WHERE df_key = p_dfkey; -- plan_blocks(p_vbkey, p_dfkey, f_chunksize(p_dbkey), p_bufsize, l_blksize, p_type, l_dfbytes, l_dfblocks, l_chunks, l_signature, l_maxrank); deb('build_read_plan built blocks: ' || ' dfkey ' || p_dfkey || ', vbkey ' || p_vbkey|| ', dfbytes ' || l_dfbytes || ', dfblocks ' || l_dfblocks || ', signature ' || l_signature, AM_DEBUG_MED); -- IF p_type = KBRSPLBLD_SMALLPURGE THEN restricted_purge(p_dfkey, l_qtype, p_vbkey, p_dbkey, p_chunks); END IF; -- IF p_type = KBRSPLBLD_OPTIMIZE THEN optimize_blocks(p_dfkey, p_vbkey, l_qtype, p_stored, l_needs); l_frees := 0; END IF; -- IF p_type = KBRSPLBLD_PIECE THEN SELECT COUNT(*) INTO l_vfound FROM vbdf WHERE df_key = p_dfkey AND vb_key = p_vbkey AND dfblocks = l_dfblocks AND signature = l_signature; -- IF l_vfound = 0 THEN SELECT nvl(dfbytes, 0) INTO l_vfound FROM vbdf WHERE df_key = p_dfkey AND vb_key = p_vbkey; -- IF l_vfound = 0 THEN UPDATE vbdf SET dfbytes = l_dfbytes, dfblocks = l_dfblocks, signature = l_signature WHERE df_key = p_dfkey AND vb_key = p_vbkey; ELSE -- -- -- SELECT count(*) INTO l_vfound FROM bp WHERE vb_key = p_vbkey AND status != 'D'; IF l_vfound = 0 THEN RAISE dbms_ra_scheduler.e_retry_error; END IF; -- -- -- deb('BUILD_READ_PLAN NEW BAD METADATA:' || ' dfkey ' || p_dfkey || ', vbkey ' || p_vbkey|| ', dfbytes ' || l_dfbytes || ', dfblocks ' || l_dfblocks || ', signature ' || l_signature, AM_DEBUG_ON); FOR i IN (SELECT * FROM vbdf WHERE df_key = p_dfkey AND vb_key = p_vbkey) LOOP deb('BUILD_READ_PLAN OLD GOOD METADATA:' || ' dfkey ' || p_dfkey || ', vbkey ' || p_vbkey|| ', dfbytes ' || i.dfbytes || ', dfblocks ' || i.dfblocks || ', signature ' || i.signature, AM_DEBUG_ON); deb('BUILD_READ_PLAN with:' || ' incr_scn ' || i.incr_scn || ', ckp_scn ' || i.ckp_scn || ', min_id ' || i.min_id, AM_DEBUG_ON); END LOOP; raise_bad_metadata(p_dfkey); END IF; END IF; END IF; -- IF l_qtype = KBRSPLBLD_PURGE THEN IF l_dfbytes = 0 THEN l_needs := 0; ELSE /* Add an extra block, to ensure we do not go over */ l_needs := trunc((l_dfbytes + l_blksize) / f_chunksize(p_dbkey)) + 1; END IF; -- SELECT COUNT(DISTINCT chunkno) INTO l_frees FROM plans_details WHERE df_key = p_dfkey AND vb_key = p_vbkey AND type = l_qtype; deb('build_read_plan purge type: ' || p_type || ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey|| ', needs ' || l_needs || ', frees ' || l_frees, AM_DEBUG_MED); -- IF (l_frees = 0 OR (p_type = KBRSPLBLD_OPTPURGE AND l_frees - l_needs < dbms_ra_scheduler.s_purge_opt_free) OR (p_type = KBRSPLBLD_PURGE AND l_frees = l_needs)) AND (s_purge_dbinc IS NULL) /* we always want to free orphans */ THEN l_needs := 0; l_frees := 0; p_stored := 0; deb('build_read_plan nothing freed', AM_DEBUG_MED); ELSE -- IF debug = AM_DEBUG_HIGH THEN deb('build_read_plan: chunks to delete'); FOR x IN (SELECT chunkno, MIN(blockno) blockno FROM plans_details WHERE df_key = p_dfkey AND type = p_type AND vb_key = p_vbkey AND blockno >= 0 GROUP BY chunkno ORDER BY chunkno) LOOP deb('delete plan dfkey ' || p_dfkey || ', chunk ' || x.chunkno || ', minbno ' || x.blockno); END LOOP; END IF; END IF; END IF; -- IF p_stored = 0 THEN l_dfblocks := NULL; END IF; UPDATE plans SET blksread = l_dfblocks, numchunks = l_chunks, maxrank = l_maxrank, needchunk = l_needs, freechunk = l_frees WHERE df_key = p_dfkey AND vb_key = p_vbkey AND type = l_qtype; COMMIT; dbms_ra_scheduler.check_for_interrupt; EXCEPTION WHEN dbms_ra_scheduler.e_no_longer_exists THEN save_error; -- IF dbms_ra_scheduler.s_current_task_type = dbms_ra_scheduler.TASK_RESTORE THEN RAISE; ELSE RAISE dbms_ra_scheduler.e_retry_error; -- Convert to retry error END IF; END build_read_plan; -- -- -- -- -- -- -- -- -- PROCEDURE ok4pool(p_dbkey IN NUMBER, p_bpkey IN NUMBER, p_update IN BOOLEAN, p_hasdups OUT BOOLEAN, p_nofityet OUT BOOLEAN, p_isok OUT BOOLEAN) IS l_bskey NUMBER; l_currinc NUMBER; l_isnew NUMBER; l_isold NUMBER; l_anynew NUMBER; l_dups NUMBER; l_keep NUMBER; l_isincr NUMBER; l_hasdups NUMBER; l_count NUMBER; l_piececnt NUMBER; l_encrypt NUMBER; l_msection NUMBER; l_pieces NUMBER; l_bdfkey NUMBER; l_incrscn NUMBER := BIGNUM; l_pieceno NUMBER := 1; l_pause NUMBER; BEGIN -- p_hasdups := FALSE; p_nofityet := FALSE; p_isok := FALSE; -- IF f_pooloff THEN RETURN; END IF; -- SELECT DECODE(encrypted, 'Y', 1, 0), bs_key INTO l_encrypt, l_bskey FROM bp WHERE bp_key = p_bpkey; IF l_encrypt > 0 THEN deb('OK4POOL: bpkey ' || p_bpkey || ', rejected encrypted backup.', AM_DEBUG_LOW); RETURN; END IF; -- -- -- -- -- -- BEGIN SELECT keep_options, DECODE(multi_section, 'Y', 1, 0), pieces INTO l_keep, l_msection, l_pieces FROM bs WHERE bs_key = l_bskey; SELECT COUNT(*) INTO l_count FROM bdf WHERE bs_key = l_bskey AND (incr_level IS NOT NULL OR incr_scn > 0); IF l_count > 0 THEN l_isincr := 1; ELSE l_isincr := 0; END IF; EXCEPTION WHEN no_data_found THEN save_error; l_isincr := 0; deb('OK4POOL: bpkey ' || p_bpkey || ', missing.', AM_DEBUG_LOW); clear_error; WHEN OTHERS THEN save_error; RAISE; END; deb('OK4POOL: bpkey ' || p_bpkey || ', incr ' || l_isincr || ', keep ' || l_keep || ', pieces ' || l_pieces || ', msection ' || l_msection, AM_DEBUG_LOW); -- -- IF l_isincr = 0 OR l_keep > 0 OR (l_msection = 0 AND l_pieces > 1) THEN RETURN; END IF; -- -- SELECT COUNT(*) INTO l_count FROM bdf b WHERE bs_key = l_bskey AND NOT EXISTS (SELECT 1 FROM df WHERE df.dbinc_key = b.dbinc_key AND df.file# = b.file#); IF (l_count > 0) THEN -- -- SELECT COUNT(*) INTO l_count FROM bdf b, dbinc i WHERE b.bs_key = l_bskey AND b.dbinc_key = i.dbinc_key AND i.dbinc_status = 'ORPHAN' AND i.parent_dbinc_key IS NULL AND NOT EXISTS (SELECT 1 FROM dbinc i2 WHERE i2.parent_dbinc_key = i.dbinc_key); IF (l_count > 0) THEN deb('OK4POOL: bpkey ' || p_bpkey || ', foreign datafile', AM_DEBUG_MED); RETURN; END IF; -- -- SELECT COUNT(*) INTO l_count FROM df WHERE dbinc_key IN (SELECT dbinc_key FROM bdf WHERE bs_key = l_bskey); IF (l_count > 0) THEN -- deb('OK4POOL: bpkey ' || p_bpkey || ', no datafile yet, ' || 'temporarily rejected', AM_DEBUG_LOW); p_nofityet := TRUE; ELSE deb('OK4POOL: bpkey ' || p_bpkey || ', no datafile is too old, ' || 'permantly rejected', AM_DEBUG_LOW); END IF; RETURN; END IF; -- SELECT COUNT(*) INTO l_count FROM bdf b WHERE bs_key = l_bskey AND EXISTS (SELECT 1 FROM vbdf v WHERE v.dbinc_key = b.dbinc_key AND v.file# = b.file# AND v.state NOT IN (VBDF_OBSOLETE, VBDF_COMPLETE, VBDF_REPOPULATE)); IF (l_count > 0) THEN deb('OK4POOL: bpkey ' || p_bpkey || ', incomplete prior backup, ' || 'temporarily rejected', AM_DEBUG_LOW); p_nofityet := TRUE; RETURN; END IF; -- SELECT MAX(dbinc_key) INTO l_currinc FROM bdf WHERE bs_key = l_bskey; IF l_msection = 1 THEN SELECT piece# INTO l_pieceno FROM bp WHERE bp_key = p_bpkey; -- -- -- -- -- -- IF l_pieceno > 1 THEN SELECT COUNT(DISTINCT piece#) INTO l_count FROM bdf JOIN bp USING (bs_key) WHERE (dbinc_key, file#, create_scn, ckp_scn) IN (SELECT dbinc_key, file#, create_scn, ckp_scn FROM bdf WHERE bs_key = l_bskey) AND vb_key IS NOT NULL AND ba_access = 'L' AND (piece# = l_pieceno OR piece# = l_pieceno - 1); -- -- -- -- -- -- deb('OK4POOL: bpkey ' || p_bpkey || ', l_count, ' || l_count , AM_DEBUG_LOW); IF l_count = 0 THEN deb('OK4POOL: bpkey ' || p_bpkey || ', wrong section, ' || 'temporarily rejected', AM_DEBUG_LOW); p_nofityet := TRUE; RETURN; ELSIF l_count = 2 THEN deb('OK4POOL: bpkey ' || p_bpkey || ', wrong section, ' || 'permanently rejected', AM_DEBUG_LOW); RETURN; END IF; ELSE -- Check prior backup, assumes single datafile. BEGIN SELECT piece#, pieces INTO l_pieceno, l_piececnt FROM (SELECT ckp_scn, piece#, pieces FROM bdf JOIN bp USING (bs_key) JOIN bs USING (bs_key) JOIN (SELECT db_key, dbinc_key, reset_scn, reset_time, db_name, NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = l_currinc CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i USING (dbinc_key) WHERE bp.ba_access = 'L' AND bp.vb_key IS NOT NULL AND bdf.ckp_scn >= i.reset_scn AND bdf.ckp_scn < i.next_reset_scn ORDER BY ckp_scn DESC, piece# DESC) f WHERE ROWNUM = 1; EXCEPTION WHEN no_data_found THEN save_error; l_pieceno := 1; l_piececnt := 1; clear_error; END; IF l_pieceno != l_piececnt THEN deb('OK4POOL: bpkey ' || p_bpkey || ', missing section, ' || 'temporarily rejected', AM_DEBUG_LOW); p_nofityet := TRUE; RETURN; END IF; l_pieceno := 1; END IF; -- l_pieceno == 1 END IF; -- l_msection == 1 deb('OK4POOL: bpkey ' || p_bpkey || ', l_pieceno, ' || l_pieceno, AM_DEBUG_LOW); IF l_pieceno = 1 THEN -- -- -- -- SELECT /* looking for too new */ /* isnew: 0 - exact fit, < 0 fits with dups, > 0 - too new, */ MAX(incr_scn - nvl(pckpscn, /* If no prior backup the following computes: */ /* incr_scn for level 0 */ /* -ckp_scn for level 1 */ incr_scn + (-1 * (incr_scn + ckp_scn) * dbms_ra_pool.incrLevel(create_scn, incr_scn)))) isnew, /* looking for too old */ /* isold: 0 - old, < 0 - ok new, > 0 too old */ NVL(MAX(pckpscn - ckp_scn), -1) isold, /* looking for any new */ /* anynew: > 0 some new, no new when <= 0 and isold == 0 */ NVL(MAX(ckp_scn - pckpscn), 1) anynew, /* looking for duplicate blocks */ /* dups: > 0 dups, <= 0 no dups */ MAX(NVL(pckpscn, incr_scn) - incr_scn) dups INTO l_isnew, l_isold, l_anynew, l_dups FROM bdf b LEFT OUTER JOIN (SELECT file#, MAX(ckp_scn) pckpscn, MAX(create_scn) create_scn FROM bdf JOIN bp USING (bs_key) JOIN (SELECT db_key, dbinc_key, reset_scn, reset_time, db_name, NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = l_currinc CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i USING (dbinc_key) WHERE bp.ba_access = 'L' AND bp.vb_key IS NOT NULL AND bp.status != 'D' AND bdf.ckp_scn >= i.reset_scn AND bdf.ckp_scn < i.next_reset_scn GROUP BY file#) f USING (file#, create_scn) WHERE b.bs_key = l_bskey; deb('OK4POOL: bpkey ' || p_bpkey || ', isnew ' || sign(l_isnew) || ', isold ' || sign(l_isold) || ', anynew ' || sign(l_anynew) || ', dups ' || sign(l_dups), AM_DEBUG_MED); -- IF l_isnew > 0 THEN deb('OK4POOL: bpkey ' || p_bpkey || ', future backup, ' || 'temporarily rejected', AM_DEBUG_LOW); -- -- -- BEGIN SELECT MAX(incr_scn - mckpscn) /* A positve value means NOT tile */ INTO l_isnew FROM bdf b JOIN (SELECT MAX(ckp_scn) mckpscn, file# FROM df JOIN (SELECT dbinc_key, file#, create_scn, ckp_scn FROM cdf UNION ALL SELECT dbinc_key, file#, create_scn, ckp_scn FROM xdf) f USING (dbinc_key, file#, create_scn) JOIN (SELECT db_key, dbinc_key, reset_scn, reset_time, db_name, NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = l_currinc CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i USING (dbinc_key) WHERE f.ckp_scn >= i.reset_scn AND f.ckp_scn < i.next_reset_scn GROUP BY file#) d USING (file#) WHERE b.bs_key = l_bskey; EXCEPTION WHEN OTHERS THEN save_error; deb('OK4POOL: bpkey ' || p_bpkey || ', datafile copy query failed with ' || SQLERRM, AM_DEBUG_ON); RAISE; END; IF l_isnew > 0 OR l_isnew IS NULL THEN p_nofityet := TRUE; END IF; RETURN; END IF; -- IF NOT p_update AND (l_isold > 0 OR (l_isold = 0 AND l_anynew <= 0)) THEN deb('OK4POOL: bpkey ' || p_bpkey || ', will not fit in dbkey ' || p_dbkey || ' and is rejected', AM_DEBUG_MED); RETURN; -- A clean return means file will not be processed again. END IF; END IF; -- for piece 1 -- deb('OK4POOL: bpkey ' || p_bpkey || ', is good for pool.', AM_DEBUG_MED); p_hasdups := (l_dups > 0); p_isok := TRUE; END ok4pool; -- -- -- -- -- -- -- -- -- -- -- PROCEDURE process_backup_piece(p_dbkey IN NUMBER, -- Database key p_bpkey IN NUMBER, -- BackupPiece key p_upd IN NUMBER DEFAULT 0, -- update oper p_complete OUT BOOLEAN) IS l_slkey NUMBER; l_toname VARCHAR2(512); l_dbid NUMBER; l_chunkno NUMBER; l_tag VARCHAR2(31); l_count NUMBER; l_bskey NUMBER; l_vbkey NUMBER := NULL; l_outbpkey NUMBER; l_loop NUMBER; l_hasdups BOOLEAN; l_nofit BOOLEAN; l_isok BOOLEAN; -- -- -- -- -- CURSOR vfiles(c_vbkey IN NUMBER) IS SELECT v.vb_key, v.dbinc_key, v.df_key, v.file#, v.blocks, v.incr_scn, v.dfbytes, f.create_scn FROM vbdf v, df f WHERE v.vb_key = c_vbkey AND v.df_key = f.df_key AND v.dbinc_key = f.dbinc_key; BEGIN saved_krbph := NULL; saved_krbphdf := NULL; saved_krbph_name := NULL; saved_krbph_spname := NULL; saved_krbph_cfname := NULL; p_complete := FALSE; -- dbms_ra_int.s_bp_save.DELETE; deb('Process_backup_piece - dbkey ' || p_dbkey || ', bpkey - ' || p_bpkey, AM_DEBUG_LOW); -- IF NOT dbms_ra_int.read_lock(dbms_ra_int.KEY_BP, p_bpkey) THEN -- -- deb('Process_backup_piece - bpkey ' || p_bpkey || ' no longer exists.', AM_DEBUG_LOW); -- l_vbkey := dbms_ra_scheduler.get_savepoint; IF l_vbkey > 0 THEN cleanup(l_vbkey); END IF; RETURN; END IF; -- SELECT bp.bs_key INTO l_bskey FROM bp, bs WHERE bp.bs_key = bs.bs_key AND bp.bp_key = p_bpkey AND bp.status != 'D' AND bp.ba_access != 'U'; -- -- -- dbms_ra_scheduler.avoid_bs(p_dbkey, l_bskey, p_bpkey); -- IF p_upd = 0 THEN saved_vbkey := 0; ELSE -- SELECT MIN(vb_key) INTO saved_vbkey FROM vbdf v, bdf d WHERE v.dbinc_key = d.dbinc_key AND v.file# = d.file# AND v.ckp_scn = d.ckp_scn AND d.bs_key = l_bskey; -- -- -- UPDATE vbdf v SET state = VBDF_REPOPULATE WHERE vb_key = saved_vbkey AND EXISTS (SELECT 1 FROM bdf d WHERE d.bs_key = l_bskey AND d.dbinc_key = v.dbinc_key AND d.file# = v.file# AND d.ckp_scn = v.ckp_scn); COMMIT; END IF; deb('Process_backup_piece - dbkey ' || p_dbkey || ' saved_vbkey - ' || saved_vbkey, AM_DEBUG_MED); -- SELECT sl_cg_name, sl_key INTO l_toname, l_slkey FROM sl join odb using(sl_key) WHERE db_key = p_dbkey; deb('Process_backup_piece - dbkey## After storage location ' || p_dbkey || ' saved_vbkey - ' || saved_vbkey, AM_DEBUG_MED); -- IF p_upd = 0 THEN -- -- -- -- SELECT MIN(vb_key) INTO l_vbkey FROM vbdf v, bdf d WHERE v.dbinc_key = d.dbinc_key AND v.file# = d.file# AND d.bs_key = l_bskey AND state NOT IN (VBDF_COMPLETE, VBDF_OBSOLETE) AND DECODE(d.section_size, 0, 1, (v.lastblk/d.section_size)) = (SELECT piece# FROM bp WHERE bp_key = p_bpkey); -- IF l_vbkey IS NOT NULL THEN cleanup(l_vbkey); END IF; -- SELECT MAX(vb_key) INTO l_vbkey FROM vbdf WHERE srcbp_key = p_bpkey AND state IN (VBDF_COMPLETE, VBDF_OBSOLETE); IF l_vbkey IS NOT NULL THEN -- saved_vbkey := l_vbkey; SELECT filename, chunkno, c.df_key INTO saved_krbph_name, saved_krbph, saved_krbphdf FROM vbdf v, chunks c WHERE v.vb_key = l_vbkey AND v.df_key = v.krbph_dfkey AND v.df_key = c.df_key AND v.krbph_chunkno = c.chunkno; deb('Process_backup_piece - piece already processed', AM_DEBUG_LOW); GOTO inspect_vb; END IF; -- ELSE deb('Process_backup_piece - repopulate: ' || l_bskey, AM_DEBUG_LOW); SELECT v.vb_key, c.filename, c.chunkno, c.df_key INTO saved_vbkey, saved_krbph_name, saved_krbph, saved_krbphdf FROM bdf b, vbdf v, chunks c WHERE b.bs_key = l_bskey AND b.dbinc_key = v.dbinc_key AND b.file# = v.file# AND b.ckp_scn = v.ckp_scn AND v.krbph_dfkey = v.df_key /* Ensure only one record returns */ AND v.krbph_dfkey = c.df_key AND v.krbph_chunkno = c.chunkno; END IF; deb('Process_backup_piece - dbkey## After Cleanup Prior ' || p_dbkey || ' saved_vbkey - ' || saved_vbkey, AM_DEBUG_MED); IF debug >= AM_DEBUG_MED THEN SELECT tag INTO l_tag FROM bp WHERE bp_key = p_bpkey; deb('PROCESS_BACKUP_PIECE: checking ' || l_tag, AM_DEBUG_MED); END IF; -- -- -- dbms_ra_scheduler.avoid_sl(DBMS_RA_SCHEDULER.TASK_PURGE, l_slkey); -- ok4pool(p_dbkey, p_bpkey, (p_upd != 0), l_hasdups, l_nofit, l_isok); IF NOT l_isok THEN -- IF l_nofit THEN RAISE dbms_ra_int.incremental_no_fit; END IF; dbms_ra_int.unlock(dbms_ra_int.KEY_BP, p_bpkey); RETURN; -- A clean return means file will not be processed again. END IF; -- -- IF l_hasdups THEN deb('Process_backup_piece duplicate blocks for bpkey ' || p_bpkey, AM_DEBUG_MED); dbms_ra_scheduler.avoid_sl(DBMS_RA_SCHEDULER.TASK_INDEX_BACKUP, l_slkey); END IF; -- -- -- SELECT COUNT(*) INTO l_count FROM vbdf v, bdf d WHERE v.dbinc_key = d.dbinc_key AND v.file# = d.file# AND v.ckp_scn = d.ckp_scn AND d.bs_key = l_bskey AND v.state NOT IN (VBDF_COMPLETE, VBDF_OBSOLETE, VBDF_REPOPULATE); IF l_count > 0 THEN deb('PROCESS_BACKUP_PIECE: other vbdf in progress'); RAISE dbms_ra_int.incremental_no_fit; END IF; -- dbms_ra_int.info_start('process_allfiles', 'bpkey ' || p_bpkey); process_allfiles (p_dbkey => p_dbkey, p_bskey => l_bskey, p_bpkey => p_bpkey, p_toname => l_toname, p_hasdups => l_hasdups, p_update => (p_upd != 0)); dbms_ra_int.info_end; -- <> -- -- FOR fil IN vfiles(saved_vbkey) LOOP -- -- SELECT COUNT(*) INTO l_count FROM bp WHERE vb_key = fil.vb_key /* one 1 datafile */ AND 1 = (SELECT COUNT(*) FROM bdf WHERE bdf.bs_key = bp.bs_key) AND EXISTS (SELECT 1 FROM bdf d /* a level 0 backup */ WHERE d.bs_key = bp.bs_key AND d.file# = fil.file# AND d.dbinc_key = fil.dbinc_key AND 0 = incrLevel(d.create_scn, d.incr_scn)); -- IF l_count = 0 THEN -- IF 1 = incrLevel(fil.create_scn, fil.incr_scn) THEN dbms_ra_int.saveBPdata(fno => fil.file#, blocks_read => fil.blocks); END IF; -- sys.kbrsi_icd.rsInspectBackupPiece( handle => saved_krbph_name, vbkey => saved_vbkey, bpsize => fil.dfbytes, chktype => DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL, fno => fil.file#, lib_key => null, /* local disk file */ ct_key => null, bpkey => l_outbpkey, template_key => null); deb('Process_backup_piece: Created bpkey ' || l_outbpkey || ', vbkey ' || saved_vbkey, AM_DEBUG_LOW); END IF; END LOOP; -- dbms_ra_int.s_bp_save.DELETE; -- SELECT COUNT(*) INTO l_count FROM vbdf WHERE vb_key = saved_vbkey AND state <> VBDF_COMPLETE; IF l_count > 0 THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'bad_vbdf_state'); END IF; -- p_complete := TRUE; deb('Process_backup_piece: completed bpkey ' || p_bpkey || ' vbkey ' || saved_vbkey|| ' tag ' || l_tag, AM_DEBUG_MED); -- dbms_ra_int.unlock(dbms_ra_int.KEY_BP, p_bpkey); -- FOR x IN (SELECT df_key FROM vbdf WHERE vb_key = saved_vbkey) LOOP trim_plan(x.df_key); END LOOP; EXCEPTION WHEN OTHERS THEN save_error; -- ROLLBACK; deb('Process_backup_piece: failed bpkey ' || p_bpkey || ', vbkey ' || saved_vbkey|| ', SQLCODE ' || SQLCODE || ', tag ' || l_tag, AM_DEBUG_ON); -- dbms_ra_int.s_bp_save.DELETE; -- IF p_upd > 0 AND saved_vbkey IS NOT NULL THEN UPDATE vbdf SET state = VBDF_COMPLETE WHERE vb_key = saved_vbkey; COMMIT; END IF; IF p_bpkey IS NOT NULL THEN dbms_ra_int.unlock(dbms_ra_int.KEY_BP, p_bpkey); END IF; -- -- IF SQLCODE = dbms_ra_scheduler.e_corrupt_num THEN deb('Process_backup_piece: VSOR Corrupt piece #####' || saved_krbph_name, AM_DEBUG_ON); dbms_ra_scheduler.log_error ( p_errno => dbms_ra_scheduler.e_corrupt_block_num, p_component => 'BACKUP', p_severity => dbms_ra_scheduler.severity_warning, p_db_key => p_dbkey, p_param_num => p_bpkey); -- clear_error; ELSE RAISE; END IF; END process_backup_piece; -- -- -- -- -- -- -- PROCEDURE purgeDB(p_slkey IN NUMBER, p_dbkey IN NUMBER, p_inline IN BOOLEAN DEFAULT FALSE) IS l_currinc NUMBER; l_resume NUMBER; l_tmp NUMBER; BEGIN deb('purgeDB - db_key ' || p_dbkey || ' Start: ' || TO_CHAR(SYSDATE, 'HH24:MI:SS'), AM_DEBUG_MED); -- purgeObsolete(p_slkey, p_dbkey, p_inline); END purgeDB; -- -- -- -- -- -- -- -- -- PROCEDURE validateDB(p_dbkey IN NUMBER) IS l_bpkey NUMBER := 0; l_bskey NUMBER; l_dfkey NUMBER := 0; l_vbkey NUMBER := 0; l_type NUMBER; l_resume NUMBER; l_count NUMBER; l_level0 BOOLEAN; l_isBPfile BOOLEAN:= FALSE; l_slParams VARCHAR2(1024); l_bpexists NUMBER; BEGIN -- -- -- -- -- l_resume := nvl(dbms_ra_scheduler.get_savepoint, 0); deb('validateDB resume is ' || l_resume); IF l_resume <= 0 THEN l_dfkey := abs(l_resume); l_level0 := TRUE; ELSE l_bpkey := nvl(l_resume, 0); SELECT min(vb_key) into l_vbkey FROM bp WHERE bp_key = l_bpkey; IF l_vbkey IS NULL THEN l_isBPfile := TRUE; ELSE l_isBPfile := FALSE; END IF; l_level0 := FALSE; END IF; -- -- -- WHILE l_bpkey IS NOT NULL LOOP -- IF l_level0 THEN -- -- BEGIN SELECT df_key, bp_key, vb_key, bs_key INTO l_dfkey, l_bpkey, l_vbkey, l_bskey FROM (SELECT v.df_key, p.bp_key, v.vb_key, p.bs_key FROM vbdf v, bp p, bdf d WHERE v.vb_key = p.vb_key AND v.df_key > l_dfkey AND v.file# = d.file# AND v.ckp_scn = d.ckp_scn AND p.db_key = p_dbkey AND v.dbinc_key = d.dbinc_key AND d.bs_key = p.bs_key AND v.state = VBDF_COMPLETE AND v.vcbp_key != p.bp_key AND p.status != 'D' ORDER BY df_key, bp_key) WHERE ROWNUM = 1; l_level0 := TRUE; deb('validateDB by df: bpkey ' || l_bpkey || ', dfkey ' || l_dfkey, AM_DEBUG_MED); EXCEPTION WHEN no_data_found THEN save_error; l_level0 := FALSE; clear_error; END; END IF; -- IF NOT l_level0 AND NOT l_isBPfile THEN l_dfkey := NULL; -- BEGIN SELECT vb_key, bp_key, bs_key INTO l_vbkey, l_bpkey, l_bskey FROM (SELECT p.vb_key, p.bp_key, p.bs_key FROM bp p, vbdf v WHERE p.vb_key = v.vb_key AND p.db_key = v.db_key AND p.bp_key = v.vcbp_key AND p.bp_key > l_bpkey AND p.db_key = p_dbkey GROUP BY p.vb_key, p.bp_key, p.bs_key ORDER BY vb_key, bp_key) WHERE ROWNUM = 1; deb('validateDB by vb: bpkey ' || l_bpkey || ', vbkey ' || l_vbkey, AM_DEBUG_MED); EXCEPTION WHEN no_data_found THEN save_error; l_bpkey := 0; l_isBPfile := TRUE; clear_error; END; END IF; -- IF l_isBPfile THEN BEGIN SELECT min(bp_key) INTO l_bpkey FROM bp WHERE bp_key > l_bpkey AND db_key = p_dbkey AND status != 'D' AND vb_key IS NULL AND lib_key IS NULL AND encrypted = 'N' /* cannot validate encrypted backups */ AND ba_access != 'U'; l_bskey := NULL; /* do not need this, better null than wrong */ IF l_bpkey IS NOT NULL THEN SELECT sl_cg_name INTO l_slParams FROM sl, sbt_catalog WHERE sl.sl_key = sbt_catalog.sl_key AND bp_key=l_bpkey; END IF; deb('validateDB by fc: bpkey ' || l_bpkey , AM_DEBUG_MED); EXCEPTION WHEN no_data_found THEN save_error; l_bpkey := NULL; clear_error; WHEN OTHERS THEN save_error; RAISE; END; END IF; -- IF l_bpkey IS NOT NULL THEN deb('validateDB: bpkey ' || l_bpkey, AM_DEBUG_MED); BEGIN IF l_isBPfile THEN -- IF NOT dbms_ra_int.read_lock(dbms_ra_int.KEY_BP, l_bpkey) THEN RAISE dbms_ra_scheduler.e_retry_error; END IF; dbms_ra_int.info_start('validateDB', 'BP dbkey ' || p_dbkey || ', bpkey ' || l_bpkey); dbms_ra_int.validateBackupPiece(p_dbkey => p_dbkey, p_bpkey => l_bpkey); dbms_ra_int.info_end; dbms_ra_int.unlock(dbms_ra_int.KEY_BP, l_bpkey); ELSE -- IF l_level0 THEN l_type := KBRSPLBLD_PIECE; ELSE l_type := KBRSPLBLD_ORIGPIECE; END IF; -- -- dealloc_plan_bp(l_bskey); -- dbms_ra_int.info_start('validateDB', 'VB dbkey ' || p_dbkey || ', bpkey ' || l_bpkey); sys.kbrsi_icd.validateTask(bpkey => l_bpkey); -- dealloc_plan_bp(l_bskey); dbms_ra_int.info_end; END IF; EXCEPTION WHEN OTHERS THEN save_error; ROLLBACK; IF l_isBPfile THEN dbms_ra_int.unlock(dbms_ra_int.KEY_BP, l_bpkey); l_bpexists := 1; ELSE -- SELECT COUNT(*) INTO l_bpexists FROM bp WHERE bp_key = l_bpkey AND ba_access != 'U' AND status = 'A'; END IF; -- IF l_level0 THEN dbms_ra_scheduler.check_for_interrupt(l_dfkey * -1); ELSE dbms_ra_scheduler.check_for_interrupt(l_bpkey); END IF; deb('validateDB failed: bpkey ' || l_bpkey || ', exists ' || l_bpexists || ', err ' || SQLCODE, AM_DEBUG_MED); -- IF l_bpexists = 0 THEN RAISE dbms_ra_scheduler.e_retry_error; END IF; -- IF SQLCODE = dbms_ra_scheduler.e_corrupt_backup_num OR SQLCODE = dbms_ra_scheduler.e_backup_io_error_rman_num OR SQLCODE = dbms_ra_scheduler.e_error_id_file_num OR SQLCODE = dbms_ra_scheduler.e_corrupt_backuppiece_num OR SQLCODE = dbms_ra_int.bad_block_metadata_num THEN -- -- -- dbms_ra_scheduler.log_error ( p_errno => dbms_ra_scheduler.e_bad_validate_num, p_param1 => to_char(l_bpkey), p_component => 'VALIDATE', p_severity => dbms_ra_scheduler.severity_error, p_db_key => p_dbkey); -- clear_error; ELSE RAISE; END IF; END; END IF; -- IF l_level0 THEN dbms_ra_scheduler.check_for_interrupt(l_dfkey * -1); ELSE dbms_ra_scheduler.check_for_interrupt(l_bpkey); END IF; END LOOP; END validateDB; -- -- -- -- -- -- FUNCTION plannedSpace (p_slkey IN NUMBER, -- Storage location p_enable_dup IN NUMBER) -- 0 or 1 = check for dups RETURN NUMBER IS l_planned NUMBER; l_dups NUMBER := 0; BEGIN -- -- -- SELECT NVL(SUM(chunks_used), 0) INTO l_planned FROM vbdf v, (SELECT db_key, param_num1 df_key, MAX(param_num2) vb_key FROM task WHERE sl_key = p_slkey AND task_type IN (dbms_ra_scheduler.TASK_PURGE_DF, dbms_ra_scheduler.TASK_PURGE_DF_NOW) GROUP BY db_key, param_num1) t WHERE v.db_key = t.db_key AND v.df_key = t.df_key AND v.vb_key <= t.vb_key AND v.state = VBDF_COMPLETE; -- -- -- IF p_enable_dup = 1 THEN SELECT NVL(SUM(chunks_used), 0) + l_planned INTO l_planned FROM vbdf v, task t WHERE t.sl_key = p_slkey AND v.db_key = t.db_key AND v.vb_key = t.param_num2 AND v.df_key = t.param_num1 AND t.state IN (dbms_ra_scheduler.STATE_RUNNING, dbms_ra_scheduler.STATE_EXECUTABLE) AND t.task_type = dbms_ra_scheduler.TASK_PURGE_DUP_DF; END IF; deb('plannedSpace - chunks ' || l_planned || ', enabled_dups '|| p_enable_dup, AM_DEBUG_MED); RETURN l_planned; END plannedSpace; -- -- -- -- -- -- -- FUNCTION plannedDBSpace (p_db_key IN NUMBER) RETURN NUMBER IS l_planned NUMBER; BEGIN -- -- -- -- SELECT NVL(SUM(chunks_used), 0) INTO l_planned FROM vbdf v, (SELECT db_key, param_num1 df_key, MAX(param_num2) vb_key FROM task WHERE db_key = p_db_key AND task_type IN (dbms_ra_scheduler.TASK_PURGE_DF, dbms_ra_scheduler.TASK_PURGE_DF_NOW) GROUP BY db_key, param_num1) t WHERE v.db_key = t.db_key AND v.df_key = t.df_key AND v.vb_key <= t.vb_key AND v.state = VBDF_COMPLETE; deb('plannedDBSpace - ' || l_planned || ' chunks', AM_DEBUG_MED); RETURN l_planned; END plannedDBSpace; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION copied_to_tape(p_dbkey IN NUMBER) RETURN NUMBER IS -- CURSOR allDF(c_dbkey IN NUMBER) IS SELECT df.* FROM df, dbinc i WHERE df.dbinc_key = i.dbinc_key AND db_key = c_dbkey ORDER BY df_key; l_tapedvb NUMBER; l_nottapedvb NUMBER; l_sumbp NUMBER; l_sumvb NUMBER; l_sumtmp NUMBER; l_lastdf NUMBER; l_count NUMBER; l_chunksize NUMBER := f_chunksize(p_dbkey); BEGIN deb('Copied_to_tape: dbkey ' || p_dbkey, AM_DEBUG_MED); -- -- -- SELECT NVL(SUM(bytes), 0) INTO l_sumbp FROM bp WHERE lib_key IS NULL AND ba_access != 'U' AND status != 'D' AND db_key = p_dbkey AND vb_key IS NULL AND bs_key IN /* list of backup sets on tape */ (SELECT bs_key FROM bp WHERE lib_key IS NOT NULL AND status != 'D' UNION /* Backup sets at or below the highest df/cf backups */ SELECT bs_key FROM (SELECT d.bs_key, MIN(x.scn - d.ckp_scn) bigger FROM (SELECT bs_key, file#, dbinc_key, ckp_scn FROM bdf UNION SELECT bs_key, 0 file#, dbinc_key, ckp_scn FROM bcf) d, /* Highest backup scns in current inc, but not keep */ (SELECT a.dbinc_key, a.file#, MAX(a.ckp_scn) scn FROM bp p, bs s, (SELECT bs_key, file#, dbinc_key, ckp_scn FROM bdf UNION SELECT bs_key, 0 file#, dbinc_key, ckp_scn FROM bcf) a, (SELECT db_key, dbinc_key, reset_scn, NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = (SELECT curr_dbinc_key FROM db WHERE db_key = p_dbkey) CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i WHERE a.bs_key = s.bs_key AND a.bs_key = p.bs_key AND a.dbinc_key = i.dbinc_key AND p.status != 'D' AND p.lib_key IS NOT NULL AND s.keep_options = 0 GROUP BY a.dbinc_key, a. file#) x WHERE d.file# = x.file# AND d.dbinc_key = x.dbinc_key GROUP BY d.bs_key) WHERE bigger >= 0); -- SELECT COUNT(*) INTO l_count FROM bp WHERE db_key = p_dbkey AND vb_key IS NOT NULL AND lib_key IS NULL AND bs_key IN (SELECT bs_key FROM bp WHERE db_key = p_dbkey AND lib_key IS NOT NULL) AND ROWNUM = 1; IF l_count = 0 THEN deb('Copied_to_tape: dbkey ' || p_dbkey || ', bp taped ' || l_sumbp/1024/1024 || 'm', AM_DEBUG_MED); RETURN l_sumbp; END IF; -- -- -- -- -- -- -- l_sumvb := 0; FOR f IN allDF(p_dbkey) LOOP -- CONTINUE WHEN f.df_key = l_lastdf; l_lastdf := f.df_key; -- -- SELECT NVL(MAX(v.vb_key), 0) INTO l_tapedvb FROM vbdf v WHERE v.df_key = f.df_key AND v.db_key = p_dbkey AND EXISTS (SELECT 1 FROM bdf d, bp p WHERE p.bs_key = d.bs_key AND p.lib_key IS NOT NULL AND d.dbinc_key = v.dbinc_key AND d.ckp_scn = v.ckp_scn AND d.file# = v.file#); -- SELECT MIN(vb_key) INTO l_nottapedvb FROM vbdf v WHERE v.df_key = f.df_key AND v.vb_key > l_tapedvb AND v.db_key = p_dbkey AND v.state = VBDF_COMPLETE AND EXISTS (SELECT 1 FROM bdf d, bp p WHERE p.bs_key = d.bs_key AND p.vb_key = v.vb_key AND p.status != 'D' AND d.dbinc_key = v.dbinc_key AND d.ckp_scn = v.ckp_scn AND d.file# = v.file#); -- -- -- IF l_nottapedvb IS NULL THEN l_nottapedvb := l_tapedvb; END IF; -- CONTINUE WHEN l_nottapedvb = 0; -- planDF(KBRSPLBLD_PURGE, f.df_key, l_nottapedvb); SELECT (freechunk - needchunk) * l_chunksize INTO l_sumtmp FROM plans WHERE df_key = f.df_key AND vb_key = l_nottapedvb AND type = KBRSPLBLD_PURGE; l_sumvb := l_sumvb + l_sumtmp; END LOOP; deb('Copied_to_tape: dbkey ' || p_dbkey || ', bp taped ' || l_sumbp/1024/1024 || 'm' || ', vb taped ' || l_sumvb/1024/1024 || 'm', AM_DEBUG_MED); RETURN (l_sumbp + l_sumvb); EXCEPTION WHEN OTHERS THEN save_error; deb('Copied_to_tape: failed with sqlcode ' || SQLCODE, AM_DEBUG_ON); RAISE; END copied_to_tape; -- -- -- -- -- -- PROCEDURE optimizeDF(p_dbkey IN NUMBER, -- Database key p_dfkey IN NUMBER, -- Datafile key p_onlylost IN BOOLEAN DEFAULT FALSE) IS l_hivbkey NUMBER; l_lowvbkey NUMBER; l_next_vbkey NUMBER; l_currinc NUMBER; l_resume NUMBER; l_count NUMBER; l_hichunk NUMBER; l_needspace BOOLEAN; l_current_frag NUMBER; l_orphans BOOLEAN; l_moving NUMBER; task_rec task%ROWTYPE; l_slkey NUMBER; BEGIN deb('optimizeDF: dfkey ' || p_dfkey, AM_DEBUG_MED); -- dbms_ra_scheduler.check_for_interrupt(0); -- BEGIN SELECT curr_dbinc_key INTO l_currinc FROM db WHERE db_key = p_dbkey; EXCEPTION WHEN no_data_found THEN -- Database has been deleted. Just go away. save_error; deb('optimizeDF: database is gone', AM_DEBUG_LOW); clear_error; RETURN; END; -- BEGIN -- purge_lock(p_dfkey); -- -- dbms_ra_int.info_start('optimizeDF chunk cleanse', 'dfkey ' || p_dfkey); dealloc_plan(p_dfkey, NULL, KBRSPLBLD_PURGE); alloc_plan(p_dbkey, p_dfkey, 0, KBRSPLBLD_PURGE); INSERT INTO plans_details (type, df_key, vb_key, chunkno, blkrank, blockno, coffset) (SELECT /*+ QB_NAME(c) INDEX(c@c) NO_INDEX_FFS(c@c) INDEX(b@b) NO_INDEX_FFS(b@b) UNNEST(@b) LEADING(c@c) USE_HASH(b@b) OPT_PARAM('optimizer_dynamic_sampling' 0) OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false') OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none') OPT_PARAM('_optimizer_use_feedback' 'false') */ KBRSPLBLD_PURGE, p_dfkey, 0, chunkno, 1 blkrank, -10 blockno, 0 coffset FROM chunks c WHERE c.df_key = p_dfkey AND c.clean_key <= (SELECT MAX(vb_key) FROM vbdf WHERE df_key = p_dfkey AND state = VBDF_COMPLETE) AND NOT EXISTS (SELECT /*+ QB_NAME(b) */ NULL FROM blocks b WHERE b.df_key = c.df_key AND b.chunkno = c.chunkno)); l_count := SQL%ROWCOUNT; COMMIT; dbms_ra_int.info_end; IF l_count > 0 THEN -- deb('optimizeDF: Lost chunks for dfkey ' || p_dfkey, AM_DEBUG_ON); purge_pool(p_dbkey, KBRSPLBLD_PURGE, KBRSPLBLD_PURGE, p_dfkey, 0); END IF; -- dealloc_plan(p_dfkey, NULL, KBRSPLBLD_PURGE); -- purge_unlock(p_dfkey); EXCEPTION WHEN OTHERS THEN save_error; purge_unlock(p_dfkey); RAISE; END; -- -- IF p_onlylost THEN RETURN; END IF; -- SELECT MAX(v.vb_key), MIN(v.vb_key) INTO l_hivbkey, l_lowvbkey FROM vbdf v, bp p, bdf d WHERE v.vb_key = p.vb_key AND v.db_key = p.db_key AND p.bs_key = d.bs_key AND v.dbinc_key = d.dbinc_key AND v.file# = d.file# AND v.ckp_scn = d.ckp_scn AND v.df_key = p_dfkey AND p.status != 'D'; -- IF l_lowvbkey IS NULL THEN deb('optimizeDF: ALL purge', AM_DEBUG_MED); -- SELECT COUNT(*) INTO l_count FROM dual WHERE EXISTS (SELECT 1 FROM chunks WHERE df_key = p_dfkey) AND NOT EXISTS (SELECT 1 FROM vbdf WHERE df_key = p_dfkey AND state NOT IN (VBDF_COMPLETE, VBDF_OBSOLETE)); -- IF l_count > 0 THEN -- SELECT sl_key INTO l_slkey FROM odb WHERE db_key = p_dbkey; -- SELECT MAX(vb_key) INTO l_hivbkey FROM vbdf WHERE df_key = p_dfkey; task_rec := NULL; task_rec.task_type := dbms_ra_scheduler.TASK_PURGE_DF; task_rec.param_num3 := KBRSPLBLD_ALLPURGE; task_rec.sl_key := l_slkey; task_rec.db_key := p_dbkey; task_rec.flags := 0; task_rec.param_num2 := l_hivbkey; task_rec.param_num1 := p_dfkey; dbms_ra_scheduler.new_task(task_rec); END IF; dbms_ra_scheduler.check_for_interrupt(0); RETURN; END IF; -- -- DELETE FROM vbdf WHERE df_key = p_dfkey AND state = VBDF_OBSOLETE AND vb_key < (SELECT vb_key FROM (SELECT vb_key, ROWNUM pos FROM vbdf WHERE df_key = p_dfkey AND state = VBDF_OBSOLETE ORDER BY vb_key DESC) WHERE pos = 100) AND ckp_scn < (SELECT MAX(ckp_scn) FROM vbdf WHERE df_key = p_dfkey AND ckp_id = min_id /* means level 0 */ AND state = VBDF_OBSOLETE); deb('optimizeDF: vbdf deleted are ' || SQL%ROWCOUNT, AM_DEBUG_MED); -- SELECT move_phase INTO l_moving FROM odb WHERE db_key = p_dbkey; -- -- IF l_moving IS NOT NULL THEN deb('optimizeDF: This was a moving clean up', AM_DEBUG_MED); RETURN; END IF; -- l_orphans := orphans(p_dbkey, p_dfkey, l_currinc); -- IF NOT l_orphans AND l_moving IS NULL THEN l_current_frag := fragmentation(p_dbkey, p_dfkey, l_hivbkey); END IF; -- -- deb('optimizeDF: Basic purge', AM_DEBUG_MED); reorderDF(KBRSPLBLD_PURGE, p_dfkey, l_lowvbkey); IF l_orphans THEN purge_vbdf(p_dbkey, KBRSPLBLD_PURGE, p_dfkey, l_lowvbkey); END IF; dbms_ra_scheduler.check_for_interrupt(0); dealloc_plan(p_dfkey, NULL, KBRSPLBLD_PURGE); -- -- IF l_orphans THEN deb('optimizeDF: Orphan incarnation prevents defragmentation', AM_DEBUG_MED); RETURN; END IF; -- -- IF l_current_frag IS NULL THEN -- planDF(KBRSPLBLD_PIECE, p_dfkey, l_hivbkey); l_current_frag := fragmentation(p_dbkey, p_dfkey, l_hivbkey); dbms_ra_scheduler.check_for_interrupt(0); -- Time 2 bail? END IF; deb('optimizeDF: df_key ' || p_dfkey || ', current frag ' || l_current_frag || ', _fragmentation ' || dbms_ra_scheduler.s_fragmentation, AM_DEBUG_MED); IF l_current_frag <= dbms_ra_scheduler.s_fragmentation THEN deb('optimizeDF: dfkey ' || p_dfkey || ' not frag.', AM_DEBUG_MED); RETURN; END IF; -- BEGIN deb('optimizeDF: Optimize prep', AM_DEBUG_MED); reorderDF(KBRSPLBLD_OPTIMIZE, p_dfkey, l_hivbkey); dbms_ra_scheduler.check_for_interrupt(0); EXCEPTION WHEN dbms_ra_scheduler.e_retry_reserve THEN save_error; l_needspace := TRUE; clear_error; WHEN OTHERS THEN save_error; RAISE; END; -- deb('optimizeDF: submit duplicate purge', AM_DEBUG_MED); task_rec := NULL; task_rec.task_type := dbms_ra_scheduler.TASK_PURGE_DUP_DF; task_rec.db_key := p_dbkey; task_rec.param_num1 := p_dfkey; task_rec.param_num2 := l_hivbkey; dbms_ra_scheduler.new_task(task_rec); -- commit and delay -- IF l_needspace THEN RAISE dbms_ra_scheduler.e_retry_reserve; END IF; END optimizeDF; -- -- -- -- -- -- PROCEDURE purgeDupDF(p_dfkey IN NUMBER, -- Datafile key p_vbkey IN NUMBER, -- Virtual backup key p_bpkey IN NUMBER, -- (optional) bp_key for locking p_newplans IN BOOLEAN DEFAULT TRUE) -- Inhibit new plans IS l_count NUMBER; l_dbkey NUMBER; BEGIN deb('purgeDupDF: dfkey ' || p_dfkey || ', vbkey ' || p_vbkey, AM_DEBUG_MED); -- IF p_bpkey > 0 THEN SELECT COUNT(*) INTO l_count FROM bp WHERE bp_key = p_bpkey AND status != 'D'; IF l_count > 0 THEN dbms_ra_int.write_lock(dbms_ra_int.KEY_BP, p_bpkey); dbms_ra_int.unlock(dbms_ra_int.KEY_BP, p_bpkey); END IF; END IF; -- SELECT COUNT(*), MAX(db_key) INTO l_count, l_dbkey FROM bp WHERE vb_key = p_vbkey AND status != 'D'; IF l_count = 0 THEN RETURN; END IF; -- SELECT COUNT(*) INTO l_count FROM dual WHERE EXISTS (SELECT 1 FROM task WHERE task_type = dbms_ra_scheduler.TASK_PURGE_DUP_DF AND db_key = l_dbkey AND param_num1 = p_dfkey AND param_num2 > p_vbkey); IF l_count > 0 THEN deb('purgeDupDF: more recent purge_dup for dfkey ' || p_dfkey, AM_DEBUG_MED); RETURN; END IF; IF orphans(l_dbkey, p_dfkey) THEN deb('purgeDupDF: Orphan backups for dfkey ' || p_dfkey || ' prevent deduplication', AM_DEBUG_MED); RETURN; END IF; -- -- reorderDF(KBRSPLBLD_DUPPURGE, p_dfkey, p_vbkey); -- IF p_newplans THEN new_plans(l_dbkey, p_dfkey); END IF; END purgeDupDF; -- -- -- -- -- -- PROCEDURE moveDF(p_dbkey IN NUMBER, -- Database key p_dfkey IN NUMBER) -- Datafile key IS l_slkey NUMBER; l_sldir sl.sl_cg_name%type; l_dbid NUMBER; l_hivbkey NUMBER; l_lowvbkey NUMBER; l_vbkey NUMBER; l_blksize NUMBER; l_issft NUMBER; l_count NUMBER; l_cmpvsn NUMBER; l_domore BOOLEAN := TRUE; l_dbinckey NUMBER; l_gotlock NUMBER := 0; BEGIN deb('moveDF: dbkey ' || p_dbkey || ', dfkey ' || p_dfkey, AM_DEBUG_MED); -- SELECT curr_dbinc_key INTO l_dbinckey FROM db WHERE db_key = p_dbkey; -- IF dbms_ra_scheduler.get_savepoint = 1 THEN BEGIN SELECT vb_key INTO l_hivbkey FROM (SELECT v.vb_key, i.dbinc_key, i.reset_scn FROM vbdf v, bp p, (SELECT db_key, dbinc_key, reset_scn, NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = l_dbinckey CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i WHERE v.vb_key = p.vb_key AND v.db_key = p.db_key AND v.df_key = p_dfkey AND v.state = VBDF_COMPLETE AND v.dbinc_key = i.dbinc_key AND v.ckp_scn >= i.reset_scn AND v.ckp_scn < i.next_reset_scn AND p.status != 'D' ORDER BY reset_scn DESC, vb_key DESC) WHERE ROWNUM = 1; EXCEPTION WHEN no_data_found THEN save_error; deb('moveDF: no vbkey for dfkey ' || p_dfkey, AM_DEBUG_MED); -- SELECT MAX(vb_key) INTO l_hivbkey FROM vbdf WHERE df_key = p_dfkey AND state = VBDF_OBSOLETE; clear_error; END; purgeDupDF(p_dfkey, l_hivbkey, NULL, FALSE); ELSE -- deb('moveDF: Basic purge', AM_DEBUG_MED); SELECT min(p.vb_key) INTO l_lowvbkey FROM vbdf v, bp p, bdf d WHERE v.vb_key = p.vb_key AND v.db_key = p.db_key AND p.bs_key = d.bs_key AND v.dbinc_key = d.dbinc_key AND v.file# = d.file# AND v.ckp_scn = d.ckp_scn AND v.df_key = p_dfkey AND p.status != 'D'; reorderDF(KBRSPLBLD_PURGE, p_dfkey, l_lowvbkey); dbms_ra_scheduler.check_for_interrupt(0); END IF; -- purge_lock(p_dfkey); -- SELECT sl_key INTO l_slkey FROM odb WHERE db_key = p_dbkey; SELECT sl_cg_name INTO l_sldir FROM sl WHERE sl_key = l_slkey; SELECT db_id INTO l_dbid FROM db WHERE db_key = p_dbkey; SELECT block_size, issft INTO l_blksize, l_issft FROM df WHERE df_key = p_dfkey AND dbinc_key = l_dbinckey; SELECT MAX(cmpvsn) INTO l_cmpvsn FROM vbdf WHERE df_key = p_dfkey; -- -- -- WHILE l_domore AND l_cmpvsn IS NOT NULL LOOP l_domore := FALSE; FOR c IN (SELECT chunkno, dbinc_key, filesize FROM chunks JOIN blocks USING (dbinc_key, df_key, chunkno) WHERE sl_key != l_slkey AND df_key = p_dfkey GROUP BY chunkno, dbinc_key, filesize) LOOP dbms_ra_scheduler.check_for_interrupt(1); -- SELECT MAX(vb_key) INTO l_vbkey FROM vbdf WHERE db_key = p_dbkey AND df_key = p_dfkey AND krbph_dfkey = p_dfkey AND ckp_id = (SELECT ckp_id FROM blocks WHERE df_key = p_dfkey AND blockno = 0 AND chunkno = c.chunkno ); IF l_vbkey IS NOT NULL THEN IF NOT dbms_ra_int.read_lock(dbms_ra_int.KEY_VB, l_vbkey) THEN -- SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'moveDF missing vbkey ' || l_vbkey); END IF; END IF; sys.kbrsi_icd.rsMovePoolDF(l_dbid, c.dbinc_key, p_dbkey, p_dfkey, c.chunkno, l_sldir, c.filesize, l_blksize, l_issft, l_cmpvsn, 0); IF l_vbkey IS NOT NULL THEN dbms_ra_int.unlock(dbms_ra_int.KEY_VB, l_vbkey); END IF; l_domore := TRUE; END LOOP; END LOOP; -- purge_unlock(p_dfkey); -- optimizeDF(p_dbkey, p_dfkey); dbms_ra_scheduler.check_for_interrupt(0); EXCEPTION WHEN OTHERS THEN save_error; IF l_vbkey IS NOT NULL THEN dbms_ra_int.unlock(dbms_ra_int.KEY_VB, l_vbkey); END IF; purge_unlock(p_dfkey); RAISE; END moveDF; -- -- -- -- -- -- -- PROCEDURE purgeDF(p_type IN NUMBER, -- Type of purge to perform p_dfkey IN NUMBER, -- Datafile key p_vbkey IN NUMBER) -- Oldest available vbkey IS l_dbkey NUMBER; l_dbinckey NUMBER; l_vbkey NUMBER; l_doreserve BOOLEAN; l_small BOOLEAN; l_savepoint NUMBER; l_allsavepoint NUMBER := NULL; l_count NUMBER; BEGIN l_savepoint := NVL(dbms_ra_scheduler.get_savepoint, 0); deb('purgeDF: type ' || p_type || ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey || ', savepoint ' || l_savepoint, AM_DEBUG_MED); -- IF l_savepoint IN (RESTART_PURGE_ALL_RETRY1, RESTART_PURGE_ALL_RETRY2, RESTART_PURGE_ALL_RETRY3) THEN l_allsavepoint := l_savepoint; l_savepoint := 0; dbms_ra_scheduler.check_for_interrupt(0); END IF; -- IF l_savepoint > 0 THEN BEGIN SELECT dbinc_key, db_key INTO l_dbinckey, l_dbkey FROM vbdf WHERE df_key = p_dfkey AND vb_key = p_vbkey; EXCEPTION WHEN no_data_found THEN -- OK, we lost the plan, start fresh save_error; l_savepoint := 0; clear_error; END; END IF; -- IF dbms_ra_scheduler.s_current_task_type = dbms_ra_scheduler.TASK_PURGE_DF_NOW THEN l_doreserve := TRUE; -- -- -- SELECT MIN(v.vb_key) INTO l_vbkey FROM vbdf v, (SELECT db_key, dbinc_key, reset_scn, NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = l_dbinckey CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i WHERE v.df_key = p_dfkey AND v.ckp_scn >= i.reset_scn AND v.ckp_scn < i.next_reset_scn AND v.dbinc_key = i.dbinc_key AND v.state != VBDF_OBSOLETE; ELSE l_doreserve := FALSE; l_vbkey := p_vbkey; END IF; -- IF p_type = KBRSPLBLD_ALLPURGE THEN -- BEGIN SELECT curr_dbinc_key, db.db_key INTO l_dbinckey, l_dbkey FROM db WHERE db_key IN (SELECT db_key FROM vbdf WHERE df_key = p_dfkey); EXCEPTION WHEN no_data_found THEN -- OK, this is gone already. Go away. save_error; clear_error; RETURN; END; -- SELECT MAX(vb_key) INTO l_vbkey FROM vbdf WHERE df_key = p_dfkey; IF p_vbkey != l_vbkey THEN RETURN; -- Another vb has been added, just let purge dup deal. END IF; END IF; -- IF NOT l_doreserve AND p_type <> KBRSPLBLD_ALLPURGE THEN -- SELECT MAX(v.dbinc_key), MAX(v.db_key) INTO l_dbinckey, l_dbkey FROM bp p, bdf d, vbdf v WHERE v.vb_key = p_vbkey AND v.df_key = p_dfkey AND p.vb_key = p_vbkey AND p.db_key = v.db_key AND p.status != 'D' AND p.bs_key = d.bs_key AND d.dbinc_key = v.dbinc_key AND d.file# = v.file# AND d.ckp_scn = v.ckp_scn AND v.state != VBDF_OBSOLETE; -- IF l_dbkey IS NULL THEN RETURN; END IF; END IF; -- IF l_savepoint <> RESTART_PURGE_VBDF THEN -- IF NOT l_doreserve THEN BEGIN -- reorderDF(p_type, p_dfkey, p_vbkey); EXCEPTION WHEN dbms_ra_scheduler.e_retry_reserve THEN save_error; l_doreserve := TRUE; clear_error; END; END IF; -- IF l_doreserve THEN l_small := TRUE; WHILE l_small LOOP purgeRes(p_dfkey, l_vbkey, l_savepoint, l_small); END LOOP; END IF; END IF; -- -- -- -- IF p_type = KBRSPLBLD_ALLPURGE AND l_allsavepoint <= RESTART_PURGE_ALL_RETRY3 THEN -- FOR x IN (SELECT DISTINCT sl_key FROM chunks WHERE df_key = p_dfkey) LOOP -- dbms_ra_scheduler.check_for_interrupt(NVL(l_allsavepoint+1, RESTART_PURGE_ALL_RETRY1)); -- dbms_ra_scheduler.avoid_sl(DBMS_RA_SCHEDULER.TASK_PURGE, x.sl_key); -- -- dbms_ra_scheduler.avoid_db(l_dbkey); END LOOP; -- END IF; -- -- -- IF NVL(dbms_ra_scheduler.get_savepoint, 0) > 0 OR s_purge_dbinc IS NOT NULL /* Orphan purge, we always need to do this */ THEN -- dbms_ra_scheduler.check_for_interrupt(RESTART_PURGE_VBDF); purge_vbdf(l_dbkey, p_type, p_dfkey, p_vbkey); dbms_ra_scheduler.check_for_interrupt(0); /* All done */ END IF; -- new_plans(l_dbkey, p_dfkey); END purgeDF; -- -- -- -- -- -- PROCEDURE planDF(p_type IN NUMBER, -- Type of plan to build p_dfkey IN NUMBER, -- Datafile key p_vbkey IN NUMBER, -- Vbkey associated with the plan p_res IN NUMBER DEFAULT 0, -- Chunks to reserve p_locked IN BOOLEAN DEFAULT FALSE, -- Key lock already held p_must IN BOOLEAN DEFAULT FALSE, -- Guaranteed, no retry p_plock IN BOOLEAN DEFAULT FALSE) -- Purge lock already held IS l_known NUMBER; l_dbkey NUMBER; l_gotlock BOOLEAN := FALSE; BEGIN deb('planDF: type ' || p_type || ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey || ', ' || systimestamp, AM_DEBUG_MED); -- IF (p_type = KBRSPLBLD_ALLPURGE) THEN SELECT COUNT(*), MAX(db_key) INTO l_known, l_dbkey FROM vbdf WHERE vb_key = p_vbkey AND df_key = p_dfkey; ELSE SELECT COUNT(*), MAX(p.db_key) INTO l_known, l_dbkey FROM bp p, bdf d, vbdf v WHERE v.vb_key = p_vbkey AND v.df_key = p_dfkey AND p.vb_key = p_vbkey AND p.db_key = v.db_key AND p.status != 'D' AND p.bs_key = d.bs_key AND d.dbinc_key = v.dbinc_key AND d.file# = v.file# AND d.ckp_scn = v.ckp_scn AND v.state = VBDF_COMPLETE; END IF; -- -- -- -- -- IF NOT p_must AND p_type IN (KBRSPLBLD_PURGE, KBRSPLBLD_SMALLPURGE, KBRSPLBLD_ALLPURGE, KBRSPLBLD_DUPPURGE, KBRSPLBLD_OPTPURGE, KBRSPLBLD_OPTIMIZE) THEN BEGIN -- IF NOT p_plock THEN purge_lock(p_dfkey); END IF; -- dealloc_plan(p_dfkey, NULL, KBRSPLBLD_OPTIMIZE); dealloc_plan(p_dfkey, NULL, KBRSPLBLD_PURGE); -- IF NOT p_plock THEN purge_unlock(p_dfkey); END IF; EXCEPTION WHEN OTHERS THEN save_error; IF NOT p_plock THEN purge_unlock(p_dfkey); END IF; RAISE; END; -- -- -- -- -- -- -- ELSE IF NOT p_plock AND dbms_ra_scheduler.s_current_task_type IN (dbms_ra_scheduler.TASK_PLAN_DF, dbms_ra_scheduler.TASK_PLAN_SBT) THEN purge_lock(p_dfkey); purge_unlock(p_dfkey); END IF; END IF; -- IF l_known = 0 THEN deb('planDF BP not known'); RETURN; END IF; -- BEGIN SELECT 1 INTO l_known FROM plans WHERE type = decode(p_type, KBRSPLBLD_OPTPURGE, KBRSPLBLD_PURGE, KBRSPLBLD_ALLPURGE, KBRSPLBLD_PURGE, KBRSPLBLD_SMALLPURGE, KBRSPLBLD_PURGE, KBRSPLBLD_DUPPURGE, KBRSPLBLD_PURGE, p_type) AND vb_key = p_vbkey AND df_key = p_dfkey AND blksread IS NOT NULL; EXCEPTION WHEN no_data_found THEN save_error; l_known := 0; clear_error; WHEN too_many_rows THEN save_error; l_known := 1; clear_error; END; -- IF l_known > 0 THEN deb('planDF plan is already done'); RETURN; END IF; -- -- -- -- IF NOT p_locked THEN l_gotlock := dbms_ra_int.read_lock(dbms_ra_int.KEY_DF, p_dfkey); END IF; -- WHILE l_known = 0 LOOP BEGIN sys.kbrsi_icd.rsPlan(l_dbkey, p_vbkey, p_dfkey, p_type, p_res); EXCEPTION WHEN dbms_ra_scheduler.e_retry_error THEN save_error; IF NOT p_must THEN RAISE; END IF; clear_error; WHEN OTHERS THEN save_error; RAISE; END; -- IF p_must THEN SELECT COUNT(*) INTO l_known FROM plans WHERE type = decode(p_type, KBRSPLBLD_OPTPURGE, KBRSPLBLD_PURGE, KBRSPLBLD_ALLPURGE, KBRSPLBLD_PURGE, KBRSPLBLD_SMALLPURGE, KBRSPLBLD_PURGE, KBRSPLBLD_DUPPURGE, KBRSPLBLD_PURGE, p_type) AND vb_key = p_vbkey AND df_key = p_dfkey AND blksread IS NOT NULL; -- Null means partial plan IF l_known = 0 THEN dbms_lock.sleep(3); END IF; ELSE l_known := 1; -- We do not care if it worked END IF; END LOOP; -- IF l_gotlock THEN dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey); l_gotlock := FALSE; END IF; deb('planDF end: type ' || p_type || ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey || ', ' || systimestamp, AM_DEBUG_MED); EXCEPTION WHEN OTHERS THEN save_error; -- -- IF l_gotlock THEN deb('planDF exception: unlocking type ' || p_type || ', dfkey ' || p_dfkey); dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey); END IF; RAISE; END planDF; -- -- -- -- -- -- -- -- -- -- -- PROCEDURE save_krbph(p_dfkey IN NUMBER, -- krbph df_key p_chunkno IN NUMBER, -- krbph chunk number p_name IN VARCHAR2, -- krbph chunk name p_splittype IN NUMBER ) -- splitting for block pool, -- -- -- -- IS BEGIN IF p_splittype = KBRS_SAVE_INFO_CFFILE THEN saved_krbph_cfname := p_name; ELSIF p_splittype = KBRS_SAVE_INFO_SPFILE THEN saved_krbph_spname := p_name; ELSE -- saved_krbphdf := p_dfkey; saved_krbph := p_chunkno; saved_krbph_name := p_name; END IF; END save_krbph; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE begin_df(p_vbkey IN OUT NUMBER, -- Virtual backup ID p_ckpid IN OUT NUMBER, -- ckp_scn --> ckp_id p_dbid IN NUMBER, -- Database ID p_fno IN NUMBER, -- Datafile number p_blocks IN NUMBER, -- (opt) Datafile size in blocks p_incrscn IN NUMBER, -- (opt) Incr_scn for backup p_crescn IN NUMBER, -- (opt) Datafile creation scn p_crestamp IN NUMBER, -- (opt) Datafile creation time p_rstscn IN NUMBER, -- (opt) reset scn p_rststamp IN NUMBER, -- (opt) reset stamp p_dfkey OUT NUMBER, -- Datafile key p_dbkey OUT NUMBER, -- Database key p_dbinckey OUT NUMBER, -- Database incarnation key p_unorderid OUT NUMBER, -- (opt) max(unorder_id) p_firstblk IN NUMBER, -- First block p_lastblk IN NUMBER) -- Last block IS l_known NUMBER := NULL; l_ckpid NUMBER; l_pdbinc_key NUMBER; l_ckpscn NUMBER := p_ckpid; -- From here p_ckpid should only be updated. l_pdbkey NUMBER; l_level NUMBER; l_count NUMBER; BEGIN -- -- -- IF p_vbkey IS NULL AND saved_vbkey = 0 THEN saved_vbkey := rman_seq.nextval; p_vbkey := saved_vbkey; deb('begin_df: New vbkey ' || saved_vbkey, AM_DEBUG_MED); dbms_ra_scheduler.check_for_interrupt(saved_vbkey); l_known := 0; END IF; -- IF p_vbkey IS NULL AND saved_vbkey != 0 THEN p_vbkey := saved_vbkey; deb('begin_df:FIRSTELSE New vbkey ' || saved_vbkey, AM_DEBUG_MED); END IF; -- IF l_known IS NULL THEN -- BEGIN SELECT 1, db_key, dbinc_key, df_key, ckp_id INTO l_known, p_dbkey, p_dbinckey, p_dfkey, l_ckpid FROM vbdf WHERE vb_key = p_vbkey AND file# = p_fno; -- IF s_purge_dbinc IS NOT NULL AND dbms_ra_scheduler.s_current_task_type = dbms_ra_scheduler.TASK_PURGE_DF THEN p_dbinckey := s_purge_dbinc; END IF; EXCEPTION WHEN no_data_found THEN save_error; l_known := 0; clear_error; END; END IF; -- IF l_known = 0 THEN -- SELECT db.db_key, df.dbinc_key, df.df_key, df.pdbinc_key INTO p_dbkey, p_dbinckey, p_dfkey, l_pdbinc_key FROM df, db, dbinc i WHERE db_id = p_dbid AND db.db_key = i.db_key AND i.dbinc_key = df.dbinc_key AND i.reset_scn = p_rstscn AND i.reset_time = dbms_ra_int.stamp2date(p_rststamp) AND df.file# = p_fno AND df.create_scn = p_crescn AND df.create_time = dbms_ra_int.stamp2date(p_crestamp); -- IF p_firstblk > 2 THEN SELECT MAX(ckp_scn) INTO l_ckpscn FROM vbdf WHERE dbinc_key = p_dbinckey AND df_key = p_dfkey AND firstblk = 2; deb('begin_df: dfkey ' || p_dfkey || ', vbkey ' || p_vbkey || ', ckpscn ' || l_ckpscn || ', firstblk ' || p_firstblk ,AM_DEBUG_MED); END IF; -- BEGIN -- SELECT 1 INTO l_count FROM vbdf WHERE df_key = p_dfkey AND ckp_id = p_ckpid; -- -- -- -- -- SELECT MIN(ckp_id) + 1 INTO l_ckpid FROM vbdf v1 WHERE df_key = p_dfkey AND ckp_id >= p_ckpid AND NOT EXISTS (SELECT 1 FROM vbdf v2 WHERE v2.df_key = p_dfkey AND v2.ckp_id = v1.ckp_id + 1); EXCEPTION WHEN no_data_found THEN save_error; l_ckpid := p_ckpid; clear_error; END; END IF; deb ('begin_df: known ' || l_known || ', dbkey ' || p_dbkey || ', dbinc_key ' || p_dbinckey || ', dfkey ' || p_dfkey ,AM_DEBUG_MED); -- -- IF l_known = 0 THEN deb('begin_df unknown: dfkey ' || p_dfkey || ', vbkey ' || p_vbkey || ', ckpid ' || l_ckpid, AM_DEBUG_MED); -- -- -- SELECT p.pdb_key, p.con_id INTO l_pdbkey, l_count FROM pdb p, pdbinc i WHERE i.pdb_key = p.pdb_key AND i.pdbinc_key = l_pdbinc_key; IF l_count > 1 THEN /* con_id > 1 */ -- SELECT MAX(inccnt) INTO l_count FROM (SELECT COUNT(*) inccnt FROM pdbinc WHERE pdb_key = l_pdbkey GROUP BY born_dbinc_key); IF l_count > 1 THEN /* we have pluggable activity */ -- -- SELECT pdbinc_key INTO l_pdbinc_key FROM (SELECT pdb_key, pdbinc_key FROM pdbinc i WHERE pdb_key = l_pdbkey AND born_dbinc_key = p_dbinckey AND begin_reset_scn <= l_ckpscn ORDER BY begin_reset_scn DESC) WHERE ROWNUM = 1; ELSE -- l_pdbinc_key := 0; END IF; ELSE -- l_pdbinc_key := 0; END IF; -- INSERT INTO vbdf (vb_key, df_key, db_key, dbinc_key, pdbinc_key, file#, blocks, firstblk, lastblk, incr_scn, ckp_scn, ckp_id, state) VALUES (p_vbkey, p_dfkey, p_dbkey, p_dbinckey, l_pdbinc_key, p_fno, p_blocks, p_firstblk, p_lastblk, p_incrscn, l_ckpscn, l_ckpid, VBDF_BUILDING); COMMIT; p_ckpid := l_ckpid; END IF; -- IF p_incrscn IS NOT NULL THEN SELECT incrLevel(create_scn, p_incrscn) INTO l_level FROM df WHERE dbinc_key = p_dbinckey AND df_key = p_dfkey; IF l_level = 1 THEN SELECT LEAST(NVL(MAX(unorder_id), p_incrscn), p_incrscn) INTO p_unorderid FROM vbdf WHERE df_key = p_dfkey AND ckp_id < l_ckpid; ELSE p_unorderid := 0; END IF; ELSE p_unorderid := KSCNINV; END IF; END begin_df; -- -- -- -- -- -- PROCEDURE end_df(p_vbkey IN NUMBER, -- Virtual backup ID p_dfkey IN NUMBER, -- Datafile key p_relfno IN NUMBER, -- Backupset relative file number p_ckpscn IN NUMBER, -- Checkpoint scn p_absscn IN NUMBER, -- Absolute fuzzy scn p_repair IN BOOLEAN, -- True if repair in progress p_cmpvsn IN NUMBER, -- backup version# p_issft IN NUMBER, -- Lowest gap scn in backup p_unorder IN NUMBER, -- 1 if unordered block found p_replev IN NUMBER DEFAULT NULL) -- Repair incr level IS l_minid NUMBER; l_level NUMBER; l_count NUMBER; l_priorvb NUMBER; l_ckpid NUMBER; l_tmpscn NUMBER; l_dbinckey NUMBER; l_incrscn NUMBER; l_lastunord NUMBER; l_fno NUMBER; BEGIN deb('end_df vbkey ' || p_vbkey || ', dfkey ' || p_dfkey || ', cmpvsn ' || p_cmpvsn || ', issft ' || p_issft, AM_DEBUG_MED); -- SELECT incrLevel(d.create_scn, v.incr_scn), v.ckp_id, v.dbinc_key, v.incr_scn, v.file# INTO l_level, l_ckpid, l_dbinckey, l_incrscn, l_fno FROM df d, vbdf v WHERE v.vb_key = p_vbkey AND v.df_key = p_dfkey AND v.dbinc_key = d.dbinc_key AND d.df_key = p_dfkey; -- IF p_repair AND p_replev IS NOT NULL THEN l_level := p_replev; END IF; deb('end_df ckpscn ' || p_ckpscn || ', incrLevel ' || l_level, AM_DEBUG_MED); -- IF l_level = 1 THEN -- -- SELECT NVL(MAX(v.min_id), 0), MAX(v.vb_key), MAX(unorder_id) INTO l_minid, l_priorvb, l_lastunord FROM vbdf v, (SELECT db_key, dbinc_key, reset_scn, NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = l_dbinckey CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i WHERE v.df_key = p_dfkey AND v.vb_key < p_vbkey AND v.ckp_scn < p_ckpscn /* Needed for repop or validate */ AND v.firstblk <= 2 /* Ensure we use piece# 1 */ AND v.dbinc_key = i.dbinc_key AND v.ckp_scn >= i.reset_scn AND v.ckp_scn < i.next_reset_scn; -- -- -- -- IF NOT p_repair THEN SELECT COUNT(*) INTO l_count FROM bp JOIN bdf USING (bs_key) WHERE vb_key = l_priorvb AND file# = l_fno AND status != 'D' AND ROWNUM = 1; IF l_count = 0 THEN deb('end_df missing prior level 0. Expected vbkey ' || l_priorvb, AM_DEBUG_ON); RAISE dbms_ra_scheduler.e_retry_error; END IF; END IF; ELSE -- -- l_minid := l_ckpid; END IF; -- IF p_unorder > 0 THEN l_lastunord := l_ckpid; END IF; -- -- -- -- UPDATE vbdf SET min_id = NVL(min_id, l_minid), -- repop cmpvsn = p_cmpvsn, relfno = nvl(relfno, p_relfno), -- repop krbph_chunkno = saved_krbph, krbph_dfkey = saved_krbphdf, abs_scn = greatest(p_absscn, l_ckpid), unorder_id = l_lastunord, state = VBDF_FIN_NOBP WHERE vb_key = p_vbkey AND df_key = p_dfkey AND (state = VBDF_BUILDING OR state = VBDF_REPOPULATE); IF SQL%ROWCOUNT != 1 THEN /* catches VBDF_ABORT */ RAISE dbms_ra_scheduler.e_retry_reserve; END IF; -- SELECT COUNT(*) INTO l_count FROM df WHERE df_key = p_dfkey AND issft IS NULL; IF l_count > 0 THEN UPDATE df SET issft = p_issft WHERE df_key = p_dfkey; END IF; COMMIT; END end_df; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE repair_df(p_vbkey IN OUT NUMBER, -- Virtual backup ID p_newvb IN OUT NUMBER, -- NULL, 1 begin_df, 0 repair p_dbid IN NUMBER, -- Database ID p_fno IN NUMBER, -- Datafile number p_blocks IN NUMBER, -- Datafile size in blocks p_relfno IN NUMBER, -- Backupset relative fileno p_crescn IN NUMBER, -- Datafile creation scn p_crestamp IN NUMBER, -- Datafile creation time p_rstscn IN NUMBER, -- reset scn p_rststamp IN NUMBER, -- reset stamp p_startscn IN NUMBER, -- Incremental start scn p_ckpscn IN NUMBER, -- Checkpoint scn p_cmpvsn IN NUMBER, -- backup version# p_issft IN NUMBER, -- Single File Tablespace p_firstblk IN NUMBER, -- First Block p_lastblk IN NUMBER, -- Last Block p_replev IN NUMBER) -- incrLevel if invalid incrscn IS l_dbkey NUMBER; l_dbinckey NUMBER; l_dfkey NUMBER; l_vbkey NUMBER; l_state NUMBER; l_tmp NUMBER; l_count NUMBER; l_scn NUMBER; l_ckpid NUMBER := p_ckpscn; l_absscn NUMBER; l_unorder NUMBER; l_gapid NUMBER; BEGIN -- BEGIN SELECT * INTO l_vbkey, l_dfkey, l_state FROM (SELECT v.vb_key, v.df_key, v.state FROM vbdf v, db d, dbinc i WHERE d.db_key = v.db_key AND i.db_key = v.db_key AND i.reset_scn = p_rstscn AND i.reset_time = dbms_ra_int.stamp2date(p_rststamp) AND v.ckp_scn = p_ckpscn AND v.cmpvsn = p_cmpvsn AND d.db_id = p_dbid AND v.file# = p_fno AND v.state = VBDF_REPAIR ORDER BY vb_key) WHERE ROWNUM = 1; EXCEPTION WHEN no_data_found THEN save_error; l_state := NULL; clear_error; END; -- IF p_newvb IS NULL AND l_state IS NOT NULL THEN BEGIN SELECT 1 INTO l_tmp FROM vbdf v, (SELECT db_key, dbinc_key, reset_scn, NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = l_dbinckey CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i WHERE v.df_key = l_dfkey AND v.vb_key > l_vbkey AND v.ckp_scn >= i.reset_scn AND v.ckp_scn < i.next_reset_scn AND v.dbinc_key = i.dbinc_key AND v.ckp_scn < p_ckpscn AND ROWNUM = 1; -- DELETE FROM vbdf WHERE vb_key = l_vbkey; deb('repair_df: Out of order vbkeys at vbkey ' || l_vbkey || ', rows deleted: ' || SQL%ROWCOUNT, AM_DEBUG_MED); COMMIT; l_state := NULL; EXCEPTION WHEN no_data_found THEN save_error; clear_error; /* expected result */ END; END IF; -- IF p_newvb = 0 AND l_state IS NULL THEN -- -- -- -- DELETE FROM vbdf WHERE df_key IN (SELECT df_key FROM vbdf WHERE vb_key = p_vbkey) AND ckp_scn >= p_ckpscn; l_count := SQL%ROWCOUNT; IF l_count > 0 THEN deb('repair_df: Must restart all, vbdf rows deleted: ' || l_count, AM_DEBUG_MED); COMMIT; RAISE dbms_ra_scheduler.e_retry_error; END IF; COMMIT; saved_vbkey := 0; /* Do not want begin_df to reuse this */ p_newvb := NULL; /* Tells caller to restart this piece */ deb('repair_df: Must restart piece', AM_DEBUG_MED); RETURN; END IF; -- IF p_newvb = 1 AND l_state IS NOT NULL THEN -- -- -- -- DELETE FROM vbdf WHERE df_key = l_dfkey AND ckp_scn >= p_ckpscn; deb('repair_df: Old piece rows deleted: ' || SQL%ROWCOUNT, AM_DEBUG_MED); l_state := NULL; /* Records are gone, continue to build new ones. */ END IF; -- IF l_state IS NOT NULL THEN saved_vbkey := l_vbkey; p_vbkey := l_vbkey; p_newvb := 0; -- -- IF l_state IN (VBDF_REPAIR, VBDF_FIN_NOBP) THEN UPDATE vbdf SET state = VBDF_FIN_NOBP, krbph_chunkno = saved_krbph, krbph_dfkey = saved_krbphdf, incr_scn = p_startscn /* incr_scn may now be invalid */ WHERE df_key = l_dfkey AND vb_key = l_vbkey AND incr_scn >= p_startscn; /* cannot go from invalid to valid */ COMMIT; ELSE -- -- deb('repair_df: bad state ' || l_state || ', dfkey ' || l_dfkey || ', vbkey ' || l_vbkey, AM_DEBUG_ON); END IF; deb('repair_df: done - vbkey ' || l_vbkey || ', dfkey ' || l_dfkey, AM_DEBUG_MED); -- ELSE p_newvb := 1; begin_df(p_vbkey, l_ckpid, p_dbid, p_fno, p_blocks, p_startscn, p_crescn, p_crestamp, p_rstscn, p_rststamp, l_dfkey, l_dbkey, l_dbinckey, l_gapid, p_firstblk, p_lastblk); -- -- -- SELECT MAX(scn), SUM(CASE WHEN scn = ckp_id AND blockno > 1 THEN 1 ELSE 0 END) INTO l_absscn, l_unorder FROM blocks WHERE df_key = l_dfkey AND ckp_id = l_ckpid; end_df(p_vbkey, l_dfkey, p_relfno, p_ckpscn, l_absscn, TRUE, p_cmpvsn, p_issft, sign(l_unorder), p_replev); -- SELECT MAX(scn), MAX(ckp_id) INTO l_scn, l_ckpid FROM blocks WHERE df_key = saved_krbphdf AND blockno = 0 AND ckp_id = l_ckpid; IF l_scn IS NOT NULL AND l_scn <> l_ckpid THEN UPDATE blocks SET scn = ckp_id WHERE df_key = saved_krbphdf AND blockno = 0 AND ckp_id = l_ckpid; COMMIT; END IF; deb('repair_df: new done - dfkey ' || l_dfkey || ', vbkey ' || p_vbkey || ', firstblk ' || p_firstblk || ', lastblk ' || p_lastblk, AM_DEBUG_MED); END IF; END repair_df; -- -- -- -- -- PROCEDURE deleteVB(p_slkey IN NUMBER, p_dbkey IN NUMBER, p_currinc IN NUMBER, p_bpkey IN NUMBER, p_noplans IN BOOLEAN, p_notasks IN BOOLEAN) IS -- CURSOR allFno(c_bpkey number) IS SELECT vb_key, df_key, tag FROM bp p, bdf b, df d WHERE p.bs_key = b.bs_key AND b.dbinc_key = d.dbinc_key AND b.file# = d.file# AND b.create_scn = d.create_scn AND p.bp_key = c_bpkey; l_purgeType NUMBER; l_count NUMBER; l_loopcount NUMBER; task_rec task%ROWTYPE; l_vbkey NUMBER; l_msection NUMBER; BEGIN -- -- -- SELECT MAX(vb_key), COUNT(*) + SUM(incrLevel(create_scn, incr_scn)) INTO l_vbkey, l_count FROM bdf JOIN bp USING (bs_key) WHERE bp_key = p_bpkey; IF l_count = 1 THEN -- IF NOT dbms_ra_int.write_lock_wait(dbms_ra_int.KEY_VB, l_vbkey) THEN RAISE dbms_ra_scheduler.e_retry_error; END IF; -- -- -- -- BEGIN FOR k in (SELECT c.filename, c.chunkno, v.file#, d.block_size, f.df_key, sign(v.ckp_id - v.min_id) ilevel FROM bp p, bdf d, df f, chunks c, vbdf v WHERE d.dbinc_key = f.dbinc_key AND d.file# = f.file# AND d.create_scn = f.create_scn AND c.chunkno IN (v.krbph_chunkno, v.new_krbph) AND c.df_key = v.krbph_dfkey AND p.bs_key = d.bs_key AND v.vb_key = p.vb_key AND v.file# = d.file# AND p.status != 'D' AND p.bp_key = p_bpkey ORDER BY chunkno DESC) LOOP deb('deleteVB: krbpd - file# ' || k.file# || ', dfkey ' || k.df_key || ', chunk ' || k.chunkno || ', bpkey ' || p_bpkey, AM_DEBUG_MED); sys.kbrsi_icd.delete_krbpd(p_dbkey, k.file#, k.filename, k.ilevel, k.block_size); EXIT; END LOOP; EXCEPTION WHEN OTHERS THEN save_error; dbms_ra_int.unlock(dbms_ra_int.KEY_VB, l_vbkey); RAISE; END; dbms_ra_int.unlock(dbms_ra_int.KEY_VB, l_vbkey); END IF; -- FOR fil IN allFno(p_bpkey) LOOP deb('deleteVB tag ' || fil.tag, AM_DEBUG_HIGH); SELECT DECODE(multi_section, 'Y', 1, 0) INTO l_msection FROM bs WHERE bs_key = (select bs_key from bp where bp_key = p_bpkey); -- -- IF l_msection = 1 THEN SELECT COUNT(*) INTO l_count FROM bp p, bdf b, vbdf v WHERE p.bs_key = b.bs_key AND b.dbinc_key = v.dbinc_key AND b.file# = v.file# AND b.ckp_scn = v.ckp_scn AND p.vb_key = v.vb_key AND p.db_key = v.db_key AND p.status != 'D' AND v.df_key = fil.df_key; deb('deleteVB bpkey msection ' || p_bpkey || ', dfkey ' || fil.df_key || ', vbkey ' || fil.vb_key || ', del ' || l_count || ', npln ' || print(p_noplans) || ', ntsk ' || print(p_notasks), AM_DEBUG_MED); CONTINUE WHEN l_count > 1; END IF; -- SELECT COUNT(*) INTO l_count FROM bp p, bdf b, vbdf v WHERE p.bs_key = b.bs_key AND p.vb_key = v.vb_key AND p.db_key = v.db_key AND b.dbinc_key = v.dbinc_key AND b.file# = v.file# AND b.ckp_scn = v.ckp_scn AND p.status != 'D' AND v.df_key = fil.df_key AND v.vb_key <= fil.vb_key; deb('deleteVB bpkey ' || p_bpkey || ', dfkey ' || fil.df_key || ', vbkey ' || fil.vb_key || ', del ' || l_count || ', npln ' || print(p_noplans) || ', ntsk ' || print(p_notasks), AM_DEBUG_MED); CONTINUE WHEN l_count > 1; -- -- -- -- -- SELECT COUNT(DISTINCT v.vb_key) INTO l_count FROM vbdf v, prot p, odb, bp b WHERE b.db_key = odb.db_key AND p.prot_key = odb.prot_key AND v.vb_key = b.vb_key AND v.df_key = fil.df_key AND b.status != 'D' AND b.bp_key != p_bpkey AND b.completion_time > (systimestamp - prot_recovery_window_goal) AND (not_taped_state IS NULL OR EXISTS (SELECT 1 FROM bp WHERE lib_key IS NOT NULL AND bp.bp_key = b.bp_key)); -- IF l_count > 2 THEN l_purgeType := KBRSPLBLD_OPTPURGE; deb('deleteVB dfkey ' || fil.df_key || ' optimized purge', AM_DEBUG_MED); ELSE -- -- SELECT count(*) INTO l_count FROM vbdf v, bp p, bdf d WHERE v.vb_key = p.vb_key AND v.db_key = p.db_key AND v.df_key = fil.df_key AND p.status != 'D' AND p.bp_key != p_bpkey AND d.bs_key = p.bs_key AND d.file# = v.file# AND d.ckp_scn = v.ckp_scn AND d.dbinc_key = v.dbinc_key; -- -- IF l_count = 0 THEN SELECT COUNT(*) INTO l_count FROM vbdf WHERE df_key = fil.df_key AND state NOT IN (VBDF_COMPLETE, VBDF_OBSOLETE); END IF; IF l_count > 0 THEN l_purgeType := KBRSPLBLD_PURGE; deb('deleteVB dfkey ' || fil.df_key || ' purging not optimized', AM_DEBUG_LOW); ELSE -- l_purgeType := KBRSPLBLD_ALLPURGE; deb('deleteVB dfkey ' || fil.df_key || ' no longer recoverable', AM_DEBUG_LOW); -- IF DBMS_RA_SCHEDULER.S_PURGING_ACTIVE THEN dbms_ra_scheduler.log_error ( p_errno => dbms_ra_scheduler.e_incr_lost_num, p_param1 => dbms_ra_int.dbkey2name(p_dbkey), p_component => 'PURGE', p_severity => dbms_ra_scheduler.severity_warning, p_db_key => p_dbkey); END IF; -- END IF; END IF; IF l_purgeType = KBRSPLBLD_ALLPURGE THEN -- SELECT MAX(vb_key) INTO l_vbkey FROM vbdf WHERE df_key = fil.df_key; ELSE -- SELECT MIN(v.vb_key) INTO l_vbkey FROM vbdf v, bp p, bdf d, (SELECT db_key, dbinc_key, reset_scn, NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = p_currinc CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i WHERE p.bp_key != p_bpkey AND v.vb_key = p.vb_key AND v.db_key = p.db_key AND v.df_key = fil.df_key AND v.ckp_scn >= i.reset_scn AND v.ckp_scn < i.next_reset_scn AND v.dbinc_key = i.dbinc_key AND p.bs_key = d.bs_key AND v.ckp_scn = d.ckp_scn AND v.file# = d.file# AND v.dbinc_key = d.dbinc_key AND p.status != 'D'; END IF; -- SELECT COUNT(DISTINCT dbinc_key) INTO l_count FROM vbdf WHERE df_key = fil.df_key AND vb_key <= l_vbkey AND state != VBDF_OBSOLETE; IF l_count > 1 THEN SELECT COUNT(*) INTO l_count FROM vbdf v, bp p, bdf d WHERE p.vb_key = v.vb_key AND p.db_key = v.db_key AND p.bs_key = d.bs_key AND v.ckp_scn = d.ckp_scn AND v.file# = d.file# AND v.dbinc_key = d.dbinc_key AND p.status != 'D' AND p.bp_key != p_bpkey AND v.df_key = fil.df_key AND v.vb_key < l_vbkey AND state != VBDF_OBSOLETE; IF l_count > 0 THEN deb('deleteVB: orphans preventing a purge', AM_DEBUG_LOW); RETURN; END IF; END IF; -- IF p_notasks THEN purgeDF(l_purgeType, fil.df_key, l_vbkey); -- ELSE task_rec := NULL; -- IF l_vbkey IS NOT NULL THEN task_rec.task_type := dbms_ra_scheduler.TASK_PURGE_DF; task_rec.param_num3 := l_purgeType; task_rec.sl_key := p_slkey; task_rec.db_key := p_dbkey; task_rec.flags := 0; task_rec.param_num2 := l_vbkey; task_rec.param_num1 := fil.df_key; dbms_ra_scheduler.new_task(task_rec); END IF; END IF; END LOOP; EXCEPTION WHEN no_data_found THEN save_error; -- deb('deleteVB no_data_found error bp_key ' || p_bpkey, AM_DEBUG_LOW); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'deleteVB no_data_found'); END deleteVB; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE repairChunks(p_dbkey IN NUMBER) -- database key IS l_numvb NUMBER; l_numbadvb NUMBER; l_newvb NUMBER; l_level NUMBER; l_resume_cno NUMBER; l_outbpkey NUMBER; l_size NUMBER; l_currinc NUMBER; l_dfkeylst NOLST; -- Array of number l_lowscnlst NOLST; -- Array of number l_dflock NUMBER := NULL; l_fixfin BOOLEAN := FALSE; l_lastdf NUMBER := 0; l_lastckpid NUMBER := 0; BEGIN deb('repairChunks: dbkey ' || p_dbkey); -- -- -- sys.kbrsi_icd.repair_chunks(p_dbkey); -- -- -- -- BEGIN SELECT 1 INTO l_numvb FROM chunks c, dbinc i, df f WHERE i.db_key = p_dbkey AND f.dbinc_key = i.dbinc_key AND c.df_key = f.df_key AND c.dbinc_key = i.dbinc_key AND c.clean_key = -1 AND ROWNUM = 1; deb('WARNING: Block pool files remain not repaired for database ' || dbms_ra_int.dbkey2name(p_dbkey), AM_DEBUG_ON); EXCEPTION WHEN no_data_found THEN /* This is what we expect */ save_error; NULL; clear_error; END; -- -- -- DELETE vbdf WHERE state NOT IN (VBDF_COMPLETE, VBDF_OBSOLETE, VBDF_REPAIR) AND db_key = p_dbkey; UPDATE vbdf SET state = VBDF_REPAIR WHERE db_key = p_dbkey AND state = VBDF_COMPLETE; -- UPDATE vbdf SET incr_scn = KSCNINV WHERE db_key = p_dbkey AND state = VBDF_OBSOLETE; -- UPDATE vbdf SET krbph_chunkno = new_krbph, new_krbph = NULL WHERE db_key = p_dbkey AND new_krbph IS NOT NULL; COMMIT; -- -- -- -- -- -- -- l_fixfin := TRUE; FOR chnk IN (SELECT c.chunkno, c.filename, f.block_size, c.df_key, b.ckp_id FROM blocks b, chunks c, df f, dbinc i WHERE i.db_key = p_dbkey AND f.dbinc_key = i.dbinc_key AND b.dbinc_key = i.dbinc_key AND b.df_key = f.df_key AND c.df_key = f.df_key AND c.chunkno = b.chunkno AND c.dbinc_key = i.dbinc_key AND b.blockno = 0 ORDER BY i.reset_time, b.ckp_id, b.scn, chunkno desc) LOOP -- IF l_lastdf <> chnk.df_key OR l_lastckpid <> chnk.ckp_id THEN saved_vbkey := 0; /* begin_df needs this */ saved_krbphdf := chnk.df_key; /* end_df needs this */ saved_krbph := chnk.chunkno; /* end_df needs this */ sys.kbrsi_icd.repair_vbdf(chnk.df_key, chnk.chunkno); END IF; l_lastdf := chnk.df_key; l_lastckpid := chnk.ckp_id; END LOOP; -- -- IF s_safemode THEN deb('repairChunks: debug, make sure relfno assigned ok'); SELECT MAX(vb_key) INTO l_numvb FROM vbdf WHERE state NOT IN (VBDF_OBSOLETE, VBDF_REPAIR) AND vb_key IN (SELECT vb_key FROM (SELECT vb_key, MAX(relfno) maxr, COUNT(*) cnt FROM vbdf GROUP BY vb_key) WHERE cnt != maxr); IF l_numvb IS NOT NULL THEN deb('repairChunks: messed up relfno in vbkey ' || l_numvb); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Bad relfno'); END IF; END IF; -- -- -- UPDATE vbdf SET state = DECODE(incr_scn, KSCNINV, VBDF_OBSOLETE, VBDF_COMPLETE) WHERE (vb_key, dbinc_key, file#, ckp_scn) IN (SELECT vb_key, dbinc_key, file#, ckp_scn FROM bdf b, bp p WHERE p.bs_key = b.bs_key AND p.vb_key IS NOT NULL AND p.status != 'D' AND p.db_key = p_dbkey) AND state = VBDF_FIN_NOBP AND db_key = p_dbkey; deb('repairChunks: ' || SQL%ROWCOUNT || ' rows repaired.', AM_DEBUG_LOW); COMMIT; -- -- -- -- UPDATE vbdf SET state = VBDF_OBSOLETE, incr_scn = KSCNINV WHERE db_key = p_dbkey AND state = VBDF_REPAIR; COMMIT; -- -- -- FOR p IN (SELECT bp.db_key, handle, sl_key, db_id, curr_dbinc_key, bp_key FROM bp, db, odb WHERE bp.db_key = db.db_key AND bp.db_key = odb.db_key AND bp.db_key = p_dbkey AND vb_key IS NOT NULL AND status != 'D' AND (bs_key, vb_key) NOT IN (SELECT d.bs_key, v.vb_key FROM bdf d, vbdf v WHERE d.dbinc_key = v.dbinc_key AND d.ckp_scn = v.ckp_scn AND v.state = VBDF_COMPLETE AND v.incr_scn < KSCNINV AND v.db_key = p_dbkey)) LOOP dbms_ra_storage.free_backup_piece_opt(p_dbkey => p.db_key, p_piecename => p.handle, p_db_slkey => p.sl_key, p_dbid => p.db_id, p_currinc => p.curr_dbinc_key, p_bpkey => p.bp_key, p_ftype => NULL, p_fincarn => NULL, p_libkey => NULL, p_spawn_job => FALSE, p_notasks => TRUE, p_noplans => TRUE); END LOOP; -- SELECT curr_dbinc_key INTO l_currinc FROM db WHERE db_key = p_dbkey; -- -- -- -- -- -- -- SELECT * BULK COLLECT INTO l_lowscnlst, l_dfkeylst FROM (SELECT MIN(scn) lowscn, b.df_key FROM df f, blocks b, (SELECT dbinc_key, NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = l_currinc CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i WHERE f.dbinc_key = l_currinc AND b.df_key = f.df_key AND (b.dbinc_key = i.dbinc_key OR b.dbinc_key NOT IN (SELECT dbinc_key FROM dbinc START WITH dbinc_key = l_currinc CONNECT BY PRIOR parent_dbinc_key = dbinc_key)) AND i.next_reset_scn-1 < b.scn GROUP BY b.df_key) WHERE lowscn IS NOT NULL; -- -- -- FOR i IN 1 .. l_dfkeylst.COUNT LOOP deb('repairChunks orphan blocks fix dfkey ' || l_dfkeylst(i) || ', below scn ' || l_lowscnlst(i), AM_DEBUG_ON); UPDATE vbdf SET state = VBDF_COMPLETE WHERE df_key = l_dfkeylst(i) AND state = VBDF_OBSOLETE AND ckp_scn < l_lowscnlst(i) AND incr_scn < KSCNINV; END LOOP; COMMIT; -- -- -- FOR piece IN (SELECT c.filename, v.vb_key, c.chunkno FROM vbdf v, chunks c, dbinc i WHERE i.db_key = p_dbkey AND v.dbinc_key = i.dbinc_key AND v.relfno = 1 AND c.df_key = v.df_key AND c.chunkno = v.krbph_chunkno AND c.df_key = v.krbph_dfkey AND c.dbinc_key = i.dbinc_key AND v.state = VBDF_FIN_NOBP ORDER BY v.vb_key) LOOP -- UPDATE vbdf SET state = VBDF_OBSOLETE WHERE vb_key = piece.vb_key AND incr_scn >= KSCNINV AND state = VBDF_FIN_NOBP; l_numbadvb := SQL%ROWCOUNT; -- FOR i IN 1 .. l_dfkeylst.COUNT LOOP UPDATE vbdf SET state = VBDF_COMPLETE WHERE vb_key = piece.vb_key AND df_key = l_dfkeylst(i) AND incr_scn >= KSCNINV AND ckp_scn < l_lowscnlst(i) AND state = VBDF_OBSOLETE; END LOOP; COMMIT; -- IF l_numbadvb = 0 THEN FOR i IN (SELECT df_key, vb_key FROM vbdf WHERE vb_key = piece.vb_key AND dfbytes IS NULL AND incr_scn < KSCNINV) LOOP IF dbms_ra_int.read_lock(dbms_ra_int.KEY_DF, i.df_key) THEN l_dflock := i.df_key; sys.kbrsi_icd.rsPlan(p_dbkey, i.vb_key, i.df_key, KBRSPLBLD_ORIGPIECE, 0); ELSE SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'no_read_lock'); END IF; dbms_ra_int.unlock(dbms_ra_int.KEY_DF, i.df_key); END LOOP; l_dflock := NULL; -- SELECT SUM(p.blksread) * AVG(f.block_size) INTO l_size FROM df f, vbdf v, plans p WHERE v.vb_key = piece.vb_key AND p.type = KBRSPLBLD_ORIGPIECE AND p.vb_key = piece.vb_key AND p.df_key = v.df_key AND f.dbinc_key = v.dbinc_key AND f.df_key = p.df_key; -- deb('repairChunks inspect piece: vbkey ' || piece.vb_key, AM_DEBUG_MED); sys.kbrsi_icd.rsInspectBackupPiece( handle => piece.filename, vbkey => piece.vb_key, bpsize => l_size, chktype => DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL, fno => null, lib_key => null, /* local disk file */ ct_key => null, bpkey => l_outbpkey, template_key => null); -- UPDATE vbdf SET vcbp_key = l_outbpkey WHERE vb_key = piece.vb_key; COMMIT; ELSE deb('repairChunks: no vcbp_key for vbkey ' || piece.vb_key || ' there are ' || l_numbadvb || ' obsolete df in piece', AM_DEBUG_MED); END IF; END LOOP; -- -- -- FOR piece IN (SELECT c.filename, v.vb_key, v.df_key, v.file#, v.dfbytes, v.ROWID FROM vbdf v, chunks c WHERE v.krbph_chunkno = c.chunkno AND v.krbph_dfkey = c.df_key AND state IN (VBDF_COMPLETE, VBDF_FIN_NOBP) AND incr_scn < KSCNINV AND db_key = p_dbkey AND NOT EXISTS (SELECT 1 FROM bp p, bdf d WHERE p.bs_key = d.bs_key AND p.vb_key = v.vb_key AND p.db_key = p_dbkey AND d.file# = v.file# AND incrLevel(d.create_scn, d.incr_scn) = 0)) LOOP -- IF dbms_ra_int.read_lock(dbms_ra_int.KEY_DF, piece.df_key) THEN l_dflock := piece.df_key; BEGIN sys.kbrsi_icd.rsPlan(p_dbkey, piece.vb_key, piece.df_key, KBRSPLBLD_PIECE, 0); EXCEPTION WHEN OTHERS THEN save_error; -- -- IF SQLCODE = dbms_ra_scheduler.e_corrupt_backup_num OR SQLCODE = dbms_ra_scheduler.e_backup_io_error_rman_num OR SQLCODE = dbms_ra_scheduler.e_error_id_file_num OR SQLCODE = dbms_ra_scheduler.e_corrupt_backuppiece_num OR SQLCODE = dbms_ra_int.bad_block_metadata_num THEN dbms_ra_scheduler.log_error ( p_errno => SQLCODE, p_component => 'REPAIR', p_severity => dbms_ra_scheduler.severity_error, p_db_key => p_dbkey); -- -- -- ELSE RAISE; END IF; clear_error; END; ELSE SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'no_read_lock2'); END IF; dbms_ra_int.unlock(dbms_ra_int.KEY_DF, piece.df_key); l_dflock := NULL; -- deb('repairChunks inspect piece: dfkey ' || piece.df_key || ', vbkey ' || piece.vb_key, AM_DEBUG_MED); sys.kbrsi_icd.rsInspectBackupPiece( handle => piece.filename, vbkey => piece.vb_key, bpsize => piece.dfbytes, chktype => DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL, fno => piece.file#, lib_key => null, /* local disk file */ ct_key => null, bpkey => l_outbpkey, template_key => null); END LOOP; -- -- -- -- FOR p IN (SELECT p.db_key, handle, sl_key, db_id, curr_dbinc_key, bp_key FROM bp p, db, odb WHERE p.db_key = db.db_key AND p.db_key = odb.db_key AND p.db_key = p_dbkey AND vb_key IN (SELECT MAX(vb_key) FROM vbdf WHERE db_key = p_dbkey GROUP BY df_key) AND EXISTS (SELECT 1 FROM bp p2 WHERE p.bs_key = p2.bs_key AND p2.vb_key IS NULL)) LOOP BEGIN sys.kbrsi_icd.validateTask(bpkey => p.bp_key); EXCEPTION WHEN dbms_ra_scheduler.E_CORRUPT_BACKUP THEN save_error; -- dbms_ra_storage.free_backup_piece_opt( p_dbkey => p.db_key, p_piecename => p.handle, p_db_slkey => p.sl_key, p_dbid => p.db_id, p_currinc => p.curr_dbinc_key, p_bpkey => p.bp_key, p_ftype => NULL, p_fincarn => NULL, p_libkey => NULL, p_spawn_job => FALSE, p_notasks => TRUE, p_noplans => TRUE); clear_error; END; END LOOP; -- IF debug = AM_DEBUG_HIGH THEN FOR x IN (SELECT * FROM vbdf ORDER BY df_key, vb_key) LOOP deb('vbdf df_key ' || x.df_key || ', vb_key ' || x.vb_key || ', ckp_scn ' || x.ckp_scn || ', dbinc_key ' || x.dbinc_key || ', state ' || x.state); END LOOP; END IF; EXCEPTION WHEN OTHERS THEN save_error; -- -- IF l_fixfin THEN UPDATE vbdf SET state = VBDF_REPAIR WHERE state = VBDF_FIN_NOBP AND db_key = p_dbkey; COMMIT; END IF; IF l_dflock IS NOT NULL THEN dbms_ra_int.unlock(dbms_ra_int.KEY_DF, l_dflock); END IF; RAISE; END repairChunks; /*---------------------------------------------------------------------------* * PRIVATE FUNCTIONS * *---------------------------------------------------------------------------*/ -- -- -- -- -- -- PROCEDURE deb(p_line IN varchar2, p_level IN NUMBER DEFAULT AM_DEBUG_ON) IS BEGIN IF debug >= p_level THEN -- -- -- sys.kbrsi_icd.rsTrace('RSPL: ' || p_line); END IF; END deb; -- -- -- -- -- -- PROCEDURE debugdf(p_dfkey IN NUMBER) IS BEGIN IF debug >= AM_DEBUG_HIGH THEN deb('DEBUGDF dfkey ' || p_dfkey); FOR f IN (SELECT bp_key, df_key, p.vb_key, dbinc_key, ckp_scn FROM bp p, vbdf v WHERE p.vb_key = v.vb_key AND p.db_key = v.db_key AND v.df_key = p_dfkey ORDER BY dbinc_key, p.vb_key, ckp_scn) LOOP deb('DEBUGDF dfkey ' || f.df_key || ', dbinc ' || f.dbinc_key || ', vbkey ' || f.vb_key || ', scn ' || f.ckp_scn || ', bpkey ' || f.bp_key); END LOOP; END IF; END debugdf; -- -- PROCEDURE save_error IS BEGIN dbms_ra_int.save_error_int; END save_error; -- -- PROCEDURE clear_error IS BEGIN dbms_ra_int.clear_error_int; END clear_error; -- -- -- -- -- FUNCTION print (p_value IN BOOLEAN) RETURN VARCHAR2 IS BEGIN IF p_value THEN RETURN 'TRUE'; ELSIF p_value IS NULL THEN RETURN 'NULL'; ELSE RETURN 'FALSE'; END IF; END print; -- -- -- -- -- PROCEDURE raise_bad_metadata(p_dfkey IN NUMBER) IS l_fno NUMBER; l_dbkey NUMBER; BEGIN -- -- SELECT MIN(db_key) INTO l_dbkey FROM dbinc i, df f WHERE i.dbinc_key = f.dbinc_key AND df_key = p_dfkey; -- SELECT max(file#) INTO l_fno FROM df WHERE df_key = p_dfkey; SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(dbms_ra_int.BAD_BLOCK_METADATA_NUM, dbms_ra_int.dbkey2name(l_dbkey), l_fno); END raise_bad_metadata; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE purge_lock(p_key IN NUMBER) IS l_hash NUMBER; l_count NUMBER; BEGIN -- SELECT ORA_HASH(p_key, 1023, 0) + 1 INTO l_hash FROM dual; dbms_ra_scheduler.get_lock(dbms_ra_scheduler.LOCK_PURGE, l_hash); -- -- SELECT MIN(task_id) INTO dbms_ra_scheduler.s_pending_interrupt FROM task WHERE task_type IN (dbms_ra_scheduler.TASK_PURGE_DF, dbms_ra_scheduler.TASK_PURGE_DF_NOW, dbms_ra_scheduler.TASK_PURGE_DUP_DF) AND param_num1 = p_key AND savepoint = RESTART_PURGE_DEL_BLOCKS AND task_id <> dbms_ra_scheduler.s_current_task; IF dbms_ra_scheduler.s_pending_interrupt IS NOT NULL THEN RAISE dbms_ra_scheduler.e_retry_error; END IF; END purge_lock; -- -- -- -- -- PROCEDURE purge_unlock(p_key IN NUMBER) IS l_hash NUMBER; BEGIN SELECT ORA_HASH(p_key, 1023, 0) + 1 INTO l_hash FROM dual; dbms_ra_scheduler.unlock(dbms_ra_scheduler.LOCK_PURGE, l_hash); END purge_unlock; -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE lock_vb(p_lock IN BOOLEAN, p_dbkey IN NUMBER, p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_qtype IN NUMBER) IS BEGIN -- FOR b IN (SELECT vb_key FROM vbdf WHERE db_key = p_dbkey AND df_key = p_dfkey AND krbph_dfkey = p_dfkey AND ckp_id IN (SELECT ckp_id FROM plans_details JOIN blocks USING (df_key, blockno, chunkno) WHERE df_key = p_dfkey AND vb_key = p_vbkey AND type = p_qtype AND blockno = 0 ) ) LOOP IF p_lock THEN IF NOT dbms_ra_int.read_lock(dbms_ra_int.KEY_VB, b.vb_key) THEN -- SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'lock_vb missing vbkey ' || b.vb_key); END IF; ELSE dbms_ra_int.unlock(dbms_ra_int.KEY_VB, b.vb_key); END IF; END LOOP; END lock_vb; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE working_ckpid(p_dbkey IN NUMBER, p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_orphans IN BOOLEAN, -- orphan backups p_dbinckey IN OUT NUMBER, -- in backup dbinc p_ckpid IN OUT NUMBER, -- in backup ckpid p_deadinc OUT NUMBER, -- orphan inc we no need p_orphaninc OUT NUMBER) -- orphan blocks inc IS l_vbkey NUMBER; l_dbinckey NUMBER; l_ckpscn NUMBER; l_minvbkey NUMBER; l_ok NUMBER; BEGIN p_deadinc := 0; /* zero better than null for later comparisons */ p_orphaninc := p_dbinckey; /* makes other algorithms work. */ -- IF NOT p_orphans THEN SELECT NVL(MAX(ckp_id), p_ckpid) INTO p_ckpid FROM vbdf WHERE df_key = p_dfkey AND state = VBDF_COMPLETE; RETURN; -- ELSE -- -- -- -- -- -- -- l_dbinckey := NULL; FOR b IN (SELECT vb_key, ckp_scn, reset_scn, dbinc_key, parent_dbinc_key FROM vbdf JOIN dbinc USING (db_key, dbinc_key) WHERE df_key = p_dfkey ORDER BY vb_key) LOOP -- -- -- -- l_ok := 1; IF NOT (b.dbinc_key = l_dbinckey OR (b.parent_dbinc_key = l_dbinckey AND b.reset_scn > l_ckpscn)) THEN -- -- SELECT COUNT(*) INTO l_ok FROM vbdf v, (SELECT dbinc_key, reset_scn, NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = b.dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key ) i WHERE v.df_key = p_dfkey AND v.dbinc_key = i.dbinc_key AND v.ckp_scn < i.next_reset_scn AND v.state != VBDF_OBSOLETE AND v.vb_key = l_vbkey; END IF; -- IF b.ckp_scn < l_ckpscn THEN l_ok := 0; END IF; -- EXIT WHEN l_ok = 0; -- l_dbinckey := b.dbinc_key; l_vbkey := b.vb_key; l_ckpscn := b.ckp_scn; END LOOP; p_orphaninc := l_dbinckey; -- IF l_ok > 0 THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'bad orphan compute'); END IF; -- -- -- IF p_vbkey >= l_vbkey THEN -- -- -- SELECT vb_key INTO l_minvbkey FROM vbdf WHERE df_key = p_dfkey AND ckp_id = (SELECT min_id FROM vbdf WHERE df_key = p_dfkey AND vb_key = p_vbkey ); IF l_minvbkey > l_vbkey THEN p_deadinc := p_orphaninc; END IF; RETURN; END IF; -- -- p_ckpid := BIGNUM; p_dbinckey := p_orphaninc; END IF; END working_ckpid; -- -- -- -- -- -- -- -- -- PROCEDURE alloc_plan(p_dbkey IN NUMBER, p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_qtype IN NUMBER) IS l_task NUMBER := NULL; BEGIN -- -- IF dbms_ra_scheduler.s_current_task_type NOT IN (dbms_ra_scheduler.TASK_INDEX_BACKUP, dbms_ra_scheduler.TASK_PLAN_DF, dbms_ra_scheduler.TASK_PLAN_SBT) THEN l_task := dbms_ra_scheduler.s_current_task; END IF; -- -- -- INSERT INTO plans (type, db_key, vb_key, df_key, task_id) VALUES (p_qtype, p_dbkey, p_vbkey, p_dfkey, l_task); COMMIT; -- deb('alloc_plan: type ' || p_qtype || ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey, AM_DEBUG_LOW); END alloc_plan; -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE dealloc_plan(p_dfkey IN NUMBER, p_vbkey IN NUMBER DEFAULT NULL, p_qtype IN NUMBER DEFAULT NULL, p_lock IN BOOLEAN DEFAULT TRUE) IS l_count NUMBER; l_task NUMBER := NULL; l_locked BOOLEAN := FALSE; l_didit BOOLEAN := FALSE; BEGIN -- IF NOT p_lock THEN l_locked := TRUE; END IF; -- -- -- FOR x IN (SELECT df_key, vb_key, type FROM plans WHERE df_key = p_dfkey AND ((type = p_qtype AND vb_key = p_vbkey) OR (type = p_qtype AND p_vbkey IS NULL) OR old = 1) ORDER BY type) -- purge plans first LOOP l_didit := TRUE; -- IF NOT l_locked AND x.type IN (KBRSPLBLD_ORIGPIECE, KBRSPLBLD_PIECE) THEN BEGIN dbms_ra_int.write_lock(dbms_ra_int.KEY_DF, p_dfkey); l_locked := TRUE; EXCEPTION WHEN dbms_ra_scheduler.e_retry_error THEN save_error; l_locked := FALSE; clear_error; END; END IF; -- IF l_locked OR x.type NOT IN (KBRSPLBLD_ORIGPIECE, KBRSPLBLD_PIECE) THEN DELETE FROM plans_details WHERE df_key = x.df_key AND vb_key = x.vb_key AND type = x.type; DELETE FROM plans WHERE df_key = x.df_key AND vb_key = x.vb_key AND type = x.type; l_count := SQL%ROWCOUNT; COMMIT; deb('dealloc_plan: type ' || x.type || ', dfkey ' || x.df_key || ', vbkey ' || x.vb_key || ', deleted ' || l_count, AM_DEBUG_LOW); -- ELSE UPDATE plans SET old = 1 WHERE df_key = x.df_key AND vb_key = x.vb_key AND type = x.type; l_count := SQL%ROWCOUNT; COMMIT; deb('dealloc_plan: type ' || x.type || ', dfkey ' || x.df_key || ', vbkey ' || x.vb_key || ', olded ' || l_count, AM_DEBUG_LOW); END IF; END LOOP; -- IF l_locked AND p_lock THEN dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey); END IF; -- IF NOT l_didit THEN deb('dealloc_plan: type ' || p_qtype || ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey || ', nothing found', AM_DEBUG_LOW); END IF; EXCEPTION WHEN OTHERS THEN save_error; -- IF l_locked AND p_lock THEN dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey); END IF; RAISE; END dealloc_plan; -- -- -- -- -- -- -- PROCEDURE trim_plan(p_dfkey IN NUMBER) IS l_plans_maintained NUMBER := dbms_ra_scheduler.s_plans_maintained; l_loopcnt NUMBER := 0; l_count NUMBER; BEGIN deb('trim_plan dfkey ' || p_dfkey, AM_DEBUG_LOW); -- FOR x IN (SELECT vb_key, old, type FROM plans p WHERE df_key = p_dfkey AND type IN (KBRSPLBLD_PIECE, KBRSPLBLD_ORIGPIECE) ORDER BY type ASC, vb_key DESC) LOOP IF l_loopcnt >= l_plans_maintained /* keep this many plans */ OR x.old = 1 /* plan is already old */ THEN -- -- SELECT COUNT(*) INTO l_count FROM (SELECT MIN(df_key) mindf, MAX(df_key) maxdf FROM sbt_task JOIN bp USING (bs_key) JOIN bdf USING (bs_key) JOIN df USING (dbinc_key, create_scn, file#) WHERE vb_key = x.vb_key GROUP BY bs_key, df_key ) WHERE mindf = p_dfkey AND mindf = maxdf AND ROWNUM = 1; IF l_count = 0 THEN dealloc_plan(p_dfkey, x.vb_key, x.type); END IF; END IF; l_loopcnt := l_loopcnt + 1; END LOOP; END trim_plan; -- -- -- -- -- -- -- -- -- -- -- FUNCTION fragmentation(p_dbkey IN NUMBER, p_dfkey IN NUMBER, p_vbkey IN NUMBER) RETURN NUMBER IS l_frag NUMBER := NULL; l_cklst NOLST; l_size NUMBER := 0; l_chunksize NUMBER := f_chunksize(p_dbkey); l_curfrag NUMBER := dbms_ra_scheduler.s_fragmentation; j NUMBER; BEGIN deb('fragmentation dfkey ' || p_dfkey || ', vbkey ' || p_vbkey); FOR i IN (SELECT chunkno, numbytes FROM plans_details WHERE type = KBRSPLBLD_PIECE AND df_key = p_dfkey AND vb_key = p_vbkey AND numbytes > 0 AND blockno > 1 ORDER BY blockno) LOOP -- j := 0; WHILE (j < l_cklst.COUNT AND l_cklst(j) <> i.chunkno) LOOP j := j + 1; END LOOP; -- IF j >= l_cklst.COUNT THEN l_cklst(j) := i.chunkno; -- IF j > l_curfrag THEN deb('fragmentation fragged dfkey ' || p_dfkey || ', chunk ' || i.chunkno || ', count ' || l_cklst.COUNT, AM_DEBUG_MED); RETURN j; END IF; END IF; -- l_size := l_size + i.numbytes; IF l_size > l_chunksize THEN l_frag := GREATEST(l_cklst.COUNT, NVL(l_frag, 0)); l_size := 0; l_cklst.DELETE; END IF; END LOOP; -- IF l_frag IS NULL AND l_size > 0 THEN l_frag := 1; END IF; RETURN l_frag; END fragmentation; -- -- -- -- -- -- PROCEDURE show_plan(p_vbkey IN NUMBER, -- Virtual backup id p_dfkey IN NUMBER, -- Datafile key p_krbph_dfkey IN NUMBER, -- Datafile key for krbph p_qtype IN NUMBER) -- KBRSPLBLD_ type stored in plan IS BEGIN IF debug <> AM_DEBUG_HIGH THEN RETURN; END IF; deb('show_plan: qtype ' || p_qtype); -- FOR x IN (SELECT dbinc_key, vb_key, ckp_id, min_id, incr_scn, ckp_scn, state FROM vbdf WHERE df_key = p_dfkey ORDER BY vb_key) LOOP deb('vbkey ' || x.vb_key || ', dbinc ' || x.dbinc_key || ', incrscn ' || x.incr_scn || ', ckpscn ' || x.ckp_scn || ', minid ' || x.min_id || ', cpi ' || x.ckp_id || ', state ' || x.state); END LOOP; -- FOR x IN (SELECT dbinc_key, parent_dbinc_key, reset_scn FROM dbinc WHERE db_key = (SELECT MAX(db_key) FROM vbdf WHERE df_key = p_dfkey) ORDER BY reset_time) LOOP deb('dbinc ' || x.dbinc_key || ', parent ' || x.parent_dbinc_key || ', reset_scn ' || x.reset_scn); END LOOP; -- -- -- -- IF p_dfkey <> p_krbph_dfkey THEN FOR x IN (SELECT /*+ LEADING(p) USE_HASH(b) */ b.blockno, b.ckp_id, b.scn, p_krbph_dfkey dfkey, b.chunkno, b.coffset, p.blkrank FROM blocks b, plans_details p WHERE b.df_key = p_krbph_dfkey AND b.blockno = 0 AND b.chunkno = p.chunkno AND b.coffset = p.coffset AND p.blockno = 0 AND p.df_key = p_dfkey AND p.type = p_qtype AND p.vb_key = p_vbkey) LOOP deb('plan bno ' || x.blockno || ', scn ' || x.scn || ', dfkey ' || x.dfkey || ', chunk ' || x.chunkno || ', cpi ' || x.ckp_id || ', o' || x.coffset); END LOOP; END IF; -- -- FOR x IN (SELECT /*+ LEADING(p) USE_HASH(b) */ DECODE(MIN(b.blockno), 1, BIGNUM, MIN(b.blockno)) blockno, b.ckp_id, b.scn, p_dfkey dfkey, b.chunkno, b.coffset, b.used, NULLIF(MAX(b.blockno), MIN(b.blockno)) endblk, p.blkrank FROM blocks b, plans_details p WHERE b.df_key = p_dfkey AND b.chunkno = p.chunkno AND b.coffset BETWEEN p.coffset AND (p.coffset + greatest(p.numbytes-1, 0)) AND p.blockno > DECODE(p_qtype, KBRSPLBLD_PIECE, 0, -1) AND p.df_key = p_dfkey AND p.type = p_qtype AND p.vb_key = p_vbkey GROUP BY b.df_key, p.blkrank, b.ckp_id, b.scn, b.used, b.chunkno, b.coffset ORDER BY blkrank, blockno) LOOP deb('plan bno ' || x.blockno || ', scn ' || x.scn || ', dfkey ' || x.dfkey || ', chunk ' || x.chunkno || ', cpi ' || x.ckp_id || ', o' || x.coffset || ', s' || x.used || ' -- ' || x.endblk); END LOOP; END show_plan; -- -- -- -- -- -- -- PROCEDURE plan_blocks(p_vbkey IN NUMBER, -- Virtual backup id p_dfkey IN NUMBER, -- Datafile key p_chunksize IN NUMBER, -- size of chunk p_bufsize IN NUMBER, -- size of read buffers p_blksize IN NUMBER, -- size of each block p_type IN NUMBER, -- KBRSPLBLD_ type p_totalsize OUT NUMBER, -- backup size of df p_totalblocks OUT NUMBER, -- blocks in datafile p_totalchunks OUT NUMBER, -- distinct chunks in plan p_signature OUT NUMBER, -- signature 4 restore p_maxrank OUT NUMBER) -- block ranking in plan IS l_fno NUMBER; -- file# l_relfno NUMBER; -- relative file# l_issft NUMBER; -- is Single File Tablespace l_krbph_dfkey NUMBER; -- df_key for block 0 data l_dbkey NUMBER; l_qtype NUMBER; l_count NUMBER; BEGIN deb('plan_blocks: type ' || p_type || ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey || ' At ' || TO_CHAR(SYSDATE, 'HH24:MI:SS'), AM_DEBUG_MED); dbms_ra_int.info_start('plan_blocks', 'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey); IF p_type IN (KBRSPLBLD_OPTPURGE, KBRSPLBLD_ALLPURGE, KBRSPLBLD_SMALLPURGE, KBRSPLBLD_DUPPURGE) THEN l_qtype := KBRSPLBLD_PURGE; ELSE l_qtype := p_type; END IF; -- BEGIN SELECT f.file#, v.relfno, f.issft, v.krbph_dfkey, db_key INTO l_fno, l_relfno, l_issft, l_krbph_dfkey, l_dbkey FROM df f, vbdf v WHERE v.vb_key = p_vbkey AND v.df_key = p_dfkey AND f.dbinc_key = v.dbinc_key AND f.df_key = p_dfkey; EXCEPTION WHEN no_data_found THEN save_error; RAISE dbms_ra_scheduler.e_retry_error; WHEN OTHERS THEN save_error; RAISE; END; -- IF p_type IN (KBRSPLBLD_PIECE, KBRSPLBLD_ORIGPIECE, KBRSPLBLD_OPTIMIZE) THEN restore_plan_blocks(p_type, p_dfkey, p_vbkey, p_blksize); ELSE -- old_chunks(p_type, p_dfkey, p_vbkey); -- IF p_type <> KBRSPLBLD_ALLPURGE THEN SELECT COUNT(*) INTO l_count FROM bp WHERE vb_key = p_vbkey; IF l_count = 0 THEN /* just give up */ RAISE dbms_ra_scheduler.e_retry_error; END IF; END IF; END IF; IF p_type <> KBRSPLBLD_ALLPURGE THEN -- SELECT NVL(SUM(case numbytes when 0 then MBLK_SIZE else numbytes end), 0), NVL(SUM(case numbytes when 0 then 1 else numblks end), 0), NVL(SUM(signature), 0), COUNT(DISTINCT chunkno), MAX(blkrank) INTO p_totalsize, p_totalblocks, p_signature, p_totalchunks, p_maxrank FROM plans_details WHERE df_key = p_dfkey AND type = l_qtype AND vb_key = p_vbkey AND blockno >= 0; IF p_totalsize = 0 AND l_qtype = KBRSPLBLD_PURGE THEN p_totalsize := p_totalsize + p_totalblocks; /* ensure we count gaps */ END IF; -- UPDATE plans_details SET blockno = DBMS_RA_INT.UB4MAXVAL WHERE df_key = p_dfkey AND type = l_qtype AND vb_key = p_vbkey AND blockno = 1; -- -- IF SQL%ROWCOUNT = 0 AND p_type IN (KBRSPLBLD_PIECE, KBRSPLBLD_ORIGPIECE) THEN deb('plan_blocks missing block 1 - type ' || p_type || ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey, AM_DEBUG_ON); raise_bad_metadata(p_dfkey); END IF; ELSE p_totalsize := 0; p_totalblocks := 0; p_signature := 0; p_totalchunks := 0; deb('plan_blocks: deleting chunks', AM_DEBUG_HIGH); END IF; -- -- -- IF debug = AM_DEBUG_HIGH AND p_type <> KBRSPLBLD_ALLPURGE THEN show_plan(p_vbkey, p_dfkey, l_krbph_dfkey, l_qtype); deb('plan_blocks - type ' || p_type || ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey|| ' Done ' || TO_CHAR(SYSDATE, 'YYYY/MM/DD HH24:MI:SS')); END IF; dbms_ra_int.info_end; END plan_blocks; -- -- -- -- -- -- -- PROCEDURE restore_plan_blocks(p_type IN NUMBER, -- KBRSPLBLD_ type p_dfkey IN NUMBER, -- Datafile key p_vbkey IN NUMBER, -- Virtual backup id p_blksize IN NUMBER) -- size of each block IS l_dbkey NUMBER; l_pdbinc_key NUMBER; l_dbinckey NUMBER; l_deadinc NUMBER; l_orphaninc NUMBER; l_blocks NUMBER; l_firstblk NUMBER; l_lastblk NUMBER; l_ckpscn NUMBER; l_absscn NUMBER; l_minckpid NUMBER; l_maxckpid NUMBER; l_ckpid NUMBER; l_incrscn NUMBER; l_orphans BOOLEAN; l_maxorphscn NUMBER; l_tmp NUMBER; BEGIN -- SELECT i.dbinc_key, v.blocks, v.firstblk, v.lastblk, v.abs_scn, v.ckp_scn, v.ckp_id, v.pdbinc_key, v.db_key, (CASE p_type WHEN KBRSPLBLD_OPTIMIZE THEN 0 WHEN KBRSPLBLD_PIECE THEN 0 WHEN KBRSPLBLD_ORIGPIECE THEN v.incr_scn ELSE KSCNINV END) incrscn, (CASE p_type WHEN KBRSPLBLD_OPTIMIZE THEN v.min_id WHEN KBRSPLBLD_PIECE THEN v.min_id WHEN KBRSPLBLD_ORIGPIECE THEN v.ckp_id ELSE KSCNINV END) minckpid INTO l_dbinckey, l_blocks, l_firstblk, l_lastblk, l_absscn, l_ckpscn, l_ckpid, l_pdbinc_key, l_dbkey, l_incrscn, l_minckpid FROM vbdf v, dbinc i WHERE v.vb_key = p_vbkey AND v.df_key = p_dfkey AND v.dbinc_key = i.dbinc_key; -- -- IF (l_firstblk = 2 AND l_lastblk = l_blocks) THEN l_firstblk := 1; END IF; -- l_orphans := orphans(l_dbkey, p_dfkey); -- l_maxckpid := l_ckpid; working_ckpid(l_dbkey, p_dfkey, p_vbkey, l_orphans, l_dbinckey, l_maxckpid, l_deadinc, l_orphaninc); -- -- IF dbms_ra_scheduler.s_current_task_type IN (dbms_ra_scheduler.TASK_INDEX_BACKUP, dbms_ra_scheduler.TASK_REPAIR_DB) THEN l_maxckpid := BIGNUM; END IF; deb('plan: dbinc ' || l_dbinckey || ', pdbinc ' || l_pdbinc_key || ', dfkey ' || p_dfkey || ', ckp_id ' || l_ckpid || ', minckpid ' || l_minckpid || ', maxckpid ' || l_maxckpid, AM_DEBUG_MED); deb('plan: blksize ' || p_blksize || ', firstblk ' || l_firstblk || ', lastblk ' || l_lastblk, AM_DEBUG_MED); -- IF l_orphans THEN -- -- -- -- -- -- -- -- orphan_common(l_dbinckey, l_orphaninc, p_dfkey, l_tmp, l_maxorphscn); IF l_pdbinc_key = 0 THEN q_restore_incs(p_type, p_dfkey, p_vbkey, l_incrscn, l_ckpscn, l_absscn, l_ckpid, l_minckpid, l_maxckpid, l_dbinckey, l_deadinc, l_orphaninc, l_maxorphscn, l_firstblk, l_lastblk); ELSE q_restore_cdb(p_type, p_dfkey, p_vbkey, l_incrscn, l_ckpscn, l_absscn, l_ckpid, l_minckpid, l_maxckpid, l_pdbinc_key, l_dbinckey, l_deadinc, l_orphaninc, l_maxorphscn, l_firstblk, l_lastblk, l_orphans); END IF; ELSE IF l_pdbinc_key = 0 THEN q_restore_fast(p_type, p_dfkey, p_vbkey, l_incrscn, l_ckpscn, l_absscn, l_ckpid, l_minckpid, l_maxckpid, l_dbinckey, l_firstblk, l_lastblk); ELSE q_restore_cdb(p_type, p_dfkey, p_vbkey, l_incrscn, l_ckpscn, l_absscn, l_ckpid, l_minckpid, l_maxckpid, l_pdbinc_key, l_dbinckey, 0,0,0, l_firstblk, l_lastblk, l_orphans); END IF; END IF; -- -- IF (l_firstblk > 1) THEN INSERT INTO plans_details (df_key, type, vb_key, blkrank, blockno, chunkno, numblks, coffset, numbytes, signature) (SELECT * FROM (SELECT /*+ INDEX(b) NO_INDEX_FFS(b) */ p_dfkey, p_type, p_vbkey, 1 blkrank, 1 blockno, chunkno, 1 numblks, coffset, used numbytes, scn signature FROM blocks b WHERE b.df_key = p_dfkey AND b.blockno = 1 AND b.ckp_id = l_ckpid ORDER BY chunkno DESC ) WHERE ROWNUM = 1 ); IF SQL%ROWCOUNT = 0 THEN deb('restore_plan_blocks: missing block 1' || ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey || ', ckp_id ' || l_ckpid, AM_DEBUG_ON); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'missing block 1' || ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey || ', ckp_id ' || l_ckpid); END IF; END IF; -- -- -- -- -- INSERT INTO plans_details (df_key, type, vb_key, blkrank, blockno, chunkno, numblks, coffset, numbytes, signature) (SELECT /*+ LEADING(v) USE_NL(b) INDEX(b) NO_INDEX_FFS(b) OPT_PARAM('optimizer_dynamic_sampling' 0) OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false') OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none') OPT_PARAM('_optimizer_use_feedback' 'false') NO_EXPAND */ p_dfkey, p_type, p_vbkey, 1 blkrank, 0 blockno, chunkno, 1 numblks, /* only count 1, kbrspl.c expects that */ p_blksize coffset, used numbytes, 0 signature /* other check avoids block 0, do not add here */ FROM blocks b, vbdf v WHERE v.vb_key = p_vbkey AND b.df_key = v.df_key AND b.chunkno = v.krbph_chunkno AND b.df_key = v.krbph_dfkey AND b.blockno = 0 AND (p_type = KBRSPLBLD_PIECE OR /* chunk can be from any df */ (p_type = KBRSPLBLD_ORIGPIECE AND b.df_key = p_dfkey))); IF SQL%ROWCOUNT = 0 AND p_type = KBRSPLBLD_PIECE THEN deb('restore_plan_blocks: missing block 0' || ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey || ', ckp_id ' || l_ckpid, AM_DEBUG_ON); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'missing block 0' || ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey || ', ckp_id ' || l_ckpid); END IF; END restore_plan_blocks; -- -- -- -- -- -- PROCEDURE old_chunks(p_type IN NUMBER, p_dfkey IN NUMBER, p_vbkey IN NUMBER) IS l_currinc NUMBER; l_dbinc NUMBER; l_ckpscn NUMBER; l_absscn NUMBER; l_ckpid NUMBER; l_minckpid NUMBER; l_maxckpid NUMBER; l_orphaninc NUMBER; l_deadinc NUMBER; l_fuzdif NUMBER; l_minscn NUMBER; l_dbkey NUMBER; l_vbkey NUMBER; l_chunksize NUMBER; l_maxrank NUMBER; l_rank NUMBER; l_size NUMBER; l_lastblk NUMBER; l_sumbytes NUMBER; BEGIN deb('old_chunks: type ' || p_type || ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey, AM_DEBUG_MED); -- SELECT db_key, dbinc_key, ckp_scn, abs_scn, ckp_id, min_id INTO l_dbkey, l_dbinc, l_ckpscn, l_absscn, l_ckpid, l_minckpid FROM vbdf WHERE df_key = p_dfkey AND vb_key = p_vbkey; -- -- -- -- -- -- -- IF p_type = KBRSPLBLD_DUPPURGE THEN SELECT MAX(ckp_id - ckp_scn), MIN(ckp_scn) INTO l_fuzdif, l_minscn FROM vbdf WHERE df_key = p_dfkey AND state = VBDF_COMPLETE; END IF; -- CASE p_type WHEN KBRSPLBLD_ALLPURGE /* Remove all blocks */ THEN q_purge_all(p_dfkey, p_vbkey, l_dbkey); -- UPDATE vbdf SET state = VBDF_ABORT WHERE df_key = p_dfkey AND state IN (VBDF_BUILDING, VBDF_FIN_NOBP); COMMIT; -- SELECT MAX(vb_key) INTO l_vbkey FROM vbdf WHERE df_key = p_dfkey -- AND state IN (VBDF_COMPLETE, VBDF_OBSOLETE); IF l_vbkey != p_vbkey THEN RAISE dbms_ra_scheduler.e_retry_error; END IF; WHEN KBRSPLBLD_DUPPURGE /* Remove duplicate blocks */ THEN q_purge_dup(p_type, p_dfkey, p_vbkey, l_dbkey, l_dbinc, l_fuzdif, l_minscn); ELSE -- -- -- -- SELECT dbinc_key INTO l_currinc FROM (SELECT dbinc_key FROM vbdf WHERE df_key = p_dfkey ORDER BY vb_key DESC ) WHERE ROWNUM = 1; -- IF orphans(l_dbkey, p_dfkey, l_currinc) THEN -- IF orphan_bp(l_dbkey, p_dfkey, l_currinc) THEN deb('old_chunks: had to kill plan', AM_DEBUG_HIGH); RETURN; END IF; -- l_maxckpid := l_ckpid; working_ckpid(l_dbkey, p_dfkey, p_vbkey, TRUE, l_dbinc, l_maxckpid, l_deadinc, l_orphaninc); -- q_purge_orphan(p_type, l_dbkey, p_dfkey, p_vbkey, l_ckpscn, l_absscn, l_ckpid, l_minckpid, l_maxckpid, l_dbinc, l_deadinc, l_orphaninc); ELSE q_purge_basic(p_type, p_dfkey, p_vbkey, l_dbkey, l_dbinc, l_ckpscn, l_absscn, l_ckpid, l_minckpid); END IF; END CASE; -- -- -- -- IF p_type <> KBRSPLBLD_ALLPURGE THEN SELECT MAX(blkrank), MAX(numbytes) INTO l_maxrank, l_size FROM plans_details WHERE df_key = p_dfkey AND type = KBRSPLBLD_PURGE AND vb_key = p_vbkey AND blockno = 0; -- -- -- -- l_rank := 2; l_sumbytes := 0; l_lastblk := -1; l_chunksize := f_chunksize(l_dbkey) - l_size; FOR i IN (SELECT blockno, numbytes FROM plans_details WHERE df_key = p_dfkey AND type = KBRSPLBLD_PURGE AND vb_key = l_vbkey AND blockno > 0 ORDER BY blkrank, blockno) LOOP IF l_sumbytes + i.numbytes > l_chunksize THEN IF l_lastblk < i.blockno - 1 THEN -- Cannot have dup blockno UPDATE plans_details SET blockno = i.blockno - 1 WHERE df_key = p_dfkey AND type = KBRSPLBLD_PURGE AND vb_key = l_vbkey AND blkrank = l_rank AND blockno = 0; EXIT WHEN SQL%ROWCOUNT = 0 OR l_rank = l_maxrank; l_rank := l_rank + 1; END IF; l_sumbytes := 0; END IF; l_lastblk := i.blockno; l_sumbytes := l_sumbytes + i.numbytes; END LOOP; COMMIT; END IF; dbms_ra_scheduler.check_for_interrupt; END old_chunks; -- -- -- -- -- -- -- PROCEDURE restricted_purge(p_dfkey IN NUMBER, -- Datafile key p_vbkey IN NUMBER, -- Virtual backup id p_type IN NUMBER, -- plan type p_dbkey IN NUMBER, p_chunks IN NUMBER) IS l_sum NUMBER := 0; l_count NUMBER := 0; l_avail NUMBER := (f_chunksize(p_dbkey) * p_chunks) - (f_chunksize(p_dbkey) * 0.15); /* do not fill last chunk */ BEGIN -- DELETE FROM plans_details WHERE chunkno IN (SELECT chunkno FROM plans_details WHERE blkrank > 1 AND blockno = 0); -- -- -- FOR i IN (SELECT chunkno, SUM(numbytes) used FROM plans_details WHERE df_key = p_dfkey AND type = p_type AND vb_key = p_vbkey AND blockno >= 0 GROUP BY chunkno ORDER BY used DESC) LOOP EXIT WHEN l_sum + i.used > l_avail; l_count := l_count + 1; l_sum := l_sum + i.used; END LOOP; -- -- DELETE FROM plans_details WHERE chunkno NOT IN (SELECT chunkno FROM (SELECT chunkno, SUM(numbytes) used FROM plans_details WHERE df_key = p_dfkey AND type = p_type AND vb_key = p_vbkey AND blockno >= 0 GROUP BY chunkno ORDER BY used DESC) WHERE ROWNUM < l_count) AND df_key = p_dfkey AND type = p_type AND vb_key = p_vbkey AND blockno >= 0; END restricted_purge; -- -- -- -- -- -- PROCEDURE optimize_blocks(p_dfkey IN NUMBER, p_vbkey IN NUMBER, -- Virtual backup id p_type IN NUMBER, -- plan type p_stored OUT NUMBER, p_needs OUT NUMBER) IS l_size NUMBER; l_chunk NUMBER; l_count NUMBER; l_krbphs NUMBER; l_dbkey NUMBER; BEGIN -- deb('optimize_blocks for df_key ' || p_dfkey, AM_DEBUG_MED); -- SELECT MAX(db_key) INTO l_dbkey FROM dbinc i, df f WHERE f.dbinc_key = i.dbinc_key AND f.df_key = p_dfkey; -- l_size := f_chunksize(l_dbkey) * 0.80; DELETE ( SELECT /*+ QB_NAME(pd) USE_HASH(pdc@pdc) LEADING(@pd pd@pd) OPT_PARAM('optimizer_dynamic_sampling' 0) OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false') OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none') OPT_PARAM('_optimizer_use_feedback' 'false') */ pd.ROWID FROM plans_details pd , ( SELECT /*+ QB_NAME(pdc) */ chunkno FROM plans_details pdc WHERE df_key = p_dfkey AND type = p_type AND vb_key = p_vbkey AND blockno >= 0 GROUP BY chunkno HAVING SUM(numbytes) > l_size ) pdc WHERE pd.df_key = p_dfkey AND pd.type = p_type AND pd.vb_key = p_vbkey AND pd.blockno >= 0 AND pd.chunkno = pdc.chunkno ); deb('optimize_blocks deleted ' || SQL%ROWCOUNT); -- SELECT COUNT(DISTINCT chunkno) INTO l_count FROM plans_details WHERE df_key = p_dfkey AND type = p_type AND vb_key = p_vbkey; deb('optimize_blocks reading ' || l_count || ' chunks', AM_DEBUG_MED); IF l_count < 2 THEN p_needs := 0; p_stored := 0; ELSE p_needs := l_count; p_stored := 1; END IF; END optimize_blocks; -- -- -- -- -- -- -- PROCEDURE purge_pool(p_dbkey IN NUMBER, p_type IN NUMBER, p_qtype IN NUMBER, p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_dflocked IN BOOLEAN DEFAULT FALSE) IS -- CURSOR debugc (c_type IN NUMBER, c_dfkey IN NUMBER, c_vbkey IN NUMBER) IS SELECT /*+ QB_NAME(m) OPT_PARAM('optimizer_adaptive_plans' 'false') OPT_PARAM('optimizer_dynamic_sampling' 0) USE_HASH(@m b@m) LEADING(@m d@m b@m) INDEX(@m b@m blocks_u) */ b.blockno, b.scn, b.chunkno FROM blocks b , ( SELECT /*+ NO_MERGE */ DISTINCT chunkno FROM plans_details WHERE type = c_type AND vb_key = c_vbkey AND df_key = c_dfkey ) d WHERE b.df_key = c_dfkey AND d.chunkno = b.chunkno ORDER BY b.blockno, b.scn, b.chunkno; CURSOR delete_chunks(c_slkey IN NUMBER) IS SELECT chunkno, filename FROM chunks JOIN (SELECT DISTINCT df_key, chunkno FROM plans_details WHERE type = p_qtype AND df_key = p_dfkey AND vb_key = p_vbkey ) USING (df_key, chunkno) WHERE df_key = p_dfkey AND sl_key = c_slkey ORDER BY chunkno; l_chunknolst dbms_sql.number_table; l_chunknamlst dbms_sql.varchar2_table; l_count NUMBER; l_dflocked BOOLEAN := FALSE; -- -- -- TYPE chunkptr_t IS TABLE OF BINARY_INTEGER; l_chunknoptr chunkptr_t := chunkptr_t(); l_ptrfound BINARY_INTEGER; BEGIN deb('purge_pool: dbkey ' || p_dbkey || ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey, AM_DEBUG_MED); -- IF debug = AM_DEBUG_HIGH THEN FOR x IN debugc(p_qtype, p_dfkey, p_vbkey) LOOP deb('purge_pool bno ' || x.blockno || ', scn ' || x.scn || ', dfkey ' || p_dfkey || ', chunk ' || x.chunkno, AM_DEBUG_HIGH); END LOOP; END IF; -- -- IF p_type = KBRSPLBLD_ALLPURGE THEN -- -- SELECT count(*) INTO l_count FROM vbdf v, bp p, bdf d WHERE v.df_key = p_dfkey AND v.vb_key = p.vb_key AND v.db_key = p.db_key AND p.status != 'D' AND d.bs_key = p.bs_key AND d.file# = v.file# AND d.ckp_scn = v.ckp_scn AND d.dbinc_key = v.dbinc_key; -- IF l_count > 0 THEN deb('purge_pool: Live BP during all purge on vbkey ' || p_vbkey, AM_DEBUG_LOW); RETURN; END IF; END IF; -- -- -- IF NOT p_dflocked THEN dbms_ra_int.write_lock(dbms_ra_int.KEY_DF, p_dfkey); l_dflocked := TRUE; END IF; -- -- dbms_ra_scheduler.check_for_interrupt(RESTART_PURGE_DEL_BLOCKS); dbms_ra_int.info_start('purge_pool ', 'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey); -- -- FOR s IN (SELECT sl_key FROM odb WHERE db_key = p_dbkey UNION ALL SELECT sl_key FROM dbsl WHERE db_key = p_dbkey) LOOP OPEN delete_chunks(s.sl_key); LOOP FETCH delete_chunks BULK COLLECT INTO l_chunknolst, l_chunknamlst LIMIT MAXDELCHUNKS; EXIT WHEN l_chunknolst.COUNT = 0; -- -- -- -- -- -- -- -- -- -- -- -- -- l_chunknoptr.EXTEND(l_chunknolst.COUNT); FOR i IN 1..l_chunknolst.COUNT LOOP l_chunknoptr(i) := i; END LOOP; WHILE (l_chunknoptr.COUNT > 0) LOOP l_count := CEIL(TOTBLKPRCHNKS / l_chunknoptr.COUNT); deb( 'purge_pool: dfkey ' || p_dfkey || ', deleting ' || l_count || ' rows per chunk, for ' || l_chunknoptr.COUNT || ' chunks' , AM_DEBUG_MED ); FORALL i IN VALUES OF l_chunknoptr DELETE /*+ DYNAMIC_SAMPLING(b 0) INDEX(b blocks_c) NO_INDEX_FFS(b) */ blocks b WHERE df_key = p_dfkey AND chunkno = l_chunknolst(i) AND ROWNUM <= l_count; l_ptrfound := 0; FOR i IN 1..l_chunknoptr.COUNT LOOP -- -- -- -- -- IF (SQL%BULK_ROWCOUNT(l_chunknoptr(i)) = l_count) THEN l_ptrfound := l_ptrfound + 1; l_chunknoptr(l_ptrfound) := l_chunknoptr(i); END IF; END LOOP; COMMIT; l_chunknoptr.TRIM(l_chunknoptr.COUNT - l_ptrfound); END LOOP; -- FOR i IN 1 .. l_chunknolst.COUNT LOOP deb('purge_pool: dfkey ' || p_dfkey || ', chunk ' || l_chunknolst(i), AM_DEBUG_MED); IF l_chunknamlst(i) IS NOT NULL THEN SYS.KBRSI_ICD.rsDeleteFile(l_chunknamlst(i)); END IF; END LOOP; -- dbms_ra_storage.free_block_pool_chunks(s.sl_key, p_dbkey, p_dfkey, l_chunknolst); EXIT WHEN l_chunknolst.COUNT < MAXDELCHUNKS; END LOOP; CLOSE delete_chunks; END LOOP; dbms_ra_int.info_end; IF NOT p_dflocked THEN dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey); l_dflocked := FALSE; END IF; EXCEPTION WHEN OTHERS THEN save_error; IF l_dflocked THEN dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey); END IF; RAISE; END purge_pool; -- -- -- -- -- -- -- -- PROCEDURE purge_vbdf(p_dbkey IN NUMBER, p_type IN NUMBER, p_dfkey IN NUMBER, p_vbkey IN NUMBER) IS l_currinc NUMBER; l_scn NUMBER := NULL; l_safevb NUMBER; l_badvb NUMBER; l_count NUMBER; BEGIN deb('purge_vbdf: dbkey ' || p_dbkey || ', type ' || p_type || ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey, AM_DEBUG_MED); -- purge_lock(p_dfkey); -- -- -- -- SELECT dbinc_key INTO l_currinc FROM (SELECT dbinc_key FROM vbdf WHERE df_key = p_dfkey ORDER BY vb_key DESC ) WHERE ROWNUM = 1; -- -- IF orphans(p_dbkey, p_dfkey, l_currinc) THEN -- -- orphan_safe(p_dbkey, p_dfkey, l_currinc, l_safevb, l_scn); -- IF NOT orphan_bp(p_dbkey, p_dfkey, l_currinc) AND NOT orphan_blocks(p_dbkey, p_dfkey) THEN l_safevb := p_vbkey; END IF; ELSE l_safevb := p_vbkey; END IF; -- -- IF p_type = KBRSPLBLD_ALLPURGE THEN -- SELECT COUNT(*) INTO l_count FROM chunks WHERE df_key = p_dfkey AND ROWNUM = 1; IF l_count = 0 THEN l_safevb := BIGNUM; END IF; END IF; -- -- SELECT LEAST(NVL(MAX(vb_key),l_safevb), l_safevb) INTO l_safevb FROM vbdf WHERE state NOT IN (VBDF_COMPLETE, VBDF_OBSOLETE); deb('purge_vbdf: safevb ' || l_safevb, AM_DEBUG_MED); -- -- dbms_ra_int.write_lock(dbms_ra_int.KEY_DF, p_dfkey); -- IF debug = AM_DEBUG_HIGH THEN FOR i IN (SELECT dbinc_key, df_key, vb_key FROM vbdf WHERE df_key = p_dfkey AND vb_key NOT IN (SELECT vb_key FROM bp WHERE vb_key IS NOT NULL AND status != 'D') AND vb_key < l_safevb AND state = VBDF_COMPLETE) LOOP deb('purge_vbdf: obsolete vbdf dbinc ' || i.dbinc_key || ', dfkey ' || i.df_key || ', vbkey ' || i.vb_key, AM_DEBUG_HIGH); END LOOP; END IF; -- -- -- UPDATE vbdf SET state = VBDF_OBSOLETE WHERE df_key = p_dfkey AND vb_key NOT IN (SELECT vb_key FROM bp WHERE vb_key IS NOT NULL AND status != 'D') AND vb_key < l_safevb AND state = VBDF_COMPLETE; deb('purge_vbdf: ' || SQL%ROWCOUNT || ' vbdf rows made obsolete', AM_DEBUG_MED); COMMIT; -- dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey); purge_unlock(p_dfkey); EXCEPTION WHEN OTHERS THEN save_error; dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey); purge_unlock(p_dfkey); RAISE; END purge_vbdf; -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE reorderDF(p_type IN NUMBER, -- Type of KBRSPLBLD_% to perform p_dfkey IN NUMBER, p_vbkey IN NUMBER) IS l_dbkey NUMBER; l_resume NUMBER; l_needchunks NUMBER; l_maxrank NUMBER; l_space NUMBER; l_qtype NUMBER; l_count NUMBER; l_complete NUMBER; l_slkey NUMBER; l_vbkey NUMBER; l_savepoint NUMBER; l_state NUMBER; BEGIN s_purge_dbinc := NULL; /* Must start out like this. */ l_savepoint := dbms_ra_scheduler.get_savepoint; deb('reorderDF: type ' || p_type || ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey || ', savepoint ' || l_savepoint, AM_DEBUG_MED); -- purge_lock(p_dfkey); IF l_savepoint = RESTART_PURGE_OBSOLETEP THEN GOTO obsolete_plans; END IF; IF l_savepoint = RESTART_PURGE_DEL_BLOCKS THEN GOTO del_blocks; END IF; -- -- -- -- -- -- -- -- -- -- -- -- -- -- IF p_type <> KBRSPLBLD_ALLPURGE THEN SELECT state INTO l_state FROM ( SELECT state FROM vbdf WHERE df_key = p_dfkey AND state IN (VBDF_OBSOLETE, VBDF_COMPLETE) GROUP BY state ORDER BY MAX(ckp_id) DESC ) WHERE ROWNUM = 1; IF l_state = VBDF_OBSOLETE THEN deb('reorderDF: obsolete backup prevent us from purging', AM_DEBUG_HIGH); purge_unlock(p_dfkey); RETURN; END IF; END IF; -- planDF(p_type, p_dfkey, p_vbkey, 0, FALSE, FALSE, TRUE); -- IF p_type = KBRSPLBLD_PURGE OR p_type = KBRSPLBLD_OPTPURGE OR p_type = KBRSPLBLD_SMALLPURGE OR p_type = KBRSPLBLD_ALLPURGE OR p_type = KBRSPLBLD_DUPPURGE THEN l_qtype := KBRSPLBLD_PURGE; ELSE l_qtype := p_type; END IF; -- -- SELECT MAX(db_key), MAX(needchunk), MAX(numchunks), MAX(maxrank) INTO l_dbkey, l_needchunks, l_complete, l_maxrank FROM plans WHERE type = l_qtype AND vb_key = p_vbkey AND df_key = p_dfkey AND blksread IS NOT NULL; /* We have a plan */ -- -- IF l_dbkey IS NULL THEN deb('reorderDF no plan or plan null', AM_DEBUG_MED); dealloc_plan(p_dfkey, NULL, KBRSPLBLD_PURGE); purge_unlock(p_dfkey); RETURN; END IF; -- -- IF l_complete IS NULL THEN deb('reorderDF competing plan', AM_DEBUG_ON); SELECT sl_key INTO l_slkey FROM odb WHERE db_key = l_dbkey; dbms_ra_scheduler.avoid_sl(DBMS_RA_SCHEDULER.TASK_PURGE, l_slkey); RAISE dbms_ra_scheduler.e_retry_error; END IF; -- IF debug = AM_DEBUG_HIGH THEN SELECT used_space INTO l_space FROM odb WHERE db_key = l_dbkey; deb('reorderDF: Beginning space usage is ' || l_space, AM_DEBUG_HIGH); END IF; -- IF l_needchunks > 0 THEN -- dbms_ra_storage.preallocate_chunks(l_dbkey, l_needchunks, TRUE); -- -- dbms_ra_int.info_start('reorderDF prep', 'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey); BEGIN -- lock_vb(TRUE, l_dbkey, p_dfkey, p_vbkey, l_qtype); -- sys.kbrsi_icd.rsPurgePrep(l_qtype, l_dbkey, p_vbkey, p_dfkey); -- lock_vb(FALSE, l_dbkey, p_dfkey, p_vbkey, l_qtype); EXCEPTION WHEN dbms_ra_scheduler.E_OAM_NOT_RUNNING THEN save_error; -- -- -- -- -- sys.kbrsi_icd.rsSetTrace(0, 1); deb('reorderDF retry the purgePrep: ' || 'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey); -- deb('plan_blocks: type ' || p_type || ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey || ' At ' || TO_CHAR(SYSDATE, 'HH24:MI:SS'), AM_DEBUG_MED); show_plan(p_vbkey, p_dfkey, p_dfkey, l_qtype); BEGIN sys.kbrsi_icd.rsPurgePrep(l_qtype, l_dbkey, p_vbkey, p_dfkey); EXCEPTION WHEN OTHERS THEN save_error; lock_vb(FALSE, l_dbkey, p_dfkey, p_vbkey, l_qtype); clear_error; END; clear_error; WHEN OTHERS THEN save_error; -- lock_vb(FALSE, l_dbkey, p_dfkey, p_vbkey, l_qtype); RAISE; END; dbms_ra_int.info_end; -- IF p_type = KBRSPLBLD_OPTIMIZE THEN dealloc_plan(p_dfkey, NULL, KBRSPLBLD_OPTIMIZE); purge_unlock(p_dfkey); dbms_ra_scheduler.check_for_interrupt(0); /* All done */ RETURN; END IF; END IF; -- dbms_ra_scheduler.check_for_interrupt(RESTART_PURGE_OBSOLETEP); <> -- obsoletePlans(p_dfkey); -- -- -- -- -- IF s_safemode AND p_type <> KBRSPLBLD_ALLPURGE AND dbms_ra_scheduler.s_current_task <> dbms_ra_scheduler.TASK_GCOPY_COMPUTE THEN SELECT MAX(vb_key) INTO l_vbkey FROM vbdf WHERE df_key = p_dfkey AND state = VBDF_COMPLETE; WHILE l_vbkey > 0 LOOP planDF(KBRSPLBLD_PIECE, p_dfkey, l_vbkey); SELECT MAX(chunkno) INTO l_needchunks FROM plans_details WHERE TYPE = KBRSPLBLD_PIECE AND df_key = p_dfkey AND vb_key = l_vbkey AND blockno > 0 /* no block 0 safety check, it may be from other df */ AND chunkno IN (SELECT chunkno FROM plans_details WHERE TYPE = KBRSPLBLD_PURGE AND df_key = p_dfkey AND vb_key = p_vbkey AND blockno <> 0); IF l_needchunks IS NOT NULL THEN deb('reorderDF failure: dfkey ' || p_dfkey || ', vbkey ' || l_vbkey || ', type ' || p_type || ', chunk ' || l_needchunks, AM_DEBUG_LOW); -- -- dbms_ra_scheduler.check_for_interrupt(0); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'purge check dfkey ' || p_dfkey || ', vbkey ' || l_vbkey || ', type ' || p_type || ', chunk ' || l_needchunks); END IF; -- IF l_vbkey > p_vbkey THEN l_vbkey := p_vbkey; ELSE l_vbkey := 0; END IF; END LOOP; END IF; <> -- purge_pool(l_dbkey, p_type, l_qtype, p_dfkey, p_vbkey); -- -- dealloc_plan(p_dfkey, NULL, KBRSPLBLD_PURGE); -- purge_unlock(p_dfkey); EXCEPTION WHEN OTHERS THEN save_error; purge_unlock(p_dfkey); RAISE; END reorderDF; -- -- -- -- -- -- -- -- -- PROCEDURE purgeRes(p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_savepoint IN NUMBER, p_small OUT BOOLEAN) IS l_dbkey NUMBER; l_space NUMBER; l_maxchunks NUMBER; l_reserved NUMBER; l_needchunks NUMBER; BEGIN deb('purgeRes: dfkey ' || p_dfkey || ' vbkey ' || p_vbkey, AM_DEBUG_LOW); -- purge_lock(p_dfkey); -- p_small := FALSE; -- planDF(KBRSPLBLD_PURGE, p_dfkey, p_vbkey, 0, FALSE, FALSE, TRUE); -- SELECT MAX(db_key), MAX(needchunk) INTO l_dbkey, l_needchunks FROM plans WHERE type = KBRSPLBLD_PURGE AND vb_key = p_vbkey AND df_key = p_dfkey AND blksread IS NOT NULL; -- -- IF l_dbkey IS NULL OR l_needchunks IS NULL THEN deb('purgeRes no plan or plan null', AM_DEBUG_LOW); -- dbms_ra_scheduler.raise_purge_priority(p_dfkey); purge_unlock(p_dfkey); RETURN; END IF; -- IF debug = AM_DEBUG_HIGH THEN SELECT used_space INTO l_space FROM odb WHERE db_key = l_dbkey; deb('purgeRes: Beginning space usage is ' || l_space, AM_DEBUG_HIGH); END IF; -- -- dbms_ra_int.write_lock(dbms_ra_int.KEY_DF, p_dfkey); -- IF l_needchunks > 0 THEN l_reserved := dbms_ra_storage.reserve_block_pool_space( p_db_key => l_dbkey, p_chunks => l_needchunks, p_maxchunks => l_maxchunks); END IF; -- -- -- -- IF (l_reserved < l_needchunks) THEN deb('purgeRes: Space stress, ' || ' df_key ' || p_dfkey || ' vbkey ' || p_vbkey || ' reserved ' || l_reserved || ' needchunks ' || l_needchunks, AM_DEBUG_LOW); -- IF dbms_ra_scheduler.set_blocking_purge(l_dbkey) IS NOT NULL THEN dbms_ra_storage.finish_block_pool_chunk(p_db_key => l_dbkey); dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey); purge_unlock(p_dfkey); RAISE dbms_ra_scheduler.e_retry_error; END IF; -- planDF(p_vbkey, p_dfkey, KBRSPLBLD_SMALLPURGE, l_reserved); p_small := TRUE; END IF; -- IF l_needchunks > 0 THEN dbms_ra_int.info_start('purgeRes prep', 'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey); BEGIN -- lock_vb(TRUE, l_dbkey, p_dfkey, p_vbkey, KBRSPLBLD_PURGE); -- sys.kbrsi_icd.rsPurgePrep(KBRSPLBLD_PURGE, l_dbkey, p_vbkey, p_dfkey); -- lock_vb(FALSE, l_dbkey, p_dfkey, p_vbkey, KBRSPLBLD_PURGE); EXCEPTION WHEN OTHERS THEN save_error; -- lock_vb(FALSE, l_dbkey, p_dfkey, p_vbkey, KBRSPLBLD_PURGE); RAISE; END; dbms_ra_int.info_end; END IF; -- obsoletePlans(p_dfkey, TRUE#, FALSE#); -- purge_pool(l_dbkey, KBRSPLBLD_PURGE, KBRSPLBLD_PURGE, p_dfkey, p_vbkey, TRUE); -- dbms_ra_storage.finish_block_pool_chunk(p_db_key => l_dbkey); -- dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey); -- purge_unlock(p_dfkey); -- IF debug = AM_DEBUG_HIGH THEN SELECT used_space INTO l_space FROM odb WHERE db_key = l_dbkey; deb('purgeRes: Ending space usage is ' || l_space, AM_DEBUG_HIGH); END IF; EXCEPTION WHEN dbms_ra_scheduler.e_retry_error THEN save_error; purge_unlock(p_dfkey); -- -- -- dbms_lock.sleep(3); dbms_ra_scheduler.s_pending_interrupt := 0; clear_error; WHEN OTHERS THEN save_error; purge_unlock(p_dfkey); RAISE; END purgeRes; -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE set_next_retention(p_dbkey IN NUMBER, p_currinc IN NUMBER, p_outscn OUT NUMBER) IS -- -- -- -- -- -- -- -- -- -- -- CURSOR rnkdf(c_purgescn NUMBER, c_currinc NUMBER, c_oldtime DATE) IS SELECT DISTINCT ckp_scn, ckp_time, DENSE_RANK() OVER (ORDER BY ckp_scn) rnk FROM bs, bp, bdf d, (SELECT db_key, dbinc_key, reset_scn, reset_time, db_name, NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = c_currinc CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i WHERE bs.bs_key = d.bs_key AND bs.bs_key = bp.bs_key AND i.dbinc_key = d.dbinc_key AND bp.status != 'D' AND bp.ba_access = 'L' /* Only backups AM wrote */ AND bp.lib_key IS NULL /* Only backups on disk */ AND bs.keep_options = 0 /* Skip keep backups */ AND d.file# = 1 AND d.ckp_scn > c_purgescn AND d.ckp_time > c_oldtime AND d.ckp_scn >= i.reset_scn AND d.ckp_scn < i.next_reset_scn ORDER BY rnk; l_purgescn NUMBER; l_purgeinc NUMBER; l_oldtime DATE; l_goaltime DATE; l_bs2time odb.bs2_timestamp%type; l_unknown BOOLEAN := FALSE; l_ckpscn1 NUMBER; l_ckptime1 DATE; l_rnk1 NUMBER; l_ckpscn2 NUMBER; l_ckptime2 DATE; l_rnk2 NUMBER; l_ckpscn3 NUMBER; l_ckptime3 DATE; l_rnk3 NUMBER; BEGIN -- -- -- SELECT bs2_timestamp, (sysdate - recovery_window_goal), purge_scn, purge_inc INTO l_oldtime, l_goaltime, l_purgescn, l_purgeinc FROM odb WHERE db_key = p_dbkey; -- -- IF l_purgeinc != p_currinc THEN l_purgescn := 0; l_oldtime := NULL; END IF; -- IF l_purgescn = BIGNUM THEN l_purgescn := 0; l_oldtime := sysdate; /* will force one backup purge */ END IF; -- -- -- -- -- IF l_oldtime IS NULL THEN l_unknown := TRUE; /* Input purge values unreliable */ SELECT MIN(ckp_scn)+1, MIN(ckp_time) INTO l_purgescn, l_oldtime FROM bs s, bp p, bdf d WHERE p.db_key = p_dbkey AND s.bs_key = d.bs_key AND s.bs_key = p.bs_key AND p.status != 'D' AND p.ba_access = 'L' /* Only backups AM wrote */ AND p.lib_key IS NULL /* Only backups on disk */ AND s.keep_options = 0 /* Skip keep backups */ AND d.file# = 1; END IF; -- IF l_oldtime > l_goaltime THEN l_oldtime := to_date('01-1-2012 00:00:00', 'DD-MM-YYYY HH24:MI:SS'); ELSE l_oldtime := l_oldtime + ((l_goaltime - l_oldtime) / 2); END IF; -- -- -- OPEN rnkdf(l_purgescn, p_currinc, l_oldtime); FETCH rnkdf INTO l_ckpscn1, l_ckptime1, l_rnk1; FETCH rnkdf INTO l_ckpscn2, l_ckptime2, l_rnk2; FETCH rnkdf INTO l_ckpscn3, l_ckptime3, l_rnk3; CLOSE rnkdf; -- IF l_ckpscn2 IS NOT NULL THEN l_purgescn := trunc(l_ckpscn1 + ((l_ckpscn2 - l_ckpscn1) / 2)); ELSE l_purgescn := BIGNUM; END IF; -- -- -- -- -- IF l_ckptime3 IS NOT NULL THEN l_bs2time := l_ckptime2 + ((l_ckptime3 - l_ckptime2) / 2); ELSE IF l_ckptime1 IS NULL THEN l_bs2time := sysdate; ELSE l_bs2time := l_ckptime1; END IF; END IF; -- -- -- -- -- -- -- -- UPDATE odb SET purge_scn = l_purgescn, purge_inc = p_currinc, bs2_timestamp = l_bs2time WHERE db_key = p_dbkey; COMMIT; deb('set_next_retention' || ': Time is ' || to_char(l_bs2time, 'DD-MM-YY HH24:MI:SS') || ', SCN is ' || l_purgescn, AM_DEBUG_MED); IF l_bs2time IS NULL THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Bad bs2timestamp'); END IF; -- -- -- IF l_bs2time > l_goaltime AND l_unknown THEN p_outscn := NULL; ELSE p_outscn := l_purgescn; END IF; END set_next_retention; -- -- -- -- -- -- PROCEDURE purgeObsolete(p_slkey IN NUMBER, p_dbkey IN NUMBER, p_notasks IN BOOLEAN) IS l_rlgscn NUMBER; l_rlgtime DATE; l_dbname VARCHAR2(30); l_dbid NUMBER; l_dbun node.db_unique_name%TYPE; l_bskey NUMBER; l_currinc NUMBER; l_purgescn NUMBER; l_ret BOOLEAN; l_firstcall BOOLEAN := TRUE; l_stat VARCHAR(10); l_nodelete BOOLEAN := TRUE; l_advance BOOLEAN := TRUE; l_purgeknows NUMBER; l_delkey NUMBER; l_delname VARCHAR(512); l_count NUMBER; l_vbkey NUMBER; lbRec dbms_rcvman.lbRec_t := NULL; lbCursor dbms_rcvman.lbCursor_t; -- l_slkey NUMBER; l_space NUMBER; l_allocated NUMBER; l_usedspace NUMBER; l_freespace NUMBER; l_chunkspace NUMBER; l_chunkcount NUMBER; l_filchunkspace NUMBER; l_checktape NUMBER := 0; l_retry BOOLEAN := FALSE; -- -- -- -- -- -- CURSOR dieingBP(c_dbkey NUMBER) IS SELECT handle, bp_key FROM bp JOIN bs USING (db_key, bs_key) WHERE ba_access = 'L' AND bp.status = 'A' AND db_key = c_dbkey ORDER BY NVL(keep_options, -1), NVL(vb_key, 0), bck_type, bs.completion_time; BEGIN -- SELECT curr_dbinc_key, db_id, reset_scn, reset_time, db_name INTO l_currinc, l_dbid, l_rlgscn, l_rlgtime, l_dbname FROM db d, dbinc i WHERE d.curr_dbinc_key = i.dbinc_key AND i.db_key = p_dbkey AND d.db_key = p_dbkey; -- -- -- set_next_retention(p_dbkey, l_currinc, l_purgescn); IF l_purgescn IS NULL THEN RETURN; END IF; -- -- -- SELECT DECODE(not_taped_state, 'B', 0, 'C', 0, NULL, 0, 1) INTO l_checktape FROM odb WHERE db_key = p_dbkey; -- deb('purgeObsolete: dbkey ' || p_dbkey || ', setUntilScn ' || to_char(l_purgescn), AM_DEBUG_MED); -- SELECT RTRIM(LTRIM(value)) INTO l_dbun FROM sys.v_$parameter WHERE LOWER(name)='db_unique_name'; dbms_rcvman.resetAll; dbms_rcvman.setDatabase(db_name => l_dbname, reset_scn => l_rlgscn, reset_time => l_rlgtime, db_id => l_dbid, db_unique_name => l_dbun, site_aware => TRUE, dummy_instance => FALSE, ors_instance => TRUE); dbms_rcvman.setAllIncarnations(TRUE); dbms_rcvman.setArchiveFileScopeAttributes(logs_shared => 1); dbms_rcvman.setBackupFileScopeAttributes(disk_backups_shared => 0, tape_backups_shared => 1); dbms_rcvman.setUntilScn(l_purgescn); dbms_rcvman.setDeviceType('SBT_TAPE'); dbms_rcvman.setOrsFile(localOnly => TRUE, libKey => NULL); dbms_rcvman.setNeedObsoleteData(TRUE); -- l_ret := TRUE; WHILE (l_ret) LOOP l_ret := dbms_rcvman.listBackup(lbRecOut => lbRec, firstcall => l_firstcall, only_obsolete => TRUE, redundancy => 1, piped_call => FALSE, lbCursor => lbCursor, lbState => dbms_rcvman.lbStatePck); l_firstcall := FALSE; IF lbRec.pkey IS NOT NULL AND lbRec.file_type = dbms_rcvman.piece_txt AND (lbRec.status = dbms_rcvman.available_txt OR lbRec.status = dbms_rcvman.expired_txt OR lbRec.status = dbms_rcvman.unavailable_txt) AND (l_checktape = 0 OR isTaped(p_dbkey, lbRec.pkey, lbRec.bs_key)) THEN -- SELECT COUNT(*), MAX(vb_key) INTO l_count, l_vbkey FROM bp WHERE bp_key = lbRec.pkey AND status != 'D'; -- l_delkey := NULL; IF l_vbkey IS NOT NULL THEN SELECT MAX(bp_key) INTO l_delkey FROM bp WHERE bs_key = lbRec.bs_key AND ba_access != 'U' AND lib_key IS NULL AND vb_key IS NULL AND status != 'D'; -- -- -- IF l_delkey IS NOT NULL THEN SELECT handle INTO l_delname FROM bp WHERE bp_key = l_delkey; dbms_ra_storage.free_backup_piece_opt( p_dbkey => p_dbkey, p_piecename => l_delname, p_db_slkey => p_slkey, p_dbid => l_dbid, p_currinc => l_currinc, p_bpkey => l_delkey, p_libkey => NULL, p_notasks => p_notasks); l_nodelete := FALSE; l_advance := FALSE; -- We will still have vb at this scn END IF; END IF; -- IF l_delkey IS NULL AND l_count > 0 THEN dbms_ra_storage.free_backup_piece_opt( p_dbkey => p_dbkey, p_piecename => lbRec.fname, p_db_slkey => p_slkey, p_dbid => l_dbid, p_currinc => l_currinc, p_bpkey => lbRec.pkey, p_libkey => lbRec.bp_lib_key, p_notasks => p_notasks); l_nodelete := FALSE; END IF; dbms_ra_scheduler.check_for_interrupt; END IF; END LOOP; IF l_nodelete THEN deb('purgeObsolete: NODELETE IS TRUE, scn ' || l_purgescn, AM_DEBUG_MED); ELSE deb('purgeObsolete: NODELETE IS FALSE', AM_DEBUG_MED); END IF; -- -- -- IF l_nodelete AND l_purgescn = BIGNUM THEN -- IF s_purgeknows IS NULL THEN SELECT max(bp_key) INTO s_purgeknows FROM bp WHERE db_key = p_dbkey; ELSE -- SELECT max(bp_key) INTO l_purgeknows FROM bp WHERE db_key = p_dbkey; IF l_purgeknows != s_purgeknows THEN s_purgeknows := NULL; ELSE -- -- deb('purgeObsolete: Not all data can be restored.', AM_DEBUG_ON); -- -- FOR b IN dieingBP(p_dbkey) LOOP BEGIN dbms_ra_storage.free_backup_piece_opt(p_dbkey => p_dbkey, p_piecename => b.handle, p_db_slkey => p_slkey, p_dbid => l_dbid, p_currinc => l_currinc, p_bpkey => b.bp_key, p_libkey => null, p_notasks => p_notasks); l_retry := FALSE; EXIT; EXCEPTION WHEN dbms_ra_scheduler.e_retry_error THEN save_error; NULL; -- Try another backup l_retry := TRUE; clear_error; WHEN OTHERS THEN save_error; RAISE; END; END LOOP; IF l_retry THEN RAISE dbms_ra_scheduler.e_retry_error; END IF; END IF; END IF; END IF; END purgeObsolete; -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE process_allfiles (p_dbkey IN NUMBER, p_bskey IN NUMBER, p_bpkey IN NUMBER, p_toname IN VARCHAR2, p_hasdups IN BOOLEAN, p_update IN BOOLEAN) IS l_state BINARY_INTEGER; l_node VARCHAR2(255); l_devtype VARCHAR2(512); l_params VARCHAR2(1024); l_pieces_done BINARY_INTEGER; l_datafiles BOOLEAN; l_incremental BOOLEAN; l_fromdisk BOOLEAN; l_device BOOLEAN; l_files BINARY_INTEGER; l_check_logical BOOLEAN := FALSE; l_handle VARCHAR2(512); l_tmphandle VARCHAR2(512); l_tag VARCHAR2(31); l_recid NUMBER; l_stamp NUMBER; l_size NUMBER; l_count NUMBER; l_done BOOLEAN; l_outhandle VARCHAR2(512); l_outbpcfkey NUMBER; l_outbpspkey NUMBER; l_outtag VARCHAR2(31); l_failover BOOLEAN := FALSE; l_amflags BINARY_INTEGER := SYS.DBMS_BACKUP_RESTORE.KRBRCB_ORS_POOL; l_slkey NUMBER; l_ilevel NUMBER; l_outbpkey NUMBER; l_blksize NUMBER; l_bcfkey NUMBER := NULL; l_bsfkey NUMBER := NULL; l_filnolst NOLST; -- Array of number l_dfkeylst NOLST; -- Array of number l_tsnmlst NMLST; -- Array of varchar2(30) l_levellst NOLST; -- Array of number task_rec task%ROWTYPE; l_lib_key NUMBER; l_ct_key NUMBER; l_sig1 NUMBER; -- safemode signature check l_sig2 NUMBER; -- safemode signature check l_chunksize NUMBER := f_chunksize(p_dbkey); BEGIN deb('Process_allfiles - bpkey ' || p_bpkey || ', bskey ' || p_bskey, AM_DEBUG_MED); -- SELECT max(bcf_key) INTO l_bcfkey FROM BCF WHERE bs_key = p_bskey; -- SELECT max(bsf_key) INTO l_bsfkey FROM BSF WHERE bs_key = p_bskey; -- -- -- -- SELECT handle, tag, bp_recid, bp_stamp, lib_key, bytes / (CASE compressed WHEN 'NO' THEN 2 ELSE 1 END) INTO l_handle, l_tag, l_recid, l_stamp, l_count, l_size FROM bp WHERE bp_key = p_bpkey; l_fromdisk := (l_count IS NULL); -- SELECT block_size INTO l_blksize FROM bs WHERE bs_key = p_bskey; -- IF NOT l_fromdisk THEN -- SELECT lib.parms, lib.lib_key INTO l_params, l_lib_key FROM sbt_lib_desc lib, bp WHERE lib.lib_key = bp.lib_key AND bp.handle = l_handle AND bp.db_key = p_dbkey; END IF; -- -- SELECT * BULK COLLECT INTO l_filnolst, l_tsnmlst, l_dfkeylst, l_levellst FROM (SELECT d.file# filno, ts.ts_name, f.df_key, incrLevel(d.create_scn, d.incr_scn) ilevel FROM bdf d, df f, ts WHERE f.file# = d.file# AND f.create_scn = d.create_scn AND f.dbinc_key = d.dbinc_key AND f.dbinc_key = ts.dbinc_key AND f.ts# = ts.ts# AND f.ts_pdbinc_key = ts.pdbinc_key AND d.bs_key = p_bskey GROUP BY d.file#, ts.ts_name, f.df_key, d.create_scn, d.incr_scn) ORDER BY ilevel; /* Level 0, followed by level 1 */ -- -- -- -- -- IF p_update THEN SELECT COUNT(*) INTO l_count FROM vbdf WHERE vb_key = saved_vbkey; IF l_count = l_dfkeylst.count THEN -- -- -- -- SELECT COUNT(*) INTO l_count FROM vbdf v, bp p WHERE v.vb_key = saved_vbkey AND v.vcbp_key = p.bp_key AND p.bs_key = p_bskey AND ROWNUM = 1; IF l_count > 0 THEN l_amflags := l_amflags + SYS.DBMS_BACKUP_RESTORE.KRBRCB_ORS_UPDKRBPH; END IF; ELSE l_amflags := l_amflags + SYS.DBMS_BACKUP_RESTORE.KRBRCB_ORS_NOKRBPH; -- SELECT krbph_chunkno, krbph_dfkey INTO saved_krbph, saved_krbphdf FROM vbdf WHERE vb_key = saved_vbkey AND ROWNUM = 1; END IF; deb('Process_allfiles update - bpkey ' || p_bpkey || ', bskey ' || p_bskey || ', vbkey ' || saved_vbkey || ', rsflags ' || l_amflags, AM_DEBUG_MED); END IF; -- dbms_ra_storage.preallocate_chunks(p_dbkey, CEIL(l_size / l_chunksize), TRUE); -- -- -- -- l_ilevel := 0; WHILE l_ilevel < 2 LOOP -- IF l_bcfkey IS NULL AND l_bsfkey IS NULL AND l_levellst(1) = 1 THEN l_ilevel := 1; END IF; -- IF l_fromdisk THEN l_devtype := sys.dbms_backup_restore.deviceAllocate( ident => 'ORA_DISK_1', node => l_node, type => null, dupcnt => 1); ELSE l_devtype := sys.dbms_backup_restore.deviceAllocate( ident => 'RA$SBT', node => l_node, type => 'SBT_TAPE', params => l_params, dupcnt => 1, allowmts => TRUE, ors_lib_key => l_lib_key); END IF; sys.dbms_backup_restore.restoreCancel(TRUE); sys.dbms_backup_restore.restoreStatus(l_state, l_pieces_done, l_files, l_datafiles, l_incremental, l_device); IF l_state != sys.dbms_backup_restore.restore_no_conversation THEN SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'unknown conversation state'); END IF; -- IF l_ilevel = 0 THEN sys.dbms_backup_restore.restoreSetDatafile( check_logical => l_check_logical ,cleanup => FALSE ,service => NULL ,chunksize => l_chunksize ,rs_flags => l_amflags); -- ELSE sys.dbms_backup_restore.applySetDatafile( check_logical => l_check_logical ,cleanup => FALSE ,service => NULL ,chunksize => l_chunksize ,rs_flags => l_amflags); END IF; -- IF l_ilevel = 0 AND l_bcfkey IS NOT NULL THEN deb('Process_allfiles controlfile bcf_key ' || l_bcfkey || ', bskey ' || p_bskey, AM_DEBUG_MED); sys.dbms_backup_restore.restoreControlfileTo(cfname => p_toname, isstby => FALSE); END IF; -- IF l_ilevel = 0 AND l_bsfkey IS NOT NULL THEN deb('Process_allfiles spfile bsf_key ' || l_bsfkey || ', bskey ' || p_bskey, AM_DEBUG_MED); sys.dbms_backup_restore.restoreSpfileTo(pfname => p_toname, sfname => p_toname); END IF; -- FOR i IN 1 .. l_filnolst.count LOOP -- -- IF l_ilevel = 1 AND l_levellst(i) = 1 THEN deb('Process_allfiles1 file# ' || l_filnolst(i) || ', bskey ' || p_bskey, AM_DEBUG_MED); sys.dbms_backup_restore.applyDataFileTo(dfnumber => l_filnolst(i), toname => p_toname, fuzziness_hint => 0, max_corrupt => 0, islevel0 => 0, recid => 0, stamp => 0); END IF; -- IF l_ilevel = 0 AND l_levellst(i) = 0 THEN deb('Process_allfiles2 file# ' || l_filnolst(i) || ', bskey ' || p_bskey, AM_DEBUG_MED); sys.dbms_backup_restore.restoreDataFileTo(dfnumber => l_filnolst(i), toname => p_toname, max_corrupt => 0, tsname => l_tsnmlst(i)); END IF; END LOOP; -- -- sys.dbms_backup_restore.restoreSetPiece(handle => l_handle, tag => l_tag, fromdisk => l_fromdisk, recid => l_recid, stamp => l_stamp); sys.dbms_backup_restore.restoreBackupPiece(done => l_done, params => l_params, outhandle => l_outhandle, outtag => l_outtag, failover => l_failover); -- sys.dbms_backup_restore.restoreCancel(TRUE); sys.dbms_backup_restore.cfileUseCurrent; -- release enqueue sys.dbms_backup_restore.deviceDeallocate; sys.dbms_backup_restore.set_client_info(''); sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0); -- IF l_ilevel = 0 AND l_bcfkey IS NOT NULL THEN SELECT filesize, handle, ct_key INTO l_size, l_tmphandle, l_ct_key FROM sbt_catalog WHERE filename = saved_krbph_cfname AND filesize is not null; sys.kbrsi_icd.rsInspectBackupPiece( handle => l_tmphandle, vbkey => NULL, bpsize => l_chunksize, chktype => DBMS_RA_INT.KBRSCHKTYPE_FILE, fno => 0, lib_key => null, /* local disk file */ ct_key => l_ct_key, bpkey => l_outbpcfkey, template_key => null); deb('Process_allfiles controlfile ' || ' handle - ' || saved_krbph_cfname, AM_DEBUG_MED); END IF; -- IF l_ilevel = 0 AND l_bsfkey IS NOT NULL THEN SELECT filesize, handle, ct_key INTO l_size, l_tmphandle, l_ct_key FROM sbt_catalog WHERE filename = saved_krbph_spname AND filesize is not null; sys.kbrsi_icd.rsInspectBackupPiece( handle => l_tmphandle, vbkey => NULL, bpsize => l_chunksize, chktype => DBMS_RA_INT.KBRSCHKTYPE_FILE, fno => 0, lib_key => null, /* local disk file */ ct_key => l_ct_key, bpkey => l_outbpspkey, template_key => null); deb('Process_allfiles spfile ' || ' handle - ' || saved_krbph_spname, AM_DEBUG_MED); END IF; deb('Process_allfiles finished level ' || l_ilevel || ', vbkey ' || saved_vbkey || ' handle - ' || saved_krbph_name, AM_DEBUG_MED); -- l_ilevel := l_ilevel + 1; -- EXIT WHEN l_levellst(l_levellst.COUNT) = 0; END LOOP; -- -- -- -- UPDATE vbdf SET srcbp_key = p_bpkey, krbph_dfkey = saved_krbphdf, krbph_chunkno = saved_krbph WHERE vb_key = saved_vbkey; COMMIT; -- -- FOR i IN 1 .. l_dfkeylst.COUNT LOOP -- IF dbms_ra_int.read_lock(dbms_ra_int.KEY_DF, l_dfkeylst(i)) THEN l_done := FALSE; WHILE NOT l_done LOOP BEGIN sys.kbrsi_icd.rsPlan(p_dbkey, saved_vbkey, l_dfkeylst(i), KBRSPLBLD_PIECE, 0); l_done := TRUE; EXCEPTION WHEN dbms_ra_scheduler.e_snapshot_too_old THEN save_error; -- -- dbms_ra_int.unlock(dbms_ra_int.KEY_DF, l_dfkeylst(i)); dbms_lock.sleep(5); clear_error; WHEN dbms_ra_scheduler.e_retry_error THEN save_error; -- dbms_ra_int.unlock(dbms_ra_int.KEY_DF, l_dfkeylst(i)); dbms_lock.sleep(5); clear_error; WHEN OTHERS THEN save_error; dbms_ra_int.unlock(dbms_ra_int.KEY_DF, l_dfkeylst(i)); RAISE; END; END LOOP; ELSE -- RAISE dbms_ra_scheduler.e_retry_error; END IF; dbms_ra_int.unlock(dbms_ra_int.KEY_DF, l_dfkeylst(i)); -- dbms_ra_scheduler.release_blocked_tasks( dbms_ra_scheduler.s_current_task, p_dbkey); END LOOP; -- -- IF p_hasdups THEN SELECT sl_key INTO l_slkey FROM odb WHERE db_key = p_dbkey; FOR i IN 1 .. l_dfkeylst.COUNT LOOP task_rec := NULL; task_rec.task_type := dbms_ra_scheduler.TASK_PURGE_DUP_DF; task_rec.db_key := p_dbkey; task_rec.sl_key := l_slkey; task_rec.param_num1 := l_dfkeylst(i); task_rec.param_num2 := saved_vbkey; task_rec.param_num3 := p_bpkey; -- Ensures this is all done. dbms_ra_scheduler.new_task(task_rec, TRUE, TRUE); -- commit and delay END LOOP; END IF; -- SELECT COUNT(*) INTO l_count FROM vbdf WHERE vb_key = saved_vbkey AND state != VBDF_FIN_NOBP; IF l_count > 0 THEN -- SELECT COUNT(*) INTO l_count FROM vbdf WHERE vb_key = saved_vbkey AND state NOT IN (VBDF_ABORT, VBDF_FIN_NOBP); IF l_count = 0 THEN deb('Process_allfiles abort on vbkey ' || saved_vbkey, AM_DEBUG_LOW); RAISE dbms_ra_scheduler.e_retry_reserve; ELSE IF NOT p_update THEN deb('Process_allfiles: corruption in vbdf for vbkey ' || saved_vbkey, AM_DEBUG_ON); SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'corrupt_vbdf'); END IF; END IF; END IF; -- IF s_safemode THEN deb('Process_allfiles: debug, make sure relfno assigned ok'); SELECT COUNT(*) INTO l_count FROM (SELECT vb_key, MAX(relfno) maxr, COUNT(*) cnt FROM vbdf WHERE vb_key = saved_vbkey GROUP BY vb_key) WHERE cnt != maxr; IF l_count = 1 THEN deb('Process_allfiles: messed up relfno in vbkey ' || saved_vbkey); -- SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR( DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Bad relfno'); END IF; END IF; -- IF s_safemode AND NOT p_update THEN deb('Process_allfiles src bpkey ' || p_bpkey || ' safemode check of orig', AM_DEBUG_MED); FOR i IN 1 .. l_dfkeylst.COUNT LOOP -- IF dbms_ra_int.read_lock(dbms_ra_int.KEY_DF, l_dfkeylst(i)) THEN l_done := FALSE; WHILE NOT l_done LOOP BEGIN deb('Process_allfiles safemode dfkey ' || l_dfkeylst(i) || ', vbkey ' || saved_vbkey, AM_DEBUG_MED); sys.kbrsi_icd.rsPlan(p_dbkey, saved_vbkey, l_dfkeylst(i), KBRSPLBLD_ORIGPIECE, 0); l_done := TRUE; EXCEPTION WHEN dbms_ra_scheduler.e_retry_error THEN save_error; -- dbms_ra_int.unlock(dbms_ra_int.KEY_DF, l_dfkeylst(i)); dbms_lock.sleep(5); clear_error; WHEN OTHERS THEN save_error; dbms_ra_int.unlock(dbms_ra_int.KEY_DF, l_dfkeylst(i)); RAISE; END; END LOOP; END IF; -- SELECT SUM(signature) INTO l_sig1 FROM plans_details WHERE df_key = l_dfkeylst(i) AND type = KBRSPLBLD_ORIGPIECE AND vb_key = saved_vbkey AND blockno > 0 AND numbytes > 0; -- SELECT SUM(scn) INTO l_sig2 FROM blocks b, vbdf v WHERE b.df_key = l_dfkeylst(i) AND v.df_key = l_dfkeylst(i) AND v.vb_key = saved_vbkey AND v.ckp_id = b.ckp_id AND b.blockno > 0 AND b.used > 0; deb('Process_allfiles: df_key ' || l_dfkeylst(i) || ', sig1 ' || l_sig1 || ', sig2 ' || l_sig2 || ', safemode check', AM_DEBUG_ON); IF l_sig1 != l_sig2 THEN -- FOR x IN (SELECT b.blockno, b.scn, b.chunkno, b.coffset, b.df_key FROM blocks b, plans_details p WHERE b.df_key = l_dfkeylst(i) AND b.chunkno = p.chunkno AND b.coffset >= p.coffset AND b.coffset < (p.coffset + p.numbytes) AND b.used > 0 AND p.df_key = l_dfkeylst(i) AND p.type = KBRSPLBLD_ORIGPIECE AND p.vb_key = saved_vbkey ORDER BY DECODE(b.blockno, 1, BIGNUM, b.blockno)) LOOP deb('bad bno ' || x.blockno || ', scn ' || x.scn || ', dfkey ' || x.df_key || ', chunk ' || x.chunkno, AM_DEBUG_ON); END LOOP; raise_bad_metadata(l_dfkeylst(i)); END IF; dbms_ra_int.unlock(dbms_ra_int.KEY_DF, l_dfkeylst(i)); dealloc_plan(l_dfkeylst(i), saved_vbkey, KBRSPLBLD_ORIGPIECE); END LOOP; END IF; -- SELECT SUM(filesize) INTO l_size FROM chunks c, vbdf v WHERE c.df_key = v.df_key AND v.vb_key = saved_vbkey AND c.clean_key = saved_vbkey; -- -- FOR x IN (SELECT file#, completion_time FROM bdf WHERE bs_key = p_bskey) LOOP dbms_ra_int.saveBPdata(fno => x.file#, completion_time => x.completion_time); END LOOP; -- -- -- IF NOT p_update THEN sys.kbrsi_icd.rsInspectBackupPiece( handle => saved_krbph_name, vbkey => saved_vbkey, bpsize => l_size, chktype => DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL, fno => null, lib_key => null, /* local disk file */ ct_key => null, bpkey => l_outbpkey, template_key => null); deb('Process_allfiles: Created bpkey ' || l_outbpkey || ', vbkey ' || saved_vbkey, AM_DEBUG_LOW); -- UPDATE vbdf v SET vcbp_key = l_outbpkey, chunks_used = (SELECT COUNT(*) FROM chunks c WHERE c.df_key = v.df_key AND c.clean_key = saved_vbkey) WHERE vb_key = saved_vbkey; COMMIT; ELSE -- UPDATE vbdf SET state = VBDF_COMPLETE WHERE vb_key = saved_vbkey AND state = VBDF_FIN_NOBP; COMMIT; l_outbpkey := 0; END IF; EXCEPTION WHEN OTHERS THEN save_error; -- BEGIN deb('Process_allfiles: failed with error ' || SQLCODE, AM_DEBUG_MED); sys.dbms_backup_restore.restoreCancel(FALSE); sys.dbms_backup_restore.cfileUseCurrent; -- release enqueue sys.dbms_backup_restore.deviceDeallocate; sys.dbms_backup_restore.set_client_info(''); sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0); -- -- -- IF debug = AM_DEBUG_HIGH THEN SELECT error_count INTO l_count FROM task WHERE task_id = dbms_ra_scheduler.s_current_task; IF l_count > dbms_ra_scheduler.s_max_task_restarts/2 THEN cleanup(saved_vbkey); END IF; ELSE cleanup(saved_vbkey); END IF; -- SELECT MAX(state) INTO l_state FROM vbdf WHERE vb_key = saved_vbkey AND state = VBDF_ABORT; IF l_state = VBDF_ABORT THEN RAISE dbms_ra_scheduler.e_retry_error; END IF; EXCEPTION WHEN OTHERS THEN save_error; deb('Process_allfiles cleanup: failed with error ' || SQLCODE, AM_DEBUG_ON); RAISE; -- Must always raise or you loose shutdown error END; RAISE; END process_allfiles; -- -- -- -- -- -- -- -- -- -- PROCEDURE cleanup(p_vbkey IN NUMBER) IS l_bskey NUMBER; l_locked BOOLEAN := FALSE; l_hash NUMBER; CURSOR fnos IS SELECT v.df_key, v.vb_key, v.dbinc_key, v.db_key FROM vbdf v WHERE v.vb_key = p_vbkey ORDER BY v.df_key; BEGIN -- deb('cleanup from a failed operation with vbkey: ' || p_vbkey, AM_DEBUG_LOW); -- SELECT MAX(bs_key) INTO l_bskey -- Use max to avoid no data found FROM bp WHERE bp.vb_key = p_vbkey AND status != 'D'; IF l_bskey IS NOT NULL THEN RETURN; END IF; -- FOR f IN fnos LOOP deb('cleanup: dfkey ' || f.df_key || ', vbkey ' || f.vb_key, AM_DEBUG_LOW); -- SELECT ORA_HASH(f.df_key, 1023, 0) + 1 INTO l_hash FROM dual; WHILE NOT l_locked LOOP l_locked := sys.kbrsi_icd.rsPurgeLock(l_hash); IF NOT l_locked THEN dbms_lock.sleep(1); END IF; END LOOP; -- dealloc_plan(f.df_key, p_vbkey, KBRSPLBLD_PURGE); alloc_plan(f.db_key, f.df_key, p_vbkey, KBRSPLBLD_PURGE); INSERT INTO plans_details (type, df_key, vb_key, chunkno, blockno, blkrank, numblks, coffset) SELECT KBRSPLBLD_PURGE, f.df_key, p_vbkey, chunkno, -10 blockno, 0 blkrank, 0 numblks, 0 coffset FROM chunks WHERE df_key = f.df_key AND clean_key = p_vbkey; -- UPDATE vbdf SET state = VBDF_CLEANUP WHERE vb_key = p_vbkey AND df_key = f.df_key; COMMIT; -- -- purge_pool(f.db_key, KBRSPLBLD_PURGE, KBRSPLBLD_PURGE, f.df_key, p_vbkey, TRUE); -- dbms_ra_scheduler.check_for_interrupt(saved_vbkey); dealloc_plan(f.df_key, p_vbkey, KBRSPLBLD_PURGE); dbms_ra_scheduler.unlock(dbms_ra_scheduler.LOCK_PURGE, l_hash); l_locked := FALSE; END LOOP; -- DELETE FROM vbdf WHERE vb_key = p_vbkey; COMMIT; EXCEPTION WHEN OTHERS THEN save_error; -- -- dbms_ra_scheduler.check_for_interrupt(p_vbkey); IF l_locked THEN dbms_ra_scheduler.unlock(dbms_ra_scheduler.LOCK_PURGE, l_hash); END IF; RAISE; END cleanup; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- FUNCTION isTaped(p_dbkey IN NUMBER, p_bpkey IN NUMBER, p_bskey IN NUMBER) RETURN BOOLEAN IS l_count NUMBER; l_vbkey NUMBER; l_dfbck NUMBER := 0; l_startscn NUMBER; BEGIN deb('isTaped bskey ' || p_bskey, AM_DEBUG_MED); -- SELECT COUNT(*) INTO l_count FROM bp WHERE bs_key = p_bskey AND lib_key IS NOT NULL; -- IF l_count = 0 THEN SELECT COUNT(*) INTO l_dfbck FROM bs WHERE bs_key = p_bskey AND (keep_options = 0 OR BCK_TYPE != 'L'); END IF; -- -- IF l_dfbck > 0 THEN SELECT SIGN(MIN(x.scn - (y.ckp_scn-1))) INTO l_count FROM (SELECT bs_key, dbinc_key, file#, ckp_scn FROM bdf UNION SELECT bs_key, dbinc_key, 0 file#, ckp_scn FROM bcf) y, /* Highest backup scns in current inc, but not keep */ (SELECT a.dbinc_key, a.file#, MAX(a.ckp_scn) scn FROM bp p, bs s, (SELECT bs_key, file#, dbinc_key, ckp_scn FROM bdf UNION SELECT bs_key, 0 file#, dbinc_key, ckp_scn FROM bcf) a, (SELECT db_key, dbinc_key, reset_scn, NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = (SELECT curr_dbinc_key FROM db WHERE db_key = p_dbkey) CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i WHERE a.bs_key = s.bs_key AND a.bs_key = p.bs_key AND a.dbinc_key = i.dbinc_key AND p.status != 'D' AND p.lib_key IS NOT NULL AND s.keep_options = 0 GROUP BY a.dbinc_key, a. file#) x WHERE x.dbinc_key = y.dbinc_key AND x.file# = y.file# AND y.bs_key = p_bskey; END IF; deb('isTaped count ' || l_count || ', bpkey ' || p_bpkey, AM_DEBUG_MED); RETURN (l_count > 0); END isTaped; -- -- -- -- -- -- PROCEDURE new_plans (p_dbkey IN NUMBER, p_dfkey IN NUMBER, p_nopurge IN BOOLEAN DEFAULT FALSE) IS task_rec task%ROWTYPE; l_count NUMBER; BEGIN deb('NEW_PLANS: Submit future plans for df_key ' || p_dfkey, AM_DEBUG_MED); -- -- -- -- FOR x IN (SELECT bs_key, vb_key FROM sbt_task JOIN task USING (task_id) JOIN bp USING (db_key, bs_key) WHERE db_key = p_dbkey AND state NOT IN (dbms_ra_scheduler.STATE_RUNNING, dbms_ra_scheduler.STATE_CANCEL, dbms_ra_scheduler.STATE_CANCELING) AND vb_key IS NOT NULL) LOOP -- task_rec := NULL; task_rec.task_type := dbms_ra_scheduler.TASK_PLAN_SBT; task_rec.db_key := p_dbkey; task_rec.param_num2 := x.vb_key; task_rec.param := x.bs_key; -- -- -- -- SELECT MAX(incrLevel(d.create_scn, d.incr_scn)) + COUNT(*) INTO l_count FROM bdf d WHERE d.bs_key = x.bs_key; -- IF l_count = 1 THEN task_rec.param_num3 := KBRSPLBLD_PIECE; ELSE task_rec.param_num3 := KBRSPLBLD_ORIGPIECE; END IF; -- FOR y IN (SELECT df_key FROM bdf d, df f WHERE d.dbinc_key = f.dbinc_key AND d.create_scn = f.create_scn AND d.file# = f.file# AND d.bs_key = x.bs_key) LOOP task_rec.param_num1 := y.df_key; dbms_ra_scheduler.new_task(task_rec, FALSE); -- Delay commit END LOOP; END LOOP; -- -- FOR i IN (SELECT MAX(vb_key) vb_key FROM bp JOIN bdf USING (bs_key) JOIN vbdf USING (db_key, vb_key) WHERE db_key = p_dbkey AND df_key = p_dfkey AND status != 'D' GROUP BY piece#) LOOP task_rec := NULL; task_rec.task_type := dbms_ra_scheduler.TASK_PLAN_DF; task_rec.db_key := p_dbkey; task_rec.param_num1 := p_dfkey; task_rec.param_num2 := i.vb_key; task_rec.param_num3 := KBRSPLBLD_PIECE; dbms_ra_scheduler.new_task(task_rec, FALSE); -- Delay commit END LOOP; COMMIT; -- SYS.KBRSI_ICD.RSRUNSCHED; END new_plans; -- -- -- -- -- -- FUNCTION orphans(p_dbkey IN NUMBER, p_dfkey IN NUMBER, p_currinc IN NUMBER DEFAULT NULL) RETURN BOOLEAN IS l_badvb NUMBER; l_currinc NUMBER := p_currinc; BEGIN IF l_currinc IS NULL THEN -- -- -- SELECT dbinc_key INTO l_currinc FROM (SELECT dbinc_key FROM vbdf WHERE df_key = p_dfkey ORDER BY vb_key DESC ) WHERE ROWNUM = 1; END IF; -- SELECT MAX(vb_key) INTO l_badvb FROM vbdf WHERE df_key = p_dfkey AND vb_key NOT IN (SELECT vb_key FROM vbdf v, (SELECT dbinc_key, NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = l_currinc CONNECT BY PRIOR parent_dbinc_key = dbinc_key ) i WHERE v.df_key = p_dfkey AND v.dbinc_key = i.dbinc_key AND v.ckp_scn < i.next_reset_scn AND v.state != VBDF_OBSOLETE ) AND state != VBDF_OBSOLETE; IF l_badvb IS NULL THEN deb('orphans: dfkey ' || p_dfkey || ', FALSE', AM_DEBUG_HIGH); RETURN FALSE; ELSE deb('orphans: dfkey ' || p_dfkey || ', TRUE', AM_DEBUG_HIGH); RETURN TRUE; END IF; END orphans; -- -- -- -- -- -- FUNCTION orphan_bp(p_dbkey IN NUMBER, p_dfkey IN NUMBER, p_currinc IN NUMBER) RETURN BOOLEAN IS l_count NUMBER; l_badvb NUMBER; l_currinc NUMBER := p_currinc; BEGIN -- SELECT MAX(p.vb_key) INTO l_badvb FROM bp p, bdf b, df f WHERE f.df_key = p_dfkey AND f.dbinc_key = b.dbinc_key AND f.file# = b.file# AND f.create_scn = b.create_scn AND p.bs_key = b.bs_key AND p.vb_key IS NOT NULL AND p.status != 'D' AND p.vb_key NOT IN (SELECT vb_key FROM vbdf v, (SELECT dbinc_key, NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = l_currinc CONNECT BY PRIOR parent_dbinc_key = dbinc_key ) i WHERE v.df_key = p_dfkey AND v.dbinc_key = i.dbinc_key AND v.ckp_scn < i.next_reset_scn AND v.state != VBDF_OBSOLETE ); IF l_badvb IS NULL THEN deb('orphan_bp: dfkey ' || p_dfkey || ', FALSE', AM_DEBUG_HIGH); RETURN FALSE; ELSE deb('orphan_bp: dfkey ' || p_dfkey || ', TRUE', AM_DEBUG_HIGH); RETURN TRUE; END IF; END orphan_bp; -- -- -- -- -- -- FUNCTION orphan_blocks(p_dbkey IN NUMBER, p_dfkey IN NUMBER) RETURN BOOLEAN IS l_count NUMBER; l_currinc NUMBER; l_currvb NUMBER; l_maxckpid NUMBER; l_tmp NUMBER; l_orphaninc NUMBER; l_maxorphscn NUMBER; BEGIN -- SELECT dbinc_key, vb_key, ckp_id INTO l_currinc, l_currvb, l_maxckpid FROM (SELECT dbinc_key, vb_key, ckp_id FROM vbdf WHERE df_key = p_dfkey ORDER BY vb_key DESC ) WHERE ROWNUM = 1; -- -- working_ckpid(p_dbkey, p_dfkey, l_currvb, TRUE, l_currinc, l_maxckpid, l_tmp, l_orphaninc); orphan_common(l_currinc, l_orphaninc, p_dfkey, l_tmp, l_maxorphscn); -- dbms_ra_int.info_start('orphan_blocks', 'dfkey ' || p_dfkey || 'currvb ' || l_currvb); -- SELECT COUNT(*) INTO l_count FROM dual WHERE EXISTS (SELECT 1 /*+ QB_NAME(badblks) */ FROM blocks WHERE df_key = p_dfkey AND scn > l_maxorphscn AND ckp_id NOT IN (SELECT ckp_id FROM vbdf v, (SELECT dbinc_key, NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = l_currinc CONNECT BY PRIOR parent_dbinc_key = dbinc_key ) i WHERE v.dbinc_key = i.dbinc_key AND v.ckp_scn < i.next_reset_scn AND v.df_key = p_dfkey AND v.state != VBDF_OBSOLETE ) ); dbms_ra_int.info_end; IF l_count = 0 THEN deb('orphan_blocks: dfkey ' || p_dfkey || ', FALSE', AM_DEBUG_HIGH); RETURN FALSE; ELSE deb('orphan_blocks: dfkey ' || p_dfkey || ', TRUE', AM_DEBUG_HIGH); RETURN TRUE; END IF; END orphan_blocks; -- -- -- -- -- -- -- -- -- -- PROCEDURE orphan_safe(p_dbkey IN NUMBER, p_dfkey IN NUMBER, p_currinc IN NUMBER, o_vbkey OUT NUMBER, o_scn OUT NUMBER) IS l_resetscn NUMBER; BEGIN -- WITH vbtree AS ( /* List of vb_key in current inc tree */ SELECT /*+ QB_NAME(vbtree) MATERIALIZE */ vb_key, reset_scn FROM vbdf v, (SELECT dbinc_key, reset_scn, NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = p_currinc CONNECT BY PRIOR parent_dbinc_key = dbinc_key ) i WHERE v.df_key = p_dfkey AND v.dbinc_key = i.dbinc_key AND v.ckp_scn < i.next_reset_scn AND v.state != VBDF_OBSOLETE ) SELECT MIN(reset_scn) INTO l_resetscn FROM vbdf JOIN dbinc USING (dbinc_key, db_key) WHERE db_key = p_dbkey AND df_key = p_dfkey AND reset_scn NOT IN (SELECT reset_scn FROM vbtree) AND state != VBDF_OBSOLETE; BEGIN SELECT vb_key, ckp_scn INTO o_vbkey, o_scn FROM ( SELECT vb_key, ckp_scn FROM vbdf WHERE ckp_scn < l_resetscn AND df_key = p_dfkey AND state != VBDF_OBSOLETE ORDER BY vb_key DESC ) WHERE ROWNUM = 1; EXCEPTION WHEN no_data_found THEN o_vbkey := 0; o_scn := 0; END; -- END orphan_safe; -- -- -- -- -- -- -- PROCEDURE orphan_common(p_dbinc_a IN NUMBER, p_dbinc_b IN NUMBER, p_dfkey IN NUMBER, o_ckpid OUT NUMBER, o_ckpscn OUT NUMBER) IS BEGIN WITH vbtree1 AS (/* List of vb_key in incarnation A tree */ SELECT /*+ QB_NAME(vbtree1) MATERIALIZE */ vb_key, ckp_scn, ckp_id FROM vbdf v, (SELECT dbinc_key, NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = p_dbinc_a CONNECT BY PRIOR parent_dbinc_key = dbinc_key ) i WHERE v.df_key = p_dfkey AND v.dbinc_key = i.dbinc_key AND v.ckp_scn < i.next_reset_scn AND v.state != VBDF_OBSOLETE ) , vbtree2 AS (/* List of vb_key in incarnation B tree */ SELECT /*+ QB_NAME(vbtree2) MATERIALIZE */ vb_key, ckp_scn, ckp_id FROM vbdf v, (SELECT dbinc_key, NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = p_dbinc_b CONNECT BY PRIOR parent_dbinc_key = dbinc_key ) i WHERE v.df_key = p_dfkey AND v.dbinc_key = i.dbinc_key AND v.ckp_scn < i.next_reset_scn AND v.state != VBDF_OBSOLETE ) , samevb AS (/* Get the vb which is in both incarnations */ SELECT ckp_scn, ckp_id FROM vbtree1 JOIN vbtree2 USING (vb_key, ckp_scn, ckp_id) ORDER BY vb_key desc ) SELECT NVL(MAX(ckp_scn), 0), NVL(MAX(ckp_id), 0) INTO o_ckpid, o_ckpscn FROM samevb WHERE ROWNUM = 1; deb('orphan_common ckpid ' || o_ckpid || ', ckpscn ' || o_ckpscn, AM_DEBUG_MED); END orphan_common; /************************** BLOCK POOL QUERIES ************************** Following this description are a collection of routines containing a single INSERT/SELECT. For best possible performance we use different queries depending on the available data. So to build a backup piece in a CDB environment would use a different query than for non-CDB. Or to build a query that contains orphan backups is different than where there are no orphan backups. Since having large DML intermixed with procedural code is difficult to read, large DML will live in routines without procedural code. Failure to get build a plan correctly can mean we deliver corrupt virtual backups that are only detected after recovery or some SQL on the client discovers the corruption. Read the following and take extreme care when modifying the queries that construct read plans for any purpose. If additional note worthy constructions are found, please document them below. Keep these details in mind when modifying read plan queries. - CKP_ID: This is either the ckp_scn, or just a little higher if this is a read only backup and this was previously backed up. The main point is that deduplication will only remove the older version of any block, which means the lowest ckp_id you should find in a backup is that of the oldest level 0 backup. Which is maintained in VBDF.MIN_ID. - Purging: This is done by making an exact copy (same ckp_id, scn) of some blocks, then taking a write lock on the df and deleting all plans and releasing the lock, then deleting the old versions (with lower ckp_id, chunkno values). This means we might be building a new plan and reading new blocks while the old blocks and chunks are being deleted. This only works if we are always sure the blocks and chunks to be deleted are no longer needed. There exists a safemode check after we've deleting the plans that actually builds the oldest valid plan for the datafile. We then check that new plan to ensure it doesn't reference any of the chunks that are to be deleted. This is expensive, that's why it's only done in safemode. - Fuzzy blocks: These have an SCN greater than the ckp_scn of the backup. However they have a matching ckp_id as the backup. So we include matching ckp_id in the result set. Additionally we never deduplicate a fuzzy block as we need to know the ckp_id to know it is fuzzy. Block 1, Gap blocks, and Corrupt blocks are all fuzzy. We use that fact to ensure correctness. - Corrupt blocks: Corrupt blocks are written into the metadata as a gap block of 1. We are then able to treat them in the same manner as gaps. - Gap blocks: carry an SCN that matches the ckp_scn of the backup. Additionally filler blocks with the same SCN but different block numbers will be put into the blocks table. A filler block has a USED value of 0. That's how you know it's a filler block. These filler blocks allow us to omit or include other blocks based on their SCN. - Blocks after gap blocks: It's possible to have a gap, then for a later backup to provide the original block. When this happens a block with an SCN prior to the GAP SCN and a CKP_ID after the GAP CKP_ID is found. These blocks are marked with a flag in the data and then written with an SCN == CKP_ID. This ensures block sequencing is maintained even though true SCN order is out of sequence. Since corrupt blocks are written as GAP blocks, the mechanism works the same. - CDB: Pluggable databases can be individually backed up and restored. The pdbinc table maintains a list of exclusion ranges. These are SCN ranges that must be excluded from the backup. This is based on the pdbinc_key which is stored in the vbdf and for normal databases, the pdbinc_key is zero. - Orphan backups: If a user does a PITR to a time before backups already provided, those backups become orphan. Because of deduplication we may still need some blocks from those orphan backups. Thus computing a restore plan when orphan backups exists is more complex. SCN values across incarnations must be checked. Additionally, the order of backup deletion must remove the orphan backups before deleting any blocks from that last good backup for both incarnations. Eventually all orphan blocks will be deleted, but until that happens the slower more complex plan building is needed. - DLC: Delayed Logging Cleanout - After a transaction commits we scan the buffers changed and clean up the ITL values releasing locks. This operation is not logged. Because of this, when a new incarnation is created, the two backups that share a common incr_scn, should have a common range of blocks between the incr_scn and the reset_scn, but don't. They don't because it is possible that the original incarnation applied a DLC that was unavailable to the new incarnation. For this reason our incarnation query must join with the vbdf table and avoid any common block ranges. This also means we need to preserve block 0 of deleted backups until after orphan incarnations are resolved, just in case we lose the metadata. - Tricky possible scenario's. Look at each and ensure that as each line is purged, you still arrive at a correct answer for each remaining ckp_id. Remember that deduplication will remove older copies of a block. So ensure the effects of dedupe play into your computations. DBINC CKP_ID SCN (Incarnation reset scn 325) 1 200 190 1 300 1 410 190 2 350 2 400 375 2 500 2 600 375 new level 0 DBINC CKP_ID SCN (Corruption and Incarnation reset scn 325) 1 200 190 1 300 1 400 190 1 500 corrupt faked with scn 500 1 600 190 1 700 2 350 2 450 2 550 DBINC CKP_ID SCN (All backups level 0: try purge min_id=400) 1 200 190 1 300 gap block faked with scn 300 1 400 gap block faked with scn 400 1 500 190 DBINC CKP_ID SCN (Corruptions: min_id=200 then 500) 1 200 190 1 300 corrupt block with scn 300 1 400 out of order block with scn 400, was repaired on db 1 500 190 -- Level 0 backup with repaired block Your query should be able to derive the correct block for all the above scenarios at every ckp_id. Same is true for purging. Walk through purging at each ckp_id, and ensure you will derive the correct value. If you have any new interesting scenario's. Please add them as part of your fix to support them. */ -- -- PROCEDURE q_restore_fast(p_type IN NUMBER, -- KBRSPLBLD_ type p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_incrscn IN NUMBER, p_ckpscn IN NUMBER, p_absscn IN NUMBER, p_ckpid IN NUMBER, p_minckpid IN NUMBER, p_maxckpid IN NUMBER, p_dbinc_key IN NUMBER, p_firstblk IN NUMBER, p_lastblk IN NUMBER) IS BEGIN dbms_ra_int.info_start('q_restore_fast', 'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey); INSERT /*+ QB_NAME(q_restore_fast) OPT_PARAM('optimizer_dynamic_sampling' 0) OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false') OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none') OPT_PARAM('_optimizer_use_feedback' 'false') */ INTO plans_details (df_key, type, vb_key, blkrank, blockno, chunkno, numblks, coffset, numbytes, signature) SELECT p_dfkey, p_type, p_vbkey, 1 blkrank, blockno, chunkno, numblks, coffset, numbytes, signature FROM TABLE( collapse( CURSOR( SELECT /*+ QB_NAME(q_rfast_c) INDEX_RS_ASC(@q_rfast_c b@q_rfast_c blocks_u) NO_INDEX_FFS(@q_rfast_c b@q_rfast_c blocks_u) OPT_PARAM('optimizer_dynamic_sampling' 0) OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false') OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none') OPT_PARAM('_optimizer_use_feedback' 'false') */ blockno, scn, chunkno, used, coffset FROM blocks b WHERE df_key = p_dfkey AND blockno BETWEEN p_firstblk AND p_lastblk AND scn BETWEEN p_incrscn AND p_absscn AND ckp_id >= p_minckpid AND (ckp_id <= p_maxckpid OR dbinc_key <> p_dbinc_key) AND (scn < p_ckpscn OR ckp_id = p_ckpid) ORDER BY blockno, scn DESC, ckp_id DESC, chunkno DESC ) ) ); deb('q_restore_fast plan records ' || SQL%ROWCOUNT, AM_DEBUG_MED); COMMIT; dbms_ra_int.info_end; END q_restore_fast; -- -- PROCEDURE q_restore_incs(p_type IN NUMBER, -- KBRSPLBLD_ type p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_incrscn IN NUMBER, p_ckpscn IN NUMBER, p_absscn IN NUMBER, p_ckpid IN NUMBER, p_minckpid IN NUMBER, p_maxckpid IN NUMBER, p_dbinc_key IN NUMBER, p_deadinc IN NUMBER, p_orphaninc IN NUMBER, p_maxorphscn IN NUMBER, p_firstblk IN NUMBER, p_lastblk IN NUMBER) IS l_safeckpid NUMBER; BEGIN -- -- -- -- -- SELECT MIN(ckp_scn) INTO l_safeckpid FROM vbdf WHERE df_key = p_dfkey AND state = VBDF_COMPLETE; deb('q_restore_incs safe_ckpid ' || l_safeckpid || ', max_orphan_scn ' || p_maxorphscn || ', orphan_inc ' || p_orphaninc || ', deadinc ' || p_deadinc, AM_DEBUG_MED); dbms_ra_int.info_start('q_restore_incs', 'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey); INSERT /*+ QB_NAME(q_restore_incs) OPT_PARAM('optimizer_dynamic_sampling' 0) OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false') OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none') OPT_PARAM('_optimizer_use_feedback' 'false') */ INTO plans_details (df_key, type, vb_key, blkrank, blockno, chunkno, numblks, coffset, numbytes, signature) SELECT p_dfkey, p_type, p_vbkey, 1 blkrank, blockno, chunkno, numblks, coffset, numbytes, signature FROM TABLE( collapse( CURSOR( WITH vi AS ( SELECT /*+ MATERIALIZE */ v.dbinc_key , v.ckp_id FROM vbdf v , ( SELECT dbinc_key , NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = p_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key ) i WHERE v.dbinc_key = i.dbinc_key AND v.df_key = p_dfkey AND v.ckp_scn < i.next_reset_scn AND v.state <> VBDF_OBSOLETE ) , orphinc AS ( -- -- -- SELECT /*+ MATERIALIZE */ dbinc_key, reset_scn FROM dbinc START WITH dbinc_key = p_orphaninc CONNECT BY PRIOR parent_dbinc_key = dbinc_key ) SELECT /*+ QB_NAME(q_rincs_c) INDEX_RS_ASC(@q_rincs_c b@q_rincs_c blocks_u) NO_INDEX_FFS(@q_rincs_c b@q_rincs_c blocks_u) OPT_PARAM('optimizer_dynamic_sampling' 0) OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false') OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none') OPT_PARAM('_optimizer_use_feedback' 'false') NO_EXPAND */ blockno, scn, chunkno, used, coffset FROM blocks b WHERE df_key = p_dfkey AND blockno BETWEEN p_firstblk AND p_lastblk AND scn BETWEEN p_incrscn AND p_absscn AND ckp_id >= p_minckpid AND (ckp_id <= p_maxckpid OR dbinc_key <> p_dbinc_key) AND (scn < p_ckpscn OR ckp_id = p_ckpid) AND dbinc_key <> p_deadinc -- -- -- -- -- AND 'y' = CASE WHEN /* Blocks older than safe ckpid are always good */ ckp_id < l_safeckpid OR /* Blocks in matching incarnation are good */ dbinc_key = p_dbinc_key OR /* Blocks from current incarnation tree no dedupe */ ckp_id IN (SELECT ckp_id FROM vi) OR ( /* Block is in orphan incarnation */ p_deadinc = 0 /* only if are using orphan blks */ AND scn < p_maxorphscn /* deduped blocks only */ AND dbinc_key IN (SELECT dbinc_key FROM orphinc) ) THEN 'y' END ORDER BY blockno, scn DESC, ckp_id DESC, chunkno DESC ) ) ); deb('q_restore_incs plan records ' || SQL%ROWCOUNT, AM_DEBUG_MED); COMMIT; dbms_ra_int.info_end; END q_restore_incs ; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROCEDURE q_restore_cdb(p_type IN NUMBER, -- KBRSPLBLD_ type p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_incrscn IN NUMBER, p_ckpscn IN NUMBER, p_absscn IN NUMBER, p_ckpid IN NUMBER, p_minckpid IN NUMBER, p_maxckpid IN NUMBER, p_pdbinc_key IN NUMBER, p_dbinc_key IN NUMBER, p_deadinc IN NUMBER, p_orphaninc IN NUMBER, p_maxorphscn IN NUMBER, p_firstblk IN NUMBER, p_lastblk IN NUMBER, p_orphans IN BOOLEAN) IS l_safeckpid NUMBER; BEGIN -- IF p_orphans THEN -- SELECT MIN(ckp_scn) INTO l_safeckpid FROM vbdf WHERE df_key = p_dfkey AND state = VBDF_COMPLETE; ELSE l_safeckpid := BIGNUM; END IF; deb('q_restore_cdb safe_ckpid ' || l_safeckpid || ', max_orphan_scn ' || p_maxorphscn || ', orphan_inc ' || p_orphaninc || ', deadinc ' || p_deadinc, AM_DEBUG_MED); dbms_ra_int.info_start('q_restore_cdb', 'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey); INSERT /*+ QB_NAME(q_restore_cdb) OPT_PARAM('optimizer_dynamic_sampling' 0) OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false') OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none') OPT_PARAM('_optimizer_use_feedback' 'false') */ INTO plans_details (df_key, type, vb_key, blkrank, blockno, chunkno, numblks, coffset, numbytes, signature) SELECT p_dfkey, p_type, p_vbkey, 1 blkrank, blockno, chunkno, numblks, coffset, numbytes, signature FROM TABLE( collapse( CURSOR( WITH vi AS ( SELECT /*+ MATERIALIZE */ v.dbinc_key , v.ckp_id FROM vbdf v , ( SELECT dbinc_key , NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = p_dbinc_key CONNECT BY PRIOR parent_dbinc_key = dbinc_key ) i WHERE v.dbinc_key = i.dbinc_key AND v.df_key = p_dfkey AND v.ckp_scn < i.next_reset_scn AND v.state <> VBDF_OBSOLETE ) , pdbs AS ( SELECT /*+ MATERIALIZE */ inc_scn, begin_reset_scn FROM pdbinc START WITH pdbinc_key = p_pdbinc_key CONNECT BY PRIOR parent_pdbinc_key = pdbinc_key ) , orphinc AS ( -- -- -- SELECT /*+ MATERIALIZE */ dbinc_key, reset_scn FROM dbinc START WITH dbinc_key = p_orphaninc CONNECT BY PRIOR parent_dbinc_key = dbinc_key ) SELECT /*+ QB_NAME(q_rcdb_c) INDEX_RS_ASC(@q_rcdb_c b@q_rcdb_c blocks_u) NO_INDEX_FFS(@q_rcdb_c b@q_rcdb_c blocks_u) OPT_PARAM('optimizer_dynamic_sampling' 0) OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false') OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none') OPT_PARAM('_optimizer_use_feedback' 'false') NO_EXPAND */ blockno, scn, chunkno, used, coffset FROM blocks b WHERE df_key = p_dfkey AND blockno BETWEEN p_firstblk AND p_lastblk AND scn BETWEEN p_incrscn AND p_absscn AND ckp_id >= p_minckpid AND (ckp_id <= p_maxckpid OR dbinc_key <> p_dbinc_key) AND (scn < p_ckpscn OR ckp_id = p_ckpid) AND dbinc_key <> p_deadinc -- -- -- -- -- AND 'y' = CASE WHEN /* Blocks older than safe ckpid are always good */ ckp_id < l_safeckpid OR /* Blocks in matching incarnation are good */ dbinc_key = p_dbinc_key OR /* Blocks from current incarnation tree no dedupe */ ckp_id IN (SELECT ckp_id FROM vi) OR ( /* Block is in orphan incarnation */ p_deadinc = 0 /* only if are using orphan blks */ AND scn < p_maxorphscn /* deduped blocks only */ AND dbinc_key IN (SELECT dbinc_key FROM orphinc) ) THEN 'y' END -- -- AND NOT EXISTS ( SELECT NULL FROM pdbs WHERE b.scn >= inc_scn AND b.scn < begin_reset_scn ) ORDER BY blockno, scn DESC, ckp_id DESC, chunkno DESC ) ) ); deb('q_restore_cdb plan records ' || SQL%ROWCOUNT, AM_DEBUG_MED); COMMIT; dbms_ra_int.info_end; END q_restore_cdb; -- -- -- PROCEDURE q_purge_basic(p_type IN NUMBER, -- KBRSPLBLD_ type p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_dbkey IN NUMBER, p_currinc IN NUMBER, p_ckpscn IN NUMBER, p_absscn IN NUMBER, p_ckpid IN NUMBER, p_minckpid IN NUMBER) IS l_toobig NUMBER; BEGIN deb('q_purge_basic ckpid ' || p_ckpid || ', minid ' || p_minckpid, AM_DEBUG_MED); -- -- -- -- -- -- IF p_type = KBRSPLBLD_OPTPURGE THEN l_toobig := f_chunksize(p_dbkey) * dbms_ra_scheduler.s_purge_opt_pct; ELSE l_toobig := BIGNUM; END IF; dbms_ra_int.info_start('q_purge_basic', 'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey); INSERT /*+ QB_NAME(q_purge_basic) OPT_PARAM('optimizer_dynamic_sampling' 0) OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false') OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none') OPT_PARAM('_optimizer_use_feedback' 'false') */ INTO plans_details (df_key, type, vb_key, blkrank, blockno, chunkno, numblks, coffset, numbytes, signature) WITH deadblks AS ( -- SELECT --+ QB_NAME(deadblks) blockno, chunkno, coffset FROM TABLE(skip_last(CURSOR( SELECT /*+ QB_NAME(q_pbas_c) OPT_PARAM('optimizer_dynamic_sampling' 0) OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false') OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none') OPT_PARAM('_optimizer_use_feedback' 'false') NO_INDEX_FFS(@q_pbas_c b@q_pbas_c blocks_u) INDEX_RS_ASC(@q_pbas_c b@q_pbas_c blocks_u) */ blockno, ckp_id, scn, chunkno, used, coffset FROM blocks b WHERE df_key = p_dfkey /* it is a FULL file scan */ AND scn <= p_absscn AND ckp_id <= p_ckpid AND (scn < p_ckpscn OR ckp_id = p_ckpid) -- -- -- -- AND (scn != ckp_id OR scn >= p_minckpid OR blockno <= 1) AND CASE -- -- -- -- WHEN blockno > 0 THEN NULL WHEN EXISTS ( SELECT NULL /* chunk is level 0 chunk */ FROM vbdf WHERE df_key = p_dfkey AND db_key = p_dbkey AND ckp_id = min_id AND krbph_dfkey = p_dfkey AND krbph_chunkno = b.chunkno AND ckp_scn > ( SELECT MAX(ckp_scn) FROM vbdf WHERE df_key = p_dfkey AND ckp_id = min_id /* means lvl 0 */ AND state = VBDF_OBSOLETE ) ) OR EXISTS ( SELECT krbph_dfkey , krbph_chunkno /* chunk is in use */ FROM vbdf v, bp p WHERE v.vb_key = p.vb_key AND v.db_key = p_dbkey AND p.db_key = p_dbkey AND p.status != 'D' AND krbph_dfkey = p_dfkey AND krbph_chunkno = b.chunkno ) OR EXISTS ( SELECT NULL /* chunk is in use */ FROM vbdf v, bp p WHERE v.vb_key = p.vb_key AND v.db_key = p_dbkey AND p.db_key = p_dbkey AND new_krbph IS NOT NULL AND p.status != 'D' AND krbph_dfkey = p_dfkey AND new_krbph = b.chunkno ) THEN '!' -- this entry must be excluded END IS NULL ORDER BY blockno, scn DESC, ckp_id DESC, chunkno DESC ))) ) , deadchunks AS ( -- SELECT DISTINCT chunkno FROM deadblks ) , saveblks AS ( -- SELECT /*+ QB_NAME(saveblks) NO_INDEX_FFS(@saveblks b@saveblks blocks_c) INDEX_RS_ASC(@saveblks b@saveblks blocks_c) LEADING(@saveblks b@saveblks d@saveblks d2@deadb b2@dup) USE_HASH(@saveblks b@saveblks) USE_HASH(@saveblks d@saveblks) USE_HASH(@saveblks d2@deadb) USE_NL(@saveblks b2@dup) SWAP_JOIN_INPUTS(@saveblks d@saveblks) */ b.chunkno, b.blockno, coffset, used, scn, -- -- ROW_NUMBER() OVER ( PARTITION BY b.chunkno, b.coffset ORDER BY b.blockno ) freq, -- -- -- ROW_NUMBER() OVER ( PARTITION BY blockno ORDER BY blockno, scn DESC, ckp_id DESC, b.chunkno DESC ) rernk FROM blocks b , deadchunks d WHERE b.df_key = p_dfkey AND b.chunkno = d.chunkno AND NOT EXISTS ( SELECT /*+ QB_NAME(deadb) HASH_AJ */ NULL FROM deadblks d2 WHERE d2.chunkno = d.chunkno AND d2.blockno = b.blockno AND d2.coffset = b.coffset ) AND NOT EXISTS ( -- avoid copying a block if it is a duplicate SELECT /*+ QB_NAME(dup) NO_INDEX_FFS(@dup b2@dup blocks_u) INDEX_RS_ASC(@dup b2@dup blocks_u) */ NULL FROM blocks b2 WHERE b2.df_key = p_dfkey AND b2.blockno = b.blockno AND b2.scn = b.scn AND b2.ckp_id = b.ckp_id AND b2.chunkno > b.chunkno ) ) , blkgroups -- -- -- -- -- AS ( SELECT --+ QB_NAME(bgrp) blockno, scn, chunkno, coffset, used, rernk, CASE WHEN LAG((rernk * DBMS_RA_INT.UB8MAXVAL) + (chunkno * MAXCHUNKSIZE) + coffset + used) OVER (ORDER BY rernk, blockno) = ((rernk * DBMS_RA_INT.UB8MAXVAL) + (chunkno * MAXCHUNKSIZE) + coffset) THEN NULL ELSE 1 END bg FROM saveblks WHERE freq = 1 ) , groups -- AS ( SELECT --+ QB_NAME(grp) blockno, scn, chunkno, coffset, used, rernk, SUM(bg) OVER (PARTITION BY rernk, chunkno ORDER BY blockno) g FROM blkgroups UNION ALL SELECT --+ QB_NAME(deadchunks) -10 blockno, 0 scn, chunkno, 0 coffset, 1 used, 0 rernk, 0 g FROM deadchunks ) , gsize -- -- AS ( SELECT g.*, SUM(used) OVER (PARTITION BY chunkno) chunksize FROM groups g ) SELECT --+ QB_NAME(ins) p_dfkey, KBRSPLBLD_PURGE, p_vbkey, rernk blkrank, MIN(blockno) blockno, chunkno, COUNT(blockno) numblks, MIN(coffset) coffset, SUM(used) numbytes, null signature FROM gsize WHERE chunksize < l_toobig GROUP BY rernk, chunkno, g ORDER BY blkrank, blockno, chunkno; deb('q_purge_basic plan records ' || SQL%ROWCOUNT, AM_DEBUG_MED); COMMIT; dbms_ra_int.info_end; END q_purge_basic; -- -- PROCEDURE q_purge_orphan(p_type IN NUMBER, -- KBRSPLBLD_ type p_dbkey IN NUMBER, p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_ckpscn IN NUMBER, p_absscn IN NUMBER, p_ckpid IN NUMBER, p_minckpid IN NUMBER, p_maxckpid IN NUMBER, p_dbinc_key IN NUMBER, p_deadinc IN NUMBER, -- Orphan inc we no need p_orphaninc IN NUMBER) -- Orphan block inc IS l_maxscn NUMBER; l_maxid NUMBER; l_deadvb NUMBER; l_orph NUMBER; l_currinc NUMBER; BEGIN dbms_ra_int.info_start('q_purge_orphan_chunk', 'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey); deb('q_purge_orphan dbinc ' || p_dbinc_key || ', deadinc ' || p_deadinc || ', orphaninc ' || p_orphaninc, AM_DEBUG_MED); -- -- IF p_deadinc > 0 THEN SELECT MAX(vb_key) INTO l_deadvb FROM vbdf WHERE dbinc_key = p_deadinc AND df_key = p_dfkey; l_orph := 0; /* we have a dead inc, we do not want to compute the tree */ ELSE l_deadvb := 0; l_orph := p_orphaninc; /* We need a tree to avoid */ END IF; -- -- SELECT dbinc_key INTO l_currinc FROM (SELECT dbinc_key FROM vbdf WHERE df_key = p_dfkey ORDER BY vb_key DESC ) WHERE ROWNUM = 1; -- -- -- -- -- -- -- -- -- INSERT /*+ QB_NAME(q_purge_orphan_chunk) OPT_PARAM('optimizer_dynamic_sampling' 0) OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false') OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none') OPT_PARAM('_optimizer_use_feedback' 'false') */ INTO plans_details (df_key, type, vb_key, blkrank, blockno, chunkno, numblks, coffset, numbytes, signature) WITH vbtree AS ( /* List of vb_key in current inc tree */ SELECT /*+ QB_NAME(vbtree) MATERIALIZE */ vb_key FROM vbdf v, (SELECT dbinc_key, NVL(PRIOR reset_scn, BIGNUM) next_reset_scn FROM dbinc START WITH dbinc_key = l_currinc CONNECT BY PRIOR parent_dbinc_key = dbinc_key ) i WHERE v.df_key = p_dfkey AND v.dbinc_key = i.dbinc_key AND v.ckp_scn < i.next_reset_scn AND v.state != VBDF_OBSOLETE ) , deadvb AS ( SELECT vb_key FROM vbdf WHERE vb_key NOT IN (SELECT vb_key FROM vbtree) AND df_key = p_dfkey AND state != VBDF_OBSOLETE ORDER BY vb_key ) , orphinc AS ( SELECT /*+ MATERIALIZE */ dbinc_key FROM dbinc START WITH dbinc_key = l_orph CONNECT BY PRIOR parent_dbinc_key = dbinc_key ) , chunk_inuse AS ( SELECT /*+ QB_NAME(chunk_inuse) MATERIALIZE */ krbph_chunkno, new_krbph FROM vbdf JOIN bp USING (db_key, vb_key) WHERE vb_key < p_vbkey AND db_key = p_dbkey AND status != 'D' AND krbph_dfkey = p_dfkey ) SELECT /*+ QB_NAME(ins) */ p_dfkey, KBRSPLBLD_PURGE, p_vbkey, 0 blkrank, -10 blockno, chunkno, 1 numblks, 0 coffset, 1 numbytes, null signature FROM chunks WHERE df_key = p_dfkey -- -- AND (dbinc_key = p_deadinc OR dbinc_key <> p_orphaninc) -- -- -- -- AND ((clean_key <= l_deadvb AND clean_key > 0) OR clean_key IN (SELECT vb_key FROM deadvb)) AND dbinc_key NOT IN (SELECT dbinc_key FROM orphinc) AND chunkno NOT IN (SELECT krbph_chunkno FROM chunk_inuse) AND chunkno NOT IN (SELECT new_krbph FROM chunk_inuse); deb('q_purge_orphan dead chunks ' || SQL%ROWCOUNT, AM_DEBUG_MED); COMMIT; dbms_ra_int.info_end; -- -- -- IF p_deadinc = 0 THEN dbms_ra_int.info_start('q_purge_orphan_blk', 'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey); -- -- orphan_common(p_dbinc_key, p_orphaninc, p_dfkey, l_maxscn, l_maxid); INSERT /*+ QB_NAME(q_purge_basic) OPT_PARAM('optimizer_dynamic_sampling' 0) OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false') OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none') OPT_PARAM('_optimizer_use_feedback' 'false') */ INTO plans_details (df_key, type, vb_key, blkrank, blockno, chunkno, numblks, coffset, numbytes, signature) WITH deadblks AS ( -- SELECT --+ QB_NAME(deadblks) blockno, chunkno, coffset FROM blocks b WHERE df_key = p_dfkey AND scn >= l_maxscn AND b.ckp_id <> l_maxid AND dbinc_key IN ( SELECT /*+ MATERIALIZE */ dbinc_key FROM dbinc START WITH dbinc_key = p_orphaninc CONNECT BY PRIOR parent_dbinc_key = dbinc_key ) AND CASE -- -- -- -- WHEN blockno > 0 THEN NULL WHEN EXISTS ( SELECT NULL /* chunk is level 0 chunk */ FROM vbdf WHERE df_key = p_dfkey AND db_key = p_dbkey AND ckp_id = min_id AND krbph_dfkey = p_dfkey AND krbph_chunkno = b.chunkno AND ckp_scn > ( SELECT MAX(ckp_scn) FROM vbdf WHERE df_key = p_dfkey AND ckp_id = min_id /* means lvl 0 */ AND state = VBDF_OBSOLETE ) ) OR EXISTS ( SELECT krbph_dfkey , krbph_chunkno /* chunk is in use */ FROM vbdf v, bp p WHERE v.vb_key = p.vb_key AND v.db_key = p_dbkey AND p.db_key = p_dbkey AND p.status != 'D' AND krbph_dfkey = p_dfkey AND krbph_chunkno = b.chunkno ) OR EXISTS ( SELECT NULL /* chunk is in use */ FROM vbdf v, bp p WHERE v.vb_key = p.vb_key AND v.db_key = p_dbkey AND p.db_key = p_dbkey AND new_krbph IS NOT NULL AND p.status != 'D' AND krbph_dfkey = p_dfkey AND new_krbph = b.chunkno ) THEN '!' -- this entry must be excluded END IS NULL ORDER BY blockno, scn DESC, ckp_id DESC, chunkno DESC ) , deadchunks AS ( -- SELECT DISTINCT chunkno FROM deadblks ) , saveblks AS ( -- SELECT /*+ QB_NAME(saveblks) NO_INDEX_FFS(@saveblks b@saveblks blocks_c) INDEX_RS_ASC(@saveblks b@saveblks blocks_c) LEADING(@saveblks b@saveblks d@saveblks d2@deadb b2@dup) USE_HASH(@saveblks b@saveblks) USE_HASH(@saveblks d@saveblks) USE_HASH(@saveblks d2@deadb) USE_NL(@saveblks b2@dup) SWAP_JOIN_INPUTS(@saveblks d@saveblks) */ b.chunkno, b.blockno, coffset, used, scn, -- -- ROW_NUMBER() OVER ( PARTITION BY b.chunkno, b.coffset ORDER BY b.blockno ) freq, -- -- -- ROW_NUMBER() OVER ( PARTITION BY blockno ORDER BY blockno, scn DESC, ckp_id DESC, b.chunkno DESC ) rernk FROM blocks b , deadchunks d WHERE b.df_key = p_dfkey AND b.chunkno = d.chunkno AND NOT EXISTS ( SELECT /*+ QB_NAME(deadb) HASH_AJ */ NULL FROM deadblks d2 WHERE d2.chunkno = d.chunkno AND d2.blockno = b.blockno AND d2.coffset = b.coffset ) AND NOT EXISTS ( -- avoid copying a block if it is a duplicate SELECT /*+ QB_NAME(dup) NO_INDEX_FFS(@dup b2@dup blocks_u) INDEX_RS_ASC(@dup b2@dup blocks_u) */ NULL FROM blocks b2 WHERE b2.df_key = p_dfkey AND b2.blockno = b.blockno AND b2.scn = b.scn AND b2.ckp_id = b.ckp_id AND b2.chunkno > b.chunkno ) ) , blkgroups -- -- -- -- -- AS ( SELECT --+ QB_NAME(bgrp) blockno, scn, chunkno, coffset, used, rernk, CASE WHEN LAG((rernk * DBMS_RA_INT.UB8MAXVAL) + (chunkno * MAXCHUNKSIZE) + coffset + used) OVER (ORDER BY rernk, blockno) = ((rernk * DBMS_RA_INT.UB8MAXVAL) + (chunkno * MAXCHUNKSIZE) + coffset) THEN NULL ELSE 1 END bg FROM saveblks WHERE freq = 1 ) , groups -- AS ( SELECT --+ QB_NAME(grp) blockno, scn, chunkno, coffset, used, rernk, SUM(bg) OVER (PARTITION BY rernk, chunkno ORDER BY blockno) g FROM blkgroups UNION ALL SELECT --+ QB_NAME(deadchunks) -10 blockno, 0 scn, chunkno, 0 coffset, 1 used, 0 rernk, 0 g FROM deadchunks ) SELECT --+ QB_NAME(ins) p_dfkey, KBRSPLBLD_PURGE, p_vbkey, rernk blkrank, MIN(blockno) blockno, chunkno, COUNT(blockno) numblks, MIN(coffset) coffset, SUM(used) numbytes, null signature FROM groups GROUP BY rernk, chunkno, g ORDER BY blkrank, blockno, chunkno; deb('q_purge_orphan blk records ' || SQL%ROWCOUNT, AM_DEBUG_MED); COMMIT; dbms_ra_int.info_end; END IF; -- s_purge_dbinc := p_orphaninc; END q_purge_orphan; -- -- -- PROCEDURE q_purge_dup(p_type IN NUMBER, p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_dbkey IN NUMBER, p_currinc IN NUMBER, p_fuzdif IN NUMBER, p_minscn IN NUMBER) IS l_maxckpid NUMBER; BEGIN SELECT MAX(ckp_id) INTO l_maxckpid FROM vbdf WHERE df_key = p_dfkey AND state = VBDF_COMPLETE; dbms_ra_int.info_start('q_purge_dup', 'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey); INSERT /*+ QB_NAME(q_purge_dup) */ INTO plans_details (df_key, type, vb_key, blkrank, blockno, chunkno, numblks, coffset, numbytes, signature) WITH rnkblocks -- -- -- AS ( SELECT /*+ QB_NAME(rnkblocks) */ chunkno, blockno, scn, coffset, used, ROW_NUMBER() OVER ( PARTITION BY blockno, scn, CASE WHEN ckp_id <= scn + p_fuzdif THEN ckp_id ELSE 0 END ORDER BY blockno, scn DESC, ckp_id DESC, chunkno DESC ) rn FROM blocks WHERE df_key = p_dfkey AND ckp_id <= l_maxckpid ) , deadblks -- AS ( SELECT --+ QB_NAME(deadblks) chunkno, blockno, scn, coffset, used FROM rnkblocks WHERE rn > 1 ) , deadchunks -- AS ( SELECT DISTINCT chunkno FROM deadblks ) , saveblks AS ( -- SELECT --+ QB_NAME(saveblks) b.chunkno, b.blockno, coffset, used, scn, -- -- ROW_NUMBER() OVER ( PARTITION BY b.chunkno, b.coffset ORDER BY b.blockno, b.chunkno, b.coffset ) freq, -- -- -- ROW_NUMBER() OVER ( PARTITION BY blockno ORDER BY blockno, scn DESC, ckp_id DESC, b.chunkno DESC ) rernk FROM blocks b, deadchunks d WHERE b.df_key = p_dfkey AND b.chunkno = d.chunkno AND (b.blockno, b.coffset) NOT IN (SELECT blockno, coffset FROM deadblks WHERE chunkno = b.chunkno) ) , blkgroups -- -- -- -- -- AS ( SELECT --+ QB_NAME(bgrp) blockno, scn, chunkno, coffset, used, rernk, CASE WHEN LAG((rernk * DBMS_RA_INT.UB8MAXVAL) + (chunkno * MAXCHUNKSIZE) + coffset + used) OVER (ORDER BY rernk, blockno) = ((rernk * DBMS_RA_INT.UB8MAXVAL) + (chunkno * MAXCHUNKSIZE) + coffset) THEN NULL ELSE 1 END bg FROM saveblks WHERE freq = 1 ) , groups -- AS ( SELECT --+ QB_NAME(grp) blockno, scn, chunkno, coffset, used, rernk, SUM(bg) OVER (PARTITION BY rernk, chunkno ORDER BY blockno) g FROM blkgroups UNION ALL SELECT --+ QB_NAME(deadchunks) -10 blockno, 0 scn, chunkno, 0 coffset, 1 used, 0 rernk, 0 g FROM deadchunks ) SELECT --+ QB_NAME(ins) p_dfkey, KBRSPLBLD_PURGE, p_vbkey, rernk blkrank, MIN(blockno) blockno, chunkno, COUNT(blockno) numblks, MIN(coffset) coffset, SUM(used) numbytes, NULL signature FROM groups GROUP BY rernk, chunkno, g ORDER BY blkrank, blockno, chunkno; deb('q_purge_dup plan records ' || SQL%ROWCOUNT, AM_DEBUG_MED); COMMIT; dbms_ra_int.info_end; END q_purge_dup; -- -- -- -- -- -- PROCEDURE q_purge_all(p_dfkey IN NUMBER, p_vbkey IN NUMBER, p_dbkey IN NUMBER) IS BEGIN dbms_ra_int.info_start('q_purge_all', 'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey); INSERT /*+ QB_NAME(q_purge_all) */ INTO plans_details (df_key, type, vb_key, blkrank, blockno, chunkno, numblks, coffset) SELECT p_dfkey, KBRSPLBLD_PURGE, p_vbkey, 1 blkrank, -10 blockno, chunkno, 1 numblks, 0 coffset FROM chunks c WHERE df_key = p_dfkey AND (filesize > 0 OR dbms_ra_scheduler.s_current_task IS NULL) AND NOT EXISTS ( -- SELECT /*+ QB_NAME(x1) */ NULL FROM vbdf v, bp p WHERE v.vb_key = p.vb_key AND v.db_key = p_dbkey AND p.db_key = p_dbkey AND p.status != 'D' AND krbph_chunkno = c.chunkno AND krbph_dfkey = p_dfkey ) AND NOT EXISTS /* @@RG DO I CARE ABOUT CHUNKS IN FLIGHT? */ ( -- SELECT /*+ QB_NAME(x2) */ NULL FROM vbdf v WHERE v.krbph_dfkey = p_dfkey AND v.new_krbph = c.chunkno AND v.vb_key = p_vbkey AND v.state = VBDF_COMPLETE ); deb('q_purge_all plan records ' || SQL%ROWCOUNT, AM_DEBUG_MED); COMMIT; dbms_ra_int.info_end; END q_purge_all; -- FUNCTION collapse ( i_cur IN collapse_blocks_c ) RETURN collapse_blocks_t PIPELINED IS -- l_limit CONSTANT NUMBER := 10 * 1024; -- l_blocknos dbms_sql.number_table; l_scns dbms_sql.number_table; l_chunknos dbms_sql.number_table; l_useds dbms_sql.number_table; l_coffsets dbms_sql.number_table; -- l_initialized BOOLEAN := FALSE; l_pchunkno NUMBER := -2; l_pblockno NUMBER := -2; l_pcoffset NUMBER := -2; -- l_pblockmn NUMBER; -- min block for a given range l_numblks PLS_INTEGER; -- count of blocks in the range l_coffset NUMBER; -- min offset l_used NUMBER; -- sum of all used values l_signature NUMBER; -- sum of all scn values -- l_e collapse_b_t; -- PROCEDURE fill IS BEGIN l_e.blockno := l_pblockmn; l_e.chunkno := l_pchunkno; l_e.numblks := l_numblks; l_e.coffset := l_coffset; l_e.numbytes := l_used; l_e.signature := l_signature; END fill; BEGIN LOOP FETCH i_cur BULK COLLECT INTO l_blocknos, l_scns, l_chunknos, l_useds, l_coffsets LIMIT l_limit; EXIT WHEN l_blocknos.COUNT = 0; FOR i IN 1..l_blocknos.COUNT LOOP CONTINUE WHEN (l_pblockno = l_blocknos(i)); IF (l_pchunkno <> l_chunknos(i) OR l_pcoffset <> l_coffsets(i)) THEN IF (l_initialized) THEN fill; PIPE ROW(l_e); ELSE l_initialized := TRUE; END IF; l_pblockmn := l_blocknos(i); l_pcoffset := l_coffsets(i); l_numblks := 0; l_used := 0; l_coffset := l_coffsets(i); l_signature := 0; END IF; l_pblockno := l_blocknos(i); l_pcoffset := l_pcoffset + l_useds(i); l_numblks := l_numblks + 1; l_pchunkno := l_chunknos(i); l_used := l_used + l_useds(i); l_signature := l_signature + l_scns(i); END LOOP; END LOOP; IF (i_cur%ISOPEN) THEN CLOSE i_cur; END IF; IF (l_initialized) THEN fill; PIPE ROW(l_e); END IF; RETURN; EXCEPTION WHEN NO_DATA_NEEDED THEN IF (i_cur%ISOPEN) THEN CLOSE i_cur; END IF; RETURN; WHEN OTHERS THEN save_error; deb ( 'collapse(): ' || sys.dbms_utility.format_error_backtrace , AM_DEBUG_MED ); RAISE; END collapse; -- FUNCTION skip_last ( i_cur IN skip_last_blocks_c ) RETURN skip_last_blocks_t PIPELINED IS -- l_limit CONSTANT NUMBER := 10 * 1024; -- l_blocknos dbms_sql.number_table; l_ckpids dbms_sql.number_table; l_scns dbms_sql.number_table; l_chunknos dbms_sql.number_table; l_useds dbms_sql.number_table; l_coffsets dbms_sql.number_table; -- l_pblockno NUMBER := -2; -- l_e skip_last_bin_t; BEGIN LOOP FETCH i_cur BULK COLLECT INTO l_blocknos, l_ckpids, l_scns, l_chunknos, l_useds, l_coffsets LIMIT l_limit; EXIT WHEN l_blocknos.COUNT = 0; FOR i IN 1..l_blocknos.COUNT LOOP -- -- IF (l_pblockno <> l_blocknos(i)) THEN l_pblockno := l_blocknos(i); CONTINUE; END IF; l_e.blockno := l_blocknos(i); l_e.ckp_id := l_ckpids(i); l_e.scn := l_scns(i); l_e.chunkno := l_chunknos(i); l_e.used := l_useds(i); l_e.coffset := l_coffsets(i); PIPE ROW(l_e); END LOOP; END LOOP; IF (i_cur%ISOPEN) THEN CLOSE i_cur; END IF; RETURN; EXCEPTION WHEN NO_DATA_NEEDED THEN IF (i_cur%ISOPEN) THEN CLOSE i_cur; END IF; RETURN; WHEN OTHERS THEN save_error; deb ( 'skip_last(): ' || sys.dbms_utility.format_error_backtrace , AM_DEBUG_MED ); RAISE; END skip_last; $IF FALSE $THEN -- FUNCTION collapse ( i_cur IN blocks_c , i_flags IN collapse_flags_t DEFAULT collapse_default ) RETURN collapse_blocks_t PIPELINED -- IS -- l_limit CONSTANT NUMBER := 10 * 1024; -- l_blocknos dbms_sql.number_table; l_scns dbms_sql.number_table; l_chunknos dbms_sql.number_table; l_useds dbms_sql.number_table; l_coffsets dbms_sql.number_table; -- l_p BINARY_INTEGER; -- l_lmxv b_t; -- -- -- -- -- -- -- l_o collapse_t; -- l_discard_gap_blocks BOOLEAN := BITAND(i_flags, discard_gap_blocks) = discard_gap_blocks; BEGIN -- -- l_o.chunkno := -1; LOOP -- -- IF (l_p IS NOT NULL) THEN l_lmxv.blockno := l_blocknos(l_p); l_lmxv.scn := l_scns(l_p); l_lmxv.chunkno := l_chunknos(l_p); l_lmxv.coffset := l_coffsets(l_p); l_lmxv.used := l_useds(l_p); END IF; -- FETCH i_cur BULK COLLECT INTO l_blocknos, l_scns, l_chunknos, l_useds, l_coffsets LIMIT l_limit; EXIT WHEN (l_blocknos.COUNT = 0); -- IF (l_lmxv.blockno IS NULL) THEN -- l_p := 0; ELSE l_blocknos(0) := l_lmxv.blockno; l_scns(0) := l_lmxv.scn; l_chunknos(0) := l_lmxv.chunkno; l_coffsets(0) := l_lmxv.coffset; l_useds(0) := l_lmxv.used; -- l_p := -1; END IF; LOOP LOOP -- -- -- -- -- -- -- -- -- l_p := l_p + 1; EXIT WHEN (l_p + 1 > l_blocknos.LAST OR l_blocknos(l_p) <> l_blocknos(l_p + 1)); END LOOP; -- EXIT WHEN l_p = l_blocknos.LAST; -- IF ( l_chunknos(l_p) <> l_o.chunkno OR l_coffsets(l_p) <> l_o.coffset + l_o.numbytes ) THEN IF (l_o.blockno IS NOT NULL) THEN PIPE ROW(l_o); END IF; -- l_o.blockno := l_blocknos(l_p); l_o.chunkno := l_chunknos(l_p); l_o.numblks := 0; l_o.coffset := l_coffsets(l_p); l_o.numbytes := 0; l_o.signature := 0; END IF; -- l_o.numblks := l_o.numblks + 1; l_o.numbytes := l_o.numbytes + l_useds(l_p); l_o.signature := l_o.signature + l_scns(l_p); END LOOP; END LOOP; -- -- -- -- IF (l_lmxv.blockno IS NOT NULL) THEN -- we have at least something to deal with IF ( l_lmxv.chunkno <> l_o.chunkno OR l_lmxv.coffset <> l_o.coffset + l_o.numbytes ) THEN -- IF (l_o.blockno IS NOT NULL) THEN PIPE ROW(l_o); END IF; -- l_o.blockno := l_lmxv.blockno; l_o.chunkno := l_lmxv.chunkno; l_o.numblks := 0; l_o.coffset := l_lmxv.coffset; l_o.numbytes := 0; l_o.signature := 0; END IF; l_o.numblks := l_o.numblks + 1; l_o.numbytes := l_o.numbytes + l_lmxv.used; l_o.signature := l_o.signature + l_lmxv.scn; -- PIPE ROW(l_o); END IF; -- IF (i_cur%ISOPEN) THEN CLOSE i_cur; END IF; RETURN; EXCEPTION WHEN NO_DATA_NEEDED THEN IF (i_cur%ISOPEN) THEN CLOSE i_cur; END IF; RETURN; WHEN OTHERS THEN deb ( 'collapse(): ' || sys.dbms_utility.format_error_backtrace , AM_DEBUG_MED ); RAISE; END collapse; $END END dbms_ra_pool; >>> define revalidate_dg_synonym <<< alter synonym sys.rs$dg compile >>> define create_instance_startup_job <<< begin dbms_scheduler.create_job ( job_name => 'ra$trigger_job' , job_type => 'plsql_block' , job_action => 'begin ' || 'dbms_ra_scheduler.init (p_instance_only => true, ' || 'p_repair => false);' || 'dbms_scheduler.disable(''ra$trigger_job'', true);' || 'end;' , enabled => false , auto_drop => false ); end; >>> define create_instance_startup_trigger <<< create or replace trigger ba_startup after startup on database begin dbms_scheduler.enable('ra$trigger_job'); end; >>> define create_instance_shutdown_trigger <<< create or replace trigger ba_shutdown before shutdown on database begin dbms_ra_scheduler.stop (p_instance_only => true); end; >>> define drop_orsownerfn <<< drop function dbms_rai_owner >>> define drop_orsverifierfn <<< drop function dbms_rai_verifier >>> define drop_am_inst_addresses <<< drop function dbms_rai_inst_addresses >>> define drop_am_sbt_parms <<< drop procedure dbms_rai_sbt_parms >>> define drop_am_url <<< drop procedure dbms_rai_url >>> define drop_am_wallet2url <<< drop procedure dbms_rai_wallet2url >>> define drop_avm_throttle_alloc <<< drop procedure dbms_rai_throttle_alloc >>> define drop_dbms_rs_scheduler <<< drop package dbms_ra_scheduler >>> define drop_dbms_rs_storage <<< drop package dbms_ra_storage >>> define drop_dbms_rs_int <<< drop package dbms_ra_int >>> define drop_dbms_rs <<< drop package dbms_ra >>> define drop_dbms_rs_dump <<< drop package dbms_ra_dump >>> define drop_dbms_rs_pool <<< drop package dbms_ra_pool >>> define drop_ba_resync_clear_error <<< drop procedure dbms_rai_fix_error >>> define drop_populate_rsr_key <<< drop procedure dbms_rai_populate_rsr_key >>> define upgcat_bdf_21057275 <<< declare CURSOR pfiles IS SELECT df_key, vb_key FROM vbdf WHERE pdbinc_key <> 0; l_value VARCHAR2(1024) := NULL; l_maxfuzzyscn NUMBER; l_maxckpscn NUMBER; l_minckpscn NUMBER; begin -- begin SELECT value INTO l_value FROM config WHERE name = '_build'; exception when no_data_found then null; end; -- -- IF (l_value IS NOT NULL AND (TO_DATE(substr(l_value, 0, INSTR(l_value, ' ')), 'DD-MM-YYYY') > TO_DATE('05-07-2015', 'DD-MM-YYYY'))) THEN RETURN; END IF; -- FOR bs IN ( SELECT s.bs_key key FROM bs s, bp p WHERE s.bs_key = p.bs_key AND s.multi_section = 'Y' AND p.vb_key IS NOT NULL AND p.status <> 'D' AND p.piece# = 1) LOOP SELECT MAX(ckp_scn), MIN(ckp_scn), MAX(abs_scn) INTO l_maxckpscn, l_minckpscn, l_maxfuzzyscn FROM vbdf WHERE vb_key IN (SELECT vb_key FROM bp WHERE bs_key = bs.key AND vb_key IS NOT NULL); IF (l_maxfuzzyscn < l_maxckpscn) THEN l_maxfuzzyscn := l_maxckpscn; END IF; UPDATE bdf SET ckp_scn = l_minckpscn, abs_fuzzy_scn = CASE WHEN l_maxfuzzyscn > l_minckpscn THEN l_maxfuzzyscn ELSE 0 END WHERE bs_key = bs.key; UPDATE vbdf SET ckp_scn = (SELECT ckp_scn FROM bdf WHERE bs_key = bs.key) WHERE vb_key IN (SELECT vb_key FROM bp WHERE bs_key = bs.key AND vb_key IS NOT NULL); END LOOP; -- -- FOR x IN pfiles LOOP DELETE FROM plans_details WHERE df_key = x.df_key AND vb_key = x.vb_key; DELETE FROM plans WHERE df_key = x.df_key AND vb_key = x.vb_key; END LOOP; -- -- UPDATE config SET value = to_char(greatest(300, to_number(value))) WHERE name = '_interrupt_max'; commit; end; >>> define mark_build <<< BEGIN MERGE INTO config USING dual ON (name = '_build') WHEN MATCHED THEN UPDATE SET value = '10-10-2017 19:40:25 RDBMS_12.2.0.1.0DBRU_LINUX.X64_171010' WHEN NOT MATCHED THEN INSERT (name, value) VALUES ('_build', '10-10-2017 19:40:25 RDBMS_12.2.0.1.0DBRU_LINUX.X64_171010'); commit; END; >>> define upgcat_bdf_21548299 <<< declare l_value VARCHAR2(1024) := NULL; begin -- -- begin SELECT value INTO l_value FROM config WHERE name = '_build'; exception when no_data_found then null; end; -- IF (l_value IS NOT NULL AND (TO_DATE(SUBSTR(l_value, 0, INSTR(l_value, ' ')), 'DD-MM-YYYY') > TO_DATE('10-12-2015', 'DD-MM-YYYY'))) THEN RETURN; END IF; -- -- UPDATE bdf SET blocks = LEAST(blocks, datafile_blocks), blocks_read = LEAST(blocks_read, datafile_blocks) WHERE bs_key IN (SELECT s.bs_key FROM bs s, bp p WHERE s.bs_key = p.bs_key AND s.multi_section = 'Y' AND p.status <> 'D' AND p.piece# = 1) AND (blocks > datafile_blocks OR blocks_read > datafile_blocks); COMMIT; END; >>>