CDB和PDB

本文 oracle 版本 12.2.0.1.0 。

Oracle 12C(2013年发布)后采用多租户架构(Multitenant architecture),引入了CDB(container database)与PDB(pluggable database),12.2后引入Application Container,一个CDB可以承载多个PDB或Application Container。

默认安装后会创建一个ORCL实例、一个CDB和一个ORCLPDB(12.2后),Application Container是可选的。

假定我们通过 Net Manager 配置了两个网络服务名 orcl 和 orclpdb(不是监听哦),在SQL Plus分别用system(或system@orcl) 和 system@orclpdb 登录,则可以连接到CDB或PDB。Sqlplus默认连接CDB。

基本概念

Multitenant Environment:多租户环境

CDB:CDB全称为 Container Database ,容器数据库。(公用用户)

PDB:PDB全称为 Pluggable Database ,可插拔数据库。(本地用户)

关系如下图:

img

通过上图我们可以清楚的看到CDB的组成部分:

1、ROOT:ROOT又叫CDB$ROOT, 存储着ORACLE提供的元数据和Common User(公用用户),元数据的一个例子是ORACLE提供的PL/SQL包的源代码,Common User 是指在每个容器中都存在的用户。 一个CDB只能有一个根。

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

3、PDB:PDB展现给用户和应用的形象就像是一个没有CDB的普通数据库一样。例 如,一个PDB可以包括支持一个特定应用程序所需的所有数据和代码。PDB 完全向后兼容Oracle12c之前版本的所有数据库。

这些组件中的每一个都可以被称为一个容器。因此,ROOT(根)是一个容器,Seed(种子)是一个容器,每个PDB是一个容器。每个容器在CDB中都有一个独一无二的的ID和名称。

我们可以很轻松的向CDB中插入一个PDB或者从CDB中拔出一个PDB。当我们将一个PDB插入CDB中时,相当于将这个PDB与CDB连接起来。反之则解除关系。

这大大方便了数据的迁移。我们可以很方便的将一个特定的PDB从一个CDB挪到另一个CDB上面而不改变里面的任何数据和架构。当然,一个PDB只能在同一时间内插入一个CDB而不是多个。每一个PDB都有自己独一无二的全局唯一标识符(GUID)来预防PDB的错乱使用。

创建

创建CDB

PDB包含在CDB中,所以,要创建PDB,必须先创建CDB。一台机器上可以有多个CDB。Oracle软件安装完成后,就可以创建CDB

数据库配置助手(Database Configuration Assistant)简称DBCA,在12c中的功能有:创建数据库、配置现有数据库、删除数据库、管理数据库模板、管理可插入数据库、Oracle RAC 数据库实例管理。

image-20191202205647183

典型配置

image-20191202210248078

image-20191202210658009

image-20191202211246482

image-20191202211734854

image-20191202212755554

高级配置

以下是部分截图,其他操作请参考 Oracle安装及客户端连接配置

image-20191208015621654

image-20191208020616949

创建PDB

image-20191202214510386

image-20191202214755463

image-20191202215122779

image-20191203205741176

若所选数据库是容器数据库就不会出现上图提示,而是进入下图:

image-20191202215318684

image-20191202215944249

image-20191202220148279

image-20191202220224291

image-20191202220515721

image-20191202220536473

连接

CDB和PDB有各自的sys账号?

连接CDB

Sqlplus默认连接CDB

1
2
3
4
5
sqlplus sys/passwd as sysdba # 任意passwd
sqlplus sys/ as sysdba
sqlplus sys as sysdba
sqlplus / as sysdba
sqlplus /as sysdba

计算机管理 > 组 > ora_dba组里的用户,无需输入用户和口令,直接以sysdba的身份登陆数据库。

image-20191130132834756

连接PDB

pdb可以通过在CDB中alter session container

1
2
alter session set container=pdb1
show con_name

也可以直接通过tns方式(如下)登录

1
sqlplus sys/oracle@pdb1 as sysdba

其中 tnsnames.ora 添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
PDB1 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = pdb1)
)
)

PDB2 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
(CONNECT_DATA =
(SERVICE_NAME = pdb2)
)
)

启动与关闭

启动关闭CDB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
SQL> show con_name # 查看容器名称和ID

CON_NAME
------------------------------
CDB$ROOT
SQL> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
SQL> startup
ORACLE 例程已经启动。

Total System Global Area 5117050880 bytes
Fixed Size 8929496 bytes
Variable Size 1140854568 bytes
Database Buffers 3959422976 bytes
Redo Buffers 7843840 bytes
数据库装载完毕。
数据库已经打开。
SQL> set linesize 2000;
SQL> select con_id,dbid,NAME,OPEN_MODE from v$pdbs;

CON_ID DBID NAME OPEN_MODE
---------- ---------- -----------------------------------------------------------------
2 4284962797 PDB$SEED READ ONLY
3 2320597118 ORCLPDB MOUNTED

从上面的操作中可以看到数据库启动的时候所有的PDBs的状态为MOUNTED

启动关闭PDB

pdb的管理可以在cdb中进行也可以在pdb中进行,如果是cdb中进行,需要PLUGGABLE关键字,如果是在pdb中直接和普通数据库一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
SQL> show con_name # 查看容器名称和ID

CON_NAME
------------------------------
CDB$ROOT
SQL> select con_id,dbid,NAME,OPEN_MODE from v$pdbs;

CON_ID DBID NAME OPEN_MODE
---------- ---------- -----------------------------------------------------------------
2 4284962797 PDB$SEED READ ONLY
3 2320597118 ORCLPDB MOUNTED

