Oracle表空間傳輸詳解

OraFige發表於2011-12-15

可傳輸表空間概述

Oracle 的可傳輸表空間特性通過將 後設資料和資料檔案 簡單地從一個資料庫移動到另一個資料庫,提供在資料庫之間有效移動大資料的一種簡易方法。代替重新建立物件,可移植表空間可以讓毫不費力地移動大物件,而所花費的時間是你手動建立這些物件的時間。可移植表空間包括將屬於源資料庫的所有資料檔案拷貝到目標資料庫,並將關於表空間資料目錄資訊從源資料庫拷貝到目標資料庫。因此,資料泵取匯出和匯入實用程式是可移表空間特性的一部分。還可以傳送屬於表的索引表空間,使整個資料移植非常地快。

可移植表空間的應用場景 :
把資料從源資料庫移動到資料倉儲
把資料從升級資料庫移動到資料集市
把資料從資料倉儲移動到資料集市
執行表空間時間點恢復 (PITR)
歸檔歷史資料

然而,在 Oracle9i 資料庫和更低版本中,可傳輸表空間僅限於在目標資料庫和源資料庫都執行在同一作業系統平臺上的少數情況下才有用 — 例如,您不能在 Solaris 和 HP-UX 平臺之間傳輸表空間。
在Oracle 資料庫 10g 中,這個侷限消失了。

位元組順序和平臺
資料檔案所以不能跨平臺,主要是由於不同平臺的位元組順序不同,這是計算機領域由來已久的問題之一,在各種計算機體系結構中,由於對於字、位元組等的儲存機制有所不同,通訊雙方交流的資訊單元(位元、位元組、字、雙字等)應該以什麼樣的順序進行傳送就成了一個問題,如果不達成一致的規則,通訊雙方將無法進行正確的編/譯碼從而導致通訊失敗。
目前在各種體系的計算機中通常採用的位元組儲存機制主要有兩種:Big-Endian和Little-Endian 。
一些作業系統(包括Windows)在低位記憶體地址中存放二進位制資料的最低有效位元組,因此這種系統被稱為Little Endian;一些作業系統(包括Solaris)將最高有效位元組儲存在低位記憶體地址中,因此這種系統被稱為Big Endian。
舉一個簡單點的例子,假如1122這樣一個資料要存入不同系統,對於Little Endian的系統,儲存的順序就是2211,小頭在前;而對於Big Endian的系統來說,儲存順序就是1122,大頭在前,顯然Big Endian更符合我們通常的語言習慣。
那麼跨平臺的問題就出現了,當一個Little Endian的系統試圖從一個Big Endian的系統中讀取資料時,就需要通過轉換,否則不同的位元組順序將導致資料不能被正確讀取。

資料庫所處平臺的位元組序可通過如下查詢得到

SQL>select * from v$transportable_platform

PLATFORM_ID PLATFORM_NAME                          ENDIAN_FORMAT
----------- -------------------------------------- --------------
          1 Solaris[tm] OE (32-bit)                Big
          2 Solaris[tm] OE (64-bit)                Big
          7 Microsoft Windows IA (32-bit)          Little
         10 Linux IA (32-bit)                      Little
          6 AIX-Based Systems (64-bit)             Big
          3 HP-UX (64-bit)                         Big
          5 HP Tru64 UNIX                          Little
          4 HP-UX IA (64-bit)                      Big
         11 Linux IA (64-bit)                      Little
         15 HP Open VMS                            Little
          8 Microsoft Windows IA (64-bit)          Little

PLATFORM_ID PLATFORM_NAME                          ENDIAN_FORMAT
----------- -------------------------------------- --------------
          9 IBM zSeries Based Linux                Big
         13 Linux 64-bit for AMD                   Little
         16 Apple Mac OS                           Big
         12 Microsoft Windows 64-bit for AMD       Little
         17 Solaris Operating System (x86)         Little
         18 IBM Power Based Linux                  Big
傳輸表空間

傳輸表空間的簡要操作步驟

1) 確定平臺的 Endian 格式
2) 確保表空間為自包含並使其只讀
3) 用 exp、expdp等實用程式匯出後設資料
4) 轉換資料檔案以匹配 Endian 格式 ( 若一致可跳過)

5) 拷貝檔案到目標系統
6) 使用 imp匯入實用程式匯入後設資料

1、確定平臺的 Endian 格式

源平臺

SQL> col PLATFORM_NAME for a30
SQL> SELECT d.platform_name, endian_format FROM v$transportable_platform. tp, v$database d WHERE tp.platform_name = d.platform_name;

