Oracle XTTS实现跨版本迁移和升级(Oracle 11g单库升级至19C RAC集群)

Oracle 11g单库升级至19C RAC集群(XTTS跨版本迁移升级)

一、案例环境

关键项 源环境 目标环境
主机名 host01 host61rac1/host62rac2
数据库架构 单库环境 RAC集群环境(2台主机)
数据库版本 11.2.0.4 19.3.0.0
操作系统 linux7.9_x64 linux7.9_x64
IP地址 192.168.11.16 192.168.11.61/62
实例名 orcl orcl1/orcl2
数据库名 orcl orcl
数据存储 /oradata/orcl /oradata1/orcl +DATA/ORCL(asm磁盘组)

本案例使用XTTS V3版本完成跨版本迁移升级

二、XTTS工具介绍

在 Oracle11gR2(推荐使用 11.2.0.4 及之后版本)以后,Oracle 推出了通过前滚数据文件,拷贝数据后再进行多次增量备份的 XTTS 来完成迁移过程,在这个过程中通过开启块跟踪特性,根据 SCN 号来执行一系列的增量备份,并且通过对块跟踪文件的扫描,来完成增量数据的增量备份应用,最后在通过一定的停机时间,在源库 read only 的状态下进行最后一次增量备份转换应用,使得整个迁移过程的停机时间同源库数据块的变化率成正比,大大的缩短了停机时间。

XTTS核心步骤概述

复制代码
1、源库主机使用XTTS,进行表空间数据文件抽取(第一次全量),记录抽取是数据文件的SCN号
2、将文件传输至目标库主机
3、目标库主机使用XTTS,将全量的数据文件,根据数据高低字节序转码(跨平台),转换为目标平台字节序,并存储至对应的数据文件目录(根据参数设置)。这个过程完成后,会记录源库和目标库数据文件的映射关系。
4、源库主机使用XTTS针对待传输的表空间数据文件,进行增量抽取(根据上一次记录的SCN号),抽取这一期间变化的数据块,完成增量数据备份,并再次生成新的SCN号(作为下一次增量的SCN起始号)
5、传输增量备份至目标库主机
6、目标库主机使用XTTS,将增量备份,应用至数据文件中(增量block应用)
7、重复4、5、6步骤。(保持目标端与源端数据的同步,整个过程不影响源端数据库使用)。
8、正式停机迁移阶段,主库将待迁移的表空间设置为read only,确保表空间的所有数据文件一致性,且不会再修改
9、源库进行最后一次增量备份,(类似步骤4),这一次备份的数据,由于表空间read only,可以确保数据文件一致性!
10、将最后一次的增量备份,传输至目标库主机
11、目标库应用最后一次增量恢复(类似步骤6)
12、目标库进行表空间元数据导入(类似传统的表空间传输方式)
13、目标库进行数据对象元数据导入

总结: XTTS 迁移方式,具备跨平台字序转换和全量初始化加增量 merge 的功能,非常适用于异构 OS 跨平台迁移,XTTS通常用于短时间(<6小时)的停机窗口进行大数据量,跨数据库版本,跨平台(不同endian format格式)的数据库迁移或者数据库升级。

xtts工具主要包含两个部分

1、xttdriver.pl:用户执行xtts的主程序,备份、转换、应用的执行脚本。

2、xtt.properties:配置xtts的参数文件,包含 XTTS 配置的路径、参数。

Oracle的XTTS迁移包含三种迁移方式

1、DBMS_FILE_TRANSFER;DBMS_FILE_TRANSFER 包是 Oracle 提供的一个用于复制二进制数据库文件或在数据库之间传输二进制文件的程序包,在 XTTS 迁移中,利用不同的参数进行数据文件传输转换完成迁移。

2、RMAN Backup;RMAN Backup 方式是基于 RMAN 备份原理,通过使用 rman-xttconvert包提供的参数,对数据库进行基于表空间的备份,将备份生产的备份集写到本地或者 NFS 盘上,然后在通过 rman-xttconvert包中包含的不同平台之间数据文件格式转换的包对进行数据文件格式转换,最后通过记录的表空间 的FILE_ID 号与生产元数据的导入来完成。

3、手工 XTTS 迁移;主要包括rman copy,数据文件格式转换,增量备份,增量转换和应用这四个阶段

备注:三种方式的目标端数据库版本均需要为 11.2.0.4 版本或者以上,如果在使用过程中,目标库的版本是 11.2.0.3 或者更低,那么需要创建一个单独的 11.2.0.4 版本数据库作为中间库来在目标端进行数据文件的格式转换,而使用 DBMS_FILE_TRANSFER 包目标端的数据库版本必须是 11.2.0.4

本案例采用RMAN Backup的方式对数据库进行迁移升级,主要包含如下方法

复制代码
$ORACLE_HOME/perl/bin/perl xttdriver.pl -p   //源库初始化、即备份表空间数据文件
$ORACLE_HOME/perl/bin/perl xttdriver.pl -c   //目标库将初始化的文件,保存至正确的数据文件存放目录
$ORACLE_HOME/perl/bin/perl xttdriver.pl -i   //源库执行增量备份
$ORACLE_HOME/perl/bin/perl xttdriver.pl -s   //源库确定下一次增量SCN号
$ORACLE_HOME/perl/bin/perl xttdriver.pl -r   //目标库执行增量恢复

注意:V4版本(rman_xttconvert_VER4.3)与V3版本的方式不一样,更便捷和简单。

三、XTTS迁移流程概述

复制代码
1、源库迁移用户和表空间确认
2、全量数据初始化前环境检查(源库和目标库)
3、NFS配置
4、源库主机配置另一个监听器(listener)
5、目标库创建指向源库的公用dblink
6、目标库RAC集群,建议只能保留一个节点正常运行
7、目标库创建directory
8、目标库关闭监听、禁止外部连接
9、配置xtts工具(源端和目标端都需要配置)
10、源端生成准备文件(待迁移的表空间第一次全量数据文件初始化,即备份)
11、目标库第一次初始化(转换初始化文件至 ASM 中)
12、源库生成测试数据
13、源库第一次执行增量备份(抽取这一期间变化的数据块)
14、目标库第一次执行增量恢复(注意增量恢复期间,目标库会重启!)
15、源库确定下一次增量开始的SCN号
16、源库再次生成测试数据
17、源库增量数据备份、目标库增量数据恢复,多次执行!
18、正式开始升级(业务需要停止!)
19、源库将待迁移表空间设为只读,确保表空间数据一致性!
20、源端执行最后一次增量备份
21、目标库最后一次增量(增量过程会重启数据库,这一点需要知晓!!!)
22、目标库生成导入表空间配置文件
23、目标库用户创建、系统权限和角色授权、profile创建
24、目标库创建临时表
25、目标库第一次元数据导入(传输表空间元数据)
26、目标库第二次元数据导入(其他对象元数据)
27、目标库后续收尾工作
28、业务程序连接重新指向,业务测试!

四、XTTS具体迁移过程

0、准备测试数据

复制代码
源库执行
create tablespace tbs_data datafile '/oradata/orcl/tbs_data_001.dbf' size 10m;
alter tablespace tbs_data add datafile '/oradata/orcl/tbs_data_002.dbf' size 10m;
create tablespace tbs2 datafile '/oradata1/orcl/tbs2_001.dbf' size 10m;
alter tablespace tbs2 add datafile '/oradata1/orcl/tbs2_002.dbf' size 10m;

create user u1  identified by u1 default tablespace tbs_data;
grant connect,resource,unlimited tablespace to u1;
grant select any table to u1;

create user u2  identified by u2 default tablespace tbs2;
grant connect,resource,unlimited tablespace to u2;
grant select any table to u2;

create user u3  identified by u3 default tablespace users;
grant connect,resource,unlimited tablespace to u3;

create table u1.tab1 as select * from dba_users;
create table u1.tab2 as select * from dba_data_files;


create table u2.tab1 as select * from dba_tablespaces;
create table u2.tab2 as select * from dba_free_space;

grant select on u1.tab1 to u3;
grant select on u1.tab2 to u3;
grant select on u2.tab1 to u3;
grant select on u2.tab2 to u3;

1、源库迁移用户和表空间确认

