前言:
在使用xtts进行迁移时,如何进行迁移前的测试以及在数据同步过程中减少对生产的影响是我们在使用xtts迁移过程中需要面对的问题,而通过在DG备库上使用xtts进行数据同步迁移可以解决上述两个问题,本文接下来将讲述如何在DG备库进行xtts测试以及迁移
环境信息:
源端主库 | 源端备库 | 目标端新环境 | |
操作系统平台 | LINUX | LINUX | LINUX |
数据库版本 | 11.2.0.4 | 11.2.0.4 | 19.3.0.0 |
db_unique_name | db | dbdg | newdb |
IP | 192.168.1.210 | 192.168.1.220 | 192.168.1.230 |
迁移步骤:
注:以下源端操作默认都在备库上进行
xtts前期准备确认:
这里步骤省略具体可以查看我之前写过的文章Oracle 使用xtts升级11g-to-19c
配置xtts(v4版本):
1 安装以及配置xtts(源端目标端都操作):
--创建安装目录并解压配置
mkdir -p /home/oracle/xtts
cd /home/oracle/xtts
unzip /tmp/rman_xttconvert_VER4.3.zip
--创建xtts文件放置目录
mkdir -p /home/oracle/xttsdir
--配置环境变量
export TMPDIR=/home/oracle/xttsdir
export PERL5LIB=$ORACLE_HOME/perl/lib
#TMPDIR
指向XTTS脚本存放位置,后续在使用perl执行xtts脚本时,会生成一些文件,这些文件默认存放到TMPDIR指向的位置
#PERL5LIB
指向perl的lib库,如果该环境变量不设置,在使用perl执行xtts脚本时,会报错
2 设置xtts参数信息(源端操作):
注意开启允许脚本在备库执行
--src_scratch_location 源端备份存放目录
--dest_scratch_location 目标端备份存放目录
--dest_datafile_location目标端数据文件路径
--parallel 数据文件copy的并行度
--增量并行度Incremental backup creation parallelism is defined by RMAN configuration for DEVICE TYPE DISK PARALLELISM. If undefined, default value is 8
--rollparallel Defines the level of parallelism for the -r roll forward operation
--allowstandby允许脚本在备库执行
cd /home/oracle/xtts
vi xtt.properties
tablespaces=XTTSTAB,XTTSIND,XTTSLOB
platformid=13
src_scratch_location=/backup
dest_scratch_location=/backup
dest_datafile_location=/u01/app/oracle/oradata/192.168.1.230/datafile
parallel=4
rollparallel=4
allowstandby=1
---将xtts配置文件拷贝到目标端
scp xtt.properties 192.168.1.230:/home/oracle/xtts/
表空间变量同步:
1 源端开启块追踪
alter database enable block change tracking using file '/u01/app/oracle/oradata/bct.trc';
2 源端进行传输表空间全量数据备份
cd /home/oracle/xtts
$ORACLE_HOME/perl/bin/perl xttdriver.pl --backup --debug 3
---会在$TMPDIR(/home/oracle/xttsdir)下面生成以下文件
-rw-r--r-- 1 oracle oinstall 305 Aug 26 10:18 xttnewdatafiles.txt
-rw-r--r-- 1 oracle oinstall 67 Aug 26 10:19 xttplan.txt
-rw-r--r-- 1 oracle oinstall 615 Aug 26 10:19 rmanconvert.cmd
-rw-r--r-- 1 oracle oinstall 310 Aug 26 10:19 res.txt
-rw-r--r-- 1 oracle oinstall 433 Aug 26 10:19 newfile.txt
drwxr-xr-x 2 oracle oinstall 4096 Aug 26 10:19 backup_Aug26_Sat_10_18_37_786
----把备份的文件拷贝到目标库/backup
scp -rp /backup/ [email protected]:/backup
----把$TMPDIR下的res.txt(记录数据文件的信息)文件拷贝到目标端对应的$TMPDIR
scp /home/oracle/xttsdir/res.txt [email protected]:/home/oracle/xttsdir/res.txt
3 目标端进行传输表空间全量恢复
--注意ORACLE_HOME以及ORACLE_SID,将会直接关联到操作的数据库
--若第一次恢复失败,执行第二次时,需要根据提示删除/home/oracle/xttsdir/FAILED,再执行
$ORACLE_HOME/perl/bin/perl xttdriver.pl --restore --debug 3
--恢复会恢复到dest_datafile_location
表空间增量同步:
1 源端增量备份
--注意ORACLE_HOME以及ORACLE_SID,将会直接关联到操作的数据库
cd /home/oracle/xtts
$ORACLE_HOME/perl/bin/perl xttdriver.pl --backup --debug 3
--会生成xttplan文件记录scn
New /home/oracle/xttsdir/xttplan.txt with FROM SCN s generated
cd /home/oracle/xttsdir
--拷贝以下增量文件到目标端stageondest(源端备库操作)
scp `cat /home/oracle/xttsdir/incrbackups.txt` [email protected]:/backup
--拷贝以下文件到目标端$TMPDIR(源端备库操作)
scp /home/oracle/xttsdir/res.txt [email protected]:/home/oracle/xttsdir
2 目标端增量恢复
$ORACLE_HOME/perl/bin/perl xttdriver.pl --restore --debug 3
模拟正式迁移(需要将备库打开到读写状态):
1 源端进行最后一次增量备份
将备库激活为读写状态
--备库停止apply日志
alter database recover managed standby database cancel;
--备库创建闪回点
CREATE RESTORE POINT STANDBY_XTTS GUARANTEE FLASHBACK DATABASE;
--激活备库为read write
ALTER DATABASE ACTIVATE STANDBY DATABASE;
ALTER DATABASE OPEN;
进行最后一次增量备份
--备库表空间设置为只读
select 'alter tablespace '||tablespace_name||' read only;'
from dba_tablespaces
where tablespace_name in ('XTTSTAB','XTTSIND','XTTSLOB','XTTSTEMP');
---------------------------------------
alter tablespace XTTSIND read only;
alter tablespace XTTSLOB read only;
alter tablespace XTTSTAB read only;
alter tablespace XTTSTEMP read only;
--进行第最后一次增量备份(源端备库操作)
cd /home/oracle/xtts
$ORACLE_HOME/perl/bin/perl xttdriver.pl --backup --debug 3
--拷贝以下增量文件到目标端stageondest(源端备库操作)
scp `cat /home/oracle/xttsdir/incrbackups.txt` [email protected]:/backup
--拷贝以下文件到目标端$TMPDIR(源端备库操作)
scp /home/oracle/xttsdir/res.txt [email protected]:/home/oracle/xttsdir
2 目标端进行最后一次增量恢复
$ORACLE_HOME/perl/bin/perl xttdriver.pl --restore --debug 3
3 目标端导入表空间元数据
--创建dump directory(源端目标端一起操作)
mkdir -p /home/oracle/destination/convert
create directory dpump_tts as '/home/oracle/destination/convert';
GRANT READ, WRITE ON DIRECTORY dpump_tts TO system;
--目标端创建dblink,指向源端备库
create public database link ttslink connect to system identified by oracle using 'dbdg';
select name from v$database@ttslink;
--拷贝文件xttplan.txt到目标端$TMPDIR(源端操作)
cd /home/oracle/xttsdir
scp xttplan.txt xttnewdatafiles.txt 192.168.1.230:/home/oracle/xttsdir
--目标端生成通过network方式的导入表空间脚本
$ORACLE_HOME/perl/bin/perl xttdriver.pl -e
--查看导出脚本xttplugin.txt
Done generating plugin file /home/oracle/xttsdir/xttplugin.txt
cat /home/oracle/xttsdir/xttplugin.txt
--目标导入前,从源端获取用户DDL在目标端进行创建,否则会提示用户不存在(目标端操作)
#从源端获取profile,并导入目标端
set long 1000000
SET PAGESIZE 3000
set lines 200
SET HEADING OFF
SET VERIFY OFF
SET FEEDBACK OFF
set echo on
set timing off
set wrap On
SET LONGCHUNKSIZE 400
with profile as(
select distinct profile from dba_profiles
)
select dbms_metadata.get_ddl('PROFILE',PROFILE) from profile
;
#从源端获取role ddl并导入目标端
select 'grant '||PRIVILEGE||' to '||GRANTEE||';' from dba_sys_privs
where grantee in (select distinct GRANTED_ROLE from dba_role_privs where GRANTEE in ('XTTSUSER'))
;
#获取用户的ddl
SELECT DBMS_METADATA.GET_DDL('USER', USERNAME) DDL_SQL FROM DBA_USERS
WHERE USERNAME IN (select owner from dba_segments
where tablespace_name not in ('SYSTEM','SYSAUX','UNDOTBS1','TEMP','EXAMPLE')
group by owner,tablespace_name) AND USERNAME NOT IN ('SYS');
#获取权限ddl
SELECT DBMS_METADATA.GET_GRANTED_DDL('SYSTEM_GRANT', USERNAME) DDL_SQL FROM DBA_USERS
WHERE USERNAME IN (select owner from dba_segments
where tablespace_name not in ('SYSTEM','SYSAUX','UNDOTBS1','TEMP','EXAMPLE')
group by owner,tablespace_name) AND USERNAME NOT IN ('SYS');
SELECT DBMS_METADATA.GET_GRANTED_DDL('ROLE_GRANT', USERNAME) DDL_SQL FROM DBA_USERS
WHERE USERNAME IN (select owner from dba_segments
where tablespace_name not in ('SYSTEM','SYSAUX','UNDOTBS1','TEMP','EXAMPLE')
group by owner,tablespace_name) AND USERNAME NOT IN ('SYS');
SELECT DBMS_METADATA.GET_GRANTED_DDL('OBJECT_GRANT', USERNAME) DDL_SQL FROM DBA_USERS
WHERE USERNAME IN (select owner from dba_segments
where tablespace_name not in ('SYSTEM','SYSAUX','UNDOTBS1','TEMP','EXAMPLE')
group by owner,tablespace_name) AND USERNAME NOT IN ('SYS');
--执行表空间元数据导入
impdp system/oracle directory=dpump_tts logfile=tts_imp.log \
network_link=ttslink transport_full_check=yes \
transport_tablespaces=XTTSTAB,XTTSIND,XTTSLOB,XTTSTEMP \
transport_datafiles='/u01/app/oracle/oradata/NEWDB/datafile/XTTSTAB_5.dbf','/u01/app/oracle/oradata/NEWDB/datafile/XTTSTAB_6.dbf','/u01/app/oracle/oradata/NEWDB/datafile/XTTSIND_7.dbf','/u01/app/oracle/oradata/NEWDB/datafile/XTTSIND_8.dbf','/u01/app/oracle/oradata/NEWDB/datafile/XTTSLOB_9.dbf','/u01/app/oracle/oradata/NEWDB/datafile/XTTSLOB_10.dbf','/u01/app/oracle/oradata/NEWDB/datafile/XTTSTEMP_11.dbf'
4 验证打开表空间
--验证表空间是否有坏块(目标端操作)
rman target /
validate tablespace XTTSTAB,XTTSIND,XTTSLOB,XTTSTEMP check logical;
--将表空间设置为read write
select 'alter tablespace '||tablespace_name||' read write;'
from dba_tablespaces
where tablespace_name in ('XTTSTAB','XTTSIND','XTTSLOB','XTTSTEMP');
--设置表空间为读写
alter tablespace XTTSIND read write;
alter tablespace XTTSLOB read write;
alter tablespace XTTSTAB read write;
alter tablespace XTTSTEMP read write;
--验证数据
select count(*) from xttsuser.xttstab;
select count(*) from xttsuser.xttstab2;
select count(*) from xttsuser.xttstab3;
5 导入存储过程等其他元数据
--第二次元数据导入,将第一次没有导入的过程,视图,包,触发器导入。
impdp directory=dpump_tts network_link=ttslink schemas= 'XTTSUSER' content=metadata_only exclude=index,table,constraint,statistics
--从源端获取临时表,并导入目标端
spool create_temp_table.sql
set long 1000000
SET PAGESIZE 3000
set lines 200
SET HEADING OFF
SET VERIFY OFF
SET FEEDBACK OFF
set echo on
set timing off
set wrap On
SET LONGCHUNKSIZE 400
select dbms_metadata.get_ddl('TABLE',TABLE_NAME,OWNER)
from DBA_TABLES
where TEMPORARY='Y' and owner in ('XTTSUSER');
spool off
--将源端库中的其余用户,权限导入到目标端中
SET SERVEROUTPUT ON
SET LINESIZE 1000
SET FEEDBACK OFF
SET TRIMSPOOL ON
set long 999999
SET PAGESIZE 1000
spool grant_role_priv.sql
select 'grant '||GRANTED_ROLE||' to '||grantee||';'from dba_role_privs where grantee in('XTTSUSER') and admin_option='NO'
union
select 'grant '||GRANTED_ROLE||' to '||grantee||' with admin option;' from dba_role_privs where grantee in ('XTTSUSER') and admin_option='YES';
spool off
SET SERVEROUTPUT ON
SET LINESIZE 1000
SET FEEDBACK OFF
set long 999999
SET TRIMSPOOL ON
SET PAGESIZE 1000
spool grant_sys_priv.sql
select 'grant '||privilege||' to '||grantee||';' from dba_sys_privs where grantee in() and admin_option='NO'
union
select 'grant '||privilege||' to '||grantee||' with admin option;' from dba_sys_privs where grantee in('XTTSUSER') and admin_option='YES';
spool off
SET SERVEROUTPUT ON
SET LINESIZE 1000
SET FEEDBACK OFF
SET TRIMSPOOL ON
set long 999999
SET PAGESIZE 1000
spool grant_tab_privs.sql
select 'grant ' || privilege || ' on ' || owner || '.'|| table_name || ' to ' || grantee || ';' from dba_tab_privs where grantee in ('XTTSUSER') and grantable='NO'
union
select 'grant ' || privilege || ' on ' || owner || '.'|| table_name || ' to ' || grantee || ' with grant option;' from dba_tab_privs where grantee in() and grantable='YES';
spool off
--目标端搜集统计信息
execDBMS_STATS.GATHER_SCHEMA_STATS(ownname=>'XTTSUSER',ESTIMATE_PERCENT=>20,method_opt=>'forall columns size skewonly',cascade=>true,force=>true,degree=>8);
准备正式迁移:
1 测试完成,备库重新转化为备库进行同步,准备正式的迁移
--启动mount状态
shutdown immediate
startup mount
--闪回到还原点
flashback database to restore point STANDBY_XTTS;
--转化为备库类型(rac集群这一步只能启动一个节点)
alter database convert to physical standby;
--转化之后,数据库会启为started,需要关闭再重新启到mount
shutdown immediate;
startup mount
--恢复
alter database recover managed standby database using current logfile disconnect from session;
alter database recover managed standby database cancel;
--删除还原点
drop restore point STANDBY_XTTS;
--开启adg
alter database open read only;
alter database recover managed standby database using current logfile disconnect from session;
---清空备份以及$TMPDIR下的文件
重复之前的4-7的数据同步步骤:
应用停机正式迁移开始
1 源端主库传输的表空间设置只读
select 'alter tablespace '||tablespace_name||' read only;'
from dba_tablespaces
where tablespace_name in ('XTTSTAB','XTTSIND','XTTSLOB','XTTSTEMP');
---------------------------------------
alter tablespace XTTSIND read only;
alter tablespace XTTSLOB read only;
alter tablespace XTTSTAB read only;
alter tablespace XTTSTEMP read only;
2 确保主库的日志传输到备库并被应用
alter system archive log current;
3 源端备库进行第最后一次增量备份
cd /home/oracle/xtts
$ORACLE_HOME/perl/bin/perl xttdriver.pl --backup --debug 3
--拷贝以下增量文件到目标端stageondest(源端备库操作)
scp `cat /home/oracle/xttsdir/incrbackups.txt` [email protected]:/backup
--拷贝以下文件到目标端$TMPDIR(源端备库操作)
scp /home/oracle/xttsdir/res.txt [email protected]:/home/oracle/xttsdir
4 目标端进行最后一次增量恢复
$ORACLE_HOME/perl/bin/perl xttdriver.pl --restore --debug 3
5 目标端导入表空间元数据
--创建dump directory(源端主库与目标端一起操作)
mkdir -p /home/oracle/destination/convert
create directory dpump_tts as '/home/oracle/destination/convert';
GRANT READ, WRITE ON DIRECTORY dpump_tts TO system;
--目标端创建dblink,指向源端主库
create public database link ttslink connect to system identified by oracle using 'db';
select name from v$database@ttslink;
--拷贝源端备库文件xttplan.txt到目标端$TMPDIR(源端操作)
cd /home/oracle/xttsdir
scp xttplan.txt xttnewdatafiles.txt 192.168.1.230:/home/oracle/xttsdir
--目标端执行生成通过network方式导入命令
$ORACLE_HOME/perl/bin/perl xttdriver.pl -e
--目标端查看生成的导入命令xttplugin.txt
Done generating plugin file /home/oracle/xttsdir/xttplugin.txt
cat /home/oracle/xttsdir/xttplugin.txt
--目标导入前,从源端获取用户DDL在目标端进行创建,否则会提示用户不存在(目标端操作)
#从源端获取profile,并导入目标端
set long 1000000
SET PAGESIZE 3000
set lines 200
SET HEADING OFF
SET VERIFY OFF
SET FEEDBACK OFF
set echo on
set timing off
set wrap On
SET LONGCHUNKSIZE 400
with profile as(
select distinct profile from dba_profiles
)
select dbms_metadata.get_ddl('PROFILE',PROFILE) from profile
;
#从源端获取role ddl并导入目标端
select 'grant '||PRIVILEGE||' to '||GRANTEE||';' from dba_sys_privs
where grantee in (select distinct GRANTED_ROLE from dba_role_privs where GRANTEE in ('XTTSUSER'))
;
#获取用户的ddl
SELECT DBMS_METADATA.GET_DDL('USER', USERNAME) DDL_SQL FROM DBA_USERS
WHERE USERNAME IN (select owner from dba_segments
where tablespace_name not in ('SYSTEM','SYSAUX','UNDOTBS1','TEMP','EXAMPLE')
group by owner,tablespace_name) AND USERNAME NOT IN ('SYS');
#获取权限ddl
SELECT DBMS_METADATA.GET_GRANTED_DDL('SYSTEM_GRANT', USERNAME) DDL_SQL FROM DBA_USERS
WHERE USERNAME IN (select owner from dba_segments
where tablespace_name not in ('SYSTEM','SYSAUX','UNDOTBS1','TEMP','EXAMPLE')
group by owner,tablespace_name) AND USERNAME NOT IN ('SYS');
SELECT DBMS_METADATA.GET_GRANTED_DDL('ROLE_GRANT', USERNAME) DDL_SQL FROM DBA_USERS
WHERE USERNAME IN (select owner from dba_segments
where tablespace_name not in ('SYSTEM','SYSAUX','UNDOTBS1','TEMP','EXAMPLE')
group by owner,tablespace_name) AND USERNAME NOT IN ('SYS');
SELECT DBMS_METADATA.GET_GRANTED_DDL('OBJECT_GRANT', USERNAME) DDL_SQL FROM DBA_USERS
WHERE USERNAME IN (select owner from dba_segments
where tablespace_name not in ('SYSTEM','SYSAUX','UNDOTBS1','TEMP','EXAMPLE')
group by owner,tablespace_name) AND USERNAME NOT IN ('SYS');
--执行表空间导入
impdp system/oracle directory=dpump_tts logfile=dbtts_imp.log \
network_link=ttslink transport_full_check=yes \
transport_tablespaces=XTTSTAB,XTTSIND,XTTSLOB,XTTSTEMP \
transport_datafiles='/u01/app/oracle/oradata/NEWDB/datafile/XTTSTAB_5.dbf','/u01/app/oracle/oradata/NEWDB/datafile/XTTSTAB_6.dbf','/u01/app/oracle/oradata/NEWDB/datafile/XTTSIND_7.dbf','/u01/app/oracle/oradata/NEWDB/datafile/XTTSIND_8.dbf','/u01/app/oracle/oradata/NEWDB/datafile/XTTSLOB_9.dbf','/u01/app/oracle/oradata/NEWDB/datafile/XTTSLOB_10.dbf','/u01/app/oracle/oradata/NEWDB/datafile/XTTSTEMP_11.dbf'
6 验证打开表空间
--验证表空间是否有坏块(目标端操作)
rman target /
validate tablespace XTTSTAB,XTTSIND,XTTSLOB,XTTSTEMP check logical;
--将表空间设置为read write
select 'alter tablespace '||tablespace_name||' read write;'
from dba_tablespaces
where tablespace_name in ('XTTSTAB','XTTSIND','XTTSLOB','XTTSTEMP');
--设置表空间为读写
alter tablespace XTTSIND read write;
alter tablespace XTTSLOB read write;
alter tablespace XTTSTAB read write;
alter tablespace XTTSTEMP read write;
--验证数据
select count(*) from xttsuser.xttstab;
select count(*) from xttsuser.xttstab2;
select count(*) from xttsuser.xttstab3;
7 导入存储过程等其他元数据
--第二次元数据导入,将第一次没有导入的过程,视图,包,触发器导入。还是从源端主库导出
impdp directory=dpump_tts network_link=ttslink schemas= 'XTTSUSER' content=metadata_only exclude=index,table,constraint,statistics
--从源端主库获取临时表,并导入目标端
spool create_temp_table.sql
set long 1000000
SET PAGESIZE 3000
set lines 200
SET HEADING OFF
SET VERIFY OFF
SET FEEDBACK OFF
set echo on
set timing off
set wrap On
SET LONGCHUNKSIZE 400
select dbms_metadata.get_ddl('TABLE',TABLE_NAME,OWNER)
from DBA_TABLES
where TEMPORARY='Y' and owner in ('XTTSUSER');
spool off
--将源端主库中的其余用户,权限导入到目标端中
SET SERVEROUTPUT ON
SET LINESIZE 1000
SET FEEDBACK OFF
SET TRIMSPOOL ON
set long 999999
SET PAGESIZE 1000
spool grant_role_priv.sql
select 'grant '||GRANTED_ROLE||' to '||grantee||';'from dba_role_privs where grantee in('XTTSUSER') and admin_option='NO'
union
select 'grant '||GRANTED_ROLE||' to '||grantee||' with admin option;' from dba_role_privs where grantee in ('XTTSUSER') and admin_option='YES';
spool off
SET SERVEROUTPUT ON
SET LINESIZE 1000
SET FEEDBACK OFF
set long 999999
SET TRIMSPOOL ON
SET PAGESIZE 1000
spool grant_sys_priv.sql
select 'grant '||privilege||' to '||grantee||';' from dba_sys_privs where grantee in() and admin_option='NO'
union
select 'grant '||privilege||' to '||grantee||' with admin option;' from dba_sys_privs where grantee in('XTTSUSER') and admin_option='YES';
spool off
SET SERVEROUTPUT ON
SET LINESIZE 1000
SET FEEDBACK OFF
SET TRIMSPOOL ON
set long 999999
SET PAGESIZE 1000
spool grant_tab_privs.sql
select 'grant ' || privilege || ' on ' || owner || '.'|| table_name || ' to ' || grantee || ';' from dba_tab_privs where grantee in ('XTTSUSER') and grantable='NO'
union
select 'grant ' || privilege || ' on ' || owner || '.'|| table_name || ' to ' || grantee || ' with grant option;' from dba_tab_privs where grantee in() and grantable='YES';
spool off
--目标端搜集统计信息
execDBMS_STATS.GATHER_SCHEMA_STATS(ownname=>'XTTSUSER',ESTIMATE_PERCENT=>20,method_opt=>'forall columns size skewonly',cascade=>true,force=>true,degree=>8);