MINI MINI MANI MO

Path : /proc/self/root/opt/oracle/product/18c/dbhomeXE/rdbms/admin/
File Upload :
Current File : //proc/self/root/opt/oracle/product/18c/dbhomeXE/rdbms/admin/olspredowngrade.sql

Rem
Rem $Header: rdbms/admin/olspredowngrade.sql /main/7 2017/05/12 13:12:17 risgupta Exp $
Rem
Rem olspredowngrade.sql
Rem
Rem Copyright (c) 2012, 2017, Oracle and/or its affiliates. 
Rem All rights reserved.
Rem
Rem    NAME
Rem      olspredowngrade.sql - OLS Pre-processing script prior to 
Rem                            downgrade from 12.1
Rem
Rem    DESCRIPTION
Rem      This is a mandatory OLS preprocess downgrade script that needs to be 
Rem      run by Label Security and Database Vault customers when downgrading 
Rem      from 12.1
Rem
Rem    NOTES
Rem      As a safety measure, before you run either the upgrade or downgrade
Rem      preprocess script, Oracle recommends that you back up your audit
Rem      records. To do this, you can archive the audit trail as described in
Rem      Oracle Database Security Guide.
Rem
Rem      Before processing the audit records, this preprocess script checks
Rem      that there is enough space in the audit tablespace to copy all the
Rem      audit records, and will exit without processing if there is not.
Rem
Rem      You may continue running your applications on the database while OLS
Rem      preprocess scripts are running.
Rem
Rem      You must run the OLS preprocess downgrade script, olspredowngrade.sql,
Rem      to process the aud$ table contents. The OLS downgrade script moves the
Rem      aud$ table from the SYS schema to the SYSTEM schema. The
Rem      olspredowngrade.sql script is a preprocessing script required in
Rem      preparation for this move. It creates a temporary table, PREDWG_AUD$,
Rem      in the SYSTEM schema and moves the SYS.aud$ records to
Rem      SYSTEM.PREDWG_AUD$. The moved records can no longer be viewed through
Rem      the DBA_AUDIT_TRAIL view, but can be viewed by directly accessing the
Rem      SYSTEM.PREDWG_AUD$ table, until the downgrade completes. Once the
Rem      downgrade completes, the SYSTEM.PREDWG_AUD$ table is permanently
Rem      deleted and all audit records, can be viewed through the
Rem      DBA_AUDIT_TRAIL view.
Rem
Rem      Auditing will continue to work and audit records will be written to
Rem      to SYS.aud$ after execution of this script.
Rem
Rem      STEPS TO RUN THE THIS SCRIPT
Rem      -----------------------------
Rem      To run the Oracle Label Security preprocess downgrade script,
Rem      run the script as SYSDBA in the 12.1 ORACLE_HOME.
Rem
Rem    BEGIN SQL_FILE_METADATA
Rem    SQL_SOURCE_FILE: rdbms/admin/olspredowngrade.sql
Rem    SQL_SHIPPED_FILE: rdbms/admin/olspredowngrade.sql
Rem    SQL_PHASE: UTILITY
Rem    SQL_STARTUP_MODE: NORMAL
Rem    SQL_IGNORABLE_ERRORS: NONE
Rem    SQL_CALLING_FILE:
Rem    END SQL_FILE_METADATA
Rem
Rem    MODIFIED   (MM/DD/YY)
Rem    risgupta    05/08/17 - Bug 26001269: Add SQL_FILE_METADATA
Rem    risgupta    02/16/16 - Bug 22733719: Must explictly set
Rem                           NLS_LENGTH_SEMANTICS to BYTE
Rem    risgupta    03/16/15 - LRG 14680081: Dont make the policy columns in
Rem                           SYSTEM.PREDWG_AUD$ invisible just after CTAS
Rem    pmojjada    02/05/15 - Bug# 20421634: Long identifier changes
Rem    aramappa    08/30/12 - bug 14539286: Do not throw errors when label
Rem                           security not installed and this script is run
Rem    srtata      06/27/12 - bug 14251893: update comments
Rem    srtata      03/12/12 - OLS pre-downgrade script for 12.1
Rem    srtata      03/12/12 - Created
Rem

set serveroutput on

-- Bug 22733719: Must explictly set NLS_LENGTH_SEMANTICS to BYTE
alter session set NLS_LENGTH_SEMANTICS=BYTE;

CREATE OR REPLACE FUNCTION is_ols_predowngd_req RETURN NUMBER
IS
  lbac_cnt    NUMBER := 0;
  ver         VARCHAR2(10);
  p_prv_version VARCHAR2(30);
