亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Oracle Database 12cR2多租戶權威指南

發布時間:2020-08-10 21:36:53 來源:ITPUB博客 閱讀:338 作者:qinghuawenkang 欄目:關系型數據庫


Anton Els,Vít ?pinka,Franck Pachot
Oracle Database 12c Release 2 Multitenant
EISBN 978-1-25-983609-1
Copyright ? 2017 by McGraw-Hill Education.
All rights reserved. No part of this publication may be reproduced or transmitted in any form or by any
means, electronic or mechanical, including without limitation photocopying, recording, taping, or any
database, information or retrieval system, without the prior written permission of the publisher.
This authorized Chinese translation edition is jointly published by McGraw-Hill Education and Tsinghua
University Press Limited. This edition is authorized for sale in the People’s Republic of China only,
excluding Hong Kong, Macao SAR and Taiwan.
Translation copyright ? 2018 by McGraw-Hill Education and Tsinghua University Press Limited.
版權所有。未經出版人事先書面許可,對本出版物的任何部分不得以任何方式或途徑復制或傳播,
包括但不限于復印、錄制、錄音,或通過任何數據庫、信息或可檢索的系統。
本授權中文簡體字翻譯版由麥格勞-希爾(亞洲)教育出版公司和清華大學出版社有限公司合作出版。
此版本經授權僅限在中國大陸區域銷售,不能銷往中國香港、澳門特別行政區和中國臺灣地區。
版權?2018 由麥格勞-希爾(亞洲)教育出版公司與清華大學出版社有限公司所有。
北京市版權局著作權合同登記號 圖字: 01-2017-3077
本書封面貼有 McGraw-Hill Education 公司防偽標簽,無標簽者不得銷售。
版權所有,侵權必究。侵權舉報電話: 010-62782989 13701121933
圖書在版編目(CIP)數據
Oracle Database 12
R2 多租戶權威指南 / (新西蘭)安東·艾爾斯(Anton Els), (捷克)維特·斯
普林克(Vít ?pinka), (瑞士)弗蘭克·帕丘特(Franck Pachot) 著;史躍東 譯. —北京:清華大學
出版社, 2018
書名原文: Oracle Database 12
Release 2 Multitenant
ISBN 978-7-302-50251-7
Ⅰ. ①O… Ⅱ. ①安… ②維… ③弗… ④史… Ⅲ. ①關系數據庫系統-指南
Ⅳ. ①TP311.138-62
中國版本圖書館 CIP 數據核字(2018)第 103253 號

責任編輯: 王 軍 李維杰
封面設計: 牛艷敏
版式設計: 思創景點
責任校對: 曹 陽
責任印制:董 瑾
出版發行: 清華大學出版社
網 址: http://www.tup.com.cn, http://www.wqbook.com
地 址:北京清華大學學研大廈 A 座 郵 編: 100084
社 總 機: 010-62770175 郵 購: 010-62786544
投稿與讀者服務: 010-62776969, c-service@tup.tsinghua.edu.cn
質 量 反 饋: 010-62772015, zhiliang@tup.tsinghua.edu.cn
印 刷 者:北京鑫豐華彩印有限公司
裝 訂 者:三河市溧源裝訂廠
經 銷: 全國新華書店
開 本: 170mm×240mm 印 張: 23 字 數: 451 千字
版 次: 2018 年 6 月第 1 版 印 次: 2018 年 6 月第 1 次印刷
印 數: 1~3500
定 價: 79.80 元
———————————————————————————————————————————
產品編號: 074808-01

