Oracle从12c开始引入了多租户架构(Multitenant Architecture),使用多租户特性,用户可以创建一个CDB(Container Database 容器数据库),容器数据库可以包含0个,1个或多个PDB(Pluggable database 可插拔数据库)。PDB即是我们以前熟悉的传统数据库,用来管理schema,objects等应用数据,CDB主要用来管理共享的资源。

在12c之前,同一台服务器上多个数据库需要创建多个实例,多份元数据,且每个实例都有自己独立的内存区域和后台进程,一定程度上造成资源的浪费。12c以后采用多租户特性,将传统的数据转换为PDB整合管理,带来如下优点:

  • 多个数据库共享一个实例,共享后台进程、内存区域,节省了服务器资源。
  • PDB可以像U盘一样随意插拔,并迁移至别的CDB,数据库的迁移非常方便。
  • 对于应用来说,PDB就好像传统的non-CDB数据库一样,各个PDB之间是完全隔离的(MySQL中数据库概念相当于Oracle中的schema),针对PDB的操作完全不会影响其他PDB,包括启停。
  • PDB可以在同一个CDB中集中监控和管理,在CDB级别收集统计信息比同时收集多个数据库的信息要简单许多。同时例如数据库的升级和备份等管理操作也可以集中进行,减少管理复杂度。

CDB基础架构图

云系统 多租户数据库架构 什么是多租户数据库_多租户

如上图所示,一个CDB(容器数据库)由3部分组成:

  • 根容器(CDB$ROOT),存储了Oracle的元数据、系统存储过程和common user。Common user在所有的PDB中都存在,可以切换PDB。一个CDB只能有1个CDB$ROOT.
  • 种子容器(PDB$SEED),CDB创建时附带的模板,可以通过复制PDB$SEED的方式来快速创建新的PDB,用户无法在PDB$SEED中创建或修改对象。一个CDB只能有1个PDB$SEED。
  • 可插拔数据库(PDB),相当于12c之前的non-CDB数据库,存储实际的应用数据。

CDB的创建方法有2种:

  • 使用DBCA创建数据库时,启用CDB特性。
  • 使用create database的enable pluggable database子句启用CDB。

PDB的创建方法有4种:

  • 从PDB$SEED复制一个PDB。
  • 从现有的PDB复制一个PDB。
  • 将一个拔出的PDB插入至CDB。
  • 将一个non-CDB数据库转化为PDB,如果是12c以前版本的数据库,可以采用export/import的方式将数据导入PDB。

用户结构:

在CDB中,用户根据权限被区分为common user和local user:

  • common user具有CDB$ROOT和所有PDB的访问权限,common user在每个PDB中权限可以不同,Oracle提供2个默认common user分别为sys/system。
  • local user只能访问特定的PDB,权限被限制在PDB之内。

由于只有common user可以连接到根容器(CDB$ROOT),所以一些特定的操作只能由common user来完成。例如:启动/关闭CDB、插拔PDB、调整CDB配置,给common user赋权等。local user只能在赋权的PDB内操作,无法知晓其他PDB的状态。

当一个non-CDB转换成PDB或新插入一个PDB时,若本地存在相同名称的common user,则原PDB的common user会与本地CDB的common user融合(本地common user密码优先),原common user自带的特殊赋权也仅在当前PDB内生效,不会扩散到其他PDB。若本地不存在同名的的common user,在插入新的CDB后,原common user会失去所有赋权,包括set container(切换PDB)权限。

为了方便区别common user和local user,oracle定义了一个common user前缀(由common_user_prefix定义,默认是C##),在创建common user时必须由前缀开头,用户可以自己定义和修改此参数。common user必须在CDB$ROOT中创建。

Local user完全是PDB的本地用户,所有权限都被限制在所属PDB之内。虽然可以给local user赋common roles,但也仅可以使用common role在本PDB之内的权限。Local user必须在其归属的PDB内创建。