数据库升级之-XTTS

来源:这里教程网 时间:2026-03-03 16:07:51 作者:

说明

该文档为 XTTS 数据库跨平台迁移方案

环境说明

源端数据库采用AIX 小机RAC 架构,数据库版本11.2.0.4 目标端采用LINUX X86 RAC 架构,数据库版本为11.2.0.4+ 最新PSU 

硬件环境检查

对于一套RAC 的实施,我们需要确保基本的硬件环境已经达到要求,具体如下:

1.        主机操作系统安装,版本在RHEL 6 以上( 本文档针对的版本)

2.        存储已经挂载,并且所有的存储LUN 已经两两映射到对应的两台主机

3.        LUN 要求:需要1G LUN 3 1T LUN 若干(具体视数据库空间) 并且互相映射

4.        网线已经正常接驳,心跳建议采用交换机模式连接 

前置条件检查

条目

是否满足

备注

源端不能是windows

源库的版本必须大于10.2

源库的compatible 参数不能大于目标端

源库和目标库字符集需要保持一致

目标端db_files 参数必须大于源端

源库必须处于归档模式

源库的rman 配置中DEVICE TYPE DISK 不能设置为COMPRESSED

要迁移的表空间数据文件必须都是online 的或者不包括offline 数据文件

排除系统表空间,避免冲突并检查业务表空间是否自包含

 

资源配置情况

配置类型

源  库

目标库

数据库版本

11.2.0.4

11.2.0.4.161018

数据库名称

XXX

XXX

数据库字符集

AMERICAN_AMERICA.ZHS16GBK

AMERICAN_AMERICA.ZHS16GBK

数据库节点

RAC 1 节点

RAC 1 节点

操作系统版本

AIX6

Linux6.8

磁盘组大小

数据库大小

Block size

8192

8192

 

生产基本数据统计

2.1 表空间统计

set linesize 200

col file_name   for a50

set pagesize 0

select   file_id,tablespace_name,file_name,status from dba_data_files;

 

需要传输的数据文件大小

set linesize   1000

col file_name   for a50

SELECT   d.FILE_ID,

       d.TABLESPACE_NAME,

       (SELECT (SUM(nb.BYTES/1024/1024))

          FROM dba_data_files nb

         WHERE nb.TABLESPACE_NAME =   d.TABLESPACE_NAME) ts_size_m,

         d.FILE_NAME,

       (d.BYTES/1024/1024) file_size_m,

       (d.USER_BYTES/1024/1024)   file_use_size_m

  FROM dba_data_files d

WHERE   d.TABLESPACE_NAME  not in (‘SYSTEM’,’SYSAUX’,’UNDOTBS1’,’UNDOTBS2’)  

 ORDER BY    file_id;

 

需要迁移的用户统计

alter session   set nls_date_format='yyyy-mm-dd hh24:mi:ss';

set line 200

SELECT   d.username,

       d.default_tablespace,

       d.temporary_tablespace,

       d.account_status,

       d.created

  from dba_users d

 where d.account_status = 'OPEN' and   d.username not like '%SYS%'

  order by d.CREATED desc;

 

select ‘‘‘‘||username||’’’,’   from dba_users where to_char(created,’yyyy-mm-dd’) > ‘2013-10-01’;

 

用户权限收集

drop table   t_tmp_user_lhr;                                                                                           

create   table   t_tmp_user_lhr( id number,   username varchar2(50), exec_sql varchar2(4000),create_type varchar2(20));

DROP  sequence     s_t_tmp_user_lhr;                                                                                 

create sequence   s_t_tmp_user_lhr;                                                                                  

                                                                                                                    