复制代码
迁移用户确认(非默认用户)
11g非默认用户
select username from dba_users 
where username not in ('SYS','SYSTEM','OUTLN','DIP','ORACLE_OCM',
'DBSNMP','APPQOSSYS','WMSYS','EXFSYS',
'CTXSYS','ANONYMOUS','XDB','XS$NULL',
'ORDPLUGINS','MDSYS','ORDSYS','ORDDATA',
'SI_INFORMTN_SCHEMA','OLAPSYS','MDDATA',
'SPATIAL_WFS_ADMIN_USR','SPATIAL_CSW_ADMIN_USR',
'SYSMAN','MGMT_VIEW','APEX_030200',
'FLOWS_FILES','APEX_PUBLIC_USER','OWBSYS',
'OWBSYS_AUDIT','SCOTT');
备注12C开始非默认用户的查询方式
select username from dba_users where ORACLE_MAINTAINED='N';

迁移表空间确认(非默认表空间)
select tablespace_name 
from dba_tablespaces 
where contents='PERMANENT' and tablespace_name not in ('SYSTEM', 'SYSAUX','USERS');
数据库初始创建时,自带创建的USERS表空间,如果没有业务对象,不建议迁移。如果确实需要迁移USERS表空间,那么目标库需要先删除USERS表空间,否则会出现冲突。

本案例,需要迁移的用户有三个U1,U2,U3,表空间有两个TBS_DATA,TBS2

如果待迁移的用户和表空间数量很多,可以在两张临时表(一张保存待迁移用户名的列表,一张保存待迁移表空间名称的列表)中先保存,因为后续很多地方的查询语句会使用到,例如:
create table system.t_username 
as 
select username from dba_users 
where username not in ('SYS','SYSTEM','OUTLN','DIP','ORACLE_OCM',
'DBSNMP','APPQOSSYS','WMSYS','EXFSYS',
'CTXSYS','ANONYMOUS','XDB','XS$NULL',
'ORDPLUGINS','MDSYS','ORDSYS','ORDDATA',
'SI_INFORMTN_SCHEMA','OLAPSYS','MDDATA',
'SPATIAL_WFS_ADMIN_USR','SPATIAL_CSW_ADMIN_USR',
'SYSMAN','MGMT_VIEW','APEX_030200',
'FLOWS_FILES','APEX_PUBLIC_USER','OWBSYS',
'OWBSYS_AUDIT','SCOTT');

create table system.t_tbs_name 
as 
select tablespace_name 
from dba_tablespaces 
where contents='PERMANENT' and tablespace_name not in ('SYSTEM', 'SYSAUX','USERS');
//根据实际情况,确认是否需要排除USERS表空间

2、全量数据初始化前环境检查(源库和目标库)

复制代码
1. 数据库版本与补丁检查(源和目标都检查)
要求:数据库版本(源端 <= 目标端),源和目标库的版本建议都>=11.2.0.4
select * from v$version;

2. 归档模式检查(源和目标都检查)
要求:XTTS要求源端和目标端数据库开启归档模式。
archive log list;
select  LOG_MODE  from v$database;

3. 块更改跟踪检查(源库)
要求:可选项,源库开启块更改跟踪可提升表空间增量备份的速度
select status, filename from v$block_change_tracking;
开启方式
alter database enable block change tracking using file '/oradata/block_change/change_track.bct';
注意:需要保持足够的空间,存储块变更跟踪文件

4. RMAN配置检查(源和目标都检查)
要求:XTTS要求RMAN不能配置压缩,备份类型不能配置BACKUP TYPE TO COPY,必须为BACKUPSET。
rman target/
CONFIGURE DEVICE TYPE DISK PARALLELISM 4 BACKUP TYPE TO BACKUPSET;
show all;

5. 字符集检查(源和目标都检查)
要求:源端和目标端数据库字符集及国家字符集必须一致。
--数据库字符集
select (select PROPERTY_VALUE from DATABASE_PROPERTIES where PROPERTY_NAME = 'NLS_LANGUAGE')||'_'|| 
       (select PROPERTY_VALUE from DATABASE_PROPERTIES where PROPERTY_NAME = 'NLS_TERRITORY')||'.'|| 
       (select PROPERTY_VALUE from DATABASE_PROPERTIES where PROPERTY_NAME = 'NLS_CHARACTERSET') 
from dual;
--国家字符集检查
select property_name, property_value from database_properties 
where property_name='NLS_NCHAR_CHARACTERSET';

6. 时区检查(源和目标都检查)
要求:源端和目标端时区必须保持一致。
-- 操作系统时区
date -R
-- 数据库时区
select dbtimezone from dual;

7. 字节序/平台检查(源库)
要求:获取源端平台的platform_id和endian_format,xxt配置文件中需要指明源端平台platform_id
set line 200
col platform_name for a60
select platform_id from v$database;
select a.platform_id,a.platform_name,a.endian_format
from v$transportable_platform a,v$database b
where  a.platform_id=b.platform_id;

8. db_files参数检查(源和目标都检查)
要求:目标端的db_files参数必须大于等于源端。
show parameter db_files;

9. compatible参数检查(源和目标都检查)
要求:目标端的compatible参数必须大于等于源端。不支持windows,必须大于10.2.0
show parameter compatible;

10. 数据库组件检查(源和目标都检查)
要求:目标端包含源库的所有组件!
set linesize 200 pagesize 999
select comp_name from dba_registry;
select * from v$option;

11. 数据文件状态检查(源库)
要求:所有数据文件必须处于ONLINE状态。
set linesize 200 pagesize 999
col name format a50
select name, status from v$datafile;

12. 压缩索引检查(源库)
要求:源库如果存在压缩索引,需要手工处理,要么迁移完毕后重建,要么整个迁移开始前删除或重建为非压缩索引
select index_name, table_name, tablespace_name 
from dba_indexes 
where compression='ENABLED' 
  and tablespace_name not in ('SYSTEM', 'SYSAUX');
元数据导入阶段,使用Data Pump工具在处理某些类型的压缩索引(如键值压缩索引)时存在兼容性问题,无法正确解析其元数据。
这种不兼容性会导致Data Pump任务直接报错失败,通常伴随的错误是 ORA-39123: Data Pump transportable job aborted 和 ORA-
解决方法
1)迁移后重建(推荐):在XTTS元数据导入时,使用Data Pump的EXCLUDE=INDEX参数排除所有压缩索引。待数据迁移完成,再在目标端手动执行CREATE INDEX语句重建索引,并在创建时根据需要决定是否启用压缩
2)预先处理,删除或者重建为非压缩索引

13.IOT索引组织表检查(源库)
要求:源库如果存在索引组织表,需要手工处理,要么迁移完毕后重建,要么整个迁移开始前删除或重建为非压缩索引
select owner,table_name from dba_tables where iot_type is not null 
and tablespace_name not in ('SYSTEM','SYSAUX');

14. Cluster对象检查
要求:如果源库存在聚簇索引,需要手工处理,记录下所有Cluster对象及其定义,在XTTS迁移完成后,在目标端手动重建这些Cluster和相关的聚簇索引
select owner, cluster_name, tablespace_name 
from dba_clusters 
where tablespace_name not in ('SYSTEM', 'SYSAUX');

15. 表空间与数据文件统计(源库)
要求:可选项,提前记录源库的表空间和数据文件的数量,便于迁移后正确性验证(数量一致是最基本的要求!)
-- 表空间个数统计(排除系统表空间)
select count(*) from v$tablespace 
where name not in ('SYSTEM', 'SYSAUX', 'USERS', 'UNDOTBS1', 'UNDOTBS2', 'TEMP');

-- 数据文件个数统计
select count(*) from dba_data_files 
where tablespace_name not in ('SYSTEM', 'SYSAUX', 'USERS', 'UNDOTBS1', 'UNDOTBS2', 'TEMP');

16. 表空间自包含检查(核心检查)(源库)
要求:核心要求,要求源库所有待传输的表空间必须满足自包含要求!!!
建议执行严格检查:full_check=true 
---要去表关联的约束,索引,lob字段等对象都需要包含在整个传输表空间集里
---执行自包含检查方法类似如下:
exec dbms_tts.transport_set_check('USERS,TBS_DATA,TBS2',TRUE,TRUE);
---查询是否有自包含对象
select * from transport_set_violations;
---对于出现自包含的对象,需要进行迁移,或者扩到传输表空间的数据以达到完全自包含

