感觉Oracle的多租户模型比较奇怪和别扭,但是怎么办呢,还是要总结一下,抓住要点,去粗取精。
简单来说就是在一个实例中,逻辑上虚拟出多个互相独立的数据库。
Oracle的多租户模型是树形结构,根部称为CDB$ROOT,也是一个数据库,可以在其中创建表等对象,其下面有可以虚拟出来多个数据库,称为PDB。CDB和PDB有共享的部分,也有独立的部分,例如CDB中的一些公共用户、PL/SQL包、UNDO表空间、控制文件、在线联机(redo)日志、实例进程,是共享的。
SYSAUX、SYSTEM、TEMP、USER表空间,CDB和PDB是独立的。
一般CDB中除了Oracle自带的共享对象,不创建表,不存储用户数据。一般是在PDB中创建表、用户和存储用户数据。
The CDB root does not store user data. Oracle recommends that you do not add common objects to the root or modify Oracle-supplied schemas in the root. However, you can create common users and roles for database administration. A common user with the necessary privileges can switch between containers.
还有一种中间节点称为Application container,可以理解为在CDB下面的CDB,Application container下面可以创建属于它的PDB,在Application container中也可以创建表、存储数据,这些表对于它的PDB是共有的,可以直接访问。
An application root differs from both the CDB root and standard PDB because it can store user-created common objects, which are called application common objects. Application common objects are accessible to the application PDBs plugged in to the application root. Application common objects are not visible to the CDB root, other application roots, or PDBs that do not belong to the application root.
show con_name -- 查看当前容器
show pdbs -- 查看pdb
一、创建CDB
使用dbca
二、在CDB下创建PDB
create pluggable database pdb2 admin user pdb2admin identified by 123456 ROLES = (dba) file_name_convert=('/u01/app/oracle/oradata/CDB/pdbseed','/u01/app/oracle/oradata/CDB/pdb2');
打开pdb2数据库:
alter pluggable database pdb2 open;
在CDB下,Appication Container及其子pdb也属于CDB的pdb,所以都可用alter pluggable database pdb2 open打开,也都可以用show pdbs查看,无论pluggable database的层级如何,是使用一个命名空间,意味着CDB的PDB、Appication Container及其子PDB,名称上都不能重命,都要唯一区别开。
切换到pdb2数据库:
alter session set container = pdb2;
在listener.ora中增加:
SID_LIST_LISTENER=
(SID_LIST=
(SID_DESC=
(GLOBAL_DBNAME=CDB.io)
(SID_NAME=CDB)
(ORACLE_HOME=/u01/app/oracle/product/19.3.0/dbhome_1)
)
(SID_DESC=
(GLOBAL_DBNAME=pdb1.io)
(SID_NAME=CDB)
(ORACLE_HOME=/u01/app/oracle/product/19.3.0/dbhome_1)
)
(SID_DESC=
(GLOBAL_DBNAME=pdb2.io)
(SID_NAME=CDB)
(ORACLE_HOME=/u01/app/oracle/product/19.3.0/dbhome_1)
)
)
然后以pdb2admin用户登录pdb2:
sqlplus / as sysdba
SYS@CDB> connect pdb2admin/123456@localhost:1521/pdb2.io
或
sqlplus pdb2admin/123456@localhost:1521/pdb2.io
删除pdb2:
drop pluggable database pdb2 including/keep datafiles;
三、在CDB下创建Application Container
create pluggable database approot as application container admin user approot1admin identified by 123456 ROLES = (dba)
file_name_convert=('/u01/app/oracle/oradata/CDB/pdbseed','/u01/app/oracle/oradata/CDB/approot');
打开Application Container数据库:
alter pluggable database approot open;
切换到Application Container数据库:
alter session set container = approot;
在listener.ora中增加:
SID_LIST_LISTENER=
(SID_LIST=
(SID_DESC=
(GLOBAL_DBNAME=CDB.io)
(SID_NAME=CDB)
(ORACLE_HOME=/u01/app/oracle/product/19.3.0/dbhome_1)
)
(SID_DESC=
(GLOBAL_DBNAME=pdb1.io)
(SID_NAME=CDB)
(ORACLE_HOME=/u01/app/oracle/product/19.3.0/dbhome_1)
)
(SID_DESC=
(GLOBAL_DBNAME=approot.io)
(SID_NAME=CDB)
(ORACLE_HOME=/u01/app/oracle/product/19.3.0/dbhome_1)
)
)
然后以approot1admin用户登录approot:
sqlplus / as sysdba
SYS@CDB> connect approot1admin/123456@localhost:1521/approot.io
或
sqlplus approot1admin/123456@localhost:1521/approot.io
删除Application Container,注意这里要求里面没有pdb:
drop pluggable database approot keep/including datafiles;
四、在Application Container下创建PDB
将当前回话设置为Application Container根数据库:
alter session set container = approot;
然后按照常规命令创建pdb:
create pluggable database app_pdb1 admin user pdb1admin identified by 123456 ROLES = (dba) file_name_convert=('/u01/app/oracle/oradata/CDB/pdbseed','/u01/app/oracle/oradata/CDB/approot/pdb1');
打开Application PDB数据库:
alter pluggable database app_pdb1 open;
以pdb1admin用户登录apdb1:
sqlplus / as sysdba
SYS@CDB> connect pdb1admin/123456@localhost:1521/apdb1.io
或
sqlplus pdb1admin/123456@localhost:1521/apdb1.io
五、公共用户和本地用户
在多组环境中,有两种用户:公用用户(Common User)和本地用户(Local User)。公共用户又分为CDB共用用户,和Application公共用户,创建pdb和Application Container的命令中创建的用户,是本地用户。
CDB公共用户:
经过授权,可以访问所有容器数据库,创建CDB公共用户名,以参数COMMON_USER_PREFIX指定的字符串开头,默认是C##:
create user c##test identified by 123456 container = all;
grant connect, create session, resource, dba to c##test container = all;
CDB可以创建公共用户,不能创建本地用户。
Application公共用户:
Application公共用户名不要以C##开头,但是创建时要包含container = all:
create user app identified by 123456 container = all;
为啥这样创建的公共用户登录不了Application PDB?
Application Root可以创建公共用户,不能创建本地用户。
本地用户:
本地用户是在PDB中创建的用户,包括CDB和Application Container下的PDB,还有创建PDB和Application Container的命令中创建的用户,这些用户只能登录自己所在的PDB,操作也只限于自己所在的PDB,创建命令与非CDB数据库创建用户无异,例如:
create user local_user identified by 123456;
PDB不可以创建公共用户,只能创建本地用户。