已索引
多租户架构
The graphic above shows a CDB with four containers: the root, the seed, and two PDBs.
The two applications (HR and SALES) use a single instance and are maintained separately.
At the physical level, the CDB has a database instance and database files, just as a non-CDB.
- The redo log files are common for the whole CDB. The information it contains is annotated with the identity of the PDB where a change occurs. Oracle GoldenGate is enhanced to understand the format of the redo log for a CDB. All PDBs in a CDB share the ARCHIVELOG mode of the CDB.
- The control files are common for the whole CDB. The control files are updated to reflect any additional tablespace and data files of plugged PDBs.
- The UNDO tablespace is common for all containers.
- A temporary tablespace common to all containers is required. But each PDB can hold its own temporary tablespace for its own local users.
- Each container has its own data dictionary stored in its proper SYSTEM tablespace, containing its own metadata, and a SYSAUX tablespace.
- The PDBs can create tablespaces within the PDB according to application needs.
- Each data file is associated with a specific container, named CON_ID.
为什么要使用CDB
对于12C之前的 oracle 数据库架构,如果需要创建多个数据库,就需要存在多个实例,它们并不共享(share nothing),导致了过多的后台进程,过高的内存消耗。同时也造成了 metadata 的冗余。
CDB 的初衷是为了满足云计算和数据库整合的需求。其好处主要有如下几点:
- 有效提高硬件资源利用率:更多的应用数据库被整合到一个硬件环境。
- 有效降低资源开销:只有一套实例,数据字典的冗余信息也降低。
- 保障数据隔离:相对于12C之前将不同的应用数据放到不同的schema来说,使用PDB可以让各应用属于不同的PDB,确保了一定的数据隔离性和职责分离性。
- 管理成本下降:只需要管理一个实例,补丁管理、备份恢复等各种管理工作都得到简化。
当 initial database 创建后,仅有 oracle 提供的objects。在 non-CDB 数据库中,用户数据的 metadata 与 oracle 提供的对象的元数据混存在数据字典里面;在CDB 中,Oracle 提供对象的元数据放在 Root Container 的数据字典中,用户数据的元数据放在 User Container 的数据字典中。User Container 要访问 oracle 提供的对象则通过 User Container 中的内部 pointer 来完成。
术语
在 CDB 中有两种 Container:the root container 和 Pluggable database container(SEED 和用户 PDBs). 可以通过 v$containers 查到所有的 container。
SQL> select con_id,name from v$containers;
CON_ID NAME
---------- ------------------------------
1 CDB$ROOT
2 PDB$SEED
3 HRPDB
4 SALESPDB
The Root
The root container, also called the root, is a collection of schemas, schema objects, and nonschema objects to which all PDBs belong. Every CDB has one and only one root container, named CDB$ROOT, which stores the system metadata required to manage PDBs. All PDBs belong to the root.
The root does not store user data. Thus, you must not add user data to the root or modify system-supplied schemas in the root. However, you can create common users and roles for database administration. A common user with the necessary privileges can switch between PDBs.
SEED
又名PDB$SEED, 是用来创建新的PDB的模版。但是,你不能在seed里添加或者修改对象,一个CDB只能有一个SEED。
PDBs
A PDB is a user-created set of schemas, objects, and related structures that appears logically to an application as a separate database. Every PDB is owned by SYS, which is a common user in the CDB, regardless of which user created the PDB.
约定:为方便起见,后面我们把整个 CDB 称为 CDB,把 Root Container 简称为 the ROOT,把 Seed Container 简称为 SEED,把 PDB Container 简称为 PDB。
容器ID规则
Container ID Rows pertain to
0 Whole CDB, or non-CDB
1 CDB$ROOT
2 PDB$SEED
3~254 User-Created PDBs
可见,包含 SEED 在内, CDB 中最多能包含 253 个 PDB。
另外,CDB 中最多只能有 512 个 services,单个 PDB 的 service 数量没有限制。
创建CDB
可以使用 dbca 工具创建 CDB。 对于手工建库,The 'CREATE DATABASE cdb1 … ENABLE PLUGGABLE DATABASE SEED FILE_NAME_CONVERT ('/u01/app/oradata/CDB1','/u01/app/oradata/CDB1/seed');' SQL statement creates a new CDB. If you do not specify the ENABLE PLUGGABLE DATABASE clause, then the newly created database is a non-CDB and can never contain PDBs.
Along with the root container (CDB$ROOT), Oracle Database automatically creates a seed PDB (PDB$SEED).
创建PDB
新的 PDB 目录会自动创建,无需手动创建。
如果设置了 OMF 参数 DB_CREATE_FILE_DEST,或者新参数 PDB_FILE_NAME_CONVERT = 'xxx','yyy',则可以在命令中不使用 FILE_NAME_CONVERT 子句。
方法一:通过seed PDB进行复制
SQL> create pluggable database hrpdb
admin user admin identified by oracle roles=(connect)
file_name_convert = ('/data/app/db/oradata/mgmtcdb/pdbseed','/data/app/db/oradata/mgmtcdb/hrdb');
The ADMIN USER clause defines the PDBA user created in the new PDB with the CONNECT and PDB_DBA roles (empty role).
新创建的 PDB 在 CDB_PDBS 视图中的状态为 NEW. 表示从未被打开过. It must be opened in READ WRITE or RESTRICTED mode for Oracle to perform processing needed to complete the integration of the PDB into the CDB and mark it NORMAL.
方法二:通过克隆现有PDB创建新的PDB
SQL> alter pluggable database hrpdb open; // 如果是新的PDB,则需要打开一次
SQL> alter pluggable database hrpdb close;
SQL> alter pluggable database hrpdb open read only;
SQL> create pluggable database salespdb from hrpdb file_name_convert = ('hrdb','salesdb');
删除PDB
检查PDB的状态,如果为 MOUNTED 表示关闭,如果没有关闭,则关闭 PDB。然后:
SQL> drop pluggable database hrpdb including datafiles;
连接ROOT Container
跟非容器数据库一样的连接方法,例如 sqlplus / as sysdba 就是连接的 CDB,也可以使用 ROOT Container 的 service name 来连接。
检查是否使用了CDB:
SQL> SELECT NAME, CDB, CON_ID FROM V$DATABASE;
NAME CDB CON_ID
--------- --- ----------
MYCDB YES 0
检查当前连接的容器名:
SQL> SHOW CON_NAME;
CON_NAME
--------
CDB$ROOT
或者:
SQL> SELECT SYS_CONTEXT('USERENV', 'CON_NAME') AS CUR_CONTAINER FROM DUAL;
查看PDB
SQL> set lines 200;
SQL> select con_id,dbid,NAME,OPEN_MODE from v$pdbs;
CON_ID DBID NAME OPEN_MODE
------- ---------- ------------- ----------
2 1411834906 PDB$SEED READ ONLY
3 2348434020 HRPDB READ ONLY
4 3675246538 SALESPDB MOUNTED
如果在PDB中执行查询则只能看当前 PDB 的信息。
连接PDB
SQL> ALTER SESSION SET CONTAINER=hrpdb;
如果要返回 ROOT,则:
SQL> alter session set container=CDB$ROOT;
打开PDB
如果是在 ROOT Container 下面,则可以:
SQL> alter pluggable database salespdb open;
SQL> alter pluggable database all open;
SQL> alter pluggable database all except salespdb open;
如果是在 PDB Container 下,则可以:
SQ.> alter database open;
SQL> alter pluggable database hrpdb open;
如果是 RAC 两个节点都要执行。
关闭PDB
关闭 PDB,即是把 PDB 置于 MOUNTED 状态。
如果是在 ROOT Container 下面,则可以:
SQL> alter pluggable database hrpdb close;
SQL> alter pluggable database all close;
SQL> alter pluggable database all except hrpdb close;
如果是在 PDB Container 下,则可以:
SQL> shutdown immediate;
SQL> alter pluggable database demo close;
如果是 RAC 两个节点都要执行。
设置 PDB 随 CDB 自动启动(触发器)
CREATE OR REPLACE TRIGGER open_pdb_all
AFTER STARTUP ON DATABASE
BEGIN
EXECUTE IMMEDIATE 'ALTER PLUGGABLE DATABASE ALL OPEN';
END open_pdb_all;
/
检查PDB与服务名的对应关系
查看服务名
SQL> col name for a20;
SQL> col pdb for a20;
SQL> set lines 200;
SQL> SELECT NAME,PDB FROM V$SERVICES ORDER BY PDB, NAME;
NAME PDB
---------------- --------------------
SYS$BACKGROUND CDB$ROOT
SYS$USERS CDB$ROOT
mycdb CDB$ROOT
mycdbXDB CDB$ROOT
hrpdb HRPDB
salespdb SALESPDB
$ lsnrctl status
Services Summary...
Service "hrpdb" has 1 instance(s).
Instance "mycdb", status READY, has 1 handler(s) for this service...
Service "mycdb" has 1 instance(s).
Instance "mycdb", status READY, has 1 handler(s) for this service...
Service "mycdbXDB" has 1 instance(s).
Instance "mycdb", status READY, has 1 handler(s) for this service...
Service "salespdb" has 1 instance(s).
Instance "mycdb", status READY, has 1 handler(s) for this service...
The command completed successfully
有了这些不同的服务名,我们就可以通过不同的 service name 连接到不同的 PDB 了。
创建服务名
如果没有 GI,则进入 PDB,执行:
EXEC DBMS_SERVICE.CREATE_SERVICE('cypdb_new','cypdb_new');
EXEC DBMS_SERVICE.START_SERVICE('cypdb_new');
EXEC DBMS_SERVICE.STOP_SERVICE('cypdb_new');
EXEC DBMS_SERVICE.DELETE_SERVICE('cypdb_new');
如果有 GI,则:
$ srvctl add service -db mycdb -service hrpdb -pdb hrpdb
$ srvctl start service -db mycdb -service hrpdb
将 non-CDBs 装载到 CDB(Plug a non-CDB into a CDB)
Three possible methods:
- TTS or TDB or full export/import
- Replication(OGG)
- XML file definition with DBMS_PDB
前两种都是经典的方法,我们这儿只演示一下第三种,但是注意,该方法只适用于12C数据库,如果你想将 12c 之前的数据库做成 PDB,则需要先将其升级到 12C,然后使用该方法装载,或者使用前两种经典方法迁移数据。
DEMO:将一个名为 mtmgdb 的非 CDB 数据库装载到名为 mgmtcdb 的 CDB 中,取名为 cypdb
1. 将源库 mtmgdb 以只读方式打开:
SQL> alter database open read only;
2. 产生描述文件:
SQL> exec dbms_pdb.describe('/tmp/mtmgdb.xml');
SQL> shutdown immediate;
The DBMS_PDB package constructs an XML file describing the non-CDB data files to plug the non-CDB into the CDB as a PDB.
3. 连接到 CDB 并创建 PDB
SQL> CREATE PLUGGABLE DATABASE cypdb USING '/tmp/mtmgdb.xml';
ERROR at line 1:
ORA-65018: 必须指定 FILE_NAME_CONVERT 或 NOCOPY **// 默认值是 COPY**
SQL> CREATE PLUGGABLE DATABASE cypdb USING '/tmp/mtmgdb.xml' nocopy;
ERROR at line 1:
ORA-27038: 所创建的文件已存在
ORA-01119: 创建数据库文件 '/data/app/db/oradata/mtmgdb/temp01.dbf' 时出错
SQL> ! mv /data/app/db/oradata/mtmgdb/temp01.dbf /home/oracle/
SQL> CREATE PLUGGABLE DATABASE cypdb USING '/tmp/mtmgdb.xml' nocopy;
4. 切换到 PDB,执行脚本:
alter session set container = cypdb;
@$ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql
该脚本删除 PDB SYSTEM 表空间中一些不必要的信息。
注意事项:
执行这个脚本时,CDB 实例的内存如果不够用,将报如下错误:
ORA-04031: unable to allocate 289080 bytes of shared memory ("shared pool","DBMS_STATS","PLSRC^1c8c4f2d","pl/sql source")当再次尝试执行脚本时,将报 ORA-600 [16201] 错误,原因如下:
The issue is caused by unpublished
Bug 18399064 - NONCDB_TO_PDB.SQL RE-RUN HITS ORA 600 [16201]The noncdb_to_pdb.sql script corrupts the data dictionary if it is re-run.
The noncdb_to_pdb.sql script is not re-runnable on the same database untill 12.2. From 12.2 onwards the sql is re-runnabble.
If the script fails due to some reason, the procedure should be started from scratch, i.e. from the back-up of the unmodified non cdb database.
5. 打开 PDB 数据库:
SQL> alter pluggable database cypdb open;
PDB 的卸载与装载(Plug Unplugged PDB into CDB)
DEMO:unplug cypdb from CDB1, then plug cypdb into CDB2
- Unplug cypdb from CDB1:
Connect to CDB1 as a common user.
Verify that cypdb is closed.
SQL> ALTER PLUGGABLE DATABASE cypdb UNPLUG INTO '/tmp/cypdb.xml';
Copy the PDB files, then drop cypdb from CDB1
- Plug cypdb into CDB2:
Connect to CDB2 as a common user.
Use the DBMS_PDB package to check the compatibility of PDB1 with CDB2.
SET SERVEROUTPUT ON;
DECLARE compat BOOLEAN;
BEGIN compat := DBMS_PDB.CHECK_PLUG_COMPATIBILITY(pdb_descr_file => '/tmp/cypdb.xml', pdb_name => 'cypdb');
IF compat THEN
DBMS_OUTPUT.PUT_LINE('PDB is compatible with the CDB');
ELSE
DBMS_OUTPUT.PUT_LINE('PDB is NOT compatible with the CDB');
END IF;
END;
/
SQL> create pluggable database cypdb using '/tmp/cypdb.xml' nocopy;
SQL> alter pluggable database cypdb open;
表空间管理
总体来说,CDB 与 PDB 的日常管理跟非 CDB 数据库的方式一样。只需要进入到 PDB 中执行相关命令即可。或者在命令中使用 pluggable 关键字。 具体语法可查询 Oracle 官方文档。这儿以表空间管理为例,抛砖引玉。然后再为大家单独列出几个话题分享。
SQL> ALTER PLUGGABLE DATABASE DATAFILE '/u03/pdb1_01.dbf' ONLINE;
SQL> ALTER PLUGGABLE DATABASE DEFAULT TABLESPACE pdb1_tbs;
When connected to the PDB, the ALTER DATABASE and ALTER PLUGGABLE DATABASE commands perform the same modifications to the PDB.
CDB 与 PDB 的用户与安全
user
可以在 CDB 中创建表空间,创建表等操作,但是,不能创建普通用户,在 CDB 架构中,Root 本来就不是设计为用来存放业务数据的。业务数据和用户应该放在 PDB 中。
SQL> create user mycdbuser identified by oracle;
create user mycdbuser identified by oracle
*
ERROR at line 1:
ORA-65096: 公用用户名或角色名无效
引入 CDB 后,Oracle 数据库用户分为 Common User 和 Local User。
Common User 是在 ROOT 的数据字典中定义的,ROOT 中不能有 Local User。ROOT 中只能定义 common user,common user 对整个 CDB 可见,用于执行一些管理任务,例如启停 CDB、PDB 等。Local User 是在 PDB 自己的数据字典中定义的,只适用于该 PDB,对其它容器不可见。Local User 需要使用 service name 来进行连接。
In a multitenant environment, the identity and password of a common user are known in the root and in every pluggable database (PDB). A common user can perform administrative tasks specific to the root or PDBs. A local user is a database user that exists only in a single PDB.
创建 Common User 范例:
SQL> CREATE USER c##hr_admin IDENTIFIED BY password
DEFAULT TABLESPACE data_ts TEMPORARY TABLESPACE temp_ts
QUOTA 100M ON test_ts QUOTA 500K ON data_ts
CONTAINER = ALL;
分配给 common user 可以连接到各个 container 的权限:
SQL> GRANT SET CONTAINER, CREATE SESSION TO c##hr_admin CONTAINER = ALL;
或者
SQL> GRANT SET CONNECT TO c##hr_admin CONTAINER = ALL;
以上权限只是让 common user 可以创建会话,可以执行 alter session set container ... 命令在不同的 PDB 之间切换,但是不具有其它权限,如果需要其它权限,需要做另外的授权,例如,如果希望 common user 可以查询数据字典信息,则:
SQL> GRANT select_catalog_role TO c##hr_admin CONTAINER = ALL;
- To explicitly designate a user account as a common user, in the CREATE USER statement, specify CONTAINER=ALL. If you are logged into the root, and if you omit the CONTAINER clause from your CREATE USER statement, then the CONTAINER=ALL clause is implied.
- Do not create objects in the schemas of common users. Doing so can cause problems during plug-in and unplug operations.
- If you specify the DEFAULT TABLESPACE, TEMPORARY TABLESPACE, QUOTA...ON, and PROFILE clauses in the CREATE USER statement for a common user account, then you must ensure that these objects exist in all containers of the CDB.
创建 Local User 范例:
SQL> CREATE USER kmurray IDENTIFIED BY password
DEFAULT TABLESPACE data_ts TEMPORARY TABLESPACE temp_ts
QUOTA 100M ON test_ts QUOTA 500K ON data_ts
CONTAINER = CURRENT;
To create a local user account, you must be connected to the PDB in which you want to create the account. You can include CONTAINER=CURRENT in the CREATE USER statement to specify the user as a local user. If you are connected to a PDB and omit this clause, then the CONTAINER=CURRENT clause is implied.
role
根 user 一样,roles 也分为 Local Roles 与 Common Roles。
A common role is created in all containers.
SQL> CREATE ROLE c##r1 CONTAINER=ALL;
A local role is created in one container.
SQL> CREATE ROLE l_role1;
privileges
Privileges 也可以分为 Local 或者 common privileges,但更准确的表述是:A privilege is either granted locally with the clause CONTAINER=CURRENT or commonly with the clause CONTAINER=ALL.
A common privilege is granted to a grantee in all containers.
SQL> GRANT create session TO c##dba CONTAINER=ALL;
A local privilege is granted to a grantee in one container.
SQL> GRANT advisor TO u1;
跟把权限分配给用户类似,可以把权限以 Local 或者 common 的方式分配给 role。
profile
A common profile is created in all containers.
SQL> CREATE PROFILE c##dev limit PASSWORD_LIFE_TIME 3600 CONTAINER=ALL;
common profile 由 common user 来创建。
A local profile is created in one container only.
SQL> CREATE PROFILE prof_schema limit PASSWORD_LIFE_TIME 90;
local profile 由 local user 或者 common user 来创建。
Local profiles and common profiles both can be assigned to local or common users.
Common profiles assigned commonly
SQL> ALTER USER c##user PROFILE c##dev CONTAINER=ALL;
Common profiles assigned locally
SQL> ALTER USER c##user PROFILE c##dev;
SQL> ALTER USER u1 PROFILE c##dev;
Local profiles assigned locally
SQL> ALTER USER hr PROFILE hr_mgr;
container_data
在会话1上创建 common user 并测试权限:
SQL> create user c##xuwang identified by oracle container = all;
SQL> grant connect to c##xuwang container = ALL;
SQL> connect c##xuwang/oracle;
SQL> desc v$session;
ERROR:
ORA-04043: 对象 "SYS"."V_$SESSION" 不存在
SQL> desc cdb_users;
ERROR:
ORA-04043: 对象 "SYS"."CDB_USERS" 不存在
SQL> connect / as sysdba;
SQL> grant SELECT_CATALOG_ROLE to c##xuwang container=all;
在会话1上连接到 hrpdb:
SQL> alter session set container=hrpdb;
在会话2上查询:
SQL> connect / as sysdba;
Connected.
SQL> select distinct con_id from v$session;
CON_ID
----------
1
3
0
SQL> connect c##xuwang/oracle;
Connected.
SQL> select distinct con_id from v$session;
CON_ID
----------
1
0
设置 CONTAINER_DATA:
SQL> connect system/oracle
SQL> ALTER USER c##xuwang SET CONTAINER_DATA = (CDB$ROOT,HRPDB) FOR V$SESSION CONTAINER=CURRENT;
SQL> connect c##xuwang/oracle;
Connected.
SQL> select distinct con_id from v$session;
CON_ID
----------
1
3
0
注意:要用 system 用户执行 set container_date 命令,对于其它用户来说, v$session 其实是一个公共同义词,被解释成了 v_$session,而对于 sys 来说,v$session 就是它的固定视图,所以会触发 ORA-02030: can only select from fixed tables/views 错误,如果是 sys 用户命令,则直接使用 v_$session 就可以了。
可以通过 dba_container_data 查看详细情况:
SQL> connect / as sysdba;
SQL> col USERNAME for a15;
SQL> col DEFAULT_ATTR for a5;
SQL> col OWNER for a10;
SQL> col OBJECT_NAME for a20;
SQL> col ALL_CONTAINERS for a5;
SQL> col CONTAINER_NAME for a15;
SQL> set lines 200;
SQL> select * from dba_container_data where username='C##XUWANG';
USERNAME DEFAU OWNER OBJECT_NAME ALL_C CONTAINER_NAME
--------- ----- ---------- -------------------- ----- ---------------
C##XUWANG N SYS V_$SESSION N CDB$ROOT
C##XUWANG N SYS V_$SESSION N HRPDB
注意: 这种访问限制只能作用于在 CDB$ROOT 中执行的查询。用户可以切换到 PDB 中去查询会话信息,例如:
SQL> connect c##xuwang/oracle;
SQL> alter session set container=cypdb;
SQL> select distinct con_id from v$session;
CON_ID
----------
5
0
数据字典
CDB_xxx All objects in the multitenant container database across all PDBs
DBA_xxx All of the objects in a container or pluggable database
ALL_xxx Objects accessible by the current user
USER_xxx Objects owned by the current user
**v$ 视图**可以被所有 container 访问(用户有权限的话),使用 CON_ID 列来做区分。例如 v$session。
示例:
SQL> CONNECT / AS SYSDBA
SQL> SELECT role, common, con_id FROM cdb_roles;
get the list of roles, common and local, of each container.
SQL> SELECT role, common FROM dba_roles;
get all common roles of the root only (there cannot be any local roles in the root).
SQL> CONNECT sys@PDB1 AS SYSDBA
SQL> SELECT role, common, con_id FROM cdb_roles;
get the list of roles, common and local container you are connected to.
SQL> SELECT role, common FROM dba_roles;
get the same list except that there is no CON_ID column.
CDB与PDB的备份恢复
CDB的归档模式决定了所有PDB的归档模式。
backup demo
$ export ORACLE_SID=mgmtcdb
$ rman target /
RMAN> report schema; 将看到CDB和PDB所有的数据文件
RMAN> backup database; 对所有CDB和PDB进行备份
RMAN> backup pluggable database "CDB$ROOT",demo,hrpdb;
RMAN> backup tablespace demo:system; 对指定表空间进行备份
Fast incremental backups using block change tracking
At CDB level: Change tracking uses absolute data file #.
Instance recovery:
CDB level only, automatic
Block recovery
No change
Checking for Block Corruption
RMAN> VALIDATE DATABASE [ROOT|pdb1,pdb2]; 不写中括号内容则是检查整个 CDB
tempfile
Automatic missing tempfile re-creation at CDB opening.
Complete media recovery
CDB mounted: Same as for non-CDB
- Redo log files, control files
- ROOT and PDB SYSTEM datafiles, UNDO datafiles
- PDB opened: Any PDB datafile other than SYSTEM
- Tablespace OFFLINE: Any other PDB or CDB datafile
Incomplete media recovery
- CDB mounted: The whole CDB back in time
- PDB closed: A whole PDB back in time
- TSPITR for any tablespace except SYSTEM, UNDO, SYSAUX
PDB PITR (like TSPITR):
RMAN> ALTER PLUGGABLE DATABASE PDB1 CLOSE;
RMAN> RUN {
SET UNTIL SCN = 1851648 ;
RESTORE pluggable DATABASE pdb2_1;
RECOVER pluggable DATABASE pdb2_1
AUXILIARY DESTINATION='/u01/app/oracle/oradata';
ALTER PLUGGABLE DATABASE pdb2_1 OPEN RESETLOGS;
}
随着在版本 12.2 中引入本地 UNDO 模式,可以将需要的所有 UNDO 信息都存储在本地 UNDO 表空间中,从而可以进行本地还原操作,就可以不需要辅助实例了。PDPITR 变得更快更简洁。
run {
set until restore point 'before_change';
restore pluggable database PDB;
recover pluggable database PDB;
alter pluggable database PDB open resetlogs;
}
PDB TPITR:
RMAN> RECOVER TABLESPACE PDB1:TEST_TBS
UNTIL SCN 832972
AUXILIARY DESTINATION '/tmp/CDB1/reco';
RMAN> ALTER TABLESPACE PDB1:TEST_TBS ONLINE;
Control File Loss
Similar to non-CDBs
RMAN> CONNECT TARGET /
RMAN> STARTUP NOMOUNT;
RMAN> RESTORE CONTROLFILE FROM AUTOBACKUP;
RMAN> ALTER DATABASE MOUNT;
RMAN> RECOVER DATABASE;
RMAN> ALTER DATABASE OPEN RESETLOGS;
RMAN> ALTER PLUGGABLE DATABASE ALL OPEN;
NOARCHIVELOG Mode
complete restoration of the CDB
Flashback database
CDB mounted, 只能在整个 CDB 级别实施,且有如下限制:
No flashback to a point earlier than the point at which PDBPITR was performed. i.e. Flashback Database operations on a CDB may not be permitted if point-in-time recovery has been performed on any of its PDBs. When point-in-time recovery is performed on a PDB, you cannot directly rewind the CDB to a point that is earlier than the point at which DBPITR for the PDB was performed.
Duplicating Pluggable Databases
A single pluggable database
RMAN> DUPLICATE DATABASE TO cdb1 PLUGGABLE DATABASE pdb1;
Several pluggable databases
RMAN> DUPLICATE DATABASE TO cdb1 PLUGGABLE DATABASE pdb1, pdb3;
All pluggable databases except one
RMAN> DUPLICATE DATABASE TO cdb1 SKIP PLUGGABLE DATABASE pdb3;
A PDB and tablespaces of other PDBs
RMAN> DUPLICATE DATABASE TO cdb1 PLUGGABLE DATABASE pdb1 TABLESPACE pdb2:users;
Miscellaneous
- 对于 EM Cloud Control 和 EM Database Express 来说,都是在 CDB 级别启用。登录 EM 后,即可看到 CDB 及其下的 PDB,进行管理。
- Oracle SQL Developer 中允许执行 CDB 与 PDB 的管理任务,包括创建 PDB 等。
- PDB 之间的数据访问,不能通过前缀来访问,只能通过 DBLINK 来访问。
- 资源计划 RM、Unified audit、Xstream 既可以在 CDB 层面实施,也可以在 PDB 层面实施。
- CDB 中所有的 PDBs 都使用同一字符集。
- 整个 CDB 使用一个参数文件,相当于所有 PDB 的默认值。如果 V$PARAMETER.ISPDB_MODIFIABLE=TRUE,则可以在 PDB 中修改参数的值。它们被保存在数据字典中。当PDB被克隆,卸载,装载时,这些参数也会一起被传递。可以在 CDB 中通过 V$SYSTEM_PARAMETER 视图来看各个 PDB 的参数的不同值设置(通过CON_ID区分)。
- Data Guard 在 CDB 级别实施,类似 non-CDBs,不能基于个单 PDB 实施。打开物理备库会将 root 和 PDBs 均打开为 READ ONLY 状态。Oracle 强制创建的备库为主库的全拷贝,即备库必须与主库保持一致。但我们可以使用 alter pluggable database PDB2 disable recovery; 移除某些不需要的PDB。扫行命令后,目标数据库依然知道该PDB,但是它的恢复标记被关闭了,这意味着不会再有REDO应用到它上面。由于所有的数据都还保留在备库中,因此很容易就能够将该PDB再添加回来。
- In Oracle Database Vault, each PDB has its own Database Vault metadata. Database Vault constructs, such as realms, are isolated within a PDB.
- Each PDB has its own master key used to encrypt data in the PDB. The master key must be transported from the source database wallet to the target database wallet when a PDB is moved from one host to another.