暂无图片
暂无图片
3
暂无图片
暂无图片
暂无图片

xtts升级迁移流程及问题记录

取名浪费我半小时 2020-11-10
3425

 

       最近在帮一个客户做xtts升级迁移,持续了有段时间了,今天就说说xtts升级迁移的大致流程、迁移过程中遇到的问题以及问题的处理过程。

     

       进入正题前,我们先来看看迁移工具tts吧,tts就是传输表空间,将表空间从源端传输到目标端,而xtts是tts的改良版,在tts的基础上实现了跨平台以及增量备份恢复。xtts迁移的基本步骤如下:


       接下来我们再来看看几种常见的迁移方案:(图片来自互联网,侵删)


  • 数据泵



  • GoldenGate



  • XTTS


然后我们看下以上几种方案的比较:



      下面我将借着这次给客户做的xtts迁移案例,列出xtts迁移的具体流程,客户的环境:源端AIX 6.1 oracle 10.2.0.4 目标端exadata x8m  oracle 19.8


  • 源端信息收集


    1、确认需要传输的用户


select username,user_id,account_status,created from dba_users order by 2 asc;

  

      查出源端所有用户后,一般情况下需要和客户确认哪些用户需要传输,假设这里需要传输的用户为user_a,user_b,user_c,user_d。


    2、确认需要传输的表空间以及表空间的大小


SET HEAD ON

SET FEEDBACK ON

BREAK ON REPORT

COMPUTE SUM LABEL'Total Spaces' OF total_m ON REPORT

COMPUTE SUM LABEL'Total Spaces' OF free_m  ON REPORT

COMPUTE SUM LABEL'Total Spaces' OF used_m  ON REPORT

col tablespace format a25

col ext_mgt  format a8

col seg_mgt  format a8

col status format a7

set feedback off

select b.tablespace_name tablespace,

       b.total_m,

       b.free_m,

       b.used_m,

       b.used_pct

from

dba_tablespaces a,

(select

   d.tablespace_name tablespace_name,

   round((d.sumbytes/1024/1024),2) total_m,

  round(decode(f.sumbytes,null,0,f.sumbytes)/1024/1024,2) free_m,

  round(((d.sumbytes-decode(f.sumbytes,null,0,f.sumbytes))/1024/1024),2)used_m,

  round((d.sumbytes-decode(f.sumbytes,null,0,f.sumbytes))*100/d.sumbytes,2)used_pct

  from

    (select

      tablespace_name,   sum(bytes) sumbytes

     from dba_free_space   group by tablespace_name) f,

    (select tablespace_name,      sum(bytes) sumbytes   

      from dba_data_files     group by tablespace_name) d

    where f.tablespace_name(+) =d.tablespace_name

    order by d.tablespace_name) b

where a.tablespace_name=b.tablespace_name

and a.tablespace_name not in ('SYSTEM','SYSAUX','UNDOTBS1','UNDOTBS2')     --根据实际情况调整

order by 5;

                   

      这一步的目的是提前准备存储用于存放源端备份文件,以及确认目标端所需存储的大小,源端数据量大的情况下这里建议如果同平台则可以使用共享存储的方式,避免网络传输消耗大量时间,如果是异构平台,可以使用NAS挂载的方式。假设这里需要传输的表空间为tbs_a,tbs_b,tbs_c,tbs_d。


     3检查是否存在用户自定义无法迁移的对象


col owner for a10

col segment_name for a50

col segment_type for a20

set linesize 150 pagesize 10000

select owner,segment_name, segment_type

from dba_segments

where tablespace_name in ('SYSTEM', 'SYSAUX')

and owner not in (select username from dba_users where user_id < 57); --根据实际情况调整


      有些开发在使用数据库的时候可能不是特别规范,将对象的默认表空间指定为了system或者sysaux,而这两个表空间在xtts迁移过程中是不会传输的,所以如果上面sql查询有结果就需要对这些对象先处理(移动到需要传输的表空间中)。


     4、源端用户权限收集


查看自己创建的角色:

select * from  user$

where type# = 0 and name not in ('PUBLIC', '_NEXT_USER');


