XTTS系列之一:U2L遷移解決方案之XTTS的使用

AlfredZhao發表於2019-07-28

本系列的定位是對XTTS及相關技術進行深入的學習研究。作為本系列的開篇,本著實用性的原則,我先把一次實際生產環境U2L的遷移實戰實施方案進行提煉簡化,旨在能清楚說明該如何使用XTTS這種解決方案來進行U2L遷移,先達到可以跟著做下來的初級目標,如果有興趣再去深入研究相關細節。

1.XTTS概述

採用XTTS(Cross Platform Transportable Tablespaces)遷移方式,準確說這裡指的是加強版XTTS,具備跨平臺位元組序轉換、全量初始化、多次增量前滾的功能,從而有效縮短正式遷移階段的生產停機時間,順利完成U2L的遷移工作。比如本次需求如下:

源端 目標端
IP地址 10.6.xx.xx 10.5.xx.xx
作業系統 AIX 5.3 RHEL 6.7
是否RAC
資料庫名稱 sourcedb targetdb
遷移業務使用者 JINGYU JINGYU

2.遷移準備階段

2.1 校驗自包含

本次只遷移 JINGYU 使用者,只檢查 JINGYU 使用者所在表空間的自包含驗證即可:

SQL> select distinct tablespace_name from dba_segments where owner='JINGYU' order by 1; 

TABLESPACE_NAME 
------------------------------ 
DBS_D_JINGYU 
DBS_I_JINGYU

SQL> execute dbms_tts.transport_set_check('DBS_D_JINGYU, DBS_I_JINGYU');
PL/SQL procedure successfully completed. 

SQL> select * from TRANSPORT_SET_VIOLATIONS; 
no rows selected

上述查詢若沒有結果行返回,說明自包含校驗通過。

2.2 建立XTTS工作目錄
本次我設定的XTTS的工作目錄是/exp/newxx,在源端和目標端都建立相關目錄,上傳並解壓MOS(文件 ID 1389592.1)提供的xttconvert指令碼。

--源端AIX建立相關目錄
mkdir -p  /exp/newxx
mkdir -p  /exp/newxx/src_backup
mkdir -p  /exp/newxx/tmp
mkdir -p  /exp/newxx/dump
mkdir -p  /exp/newxx/backup_incre
chown -R ora103:dba /exp/newxx

--源端AIX上傳rman-xttconvert_2.0.zip至/exp/newxx
cd /exp/newxx
unzip rman-xttconvert_2.0.zip

--目標端Linux建立相關目錄
mkdir -p  /exp/newxx
mkdir -p  /exp/newxx/src_backup
mkdir -p  /exp/newxx/tmp
mkdir -p  /exp/newxx/dump
mkdir -p  /exp/newxx/backup_incre
chown -R ora11g:dba /exp/newxx

--目標端Linux上傳rman-xttconvert_2.0.zip至/exp/newxx
cd /exp/newxx
unzip rman-xttconvert_2.0.zip

2.3 源端開啟 bct
源端開啟bct(block change tracking)

SQL> alter database enable block change tracking using file '/exp/newxx/bct2'; 
Database altered.

如果測試階段發現bct無法生效(增量備份時間很長),可考慮手工進行一次表空間的0級備份:

--手動以level 0進行備份待遷移的表空間(只是為了增量可讀bct,不做其他恢復操作)
RMAN> CONFIGURE DEVICE TYPE DISK PARALLELISM 16 BACKUP TYPE TO BACKUPSET;
RMAN> backup incremental level 0 tablespace DBS_D_JINGYU, DBS_I_JINGYU format '/exp/test/%U.bck';

注:這是特殊情況,不一定會遇到,根據你的實際測試情況選擇是否要做。本次大概2T的表空間0級備份時間:2h。

2.4 配置 xtt.properties

配置源端AIX xtt.properties屬性檔案:

cd /exp/newxx
vi xtt.properties

