溫馨提示×

溫馨提示×

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

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

Oracle Database 12cR2多租戶權(quán)威指南

發(fā)布時間:2020-08-10 21:36:53 來源:ITPUB博客 閱讀:332 作者:qinghuawenkang 欄目:關(guān)系型數(shù)據(jù)庫


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.
版權(quán)所有。未經(jīng)出版人事先書面許可,對本出版物的任何部分不得以任何方式或途徑復(fù)制或傳播,
包括但不限于復(fù)印、錄制、錄音,或通過任何數(shù)據(jù)庫、信息或可檢索的系統(tǒng)。
本授權(quán)中文簡體字翻譯版由麥格勞-希爾(亞洲)教育出版公司和清華大學(xué)出版社有限公司合作出版。
此版本經(jīng)授權(quán)僅限在中國大陸區(qū)域銷售,不能銷往中國香港、澳門特別行政區(qū)和中國臺灣地區(qū)。
版權(quán)?2018 由麥格勞-希爾(亞洲)教育出版公司與清華大學(xué)出版社有限公司所有。
北京市版權(quán)局著作權(quán)合同登記號 圖字: 01-2017-3077
本書封面貼有 McGraw-Hill Education 公司防偽標(biāo)簽,無標(biāo)簽者不得銷售。
版權(quán)所有,侵權(quán)必究。侵權(quán)舉報電話: 010-62782989 13701121933
圖書在版編目(CIP)數(shù)據(jù)
Oracle Database 12
R2 多租戶權(quán)威指南 / (新西蘭)安東·艾爾斯(Anton Els), (捷克)維特·斯
普林克(Vít ?pinka), (瑞士)弗蘭克·帕丘特(Franck Pachot) 著;史躍東 譯. —北京:清華大學(xué)
出版社, 2018
書名原文: Oracle Database 12
Release 2 Multitenant
ISBN 978-7-302-50251-7
Ⅰ. ①O… Ⅱ. ①安… ②維… ③弗… ④史… Ⅲ. ①關(guān)系數(shù)據(jù)庫系統(tǒng)-指南
Ⅳ. ①TP311.138-62
中國版本圖書館 CIP 數(shù)據(jù)核字(2018)第 103253 號

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

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

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

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

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