本打算趁著農歷春節之前,利用調休的時間將這本 400 多頁的書翻譯完畢,
誰曾想諸事纏身,一頓忙活之后,也就到了年三十。于是這本書也就只能在春
節之后搞定了。
嚴格來說,這本書是去年 9 月時著手翻譯的,到 2018 年 2 月,又是 6 個月
的時間。回想起去年翻譯《云端存儲 Oracle ASM 核心指南》時,也是斷斷續
續忙了 5 個月才完工。留意起來,才意識到翻譯這個活兒,真心是一項費時費
心的工作。平時工作繁忙,也只能擠出晚上或周末,抑或調休的時間進行翻譯。
并且書中很多詞句都要斟酌再三、反復琢磨,才能夠將原文的意思準確表達出
來。自己寫書,是對自己會的知識進行梳理;而翻譯,則是研究自己不會的東
西。因此,從某種程度上來說,翻譯的過程,實質上也是學習新技術、新知識
的過程。
多租戶與 IMO 一道,并稱為 Oracle Database 12c 的兩大關鍵特性。此番有
幸從清華大學出版社拿到這本書的翻譯權,也是件值得高興的事情。只不過與
IMO 相關的一本書, 則被 Oracle 原廠拿去翻譯了。若是這兩本書都由筆者翻譯,
再加上前面的 ASM,豈不是完美?可惜。
多租戶技術,是 Oracle 自 12.1 版本開始引入的一項全新特性。它從根本上
改變了 Oracle 數據庫長久以來的體系結構,也是 Oracle 在這個風起云涌的時代,
全面迎合云計算的具體表現。對于傳統的 Oracle DBA 來說,熟練掌握 12c 版本
中的這一新特性,已經是毋庸置疑的事情。
本書的封底,指出這本書由 OCM 專家團隊編寫,而實際上,翻閱了本書
前言的各位讀者就會知道,本書的三位作者均是 Oracle ACE。他們不僅有著多
年的實踐經驗,也在各大技術社區和相關會議上進行技術分享。由這樣的人撰
寫本書, 本書內容的實戰性可想而知。本書從多租戶的基本概念入手, 涵蓋 CDB
與 PDB 的創建和管理、網絡與服務、安全、備份和恢復、數據移動以及多租戶
的諸多高級特性,尤其是深入探討了諸多技術在多租戶環境下和此前版本中的
不同之處,這對于我們的實際工作來說,顯然是極具價值的內容。
當然,依然要感謝所有在本書付梓出版的過程中給筆者提供幫助的各位人
士,正是你們一直以來的關心與幫助,筆者才能夠筆耕不輟、日日向前。
由于筆者才疏學淺,因此在本書的翻譯過程中注定會有些錯誤與不足之處,
各位讀者見到后,望不吝賜教。
2018 年 2 月 22 日
Anton Els 是一位 Oracle ACE,目前是 Dbvisit 軟件有限公司的高級副總裁。
Anton 在數據庫技術領域已經有超過 15 年的工作經驗,擅長 Oracle 數據庫、備
份和恢復、數據庫備庫、 Oracle Linux、虛擬化以及 docker 技術。 Anton 是獨立
Oracle 用戶組(Independent Oracle Users Group, IOUG)的活躍成員,同時也是新
西蘭 Oracle 用戶組(New Zealand Oracle Users Group, NZOUG)的副主席。 Anton
擁有 Oracle Database 11g OCM 證書,還擁有從 8i 到 12c 的全部 OCP 證書。同
時,他還擁有 Oracle Database 11g RAC 與 GI 管理員方向的 OCE 證書、 Red Hat
5 RHSA 證書,以及 Oracle Solaris 10 的 SCSA 證書。 Anton 經常出席相關工業
及用戶組會議,例如一些行業合作會議、在日本舉行的 Oracle OpenWorld 數據
庫技術專場會議、 NZOUG,以及亞太和拉美地區的 Oracle 技術網絡(OTN)年
會等。可以訪問他的 Twitter(@aelsnz)或博客(www.oraclekiwi.co.nz)。
Vít ?pinka 是一位 Oracle ACE-A, 目前是 Dbvisit 軟件有限公司的首席架構
師。 Vít 在數據庫技術領域也有超過 15 年的工作經驗,主要擅長 Oracle 數據庫
技術。 Vít 也是 IOUG 的活躍成員,并經常出席 Oracle OpenWorld、行業合伙
會議、UKOUG、DOAG 以及 NZOUG 的相關活動。Vít 擁有 Oracle Database 10g、
11g 以及 12c 的 OCM 證書,還擁有從 9i 到 12c 的 OCP 證書、Oracle Database 10g
RAC 管理員專家認證,以及 LPIC-2 Linux 網絡專業認證。可以訪問他的
Twitter(@vitspinka)或博客(http://vitspinka.blogspot.com)。
Franck Pachot 是一位 Oracle ACE 總監,目前是 dbi 服務公司(瑞士)的首席
顧問、培訓專家以及 Oracle 技術領導人。 Franck 在 Oracle 技術領域擁有超過
20 年的工作經驗。 Franck 也經常參加 Oracle OpenWorld、 IOUG 合作會議、
DOAG、 SOUG 以及 UKOUG 的活動。他是 SOUG 和 DOAG 的活躍成員,同
時還是 OraWorld 團隊的榮譽成員。 Franck 擁有 Oracle Database 11g 和 12c 的
OCM 證書, 還擁有從 8i 到 12c 的所有 OCP 證書, 同時擁有 Oracle Database 12c
性能管理與優化方向的 OCE 證書。另外,他還擁有 Oracle Exadata Database
Machine 2014 實施認證證書。可以訪問他的 Twitter(@franckpachot)或博客
(http://blog.pachot.net)。

Deiby Gómez 是世界上最年輕的 Oracle ACE(23 歲)以及 ACE 總監(25 歲),
同時也是母國危地馬拉的第一位 ACE 和 ACE 總監,還是拉美地區最年輕(24
歲, 2015.2)的 Oracle 11g OCM 證書獲得者。他是危地馬拉第一位 OCM 證書獲
得者,另外也是最年輕(26 歲, 2016.4)的 Oracle 12c OCM 證書獲得者,是中央
美洲第一位 Oracle 12c OCM,是最近的 2016 年度編輯選擇大獎的獲得者(拉斯
維加斯,內華達州)。他經常在 Oracle 全球技術大會上發表演講,包括 2013 年
至 2016 年的 Oracle 技術網絡拉丁美洲年會、合作會議(美國)以及 Oracle
OpenWorld 等。 Deiby 也是 Oracle 12cR2 beta 版本在危地馬拉的第一位測試者。
Deiby 分別用英文、西班牙文以及葡萄牙文發表過多篇技術文章,這些文章發
表在 Oracle 網站和 DELL’s Toad World 上。另外,在自己的博客上,他也發表
過數百篇技術文章。他曾以杰出專家的身份出現在 2014 年 11 月份和 12 月份
的 Oracle 雜志上。同時, Deiby 也是危地馬拉 Oracle 用戶組(GOUG)的主席、
拉美 Oracle 用戶組社區(LAOUC)的技術支持總監,他還是 OraWorld 團隊的共
同發起人。目前, Deiby 擁有自己的公司 NUVOLA,S.A,為拉美地區的客戶提供
Oracle 技術服務。
Arup Nanda 以 DBA 的身份工作超過 20 年,工作經驗幾乎涉及 Oracle 技
術的所有方面,從建模到性能調整,再到 Exadata 均有涉獵。他已經發表過大
約 500 篇文章,是 5 本書的合著者,發表過 300 多場演講。其博客網站為 arup.
blogspot.com,他也是新手技術導師,是一名經驗豐富的 DBA。他曾于 2003 年
獲得過 Oracle 年度 DBA 大獎,在 2012 年獲得過年度企業架構師大獎。他也是
一位 ACE 總監,同時也是 Oak Table 網絡的成員。

Mike Donovan 于 2007 年加入 Dbvisit,在該公司, Mike 扮演了多個角色,
包括擔任全球支持團隊的領導人以及數字業務開發先驅。并且就在最近,他成
為該公司的 CTO。 Mike 對新技術有著狂熱的激情,他與客戶及合作伙伴一起
工作,努力搭建數據庫技術與大數據等前沿技術之間的橋梁,從而創造出商業
價值。他喜歡接受挑戰,會嘗試探求更智能、更低成本的解決方案或替代方案。
Mike 具有技術、藝術以及客戶支持和軟件開發等多方面的復合背景。他對
Oracle 數據庫技術極有熱情,并為之工作超過 10 年的時間。他也在多個行業會
議上發表演講,包括 OOW、 RMOUG、日本數據技術會議以及合作會議等。
Mike 作為產品 DBA 工作多年,獲得了從 9i 到 12c 的多項認證。

在 Oracle Database 12cR1 版本(12.1)中, 開始引入名為“多租戶”的新選項。
從那時起,新的術語“可插拔數據庫”便傳播開來。但是這個術語,往往意味
著對該特性或其影響并沒有清晰的理解。從 12c 的第一個版本開始,多租戶已
經是 Oracle 數據庫中最為重大的架構變革之一,同時該選項在數據庫軟件中已
經被落地實施。多租戶選項帶來了很多新的特性,但也影響到了 Oracle DBA
進行日常管理的方式。從 12c 的第二個版本(12.2)開始,對多租戶選項的可用特
性進行了更多的擴展。現在比較清楚的一點就是,舊的系統架構已經被拋棄,
多租戶則已經開始生根發芽——不容忽視。
12cR2 中多租戶的到來,需要 DBA 調整他們現有的思考方式,以及進行日
常管理的方式。無論是運行單租戶數據庫,還是運行包含大量租戶的數據庫,
都需要經歷一個新的學習過程。所以,相比于單純描述多租戶這個新東西究竟
包含了什么內容,本書更傾向于描述與 DBA 相關的工作究竟發生了怎樣的變
化,無論是核心的日常維護操作,還是一些相關的高級特性。可以將本書視為
Oracle Database 12c 的管理指南。此外,還可以學到關于這些新特性的一些實
戰知識,包括語法上的改變,以及最佳實踐等方面的內容。本書由三位具有豐
富 DBA 經驗并具備相關認證的 DBA 撰寫,并經由諸多技術精湛的審核人員進
行嚴格審查,從而使內容的價值得到進一步的提升。唯有如此,才能讓你帶著
洞察一切的激情來了解 Oracle 數據庫的管理工作。
本書第Ⅰ部分介紹多租戶的功能。其關鍵問題包括, Oracle 公司為何要引
入這一選項,并以何種方式來模仿其他數據庫產品,以及該選項是否能夠真正
為我們設計并部署應用的方式所需要。第 1 章專注這些問題并解釋多租戶架構。
第 2 章討論容器數據庫(CDB)的創建流程,以及如何正確完成這一流程。因為
在 12c 版本中,創建 CDB 已經是默認的選項,不管信不信,我們真的遇到一些
人在對 CDB 毫不知情的情況下就創建了 CDB。在對多租戶的各種特性進行詳
細描述之前,第 3 章會為你提供信息,讓你決定究竟是選擇使用 CDB 還是非
CDB 數據庫,并且第 3 章還提供不同可用版本和選項的概要信息。
第Ⅱ部分將會講述當使用多租戶特性時,你的日常工作將會發生怎樣的改
變。這一部分從第 4 章開始,該章關注 PDB 的創建與管理,并且也會涉及將數
據庫升級到 12c 版本的內容。第 5 章將會詳細討論數據庫的網絡與服務。接下
來的第 6 章,則會關注另一個重要議題——安全——我們將探討 PDB 的隔離、
用戶的公共性以及加密。
第Ⅲ部分將會討論備份與復制操作等方面的巨大提升。當然,主要是在
PDB 級別。第 7 章將會詳細研究作為每一個 DBA 都應該足夠熟悉的領域——
備份和恢復——以及如果需要的話,如何將數據庫恢復到過去的某個狀態。第
8 章討論如何使用數據庫閃回技術實現歸檔,以及如何在 PDB 級別實現基于時
間點的恢復。本部分的最后一章,第 9 章將會研究如何插入/拔出 PDB,以及如
何對 PDB 進行克隆、傳輸或在線重定位(online relocation)。
在本書的第Ⅳ部分,你將會在一個新的層次或級別上學習多租戶。當對多
個 PDB 進行集成時,將不得不意識到資源管理器(Resource Manager, RM)的價
值。關于 RM,將在第 10 章進行討論。在多租戶環境中, RM 將會發揮極為重
要的作用。第 11 章將會關注如何使用 DG 來對多租戶數據庫進行保護。第 12
章將會討論 CDB 中的數據共享問題。與物理克隆或同步技術相比,基于云的
解決方案,則需要數據能夠以一種更具靈活性的方式來提供。我們將在第 13
章討論邏輯復制的相關內容。

第 1 章 多租戶概述 ······················3
1.1 歷史課堂: IT 技術的
新時代·································4
1.1.1 通往多租戶之路············ 5
1.1.2 方案集成 ······················· 6
1.1.3 表集成 ··························· 9
1.1.4 服務器集成 ··················· 9
1.1.5 虛擬化 ························· 10
1.1.6 一個實例管理多個
數據庫 ·························
10
1.1.7 集成策略總結·············· 11
1.2 系統字典與多租戶架構 ··· 11
1.2.1 過去:非 CDB············· 11
1.2.2 多租戶容器·················· 14
1.2.3 多租戶字典·················· 16
1.2.4 使用容器 ····················· 21
1.3 什么是 CDB 級別的
集成···································27
1.4 本章小結 ··························33
第 2 章 創建數據庫 ····················35
2.1 創建容器數據庫(CDB) ····36
2.1.1 OMF 概述···················· 36
2.1.2 CDB 創建選項 ············ 37
2.2 創建可插拔數據庫
(PDB) ································52
2.2.1 使用 PDB$SEDD 創建
新的 PDB ····················
53
2.2.2 使用本地克隆方式創建
新的 PDB ····················
56
2.2.3 使用 SQL Developer
創建 PDB ····················
57
2.2.4 使用 DBCA 創建 PDB··· 60
2.2.5 使用 Cloud Control
創建 PDB ····················
61
2.3 使用 catcon.pl 腳本 ··········62
2.4 本章小結 ··························64
第 3 章 單租戶、多租戶以及應用
容器·······························65
3.1 多租戶架構不是一個
選項 ··································66
3.1.1 拋棄非 CDB ················ 66
3.1.2 不兼容特性 ················· 67
3.2 標準版中的單租戶···········68
3.2.1 數據移動 ····················· 68
3.2.2 安全 ····························· 69
3.2.3 與 SE2 集成················· 69
3.3 企業版中的單租戶···········70
3.3.1 閃回 PDB····················· 71
3.3.2 PDB 的最大數量 ········· 71
3.4 使用多租戶選項···············73
3.4.1 應用容器 ····················· 73
3.4.2 與多租戶選項集成 ······ 76
3.5 本章小結 ··························77
第 4 章 日常管理 ·······················79
4.1 選擇要使用的容器···········81
4.2 管理 CDB ·························83
4.2.1 創建數據庫·················· 83
4.2.2 啟動與關閉數據庫 ······ 83
4.2.3 刪除數據庫·················· 84
4.2.4 修改整個 CDB············· 84
4.2.5 修改根容器·················· 85
4.3 管理 PDB··························86
4.3.1 創建新的 PDB ············· 86
4.3.2 打開和關閉 PDB ········· 86
4.3.3 查看 PDB 的狀態 ········ 90
4.3.4 查看 PDB 的操作
歷史 ·····························
90
4.3.5 在多個 PDB 上運行
SQL······························
90
4.3.6 修改 PDB····················· 91
4.3.7 刪除 PDB····················· 93
4.4 打補丁與升級···················93
4.4.1 升級 CDB ···················· 94
4.4.2 插入 ·························· 103
4.4.3 打補丁 ······················ 105
4.5 使用 CDB 級別與 PDB 級別
的參數·····························106
4.5.1 CDB SPFILE············· 106
4.5.2 PDB SFPILE 的
等價性 ······················
106
4.5.3 SCOPE=MEMORY ··· 108
4.5.4 ALTER SYSTEM
RESET·······················
108
4.5.5 ISPDB_MODIFIABLE··· 108
4.5.6 CONTAINER=ALL ··· 109
4.5.7 DB_UNQIUE_
NAME ·······················
110
4.6 本章小結 ························ 111
第 5 章 網絡與服務 ··················113
5.1 Oracle Net ······················· 114
5.2 Oracle 網絡監聽 ············· 114
5.3 LREG 進程 ····················· 115
5.4 網絡:多線程與
多租戶····························· 117
5.5 服務名稱 ························ 119
5.5.1 默認服務與連接到
PDB ···························
119
5.5.2 創建服務 ··················· 122
5.6 為 PDB 創建專用監聽 ···127
5.7 本章小結 ························130
第 6 章 安全·····························131
6.1 用戶、角色以及權限·····132
6.1.1 公共用戶還是本地
用戶? ·······················
132
6.1.2 何為用戶? ··············· 133
6.1.3 CONTAINER=
CURRENT·················
134
6.1.4 CONTAINER=
COMMON·················
135
6.1.5 本地授權 ··················· 138
6.1.6 公共授權 ··················· 139
6.1.7 沖突解決 ··················· 140
6.1.8 保持清晰與簡單······· 143
6.1.9 CONTAINER_
DATA························
143
6.1.10 角色 ························ 145
6.1.11 代理用戶················· 145
6.2 鎖定概要文件
(lockdown profile)············147
6.2.1 禁用數據庫選項······· 148
6.2.2 禁用 ALYTER
SYSTEM···················
148
6.2.3 禁用特性 ·················· 150
6.3 PDB 隔離························150
6.3.1 PDB_OS_
CREDENTIALS········
150
6.3.2 PATH_PREFIX ········· 151
6.3.3 CREATE_FILE_
DEST ························
151
6.4 透明數據加密(TDE) ······151
6.4.1 創建 TDE·················· 152
6.4.2 帶有 TDE 的插入與克隆
操作 ··························
157
6.4.3 TDE 總結·················· 157
6.5 本章小結 ························157
第 7 章 備份和恢復··················161
7.1 回到基礎知識·················162
7.1.1 熱備份與冷備份······· 162
7.1.2 RMAN:默認配置 ··· 164
7.1.3 RMAN 冗余備份······ 165
7.1.4 SYSBACKUP 權限··· 166
7.2 CDB 備份與 PDB 備份 ···166
7.2.1 CDB 備份 ·················· 167
7.2.2 PDB 備份··················· 171
7.2.3 別忘了歸檔日志! ···· 174
7.3 恢復場景 ························174
7.3.1 實例恢復 ··················· 175
7.3.2 對 CDB 進行還原和
恢復···························
176
7.3.3 對 PDB 進行還原和
恢復···························
178
7.4 RMAN 優化方面的一些
考量·································180
7.5 數據恢復指導·················183
7.6 塊損壞 ····························184
7.7 使用 Cloud Control 進行
備份 ································184
7.8 本章小結 ························186
第 8 章 閃回與基于時間點的
恢復·····························189
8.1 PDB 的基于時間點的
恢復 ································190
8.1.1 在指定時間恢復
PDB ···························
191
8.1.2 UNDO 在哪里? ······· 193
8.1.3 版本 12.1 中的
PDBPITR 總結 ··········
195
8.2 版本 12.2 中的本地
UNDO ·····························196
8.2.1 數據庫屬性 ··············· 197
8.2.2 創建數據庫 ··············· 197
8.2.3 修改 UNDO 表空間 ·· 198
8.2.4 修改 UNDO 管理
模式···························
199
8.2.5 共享 UNDO 還是本地
UNDO? ···················
200
8.3 版本 12.2 中 PDBPITR···201
8.3.1 共享 UNDO 模式下的
PDBPITR··················
201
8.3.2 本地 UNDO 模式下的
PDBPITR··················
202
8.4 閃回 PDB························202
8.4.1 閃回日志 ·················· 203
8.4.2 使用本地 UNDO 進行
閃回 ··························
205
8.4.3 使用共享 UNDO 進行
閃回 ··························
205
8.4.4 CDB 和 PDB 級別的
還原點 ······················
206
8.4.5 干凈還原點··············· 209
8.5 resetlogs ·························· 210
8.6 閃回與 PITR···················212
8.6.1 何時需要 PITR 或
閃回? ······················
212
8.6.2 對備庫的影響··········· 212
8.6.3 輔助實例的清除······· 214
8.7 本章小結 ························215
第 9 章 移動數據 ·····················217
9.1 錨定 PDB 文件位置 ·······218
9.2 插入與拔出 ····················218
9.2.1 PDB 的拔出與插入 ·· 219
9.2.2 停留在源庫中的已拔出
數據庫 ······················
220
9.2.3 XML 文件中究竟有
什么? ······················
222
9.2.4 為插入操作檢查
兼容性 ······················
225
9.2.5 像克隆一樣插入········ 226
9.2.6 PDB 的歸檔文件 ······· 228
9.3 克隆 ································229
9.3.1 克隆本地 PDB··········· 229
9.3.2 克隆遠程 PDB··········· 231
9.4 應用容器的一些考量·····236
9.5 轉換非 CDB 數據庫·······236
9.5.1 插入非 CDB ·············· 237
9.5.2 克隆非 CDB ·············· 239
9.6 將 PDB 移動到云上 ·······240
9.7 基于 PDB 操作的
觸發器·····························241
9.8 全傳輸導出/導入············241
9.9 可傳輸表空間·················244
9.10 本章小
結 ··························· 245
第 10 章 Oracle 數據庫資源
管理器························249
10.1 資源管理器基礎···········250
10.1.1 資源管理器關鍵
術語 ·······················
251
10.1.2 資源管理器的
需求 ·······················
253
10.1.3 資源管理器的
級別 ·······················
253
10.2 CDB 資源計劃··············254
10.2.1 資源分配與使用
限制 ·······················
254
10.2.2 默認與自動任務
指令 ·······················
256
10.2.3 創建 CDB 資源
計劃 ·······················
257
10.3 PDB 資源計劃··············265
10.3.1 創建 PDB 資源
計劃 ······················
266
10.3.2 啟用或禁用 PDB 資源
計劃 ······················
268
10.3.3 移除 PDB 資源
計劃 ······················
269
10.4 使用初始化參數管理 PDB
的內存和 I/O ················269
10.4.1 PDB 的內存分配·· 269
10.4.2 限制 PDB 的 I/O··· 270
10.5 實例囚籠
(instance caging) ··········· 270
10.6 監控資源管理器···········272
10.6.1 查看資源計劃與資源
計劃指令···············
272
10.6.2 監控被資源管理器
管理的 PDB ··········
273
10.7 本章小結 ······················274
第 11 章 Data Guard ···············275
11.1 ADG 選項·····················276
11.2 創建物理備庫···············277
11.2.1 使用 RMAN 進行
復制 ······················
277
11.2.2 使用 EMCC 創建
備庫 ······················
289
11.3 在多租戶環境下管理
物理備庫 ······················292
11.3.1 在源端創建新的
PDB ······················
293
11.3.2 將 PDB 從源端
刪除 ······················
294
11.3.3 修改子集 ·············· 295 11.3.4 EMCC···················· 298
11.4 云上的備庫···················298
11.5 本章小結·······················301
第 12 章 在 PDB 之間共享
數據···························303
12.1 數據庫鏈接···················304
12.2 共享公共只讀數據·······305
12.2.1 可傳輸表空間········ 306
12.2.2 存儲快照與基于寫的復
制(copy on wirte) ···
307
12.3 跨 PDB 視圖·················308
12.3.1 簡單用戶表 ··········· 309
12.3.2 集成數據 ··············· 313
12.4 跨數據庫復制···············327
12.5 本章小結 ······················327
第 13 章 邏輯復制····················329
13.1 Oracle 日志挖掘器
(LogMiner)····················331
13.2 已過期的特性···············332
13.2.1 Oracle CDC··········· 332
13.2.2 Oracle 流技術 ······· 332
13.2.3 Oracle 高級復制 ··· 332
13.3 OGG(Oracle
GoldenGate)··················333
13.3.1 OGG 中的多租戶
支持 ······················
333
13.3.2 大數據適配器······· 343
13.4 Oracle XStream·············345
13.5 邏輯備庫 ······················346
13.6 其他第三方選項···········347
13.6.1 Dbvisit Replicate ··· 347
13.6.2 Dell SharePlex······· 347
13.7 本章小結 ······················347
多租戶意味著什么

多租戶概述
在 Oracle Database 12c 中, Oracle 引入了一項發生于數據庫體系結構上的
重大調整。在 Oracle Database 12c 以前,一個實例只能打開一個數據庫。如果
想處理多個數據庫,那么需要啟動多個實例才行。因為它們都是完全隔離的架
構,即便這些數據庫都安裝在同一臺服務器上也是如此。這一點與其他關系型
數據庫頗為不同,其他很多的數據庫,都是可以使用一個實例來管理多個數據
庫的。
進入 Oracle Database 12c 之后,一個實例就可以打開多個可插拔數據庫,
或者稱之為 PDB(Pluggable DataBase)。 Oracle 將之稱為新多租戶架構,以前舊
的架構名稱便被拋棄了。無論是否使用了多租戶選項,將來所有的 Oracle 數據
庫都會運行在多租戶架構上。關于這點事實,所有的 DBA 都是不能忽視的。
1.1 歷史課堂: IT 技術的新時代
在介紹將來的架構之前,讓我們先簡要回顧一下使用數據庫的歷史。如你
在圖 1-1 中所看到的,我們并不關注時間,而是關注數據庫版本,通過它來回
顧 Oracle 數據庫的演化歷程。

Oracle Database 12cR2多租戶權威指南

圖 1-1 從 IT 集成到云
當 Oracle Database 8i 和 9i 出現在市場上時, 數據中心使用中型機逐漸變得
流行起來。我們從大型機時代開始步入客戶端/服務器時代。而當時的 Oracle
數據庫的體系結構,顯然是非常適應這一趨勢的。由于 Oracle 數據庫是使用 C
語言編寫的,因此它在多種平臺上均能成功運轉。并且,所有用戶管理信息都
存儲在數據庫的數據字典中。 Oracle 數據庫顯然為客戶端/服務器架構做好了準
備,它可以使用操作系統來監聽 TCP/IP 端口并存儲文件。此外,數據庫的架構
在小型機上也是可擴展的,這多虧了一個被稱為并行服務器的特性。當然,后
來它被稱為 RAC(Real Application Cluster)。
隨著服務器數量的增長,數據庫的數量也隨著增長。在那時,一家公司往
往會擁有很多臺物理服務器,并且使用 DAS(Direct Attached Disks,直連存儲)
作為存儲,而在每臺服務器上,則又運行著 1 個或 2 個 Oracle Database8i 或 9i
實例。
隨著數據庫數量的增長,管理所有的服務器和磁盤則又成為噩夢一般的存
在。面對著數據的指數級增長,還依然使用內部磁盤來管理這些數據的話,則
容量規劃就變得極其困難。此時, Oracle Database 10g 便應運而生。我們需要
對存儲進行集成,這樣我們就可以把數據庫文件存放到一個存儲陣列中,并通
過 SAN(Storage Area Network, 存儲區域網絡)讓所有的服務器都可以共享訪問。
這就是存儲集成。
隨著時間的流逝, Oracle Database 11g 開始登場。早期,比較流行的想法
是,我們使用服務器,然后每臺服務器上都帶有磁盤。但是,相比于設置多臺
服務器的容量并對其進行維護而言,虛擬化軟件則為我們提供了一種新的可能:
我們可以將多臺物理服務器放在一起,并在此基礎之上提供虛擬機。在以前的
時代,我們就是使用這樣的方法:應用服務器、 SAN 或 NAS,以及虛擬機。
現在, Oracle Database 12c 為我們帶來一種新的方法。很多擁有集成存儲
和服務器的組織,目前已經意識到運營這樣的架構其實并非他們的核心業務。
相反,他們將 IT 需求視作一個服務,它應該具有可擴展性和靈活性。小公司想
要使用公有云來提供他們所需的 IT,大一些的公司則打算建立自己的私有云。
在這樣的情況下,虛擬化就可以提供 IaaS(Infrastructure as a Service,基礎設施
即服務)。但是,我們也需要 AaaS(Application as a Service,應用即服務)和
DBaaS(DataBase as a Service,數據庫即服務)。對于 IT 技術生態圈而言,這顯
然是一個極為重大的變化。 這與當年從客戶端/服務器架構進化到應用服務器時
代頗為相似,無論是擴展性方面還是重要性方面。當然,這一過程并非一蹴而
就——它需要時間。不過,現在就可以斷言,在接下來的十年中,混合模型(按
需供應/云)將變得更強大,但是也終將會被云慢慢替代。
正如我們所期待的,新的時代有著不同的需求。數據庫的未來也將與集成、
敏捷開發,以及快速就緒等聯系在一起。對于 Oracle 而言,類似這樣的一些特
性,其實從 9i 到 11g 一直都處于快速進化之中。比如簡單數據傳輸、克隆,以
及精簡指令配置(thin provisioning)等。但是數據庫中的兩個核心架構功能:一
數據庫一實例,以及一數據庫一數據字典,一直以來都是如此,尚未做好集成
的準備。為此, Oracle Database 12c 提供了這兩個問題的答案:多租戶。在保
留原有可移植性架構的基礎之上, Oracle 對其架構進行了設計調整,從而使得
可以在同一個數據庫上運行應用——無論程序是運行在小型服務器上,還是運
行在很大的云上。
1.1.1 通往多租戶之路
新的時代是關于集成的時代。一些人會將其想象成一個集中式系統,并輔
以集中管理。但是這帶來了新挑戰:我們需要越來越高的敏捷性。讓一個數
據庫快速就緒在今天而言,本非一件容易之事。但至少,我們不能讓它變得
更糟糕。
考慮這樣一個例子。你是一個 Oracle DBA。然后一個開發人員來到你的辦
公桌前,并表示她需要一個新的數據庫。在她的意識里,可能會認為這是一個
很簡單的需求,你只需要在一個管理界面上單擊幾下鼠標應該就能搞定。你看
著她,瞪大眼睛,然后告訴她需要去填一張需求申請單,上面需要指定存儲、
內存、 CPU 以及可用性方面的內容。并且,你還得解釋,這樣的需求要上級領
導批準,需要花費數天甚至一周的時間才能建立一個數據庫。顯然,這里就是
開發人員與運維人員之間通常會產生誤解的地方。
開發人員可能以前就沒有使用過 Oracle 數據庫, 所以她就閃過一些念頭,
認為數據庫不過就是用來裝她的應用程序表的一個容器罷了,并且這個容器
還是一個很輕量級的玩意——在很多其他的非 Oracle 數據庫中,這實際上就是
“數據庫”。
但是在 Oracle 中,恰恰相反,我們是有一些輕量級的容器——邏輯級別上
的方案(scheme),以及物理級別上的表空間(tablespace)——但是數據庫,則不僅
僅是這些內容的整個組合。 Oracle 數據庫,是一組方案和表空間的集合,然后
再加上用于管理這些內容的元數據(數據字典),以及為數眾多的用于實施各種
特性的 PL/SQL 代碼(DBMS 包)。每一個數據庫都必須擁有自己的實例,而實
例又由一組后臺進程和一塊共享內存構成。并且每一個數據庫也都有相應的結
構來保護事務的完整性,比如 UNDO 表空間和 REDO 日志。
因此,基于上述這些理由,提供一個新的數據庫并不是件很瑣碎細微的事
情。要創建一個新的數據庫,需要與系統管理員和存儲團隊進行溝通,因為需
要服務器和磁盤資源。你并不打算在一臺服務器上部署太多實例,但是你也不
太可能在一臺服務器上只部署一個數據庫。正是因為這些,現在我們通常使用
虛擬化技術,然后為每個實例提供一臺虛擬機(Virtual Machine, VM)。當然,
這種方法并不適用于每一個應用或每一個環境,從敏捷的角度來看——因為這
樣的話,需要的虛擬機就太多了。另外,當為每一個數據庫都不得不分配服務
器、存儲以及實例時,最終你就會發現,這樣浪費太多資源了。
在 Oracle Database 12c 以前,這種場景下,對于開發人員來說,比較合適
的方法,就是在現有的數據庫中為其創建新的方案。但是這種方法并不總是可
能的,或者說是可行的。讓我們解釋一下為什么。
1.1.2 方案集成
在 Oracle Database 12c 以前,方案就是可用的解決方法。每一個應用程序
都可以有自己的方案,或是一組方案,如果想將表和存儲過程分開的話。這些
方案在邏輯上是隔離的,并使用權限管理來保證其安全性。
從物理上來講,也可以為每個應用設置不同的表空間。這就意味著,一旦
數據文件丟失,在還原期間,可能就只有一個應用處于離線狀態。如果想將表
空間重新分布到其他文件系統中,也是如此。但是,除此之外,為了優化資源
使用,其他的所有資源我們都是共享的:實例進程與內存、SYSTEM 與 SYSAUX
表空間、數據字典等。
備份策略和高可用(High Availability, HA)策略也都是相同的。一個 DBA
管理一個數據庫,然后在這個數據庫上運行多個應用。在 Oracle 數據庫的早期
版本中,數據庫就是按照這樣的方式來設計的。
1. 可傳輸表空間
在 Oracle 數據庫中,很多操作都是發生在表空間級別的。尤其是可傳輸表
空間這一特性。通過這一特性,可以將應用的數據文件物理地拷貝到其他數據
庫中,即便是拷貝到一個更高版本的數據庫中也是可以的。可傳輸表空間這一
特性足夠重要,因為它被認為是多租戶技術的先驅,或者是始祖。1997 年, Oracle
公司為可傳輸表空間技術申請專利,名為“數據庫系統的可插拔表空間”。而現
在,多租戶架構恰恰就是可插拔數據庫的基礎。
在這里,可插拔的意思,就是可以直接將一個物理結構(數據文件)插到一
個數據庫中,并令其成為該數據庫的一部分。可傳輸表空間這一特性,就能夠
將用戶表空間的數據文件插入到數據庫中。 然后就只需要導入相應的元數據(數
據字典實體)即可。這樣,在新的數據庫中,這些邏輯對象的定義就與數據文件
中的物理內容相匹配了。
當然,在 Oracle Database 12c 中,也可以傳輸表空間,這樣的操作也足夠
簡單。如果想傳輸所有的用戶表空間,使用“FULL=Y”選項即可。但是相關
的元數據還是需要被邏輯傳輸。如果有數百張表的元數據需要傳輸,那么這個
時間可能就會比較長。即便這些表都是空表也是如此。例如,如果想遷移一個
PeopleSoft 數據庫,它里面包含 20 000+張表。即便這些表都是空的,導入元數
據也需要幾個小時的時間。
正如你將看到的,由于多租戶更卓越的性能,傳輸一個可插拔數據庫,實
際上就成為所有數據文件的傳輸,包括 SYSTEM 和 SYSAUX 中的數據文件。
顯然,這里面就包含了數據字典,甚至還可能包含 UNDO 信息。這就意味著所
有的元數據也將會被物理導入。因此,相比傳統的可傳輸表空間技術,這樣的
操作就快了很多。
2. 方案名稱沖突
在真實世界中,想實現方案集成,其實還是很有難度的。你可能想將很多
應用都集成到一個數據庫中,甚至包括同一個應用的測試環境也想集成進來。
此時,就會面對一系列應用程序的約束問題。
如果應用中的方案所有者是硬編碼的,不能修改,那么此時該怎么辦?如
果我們需要建立一個電話清單系統,而該系統在數據庫中對應的方案為 PB,然
后我們想將多個環境都集成到測試數據庫中,那么這顯然是被禁止的。原因是
該方案的名稱已經硬編碼到應用程序以及包中,當然還有其他地方。如果有應
用程序供應商派來的顧問,也許我們還能夠比較好地理解這些奇怪的方案名稱。
但是如果沒有,可能就得去猜測這些方案名稱最初究竟是什么意思。
當然,如果應用是在你的掌控之下進行設計的,那么你就可以避免這樣的
問題。并且無須多言,你應該在自己的應用程序中從來都不要對方案名稱進行
硬編碼。可以使用某一用戶連接到數據庫,然后簡單地使用 ALTER SESSION
SET CURRENT_SCHEMA 語句來設置當前應用程序的方案所有者,從而來訪
問所有相關的對象。如果有多個方案?那么為應用程序使用多個方案倒也不算
是一個壞主意。
例如,可以使用代碼(PL/SQL 包)來分離數據(表)。這能夠讓數據實現更好
的隔離與封裝。但即便是在這種情況下,也不要將表所在的方案名硬編碼到包
中。可以在包所在的方案中,為這些對象創建同義詞即可。這樣,就可以在
PL/SQL 代碼中引用這些對象,而不用使用方案名(因為同義詞與代碼在同一個
方案中),而這些同義詞會自動關聯到相應的對象上。如果對象名稱發生改變,
重新創建同義詞就行了。這些動作都可以很簡單地完成,也可以自動完成。
3. 公共同義詞與數據庫鏈接
對于上面提到的同義詞,顯然,我們討論的是私有同義詞。不要使用公共
同義詞。因為它們會覆蓋整個名稱空間中的私有同義詞。當一個應用程序創建
公共同義詞時,無法讓其綁定其他任何東西。這就是方案集成的一個限制:不
屬于特定方案的對象,容易與其他應用程序,或是其他版本、其他環境中的同
一應用的對象產生沖突。
4. 角色、表空間名稱與目錄
一個應用程序可以定義或引用其他對象,只要這些對象均處于數據庫的公
共名稱空間即可——例如角色、目錄以及表空間名稱。如果一個應用程序在不
同環境中運行,則這些環境其實也可以被集成到同一個數據庫中。只需要在執
行 DDL 腳本時,為不同的環境分別設置不同的參數,從而可以讓這些數據庫
對象分別適用不同的環境即可。如果不是這種情況的話,那么想實現方案集成
就有難度了。
另外一方面,這些不屬于特定方案的對象,也會讓數據移動的實現變得更
為復雜。例如,當想使用數據泵(Data Pump)來導入一個方案時,這些對象可能
需要在事先就完成創建。
5. 游標共享
即便一個應用程序是專門為方案集成而設計的,在將所有的東西都集成
到一個數據庫里面時,也照樣可能會遇到性能方面的問題。我們曾經處理過
一個包含 3000 個方案的數據庫,它其實是一堆數據集市(data mart):結構相
同,數據不同。
另外,很顯然,應用程序的代碼也都是相同的。用戶需要連接到其中一個
數據集市,然后執行查詢,而這些查詢已經在應用程序中進行了定義。這就意
味著同樣的查詢——甚至在 SQL 文本上也是完全相同的——將會運行在不同
的方案上。如果知道 Oracle 數據庫中的游標共享是如何實現的,就立即能夠看
到問題所在:一個游標會有上千個子游標。一個父游標會被所有的 SQL 文本共
享,當對象不同時,便會創建不同的子游標。當在多個方案中執行這些代碼時,
問題就出來了。 SQL 解析時需要掃描一個相當長的子游標鏈表,而在掃描期間
需要持有 latch,這顯然會導致很嚴重的庫緩存競爭。
在多租戶環境下,為滿足集成的目的,父游標會被共享,但是在子游標搜
索方面需要進行一些性能方面的提升,從而緩解上述問題。
1.1.3 表集成
當想要對多個環境中的數據進行集成時,而這些環境又有著相同的應用程
序及代碼版本,這就意味著要用到的表將會具有完全相同的結構,可以把所
有的東西都放到一張表中。通常情況下,我們是在每一個主鍵值中添加環境
ID(公司、國家、市場以及其他信息)來區別數據。這樣做的好處,是可以一次
性管理所有的東西。例如,當想要添加索引時,可以為所有的環境添加。
基于性能和維護方面的原因考慮,可以基于環境 ID 來對表中的數據進行
物理分區,并將不同的分區數據存放在不同的表空間中。但是,這樣做,其隔
離級別就會很低,并進而影響到性能、安全以及系統的可用性。
實際上,大部分應用程序都采用類似這樣的設計,并且一般都把數據存儲
在一個環境中。絕大部分情況下,添加到主鍵值前面的 ID 往往都只有一個值,
而這也是 Oracle 引入索引跳躍掃描的原因之一。可以使用虛擬私有數據庫策略
來管理對這些環境的訪問。可以使用分區交換技術,在物理上實現對這些分區
的獨立管理。如果想找一個類似的例子,可以看一下 RMAN 的資料庫(恢復目
錄):所有已注冊的數據庫,其信息都存儲在相同的表中。但是,在存儲不同環
境(測試、開發以及生產環境)中的數據時,或是存儲不同版本(數據模型也不盡
相同)的數據時,這樣的隔離其實是不夠的。
1.1.4 服務器集成
如果有多個獨立的數據庫,但是又不想為每個數據庫都配置一臺服務器,那
么可以將這些實例集成到一臺服務器上。如果曾經登錄過 Oracle 的 Ask Tom 網
站(astome.oracle.com/),并咨詢過在一臺服務器上推薦配置幾個實例, Tom Kate
的答案是這樣的:“我們不建議在一臺主機上部署多個實例——主機可以是虛擬
機或物理機,我們并不關注——但是你可以這樣認為:一臺主機 = 一個實例。”
但是在真實生活中,就像我們看到的那樣,一臺數據庫服務器上往往運行著多個
實例。可以在一臺主機上安裝多個版本的數據庫(ORACLE_HOME),也可以在一
臺主機上運行多個實例——并且很多時候都是不得不如此。我們曾經見過一臺
服務器上運行著多達 70 個實例。
這種情況下,在實例之間進行隔離的方法就比較少了。比如內存,可以通
過設置 SGA_MAX_SIZE 參數來在物理上對內存進行分割。也可以在 Oracle
Database 12c 中使用 PGA_AGGREGATE_LIMIT 來限制進程使用的內存。可以
使用實例囚籠策略,來設置每個實例在 CPU 上運行的最大進程數量。在最新的
Oracle Database 12cR2 中,不需要企業版就可以使用實例囚籠策略。我們將在
第 3 章中討論這個主題。
但是,在一臺服務器上運行大量的實例依然是個問題。例如,當要重啟服
務器時,需要啟動大量的進程,并完成內存分配。一次服務器停機,無論是計
劃內的還是計劃外的,都會對大量應用程序造成影響,并且需要消耗大量資源
來處理多個 SGA 以及數據字典表。
1.1.5 虛擬化
現今,虛擬化是一個非常好的方法,可以在不需要管理大量物理服務器的
前提下實現一個實例一臺服務器。可以對環境進行極好的隔離設置,在限制范
圍內分配 CPU、內存以及 I/O 帶寬。甚至可以使用不同的網絡來隔離這些數據
庫。但是,即便這些服務器都是虛擬機器,也還是無法解決資源浪費,因為還
是要持有多個 OS、 Oracle 軟件、內存以及數據字典。并且,還是得管理多個數
據庫——備份恢復、實現高可用特性,比如 Data Guard 等。然后,還是有多個
OS 需要打補丁和監控。
此外,在虛擬化環境中,軟件許可也是夢魘般的存在。當進行軟件安裝
時, Oracle 軟件是按照處理器數量進行授權的, Oracle 會考慮這些因素,比
如與虛擬化技術相關的授權問題,以及在虛擬機上安裝軟件并運行,等等。
當然,這些也依賴供應商所提供的管理程序,以及這些管理程序的版本。
1.1.6 一個實例管理多個數據庫
那么問題來了,如何找到一種方法,能夠實現這樣的一種隔離級別:能夠
同時滿足環境的隔離與資源集成兩個目的。顯然,這種隔離級別高于方案隔離,
但是又低于我們現在所知道的實例與數據庫。也就是說,我們可以在一臺服務
器上,使用一個實例來管理多個數據庫。
在 12c 以前的 Oracle 數據庫版本中,顯然沒有這樣的功能。但是在現今
的多租戶架構中,這種方法就頗為可行了。現在,一個集成的數據庫可以管
理多個可插拔數據庫。另外,也出現了一種新的隔離級別,即獨立數據庫——
可插拔數據庫,這種架構在環境準備、移動以及系統升級等方面都提供了相
當高的敏捷性。
1.1.7 集成策略總結
表 1-1 簡要總結了在多租戶技術出現之前,幾種可選的集成策略之間的不
同之處。
表 1-1 不同集成策略的優劣分析

集成策略 優勢 劣勢
將所有內容當成一個整體來進行管理 隔離級別受限較大,且不適用于不
同環境
方案 可以實現實例、數據字典以及 HA 級
別的共享
公共對象之間容易出現沖突,且隔
離級別受限
數據庫 只需要管理一個數據庫 需要多個 SGA 及多組后臺進程,也
需要維護多個備份與 HA 配置
虛擬化 可以提供最佳的隔離級別,可以實現
職責分離,并提供 HA 以及 vMotion
方面的特性
授權許可問題,需要學習新的技術,
需要管理并運行多臺主機


1.2 系統字典與多租戶架構
在多租戶架構中,系統字典是變化最大的部分之一。讓我們來看看在以前
的版本中,系統字典是如何實現的,以及在 Oracle Database 12c 中,它又發生
了哪些變化。
1.2.1 過去:非 CDB
數據庫中既存儲數據,又存儲元數據。例如,假設在 SCOTT 方案下有一
張表 EMP。該表的描述信息——名稱、包含的列以及數據類型等——同樣也存
儲在數據庫中。這些描述信息——也就是元數據——存儲于系統表中,并且是
系統字典的一部分。
1. 字典
Codd 的規則(由 E.F.Codd 建立, 其提出了關系模型)定義了關系型數據庫
的元數據必須與數據有著同樣的表現形式:可以使用 SQL 來查詢元數據或數
據。作為數據庫管理員,這樣的事情幾乎每天都在做。通過查詢字典視圖,例
如 DBA_TABLES,來獲取數據庫中對象的相關信息。 Codd 的規則雖然只用于
表述邏輯層面,并由字典視圖提供這些信息;但是 Oracle 走得更遠——通過在
關系型表中物理存儲這些元數據信息——對于同樣類型的表和應用程序表,這
些都為 SYS 方案所擁有,并存儲在系統表空間(SYSTEM 和 SYSAUX)中。
其實,在處理數據及元數據信息存儲時,并不需要使用 Oracle 字典的實際
名稱和詳細信息,如圖 1-2 所示。表 SCOTT.DEPT 用于存儲用戶數據,該表的
定義則存儲在字典表中, 即 SYS.COLUMNS。該字典表用于存儲列的相關信息,
并且由于這個字典本身也是表,因此它的定義信息也采用同樣的方式存儲下來。

Oracle Database 12cR2多租戶權威指南

圖 1-2 數據及元數據信息存儲
當然,系統字典表中不僅僅存儲了表的定義信息。一直到 8i 版本,數據存
儲(表的 extent 信息)的物理描述信息也都是存儲在字典表中的。但是,為了適
應可插拔的需求,表空間已經變得越來越自包含了。因此,數據存儲的處理方
式,隨著本地管理表空間的出現而發生了變化。另一方面,在每一個新的數據
庫版本中,都會有很多新的信息會被添加到系統字典中。在當前的數據庫版本
中, Oracle 數據庫軟件的很大一部分功能,都是用 PL/SQL 包來實現的,而這
些內容,也是存儲在系統字典中的。
2. Oracle 管理的對象
對于 Oracle 數據庫而言, 其系統字典的實現方式, 就是我們前面所討論的:
字典存儲在數據庫中。每一個數據庫都有其自己的系統字典。并且當使用邏輯
導入/導出工具(EXP/IMP 或數據泵)來移動數據庫時,可能就會發現,有些字典
對象屬于系統,有些用戶對象屬于應用程序,而如何將這些對象區分開來,則
是一件很棘手的事情。當將一個數據庫完整地導入(在 IMPDP 中使用 FULL=Y
選項, 這將在第 8 章進行討論)新建的數據庫中時, 你不會想把字典信息也導入,
因為在目標數據庫中,這些內容已經存在了。
當然, SYS 方案中的對象就是字典對象,并且它們會被數據泵忽略。但是
如果有人在 sys 下創建了用戶對象,那么這些對象就會丟失,基于 sys 對象的
授權也會丟失。并且在其他地方也可以找到一些系統對象,例如在 OUTLN、
MDSYS 以及 XDB 等方案中。另外,系統中也有很多角色,也可以創建自己的
角色。想把它們區分開也不是那么容易。
幸運的是, 在 12c 版本中, DBA_OBJECTS、 DBA_USERS 以及 DBA_ROLES
視圖中都包含了一個標記,用來指明哪些是數據庫維護的對象,是由數據庫創建
的,并且不屬于你的應用程序。我們可以在 12c 版本中查詢出這些 Oracle 維護的
方案列表:
在 12c 版本中,這顯然是一個非常大的提升。可以很簡單地確認哪些方案
屬于你的應用程序,而哪些又屬于數據庫系統。 ORACLE_MAINTAINED 標記
列在 DBA_OBJECTS、 DBA_USERS 以及 DBA_ROLES 視圖中存在,因此現在
就可以很容易地區分哪些對象是由數據庫創建的,以及哪些對象是由應用程序
創建的。
注意:
12c Oracle EXP/IMP EXU8USR KU_NOEXP_TAB Data Guard LOGSTDBY_SKIP_SUPPORT DEFAULT_PWD$ V$SYSAUX_OCCUPANTS DBA_REGISTRY 3. 系統元數據與應用程序元數據
我們已經描述了如下元數據結構: 方案、 對象以及角色。 讓我們再深入一點,
深入數據去看一看。你已經知道表的定義信息存儲在字典表中, 例如在圖 1-2 中,
我們簡要提了一下 SYS.COLUMN 表。但是,字典數據模型其實是很復雜的。
實際上,對象名稱存儲在 SYS.OBJ$中,表的信息存儲在 SYS.TAB$中,列的
信息則存儲在 SYS.COL$中,等等。這些都是表,并且每一個都有自己的定義
信息——元數據——存儲在字典表 SYS.TAB$中。例如,它里面存儲了你自己
創建的表的信息,但是也存儲了所有字典表的相關信息。
在 SYS.TAB$中,有一行數據是用于存儲自身的定義信息。你可能會問,
在創建表時(當然也是創建數據庫時),這一行是怎樣插入到表中的,因為當時
這張表應該還不存在。在 ORACLE_HOME 中,Oracle 有一段特殊的引導代碼(關
于這部分內容,已經超出了本書的范圍。不過可以查看 ORACLE_HOME/
rdbms/admin 目錄下的 dcore.bsq 文件。也可以查詢 BOOTSTRAP$表,看看在啟
動階段,數據庫是如何在字典緩沖區中創建這些表的。此時這些基礎的元數據
都是立即可用的,從而允許對余下的元數據進行訪問)。
所有的元數據都存儲在這些表中,但是在非多租戶環境下有一個問題:系統
信息(屬于數據庫的信息)與用戶信息(屬于應用程序的信息)是混雜在一起的。這
些元數據都存儲在同樣的表中,并且所有這些東西都存儲在同一個容器——數
據庫中。
這就是多租戶架構中與之前不同的地方:我們現在可以使用多個容器,從
而將系統信息與應用程序信息分離開來。
1.2.2 多租戶容器
在多租戶數據庫中,最重要的結構就是容器。一個容器包含數據和元數據。
多租戶中的不同之處在于:一個容器可以包含多個容器,從而分離對象,無論
是物理上還是邏輯上。一個容器數據庫可以包含多個可插拔數據庫,以及一個
根容器,用來存儲公共對象。
多租戶數據庫是容器數據庫(Container DataBase, CDB)。在原有的架構中,
一個數據庫就是一個單一的容器,并且無法再分,這被稱為非 CDB。在 12c 版本
中,可以選擇是創建 CDB 還是非 CDB。可以創建一個 CDB,也就是多租戶數據
庫,通過在實例參數中設置 ENABLE_PLUGGABLE=true,并且在 CREATE
DATABASE語句中添加 ENBALE PLUGGABLE 選項來完成(更多細節請參閱第
2 章)。
這樣就會創建出一個 CDB, 其中可以包含其他容器。這些容器可使用數字、
容器 ID 或名稱進行標識。一個 CDB 中至少包含一個根容器和一個種子容器,
也可以添加自己的容器,在 12.1 版本中,最多可以添加 252 個容器;在 12.2
版本中,則可以多達上千個容器。
1. 可插拔數據庫
多租戶的目的是集成。相比于在一臺服務器上部署多個數據庫,現在我們
只需要創建一個集成的數據庫即可,也就是 CDB。它里面可以包含多個可插拔
數據庫(PDB)。并且每一個 PDB 對于它的用戶來說,都是一個完整的數據庫。
它有多個方案、公共對象,有系統表空間、字典視圖等。
多租戶架構可以用來在私有云或公有云上進行集成。可以實現數百個甚至
上千個 PDB 的集成。其目的是,可以提供多個 PDB 的快速就緒服務,但呈現
出來的狀態卻像是一個數據庫。根據這種設計方式,任意連接到一個 PDB 的用
戶都無法區分自己是連接到了一個 PDB 還是一個獨立的數據庫。
另外, 所有以前版本中使用的命令現在照樣可用。例如, 當連接到一個 PDB
時,可以執行 shutdown 來關閉這個 PDB。當然,它實際上并不會關閉實例。
因為該實例還管理著其他 PDB。但是對于用戶來說,他所看到的,與關閉一臺
獨立數據庫并無二致。
考慮另外一個例子。我們正連接到一個 PDB,并且我們沒有自己的 UNDO
表空間,因為該表空間是 CDB 級別的(在 12.2 版本中,我們可以改變這一點,
但是到第 8 章才能看到相關內容)。讓我們試著創建一個 UNDO 表空間:
這里并沒有報錯。但是 UNDO 表空間顯然沒有創建出來。畢竟,要創建一
個 100TB 的數據文件是不可能的。我們所提交的語句只是被忽略了。其想法是,
既然在一個數據庫中提交的腳本可以創建一個 UNDO 表空間, 那么這樣的語法
在一個 PDB 中顯然也是應該被接受的。被接受的原因是,所有在非 CDB 中可
以做的事情,在 PDB 中必須也是可以進行的。但是它被忽略了,因為 UNDO
表空間是 CDB 級別的對象。
在多租戶環境中,也會有一些新的命令可用,并且你所知道的所有命令也
都被 PDB 所接受。可以為一個 PDB 用戶授予 DBA 角色,這樣該用戶就可以做
一個 DBA 能夠做的所有事情。并且該 PDB 用戶會被從其他 PDB 中隔離出來,
并將也將無法看到 CDB 級別的信息。
2. CDB$ROOT
你的 SYSTEM 表空間有多大?在數據庫剛剛創建時,它差不就有幾個 GB
那么大了。對于數據庫創建,我們這里并不是指 CREATE DATABASE 語句,而
是指運行 catalog.sql 以及 catproc.sql(當然,在多租戶環境中,我們就不這樣稱呼
它們了,我們稱之為 catcdb.sql。實際運行的腳本還是一樣)。一個空數據庫的字
典表,也將會占用數 GB的空間,用來存儲字典結構以及系統包,它們都是 Oracle
軟件的一部分——ORACLE_HOME 下的二進制文件——但它們是以存儲過程
和包的形式部署在數據庫中的。如果在一臺服務器上部署 50 個數據庫,那么就有
50 個 SYSTEM 表空間并存儲同樣的內容(假設它們的版本和補丁號都一樣)。如果
想對數百個或數千個數據庫進行集成, 正如對 PDB 所做的那樣, 你可能不想對每
一個數據庫都存儲同樣的內容。可以將所有的公共數據只存儲在一個容器中,
并讓其他容器共享這些內容。這就是 CDB$ROOT:它是一個 CDB 中唯一的非
PDB 容器,用來存儲 PDB 之間的所有公共信息。
基本上, CDB$ROOT 將會存儲所有的字典表、 字典視圖、 系統包(以 dbms_
開頭)以及系統用戶(SYS、 SYSTEM 等)——并且不再存儲其他內容。不要在
CDB$ROOT 中存儲用戶數據。如果需要,可以在所有的 PDB 中創建自己的用
戶。關于公共用戶,可以在第 6 章中了解更多信息。
也可將 CDB$ROOT 視為 ORACLE_HOME 的擴展。它是數據庫軟件的一
部分,并存儲于數據庫中。它與 ORACLE_HOME 的版本相關,只要版本相同,
那么所有 CDB 中的 CDB$ROOT 都是一樣的。 12.2.0.1 版本中的 CDB$ROOT
與你的數據庫基本也是一樣的。
3. PDB$SEED
多租戶數據庫 CDB 的目的是創建多個 PDB。不僅如此,還應該能夠根據
需要,簡單快速地創建 PDB。這也是 DBaaS(DataBase as a Service,數據庫即服
務)架構所關注的。如何通過 DBCA 來快速創建一個數據庫?可以通過一個包
含所有文件的模板來創建數據庫。如果能夠克隆一個現成的空數據庫,那么就
不再需要去重新創建所有的東西了(正如 catalog.sql 和 catproc.sql 所做的)。 這就
是 PDB$SEED: 它是一個空的 PDB, 可以對它進行克隆, 從而創建另外的 PDB。
不能對它進行修改,因為它是只讀的,只能將它作為一個新 PDB 的源頭。
一個 CDB 最少包含一個 CDB$ROOT 容器和一個 PDB$SEED 容器。不能
對它們進行修改,只能使用它們。只有在對 CDB 進行升級或打補丁時,它們
的結構才會發生變化。
1.2.3 多租戶字典
多租戶架構的目的之一,就是將系統元數據從應用程序元數據中分離出來。
系統元數據, PDB 之間所有的公共信息,都存儲在 CDB$ROOT 中,稱為系統
對象。例如,包的定義,存儲在字典表 SOURCE$中,我們可以通過查詢
DBA_SOURCE 視圖來獲取這些內容。在一個非 CDB 中,該表則存儲了系統包
和你自己創建的包——有的包由 SYS 擁有,有的則由應用程序方案擁有;就讓
我們叫它 ERP 吧。在多租戶環境中, CDB$ROOT 只包含系統元數據,因此在
前面的例子中,這也就意味著這些都是 SYS 包。
在我們指向應用程序的 PDB 中,我們稱其為 PDBERP, SOURCE$中將會
只包含我們應用程序的包,也就是 ERP 的包。讓我們看一個例子。我們使用
CDB$ROOT 并統計 SOURCE$中的行數。我們將其與 DBA_OBJECTS 進行關
聯,從而顯示出哪些是 Oracle 管理的對象(系統對象):
SOURCE$中所有的行都是 Oracle 管理的對象,也就是系統包。
現在我們在 PDB 中看一眼:

這里的結果就不是系統包了,而是應用程序創建的包。當然,在你的環境
中,可能查詢結果會有所不同。但是這個例子,基本上已經顯示出了多租戶環
境下,字典信息是如何分離的:在非 CDB 中,元數據存儲于同樣的字典表中,
但是現在存儲到了不同的容器中,從而讓 Oracle 元數據與應用程序元數據分離
開來。注意,這與分區不同,對于字典表來說,它們倒更像是不同的數據庫。
1. 字典視圖
你知道我們為什么查詢 SOURCE$而不是 DBA_SOURCE,假設它們能夠提
供同樣的結果嗎?檢查如下內容:

在 CDB$ROOT 中,這與上面查詢得到的行數相同。但是在 PDB 中:
這里,我們看到有更多的行數。實際上,我們是從 CDB$ROOT 中看到的
這些行。這里有兩個原因。首先,我們說存儲在 CDB$ROOT 中的是公共信息,
因此在 PDB 中顯然也能夠看到這些信息。其次,我們說當一個用戶連接到一個
PDB 時,該用戶在一個獨立的數據庫中能看到什么,在一個 PDB 中就也應該
能看到什么。而在一個獨立的數據庫中,基于 DBA_SOURCE 的查詢應該顯示
所有的內容,包含系統的以及應用程序的。但是在查詢 SOURCE$時則不是這
樣。當然你也不希望這樣。只有視圖記錄下了這些信息,并且你會期望去查詢
這些視圖。
PDB 中的字典視圖,提供了 PDB 的信息,以及來自 CDB$ROOT 的信息。
它不是分區,也不是一個數據庫鏈接。我們將在接下來的部分看看 Oracle 是如
何進行處理的。
當連接到 CDB$ROOT 時, DBA_SOURCE 視圖將會只顯示容器中的信息。
但是新的以 CDB_開頭的視圖,則會顯示所有容器中的內容,你將在本節后面
1.2.4 節的“5. 容器中的字典視圖”部分看到這一點。
因此,從物理上來說,這些字典信息是分離的。每一個容器都存儲各自用
戶對象的元數據,根容器則存儲公共部分——主要是系統元數據。從邏輯上來
說,從這些視圖中,我們可以看到所有的信息,因為我們在非 CDB 中就可以
看到, PDB 顯然應該兼容這一點。
2. 元數據鏈接
Oracle 引入了一種新的方式,來將一個容器中的對象鏈接到其他容器:元
數據鏈接。每一個容器都擁有所有的字典對象(存儲在 OBJ$中并且可以通過
DBA_OBJECTS 訪問到),例如前面的例子中用到的系統包名稱。但是更多的對
象定義信息(例如包的代碼文本)并非存儲在所有的容器中,而是只存儲在
CDB$ROOT 中。在 OBJ$中,每一個容器都有一個標識,這可以通過 DBA_
OBJECTS 中的 SHARING 列得到。當需要獲取某個對象的定義信息時,該標志
就會告訴 Oracle,這些信息需要切換到 CDB$ROOT 容器去獲取。
如下是一些關于這些包中的某個包的信息,所有的容器都包含相同的定義
信息,查詢 CDB$ROOT 的 DBA_OBJECTS:
如下信息則是從 PDB 中查詢得到:
可以看到,這些對象都具有相同的名稱和類型,并且都定義為 Oracle 管理的,
SHARING 列也都為 METADATA LINK。它們有不同的對象 ID。在對它們進行
鏈接時,只需要使用名稱和內部標簽。根據這些內容,我們就可以知道,這些
對象都是系統對象(Oracle 管理的),因此當我們在 PDB 中查詢這些對象時,
Oracle 就會知道需要切換到根容器來獲取它們的信息。這就是元數據鏈接的具
體處理行為。字典對象往往都比較大,因此只會存儲在 CDB$ROOT 中。但是
它們可以通過字典視圖,從而在任意位置都可以訪問到。
這與元數據有關。對于應用程序而言,相關的元數據則會存儲在對應的
PDB 中。 Oracle 管理的對象則存儲在 CDB$ROOT 中。后者是靜態信息:它們
只有在對數據庫進行升級或打補丁時才會更新。可以看到,這樣做的好處,一
是可以降低信息的重復程度,二是能夠加快 PDB 升級的速度,因為 PDB 中只
是一些鏈接罷了。
圖 1-3 顯示了字典信息是如何分離的,當然也是對前面圖 1-2 的簡單擴展。
3. 數據鏈接(在版本 12.1中稱為對象鏈接)
當然,在字典中不僅僅只有元數據。在 CDB 級別,多租戶數據庫也會存
儲一些數據。這里是一個簡單的例子。假設 CDB 需要維護一個容器列表,并
將其存儲在系統表 CONTAINER$中然后可以通過字典視圖 DBA_PDBS 進行訪
問。這些數據可以更新,從而用來存儲容器的狀態信息。但是,這些數據雖然
只在 CDB 級別才有意義,不過所有的 PDB 都可以訪問得到。下面我們就來看
看是如何共享這些信息的。

Oracle Database 12cR2多租戶權威指南

圖 1-3 系統與用戶元數據的分離
先查詢 CDB$ROOT:
然后查詢 PDB:
可以看到,訪問 CONTAINER$的視圖,實質上是一個數據鏈接。這就意味
著,當有會話來執行這些查詢時,其實信息是從 CDB$ROOT 獲取到的。實際
上, CONTAINER$表在所有的容器中都存在,但是只有在根容器中是真正存儲
數據的,其他都是空的。
1.2.4 使用容器
既然有了這么多的 PDB,那么如何使用它們?可以從識別它們開始。
1. 通過名稱和 ID 來識別容器
一個集成的 CDB 中,可以包含多個容器,它們可以通過名稱和數字,也
就是 CON_ID 來進行識別。在 12c 版本中,所有用來顯示一個實例中包含哪些
對象的 V$視圖,都額外添加了一列,用來顯示 CON_ID,以便標記對象屬于哪
一個容器。 CDB 本身就是一個容器,其容器 ID 為 CON_ID=0。被標記為
CON_ID=0 的對象,都是 CDB 級別的對象,并且不會關聯到其他容器。
例如,如下是我們在根容器中查詢 V$DATABASE 后得到的信息:
下面則是在 PDB 中執行查詢:
如果在不同的容器中執行上述查詢,結果可能也會有所不同。但是無論哪
種情況,所獲取到的數據庫信息,都只是 CBD 級別的。該視圖中包含的信息
來自于控制文件,你將看到這些其實就是公共信息,因此 CON_ID 被設置為 。
如果是非 CDB,那么對于所有的對象而言, CON_ID 都為 。但是如果是在一
個多租戶架構中,那么大部分對象都屬于特定容器。
任一 CDB 環境中,第一個容器都是根容器,名為 CDB$ROOT,并且
CON_ID=1。其他所有的容器都是 PDB。
任一 CDB 中的第一個 PDB,都是種子容器,名為 PDB$SEED。因為它是
CDB 中的第二個容器,所以 CON_ID=2。
CON_ID>2 的容器,就是用戶 PDB。在版本 12.1 中,可以創建額外的 252

個 PDB。在版本 12.2 中,則為 4096 個 PDB。
2. 容器列表
字典視圖 DBA_PDBS列出了所有的 PDB(所有的容器,除了根容器)及其狀態:
對于 PDB 而言,當剛剛創建時,其狀態為 NEW,并且在第一次將其以讀/
寫方式打開時,其狀態調整為 NORMAL,因為在第一次打開 PDB 時,需要進
行一些相關操作。狀態為 UNUSABLE 表明該 PDB 創建失敗,并且唯一允許的
操作是將其刪除。狀態為 UNPLUGGED,則表明該 PDB 將會被傳輸到其他
CDB,而在源 CDB 上,唯一能做的操作,就是將該 PDB 刪除。
在版本 12.1 中,可以看到 NEW 這樣的狀態,此外還有其他一些狀態:NEED
UPGRADE,表明該 PDB 來源于其他版本的數據庫; CONVERTING,表明其
來自于一個非 CDB。當然,還有其他三種狀態: RELOCATING、 REFRESHING
以及 RELOCATED。我們將在第 9 章討論這些內容。
如下信息是從數據庫字典中查到的。我們可以通過實例來列出容器的信息,
這里顯示了其打開的狀態:
在非 CDB 中, MOUNTED 狀態表明當前控制文件已經被讀取,但是數據
文件還沒有被實例進程打開。這里查詢到的結果與之頗為類似:一個處于關閉
狀態的 PDB,其數據文件為未打開狀態。 PDB 沒有 NOMOUNT 狀態,因為控
制文件是公用的。
要注意,無論是 SQL*Plus 還是 SQL Developer,都有一種快捷方式,可以

用來顯示當前的 PDB。如果正處于根容器中,還可以顯示所有的 PDB:
3. 通過 CON_UID 和 DBID 來識別容器
可以看到,除了容器的名稱,還可以通過 ID 或 CDB 中的 CON_ID 來識別
容器。但是,當移動 PDB 時,其 CON_ID 將會發生變化。基于這個原因,還需要
一個唯一的標識符 CON_UID。該號碼在 PDB 發生移動時也依然可以用來標識
PDB。 CDB$ROOT 是一個容器但不是 PDB,并且它也不會移動,因此其 CON_UID
為 1。
基于數據庫的兼容性考慮,每個容器都有一個 DBID。 CDB 的 DBID 就是
CDB$ROOT, PDB 的 DBID 則為 CON_UID。
另外,每一個容器都還有一個 GUID:一個包含 16 個字節的 RAW 值。它
在 PDB 創建時生成,并且永遠都不會再改變。當使用 OMF(Oracle Managed
Files, Oracle 管理的文件)時, GUID 被用于目錄結構,并作為 PDB 的唯一標識
符。
所有這些標識符都存儲于 V$CONTAINER 中,當然也可以使用這些函數來獲
取一個容器的 ID: CON_NAME_TO_ID、 CON_DBID_TO_ID、 CON_UID_TO_ID
以及 CON_GUID_TO_ID。如果容器不存在,就返回 null 值,如下是一些例子:
4. 連接到容器
前面我們對多租戶的分析, 是將其作為突破方案集成限制的一種方法來進行
討論的。那么問題來了,如何在多個方案之間進行切換?而不是使用方案用戶進
行直接連接?這里,可以使用 ALTER SESSION SET CURRENT_SCHEMA。
當然,也可以直接連接到一個 PDB,但是這部分內容我們將在第 5 章進行
討論。這些內容與服務有關,并且這是從用戶或應用程序連接到 PDB 的正確做

法。但是現在,你已經連接到了 CDB,可以使用 ALTER SESSION SET
CONTAINER 命令,從而簡單地將會話切換到一個新的容器。
現在,我們已經連接到了 CDB$ROOT:
我們來改變一下當前容器:
現在我們就在 PDB 中了:
事務 如果在一個容器中開啟了一個事務,那么將無法在其他容器中開啟
另外的事務。
可以離開當前事務,并切換容器:
但是現在無法執行 DML 語句,因為它需要一個新的事務:
首先,需要回到原來的容器并結束事務:
然后可以在另外的容器中開啟一個新的事務:
游標 如果在一個容器中打開了一個游標,將無法在另一個容器中對該游
標進行獲取操作。需要回到游標所在的容器并進行獲取:
基本上,從一個容器切換到另外一個容器往往是很容易的。但是在不同的
容器中進行的操作,則是相互隔離的,并且以前容器中的狀態是無法共享的。
例如,我們連接到 PDB1,設置 serveroutput 為 on,然后使用 dbms_output
命令:
dbms_output 產生了輸出,可以看到 USERENV 顯示了當前的容器名稱。
現在我們切換到 PDB2:
這里就沒有任何輸出結果了。 serveroutput 只是在 PDB1 中進行了設置,我
們需要在 PDB2 中也進行設置:
現在我們回到 PDB1:
這里就不需要再次設置 serveroutput 了。當我們切換回來時,我們重新獲取
了原來 PDB 中的狀態。
使用 JDBC 或 OCI 我們的例子是在 SQL*Plus 中運行的,但是其他客戶
端就不能這么做了。當使用一個在根容器中進行定義的用戶(公共用戶),并且
該用戶也被授予 PDB 的 SET CONTAINER 系統權限時,就可以切換到這個
PDB。可以使用 JDBC(Java DataBase Connectivity )或 OCI(Oracle Call Interface)
來完成這個操作。例如,可以在應用服務器上配置一個連接池,這樣在拿到連
接時,就可以將連接切換到所需的容器。當為數據庫多租戶創建公共應用服務
器時,這種方法是值得考慮的。
注意:
12.2 PDB 12.2 ORA-24964:ALTER SESSION SET CONTAINER 設置容器觸發器 基于某些理由,如果想在一個會話進行容器切換時執行某
些動作,例如設置不同的優化器參數,那么可以創建 BEFORE SET CONTAINER
和 AFTER SET CONTAINER 觸發器。
如下是這些觸發器的工作機制:
● 在 PDB1 中創建 BEFORE SET CONTAINER 觸發器, 當處于 PDB1 中,
然后執行 ALTER SESSION SET CONTAINER 時就會觸發。如果觸發
器讀取到了容器的名稱,那就是 PDB1。
● 在 PDB2 中創建 AFTER SET CONTAINER 觸發器,當執行 ALTER
SESSION SET CONTAINER=PDB2 時就會觸發。

這就意味著,如果在 PDB1 和 PDB2 中分別創建 before 和 after 觸發器,那
么當從 PDB1 切換到 PDB2 時,這兩個觸發器都會分別觸發。
這是 PDB 中兩種不同的工作方式。也可以通過服務來連接到容器,我們將
在第 5 章討論這些內容。此時,在會話開始時,就可以使用 AFTER LOGON ON
PLUGGABLE DATABASE 觸發器執行某些代碼。或者,也可以使用 SET
CONTAINER,然后使用 AFTER SET CONTAINER ON PLUGGABLE DATBASE
觸發器。當一個用戶在 PDB 中工作時,如果想對這些會話進行某些確定的設置,
那么前面說的這兩項操作就都需要進行定義。要注意這里的 PLUGGABLE 單詞
并不是必需的,因為這里的語法與數據庫的行為是兼容的。
5. 容器中的字典視圖
PDB中包含了所有你想從一個數據庫中看到的內容。這就意味著對一個PDB
中的字典視圖進行查詢,其結果應該與對一個數據庫進行查詢所返回的結果一
致。你同樣也擁有 DBA_/ALL_/USER_視圖,用來獲取 PDB 中對象的元數據。
那些對象,要么有權限去訪問,要么是你自己創建的。事實是,系統對象存儲在
什么地方是透明的:可以在 DBA_OBJECTS 中看到系統對象,在 DBA_TABLES
中看到系統表,以及在 V$視圖中看到實例信息。但是你所看到的行,都跟你當
前所在的 PDB 相關。
當處于 CDB$ROOT 中時,就可以看到 CDB_視圖。這些視圖就像是所有
打開容器中 DBA_視圖的 UNION ALL 結果。 這是一個 CDB 數據庫管理員可以
使用的方法,從而查看所有的對象。對于 CDB$ROOT 的用戶, V$視圖將會顯
示所有容器內的信息。
最后,你可能想知道,你是在非 CDB 環境中還是在多租戶環境中。
V$DATABASE 中的 CDB 列為你提供了答案:
1.3 什么是 CDB 級別的集成
對于集成而言,實現共享資源的公共性是其主要目標。在實例與字典之上,
很多數據庫結構都是在 CDB 層面進行管理的。我們這里并不討論數據文件,
因為它們被指定到每一個容器上。并且它們之間唯一的共同之處就是必須擁有
相同的字符集(除了在將一個容器從另外一個 CDB 中傳輸過來時, 當然這一點我
們要到第 9 章才進行討論)。在一個容器數據庫中,其他類型的文件都是公共的。

SPFILE
對于所有容器而言,數據庫實例是公用的, SPFILE持有該實例的相關參
數,并為整個 CDB 進行屬性設置。 SPFILE 包含的設置,無法存儲在數據庫或控
制文件中,因為這些設置必須在數據庫處于 mount 狀態之前就可用才行。
有些參數可以在 PDB 級別進行設置(在 V$PARAMETER 中,這些參數的
ISPDB_MODIFIABLE 列為 TRUE)。對這類參數的修改當然也可以持久保存下
來。但是在修改這些參數時,即便在語法上設置 SCOPE=SPFILE,這些 PDB
級別的參數實際也會存儲在 CDB 的字典表(即 PDB_SPFILE$)中。它們不會存
儲在自身的 PDB 中,因為這些參數必須在打開 PDB 之前就能夠訪問。在稍后
我們將會看到,當移動一個 PDB(插入/拔出)時,這些參數將會被抽取出來存放
到一個 XML 文件中,并隨著 PDB 的數據文件一起被傳輸。
控制文件
控制文件與數據庫中的所有其他結構都有關系。例如,控制文件是唯一真
正存儲數據文件名稱的地方,在字典表中為 FILE_ID 列,只是對具體位置的引
用而已。在多租戶環境中,控制文件位于 CDB 級別,并持有所有 PDB 的數據
文件信息。可以在第 9 章中看到這些與 PDB 相關的內容,即當一個 PDB 被拔
出/插入時,所有與該 PDB 相關的數據文件信息,也會被從控制文件中導出,
然后存儲到一個 XML 文件中。
注意:
(control files) 當討論數據文件時,有一個初始化參數可以用來控制一個實例可以打開的
最大文件數量。就是 DB_FILES,其默認值為 200。要注意,如果想創建數百
個 PDB,那么很快就會達到這一限制。到時候就無法再創建新的表空間或 PDB
了,除非重啟實例。在多租戶環境中,重啟實例意味著會引起很多應用的停機
操作。因此應該避免這一點。故而,當打算在容器中管理多個 PDB 時,不要忘
記對 DB_FILES 參數進行正確設置。
UNDO
在版本 12.1 中,即第一個帶有多租戶架構的 Oracle 數據庫版本中, UNDO
表空間是公共的,并且處于 CDB 級別。但是在版本 12.2 中,我們有了新的選
項,可以在本地 UNDO 模式下運行 CDB。如果 LOCAL UNDO 被設置為 on,
則每一個 PDB 都擁有自身的 UNDO 表空間, 并且當所有會話往 PDB 的數據塊
中寫數據時,其 UNDO 信息都會被存儲到該 PDB 本地的 UNDO 表空間中。只

有在 CDB$ROOT 中執行的修改操作, 才會將 UNDO 信息記錄到 root 的 UNDO
表空間中。
簡單點說,如果可能的話,將 CDB 運行在本地 UNDO 模式下比較好。UNDO
中包含了應用數據,并且如果我們將這些數據存放到公共的 UNDO 文件中的
話,我們就無法實現 PDB 的隔離了。一個需要使用本地 UNDO 模式的原因,
就是當我們打算進行 PDB 的快速閃回或是基于時間點的恢復時。我們將在第 8
章解釋這些內容。
臨時表空間
臨時表空間可以在 CDB 或 PDB 級別創建。如果某個 PDB 中的用戶在運行
會話時沒有指定臨時表空間,并且該 PDB 也沒有默認的臨時表空間,該會話將
會使用 CDB 的臨時表空間。但這不是推薦的做法。我們可以為 root 的臨時表
空間設置限額(MAX_SHARED_TEMP_SIZE),從而控制 PDB 對它的使用。
當需要分配工作區,從而完成對對象鏈接視圖的遞歸查詢時, CDB$ROOT
的臨時表空間一般都由連接到根容器的會話使用, 或者由來自一個 PDB 的會話
使用。
當將一個臨時表空間設置為默認的臨時表空間時,如果是你創建了該
PDB,那么你也可以指定其他的臨時表空間為默認的臨時表空間。但是在此之
后,你就無法將 CBD 的臨時表空間設置為該 PDB 的默認臨時表空間了。
重做日志
重做日志是用來保護實例的,因此,它們也是公共的。重做日志的主要用
途,是對 buffer cache 中所有的修改進行記錄,并確保這些所有已提交事務的更
改能夠持久保存下去。
多租戶環境下的 REDO 數據流與之前版本中的類似,除了在每一條 REDO
記錄中都要添加額外的信息用來標記容器之外。并且對于恢復操作而言, REDO
數據的格式也極為關鍵,基于此, Oracle 很少去改變這些東西。
使用統一的 REDO 線程來處理所有的 PDB,對于 DBA 管理 CDB 而言,
也是頗有益處的。在非 CDB 環境中,當打算準備一個新的數據庫時,將會花
費很多時間和精力去設置恢復區大小、建立備份,以及創建并配置 Data Guard
物理備庫,如果使用了的話。但是在多租戶環境下,類似的工作,只需要做一
次就夠了,也就是 CDB。因為這就是與數據庫可用性相關的功能匯聚的地方:你
的備份、 Data Guard 以及 RAC 配置。可以簡單地創建一個新的 PDB,并從這個
已經配置好可用性的環境中受益:它會隨著 CDB 進行自動備份,自動在物理
備庫中創建(當然這里需要使用 Active Data Guard), 以及能夠自動被所有 RAC
實例訪問。再強調一次,這就是因為用來實現數據庫可用性的關鍵架構——
REDO 數據流,都是在 CDB 級別進行運作的。

但是,如果只使用一個 REDO 數據流,有時候也會導致性能問題。如果曾
經遇到過與日志寫相關的性能問題,例如基于“log file sync”事件的長等待,
那么就可以想象出,當 LGWR 進程需要進行所有 PDB 的 REDO 寫操作時,會
發生什么事情。其結果就是,如果 LGWR 無法跟上 REDO 的生成速度,那么
當用戶執行提交操作時,就不得不進入等待狀態。
因此,基于 LGWR 的可擴展性考慮, Oracle 在 12c 版本中引入了多線程
LGWR 結構。這里, LGWR 是一個協調進程, 然后有多個從屬進程(LG00、 LG01
等)與之相關聯。這樣,實例的 REDO 數據流就可以采用并行方式進行數據寫
操作。當然, RAC 仍然是另一種實現 REDO 并行處理的方式。需要牢記在腦
海中的是,在多租戶環境中,調整 LGWR 以及 REDO 寫的數量是至關重要的。
當進行集成時,需要對存放 REDO 日志的磁盤性能加以特別關注。
數據文件
存儲在表空間數據塊中的數據文件,屬于各自的容器,但它們也同樣為
CDB 所管理。對于 CDB 而言,這些數據文件都有唯一的標識符,也就是
FILE_ID:
relative file number,中文為相對文件編號,是隨著可傳輸表空間被引入進
來的。因此在 12c 以前的版本中,這個特性已經存在相當一段時間了。多租戶
環境下,在 PDB 中,數據文件是通過表空間編號和該文件在表空間中的相對文
件編號(RELATIVE_FNO)進行標識的。此外,當進行文件的移動、克隆或插入
到 PDB 中時,文件編號的修改都不是必需的。只有絕對文件編號(FILE_ID)會
被重新編號,從而確保其在 CDB 中的唯一性——但是在控制文件和數據文件

頭中,這個重新編號的動作,是極其快速的。
CDB 級別的數據與元數據
至此,我們已經解釋了與系統對象相關的字典,它們存儲在 CDB$ROOT
的 SYSTEM 和 SYSAUX 表空間中。它們是公共的,并且可以被 PDB 訪問。但
是除了這些基礎的數據庫對象(由 catalog.sql 和 catproc.sql 創建)外, 還有更多的
公共信息也都存儲在根容器中。
1. APEX
默認情況下,一旦安裝了 APEX(在版本 12.2 中,可以選擇該組件),它就
處于 CDB 級別。 APEX 與系統字典類似,它們都用來存儲元數據,并且不需要
安裝在 PDB$SEED 或其他 PDB 中。但是,這種方式有一個非常大的缺點:在
你的 CDB 中,只有一個 APEX 版本。并且當想在該 CDB 中插入一個運行 APEX
5.0 版本的非 CDB 時,將會遇到問題。例如,在 Oracle 云服務中,當前的 CDB
上安裝的是 APEX 4.2 版本。
注意:
Mike Dietrich blogs.oracle.
com/UPGRADE/entry/apex_in_pdb_dose_not
APEX 5.0 Oracle APEX PDB Oracle Application
Express(APEX)
2. AWR
AWR(Automatic Workload Repository,自動工作量資料檔案庫)從實例的動
態視圖中收集大量的信息(統計信息、等待事件等)。在多租戶環境下,這些是
在 CDB 級別完成的。只有一個 job 用來收集所有容器的所有統計信息,并存儲
在 CDB$ROOT 中。這就是對象鏈接視圖——AWR 視圖(以 DBA_HIST 開頭)
主要的應用案例。它們可以由每一個 PDB 進行查詢,但是讀取的數據實際上是
存儲在根容器中的。
因此,這里有兩個重要的結論。其一,如果移動了一個 PDB,那么 AWR
歷史數據將不會隨之移動;相反,它將仍然保留在原始的 CDB 中。可以使用
原來的數據庫讀取這些視圖,或者在他處將其導出。但是存儲在 AWR 中的
CON_ID,應該是生成快照時的容器 ID,因此需要你去檢查 CON_DBID,從而
確認某一指定的 PDB。在每一個以 DBA_HIST 開頭的視圖中,實際上有三個
不同的標識符:
● DBID是 CDB的 DBID,這與非 CDB環境中的一樣。該標識符與 SNAP_ID
和 INSTANCE_NUMBER 一起,可以用來確定唯一的快照。

● CON_ID 是容器 ID,是生成快照時所查詢的 V$視圖所在的容器 ID。
視圖中有些行可能不與任意容器相關聯,此時 CON_ID=0。其他行則
記錄了某個容器對象的統計信息,因此在生成快照時,就記錄下了相
應的 CON_ID。
● CON_DBID 用來唯一標識一個 PDB,它和 DBID 用來唯一標識一個數
據庫一樣。
對于在 CDB 級別收集統計信息的 AWR 而言,第二個結論是:當在 PDB
級別運行 AWR 報告時,它只會過濾出與你的容器相關的統計信息,并且與查
詢 PDB 中 V$視圖得到的信息一樣。但是你仍然需要知道,在同一份 AWR 報
告中,還是可以看到一些在 CDB 級別收集的統計信息(這些行的 CON_ID=0)。
這就意味著,例如,可以在 AWR 的實例統計信息部分,看到實例所完成的邏
輯讀的數量,但是在展示具體的細節(在 SQL 部分或段部分)時,只會顯示與你
的 PDB 相關的信息。讓我們看一個例子。
在閱讀 AWR 報告的細節之前,我們通常會檢查一下大部分被捕獲的 SQL
語句,因為如果我們不打算去研究 SQL 語句的細節的話,這樣的動作就沒有必
要繼續了。如下是一份 AWR 報告中的 SQL ordered by Gets 部分:
這里顯示捕獲了 89%的 SQL 語句,并且我們知道,當我們想去研究高邏輯
讀問題時,我們有了所需的細節。如果該比例比較低,那么通常意味著我們生
成的報告,覆蓋了一個太大的時間窗口。因此大部分 SQL 語句在 end snapshot
之前都已經由于超時而被移出共享池了。但是,當在一個 PDB 上運行 AWR 報
告時,也可以看到另外一個原因:

這里看不到任何區別,除了只捕獲了 21%的 SQL 語句。需要檢查 AWR 報
告的頭部,來看看它是否只覆蓋了一個 PDB。事實上我們有兩個 PDB 在此時
處于活動狀態,如下是另外一個 PDB:
從一個 PDB 中,沒有辦法確認該 PDB 所有的 SQL 語句是否都已被捕獲。
對于該 PDB 而言,沒有類似總的邏輯讀這樣的統計信息。
注意:
12.1 PDB V$CON_
SYSSTAT
ARW 12.2 DBA_HIST_CON_SYSSTAT (DBA_HIST_CON_SYS_TIME_MODEL) (DBA_HIST_CON_ SYSTEM_
EVENT)
12.2 AWR statspack 如果沒有診斷包,那就無法使用 AWR,可以安裝 statspack。通
過查閱相關文檔(spdoc.txt),可以知道 statspack 只能在 PDB 級別進行安裝。當
然,我們認為在 CDB 級別安裝也是有用處的,因為你會想去分析一下
CDB$ROOT 的活動情況。每一個想要收集快照的 PDB 都將存儲其自身的統計
信息。因為現在統計信息是在 PDB 級別被收集的,所以相關的行為就與 AWR
不同。我們在與前面例子中相同的時間點獲取 statspack 的快照,此時,從
spreport.sql 中讀到的信息如下:當報告運行在 CDB$ROOT 上時,會話邏輯讀
的數值為 24 956 570;在其中一個 PDB 上運行時,數值為 5 709 168(22%);在
另外一個 PDB 上數值為 17 138 586(68%)。當在根容器上運行時, statspack 收
集與該 CDB 相關的統計信息,而在 PDB 上運行時,則收集該容器的統計信息。
1.4 本章小結
在前面長長的介紹中,我們已經解釋了在 2013 年, Oracle 為何要在版本
12c 中引入多租戶特性。我們已經看到了不同的集成選項,當然你也可能認為
并不需要在多租戶環境下運行應用。但是,這種新的架構將來會成為 Oracle 唯
一支持的數據庫架構,原有的非 CDB 架構正在被拋棄。因此,即便現在不想
在一個實例上運行多個 PDB,也得運行我們稱之為“單租戶”的數據庫(我們
將在第 3 章討論這一點),并且也不得不管理容器數據庫。
除了集成,新的架構也將應用數據與元數據從系統字典中分離開來,從而
為數據移動和位置透明提供更強大的敏捷性。這些我們將在第 9 章進行探討。
下一章,將從創建一個集成數據庫開始。

購買地址:

https://item.jd.com/12393662.html


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

拜泉县| 龙胜| 卢龙县| 广州市| 铁岭市| 宁蒗| 仁化县| 霍山县| 墨玉县| 莱州市| 黔西县| 吉安县| 射洪县| 阜康市| 广丰县| 盐池县| 乳源| 靖宇县| 遂平县| 渝北区| 梁平县| 文山县| 江油市| 修文县| 麻江县| 南丹县| 安顺市| 蚌埠市| 兴城市| 松原市| 兴文县| 临清市| 龙泉市| 麻栗坡县| 蕲春县| 鄂托克旗| 陕西省| 赣州市| 阿克苏市| 射洪县| 乐都县|