Oracle-Container-Base-1

Oracle容器数据库基本知识

容器数据库,又称为可插入数据库,又可以称为多租户容器数据库
Oracle Multitenant Container Database(CDB)

CDB 是 Oracle 12C 引入的特性,指的是可以容纳一个或者多个可插拔数据库的数据库,这个特性允许在 CDB 容器数据库中创建并且维护多个数据库,在 CDB 中创建的数据库被称为PDB,每个 PDB 在 CDB 中是相互独立存在的,在单独使用 PDB 时,与普通数据库无任何区别。

CDB 根容器数据库的主要作用就是容纳所有相关的 PDB 的元数据,以及在 CDB 中对所有的 PDB 进行管理。

即容器被称为 CDB,容器里的子数据库被称为 PDB。

一、容器数据库的组成

1.1 ROOT

Root 容器数据库,是 CDB 环境中的根数据库,在根数据库中含有主数据字典视图,其中包含了与 Root 容器有关的元数据和 CDB 中所包含的所有的 PDB 信息。在 CDB 环境中被标识为 CDB$ROOT,每个 CDB 环境中只能有一个 Root 容器数据库。

1.2 CDB seed

CDB seed 为 PDB 的种子,其中提供了数据文件,在 CDB 环境中被标识为 PDB$SEED ,是 创 建 新 的 PDB 的 模 板 , 你 可 以 连 接 PDB$SEED,是创建新的 PDB 的模板,你可以连接 PDB$SEED,是创建新的 PDB 的模板,你可以连接 PDB$SEED,但是不能执行任何事物,因为 PDB$SEED 是只读的,不可进行修改。

1.3 PDBs

PDB 数据库,在 CDB 环境中每个 PDB 都是独立存在的,与传统的 Oracle 数据库基本无差别,每个 PDB 拥有自己的数据文件和 objects,唯一的区别在于 PDB 可以插入到 CDB 中,以及在 CDB 中拔出,并且在任何一个时间点之上 PDB 必须拔出或者插入到一个 CDB 中,当用户链接 PDB 时不会感觉到根容器和其他 PDB 的存在。

1.4 Application Containers

Oracle 在 12c R2 版本中,对容器功能进行了增强,在 CDB root 容器中可以还创建一个叫做 Application root 的容器,可在其内创建多个依赖于 Application root 的 Application PDBs,架构图如下:

简单地说就是容器里还能创建容器。

1.5 根环境的用户

在之前的版本中,单个 PDB 可以有多个用户,每个用户又可以有自己的表空间,上升到 CDB 级别,用户被分成了两类:
公用用户和本地用户。

公用用户

公用用户是在 root 数据库中和所有的PDB数据库中都存在的用户,公用用户必须在根容器中创建,然后此用户会在所有的现存的 PDB 中自动创建,公用用户标识必须以 c## 或者C##开头,sys 和 system 用户是 Oracle 在 CDB 环境中自动创建的公用用户。

本地用户

本地用户指的是在 PDB 中创建的普通用户,只有在创建它的 PDB 中才会存在该用户,并且 PDB 中只能创建本地用户。

另外值得一提的是,PDB 中没有以前默认的 scott 用户了,需要我们重新创建。
还有,通过 sqlplus / as sysdba 登录连接的是 CDB。(重点)

二、容器数据库的安装及使用

2.1 安装

记得在 DBCA 创建 数据库时 有一个 是否创建容器数据库的勾选(只要勾选就是创建了容器数据库)

2.2 常用命令

在安装好之后,打开 sqlplus,用管理员账户登录

1
sqlplus / as sysdba

2.2.1 查看当前的容器

方式一

1
show con_name;

方式二

1
select sys_context('userenv', 'con_name') from dual;

可以看到当前是根容器。

2.2.2 查看数据库是否为 CDB

1
select name,cdb,open_mode,con_id from v$database;

Open_mode 是读写权限

2.2.3 查看 CDB 中的 PDB 信息

方式一

1
show pdbs;

方式二

1
select con_id,dbid,name,open_mode from v$pdbs;

可以看到里面是种子和默认的 PDB。

2.2.4 启动和关闭已创建好的 PDB 数据库 (PDB(容器数据库)的启停非常的快,因为需要的资源和配置较少)

1 容器命令进行启停 PDB 数据库

开启 PDB 命令

1
alter pluggable database pdb1 open;

关闭 PDB 命令

1
alter pluggable database pdb1 close;