begin                                                                                                              

                                                                                                                   

  for cur in (SELECT d.username,                                                                                   

                       d.default_tablespace,                                                                          

                     d.account_status,                                                                             

                     ‘create user ‘ ||   d.username || ‘ identified by ‘ ||                                         

                     d.username || ‘ default   tablespace ‘ ||                                                       

                     d.default_tablespace || ‘  TEMPORARY TABLESPACE  ‘ ||                                        

                     D.temporary_tablespace   || ‘;’ CREATE_USER,                                                     

                     replace(to_char(DBMS_METADATA.GET_DDL(‘USER’,                                                  

                                                             D.username)),                                          

                             chr(10),                                                                               

                             ‘‘)   create_USER1                                                                       

                FROM dba_users d                                                                                   

 WHERE d.username   in    (‘TPCC’,’CURRY4’,’TEST24’,’JJF’,’CURRY3’,’CURRY2’,’CURRY1’,’HR’,’TEST’,’HZMCMEMAUDIT’,’CURRY’,’CURRY5’,’TEST1’,’JTEST’,’TEST02’,’ZJJBUNI2REP’,’ZJJBUNI2’,’QMCB_NEW’,’JBGC’))   loop                                                       

    INSERT INTO t_tmp_user_lhr                                                                                      

      (id, username, exec_sql,   create_type)                                                                          

    values                                                                                                          

      (s_t_tmp_user_lhr.nextval,   cur.username, cur.CREATE_USER, ‘USER’);                                           

                                                                                                                    

    INSERT INTO t_tmp_user_lhr                                                                                      

      (id, username, exec_sql,   create_type)                                                                         

      SELECT s_t_tmp_user_lhr.nextval,                                                                              

             cur.username,                                                                                         

             CASE                                                                                                   

               WHEN D.ADMIN_OPTION = ‘YES’   THEN                                                                    

                ‘GRANT ‘ || d.privilege || ‘   TO ‘ || d.GRANTEE ||                                                   

                ‘ WITH GRANT OPTION ;’                                                                             

               ELSE                                                                                                 

                ‘GRANT ‘ || d.privilege || ‘   TO ‘ || d.GRANTEE || ‘;’                                              

             END priv,                                                                                              

             ‘DBA_SYS_PRIVS’                                                                                        

        FROM dba_sys_privs d                                                                                        

       WHERE D.GRANTEE = CUR.USERNAME;                                                                              

                                                                                                                   

    INSERT INTO t_tmp_user_lhr                                                                                     

      (id, username, exec_sql, create_type)                                                                        

      SELECT s_t_tmp_user_lhr.nextval,                                                                              

             cur.username,                                                                                           

             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 priv,                                                                                             

             ‘DBA_ROLE_PRIVS’                                                                                       

        FROM DBA_ROLE_PRIVS d                                                                                      

       WHERE D.GRANTEE = CUR.USERNAME;                                                                              

                                                                                                                     

      INSERT INTO t_tmp_user_lhr                                                                                      

      (id, username, exec_sql,   create_type)                                                                          

      SELECT s_t_tmp_user_lhr.nextval,                                                                              

             cur.username,                                                                                          

             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 priv,                                                                                              

             ‘DBA_TAB_PRIVS’                                                                                        

        FROM DBA_TAB_PRIVS d                                                                                        

       WHERE D.GRANTEE = CUR.USERNAME;                                                                              

    end loop;                                                                                                         

    COMMIT;                                                                                                          

end;                                                                                                                

/                                                                                                                    

SELECT * FROM t_tmp_user_lhr;

col username for a17

col CREATE_TYPE for a17

col EXEC_SQL for a110

set line 200

SELECT   id,username,CREATE_TYPE,EXEC_SQL FROM t_tmp_user_lhr where CREATE_TYPE not in   (‘USER’);                                                                                

 

用户表格规模统计

select d.owner, (sum(bytes) / 1024   / 1024) sizes_m

    from dba_segments d

    where d.owner   in (‘TPCC’,’CURRY4’,’TEST24’,’JJF’,’CURRY3’,’CURRY2’,’CURRY1’,’HR’,’TEST’,’HZMCMEMAUDIT’,’CURRY’,’CURRY5’,’TEST1’,’JTEST’,’TEST02’,’ZJJBUNI2REP’,’ZJJBUNI2’,’QMCB_NEW’,’JBGC’)

 AND NOT EXISTS (SELECT 1 FROM DBA_RECYCLEBIN   B WHERE B.object_name=D.segment_name AND D.OWNER=B.owner)

 GROUP BY d.owner

 order by sum(bytes) desc;

用户对象个数统计