#增加如下配置資訊:
tablespaces=DBS_D_JINGYU,DBS_I_JINGYU
platformid=6
dfcopydir=/exp/newxx/src_backup
backupformat=/exp/newxx/backup_incre
backupondest=/exp/newxx/backup_incre
stageondest=/exp/newxx/src_backup
storageondest=+DG_DATA/targetdb/datafile
parallel=16
rollparallel=16
getfileparallel=6

配置目標端Linux xtt.properties屬性檔案:

cd /exp/newxx
vi xtt.properties

#增加如下配置資訊:
tablespaces=DBS_D_JINGYU,DBS_I_JINGYU
platformid=6
dfcopydir=/exp/newxx/src_backup
backupformat=/exp/newxx/backup_incre
backupondest=/exp/newxx/backup_incre
stageondest=/exp/newxx/backup_incre
storageondest=+DG_DATA/targetdb/datafile
parallel=16
rollparallel=16
getfileparallel=6
asm_home=/opt/app/11.2.0/grid
asm_sid=+ASM1

注:這裡的platformid=6是根據源端的OS平臺決定的,可以通過查詢v$database的platform_id欄位進行確認,也可參照v$transportable_platform中的平臺對應。

2.5 目標端提前建立使用者角色
目標端建立JINGYU使用者,完成後設資料匯入後才可修改預設表空間。
以下是在源端執行獲取建立使用者和對應角色、許可權的語句後,在目標端對應建立(如果你很清楚要遷移業務使用者的使用者密碼和許可權等資訊,也可以選擇直接建立):

