12c 可插拔數據庫的幾種克隆遷移方法

原文鏈接:https://blog.csdn.net/cuiruipan6325/article/details/100510330

Oacle 多租戶環境包含一個容器數據庫(CDB)和零個或多個可插拔數據庫(PDB),這種讓數據庫系統擴展也變得非常的靈活,oracle 12c提供了許多種關於多租戶模式下數據庫的克隆遷移方式,以下對於幾種克隆遷移的方式進行實驗介紹。

一.通過現有PDB直接創建(CREATE PLUGGABLE DATABASE..FROM..)

1. 從本地PDB創建

(1)克隆完整PDB

創建語句:

CREATE PLUGGABLE DATABASE pdb3 FROM pdb2

    PATH_PREFIX = ' /u01/app/oracle/oradata/ ' --- 指定pdb相關聯的目錄,可以不設置

    FILE_NAME_CON VERT = (' /u01/app/oracle/oradata/orclcwd/pdb2/',   '/u01/app/oracle/oradata/orclcwd/pdb3/' ) - 數據文件存放路徑,在ASM中可以指定DG

SERVICE_NAME_CONVERT = ('pdb2','pdb3') – 服務名轉換

    NOLOGGING;

SQL> SQL>   CREATE PLUGGABLE DATABASE pdb3 FROM pdb2

  2      PATH_PREFIX = '/u01/app/oracle/oradata/'

  3      FILE_NAME_CONVERT =   ('/u01/app/oracle/product/12.1.0/dbhome_1/dbs/u01/app/oracle/oradata/orclcwd/',   '/u01/app/oracle/oradata/orclcwd/pdb3/')

  4    SERVICE_NAME_CONVERT = ('pdb2','pdb3');

Pluggable database   created.

 

主要的選項說明:

PATH_PREFIX :將 PDB 的相 對 目 錄對 象路徑 設置爲 特定目 錄 。 因此,需要 設 置 PATH_PREFIX

FILE_NAME_CONVERT :指定數據文件的轉換路徑

Storage: 如果需要限制新建pdb的大小,可以使用storage=xxG 來限制。

創建的過程日誌:

CREATE PLUGGABLE DATABASE pdb3 FROM pdb2

    PATH_PREFIX = '/u01/app/oracle/oradata/'

    FILE_NAME_CONVERT =   ('/u01/app/oracle/product/12.1.0/dbhome_1/dbs/u01/app/oracle/oradata/orclcwd/',   '/u01/app/oracle/oradata/orclcwd/pdb3/')

SERVICE_NAME_CONVERT = ('pdb2','pdb3') <<<<<<<<<< 創建命令開始

Fri Aug 18 14:22:11 2017

Opatch XML is skipped for PDB PDB2 (conid=3) <<<<< 跳過PDB2(源)Opatch   XML,看起來與版本檢查有關

 APEX_040200.WWV_FLOW_ADVISOR_CHECKS   (CHECK_STATEMENT) - CLOB populated

Fri Aug 18 14:24:15 2017 <<<< 開始創建新的PDB3,但此時的狀態先爲UNUSABLE

****************************************************************

Pluggable Database PDB3 with pdb id - 4 is   created as UNUSABLE.

If any errors are encountered before the pdb   is marked as NEW,

then the pdb must be dropped

****************************************************************

Database Characterset for PDB3 is ZHS16GBK <<< 字符集檢查

Fri Aug 18 14:24:26 2017 <<<<<<<< 刪除換舊的數據文件並生成新的數據文件

Deleting old file#8 from file$

Deleting old file#9 from file$

Adding new file#11 to file$(old file#8)

Adding new file#12 to file$(old file#9)

Successfully created internal service pdb3 at   open <<<<<< 創建服務成功

ALTER SYSTEM: Flushing buffer cache inst=0   container=4 local <<<<< 刷新新PDB的buffer

****************************************************************

Post plug operations are now complete.  <<<<< 插入PDB操作

Pluggable database PDB3 with pdb id - 4 is   now marked as NEW. <<<<PDB 狀態定位NEW

****************************************************************

Completed: CREATE PLUGGABLE DATABASE pdb3   FROM pdb2 <<<< 完成

    PATH_PREFIX = '/u01/app/oracle/oradata/'

    FILE_NAME_CONVERT =   ('/u01/app/oracle/product/12.1.0/dbhome_1/dbs/u01/app/oracle/oradata/orclcwd/',   '/u01/app/oracle/oradata/orclcwd/pdb3/')

SERVICE_NAME_CONVERT = ('pdb2','pdb3')

 

 

(2) 僅克隆PDB元數據

有時並不需要克隆表裏的數據,可使用NO DATA來克隆一個PDB,但僅僅克隆元數據。

以下示例:

1) 源PDB中表存在多行數據,這裏特意選擇了三種情況,看看是否NO DATA的機制如何:

A.   SYS 用戶的表,表空間在SYSTEM

B.   個人用戶的表,表空間在SYSTEM

C.   個人用戶的表,表空間在普通表空間

 

 

2 )將源PDB打開到read only模式下:

ALTER PLUGGABLE DATABASE pdb1 OPEN READ ONLY;

 

3 )克隆PDB:

CREATE PLUGGABLE DATABASE pdb4 FROM pdb3 NO DATA  FILE_NAME_CONVERT = ('/u01/app/oracle/oradata/orclcwd/pdb3/', '/u01/app/oracle/oradata/orclcwd/pdb4/');

SQL> SQL> CREATE PLUGGABLE DATABASE   pdb4 FROM pdb3 NO DATA;

CREATE PLUGGABLE DATABASE pdb4 FROM pdb3 NO   DATA

                                               *

ERROR at line 1:

ORA-65016: FILE_NAME_CONVERT must be   specified

SQL>    CREATE PLUGGABLE DATABASE pdb4 FROM pdb3 NO DATA

    2    FILE_NAME_CONVERT =   ('/u01/app/oracle/oradata/orclcwd/pdb3/',   '/u01/app/oracle/oradata/orclcwd/pdb4/');

 

Pluggable database created.

4 )打開新克隆的PDB:

ALTER PLUGGABLE DATABASE pdb4 OPEN;

 

5 )到新的PDB下查詢表數據:

 

從查詢結果來看,使 用NO DATA的方式克隆PDB時,SYSTEM表空間下的表數據是會克隆過去,但用戶表空間下表數據庫就僅克隆了元數據。

  

2. 從遠程PDB或non-CDB創建

  通過遠程方式創建克隆主要依靠的是dblink,因此需要源庫和目標庫之間網絡保持暢通,而遠處創建的方式和本地創建相差不大,遠程模式可以增加從一個NON-CDB數據庫克隆到CDB中。

(1) 從PDB創建

)查看目標CDB當前情況:

 

)在目標CDB創建連接遠程CDB的dblink:

SQL> create   public database link cdb1 connect to system identified by "111111"   using 'cdb1';

Database link   created.

 

)使用dblink遠程創建

SQL>  CREATE PLUGGABLE DATABASE pdb5 FROM   pdb4@cdb1                                                            

  2      FILE_NAME_CONVERT = ('/u01/app/oracle/oradata/orclcwd/pdb4/',   '/u01/app/oracle/oradata/orclcwd/pdb5/');

 

Pluggable   database created.

)完成創建:

 

  

(2)從NOCDB創建

)在目標CDB創建連接遠程非CDB的dblink:

SQL> create   public database link nocdb1 connect to system identified by   "111111" using 'nocdb1';

Database link   created.

 

)使用dblink遠程創建

SQL> CREATE   PLUGGABLE DATABASE pdb6 FROM nocdb1@nocdb1                                                            

  2      FILE_NAME_CONVERT = ('/u01/app/oracle/oradata/nocdb1/',   '/u01/app/oracle/oradata/orclcwd/pdb6/');

 

Pluggable   database created.

)創建完成

 

)執行PDB轉換腳本

