Oracle数据库迁移:异构传输表空间TTS HP-UX迁移至Redhat Linux 7.7

墨墨导读:本文来自墨天轮用户“你好我是李白”的投稿,记录一个Oracle数据库迁移过程 :异构传输表空间TTS HP-UX迁移至Redhat Linux 7.7。

墨天轮主页:https://www.modb.pro/u/3997

传输表空间

异构跨平台传输表空间分为两种

  1. 使用MOS提供rman_xttconvert工具包进行在线迁移,即通常所说xtts。

  2. 表空间置为Read only离线,通过RMAN进行convert结合exp/imp expdp/impdp导出导入元数据进行迁移。

  3. 12c 引入了使用备份进行跨平台传输表空间,与上述第二种方法大部分步骤相同,RMAN备份方式可以充分利用RMAN压缩等降低文件大小,减少read only时间。

  • 可以参考文章:https://www.cndba.cn/dave/article/4404

由于一般数据库都需要在迁移过程中对外提供服务,所以表空间置为只读在大部分情况下不可接受,所以一般使用第一种xtts工具包进行在线迁移,本文则使用第二种方式迁移。

1. 环境介绍

1.1 版本介绍

  • 源 端:HP-UX Oracle 11.2.0.3 ASM存储 数据量30TB

  • 目标端:RHEL 7.7 Oracle 11.2.0.3 NAS存储

1.2 迁移方式

由于本次迁移为历史库迁移,且数据库未开启归档模式,所以选择较为便捷第二种方式进行迁移。

2. 环境准备

2.1 挂载NFS

源库30TB,HP-UX与Linux通过NFS挂载目标库NAS存储磁盘,直接convert转换数据文件至最终NAS存储,省去拷贝时间。

HP-UX

mount -F nfs hard,bg,proto=tcp,rsize=32768,wsize=32768,nointr,noac,forcedirectio,llock xx.xx.xx.xx:/data/nfs /tts

Linux:

mount -t nfs -o hard,bg,nolock xx.xx.xx.xx:/data/nfs /data

2.2 查询源端平台与目标平台是否可转换

select * from v$transportable_platform; PLATFORM_ID PLATFORM_NAME ENDIAN_FORMAT------------ ------------------------------------ --------------... 4 HP-UX IA (64-bit) Big... 13 Linux x86 64-bit Little...
--可以看到可以转换,但是由于字节序不同,所以需要转换。
select platform_id,platform_name from v$database; PLATFORM_ID PLATFORM_NAME ------------ -------------------- 4 HP-UX IA (64-bit)

3. 迁移准备

3.1 提取需要转换的表空间

由于本次为整库迁移,所以除一些系统表空间外,其他均需要转换

  1. 查看system users sysaux是否有非sys以及一些组件对象

select owner ,table_name ,tablespace_name from dba_tables where owner not in ('SYS','SYSTEM','OUTLN','SCOTT') and tablespace_name in ('SYSTEM','SYSAUX','USERS');

根据查询出来对象,决定是否需要额外处理这几个表空间,users表空间如果包含非sys对象,则需要在目标端删除users表空间,将源库users一起转换,本次查询users表空间也需要一同转换

  1. 获取需要迁移表空间列表

select distinct tablespace_name from dba_tablespaces where tablespace_name not in ('SYSTEM','SYSAUX','UNDOTBS1','UNDOTBS2')minusselect distinct tablespace_name from dba_temp_files;

3.2 验证要传输表空间是否自包含

SYS > EXEC SYS.DBMS_TTS.TRANSPORT_SET_CHECK(ts_list => '<TABLESPACE_NAME>', incl_constraints => TRUE); SYS > SELECT * FROM TRANSPORT_SET_VIOLATIONS;VIOLATIONS--------------------------------------------------------------------ORA-39921: Default Partition (Table) Tablespace xxx(表空间名) for xxx(表名) not contained in transportable set.# 可以根据下满Mos文档进行相应处理# 我的环境中,违反表空间不存在,也无相应segment在该表空间,根据表空间名称,创建之后,一起转换解决报错问题。

Using Dbms_tts.transport_set_check Results in Entry in Transport_set_violations (Doc ID 114915.1)

