MINI MINI MANI MO
# Copyright (c) 1996, 2018, 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 <hash>STOP_SED and <hash>START_SED (where <hash> 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 '18.04.00.00'
raschemaversion 0
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,
FEPFCPS NUMBER,
FEPFAFN 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
<<getnext>>
--
--
--
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$currentTime'
<<<
function currentTime return date is
begin
return CAST(SYS_EXTRACT_UTC(SYSTIMESTAMP) AS DATE);
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));
<<retry>>
begin
sys.dbms_backup_restore.refreshAgedFiles;
exception
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;
pdb_dict_check_sby 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, pdbdbn name
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,
fe.fepfcps pdb_foreign_ckp_scn,
fe.fepfafn pdb_foreign_afn
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, value pvalue, instr(value, 'CONNECT') pos
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);
if confrec.pos > 0 then
confrec.pvalue :=
substr(confrec.pvalue, 1, confrec.pos - 1) || 'CONNECT *******';
end if;
deb('resync', ' Name: ' || confrec.name ||
' Value: '|| confrec.pvalue, 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;
<<all_tf_found>>
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;
<<restart_resync>> -- 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;
<<resync_after_incarnation>> -- 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;
<<snapshot>> -- 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, dbid 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
if full_resync or auto_prim_resync then
pdb_dict_check(pdbrec.con_id) := 1;
if auto_prim_resync then
pdb_dict_check_sby(pdbrec.con_id) := 1;
krmicd.writeMsg(20073, pdbrec.name);
end if;
deb('resync', 'con_id=' || pdbrec.con_id ||
' needs dictionary check', dbtype);
end if;
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>> -- 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, dfrec.pdb_foreign_ckp_scn,
dfrec.pdb_foreign_afn);
--
--
--
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;
<<all_df_found>>
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
deb('resync', 'plugin_scn = ' || dfrec.plugin_scn ||
' plugged_readonly = ' || dfRec.plugged_readonly ||
' clean_flag = ' || dfRec.clean_flag ||
' read_enabled_flag = ' || dfRec.read_enabled_flag);
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
deb('resync', 'the file is clean');
read_only := 1;
ELSE
deb('resync', 'the file is offline clean');
read_only := 0; -- offline clean
END IF;
ELSE -- the file is not clean
deb('resync', '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 ||
' create_scn = ' || dfRec.create_scn ||
' plugin_scn = ' || dfRec.plugin_scn ||
' stop_scn = ' || dfRec.stop_scn ||
' read_only = ' || read_only);
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, sync_retries > 0,
pdb_dict_check_sby.exists(dfrec.con_id));
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;
<<all_df_found_for_standby>>
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;
<<all_stby_tf_found>>
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;
<<retry_mining>>
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;
<<retry_rout_mining>>
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
<<al_resync_again>>
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;
pdb_dict_check_sby.delete;
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;
<<next_object>>
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;
preplugin boolean;
pdbid number;
pplcdbdbid number;
ppltrans number;
begin
&object&
if (preplugin) then
krmicd.getPrePluginTranslation(pdbid, pplcdbdbid);
ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation(
pdbid => pdbid, pplcdbdbid => pplcdbdbid);
end if;
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);
if (ppltrans > 0) then
sys.dbms_backup_restore.endPrePluginTranslation;
end if;
end;
>>>
define catalc
<<<
--
declare
fname varchar2(512);
full_name varchar2(512);
recid number;
stamp number;
rsid number;
rsts number;
preplugin boolean;
pdbid number;
pplcdbdbid number;
ppltrans number;
begin
&object&
if (preplugin) then
krmicd.getPrePluginTranslation(pdbid, pplcdbdbid);
ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation(
pdbid => pdbid, pplcdbdbid => pplcdbdbid);
end if;
sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
sys.dbms_backup_restore.inspectArchivedLog(fname => fname,
full_name => full_name, recid => recid, stamp => stamp,
change_rdi => TRUE, preplugin => preplugin);
krmicd.writeMsg(8051);
krmicd.writeMsg(8514, full_name, to_char(recid), to_char(stamp));
sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0);
if (ppltrans > 0) then
sys.dbms_backup_restore.endPrePluginTranslation;
end if;
end;
>>>
define catbcf
<<<
--
declare
fname varchar2(512);
full_name varchar2(512);
recid number;
stamp number;
rsid number;
rsts number;
preplugin boolean;
pdbid number;
pplcdbdbid number;
ppltrans number;
begin
&object&
if (preplugin) then
krmicd.getPrePluginTranslation(pdbid, pplcdbdbid);
ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation(
pdbid => pdbid, pplcdbdbid => pplcdbdbid);
end if;
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);
if (ppltrans > 0) then
sys.dbms_backup_restore.endPrePluginTranslation;
end if;
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;
preplugin boolean;
pdbid number;
pplcdbdbid number;
ppltrans number;
db_not_mounted exception;
pragma exception_init(db_not_mounted, -1507);
begin
&object&
if (preplugin) then
krmicd.getPrePluginTranslation(pdbid, pplcdbdbid);
ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation(
pdbid => pdbid, pplcdbdbid => pplcdbdbid);
end if;
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);
if (ppltrans > 0) then
sys.dbms_backup_restore.endPrePluginTranslation;
end if;
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: budf_start */
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;
mirror_num number := 0; /* 0: do not use a specific mirror */
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;
<<start_convo>>
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,
mirror_num => mirror_num);
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);
<<name_files>>
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: bual_start */
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;
<<start_convo>>
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);
<<name_files>>
>>>
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;
compressalg varchar2(80);
compressasof number;
compresslopt binary_integer;
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;
cnvrtfr 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&
--
&7&
--
&comp_alg&
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;
ispwdfile boolean := false;
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
--
--
--
--
<<snapshot>> -- 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&
if ispwdfile then
src_name := sys.dbms_backup_restore.getParm(12);
end if;
>>>
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
<<<
--
<<create_piece>>
sys.dbms_backup_restore.backupStatus(state, setid, stamp, pieceno, files,
datafiles, incremental, nochecksum,
device);
starttime := currentTime();
--
--
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
<<snapshot>>
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
elapsed := currentTime() - starttime;
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
<<<
--
<<create_piece>>
sys.dbms_backup_restore.backupStatus(state, setid, stamp, pieceno, files,
datafiles, incremental, nochecksum,
device);
starttime := currentTime();
--
--
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);
<<snapshot>>
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
,mirrornum => blkstat(i).mirrornum
,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; -- <<snapshot>>
elapsed := currentTime() - starttime;
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
<<<
--
start_time := currentTime();
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
cnvrtfr := TRUE;
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
if docompress then
krmicd.writeMsg(8631, krmicd.getChid, to_char(pieceno),
to_char(sysdate));
else
krmicd.writeMsg(8038, krmicd.getChid, to_char(pieceno),
to_char(sysdate));
end if;
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_bool boolean;
dummy_num number;
outtag varchar2(31);
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;
<<failover>>
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));
sys.dbms_backup_restore.backupSetPiece(
&args_tag&,
&args_start&,
convertfr => cnvrtfr,
pltfrmfr => pltfrmfr,
orsbck => FALSE);
setBackupParams(FALSE);
sys.dbms_backup_restore.backupPieceBackup(
bpname => pnames(piececopy),
copyno => max_copy,
copy_recid => precid(piececopy),
copy_stamp => pstamp(piececopy),
npieces => npieces);
sys.dbms_backup_restore.backupPieceCreate(
fname => fnames(0),
pieceno => dummy_num,
done => dummy_bool,
handle => handle,
comment => comment,
media => media,
concur => concur,
&args_create&,
&args_reuse&,
archlog_failover => dummy_bool,
deffmt => deffmt,
recid => recid,
stamp => stamp,
tag => outtag,
docompress => docompress,
dest => dest,
post10_2 => TRUE,
netalias => NULL,
compressalg => compressalg,
compressasof => compressasof,
compresslopt => compresslopt);
sys.dbms_backup_restore.backupCancel();
--
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
sys.dbms_backup_restore.backupCancel();
piececopy := piececopy + 1;
if (piececopy >= piececnt) then
raise;
end if;
krmicd.writeMsg(8110);
krmicd.clearErrors; -- clear failover errors
goto failover;
when in_use then
sys.dbms_backup_restore.backupCancel();
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
sys.dbms_backup_restore.backupCancel();
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
sys.dbms_backup_restore.backupCancel();
krmicd.writeMsg(6826, pnames(piececopy));
piececopy := piececopy + 1;
krmicd.clearErrors;
when others then
sys.dbms_backup_restore.backupCancel();
raise;
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;
elapsed := currentTime() - start_time;
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;
hours number;
mins number;
secs number;
starttime date;
elapsed number;
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
starttime := currentTime();
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);
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);
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);
end if;
elapsed := currentTime() - starttime;
dur2time(elapsed, hours, mins, secs);
krmicd.writeMsg(8007, krmicd.getChid, to_char(dfnumber, 'FM09999'),
to_char(hours, 'FM09') || ':' ||
to_char(mins, 'FM09') || ':' ||
to_char(secs, 'FM09'));
if byduplicate and copy is not null and fname is not null then
krmicd.writeMsg(8505, full_name);
elsif preplugin then
krmicd.writeMsg(8505, full_name);
else
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: rsdf_start */
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);
orgname 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;
start_time := currentTime();
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;
<<start_convo>>
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;
<<name_files>>
deb('rsdf_start', 'set_stamp=' || set_stamp || ' set_count=' || set_count,
rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN);
>>>
define ridf_start
<<<
--
declare
/* restoreStatus: ridf_start */
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);
orgname 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;
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;
start_time := currentTime();
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;
<<start_convo>>
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;
<<name_files>>
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, orgname);
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, orgname);
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
<<<
--
<<restore_piece>>
>>>
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
elapsed := currentTime() - start_time;
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
if (ppltrans > 0) then
sys.dbms_backup_restore.endPrePluginTranslation;
end if;
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;
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;
--
<<restore_failover>>
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);
err_msg varchar2(2048);
begin
krmicd.getMSR(dfnumber, msrfname);
sys.dbms_backup_restore.setParms(p0 => 5,
p1 => dfnumber,
p5 => msrfname);
exception
when sys.dbms_backup_restore.retryable_error_exp then
err_msg := sqlerrm;
if not krmicd.doRestoreFailover(rman_constant.BACKUPPIECE) then
raise;
end if;
--
krmicd.writeErrMsg(8615, krmicd.getChid||': '||err_msg);
krmicd.clearErrors;
end;
>>>
define msr_error_clean
<<<
--
declare
dfnumber number;
msrfname varchar2(1024);
begin
krmicd.getMSRError(dfnumber, msrfname);
if (msrfname is not null) then
sys.dbms_backup_restore.deleteFile(msrfname);
end if;
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: rsal_start */
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);
start_time := currentTime();
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;
<<start_convo>>
&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;
<<name_files>>
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
,newfno => dfnumber);
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&
start_time := currentTime();
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, preplugin, 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;
elapsed := currentTime() - start_time;
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;
elapsed := currentTime() - start_time;
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;
elapsed := currentTime() - start_time;
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);
cant_open_log exception;
pragma exception_init(cant_open_log, -308);
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;
<<do_cont_again>>
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';
<<restart_recovery>> -- recovery is never restarted for bmr
begin
start_time := currentTime();
--
--
--
--
--
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;
--
<<get_log>>
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);
elapsed := currentTime() - start_time;
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);
elapsed := currentTime() - start_time;
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;
elapsed := currentTime() - start_time;
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 or cant_open_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', 0, pdbname);
else
krmicd.writeMsg(6958, 'alter database datafile ' || fileno ||
' offline');
krmicd.execSql('alter database datafile ' || fileno ||
' offline', 0, pdbname);
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 <logon> and <directory>.
impdp <logon> directory=<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);
<<scan_log>> -- 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);
orgname 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;
encdec_restore number := 0;
begin
&1& -- set conversation variables
--
if preview then
deb('net_rsdf_start', 'preview');
return;
end if;
start_time := currentTime();
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
,encdec_restore => encdec_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);
orgname 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;
start_time := currentTime();
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);
orgname 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;
networkfal boolean := FALSE;
restore_not_complete exception;
begin
&1&
--
if preview then
deb('net_rsal_start', 'preview');
return;
end if;
start_time := currentTime();
sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
--
if networkfal then
sys.dbms_backup_restore.restoreSetForeignAL(
destination => destination
,cleanup => FALSE
,service => service);
else
sys.dbms_backup_restore.restoreSetArchivedLog(
destination => destination
,cleanup => FALSE
,service => service);
end if;
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;
orgname := null;
max_corrupt := 0;
&object& -- dfnumber, toname, max_corrupt, tsname, orgname
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'), orgname);
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;
elapsed := currentTime() - start_time;
dur2time(elapsed, hours, mins, secs);
--
--
if (transname) then
xfno := sys.dbms_backup_restore.getXttsName(toname);
krmicd.writeMsg(8626, krmicd.getChid, xfno, toname);
if orgname is not null then
krmicd.isRestorePlugin(true);
krmicd.addxttfile(xfno, orgname);
krmicd.isRestorePlugin(false);
krmicd.addxttfile(xfno, toname);
end if;
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;
<<snapshot>> -- 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);
orgname 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;
start_time := currentTime();
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;
elapsed := currentTime() - start_time;
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_cl_pwdfile
<<<
passwordfile auxiliary format &1&
>>>
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_as_encrypted
<<<
as encrypted
>>>
define cl_as_decrypted
<<<
as decrypted
>>>
define cl_db
<<<
clone database
>>>
define cl_xtt_pdb
<<<
clone foreign pluggable database
&1&
>>>
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 res_cl_falfs
<<<
restore clone force from service &1&
foreign archivelog from scn &2&;
>>>
define res_cl_setaldest
<<<
set archivelog destination to &1&;
>>>
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_fdfs
<<<
clone foreign datafilecopy
&1& from service &2&
>>>
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 rec_cl_delarc
<<<
delete clone force archivelog all;
>>>
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 disable_system_trigger
<<<
sql clone 'alter system set "_system_trig_enabled"=FALSE';
>>>
define reset_system_trigger
<<<
sql clone 'alter system reset "_system_trig_enabled"';
>>>
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;
imp_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&
if (recall = FALSE) then
imp_recall :=
krmicd.getVendorType = sys.dbms_backup_restore.DEVICEQUERY_OPC OR
krmicd.getVendorType = sys.dbms_backup_restore.DEVICEQUERY_BA;
recall := imp_recall;
end if;
--
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 and not imp_recall 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);
<<snapshot>> -- 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;
start_time := currentTime();
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>> -- 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;
<<raut_search_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;
elapsed := currentTime() - start_time;
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
if validate then
krmicd.writeMsg(8096, krmicd.getChid);
else
krmicd.writeMsg(8554, krmicd.getChid, outhandle);
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.restoreSpFileTo(pfname => pfname,
sfname => sfname);
end if;
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&
start_time := currentTime();
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);
elapsed := currentTime() - start_time;
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&
start_time := currentTime();
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);
elapsed := currentTime() - start_time;
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
start_time := currentTime();
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;
elapsed := currentTime() - start_time;
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&
start_time := currentTime();
filename := krmicd.getRepairScriptName;
deb('update_repair_option', 'script_name=' || filename);
sys.dbms_ir.updateRepairOption(
adviseid => adviseid
,optionidx => optionidx
,scriptname => filename);
elapsed := currentTime() - start_time;
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&
start_time := currentTime();
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;
elapsed := currentTime() - start_time;
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&
start_time := currentTime();
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;
elapsed := currentTime() - start_time;
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: res_xtt_start */
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);
start_time := currentTime();
--
--
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;
<<start_convo>>
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;
<<name_files>>
>>>
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
elapsed := currentTime() - start_time;
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;
>>>
define stbysync_restore_ctl_fservice
<<<
restore standby controlfile from service &1&;
alter database mount standby database;
>>>
define stbysync_restore_ctl
<<<
restore standby controlfile;
alter database mount standby database;
>>>
define cl_tar_catb
<<<
catalog datafilecopy
&1&
>>>
define stbysync_cl_swi
<<<
switch datafile all;
>>>
define stbysync_cl_setnt
<<<
set newname for tempfile &1& to new;
>>>
define stbysync_cl_swit
<<<
switch tempfile all;
>>>
define stbysync_cl_resetdb
<<<
reset database to incarnation &1&;
>>>
define stbysync_cl_resdffs
<<<
restore from service &1& datafile
&2&;
>>>
define stbysync_cl_resdf
<<<
restore datafile
&2&;
>>>
define stbysync_cl_recfs
<<<
recover database from service &1&;
>>>
define stbysync_cl_rec
<<<
recover database noredo;
>>>
#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_i_curr_dbinc_key
<<<
CREATE INDEX fc$db_i_curr_dbinc_key on db(curr_dbinc_key) COMPRESS 1
&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 node_i_db_key
<<<
CREATE INDEX fc$node_i_db_key on node(db_key) COMPRESS 1
&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 dbinc_i_db_key
<<<
CREATE INDEX fc$dbinc_i_db_key on dbinc(db_key) COMPRESS 1
&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 pdbinc_i_born_dbinc_key
<<<
CREATE INDEX fc$pdbinc_i_born_dbinc_key on pdbinc(born_dbinc_key) COMPRESS 1
&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 pdb_dbinc_i_pdb_key
<<<
CREATE INDEX fc$pdb_dbinc_i_pdb_key on pdb_dbinc(pdb_key) COMPRESS 1
&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 ckp_i_site_key
<<<
CREATE INDEX fc$ckp_i_site_key on ckp(site_key) COMPRESS 1
&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 ts_i_pdbinc_key
<<<
CREATE INDEX fc$ts_i_pdbinc_key on ts(pdbinc_key) COMPRESS 1
&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 tsatt_i_pdbinc_key
<<<
CREATE INDEX fc$tsatt_i_pdbinc_key on tsatt(pdbinc_key) COMPRESS 1
&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,
pdb_foreign_ckp_scn NUMBER DEFAULT 0 NOT NULL,
--
--
--
pdb_foreign_afn 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 df_i_pdbinc_key
<<<
CREATE INDEX fc$df_i_pdbinc_key on df(pdbinc_key) COMPRESS 1
&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 site_dfatt_i_site_key
<<<
CREATE INDEX fc$site_dfatt_i_site_key on site_dfatt(site_key) COMPRESS 1
&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 tf_i_pdb_key
<<<
CREATE INDEX fc$tf_i_pdb_key on tf(pdb_key) COMPRESS 1
&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 site_tfatt_i_site_key
<<<
CREATE INDEX fc$site_tfatt_i_site_key on site_tfatt(site_key) COMPRESS 1
&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 rr_i_dbinc_key
<<<
CREATE INDEX fc$rr_i_dbinc_key on rr(dbinc_key) COMPRESS 1
&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 orl_i_site_key
<<<
CREATE INDEX fc$orl_i_site_key on orl(site_key) COMPRESS 1
&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 al_i_site_key
<<<
CREATE INDEX fc$al_i_site_key on al(site_key) COMPRESS 1
&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 bs_i_cleanupBV
<<<
CREATE INDEX bs_i_cleanupBV on bs
(db_key, input_file_scan_only, completion_time, status)
&tablespace&
>>>
define bs_i_pdb_key
<<<
CREATE INDEX fc$bs_i_pdb_key on bs(pdb_key) COMPRESS 1
&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 bp_i_pdb_key
<<<
CREATE INDEX fc$bp_i_pdb_key on bp(pdb_key) COMPRESS 1
&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 bcf_i_pdb_key
<<<
CREATE INDEX fc$bcf_i_pdb_key on bcf(pdb_key) COMPRESS 1
&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 ccf_i_site_key
<<<
CREATE INDEX fc$ccf_i_site_key on ccf(site_key) COMPRESS 1
&tablespace&
>>>
define ccf_i_pdb_key
<<<
CREATE INDEX fc$ccf_i_pdb_key on ccf(pdb_key) COMPRESS 1
&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 xcf_i_pdb_key
<<<
CREATE INDEX fc$xcf_i_pdb_key on xcf(pdb_key) COMPRESS 1
&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 bsf_i_pdb_key
<<<
CREATE INDEX fc$bsf_i_pdb_key on bsf(pdb_key) COMPRESS 1
&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_f3 FOREIGN KEY (dbinc_key)
REFERENCES dbinc ON DELETE CASCADE,
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 bdf_i_pdb_key
<<<
CREATE INDEX fc$bdf_i_pdb_key on bdf(pdb_key) COMPRESS 1
&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 cdf_i_site_key
<<<
CREATE INDEX fc$cdf_i_site_key on cdf(site_key) COMPRESS 1
&tablespace&
>>>
define cdf_i_pdb_key
<<<
CREATE INDEX fc$cdf_i_pdb_key on cdf(pdb_key) COMPRESS 1
&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 xdf_i_site_key
<<<
CREATE INDEX fc$xdf_i_site_key on xdf(site_key) COMPRESS 1
&tablespace&
>>>
define xdf_i_pdb_key
<<<
CREATE INDEX fc$xdf_i_pdb_key on xdf(pdb_key) COMPRESS 1
&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 xal_i_site_key
<<<
CREATE INDEX fc$xal_i_site_key on xal(site_key) COMPRESS 1
&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 rsr_i_site_key
<<<
CREATE INDEX fc$rsr_i_site_key on rsr(site_key) COMPRESS 1
&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 grsp_i_pdb_key
<<<
CREATE INDEX fc$grsp_i_pdb_key on grsp(pdb_key) COMPRESS 1
&tablespace&
>>>
define grsp_i_dbinc_key
<<<
CREATE INDEX fc$grsp_i_dbinc_key on grsp(dbinc_key) COMPRESS 1
&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 nrsp_i_pdb_key
<<<
CREATE INDEX fc$nrsp_i_pdb_key on nrsp(pdb_key) COMPRESS 1
&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 bcr_i_site_key
<<<
CREATE INDEX fc$bcr_i_site_key on bcr(site_key) COMPRESS 1
&tablespace&
>>>
define bcr_i_df_site_key
<<<
CREATE INDEX fc$bcr_i_df_site_key on bcr(df_key, site_key) COMPRESS 1
&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,
pdb.guid
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,
pdb.guid
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_foreign_ckp_scn,
a.pdb_nobackup,
a.pdb_foreign_afn
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,
df.pdb_foreign_ckp_scn,
pdb.nobackup pdb_nobackup,
df.pdb_foreign_afn
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 ts.plugin_scn = df.ts_plugin_scn
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_foreign_ckp_scn,
a.pdb_nobackup,
a.pdb_foreign_afn
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,
df.pdb_foreign_ckp_scn,
pdbinc.nobackup pdb_nobackup,
df.pdb_foreign_afn
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 ts.plugin_scn = df.ts_plugin_scn
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 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 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,
pdb_foreign_ckp_scn IN NUMBER DEFAULT 0,
pdb_foreign_afn 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,
did_prim_resync IN BOOLEAN DEFAULT FALSE,
pdb_dict_check IN BOOLEAN DEFAULT FALSE);
--
--
--
--
--
--
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
,new_recid 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
,new_recid 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
,new_recid 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
pdbForeignCkpScn number, -- foreign ckp scn of PDB datafile during plugin
noBackupPdb number, -- this PDB is excluded from backup
pdbForeignAfn number -- foreign PDB absolute datafile number
);
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,
order_hint 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,
rl_snapstandby VARCHAR2(3),
--
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),
pdbGuid 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;
FUNCTION translatePdbGuid2Name(
pdbGuid IN VARCHAR2,
pdbId OUT 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
,atAnyScn IN boolean DEFAULT FALSE);
--
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 number -- 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;
--
FUNCTION translatePdbName(pdbName IN VARCHAR2,
pdbGuid OUT 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;
--
FUNCTION pdbHasDatafile(pdbId IN NUMBER) 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_mod
<<<
alter table rcver modify (version varchar2(15))
>>>
define rcver
<<<
CREATE TABLE rcver
(
version varchar2(15) 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_setvsn
<<<
begin
delete from rcver;
insert into rcver values(&vsnstr&);
commit;
end;
>>>
define raschemaver_update
<<<
begin
delete from raschemaver;
insert into raschemaver values (0);
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
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
catalogVersion CONSTANT VARCHAR2(11) := '18.04.00.00'; -- @@VERSION_CHANGE@@ set
--
--
type version_list_type is table of varchar2(14);
version_list version_list_type := version_list_type(
'08.00.04.00'
,'08.00.05.00'
,'08.01.03.00'
,'08.01.06.00'
,'08.01.07.00'
,'09.00.00.00'
,'09.02.00.00'
,'10.01.00.00'
,'10.02.00.00'
,'10.02.00.01'
,'11.01.00.00'
,'11.01.00.01'
,'11.01.00.02'
,'11.01.00.03'
,'11.01.00.04'
,'11.01.00.05'
,'11.01.00.06'
,'11.01.00.07'
,'11.02.00.00'
,'11.02.00.01'
,'11.02.00.02'
,'12.01.00.00'
,'12.01.00.01'
,'12.01.00.02'
,'12.02.00.00'
,'12.02.00.01'
,'12.02.00.02'
,catalogVersion -- @@VSN_CHANGE@@
);
version_max_index binary_integer;
version_counter binary_integer := 1;
/*-----------*
* Constants *
*-----------*/
MAXNUMVAL CONSTANT NUMBER := 2**32-1;
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) := '<?xml version="1.0"?> <ALL_TABLES> ';
this_xml_signature_end VARCHAR2(50) := ' </ALL_TABLES> ';
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;
--
FUNCTION maskConnectString(value IN VARCHAR2)
RETURN VARCHAR2 IS
lpos PLS_INTEGER;
BEGIN
lpos := instr(value, 'CONNECT');
IF lpos > 0
THEN
RETURN substr(value, 1, lpos - 1) || 'CONNECT *******';
ELSE
RETURN value;
END IF;
END maskConnectString;
--
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 LIKE 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 LIKE 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 LIKE 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 LIKE 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 LIKE 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;
<<now_try_with_dbid>>
--
--
--
--
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;
<<ret>>
--
--
--
--
--
--
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_noncir_watermarks boolean := TRUE;
local_reset_cir_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_noncir_watermarks := TRUE;
IF (cf_version = local.cf_create_time) THEN
local_reset_cir_watermarks := FALSE;
ELSE
local_reset_cir_watermarks := TRUE;
END IF;
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_noncir_watermarks := FALSE;
local_reset_cir_watermarks := FALSE;
ELSE
deb('beginCkpt - Resync from different control file');
local_reset_noncir_watermarks := TRUE;
local_reset_cir_watermarks := TRUE;
END IF;
ELSE
--
--
IF (ckp_db_status = 'BACKUP') THEN
deb('beginCkpt - Resync from control file copy');
local_reset_noncir_watermarks := TRUE;
local_reset_cir_watermarks := TRUE;
ELSE
--
--
IF (kccdivts = sessionWaterMarks.last_kccdivts) THEN
deb('beginCkpt - Resync from same backup control file');
local_reset_noncir_watermarks := FALSE;
local_reset_cir_watermarks := FALSE;
ELSE
deb('beginCkpt - Resync from different backup control file');
local_reset_noncir_watermarks := TRUE;
local_reset_cir_watermarks := TRUE;
END IF;
END IF;
END IF;
IF (local_reset_cir_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_noncir_watermarks THEN
deb('beginCkpt - update ckp_scn and use existing non cir 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 non cir 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),
bcr_in_use = nvl2(high_bcr_recid, 'YES', 'NO'),
high_ts_recid = NULL,
high_df_recid = NULL,
high_rt_recid = NULL,
high_orl_recid = NULL,
high_tf_recid = 0,
high_grsp_recid = 0,
high_pdb_recid = NULL
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;
IF (local_reset_cir_watermarks) THEN
--
--
--
deb('beginCkpt - update reset circular water marks, this_site_key '||
this_site_key);
UPDATE node SET
high_ic_recid = 0,
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_nrsp_recid = 0,
high_bcr_recid = 0,
bcr_in_use = nvl2(high_bcr_recid, 'YES', 'NO'),
high_pic_recid = 0
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;
<<get_next_rec>>
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;
<<next_Ts>>
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,
pdb_foreign_ckp_scn IN NUMBER,
pdb_foreign_afn 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,
pdb_foreign_ckp_scn, pdb_foreign_afn)
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,
pdb_foreign_ckp_scn, pdb_foreign_afn);
--
--
--
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,
did_prim_resync IN BOOLEAN DEFAULT FALSE,
pdb_dict_check IN BOOLEAN DEFAULT FALSE) 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 pdb_dict_check THEN
deb('checkDataFileForStandby - skipping df, needs dictionary check');
RETURN;
END IF;
--
--
IF this_ckp_scn > last_full_ckp_scn THEN
IF (file# != dfRec.file#) THEN
IF (file# > dfRec.file#) THEN
deb('checkDataFileForStandby - dropped file#=' || dfRec.file#);
ELSE
--
deb('checkDataFileForStandby - 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('checkDataFileForStandby - change for file#= ' || file# ||
' create_scn = ' || create_scn ||
' dfRec.create_scn = ' || dfRec.create_scn ||
' plugin_scn = ' || plugin_scn ||
' dfRec.plugin_scn = ' || dfRec.plugin_scn ||
' stop_scn = ' || stop_scn ||
' dfRec.stop_scn = ' || dfRec.stop_scn ||
' read_only = ' || read_only ||
' dfRec.read_only = ' || dfRec.read_only);
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
IF NOT did_prim_resync THEN
raise_application_error(-20079,
'full resync from primary database is not done');
ELSE
--
--
raise_application_error(-20999,
'Internal error in checkDataFileForStandby - 1 ');
END IF;
--
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,
pdb_foreign_ckp_scn IN NUMBER DEFAULT 0,
pdb_foreign_afn 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,
pdb_foreign_ckp_scn, pdb_foreign_afn);
--
--
--
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 IS NOT NULL AND
dfRec.create_time IS NOT NULL AND
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 (dfRec.create_time IS NULL AND create_time IS NOT NULL) THEN
UPDATE df
SET create_time = checkDatafile.create_time
WHERE df_key = local_df_key;
deb('checkDatafile - updated create_time which is NULL');
END IF;
--
--
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,
pdb_foreign_ckp_scn, pdb_foreign_afn);
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
my_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;
my_dbinc_key := checkIncarnation(resetlogs_change#, resetlogs_time);
--
--
deb('checkGuaranteedRP - con_id=' || con_id);
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(nvl(checkGuaranteedRP.con_id, 0), 0, 1))
AND pdb.pdb_key = pdb_dbinc.pdb_key
AND pdb_dbinc.dbinc_key = my_dbinc_key;
deb('checkGuaranteedRP - local_pdb_key=' || local_pdb_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, my_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 = my_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) ||
' dfbloks ' || to_char(conflict_rec.datafile_blocks) ||
' block_size ' || to_char(conflict_rec.block_size) ||
' plugin_scn ' || to_char(conflict_rec.plugin_scn) ||
' secsize ' || 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) ||
' dfblocks ' || to_char(addBackupDataFile.datafile_blocks) ||
' block_size '|| to_char(addBackupDataFile.block_size) ||
' plugin_scn '|| to_char(addBackupDataFile.plugin_scn) ||
' secsize ' || to_char(addBackupDataFile.section_size));
END;
raise_application_error(-20110, 'set stamp set count conflict');
END IF;
--
--
SELECT dbinc_key, create_scn, bdf_key, bdf_recid,
bdf_stamp, plugin_scn, completion_time,
abs_fuzzy_scn, datafile_blocks, blocks,
nvl(blocks_read, datafile_blocks), ckp_scn, ckp_time,
used_optim, used_chg_track, nvl(marked_corrupt, 0)
INTO local.dbinc_key, local.create_scn, local.bdf_key, local.bdf_recid,
local.bdf_stamp, local.plugin_scn, local.completion_time,
local.abs_fuzzy_scn, local.datafile_blocks, 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
local.bdf_recid := bdf_recid;
local.bdf_stamp := bdf_stamp;
END IF;
--
--
IF (local.completion_time < addBackupDataFile.completion_time) THEN
local.completion_time := addBackupDataFile.completion_time;
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 (local.ckp_scn > addBackupDataFile.ckp_scn) THEN
deb('addBackupDataFile - updated bdf ckp_scn: '||
to_char(addBackupDataFile.ckp_scn) || ' local bdf ckp_scn:' ||
to_char(local.ckp_scn));
local.ckp_scn := addBackupDataFile.ckp_scn;
local.ckp_time := addBackupDataFile.ckp_time;
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.
*/
--
--
deb('addBackupDataFile - bdf local.abs_fuzzy_scn: ' ||
to_char(local.abs_fuzzy_scn));
local.abs_fuzzy_scn :=
GREATEST(local.abs_fuzzy_scn, addBackupDataFile.abs_fuzzy_scn);
--
--
IF (local.abs_fuzzy_scn < local.ckp_scn) THEN
local.abs_fuzzy_scn := 0;
deb('addBackupDataFile - updated bdf abs_fuzzy_scn to 0');
END IF;
IF (local.abs_fuzzy_scn = addBackupDataFile.abs_fuzzy_scn) THEN
deb('addBackupDataFile - updated bdf abs_fuzzy_scn: '||
to_char(local.abs_fuzzy_scn));
END IF;
--
--
local.datafile_blocks :=
GREATEST(local.datafile_blocks, addBackupDataFile.datafile_blocks);
--
--
--
--
--
--
--
--
IF (isVirtual AND addBackupDataFile.section_size > 0) THEN
local.blocks_read := local.blocks_read + addBackupDataFile.blocks_read;
local.blocks := local.blocks + addBackupDataFile.blocks;
local.marked_corrupt :=
local.marked_corrupt + addBackupDataFile.marked_corrupt;
ELSE
local.blocks_read :=
GREATEST(local.blocks_read, addBackupDataFile.blocks_read);
local.blocks :=
GREATEST(local.blocks, addBackupDataFile.blocks);
local.marked_corrupt :=
GREATEST(local.marked_corrupt, addBackupDataFile.marked_corrupt);
END IF;
--
local.blocks := LEAST(local.blocks, local.datafile_blocks);
local.blocks_read := LEAST(local.blocks_read, local.datafile_blocks);
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
IF (local.blocks > l_UB4MAXVAL) THEN
--
deb('addBackupDataFile - blocks overflow'||
to_char(local.blocks) || ' ' ||
to_char(local.datafile_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(local.datafile_blocks));
local.blocks_read := l_UB4MAXVAL;
END IF;
IF (addBackupDataFile.used_chg_track = 'YES') THEN
local.used_chg_track := 'Y';
END IF;
IF (addBackupDataFile.used_optim = 'YES') THEN
local.used_optim := 'Y';
END IF;
--
--
UPDATE bdf
SET bdf_recid = local.bdf_recid,
bdf_stamp = local.bdf_stamp,
completion_time = local.completion_time,
ckp_scn = local.ckp_scn,
ckp_time = local.ckp_time,
abs_fuzzy_scn = local.abs_fuzzy_scn,
blocks_read = local.blocks_read,
blocks = local.blocks,
datafile_blocks = local.datafile_blocks,
marked_corrupt = local.marked_corrupt,
used_chg_track = local.used_chg_track,
used_optim = local.used_optim
WHERE bdf.bdf_key = local.bdf_key;
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;
new_recid number := 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;
ELSIF (object_type = 'DATAFILE COPY MOVED') THEN
new_status := NULL;
new_recid := 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, new_recid);
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';
ELSIF (object_type = 'ARCHIVED LOG MOVED') THEN
new_status := NULL;
new_recid := object_data;
ELSE
raise_application_error(-20999,
'Internal error in checkDeletedObject(): bad object_type '||
object_type);
END IF;
changeArchivedLog(object_recid, object_stamp, new_status, new_recid);
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;
<<rsr_key_known>>
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;
<<rout_skey_known>>
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
,new_recid IN NUMBER DEFAULT NULL
) 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, new_recid);
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;
IF new_recid IS NOT NULL THEN
UPDATE cdf SET cdf_recid = changeDatafileCopy.new_recid
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
,new_recid IN NUMBER DEFAULT NULL
) 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;
IF new_recid IS NOT NULL THEN
UPDATE ccf SET ccf_recid = changeControlfileCopy.new_recid
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
,new_recid IN NUMBER DEFAULT NULL
) IS
BEGIN
IF (this_dbinc_key IS NULL) THEN
raise_application_error(-20020, 'Database incarnation not set');
END IF;
IF status IS NULL THEN
IF (new_recid IS NOT NULL) THEN
UPDATE al SET al_recid = changeArchivedLog.new_recid
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));
END IF;
ELSIF 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=(' || maskConnectString(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=' || maskConnectString(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=(' || maskConnectString(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;
deb('checkIncarnation - returning ' || local.dbinc_key);
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);
deb('checkIncarnation - (2) returning ' || local.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);
--
--
deb('checkRestorePoint - con_id=' || con_id || ',deleted=' || deleted);
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(nvl(checkRestorePoint.con_id, 0), 0, 1))
AND pdb.pdb_key = pdb_dbinc.pdb_key
AND pdb_dbinc.dbinc_key = my_dbinc_key;
deb('checkRestorePoint - local_pdb_key=' || local_pdb_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;
<<tryagain>>
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;
--
--
update vpc_databases
set db_id = dbid,
reg_db_unique_name = null
where filter_user = userid
and db_id = 0
and reg_db_unique_name = p_dbun;
--
--
if sql%rowcount = 0 then
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)));
end if;
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_ecatowner
, 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_ecatowner
, vtr_tname(i)
, vtr_tname(i)
, g_ecatowner
, 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_ecatowner
, vtr_tname(i)
, vtr_tname(i)
, g_ecatowner
, 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(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 = %e';
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;
}', '%e', g_ecatowner), '%o', g_catowner);
ELSE
EXECUTE IMMEDIATE REGEXP_REPLACE(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 = %e';
EXCEPTION
WHEN NO_DATA_FOUND
THEN NULL;
END;
}', '%e', g_ecatowner), '%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;
<<retry_request_again>>
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;
<<retry_request_again>>
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,
'<TABLE_' || record_tbl(idx) ||'>'));
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,
'<TABLE_' || record_tbl(idx) ||'>'));
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,
'<TABLE_' || record_tbl(idx) ||'>'));
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,
'<TABLE_RC_WATERMARKS>'));
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_FOREIGN_CKP_SCN,
PDB_NOBACKUP,
PDB_FOREIGN_AFN
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,
pdb_foreign_ckp_scn => dfRec.pdb_foreign_ckp_scn,
pdb_foreign_afn => dfRec.pdb_foreign_afn);
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,
'<TABLE_' || record_tbl(idx) ||'>'));
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 dbms_assert.enquote_name(l_eschema, FALSE);
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_max_index := version_list.COUNT; -- must match highest index
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
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
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
catalogVersion CONSTANT VARCHAR2(11) := '18.04.00.00'; -- @@VERSION_CHANGE@@ set
--
--
--
TYPE versionList_t IS TABLE OF varchar2(11);
--
--
versionList versionList_t := versionList_t(
'08.00.04.00'
,'08.00.05.00'
,'08.01.03.00'
,'08.01.05.00'
,'08.01.06.00'
,'08.01.07.00'
,'09.00.00.00'
,'09.02.00.00'
,'10.01.00.00'
,'10.02.00.00'
,'10.02.00.01'
,'11.01.00.00'
,'11.01.00.01'
,'11.01.00.02'
,'11.01.00.03'
,'11.01.00.04'
,'11.01.00.05'
,'11.01.00.06'
,'11.01.00.07'
,'11.02.00.00'
,'11.02.00.01'
,'11.02.00.02'
,'12.01.00.00'
,'12.01.00.01'
,'12.01.00.02'
,'12.02.00.00'
,'12.02.00.01'
,'12.02.00.02'
,catalogVersion -- @@VSN_CHANGE@@
);
versionMaxIndex binary_integer;
versionCounter binary_integer;
--
--
--
--
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 rl_snapstandby,
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 rl_snapstandby,
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 rl_snapstandby,
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 rl_snapstandby,
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,
'NO' rl_snapstandby,
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,
null rl_snapstandby,
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 rl_snapstandby,
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 rl_snapstandby,
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,
'NO' rl_snapstandby,
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 rl_snapstandby,
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 rl_snapstandby,
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,
'NO' rl_snapstandby,
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 pdbNameRec_t index by rc_pdbs.name%TYPE;
pdbNameList pdbNameList_t;
pdbGuidList pdbNameList_t;
--
TYPE pdbId2NameList_t is table of rc_pdbs.name%TYPE index by binary_integer;
pdbId2NameList pdbId2NameList_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,
rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
rcd.pdb_foreign_afn pdbForeignAfn
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,
rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
rcd.pdb_foreign_afn pdbForeignAfn
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,
rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
rcd.pdb_foreign_afn pdbForeignAfn
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,
rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
rcd.pdb_foreign_afn pdbForeignAfn
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,
rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
rcd.pdb_foreign_afn pdbForeignAfn
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,
rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
rcd.pdb_foreign_afn pdbForeignAfn
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,
rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
rcd.pdb_foreign_afn pdbForeignAfn
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,
rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
rcd.pdb_foreign_afn pdbForeignAfn
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,
rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
rcd.pdb_foreign_afn pdbForeignAfn
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,
rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
rcd.pdb_foreign_afn pdbForeignAfn
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,
rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
rcd.pdb_foreign_afn pdbForeignAfn
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,
DECODE(brl.activation, 'Y', -2, 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
,backedUpAnyScn IN number)
RETURN bhistoryRec_t IS
WITH
my_dbinc AS
(SELECT db_key,
dbinc_key,
reset_scn,
reset_time,
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 db_key,
null reset_scn,
null reset_time,
null next_reset_scn
FROM dual)
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,
my_dbinc dbinc,
(SELECT DISTINCT
cdf.file#, cdf.create_scn, cdf.plugin_scn,
cdf.plugged_readonly, cdf.ckp_scn, cdf.ckp_time, cdf.dbinc_key,
cdf.abs_fuzzy_scn
FROM cdf, my_dbinc 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'
AND (dcBackupHistory_c.backedUpAnyScn = FALSE# OR
(dcBackupHistory_c.backedUpAnyScn = TRUE# AND
cdf.file# >0 AND
(dbinc.next_reset_scn IS NULL OR
cdf.abs_fuzzy_scn <= dbinc.next_reset_scn)))) 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 (dcBackupHistory_c.backedUpAnyScn = TRUE# OR
(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,
my_dbinc dbinc,
(SELECT DISTINCT
ccf.ckp_scn, ccf.ckp_time, ccf.dbinc_key
FROM ccf, my_dbinc 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, my_dbinc 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,
cdf.abs_fuzzy_scn
FROM cdf, my_dbinc dbinc
WHERE cdf.dbinc_key = dbinc.dbinc_key
AND dbinc.db_key = this_db_key
AND cdf.status = 'A'
AND (dcBackupHistory_c.backedUpAnyScn = FALSE# OR
(dcBackupHistory_c.backedUpAnyScn = TRUE# AND
cdf.file# > 0 AND
(dbinc.next_reset_scn IS NULL OR
cdf.abs_fuzzy_scn <= dbinc.next_reset_scn)))) 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 (dcBackupHistory_c.backedUpAnyScn = TRUE# OR
(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,
absolute_fuzzy_change#
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, guid
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');
<<validationLoop>>
LOOP
<<nextRow>>
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
nvl(greatest(afzSCN, toSCN), 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;
--
<<seekNext>>
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;
<<seekCurrent>>
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;
<<retry>>
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;
pdbGuidList.delete;
pdbId2NameList.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;
<<nextRow>>
FETCH translatePdbName_c INTO local;
IF translatePdbName_c%NOTFOUND THEN
CLOSE translatePdbName_c;
ELSE
pdbNameList(local.name) := local;
pdbGuidList(local.pdbGuid) := local;
pdbId2NameList(local.pdbId) := local.name;
goto nextRow;
END IF;
local.name := cdbRoot_txt;
local.pdbId := 1;
local.pdbGuid := 0;
pdbNameList(local.name) := local;
pdbGuidList(local.pdbGuid) := local;
pdbId2NameList(local.pdbId) := local.name;
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));
<<nextRow>>
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
bsindex binary_integer := NULL;
bsrec cacheBsRecRow_t;
bucket number;
sb4_bucket binary_integer;
addstatus boolean;
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
addstatus := addKeyToBsRecCache(bskey);
END IF;
FOR i in 1..cacheBsRecTable.bsRec(sb4_bucket).bslist.count LOOP
IF (cacheBsRecTable.bsRec(sb4_bucket).bslist(i).bskey = bskey) THEN
bsindex := i;
EXIT;
END IF;
END LOOP;
IF (bsindex IS NULL) THEN
addstatus := addKeyToBsRecCache(bskey);
bsindex := 1;
END IF;
cacheBsRecTable.bsRec(sb4_bucket).bslist(bsindex).copy(icopy) := bsrec;
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);
--
--
--
--
--
<<mixCopyLoop>>
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
<<nextRow>>
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;
<<addAnother>>
--
--
--
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;
<<done>>
--
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);
--
--
--
<<action_loop>>
LOOP
<<next_row>>
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));
<<dbinc_loop>>
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 substr(version,1,11) = 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;
<<parent_inc>>
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;
<<parent_inc>>
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;
<<parent_inc>>
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;
this_stdby_controlfile_scn := 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 rl_snapstandby,
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 rl_snapstandby,
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 rl_snapstandby,
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 rl_snapstandby,
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,
'NO' rl_snapstandby,
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,
null rl_snapstandby,
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 rl_snapstandby,
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 rl_snapstandby,
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,
'NO' rl_snapstandby,
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 rl_snapstandby,
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 rl_snapstandby,
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,
'NO' rl_snapstandby,
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 pdbHasDatafile(pdbId IN NUMBER)
RETURN NUMBER IS
datafile_count NUMBER;
BEGIN
deb(DEB_ENTER, 'pdbHasDatafile, pdbId=' || pdbId);
--
SELECT count(*) INTO datafile_count
FROM rci_datafile_this_dbinc
WHERE db_key = this_db_key
AND dbinc_key = this_dbinc_key
AND con_id = pdbHasDatafile.pdbId
AND rownum = 1;
IF (datafile_count > 0) THEN
deb(DEB_EXIT, 'with: TRUE#');
RETURN TRUE#;
ELSE
deb(DEB_EXIT, 'with: FALSE#');
RETURN FALSE#;
END IF;
END pdbHasDatafile;
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
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;
<<nextRow>>
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;
EXCEPTION
WHEN VALUE_ERROR THEN
--
--
--
--
IF (instr(tsName, ':') <> 0) THEN
deb(DEB_PRINT, 'skipTableSpace: pdb name could be prepended to ts');
raise_application_error(-20044, 'Invalid tablespace name');
END IF;
deb(DEB_EXIT, 'skipTableSpace: exit due to exception');
RAISE;
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');
<<nextRow>>
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');
<<nextRow>>
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');
<<retry>>
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;
<<NextRow>>
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');
<<nextRow>>
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;
<<nextRow>>
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
<<checkAgain>>
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;
<<checkAgain>>
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;
<<nextRow>>
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');
<<nextRow>>
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');
<<nextRow>>
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');
<<get_next>>
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');
<<get_next>>
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');
<<nextRow>>
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;
<<nextRow>>
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
<<nextRow>>
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;
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;
--
--
--
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');
<<getNext>>
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;
<<merge_actions>>
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');
<<get_next>>
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_dfRecTab>>
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_travelinc>>
LOOP
translateDatabase(TRUE#);
<<loop_genDfRecTab>>
LOOP
BEGIN
getDatafile(dfRec);
EXCEPTION
WHEN no_data_found THEN EXIT loop_genDfRecTab;
END;
--
--
--
--
--
j := dfRec.dfNumber;
<<loop_scanDfRecTab>>
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;
<<ObsoleteDataSkip>>
--
--
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;
<<main_loop>>
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
<<loop_copy>>
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 (lbRec.file_type <> spfile_txt AND
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 (recoveryDestFile AND lbRec.rl_snapstandby = 'YES') THEN
IF (debug) THEN
deb(DEB_IN, 'snapshot standby archivelog');
END IF;
--
--
--
--
ELSIF ((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;
--
--
<<loop_lbDfRecTab>>
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
--
<<reverse_loop_lbDfRecTab>>
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;
<<listBackup_returnRec>>
--
IF (lbState.lbRecOutTab_count > 0)
THEN
lbState.lbRecOutTab_count := lbState.lbRecOutTab_count - 1;
lbRecOut := lbState.lbRecOutTab(lbState.lbRecOutTab_count);
END IF;
<<listBackup_end>>
--
--
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;
firstDf boolean;
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;
con_id := 0;
--
--
--
--
--
--
--
--
--
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;
--
IF (dfRec.PdbId <= 1 OR translatePdb2Name(dfRec.PdbId) IS NOT NULL) THEN
dfRecTab(dfRecTab.count) := dfRec;
END IF;
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 => backupMask_con_t +
offlineRangeRec_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)
THEN
firstDf := TRUE;
ELSE
firstDf := FALSE;
IF (con_id > 1)
THEN
IF (dfRec.tsNumber = 0 AND dfRec.rfNumber IN (1, 1024))
THEN
firstDf := TRUE;
END IF;
END IF;
END IF;
--
IF (firstDf 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 (NOT firstDf 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 (NOT firstDf 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;
--
--
--
IF (con_id <= 1)
THEN
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;
END IF;
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;
<<nextRow>>
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;
--
--
<<lastRow>>
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
,atAnyScn IN boolean DEFAULT FALSE)
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;
backedUpAnyScn number;
BEGIN
deb(DEB_ENTER, 'getDcBackupHistory');
--
--
--
IF (atAnyScn) THEN
backedUpAnyScn := TRUE#;
ELSE
backedUpAnyScn := FALSE#;
END IF;
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),
backedUpAnyScn => backedUpAnyScn);
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;
<<nextRow>>
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;
--
--
<<lastRow>>
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;
<<nextRow>>
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;
--
--
<<lastRow>>
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;
<<nextRow>>
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;
--
--
<<lastRow>>
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);
<<nextRow>>
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);
<<nextRow>>
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));
<<nextRow>>
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;
<<addAnother>>
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
<<nextbrlRec>>
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;
<<addAnother>>
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;
<<addAnother>>
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 number
,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;
afzSCN number;
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;
<<next>>
FETCH getCopyofDatafile_c2
INTO fno, crescn, rlogscn, rlgtime, recid, stamp, name, otag, status,
nblocks, bsz, ctime, toscn, totime, pluggedRonly, pluginSCN,
pluginRlgSCN, pluginRlgTime, afzSCN;
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
nvl(greatest(afzSCN, toSCN), 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
pdbGuid VARCHAR2(128);
BEGIN
RETURN translatePdbName(pdbName, pdbGuid);
END translatePdbName;
--
FUNCTION translatePdbName(pdbName IN VARCHAR2, pdbGuid OUT VARCHAR2)
RETURN NUMBER IS
local pdbNameRec_t;
BEGIN
initPdbNameList;
IF (pdbNameList.exists(pdbName)) THEN
local := pdbNameList(pdbName);
pdbGuid := local.pdbGuid;
RETURN local.pdbId;
ELSE
pdbGuid := NULL;
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;
IF (pdbId2NameList.exists(pdbId)) THEN
RETURN pdbId2NameList(pdbId);
ELSE
RETURN NULL;
END IF;
END translatePdb2Name;
--
FUNCTION translatePdbGuid2Name(pdbGuid IN VARCHAR2, pdbId OUT NUMBER)
RETURN VARCHAR2 IS
local pdbNameRec_t;
BEGIN
--
--
IF (pdbGuid IS NULL) THEN
pdbId := NULL;
RETURN NULL;
END IF;
initPdbNameList;
IF (pdbGuidList.exists(pdbGuid)) THEN
local := pdbGuidList(pdbGuid);
pdbId := local.pdbId;
RETURN local.name;
ELSE
pdbId := NULL;
RETURN NULL;
END IF;
END translatePdbGuid2Name;
--
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
--
--
--
versionCounter := 1;
versionMaxIndex := versionList.COUNT; -- must match highest index
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
<<<alter table brl add CONSTRAINT brl_u2 UNIQUE (bs_key, thread#, sequence#)>>>
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 '18.04.00.00';
end;
function getCatalogVersion return varchar2 is
begin
return '18.04.00.00';
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 upgcat_remove_orphan_bdf
<<<
delete bdf where not exists
(select 1 from dbinc where dbinc.dbinc_key = bdf.dbinc_key)
>>>
define upgcat_add_bdf_f3
<<<
alter table bdf add CONSTRAINT bdf_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 not exists (select 1 from pdb where pdb.db_key = db.db_key)
--
order by db.db_key, nvl2(dbinc.parent_dbinc_key, 1, 0),
dbinc.reset_time, dbinc.reset_scn;
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
<<<alter table config add CONSTRAINT config_p PRIMARY KEY (name)>>>
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(15);
begin
select max(version) into rcver_i from rcver ;
IF rcver_i < '12.01.00.00' OR rcver_i < '12.01.00.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(15);
begin
select max(version) into rcver_i from rcver ;
IF rcver_i < '12.01.00.00' OR rcver_i < '12.01.00.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 upgcat_df_add_pfckpscn
<<<
alter table df add (pdb_foreign_ckp_scn number default 0 not null)
>>>
define upgcat_df_add_pfafn
<<<
alter table df add (pdb_foreign_afn number default 0 not null)
>>>
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('<r><c>' ||
replace(str,',','</c><c>') || '</c></r>')
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('<r><c>' ||
replace(str,',','</c><c>') || '</c></r>')
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('<r><c>' ||
replace(str,',','</c><c>') || '</c></r>')
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 ' ||
'<Emphasis Role = "CodeInline">V$SESSION.WAIT_TIME</Emphasis> ' ||
'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: ' ||
'<Emphasis Role = "CodeInline">WAITING</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">WAITED UNKNOWN TIME</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">WAITED SHORT TIME</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">WAITED KNOWN TIME</Emphasis>. ' ||
'See description of ' ||
'<Emphasis Role = "CodeInline">V$SESSION.STATE</Emphasis> ' ||
'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: <Emphasis Role =' ||
'"CodeInline">EXECUTABLE</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">RUNNING</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">COMPLETED</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">TASK_WAIT</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">FAILED</Emphasis>, ' ||
'and so on.''';
execute immediate 'comment on column ra_active_session.' ||
'job_name is ' ||
'''The <Emphasis Role = "CodeInline">DBMS_SCHEDULER</Emphasis> 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: <Emphasis Role = "CodeInline">ON</Emphasis> ' ||
'if the Recovery Appliance is running; ' ||
'<Emphasis Role = "CodeInline">OFF</Emphasis> 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: ' ||
'<Emphasis Role = "CodeInline">TRUE</Emphasis> to delete files ' ||
'as they are accepted; <Emphasis Role = "CodeInline">FALSE</Emphasis> ' ||
'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: ' ||
'<Emphasis Role = "CodeInline">YES</Emphasis> means that ' ||
'the Recovery Appliance replicates backups or copies them to tape before deleting them; ' ||
'<Emphasis Role = "CodeInline">NO</Emphasis> 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 '||
'''<Emphasis Role = "CodeInline">YES</Emphasis> 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 ' ||
'<Emphasis Role = "CodeInline">recovery_window_goal</Emphasis> 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: ' ||
'<Emphasis Role = "CodeInline">YES</Emphasis> means that ' ||
'the Recovery Appliance replicates backups or copies them to tape before deleting them; ' ||
'<Emphasis Role = "CodeInline">NO</Emphasis> 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 '||
'''<Emphasis Role = "CodeInline">YES</Emphasis> if real-time redo transport is ' ||
'active. <Emphasis Role = "CodeInline">NO</Emphasis> 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: <Emphasis Role = "CodeInline">' ||
'EXECUTABLE</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">RUNNING</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">COMPLETED</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">TASK_WAIT</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">FAILED</Emphasis>, ' ||
'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 <Emphasis Role = "CodeInline">TASK_WAIT</Emphasis>.''';
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: ' ||
'<Emphasis Role = "CodeInline">Y</Emphasis> ' ||
'if it has moved to the archive; otherwise, <Emphasis Role = ' ||
'"CodeInline">N</Emphasis>.''';
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 ' ||
'<Emphasis Role = "CodeInline">LOW_SCN</Emphasis> 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 ' ||
'<Emphasis Role = "CodeInline">HIGH_SCN</Emphasis> 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 <Emphasis Role = "CodeInline">SEND</Emphasis> command string ' ||
'passed to the allocated channel.''';
execute immediate 'comment on column ra_sbt_library.' ||
'status is ' ||
'''The SBT library status: <Emphasis Role = "CodeInline">READY</Emphasis>, '||
'<Emphasis Role = "CodeInline">PAUSE</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">ERROR</Emphasis>, 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 <Emphasis Role = "CodeInline">SEND</Emphasis> 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: ' ||
'<Emphasis Role = "CodeInline">ALL</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">FULL</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">INCR</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">ARCH</Emphasis>, or ' ||
'<Emphasis Role = "CodeInline">TAPE_RESERVE</Emphasis>.''';
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: ' ||
'<Emphasis Role = "CodeInline">EXECUTABLE</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">RUNNING</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">COMPLETED</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">TASK_WAIT</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">FAILED</Emphasis>, ' ||
'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: <Emphasis Role = "CodeInline">YES</Emphasis> if this ' ||
'is a restore task; <Emphasis Role = "CodeInline">NO</Emphasis> 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: <Emphasis Role = "CodeInline">YES</Emphasis> ' ||
'if this is a replication task; ' ||
'<Emphasis Role = "CodeInline">NO</Emphasis> ' ||
'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: ' ||
'<Emphasis Role = "CodeInline">SUCCESS</Emphasis> ' ||
'or <Emphasis Role = "CodeInline">FAIL</Emphasis>.''';
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: ' ||
'<Emphasis Role = "CodeInline">AVAILABLE</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">CREATING</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">DELETING</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">TESTING COMMUNICATION</Emphasis>, ' ||
'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 ' ||
'<Emphasis Role = "Italic">proxy_server_http_address:port_' ||
'of_proxy_server</Emphasis>.''';
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: <Emphasis Role = ' ||
'"CodeInline">ACTIVE</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">FIXED</Emphasis>, or ' ||
'<Emphasis Role = "CodeInline">RESET</Emphasis>.''';
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: ' ||
'<Emphasis Role = "CodeInline">ALL</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">FULL</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">INCR</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">ARCH</Emphasis>, or ' ||
'<Emphasis Role = "CodeInline">TAPE_RESERVE</Emphasis>.''';
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: ' ||
'<Emphasis Role = "CodeInline">READY</Emphasis>, ' ||
'<Emphasis Role = "CodeInline">PAUSE</Emphasis>, or ' ||
'<Emphasis Role = "CodeInline">ERROR</Emphasis>.''';
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 := '<MediaInfo>';
FOR i in 0..l_mhandle.count-1 LOOP
IF (l_mhandle(i) IS NOT NULL) THEN
l_mclob := l_mclob || '<MediaHandle>' ||
l_mhandle(i)||'</MediaHandle>';
END IF;
END LOOP;
IF (l_single > 0) THEN
l_mclob := l_mclob || '<Single>TRUE</Single>';
ELSE
l_mclob := l_mclob || '<Single>FALSE</Single>';
END IF;
l_mclob := l_mclob || '</MediaInfo>';
--
--
--
--
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 odb.platform_id IS NOT 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 || '<OTHER>';
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('<r><c>' ||
replace(str,',','</c><c>') || '</c></r>')
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
<<try_try_again>>
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_priority<PRIO_MIN_BUSYWORK) AND (l_interrupt_count>s_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
<<get_next_db>>
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);
<<do_reserve>>
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('<r><c>' ||
replace(str,',','</c><c>') || '</c></r>')
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('<r><c>' ||
replace(str,',','</c><c>') || '</c></r>')
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('<r><c>' ||
replace(str,',','</c><c>') || '</c></r>')
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;
<<RETRY_TASK_HISTORY>>
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;
<<TRY_TRY_AGAIN>>
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;
<<RETRY_TASK_HISTORY>>
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;
--
<<inspect_vb>>
--
--
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);
<<obsolete_plans>>
--
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;
<<del_blocks>>
--
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 = '18-10-2018 04:33:00 RDBMS_18.4.0.0.0DBRU_LINUX.X64_181017'
WHEN NOT MATCHED THEN
INSERT (name, value)
VALUES ('_build', '18-10-2018 04:33:00 RDBMS_18.4.0.0.0DBRU_LINUX.X64_181017');
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;
>>>
OHA YOOOO