合 Oracle 12C 中CDB和PDB的参数文件管理
Tags: Oracle
Oracle 12C 中CDB和PDB的参数文件管理
每个 CDB 有一个 SPFILE 用于存储参数。参数值与根相关联,应用于根,并且可用作所有其他容器的默认值。可以在 PDB 中为参数设置不同的值,前提是 V$PARAMETER 中的列 ISPDB_MODIFIABLE 为 TRUE 。这些值全部在 PDB 作用域内设置,在 PDB 关闭再打开后以及在 CDB 实例关闭又启动后都会相应地保留。执行克隆和移走 / 插入操作后,也会保留。其他初始化参数只能针对根设置。
SQL> select PDB_UID, NAME, VALUE$ from pdb_spfile$;
PDB_UID NAME VALUE$
3100074415 optimizer_use_sql_plan_baselines FALSE
2862146267 optimizer_use_sql_plan_baselines FALSE
2862146267 ddl_lock_timeout 10
PDB 的参数存储在 CDB 的 PDB_SPFILE$ 字典表中以 con_id 区别,所以, PDB 的 PDB_SPFILE$ 表是空的。
col NAME format a25
col value$ format a30
select a.pdb_uid , b.NAME , a.name , a.value$
from pdb_spfile$ a , v$pdbs b
where a.pdb_uid = b.CON_UID
order by b.NAME ;
SELECT * FROM V$SYSTEM_PARAMETER d where d.NAME='db_create_file_dest';
SELECT * FROM cdb_tables d where d.TABLE_NAME='PDB_SPFILE$';
http://blog.itpub.net/26736162/viewspace-2213348/
修改 PDB 中的初始化参数,事实:
l PDB 从根 CDB 继承参数值,除非它们在 PDB 级别被重写。
l 普通的 “ ALTER System ”命令用于修改 PDB 级别的参数,但持久性机制不同。
l PDB 级别的初始化参数不是存储在 SPFILE 中,而是存储在 C DB 的数据字典 PDB_SPFILE$ 内部表中。
l 对于整个 CDB 及其所有 PDBs ,只有一个 物理 spfile 。打开根 CDB 时读取此 spfile 。
l 与 PDB 的 spfile 等价的是 CDB 的 PDB_SPFILE$ 表。
l 每个容器都有一个 PDB_SPFILE$ 表 (CDB$root 和所有 PDB) 。但是,只有 CDB 的 PDB_SPFILE$ 表包含为 PDB 专门设置的参数。
l 只要根的 CDB 是打开的, PDBs 中的 SPFILE 总是被启用的。即使 CDB 不使用 SPFILE , Oracle 也允许 PDB 使用 SPFILE ,因为 PDB 没有任何其他方法用于持久参数 (PDB 不支持 Pfile 或 init.ora 文件 ) 。
l 在 PDB 中只能在本地修改整个 Oracle DB 初始化参数的一个子集。使用 V$PARAMETER.ISPDB_AUDIBE= ‘ YES ’查找这些参数。
l PDB 级别的参数在数据库重新启动的过程中持续存在,在拔出 / 插件甚至克隆操作中也是如此。
l 根的 PDB_SPFILE$ 表是内部查询的,在打开可插拔数据库 / 实例时会相应地设置参数。
l 当以特权用户的身份连接到根容器 DB 时,默认情况下,任何 ALTER System 命令都只指向根容器。
l 传统的查看 SPFILE 甚至警报日志的方法只对 CDB 数据库有用。这是因为 CDB 是控制 CDB 和 PDB 之间共享的许多项的根级别。
l 要查看 CDB 和所有 PDB 的参数 (PDB$SEED 除外 ) ,可以查询 V$System_Parameter 。但是,除非安装了 bug#20700587 的修复程序,否则不会列出隐藏参数或下划线参数。
l V$SPPARAMETER 视图也可以被查询以在从 PDB 内部查询时显示 PDB 的 SPFILE 参数。
l 在非 CDB 中, V$SPPARAMETER 视图读取 spfile 并将参数显示为查询结果。 CDB 中的相同视图读取根中的 PDB_SPFILE$ 表,并在 PDB 中显示 PDB 的 SPFILE 参数。
l 为了在 PDB 级别修改参数,您需要连接到要对其进行修改的 PDB 容器。如果在根容器中连接,参数修改将对整个 CDB 进行。
l 每次打开 PDB 时,如果特定的 PDB 对于某些 init 参数有自己的值,那么 CDB 的 SPFILE 的值将被 PDB_SPFILE$ 的值覆盖。
l 可以为根 CDB DB 设置所有初始化参数。对于没有为 PDB 显式设置的任何初始化参数, PDB 继承根的参数值。
l 就像正常的初始化参数一样,有些下划线参数不能在系统级别修改,或者不能在 PDB 级别上修改,或者参数 - 隐藏的或不隐藏的 - 需要在所有 RAC 实例中具有相同的值。
l 每个 PDB 中的 PDB_SPFILE$ 表都是截断 / 空的,每个 PDB 的所有初始化参数都存储在根的 PDB_SPFILE$ 表中。
l 当 PDB 插入到新的 CDB 中时,参数及其值将被恢复。
l 当一个 PDB 被拔出时,它自己的初始化参数也会被复制到 PDB 自己的 PDB_SPFILE$ 表中,这样做是为了防止 XML 丢失。
l 将 PDB 插入到 CDB 并导入其所有参数后,本地 PDB 的 PDB_SPFILE$ 表将被截断。
l 由于 PDB 的 spfile 参数存储在根 CDB 中的字典表中,所以“ ALTER System Reset ”命令只是从根中的 PDB_SPFILE$ 表中删除 PDB 参数的行。这相当于从非 CDB 中的常规 spfile 中删除参数。
l 当前不支持为常规的非多租户数据库重置内存中的参数,因此 PDB 也不支持这一点。
l 当 PDB 关闭时,用于设置 / 重置参数的 PDB ‘ Alter System Set/Reset. ’命令不能用作用域 = 内存执行。当读取封闭 PDB 的参数时,我们需要提供参数的根值,因为 PDB 是从根继承的。
在本例中, pdb2 中为 DDL_LOCK_TIMEOUT 参数设置了不同的值。 PDB 关闭再打开后,更改的值会保留。 V$SYSTEM_PARAMETER 视图中的新列 CON_ID 显示每个容器(即根、 pdb1 和 pdb2 )中的 DDL_LOCK_TIMEOUT 值。
一、 Oracle12c多租户CDB 与 PDB 参数文件位置
CDB的参数文件依然使用12c以前的SPIFLE,pdb的参数文件不会出现在SPFILE中,而是直接从CDB中继承,如果PDB中有privete Local parameter 会存在 CDB 的 PDB_SPFILE$字典表 中以con_id区别,当PDB UN-Plug时,PDB参数会写入PDB的XML文件中,当drop pluggable database后,pdb信息和PDB_SPFILE$记录也会被清除。再当PDB重新Plug-in到CDB时会重新加载回PDB, 但是由于一些PDB特殊参数在plug-in时会被遗弃。
实验验证:
SQL> show con_name
CON_NAME
------------------------------
CDB$ROOT
SQL> show parameter spfile
NAME TYPE VALUE
spfile string /home/oracle/app/oracle/produc
t/12.2.0/dbhome_1/dbs/spfilean
dycdb.ora
SQL> alter session set container=pdb01;
Session altered.
SQL> show parameter spfile
NAME TYPE VALUE
spfile string /home/oracle/app/oracle/produc
t/12.2.0/dbhome_1/dbs/spfilean
dycdb.ora
到这一步验证了:CDB的参数文件依然使用12c以前的SPIFLE,pdb的参数文件不会出现在SPFILE中,而是直接从CDB中继承。
SQL> show parameter undo_retention
NAME TYPE VALUE
undo_retention integer 900
SQL> alter system set undo_retention=901;
System altered.
SQL> show parameter undo_reten
NAME TYPE VALUE
undo_retention integer 901
SQL> select pdb_uid,name,value$ from PDB_SPFILE$;
no rows selected
SQL> alter session set container=cdb$root;
Session altered.
SQL> select pdb_uid,name,value$ from PDB_SPFILE$;
PDB_UID NAME VALUE$
2550500229 undo_retention 901
SQL> select con_id,dbid,con_uid,guid from v$pdbs;
CON_ID DBID CON_UID GUID
2 2683777510 2683777510 4ECF66D93A6233B5E0531019640A6041
3 2550500229 2550500229 4ECF8621E3DA38EEE0531019640AA598
到这一步验证了:如果PDB中有privete Local parameter 会存在 CDB 的 PDB_SPFILE$字典表 中以con_id区别
SQL>alter pluggable database pdb01 close immediate;
SQL>alter pluggable database pdb01 unplug into '/home/oracle/pdb01.xml';
[oracle@12c01 ~]$ pwd
/home/oracle
[oracle@12c01 ~]$ ll pdb01.xml
-rw-r--r--. 1 oracle oinstall 7758 May 7 05:09 pdb01.xml
[oracle@12c01 ~]$ cat pdb01.xml
<?xml version="1.0" encoding="UTF-8"?>
...省略
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 PDB01 MOUNTED
SQL> drop pluggable database pdb01 keep datafiles;
Pluggable database dropped.
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
SQL> select pdb_uid,name,value$ from PDB_SPFILE$;
no rows selected
到这一步验证了:PDB un-plug后pdb parameter and spfile会先进xml文件, 当drop pluggable database后,pdb信息和PDB_SPFILE$记录也会被清除。
SQL> create pluggable database pdb01 using '/home/oracle/pdb01.xml' nocopy;
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 PDB01 MOUNTED
SQL> alter pluggable database pdb01 open;
Pluggable database altered.
SQL> select pdb_uid,name,value$ from PDB_SPFILE$;
PDB_UID NAME VALUE$
---------- ---------------------------------------- -------------------------
1196085469 undo_retention 901
到这一步验证了:当PDB重新Plug-in到CDB时会重新加载回PDB, 但是由于一些PDB参数特殊原因在plug-in时会被遗弃。这里因为没有特殊参数,所以没有丢失参数。
二、 CDB 与 PDB 不同值的相同参数
多租户环境下,如果在设定参数时,cdb中设置CONTAINER=ALL,那么PDB的参数也会继承这个值,但可以通过ALTER SYSTEM在PDB container中修改 PDB local parameter,将覆盖(优先)从CDB继承的参数。有时候,我们有中需求,需要核实对比 PDB 中哪些参数与 CDB 不同。我们该怎么办,下面我们一起探讨下。
例子: 查询 名为 pdb01 的PDB 与 CDB 不同值的相同参数有哪些
\1. 实验环境查看
SQL> show con_name
CON_NAME
\------------------------------
CDB$ROOT
SQL> show parameter undo_reten
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_retention integer 900
SQL> alter session set container=pdb01;
SQL> show parameter undo_reten
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_retention integer 901
\2. 查询 PDB 中哪些参数与 CDB 不同
SQL>
set lin 300;
set pages 300;
col pdb_name for a30;
col parameter for a25;
col value$ for a20;
select v.dbid,v.name pdb_name,p.name parameter,p.value$
from pdb_spfile$ p,v$pdbs v
where p.pdb_uid=v.con_uid and v.name='PDB01' ;
DBID PDB_NAME PARAMETER VALUE$
---------- ------------------------------ ------------------------- -------------
2550500229 PDB01 undo_retention 901
\------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
在ORACLE 12C中参数文件只是记录了cdb的参数信息,没有记录任何的pdb的信息,那ORACLE是如何管理使得各个pdb有自己的参数,这里通过试验的出来ORACLE 12C CDB环境中是通过参数文件结合PDB_SPFILE$来实现参数管理
数据库版本
```
SQL> ` `select ` `* ` `from ` `v$version; ` `BANNER CON_ID ` `-------------------------------------------------------------------------------- ---------- ` `Oracle ` `Database ` `12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production 0 ` `PL/SQL Release 12.1.0.1.0 - Production 0 ` `CORE 12.1.0.1.0 Production 0 ` `TNS ` `for ` `Linux: Version 12.1.0.1.0 - Production 0 ` `NLSRTL Version 12.1.0.1.0 - Production 0
```
pdb信息
```
SQL> ` `select ` `PDB_NAME,CON_UID,pdb_id,status ` `from ` `dba_pdbs; ` `PDB_NAME CON_UID PDB_ID STATUS ` `---------- ---------- ---------- ------------- ` `PDB1 3313918585 3 NORMAL ` `PDB$SEED 4048821679 2 NORMAL ` `PDB2 3872456618 4 NORMAL ` `SQL> ` `select ` `con_id,dbid, ` `NAME ` `,OPEN_MODE ` `from ` `v$pdbs; ` ` ` `CON_ID DBID ` `NAME ` `OPEN_MODE ` `---------- ---------- ------------------------------ ---------- ` ` ` `2 4048821679 PDB$SEED ` `READ ` `ONLY ` ` ` `3 3313918585 PDB1 ` `READ ` `WRITE ` ` ` `4 3872456618 PDB2 MOUNTED
```
CDB$ROOT中修改参数
```
--指定container=all ` `SQL> show con_name ` `CON_NAME ` `------------------------------ ` `CDB$ROOT ` `SQL> ` `alter ` `system ` `set ` `open_cursors=500 container= ` `all ` `; ` `System altered. ` `SQL> show parameter open_cursors; ` `NAME ` `TYPE VALUE ` `------------------------------------ ----------- ------------------------------ ` `open_cursors ` `integer ` `500 ` `SQL> ` `alter ` `session ` `set ` `container=pdb1; ` `Session altered. ` `SQL> show con_name ` `CON_NAME ` `------------------------------ ` `PDB1 ` `SQL> show parameter open_cursors; ` `NAME ` `TYPE VALUE ` `------------------------------------ ----------- ------------------------------ ` `open_cursors ` `integer ` `500 ` `--在CDB$ROOT中修改不指定container参数表示全部pdb生效 ` `SQL> ` `alter ` `session ` `set ` `container=CDB$ROOT; ` `Session altered. ` `SQL> ` `alter ` `system ` `set ` `open_cursors=100; ` `System altered. ` `SQL> show parameter open_cursors; ` `NAME ` `TYPE VALUE ` `------------------------------------ ----------- ------------------------------ ` `open_cursors ` `integer ` `100 ` `SQL> ` `alter ` `session ` `set ` `container=pdb1; ` `Session altered. ` `SQL> show parameter open_cursors; ` `NAME ` `TYPE VALUE ` `------------------------------------ ----------- ------------------------------ ` `open_cursors ` `integer ` `100 ` `--指定container=current ` `SQL> ` `alter ` `system ` `set ` `open_cursors=120 container= ` `current ` `; ` `System altered. ` `SQL> show parameter open_cursors; ` `NAME ` `TYPE VALUE ` `------------------------------------ ----------- ------------------------------ ` `open_cursors ` `integer ` `120 ` `SQL> ` `alter ` `session ` `set ` `container=pdb2 ; ` `Session altered. ` `SQL> show parameter open_cursors; ` `NAME ` `TYPE VALUE ` `------------------------------------ ----------- ------------------------------ ` `open_cursors ` `integer ` `120
```
这里可以看出来,在ROOT中修改参数,默认情况和指定container=all/current均是所有open的pdb都生效.
这里有个疑问ORACLE的参数文件只是记录的cdb的sid的参数,并未记录各个pdb的参数,那是如何实现cdb中各个pdb参数不一致的呢?继续分析
修改pdb参数做10046
```
SQL> show con_name; ` `CON_NAME ` `------------------------------ ` `PDB1 ` `SQL> oradebug setmypid ` `Statement processed. ` `SQL> oradebug EVENT 10046 TRACE ` `NAME ` `CONTEXT FOREVER, ` `LEVEL ` `12 ` `Statement processed. ` `SQL> oradebug TRACEFILE_NAME ` `/u01/app/oracle/diag/rdbms/cdb/cdb/trace/cdb_ora_18377.trc ` `SQL> ` `alter ` `system ` `set ` `sessions=100; ` `System altered. ` `SQL> oradebug EVENT 10046 trace ` `name ` `context ` `off ` `Statement processed. ` `--继续修改pdb参数 ` `SQL> ` `alter ` `session ` `set ` `container=pdb1; ` `Session altered. ` `SQL> oradebug setmypid ` `Statement processed. ` `SQL> oradebug EVENT 10046 TRACE ` `NAME ` `CONTEXT FOREVER, ` `LEVEL ` `12 ` `Statement processed. ` `SQL> oradebug TRACEFILE_NAME ` `/u01/app/oracle/diag/rdbms/cdb/cdb/trace/cdb_ora_20275.trc ` `SQL> ` `alter ` `system ` `set ` `sessions=101; ` `System altered. ` `SQL> oradebug EVENT 10046 trace ` `name ` `context ` `off ` `Statement processed.
```
分析trace文件
```
--第一次修改pdb参数值 ` `insert into pdb_spfile$(db_uniq_name, pdb_uid, sid, name, value$, comment$) values(:1,:2,:3,:4,:5,:6) ` `END OF STMT ` `PARSE ` `#140085118752824:c=3999,e=3397,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,plh=0,tim=99767937623 ` `BINDS ` `#140085118752824: ` ` ` `Bind ` `#0 ` ` ` `oacdty=01 mxl=32(03) mxlc=00 mal=00 scl=00 pre=00 ` ` ` `oacflg=10 fl2=0001 frm=01 csi=852 siz=32 off=0 ` ` ` `kxsbbbfp=7fffcfaa5842 bln=32 avl=03 flg=09 ` ` ` `value= ` `"cdb" ` ` ` `Bind ` `#1 ` ` ` `oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00 ` ` ` `oacflg=00 fl2=1000001 frm=00 csi=00 siz=24 off=0 ` ` ` `kxsbbbfp=7f681bbb2170 bln=22 avl=06 flg=05 ` ` ` `value=3313918585 ` ` ` `Bind ` `#2 ` ` ` `oacdty=01 mxl=32(01) mxlc=00 mal=00 scl=00 pre=00 ` ` ` `oacflg=10 fl2=0001 frm=01 csi=852 siz=32 off=0 ` ` ` `kxsbbbfp=7fffcfaa46f8 bln=32 avl=01 flg=09 ` ` ` `value= ` `"*" ` ` ` `Bind ` `#3 ` ` ` `oacdty=01 mxl=32(08) mxlc=00 mal=00 scl=00 pre=00 ` ` ` `oacflg=10 fl2=0001 frm=01 csi=852 siz=32 off=0 ` ` ` `kxsbbbfp=0bc220d8 bln=32 avl=08 flg=09 ` ` ` `value= ` `"sessions" ` ` ` `Bind ` `#4 ` ` ` `oacdty=01 mxl=32(03) mxlc=00 mal=00 scl=00 pre=00 ` ` ` `oacflg=10 fl2=0001 frm=01 csi=852 siz=32 off=0 ` ` ` `kxsbbbfp=7fffcfaa474c bln=32 avl=03 flg=09 ` ` ` `value= ` `"100" ` ` ` `Bind ` `#5 ` ` ` `oacdty=01 mxl=32(00) mxlc=00 mal=00 scl=00 pre=00 ` ` ` `oacflg=10 fl2=0001 frm=01 csi=852 siz=32 off=0 ` ` ` `kxsbbbfp=00000000 bln=32 avl=00 flg=09 ` `--第二次修改pdb参数值(相同参数) ` `update pdb_spfile$ ` `set ` `value$=:5, comment$=:6 where name=:1 and pdb_uid=:2 and db_uniq_name=:3 and sid=:4 ` `BINDS ` `#140603847818408: ` ` ` `Bind ` `#0 ` ` ` `oacdty=01 mxl=32(03) mxlc=00 mal=00 scl=00 pre=00 ` ` ` `oacflg=10 fl2=0001 frm=01 csi=852 siz=32 off=0 ` ` ` `kxsbbbfp=7ffff6477dcc bln=32 avl=03 flg=09 ` ` ` `value= ` `"101" ` ` ` `Bind ` `#1 ` ` ` `oacdty=01 mxl=32(00) mxlc=00 mal=00 scl=00 pre=00 ` ` ` `oacflg=10 fl2=0001 frm=01 csi=852 siz=32 off=0 ` ` ` `kxsbbbfp=00000000 bln=32 avl=00 flg=09 ` ` ` `Bind ` `#2 ` ` ` `oacdty=01 mxl=32(08) mxlc=00 mal=00 scl=00 pre=00 ` ` ` `oacflg=10 fl2=0001 frm=01 csi=852 siz=32 off=0 ` ` ` `kxsbbbfp=0bc220d8 bln=32 avl=08 flg=09 ` ` ` `value= ` `"sessions" ` ` ` `Bind ` `#3 ` ` ` `oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00 ` ` ` `oacflg=00 fl2=1000001 frm=00 csi=00 siz=24 off=0 ` ` ` `kxsbbbfp=7fe0e2638320 bln=22 avl=06 flg=05 ` ` ` `value=3313918585 ` ` ` `Bind ` `#4 ` ` ` `oacdty=01 mxl=32(03) mxlc=00 mal=00 scl=00 pre=00 ` ` ` `oacflg=10 fl2=0001 frm=01 csi=852 siz=32 off=0 ` ` ` `kxsbbbfp=7ffff6478ec2 bln=32 avl=03 flg=09 ` ` ` `value= ` `"cdb" ` ` ` `Bind ` `#5 ` ` ` `oacdty=01 mxl=32(01) mxlc=00 mal=00 scl=00 pre=00 ` ` ` `oacflg=10 fl2=0001 frm=01 csi=852 siz=32 off=0 ` ` ` `kxsbbbfp=7ffff6477d78 bln=32 avl=01 flg=09 ` ` ` `value= ` `"*"
```
通过这里我们发现在独立修改pdb参数之时,其本质是在pdb_spfile$基表中插入或者修改相关记录(第一次修改插入,后续修改是更新)
关于pdb_spfile$基表分析
```
SQL> SHOW CON_NAME; ` `CON_NAME ` `------------------------------ ` `CDB$ROOT ` `SQL> COL OWNER ` `FOR ` `A10 ` `SQL> ` `select ` `con_id,owner,object_type ` `from ` `cdb_objects ` `where ` `object_name= ` `'PDB_SPFILE$' ` `; ` ` ` `CON_ID OWNER OBJECT_TYPE ` `---------- ---------- ----------------------- ` ` ` `2 SYS ` `TABLE ` ` ` `1 SYS ` `TABLE ` ` ` `3 SYS ` `TABLE ` `SQL> COL DB_UNIQ_NAME ` `FOR ` `A10 ` `SQL> COL ` `NAME ` `FOR ` `A15 ` `SQL> COL VALUE$ ` `FOR ` `A10 ` `SQL> ` `SELECT ` `DB_UNIQ_NAME,PDB_UID, ` `NAME ` `,VALUE$ ` `FROM ` `PDB_SPFILE$; ` `DB_UNIQ_NA PDB_UID ` `NAME ` `VALUE$ ` `---------- ---------- --------------- ---------- ` `cdb 3313918585 sessions 101 ` `SQL> ` `ALTER ` `SESSION ` `SET ` `CONTAINER=pdb1; ` `Session altered. ` `SQL> ` `SELECT ` `DB_UNIQ_NAME,PDB_UID, ` `NAME ` `,VALUE$ ` `FROM ` `PDB_SPFILE$; ` `no ` `rows ` `selected
```