PLATFORM_NAME                  ENDIAN_FORMAT
------------------------------ --------------
Linux IA (32-bit)              Little


目標平臺:

SQL> col platform_name for a40
SQL> SELECT d.platform_name, endian_format FROM v$transportable_platform. tp, v$database d WHERE tp.platform_name = d.platform_name;

PLATFORM_NAME                  ENDIAN_FORMAT
------------------------------ --------------
Linux IA (32-bit)              Little
這裡平臺之間的位元組序一致,不需要轉換。

2、確保表空間為自包含並使其只讀

自包含表示用於傳輸的內部表空間集沒有任何物件引用指向外部表空間集。自包含分為兩種:一般自包含表空間集和完全(嚴格)自包含表空間集。
下面是一些典型的違反自包含的例子:
索引在待傳輸表空間集中而表卻不在,即索引在內部表空間集,而表在外部表空間集。(注意,如果表在待傳輸表空間集中,而索引不在並不違反自包含原則,即表在內部表空間集,而索引在外部表空間集,不違反自包含。當然如果你堅持這樣傳輸的話,會造成目標庫中該表索引丟失)。
分割槽表中只有部分分割槽在待傳輸表空間集(對於分割槽表,要麼全部包含在待傳輸表空間集中,要麼全不包含,解決:需要進行分割槽交換,完全包含在內部表空間集中)。
待傳輸表空間中,對於引用完整性約束,如果約束指向的表不在待傳輸表空間集,則違反自包含約束;但如果不傳輸該約束,則與約束指向無關。

對於包含LOB列的表,如果表在待傳輸表空間集中,而Lob列不在,也是違反自包含原則的。
自包含還有嚴格(strict)或完全(full)self_contained.這時:
set the TTS_FULL_CHECK parameter to TRUE,物件及其依賴物件完全在內部表空間集
而非嚴格自包含,表在內部表空間集,依賴於表的物件在外部白空間集不違反,但只是依賴於表的物件在內部表空間集,而表在外部表空間集就違反了。

我們可以通過使用dbms_tts包裡的儲存過程transport_set_check,檢查要傳輸的表空間是否是自包含。具體定義如下

PROCEDURE TRANSPORT_SET_CHECK
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 TS_LIST                        CLOB                    IN
 INCL_CONSTRAINTS               BOOLEAN                 IN     DEFAULT
 FULL_CHECK                     BOOLEAN                 IN     DEFAULT

TS_LIST表示要傳輸的表空間名稱列表,不同的表空間名稱之間以逗號隔開

INCL_CONSTRAINTS表示要檢查的子表外建(true表示是,false表示否。預設為false),也就是說,如果在要傳輸的表空間裡的某個子表上存在外建,且該外建所指向的父表在其他表空間內,則INCL_CONSTRAINTS為true,表明違反了自包含。否則為false,表明沒有違反自包含。

FULL_CHECK表示是否要檢查表的索引(true表示是,false表示否。預設為false),也就是說,如果在要傳輸的表空間裡的某個表的索引位於其他表空間內,FULL_CHECK則為true,表明違反了自包含。否則為false,表明沒有違反自包含。檢查後的結果在transport_set_violations檢視中體現。

下面做一個簡單測試

外建約束測試

SQL> create table t tablespace users
  2  as
  3  select object_id,object_name from user_objects;
Table created.

SQL> create table t_child tablespace example
  2  as
  3  select object_id,object_name from user_objects
  4  where 1=2;
Table created.


SQL> alter table t add primary key(object_id);
Table altered.


SQL> alter table t_child add foreign key(object_id)
  2  references
  3* t(object_id)


進行外來鍵檢查

SQL> execute dbms_tts.transport_set_check('example',incl_constraints=>true);
PL/SQL procedure successfully completed.

SQL> select * from transport_set_violations;
VIOLATIONS
--------------------------------------------------------------------------------
Constraint SYS_C005435 between table HR.T in tablespace USERS and table HR.T_CHI
LD in tablespace EXAMPLE


SQL> execute dbms_tts.transport_set_check('users',incl_constraints=>true);
PL/SQL procedure successfully completed.

SQL> select * from transport_set_violations;
no rows selected

將users和example表空間一起進行檢查

SQL> execute dbms_tts.transport_set_check('users,example',incl_constraints=>true);
PL/SQL procedure successfully completed.

SQL> select * from transport_set_violations;
no rows selected

進行FULL_CHECK測試

SQL> create index t_index on t_child(object_id) tablespace indx;
Index created.

SQL> execute dbms_tts.transport_set_check('example',full_check=>true);
PL/SQL procedure successfully completed.

SQL> select * from transport_set_violations;