3.3 表空间置为read only

select 'ALTER TABLESPACE '||TABLESPACE_NAME||' READ ONLY;'FROM ( SELECT DISTINCT TABLESPACE_NAME FROM DBA_TABLESPACES WHERE TABLESPACE_NAME NOT IN ('SYSTEM','SYSAUX','UNDOTBS1','UNDOTBS2') MINUS SELECT DISTINCT TABLESPACE_NAME FROM DBA_TEMP_FILES);
'ALTERTABLESPACE'||TABLESPACE_NAME||'READONLY;'----------------------------------------------------------ALTER TABLESPACE XXX READ ONLY;...

置为read only过程中,遇到部分表空间无法read only,kill掉所有会话,但是依然无法read only,查询等待事件为wait for another txn - txn abort,该等待一般为有状态处于dead状态事务,需要等待smon回滚结束,通过下面语句可以查询进度。

SELECT count(*) FROM x$ktuxe WHERE ktuxesta != 'INACTIVE' AND ktuxecfl LIKE '%DEAD%'; SELECT ktuxesiz FROM x$ktuxe WHERE ktuxesta != 'INACTIVE' AND ktuxecfl LIKE '%DEAD%';
  • 确认表空间是否置为只读

select distinct tablespace_name,status from dba_tablespaces where tablespace_name not in ('SYSTEM','SYSAUX','UNDOTBS1','UNDOTBS2')minusselect distinct tablespace_name,status from dba_temp_files;

4. 源库转换与元数据导出

4.1 rman convert转换

可以在远端convert tablespace,也可以在目标端convert datafile

#!/bin/sh# rman convert scriptexport ORACLE_SID=v_date=$(date +%Y%m%d%H%M%S)
echo "Job Start time ${v_date}\n" >> rman_xtts_${v_date}.logrman target / >> rman_xtts_${v_date}.log <<EOFrun{allocate channel c1 type disk;...convert tablespace tbs1,tbs2... to platform 'Linux x86 64-bit' format '/rman/xtts/xtts_%U.dbf';release channel c1;...}EOFv_end_date=$(date +%Y%m%d%H%M%S)echo "Job End Time ${v_date}\n" >> rman_xtts_${v_date}.log

4.2 expdp导出元数据

$ nohup expdp system/111111 directory=xtts dumpfile=xtts.dmp parfile=expdp.par logfile=xtts_expdp.log &$ vi expdp.parTRANSPORT_TABLESPACES=tbs1,tbs2...,tbsn

导出元数据时,expdp导出非常慢,查询相关文档,进行如下尝试:

  1. 尝试收集dictionary统计信息,并未提高效率。

  2. 根据下面文档,尝试使用非sysdba用户导出,效率有所提升。

Slow DataPump Import (IMPDP) For A Partitioned Table (Doc ID 2014960.1)
  1. 11.2.0.3版本有如下bug,需要打patch 13717234。

Bug 13717234 - Datapump export for transport is slow handling a large number of objects (Doc ID 13717234.8)Transport Tablespace Expdp is Slow when Handling Large Number of Objects in the Database (Doc ID 1554570.1)

5. 目标端准备

由于NAS存储可以直接挂载到目标端,所以省去了scp或ftp传输到目标端转换好的数据文件步骤。

5.1 目标端安装oracle软件dbca建库

根据安装文档安装oracle软件,dbca创建空库。

5.2 处理users表空间

由于要传输源端users表空间,所以目标端需要更改默认表空间,删除users表空间

create tablespace users_xtts datafile 'path' size 1g autoextend on;alter database default tablespace users_xtts;drop tablespace users including contents and datafiles;

5.3 目标端创建用户

由于需要导入元数据以及表空间,但是目标库并没有源端用户,所以需要提前创建。

