Oracle Database 12c 新特色(2) by oradba | CodeData
top

Oracle Database 12c 新特色(2)

分享:

Oracle Database 12c 新特色(1) << 前情

Oracle多租戶環境 Multitenant Environment (Pluggable Database) 建立與管理

在前一篇文章中,我們介紹了Oracle Multitenant Environment 的基本觀念,接下來我們實際操作看看!

建立Multitenant Container Database

在Oracle Database 12c中,允許我們建立Multitenant Container Database (CDB) 及與11g 之前相同的一般資料庫(Non-CDB)。  與建立Non-CDB相同,我們可以透過下列方式建立CDB:

1. 透過圖形化介面 DBCA(Database Configuration Assistant)。
2. 使用SQL*Plus 執行SQL語法: “Create Database"。

事實上,可於安裝Oracle Database 12c時,一起建立Container Database 及Pluggable Database。圖形化介面之操作,請參考Oracle Learning Library內文章, “Oracle Database 12c 2-Day DBA Series: Installing Oracle Database Software and Creating a Database”, 在此只介紹透過SQL*Plus 之方法。

首先建立Container Database,繼而建立各PDB

使用SQL*Plus建立Container Database

  1. 先設定環境變數 $ORACLE_HOME, $ORACLE_BASE, $ORACLE_SID
    export ORACLE_BASE=/u01/app/oracle
    export ORACLE_HOME=$ORACLE_BASE/product/12.1.0/dbhome_1
    export ORACLE_SID=CDB1
  2. 準備參數檔 $ORACLE_HOME/dbs/initCDB1.ora (假設Instance Name欲設為CDB1)。
    # $ORACLE_HOME/dbs/initCDB1.ora  # CDB1預設的init參數檔
    *.compatible='12.1.0.0.0'
    *.db_block_size=8192
    *.db_domain=''
    *.db_name='CDB1'
    *.diagnostic_dest='/u01/app/oracle'
    *.enable_pluggable_database=true
    *.memory_target=600m
    *.open_cursors=300
    *.processes=300
    *.remote_login_passwordfile='EXCLUSIVE'
    ## OMF setting ##
    *.db_create_file_dest='/oradata'
    *.db_create_online_log_dest_1='/oradata'
    *.db_create_online_log_dest_2='/u01/app/oracle/recovery_area'
    

除了一般non-CDB資料庫要設定的參數外,”compatible”必須設為’12.1.0.0.0’或其後之版本,因為pluggable database 是Oracle Database 12c以後才提供的功能。另外在建立CDB之前,必須將參數”enable_pluggable_database”設為TRUE。

為了方便管理,我們採用OMF(Oracle Managed File),將資料庫檔案交由Oracle自動管理。所以只須設定”db_create_file_dest”, “db_create_online_log_dest_1”, “db_create_online_log_dest_2” 等 OMF參數即可,不須設定”control_files”參數。為了讓Oracle自動更改參數檔之內容,我們將採用SPFILE。控制檔建立後,Oracle會自動修改SPFILE之參數 “control_files”,以符合OMF自動決定之檔案名稱。

3. 準備password file 讓DBA遠端管理資料庫。

orapwd file=$ORACLE_HOME/dbs/orapwCDB1 password=sys_password

4. 同時依照OMF參數設定建立相關OS目錄 ‘/oradata’ , ‘/u01/app/oracle/recovery_area’ 。再根據參數audit_file_dest設定值,建立目錄 ‘/u01/app/oracle/admin/CDB1/adump’(內定位置為 $ORACLE_BASE/admin/db_name/adump)  。

mkdir -p /oradata
mkdir -p /u01/app/oracle/recovery_area
mkdir -p /u01/app/oracle/admin/CDB1/adump

5. 建立spfile, 並啟動Instance 為nomount之狀態。

sqlplus / as sysdba
create spfile from pfile;
startup nomount

startup_nomount

6. 準備create database 指令檔 cr_cdb1.sql