BEGIN
  -- fetch the previous version
  SELECT prv_version INTO p_prv_version
  FROM registry$ 
  WHERE cid='CATPROC';
  
  IF p_prv_version IS NULL THEN
    DBMS_OUTPUT.PUT_LINE(
'olspredowngrade.sql should not be executed - database has not been upgraded');
    return 0;
  END IF;

  -- olspredowngrade.sql required only for downgrades to 11.2, 11.1
  IF substr(p_prv_version, 1, 4) NOT IN ('11.1','11.2') THEN
    DBMS_OUTPUT.PUT_LINE(
      'olspredowngrade.sql should not be executed for this database version');
    RETURN 0;
  END IF;

  SELECT COUNT(*) INTO lbac_cnt
  FROM dba_users
  WHERE username = 'LBACSYS';

  IF lbac_cnt = 0 THEN
    DBMS_OUTPUT.PUT_LINE('****THIS SCRIPT IS NEEDED ONLY IF ' ||
               'ORACLE LABEL SECURITY OR DATABASE VAULT ARE CONFIGURED*****');
    RETURN 0;
  END IF;

  RETURN 1;
END;
/
show errors;

CREATE OR REPLACE FUNCTION get_space_required(audit_trail_tbs IN VARCHAR2) 
RETURN   NUMBER
AS
    tab_rows        NUMBER := 0;
    temp_rows       NUMBER := 0;
    m_part_cnt      NUMBER := 0;
    space_occ       NUMBER := 0;
    space_req       NUMBER := 0;
    block_size      NUMBER := 0;
    blocks_used     NUMBER := 0;
    div_quotient    NUMBER := 0;
    cursor sel_dba_par IS
      SELECT PARTITION_POSITION, PARTITION_NAME, TABLESPACE_NAME
      FROM DBA_TAB_PARTITIONS
      WHERE TABLE_NAME = 'AUD$' AND
            TABLE_OWNER = 'SYS'
      ORDER BY PARTITION_POSITION;

BEGIN
-- Check space before proceeding with processing
    -- Is the table partitioned?
    SELECT COUNT(PARTITION_POSITION) INTO m_part_cnt
    FROM DBA_TAB_PARTITIONS
    WHERE TABLE_NAME = 'AUD$'
    AND TABLE_OWNER = 'SYS';

    IF m_part_cnt <= 0
    THEN
      -- Not partitioned
      SELECT BLOCK_SIZE INTO block_size FROM DBA_TABLESPACES
      WHERE TABLESPACE_NAME = audit_trail_tbs;
      --DBMS_OUTPUT.PUT_LINE('block_size = ' || block_size);

      SELECT NVL(BLOCKS,0) INTO blocks_used FROM DBA_TABLES
      WHERE TABLE_NAME = 'AUD$' AND OWNER='SYS';
      --DBMS_OUTPUT.PUT_LINE('blocks_used = ' || blocks_used);

      -- Add 3 blocks for meta data
      space_occ := (blocks_used + 3) * block_size;
      --DBMS_OUTPUT.PUT_LINE('space_occ = ' || space_occ);

      SELECT NUM_ROWS INTO tab_rows FROM DBA_TABLES
      WHERE TABLE_NAME = 'AUD$'
      AND OWNER='SYS';

      space_req :=  space_occ + 65536; /* minimum, 64 KB */
      --DBMS_OUTPUT.PUT_LINE('space_req non partitioned = '|| space_req);
    ELSE
      -- Partitioned
      space_occ := 0;
      tab_rows := 0;
      space_req := 0;
      FOR part_info IN sel_dba_par LOOP
        SELECT BLOCK_SIZE INTO block_size FROM DBA_TABLESPACES
        WHERE TABLESPACE_NAME = part_info.tablespace_name;

        SELECT BLOCKS, NUM_ROWS INTO blocks_used, temp_rows
        FROM DBA_TAB_PARTITIONS
        WHERE TABLE_NAME = 'AUD$'
        AND TABLE_OWNER = 'SYS';

        -- Add 3 blocks for meta data
        space_occ := (blocks_used + 3) * block_size;

        tab_rows := tab_rows + temp_rows;

        IF(temp_rows > 0) THEN
          space_req := space_req + space_occ;
        END IF;
      END LOOP;

      space_req :=  space_req+ 65536; /* minimum, 64 KB */
      --DBMS_OUTPUT.PUT_LINE('space_req partitioned = '|| space_req);
    END IF; -- Partitioned/Non-partitioned

       -- Space required must be a multiple of 64 KB
    div_quotient := space_req / 65536;
    space_req := CEIL(div_quotient) * 65536;
    --DBMS_OUTPUT.PUT_LINE('space_req= '|| space_req);
    RETURN space_req;