SELECT DBMS_METADATA.GET_DDL('ROLE','XXX') FROM DUAL;


查看角色的授权:

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

       'DBA_SYS_PRIVS'

  FROM dba_sys_privs d

 WHERE D.GRANTEE in ('XXX');

 

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

       'DBA_ROLE_PRIVS'

  FROM DBA_ROLE_PRIVS d

 WHERE D.GRANTEE in ('XXX');


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

       'DBA_TAB_PRIVS'

  FROM DBA_TAB_PRIVS d

 WHERE D.GRANTEE in ('XXX');


查看用户的权限:

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

       'DBA_SYS_PRIVS'

  FROM dba_sys_privs d

 WHERE D.GRANTEE in ('USER_A','USER_B','USER_C','USER_D')

 order by grantee;

 

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

       'DBA_ROLE_PRIVS'

  FROM DBA_ROLE_PRIVS d

 WHERE D.GRANTEE in ('USER_A','USER_B','USER_C','USER_D')

 order by grantee;

 

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

       'DBA_TAB_PRIVS'

  FROM DBA_TAB_PRIVS d

 WHERE D.GRANTEE in ('USER_A','USER_B','USER_C','USER_D')

 order by grantee;


     5、 临时表空间和undo表空间信息收集


select tablespace_name,sum(bytes)/1024/1024/1024 size_GB from dba_temp_files group by tablespace_name;


select file_name,bytes/1024/1024 MB from dba_data_files where tablespace_name like '%UNDO%';


     6、 判断表空间是否自包含


execute sys.dbms_tts.transport_set_check('TBS_A,TBS_B,TBS_C,TBS_D',true);


col violations fora100

select * from sys.transport_set_violations;


      有自包含对象需要进行提前处理(将涉及到的对象移动到system表空间中),表分区跨越了多个表空间就不再自包含了,索引在其他表空间也会不自包含。


     7、 源端收集tns、listener、sqlnet配置


     8、 源端dblink信息收集


select * from dba_db_links;

select dbms_metadata.get_ddl('DB_LINK','XXX','SYS') from dual;


  • 源端配置


     9、 NAS挂载


      关于nas挂载的client端以及server端有很多种情况,主要根据源端目标端的空间大小而定,比如源端和目标端都没有多余的空间用于中间磁盘的划分,那么这时候server端可能就是一个nas存储,源端和目标端都作为client端,分别通过nfs挂载即可。下图(图片来自官方文档)为各平台rac情况下详细的挂载参数:



注:AIX平台需要修改如下参数:


# nfso -p -onfs_use_reserved_ports=1;


为了解决nfs目录导出报错,需要设置10298事件:


alter system set events '10298 trace name context forever, level 32';


      挂载目录最好使用二级目录例如:/mig/xtts,并且由于源端和目标端的oracle用户id可能不一致,所以在源端和目标端分别看/mig/xtts目录的时候,属主属组可能是不一致的,所以后续分别在源端和目标端操作的时候,每次都需要先修改/mig/xtts的属组和属主。


cd mig/xtts

mkdir tmp

mkdir data


     10、 源端全备前开启BCT


alter database enable block change tracking using file '/+DATA/ORACLE_SID/rman_trace.log';  --路径根据实际情况而定


select filename from v$block_change_tracking;


       注意如果源端为rac环境,那么rman_trace.log需要放在共享存储上。


     11、 源端创建到目标端的dblink


       这一步主要用于后面恢复完成之后的对象状态和数量的比对。


create database link to_target connect to system identified by password using 'xxx.xx.x.x:1521/oracle_sid';  --根据实际情况而定


  • 目标端配置


     12、 目标端dbca建库


      字符集和源端库保持一致,sga、pga、process、db_files(建议1024)不小于源端环境,SID可根据实际情况而定。

 

     13、 目标端配置tns、listener、sqlnet


     14、 目标端创建临时表空间及profile


     15、 目标端修改undo表空间大小


     16、 目标端调整redo log


  • 备份恢复阶段


     17、 上传并配置xtts脚本


      这里使用的是xtts 4.3