CREATE DATABASE CDB1
  USER SYS IDENTIFIED BY sys_password
  USER SYSTEM IDENTIFIED BY system_password
  LOGFILE GROUP 1 SIZE 100M BLOCKSIZE 512,
          GROUP 2 SIZE 100M BLOCKSIZE 512,
          GROUP 3 SIZE 100M BLOCKSIZE 512
  MAXLOGHISTORY 1
  MAXLOGFILES 16
  MAXLOGMEMBERS 3
  MAXDATAFILES 1024
  CHARACTER SET AL32UTF8
  NATIONAL CHARACTER SET AL16UTF16
  EXTENT MANAGEMENT LOCAL
  DATAFILE SIZE 700M AUTOEXTEND ON NEXT 10240K MAXSIZE UNLIMITED
  SYSAUX DATAFILE SIZE 550M AUTOEXTEND ON NEXT 10240K MAXSIZE UNLIMITED
  DEFAULT TABLESPACE deftbs
    DATAFILE SIZE 500M AUTOEXTEND ON MAXSIZE UNLIMITED
  DEFAULT TEMPORARY TABLESPACE tempts1
    TEMPFILE SIZE 20M AUTOEXTEND ON NEXT 640K MAXSIZE UNLIMITED
  UNDO TABLESPACE undotbs1
    DATAFILE SIZE 200M AUTOEXTEND ON NEXT 5120K MAXSIZE UNLIMITED
  ENABLE PLUGGABLE DATABASE
    SEED FILE_NAME_CONVERT=('/oradata/CDB1/','/oradata/CDB1_SEED/')
    SYSTEM DATAFILES SIZE 125M AUTOEXTEND ON NEXT 10M MAXSIZE UNLIMITED
    SYSAUX DATAFILES SIZE 100M
  USER_DATA TABLESPACE usertbs
    DATAFILE SIZE 200M AUTOEXTEND ON MAXSIZE UNLIMITED;

在 “ENABLE PLUGGABLE DATABASE”句子之前的語法與建立一般oracle 資料庫(non-cdb) 之語法相同。

  • “USER SYS” 及 “USER SYSTEM” 語句,宣告兩個內建之資料庫管理者帳號。在CDB環境中,這兩個帳號為common user,也就是每一個PDB(包括未來新建的PDB)都會有這兩個帳號。
  • “LOGFILE” 語句,宣告online redo logfile之群組。因為我們未宣告其檔案名稱,所以Oracle 會使用OMF參數自動指定檔案名稱。要特別注意的是在CDB環境中,online redo logfile 是整個CDB中所有的PDB共用。在RAC (Real Application Cluster)環境中,每個Instance需要有自己的緒列(Threads)。
  • “MAXLOGHISTORY”,"MAXLOGFILES",…等MAX開頭之語句,是宣告controlfile 預留之空間大小,以儲存相關檔案之資訊。
  • “CHARACTER SET” , “NATIONAL CHARACTER SET”用來宣告資料庫字元集及國際語系字元集。整個CDB的字元集必須相同。
  • 第一個“DATAFILE”語句, 用來宣告container “CDB$ROOT”之SYSTEM 表格空間大小等設定。若未設定大小,則視是否採用OMF機制管理,若採用OMF與一般資料檔案相同為100MB,且autoextend on。若不採用OMF機制則必須宣告檔案名稱及其大小。
  • “SYSAUX” 語句,用來宣告container “CDB$ROOT”之SYSAUX 表格空間大小等設定。若未設定大小,則視是否採用OMF機制管理,若採用OMF與一般資料檔案相同為100MB,且autoextend on。若不採用OMF機制則必須宣告檔案名稱及其大小。
  • “DEFAULT TABLESPACE”指定使用者預設之表格空間,使用者建立物件時若不指定儲存空間,就會存放於此空間。Oracle 會在root及seed各自建立該表格空間。若未宣告,將不會建立此一表格空間。若未設定大小,則視是否採用OMF機制管理,若採用OMF與一般資料檔案相同為100MB,且autoextend on。若不採用OMF機制則必須宣告檔案名稱及其大小。
  • “DEFAULT TEMPORARY TABLESPACE” 指定root及seed之暫存表格空間名稱及大小等設定值。針對"extent management local"的資料庫, 採用OMF時,未宣告此語法,Oracle 會在root及seed各自建立名為TEMP之暫存表格空間。若未採用OMF,則必須宣告此語法以指定預設之暫存表格空間。我們建議盡量採用"locally managed" 資料庫。
  • “UNDO TABLESPACE” 指定UNDO空間給整個CDB使用,RAC環境中,每一個Instance同一時間只能使用一個作用中(active)的UNDO 表格空間。未宣告此語句時,若採用OMF 則Oracle 會自動建立undo 表格空間: SYS_UNDOTS 給整個CDB使用。未設定大小,則初始大小為10MB,且autoextend on。若不採用OMF機制則必須宣告表格空間及其檔案名稱大小。