本案例使用PL/SQL批量检查所有非系统表空间(适用于迁移的表空间数量很多的时候!)
set serveroutput on;
declare
  tslist varchar2(32767);
  first boolean:=true;
begin
  for c in (select tablespace_name from dba_tablespaces 
            where contents='PERMANENT' 
              and tablespace_name not in ('SYSTEM', 'SYSAUX')) 
  loop
    if first = true then
      first:=false;
    else
      tslist:=tslist||',';
    end if;
    tslist:=tslist||c.tablespace_name;
  end loop;
  dbms_output.put_line('Checking: '||tslist);
  dbms_tts.transport_set_check(to_clob(tslist), false, false);
  for c in (select violations from transport_set_violations) 
  loop
    dbms_output.put_line(c.violations);
  end loop;
end;
/

-- 查看违规记录
select * from transport_set_violations;


17. 加密对象检查(源库)
要求:源库进行加密对象和加密表空间检查,v3版本不支持加密对象和加密表空间,V4版本才开始支持!
-- 加密表空间检查
select tablespace_name, ENCRYPTED from dba_tablespaces where ENCRYPTED='YES';
-- 加密列检查
SELECT OWNER, TABLE_NAME, COLUMN_NAME FROM DBA_ENCRYPTED_COLUMNS;

18. XML类型数据检查(源库)
要求:源库待传输的表空间中不要包含XML类型数据
-- 检查表空间中是否包含XML类型数据
select distinct p.tablespace_name
from dba_tablespaces p, dba_xml_tables x, dba_users u, all_all_tables t
where t.table_name=x.table_name 
  and t.tablespace_name=p.tablespace_name 
  and x.owner=u.username;
根据Oracle官方文档,进行包含XMLType数据的表空间传输时,必须使用传统的 exp 和 imp 工具来导出和导入元数据,使用expdp/impdp,就可能导致 ORA-39123 或 ORA-39943 等错误,使元数据导入失败。XMLType 数据中包含的某些特殊类型(如Opaque Types)在跨平台迁移时不会自动转换字节序

19. 用户对象依赖表空间检查(源库)
检查SYSTEM和SYSAUX表空间中是否存在用户对象
select owner, segment_name, segment_type
from dba_segments
where tablespace_name in ('SYSTEM', 'SYSAUX') 
  and owner in ('U1','U2','U3');
如果有,迁移规划前,move至业务表空间

检查SYS/SYSTEM用户下的对象,是否有存储在业务表空间上
-- 检查表
select owner, table_name from dba_tables 
where tablespace_name in ('TBS_DATA','TBS2') 
  and owner in ('SYS','SYSTEM');
-- 检查索引
select owner, table_name from dba_indexes 
where tablespace_name in ('TBS_DATA','TBS2') 
  and owner in ('SYS','SYSTEM');
-- 检查段
select owner, segment_name from dba_segments 
where tablespace_name in ('TBS_DATA','TBS2') 
  and owner in ('SYS','SYSTEM');
-- 检查LOB
select owner, table_name from dba_lobs 
where tablespace_name in ('TBS_DATA','TBS2') 
  and owner in ('SYS','SYSTEM');
如果有,迁移规划前,SYS/SYSTEM用户下的对象,删除掉或者move至system或者sysaux表空间中

20. 用户对象统计(源库)
要求:可选项,便于迁移后正确性验证
-- 按用户和对象类型统计
select owner, object_type, count(1) 
from dba_objects 
where object_name not like 'BIN%' and owner in ('U1','U2','U3')
group by owner, object_type 
order by owner, object_type;

21. 用户创建信息收集(源库)
要求:提前准备待迁移的用户创建脚本
SET LONG 9999
--用户创建脚本收集
SELECT DBMS_METADATA.GET_DDL('USER', USERNAME) DDL_SQL FROM DBA_USERS WHERE USERNAME IN ('U1','U2','U3');
//抽取出来的用户创建脚本,默认表空间需要调整,因为在表空间迁移前,目标库上并没有这些表空间,在目标库上直接创建这些用户会报错

--用户默认表空间修改收集(迁移完毕后,需要将用的默认表空间,根据源库修改回去)
select 'alter user '||username||' default tablespace '||default_tablespace||' temporary tablespace '||TEMPORARY_TABLESPACE|| ' profile '||profile||';' 
from dba_users
where username in ('U1',U2','U3');

22. 用户权限与角色信息收集(源库)
要求:提前准备待迁移的用户权限,方便表空间迁移后进行用户权限迁移
方法一:
--用户系统权限收集
SELECT DBMS_METADATA.GET_GRANTED_DDL('SYSTEM_GRANT', USERNAME) DDL_SQL 
FROM DBA_USERS 
WHERE USERNAME IN ('U1','U2','U3');
--用户角色权限收集
SELECT DBMS_METADATA.GET_GRANTED_DDL('ROLE_GRANT', USERNAME) DDL_SQL 
FROM DBA_USERS 
WHERE USERNAME IN ('U1','U2','U3');
--用户对象权限收集
SELECT DBMS_METADATA.GET_GRANTED_DDL('OBJECT_GRANT', USERNAME) DDL_SQL 
FROM DBA_USERS 
WHERE USERNAME IN ('U1','U2','U3');
备注,OBJECT_GRANT获取是可能报如下错误
ORA-31608: specified object of type OBJECT_GRANT not found
ORA-06512: at "SYS.DBMS_METADATA", line 5805
ORA-06512: at "SYS.DBMS_METADATA", line 8492
ORA-06512: at line 1
由于该用户没有对象权限,所以执行时报错!需要用户单独执行,例如先获取U1的,报错忽略,然后获取U2,继续U3,直到最后!

方法二:
--用户系统权限收集
SELECT CASE
         WHEN D.ADMIN_OPTION = 'YES' THEN
          'GRANT ' || d.privilege || ' TO ' || d.GRANTEE ||
          ' WITH GRANT OPTION ;'
         ELSE
          'GRANT ' || d.privilege || ' TO ' || d.GRANTEE || ';'
       END sys_priv
  FROM dba_sys_privs d
 WHERE D.GRANTEE in ('U1','U2','U3');
--用户角色权限收集
 SELECT CASE
          WHEN D.ADMIN_OPTION = 'YES' THEN
           'GRANT ' || d.GRANTED_ROLE || ' TO ' || d.GRANTEE ||
           ' WITH GRANT OPTION;'
          ELSE
           'GRANT ' || d.GRANTED_ROLE || ' TO ' || d.GRANTEE || ';'
        END role_priv
   FROM DBA_ROLE_PRIVS d
  WHERE D.GRANTEE in ('U1','U2','U3');
--用户对象权限收集
SELECT CASE
         WHEN d.grantable = 'YES' THEN
          'GRANT ' || d.privilege || ' ON ' || d.owner || '.' ||
          d.table_name || '  TO  ' || d.GRANTEE ||
          '    WITH  GRANT OPTION ;'
         ELSE
          'GRANT ' || d.privilege || ' ON ' || d.owner || '.' ||
          d.table_name || ' TO ' || d.GRANTEE || ';'
       END tab_priv
  FROM DBA_TAB_PRIVS d
 WHERE D.GRANTEE in ('U1','U2','U3');
 
方法三:
expdp/impdp 工具导出和导入
 

23. 临时表检查(源库)
要求:XTTS最后导入元数据时不支持导入临时表,需要手动获取临时表DDL,迁移完成后,目标库上重建临时表
--用户临时表创建脚本收集
select dbms_metadata.get_ddl('TABLE', TABLE_NAME, OWNER) 
from dba_tables 
where temporary='Y' 
  and owner IN ('U1','U2','U3');
  
  
24. 外部表检查(源库)
要求:存在外部表时,XTTS迁移后需要手动迁移外部文件
select owner, table_name from dba_external_tables;

25. 禁用和清空回收站(源库)
要求:可选项,xtts本身并不会检查或要求回收站状态,建议迁移前禁用和清空回收站
禁用
ALTER SYSTEM SET RECYCLEBIN = 'OFF' SCOPE=BOTH;
-- 清空回收站
purge dba_recyclebin;
rman_xttconvert_v3脚本本身并不会检查或要求回收站状态。目的是为了避免expdp导出时可能出现的、难以排查的错误(在expdp导出元数据的阶段,如果回收站中包含了属于待迁移表空间的对象,例如,一个被删除的表,其残留信息仍在回收站中,expdp在验证表空间自包含性时可能会失败,并抛出ORA-39943错误)

26.Profile检查(源库)
要求:提前准备待迁移profile,从源库抽取,在目标库上提前创建
set long 1000000
set linesize 1000
set head off
set echo off
set feedback off
set pagesize 0
set termout off
set trimspool on
set trimout on
spool create_profile.sql
with profile as(select distinct profile from dba_profiles)
select dbms_metadata.get_ddl('PROFILE',PROFILE) from profile;
spool off

27.Public DBLINK检查(源库)
要求:公用dblink不会随着元数据导入,需要人工单独处理,在目标库上提前创建
select owner,object_name from dba_objects where object_type='DATABASE LINK';
select * from dba_db_links;

3、NFS配置

目标库主机搭建NFS服务端,源端主机为NFS客户端。

源库通过rman backup方式抽取出来的待迁移数据文件(包括后续的增量文件),直接保存至NFS上(挂载点为目标库的文件系统目录),减少数据文件的多次传输过程。

复制代码
NFS服务端(目标库主机)
# 安装NFS服务
yum install -y nfs-utils
# 创建共享目录并设置权限
mkdir -p /backup
chown -R nfsnobody:nfsnobody /backup
chmod 777 /backup

# 编辑配置文件
echo "/backup/ 192.168.11.0/24(rw,sync,all_squash)" >> /etc/exports
# 启动服务
systemctl start rpcbind nfs-server
systemctl enable rpcbind nfs-server
# 验证共享
exportfs -v


NFS客户端(源库主机)
yum install -y nfs-utils
mkdir /backup
mount -t nfs -o rw,bg,hard,nointr,rsize=32768,wsize=32768,tcp,vers=3,timeo=600,actimeo=0 192.168.11.61:/backup /backup

4、源库主机配置另一个监听器(listener)

备注:监听器的端口与现有监听不同,例如1522。

作用:正式升级割接时,业务停机后,需要停止默认的数据库监听,防止意外连接进入。另一个监听和端口,则可以继续和目标库进行连接交互。

复制代码
源库上,配置1522的监听文件
su - oracle
cat >>$ORACLE_HOME/network/admin/listener.ora <<EOF
LISTENER2 =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = host01)(PORT = 1522))
    )
  )