SQL> alter   session set container=pdb6;

SQL>   @?/rdbms/admin/ noncdb_to_pdb.sql

… 一系列日誌

Plug 過程的一些問題提示:

通過PDB_PLUG_IN_VIOLATIONS視圖可以查詢plug過程中的問題,例如以下,源PDB和當前CDB的字符集不同導致PDB open 後是限制模式,這個可以通過 ALTER DATABASE CHARACTER SET internal_use ZHS16GBK; 更改,如果在 實際應 用中就要事先注意 檢查 字符集是否相同。

 

  

二.通過插拔方式創建(CREATE PLUGGABLE DATABASE..USING ‘XML’..)

插拔的方式,是將一個PDB從CDB中拔出,之後插入到另外一個CDB的過程,一個拔掉的 PDB 由描述 PDB 的 XML 文件和其相關數據文件 組 成。

1. 從PDB插拔

)選擇準備拔出的 PDB ,這裏選擇 PDB4.

 

2) 關閉 PDB

 

3) 生成PDB的描述XML文件

ALTER PLUGGABLE DATABASE PDB4 UNPLUG INTO '/home/oracle/PDB4.xml';

  

4 )將PDB4的文件傳輸到目標庫相同路徑下:

 

5 )將生成的XML文件傳輸到目標庫

 

)執行DBMS_PDB.CHECK_PLUG_COMPATIBILITY 檢查要插入PDB是否和目標CDB兼容。

SET   SERVEROUTPUT ON

DECLARE

 compatible CONSTANT VARCHAR2(3) :=

  CASE DBMS_PDB.CHECK_PLUG_COMPATIBILITY(

      pdb_descr_file =>   '/home/oracle/PDB4.xml')

  WHEN TRUE THEN 'YES'

  ELSE 'NO'

END;

BEGIN

 DBMS_OUTPUT.PUT_LINE(compatible);

END;

/

 

SQL>   SET SERVEROUTPUT ON

SQL>   DECLARE

  2     compatible CONSTANT VARCHAR2(3) :=

  3      CASE DBMS_PDB.CHECK_PLUG_COMPATIBILITY(

  4          pdb_descr_file => '/home/oracle/PDB4.xml')

  5      WHEN TRUE THEN 'YES'

  6      ELSE 'NO'

  7    END;

  8    BEGIN

  9     DBMS_OUTPUT.PUT_LINE(compatible);

 10    END;

 11  /

NO  < <<< 檢查 不通 過 ,原來出 現 字符集不同

SQL>   ALTER SYSTEM ENABLE RESTRICTED SESSION;  

System   altered.

SQL> ALTER DATABASE CHARACTER SET internal_use ZHS16GBK;

Database   altered.

SQL>   SET SERVEROUTPUT ON

SQL>   DECLARE

  2     compatible CONSTANT VARCHAR2(3) :=

  3      CASE DBMS_PDB.CHECK_PLUG_COMPATIBILITY(

  4          pdb_descr_file => '/home/oracle/PDB4.xml')

  5      WHEN TRUE THEN 'YES'

  6      ELSE 'NO'

  7    END;

  8    BEGIN

  9     DBMS_OUTPUT.PUT_LINE(compatible);

 10    END;

 11  /

YES 《 《《《 檢查 通 

PL/SQL   procedure successfully completed.

 

對於插入一個PDB,必須滿足以下條件:

  • 目 標 CDB 必 須 與源 CDB 具有相同的字 節碼(主要涉及平臺問題) 。
•CDB 必 須 安裝相同的 選項 。
• 源 CDB 和目 標 CDB 必 須 具有兼容的字符集和國家字符集。

 

)使用XML元數據文件把PDB插入(克隆模式)

create pluggable database MYPDB3 AS CLONE  using '/home/oracle/PDB4.xml'  NOCOPY  TEMPFILE REUSE;

 

這裏使用NOCOPY是因爲將目標庫數據文件路徑設成了與源庫相同。