基于用户对象统计

  FROM dba_objects d

 WHERE d.OWNER   in (‘TPCC’,’CURRY4’,’TEST24’,’JJF’,’CURRY3’,’CURRY2’,’CURRY1’,’HR’,’TEST’,’HZMCMEMAUDIT’,’CURRY’,’CURRY5’,’TEST1’,’JTEST’,’TEST02’,’ZJJBUNI2REP’,’ZJJBUNI2’,’QMCB_NEW’,’JBGC’)

 and d.OWNER not in (‘PUBLIC’)  

 AND NOT EXISTS (SELECT 1   FROM DBA_RECYCLEBIN B WHERE B.object_name=D.OBJECT_NAME AND D.OWNER=B.owner)

 GROUP BY D.OWNER

 ORDER BY COUNT(1) desc;

  基于用户对象类型统计

   FROM dba_objects d

  WHERE d.OWNER in (‘TPCC’,’CURRY4’,’TEST24’,’JJF’,’CURRY3’,’CURRY2’,’CURRY1’,’HR’,’TEST’,’HZMCMEMAUDIT’,’CURRY’,’CURRY5’,’TEST1’,’JTEST’,’TEST02’,’ZJJBUNI2REP’,’ZJJBUNI2’,’QMCB_NEW’,’JBGC’)

    and d.OWNER not in (‘PUBLIC’)

    AND NOT EXISTS (SELECT 1

           FROM   DBA_RECYCLEBIN B

          WHERE   B.object_name = D.OBJECT_NAME

            AND D.OWNER =   B.owner)

  GROUP BY D.OWNER,   D.OBJECT_TYPE

  ORDER BY D.OWNER ,COUNT(1)   desc;

 

2.7 备份对象信息,方便无效对象比对

无效对象统计

spool invald.lst

select   owner,object_name,object_type,status from dba_objects where status<>‘VALID’   ;

select count(*),status from   dba_objects group by status;

select   owner,object_name,object_type,status from dba_objects where status<>‘VALID’   and owner in ;

select count(*),status from   dba_objects where owner in (‘TPCC’,’CURRY4’,’TEST24’,’JJF’,’CURRY3’,’CURRY2’,’CURRY1’,’HR’,’TEST’,’HZMCMEMAUDIT’,’CURRY’,’CURRY5’,’TEST1’,’JTEST’,’TEST02’,’ZJJBUNI2REP’,’ZJJBUNI2’,’QMCB_NEW’,’JBGC’)   group by status;

spool off

create table invalid_object_201702   as select * from dba_objects where status<>‘VALID’;

 

select count(*),status from   dba_objects where owner in (‘TPCC’,’CURRY4’,’TEST24’,’JJF’,’CURRY3’,’CURRY2’,’CURRY1’,’HR’,’TEST’,’HZMCMEMAUDIT’,’CURRY’,’CURRY5’,’TEST1’,’JTEST’,’TEST02’,’ZJJBUNI2REP’,’ZJJBUNI2’,’QMCB_NEW’,’JBGC’)   group by status;

 

select count(*),status from dba_objects where owner in (‘TPCC’,’CURRY4’,’TEST24’,’JJF’,’CURRY3’,’CURRY2’,’CURRY1’,’HR’,’TEST’,’HZMCMEMAUDIT’,’CURRY’,’CURRY5’,’TEST1’,’JTEST’,’TEST02’,’ZJJBUNI2REP’,’ZJJBUNI2’,’QMCB_NEW’,’JBGC’)   and object_type like ‘PACKAGE%’ group by status;

 

2.8 确定 SYS SYSTEM 下是否存在业务对象

SYS SYSTEM 重复对象检查

SQL> select object_name, object_type from dba_objects where   (object_name,object_type) in (select object_name,object_type from dba_objects   where owner = ‘SYS’) and owner = ‘SYSTEM’;

  SYSTEM 表空间下是否存在对象