ADR_BASE_LISTENER2 = /u01/app/oracle
EOF

lsnrctl start listener2

修改local_listener参数,将1522端口注册至监听器中
sqlplus "/as sysdba"
alter system set local_listener='(ADDRESS_LIST=(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.11.16)(PORT = 1521))(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.11.16)(PORT = 1522)))' scope=both;

5、目标库创建指向源库的公用dblink

备注:该公用dblink,使用非默认的端口与源库通信,即1522端口

复制代码
目标库创建public database link,使用1522端口
create public database link ttslink connect to system identified by oracle using '(DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.11.16)(PORT = 1522))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcl)
    )
  )';

测试
select host_name from v$instance@ttslink;

6、目标库RAC集群,建议只能保留一个节点正常运行

本案例停止实例2

复制代码
srvctl stop database --db orcl --instance orcl2 --o immediate
备注:建议指定一个节点来专门负责所有XTTS操作,确保迁移过程简单、平稳、可控

7、目标库创建directory

作用:impdp导入元数据时需要使用

复制代码
su - oracle
mkdir /home/oracle/expdir
sqlplus "/as sysdba"
create directory expdir as '/home/oracle/expdir';
grant read,write on directory expdir to system;

8、目标库关闭监听、禁止外部连接

作用:防止业务意外连接进来

复制代码
集群关闭监听方法如下:
su - grid
srvctl stop listener -n host61rac1 
srvctl stop listener -n host62rac2
srvctl stop scan_listener -f
备注:
-n 后面为node_name,一般为主机名,也可以通过olsnodes -n命令来查看确认

9、配置xtts工具(源端和目标端都需要配置)

复制代码
源库主机:(配置rman_xttconvert_v3)
su - oracle
mkdir /home/oracle/xtts
unzip -q rman_xttconvert_v3.zip -d /home/oracle/xtts
ls -ltr /home/oracle/xtts
cd /home/oracle/xtts
mv  xtt.properties  xtt.properties.bak
cat > xtt.properties  <<EOF
#要迁移的表空间列表(必须是大写,一行写完)
tablespaces=TBS_DATA,TBS2
#源端平台ID
platformid=13
#源端存放全量数据文件副本的路径
dfcopydir=/backup
# 源端存放增量备份的路径(必须为文件系统)
backupformat=/backup
#目标端存放全量数据文件副本的路径(必须为文件系统)
stageondest=/backup
#目标端数据文件最终存放路径(目标库为ASM磁盘组,则必须填写为ASM磁盘组,如果为文件系统则填写对应的文件系统目录)
storageondest=+DATA/ORCL
#目标端存放增量备份的临时路径(文件系统和ASM磁盘组都可以,建议存放至文件系统)
#目标端增量应用完毕,会自动删除这些增量文件的
backupondest=/backup/incr
#backupondest=+ARCH 如果存放至asm磁盘组,类似这样就行
#目标端ASM环境信息(因为storageondest为ASM路径,配置)
#注意:如果backupondest设置为文件系统位置,则需要同时注释掉asm_home和asm_sid。
asm_home=/u01/app/19c/grid
asm_sid=+ASM1
#asm_home表示GI HOME目录
#并行度设置
parallel=4
rollparallel=4
EOF


备注:xtts参数文件解释
tablespaces:需要迁移的表空间名,如果有多个表空间,使用逗号分开(注意大小写敏感,所以要填大写的表空间名)
platformid:数据库平台号(v$database视图platform_id)
dstdir:目标端数据库文件存放路径,只用于dbms_file_transfer进行传输(填directory name)
srcdir:源端数据库文件存放路径,只用于dbms_file_transfer进行传输,可以N:1,N:N(填directory name)
srclink:目标端端指向源端的dblink,dbms_file_transfer通过此dblink进行传输,用于dbms_file_transfer进行传输
dfcopydir:源机上rman复制数据文件进行存放的目录,使用rman进行初始化用到(全量数据),该目录要有足够的空间存放备份
backupformat:源机上增量备份的存放目录(增量数据),该目录要有足够的空间存放备份
stageondest:目标机上存放源机传输的备份的目录(全量+增量),该目录要有足够的空间存放备份
storageondest:目标机上存放转换后的数据文件(即目标机数据库的数据文件所在目录),该目录要有足够的空间存放数据文件
backupondest:目标机上存放转换后的应用增量数据的目录,该目录要有足够的空间存放增量文件
cnvinst_home:增量转换实例的家目录
cnvinst_sid:执行增量转换的实例
asm_home:目标系统上运行ASM实例的ORACLE_HOME。注意:如果backupondest设置为文件系统位置,则需要同时注释掉asm_home和asm_sid。
asm_sid:目标系统上运行ASM实例的ORACLE_SID。
parallel:定义RMAN CONVERT命令文件rmanconvert.cmd中设置的并行度。该文件在准备阶段创建,供RMAN在转换数据文件步骤中使用,用于转换目标系统上的数据文件副本。如果未设置该参数,xttdriver.pl将使用parallel=8。
注意:RMAN备份准备阶段创建数据文件副本时所用的并行度,以及前滚阶段创建增量备份时所用的并行度,均由源系统上的RMAN配置控制,不受本参数影响。
rollparallel:应用增量数据的并行度,对应-r 操作
getfileparallel:数据文件转换时的并行度对应-g 操作

10、源端生成准备文件(待迁移的表空间第一次全量数据文件初始化,即备份)