透過 “ENABLE PLUGGABLE DATABASE”句子宣告此一資料庫為Multitenant 環境之資料庫,允許建立可插拔資料庫。Oracle 建立root container(CDB$ROOT)後,會自動建立一個唯讀(read-only)的PDB:seed (PDB$SEED)。

“SEED” 語句,開始有關”PDB$SEED”之設定。Oracle 依照OMF 機制或使用 ”FILE_NAME_CONVERT”語句之設定,決定SYSTEM, SYSAUX及DEFAULT TEMPORARY TABLESPACE 之檔案名稱。將來新建每一個PDB,可透過複製PDB$SEED之檔案快速建立。

  • “FILE_NAME_CONVERT”語句,宣告檔案位置與root之差異部分。Oracle會自動將root之檔案名稱,轉換成相對應之名稱。例如:
    若”FILE_NAME_CONVERT”宣告為(’/oradata/CDB1/’,’/oradata/CDB1_SEED/’),則Oracle 會將CDB$ROOT SYSTEM 表格空間檔案:”/oradata/CDB1/system01.dbf’ 複製為 PDB$SEED SYSTEM 表格空間檔案: “/oradata/CDB1_SEED/system01.dbf”。但若設定了OMF之參數時,Oracle 會忽略此一語句。
  • “SYSTEM” 及 “SYSAUX”語句,宣告相關表格空間大小等設定。但不能設定檔案位置及名稱,檔案之位置及名稱由OMF 或是FILE_NAME_CONVERT之語句決定,抑或是由”PDB_FILE_NAME_CONVERT”參數之設定決定。因為root container之檔案大小及其他屬性,不見得適用於 SEED container。因此透過這些語句設定適用之大小及其他屬性。若未設定大小,Oracle 會使用預設之大小:針對 seed 其SYSTEM及 SYSAUX預設大小為root相對表格空間的0.3倍。
  • “USER_DATA” 語句,宣告seed 額外建立的表格空間,將來每一個新建的PDB都會自動建立此一表格空間。但root不會有此表格空間。使用USER_DATA建立額外表格空間時,一定要指定其空間大小。(即使採用OMF亦如此)

上述create database 例子,Oracle會建立下列表格空間:

  • root(CDB$ROOT)
    SYSTEM
    SYSAUX
    DEFTBS (Default permanent tablespace)
    UNDOTBS1 (undo tablespace ,整個CDB共用)
    TEMPTS1 (Default temporary tablespace)
  •  seed(PDB$SEED)
    SYSTEM
    SYSAUX
    DEFTBS(Default permanent tablespace)
    USERTBS
    TEMPTS1(Default temporary tablespace)

事實上,若採用OMF,建立CDB database最簡單的語法為

CREATE DATABASE ENABLE PLUGGABLE DATABASE;

但Oracle 只會建立下列表格空間:

  • root (CDB$ROOT)
    SYSTEM(Default Permanent & Temporary Tablespace) , 100MB
    SYSAUX , 100MB
    SYS_UNDOTS (undo tablespace,整個CDB 共用) , 10MB
  •  seed(PDB$SEED)
    SYSTEM (Default Permanent & Temporary Tablespace) , 23.4375 MB
    SYSAUX , 11.71875MB

因為Oracle 會將預設的永久及暫存表格空間都設為”SYSTEM”,建議還是要宣告”DEFAULT TABLESPACE”及”TEMPORARY TABLESPACE”至其他表格空間。所以,還是比較建議用第一種語法。

7. 執行 cr_cdb1.sql 手動建立CDB1

cr_cdb1

