暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

oracle 12c pdb,cbd

原创 逆风飞翔 2022-03-17
1386

CDB组件(Components of a CDB)
一个CDB数据库容器包含了下面一些组件:
ROOT组件
ROOT又叫CDB$ROOT, 存储着ORACLE提供的元数据和Common User,元数据的一个例子是ORACLE提供的PL/SQL包的源代码,Common User 是指在每个容器中都存在的用户。

SEED组件
  Seed又叫PDB$SEED,这个是你创建PDBS数据库的模板,你不能在Seed中添加或修改一个对象。一个CDB中有且只能有一个Seed. 这个感念,个人感觉非常类似SQL SERVER中的model数据库。

PDBS
    CDB中可以有一个或多个PDBS,PDBS向后兼容,可以像以前在数据库中那样操作PDBS,这里指大多数常规操作。
    这些组件中的每一个都可以被称为一个容器。因此,ROOT(根)是一个容器,Seed(种子)是一个容器,每个PDB是一个容器。每个容器在CDB中都有一个独一无二的的ID和名称。


select con_id,dbid,NAME,OPEN_MODE from v$pdbs;

CBD:
alter PLUGGABLE database pdb1 open;
alter PLUGGABLE database pdb1 close;

PDB:
alter PLUGGABLE database all open;
alter PLUGGABLE database all close;

alter session set container=pdb1;

--自动启动PDB
--在12.1.0.2及其以后版本,可以通过设置
ALTER PLUGGABLE DATABASE PDB SAVE STATE;
--来实现在cdb open之后业务pdb能够自动open.


sqlplus sys/xifenfei@pdb1 as sysdba ##连接CDB

show con_name;

[oracle@xifenfei ~]$ sqlplus / as sysdba
SQL> alter session set container=pdb1; ##切换到PDB
show con_name;