# 源端库生成建用户语句,在目标库执行创建用户select 'create user '||username||' identified by oracle default tablespace users_xtts temporary tablespace temp;'from dba_userswhere username not in ('SYS','SYSTEM','DBSNMP','OUTLN','ORACLE_OCM','XS$NULL','MDDATA','SPATIAL_UFS_ADMIN_USR','SPATIAL_CSW_ADMIN_USR','MGMT_VIEW','APEX_PUBLIC_USER') AND DEFAULT_TABLESPACE NOT IN ('SYSAUX')ORDER BY TEMPORARY_TABLESPACE;
# 先赋予DBA权限,防止导入时由于缺乏权限失败,待导入数据完成,最后再根据源库权限赋予目标库用户相应权限select 'grant dba to '||username||';'from dba_userswhere username not in ('SYS','SYSTEM','DBSNMP','OUTLN','ORACLE_OCM','XS$NULL','MDDATA','SPATIAL_UFS_ADMIN_USR','SPATIAL_CSW_ADMIN_USR','MGMT_VIEW','APEX_PUBLIC_USER') AND DEFAULT_TABLESPACE NOT IN ('SYSAUX')ORDER BY TEMPORARY_TABLESPACE;

6. 目标库导入

6.1 impdp导入元数据与datafile

# 下面为测试环境示例,并非真实环境,真实环境只是使用路径与名称不同$ impdp \'\/ as sysdba\' directory=xtts dumpfile=xtts.dmp parfile=xtts.par logfile=impdp_xtts.log
$ vi xtts.parTRANSPORT_DATAFILES=('/rman/xtts/xtts_data_D-MESSAY_I-2399541070_TS-XTTS1_FNO-15_04vhgsno.dbf','/rman/xtts/xtts_data_D-MESSAY_I-2399541070_TS-XTTS_FNO-14_03vhgsnm.dbf','/rman/xtts/xtts_data_D-MESSAY_I-2399541070_TS-XTTS_FNO-8_02vhgsnl.dbf')
Import: Release 11.2.0.4.0 - Production on Fri Jan 8 12:40:24 2021
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit ProductionWith the Partitioning, Real Application Clusters, OLAP, Data Miningand Real Application Testing optionsMaster table "SYS"."SYS_IMPORT_TRANSPORTABLE_01" successfully loaded/unloadedStarting "SYS"."SYS_IMPORT_TRANSPORTABLE_01": "/******** AS SYSDBA" directory=xtts dumpfile=xtts.dmp parfile=xtts.par logfile=impdp_xtts.log Processing object type TRANSPORTABLE_EXPORT/PLUGTS_BLKProcessing object type TRANSPORTABLE_EXPORT/TABLEProcessing object type TRANSPORTABLE_EXPORT/TABLE_STATISTICSProcessing object type TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLKJob "SYS"."SYS_IMPORT_TRANSPORTABLE_01" successfully completed at Fri Jan 8 12:40:34 2021 elapsed 0 00:00:08

6.2 表空间置为读写

SYS > alter tablespace tbs1 read write;...

7. 目标库后续处理

7.1 目标库创建临时表空间

创建与源库相同表空间

# 源库查询是否使用临时表空间组SQL > select * from DBA_TABLESPACE_GROUPS;# 源库生成创建语句SELECT 'create temporary tablespace '||TABLESPACE_NAME||' tempfile ''/path/'||tablespace_name||file_id||'.dbf'' size 32767M;' from dba_temp_files order by tablespace_name;# 如果表空间有多个文件,还需要适当修改上述输出。

7.2 目标库赋权

# 源库获取用户列表select usernamefrom dba_userswhere username not in ('SYS','SYSTEM','DBSNMP','OUTLN','ORACLE_OCM','XS$NULL','MDDATA','SPATIAL_UFS_ADMIN_USR','SPATIAL_CSW_ADMIN_USR','MGMT_VIEW','APEX_PUBLIC_USER') AND DEFAULT_TABLESPACE NOT IN ('SYSAUX');
# 源库生成系统权限授权语句#!/bin/sh# sys privs generate scriptfor c in user1 user2do sqlplus -S system/oracle >> sys_priv_grants.log <<EOFcol PRIVILEGE for a30col GRANTEE for a20col ADMIN_OPT for a15set lines 180set pagesize 1000set echo offset heading offset feedback offSELECT '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;EOFdone
# 源库生成对象权限授权语句#!/bin/sh# tab privs generate scriptfor c in user1 user2do sqlplus -S system/oracle >> object_grants.log <<EOFset lines 180set pagesize 1000set echo offset heading offset feedback offcol grantee for a15col owner for a15col table_name for a30col grantor for a15SELECT '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;EOFdone