2 传统的 shartup 与 shutdown (需要连接到对应的 PDB 数据库)

切换 PDB 会话 命令

1
alter session set container = pdb1;

开启 PDB 命令

1
shartup;

关闭 PDB 命令

1
shutdown immediate;

补充说明

启动 PDB:

1
2
3
4
5
6
--开启所有 PDB
alter pluggable database all open;
--开启名称为 PDBNAME 的 PDB
alter pluggable database PDBNAME open;
-- 切换名称为 PDBNAME 的 PDB 里面去开启
alter session set container=PDBNAME; 再执行startup

关闭 PDB:

1
2
3
4
5
6
--关闭所有 PDB,不加 immediate 就是默认的 normal
alter pluggable database all close immediate;
--关闭名称为 PDBNAME 的 PDB,不加 immediate 就是默认的 normal
alter pluggable database PDBNAME close immediate;
--切换名称为 PDBNAME 的 PDB 里面去关闭
alter session set container=PDBNAME;再执行 shutdown immediate

这里给出 SHUTDOWN 的几个参数及含义

shutdown normal: shutdown 的默认方式,a.不允许新的数据库连接;b.只有当所有连接都断开后才能关闭,效率较低
shutdown immidiate: shutdown 的常用方式,a.不允许创建新连接;b.已经创建的连接,如果有未执行完的 SQL 语句,等待其完成,如果没有立刻断开;c.未提交事务全部回滚
shutdown transactional: 使用率很低
shutdown abort: a.未提交事务不回滚;b.终止所有 SQL 操作;c.所有连接都断开。数据库关闭迅速,但是下一次开启需要进行实例恢复,启动慢;而且回滚段数据与数据文件可能不一致。

2.2.5 CDB 与 PDB 的切换

1
2
3
4
5
6
-- 切换到 PDB1 容器数据库中
alter session set container=PDB1;
-- 切换到 CDB 数据库中
alter session set container=CDB$ROOT;
-- 查看当前容器的名称
show con_name;

2.3 PDB 的创建与删除

PDB 数据库的创建可以从现存的数据库中复制数据文件,包括种子容器、可插拔数据库、non-CDB 数据库,创建时可以使用 CREATE PLUGGABLE、RMAN、DBCA 以及 EM 等。
在 12.1 版本中在创建 PDB 时,Source PDB 必须处于read only状态,在 12.2 版本中,因为 undo local mode 新特性的推出,在创建 PDB 时,Source PDB 在 read write 状态,依然可以创建。
另外在 12.2 版本中 Oracle 推出了 refresh PDB 特性,具有对 Source PDB 进行增量同步的功能。

使用 CREATE PLUGGABLE 命令可以使用以下资源创建 PDB

😊 CDB seed (PDB$SEED)
😊 克隆已经存在的PDB
😊 Local PDB
😊 Remote PDB
😊 non-CDB数据库

2.3.1 以种子 PDB 为模板创建新的 PDB

1
CREATE PLUGGABLE DATABASE PDB2 ADMIN USER PDB2_DBA IDENTIFIED BY "PDB2_DBA" STORAGE (MAXSIZE 2G) DEFAULT TABLESPACE USERS PATH_PREFIX='D:\SEVATTAL\ORACLE\ORADATA\ORCL\PDB2\' FILE_NAME_CONVERT=('D:\SEVATTAL\ORACLE\ORADATA\ORCL\PDBSEED','D:\SEVATTAL\ORACLE\ORADATA\ORCL\PDB2');

2.3.2 克隆其他 PDB 为新的 PDB

在 Clone 本地 PDB 时需要注意一下几点:

😊 使用的用户必须拥有 'CREATE PLUGGABLE DATABASE' 的权限
😊 源 PDB 不可以是关闭状态
😊 如果 CDB 为 shared undo,PDB 必须为 READ-ONLY 状态
😊 如果 CDB 不是归档模式,那么 PDB 必须为 READ-ONLY 状态
1
CREATE PLUGGABLE DATABASE PDB3 FROM PDB2 FILE_NAME_CONVERT=('D:\SEVATTAL\ORACLE\ORADATA\ORCL\PDB2','D:\SEVATTAL\ORACLE\ORADATA\ORCL\PDB3');

ORA-65036: pluggable database PDB2 not open in required mode

2.3.3 通过一个未插入的 PDB 创建 PDB (也就是 使用 unplug 拔出命令的导出文件)

