一 描述
1.1 方法汇总
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
描述
使用PDB $ SEED文件在CDB根目录中创建PDB,复制PDB$SEED文件到新位置,并与新建PDB关联。
创建
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 参数指定

为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
在CDB 设置pdb_file_name_convert 参数

alter system set pdb_file_name_convert='/oracle/app/oradata/orcl/pdbseed','/oracle/app/oradata/orcl/testpdb'; 目录可以不存在,会自动创建。
创建时指定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 directoryLinux-x86_64 Error: 2: No such file or directory
创建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
描述
三种方式:
克隆本地PDB
克隆远程PDB
克隆远程非CDB
克隆本地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
克隆远程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 serverORA-01031: insufficient privileges 原因就是源PDB 用户权限不够 注意CREATE PLUGGABLE DATABASE 以及sysoper 权限
错误2:// 在PDB 中创建用户无法连接,使用DBLINK 远程克隆时会报如下错误:ORA-17627: ORA-01017: invalid username/password; logon deniedORA-17629: Cannot connect to the remote database server
克隆非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 testpdbfrom prod@prodfile_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
描述
在将可插拔数据库插入另一个CDB前,必须先将其从CDB中拔出。拔出是指使可插拔数据库不再与CDB关联,并生成一个描述可插拔数据库已拔出状态的XML文件。将来使用这个XML文件,可以将可插拔数据库插入到另一个CDB中。
插拔远程PDB
确定拔出的PDB
SQL> show con_nameCON_NAME------------------------------CDB$ROOT SQL> select con_id,name from v$containers; CON_ID NAME---------- -------------------- 1 CDB$ROOT 2 PDB$SEED 3 ORCLPDB 4 SALESPDB
拔出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
将XML 文件拷贝到远端CDB
将其拷贝到远端的CDB 中,并将其插入[oracle@server2 ~]$ scp salespdb.xml 192.168.199.216:/home/oracle/[oracle@server1 ~]$ ls salespdb.xml salespdb.xml
插入前检查兼容性
在将可插拔数据库插入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视图,可以详细了解它们不兼容的原因。
将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
在目的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'
插拔非CDB
SQL> alter session set container=testpdb;Session altered. 必须运行该脚本后才可打开数据库: SQL>@$ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql
五 Relocate PDB
描述
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 事务不会受到任何影响
流程
确认重定位的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 至目标端
创建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.
目标端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.
源端与目标端状态对比
查看源端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.
目标端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 ;
源端与目标端状态再次对比
在源端查看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
总结
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 的零停机。
