揭秘Oracle 12c数据库新特性之 Oracle多租户容器数据库(一)

1、什么是多租户容器数据库

Oracle 12c 引入了多租户数据库。

多租户容器数据库是指Oracle数据库管理模型的一种革新,它引入了容器数据库(CDB)和租户数据库(PDB)的概念。以下是对这两个概念的详细解释:

容器数据库(CDB):CDB是一个全局数据库容器,可以包含一个或多个租户数据库(PDB)。它可以共享一组系统资源(例如SGA和PGA),同时也可以包含多个PDB。CDB拥有自己的系统表空间和用户数据表空间,以及共享的SGA和PGA。可以看作是一个包含了多个独立数据库的容器,这些独立数据库共享了一些系统级别的资源。租户数据库(PDB):PDB是CDB中的一个独立数据库单元。每个PDB拥有自己的数据文件、表空间、用户、权限等数据库资源,它们是逻辑上隔离的。PDB中的数据和用户完全独立于其他PDB,就像它是一个独立的数据库一样。PDB可以有自己的特定配置和特性,因此可以根据需要对不同的PDB进行定制。

通过CDB和PDB模型,可以在一个数据库实例中同时管理多个独立的数据库,这些数据库彼此隔离,但又能共享一部分系统级别的资源。这种架构在云环境中尤其有用,允许在共享的基础设施上为多个客户提供服务,从而提高了资源利用率并降低了成本。

总的来说,Oracle 12c 多租户数据库提供了一种高效灵活的数据库管理方式,适用于各种环境,尤其在云环境中发挥了它的独特优势。

2、多租户容器数据库的优点

2.1. 非多租户容器数据库遇到的挑战

  • 数据库没有完全使用硬件,硬件存在资源浪费
  • 数据库数量多,管理维护复杂
  • 需要大量的时间修补或更新补丁
  • 需要更多的授权

2.2. 多租户容器数据库的优点

  • 降低服务器和存储硬件成本
  • 实例开销低
  • 节约打补丁和升级时间
  • 提供隔离
  • 需要更少的授权,默认3个pdb免费

3、多租户容器数据库体系结构


Oracle 12cR1 不支持PDB中undo表空间

Oracle 12cR2开始支持PDB中undo表空间

4、多租户数据库的组件

4.1. 多租户容器数据库中的两种类型的容器

根容器CDB(CDB$ROOT)

  • 在创建CDB时创建的第一个容器
  • 提供管理服务:管理公用对象和元数据,管理公用用户和角色

可插拔数据库容器(PDB)

  • PDB是应用程序容器,表空间,schema,object,权限
  • PDB可以创建,克隆,移动,拔出/插入
  • PDB$SEED是特殊的PDB,提供创建PDB的模板

5、多租户数据库用户

5.1. 公用用户和本地用户

多租户数据库引入了两类用户:公用用户(common user)和本地用户(local user)

  • 公用用户 : 公用用户存储在所有容器中(root and all PDBs)。在CDB中创建的用户是公用用户。
  • 本地用户 : 本地用户仅存储在指定的PDB中。在PDB中创建的用户是本地用户。相同的用户名可以在多个不同的PDB中,但是它们是不相关的。
  • 不能在root容器中创建本地用户。

5.2. 创建用户的选项

  • container=all
  • container=current

如果当前container是CDB,那么,默认container选项是container=all。在CDB中创建用户不支持container=current。

如果当前container是PDB,那么,默认container选项是container=current。在PDB中创建用户不支持container=all。

5.3. 操作示例

##在cdb操作:[oracle@db19c ~]$ cdb1[oracle@db19c ~]$ sqlplus / as sysdbaSQL*Plus: Release 19.0.0.0.0 - Production on Mon Oct 16 19:30:39 2023Version 19.3.0.0.0Copyright (c) 1982, 2019, Oracle.All rights reserved.Connected to:Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0SYS@cdb1>SYS@cdb1>SYS@cdb1> create user lzy identified by lzy container=all; ##显式指定container=allUser created.SYS@cdb1> create user zlx identified by zlx;##不显式指定container=allUser created.SYS@cdb1>select username,common,con_id from cdb_users where username in ('LZY','ZLX') order by 1,3;USERNAME COMMON CON_ID---------- ---------- ----------LZYYES 1LZYYES 3LZYYES 4LZYYES 5LZYYES 6ZLXYES 1ZLXYES 3ZLXYES 4ZLXYES 5ZLXYES 610 rows selected.SYS@cdb1>##在pdb操作[oracle@db19c ~]$ sqlplus sys/oracle@pdb1 as sysdbaSQL*Plus: Release 19.0.0.0.0 - Production on Mon Oct 16 19:42:15 2023Version 19.3.0.0.0Copyright (c) 1982, 2019, Oracle.All rights reserved.Connected to:Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0SYS@pdb1> create user spk identified by spk container=current;User created.SYS@pdb1> select username,common,con_id from cdb_users where username in ('LZY','ZLX','SPK') order by 1,3;USERNAME COMMON CON_ID---------- ---------- ----------LZYYES 3SPKNO3ZLXYES 3SYS@pdb1>