SQL> alter pluggable database orclpdb open;

插接式数据库已变更。

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

CON_ID DBID NAME OPEN_MODE
---------- ---------- -----------------------------------------------------------------
2 4284962797 PDB$SEED READ ONLY
3 2320597118 ORCLPDB READ WRITE

SQL> alter pluggable database orclpdb close;

插接式数据库已变更。

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

CON_ID DBID NAME OPEN_MODE
---------- ---------- -----------------------------------------------------------------
2 4284962797 PDB$SEED READ ONLY
3 2320597118 ORCLPDB MOUNTED

SQL> alter pluggable database all open; # 启动所有

插接式数据库已变更。

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

CON_ID DBID NAME OPEN_MODE
---------- ---------- -----------------------------------------------------------------
2 4284962797 PDB$SEED READ ONLY
3 2320597118 ORCLPDB READ WRITE

SQL> alter pluggable database all close; # 关闭所有

插接式数据库已变更。

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

CON_ID DBID NAME OPEN_MODE
---------- ---------- -----------------------------------------------------------------
2 4284962797 PDB$SEED READ ONLY
3 2320597118 ORCLPDB MOUNTED

SQL> alter session set container=orclpdb ; # 切换

会话已更改。

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

CON_ID DBID NAME OPEN_MODE
---------- ---------- -----------------------------------------------------------------
3 2320597118 ORCLPDB MOUNTED

SQL> startup
插接式数据库已打开。
SQL> select con_id,dbid,NAME,OPEN_MODE from v$pdbs;

CON_ID DBID NAME OPEN_MODE
---------- ---------- -----------------------------------------------------------------
3 2320597118 ORCLPDB READ WRITE

SQL> shutdown
插接式数据库已关闭。
SQL> select con_id,dbid,NAME,OPEN_MODE from v$pdbs;

CON_ID DBID NAME OPEN_MODE
---------- ---------- -----------------------------------------------------------------
3 2320597118 ORCLPDB MOUNTED

SQL>

自动启动所有PDB

从上面的操作中可以看到数据库启动的时候所有的PDBs的状态为MOUNTED,在实际应用可以考虑增加如下的触发器使所有的PDBs都处于打开状态。

1
2
3
4
create or replace trigger sys.open_all_pdbs after startup on database
begin
execute immediate 'alter pluggable database all open';
end open_all_pdbs;

验证过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
SQL> create or replace trigger sys.open_all_pdbs after startup on database

2 begin

3 execute immediate 'alter pluggable database all open';

4 end open_all_pdbs;

5 /

触发器已创建

SQL> shutdown

数据库已经关闭。

已经卸载数据库。

ORACLE 例程已经关闭。

SQL> startup

ORACLE 例程已经启动。

Total System Global Area 5044088832 bytes

Fixed Size 2413072 bytes

Variable Size 1040190960 bytes

Database Buffers 3992977408 bytes

Redo Buffers 8507392 bytes

数据库装载完毕。

数据库已经打开。

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

CON_ID DBID NAME OPEN_MODE

---------- ---------- ------------------------------ ----------

2 4122484437 PDB$SEED READ ONLY

3 3387525155 PDB1 READ WRITE

4 3946119498 PDB2 READ WRITE

SQL>

常用SQL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
-- 查看数据库版本
select * from v$version;

-- 查询所有服务 吗?吗?吗?
select name,pdb from v$services;

# 查看当前所在的容器
show con_name;
select sys_context('USERENV','CON_NAME') from dual; -- 使用sys_context查看属于哪个容器

# 查看所有pdb及状态
show pdbs;
select con_id,dbid,guid,name,open_mode,restricted from v$pdbs; -- 通过视图查询

# 切入container
alter session set container=orclpdb; -- 切换到ORCLPDB可拔插数据库
alter session set container=CDB$ROOT; -- 切回到CDB容器数据库

# 启动PDB
alter pluggable database orclpdb open; -- 开启指定PDB
alter pluggable database all open; -- 开启所有PDB
alter session set container=orclpdb; -- 切换到PDB进去开启数据库
startup;

# 关闭PDB
alter pluggable database orcl1 close; -- 关闭指定的PDB
alter pluggable database all close; -- 关闭所有PDB
alter session set container=orcl1; -- 切换到PDB进去关闭数据库
shutdown immediate;

# 查看当前数据库名
show parameter db_name;
select name from v$database; -- 通过视图查询

# 查看数据库实例名
show parameter instance_name;
select instance_name from v$instance; -- 通过视图查询

# 查看数据库域名
show parameter db_domain;
select value from v$parameter where name='db_domain';

# 查看数据库服务名
show parameter service_name; -- 第一次安装数据库勾选【创建为容器数据库】时,都是orcl.zhaolq.com,不理解

# 查看全局数据库名
SELECT * FROM GLOBAL_NAME;

参考

CDB和PDB的创建、连接、启动、关闭

ORACLE-BASE - Multitenant : Overview of Container Databases (CDB) and Pluggable Databases (PDB)

【ORACLE】ORACLE 12c PDB 基础 - 临渊羡鱼 - 博客频道 - CSDN.NET

CDB和PDB基本管理 - Ziyoo - 博客园

ORACLE 12C PDB 维护基础介绍 – 提供专业ORACLE技术咨询和支持@Phone:13429648788 - 惜分飞

Oracle 12c CDB PDB - 丁应思 - 博客园

Oracle 12c入门第三讲: Oracle 12c基本体系结构 (3) pdb,cdb元数据关系 …,数据智能网,Oracle 12C

浅谈Oracle数据库12c PDB技术 - Oracle安装与升级 - TechTarget数据库