閱讀432 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Oracle 12c新特性:多租戶中使用 CONTAINERS 語句跨越PDB查詢

640?tp=webp&wxfrom=5&wx_lazy=1
張樂奕

雲和恩墨副總經理,Oracle ACE總監,ACOUG 聯合創始人


在最新版本的 Oracle Database 12.1.0.2 中,新特性提供了 PDB Containers 子句,用以從 CDB$ROOT 層麵直接聚合查詢多個 PDB 中同一張表的數據。在新特性文檔中該段如下描述:

640?tp=webp&wxfrom=5&wx_lazy=1


但是實現起來並非看上去如此簡單。

現有測試環境如下:當前 CDB 中有 2 個 PDB,分別是 PDB1 和 PDB2;每個 PDB 中都有一個相同名字的 Local User,為 KAMUS;每個 KAMUS 用戶下都有一個 TT 表,表結構相同,數據不同。


首先按照想象,在 CDB$ROOT 中直接使用 SYS 用戶查詢,會報 ORA-00942 錯誤。

640?tp=webp&wxfrom=5&wx_lazy=1


這要求我們首先創建一個 Common User。並賦予其足夠的權限。賦予 select any table 權限是為了方便測試,在真實環境中你可能需要更精細地規劃權限。

640?tp=webp&wxfrom=5&wx_lazy=1


其次要求用 Common User 分別連接所有需要聚合查詢的 PDB,在其中創建一個與表名字相同的視圖。

640?tp=webp&wxfrom=5&wx_lazy=1


然後還需要在 Common User 中創建一個相同名字的空表,否則查詢仍然會報 ORA-00942 錯誤。

640?tp=webp&wxfrom=5&wx_lazy=1


隻需要創建一個名字相同的表,已經可以聚合查詢 count(*)了。但是如果在 SQL 語句中涉及到特定列仍會有問題。從報錯中透露的 P000 進程,可知 Oracle 在實現此過程中使用了並行查詢,不同的並行子進程在不同的 PDB 中查詢相關表,最後在 CDB 級別中的匯總顯示。

640?tp=webp&wxfrom=5&wx_lazy=1


因此可以將所有期望聚合查詢的列都加入到 C##KAMUS 用戶的TT表中,此處增加了 OBJECT_NAME 字段,可以看到特意在測試中增加了 number 類型的 OBJECT_NAME 字段,而 PDB 中的 OBJECT_NAME 字段均為 varchar2 類型,因此可見隻需列名稱相同即可,無需類型相同。

640?tp=webp&wxfrom=5&wx_lazy=1


從以上已經看出,如果更簡單,那麼在 C##KAMUS 中創建一個與 PDB 中 KAMUS.TT 表完全相同結構的空表即可。這裏用 impdp 來實現。

640?tp=webp&wxfrom=5&wx_lazy=1


查看執行計劃,在執行計劃中已經完全沒有顯示最終表的名稱,而是出現 X$CDBVW$ 這樣的 FIXED TABLE 名稱,在 CDB 中的執行計劃將很難判斷真實的執行路徑。

640?tp=webp&wxfrom=5&wx_lazy=1

640?tp=webp&wxfrom=5&wx_lazy=1

640?tp=webp&wxfrom=5&wx_lazy=1

結論:操作起來稍顯複雜,功能正常。


文章轉自數據和雲公眾號,原文鏈接

最後更新:2017-07-18 12:03:03

  上一篇:go  Oracle 12c ASM 防範異常的恢複增強
  下一篇:go  嵌入雲端:12c Policy-Managed Cluster為Oracle DBaaS助力