VIOLATIONS
--------------------------------------------------------------------------------
Index HR.T_INDEX in tablespace INDX points to table HR.T_CHILD in tablespace EXA
MPLE

SQL> execute dbms_tts.transport_set_check('example,indx',full_check=>true);
PL/SQL procedure successfully completed.

SQL> select * from transport_set_violations;
no rows selected

將索引和外來鍵同時檢查。
SQL> execute dbms_tts.transport_set_check('users,example,indx',true,true);
PL/SQL procedure successfully completed.

SQL> select * from transport_set_violations;
no rows selected

現在將users,example,indx表空間置為只讀

SQL> alter tablespace users read only;
Tablespace altered.

SQL> alter tablespace example read only;
Tablespace altered.

SQL> alter tablespace indx read only;
Tablespace altered.


3、用 exp、expdp等實用程式匯出後設資料

$ exp \'/ as sysdba \' file=usr_exp_idx.tbs.dmp transport_tablespace=y tablespace=users,example,indx
LRM-00101: unknown parameter name 'tablespace'

EXP-00019: failed to process parameters, type 'EXP HELP=Y' for help
EXP-00000: Export terminated unsuccessfully
[oracle@dg1 ~]$ exp \'/ as sysdba \' file=usr_exp_idx.tbs.dmp transport_tablespace=y tablespaces=users,example,indx
Export: Release 10.2.0.1.0 - Production on Thu Nov 17 10:43:09 2011
Copyright (c) 1982, 2005, Oracle.  All rights reserved.

Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
Export done in US7ASCII character set and AL16UTF16 NCHAR character set
server uses WE8ISO8859P1 character set (possible charset conversion)
Note: table data (rows) will not be exported
About to export transportable tablespace metadata...
...........................................................................................................

. end transportable tablespace metadata export
Export terminated successfully without warnings.

4、轉換資料檔案以匹配 Endian 格式 ( 若一致可跳過)

這裡筆者的平臺位元組序是一致的不需要轉換,如需轉換則可以使用如下命令

$ rman target /

RMAN> convert tablespace trans
2> to platform. 'Microsoft Windows IA (32-bit)'
3> format '/tmp/%N_%f';

5、拷貝檔案到目標系統

$ scp /u01/app/oracle/oradata/czmmiao/indx01.dbf /u01/app/oracle/oradata/czmmiao/example.dbf /u01/app/oracle/oradata/czmmiao/users01.dbf usr_exp_idx.tbs.dmp 192.168.0.102:/home/oracle/
oracle@192.168.0.102's password:
indx01.dbf                                    100%   10MB   5.0MB/s   00:02   
example.dbf                                   100%  100MB   4.4MB/s   00:23   
users01.dbf                                   100% 5128KB   5.0MB/s   00:01   
usr_exp_idx.tbs.dmp                           100% 1072KB   1.1MB/s   00:01

6、使用 imp匯入實用程式匯入後設資料

在匯入之前我們需要確認目標資料庫具有我們想匯入的表空間內的物件的屬主。

源資料庫的物件屬主

SQL> select distinct owner from dba_segments where tablespace_name in ('EXAMPLE','USERS','INDX');
OWNER
------------------------------
HR
SCOTT
OE
PM
SH
IX
SYS
TRANS

如果在目標平臺沒有存在該使用者就會報如下錯誤。

IMP-00003: ORACLE error 29342 encountered
ORA-29342: user HR does not exist in the database
ORA-06512: at "SYS.DBMS_PLUGTS", line 1895
ORA-06512: at line 1
IMP-00000: Import terminated unsuccessfully

注意,如果在目標平臺已經存在相應的表空間也無法成功匯入,報錯如下

IMP-00003: ORACLE error 29349 encountered
ORA-29349: tablespace 'USERS' already exists
ORA-06512: at "SYS.DBMS_PLUGTS", line 1801
ORA-06512: at line 1
IMP-00000: Import terminated unsuccessfully

執行匯入命令

$ imp \'/ as sysdba \' file=usr_exp_idx.tbs.dmp transport_tablespace=y tablespaces=example,users,indx datafiles=/home/oracle/users01.dbf,/home/oracle/example.dbf,/home/oracle/indx01.dbf

注意表空間名要與源資料庫一致

將這3個表空間設為可讀寫

SQL> alter tablespace example read write;
Tablespace altered.

SQL>  alter tablespace indx read write;
Tablespace altered.


SQL> alter tablespace users read write;
Tablespace altered.

至此,匯入成功。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26464953/viewspace-713406/,如需轉載,請註明出處,否則將追究法律責任。

相關文章