第 1 章 多租戶概述 ······················3
1.1 歷史課堂: IT 技術(shù)的
新時代·································4
1.1.1 通往多租戶之路············ 5
1.1.2 方案集成 ······················· 6
1.1.3 表集成 ··························· 9
1.1.4 服務(wù)器集成 ··················· 9
1.1.5 虛擬化 ························· 10
1.1.6 一個實例管理多個
數(shù)據(jù)庫 ·························
10
1.1.7 集成策略總結(jié)·············· 11
1.2 系統(tǒng)字典與多租戶架構(gòu) ··· 11
1.2.1 過去:非 CDB············· 11
1.2.2 多租戶容器·················· 14
1.2.3 多租戶字典·················· 16
1.2.4 使用容器 ····················· 21
1.3 什么是 CDB 級別的
集成···································27
1.4 本章小結(jié) ··························33
第 2 章 創(chuàng)建數(shù)據(jù)庫 ····················35
2.1 創(chuàng)建容器數(shù)據(jù)庫(CDB) ····36
2.1.1 OMF 概述···················· 36
2.1.2 CDB 創(chuàng)建選項 ············ 37
2.2 創(chuàng)建可插拔數(shù)據(jù)庫
(PDB) ································52
2.2.1 使用 PDB$SEDD 創(chuàng)建
新的 PDB ····················
53
2.2.2 使用本地克隆方式創(chuàng)建
新的 PDB ····················
56
2.2.3 使用 SQL Developer
創(chuàng)建 PDB ····················
57
2.2.4 使用 DBCA 創(chuàng)建 PDB··· 60
2.2.5 使用 Cloud Control
創(chuàng)建 PDB ····················
61
2.3 使用 catcon.pl 腳本 ··········62
2.4 本章小結(jié) ··························64
第 3 章 單租戶、多租戶以及應(yīng)用
容器·······························65
3.1 多租戶架構(gòu)不是一個
選項 ··································66
3.1.1 拋棄非 CDB ················ 66
3.1.2 不兼容特性 ················· 67
3.2 標(biāo)準(zhǔn)版中的單租戶···········68
3.2.1 數(shù)據(jù)移動 ····················· 68
3.2.2 安全 ····························· 69
3.2.3 與 SE2 集成················· 69
3.3 企業(yè)版中的單租戶···········70
3.3.1 閃回 PDB····················· 71
3.3.2 PDB 的最大數(shù)量 ········· 71
3.4 使用多租戶選項···············73
3.4.1 應(yīng)用容器 ····················· 73
3.4.2 與多租戶選項集成 ······ 76
3.5 本章小結(jié) ··························77
第 4 章 日常管理 ·······················79
4.1 選擇要使用的容器···········81
4.2 管理 CDB ·························83
4.2.1 創(chuàng)建數(shù)據(jù)庫·················· 83
4.2.2 啟動與關(guān)閉數(shù)據(jù)庫 ······ 83
4.2.3 刪除數(shù)據(jù)庫·················· 84
4.2.4 修改整個 CDB············· 84
4.2.5 修改根容器·················· 85
4.3 管理 PDB··························86
4.3.1 創(chuàng)建新的 PDB ············· 86
4.3.2 打開和關(guān)閉 PDB ········· 86
4.3.3 查看 PDB 的狀態(tài) ········ 90
4.3.4 查看 PDB 的操作
歷史 ·····························
90
4.3.5 在多個 PDB 上運(yùn)行
SQL······························
90
4.3.6 修改 PDB····················· 91
4.3.7 刪除 PDB····················· 93
4.4 打補(bǔ)丁與升級···················93
4.4.1 升級 CDB ···················· 94
4.4.2 插入 ·························· 103
4.4.3 打補(bǔ)丁 ······················ 105
4.5 使用 CDB 級別與 PDB 級別
的參數(shù)·····························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 本章小結(jié) ························ 111
第 5 章 網(wǎng)絡(luò)與服務(wù) ··················113
5.1 Oracle Net ······················· 114
5.2 Oracle 網(wǎng)絡(luò)監(jiān)聽 ············· 114
5.3 LREG 進(jìn)程 ····················· 115
5.4 網(wǎng)絡(luò):多線程與
多租戶····························· 117
5.5 服務(wù)名稱 ························ 119
5.5.1 默認(rèn)服務(wù)與連接到
PDB ···························
119
5.5.2 創(chuàng)建服務(wù) ··················· 122
5.6 為 PDB 創(chuàng)建專用監(jiān)聽 ···127
5.7 本章小結(jié) ························130
第 6 章 安全·····························131
6.1 用戶、角色以及權(quán)限·····132
6.1.1 公共用戶還是本地
用戶? ·······················
132
6.1.2 何為用戶? ··············· 133
6.1.3 CONTAINER=
CURRENT·················
134
6.1.4 CONTAINER=
COMMON·················
135
6.1.5 本地授權(quán) ··················· 138
6.1.6 公共授權(quán) ··················· 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 禁用數(shù)據(jù)庫選項······· 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 透明數(shù)據(jù)加密(TDE) ······151
6.4.1 創(chuàng)建 TDE·················· 152
6.4.2 帶有 TDE 的插入與克隆
操作 ··························
157
6.4.3 TDE 總結(jié)·················· 157
6.5 本章小結(jié) ························157
第 7 章 備份和恢復(fù)··················161
7.1 回到基礎(chǔ)知識·················162
7.1.1 熱備份與冷備份······· 162
7.1.2 RMAN:默認(rèn)配置 ··· 164
7.1.3 RMAN 冗余備份······ 165
7.1.4 SYSBACKUP 權(quán)限··· 166
7.2 CDB 備份與 PDB 備份 ···166
7.2.1 CDB 備份 ·················· 167
7.2.2 PDB 備份··················· 171
7.2.3 別忘了歸檔日志! ···· 174
7.3 恢復(fù)場景 ························174
7.3.1 實例恢復(fù) ··················· 175
7.3.2 對 CDB 進(jìn)行還原和
恢復(fù)···························
176
7.3.3 對 PDB 進(jìn)行還原和
恢復(fù)···························
178
7.4 RMAN 優(yōu)化方面的一些
考量·································180
7.5 數(shù)據(jù)恢復(fù)指導(dǎo)·················183
7.6 塊損壞 ····························184
7.7 使用 Cloud Control 進(jìn)行
備份 ································184
7.8 本章小結(jié) ························186
第 8 章 閃回與基于時間點的
恢復(fù)·····························189
8.1 PDB 的基于時間點的
恢復(fù) ································190
8.1.1 在指定時間恢復(fù)
PDB ···························
191
8.1.2 UNDO 在哪里? ······· 193
8.1.3 版本 12.1 中的
PDBPITR 總結(jié) ··········
195
8.2 版本 12.2 中的本地
UNDO ·····························196
8.2.1 數(shù)據(jù)庫屬性 ··············· 197
8.2.2 創(chuàng)建數(shù)據(jù)庫 ··············· 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 進(jìn)行
閃回 ··························
205
8.4.3 使用共享 UNDO 進(jìn)行
閃回 ··························
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 本章小結(jié) ························215
第 9 章 移動數(shù)據(jù) ·····················217
9.1 錨定 PDB 文件位置 ·······218
9.2 插入與拔出 ····················218
9.2.1 PDB 的拔出與插入 ·· 219
9.2.2 停留在源庫中的已拔出
數(shù)據(jù)庫 ······················
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 克隆遠(yuǎn)程 PDB··········· 231
9.4 應(yīng)用容器的一些考量·····236
9.5 轉(zhuǎn)換非 CDB 數(shù)據(jù)庫·······236
9.5.1 插入非 CDB ·············· 237
9.5.2 克隆非 CDB ·············· 239
9.6 將 PDB 移動到云上 ·······240
9.7 基于 PDB 操作的
觸發(fā)器·····························241
9.8 全傳輸導(dǎo)出/導(dǎo)入············241
9.9 可傳輸表空間·················244
9.10 本章小
結(jié) ··························· 245
第 10 章 Oracle 數(shù)據(jù)庫資源
管理器························249
10.1 資源管理器基礎(chǔ)···········250
10.1.1 資源管理器關(guān)鍵
術(shù)語 ·······················
251
10.1.2 資源管理器的
需求 ·······················
253
10.1.3 資源管理器的
級別 ·······················
253
10.2 CDB 資源計劃··············254
10.2.1 資源分配與使用
限制 ·······················
254
10.2.2 默認(rèn)與自動任務(wù)
指令 ·······················
256
10.2.3 創(chuàng)建 CDB 資源
計劃 ·······················
257
10.3 PDB 資源計劃··············265
10.3.1 創(chuàng)建 PDB 資源
計劃 ······················
266
10.3.2 啟用或禁用 PDB 資源
計劃 ······················
268
10.3.3 移除 PDB 資源
計劃 ······················
269
10.4 使用初始化參數(shù)管理 PDB
的內(nèi)存和 I/O ················269
10.4.1 PDB 的內(nèi)存分配·· 269
10.4.2 限制 PDB 的 I/O··· 270
10.5 實例囚籠
(instance caging) ··········· 270
10.6 監(jiān)控資源管理器···········272
10.6.1 查看資源計劃與資源
計劃指令···············
272
10.6.2 監(jiān)控被資源管理器
管理的 PDB ··········
273
10.7 本章小結(jié) ······················274
第 11 章 Data Guard ···············275
11.1 ADG 選項·····················276
11.2 創(chuàng)建物理備庫···············277
11.2.1 使用 RMAN 進(jìn)行
復(fù)制 ······················
277
11.2.2 使用 EMCC 創(chuàng)建
備庫 ······················
289
11.3 在多租戶環(huán)境下管理
物理備庫 ······················292
11.3.1 在源端創(chuàng)建新的
PDB ······················
293
11.3.2 將 PDB 從源端
刪除 ······················
294
11.3.3 修改子集 ·············· 295 11.3.4 EMCC···················· 298
11.4 云上的備庫···················298
11.5 本章小結(jié)·······················301
第 12 章 在 PDB 之間共享
數(shù)據(jù)···························303
12.1 數(shù)據(jù)庫鏈接···················304
12.2 共享公共只讀數(shù)據(jù)·······305
12.2.1 可傳輸表空間········ 306
12.2.2 存儲快照與基于寫的復(fù)
制(copy on wirte) ···
307
12.3 跨 PDB 視圖·················308
12.3.1 簡單用戶表 ··········· 309
12.3.2 集成數(shù)據(jù) ··············· 313
12.4 跨數(shù)據(jù)庫復(fù)制···············327
12.5 本章小結(jié) ······················327
第 13 章 邏輯復(fù)制····················329
13.1 Oracle 日志挖掘器
(LogMiner)····················331
13.2 已過期的特性···············332
13.2.1 Oracle CDC··········· 332
13.2.2 Oracle 流技術(shù) ······· 332
13.2.3 Oracle 高級復(fù)制 ··· 332
13.3 OGG(Oracle
GoldenGate)··················333
13.3.1 OGG 中的多租戶
支持 ······················
333
13.3.2 大數(shù)據(jù)適配器······· 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 本章小結(jié) ······················347
多租戶意味著什么

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

Oracle Database 12cR2多租戶權(quán)威指南

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

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


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

Oracle Database 12cR2多租戶權(quán)威指南

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

這里的結(jié)果就不是系統(tǒng)包了,而是應(yīng)用程序創(chuàng)建的包。當(dāng)然,在你的環(huán)境
中,可能查詢結(jié)果會有所不同。但是這個例子,基本上已經(jīng)顯示出了多租戶環(huán)
境下,字典信息是如何分離的:在非 CDB 中,元數(shù)據(jù)存儲于同樣的字典表中,
但是現(xiàn)在存儲到了不同的容器中,從而讓 Oracle 元數(shù)據(jù)與應(yīng)用程序元數(shù)據(jù)分離
開來。注意,這與分區(qū)不同,對于字典表來說,它們倒更像是不同的數(shù)據(jù)庫。
1. 字典視圖
你知道我們?yōu)槭裁床樵? SOURCE$而不是 DBA_SOURCE,假設(shè)它們能夠提
供同樣的結(jié)果嗎?檢查如下內(nèi)容:

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

Oracle Database 12cR2多租戶權(quán)威指南

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

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

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

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

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

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

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

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

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

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

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

    購買地址:

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


    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI