xttprep.tmpl

SET FEEDBACK OFF NUMWIDTH 10 LINESIZE 32767 TRIMSPOOL ON TAB OFF PAGESIZE 0 EMB ON
SET APPINFO ON DEFINE "&" VERIFY OFF SERVEROUTPUT ON SIZE 1000000 FORMAT TRUNCATED

-- ALTER SESSION SET PLSQL_CCFLAGS='XTT_TESTING:TRUE';

-- REM DON'T FORGET ABOUT THIS SPOOL
SPOOL %%tmp%%/xttprepare.cmd
DECLARE
l_detnew CONSTANT BOOLEAN := ('%%type%%' = 'DETNEW');
l_prepare CONSTANT BOOLEAN := ('%%type%%' = 'PREPARE');
l_transfer CONSTANT BOOLEAN := ('%%type%%' = 'TRANSFER');
l_prepnext CONSTANT BOOLEAN := ('%%type%%' = 'PREPNEXT');
l_transport CONSTANT BOOLEAN := ('%%type%%' = 'BACKUP');
lc_batch_size CONSTANT NUMBER := 10000;
DEBUG CONSTANT BOOLEAN := FALSE;
CRLF CONSTANT BOOLEAN := TRUE;
PLAN CONSTANT BOOLEAN := TRUE;
l_tsn dbms_sql.number_table;
l_names dbms_sql.varchar2_table;
l_dnames dbms_sql.varchar2_table;
l_fnames dbms_sql.varchar2_table;
l_prev user_tablespaces.tablespace_name%TYPE;
l_files dbms_sql.number_table;
l_ckpch dbms_sql.number_table;
l_pname v$database.platform_name%TYPE;
l_stageondest CONSTANT VARCHAR2(4000) := '%%stageondest%%';
l_storageondest CONSTANT VARCHAR2(4000) := '%%storageondest%%';
l_dfcopydir CONSTANT VARCHAR2(4000) := '%%dfcopydir%%';
l_tmp CONSTANT VARCHAR2(4000) := '%%tmp%%';
l_parallelism CONSTANT VARCHAR2(200) := '%%parallel%%';
l_backupdir CONSTANT VARCHAR2(4000) := '%%backupformat%%';