复制代码
源主机执行
su - oracle
cd /home/oracle/xtts/
cat > source_full.sh  <<'EOF'
export ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1
export PERL5LIB=$ORACLE_HOME/perl/lib
export TMPDIR=/home/oracle/xtts
export ORACLE_SID=orcl
export XTTDEBUG=1
$ORACLE_HOME/perl/bin/perl xttdriver.pl -p
EOF

cd /home/oracle/xtts/
nohup sh source_full.sh >source_full.out 2>source_full.out &

备注:
1)export TMPDIR=/home/oracle/xtts 指向XTTS脚本存放位置,后续在使用perl执行xtts脚本时,会生成一些文件,这些文件默认存放到TMPDIR指向的位置
2)export PERL5LIB=$ORACLE_HOME/perl/lib 指向perl的lib库,如果该环境变量不设置,在使用perl执行xtts脚本时,可能会报错
3)export XTTDEBUG=1 执行xtt脚本时,调试信息会显示出来
4)一定要进入cd /home/oracle/xtts目录执行,否则$ORACLE_HOME/perl/bin/perl xttdriver.pl执行时,会提示:Can't open perl script "xttdriver.pl": No such file or directory错误。
5)如果执行失败,会在TMPDIR=/home/oracle/xtts 目录,产生一个FAILED文件标记,下次需要执行时,必须删除这个文件(rm -f FAILED ),才可以正常执行!


全量初始化后,会在TMPDIR=/home/oracle/xttsdir目录下主要产生三个文件
初始化之后产生 xttplan.txt、rmanconvert.cmd、xttnewdatafiles.txt
xttplan.txt 记录了当前 SCN,也就是下次需要增量的开始 SCN;
rmanconvert.cmd 记录了文件初始化后,转换的名称
xttnewdatafiles.txt 记录了目标库与主库的文件名映射关系

[oracle@host01 xttsdir]$ cat xttplan.txt 
TBS_DATA::::2455428    //记录下次一增量开始的SCN号
5
6
TBS2::::2455463        //记录下次一增量开始的SCN号
7
8

[oracle@host01 xttsdir]$ cat rmanconvert.cmd
host 'echo ts::TBS_DATA'; 
  convert from platform 'Linux x86 64-bit' 
  datafile 
   '/backup/TBS_DATA_5.tf' 
  ,'/backup/TBS_DATA_6.tf' 
  format '+DATA/ORCL/%N_%f.dbf' 
 parallelism 4; 
host 'echo ts::TBS2'; 
  convert from platform 'Linux x86 64-bit' 
  datafile 
   '/backup/TBS2_7.tf' 
  ,'/backup/TBS2_8.tf' 
  format '+DATA/ORCL/%N_%f.dbf' 
 parallelism 4; 
 
[oracle@host01 xttsdir]$ cat xttnewdatafiles.txt
::TBS_DATA
5,+DATA/ORCL/TBS_DATA_5.dbf
6,+DATA/ORCL/TBS_DATA_6.dbf
::TBS2
7,+DATA/ORCL/TBS2_7.dbf
8,+DATA/ORCL/TBS2_8.dbf

11、目标库第一次初始化(转换初始化文件至 ASM 中)

复制代码
1、目标主机配置rman_xttconvert_v3
将源主机/home/oracle/xtts目录全部复制过来
目标主机执行:
cd /home/oracle
scp -r 192.168.11.16:/home/oracle/xtts  /home/oracle

2、目标主机修改源库抽取的数据文件属主(即NFS挂载目录/backup下的源库抽取出来的全量和增量文件)
root执行(将/backup里面的文件全部改为oracle属主,而非nfs设置的nfsnobody)
chown -R oracle:oinstall /backup/*
备注:如果不修改,会报oracle用户没有访问文件权限的错误

3、目标库第一次初始化(确认/backup里面的文件,oracle用户可读写!!)
su - oracle
cd /home/oracle/xtts
cat >des_full.sh <<'EOF'
export ORACLE_HOME=/u01/app/oracle/product/19c/db_1
export PERL5LIB=$ORACLE_HOME/perl/lib
export TMPDIR=/home/oracle/xtts
export ORACLE_SID=orcl1
export XTTDEBUG=1
$ORACLE_HOME/perl/bin/perl xttdriver.pl -c
EOF
备注:xttdriver.pl -c命令,主要完成下面两个工作
将备份文件转换为目标端字节序格式
将数据文件恢复到 ASM 磁盘组的目标路径

nohup sh des_full.sh >des_full.out 2>des_full.out &


执行完毕后,目标库会产生一个新的xttnewdatafiles.txt文件,根据实际情况,建立源库和目标库的数据文件映射关系
[oracle@host61rac1 xtts]$ cat xttnewdatafiles.txt 
::TBS_DATA
5,+DATA/ORCL/tbs_data_5.dbf
6,+DATA/ORCL/tbs_data_6.dbf
::TBS2
7,+DATA/ORCL/tbs2_7.dbf
8,+DATA/ORCL/tbs2_8.dbf

12、源库生成测试数据

复制代码
insert into u1.tab1 select * from  u1.tab1;
commit;
insert into u1.tab2 select * from  u1.tab2;
commit;

create table u1.tab3 as select * from dba_directories;

13、源库第一次执行增量备份(抽取这一期间变化的数据块)

复制代码
cd /home/oracle
cp -r /home/oracle/xtts  /home/oracle/xtts1
cd /home/oracle/xtts1
#注意这里需要进入到新的xtts1目录
cat >source_inc1.sh  <<'EOF'
export ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1
export PERL5LIB=$ORACLE_HOME/perl/lib
export TMPDIR=/home/oracle/xtts1
#注意TMPDIR=/home/oracle/xtts1,这里需要修改为xtts1目录
export ORACLE_SID=orcl
export XTTDEBUG=1
$ORACLE_HOME/perl/bin/perl xttdriver.pl -i
EOF

nohup sh source_inc1.sh  >source_inc1.out 2>source_inc1.out &

增量完成以后,在目录下生成三个文件
xttplan.txt.new 记录新的SCN,下一次增量的开始SCN
tsbkupmap.txt  记录数据文件对应的增量文件
incrbackups.txt 记录生成的增量文件

[oracle@host01 xtts1]$ cat xttplan.txt.new
 TBS_DATA::::2455826    //记录下次一增量开始的SCN号
 5
 6
 TBS2::::2455861        //记录下次一增量开始的SCN号
 7
 8
 
[oracle@host01 xtts1]$ cat tsbkupmap.txt
TBS_DATA::5:::1=0t4t0t8a_1_1
TBS_DATA::6:::2=0u4t0t8a_1_1
TBS2::7:::1=0v4t0t8c_1_1
TBS2::8:::2=104t0t8c_1_1          
//上面记录数据文件对应的增量文件

[oracle@host01 xtts1]$ cat incrbackups.txt
/backup/0t4t0t8a_1_1    
/backup/0u4t0t8a_1_1
/backup/0v4t0t8c_1_1
/backup/104t0t8c_1_1
//上面记录了记录生成的增量文件

14、目标库第一次执行增量恢复(注意增量恢复期间,目标库会重启!)

复制代码
1、目标主机重新配置rman_xttconvert_v3
将源主机/home/oracle/xtts1目录全部复制过来
目标主机执行:
cd /home/oracle
scp -r 192.168.11.16:/home/oracle/xtts1  /home/oracle

2、目标主机修改源库抽取的数据文件属主(即NFS挂载目录/backup下的源库抽取出来的全量和增量文件)
root执行(将/backup里面的文件全部改为oracle属主,而非nfs设置的nfsnobody)
chown -R oracle:oinstall /backup/*
备注:如果不修改,会报oracle用户没有访问文件权限的错误

3、目标库第一次执行增量恢复(确认/backup里面的文件,oracle用户可读写!!)
su - oracle
cd /home/oracle/xtts1
#注意这里需要进入到新的xtts1目录
cat >des_inc1.sh <<'EOF'
export ORACLE_HOME=/u01/app/oracle/product/19c/db_1
export PERL5LIB=$ORACLE_HOME/perl/lib
export TMPDIR=/home/oracle/xtts1
#注意TMPDIR=/home/oracle/xtts1,这里需要修改为xtts1目录
export ORACLE_SID=orcl1
export XTTDEBUG=1
$ORACLE_HOME/perl/bin/perl xttdriver.pl -r
EOF
cd /home/oracle/xtts1
nohup sh des_inc1.sh >des_inc1.out 2>des_inc1.out &

备注:可以观察到,增量应用过程中,/backup/incr目录会产生增量应用文件,增量完毕后,这些文件会自动删除
[root@host61rac1 ~]# ls -ltr /backup/incr
total 304
-rw-r----- 1 oracle asmadmin  40960 Jul 11 23:39 xib_0u4t0t8a_1_1_6
-rw-r----- 1 oracle asmadmin  40960 Jul 11 23:39 xib_104t0t8c_1_1_8
-rw-r----- 1 oracle asmadmin  40960 Jul 11 23:39 xib_0v4t0t8c_1_1_7
-rw-r----- 1 oracle asmadmin 188416 Jul 11 23:39 xib_0t4t0t8a_1_1_5
[root@host61rac1 ~]# ls -ltr /backup/incr
total 0
还会产生一个新的tsbkupmap_comp.txt文件,保存数据文件和增量文件的关系
[root@host01 backup]# cat tsbkupmap_comp.txt
TBS_DATA::6:::2=2a4t3r6k_1_1
TBS2::7:::1=2b4t3r6l_1_1
TBS_DATA::5:::1=294t3r6k_1_1
TBS2::8:::2=2c4t3r6l_1_1

15、源库确定下一次增量开始的SCN号

复制代码
源库主机执行
su - oracle
export TMPDIR=/home/oracle/xtts1
#注意TMPDIR=/home/oracle/xtts1,这里需要修改为xtts1目录
cd /home/db/oracle/xtt1/
$ORACLE_HOME/perl/bin/perl xttdriver.pl -s

最后会有如下输出
New /home/oracle/xtts1/xttplan.txt with FROM SCN's generated

16、源库再次生成测试数据

复制代码
insert into u2.tab1 select * from  u2.tab1;
commit;
insert into u2.tab2 select * from  u2.tab2;
commit;

create table u2.tab3 as select * from dba_directories;

17、源库增量数据备份、目标库增量数据恢复,多次执行!

这两个步骤,可以重复多次执行(方法与上面基本类似!!),减少正式停机时,需要备份和恢复的数据量,减少整个迁移升级所需时间!!!

18、正式开始升级(业务需要停止!)

19、源库将待迁移表空间设为只读,确保表空间数据一致性!

复制代码
1、源库停止默认监听
lsnrctl stop
3、kill掉外部进程(确认没有大事务)
ps -ef|grep LOCAL=NO|awk '{print $2}'|xargs kill -9
3、执行检查点(加快后续表空间read only的时间)
alter system checkpoint;
alter system checkpoint;
4、停用job
alter system set job_queue_processes=0;
4、待迁移的表空间设置为只读!!
set linesize 200 pagesize 999
select 'alter tablespace '||tablespace_name||' read only;'  str
from dba_tablespaces 
where contents='PERMANENT' and tablespace_name not in ('SYSTEM', 'SYSAUX','USERS');

alter tablespace TBS_DATA read only;
alter tablespace TBS2 read only;

20、源库执行最后一次增量备份

复制代码
cd /home/oracle
cp -r /home/oracle/xtts1  /home/oracle/xtts2
cd /home/oracle/xtts2
#注意这里需要进入到新的xtts2目录
cat >source_inc2.sh  <<'EOF'
export ORACLE_HOME=/u01/app/oracle/product/19c/db_1
export PERL5LIB=$ORACLE_HOME/perl/lib
export TMPDIR=/home/oracle/xtts2
#注意TMPDIR=/home/oracle/xtts2,这里需要修改为xtts2目录
export ORACLE_SID=orcl1
export XTTDEBUG=1
$ORACLE_HOME/perl/bin/perl xttdriver.pl -r
EOF

nohup sh source_inc2.sh  >source_inc2.out 2>source_inc2.out &


备注:
增量完成以后,在目录下生成三个文件
xttplan.txt.new 记录新的SCN,下一次增量的开始SCN
tsbkupmap.txt  记录数据文件对应的增量文件
incrbackups.txt 记录生成的增量文件
[oracle@host01 xtts2]$ cat xttplan.txt.new
 TBS_DATA::::2457683
 5
 TBS2::::2457692
 7
[oracle@host01 xtts2]$ cat tsbkupmap.txt
TBS2::8:::2=144t0ude_1_1
TBS_DATA::5:::1=114t0udd_1_1
TBS_DATA::6:::2=124t0udd_1_1
TBS2::7:::1=134t0ude_1_1
[oracle@host01 xtts2]$ cat incrbackups.txt
/backup/144t0ude_1_1
/backup/114t0udd_1_1
/backup/124t0udd_1_1
/backup/134t0ude_1_1

21、目标库最后一次增量(增量过程会重启数据库,这一点需要知晓!!!)

复制代码
1、目标主机重新配置rman_xttconvert_v3
将源主机/home/oracle/xtts2目录全部复制过来
目标主机执行:
cd /home/oracle
scp -r 192.168.11.16:/home/oracle/xtts2  /home/oracle

2、目标主机修改源库抽取的数据文件属主(即NFS挂载目录/backup下的源库抽取出来的全量和增量文件)
root执行(将/backup里面的文件全部改为oracle属主,而非nfs设置的nfsnobody)
chown -R oracle:oinstall /backup/*
备注:如果不修改,会报oracle用户没有访问文件权限的错误

3、目标库第一次执行增量恢复(确认/backup里面的文件,oracle用户可读写!!)
su - oracle
cd /home/oracle/xtts2
#注意这里需要进入到新的xtts2目录
cat >des_inc2.sh <<'EOF'
export ORACLE_HOME=/u01/app/oracle/product/19c/db_1
export PERL5LIB=$ORACLE_HOME/perl/lib
export TMPDIR=/home/oracle/xtts2
#注意TMPDIR=/home/oracle/xtts2,这里需要修改为xtts2目录
export ORACLE_SID=orcl1
export XTTDEBUG=1
$ORACLE_HOME/perl/bin/perl xttdriver.pl -r
EOF

nohup sh des_inc2.sh >des_inc2.out 2>des_inc2.out &

22、目标库生成导入表空间配置文件

复制代码
export TMPDIR=/home/oracle/xtts2
$ORACLE_HOME/perl/bin/perl xttdriver.pl -e
最有输出部分:
--------------------------------------------------------------------
Done generating plugin file /home/oracle/xtts2/xttplugin.txt
--------------------------------------------------------------------

[oracle@host61rac1 xtts2]$ cat  /home/oracle/xtts2/xttplugin.txt
impdp directory=<DATA_PUMP_DIR> logfile=<tts_imp.log> \
network_link=<ttslink> transport_full_check=no \
transport_tablespaces=TBS_DATA,TBS2 \
transport_datafiles='+DATA/ORCL/TBS_DATA_5.dbf','+DATA/ORCL/TBS_DATA_6.dbf','+DATA/ORCL/TBS2_7.dbf','+DATA/ORCL/TBS2_8.dbf'

根据实际情况进行修改,最后内容如下
impdp \"/as sysdba\" directory=expdir logfile=tts_imp.log \
network_link=ttslink transport_full_check=no \
transport_tablespaces=TBS_DATA,TBS2 \
transport_datafiles='+DATA/ORCL/TBS_DATA_5.dbf','+DATA/ORCL/TBS_DATA_6.dbf','+DATA/ORCL/TBS2_7.dbf','+DATA/ORCL/TBS2_8.dbf'

23、目标库用户创建、系统权限和角色授权、profile创建

可以在源库执行最后一次增量备份时,完成这块内容(已经不会在变动了)

复制代码
根据《源库和目标库全量数据初始化前环境检查》21和26部分

类似如下:
CREATE USER "U1" IDENTIFIED BY VALUES 'S:2053E1E4404D768DA40792A2CF1BC34B714A404564A78EE71E0B660B75D9;3E81B724A296E296'
      DEFAULT TABLESPACE "USERS"
      TEMPORARY TABLESPACE "TEMP";
CREATE USER "U2" IDENTIFIED BY VALUES 'S:25E065005B02F3A07C5427C110D9C1000AC6D61394117FFE3B8F2BE7FB59;668509DF9DD36B43'
      DEFAULT TABLESPACE "USERS"
      TEMPORARY TABLESPACE "TEMP";
CREATE USER "U3" IDENTIFIED BY VALUES 'S:E67F5F8D7D2F15A3E5B5590F97C47310E205575B4D52E047C520F73B6880;9CE6AF1E3F609FFC'
      DEFAULT TABLESPACE "USERS"
      TEMPORARY TABLESPACE "TEMP";
      
grant connect,resource,unlimited tablespace to u1;
grant connect,resource,unlimited tablespace to u2;
grant connect,resource,unlimited tablespace to u3;

特别注意:
1、用户创建时的默认表空间,需要指定一个临时的,因为待迁移的表空间,在目标库上还未创建!!!(等待表空间迁移完成后,再修改过来)。
2、用户的表空间配额问题,也是一样处理!

24、目标库创建临时表

复制代码
根据《源库和目标库全量数据初始化前环境检查》部分

25、目标库第一次元数据导入(传输表空间元数据)

复制代码
impdp \"/as sysdba\" directory=expdir logfile=tts_imp.log \
network_link=ttslink transport_full_check=no \
transport_tablespaces=TBS_DATA,TBS2 \
transport_datafiles='+DATA/ORCL/TBS_DATA_5.dbf','+DATA/ORCL/TBS_DATA_6.dbf','+DATA/ORCL/TBS2_7.dbf','+DATA/ORCL/TBS2_8.dbf'

26、目标库第二次元数据导入(其他对象元数据)

复制代码
---第二次元数据导入,将第一次没有导入的过程,视图,包,触发器导入。
impdp \"/as sysdba\" directory=expdir logfile=tts_imp2.log network_link=ttslink schemas=U1,U2,U3 content=metadata_only parallel=4 exclude=table,index,statistics

根据输出,会自动导入系统对象、角色、对象权限,都会自动完成导入!
Processing object type SCHEMA_EXPORT/SYSTEM_GRANT
Processing object type SCHEMA_EXPORT/ROLE_GRANT
Processing object type SCHEMA_EXPORT/DEFAULT_ROLE
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA

27、目标库后续收尾工作

复制代码
1、表空间逻辑验证
rman target /
validate tablespace TBS_DATA check logical;
validate tablespace TBS2 check logical;

2、压缩索引、IOT索引组织表、聚簇索引、外部表,这些不支持的对象,手工处理(重建)

3、对象编译
@?/rdbms/admin/utlrp
并行编译
exec utl_recomp.recomp_parallel(32);

4、修改用户默认表空间
select 'alter user '||username||' default tablespace '||default_tablespace||' temporary tablespace '||TEMPORARY_TABLESPACE|| ' profile '||profile||';' 
from dba_users@ttslink 
where username in ('U1','U2','U3');
alter user U1 default tablespace TBS_DATA temporary tablespace TEMP profile DEFAULT;
alter user U2 default tablespace TBS2 temporary tablespace TEMP profile DEFAULT;
alter user U3 default tablespace USERS temporary tablespace TEMP profile DEFAULT;

5、添加表空间配额权限
根据源库的dba_ts_quotas来查询

6、比较对象(源库和目标库)
select owner, object_type, count(*)
from dba_objects
where object_name not like 'BIN%'
and owner in ('U1','U2','U3')
group by owner, object_type
order by 1,2 desc;

select owner, object_type, count(*)
from dba_objects@ttslink
where object_name not like 'BIN%'
and owner in ('U1','U2','U3')
group by owner, object_type
order by 1,2 desc;

7、目标库将表空间设置为read write
select 'alter tablespace '||tablespace_name||' read write;' STR
from dba_tablespaces
where tablespace_name in ('TBS_DATA','TBS2');
alter tablespace TBS2 read write;
alter tablespace TBS_DATA read write;

8、统计信息收集
1)为了防止同时收集统计信息,造成系统资源的消耗,建议先提前关闭后台自动收集统计信息的任务。
exec DBMS_AUTO_TASK_ADMIN.DISABLE(client_name => 'auto optimizer stats collection',operation => NULL,window_name => NULL);
2)目标端搜集统计信息
exec dbms_stats.gather_database_stats(estimate_percent =>dbms_stats.AUTO_SAMPLE_SIZE,METHOD_OPT=>'FOR ALL COLUMNS SIZE 1',options=> 'GATHER',degree=>8, granularity =>'all',cascade=> TRUE);
收集数据字典统计信息:
exec DBMS_STATS.GATHER_DICTIONARY_STATS(degree=>16);
3)开启后台自动收集统计信息的任务
exec DBMS_AUTO_TASK_ADMIN.ENABLE(client_name => 'auto optimizer stats collection',operation => NULL,window_name => NULL);

9、表数据量比较(源库和目标库)
根据实际情况,进行比较!
select count(*) from u1.tab1;
select count(*) from u1.tab2;
select count(*) from u1.tab3;
select count(*) from u1.tab1@ttslink;
select count(*) from u1.tab2@ttslink;
select count(*) from u2.tab1;
select count(*) from u2.tab2;
select count(*) from u2.tab3;
select count(*) from u2.tab1@ttslink;
select count(*) from u2.tab2@ttslink;

10、权限比较(源库和目标库)
省略

11、开启节点2实例
srvctl start database --db orcl --instance orcl2

12、开启监听程序对外提供服务
su - grid
srvctl start listener -n host61rac1 
srvctl start listener -n host62rac2
srvctl start scan_listener

28、业务程序连接重新指向,业务测试!

至此,通过XTTS跨版本迁移升级,完成Oracle 11g单库升级至19C RAC集群

五、XTTS前置条件或限制总结

复制代码
1、目前的官方提供的xtts V3工具不支持window平台
2、使用xtts,源端数据库版本都需要10.2.0.3以上版本
3、数据库版本必须为企业版不能为标准版本
4、源端数据库不能大于目标端数据库
5、源端和目标数据库都需要开启归档模式
6、目标端数据库版本都需要11.2.0.4以上
7、rman管道不能配置压缩、rman备份类型只能使用backupset方式,不能是copy类型
8、待传输表空间状态必须是在线的,数据文件必须是在线的
9、待传输的表空间必须是自包含的,建议进行自包含严格检查
10、xtts虽然首要的操作系统为linux,但也可以用于unix操作系统平台,只是需要确保源端和目标端都是11.2.0.4以上
11、源端的版本低于或等于目标端,因此,xtts方法也可以作为一种upgrade的方式(各版本之前的升级路线,可以参考官方提供的19c升级路线)
12、过程不支持在备库或者快照库执行
13、只同步非sys用户表空间,不同步sysaux,system
14、sys和system用户不能有对象存放在待传输的表空间中
15、XTTS最后的迁移时间其实取决于元数据的大小,xtts只是同步那些段对象,对于pl/sql objects, sequences等存放于system,sysaux表空间的需要额外使用expdp/impdp进行导出导入)
16、对于目标库版本为11.2.0.3或往前的版本,需要使用11.2.0.4的临时实例进行增量恢复,或是存在生产库往生产库迁移的方式
17、增量恢复需要重启实例,可以通过建立临时实例进行增量恢复解决
18、源库建议开启块更改跟踪检查
19、字符集必须一致
20、时区一致
21、目标端的db_files参数必须大于等于源端
22、目标端的compatible参数必须大于等于源端
23、目标端包含源库的所有组件
24、索引检查、IOT索引组织表、聚簇索引、临时表都不支持,需要手工处理
25、加密对象、XML类型数据都不支持(或者不友好)
26、存在外部表时,XTTS迁移后需要手动迁移外部文件
27、建议禁用和清空回收站

六、XXTS另一个更简便方式总结

核心思想

1)将TMPDIR=/backup 设置为源和目标共享的目录(这样就不需要每次复制源端TMPDIR的内容至目标端)

复制代码
上面案例中,为了将源端TMPDIR的内容至目标端,每次都是直接将整个目录重新生成,然后直接复制新目录至目标库,类似如下
第一次全量初始化
TMPDIR=/home/oracle/xtts
执行全量
全量完毕后,将/home/oracle/xtts目录直接复制到目标库

第一次增量
cp -r /home/oracle/xtts   /home/oracle/xtts1
TMPDIR=/home/oracle/xtts1
增量完毕后,将/home/oracle/xtts1目录直接复制到目标库

第二次增量
cp -r /home/oracle/xtts1   /home/oracle/xtts2
TMPDIR=/home/oracle/xtts2
增量完毕后,将/home/oracle/xtts2目录直接复制到目标库

2)源端和目标端存放备份文件路径,设置为源和目标共享的目录,如下

复制代码
上面案例中,就是使用此方法,减少全量文件和增量文件的传输过程
xtt.properties参数配置
#源端存放全量数据文件副本的路径
dfcopydir=/backup
# 源端存放增量备份的路径(必须为文件系统)
backupformat=/backup
#目标端存放全量数据文件副本的路径(必须为文件系统)
stageondest=/backup

简单过程

复制代码
1、NFS配置
目标库配置NFS,并将对外提供的/backup目录权限设置为如下
chown nfsnobody:nfsnobody /backup
chmod 777 /backup
源库挂载
mount -t nfs -o rw,bg,hard,nointr,rsize=32768,wsize=32768,tcp,vers=3,timeo=600,actimeo=0 192.168.11.61:/backup /backup

2、源库XTTS配置
su - oracle
mkdir /home/oracle/xtts
unzip -q rman_xttconvert_v3.zip -d /home/oracle/xtts
ls -ltr /home/oracle/xtts
cd /home/oracle/xtts
mv  xtt.properties  xtt.properties.bak
cat > xtt.properties  <<EOF
#要迁移的表空间列表(必须是大写,一行写完)
tablespaces=TBS_DATA,TBS2
#源端平台ID
platformid=13
#源端存放全量数据文件副本的路径
dfcopydir=/backup
# 源端存放增量备份的路径(必须为文件系统)
backupformat=/backup
#目标端存放全量数据文件副本的路径(必须为文件系统)
stageondest=/backup
#目标端数据文件最终存放路径(目标库为ASM磁盘组,则必须填写为ASM磁盘组,如果为文件系统则填写对应的文件系统目录)
storageondest=+DATA/ORCL
#目标端存放增量备份的临时路径(文件系统和ASM磁盘组都可以,建议存放至文件系统)
#目标端增量应用完毕,会自动删除这些增量文件的
#backupondest=/backup/incr
backupondest=+DATA
#目标端ASM环境信息(因为storageondest为ASM路径,配置)
#注意:如果backupondest设置为文件系统位置,则需要同时注释掉asm_home和asm_sid。
asm_home=/u01/app/19c/grid
asm_sid=+ASM1
#asm_home表示GI HOME目录
#并行度设置
parallel=4
rollparallel=4
EOF


3、目标库XTTS配置
将源库的/home/oracle/xtts复制过来
scp -r  oracle@192.168.11.16:/home/oracle/xtts   /home/oracle

4、源库执行第一次全量备份
su - oracle
cd /home/oracle/xtts/
cat > source_full.sh  <<'EOF'
export ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1
export PERL5LIB=$ORACLE_HOME/perl/lib
export TMPDIR=/backup
export ORACLE_SID=orcl
export XTTDEBUG=1
$ORACLE_HOME/perl/bin/perl xttdriver.pl -p
EOF
nohup sh source_full.sh  &

chmod 666 /backup/*
#将/backup/目录下的文件修改为任何人都可以读写,如果不修改,目标库初始化、增量应用是,会报oracle用户没有访问文件权限的错误

5、目标库执行第一次全量恢复
su - oracle
cd /home/oracle/xtts
cat >des_full.sh <<'EOF'
export ORACLE_HOME=/u01/app/oracle/product/19c/db_1
export PERL5LIB=$ORACLE_HOME/perl/lib
export TMPDIR=/backup
export ORACLE_SID=orcl1
export XTTDEBUG=1
$ORACLE_HOME/perl/bin/perl xttdriver.pl -c
EOF

nohup sh des_full.sh  &

6、源库第一次产生增量数据

7、源库执行第一次增量备份
源主机执行
su - oracle
cd /home/oracle/xtts/
cat > source_inc1.sh  <<'EOF'
export ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1
export PERL5LIB=$ORACLE_HOME/perl/lib
export TMPDIR=/backup
export ORACLE_SID=orcl
export XTTDEBUG=1
$ORACLE_HOME/perl/bin/perl xttdriver.pl -i
EOF

nohup sh source_inc1.sh  &

chmod 666 /backup/*
#将/backup/目录下的文件修改为任何人都可以读写,如果不修改,目标库初始化、增量应用是,会报oracle用户没有访问文件权限的错误

下面错误忽略,因为是目标库产生的,无权修改,忽略即可
[oracle@host01 xtts]$ chmod 666 /backup/*
chmod: changing permissions of '/backup/convert_Jul13_Mon_10_11_23_446': Operation not permitted
chmod: changing permissions of '/backup/xttnewdatafiles.txt': Operation not permitted

8、目标库执行第一次增量恢复
su - oracle
cd /home/oracle/xtts
cat >des_inc1.sh <<'EOF'
export ORACLE_HOME=/u01/app/oracle/product/19c/db_1
export PERL5LIB=$ORACLE_HOME/perl/lib
export TMPDIR=/backup
export ORACLE_SID=orcl1
export XTTDEBUG=1
$ORACLE_HOME/perl/bin/perl xttdriver.pl -r
EOF
nohup sh des_inc1.sh  &

9、源库确定下一次增量开始的SCN号
源库主机执行
su - oracle
export TMPDIR=/backup
cd /home/oracle/xtts
$ORACLE_HOME/perl/bin/perl xttdriver.pl -s

10、源库第二次产生增量数据

源库增量数据备份、目标库增量数据恢复,多次执行
正式开始升级(业务需要停止!)
源库将待迁移表空间设为只读,确保表空间数据一致性!

11、源库执行最后一次增量备份
su - oracle
cd /home/oracle/xtts/
cat > source_inc2.sh  <<'EOF'
export ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1
export PERL5LIB=$ORACLE_HOME/perl/lib
export TMPDIR=/backup
export ORACLE_SID=orcl
export XTTDEBUG=1
$ORACLE_HOME/perl/bin/perl xttdriver.pl -i
EOF
nohup sh source_inc2.sh  &

chmod 666 /backup/*
#将/backup/目录下的文件修改为任何人都可以读写,如果不修改,目标库初始化、增量应用是,会报oracle用户没有访问文件权限的错误

12、目标库执行最后增量恢复
su - oracle
cd /home/oracle/xtts
cat >des_inc2.sh <<'EOF'
export ORACLE_HOME=/u01/app/oracle/product/19c/db_1
export PERL5LIB=$ORACLE_HOME/perl/lib
export TMPDIR=/backup
export ORACLE_SID=orcl1
export XTTDEBUG=1
$ORACLE_HOME/perl/bin/perl xttdriver.pl -r
EOF
nohup sh des_inc2.sh  &

至此,核心步骤完成
相关推荐
z123456789862 小时前
2026最新两款AI编程工具深度对比实测
java·数据库·ai编程
程序猿DD2 小时前
一个 API Key,统一调用大模型、生图和联网搜索
数据库·网关
TlSfoward3 小时前
抓包代理链路下的 TLS 指纹变化分析 TLSFOWARD抓包工具
数据库·爬虫·网络协议·搜索引擎·php
数智化管理手记3 小时前
账龄分析手工统计易遗漏?自动账龄分析工具怎么搭建
大数据·网络·数据库·人工智能·数据挖掘
LabVIEW开发4 小时前
NI Package Manager安装LabVIEW时InternalServerError错误
网络·数据库·labview·labview知识·labview功能·labview程序
SelectDB4 小时前
PostgreSQL 实时同步到 Apache Doris:一站式 CDC 解决方案
数据库
Database_Cool_4 小时前
AI Agent 长期记忆怎么存?阿里云 PolarDB-X 对接 Mem0 记忆框架实践
数据库·阿里云
会编程的土豆5 小时前
数据库范式
数据库·oracle
L1624765 小时前
MySQL 全环境生产快速安装 + 完整配置手册(整合国产银河麒麟适配 + 主从补充版)
数据库·mysql