可傳輸資料表空間,傳輸資料表空間

來源:互聯網
上載者:User

可傳輸資料表空間,傳輸資料表空間
oracle2271

對於可傳輸資料表空間有一個重要概念:自包含(Self-Contained)。
在資料表空間傳輸的中,要求資料表空間集為自包含的,自包含表示用於傳輸的內部資料表空間集沒有引用指向外部表格空間集。自包含分為兩種:一般自包含資料表空間集和完全(嚴格)自包含資料表空間集。
常見的以下情況是違反自包含原則的:
 索引在內部資料表空間集,而表在外部表格空間集(相反地,如果表在內部資料表空間集,而索引在外部表格空間集,則不違反自包含原則)。
 分區表一部分區在內部資料表空間集,一部分在外部表格空間集(對於分區表,要麼全部包含在內部資料表空間集中,要麼全不包含)。
 如果在傳輸資料表空間時同時傳輸約束,則對於參考完整性約束,約束指向的表在外部表格空間集,則違反自包含約束;如果不傳輸約束,則與約束指向無關。
 表在內部資料表空間集,而lob列在外部表格空間集,則違反自包含約束。
通常可以通過系統包DBMS_TTS來檢查資料表空間是否自包含,驗證可以以兩種方式執行:非嚴格方式和嚴格方式。
以下是一個簡單的驗證過程,假定在eygle資料表空間存在一個表eygle,其上存在索引儲存在USERS資料表空間:

SQL> create table eygle as select rownum id ,username from dba_users;
Table created.

SQL> create index ind_id on eygle(id) tablespace users;
Index created.

以SYS使用者執行非嚴格自包含檢查(full_check=false):

SQL> connect / as sysdba
Connected.
SQL> exec dbms_tts.transport_set_check('EYGLE', TRUE);
PL/SQL procedure successfully completed.

SQL> SELECT * FROM TRANSPORT_SET_VIOLATIONS;
no rows selected

執行嚴格自包含檢查(full_check=true):

SQL> exec dbms_tts.transport_set_check('EYGLE', TRUE, True);
PL/SQL procedure successfully completed.

SQL> SELECT * FROM TRANSPORT_SET_VIOLATIONS;
VIOLATIONS
--------------------------------------------------------------------------------------
Index EYGLE.IND_ID in tablespace USERS points to table EYGLE.EYGLE in tablespace EYGLE

反過來對於USERS資料表空間來說,非嚴格檢查也是無法通過的:

SQL> exec dbms_tts.transport_set_check('USERS', TRUE);
PL/SQL procedure successfully completed.

SQL> SELECT * FROM TRANSPORT_SET_VIOLATIONS;
VIOLATIONS
----------------------------------------------------------------------------------------
Index EYGLE.IND_ID in tablespace USERS points to table EYGLE.EYGLE in tablespace EYGLE

但是可以對多個資料表空間同時傳輸,則一些自包含問題就可以得到解決:

SQL> exec dbms_tts.transport_set_check('USERS,EYGLE', TRUE, True);
PL/SQL procedure successfully completed.

SQL> SELECT * FROM TRANSPORT_SET_VIOLATIONS;
no rows selected


官方解釋如下:

There may be logical or physical dependencies between objects in the transportable set and those outside of the set. You can only transport a set of tablespaces that is self-contained. In this context "self-contained" means that there are no references from inside the set of tablespaces pointing outside of the tablespaces. Some examples of self contained tablespace violations are:

  • An index inside the set of tablespaces is for a table outside of the set of tablespaces.

    Note:

    It is not a violation if a corresponding index for a table is outside of the set of tablespaces.
  • A partitioned table is partially contained in the set of tablespaces.

    The tablespace set you want to copy must contain either all partitions of a partitioned table, or none of the partitions of a partitioned table. If you want to transport a subset of a partition table, you must exchange the partitions into tables.

  • A referential integrity constraint points to a table across a set boundary.

    When transporting a set of tablespaces, you can choose to include referential integrity constraints. However, doing so can affect whether or not a set of tablespaces is self-contained. If you decide not to transport constraints, then the constraints are not considered as pointers.

  • A table inside the set of tablespaces contains a LOB column that points to LOBs outside the set of tablespaces.

  • An XML DB schema (*.xsd) that was registered by user A imports a global schema that was registered by user B, and the following is true: the default tablespace for user A is tablespace A, the default tablespace for user B is tablespace B, and only tablespace A is included in the set of tablespaces.