select   owner,segment_name,segment_type,tablespace_name from dba_segments where   tablespace_name in (‘SYSTEM’,’SYSAUX’) and owner in (‘TPCC’,’CURRY4’,’TEST24’,’JJF’,’CURRY3’,’CURRY2’,’CURRY1’,’HR’,’TEST’,’HZMCMEMAUDIT’,’CURRY’,’CURRY5’,’TEST1’,’JTEST’,’TEST02’,’ZJJBUNI2REP’,’ZJJBUNI2’,’QMCB_NEW’,’JBGC’);

 

确定平台字节序

col platform_name for a40

select tp.platform_name,   tp.endian_format

  from   v$transportable_platform tp

where tp.platform_name in (‘Linux   x86 64-bit’, ‘AIX-Based Systems (64-bit)’);

 

判断表空间是否自包含

当检测到表空间不是自包含时,需要迁移跨表空间对象至同一表空间。 详见附录一:

execute sys.dbms_tts.transport_set_check(‘CURRY,CURRY1,CURRY2,CURRY3,CURRY4,CURRY5,USERS’,true);col violations for a150select * from   sys.transport_set_violations;

 

获取需传输的表空间

set serveroutput on

declare

    tsname varchar(30);

    i number := 0;

begin

    dbms_output.put(‘tablespaces=‘);

    for ts in 

      (select tablespace_name from dba_tablespaces

     where tablespace_name not in (‘SYSTEM’,’SYSAUX’)  

       and contents = ‘PERMANENT’

     order by tablespace_name)

    loop

      if (i!=0) then

      dbms_output.put_line(tsname||’,’);

      end if;

      i := 1;

      tsname := ts.tablespace_name;

    end loop;

    dbms_output.put_line(tsname);

    dbms_output.put_line(‘‘);

end;

/

 

LINUX 端环境准备( 目标端)

配置到生产的NFS

LINUX 端准备 开启NFS service nfs startchkconfig nfs onvi /etc/exports/backup 192.168.200.*(rw,sync,all_squash)exportfs –ashowmount -e AIX 源端配置: 检查aix 是否启用自定义端口# nfso -a|grep nfs_use_reserved_ports 启用aix 自定义端口

nfso -p -o nfs_use_reserved_ports=1

# showmount -e

# mount -o cio,rw,bg,hard,nointr,rsize=32768,wsize=32768,proto=tcp,noac,vers=3,timeo=600 192.168.200.90:/backup /backup  至此,源端和目标端均有/backup 目录 注意:在源端挂载目标端 NFS 文件系统时,在目标端 /etc/exports 中需指定源端物理 IP ,否则会造成源端挂载失败

安装集群创建数据库

安装最新11.2.0.4 集群+ 最新PSU 创建数据库,原则上和生产保持一致名称,特别注意字符集,需要和生产保持一致。 注意:需保持源端和目标端数据库 service_names 参数设置一致,否则会造成应用连接失败  

准备XTTS 介质

上传介质到生产源端环境/backup 目录下 

生产端操作

生产库必须满足归档开启策略 

创建directory

源端创建directory 指向源端数据文件所在的位置create directory sourcedir as ‘+DATA/XXX/datafile’;grant all on directory sourcedir to public; 

编辑xtt.properties 文件

$ mv xtt.properties xtt.properties.bak$ touch xtt.propertiesvi xtt.properties 填写以下内容

tablespaces=CURRY,CURRY1,CURRY2,CURRY3,CURRY4,CURRY5,USERSplatformid=6srcdir=SOURCEDIRdstdir=DESTDIRsrclink=TTSLINKdfcopydir=/backupbackupformat=/backupstageondest=/backupstorageondest=+DATAbackupondest=+DATAasm_home=/oracle/grid/crs_1asm_sid=+ASM1

需要迁移的表空间

源端数据库平台参数, V$DATABASE.PLATFORM_ID

源端根据数据文件所在目录

目标端最终数据文件所在的目录

目标端连接源端创建的db link

源端rman 备份目录

源端增量备份目录

目标端存放备份目录

目标端rman 恢复目录

目标端增量恢复目录

目标端asm home 目录

目标端asm 实例名

  第一条tablespaces 参数,命令参考脚本:

