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

1 传输表空间

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

  1. 使用MOS提供rman_xttconvert工具包进行在线迁移,即通常所说xtts。
  2. 表空间置为Read only离线,通过RMAN进行convert结合exp/imp expdp/impdp导出导入元数据进行迁移。
  3. 12c 引入了使用备份进行跨平台传输表空间,与上述第二种方法大部分步骤相同,RMAN备份方式可以充分利用RMAN压缩等降低文件大小,减少read only时间

2 版本介绍

  1. 源 端:HP-UX Oracle 11.2.0.3 ASM存储 数据量30TB
  2. 目标端:RHEL 7.7 Oracle 11.2.0.3 NAS存储

3 挂载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');

扫描二维码关注公众号,回复: 12740101 查看本文章

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

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

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;

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
)

置为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%';

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

4.1 rman convert转换

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

#!/bin/sh
# rman convert script
export ORACLE_SID=
v_date=$(date +%Y%m%d%H%M%S)

echo "Job Start time ${v_date}\n" >> rman_xtts_${v_date}.log
rman target / >> rman_xtts_${v_date}.log <<EOF
run{
allocate channel c1 type disk;
...
convert tablespace tbs1,tbs2... to platform 'Linux x86 64-bit' format '/rman/xtts/xtts_%U.dbf';
release channel c1;
...
}
EOF
v_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.par
TRANSPORT_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)

6. 目标库导入

6.1 impdp导入元数据与datafile

# 下面为测试环境示例,并非真实环境,真实环境只是使用路径与名称不同
$ impdp \'\/ as sysdba\' directory=xtts dumpfile=xtts.dmp parfile=xtts.par logfile=impdp_xtts.log

$ vi xtts.par
TRANSPORT_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 Production
With the Partitioning, Real Application Clusters, OLAP, Data Mining
and Real Application Testing options
Master table "SYS"."SYS_IMPORT_TRANSPORTABLE_01" successfully loaded/unloaded
Starting "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_BLK
Processing object type TRANSPORTABLE_EXPORT/TABLE
Processing object type TRANSPORTABLE_EXPORT/TABLE_STATISTICS
Processing object type TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLK
Job "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 username
from dba_users
where 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 script
for c in user1 user2
do
        sqlplus -S system/oracle >> sys_priv_grants.log <<EOF
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

# 源库生成对象权限授权语句
#!/bin/sh
# tab privs generate script
for c in user1 user2
do
        sqlplus -S system/oracle >> object_grants.log <<EOF
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

7.3 回收DBA权限

select 'revoke dba from '||username||';'
from dba_users
where 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.par
content=metadata_only
schemas=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 scripts
for c in user1 user2
do
        sqlplus -S system/oracle >> users_object_count.log <<EOF
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

-  比对对象数量过程中遇到如下几个问题
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语句
--供参考
declare
v_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 <<EOF
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 >> user_count.log <<EOF
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

-- 校验
-- 可以在目标库创建源端db link进行比对
-- 也可以将源端比对数据表导入目标库进行比对
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;

--如果要计算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 exported
EXP-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、目录对象需要手工创建。

猜你喜欢

转载自blog.csdn.net/oradbm/article/details/113991945