unzip rman_xttconvert_v4.3.zip;


vi xtt.properties


tablespaces=TBS_A,TBS_B,TBS_C,TBS_D

platformid=6     --源端平台ID

src_scratch_location=/mig/xtts/data    --源端备份目录

dest_datafile_location=+DATA/oracle_sid/datafile       --目标端最终数据文件存放目录

dest_scratch_location=/mig/xtts/data   --目标端恢复目录

parallel=8      

rollparallel=8

getfileparallel=8


xtt.properties作为xtts最核心的配置文件,我们来看看各个参数分别代表的含义:



      18、 源端进行第一次数据库全备


export TMPDIR=/mig/xtts/tmp


nohup perl xttdriver.pl --backup -d 3 > full_backup.log &


      注意全备前需要检查源端环境rman备份的并行参数,因为xtts的配置文件xtt.properties中的parallel参数只是用于控制转换数据文件(源端和目标端数据文件字节序的转换)的并行度,而源端rman备份的并行度是由源端环境中rman的配置决定的。


      19、 目标端进行第一次全备恢复


cd mig/xtts/tmp/

chmod 777 *

cd mig/xtts/data/

chmod 777 *


cd mig/xtts/

export TMPDIR=/mig/xtts/tmp

nohup $ORACLE_HOME/perl/bin/perl xttdriver.pl --restore -d 3 > full_restore.log &


      20、 源端进行增量备份(进行多次)


cd   /mig/xtts/

export TMPDIR=/mig/xtts/tmp


nohup perl xttdriver.pl --backup -d 3 > incr_backup1.log  &


      21、 目标端进行增量恢复(进行多次)


cd mig/xtts/tmp/

chmod 777 *

cd mig/xtts/data/

chmod 777 *

cd mig/xtts/

export TMPDIR=/mig/xtts/tmp


nohup $ORACLE_HOME/perl/bin/perl xttdriver.pl --restore -d 3 > incr_restore1.log  &


      22、 源端导出元数据,全局临时表,public对象


create directory mig_dir as '/mig/xtts/data';


导出元数据:

vi expdp_xtts_other.par 


schemas=USER_A,USER_B,USER_C,USER_D  

directory=mig_dir

dumpfile=xtts_other_%U.dmp

logfile=expdp_xtts_other.log

metrics=y

exclude=TABLE,INDEX,CONSTRAINT,COMMENT,MATERIALIZED_VIEW,MATERIALIZED_VIEW_LOG,sequence

parallel=2


expdp \'\/ as sysdba\' parfile=expdp_xtts_other.par


导出全局临时表:

select owner,table_name from dba_tables where temporary='Y' and owner  in('USER_A','USER_B','USER_C','USER_D');   --先查出有哪些全局临时表


vi exp_xtts_tmp.par


file=xtts_tmp.dmp

log=expdp_xtts_tmp.log

metrics=y

tables=('xxx.xxxxxx')


exp \'\/ as sysdba\' parfile=expdp_xtts_tmp.par


源端导出public对象:

vi expdp_xtts_public.par


include=db_link:"IN(select DB_LINK from dba_db_links where owner='PUBLIC')",PUBLIC_SYNONYM

full=y

directory=mig_dir

dumpfile=xtts_public.dmp

logfile=expdp_xtts_public.log

metrics=y


expdp \'\/ as sysdba\' parfile= expdp_xtts_public.par



      23、 目标端导入元数据,全局临时表,public对象


create directory mig_dir_imp as '/mig/xtts/data';


目标端导入元数据:

vi impdp_xtts_other.par


directory=mig_dir_imp

dumpfile=xtts_other_%U.dmp

full=y

logfile=impdp_xtts_other.log

EXCLUDE=TABLESPACE,PROCOBJ,RLS_CONTEXT,RLS_GROUP,RLS_POLICY,TABLESPACE_QUOTA

metrics=y

remap_tablespace=

TBS_A:system,

TBS_B:system,

TBS_C:system,

TBS_D:system


impdp \'\/ as sysdba\' parfile=impdp_xtts_other.par


目标端导入全局临时表:

