Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護

shilei1發表於2017-02-12

COMMON 和 Local 使用者

無論在 CDB 和 Non-CDB 資料庫中,使用者都擁有一個 Schema,擁有一系列的 Schema 物件,在 CDB 中由於 PDB 的引入,使用者範疇有所不同。


在 CDB 模式下,公用使用者(Common User)和本地使用者(Local User)兩個概念被引入進來,公用使用者可以在 CDB 和 PDB中同時存在,能夠連線 ROOT 和 PDB 進行操作;而本地使用者則只在特定的 PDB 中存在,也只能在特定的 PDB 中執行操作;在 PDB 中不能建立公用使用者,而在 CDB 中(CDB$ROOT 中)同樣不能建立本地使用者。


在 CDB 中建立的公用使用者要求以 c##或C## 開頭,以下測試以常規方式命名的使用者將會建立失敗,符合規則的使用者可以被建立:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護
當建立公用使用者時,Oracle 會向每個 PDB 中同時建立該使用者,如果 PDB 未開啟,則建立工作會以任務的方式延後。以下查詢顯示資料庫中只在容器1中存在新建立的使用者:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護

此時開啟 PDB,則資料庫會自動完成之前掛起的內部建立工作:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護


下圖描述了公用使用者和本地使用者的區別:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護


在擁有了 CREATE SESSION 許可權後,公用使用者能夠登陸包括 Root 在內的任何 Container。公用使用者一般在每個 PDB 中都存在對應的使用者資訊,在 PDB 中不能存在與公用使用者重名的使用者,如初始的 SYS 和 SYSTEM 使用者都屬於公用使用者。也只有公用使用者能夠授權或被授權相應的公用角色和許可權。

 

公用許可權是指對所有 Container 都有效的系統或者物件許可權,例如一個公用使用者被授予了公用許可權 CREATE ANY TABLEWITH ADMIN OPTION 可以將這個許可權轉授給其他公用使用者。公用使用者之外的許可權被稱為本地許可權(Local Privilege).

 

公用角色是指在所有 Container 中都可見的角色,這些角色可能包含全域性和本地許可權。本地角色只能包含本地許可權。授予公用角色的公用許可權,對於具有該角色的使用者在任何可以連線的 Container 中都將具有該許可權。

 

以下是一些相關的常識性介紹:

  • 一個公用使用者在不同 Container 中的 Schema 可以不同;

  • 本地使用者只能在各自的 PDB 中進行操作,在不同 PDB 中可以存在同名的本地使用者;

  • PDB 中的本地使用者不能登陸其他 PDB 或 ROOT;

  • PDB 的本地使用者只需要在本 PDB 內保持使用者名稱唯一;

  • 本地使用者能否訪問一個公用 Schema 中的物件取決於其擁有的具體許可權;

  • PDB 能夠通過 DB Link 訪問其他的 PDB;

 

在 CDB、PDB 模式下,一個許可權在被授權的 Container 中存在。因此,在 PDB 中授予的本地許可權和角色和在 Non-CDB 中沒有不同,例如,在 PDBHRPDB 中授予本地使用者 HR 的 SELECT ANYTABLE 許可權,僅在該 PDB 中生效。

 

相對而言,公用許可權和角色可以跨越 Container 生效,當需要跨 Container 進行操作時,需要公用許可權或角色,並且這些許可權需要在現有和將來建立的 Container 中生效。

 

在 CDB 中,每個許可權或者是在某個 Container 中的本地許可權,或者是在所有Container中生效的公用許可權。公用許可權確保公用使用者無需在不同 PDB中重複授權。

 

類似 CREATE ANYTABLE 的許可權,其自身既不是公用許可權也不是本地許可權,如果一個使用者通過 CONTAINER=CURRENT 方式授權,則被授權使用者擁有的是本地許可權;如果一個許可權通過 CONTAINER=ALL 方式授權,則使用者獲得的是公用許可權。因此,一個許可權稱其為本地或公用許可權,完全依賴於其授權方式。

 

在 CDB 中,每個角色或者是基於 PDB 的本地角色,或者是對全體 PDB 生效的公用角色,所有系統提供的角色(如 DBA)都屬於公用角色。

 

在檢視 DBA_USERS 和 CDB_USERS 中都包含了一個欄位 COMMON,用於標識公用使用者和本地使用者。


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護