-- The hints for the query below are handcrafted
-- and should cover 11g (w/ and w/o the fix for
-- bug#8248459 in place) well as 12c. Ideally a
-- backport of 8248459 has to be applied on both
-- source and target databases.
CURSOR dc
IS

SELECT ts#
     , name
     , df.dname
     , df.fname
     , file#
     , checkpoint_change#
  FROM (
       SELECT /*+
                LEADING(t.x$kccts)
                USE_HASH(d.df)
                FULL(t.x$kccts)
                FULL(d.df)
                USE_HASH(d.fe)
                USE_HASH(d.fn)
                USE_HASH(d.fh)
                LEADING(d.fe d.fn d.fh)
              */
              ROW_NUMBER()
              OVER (
                PARTITION BY d.ts# ORDER BY file#
              ) rn
            , MIN(
                CASE
                  WHEN enabled = 'READ WRITE'
                   AND status = 'ONLINE'
                  THEN d.ts#
                  ELSE -d.ts#
                END
              ) OVER (
                 PARTITION BY d.ts#
              ) ts#
            , t.name
            , REGEXP_REPLACE(d.name, '(.*)/(.*)', '\1') dname
            , REGEXP_REPLACE(d.name, '(.*)/(.*)', '\2') fname
            , file#
            , MIN(checkpoint_change#)
              OVER (
                PARTITION BY d.ts#
              ) checkpoint_change#
         FROM $IF $$XTT_TESTING
              $THEN
              (
              SELECT USERENV('INSTANCE') inst_id
                   , ts#
                   , CASE WHEN ts# = 0
                          THEN status
                          WHEN ts# IN (8)
                          THEN 'OFFLINE'
                          ELSE 'ONLINE'
                     END status
                   , CASE WHEN ts# = 0
                          THEN enabled
                          WHEN ts# IN (9)
                          THEN 'READ ONLY'
                          ELSE 'READ WRITE'
                     END enabled
                   , file#
                   , checkpoint_change#
                FROM gv$datafile
              )
              $ELSE
              gv$datafile
              $END d
            , v$tablespace t
        WHERE d.ts# = t.ts#
          AND d.inst_id = USERENV('INSTANCE')
          AND t.name IN (
                %%TABLESPACES%%
              )
      ) df
 WHERE rn = 1
    OR ts# > 0
 ORDER BY
       ts#
     , rn
;

PROCEDURE d (

i_msg           VARCHAR2 DEFAULT NULL

, i_crlf BOOLEAN DEFAULT TRUE
)
IS
BEGIN

IF (DEBUG)
THEN
  IF (i_crlf)
  THEN
    dbms_output.put_line(
      '#DEBUG:' || i_msg
    );
  ELSE
    dbms_output.put(
      '#DEBUG:' || i_msg
    );
  END IF;
END IF;

END d;

PROCEDURE t (

i_msg           VARCHAR2 DEFAULT NULL

, i_crlf BOOLEAN DEFAULT TRUE
)
IS

l_prepend       VARCHAR2(256) := '#TRANSFER:';

BEGIN

IF (l_transfer)
THEN
  IF (i_crlf)
  THEN
    dbms_output.put_line(
      l_prepend || 'source_file_name=' || i_msg || ''
    );
  ELSE
    dbms_output.put(
      l_prepend || 'source_file_name=' || i_msg || ''
    );
  END IF;
END IF;

END t;

PROCEDURE p (

i_msg           VARCHAR2 DEFAULT NULL

, i_crlf BOOLEAN DEFAULT TRUE
)
IS

l_prepend       VARCHAR2(256) := CASE
                                   WHEN (l_prepare OR l_transfer OR 
                                         l_transport)
                                     THEN '#PLAN:'
                                     ELSE ' '
                                 END;

BEGIN

IF ((l_prepare OR l_transfer OR l_transport) OR l_detnew)
THEN
  IF (i_crlf)
  THEN
    dbms_output.put_line(
      l_prepend || i_msg
    );
  ELSE
    dbms_output.put(
      l_prepend || i_msg
    );
  END IF;
END IF;

END p;

PROCEDURE r (

i_msg           VARCHAR2 DEFAULT NULL

, i_crlf BOOLEAN DEFAULT TRUE
)
IS
BEGIN

IF (l_prepare) THEN
  IF (i_crlf)
  THEN
    dbms_output.put_line(
      '#CONVERT:' || i_msg
    );
  ELSE
    dbms_output.put(
      '#CONVERT:' || i_msg
    );
  END IF;
END IF;

END r;

PROCEDURE cp (

i_msg           VARCHAR2 DEFAULT NULL

, i_crlf BOOLEAN DEFAULT TRUE
)
IS
BEGIN

IF (l_prepare OR l_transport)
THEN
  IF (i_crlf)
  THEN
    dbms_output.put_line(i_msg);
  ELSE
    dbms_output.put(i_msg);
  END IF;
END IF;

END cp;

PROCEDURE t_listdatfiles (

i_msg           VARCHAR2 DEFAULT NULL

, i_dfdir BOOLEAN DEFAULT FALSE
)
IS

l_prepend       VARCHAR2(256) := '#FNAME:';

BEGIN


IF (l_transfer)
THEN
IF (i_dfdir)
THEN
  l_prepend := '#DNAME:';
END IF;

dbms_output.put_line(
    l_prepend || i_msg
    );
END IF;

END t_listdatfiles;

PROCEDURE t_newdatafiles (

i_msg           VARCHAR2 DEFAULT NULL

, i_crlf BOOLEAN DEFAULT TRUE
)
IS

l_prepend       VARCHAR2(256) := '#NEWDESTDF:';

BEGIN

IF (l_transfer OR l_transport)
THEN
  IF (i_crlf)
  THEN
    dbms_output.put_line(
      l_prepend || i_msg
    );
  ELSE
    dbms_output.put(
      l_prepend || i_msg
    );
  END IF;
END IF;

END t_newdatafiles;

BEGIN
OPEN dc;
LOOP

FETCH dc
 BULK COLLECT
 INTO l_tsn
    , l_names
    , l_dnames  
    , l_fnames  
    , l_files
    , l_ckpch
LIMIT lc_batch_size;
EXIT WHEN l_tsn.COUNT = 0;
FOR i IN 1..l_tsn.COUNT
LOOP
  IF (((l_prepare OR l_transfer OR l_transport) OR l_prepnext)  AND 
      l_tsn(i) < 1)
  THEN
    d( 'Tablespace ' || l_names(i) || ' [' || -l_tsn(i) || ']'
    || ' is special, read only or has some offline files! Skipping...'
    );
    RAISE_APPLICATION_ERROR(-20001, 'TABLESPACE(S) IS READONLY OR,
                                     OFFLINE JUST CONVERT, COPY');
  ELSE
    IF (l_prepare AND l_pname IS NULL)
    THEN
      SELECT platform_name
        INTO l_pname
        FROM v$database;
    END IF;
    t_listdatfiles(l_dnames(i), TRUE);
    t_listdatfiles(l_fnames(i));
    d( 'Processing file# ' || l_files(i)
    || ' with checkpoint_change# ' || l_ckpch(i) || ' of '
    || l_names(i) || ' [' || l_tsn(i) || ']'
    );
    -- June 04 2014: Following change was done to allow many datafiles
    -- to be copied together instead of be done in a serial manner.
    -- It will be like backup as copy datafile x,y,z instead of the
    -- current backup as copy datafile x, backup as copy datafile y.
    IF (l_prev IS NULL)
    THEN
      p(l_names(i) || '::::' || TO_CHAR(l_ckpch(i), 'FM999999999999999'));
      r('host ''echo ts::' || l_names(i) || ''';');
      IF (l_prepare) THEN
        r('  convert from platform ''' || l_pname || '''');
        r('  datafile ');
        cp('backup as copy tag ''' ||  'prepare' || ''' datafile');
      END IF;
      IF (l_transport) THEN
        cp('backup for transport allow inconsistent ' ||
           'incremental level 0 datafile');
      END IF;
    END IF;
    -- June 04 2014: Following change was done to allow many datafiles
    -- to be copied together instead of be done in a serial manner.
    -- It will be like backup as copy datafile x,y,z instead of the
    -- current backup as copy datafile x, backup as copy datafile y.
    IF (l_prev <> l_names(i))
    THEN
       r('  format ''' || l_storageondest || '/%N_%f.xtf''');
       r(' parallelism ' || l_parallelism || ';');
       p(l_names(i) || '::::' || TO_CHAR(l_ckpch(i), 'FM999999999999999'));
       r('host ''echo ts::' || l_names(i) || ''';');
       r('  convert from platform ''' || l_pname || '''');
       r('  datafile ');
    END IF; 
    r('  ' ||
      CASE
        WHEN l_prev = l_names(i)
        THEN ','
        ELSE ' '
      END 
    || ''''
    || l_stageondest || '/' || l_names(i)
    || '_' || l_files(i) || '.tf'''
    );
    -- Feb 2015: Print the directory names also
    t( 
       l_names(i) || ',' || l_dnames(i) || ',' || l_fnames(i)
    );
    t_newdatafiles( 
      CASE
    WHEN l_transport THEN
      l_files(i) || ',' || l_storageondest || '/'
      || l_fnames(i)
    ELSE
      -- Feb 2015: Print the directory names also
      l_files(i) || ',' || 'DESTDIR:' || l_dnames(i) || ',' || '/'
      || l_fnames(i)
    END
    );
    cp(
   CASE
       -- June 04 2014: Following change was done to allow many datafiles
       -- to be copied together instead of be done in a serial manner.
       -- It will be like backup as copy datafile x,y,z instead of the
       -- current backup as copy datafile x, backup as copy datafile y.
        WHEN l_prev IS NULL
        THEN ' '
        ELSE ','
   END
    || l_files(i)
    );
    p(l_files(i));
    l_prev := l_names(i);
  END IF;
END LOOP;

END LOOP;
IF (l_prepare AND l_prev IS NOT NULL)
THEN

r('  format ''' || l_storageondest || '/%N_%f.xtf''');
r(' parallelism ' || l_parallelism || ';');
cp('  format ''' || l_dfcopydir || '/%N_%f.tf'';');

END IF;
IF (l_transport AND l_prev IS NOT NULL)
THEN

cp('  format ''' || l_backupdir || '/%N_%f_%U.bkp'';');

END IF;
CLOSE dc;
END;
/
SPOOL OFF
EXIT

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值