imp \'\/ as sysdba\' file=xtts_tmp.dmp  full=y log=imp_xtts_tmp.log


目标端导入public对象:

impdp \'\/ as sysdba\' directory=mig_dir_imp dumpfile=xtts_public.dmp logfile=impdp_xtts_public.log metrics=y


  • 最终切换上线


      24、 源端停止业务,禁用job,停监听,重启数据库


      25、 源端将表空间置为read only


alter tablespace TBS_A read only;

alter tablespace TBS_B read only;

alter tablespace TBS_C read only;

alter tablespace TBS_D read only;


       26、 源端进行最后一次增量备份


cd   /mig/xtts/

export TMPDIR=/mig/xtts/tmp


nohup perl  xttdriver.pl --backup -d 3 > incr_backup_final.log  &


       27、 源端导出传输表空间元数据


vi expdp_xtts_metadata.par


directory=mig_dir

dumpfile=xtts_metadata%U.dmp

filesize=1048576000

logfile=expdp_xtts_metadata.log

metrics=y

transport_tablespaces=TBS_A,TBS_B,TBS_C,TBS_D


expdp \'\/ as sysdba\' parfile=expdp_xtts_metadata.par


       28、 源端导出sequence


vi expdp_xtts_seq.par


schemas=USER_A,USER_B,USER_C,USER_D       

directory=mig_dir

dumpfile=xtts_seq_%U.dmp

logfile=expdp_xtts_seq.log

metrics=y

include=sequence

parallel=2


expdp \'\/ as sysdba\' parfile=expdp_xtts_seq.par


        29、 目标端进行最后一次增量恢复


cd mig/xtts/tmp/

chmod 777 *

cd mig/xtts/data/

chmod 777 *


cd mig/xtts/

export TMPDIR=/mig/xtts/tmp


$ORACLE_HOME/perl/bin/perl  xttdriver.pl --restore -d 3 > incr_restore_final.log  &


        30、 目标端导入传输表空间元数据


vi impdp_xtts_metadata.par


directory=mig_dir_imp

dumpfile=xtts_metadata%U.dmp

logfile=impdp_xtts_metadata.log

metrics=y

transport_datafiles=

'+DATA/ORACLE_SID/DATAFILE/TBS_A.dbf',

'+DATA/ORACLE_SID/DATAFILE/TBS_B.dbf',

'+DATA/ORACLE_SID/DATAFILE/TBS_C.dbf',

'+DATA/ORACLE_SID/DATAFILE/TBS_D.dbf'


impdp \'\/ as sysdba\' parfile=impdp_xtts_metadata.par


        31、 目标端sequence导入


cd mig/xtts/data/

chmod 777 *

cd mig/xtts/tmp/

chmod 777 *


vi impdp_xtts_seq.par


directory=mig_dir_imp

dumpfile=xtts_seq_%U.dmp

full=y

logfile=impdp_xtts_seq.log

metrics=y


impdp \'\/ as sysdba\' parfile=impdp_xtts_seq.par


       32、 目标端执行授权脚本


       33、 目标端表空间置为read write


alter tablespace TBS_A read write;

alter tablespace TBS_B read write;

alter tablespace TBS_C  read write;

alter tablespace TBS_D read write;

  

        34、 修改用户默认表空间


alter user USER_A default tablespace TBS_A ;

alter user USER_B default tablespace TBS_B ;

alter user USER_C default tablespace TBS_C ;

alter user USER_D default tablespace TBS_D ;


        35、 编译无效对象


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


        36、 比对源端和目标端对象状态和数量


select owner,object_type,count(*) from dba_objects

where owner in ('USER_A','USER_B','USER_C','USER_D')

and object_type!='INDEX'

group by owner,object_type

minus

select owner,object_type,count(*)from dba_objects@to_target

where owner in('USER_A','USER_B','USER_C','USER_D')

and object_type!='INDEX'

