啊,众所周知,19c作为原有序列的12c最后一个版本,可以说是集大成的版本,目前应用最广泛的11g 的 11.2.0.4 版本,其支持仅仅到 2018年12月31日。所以小编建议大家伙可以考虑开始使用船新版本的19c,谁用谁知道!而 19c 是有PDB的概念的,我先给大家简单说明什么是PDB,然后在给大家说说PDB如何去创建。
PDB是什么?
PDB是Oracle 12C及以上版本中引入的一种特殊的数据库类型,它是多租户架构下的一种数据库,可以在一个CDB(容器数据库)中存在多个PDB。CDB全称为Container Database,即容器数据库,PDB全称为Pluggable Database,即可插拔数据库。在Oracle 12C之前,实例与数据库是一对一或多对一关系,而不能实现一对多的关系。在Oracle 12C中,基于多租用户环境这一新特性,实现了实例与数据库的一对多关系。
简单说明了PDB和CDB的概念,接下来就给大家展示如何创建PDB。
一 描述
Creating from scratch:
使用种子容器或应用程序种子的文件在CDB中创建PDB。此技术将与种子容器关联的文件复制到新位置,并将复制的文件与新的PDB关联,这是默认的创建机制。
Cloning:
通过克隆源PDB或非CDB创建PDB。源可以是本地CDB中的PDB,远程CDB中的PDB,此技术将与源关联的文件复制到新位置,并将复制的文件与新的PDB关联。
Relocate a PDB to a different CDB
此技术是在最少停机时间或没有停机时间的情况下移动PDB的最快方法。否则,拔出源PDB会导致PDB中断,直到将PDB插入目标CDB为止。
该操作将与PDB关联的文件移动到新位置,将PDB添加到目标CDB,然后打开PDB。
Plug an unplugged PDB into a CDB
通过使用描述PDB的XML元数据文件和与PDB关联的文件来创建PDB,以将其插入CDB。
二 从种子容器中创建pdb
2.1 描述
使用PDB $ SEED文件在CDB根目录中创建PDB,复制PDB$SEED文件到新位置,并与新建PDB关联。
2.2 创建
SQL>CREATE PLUGGABLE DATABASE salespdb
ADMIN USER dbhang IDENTIFIED BY dbhang;
//
该方法必须为CDB启用了OMF,或者PDB_FILE_NAME_CONVERT设置了初始化参数,
否则会报错:
ORA-65016: FILE_NAME_CONVERT must be specified
可以使用file_name_convert参数指定.
也可以使用create_file_dest参数指定
2.2.1为CDB开启OMF功能
创建出来的文件为OMF文件管理格式:
SQL> alter session set container=testpdb;
Session altered.
SQL> select name from v$datafile;
NAME
--------------------------------------------------------------------------------
/oracle/app/oradata/orcl/ORCL/AA2EA0F75BFC6CFBE053D8C7A8C01395/datafile/o1_mf_sy
stem_hjmx322m_.dbf
/oracle/app/oradata/orcl/ORCL/AA2EA0F75BFC6CFBE053D8C7A8C01395/datafile/o1_mf_sy
saux_hjmx322v_.dbf
/oracle/app/oradata/orcl/ORCL/AA2EA0F75BFC6CFBE053D8C7A8C01395/datafile/o1_mf_un
dotbs1_hjmx322w_.dbf
2.2.2 在CDB设置pdb_file_name_convert参数
alter system set
pdb_file_name_convert='/oracle/app/oradata/orcl/pdbseed','/oracle/app/oradata/orcl/testpdb';
目录可以不存在,会自动创建。
2.2.3 创建时指定create_file_dest参数
SQL>
CREATE PLUGGABLE DATABASE test2pdb
ADMIN USER dbhang IDENTIFIED BY dbhang
create_file_dest='/oracle/app/oradata/orcl/test2pdb/';
Create_file_dest位置必须事先被创建好,否则会报如下错误:
ERROR at line 1:
ORA-65165: missing or invalid path for file creation
/oracle/app/oradata/orcl/test2pdb/
ORA-01262: Stat failed on a file destination directory
Linux-x86_64 Error: 2: No such file or directory
2.2.4 创建PDB时的子句选项
CREATE PLUGGABLE DATABASE salespdb
ADMIN USER salesadm IDENTIFIED BY password
STORAGE (MAXSIZE 2G)
DEFAULT TABLESPACE sales
DATAFILE '/disk1/oracle/dbs/salespdb/sales01.dbf' SIZE 250M
AUTOEXTEND ON
PATH_PREFIX = '/disk1/oracle/dbs/salespdb/'
FILE_NAME_CONVERT = ('/disk1/oracle/dbs/pdbseed/',
'/disk1/oracle/dbs/salespdb/');
ADMIN USER:创建用于执行管理任务的本地用户
STORAGE MAXSIZE 可插拔数据库可使用空间的最大值
DEFAULT:新建用户的默认永久表空间:
DATAFILE:默认表空间数据文件的路径和名称
PATH_PREFIX:设置可插拔数据库新增的数据文件必须存储在该目录或其子目录中。
三 克隆现存的PDB
3.1 描述
三种方式:
克隆本地PDB
克隆远程PDB
克隆远程非CDB
3.2 克隆本地PDB
先连接根容器,然后将源PDB切换为只读模式:
SQL> alter pluggable database salespdb close;
Pluggable database altered.
SQL> alter pluggable database salespdb open read only;
Pluggable database altered.
如果CDB不在本地撤消模式下,则源PDB必须处于打开的只读模式。如果CDB处于本地撤消模式,则此要求不适用。
如果CDB不在ARCHIVELOG模式下,则源PDB必须处于只读模式。如果CDB处于ARCHIVELOG模式,则此要求不适用。
创建:
SQL>
Create pluggable database salespdb from orclpdb //from后无法接种子容器
file_name_convert = ('/oracle/app/oradata/orcl/orclpdb','/oracle/app/oradata/orcl/salespdb');
如果启用Oracle托管文件,或设置PDB_FILE_NAME_CONVERT初始化参数。
该FILE_NAME_CONVERT子句和该CREATE_FILE_DEST子句不是必需的。
克隆时,源PDB必须处于打开状态,不可为mount模式,
要么read only 要么为read write
ORA-65036: pluggable database ORCLPDB not open in required mode
3.3 克隆远程PDB
源CDB:
SQL> select con_id,name from v$containers;
CON_ID NAME
---------- --------------------
1 CDB$ROOT
2 PDB$SEED
3 ORCLPDB
4 SALESPDB
在源CDB中创建DBlink连接用户:
SQL> create user c##byh identified by byh;
SQL> grant CREATE PLUGGABLE DATABASE to c##byh
SQL> grant create session,connect,resource,sysoper to c##byh
//官方要求必须存在CREATE PLUGGABLE DATABASE权限
在目的CDB中创建连接远程PDB的DBLINK:
SQL> create database link salespdb
connect to c##byh identified by byh
using 'orcl2';
Database link created.
连接源CDB将PDB置为redo only状态:
[oracle@server1 admin]$ sqlplus sys/oracle@orcl2 as sysdba
SQL> alter pluggable database salespdb close;
Pluggable database altered.
SQL> alter pluggable database salespdb open read only;
Pluggable database altered.
使用SYS用户连接目的CDB,然后通过克隆远程PDB,创建新的PDB:
[oracle@server1 admin]$ sqlplus / as sysdba
SQL>create pluggable database salespdb2
from salespdb@salespdb
file_name_convert = ('/oracle/app/oradata/orcl/salespdb','/oracle/app/oradata/orcl/salespdb2');
Pluggable database created.
遇到的错误:
错误1:
ERROR at line 1:
ORA-17628: Oracle error 1031 returned by remote Oracle server
ORA-01031: insufficient privileges
原因就是源PDB用户权限不够 注意CREATE PLUGGABLE DATABASE 以及sysoper权限
错误2:
//在PDB中创建用户无法连接,使用DBLINK远程克隆时会报如下错误:
ORA-17627: ORA-01017: invalid username/password; logon denied
ORA-17629: Cannot connect to the remote database server
3.4 克隆非CDB
要求:
CDB和非CDB必须运行Oracle Database 12c第1版(12.1.0.2)或更高版本。
CDB和非CDB必须运行相同的Oracle数据库版本。
新创建的PDB的数据块大小必须与CDB相匹配。
在源库非CDB创建DBLINK连接用户
SQL> select cdb from v$database;
CDB
---
NO
SQL> create user byh identified by byh;
给用户授予权限:
SQL> grant CREATE PLUGGABLE DATABASE to byh
SQL> grant create session,connect,resource,sysoper to byh
建立DBlink:
SQL> create database link prod
connect to byh identified by byh
using 'prod';
Database link created.
源库状态:
SQL> select open_mode from v$database;
OPEN_MODE
--------------------
READ WRITE
如果非CDB处于NOARCHIVELOG模式下,则必须以只读模式打开它。如果非CDB处于ARCHIVELOG模式,则可以将其打开为只读或读/写状态。
目标库进行克隆
SQL>create pluggable database testpdb
from prod@prod
file_name_convert = ('/oracle/app/oradata/PROD/','/ora19c/app/oracle/oradata/ORA19C/ORA19C/testpdb/');
Pluggable database created.
'/oracle/app/oradata/PROD/' 非CDB数据库的数据文件存放路径
'/ora19c/app/oracle/oradata/ORA19C/ORA19C/testpdb/' 目标库新建PDB存放路径
连接该PDB并运行脚本:
SQL> alter session set container=testpdb;
Session altered.
必须运行该脚本后才可打开数据库:
SQL>@$ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql
新建的PDB是无法直接open read only状态打开,必须需要先open read write一次,将其与CDB集成。
SQL> alter database open read only;
alter database open read only
*
ERROR at line 1:
ORA-65085: cannot open pluggable database in read-only mode
SQL> alter database open read write;
后续就可read only打开
四 插拔PDB
4.1 描述
在将可插拔数据库插入另一个CDB前,必须先将其从CDB中拔出。拔出是指使可插拔数据库不再与CDB关联,并生成一个描述可插拔数据库已拔出状态的XML文件。将来使用这个XML文件,可以将可插拔数据库插入到另一个CDB中。
4.2 插拔远程PDB
4.2.1 确定拔出的PDB
SQL> show con_name
CON_NAME
------------------------------
CDB$ROOT
SQL> select con_id,name from v$containers;
CON_ID NAME
---------- --------------------
1 CDB$ROOT
2 PDB$SEED
3 ORCLPDB
4 SALESPDB
4.2.2 拔出PDB生成XML文件
SQL> alter pluggable database salespdb close immediate;
Pluggable database altered.
SQL> alter pluggable database salespdb unplug into '/home/oracle/salespdb.xml';
Pluggable database altered.
[oracle@server2 ~]$ ll salespdb.xml
-rw-r--r-- 1 oracle oinstall 7336 Jul 12 23:31 salespdb.xml
4.2.3 将XML文件拷贝到远端CDB
将其拷贝到远端的CDB中,并将其插入
[oracle@server2 ~]$ scp salespdb.xml 192.168.199.216:/home/oracle/
[oracle@server1 ~]$ ls salespdb.xml
salespdb.xml
4.2.4插入前检查兼容性
在将可插拔数据库插入CDB前,必须检查可插拔数据库与CDB之间的兼容性。
DBMS_PDB软件包可以检查这些兼容性。
使用该软件包检查兼容性时,你必须提供拔出可插拔数据库时创建的XML文件的名称和存储目录。
set serveroutput on
declare
hold_var boolean;
begin
hold_var := DBMS_PDB.CHECK_PLUG_COMPATIBILITY(pdb_descr_file=> '/home/oracle/salespdb.xml');
if hold_var then
dbms_output.put_line('YES');
else
dbms_output.put_line('NO');
end if;
end;
/
YES
PL/SQL procedure successfully completed.
如果这两个数据库之间没有兼容性问题,运行这段代码会输出YES。如果存在兼容性问题,运行这段代码会输出NO。
查询PDB_PLUG_IN_VIOLATIONS视图,可以详细了解它们不兼容的原因。
4.2.5 将PDB的数据文件打包拷贝
数据文件打包:
SQL> alter session set container=salespdb;
Session altered.
SQL> select name from v$datafile;
NAME
--------------------------------------------------------------------------------
/oracle/app/oradata/orcl/salespdb/system01.dbf
/oracle/app/oradata/orcl/salespdb/sysaux01.dbf
/oracle/app/oradata/orcl/salespdb/undotbs01.dbf
/oracle/app/oradata/orcl/salespdb/users01.dbf
[oracle@server2 orcl]$ tar cvf salespdb.tar.gz salespdb/
[oracle@server2 orcl]$ scp salespdb.tar.gz 192.168.199.216:/oracle/app/oradata/orcl/
[oracle@server1 orcl]$ tar xf salespdb.tar.gz
4.2.6在目的CDB中插入PDB
[oracle@server1 ~]$ sqlplus / as sysdba
SQL> show con_name
CON_NAME
------------------------------
CDB$ROOT
SQL>create pluggable database salespdb
using '/home/oracle/salespdb.xml'
Nocopy
Tempfile reuse;
Pluggable database created.
不指定nocopy:
ORA-65005: missing or invalid file name pattern for file -
/oracle/app/oradata/orcl/salespdb/system01.dbf
不指定TEMPFILE REUSE;
ERROR at line 1:
ORA-27038: created file already exists
ORA-01119: error in creating database file
'/oracle/app/oradata/orcl/salespdb/temp01.dbf'
4.3 插拔非CDB
SQL> alter session set container=testpdb;
Session altered.
必须运行该脚本后才可打开数据库:
SQL>@$ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql
五 Relocate PDB
5.1 描述
Relocating a PDB 是 Oracle 在 12C 中推出的一种新的数据迁移方式,在采用 Relocate 时可以使用最短的停机时间在不同的 CDB 之间直接迁移 PDB 。
Oracle 12.1 中 Relocate 迁移数据时,需要源库处于 read only 状态,但由于 12.2 中 local undo 的推出,可以实现完全在线迁移,源库的 PDB 在 read-write 模式下就可以 Relocate 到远端 CDB 中, 源 PDB 中的 DML 事务不会受到任何影响
5.2 流程
5.2.1确认重定位的PDB
源端:
SQL> show pdbs;
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 PDB1 READ WRITE NO
4 PDB3 READ WRITE NO
5 SALESPDB MOUNTED
目标端:
SQL> show pdbs;
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 PDB1 MOUNTED
6 SALESPDB READ WRITE NO
需求:将PDB3进行relocate至目标端
5.2.2创建DBLINK
在源端根容器下创建公有用户:
SQL> create user c##byh identified by byh;
User created.
SQL> grant CREATE PLUGGABLE DATABASE to c##byh container=all;
SQL> grant create session,connect,resource,sysoper to c##byh container=all;
在目标端创建DBLINK:
SQL>
create database link PDB3
connect to c##byh identified by byh
using 'orcl2';
在源端创建一个测试表:
SQL> create table test (id number);
Table created.
SQL> insert into test values(1);
1 row created.
SQL> commit;
Commit complete.
5.2.3目标端relocate
目标端进行relocate:
SQL>
CREATE PLUGGABLE DATABASE PDB3 FROM PDB3@PDB3 RELOCATE AVAILABILITY MAX;
ERROR at line 1: ORA-65016: FILE_NAME_CONVERT must be specified
SQL> CREATE PLUGGABLE DATABASE PDB3 FROM PDB3@PDB3 RELOCATE AVAILABILITY MAX FILE_NAME_CONVERT=('/oracle/app/oradata/orcl/pdb3','/oracle/app/oradata/orcl/pdb3')
Pluggable database created.
5.2.4源端与目标端状态对比
查看源端PDB3状态:
SQL> show pdbs;
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 PDB1 READ WRITE NO
4 PDB3 READ WRITE NO
5 SALESPDB MOUNTED
查看目标端PDB3状态:
SQL> show pdbs;
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 PDB1 MOUNTED
4 PDB3 MOUNTED
6 SALESPDB READ WRITE NO
在源端再开启一个事务:
SQL> create table test2 as select * from dba_objects;
Table created.
SQL> insert into test2 select * from test2;
72703 rows created.
SQL> /
145406 rows created.
SQL> /
290812 rows created.
SQL> commit;
SQL> delete from test2;
SQL> commit;
Commit complete.
SQL> create table test3 as select * from dba_objects;
Table created.
5.2.5目标端PDB启动
目标端启动:
SQL> alter session set container=pdb3;
Session altered.
SQL> alter database open; alter database open
* ERROR at line 1: ORA-65106: Pluggable database #4 (PDB3) is in an invalid state.
使用CDB启动:
SQL>alter pluggable database pdb3 open;
5.2.5源端与目标端状态再次对比
在源端查看PDB的状态:
SQL> show pdbs;
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 PDB1 MOUNTED
4 PDB3 MOUNTED
5 SALESPDB MOUNTED
尝试在源端打开PDB3:
SQL> alter pluggable database pdb3 open;
alter pluggable database pdb3 open
*
ERROR at line 1:
ORA-65086: cannot open/close the pluggable database
目标端 PDB状态:
SQL> show pdbs;
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 PDB1 MOUNTED
4 PDB3 READ WRITE NO
6 SALESPDB READ WRITE NO
SQL> alter session set container=pdb3;
Session altered.
SQL> select count(*) from test2;
COUNT(*)
0
SQL> select count(*) from test3;
COUNT(*)
72704
5.3 总结
1.
在目标 PDB 执行“ create pluggable database xxx relocate ”完成后,源 CDB 和目标 CDB 会同时存在 2 个 Relocate PDB ,此时目标 CDB 中该 PDB 处于 MOUNT 状态,而源库的 PDB 仍然处于 READ WRITE 状态。当在目标 CDB 中的 PDB 执行 OPEN 时,源 PDB 会停止且 Oracle 会自动 KILL 掉源 PDB 连接的所有会话,并同步且应用源 PDB 的日志到目标 PDB ,同时也会回滚未提交的事务,应用完成后 源 PDB 库的所有数据文件将会自动删除,源库会被删除** ,目标 PDB 可以对外提供服务。
2.
PDB relocate 的基本实现方式 hot clone 和通过 dblink 的增量 redo apply 。在线 Pdb Relocate 需要在目标 CDB 中创建一个 database link 指向源库的 CDB ,需要 DBLINK 使用的 common 用户有 create pluggable database 的权限, relocate 的 AVAILABILITY (高用选项)有 normal|max|high ,当目标库使用 create pluggable database relocate 选项时,源库会一直在 read-write open 状态,甚至到 create pdb 的命令完成,源 PDB ( READ-WRITE OPEN )上的用户 DML 事务都不会有任何影响。当目标库的 CREATE PDB RELOCATE 完成时,会在源 CDB 和目标 CDB 存在 2 个 relocate 的 PDB ,只不过在目标 CDB 中该 PDB 是 mount 状态,此时源库的 DML 生成的 redo 日志会用作后期的 PDB 切换, PDB 的切换操作是在目标 CDB 中的 PDB open read-write 时,此时源 PDB 会暂停,并且 KILL 掉源 PDB 库连接的会话,同步并应用源库 PDB 的 redo 到目标 PDB ,并且应用 undo 数据回滚未提交的事务,当应用完成后源 pdb 库的所有数据文件将会自动删除,目标 PDB 事务继续,在这短暂的操作期间如果使用 AVAILABILITY 如果有新的连接请求, Oracle 可以跳过连接到新 PDB 上,实现了移动 PDB 的零停机。