6、多租户数据库角色

6.1. 公用角色和本地角色

  • 公用角色:公用角色存储在所有容器中(root and all PDBs)。在CDB中创建的用户是公用角色。
  • 本地用户:本地角色仅存储在指定的PDB中。在PDB中创建的角色是本地角色。相同的角色名可以在多个不同的PDB中,但是它们是不相关的。
  • 不能在root容器中创建本地角色。

6.2. 创建角色 container选项

  • container=all
  • container=current

如果当前容器是CDB,默认的container选项是all。在CDB中创建角色不支持container=current。
如果当前容器是PDB,默认的container选项是current。在PDB中创建角色不支持container=all。

6.3. 操作示例

##在cdb操作:SYS@cdb1> create role role1 container=all;Role created.SYS@cdb1> select role,role_id,common from dba_roles where role in ('ROLE1','ROLE2');ROLE ROLE_ID COMMON------------ ------ROLE1110 YESSYS@cdb1>##在pdb操作SYS@pdb1> create role role2 container=current;Role created.SYS@pdb1> select role,role_id,common from dba_roles where role in ('ROLE1','ROLE2');ROLE ROLE_ID COMMON------------ ------ROLE1110 YESROLE2111 NOSYS@pdb1>

7、 多租户数据库权限

7.1. 公用权限和本地权限

  • 在所有容器中授予的权限是公用权限。
  • 在单个PDB的上下文中授予的权限是本地权限。
  • 本地用户只能在本地PDB中行使权限
  • 公用用户只能在所连接的PDB行使权限
  • 连接到根容器的公用用户可以行使跨容器权限,如创建公用用户

7.2. 权限授予选项

  • container=current
  • container=all

如果当前容器是CDB:

​ 指定container=current授予系统权限,对象权限,角色给一个公用用户或公用角色,权限或角色只在本CDB有效。

​ 指定container=all授予系统权限,对象权限,角色给一个公用用户或公用角色,权限或角色在所有容器中有效。如果忽略了container=all,则container=current是默认选项。

如果当前的容器是PDB:

​ 指定container=current授予系统权限,对象权限,角色给一个用户或角色,权限或角色只在本PDB有效。

7.3. 操作示例

##在cdb操作SYS@cdb1> grant create session to lzy container=all;Grant succeeded.SYS@cdb1> grant create session to zlx container=current;Grant succeeded.SYS@cdb1> select grantee,privilege,admin_option,common,con_id from cdb_sys_privs where grantee in ('LZY','ZLX') order by 1,5;GRANTEEPRIVILEGEADMIN_OPTIONCOMMON CON_ID---------- ---------------------------------------- --------------- ---------- ----------LZYCREATE SESSION NOYES 1LZYCREATE SESSION NOYES 3LZYCREATE SESSION NOYES 4LZYCREATE SESSION NOYES 5LZYCREATE SESSION NOYES 6ZLXCREATE SESSION NONO1SYS@cdb1> conn zlx/zlx@pdb1ERROR:ORA-01045: user ZLX lacks CREATE SESSION privilege; logon deniedWarning: You are no longer connected to ORACLE.@>##在pdb操作SYS@pdb1> grant create session to spk container=current;Grant succeeded.SYS@pdb1> select grantee,privilege,admin_option,common,con_id from cdb_sys_privs where grantee in ('LZY','ZLX','SPK');GRANTEEPRIVILEGEADMIN_OPTIONCOMMON CON_ID---------- -------------------- --------------- ---------- ----------SPKCREATE SESSION NONO3LZYCREATE SESSION NOYES 3SYS@pdb1> conn spk/spk@pdb2ERROR:ORA-01017: invalid username/password; logon deniedWarning: You are no longer connected to ORACLE.@> conn spk/spk@cdb1ERROR:ORA-01017: invalid username/password; logon denied

8、如何访问多租户容器数据库

8.1. 方法一 alter session set container

[oracle@db19c ~]$ cdb1[oracle@db19c ~]$ sqlplus / as sysdbaSQL*Plus: Release 19.0.0.0.0 - Production on Mon Oct 16 18:31:27 2023Version 19.3.0.0.0Copyright (c) 1982, 2019, Oracle.All rights reserved.Connected to:Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0SYS@cdb1> show pdbsCON_ID CON_NAME OPEN MODERESTRICTED---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLYNO 3 PDB1 READ WRITE NO 4 PDB2 READ WRITE NO 5 PDB3 READ WRITE NO 6 PDB4 READ WRITE NOSYS@cdb1> show con_nameCON_NAME------------------------------CDB$ROOTSYS@cdb1> alter session set container=pdb1;Session altered.SYS@cdb1> show con_nameCON_NAME------------------------------PDB1SYS@cdb1>SYS@cdb1> alter session set container=cdb$root;Session altered.SYS@cdb1> show con_nameCON_NAME------------------------------CDB$ROOTSYS@cdb1>