END;
/
show errors;

CREATE OR REPLACE FUNCTION get_free_space_avail(
                          audit_trail_tbs IN VARCHAR2)
RETURN   NUMBER
AS
  space_auto  NUMBER:=0;
  space_avail NUMBER:=0;
  space_inuse  NUMBER:=0;
  space_alloc NUMBER:=0;
  sum_bytes NUMBER:=0;
  
BEGIN
  -- Get number of kbytes used
  EXECUTE IMMEDIATE
    'SELECT SUM(bytes) FROM sys.dba_segments seg WHERE ' || 
    'seg.tablespace_name = :1'
        INTO sum_bytes 
        USING audit_trail_tbs;

  IF sum_bytes IS NULL THEN
    space_inuse :=0;
  ELSIF sum_bytes <= 1024 THEN 
    space_inuse :=1;
  ELSE
    space_inuse:=ROUND(sum_bytes/1024);
  END IF;

  -- Get number of kbytes allocated

  EXECUTE IMMEDIATE
    'SELECT SUM(bytes) FROM sys.dba_data_files files WHERE ' ||
    'files.tablespace_name = :1'
     INTO sum_bytes
    USING audit_trail_tbs;

  IF sum_bytes IS NULL THEN
    space_alloc :=0;
  ELSIF sum_bytes <= 1024 THEN 
    space_alloc :=1;
  ELSE
    space_alloc :=ROUND(sum_bytes/1024);
  END IF;

  EXECUTE IMMEDIATE
    'SELECT SUM(decode(maxbytes, 0, 0, maxbytes-bytes)) ' ||
    'FROM sys.dba_data_files WHERE tablespace_name=:1'
    INTO sum_bytes
    USING audit_trail_tbs;

  IF sum_bytes IS NULL THEN
    space_auto :=0;
  ELSIF sum_bytes <= 1024 THEN 
    space_auto :=1;
  ELSE
    space_auto :=ROUND(sum_bytes/1024);
  END IF;

  space_avail := (space_auto + space_alloc - space_inuse)*1024;
  return space_avail;

END;
/
show errors;


------------------------------------------------------------------------------
-- BEGIN PRE-downgrade SCRIPT. 

DECLARE

-- Tab_Name will always be PREDWG_AUD$, and doesn't need to be
-- extended to VARCHAR2(128) or dbms_id
tab_name  VARCHAR2(30); 
audtbs    VARCHAR2(256);
col_name  DBMS_ID; 
col_str   VARCHAR2(4000) := NULL;
space_req    NUMBER := 0;
space_avail  NUMBER := 0;
lbac_cnt     NUMBER := 0;
col_name1  DBMS_QUOTED_ID; 
timest      VARCHAR2(60);
npol NUMBER :=0;
sqlstmt VARCHAR2(4000);

TYPE ref_cur_type IS REF CURSOR;
policy_col_cur ref_cur_type;
BEGIN

  -- check if we need to run olspredowngrade.sql
  IF is_ols_predowngd_req = 0 THEN
    RETURN;
  END IF;

  BEGIN
    SELECT object_name INTO tab_name 
    FROM all_objects
    WHERE object_name = 'PREDWG_AUD$' 
    AND owner = 'SYSTEM' 
    AND object_type='TABLE';

    DBMS_OUTPUT.PUT_LINE('olspredowngrade.sql has been already run');
    RETURN;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
    NULL;
  END;

  -- get the tablespace used for auditing
  sqlstmt := 'SELECT tablespace_name FROM SYS.dba_tables ' ||
             'WHERE table_name = ''AUD$'' AND owner = ''SYS''';

  EXECUTE IMMEDIATE sqlstmt INTO audtbs;

  SELECT TO_CHAR(SYSTIMESTAMP,'YYYY-MM-DD HH24:MI:SS ') INTO timest FROM DUAL;
  DBMS_OUTPUT.PUT_LINE(timest||
                       '******* BEGINNING OLS PRE DOWNGRADE SCRIPT ********');

  --Space checks
  space_req := get_space_required(audtbs);
  --get space availble in the audit tablespace
  space_avail := get_free_space_avail(audtbs);

  -- Note that space_req is 64KB greater than actual space occupied
  -- but this is needed to account for any incoming records.
  DBMS_OUTPUT.PUT_LINE('The amount of FREE space required = '
                       || space_req || ' Bytes');
  DBMS_OUTPUT.PUT_LINE('Free space available  on ' || audtbs ||
                       ' tablespace= ' || space_avail || ' Bytes');

  IF space_avail < space_req  THEN
    DBMS_OUTPUT.PUT_LINE('NOT ENOUGH SPACE ON TABLESPACE ' || audtbs);
    RETURN;
  END IF;

  -- Construct a string with the list of policy columns 
  BEGIN
    OPEN policy_col_cur FOR 'SELECT column_name FROM lbacsys.ols$pol';
    LOOP
      FETCH policy_col_cur INTO col_name;
      EXIT WHEN policy_col_cur%NOTFOUND;

      npol:= npol+1;

      -- 1. Use DBMS_ASSERT.ENQUOTE_NAME for SELECT column list.
      col_name1 := dbms_assert.enquote_name(col_name, false);

      IF npol <> 1 THEN
        col_str := col_str || ', t.' || col_name1;
      ELSE
        col_str := ', t.' || col_name1;
      END IF;
    END LOOP;   
    CLOSE policy_col_cur;
  EXCEPTION
    WHEN OTHERS THEN
      CLOSE policy_col_cur;
      RAISE;
  END;
  
  sqlstmt := 'CREATE TABLE SYSTEM.PREDWG_AUD$ PARALLEL TABLESPACE ' || 
              dbms_assert.simple_sql_name(audtbs) || 
              ' AS SELECT t.* ' || col_str || ' FROM SYS.AUD$ t' ;

  EXECUTE IMMEDIATE sqlstmt;
  DBMS_OUTPUT.PUT_LINE('Audit records successfully moved to SYSTEM.PREDWG_AUD$');
END;
/

-- delete the processed rows in SYS.aud$
DECLARE
counter      NUMBER := 0;
nrows        NUMBER := 0;
tot_count    NUMBER := 0;
maxtime1      TIMESTAMP(6);
type ctyp is ref cursor;
rowid_cur ctyp;
rowid_tab dbms_sql.urowid_table;
timest      VARCHAR2(60);
BEGIN
  -- check if we need to run olspredowngrade.sql
  IF is_ols_predowngd_req = 0 THEN
    RETURN;
  END IF;

  -- Get a count of audit records in SYS.AUD$
  select count(*) INTO nrows from sys.aud$ ;

  IF nrows = 0 THEN
   RETURN;
  END IF;

  counter := ceil(nrows/1000000);

  EXECUTE IMMEDIATE 'SELECT MAX(ntimestamp#) FROM SYSTEM.PREDWG_AUD$' 
  INTO maxtime1;

  LOOP
    OPEN rowid_cur FOR 'select rowid from SYS.aud$' ||
         ' where rownum <= 1000000 and ntimestamp#<= TO_TIMESTAMP('''||
           TO_CHAR(maxtime1) || ''')';

    -- Fetch 1st 100000 rows
    FETCH rowid_cur bulk collect into rowid_tab limit 100000;

    -- Exit, if no rows
    IF (rowid_tab.count = 0) THEN
      EXIT;
    END IF;

    -- For each row fetched
    LOOP
        --  Delete from SYSTEM.aud$
        FORALL i in 1..rowid_tab.count
          EXECUTE IMMEDIATE
          ' DELETE FROM SYS.aud$ WHERE rowid = :1 ' using rowid_tab(i);

        COMMIT;

        -- Exit if total rows is less than 100000
        IF (counter = 1 and nrows <= 100000) THEN
          EXIT;
        END IF;

        nrows := nrows - 100000;
        -- Fetch next 100000 rows
        FETCH rowid_cur bulk collect into rowid_tab limit 100000;

        -- Exit, if no rows left
        IF (rowid_tab.count = 0) THEN
          EXIT;
        END IF;
    END LOOP;
    counter := counter - 1;
  END LOOP;
  CLOSE rowid_cur;

  EXECUTE IMMEDIATE 'SELECT count(*) FROM SYSTEM.PREDWG_AUD$'
  INTO tot_count;

  DBMS_OUTPUT.PUT_LINE('Total number of rows in SYSTEM.PREDWG_AUD$: '||
                        tot_count);

  SELECT TO_CHAR(SYSTIMESTAMP,'YYYY-MM-DD HH24:MI:SS ') INTO timest FROM DUAL;
  DBMS_OUTPUT.PUT_LINE(timest||
                       ' ******* FINISHING OLS PRE DOWNRADE SCRIPT ********');
EXCEPTION
  WHEN OTHERS THEN
    ROLLBACK;
    RAISE;
END;
/
show errors;

set serveroutput off

OHA YOOOO