8. 查看目前已建立之container。

col name for a10
col open_mode for a10
select con_id,dbid,name,open_mode,total_size
from v$containers;

v$containers

可觀察到Oracle建立了兩個container:CDB$ROOT 及 PDB$SEED。

9. 查看CDB database 資訊。

select dbid,name,cdb,con_id,con_dbid
from v$database;

v$database_cdb

其中CON_ID之欄位會出現在許多與CDB有關的資料字典中,其值可能為:
0 :指該筆資料涉及整個CDB,或是該資料庫為Non-CDB。(可透過 V$DATABASE之CDB欄位判斷)
1 :指該筆資料僅涉及root container。
n : 2<=n<=254,指該筆資料涉及第n個container,n 為其container之ID。

10. 查詢PDB資訊。

col name for a10
select con_id,DBID,name,open_mode,guid from v$pdbs;

v$pdbs_seed_only

可觀察到目前只有一個唯讀的PDB:PDB$SEED,稍微注意其GUID。OMF 建立PDB檔案時會將相關檔案存放於名稱與GUID相同之目錄下。

11. 查看表格空間。

select con_id,ts#,name
from v$tablespace
order by 1,2;

v$tablespace

CON_ID:1代表與CDB$ROOT相關,2 代表與PDB$SEED相關。

12. 查看資料庫各種檔案名稱。

set linesize 110
col name for a85
col con_id for 99999
select con_id,name from v$datafile order by 1;

v$datafile

 select con_id,name from v$tempfile order by 1;

v$tempfile

col member for a80
select con_id,member from v$logfile;

v$logfile

 select con_id,name from v$controlfile;

v$controlfile

可觀察到:

OMF 會將PDB 相關檔案存放於CDB檔案目錄之子目錄下,且該子目錄名稱為PDB之GUID。
透過CON_ID=0,得知整個CDB共用控制檔(Controlfile)及重作日誌檔(Online Redo Logfiles)  。
注:root container所擁有之物件也是整個CDB所共用。例如,資料字典、Oracle 提供之物件、undo tablespace 等。

 步驟6準備的cr_cdb1.sql會建立Multitenant Container Database:”CDB1”,包含兩個container:”CDB$ROOT”及”PDB$SEED”。(如圖1)CDB1_seed_only

12. 因為,尚未建立Data Dictionary Views,所以目前查詢 DBA_*, 或是 CDB_* 的views都會出現”ora-00942”的異常。所以必須執行Oracle 提供的指令檔案:"$ORACLE_HOME/rdbms/admin/catcdb.sql"catcdb_error.sql

依照Oracle 原廠文件說明,可執行$ORACLE_HOME/rdbms/admin/catcdb.sql 建立所有CDB相關之Data Dictionary Views。不過,實際執行卻找不到該指令檔案。經查確認為目前版本12.1的bug (Bug 17316776 )。 若嘗試透過執行catalog.sql , catproc.sql 等指令檔建立Data Dictionay Views,則只會在root container中建立相關Views,並不會建立在Seed PDB中,解決辦法就是要使用Oracle 提供之perl指令檔 catcon.pl 針對每個container執行 catalog.sql , cataproc.sql 及 pupbld.sql 等指令檔。

解決方法:請在OS環境執行下列指令

PERL5LIB=$ORACLE_HOME/rdbms/admin:$PERL5LIB; export PERL5LIB
perl $ORACLE_HOME/rdbms/admin/catcon.pl -n 1 -l /home/oracle -b catalog $ORACLE_HOME/rdbms/admin/catalog.sql;
perl $ORACLE_HOME/rdbms/admin/catcon.pl -n 1 -l /home/oracle -b catblock $ORACLE_HOME/rdbms/admin/catblock.sql;
perl $ORACLE_HOME/rdbms/admin/catcon.pl -n 1 -l /home/oracle -b catproc  $ORACLE_HOME/rdbms/admin/catproc.sql;
perl $ORACLE_HOME/rdbms/admin/catcon.pl -n 1 -l /home/oracle -b catoctk $ORACLE_HOME/rdbms/admin/catoctk.sql;
perl $ORACLE_HOME/rdbms/admin/catcon.pl -n 1 -l /home/oracle -b owminst $ORACLE_HOME/rdbms/admin/owminst.plb;
perl $ORACLE_HOME/rdbms/admin/catcon.pl -n 1 -l /home/oracle -b pupbld -u \ SYSTEM/system_password $ORACLE_HOME/sqlplus/admin/pupbld.sql;