set   serveroutput ondeclare    tsname varchar(30);  i number := 0;begin    dbms_output.put(‘tablespaces=‘);  for   ts in     (select tablespace_name from   dba_tablespaces     where tablespace_name not in (‘SYSTEM’,’SYSAUX’)         and contents = ‘PERMANENT’     order by tablespace_name)  loop    if (i!=0) then      dbms_output.put_line(tsname||’,’);    end   if;    i := 1;    tsname := ts.tablespace_name;  end loop;  dbms_output.put_line(tsname);  dbms_output.put_line(‘‘);end;  /

  由于是NFS 挂载的,所以所有文件都不需要拷贝到目标端

目标端操作

创建目标directory

destdir 目标端数据文件最终所在的目录:

create directory destdir as ‘+DATA/XXX’; grant all on directory destdir to public;

 

创建DATA_PUMP_DIR

DATA_PUMP_DIR 目录创建用于元数据导入

create or replace directory   as ‘/backup’;grant all on directory DATA_PUMP_DIR to   public;

 

创建DB_LINK

xtts =  (DESCRIPTION =    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.200.71)(PORT = 1521))    (CONNECT_DATA =      (SERVER = DEDICATED)      (SERVICE_NAME = XXX)    )  ) 创建连接源端数据库的dblink create public database link ttslink connect to system identified by oracle using ‘xtts’;       备注:

如果users 表空间已经存在了,这里把target 端的users 表空间重命名一下就可以了: alter tablespace users rename to users01; 

临时创建所有表空间语句

临时创建所有表空间语句,用于从生产导入所有的权限及用户 相关脚本如下:(在生产端运行并生产文件)

set heading off feedback off trimspool on   linesize 500spool tts_create_ts.sqlprompt /* ===================== */prompt /* Create user tablespaces */prompt /* ===================== */select ‘create TABLESPACE ‘ ||   tablespace_name ||         ‘ DATAFILE ‘ ||’’’+DATA/XXX/’||tablespace_name||’.dbf’’’||’ size 10M autoextend on;’     from dba_tablespaces     where tablespace_name not in (‘SYSTEM’,’SYSAUX’)        and contents = ‘PERMANENT’;spool off

 

导入生产库用户及权限

同步用户和权限

impdp \’/ as sysdba\’ DIRECTORY=DATA_PUMP_DIR   LOGFILE=dp_userimp01.log NETWORK_LINK=ttslink FULL=y   INCLUDE=USER,ROLE,ROLE_GRANT,PROFILE

 

 

删除表空间:该操作要明确,是在目标端操作的,即新环境端,操作前谨记,再三确认,操作前必须关闭生产库所有界面,只保留目标端,并且操作完后清理掉 tts_drop_ts.sql

set   heading off feedback off trimspool on linesize 500

spool   tts_drop_ts.sql

prompt   /* ===================== */

prompt   /* Drop user tablespaces */

prompt   /* ===================== */

select   ‘DROP TABLESPACE ‘ || tablespace_name ||

       ‘ INCLUDING CONTENTS AND DATAFILES;’

   from dba_tablespaces

   where tablespace_name not in (‘SYSTEM’,’SYSAUX’)  

      and contents = ‘PERMANENT’;

spool   off

删除$ rm tts_drop_ts.sql 脚本

 

 

删除目标端USERS 表空间

为使得源端USERS 表空间顺利传输过来,删除USERS 表空间:alter database default tablespace SYSAUX;SQL> drop tablespace users including contents and datafiles;

 

设置 TMPDIR

源端(生产端):export TMPDIR=/home/oracle/tmp 目标端(新库):export TMPDIR=/home/oracle/tmp  

数据全量传输阶段

数据全量传输采用两种方式:Phase 2A - dbms_file_transfer MethodPhase 2B - RMAN Backup Method 增量阶段发现还是应该打开块跟踪会比较好,加快速度,应该在全同步之前打开 alter database enable block change tracking using file ‘+DATA/trace.log’;alter database disable block change tracking;   

生成增量所需文件

[oracle@source]$ export XTTDEBUG=1 [oracle@source]$ $ORACLE_HOME/perl/bin/perl xttdriver.pl -S

xttplan.txt             # 记录数据文件 SCN xttnewdatafiles.txt      # 记录数据文件位置

 

手动 rman 拷贝方式传输文件