To determine whether a set of tablespaces is self-contained, you can invoke the TRANSPORT_SET_CHECK procedure in the Oracle supplied package DBMS_TTS. You must have been granted the EXECUTE_CATALOG_ROLE role (initially signed to SYS) to execute this procedure.

When you invoke the DBMS_TTS package, you specify the list of tablespaces in the transportable set to be checked for self containment. You can optionally specify if constraints must be included. For strict or full containment, you must additionally set the TTS_FULL_CHECK parameter to TRUE.

The strict or full containment check is for cases that require capturing not only references going outside the transportable set, but also those coming into the set. Tablespace Point-in-Time Recovery (TSPITR) is one such case where dependent objects must be fully contained or fully outside the transportable set.

For example, it is a violation to perform. TSPITR on a tablespace containing a table t but not its index i because the index and data will be inconsistent after the transport. A full containment check ensures that there are no dependencies going outside or coming into the transportable set. See the example for TSPITR in the Oracle Database Backup and Recovery User's Guide.

incl_constraints

TRUE if you want to count in referential integrity constraints when examining if the set of tablespaces is self-contained. (Theincl_constraints parameter is a default so that TRANSPORT_SET_CHECK will work if it is called with only the ts_list argument.)

full_check

Indicates whether a full or partial dependency check is required. If TRUE, treats all IN and OUT pointers (dependencies) and captures them as violations if they are not self-contained in the transportable set. The parameter should be set to TRUE for TSPITR or if a strict version of transportable is desired. By default the parameter is set to false. It will only consider OUT pointers as violations.



1.3.5可傳輸資料表空間

在很多Oracle文檔中,可能大家都注意過Oracle用來進行測試的一個資料表空間,這個資料表空間中有一系列預置的使用者和資料,可以用於資料庫或BI的很多測試實驗。
這個資料表空間在使用模板建庫時是可以選擇的,在1-22所示的這個介面中,可以選擇建庫時包含這個範例資料表空間(預設是未選擇的)。

如果選擇了包含樣本方案,則cloneDBCreation.sql指令碼將會有所改變,主要增加了如下語句:

connect "SYS"/"&&sysPassword" as SYSDBA
@C:\oracle\10.2.0\demo\schema\mkplug.sql &&sysPassword change_on_install change_on_install 
change_on_install change_on_install change_on_install change_on_install C:\oracle\10.2.0\assistants\dbca\templates\example.dmp C:\oracle\10.2.0\assistants\dbca\templates\example01.dfb C:\oracle\oradata\eygle\example01.dbf C:\oracle\admin\eygle\scripts\ "'SYS/&&sysPassword as SYSDBA'";

看到這裡,再次引用了模板目錄中的檔案:

C:\>dir C:\oracle\10.2.0\assistants\dbca\templates\ex*
磁碟機 C 中的卷是 SYSTEM
卷的序號是 8C88-D1B4

C:\oracle\10.2.0\assistants\dbca\templates 的目錄

2005-09-07 13:02 983,040 example.dmp
2005-09-07 13:02 20,897,792 example01.dfb
2 個檔案 21,880,832 位元組
0 個目錄 915,578,880 可用位元組

通過mkplug.sql指令碼來載入這個範例資料表空間,來看一下這個指令碼的主要內容。
同樣,最重要的是通過dbms_backup_restore包從example01.dfb檔案中恢複資料檔案:


