1.3 Oracle 12c体系结构

Oracle 12c属于容器数据库(Container Database, CDB),顾名思义,容器数据库就是由多个位于不同地理位置的同构或者异构的数据库构成,由Oracle 12c将这些数据库整合(Consolidate)在一起进行管理,将这些数据库统一到同一个数据库中,就如同将物品放置到一个容器里一样,可以随时向该容器里放置物品或者从中取出物品,对于Oracle 12c来讲,不论是同构数据库或者异构数据库都可以放到Oracle 12c这个“容器”里,将新的数据库插接(Plug)到Oracle 12c这个“容器”里必须先将其整合到该容器里,能够插接到Oracle 12c中的数据库称为可插接式数据库(Pluggable Database, PDB),有的书上称为可插接式数据库。

CDB和PDB是Oracle Database 12c的两个重要组件。Oracle引入PDB以后,如同从底层硬件中将操作系统抽象出来一样,PDB就是从管理系统中将数据库抽象出来。使用CDB和PDB技术可以加速数据库部署,通过对CDB升级或者给CDB打补丁就可以将CDB所有更新与PDB保持同步。也可以新创建一个CDB后进行升级更新,再将其他的PDB插入该CDB中,可以达到相同的效果。在Oracle 12c中,两个PDB之间的安全性级别同两个单一的Oracle数据库的安全性级别相同。在Oracle 12c之前的版本没有容器数据库的概念,在Oracle 12c中引入CDB的概念简化了数据库管理员对多个数据库操作,使得容器数据库管理员可以同时对该容器中的所有数据库进行操作,每一个可插接式数据库DBA可以对其可插接式数据库进行管理,Oracle 12c之前的版本操作数据库必须先创建一个数据库实例。在Oracle 12c中,数据库管理员要操作CDB中的这些数据库只要创建一个CDB实例即可。由于这些数据库都属于同一个CDB管理,因此通过CDB实例就可完成对这些数据库的操作,从而大大简化了操作。

CDB、PDB以及CDB实例之间的关系如图1-1所示。在该图中,容器数据库CDB1中有3个可插接式数据库,即PDB_A、PDB_B、PDB_C,这样在操作系统下就有4个数据库文件,即PDB_A、PDB_B、PDB_C和CDB1, CDB1文件中记录了3个可插接数据库的信息,即PDB_A、PDB_B和PDB_C,可插接数据库PDB_A、PDB_B和PDB_C自身没有对应的实例。当创建了CDB的一个实例CDB1后,PDB_A、PDB_B、PDB_C共用一个实例CDB1, PDB_A、PDB_B和PDB_C共享CDB的控制文件、日志文件和UNDO表空间。对于非容器数据库用户,应用程序可以通过服务名或者实例名连接到Oracle 12c数据库服务器,对于容器数据库用户应用程序同样可以通过服务名或者实例名连接到Oracle 12c数据库服务器,而对于可插接数据库用户应用程序只能通过服务名连接到Oracle 12c数据库服务器,对于使用Oracle 12c进行应用程序开发人员,这一点非常重要。以上就是Oracle 12c多租户(Multitenant)思想。

图1-1 CDB和PDB结构

在Oracle 12c之前的版本中,实例与数据库是一对一或多对一关系:即一个实例只能与一个数据库相关联,或者多个实例加载到一个数据库中,实例与数据库不能是一对多的关系,对于Oracle 12c,实例与数据库可以是一对多的关系,这个实例对应图1-1中的CDB1,多个PDB数据库对应图1-1中的PDB_A、PDB_B和PDB_C。

在Oracle 12c的基础体系结构中含有1个CDB。在CDB中可包含0个、1个或者多个PDB、1个根容器(Root Container)和1个种子PDB(Seed PDB)。

用户可以创建一个或者多个PDB,也可以不创建PDB, Oracle 12c要求一个CDB最多可以包含250个PDB。一个PDB是由可移植的模式(Schema)、模式对象和非模式对象组成的集合,这些对象组成的集合是以Oracle Net客户端(非CDB)的形式展现。PDB是用户创建的包含数据和代码的一个数据库实体,用户可以基于其具体需求创建PDB。

根容器中保存了Oracle 12c提供的元数据和公共用户信息,例如Oracle 12c提供的PL/SQL包就是元数据,公共用户是容器数据库中的每一个数据库用户都可看到的一个用户。用户可以通过命令“SQL>show con_name”查看根容器名,Oracle 12c将根容器命名为CDB$ROOT。

公共用户与现有的PDB和未来的PDB都具有相同的根(Root)和ID,公共用户不仅在根中记录有日志,而且在操作的PDB中也记录有日志。公共用户能够执行的操作依赖于授予给它的权限,一些管理任务(例如创建PDB或者拔出PDB)必须由公共用户完成。CDB也支持本地用户,一个本地用户就是PDB一个实实在在的用户。

种子PDB是Oracle 12c提供的一个系统模板,CDB利用该模板来创建新的PDB,用户可以通过命令“SQL>SELECT con_id, dbid, name, open_mode FROM v$pdbs; ”查看种子PDB的名字,Oracle 12c将种子PDB命名为PDB$SEED,用户不能对种子数据库进行修改,也不能增加新的种子数据库。

CDB和PDB的关系示意如图1-2所示。

图1-2 CDB和PDB的关系

Oracle 12c的基础体系结构中的每一个组件都被称为一个容器。因此,根是一个容器,种子是一个容器,每个PDB也都是一个容器,因此,一个CDB结构中包含多个容器,分别是root、seed PDB和用户PDB容器。图1-3给出了Oracle 12c的基础体系结构,该结构图中包含了4个容器,分别是root、seed PDB、app1_pdb和app2_pdb。app1_pdb和app2_pdb的数据是用户的业务数据。从逻辑上看图1-3是一个整体,但文件的存放位置等物理结构是不同的。每个容器在CDB中都有唯一的ID和名称,PDB唯一的ID主要用于产生存储PDB文件的目录名,包括Oracle Managed Files目录和non-Oracle Managed Files目录。

图1-3 Oracle 12c的基础体系结构

用户可以很容易将PDB插入CDB或者从CDB中拔出PDB,当将一个PDB插入CDB后,就实现了PDB与CDB的关联。PDB文件信息和拔出PDB的信息写在XML文件中(例如数据文件和钱夹子文件)。

用户可以将一个PDB从其所属的CDB中拔出,将其插入另一个CDB中,而这样不会改变用户的模式和应用,但是一个PDB在某一时间只能插入一个CDB中。

当然,一个PDB数据库在某一时刻只能插入一个CDB,而不能插入多个CDB数据库,每一个PDB数据库都有其全局唯一标识ID,该ID用于区别同一个CDB中不同的PDB数据库。