Oracle 9i 11g历史库升级迁移数据至19c CDB

Oracle 9i 11g历史库升级迁移数据至19c CDB.docx


Oracle 9i/11g历史库升级迁移数据至19c CDB

1 背景介绍

1.1 需求

l   利用历史库备份集迁移数据至19c多租户环境,归档历史数据

l   涉及9.2.0.7、9.2.0.8、11.2.0.4,Aix、Linux环境数套数据库

l   升级至19c保留源库字符集,涉及ZHS16GBK、US7ASCII两种字符集

l   由于从备份集恢复,无停机时间要求,所以下面方案均不考虑停机时间

1.2 方案选择

1.2.1 对于9.2.0.7 Aix到Linux,

(1)需要利用Aix中间环境恢复。

(2)数据迁移可以使用先升级至9.2.0.8,然后升级至11.2.0.4,然后dbua升级至19c中间库,最后通过hot clone保留字符集到最终19c库。

(3)或者使用dbca建立19c与源库相同字符集中间库,hot clone至19c AL32UTF8字符集的最终库,直接使用exp/imp升级至19c,保留原字符集。

1.2.2 对于11204升级至19c

(1)Aix平台利用中间环境恢复,然后使用dbua或者expdp/impdp升级至19c中间库,通过hot clone保留字符集。

(2)Linux平台源库,可以直接在19c Linux中间库环境恢复,dbua就地升级至19c,然后通过non-cdb转换方式转换成cdb,最后hot-clone方式克隆到最终19c数据库。

1.2.3 对于保留字符集说明

Oracle 12.2版本以后可以PDB与CDB字符集不同,但是在CREATE PLUGGABLE DATABASE语句中并无指定字符集相关语法,需要通过hot-clone方式实现与cdb不同字符集。

1.3 环境说明

l   Aix中间机器一台:Aix 7.1 预装9.2.0.8、11.2.0.4两个版本软件。

l   CentOS 7.6机器两台

ü   A机器作为19c中间库,安装11.2.0.4/19.3 Oracle软件。

ü   B作为19c最终库,安装19.3数据库软件。

l   下面敏感字段均做过处理。

l   文档会针对三种场景进行介绍。

2 AIX 9.2.0.7升级迁移Linux 7.6 19c

l   源库:Aix 9.2.0.7

l   Aix中间库: Aix 9.2.0.8

l   Linux中间库:CentOS 7.6 19.3

l   Linux目标库:CentOS 7.6 19.3

2.1 恢复步骤概述

l   Aix使用dbms_backup_restore恢复备份集

l   exp导出

l   19c中间库导入

l   19c目标库hot clone保留源库字符集迁移

2.2 Aix中间库恢复备份集

2.2.1 编写pfile建立相关目录启动实例

*.background_dump_dest='/oradata/ora9/app/oracle/admin/db1/bdump'

*.compatible='9.2.0.0.0'

*.control_files='/control01.ctl'

*.core_dump_dest='/oradata/ora9/app/oracle/admin/db1/cdump'

*.cursor_space_for_time=TRUE

*.db_block_size=8192

*.db_cache_size=2147483648

*.db_domain=''

*.db_file_multiblock_read_count=32

*.db_keep_cache_size=268435456

*.db_name='db1'

*.db_writer_processes=3

*.fast_start_mttr_target=300

*.java_pool_size=0

*.job_queue_processes=12

*.large_pool_size=134217728

*.log_archive_start=TRUE

*.log_buffer=10485760

*.log_checkpoint_interval=10000

*.max_dump_file_size='10240'

*.open_cursors=2000

*.partition_view_enabled=TRUE

*.pga_aggregate_target=134217728

*.pre_page_sga=TRUE

*.processes=2000

*.remote_login_passwordfile='EXCLUSIVE'

*.shared_pool_size=536870912

db11.thread=1

db12.thread=2

*.timed_statistics=TRUE

*.undo_management='AUTO'

*.undo_tablespace='UNDO1'

*.user_dump_dest='/oradata/ora9/app/oracle/admin/db1/udump'

 

mkdir -p /oradata/ora9/app/oracle/admin/db1/bdump

mkdir -p /oradata/ora9/app/oracle/admin/db1/udump

mkdir -p /oradata/ora9/app/oracle/admin/db1/cdump

 

sqlplus /nolog

conn / as sysba

startup nomount pfile='/tmp/pfile.ora';

 

rman target /

RMAN> restore controlfile from ‘/db1/ctl_bak.rman’;

RMAN> alter database mount;

 

2.2.2 传输备份集,使用dbms_backup_restore恢复