拔出 PDB

1
2
3
4
--关闭之后才能拔出
alter pluggable database PDBNAME close;
--拔出数据库,Window 下最好使用 "\" Linux 下使用 "/"
alter pluggable database PDBNAME unplug into 'D:\sevattal\oracle\unplugged_pdbs\PDBNAME.xml';

注意事项:

1. 被 unplug 的 pdb,不允许在被打开
2. XML文件中包含了每个数据文件的位置,以及初始化参数等信息 

插入 plug PDB

1
CREATE PLUGGABLE DATABASE salespdb USING '/disk1/usr/financepdb.xml' NOCOPY

上述 create pluggable database 语句中,因为数据文件都在xml文件指定的位置,且仍使用原来的位置作为新的 pdb 的数据文件的存储位置,因此没有包含其他子句。

另外一条 plug PDB 的语句也可能如下:

1
CREATE PLUGGABLE DATABASE pdbname USING '/location/filename.xml' SOURCE_FILE_NAME_CONVERT=('/location1/','/location2/') MOVEFILE_NAME_CONVERT=('/location2/','/location3/') PATH_PREFIX='/location3/' STORAGE (MAXSIZE 2G MAX_SHARED_TEMP_SIZE 100M);

这里 xml 文件中指示数据文件在 /location1/ 中,而实际上数据文件在 /location2/ 中,且最终我们要将数据文件放在 /location3 /中。

2.3.4 使用一个 Non-CDB 来创建新的 PDB

登录 Non-CDB,关闭 non-CDB 数据库并重启至只读状态,再对 non-CDB 数据库创建一个 xml 文件,再关闭 Non-CDB

1
2
3
4
5
SELECT NAME, CDB, CON_ID FROM V$DATABASE;
shutdown immediate;
startup open read only;
exec dbms_pdb.describe(pdb_descr_file=>'/home/oracle/OCP.xml');
shutdown immediate;

登录CDB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SELECT NAME, CDB, CON_ID FROM V$DATABASE;
show con_name
show pdbs
SET SERVEROUTPUT ON
DECLARE
compatible CONSTANT VARCHAR2(3) :=
CASE DBMS_PDB.CHECK_PLUG_COMPATIBILITY(
pdb_descr_file => '/home/oracle/OCP.xml',
pdb_name => 'SALESPDB')
WHEN TRUE THEN 'YES'
ELSE 'NO'
END;
BEGIN
DBMS_OUTPUT.PUT_LINE(compatible);
END;
/

执行以上语句,确保数据库是兼容的

1
create pluggable database OCP using '/home/oracle/OCP.xml' nocopy tempfile reuse;

1
2
3
4
5
6
7
show pdbs
alter session set container=OCP;
@$ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql
alter database open;
show pdbs
alter session set container=CDB$ROOT;
show pdbs

2.3.5 删除 PDB

1
2
3
4
--关闭之后才能删除
alter pluggable database PDBNAME close immediate;
--删除 PDB 并同时把数据文件也从磁盘上删除了
drop pluggable database PDBNAME including datafiles;

2.4 通过 SQL Developer 使用

但是,我们日常使用时是用 SQL Developer 的,这里与我们平时使用的又有一点区别。

2.4.1 打开 PDB1

首先,还是用管理员账户登录(此时数据库选项里是没有我们想用的 PDB1 的)

打开一个命令窗口吗,看一下当前 CDB 里 PDB 的信息

2.4.2 创建用户并授权

上面说了,PDB 里是没有我们所知道的 Scott 用户的,这里需要我们重新创建他

1
2
3
4
5
6
-- 创建用户
create user scott identified by "scott";
-- 给用户授予权限
grant connect,resource,dba to scott;
-- 删除用户
drop user scott;

创建表空间,为用户指定表空间及为用户授予权限都与以前的使用方式一样。

2.4.3 配置

前言关于数据库名称的说明(虽然以前也在 blog 中记录过,但是为了加深印象这边再次记录一次)

GLOBAL_DBNAME,SID_NAME,SERVICE_NAME

glocal_name

对一个数据库的唯一标识,在创建数据库的时候决定,缺省值为 db_name.db_domain 。在之后对参数文件中 db_name 和 db_domain 参数的任何修改都不影响 global_name 的值,如果要修改 glocal_name,只能 alter database rename global_name to <db_name,db_domain> 来进行修改,然后修改相应的参数

service_name