SELECT TO_CHAR(systimestamp, 'YYYYMMDD HH:MI:SS')  FROM dual;
variable new_datafile varchar2(512)
declare
  done boolean;
  v_db_create_file_dest VARCHAR2(512);
  devicename varchar2(255);
  data_file_id number;
  rec_id number;
  stamp number;
  resetlogs_change number;
  creation_change number;
  checkpoint_change number;
  blksize number; 
  omfname varchar2(512);
  real_file_name varchar2(512);


  begin
    dbms_output.put_line(' ');
    dbms_output.put_line(' Allocating device.... ');
    dbms_output.put_line(' Specifying datafiles... ');
       devicename := dbms_backup_restore.deviceAllocate;
    dbms_output.put_line(' Specifing datafiles... ');
    SELECT MAX(file_id)+1 INTO data_file_id FROM dba_data_files;
    SELECT value INTO v_db_create_file_dest FROM v$parameter WHERE name ='db_create_file_dest';
    IF v_db_create_file_dest IS NOT NULL
     THEN
      dbms_backup_restore.restoreSetDataFile;
      dbms_backup_restore.getOMFFileName('EXAMPLE',omfname);
      dbms_backup_restore.restoreDataFileTo(data_file_id, omfname, 0,'EXAMPLE');
     ELSE
      dbms_backup_restore.restoreSetDataFile; 
      dbms_backup_restore.restoreDataFileTo(data_file_id,'&data_file_name');
     END IF;
    dbms_output.put_line(' Restoring ... ');
    dbms_backup_restore.restoreBackupPiece('&data_file_backup', done);
    SELECT max(recid) INTO rec_id FROM v$datafile_copy;


    -- Now get the real file name. It could be also OMF filename
    SELECT name, stamp, resetlogs_change#, creation_change#, checkpoint_change#,block_size
    INTO real_file_name, stamp,resetlogs_change, creation_change, checkpoint_change, blksize
    FROM V$DATAFILE_COPY
     WHERE recid = rec_id and file# = data_file_id;
    
    -- Uncatalog the file from V$DATAFILE_COPY. This important.
    dbms_backup_restore.deleteDataFileCopy(recid => rec_id, 
                                           stamp => stamp, 
                                           fname => real_file_name,
                                           dfnumber => data_file_id, 
                                           resetlogs_change => resetlogs_change, 
                                           creation_change => creation_change, 
                                           checkpoint_change => checkpoint_change, 
                                           blksize => blksize,
                                           no_delete => 1, 
                                           force => 1);
    -- Set the bindvariable to the real filename                                       
    :new_datafile := real_file_name;
    
    if done then
        dbms_output.put_line(' Restore done.');
    else
        dbms_output.put_line(' ORA-XXXX: Restore failed ');
    end if;
  end;
/

這個恢複完成之後,接下來最重要的部分就是通過傳輸資料表空間技術將example資料表空間匯入到當前的資料庫。
考慮一下這種情況,當進行跨資料庫遷移時,需要將一個使用者資料表空間中的資料移轉到另外一個資料庫,應該使用什麼樣的方法呢?最常規的做法可能是通過EXP工具將資料全部匯出,然後在目標資料庫上IMP匯入,可是這種方法可能會比較緩慢。EXP工具同時還提供另外一種技術-可傳輸資料表空間技術,可以用於加快這個過程。
在exp -help的協助中,可以看到這樣一個參數:
TRANSPORT_TABLESPACE 匯出可傳輸的資料表空間中繼資料 (N)

通過這個選項,我們可以對一組自包含、唯讀資料表空間只匯出中繼資料,然後在作業系統層將這些資料表空間的資料檔案拷貝至目標平台,並將中繼資料匯入資料字典(這個過程稱為插入,plugging),即完成遷移。
對於可傳輸資料表空間有一個重要概念:自包含(Self-Contained)。
在資料表空間傳輸的中,要求資料表空間集為自包含的,自包含表示用於傳輸的內部資料表空間集沒有引用指向外部表格空間集。自包含分為兩種:一般自包含資料表空間集和完全(嚴格)自包含資料表空間集。
常見的以下情況是違反自包含原則的:
 索引在內部資料表空間集,而表在外部表格空間集(相反地,如果表在內部資料表空間集,而索引在外部表格空間集,則不違反自包含原則)。
 分區表一部分區在內部資料表空間集,一部分在外部表格空間集(對於分區表,要麼全部包含在內部資料表空間集中,要麼全不包含)。
 如果在傳輸資料表空間時同時傳輸約束,則對於參考完整性約束,約束指向的表在外部表格空間集,則違反自包含約束;如果不傳輸約束,則與約束指向無關。
 表在內部資料表空間集,而lob列在外部表格空間集,則違反自包含約束。