group by owner,object_type;


        37、 启动监听,启动业务,并进行业务验证




  • 迁移过程中问题记录


       据客户描述AIX到NAS存储和一体机到NAS存储之间都是万兆网,为了测试网络传输速度能达到多少,我在进行全备测试之前先进行了文件拷贝的速度测试,测试结果如下:


  • 一体机--->NAS存储   cp/mv  14G   42s   (多次测试都是40秒左右)

  • NAS存储--->一体机   cp/mv  14G   42s   (多次测试都是40秒左右)

  • AIX--->NAS存储   cp/mv  14G   240s   (多次测试都是240秒左右)

  • NAS存储--->AIX   cp/mv  14G   240s   (多次测试都是240秒左右)


       同样是万兆网络为什么差别这么大呢?接下来我查阅了相关资料,看到有一篇文章说的是AIX单个进程读取是有上限的,为了更快的备份可以开启并行,于是在xtts配置文件中配置了4个并行,之后进行正式全备测试。


       源端进行数据库全备的时候,由于数据量为8T左右,所以测试的时候只选择了一个表空间,大小为632G,该表空间包含21个数据文件,测试的时候xtts的配置文件如下:


tablespaces=TBS_XXX

platformid=6

src_scratch_location=/mig/xtts/data

dest_datafile_location=+DATA/oracle_sid/datafile

dest_scratch_location=/mig/xtts/data

parallel=4

rollparallel=4

getfileparallel=4


       测试结果为632G的表空间全备需要将近3小时,网络传输速度大概在60M/s左右,按照这个速度8T的数据量全备的时间将近39小时,这显然是不能接受的。问题在于生产环境和NAS存储之间是万兆网,但为什么传输速度只有60M/s左右呢?

       实际全备测试的传输速度和我一开始拷贝文件的速度基本是一致的,不应该啊,我明明开了4个并行,理论上一个进程速度是60M/s,那么四个进程至少也得有200多M/s啊。


      下面是全备测试过程中的相关截图:



 测试过程中持续观察发现en14网卡的流量一直在60--80M之间



也的确是万兆网络



上面两张图分别是aix和一体机到NAS存储的路由情况,可以看出也是一样的。


那到底是为什么呢?


接下来我查看了xtts全备时的日志,关键部分截图如下:



      从日志里看出了问题,我前面明明配置了4个并行,为什么这里rman在进行备份的时候,只开了一个channel呢?是什么原因导致并行没有生效呢?为了验证是因为并行没有生效才导致传输速度上不去,我在进行全备的过程中,又开了一个窗口,从AIX本地复制大文件到NAS存储,这样一来就等于模拟了并行,果不其然在拷贝开始之后网络流量马上就从原来的60M/s增长到150多M/s如下图:



     到目前为止基本定位到了问题的原因:xtts备份的过程中配置文件中parallel=4的参数没有生效,导致rman全备的时候是单进程在工作,所以慢也是可以理解的,接下来继续查官方文档,终于找到了答案:



        这篇文档中对parallel参数的描述很清楚,parallel参数只用于控制转换数据文件(源端和目标端数据文件字节序的转换)的并行度,而源端rman备份的并行度是由源端环境中rman的配置决定的,接下来在生产环境验证:


rman  target 

show all;



从上图看一看到生产环境中rman备份的并行度默认是1,到此真相大白了。


将rman备份的并行度参数修改为4:


RMAN>configure device type disk parallelism 4;


      再次发起数据库全备,632G表空间由原来的3小时候备份完提升到70分钟备份完,虽然时间还不是特别快,但目前只开了4个并行,后续可以根据生产的压力相应的做调整。


开启4个并行的情况下,网卡流量由最初的60M/s提升到270M/s左右



最后观察xtts备份的日志:



        rman备份的时候,的确是开启了4个并行,至此问题解决,但还有一个疑惑的点,最后我们再回到文件拷贝测试的那一部分,明明都是万兆网络,明明都是单进程在干活,为什么14G的文件,一体机到NAS存储的拷贝只需要42秒,而AIX到NAS存储的拷贝却要240秒呢?


        答案是磁盘的能力不同,AIX的磁盘跟一体机的存储相比性能差太多了,那么单进程在读取拷贝不同性能的磁盘的时候,速度也是不一样的。







最后修改时间:2020-11-25 10:44:19
文章转载自取名浪费我半小时,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论