查询语句源端查询,拷贝source 端数据文件至NFS 共享目录/backup

select ‘copy datafile ‘||’’’’||file_name||’’’’||’   to ‘||’’’’||’/backup/’||substr(file_name,instr(file_name,’/’,-1)+1)||’’’;’   from dba_data_files;

 

copy datafile ‘+DATA/XXX/users01.dbf’   to ‘/backup/users01.dbf’;

copy datafile ‘+DATA/XXX/curry01.dbf’   to ‘/backup/curry01.dbf’;

copy datafile ‘+DATA/XXX/curry1.dbf’   to ‘/backup/curry1.dbf’;

copy datafile ‘+DATA/XXX/curry2.dbf’   to ‘/backup/curry2.dbf’;

copy datafile ‘+DATA/XXX/curry3.dbf’   to ‘/backup/curry3.dbf’;

copy datafile ‘+DATA/XXX/curry4.dbf’   to ‘/backup/curry4.dbf’;copy   datafile ‘+DATA/XXX/curry5.dbf’ to ‘/backup/curry5.dbf’;

 

目标端手动 convert 数据文件

修改数据文件权限

chown grid.oinstall *.dbf

  查询语句源端查询,在目标端执行convert 操作

select   ‘CONVERT FROM PLATFORM ‘||’’’’||’AIX-Based Systems (64-bit)’||’’’’||’   PARALLELISM 10’||’ datafile ‘||’’’’||’/backup/’||SUBSTR(NAME,INSTR(NAME,’/’,-1)+1)||’’’’||’   format ‘||’’’’||’+DATA/XXX/’||SUBSTR(NAME,INSTR(NAME,’/’,-1)+1)||’’’;’ from   v$datafile;

 

CONVERT   FROM PLATFORM ‘AIX-Based Systems (64-bit)’ PARALLELISM 10 datafile ‘/backup/users01.dbf’   format ‘+DATA/XXX/users01.dbf’;

CONVERT   FROM PLATFORM ‘AIX-Based Systems (64-bit)’ PARALLELISM 10 datafile ‘/backup/curry01.dbf’   format ‘+DATA/XXX/curry01.dbf’;

CONVERT   FROM PLATFORM ‘AIX-Based Systems (64-bit)’ PARALLELISM 10 datafile ‘/backup/curry1.dbf’   format ‘+DATA/XXX/curry1.dbf’;

CONVERT   FROM PLATFORM ‘AIX-Based Systems (64-bit)’ PARALLELISM 10 datafile ‘/backup/curry2.dbf’   format ‘+DATA/XXX/curry2.dbf’;

CONVERT   FROM PLATFORM ‘AIX-Based Systems (64-bit)’ PARALLELISM 10 datafile ‘/backup/curry3.dbf’   format ‘+DATA/XXX/curry3.dbf’;

CONVERT   FROM PLATFORM ‘AIX-Based Systems (64-bit)’ PARALLELISM 10 datafile ‘/backup/curry4.dbf’   format ‘+DATA/XXX/curry4.dbf’;

CONVERT   FROM PLATFORM ‘AIX-Based Systems (64-bit)’ PARALLELISM 10 datafile ‘/backup/curry5.dbf’   format ‘+DATA/XXX/curry5.dbf’;

 

前滚阶段(增量恢复阶段)

7.1 源端执行

检查增量备份的路径,比如 xtt.properties 文件的路径信息权限等  源端增量备份阶段:

$export XTTDEBUG=1$ $ORACLE_HOME/perl/bin/perl xttdriver.pl -i

  拷贝或替换源端以下文件至目标端

xttnewdatafiles.txt xttplan.txt tsbkupmap.txt

 

 

目标端执行

修改增量备份片权限

chown grid.oinstall *_1_1

  目标端增量应用日志:

$export XTTDEBUG=1$ $ORACLE_HOME/perl/bin/perl xttdriver.pl   -r

  

源端确认下一个增量的SCN

源端执行:

[oracle@source]$   $ORACLE_HOME/perl/bin/perl xttdriver.pl -s

 

继续轮询增量恢复

如果还需要增量恢复,重复执行7.1~7.3

最后一次增量前滚