7.3 回收DBA权限

select 'revoke dba from '||username||';'from dba_userswhere username not in ('SYS','SYSTEM','DBSNMP','OUTLN','ORACLE_OCM','XS$NULL','MDDATA','SPATIAL_UFS_ADMIN_USR','SPATIAL_CSW_ADMIN_USR','MGMT_VIEW','APEX_PUBLIC_USER') AND DEFAULT_TABLESPACE NOT IN ('SYSAUX')ORDER BY TEMPORARY_TABLESPACE;

7.4 目标库表空间置为读写

select 'ALTER TABLESPACE '||TABLESPACE_NAME||' READ WRITE;'FROM ( SELECT DISTINCT TABLESPACE_NAME FROM DBA_TABLESPACES WHERE TABLESPACE_NAME NOT IN ('SYSTEM','SYSAUX','UNDOTBS1','UNDOTBS2') MINUS SELECT DISTINCT TABLESPACE_NAME FROM DBA_TEMP_FILES);
SELECT TABLESPACE_NAME,STATUS FROM DBA_TABLESPACES;

7.5 全局临时表、db link 存储过程等对象处理

由于只转换了非system 、sysaux表空间,所以还需要单独导出业务用户除表、索引以外其他对象,例如序列、db link、全局临时表等,这些对象存储在system表空间数据字典。

--源端导出元数据nohup expdp system/oracle directory=xtts parfile=expdp.par dumpfile=xtts_expdp_%U.dmp cluster=no logfile=xtts_expdp.log &$ vi expdp.parcontent=metadata_onlyschemas=user1,user2...,userN
--目标端导入--一些目录对象nohup impdp system/oracle directory=xtts table_exists_action=append dumpfile=xtts_expdp_%U.dmp logfile=impdp_xtts.log &

实际比对过程中,如下两部分有个别用户不同:1.lob部分目标端缺失,经排查,此部分lob在源端也不属于任何表。2.table partition部分目标端没有,经排查,部分回收站分区被统计,排除回收站名称分区 ,分区一致,开启recyclebin时,drop分区表之后,dba_tab_partitions依然可以查询到删除的BIN开头的分区,https://www.eygle.com/archives/2017/04/drop_partition_recyclebin.html

7.6 数据比对

  1. 对象数量比对

