生产上遇到一个迁移场景,大概1T数据量左右,由于没用XTTS做过迁移,所以准备尝试一下,本次迁移采用XTTS(增强传输表空间) V3版本的DBMS_FILE_TRANSFER方式。
从目标库及源库情况来看,选用XTTS并不是个好选择。XTTS主要还是用在跨平台、跨版本且数据量大的场景下,当前的场景:服务器间网络传输速率高用DataPump的netlink方式最简单,用DG停机时间可以做到最短。
源库 | 目标库 | |
---|---|---|
IP地址 | 10.0.11.XXX | 10.0.14.XXX |
系统版本 | CentOS 5.7 | CentOS Linux release 7.6.1810 (Core) |
数据库版本 | 11.2.0.3.0 | 11.2.0.4.181016 (28204707) |
字符集 | AL32UTF8 | AL32UTF8 |
实例名 | XKORG | XKORG |
CPU | 16 | 16 |
内存(GB) | 32 | 32 |
数据量GB | 1000 |
要迁移的表空间:USERS、ORCLTBS
mos 1389592.1
使用rman_xttconvert_v3.zip脚本
文档及脚本放到网盘中,公众号回复XTTS获取网盘地址
XTTS使用限制较多,V3版本按照本节逐项检查
源库:CentOS 5.7 目标库:CentOS Linux 7.6.1810
sqlplus -v
源库版本:Release 11.2.0.3.0 Production
show parameter compatible
检查结果:11.2.0.0.0
show parameter compatible
源库:11.2.0.0.0 目标库:11.2.0.4.0
archive log list
检查结果:已在归档模式下
sqlplus -v
检查结果:11.2.0.4.0
检查结果:
show all
检查结果:
CONFIGURE DEVICE TYPE DISK PARALLELISM 1 BACKUP TYPE TO BACKUPSET; # default
select file_name,online_status from dba_data_files t where t.online_status not in ('ONLINE','SYSTEM');
select tablespace_name,status from dba_tablespaces t where t.status<> 'ONLINE';
检查结果:均为online状态
select * from nls_database_parameters t where t.parameter in ('NLS_CHARACTERSET','NLS_NCHAR_CHARACTERSET');
检查结果:源库、目标库均为:
show parameter db_files
源库:200 目标库:200 目标库不符合要求,修改
alter system set db_files=500 scope=spfile;
见3.2.2
见3.2.2
SELECT DISTINCT owner FROM DBA_EXTERNAL_TABLES;
select owner, TABLE_NAME, DEFAULT_DIRECTORY_OWNER, DEFAULT_DIRECTORY_NAME from DBA_EXTERNAL_TABLES;
检查结果:
SELECT owner, table_name, COUNT(*) FROM DBA_ENCRYPTED_COLUMNS GROUP BY owner, table_name;
SELECT tablespace_name, ENCRYPTED FROM dba_tablespaces WHERE ENCRYPTED = 'YES';
检查结果:
select dbtimezone from dual;
select name,value$ from props$ where name ='DST_PRIMARY_TT_VERSION';
检查结果:源库、目标库均为
alter database enable block change tracking using file '/u02/data/XKORG/trace.log';
select status, filename from v$block_change_tracking;
alter system set "_bct_bitmaps_per_file"=100;
启动BCT后,XTTS使用tracking file里的信息,只需要读取改变的数据块信息,而不用再对全部数据文件进行扫描,从而提高了XTTS增量备份的性能。
搞大点
select * from v$dbfile;
alter database datafile 3 resize 32766m;
alter tablespace TEMP add tempfile '/oradata/datafile/XKORG/temp02.dbf' size 20G autoextend on;
需要传输的表空间中包含USER,需要将目标库USER替换为users_back
create tablespace users_back datafile '/oradata/datafile/XKORG/users_back.dbf' size 10m;
alter database default tablespace users_back;
drop tablespace users;
创建一个单独的用户表,这个表里面存放的是要迁移的用户,在checkobject(迁移完检查源库目标库对象是否一致)脚本与导入临时表的脚本中都会用到这个表create_migrate_useranme.sql
@/home/oracle/xtts_scripts/create_migrate_username.sql
--脚本内容
CREATE TABLE SYSTEM.migrate_username
AS
SELECT username
FROM dba_users
WHERE username NOT IN ('ANONYMOUS',
'APEX_030200',
'APEX_PUBLIC_USER',
'APPQOSSYS',
'CTXSYS',
'DBSNMP',
'DIP',
'EXFSYS',
'FLOWS_FILES',
'MDDATA',
'MDSYS',
'MGMT_VIEW',
'OLAPSYS',
'ORACLE_OCM',
'ORDDATA',
'ORDPLUGINS',
'ORDSYS',
'OUTLN',
'OWBSYS',
'OWBSYS_AUDIT',
'SCOTT',
'SI_INFORMTN_SCHEMA',
'SPATIAL_CSW_ADMIN_USR',
'SPATIAL_WFS_ADMIN_USR',
'SYS',
'SYSMAN',
'SYSTEM',
'WMSYS',
'XDB',
'XS$NULL',
'GGADM',
'SPA');
将源库/ete/hosts文件内容复制到目标环境中
检查结果:已按要求安装软件并创建数据库,实例名同源库
execute dbms_tts.transport_set_check('USERS,ORCLTBS',true);
select * from transport_set_violations;
我在迁移时候出现非自包含情况,检查发现有分区表及索引存储在SYSTEM表空间中,需要将这部分数据首先移动到业务表空间,详见:【迁移】Oracle分区表及索引迁移表空间(https://www.modb.pro/db/42030) 迁移完成后,检查结果如下:
create directory source_dir as '/u02/data/XKORG/';
create directory dest_dir as '/oradata/datafile/XKORG/';
create public database link to_old connect to system identified by oracle using '(DESCRIPTION =
(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.11.XXX)(PORT = 1521)))
(CONNECT_DATA = (SERVICE_NAME = XKORG))
)';
验证是否创建成功
select * from dual@to_old;
mkdir /home/oracle/xtts
chown -R oracle:dba /home/oracle/xtts/
上传官方脚本 rman_xttconvert_v3.zip 文件到xtts目录下,并授权
cd /home/oracle/xtts/
unzip rman_xttconvert_v3.zip
修改如下参数
tablespaces= USERS,ORCLTBS --要迁移的表空间名称
platformid=13 --select platform_id from v$database;
srcdir = SOURCE_DIR --dft时使用,源库存放数据文件的路径
dstdir = DEST_DIR --dft时使用,目标库存放数据文件的路径
srclink=to_old --目标库创建的DBLINK
backupformat=/home/oracle/xtts/bakincr --源端用于存放增量备份的路径
stageondest=/home/oracle/xtts/bak --目标端存放数据文件副本目录,和存放增量备份目录
backupondest=/home/oracle/xtts/bak --目标端增量备份的最终存放目录
parallel= 8
rollparallel= 8 --增量备份的并行度
getfileparallel= 8 --获取文件的并行度
说明:在v$transportable_platform视图中标记了platformid对应的platformname及字节序
源端创建目录
mkdir -p /home/oracle/xtts/bakincr
mkdir -p /home/oracle/xtts/bak
chown oracle:dba /home/oracle/xtts/bakincr
chown oracle:dba /home/oracle/xtts/bak
目标端创建目录
mkdir -p /home/oracle/xtts/bak
Oracle用户环境变量
$export TMPDIR=/home/oracle/xtts
scp -P 10011 /home/oracle/xtts/* 10.0.14.XXX:/home/oracle/xtts/
在这个阶段,表空间数据文件会从源库传输到目标库,并且会做一个自动的字节格式的转换。这个步骤只需要做一次。在此阶段,源端数据库可以正常进行访问。
下图为官方脚本功能说明:
[oracle@source]$ nohup $ORACLE_HOME/perl/bin/perl xttdriver.pl -S &
这个命令会执行以下动作:
scp -P 10011 xttnewdatafiles.txt getfile.sql 10.0.14.XXX:/home/oracle/xtts/
[oracle@dest]$ nohup $ORACLE_HOME/perl/bin/perl xttdriver.pl -G &
当这一步完成,数据文件将会被传输到目标端最终位置,并且被目标库使用,可见数据文件出现在目标库数据文件存放目录下,相当于将一份全备应用到了目标库。
在这个阶段中,源库会创建一个增量备份,传输到备库。并且会转换为目标库字节格式,并应用于目标库。这个阶段可以运行多次,每一个成功的增量备份所花的时间应该比之前的要少,并且使目标库的数据与源库更接近。
nohup perl xttdriver.pl -i &
这个命令会对传输的表空间产生一个增量备份集。备份集位于 backupformat 目录下。并且会产生两个文件:tsbkupmap.txt,incrbackups.txt
scp -P 10011 'cat incrbackups.txt' 10.0.14.XXX:/home/oracle/xtts/bak/
源端复制xttplan.txt,tsbkupmap.txt 到目标端
scp -P 10011 xttplan.txt tsbkupmap.txt 10.0.14.XXX:/home/oracle/xtts/
目标端执行以下命令,应用增量备份
nohup perl xttdriver.pl -r &
源库运行下面脚本, 确定一个新的scn, 记录在 xttplan.txt 文件中
nohup perl xttdriver.pl -s &
如果你需要使目标库更接近源库,则需要重复进行1-4 步骤;如果目标库已经足够接近源库,那就直接进行传输阶段。
在传输阶段,源库需要被设置为read only 模式,目标库会被应用最后一次增量备份。在目标数据文件一致后,将执行一次普通的传输表空间的步骤,从源库导出元数据对象并导入目标库。在此阶段结束之前,源库只能通过 read only 方式访问数据。
将资源控制文件profile,通过network_link方式导入目标库
nohup impdp \"/as sysdba\" metrics=yes network_link=to_old include=profile full=y content=metadata_only > profile.log 2>&1 &
将角色通过network_link方式导入目标库
nohup impdp \"/as sysdba\" metrics=yes network_link=to_old include=role full=y content=metadata_only > role.log 2>&1 &
select username,created from dba_users where created in (select max(CREATED) from dba_users);
select file#,name,creation_time from v$datafile where creation_time in (select max(creation_time) from v$datafile);
从这里开始计算停机时间
purge dba_recyclebin;
关于统计信息有两种处理方式:导出再倒入 或者 目标库重新收集。这里选择重新收集更合理一些,所以可以不导出统计信息,更节省时间。
nohup expdp \"/as sysdba\" directory=DUMPDIR dumpfile=stat_dblink.dmp logfile=stat_dblink.log include=statistics,DB_LINK full=y &
这里的directory=DUMPDIR指向一个NAS,该NAS挂载到了源库与目标库。
alter system set job_queue_processes=0;
show parameter job_queue_processes;
确认无活动事务与死事务,包括分布式事务
ps -ef| grep LOCAL=NO| grep -v grep| awk '{print $2}'| xargs kill -9
select local_tran_id,state from dba_2pc_pending;
create user TEST identified by oracle default tablespace USERS;
grant connect,resource to TEST;
--create_test_table.sql 内容就是创建两个测试表,用于迁移完验证是否在目标库也能查询到
@/home/oracle/xtts_scripts/create_test_table.sql
alter system switch logfile;
purge dba_recyclebin;
alter tablespace USERS read only;
alter tablespace ORCLTBS read only;
建议通知客户停业务之前再做一次增量备份应用,以减少数据差异,缩短停业务后的这次增量备时间
nohup perl xttdriver.pl -i &
scp 'cat incrbackups.txt' 10.0.14.XXX:/home/oracle/xtts/bak/
scp xttplan.txt tsbkupmap.txt 10.0.14.XXX:/home/oracle/xtts/
nohup perl xttdriver.pl -r &
目标库执行脚本,通过之间创建的dblink,在目标端创建用户,脚本不是自己写的就不放出来了
@/home/oracle/xtts_scripts/create_user.sql
给上一步创建的用户加权限 grant create database link to X
@/home/oracle/xtts_scripts/drm_grant_create_link.sql
脚本内容就是开启闪回,创建restore point
@/home/oracle/xtts_scripts/drm_enable_flashback.sql
目标端执行以下命令
nohup perl xttdriver.pl -e &
这个命令会产生一个DataPump 导入模板文件 xttplugin.txt 。该文件里是impdp的导入模板,编辑并执行导入 注意:
这一步应该放到应用最终测试完成后再执行
@/home/oracle/xtts_scripts/drm_disable_flashback.sql
@/home/oracle/xtts_scripts/query_test_table_data.sql
查询结果:
select tablespace_name,file_name from dba_data_files;
alter tablespace USERS read write;
alter tablespace ORCLTBS read write;
select TABLESPACE_NAME,status,CONTENTS from dba_tablespaces;
该步骤执行时间较长
RMAN> validate tablespace USERS, ORCLTBS check logical;
nohup impdp \"/ as sysdba\" network_link=to_old SCHEMAS='XXX','XXX' content=metadata_only TABLE_EXISTS_ACTION=SKIP exclude=table,index parallel=8 metrics=y directory=DUMPDIR > imp_meta.log 2>&1 &
--源库查询无用户自定义临时表
select owner,table_name from dba_tables where TEMPORARY='Y';
如果有的话按下面语句导入
nohup impdp \"/ as sysdba\" metrics=yes network_link=to_old logfile=temp_table.log schemas='XXX','XXX' include=TABLE:\"" in \(select table_name from dba_tables where TEMPORARY=\'Y\'\)\"" > imp_tmp.log 2>&1 &"
@/home/oracle/xtts_scripts/drm_revoke_database_link.sql
还是通过dblink获取
@/home/oracle/xtts_scripts/alter_user_default_tablespace.sql
Select username,default_tablespace from dba_users;
select 'grant '||GRANTED_ROLE||' to '||grantee||';' from dba_role_privs where grantee in(select username from dba_users where default_tablespace in ('USERS','ORCLTBS') and user_id >='84');
源库查询后,在目标库执行 对象权限、角色权限、DDL权限 后续执行checkobject.sql脚本时生成后在目标库执行即可
DECLARE
threads pls_integer := 150;
BEGIN
utl_recomp.recomp_parallel(threads);
END;
/
@/home/oracle/xtts_scripts/checkobject.sql
select object_type,count(*) as num from dba_objects where owner='MAOTAI' group by object_type order by num desc;
方式1:导入统计信息及dblink 如果在3.5.7小节导出了统计信息,那么这里可以选择导入,但是时间会很长
nohup impdp \"/as sysdba\" directory=DUMPDIR dumpfile=stat_dblink.dmp logfile=stat_dblink_i.log include=statistics,DB_LINK full=y &
方式2:手工统计
select 'EXEC DBMS_STATS.GATHER_TABLE_STATS('''||owner||''','''||table_name||''',estimate_percent=>10,method_opt=>''FOR ALL COLUMNS SIZE AUTO'',degree=>12,cascade=>TRUE);' from dba_tables where owner in('schema1','schema2') ;
源库执行生成语句,编辑一个static.sql文件在目标库执行,此处是按表统计也可选择按schema统计GATHER_SCHEMA_STATS;
@/home/oracle/xtts_scripts/static.sql
注意:这次迁移最占用时间的步骤来了,一开始estimate 设置为80,但是特别慢,后续改为10,也跑了3个小时才完成,后来咨询大拿,这里其实收集个0.01就可以了,也就是收集0.01%的统计信息。注意并行度16个cpu开到12。
select sql_id,program,status,state,LAST_CALL_ET from v$session where program like '%P0%' and sql_id is not null order by 3
通过上述语句查询开启的并行进程,LAST_CALL_ET为该进程执行的时间 执行过程中可到v$lock 视图查询是否有锁 TM TX 如果执行过慢,可查询dba_segments bytes字段查询大小
EXEC DBMS_STATS.GATHER_DICTIONARY_STATS;
EXEC DBMS_STATS.GATHER_FIXED_OBJECTS_STATS;
迁移后与目标库对比
set line 1000 pages 500
col owner for a20
col object_name for a50
col object_type for a15
SELECT owner, object_name, object_type,status
FROM dba_objects
WHERE status = 'INVALID' and owner in('schema1','schema2');
select owner,object_name,object_type,status from dba_objects@to_old where object_name in(select object_name from dba_objects where status='INVALID' and owner!='PUBLIC');
alter system set job_queue_processes=1000;
XTTS迁移方式对源库变动主要是设置要迁移表空间read only,如迁移发现异常,按照如下步骤恢复:
alter tablespace USERS read write;
alter tablespace ORCLTBS read write;
1、实际迁移花费6个小时,消耗时间最多的是收集统计信息耗费3小时,其次是最后一次增量备占用1小时,再次是坏块检查; 2、收集统计信息部分,事后咨询专家后知道其实收集0.01%就可以; 3、设置源库表空间为read only后的增量备时间有点长,现在看应该在停业务前再应用一次增量,应该能再减少这部分时间; 4、检查物理和逻辑块损坏,并验证数据,虽然是极小概率的情况,我觉得还是不要省为好 5、脚本很强大,能省很多时间,有专家用自己写的脚本不用官方脚本