在 oracle 的并行环境中,一个数据库对应多个实例,就需要多个网络服务名,设置比较繁琐。service_names 参数就是为了解决这个问题,该参数对应一个数据库,而不是一个实例,缺省值为 db_name.db_domain,即等于 global_name。一个数据库可以对应多个 service_name.

oracle_sid

oracle_sid 这个参数是操作系统中用到的,他是描述默认连接的数据库实例.instance_name 是数据库参数。而 oracle_sid 是操作系统的环境变量,oracle_sid 必须与 instance_name 的值一致。

查看数据库的实例名称 instance_name 也就是 监听文件里面的 SID_NAME 参数

1
2
3
show parameter instance_name;
--或者查看 v$instance 视图
select instance_name from v$instance;

查看 容器数据库 的 全局名称 (global_name)

1
select * from global_name;

想要用 SQL Developer 登录 PDB1,我们需要更改 tnsnames.ora 文件,添加以下配置

tnsnames.ora 文件

1
2
3
4
5
6
7
8
PDB1 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = SME-IT-96966.mshome.net)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = pdb1)
)
)

listener.ora 文件 作为参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
LISTENER_ORCL =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = SME-IT-96966.mshome.net)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)

SID_LIST_LISTENER_ORCL =
(SID_LIST =
(SID_DESC =
(SID_NAME = orcl)
(GLOBAL_DBNAME = ORCL.MSHOME.NET)
(ORACLE_HOME = D:\sevattal\WINDOWS.X64_193000_db_home)
(PROGRAM = extproc)
)
(SID_DESC =
(SID_NAME = orcl)
(GLOBAL_DBNAME = pdb1)
)
)

配置完成需要重启监听

1
2
lsnrctl stop
lsnrctl start

为了马上使实例注册到监听中,可以登陆数据库执行语句(因为实例不能马上注册到监听中,需要一点时间 POM 每隔 1 分钟会重新扫描实例一次)

1
alter system register;

使用 命令行 sqlplus 进行登陆

(若连接不上,先尝试重启 PDB,再尝试重启 CDB,还是不行尝试更改 CDB 的服务名 service_names 然后重启 CDB 与 PDB)

SQL Developer 配置连接

2.5 因为所有 PDB 共享日志,所以只能在 root 容器新建日志

1
2
alter session set container = CDB$ROOT;
alter database add logfile ('/home/oracle/redo501.log','/home/oracle/redo502.log') size 10M;
Contents
  1. 1. Oracle容器数据库基本知识
    1. 1.1. 一、容器数据库的组成
      1. 1.1.1. 1.1 ROOT
      2. 1.1.2. 1.2 CDB seed
      3. 1.1.3. 1.3 PDBs
      4. 1.1.4. 1.4 Application Containers
      5. 1.1.5. 1.5 根环境的用户
    2. 1.2. 二、容器数据库的安装及使用
      1. 1.2.1. 2.1 安装
      2. 1.2.2. 2.2 常用命令
        1. 1.2.2.1. 2.2.1 查看当前的容器
        2. 1.2.2.2. 2.2.2 查看数据库是否为 CDB
        3. 1.2.2.3. 2.2.3 查看 CDB 中的 PDB 信息
        4. 1.2.2.4. 2.2.4 启动和关闭已创建好的 PDB 数据库 (PDB(容器数据库)的启停非常的快,因为需要的资源和配置较少)
        5. 1.2.2.5. 2.2.5 CDB 与 PDB 的切换
      3. 1.2.3. 2.3 PDB 的创建与删除
        1. 1.2.3.1. 2.3.1 以种子 PDB 为模板创建新的 PDB
        2. 1.2.3.2. 2.3.2 克隆其他 PDB 为新的 PDB
        3. 1.2.3.3. 2.3.3 通过一个未插入的 PDB 创建 PDB (也就是 使用 unplug 拔出命令的导出文件)
        4. 1.2.3.4. 2.3.4 使用一个 Non-CDB 来创建新的 PDB
        5. 1.2.3.5. 2.3.5 删除 PDB
      4. 1.2.4. 2.4 通过 SQL Developer 使用
        1. 1.2.4.1. 2.4.1 打开 PDB1
        2. 1.2.4.2. 2.4.2 创建用户并授权
        3. 1.2.4.3. 2.4.3 配置
      5. 1.2.5. 2.5 因为所有 PDB 共享日志,所以只能在 root 容器新建日志
|