打開新的插入的PDB,但出現錯誤

 

SQL> !oerr ora 65054

65054, 00000, "Cannot   open a pluggable database in the desired mode."

// *Cause:  An attempt was made to open a pluggable   database in a mode

//          incompatible with that of the CDB.

// *Action: Open the CDB   in a compatible mode first and retry the operation.

看起來是新的PDB和CDB OPEN時不兼容,這裏我嘗試重啓整個CDB後竟然可以順利打開新插入的PDB了。

 

  

2. 從 NON-CDB 插拔

從NON-CDB轉換克隆的模式實際與從CDB相差不大,與從現有NOCDB創建的模式一樣,這裏也需要執行noncdb_to_pdb.sql腳本來轉換數據字典等。

以下列舉出執行的語句:

1 )關閉原NONCDB數據庫,並開啓到只讀模式

sqlplus / as sysdba

sql> shutdown immediate

sql> startup open read   only

2 )生成數據庫的XML元數據文件。

BEGIN

DBMS_PDB.DESCRIBE(pdb_descr_file   => '/home/oracle/12cNonPDB.xml');

END;

/

3 )關閉數據庫

sql> shutdown immediate

4 )同樣將原數據庫文件傳輸到新數據庫磁盤中。

5 )檢查兼容性

SET SERVEROUTPUT ON;

DECLARE

compatible CONSTANT   VARCHAR2(3) := CASE DBMS_PDB.CHECK_PLUG_COMPATIBILITY(pdb_descr_file => '/home/oracle   /12cNonPDB.xml')

WHEN TRUE THEN 'YES'

ELSE 'NO'

END;

BEGIN

DBMS_OUTPUT.PUT_LINE(compatible);

END;

/

6 )檢查是否有錯誤

col cause for a20

col name for a20

col message for a35   word_wrapped

select   name,cause,type,message,status from PDB_PLUG_IN_VIOLATIONS where   name='<noncdb database name>';

7 )創建PDB

CREATE PLUGGABLE DATABASE PDB8   USING ' /home/oracle/12cNonPDB.xml'

COPY

FILE_NAME_CONVERT =   ('/u01/app/oracle/12c/oradata/12cNonPDB/', '/u01/app/oracle/oradata/12c/ PDB8/');

8 )執行轉換腳本

sql> ALTER SESSION SET   CONTAINER= PDB8;

sql>   @$ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql

9 )打開新的PDB

ALTER PLUGGABLE DATABASE   PDB8 OPEN;

 

三.通過RMAN備份恢復

1. 整體數據庫備份恢復

有時可能需要遷移的僅僅是其中某幾個PDB,在整庫數據量不大情況下,可以直接備份整庫來異機恢復即可,這樣和普通的的數據庫模式是相同的。

(1)整庫備份

run{

allocate channel CH1 device type disk format  '/home/oracle/backup/full_db_%U';

backup database include current controlfile plus   archivelog  ;

release    channel CH1 ;

}

BACKUP current controlfile  format '/home/oracle/backup/control_%d_%T_%u.ctl';

 (2) 傳輸備份片到目標庫

[oracle@redhat1 ~]$ pwd

/home/oracle

[oracle@redhat1 ~]$  scp -r backup 172.16.155.67:/home/oracle/

(3) 恢復控制文件

Startup nomout

restore controlfile from '/home/oracle/backup/control_ORCLCWD_20170819_1esc91u4.ctl';

alter database mount;

(4)恢復全庫

run{

allocate channel CH1;

restore database ;

recover database;

release    channel CH1 ;

}

alter database open resetlogs;

2. 只恢復CDB、pdb$seed和需要的PDB

(1)備份數據庫

這裏使用上一步驟的全庫備份,這裏有個問題,就是我只需要恢復其中某一個PDB,那麼,是否可以直接備份root database ,種子pdb 和所要的pdb來單獨恢復,這個在後面進行詳細實驗。

(2)創建參數文件.

這個不做說明

(3)恢復控制文件

Startup nomout

restore controlfile from   '/home/oracle/backup/control_ORCLCWD_20170819_1esc91u4.ctl';

alter database mount;

 

(4)恢復所需要的 CDB$ROOT,PDB$SEED 和PDB4

run {

  ALLOCATE   CHANNEL c1 TYPE disk;

 restore database root ;  ------------------------->CDB$ROOT

 restore database "PDB$SEED";   -------->PDB$SEED is required

 restore database PDB4; -------------->PDB   we want to restore

RELEASE CHANNEL c1;

}

 

  

如果源庫和目標庫的數據文件路徑不同,這使用set new name 方式來更改文件路徑。

(5) 跳過不需要的PDB的表空間來做recover.

在本示例中, 數據庫中除了CDB$ROOT 和 PDB$SEED,還有PDB2和PDB4,選擇恢復的是PDB4,因此PDB2在recover時必須進行排除。

un   {

                      recover   database skip forever tablespace PDB2:SYSTEM,PDB2:SYSAUX; }

 

 

 

  

(6) 打開數據庫.

 

  打開後查看發現有pdb2,這個實際時不可用的,且沒有實際數據,直接drop掉即可。

SQL> show   pdbs

 

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED

----------   ------------------------------ ---------- ----------

         2 PDB$SEED                       MOUNTED

         3 PDB2                           MOUNTED

         5 PDB4                           MOUNTED

SQL> alter   pluggable database PDB2 open;

alter   pluggable database PDB2 open

*

ERROR at line   1:

ORA-01147: SYSTEM   tablespace file 8 is offline

SQL> drop   pluggable database pdb2 including datafiles;

 

Pluggable   database dropped.

而在打開PDB4時報出了ORA-65086,這裏可以試下插拔一次。

SQL> alter   pluggable database pdb4 open;

alter   pluggable database pdb4 open

*

ERROR at line   1:

ORA-65086:   cannot open/close the pluggable database

 

SQL> alter   pluggable database pdb4 unplug into '/tmp/pdb41.xml';

Pluggable   database altered.

 

1* select   pdb_name,status from dba_pdbs

SQL> /

 

PDB_NAME             STATUS

--------------------   ---------

PDB$SEED             NEW

PDB4                 UNPLUGGED

 

SQL> drop   pluggable database pdb4 keep datafiles;

 

Pluggable   database dropped.

 

SQL> select   pdb_name,status from dba_pdbs;

 

PDB_NAME             STATUS

--------------------   ---------

PDB$SEED             NEW

 

SQL> create   pluggable database PDB4 using '/tmp/pdb41.xml' nocopy tempfile reuse;

Pluggable   database created.

SQL> select   pdb_name,status from dba_pdbs;

PDB_NAME             STATUS

--------------------   ---------

PDB4                 NEW

PDB$SEED             NEW

SQL> alter   pluggable database pdb4 open;

Pluggable   database altered.

 

SQL> show   pdbs

 

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED

----------   ------------------------------ ---------- ----------

         2 PDB$SEED                       MOUNTED

         3 PDB4                           READ WRITE NO

 

  經過測試,可以只對需要的PDB進行備份後進行恢復即可,在遷移時並不需要整個庫都備份,這樣的話可以節省不少時間和空間。

run{

allocate   channel CH1 device type disk format    '/home/oracle/backup/full_db_%U';

 backup database root include current   controlfile plus archivelog; 

 backup    database "PDB$SEED";

 backup pluggable database PDB4 include   current controlfile plus archivelog;

release  channel CH1 ;

}

BACKUP current   controlfile  format '/home/oracle/backup/control_%d_%T_%u.ctl';

後面恢復的方法與以上相同。

 

總結:

   oracle 12c 隨着可插拔數據推出的 CREATE PLUGGABLE DATABASE 的方法都已經比較成熟,並且可以靈活使用,適合多種應用場景,而通過傳統的 rman 方式可能會出現一些不可預估的錯誤,經過測試,也非致命問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章