以下查詢顯示 SYSTEM 作為公用使用者在四個容器中存在:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護


資料庫中存在17個公用使用者:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護


以下查詢列出了資料庫中的本地使用者:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護


通過指定 CONTAINER 可以限定建立使用者的型別,當使用 ALL 選項時,以下命令就建立了一個名為 APPADMIN 的公用使用者:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護

查詢 dba_users 檢視,可以看到 APPADMIN 的相關使用者屬性:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護


注意,在 CDB$ROOT 中不能建立本地使用者或角色:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護


在 PDB 中才可以建立本地使用者,以下測試首先連線到 PDB(名稱為 ENMO)中,連線使用者具備 DBA 許可權可以建立使用者:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護


當然在 PDB 中也不允許建立公用使用者:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護


同樣在 PDB 中也不能刪除公用使用者:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護

以下 SQL 成功在 PDB 下建立了本地使用者:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護

類似的,本地使用者不能被授予公用許可權或角色,以下嘗試在全域性授權的命令會返回明確的錯誤:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護

在 PDB 內授予本地許可權之後,新建立的使用者可以登陸本地 PDB 資料庫:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護
下面來研究一下角色。在 CDB_ROLES 檢視可以查詢 CDB 的角色資訊,以下查詢可以看到由於 PDB 的引入,角色記錄大大增加:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護

對於 DBA 公用角色來說,在每個 Container 中都存在相應的資訊記錄:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護
而對於 PDB_DBA 角色,僅在 PDB 中存在:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護

同使用者管理類似,在 CDB$ROOT 中可以建立公用角色,但是不能建立本地角色,公用角色在每個 PDB 中都存在,同樣需要以 c## 為字首開頭:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護

在 PDB 中,同樣不能建立公用角色,僅能建立本地角色:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護

對於系統許可權和物件許可權,CDB 相應的增加了對應檢視用於儲存這些資訊:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護

在 CDB 中可以像在 NON-CDB 的資料庫中一樣進行許可權授予與回收:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護


COMMON 和 Local 使用者的內部隔離


在技術實現上,本地使用者和公用使用者都儲存在底層的 USER$ 字典表,該表的結構如下(內容摘錄自 $ORACLE_HOME/rdbms/admin/dcore.bsq 檔案):


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護


注意以上結構中的 SPARE1 欄位,該欄位的註釋是“用於 Schema 級別的補充記錄”,那麼這裡補充記錄的是什麼內容呢?


我們再來檢視一下 DBA_USERS 這個檢視的內容(摘錄內容自$ORACLE_HOME/rdbms/admin/cdenv.sql 檔案),其中顯示 COMMON 欄位內容對應了“decode(bitand(u.spare1,128), 128, 'YES', 'NO')”這一運算結果:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護

 

針對在 PDB 中建立的 EYGLE 使用者,我們來解析一下 CDB 和 PDB 的使用者隔離,由於使用者資訊是儲存在 USER$ 表中,以下查詢顯示在 PDB 中存在的使用者在 CDB 中並不存在,也就是說 PDB 中的使用者,僅在 PDB 自己的 SYSTEM 表空間字典表 USER$ 中存在:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護


 首先我們跟蹤一下在 PDB 中建立使用者的過程:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護


在跟蹤檔案目錄搜尋一下建立使用者的語句:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護


在跟蹤檔案中記錄了建立使用者的過程,密碼已經被隱藏,摘錄主要語句如下,注意 insert 語句將使用者資訊插入到 USER$ 表中:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護


如果我們在 CDB 級別建立一個公用使用者,那麼 Oracle 資料庫將如何處理呢?

以下在 CDB 級別進行一次跟蹤:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護


檢查跟蹤檔案,可以發現存在兩次 INSERT USER$ 的操作,其中一次是使用者程式執行的,另外一次由並行程式執行,也就是將同樣的記錄插入到 PDB 中:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護

 

現在我們再建立一個新的 PDB:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護


開啟兩個 PDB:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護


接下來啟用會話和全域性的跟蹤:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護


現在可以看到,除了會話程式插入 USER$ 之外,兩個並行程式執行了向 PDB 的資料插入,這也就是 CDB 與 PDB 的使用者隔離與管理:


Oracle 12c多租戶特性詳解:全域性使用者與本地使用者的原理與維護

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/196700/viewspace-2133423/,如需轉載,請註明出處,否則將追究法律責任。

相關文章