源端表空间READ ONLY

生产端运行如下脚本,获取READ ONLY 脚本  脚本如下:

set heading off feedback off trimspool on   linesize 500spool tts_tsro.sqlprompt /*   =================================== */prompt /* Make all user tablespaces READ   ONLY */prompt /*   =================================== */select ‘ALTER TABLESPACE ‘ ||   tablespace_name || ‘ READ ONLY;’     from dba_tablespaces     where tablespace_name not in (‘SYSTEM’,’SYSAUX’)        and contents = ‘PERMANENT’;spool off

  检查状态:SQL> select tablespace_name,status,contents from dba_tablespaces; 

最后一次增量备份

生产端执行:

[oracle@source]$   $ORACLE_HOME/perl/bin/perl xttdriver.pl -i

  最后一次增量结束关闭块跟踪alter database disable block change tracking;  目标端执行:

[oracle@dest]$ $ORACLE_HOME/perl/bin/perl   xttdriver.pl -r

 

数据同步

元数据同步

[oracle@dest]$ $ORACLE_HOME/perl/bin/perl   xttdriver.pl -e

相关语句如下:(transport_tablespaces transport_datafiles 根据实际情况修改)

impdp "‘"/   as sysdba"‘" directory=DATA_PUMP_DIR logfile=tts_imp.log \

network_link=ttslink   transport_full_check=no \

transport_tablespaces=CURRY,CURRY1,CURRY2,CURRY3,CURRY4,CURRY5,USERS   \

transport_datafiles=‘+DATA/XXX/curry01.dbf’,’+DATA/XXX/curry1.dbf’,’+DATA/XXX/curry2.dbf’,’+DATA/XXX/curry3.dbf’,’+DATA/XXX/curry4.dbf’,’+DATA/XXX/curry5.dbf’,’+DATA

/nocdb/users01.dbf’  

  测试过程由于各种原因导致时间不够,因此为了加快进度, 没有将统计信息导入,采用后续手工统计  获取transport_tablespaces

declare    tsname varchar(30);  i   number := 0;begin    dbms_output.put(‘transport_tablespaces=‘);    for ts in     (select tablespace_name from dba_tablespaces         where tablespace_name not in (‘SYSTEM’,’SYSAUX’)         and contents = ‘PERMANENT’       order by tablespace_name)    loop      if (i!=0) then        dbms_output.put_line(tsname||’, \’);      end if;    i := 1;      tsname := ts.tablespace_name;    end loop;    dbms_output.put_line(tsname);    dbms_output.put_line(‘‘);end;/

  获取transport_datafiles

declare    fname varchar(513);  i   number := 0;begin    dbms_output.put(‘transport_datafiles=‘);  for df in      (select file_name from dba_tablespaces a, dba_data_files b       where a.tablespace_name = b.tablespace_name         and a.tablespace_name not in (‘SYSTEM’,’SYSAUX’)         and contents = ‘PERMANENT’       order by a.tablespace_name)    loop      if (i!=0) then        dbms_output.put_line(‘‘‘+DATA/XXX/’||substr(fname,instr(fname,’/’,-1)+1)||’’’,   \’);      end if;      i := 1;      fname := df.file_name;    end loop;    dbms_output.put_line(‘‘‘+DATA/XXX/’||substr(fname,instr(fname,’/’,-1)+1)||’’’’);      dbms_output.put_line(‘‘);end;/

  转换结束,检查目标端表空间、数据文件状态:

col file_name for a40set linesize 1000select tablespace_name,file_name,status   from dba_data_files; col name for a40select name,status from v$datafile;

  

目标库表空间置成 READ WRITE 模式

目标端运行如下脚本,获取READ WRITE 脚本 脚本如下:

set heading off feedback off trimspool on   linesize 500spool tts_tsro.sqlprompt /*   ==================================== */prompt /* Make all user tablespaces READ   WRITE */prompt /*   ==================================== */select ‘ALTER TABLESPACE ‘ ||   tablespace_name || ‘ READ WRITE;’     from dba_tablespaces     where tablespace_name not in (‘SYSTEM’,’SYSAUX’)        and contents = ‘PERMANENT’;spool off

检查状态:SQL> select tablespace_name,status,contents from dba_tablespaces; 

临时表同步& 数据同步

生产端临时表格处理:

select TEMPORARY,table_name,owner    from dba_tables where owner in (‘TPCC’,’CURRY4’,’TEST24’,’JJF’,’CURRY3’,’CURRY2’,’CURRY1’,’HR’,’TEST’,’HZMCMEMAUDIT’,’CURRY’,’CURRY5’,’TEST1’,’JTEST’,’TEST02’)  and TEMPORARY=‘Y’;

  生产端获取建表语句

set heading off;set echo off;Set pages 999;set long 90000;spool get_tmptable_ddl.sqlselect dbms_metadata.get_ddl(‘TABLE’,’TMPTAB’,’BUDGET’) FROM dual; . . . .

   此时手动授权 GRANT 语句,会发现很多对象不存在,在元数据同步之后还是有 部分对象缺失,所以再导一次相关对象:  进行缺失对象导入时,优先导入DB_LINK

impdp \’/   as sysdba\’ DIRECTORY=DATA_PUMP_DIR LOGFILE=dp_userimp.log   NETWORK_LINK=ttslink FULL=y INCLUDE=DB_LINK

 

grant create database link to xxx;

  确认DB_LINK 导入无误后,再导入其他对象

impdp   \’/ as sysdba\’ DIRECTORY=DATA_PUMP_DIR LOGFILE=dp_userimp.log   NETWORK_LINK=ttslink FULL=y INCLUDE=INDEX,FUNCTION,VIEW,SYNONYM,PACKAGE   BODY,SEQUENCE,PACKAGE,JOB,TRIGGER,PROCEDURE

  确认缺少对象导入之后,进行权限GRANT 导入

impdp   \’/ as sysdba\’ DIRECTORY=DATA_PUMP_DIR LOGFILE=dp_userimp01.log   NETWORK_LINK=ttslink FULL=y INCLUDE= GRANT

  在测试迁移阶段,发现即使进行权限 GRANT 完全导入之后,还是有部分基于 sys 下一些数据字典权限没有同步至目标库。此时需要手动执行 grant 语句授权。 @user_privs_collect.sql   待相关对象同步好之后,再开始进行数据校验。 

目标库统计信息收集

数据校验完全一致后,收集目标库统计信息

exec   dbms_stats.gather_database_stats(estimate_percent=>10,Degree=>8,Cascade=>TRUE,Granularity=>‘ALL’);exec dbms_stats.gather_dictionary_stats(estimate_percent=>100,Degree=>8,Cascade=>TRUE,Granularity=>‘ALL’);exec   dbms_stats.gather_fixed_objects_stats;

 

备忘录

源库禁用块跟踪

测试迁移结束之后,源库禁用块跟踪。正式迁移跳过此步。select * from v$block_change_tracking;alter database disable block change tracking; 

源端表空间READ WRITE

测试迁移结束之后,源库表空间置回读写模式。正式迁移跳过此步。READ WRITE 脚本如下:

set heading off feedback off trimspool on linesize 500 spool tts_tsro.sqlprompt /* ==================================== */prompt /* Make all user tablespaces READ WRITE */prompt /* ==================================== */select ‘ALTER TABLESPACE ‘ || tablespace_name || ‘ READ WRITE;’   from dba_tablespaces   where tablespace_name not   in (‘SYSTEM’,’SYSAUX’)      and contents = ‘PERMANENT’;spool off

检查状态:SQL> select tablespace_name,status,contents from dba_tablespaces; 

源库JOB 禁用& 启用

由于迁移时间是月初,时间比较敏感,大量JOB 可能都在该时段触发,与客户和应用确认是否要禁用生产库JOBalter system set job_queue_processes=0 scope=both sid=‘*’; 

目标库JOB 禁用& 启用

为了防止JOB 调度而引起的数据校验不一致,在迁移前禁用所有JOBalter system set job_queue_processes=0 scope=both sid=‘*’;  迁移结束,应用测试结束,三方确认无误后,开启JOBalter system set job_queue_processes=1000 scope=both sid=‘*’;

相关推荐