12C中CDB和PDB的一些概念

1.通过名称和ID来识别容器

一个集成的CDB中,可以包含多个容器,他们可以通过名称和数字,也就是con_id来进行识别.在12c版本中,所有用来显示一个实例中包含哪些对象的v$视图,都添加了一列,用来显示CON_ID,以便标记对象属于哪个PDB.

CDB本身是一个容器,其容器CON_ID为0,被标记为CON_ID=0的对象,都是 CDB级别的对象,并且不会关联到其它的容器.

在任意CDB环境中,第一个容器都是根容器,名为CDB$ROOT,并且CON_ID=1,其它所有的容器都是PDB

在任意CDB中的第一个PDB容器,都是种子容器,名为PDB$SEED,因为他的CDB中的第二个容器,所以CON_ID=2

在CON_ID>2的容器就是用户PDB

在PDB中查询dba_pdbs中,CON_UID和DBID一致,表示当前PDB的唯一ID

而在V$DATABASE中查询的DBID是CDB$ROOT的唯一ID,和以前的概念一致.

 

2.容器列表

视图DBA_PDBS列出了所有的PDB及其状态:

 

    PDB_ID PDB_NAME           STATUS       DBID     CON_ID
---------- ------------------------------ ---------- ---------- ----------
     2 PDB$SEED           NORMAL     3575060827      2
 

对于PDB而言,当刚创建时,其状态为NEW,并且在第一次将其以读/写方式打开时,其状态调整为NORMAL,因为在第一次打开PDB的时候,需要进行一些相关操作.状态为UNUSABLE表明该PDB创建失败,并且唯一允许的操作是将其删除.

状态为UNPLUGGED,表明该PDB将会被传输到其它的CDB,而在源CDB上,唯一能做的操作就是将该PDB删除.

 

SQL> l
  1* select con_id,name,open_mode,open_time from v$pdbs
SQL> /
 
    CON_ID NAME               OPEN_MODE  OPEN_TIME
---------- ------------------------------ ---------- ---------------------------------------------------------------------------
     2 PDB$SEED           READ ONLY  21-JUN-19 10.31.47.849 AM +08:00
 

在非PDB中,MOUNTED状态表明当前的控制文件已经被读取,但是数据文件还没有被实例打开.可以使用show pdbs来查看当前的PDB状态,如果正处于根容器中,还可以显示所有的PDB:

 

SQL> show pdbs
 
    CON_ID CON_NAME           OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
     2 PDB$SEED           READ ONLY  NO
 

 

3.通过CON_ID和DBID来识别容器

CON_ID来标识容器,但是当PDB移动的时候,CON_ID就会变化,因此使用CON_UID来唯一标识PDB.

 

4.连接到容器

使用show con_id和show con_name来查看当前连接的pdb

 

SQL> show con_id
 
CON_ID
------------------------------
1
SQL> show con_name
 
CON_NAME
------------------------------
CDB$ROOT

可以使用alter session命令来切换容器,例如:

 

SQL> alter session set container=brent;
 
Session altered.
 

PDB的隔离性:

在pdb中只能访问到当前PDB的数据.不同PDB之间的操作是相互独立的.你可以使用alter session set container=XX;来在PDB之间进行切换.

但是注意当在一个PDB上进行事务的时候,如果没有提交或者回滚,在不能在另一个PDB上开启事务.

如果你想使用PDB,CDB的特性,则需要使用12c的客户端,否则在执行切换PDB的时候会产生错误.

注意:

不同的PDB可以使用自己的system,sysaux,undo,temp,users表空间(推荐这么做),但是使用共有的redo日志,控制文件和参数文件.

如果想在切换不同的pdb的时候执行不同的参数,可以在PDB中创建BEFORE SET CONTAINER或者AFTER SET CONTAINER触发器.

 

5.容器中的字典

当你处在PDB中时候,pdb中包含了所有你想从数据库中看到的内容.当你在一个PDB中进行数据字典查询的时候,与你在其它非CDB环境中的一样.DBA_和V$视图都是当前PDB下的.

当你处在CDB的时候,就可以看CDB_视图,这些视图是所有容器DBA_视图的union all结果.这是一个CDB管理员使用的方法,从而查看所有对象.

对于CDB$ROOT用户,v$视图将会显示所有的容器内的信息.例如v$session中con_id标识了此会话当前属于哪个PDB.

 

6.参数文件

对于所有的容器,spfile是公用的,spfile持有的该实例的相关参数,并为整个CDB进行属性设置.

有些参数可以在PDB级别进行单独配置.具体哪些参数,可以参考v$parameter中的ISPDB_MODIFIABLE为TRUE的列.

如果手工指定了某pdb的参数,那么此pdb的参数将覆盖cdb的参数.不再参考cdb的参数值.而且此pdb的参数是存放在CDB的数据字典PDB_SPFILE$中.

可以通过查看数据字典pdb_spfile$来查看pdb指定的参数:

 

SQL> select a.name,a.dbid,b.pdb_uid,b.name,b.value$ from v$pdbs a ,pdb_spfile$ b where a.dbid=b.pdb_uid and a.name='PDB2'
SQL> /
 
NAME                     DBID    PDB_UID NAME                                         VALUE$
------------------------------ ---------- ---------- -------------------------------------------------------------------------------- ------------------------------
PDB2                   2158045800 2158045800 db_securefile                                    'PREFERRED'
PDB2                   2158045800 2158045800 open_cursors                                     1000

注意一个DB_FILES参数,默认为200,当你有很多PDB的时候,可能很快就会超过,因此注意在创建CDB的时候就修改其大小.

 

7.控制文件

控制文件也是CDB级别的.控制文件是唯一真正存储数据文件名称的地方.例如你在CDB中查询dba_data_files只显示当前CDB的数据文件,并不会列出所有的数据文件,

但是你查询v$datafile会列出所有的数据文件,因为v$datafile查询的是控制文件.

当一个PDB被拔出或者插入的时候,所有与该PDB相关的数据文件信息,也会被控制文件中导出,然后存储到一个XML文件中.

 

8.UNDO文件

在12.1中UNDO是CDB级别的.

但是在12.2中UNDO可以是PDB级别的,当LOCAL_UNDO被设置为on的时候,每个PDB都拥有自身的UNDO表空间

建议将UNDO本地管理,即每个PDB都拥有其独立的undo,这样可以做到PDB隔离,而且在PDB闪回的时候也更方便.

 

9.临时表空间

临时表空间可以是PDB或者CDB级别创建,建议每个PDB拥有其独立的临时表空间

如果某个会话在执行的过程中没有指定临时表空间,而且该PDB也没有默认的临时表空间,则使用CDB的临时表空间.

 

10.redo日志

redo日志是CDB级别的,所有的PDB公用相同的redo日志

CDB环境下的redo日志与以前的类似,但是需要在每一条redo中记录额外的信息用来标记来至哪个容器.

使用统一的redo线程来处理所有的PDB,因此对于DBA管理CDB而言就变得轻松.所有的备份,rac配置,dg配置都是在CDB级别进行配置,PDB会随着CDB自动进行备份,配置,DG等.

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(oracle12c,CDB,19c)