转自:http://www.xifenfei.com/2013/06/oracle-12c-cdb%E4%B8%ADpdb%E5%8F%82%E6%95%B0%E7%AE%A1%E7%90%86%E6%9C%BA%E5%88%B6.html
在ORACLE 12C中参数文件只是记录了cdb的参数信息,没有记录任何的pdb的信息,那ORACLE是如何管理使得各个pdb有自己的参数,这里通过试验的出来ORACLE 12C CDB环境中是通过参数文件结合PDB_SPFILE$来实现参数管理
数据库版本
<code>SQL></code><code>select</code> <code>*</code><code>from</code> <code>v$version;</code>
<code>BANNER CON_ID</code>
<code>-------------------------------------------------------------------------------- ----------</code>
<code>Oracle</code><code>Database</code> <code>12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production 0</code>
<code>PL/SQL Release 12.1.0.1.0 - Production 0</code>
<code>CORE 12.1.0.1.0 Production 0</code>
<code>TNS</code><code>for</code> <code>Linux: Version 12.1.0.1.0 - Production 0</code>
<code>NLSRTL Version 12.1.0.1.0 - Production 0</code>
pdb信息
<code>SQL> </code><code>select</code> <code>PDB_NAME,CON_UID,pdb_id,status</code><code>from</code> <code>dba_pdbs;</code>
<code>PDB_NAME CON_UID PDB_ID STATUS</code>
<code>---------- ---------- ---------- -------------</code>
<code>PDB1 3313918585 3 NORMAL</code>
<code>PDB$SEED 4048821679 2 NORMAL</code>
<code>PDB2 3872456618 4 NORMAL</code>
<code>SQL></code><code>select</code> <code>con_id,dbid,</code><code>NAME</code><code>,OPEN_MODE</code><code>from</code> <code>v$pdbs;</code>
<code> </code><code>CON_ID DBID</code><code>NAME</code> <code>OPEN_MODE</code>
<code>---------- ---------- ------------------------------ ----------</code>
<code> </code><code>2 4048821679 PDB$SEED </code><code>READ</code> <code>ONLY</code>
<code> </code><code>3 3313918585 PDB1 </code><code>READ</code> <code>WRITE</code>
<code> </code><code>4 3872456618 PDB2 MOUNTED</code>
CDB$ROOT中修改参数
<code>--指定container=all</code>
<code>SQL> show con_name</code>
<code>CON_NAME</code>
<code>------------------------------</code>
<code>CDB$ROOT</code>
<code>SQL></code><code>alter</code> <code>system</code><code>set</code> <code>open_cursors=500 container=</code><code>all</code><code>;</code>
<code>System altered.</code>
<code>SQL> show parameter open_cursors;</code>
<code>NAME</code> <code>TYPE VALUE</code>
<code>------------------------------------ ----------- ------------------------------</code>
<code>open_cursors </code><code>integer</code> <code>500</code>
<code>SQL></code><code>alter</code> <code>session</code><code>set</code> <code>container=pdb1;</code>
<code>Session altered.</code>
<code>PDB1</code>
<code>--在CDB$ROOT中修改不指定container参数表示全部pdb生效</code>
<code>SQL></code><code>alter</code> <code>session</code><code>set</code> <code>container=CDB$ROOT;</code>
<code>SQL></code><code>alter</code> <code>system</code><code>set</code> <code>open_cursors=100;</code>
<code>SQL> show parameter open_cursors;</code>
<code>open_cursors </code><code>integer</code> <code>100</code>
<code>--指定container=current</code>
<code>SQL></code><code>alter</code> <code>system</code><code>set</code> <code>open_cursors=120 container=</code><code>current</code><code>;</code>
<code>open_cursors </code><code>integer</code> <code>120</code>
<code>SQL></code><code>alter</code> <code>session</code><code>set</code> <code>container=pdb2 ;</code>
这里可以看出来,在ROOT中修改参数,默认情况和指定container=all/current均是所有open的pdb都生效.
这里有个疑问ORACLE的参数文件只是记录的cdb的sid的参数,并未记录各个pdb的参数,那是如何实现cdb中各个pdb参数不一致的呢?继续分析
修改pdb参数做10046
<code>SQL> show con_name;</code>
<code>SQL> oradebug setmypid</code>
<code>Statement processed.</code>
<code>SQL> oradebug EVENT 10046 TRACE</code><code>NAME</code> <code>CONTEXT FOREVER,</code><code>LEVEL</code> <code>12</code>
<code>SQL> oradebug TRACEFILE_NAME</code>
<code>/u01/app/oracle/diag/rdbms/cdb/cdb/trace/cdb_ora_18377.trc</code>
<code>SQL></code><code>alter</code> <code>system</code><code>set</code> <code>sessions=100;</code>
<code>SQL> oradebug EVENT 10046 trace</code><code>name</code> <code>context</code><code>off</code>
<code>--继续修改pdb参数</code>
<code>SQL> oradebug setmypid</code>
<code>SQL> oradebug TRACEFILE_NAME</code>
<code>/u01/app/oracle/diag/rdbms/cdb/cdb/trace/cdb_ora_20275.trc</code>
<code>SQL></code><code>alter</code> <code>system</code><code>set</code> <code>sessions=101;</code>
分析trace文件
<code>--第一次修改pdb参数值</code>
<code>insert into pdb_spfile$(db_uniq_name, pdb_uid, sid, name, value$, comment$) values(:1,:2,:3,:4,:5,:6)</code>
<code>END OF STMT</code>
<code>PARSE</code><code>#140085118752824:c=3999,e=3397,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,plh=0,tim=99767937623</code>
<code>BINDS</code><code>#140085118752824:</code>
<code> </code><code>Bind</code><code>#0</code>
<code> </code><code>oacdty=01 mxl=32(03) mxlc=00 mal=00 scl=00 pre=00</code>
<code> </code><code>oacflg=10 fl2=0001 frm=01 csi=852 siz=32 off=0</code>
<code> </code><code>kxsbbbfp=7fffcfaa5842 bln=32 avl=03 flg=09</code>
<code> </code><code>value=</code><code>"cdb"</code>
<code> </code><code>Bind</code><code>#1</code>
<code> </code><code>oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00</code>
<code> </code><code>oacflg=00 fl2=1000001 frm=00 csi=00 siz=24 off=0</code>
<code> </code><code>kxsbbbfp=7f681bbb2170 bln=22 avl=06 flg=05</code>
<code> </code><code>value=3313918585</code>
<code> </code><code>Bind</code><code>#2</code>
<code> </code><code>oacdty=01 mxl=32(01) mxlc=00 mal=00 scl=00 pre=00</code>
<code> </code><code>kxsbbbfp=7fffcfaa46f8 bln=32 avl=01 flg=09</code>
<code> </code><code>value=</code><code>"*"</code>
<code> </code><code>Bind</code><code>#3</code>
<code> </code><code>oacdty=01 mxl=32(08) mxlc=00 mal=00 scl=00 pre=00</code>
<code> </code><code>kxsbbbfp=0bc220d8 bln=32 avl=08 flg=09</code>
<code> </code><code>value=</code><code>"sessions"</code>
<code> </code><code>Bind</code><code>#4</code>
<code> </code><code>kxsbbbfp=7fffcfaa474c bln=32 avl=03 flg=09</code>
<code> </code><code>value=</code><code>"100"</code>
<code> </code><code>Bind</code><code>#5</code>
<code> </code><code>oacdty=01 mxl=32(00) mxlc=00 mal=00 scl=00 pre=00</code>
<code> </code><code>kxsbbbfp=00000000 bln=32 avl=00 flg=09</code>
<code>--第二次修改pdb参数值(相同参数)</code>
<code>update pdb_spfile$</code><code>set</code> <code>value$=:5, comment$=:6 where name=:1 and pdb_uid=:2 and db_uniq_name=:3 and sid=:4</code>
<code>BINDS</code><code>#140603847818408:</code>
<code> </code><code>kxsbbbfp=7ffff6477dcc bln=32 avl=03 flg=09</code>
<code> </code><code>value=</code><code>"101"</code>
<code> </code><code>kxsbbbfp=7fe0e2638320 bln=22 avl=06 flg=05</code>
<code> </code><code>kxsbbbfp=7ffff6478ec2 bln=32 avl=03 flg=09</code>
<code> </code><code>kxsbbbfp=7ffff6477d78 bln=32 avl=01 flg=09</code>
通过这里我们发现在独立修改pdb参数之时,其本质是在pdb_spfile$基表中插入或者修改相关记录(第一次修改插入,后续修改是更新)
关于pdb_spfile$基表分析
<code>SQL> SHOW CON_NAME;</code>
<code>SQL> COL OWNER</code><code>FOR</code> <code>A10</code>
<code>SQL></code><code>select</code> <code>con_id,owner,object_type</code><code>from</code> <code>cdb_objects</code><code>where</code> <code>object_name=</code><code>'PDB_SPFILE$'</code><code>;</code>
<code> </code><code>CON_ID OWNER OBJECT_TYPE</code>
<code>---------- ---------- -----------------------</code>
<code> </code><code>2 SYS </code><code>TABLE</code>
<code> </code><code>1 SYS </code><code>TABLE</code>
<code> </code><code>3 SYS </code><code>TABLE</code>
<code>SQL> COL DB_UNIQ_NAME</code><code>FOR</code> <code>A10</code>
<code>SQL> COL</code><code>NAME</code> <code>FOR</code> <code>A15</code>
<code>SQL> COL VALUE$</code><code>FOR</code> <code>A10</code>
<code>SQL></code><code>SELECT</code> <code>DB_UNIQ_NAME,PDB_UID,</code><code>NAME</code><code>,VALUE$</code><code>FROM</code> <code>PDB_SPFILE$;</code>
<code>DB_UNIQ_NA PDB_UID</code><code>NAME</code> <code>VALUE$</code>
<code>---------- ---------- --------------- ----------</code>
<code>cdb 3313918585 sessions 101</code>
<code>SQL></code><code>ALTER</code> <code>SESSION</code><code>SET</code> <code>CONTAINER=pdb1;</code>
<code>SQL> </code><code>SELECT</code> <code>DB_UNIQ_NAME,PDB_UID,</code><code>NAME</code><code>,VALUE$</code><code>FROM</code> <code>PDB_SPFILE$;</code>
<code>no</code> <code>rows</code> <code>selected</code>
证明pdb中不同于root的参数是记录在root的PDB_SPFILE$基表中.
整个CDB的工作原理是如果在PDB_SPFILE$中无相关参数记录,则继承cdb的参数文件中值,如果PDB_SPFILE$中有记录则使用该值覆盖cdb参数文件值.
删除PDB_SPFILE$验证
<code>SQL> </code><code>select</code> <code>con_id,dbid,</code><code>NAME</code><code>,OPEN_MODE</code><code>from</code> <code>v$pdbs;</code>
<code> </code><code>3 3313918585 PDB1 MOUNTED</code>
<code> </code><code>4 3872456618 PDB2 </code><code>READ</code> <code>WRITE</code>
<code>SQL></code><code>alter</code> <code>session</code><code>set</code> <code>container=pdb2;</code>
<code>SQL></code><code>alter</code> <code>system</code><code>set</code> <code>open_cursors=110;</code>
<code>open_cursors </code><code>integer</code> <code>110</code>
<code>SQL> conn /</code><code>as</code> <code>sysdba</code>
<code>Connected.</code>
<code>SQL></code><code>select</code> <code>value$</code><code>from</code> <code>pdb_spfile$</code><code>where</code> <code>name</code><code>=</code><code>'open_cursors'</code><code>;</code>
<code>VALUE$</code>
<code>--------------------------------------------------------------------------------</code>
<code>110</code>
<code>SQL></code><code>delete</code> <code>from</code> <code>pdb_spfile$</code><code>where</code> <code>name</code><code>=</code><code>'open_cursors'</code><code>;</code>
<code>1 row deleted.</code>
<code>SQL></code><code>commit</code><code>;</code>
<code>Commit</code> <code>complete.</code>
<code>SQL> startup</code>
<code>ORACLE instance started.</code>
<code>Total System</code><code>Global</code> <code>Area 597098496 bytes</code>
<code>Fixed</code><code>Size</code> <code>2291072 bytes</code>
<code>Variable</code><code>Size</code> <code>272632448 bytes</code>
<code>Database</code> <code>Buffers 314572800 bytes</code>
<code>Redo Buffers 7602176 bytes</code>
<code>Database</code> <code>mounted.</code>
<code>Database</code> <code>opened.</code>
<code>SQL></code><code>alter</code> <code>database</code> <code>open</code><code>;</code>
<code>Database</code> <code>altered.</code>
删除PDB_SPFILE$中相关记录,pdb的参数值会自动继续继承cdb中参数值
总结说明:通过上述的一些列试验证明cdb中参数关系,在cdb中修改,会默认所有pdb均自动继承;如果在pdb中修改值会覆盖cdb参数,而且只对当前pdb生效,并记录在PDB_SPFILE$