8.2. 方法二 使用TNSNAMES方式

[oracle@db19c ~]$ cat $ORACLE_HOME/network/admin/tnsnames.ora# tnsnames.ora Network Configuration File: /u01/app/oracle/product/19c/dbhome_1/network/admin/tnsnames.ora# Generated by Oracle configuration tools.cdb1 =(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = db19c)(PORT = 1521))(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = cdb1)))pdb1 =(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = db19c)(PORT = 1521))(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = pdb1)))pdb2 =(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = db19c)(PORT = 1521))(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = pdb2)))pdb3 =(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = db19c)(PORT = 1521))(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = pdb3)))pdb4 =(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = db19c)(PORT = 1521))(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = pdb4)))[oracle@db19c ~]$[oracle@db19c ~]$ sqlplus system/oracle@cdb1SQL*Plus: Release 19.0.0.0.0 - Production on Mon Oct 16 19:26:39 2023Version 19.3.0.0.0Copyright (c) 1982, 2019, Oracle.All rights reserved.Last Successful login time: Mon Oct 16 2023 18:47:19 +08:00Connected to:Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0SYSTEM@cdb1> exitDisconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0[oracle@db19c ~]$ sqlplus system/oracle@pdb1SQL*Plus: Release 19.0.0.0.0 - Production on Mon Oct 16 19:26:44 2023Version 19.3.0.0.0Copyright (c) 1982, 2019, Oracle.All rights reserved.Last Successful login time: Mon Oct 16 2023 19:26:39 +08:00Connected to:Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0SYSTEM@pdb1> exitDisconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0[oracle@db19c ~]$ sqlplus system/oracle@pdb2SQL*Plus: Release 19.0.0.0.0 - Production on Mon Oct 16 19:26:50 2023Version 19.3.0.0.0Copyright (c) 1982, 2019, Oracle.All rights reserved.Last Successful login time: Mon Oct 16 2023 19:26:44 +08:00Connected to:Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0SYSTEM@pdb2> exitDisconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0[oracle@db19c ~]$ sqlplus system/oracle@pdb3SQL*Plus: Release 19.0.0.0.0 - Production on Mon Oct 16 19:26:55 2023Version 19.3.0.0.0Copyright (c) 1982, 2019, Oracle.All rights reserved.Last Successful login time: Mon Oct 16 2023 19:26:50 +08:00Connected to:Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0SYSTEM@pdb3> exitDisconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0[oracle@db19c ~]$ sqlplus system/oracle@pdb4SQL*Plus: Release 19.0.0.0.0 - Production on Mon Oct 16 19:26:58 2023Version 19.3.0.0.0Copyright (c) 1982, 2019, Oracle.All rights reserved.Last Successful login time: Mon Oct 16 2023 19:26:55 +08:00Connected to:Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0SYSTEM@pdb4> exitDisconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0[oracle@db19c ~]$

8.3. 方法三 使用ezconnect 方式

[oracle@db19c ~]$ sqlplus system/oracle@10.1.12.92:1521/pdb1SQL*Plus: Release 19.0.0.0.0 - Production on Mon Oct 16 19:28:16 2023Version 19.3.0.0.0Copyright (c) 1982, 2019, Oracle.All rights reserved.Last Successful login time: Mon Oct 16 2023 19:26:59 +08:00Connected to:Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0SYSTEM@10.1.12.92:1521/pdb1> exitDisconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0[oracle@db19c ~]$ sqlplus system/oracle@10.1.12.92:1521/pdb2SQL*Plus: Release 19.0.0.0.0 - Production on Mon Oct 16 19:28:19 2023Version 19.3.0.0.0Copyright (c) 1982, 2019, Oracle.All rights reserved.Last Successful login time: Mon Oct 16 2023 19:28:16 +08:00Connected to:Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0SYSTEM@10.1.12.92:1521/pdb2> exitDisconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0[oracle@db19c ~]$ sqlplus system/oracle@10.1.12.92:1521/pdb3SQL*Plus: Release 19.0.0.0.0 - Production on Mon Oct 16 19:28:25 2023Version 19.3.0.0.0Copyright (c) 1982, 2019, Oracle.All rights reserved.Last Successful login time: Mon Oct 16 2023 19:28:19 +08:00Connected to:Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0SYSTEM@10.1.12.92:1521/pdb3> exitDisconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0[oracle@db19c ~]$[oracle@db19c ~]$ sqlplus system/oracle@10.1.12.92:1521/pdb4SQL*Plus: Release 19.0.0.0.0 - Production on Mon Oct 16 19:28:29 2023Version 19.3.0.0.0Copyright (c) 1982, 2019, Oracle.All rights reserved.Last Successful login time: Mon Oct 16 2023 19:28:25 +08:00Connected to:Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0SYSTEM@10.1.12.92:1521/pdb4> exitDisconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - ProductionVersion 19.3.0.0.0[oracle@db19c ~]$