upgrade migration - liamlamth/blog GitHub Wiki

export/import

1. before information

  • pick a good holiday day time ,disable any job that accessing database
    [root@myserver ~] $ systemctl stop cron
  • login as system and create export directory
    sql> create or replace directory orclexp AS '/export/';
  • sql
    re-execute
    drop table migrate_roles;
    drop table migrate_tables;
    drop table migrate_db_links;
    drop table migrate_sys_privs;
    drop table migrate_role_privs;
    drop table migrate_tab_privs;
    drop table migrate_objects;
    drop table migrate_indexes;
    drop table migrate_lobs;
    drop table migrate_sequences;
    drop table migrate_directories;
    drop table migrate_scheduler_jobs;
    drop table migrate_policies;
    
    create table migrate_roles              as select * from dba_roles;
    create table migrate_tables             as select * from dba_tables;
    create table migrate_db_links           as select * from dba_db_links;
    create table migrate_sys_privs          as select * from dba_sys_privs;
    create table migrate_role_privs         as select * from dba_role_privs;
    create table migrate_tab_privs          as select * from dba_tab_privs;
    create table migrate_objects            as select * from dba_objects;
    create table migrate_indexes            as select * from dba_indexes;
    create table migrate_lobs               as select * from dba_lobs;
    create table migrate_sequences          as select * from dba_sequences;
    create table migrate_directories        as select * from dba_directories;
    create table migrate_scheduler_jobs     as select * from dba_scheduler_jobs;
    create table migrate_policies           as select * from dba_policies;
    

2. export

  • full export:
    [root@myserver ~] $ expdp system/syspasswd@db_name full=Y directory=orclexp dumpfile=exp_full_220101A.dmp logfile=exp_full_220101A.log
  • partial export/import
    • table export: [root@myserver ~] $ expdp system/syspasswd@db_name tables=appowner.document,appowner.details directory=orclexp dumpfile=exp_table_220101A.dmp logfile=exp_table_220101A.log
    • source export: [root@myserver ~] $ expdp system/syspasswd@db_name schemas=appowner include=sequence,procedure,function directory=orclexp dumpfile=exp_source_220101A.dmp logfile=exp_source_220101A.log

3. import

  • re-execute
    alter pluggable database pdb_name close immediate;
    drop pluggable database pdb_name including datafiles;
    
    create pluggable database PDB_NAME admin user pdbadmin identified by password file_name_convert=('/u02/oradata/CDB_NAME/pdbseed/','/u02/oradata/CDB_NAME/PDB_NAME/');
    create or replace directory orclexp AS '/export/';
    
  • replicate tablespace
    • rebuild temp tablespace
      set lines 230;
      col file_name format a50;
      col maxbytes format 999999999999999;
      select file_name, tablespace_name, bytes, maxbytes, AUTOEXTENSIBLE from dba_temp_files;
      create temporary tablespace "TEMP02" tempfile...;
      alter database default temporary tablespace temp02;
      drop tablespace temp including contents and datafiles;
      create temporary tablespace "TEMP" tempfile...;
      alter database default temporary tablespace temp;
      drop tablespace temp02 including contents and datafiles;
      
    • build normal tablespace
      create bigfile tablespace "DATA" datafile...;
      
  • optional step incase error
    SQL> grant become user to system;
  • import
    • full import
      impdp system/password@pdb_name full=Y STREAMS_CONFIGURATION=N directory=orclexp dumpfile=exp_full_220101A.dmp logfile=imp_full_220101A.log
    • partial import and remote clone
      • build schema
        create role app_role;
        create user appuser_a identified by password default tablespace data temporary tablespace temp;
        grant app_role to appuser_a;
        

        grant alter session to appuser_a; grant create session to appuser_a; grant create session to appconnect;

        grant create any synonym to appowner; grant create view to appowner; grant drop any synonym to appowner; grant flashback any table to appowner; grant select any table to appowner; grant unlimited tablespace to appowner; alter user appowner quota unlimited on data;

        create public database link OLD_DB using 'OLD_DB';

      • remote clone
        create table lob_table tablespace data as select * from lob_table@old_db;
        create unique index appowner.pk_lob_table on appowner.lob_table (column1, column2)
        grant select on appowner.lob_table to appuser_a;
        

        create global temporary table appowner.gtemp_table grant select on appowner.lob_table to appuser_a; grant insert on appowner.lob_table to appuser_a; grant update on appowner.lob_table to appuser_a; grant delete on appowner.lob_table to appuser_a;

      • import

        impdp system/password@pdb_name tables=appowner.document,appowner.details, directory=orclexp dumpfile=exp_table_220101A.dmp logfile=imp_table_220101A.log
        impdp system/password@pdb_name schemas=appowner include=sequence,procedure,function directory=orclexp dumpfile=exp_source_220101A.dmp logfile=imp_source_220101A.log
        

4. validation

  • compare migrate table with dba view
    -----------------------------------------------------------------------------------------------------------
    select a.role mg_role, b.role 
    from   migrate_roles a
    full outer join dba_roles b on a.role = b.role
    where  greatest(a.role, b.role) is null;
    -----------------------------------------------------------------------------------------------------------
    select * 
    from  (select table_name mg_table_name, tablespace_name mg_tablespace_name, num_rows mg_num_rows
           from migrate_tables
           where owner='APPOWNER') a
    full outer join 
          (select table_name, tablespace_name, num_rows 
           from dba_tables
           where owner='APPOWNER') b on mg_table_name = table_name
    where  greatest(mg_table_name, table_name) is null
    or 	 mg_num_rows <> num_rows
    or     mg_tablespace_name <> tablespace_name;
    -----------------------------------------------------------------------------------------------------------
    select a.owner mg_owner, a.db_link mg_db_link, a.username mb_username, a.host mb_host,
           b.owner, b.db_link, b.username, b.host
    from   migrate_db_links a
    full outer join dba_db_links b on a.owner=b.owner
                                  and a.db_link=b.db_link
                                  and a.username=b.username
                                  and a.host=b.host
    -----------------------------------------------------------------------------------------------------------
    select a.grantee mg_grantee, a.privilege mg_privilege,
           b.grantee, b.privilege
    from   migrate_sys_privs a
    full outer join dba_sys_privs b on a.grantee=b.grantee and a.privilege=b.privilege
    where  greatest(a.privilege, b.privilege) is null
    order by a.grantee, a.privilege, b.grantee;
    select a.grantee mg_grantee, a.granted_role mg_granted_role, b.grantee, b.granted_role from migrate_role_privs a full outer join dba_role_privs b on a.grantee=b.grantee and a.granted_role=b.granted_role where greatest(a.granted_role, b.granted_role) is null order by a.grantee, a.granted_role, b.grantee;
    select * from (select grantee mg_grantee, owner mg_owner, table_name mg_table_name, privilege mg_privilege from migrate_tab_privs where grantee in ('APPUSER_A', 'APPUSER_B')) a full outer join (select grantee, owner, table_name, privilege from dba_tab_privs where grantee in ('APPUSER_A', 'APPUSER_B')) b on mg_grantee=grantee and mg_owner=owner and mg_table_name=table_name and mg_privilege=privilege where greatest(mg_table_name, table_name) is null; ----------------------------------------------------------------------------------------------------------- select a.*, b.*, 'alter '||object_type||' '||owner||'.'||object_name||' compile;' action from (select owner mg_owner, object_name mg_object_name, object_type mg_object_type, status mg_status from migrate_objects where owner in ('APPUSER_A', 'APPUSER_B')) a full outer join (select owner, object_name, object_type, status from dba_objects where owner in ('APPUSER_A', 'APPUSER_B')) b on mg_owner=owner and mg_object_name = object_name and mg_object_type=object_type where greatest(mg_object_name, object_name) is null or mg_status <> status;
    QUICK FIX: @$ORACLE_HOME/rdbms/admin/utlrp.sql
    declare cursor c1 is SELECT object_type,owner,object_name FROM DBA_objects where status = 'INVALID'; begin for c1_rec in c1 loop if c1_rec.owner='PUBLIC' and c1_rec.object_type='SYNONYM' then execute immediate 'alter PUBLIC SYNONYM "'||c1_rec.object_name||'" compile'; elsif c1_rec.object_type='PACKAGE BODY' then execute immediate 'alter PACKAGE "'||c1_rec.owner||'"."'||c1_rec.object_name||'" compile'; elsif c1_rec.object_type='TYPE BODY' then execute immediate 'alter TYPE "'||c1_rec.owner||'"."'||c1_rec.object_name||'" compile'; else execute immediate 'alter '||c1_rec.object_type||' "'||c1_rec.owner||'"."'||c1_rec.object_name||'" compile'; end if; end loop; end; / ----------------------------------------------------------------------------------------------------------- select 'create synonym '||OWNER||'.'||SYNONYM_NAME||' for '||TABLE_OWNER||'.'||TABLE_NAME||';' from migrate_synonyms where table_owner = 'APPOWNER'; ----------------------------------------------------------------------------------------------------------- select * from (select table_name mg_table_name, count(index_name) mg_index_count from migrate_indexes where owner = 'APPOWNER' group by owner, table_name) a full outer join (select table_name, count(index_name) index_count from dba_indexes where owner = 'APPOWNER' group by owner, table_name) b on mg_table_name = table_name where mg_index_count <> index_count or greatest(mg_table_name, table_name) is null; ----------------------------------------------------------------------------------------------------------- select 'migrate_lobs', count(*) from migrate_lobs where owner='APPOWNER' union all select 'dba_lobs', count(*) from dba_lobs where owner='APPOWNER';

    select 'migrate_sequences', count(*) from migrate_sequences where sequence_owner='APPOWNER' union all select 'dba_sequences', count(*) from dba_sequences where sequence_owner='APPOWNER';
    select * from dba_directories

problems after upgrade

  • if user a is trying to select a view owned by user b that pointing to a table owner by user c,
    even though user a is granted select right on the b.view and the c.table, error will be thrown.
    solution: grant select on c.table to b with grant option;

    ORA-01031: insufficient privileges

  • a user access a table that he didn't not owned over db link
    solution: grant inherit remote privileges on user <database_user> to <package_owner>;

    ORA-25433: User Does Not Have INHERIT REMOTE PRIVILEGES Privilege On Connected User

⚠️ **GitHub.com Fallback** ⚠️