查看各記錄檔(/home/oracle/*.log),確定所有指令檔皆順利完成。
(每個記錄檔都會記錄開始及結束之時間,若順利完成最後也會有” ========== PROCESS ENDED SUCCESSFULLY ==========”之字樣。)
再查詢DBA_* 或是 CDB_* 之Data Dictionary Views。cdb_pdbscdb_tablespacesdba_tablespaces

名稱為“DBA_”開頭的Data Dictionary Views,可看到目前連上之container本身之內容。而”CDB_”開頭的Data Dictionary Views,依連上之container 種類有不同的結果,若連上的是root,則可觀察到整個CDB內之內容,其中con_id代表相關之container 代號。但若連上的是PDB,則看到之內容與”DBA_”開頭的views 內容類似,只是多了con_id欄位。

13. 將CDB關閉再重新啟動,查看PDB狀態。seed_read_only

可發現seed 在每次CDB 開啟時會自動設為唯讀模式。

新增pdb 之方法有:
1. 使用seed 建立新的PDB (CREATE PLUGGABLE DATABASE ADMIN USER….)
2. 複製已存在之PDB (CREATE PLUGGABLE DATABASE FROM)
3. 插入已拔除的PDB (CREATE PLUGGABLE DATABASE USING)
4. 將Non-CDB 準備成PDB插入CDB中( DBMS_PDB.DESCRIBE )

使用seed 建立新的可插拔資料庫

我們剛透過SQL*Plus 將CDB建立成功,接著嘗試透過SQL*Plus建立新的PDB。

CREATE PLUGGABLE DATABASE PDB1
ADMIN USER admin_pdb1 IDENTIFIED BY oracle
ROLES=(RESOURCE);

透過seed 建立一個PDB大約只需1分鐘,Oracle會將seed(PDB$SEED)視為樣板template,透過複製seed之資料檔案,快速建立新的PDB。cr_pdb1_from_seed

  •  透過"ADMIN USER"指定將seed當作樣板,複製其資料檔案快速建立新的可插拔資料庫(本例為pdb1)。 另外,也要求新增一個PDB管理者帳號 (本例為 admin_pdb1,為局部使用者Local User也就是只存在於該PDB中之使用者帳號)。Oracle 會自動授權此管理者帳號對該PDB擁有扮演及管理"PDB_DBA"角色之權限。
  • “IDENTIFIED BY" 指定PDB 管理者帳號之密碼。
  • “ROLES=(role_name,role_name,…)" : 除了一開始就授予角色"PDB_DBA"之權限(CREATE_SESSION, SET_CONTAINER, CREATE PLUGGABLE DATABASE),還可指定額外的角色給"PDB_DBA",讓管理者帳號額外擁有其他權限。

查看pdb1 之狀態。

v$pdbs_w_pdb1發現pdb1為"MOUNTED"之狀態。嘗試透過CDB_xxxx等views 查各container之物件,發現無法查看pdb1之物件。check_obj_when_pdb1_mounted將pdb1開啟,再查看相關訊息。cdb_tablespaces_pdb1pdb1之tablespace與seed 完全相同。cdb_users_pdb1Oracle 在pdb1新增了一個管理者帳號"ADMIN_PDB1″。cdb_tables_pdb1當pdb1開啟後,可透過CDB_xxxx views查看其物件。
查看新增之服務名稱。cdb_services_pdb1建立新的PDB時,Oracle會自動加入與PDB名稱相同的服務名稱。
嘗試連上pdb1,並查看相關資訊。cdb_tablespaces_in_pdb1con_id_con_namepdb1_table_count

複製(clone)pdb1以建立新的可插拔資料庫pdb2

透過複製事先存在的pluggable database pdb1的資料檔案,可快速建立新的pluggable database。

1. 先將pdb1 關閉後開啟為唯讀模式。pdb1_open_read_only1

2. 嘗試在目前的container建立新的pdb,會發生ORA-65040之異常。必須連上root才能建立、複製、移除或插拔PDB。cr_pdb2_err

3. 將container設為root,再嘗試一次就能成功建立。cr_pdb2_success透過"CREATE PLUGGABLE DATABASE … FROM"語法,可複製PDB。被複製的PDB必須以唯讀模式開啟,也可複製遠端之PDB,但有些規則須符合(如資料庫字元集),請參照Oracle 原廠文件說明。

4. 將PDB2開啟查看資料檔案位置。pdb2_data_file

拔除(unplug)及插入(plug) PDB

當我們暫時不需要某一個PDB時,或是要將該PDB搬移到另一個CDB時,我們可將該PDB從CDB中拔除。透過下列指令,可將pdb2從cdb1中拔除。

ALTER PLUGGABLE DATABASE pdb2 CLOSE IMMEDIATE;
ALTER PLUGGABLE DATABASE pdb2 UNPLUG INTO '/u02/oradata/pdb2.xml';

當某個PDB被拔除後,會維持在Mounted狀態,在原來的CDB中除了可透過RMAN繼續對其進行備份外,我們只能將該PDB捨棄(drop)。其他操作都會出現異常。例如,當我們嘗試要將已拔除的pdb2開啟時,會有下列異常:open_unplugged_pdb_err若要將已拔除之PDB插回原CDB中,必須先將該PDB捨棄。再將其插入。plug_in_pdb因為磁碟空間安排,將原先之資料檔搬移到’/u02/oradata/CDB1_pdb2′目錄下。因此,記錄於’/u02/oradata/pdb2.xml’之資料檔案位置不正確,需透過"SOURCE_FILE_NAME_CONVER"語法宣告目前資料檔案之位置。若有需要,該語法可宣告多組配對。另外在插入PDB時,Oracle 會自動建立暫存檔案(Tempfile),所以需先將該檔案移除。

複製或插入後的PDB狀態一開始為"Mounted",第一次開啟必須允許讀寫,以便Oracle 異動其檔頭(File Header),否則會有下列錯誤:first_time_open_read_only_err1開啟後查看其狀態:open_aft_plugin

嘗試將CDB關閉後重新啟動,再查看各PDB之狀態,可發現除了PDB$SEED之外其他PDB 都是"MOUNTED"。若希望各PDB自動開啟,可設定觸發程式 (Database Trigger: AFTER STARTUP):restart_cdb_1

CREATE TRIGGER aft_startup
AFTER STARTUP ON DATABASE
BEGIN
  EXECUTE IMMEDIATE 'ALTER PLUGGABLE DATABASE all OPEN';
END;
/

restart_cdb_2

將Non-CDB 準備成PDB插入CDB中

除了可將其他PDB複製或插入CDB以外,也可以將non-CDB(12c 以後)準備成已拔除的 pdb,方便插入CDB中。

1. 將non-CDB 開啟為唯讀模式。open_ncdb_in_ro

2. 透過DBMS_PDB套裝程式產生xml檔案。DBMS_PDB

3. 若是要將non-CDB之資料庫搬入CDB中,則在插入前最好先將non-CDB關閉。如果僅是複製non-CDB為CDB中的PDB,則可在non-CDB為唯讀模式進行插入。

4. 插入non-CDB。cr_pdb_from_ncdb

5. 在第一次開啟前必須先執行$ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql。

alter session set container=plug_in_ncdb;
@?/rdbms/admin/noncdb_to_pdb.sql

6. 查看其狀態。plug_in_ncdb_open

有關多租戶環境之可插拔資料庫的建立及複製等操作,就先介紹到此。下一篇我們將介紹有關使用者、權限及角色扮演等在多租戶環境中的新觀念。

分享:
按讚!加入 CodeData Facebook 粉絲群

相關文章

留言

留言請先。還沒帳號註冊也可以使用FacebookGoogle+登錄留言

關於作者

Oracle 特約講師,多年的 Oracle DBA 工作及相關課程的教學經驗,想藉此園地與大家分享 Oracle Database 的一些觀念及心得。

熱門論壇文章

熱門技術文章