--源端執行:
--create user
sqlplus -S / as sysdba
set pages 0
set feedback off
spool /exp/newxx/scripts/create_user.sql
select 'create user '||name||' identified by values '''||password||''';' from user$ where name = 'JINGYU' and type#=1;
spool off
exit

--create role
sqlplus -S / as sysdba
set pages 0
set feedback off
spool /exp/newxx/scripts/create_role.sql
select 'grant '||GRANTED_ROLE||' to '||grantee||';' from dba_role_privs where grantee = 'JINGYU';
spool off
exit

--owner為sys的表的許可權需要手動賦予
sqlplus -S / as sysdba
set pages 0
set feedback off
spool /exp/newxx/scripts/grant_sys_privs.sql
select 'grant '||PRIVILEGE||' on '||owner||'.'||table_name||' to '||GRANTEE||';' from dba_tab_privs where owner='SYS'  and GRANTEE = 'JINGYU';
spool off
exit

--源端驗證SQL正確與否:
cat /exp/newxx/scripts/create_user.sql
cat /exp/newxx/scripts/create_role.sql
cat /exp/newxx/scripts/grant_sys_privs.sql

--目標端執行:
@/exp/newxx/scripts/create_user.sql
@/exp/newxx/scripts/create_role.sql
@/exp/newxx/scripts/grant_sys_privs.sql

2.6 表空間全量備份
源端AIX執行被傳輸業務表空間全量備份建立xtts表空間全量備份指令碼執行過程中產生的配置檔案,用於資料檔案轉換及每次增量備份及恢復,同時每次執行增量備份過程中,配置檔案內容會發生變化,用於新的增量恢復,主要是SCN的變化。
增加rman備份並行度:

RMAN> CONFIGURE DEVICE TYPE DISK PARALLELISM 16 BACKUP TYPE TO BACKUPSET;

編輯備份檔案,每次備份失敗會在/exp/newxx/tmp產生fails檔案需要刪除後方可再次執行

cd /exp/newxx
--full_backup.sh指令碼內容如下
export ORACLE_SID=sourcedb
export TMPDIR=/exp/newxx/tmp
export PERL5LIB=/opt/app/ora103/10.2.0/product/perl/lib
/opt/app/ora103/10.2.0/product/perl/bin/perl /exp/newxx/xttdriver.pl -p –d

在後臺執行全量備份:

cd /exp/newxx
nohup sh full_backup.sh > full_backup.log &

檢視/exp/newxx/src_backup產生的全量備份大小(本次測試大小為 2T,備份耗時 4小時34分鐘)

2.7 表空間全量恢復及轉換
將檔案傳輸至目標端

cd /exp/newxx/src_backup
scp * ora11g@10.5.xx.xx:/exp/newxx/src_backup
--scp拷貝耗時10小時
cd /exp/newxx/tmp
scp * ora11g@10.5.xx.xx:/exp/newxx/tmp

目標端 Linux 執行表空間恢復並將資料檔案轉換至 ASM 磁碟組中,每次恢復失敗時會在/exp/newxx/tmp 產生 fails 檔案需要刪除後方可再次執行(詳見下面3.2節的特別說明)。

cd /exp/newxx
--full_restore.sh指令碼內容如下
export TMPDIR=/exp/newxx/tmp
export ORACLE_SID=targetdb1
/opt/app/ora11g/product/11.2.0/perl/bin/perl /exp/newxx/xttdriver.pl -c –d

在後臺執行全量恢復及轉換:

nohup sh full_restore.sh > full_restore.log &

本次恢復及轉換耗時:4 小時15分鐘。

3.增量前滾階段

3.1 表空間增量備份
源端進行增量備份:

cd /exp/newxx
--增量備份指令碼incre_backup.sh內容如下
export ORACLE_SID=sourcedb
export TMPDIR=/exp/newxx/tmp
export PERL5LIB=/opt/app/ora103/10.2.0/product/perl/lib
/opt/app/ora103/10.2.0/product/perl/bin/perl /exp/newxx/xttdriver.pl -i –d

在後臺執行增量備份:

cd /exp/newxx
nohup sh incre_backup.sh > incre_backup.log &

增量備份前確認xtt.properties檔案配置正確,增量備份耗時幾分鐘,說明bct起作用了。

--(選做)第二次做一個測試驗證表:
SQL> create table JINGYU.xttstest tablespace DBS_D_JINGYUas SELECT * FROM DBA_objects;
Select count(1) from JINGYU.xttstest;

將檔案傳輸至目標端:

cd /exp/newxx/backup_incre
scp *_1_1 ora11g@10.5.xx.xx:/exp/newxx/backup_incre
cd /exp/newxx/tmp
scp * ora11g@10.5.xx.xx:/exp/newxx/tmp

3.2 表空間增量恢復
目標端進行增量恢復:

cd /exp/newxx
--incre_recover.sh指令碼內容如下
export TMPDIR=/exp/newxx/tmp
export ORACLE_SID=targetdb1
/opt/app/ora11g/product/11.2.0/perl/bin/perl /exp/newxx/xttdriver.pl -r –d

在後臺執行增量恢復:

nohup sh incre_recover.sh > incre_recover.log &

特別說明:
1.以上增量前滾的步驟在正式遷移前可重複執行多次,用於對目標庫進行多次表空間增量恢復,使目標端資料庫在正式遷移前與生產資料庫近乎一致,大幅減少遷移停機時間。
2.每次備份(全量和增量)成功後,源端/exp/newxx/tmp目錄中會生成檔案,需要將此目錄下的所有檔案傳輸到/exp/newxx/tmp下(每次覆蓋即可)
3.每次備份(全量和增量)後,/exp/newxx/tmp目錄中會生成最新的xttplan.txt.new檔案,該檔案中記錄了各表空間最新的scn,需要將舊的xttplan.txt檔案在每次增量恢復前linux端進行如下改名操作:
cd /exp/newxx/tmp
mv xttplan.txt xttplan.old1.txt
mv xttplan.txt.new xttplan.txt

4.正式遷移階段

4.1 表空間read only
應用側停止業務後,資料庫層面複查確認沒有使用者會話連線;
源端AIX將被傳輸業務表空間修改為READ ONLY狀態:

sqlplus -S / as sysdba
set pages 0
set feedback off
spool /exp/newxx/scripts/read_only.sql
select 'alter tablespace '||name||' read only;' from v$tablespace where name in ('DBS_D_JINGYU','DBS_I_JINGYU') order by 1;
spool off
exit

cat /exp/newxx/scripts/read_only.sql 
@/exp/newxx/scripts/read_only.sql

4.2 最後一次增量操作
按照前面 增量前滾階段的方法,完成最後一次增量備份與恢復。
本次測試,最後一次增量備份時間用時 21 分鐘。

4.3 目標端開啟閃回
目標端Linux開啟在匯入後設資料前開啟閃回

SQL> alter system set db_recovery_file_dest_size=100g scope=both;
System altered.

SQL> alter system set db_recovery_file_dest='+DG_DATA' scope=both;
System altered.

SQL> alter database flashback on;
Database altered.

SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------
YES

SQL> create restore point before_imp_xtts guarantee flashback database;
Restore point created.

SQL> select name from v$restore_point;
確認有剛建立的restore point。

4.4 匯入XTTS後設資料
4.4.1 AIX源端匯出XTTS後設資料:

create directory dump as '/exp/newxx/dump';

匯出表空間、使用者後設資料:

--匯出表空間後設資料(vi expdp_xtts.sh)
expdp system/oracle parfile=expdp_xtts.par
--expdp_xtts.par內容如下:
directory=dump
dumpfile=tbs_xtts.dmp
logfile=expdp_xtts.log
transport_tablespaces=('DBS_D_JINGYU','DBS_I_JINGYU')
transport_full_check=y
metrics=yes

--匯出使用者後設資料(vi expdp_xtts_other.sh)
expdp system/oracle parfile=expdp_xtts_other.par
--expdp_xtts_other.par內容如下
directory=dump
dumpfile=tbs_xtts_other.dmp
logfile=expdp_xtts_other.log
content=metadata_only
schemas=JINGYU
metrics=yes

執行匯出表空間、使用者後設資料的指令碼:

cd /exp/newxx/dump
./expdp_xtts.sh
./expdp_xtts_other.sh

匯出完成後將dump檔案傳輸到目標端/exp/newxx/dump目錄

cd /exp/newxx/dump
scp *.dmp ora11g@10.5.108.28:/exp/newxx/dump

4.4.2 LINUX目標端匯入XTTS後設資料:
建立directory:

create or replace directory dump as '/exp/newxx/dump';

匯入XTTS後設資料:

--匯入XTTS後設資料(vi impdp_xtts.sh)
impdp system/oracle parfile=impdp_xtts.par
--impdp_xtts.par內容如下:
directory=dump
logfile=impdp_xtts.log
dumpfile=tbs_xtts.dmp
cluster=n
metrics=yes
transport_datafiles='+DG_DATA/targetdb/DATAFILE/DBS_D_JINGYU.290.976290433',
'+DG_DATA/targetdb/DATAFILE/DBS_I_JINGYU.286.976290433'

注意:上面資料檔案路徑需要根據實際匯入情況更改。

執行匯入XTTS後設資料的指令碼:

cd /exp/newxx/dump
./impdp_xtts.sh
SQL> select count(1) from JINGYU.xttstest;
正常返回結果.

執行完成後,同時驗證成功。

4.5 表空間read write
LINUX目標端表空間read write:

sqlplus -S / as sysdba
set pages 0
set feedback off
spool /exp/newxx/scripts/read_write.sql
select 'alter tablespace '||name||' read write;' from v$tablespace where name in ('DBS_D_JINGYU','DBS_I_JINGYU') order by 1;
spool off
exit 

cat /exp/newxx/scripts/read_write.sql
@/exp/newxx/scripts/read_write.sql

4.6 第二次開啟閃回
目標端Linux在其他後設資料匯入前再次開啟閃回

sqlplus / as sysdba
select flashback_on from v$database;
create restore point before_imp_other guarantee flashback database;
select name from v$restore_point;

4.7 匯入其他後設資料
匯入其他後設資料

--匯入其他後設資料(vi impdp_xtts_other.sh)
impdp system/oracle parfile=impdp_xtts_other.par 
--impdp_xtts_other.par 內容如下
directory=dump 
dumpfile=tbs_xtts_other.dmp
logfile=impdp_xtts_other.log 
content=metadata_only
schemas=JINGYU
cluster=n
metrics=yes

執行匯入其他後設資料的指令碼:

cd /exp/newxx/dump
./impdp_xtts_other.sh

4.8 檢查public dblink
原生產環境查詢public dblink,若有結果,到新生產環境建立:

--原生產環境查詢:
select * from dba_db_links;
OWNER                          DB_LINK                        USERNAME                       HOST                           CREATED
------------------------------ ------------------------------ ------------------------------ ------------------------------ -------------------
JINGYU                          XXX_TMP                        JINGYU                          xxdb                          2008-05-20 09:51:14

select dbms_metadata.get_ddl('DB_LINK',DB_LINK,'JINGYU') FROM DBA_DB_LINKS where owner='JINGYU';

CREATE DATABASE LINK "XXX_TMP"
   CONNECT TO "JINGYU" IDENTIFIED BY VALUES '056414CFC01C4F42E2E496B913FDC0212A'
   USING 'xxdb';

--連線到JINGYU使用者建立即可,開始沒有許可權:
grant create database link to JINGYU;

4.9 檢查public synonyms
原生產環境查詢public synonyms,若有結果,到新生產環境建立:

select owner,SYNONYM_NAME,TABLE_OWNER,TABLE_NAME from dba_synonyms where owner='PUBLIC' and table_owner in ('JINGYU');

本次無結果。

4.10 檢查外部表
原生產環境查詢外部表資訊,若有結果,到新生產環境建立:

SQL> select * from dba_external_tables;

本次無結果。

4.11 資料比對
源環境和目標環境分別查詢比對:

set linesize 200
set pagesize 9999
col owner format a15
col object_type format a15
select owner, object_type, count(*)
  from dba_objects
 where object_name not like 'BIN%'
   and owner in ('JINGYU')
 group by owner, object_type
 order by 1,2 desc;

OWNER           OBJECT_TYPE       COUNT(*)
--------------- --------------- ----------
JINGYU           VIEW                     2
JINGYU           TABLE PARTITION         25
JINGYU           TABLE                   49
JINGYU           SEQUENCE                 4
JINGYU           PROCEDURE                5
JINGYU           INDEX PARTITION        225
JINGYU           INDEX                   55
JINGYU           FUNCTION                 3
JINGYU           DATABASE LINK            1

9 rows selected.

4.12 編譯失效物件
查詢失效物件數量,按物件型別分組統計:

sqlplus / as sysdba
set timing on
select owner, object_type, count(*)
  from dba_objects
 where status <> 'VALID'
   and owner in ('JINGYU')
 group by owner, object_type
 order by 1, 2 desc;

OWNER           OBJECT_TYPE       COUNT(*)
--------------- --------------- ----------
JINGYU           PROCEDURE                1
JINGYU           FUNCTION                 1

--檢視具體失效物件,比對源端、目標端:
set linesize 200
set pagesize 9999
col owner format a15
col object_type format a15
col OBJECT_NAME for a32
select owner,object_name, object_type, status
  from dba_objects
 where status <> 'VALID'
   and owner in ('JINGYU') order by 2;

OWNER           OBJECT_NAME                      OBJECT_TYPE     STATUS
--------------- -------------------------------- --------------- -------
JINGYU           XXXXCITY                         FUNCTION        INVALID
JINGYU           TAB_MAINTAIN_XXX                 PROCEDURE       INVALID

編譯失效物件(若兩邊失效物件一致可不做)
exec utl_recomp.recomp_parallel(64);

4.13 更改使用者預設表空間
由於表空間比使用者晚建立,需要手動更改預設表空間:

alter user JINGYU default tablespace DBS_D_JINGYU;
select username,default_tablespace,temporary_tablespace from dba_users where username='JINGYU';

4.14 刪除閃回點

確認本次遷移成功後,手動刪除閃回點

--(選做)此時可以先刪除之前的測試表:
drop table JINGYU.xttstest;

--手動刪除閃回點:
drop restore point BEFORE_IMP_XTTS;
drop restore point before_imp_other;
select name from v$restore_point;

--關閉閃回資料庫的功能:
SQL> alter database flashback off;

Database altered.

SQL> select flashback_on from v$database;

FLASHBACK_ON
------------------
NO

SQL> alter system set db_recovery_file_dest='' sid='*' scope=both;

System altered.

4.15 修改service引數
手動修改和使用者同名的service引數:

--service_names引數保持和源端一致:
show parameter service_names
alter system set service_names ='dbaas','targetdb','jingyursv', 'jingyu' sid='*' scope=both;
alter system register;

檢查監聽註冊情況:

--本次環境使用的非預設監聽,名字是targetdb:
lsnrctl status targetdb

5.其他注意事項

收集了公司同事在其他專案實際進行XTTS遷移專案的經驗,再結合本次自己實施過程中遇到的情況,列舉了XTTS相關的其他注意事項(歡迎大家繼續補充自己做XTTS時踩過的坑和對應的經驗分享):

  • 1.使用XTTS遷移所需時間根據情況不同所花費時間也不同,每次都需要評估好停機時間;
  • 2.XTTS遷移速度主要在於後設資料的匯出匯入時間(無法使用並行),物件數越多匯入匯出越慢;
  • 3.匯入過程中檢查是否有其他使用者建在匯出使用者表空間上的索引,此種索引無法在自包含檢查中檢測出來,所以應在全量備份前進行檢查。提前處理此種物件,我這次沒有遇到:
  /*查詢表空間中物件的詳細資訊*/
  SELECT OWNER                  AS OWNER
       ,SEGMENT_NAME           AS SEGMENT_NAME
       ,SEGMENT_TYPE           AS SEGMENT_TYPE
     ,SUM(BYTES)/1024/1024   AS SEGMENT_SIZE
  FROM DBA_SEGMENTS
  WHERE TABLESPACE_NAME in ('DBS_D_JINGYU','DBS_I_JINGYU') and owner <> 'JINGYU'
  GROUP BY OWNER,SEGMENT_NAME,SEGMENT_TYPE
  ORDER BY 4;
  • 4.使用XTTS遷移資料庫必須每套資料庫都進行測試,並生成細緻操作文件(由於每個資料庫每個使用者物件之間的關聯關係不同,再倒入後設資料的時候相互依賴關係可能比較難梳理。必須提前做測試進行梳理);
  • 5.XTTS目標段必須有11.2.0.4的軟體進行資料檔案轉換,源端最低為10G資料庫;
  • 6.XTTS在目標段做全量以及增量恢復時,會重啟執行恢復指令碼的例項(如果目標端資料庫還有其他業務使用者屬於生產執行,尤其要注意這點);
  • 7.本次測試遇到因源庫資料檔名稱包含特殊字元導致表空間全量備份缺失檔案且日誌不報任何錯誤,在恢復階段才發現缺少檔案,所以建議以後準備工作多加一項資料檔案數量的檢查比對:
  select count(1) from dba_data_files where tablespace_name in ('DBS_D_JINGYU','DBS_I_JINGYU');
  --本次遷移資料檔案數量135,與表空間全量備份出來的檔案數量進行對比確認一致。

關於第7項,我實際遇到並在測試環境進行了重現,具體可參考之前的隨筆:

相關文章