通常可以通過系統包DBMS_TTS來檢查資料表空間是否自包含,驗證可以以兩種方式執行:非嚴格方式和嚴格方式。
以下是一個簡單的驗證過程,假定在eygle資料表空間存在一個表eygle,其上存在索引儲存在USERS資料表空間:

SQL> create table eygle as select rownum id ,username from dba_users;
Table created.

SQL> create index ind_id on eygle(id) tablespace users;
Index created.

以SYS使用者執行非嚴格自包含檢查(full_check=false):

SQL> connect / as sysdba
Connected.
SQL> exec dbms_tts.transport_set_check('EYGLE', TRUE);
PL/SQL procedure successfully completed.

SQL> SELECT * FROM TRANSPORT_SET_VIOLATIONS;
no rows selected

執行嚴格自包含檢查(full_check=true):

SQL> exec dbms_tts.transport_set_check('EYGLE', TRUE, True);
PL/SQL procedure successfully completed.

SQL> SELECT * FROM TRANSPORT_SET_VIOLATIONS;
VIOLATIONS
--------------------------------------------------------------------------------------
Index EYGLE.IND_ID in tablespace USERS points to table EYGLE.EYGLE in tablespace EYGLE

反過來對於USERS資料表空間來說,非嚴格檢查也是無法通過的:

SQL> exec dbms_tts.transport_set_check('USERS', TRUE);
PL/SQL procedure successfully completed.

SQL> SELECT * FROM TRANSPORT_SET_VIOLATIONS;
VIOLATIONS
----------------------------------------------------------------------------------------
Index EYGLE.IND_ID in tablespace USERS points to table EYGLE.EYGLE in tablespace EYGLE

但是可以對多個資料表空間同時傳輸,則一些自包含問題就可以得到解決:

SQL> exec dbms_tts.transport_set_check('USERS,EYGLE', TRUE, True);
PL/SQL procedure successfully completed.

SQL> SELECT * FROM TRANSPORT_SET_VIOLATIONS;
no rows selected

資料表空間自包含確認之後,進行資料表空間傳輸就很方便了,一般包含如下幾個步驟。
(1) 將資料表空間設定為唯讀:
alter tablespace users read only;
(2) 匯出資料表空間。在作業系統提示符下執行:
exp username/passwd tablespaces=users transport_tablespace=y file=exp_users.dmp
此處的匯出檔案只包含中繼資料,所以匯出檔案很小,匯出速度也會很快。
(3) 轉移。將匯出的中繼資料檔案(此處是exp_users.dmp)和傳輸資料表空間的資料檔案(此處是users資料表空間的資料檔案user01.dbf)轉移至目標主機(轉移過程如果使用FTP方式,應該注意使用二進位方式)。
(4) 傳輸。在目標資料庫將資料表空間插入到資料庫中,完成資料表空間傳輸。在作業系統命令提示字元下執行下面的語句:
imp username/passwd tablespaces=users transport_tablespace=y file=exp_users.dmp datafiles='users01.dbf'

瞭解了Oracle的可傳輸資料表空間技術後,來看一下example資料表空間的插入,以下指令碼仍然來自mkplug.sql指令碼:

--
-- Importing the metadata and plugging in the tablespace at the same
-- time, using the restored database file 
--
DEFINE imp_logfile = &log_path.tts_example_imp.log

-- When importing use filename got after restore is finished
host imp "'sys/&&password_sys AS SYSDBA'" transport_tablespace=y file=&imp_file log=&imp_logfile datafiles='&datafile' tablespaces=EXAMPLE tts_owners=hr,oe,pm,ix,sh


完成plugging之後,這個資料表空間就被包含在了建立的資料庫之中。

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.