l   sftp传输rman备份集

l   由于备份集中控制文件未包含备份集信息,9i catalog命令未提供注册备份集功能,所以只能使用dbms_backup_restore包恢复数据文件。

#DBMS_BACKUP_RESTORE恢复数据库:

注意:

l   下面备份集名称与下面datafile集合要对应,可以从rman备份日志中查看,如果没有日志,则只能进行组合尝试。

l   也可以一次恢复多个备份集,但是备份集顺序与下面数据文件列表集合顺序要对应,否则会报无法找到某个数据文件备份。

DECLARE

    V_DEVICE VARCHAR2(100);

    V_FINISH BOOLEAN;

    TYPE T_FILENAMETABLE IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;

    V_FILENAMETABLE T_FILENAMETABLE;

    V_MAXPIECES NUMBER :=4;

BEGIN

    V_FILENAMETABLE(1) := '/oradata/ora9/db1rman_final/fulldb_db1_20191025_58106_1';

    V_DEVICE := SYS.DBMS_BACKUP_RESTORE.DEVICEALLOCATE();

    SYS.DBMS_BACKUP_RESTORE.RESTORESETDATAFILE;

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(56,'/rlvdb1_db1_idx11.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(62,'/rlvdb1_db1_3_12.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(52,'/rlvdb1_db1_1_08.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(42,'/rlvdb1_db1_4_07.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(49,'/rlvdb1_db1_4_10.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(06,'/rlvdb1_db1_1_01.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(10,'/rlvdb1_db1_1_05.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(14,'/rlvdb1_db1_2_04.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(18,'/rlvdb1_db1_3_03.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(22,'/rlvdb1_db1_4_02.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(26,'/rlvdb1_db1_idx1.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(30,'/rlvdb1_xc_def01.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(38,'/rlvdb1_db1_idx6.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(48,'/rlvdb1_db1_def04.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(01,'/rlvdb1_system.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(35,'/rlvdb1_db1_def02.dbf');

    FOR I IN 1..V_MAXPIECES LOOP

       SYS.DBMS_BACKUP_RESTORE.RESTOREBACKUPPIECE(V_FILENAMETABLE(I),V_FINISH);

       IF V_FINISH THEN

           SYS.DBMS_BACKUP_RESTORE.DEVICEDEALLOCATE;

           RETURN;

       END IF;

    END LOOP;

    SYS.DBMS_BACKUP_RESTORE.DEVICEDEALLOCATE;

END;

/

 

DECLARE

    V_DEVICE VARCHAR2(100);

    V_FINISH BOOLEAN;

    TYPE T_FILENAMETABLE IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;

    V_FILENAMETABLE T_FILENAMETABLE;

    V_MAXPIECES NUMBER :=4;

BEGIN

       V_FILENAMETABLE(1) := '/oradata/ora9/db1rman_final/fulldb_db1_20191025_58107_1';

    V_DEVICE := SYS.DBMS_BACKUP_RESTORE.DEVICEALLOCATE();

    SYS.DBMS_BACKUP_RESTORE.RESTORESETDATAFILE;

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(57,'/rlvdb1_db1_idx12.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(63,'/rlvdb1_db1_3_08.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(54,'/rlvdb1_db1_idx10.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(02,'/rlvdb1_undotbs1.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(59,'/rlvdb1_db1_def05.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(53,'/rlvdb1_db1_2_07.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(09,'/rlvdb1_db1_1_04.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(13,'/rlvdb1_db1_2_03.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(17,'/rlvdb1_db1_3_02.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(21,'/rlvdb1_db1_4_01.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(25,'/rlvdb1_db1_4_05.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(29,'/rlvdb1_db1_idx4.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(36,'/rlvdb1_db1_idx5.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(43,'/rlvdb1_db1_1_06.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(05,'/rlvdb1_db1_def01.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(04,'/rlvdb1_pub_def1.dbf');

    FOR I IN 1..V_MAXPIECES LOOP

       SYS.DBMS_BACKUP_RESTORE.RESTOREBACKUPPIECE(V_FILENAMETABLE(I),V_FINISH);

       IF V_FINISH THEN

           SYS.DBMS_BACKUP_RESTORE.DEVICEDEALLOCATE;

           RETURN;

       END IF;

    END LOOP;

    SYS.DBMS_BACKUP_RESTORE.DEVICEDEALLOCATE;

END;

/

 

DECLARE

    V_DEVICE VARCHAR2(100);

    V_FINISH BOOLEAN;

    TYPE T_FILENAMETABLE IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;

    V_FILENAMETABLE T_FILENAMETABLE;

    V_MAXPIECES NUMBER :=4;

BEGIN

    V_FILENAMETABLE(1) := '/oradata/ora9/db1rman_final/fulldb_db1_20191025_58108_1';

    V_DEVICE := SYS.DBMS_BACKUP_RESTORE.DEVICEALLOCATE();

    SYS.DBMS_BACKUP_RESTORE.RESTORESETDATAFILE;

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(58,'/rlvdb1_db1_idx13.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(61,'/rlvdb1_db1_2_08.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(45,'/rlvdb1_db1_idx9.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(44,'/rlvdb1_db1_1_07.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(03,'/rlvdb1_undotbs2.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(50,'/rlvdb1_db1_4_09.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(07,'/rlvdb1_db1_1_02.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(11,'/rlvdb1_db1_2_01.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(15,'/rlvdb1_db1_2_05.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(19,'/rlvdb1_db1_3_04.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(23,'/rlvdb1_db1_4_03.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(27,'/rlvdb1_db1_idx2.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(31,'/rlvdb1_xc_def02.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(39,'/rlvdb1_db1_4_06.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(37,'/rlvdb1_db1_def03.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(47,'/rlvdb1_pub_def2.dbf');

    FOR I IN 1..V_MAXPIECES LOOP

       SYS.DBMS_BACKUP_RESTORE.RESTOREBACKUPPIECE(V_FILENAMETABLE(I),V_FINISH);

       IF V_FINISH THEN

           SYS.DBMS_BACKUP_RESTORE.DEVICEDEALLOCATE;

           RETURN;

       END IF;

    END LOOP;

    SYS.DBMS_BACKUP_RESTORE.DEVICEDEALLOCATE;

END;

/

 

DECLARE

    V_DEVICE VARCHAR2(100);

    V_FINISH BOOLEAN;

    TYPE T_FILENAMETABLE IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;

    V_FILENAMETABLE T_FILENAMETABLE;

    V_MAXPIECES NUMBER :=4;

BEGIN

    V_FILENAMETABLE(1) := '/oradata/ora9/db1rman_final/fulldb_db1_20191025_58109_1';

    V_DEVICE := SYS.DBMS_BACKUP_RESTORE.DEVICEALLOCATE();

    SYS.DBMS_BACKUP_RESTORE.RESTORESETDATAFILE;

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(34,'/rlvdb1_db1_4_11.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(60,'/rlvdb1_db1_1_09.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(64,'/rlvdb1_db1_4_12.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(41,'/rlvdb1_db1_idx8.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(46,'/rlvdb1_db1_4_08.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(51,'/rlvdb1_xc_def03.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(08,'/rlvdb1_db1_1_03.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(12,'/rlvdb1_db1_2_02.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(16,'/rlvdb1_db1_3_01.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(20,'/rlvdb1_db1_3_05.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(24,'/rlvdb1_db1_4_04.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(28,'/rlvdb1_db1_idx3.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(33,'/rlvdb1_db1_3_07.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(40,'/rlvdb1_db1_idx7.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(55,'/rlvdb1_pub_def3.dbf');

    SYS.DBMS_BACKUP_RESTORE.RESTOREDATAFILETO(32,'/rlvdb1_db1_2_06.dbf');

    FOR I IN 1..V_MAXPIECES LOOP

       SYS.DBMS_BACKUP_RESTORE.RESTOREBACKUPPIECE(V_FILENAMETABLE(I),V_FINISH);

       IF V_FINISH THEN

           SYS.DBMS_BACKUP_RESTORE.DEVICEDEALLOCATE;

           RETURN;

       END IF;

    END LOOP;

    SYS.DBMS_BACKUP_RESTORE.DEVICEDEALLOCATE;

END;

/

2.2.3 切换控制文件记录数据文件位置

# 9i使用catalog注册数据文件镜像或者使用alter database rename file '' to '';

catalog datafilecopy '/db1/rlvdb1_db1_1_05.dbf';

catalog datafilecopy '/db1/rlvdb1_db1_3_07.dbf';

 

alter database rename file '/dev/rlvdb1_undotbs1'to '/db1/rlvdb1_undotbs1.dbf';

alter database rename file '/dev/rlvdb1_db1_4_12' to '/db1/rlvdb1_db1_4_12.dbf';

2.2.4 修改redo联机日志位置

select 'alter database rename file '''||member||''' TO '''||'/'||member||'.log'||''';' from v$logfile;

alter database rename file '/dev/rlvdb1_log11a' TO '/rlvdb1_log11a.log';

alter database rename file '/dev/rlvdb1_log12a' TO '/rlvdb1_log12a.log';

alter database rename file '/dev/rlvdb1_log13a' TO '/rlvdb1_log13a.log';

alter database rename file '/dev/rlvdb1_log14a' TO '/rlvdb1_log14a.log';

alter database rename file '/dev/rlvdb1_log21a' TO '/rlvdb1_log21a.log';

alter database rename file '/dev/rlvdb1_log22a' TO '/rlvdb1_log22a.log';

alter database rename file '/dev/rlvdb1_log23a' TO '/rlvdb1_log23a.log';

alter database rename file '/dev/rlvdb1_log24a' TO '/rlvdb1_log24a.log';

2.2.5 migrate打开数据库升级9.2.0.8

SQL> alter database open resetlogs migrate;

Database altered.

 

SQL> SPOOL patch.log

SQL> @?/rdbms/admin/catpatch.sql

SQL> SPOOL OFF

2.3 exp/imp迁移至19c中间库

2.3.1 9.2.0.8库生成批量创建表空间语句

select 'create tablespace '||tablespace_name||' datafile '''||'/u01/app/oracle/oradata/HASWMID/db1'||file_name||''' size '||bytes/1024/1024||'M;' from dba_data_files order by tablespace_name;

2.3.2 19c中间库创建同名pdb并创建表空间

create pluggable database db1 admin user db1 identified by oracle file_name_convert=('/testmid/pdbseed','/testmid/db1');

l   所有表空间都要创建,且大小要与源库至少相同

create tablespace TBS_PUBL_DEF datafile '/u01/app/oracle/oradata/HASWMID/db1/rlvdb1_pub_def1.dbf' size 1000M;

alter tablespace TBS_ZZSFP_IDX add datafile '/u01/app/oracle/oradata/HASWMID/db1/rlvdb1_db1_idx4.dbf' size 8000M;

2.3.3 19c中间库pdb创建用户

l   9.2.0.8源库生成语句

select 'create user '||username||' identified by oracle default tablespace '||default_tablespace||' temporary tablespace '||temporary_tablespace||';' from dba_users order by temporary_tablespace;

l   pdb创建临时表空间

create temporary tablespace TBS_ZZSFP_TMP tempfile '/u01/app/oracle/oradata/HASWMID/db1/TBS_ZZSFP_TMP01.dbf' size 32767M;

 

create user test1 identified by oracle default tablespace test_tmp temporary tablespace TBS_ZZSFP_TMP;

create user test2 identified by oracle default tablespace SYSTEM temporary tablespace TEMP;

2.3.4 用户赋系统权限

l   9.2.0.8生成赋权语句脚本

l   生成语句之后,目标库执行即可

l   建议对所有用户单独赋予unlimited tablespace权限,防止导入失败

for c in user1 user2

do

       ./sqlplus -S system/oracle >> sys_priv_grants.log <

col PRIVILEGE for a30

col GRANTEE for a20

col ADMIN_OPT for a15

set lines 180

set pagesize 1000

set echo off

set heading off

set feedback off

SELECT 'GRANT '||a.PRIVILEGE||' TO '||'${c}'||';'

FROM

(

       SELECT *

       FROM DBA_SYS_PRIVS

       WHERE GRANTEE = '${c}'

       UNION ALL

       SELECT *

       FROM DBA_SYS_PRIVS

       WHERE GRANTEE IN

            (SELECT GRANTED_ROLE FROM DBA_ROLE_PRIVS WHERE GRANTEE = '${c}' AND granted_role not in('EXP_FULL_DATABASE','IMP_FULL_DATABASE'))

) a;

exit;

EOF

done

2.3.5 exp/imp迁移数据至中间库

l   9.2.0.8 exp

export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK

 

nohup ./exp system/oracle file=/oradata/ora9/app/oradata/db1exp/db1_$(date +%Y%m%d_%H%M%S).dmp parfile=/oradata/ora9/app/oradata/db1exp/db1.par log=/oradata/ora9/app/oradata/db1exp/db1_exp_$(date +%Y%m%d_%H%M%S).log &

db1.par

COMPRESS=n

FEEDBACK=10000

DIRECT=y

STATISTICS=none

RECORDLENGTH=65536

FULL=y

l   19c pdb导入

nohup imp userid=system/oracle@db1 BUFFER=1073741824 FILE=/u01/expdmp/db1_20201126_104224.dmp IGNORE=y STATISTICS=NONE FEEDBACK=10000 FULL=y LOG=/u01/expdmp/IMP_db1_$(date +%Y%m%d_%H%M%S).log &

l   导入完成赋予对象权限

ü   9.2.0.8源库生成对象权限脚本

for c in user1 user2

do

       ./sqlplus -S system/oracle >> object_grants.log <

set lines 180

set pagesize 1000

set echo off

set heading off

set feedback off

col grantee for a15

col owner for a15

col table_name for a30

col grantor for a15

SELECT 'GRANT '||a.PRIVILEGE||' ON '||a.owner||'."'||a.table_name||'" TO '||'${c}'||';'

FROM

(

       SELECT *

       FROM DBA_TAB_PRIVS

       WHERE GRANTEE = '${c}'

       UNION ALL

       SELECT *

       FROM DBA_TAB_PRIVS

       WHERE GRANTEE IN

            (SELECT GRANTED_ROLE FROM DBA_ROLE_PRIVS WHERE GRANTEE = '${c}' and granted_role not in('EXP_FULL_DATABASE','IMP_FULL_DATABASE'))

) a;

exit;

EOF

done

l   如果导入失败,批量删除用户脚本

for c in user1 user2

do

       ./sqlplus -S system/oracle >>drop_user.log <

DROP USER ${c} cascade;

exit;

EOF

done

2.4 19c目标库克隆中间库

l   目标库dbca字符集必须AL32UTF8

l   建议打开中间库19c归档模式,否则hot clone有机率由于最后refresh不在当前几个redo组导致hot clone失败

2.4.1 19c中间库配置以便热克隆

create user c##clone identified by oracle container=all;

grant dba to c##clone container=all;

grant create pluggable database to c##clone container=all;

grant create session,connect,resource,cdb_dba,sysoper to c##clone container=all;

2.4.2 目标库19c创建中间库19c db link

SQL> create public database link clone_link connect to c##clone identified by oracle using 'HASWMID';

2.4.3 热克隆

SQL> create pluggable database db1 from db1@clone_link file_name_convert=('/u01/app/oracle/oradata/source/db1','/u01/app/oracle/oradata/target/db1');

 

SQL> alter pluggable database db1 open;

SQL> alter system set job_queue_processes=0;

SQL> alter pluggable database db1 save state;

 

# 由于字符集不同,所以会报告警如下

SQL>  select * from PDB_PLUG_IN_VIOLATIONS

TIME                 NAM CAUSE      TYPE      ERROR_NUMBER       LINE MESSAGE                                  STATUS    ACTION                                       CON_ID

-------------------- --- ---------- --------- ------------ ---------- ---------------------------------------- --------- ---------------------------------------- ----------

27-NOV-20 10.09.16.8 db1  PDB not Un WARNING              0          1 Character set mismatch: PDB character se PENDING   Oracle recommends using Unicode (AL32UTF          3

42492 AM                 icode                                        t ZHS16GBK. CDB character set AL32UTF8.            8) character set for the database. Consi

                                                                                                                         der migrating the database to Unicode.

 

2.5 数据比对

2.5.1 对象数量校验

l   9i源库

for c in user1 user2

do

       ./sqlplus -S system/oracle >> Users_object_count.log <

set echo off

set heading off

set lines 180

set pagesize 1000

SELECT DISTINCT OBJECT_TYPE,COUNT(*) FROM dba_objects where owner='${c}' GROUP BY OBJECT_TYPE ORDER BY 1;

exit;

EOF

done

l   19c目标库

for c in user1 user2

do

    sqlplus -S system/oracle@db1 >> Users_object_count.log <

set echo off

set heading off

set lines 180

set pagesize 1000

SELECT DISTINCT OBJECT_TYPE,COUNT(*) FROM dba_objects where owner='${c}' GROUP BY OBJECT_TYPE ORDER BY 1;

exit;

EOF

done

2.5.2 数据行数比对

l   源端目标端均执行,然后可以将源库table_hash导入目标库通过语句校验。

# 创建存储表数据量 table_hash

sqlplus -S system/oracle <

CREATE TABLE table_hash(owner varchar2(100),table_name varchar2(100),tc number,primary key(owner,table_name));

EXIT;

EOF

 

# 计算所有表数据量

for c in user1 user2

do

       sqlplus -S system/oracle@jh >> user_count.log <

DECLARE

       v_cc number;

       CURSOR v_tbl IS SELECT owner,table_name FROM dba_tables WHERE OWNER='${c}';

BEGIN

       FOR c IN v_tbl LOOP

       EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM '||c.owner||'.'||'"'||c.table_name||'"' INTO v_cc;

       INSERT INTO TABLE_HASH VALUES(c.owner,c.table_name,v_cc);

       END LOOP;

       COMMIT;

END;

/

EXIT;

EOF

done

l   校验

COL OWNER FOR A20

COL TABLE_NAME FOR A40

SET LINES 200 PAGES 2000 

SELECT DEST.OWNER,DEST.TABLE_NAME,DEST.TC,SOURCE.TC   

FROM TABLE_HASH DEST,

    SOURCE.TABLE_HASH SOURCE

WHERE DEST.OWNER = SOURCE.OWNER

AND DEST.TABLE_NAME = SOURCE.TABLE_NAME

AND DEST.TC != SOURCE.TC;

 

SELECT * FROM

    SOURCE.TABLE_HASH SOURCE

    MINUS

SELECT * FROM

TABLE_HASH DEST;

3 Linux 11.2.0.4 dbua升级并保留字符集迁移19c

3.1 db2恢复步骤概述

l   Linux 11.2.0.4恢复备份集

l   dbua升级至19c non-cdb

l   转换non-cdb至19c cdb中间库

l   目标库19c hot clone完成保留字符集迁移

3.2 利用备份集恢复

3.2.1 启动实例恢复控制文件

*.audit_file_dest='/u01/app/oracle/admin/db2/adump'

*.audit_trail='db'

*.compatible='11.2.0.4.0'

*.control_files='/u01/app/oracle/product/11.2.0/dbhome_1/oradata/db2/control01.ctl'

*.db_block_size=8192

*.db_domain=''

*.db_name='db2'

*.diagnostic_dest='/u01/app/oracle'

*.dispatchers='(PROTOCOL=TCP) (SERVICE=dzfpXDB)'

*.memory_target=8G

*.open_cursors=300

*.processes=2000

*.remote_login_passwordfile='exclusive'

*.sessions=610

*.undo_tablespace='UNDOTBS1'

*.job_queue_processes=0

 

SQL> startup nomount pfile='/tmp/11.txt';

ORACLE instance started.

 

RMAN> restore controlfile from '/u01/db2rman_final/c-c-2343833572-20191025-00';

RMAN> alter database mount;

RMAN> crosscheck backup;

RMAN> delete noprompt expired backup;

RMAN> crosscheck archivelog all;

RMAN> delete noprompt expired archivelog all;

RMAN> catalog start with '/u01/db2rman_final';

3.2.2 恢复数据文件

RMAN> run{

allocate channel c1 type disk;

allocate channel c2 type disk;

allocate channel c3 type disk;

allocate channel c4 type disk;

allocate channel c5 type disk;

allocate channel c6 type disk;

set newname for datafile 1 to '/u01/app/oracle/product/11.2.0/dbhome_1/oradata/db2/system.dbf';

set newname for datafile 116 to '/u01/app/oracle/product/11.2.0/dbhome_1/oradata/db2/lvsksk_i_js_jsp_02.dbf';

restore database;

switch datafile all;

release channel c1;

release channel c2;

release channel c3;

release channel c4;

release channel c5;

release channel c6;

}

3.2.3 重命名redo联机日志

select 'alter database rename file '''||member||''' TO ''/u01/app/oracle/product/11.2.0/dbhome_1/oradata/db2'||'/'||member||'.log'||''';' from v$logfile;

 

alter database rename file '+DATA/db2/onlinelog/group_2.275.918765543' TO '/u01/app/oracle/product/11.2.0/dbhome_1/oradata/db2/group_2.log';

alter database rename file '+DATA/db2/onlinelog/group_4.302.918765673' TO '/u01/app/oracle/product/11.2.0/dbhome_1/oradata/db2/group_4.log';

3.2.4 打开数据库添加temp文件

SQL> alter database open resetlogs;

 

SQL> alter tablespace temp add tempfile '/u01/app/oracle/product/11.2.0/dbhome_1/oradata/db2/temp01.dbf' size 32767m;

 

SQL>  alter tablespace temp01 add tempfile '/u01/app/oracle/product/11.2.0/dbhome_1/oradata/db2/temp01_01.dbf' size 32767m;

 

SQL> alter tablespace temp drop tempfile '+DATA/db2/tempfile/temp.305.918765545';

 

SQL> alter tablespace temp01 drop tempfile '+DATA/db2/datafile/temp01.dbf';

 

 

3.3 dbua升级至non-cdb 19c

3.3.1 修改闪回区

l   空间允许尽量设置大,否则可能会由于闪回区空间不足导致dbua升级失败

SQL> alter system set db_recovery_file_dest_size=200g;

SQL>  alter system set db_recovery_file_dest='/u01/app/oracle/product/11.2.0/dbhome_1/oradata/db2/fra';

3.3.2 19c dbua

# dbua 会有使用 19c 预升级脚本进行检查 11.2.0.4 库,不符合条件或者警告,需要进行配置修改,然后继续运行 dbua

$ dbua

3.3.3 non-cdb转换pdb

l   non-cdb需要read only:

SQL> startup read only;

BEGIN

    DBMS_PDB.DESCRIBE(

       pdb_descr_file => '/u01/db2ncdb.xml' );

END;

/

l   19c中间库 cdb检查是否可以plug in

SET SERVEROUTPUT ON

DECLARE

    compatible CONSTANT VARCHAR2(3) :=

       CASE DBMS_PDB.CHECK_PLUG_COMPATIBILITY(

           pdb_descr_file => '/u01/db2ncdb.xml',

           pdb_name => 'DB2')

       WHEN TRUE THEN 'YES'

       ELSE 'NO'

    END;

    BEGIN

       DBMS_OUTPUT.PUT_LINE(compatible);

    END;

    /

l   如果输出结果为NO,查看下面视图解决对应问题

SELECT * FROM PDB_PLUG_IN_VIOLATIONS;

# 由于 Aplex 无法升级,所以在升级 19c 之前需要移除 Apex 组件

l   使用11g apxremov.sql移除apex组件,重新执行上面命令

 

SQL> @apxremov.sql

l   可以转换之后,19c中间库进行non-cdb插入cdb操作

CREATE PLUGGABLE DATABASE db2 USING '/u01/db2ncdb.xml'

COPY

FILE_NAME_CONVERT = ('/u01/app/oracle/product/11.2.0/dbhome_1/oradata/db2','/u01/app/oracle/oradata/test/db2');

l   执行noncdb_to_pdb.sql脚本

SQL> alter session set container=db2;

SQL> @?/rdbms/admin/noncdb_to_pdb.sql

l   第一次必须以read write 打开

SQL> alter pluggable database db2 open;

3.3.4 open报错解决

l   报错如下

*** 2020-12-01T17:26:12.013790+08:00 (CDB$ROOT(1))

Unexpected error 4088 in job slave process

at 0x7ffe839acec0 placed kkj.c@1175

ORA-04088: error during execution of trigger 'SYS.LOGOFF_AUDIT_TRIGGER'

ORA-00604: error occurred at recursive SQL level 1

ORA-01427: single-row subquery returns more than one row

ORA-06512: at line 5

ORA-12012: error on auto execute of job "SYS"."CLEANUP_NON_EXIST_OBJ"

ORA-04088: error during execution of trigger 'SYS.LOGOFF_AUDIT_TRIGGER'

ORA-00604: error occurred at recursive SQL level 1

ORA-01427: single-row subquery returns more than one row

ORA-06512: at line 5

 

ORA-06512: at line 5

2020-12-02T07:44:17.085945+08:00

Errors in file /u01/app/oracle/diag/rdbms/test/test/trace/test_j008_19026.trc:

ORA-04088: error during execution of trigger 'SYS.LOGOFF_AUDIT_TRIGGER'

ORA-00604: error occurred at recursive SQL level 1

ORA-01427: single-row subquery returns more than one row

ORA-06512: at line 5

ORA-12012: error on auto execute of job "SYS"."CLEANUP_NON_EXIST_OBJ"

ORA-04088: error during execution of trigger 'SYS.LOGOFF_AUDIT_TRIGGER'

ORA-00604: error occurred at recursive SQL level 1

ORA-01427: single-row subquery returns more than one row

ORA-06512: at line 5

2020-12-02T07:44:17.087638+08:00

Errors in file /u01/app/oracle/diag/rdbms/test/test/trace/test_j006_19022.trc:

ORA-04088: error during execution of trigger 'SYS.LOGOFF_AUDIT_TRIGGER'

ORA-00604: error occurred at recursive SQL level 1

ORA-01427: single-row subquery returns more than one row

ORA-06512: at line 5

ORA-12012: error on auto execute of job "SYS"."PURGE_LOG"

ORA-04088: error during execution of trigger 'SYS.LOGOFF_AUDIT_TRIGGER'

ORA-00604: error occurred at recursive SQL level 1

ORA-01427: single-row subquery returns more than one row

ORA-06512: at line 5

2020-12-02T07:47:24.277315+08:00

l   解决

根据相关trace文件,以及打开10046追踪open pdb过程,发现报错为trigger插入相关stat$基表违反唯一约束导致,truncate相关统计信息基表,再次测试重启pdb,报错不再发生。

3.4 19c目标库热克隆

create pluggable database db2 from db2@clone_link file_name_convert=('/u01/app/oracle/oradata/test/db2','/u01/app/oracle/oradata/TEST/db2');

4 Linux 11.2.0.4 expdp迁移升级至19c

4.1 利用备份集恢复

4.1.1 启动实例恢复控制文件

*.audit_file_dest='/u01/app/oracle/admin/db3/adump'

*.audit_trail='db'

*.control_files='/u01/app/oracle/product/11.2.0/dbhome_1/oradata/db3/control01.ctl'

*.db_block_size=8192

*.db_domain=''

*.db_name='db3'

*.compatible='11.2.0.4.0'

*.diagnostic_dest='/u01/app/oracle'

*.dispatchers='(PROTOCOL=TCP) (SERVICE=dzfpXDB)'

*.memory_target=8G

*.open_cursors=300

*.processes=2000

*.remote_login_passwordfile='exclusive'

*.sessions=610

*.undo_tablespace='UNDOTBS1'

*.job_queue_processes=0

 

SQL> startup nomount pfile='/tmp/11.txt';

SQL> create spfile from pfile='/tmp/11.txt';

 

RMAN> restore controlfile from '/u01/db3rman_final/db3_09uf6rdp_1_1';

4.1.2 恢复数据文件

RMAN> alter database mount;

RMAN> catalog start with '/u01/db3rman_final';

run{

allocate channel c1 type disk;

allocate channel c2 type disk;

allocate channel c3 type disk;

allocate channel c4 type disk;

allocate channel c5 type disk;

allocate channel c6 type disk;

set newname for datafile 1 to '/u01/app/oracle/product/11.2.0/dbhome_1/oradata/db3/system01.dbf';

set newname for datafile 45 to '/u01/app/oracle/product/11.2.0/dbhome_1/oradata/db3/indx11.dbf';

restore database;

switch datafile all;

release channel c1;

release channel c2;

release channel c3;

release channel c4;

release channel c5;

release channel c6;

}

4.1.3 重命名redo联机日志

select 'alter database rename file '''||member||''' TO ''/u01/app/oracle/product/11.2.0/dbhome_1/oradata/db3/'||'/'||member||'.log'||''';' from v$logfile;

 

alter database rename file '/u01/app/oracle/oradata/db3/redo07.log' TO '/u01/app/oracle/product/11.2.0/dbhome_1/oradata/db3/redo07.log.log';

alter database rename file '/u01/app/oracle/oradata/db3/redo02.log' TO '/u01/app/oracle/product/11.2.0/dbhome_1/oradata/db3/redo02.log.log';

 

SQL> alter database open resetlogs;

4.2 源库expdp导出

nohup ./expdp system/oracle dumpfile=expdp_db3_%U.dmp directory=expdp parallel=8 full=y exclude=statistics &

4.3 中间库创建pdb

SQL> create pluggable database db3 admin user db3 identified by oracle file_name_convert=('/u01/app/oracle/oradata/test/pdbseed','/u01/app/oracle/oradata/test/db3');

4.4 中间库库创建表空间

l   11.2.0.4源库生成语句并修改

select 'create tablespace '||t.name||' datafile '''||'/u01/app/oracle/product/11.2.0/dbhome_1/oradata/db3/'||t.name||d.file#||'.dbf'||''' size '||d.bytes/1024/1024||'M;' from v$datafile d,v$tablespace t where d.ts# = t.ts# order by t.name;

l   中间库pdb创建表空间

create tablespace testdatafile '/u01/app/oracle/product/11.2.0/dbhome_1/oradata/db3/HEAD7.dbf' size 32766M;

alter tablespace test_IND add datafile '/u01/app/oracle/product/11.2.0/dbhome_1/oradata/db3/WSBS_IND21.dbf' size 20480M;

l   修改表空间均修改为自动扩展

select 'ALTER DATABASE DATAFILE '''||file_name||''' AUTOEXTEND ON;' from dba_data_files where tablespace_name not in ('SYSTEM','SYSAUX','UNDOTBS1','USERS') AND AUTOEXTENSIBLE='NO';

4.5 中间库impdp导入

nohup impdp system/oracle dumpfile=expdp_db3_%U.dmp directory=expdmp parallel=8 &

4.6 目标库热克隆保留字符集

SQL> create pluggable database db3 from db3@clone_link file_name_convert=('/u01/app/oracle/oradata/HASWMID/db3','/u01/app/oracle/oradata/TEST/db3','/u01/app/oracle/product/11.2.0/dbhome_1/oradata/db3','/u01/app/oracle/oradata/TEST/db3');

 


请使用浏览器的分享功能分享到微信等