-- 源端目标端均执行-- 会生成user_object_count.log文件,源端目标端比对即可-- 也可以采用下面比对行数方法创建oracle内部表进行比对#!/bin/sh# object count scriptsfor c in user1 user2do sqlplus -S system/oracle >> users_object_count.log <<EOFset echo offset heading offset lines 180set pagesize 1000SELECT DISTINCT OBJECT_TYPE,COUNT(*) FROM dba_objects where owner='${c}' GROUP BY OBJECT_TYPE ORDER BY 1;exit;EOFdone
- 比对对象数量过程中遇到如下几个问题1.table partition数量不一致,经排查,为源端drop了一部分分区表,drop的分区表在查询dba_tab_partitions时,依然可以查到分区,只不过名称都变成了BIN开头。2.index partition数量不一致,也是由于上述原因,排除BIN$开头索引分区其余一致。3.部分materialized view、view由于使用db link,而db link由于网络导致创建失败导致失效,后面需要手工迁移db link下面为批量获取源端db link ddl语句--供参考declarev_objowner varchar2(50);v_objname varchar2(50);v_test clob;cursor c is select owner,db_link from dba_db_links;begin open c; loop fetch c into v_objowner,v_objname; if c%found then execute immediate 'select dbms_metadata.get_ddl(''DB_LINK'''||','''||v_objname||''','''||v_objowner||''') from dual' into v_test; dbms_output.put_line(v_test||';'); else exit; end if; end loop; close c;end;/
4.目录对象需要手工在目标端创建。
  1. 数据行数比对

-- 源端目标端均执行,然后可以将源库table_hash导入目标库通过语句校验。-- 创建存储表数据量table_hash表sqlplus -S system/oracle <<EOFCREATE TABLE table_hash(owner varchar2(100),table_name varchar2(100),tc number,primary key(owner,table_name));EXIT;EOF
-- 计算所有表数据量for c in user1 user2do sqlplus -S system/oracle >> user_count.log <<EOFDECLARE 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;EOFdone
-- 校验-- 可以在目标库创建源端db link进行比对-- 也可以将源端比对数据表导入目标库进行比对COL OWNER FOR A20COL TABLE_NAME FOR A40SET LINES 200 PAGES 2000 SELECT DEST.OWNER,DEST.TABLE_NAME,DEST.TC,SOURCE.TC FROM TABLE_HASH DEST, SOURCE.TABLE_HASH SOURCEWHERE DEST.OWNER = SOURCE.OWNERAND DEST.TABLE_NAME = SOURCE.TABLE_NAMEAND DEST.TC != SOURCE.TC;
SELECT * FROM SOURCE.TABLE_HASH SOURCE MINUSSELECT * FROM TABLE_HASH DEST;
--如果要计算hash值,计算绝对是否一致需要使用函数进行离线计算或者使用ogg veridata进行比对,SharePlex复制软件也有compare比对功能

7.7 目标库无效对象编译

SQL> EXEC UTL_RECOMP.recomp_parallel(4);# 查询是否还有无效对象,再根据具体无效原因进行处理SQL> select owner,object_type,object_name from dba_objects where status='INVALID';

7.8 收集统计信息

begin dbms_stats.gather_database_stats(estimate_percent=>5,method_opt=>'for all columns size 1',degree=>16,cascade=>true,gather_sys=>true,gather_temp=>false,gather_fixed=>true);end;/
begin dbms_stats.gather_dictionary_stats(method_opt=>'for all columns size 1',degree=>16);end;/

7.9 根据源端调整数据库参数

根据源端参数相关设置,调整目标库参数设置。

7.10 修改弱密码

修改数据库内部以及操作系统弱密码符合安全要求。

8. 迁移过程遇到问题

expdp导出非常慢,中间尝试使用exp导出元数据

8.1 exp 使用tts传输表空间遇到报错

# 10g以后引入的分区技术,exp均不支持EXP-00113: Feature New Composite Partitioning Method is unsupported,table will not be exported
# 11g引入了Virtual Column与基于Virtual Column的分区技术EXP-00107: Feature(VIRTUAL COLUMN) of column xxx in table xxx.xxx is not supported,table will not be exported
# BINARY_DOUBLE BINARY_FLOAT为Oracle 10g引入的两种数据类型EXP-00104: datatype (BINARY_DOUBLE) of column xxx in table xxx.xxx is not supported,table will not be exportedEXP-00104: datatype (BINARY_FLOAT) of column xxx in table xxx.xxx is not supported,table will not be exported

8.2 expdp导出缓慢

expdp导出数据缓慢,通过10046以及结合现象判断与下面两个问题高度关联

Slow DataPump Import (IMPDP) For A Partitioned Table (Doc ID 2014960.1)# 解决方案: 需要使用非sysdba用户导出 Bug 13717234 - Datapump export for transport is slow handling a large number of objects (Doc ID 13717234.8)Transport Tablespace Expdp is Slow when Handling Large Number of Objects in the Database (Doc ID 1554570.1)# 解决方案:需要为11.2.0.3打补丁patch 13717234

8.3 一些元数据处理

  1. 由于我们迁移无法重启数据库,所以无法将数据库置为read only,如果可以将数据库置为read only,则直接可以在rman中convert database,无需convert tablespace转换。

  2. convert tablespace由于未传输system表空间,所以一些存放在数据字典中对象db link、目录对象需要手工创建。

作者

陈振海,4年数据库运维经验,擅长Oracle、MySQL,具有Oracle 11g OCM、OBCA等数据库认证,长期服务于公安、保险、税务等客户。

墨天轮原文链接:https://www.modb.pro/db/45423(复制到浏览器打开或者点击“阅读原文”立即查看)

(0)

相关推荐