创建用户: 在cdb中只能创建全局用户(c##开头)

create user c##xff identified by xifenfei;

SELECT USERNAME,CON_ID,USER_ID FROM CDB_USERS WHERE USERNAME;

SQL> alter session set container=pdb1;

SQL> show con_name
CON_NAME
------------------------------
PDB1
SQL> create user xff identified by xifenfei;

创建用户默认的是container=all,在cdb中只能创建全局用户(c##开头),会在cdb和所有的pdb中创建该用户(但是pdb中的全局用户需要另外授权才能够在pdb中访问)。在pdb中只能创建的用户为本地用户


用户授权

SQL> grant connect to c##xff;

Grant succeeded.

SQL> select GRANTEE,con_id from cdb_ROLE_PRIVS where GRANTED_ROLE='CONNECT' AND GRANTEE='C##XFF';


SQL> grant resource to c##xff container=all;

Grant succeeded.

SQL>select GRANTEE,con_id from cdb_ROLE_PRIVS where GRANTED_ROLE='RESOURCE' AND? GRANTEE='C##XFF';

用户授权默认情况下是只会给当前container,在cdb中也可以指定container=all,对所有open的pdb且存在该用户都进行授权

修改参数:
1.cDB
alter system set open_cursors=500 container=all;

2.pdb
SQL> conn sys/xifenfei@pdb1 as sysdba
SQL> alter database open;
SQL> alter system set open_cursors=100;

这里可以看到在cdb中修改,pdb会继承进去;如果在pdb中修改会覆盖pdb从cdb中继承的参数含义

在ORACLE 12C中参数文件只是记录了cdb的参数信息,没有记录任何的pdb的信息,那ORACLE是如何管理使得各个pdb有自己的参数,这里通过试验的出来ORACLE 12C CDB环境中是通过参数文件结合
PDB_SPFILE$来实现参数管理

pdb信息

select PDB_NAME,CON_UID,pdb_id,status from dba_pdbs;
select con_id,dbid,NAME,OPEN_MODE from v$pdbs;

CDB$ROOT中修改参数

--指定container=all
SQL> show con_name

CON_NAME
------------------------------
CDB$ROOT

SQL> alter system set open_cursors=500 container=all;

SQL> show parameter open_cursors;

SQL> alter session set container=pdb1;

SQL> show con_name

SQL> show parameter open_cursors;

--在CDB$ROOT中修改不指定container参数,表示全部pdb生效
SQL> alter session set container=CDB$ROOT;

SQL> alter system set open_cursors=100;

SQL>? show parameter open_cursors;

SQL> alter session set container=pdb1;

SQL> show parameter open_cursors;

--指定container=current
SQL> alter system set open_cursors=120 container=current;

SQL> show parameter open_cursors;

SQL> alter session set container=pdb2 ;

SQL> show parameter open_cursors;

这里可以看出来,在ROOT中修改参数,默认情况和指定container=all/current均是所有open的pdb都生效.
这里有个疑问ORACLE的参数文件只是记录的cdb的sid的参数,并未记录各个pdb的参数,那是如何实现cdb中各个pdb参数不一致的呢?继续分析

修改pdb参数做10046

SQL> show con_name;
CON_NAME
------------------------------
PDB1
SQL> oradebug setmypid
oradebug event 10046 trace name context forever ,level 12;

SQL> oradebug TRACEFILE_NAME /u01/app/oracle/diag/rdbms/cdb/cdb/trace/cdb_ora_18377.trc
SQL> alter system set sessions=100;

SQL> oradebug event 10046 trace name context off;

--继续修改pdb参数
SQL> alter session set container=pdb1;

SQL>oradebug setmypid

SQL> oradebug EVENT 10046 TRACE NAME CONTEXT FOREVER, LEVEL 12

SQL>oradebug TRACEFILE_NAME /u01/app/oracle/diag/rdbms/cdb/cdb/trace/cdb_ora_20275.trc;
SQL> alter system set sessions=101;

SQL> oradebug EVENT 10046 trace name context off;

分析trace文件

--第一次修改pdb参数值
insert into pdb_spfile$(db_uniq_name, pdb_uid, sid, name, value$, comment$) values(:1,:2,:3,:4,:5,:6);

--第二次修改pdb参数值(相同参数)
update pdb_spfile$ set value$=:5, comment$=:6 where name=:1 and pdb_uid=:2 and db_uniq_name=:3 and sid=:4;

这里我们发现在独立修改pdb参数之时,其本质是在pdb_spfile$基表中插入或者修改相关记录(第一次修改插入,后续修改是更新)

关于pdb_spfile$基表分析

select con_id,owner,object_type from cdb_objects where object_name='PDB';

SELECT DB_UNIQ_NAME,PDB_UID,NAME,VALUE$ FROM PDB_SPFILE$;

ALTER SESSION SET CONTAINER=pdb1;

SQL>SELECT DB_UNIQ_NAME,PDB_UID,NAME,VALUE$ FROM PDB_SPFILE$;

证明pdb中不同于root的参数是记录在root的PDB_SPFILE$基表中.
整个CDB的工作原理是如果在PDB_SPFILE$中无相关参数记录,则继承cdb的参数文件中值,
如果PDB_SPFILE$中有记录则使用该值覆盖cdb参数文件值.

删除PDB_SPFILE$验证

select value$ from pdb_spfile$ where name='open_cursors';

delete from pdb_spfile$ where name='open_cursors';

删除PDB_SPFILE$中相关记录,pdb的参数值会自动继续继承cdb中参数值

cdb中参数关系,在cdb中修改,会默认所有pdb均自动继承;如果在pdb中修改值会覆盖cdb参数,而且只对当前pdb生效,并记录在 PDB_SPFILE$

在ORACLE 12C中引入了CDB和PDB的概念,实现了ORACLE数据库的可插拔,在一个CDB数据库中,有多个PDB,而每一个PDB又可以理解为一个独立的传统ORACLE 数据库,
那为了能够通过一个sql查询获得整个CDB数据库的信息,ORALCE 引入了 CDB_* 开头的视图,该视图就是在传统的 DBA_* 视图基础之上增加了CON_ID,用来区分不同的PDB,
从而实现了一个简单sql查询在有足够权限的情况下,可以查询所有PDB中信息


确定是否是CDB
SELECT CDB FROM V$DATABASE;

CDB中各容器信息
SELECT NAME, CON_ID, DBID, CON_UID, GUID FROM V$CONTAINERS ORDER BY CON_ID;

elect CON_NAME_TO_ID('PDB1') FROM DUAL;
SELECT CON_DBID_TO_ID(3313918585) FROM DUAL;
SELECT CON_UID_TO_ID(3313918585) FROM DUAL;

PDB部分信息

SELECT PDB_ID, PDB_NAME, STATUS FROM DBA_PDBS ORDER BY PDB_ID;

SELECT NAME, OPEN_MODE, RESTRICTED, OPEN_TIME FROM V$PDBS;

CDB中查询对象信息

SELECT p.PDB_ID, p.PDB_NAME, t.OWNER, t.TABLE_NAME
FROM DBA_PDBS p, CDB_TABLES t
WHERE p.PDB_ID > 2
AND T.TABLE_NAME='COL$'
AND p.PDB_ID = t.CON_ID
ORDER BY p.PDB_ID;

查询在CDB中的PDB数据/临时文件信息

SELECT p.PDB_ID, p.PDB_NAME, d.FILE_ID, d.TABLESPACE_NAME, d.FILE_NAME
FROM DBA_PDBS p, CDB_DATA_FILES d
WHERE p.PDB_ID = d.CON_ID
ORDER BY p.PDB_ID;


SELECT CON_ID, FILE_ID, TABLESPACE_NAME, FILE_NAME
FROM CDB_TEMP_FILES
ORDER BY CON_ID;

查询PDB的service信息

SELECT PDB, NETWORK_NAME, CON_ID FROM CDB_SERVICES
WHERE PDB IS NOT NULL AND
CON_ID > 2
ORDER BY PDB;

PDB中可以修改参数

SELECT NAME FROM V$SYSTEM_PARAMETER
WHERE ISPDB_MODIFIABLE = 'TRUE'
ORDER BY NAME;


查看PDB历史信息
SELECT DB_NAME, CON_ID, PDB_NAME, OPERATION, OP_TIMESTAMP, CLONED_FROM_PDB_NAME
FROM CDB_PDB_HISTORY
WHERE CON_ID > 2
ORDER BY CON_ID;


CREATE PDB
SELECT NAME,CDB FROM V$DATABASE;

select pdb_id,pdb_name,dbid,STATUS,CREATION_SCN from dba_pdbs;

CREATE PLUGGABLE DATABASE xff_db ADMIN USER xff IDENTIFIED BY xifenfei
STORAGE (MAXSIZE 2G MAX_SHARED_TEMP_SIZE 100M)
DEFAULT TABLESPACE xifenfei
DATAFILE '/u01/app/oracle/oradata/xifenfei/xff/xifenfei01.dbf' SIZE 25M AUTOEXTEND ON
PATH_PREFIX = '/u01/app/oracle/oradata/xifenfei/xff/'
FILE_NAME_CONVERT = ('/u01/app/oracle/oradata/xifenfei/pdbseed/', '/u01/app/oracle/oradata/xifenfei/xff/');

select pdb_id,pdb_name,dbid,STATUS,CREATION_SCN from dba_pdbs;

OPEN PDB

alter pluggable database xff_db open;

select pdb_id,pdb_name,dbid,STATUS,CREATION_SCN? from dba_pdbs;

alter pluggable database all close immediate;

select con_id,dbid,NAME,OPEN_MODE from v$pdbs;

alter pluggable database all open;

select con_id,dbid,NAME,OPEN_MODE from v$pdbs;

Unplugging a PDB from a CDB

alter pluggable database FF close immediate;

alter pluggable database ff UNPLUG into '/tmp/ff.xml';


DROP PDB

DROP PLUGGABLE DATABASE xff_db INCLUDING DATAFILES;

Plug Unplugged PDB into CDB


create pluggable database ff using '/tmp/ff.xml'
copy file_name_convert=('/u01/app/oracle/oradata/xifenfei/FF/','/u01/app/oracle/oradata/xff_l/xff');

exec DBMS_PDB.SYNC_PDB();

select con_id,dbid,NAME,OPEN_MODE from v$pdbs;
alter pluggable database all open;


ALTER PLUGGABLE DATABASE PDB SAVE STATE来实现在cdb open之后业务pdb能够自动open.

select con_name, state from dba_pdb_saved_states;

在数据库mount状态下save state
ALTER PLUGGABLE DATABASE PDB save state;

pdb为mount状态下,执行save state无记录,证明save state不成功

在数据库open状态下save state—-设置pdb随cdb启动

ALTER PLUGGABLE DATABASE PDB open;

插接式数据库已变更。

ALTER PLUGGABLE DATABASE PDB save state;

插接式数据库已变更。

select con_name, state from dba_pdb_saved_states;
pdb为open状态下,执save state成功.

需要注意 save state 需要在 pdb open情 况下执行才能够生效.

禁用pdb随cdb启动—DISCARD STATE

ALTER PLUGGABLE DATABASE PDB DISCARD state;

12.1.0.1中设置pdb随cdb启动

CREATE TRIGGER open_all_pdbs
AFTER STARTUP
ON DATABASE
BEGIN
EXECUTE IMMEDIATE 'alter pluggable database all open';
END open_all_pdbs;
/

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论