数据库教程FGMT25‑Oracle多租户架构CDB与PDB运维管理
前言
Oracle多租户CDB/PDB容器架构自12c版本推出之后,已经成为Oracle数据库主流部署形态,Oracle21c/26ai已经不再支持创建non‑CDB传统非容器数据库,所有新建数据库强制采用CDB多租户架构。多租户架构可以将多个业务库整合至一套CDB容器,实现资源池化、快速克隆、插拔迁移、统一补丁升级;但同时带来全新运维模型,容器切换、公共/本地用户管理、PDB启停状态保存、克隆、快照PDB、插拔迁移、应用容器、non‑CDB迁移、补丁datapatch、备份恢复、资源管理器等均有别于传统单机non‑CDB数据库。风哥教程本文围绕CDB/PDB完整运维体系展开,覆盖架构理论、各类PDB创建方式、用户权限管理、PDB生命周期运维、克隆、快照、unplug/plug插拔、relocate在线热迁移、non‑CDB迁移PDB、应用容器、数据泵使用、RMAN备份恢复、补丁datapatch、资源管理器、故障排查,帮助DBA掌握多租户环境完整运维手段。风哥 itpux‑com
本套风哥教程面向DBA、数据库架构师、运维实施工程师;实验主机fgedu‑net‑cn ,硬件规格64G内存,8颗CPU;CDB数据库实例名fgedudb,数据库名fgedudb,业务测试用户名fgedu,根目录统一/fgedudb,基于Oracle19c企业版(本地undo模式)完成实验。风哥教程本文分为前言与大纲介绍、核心理论知识、实战操作演练、风哥针对本文总结四大模块;实战章节包含大量可直接复制运行shell、PL/SQL脚本,读者可以在测试环境完整复现多租户全套运维操作。网上搜索风哥教程可以学习全套数据库教程
内容大纲
- Oracle多租户CDB/PDB架构综述,CDBROOT、PDBROOT、PDBROOT、PDBSEED、业务PDB核心组件说明
- 本地undo与共享undo模式原理,公共用户、本地用户、角色权限管理规则
- 多租户核心数据字典视图,容器切换原理,PDB各种打开关闭模式
- PDB多种创建方式:seed模板创建、本地克隆、远程克隆、快照PDB、relocate在线迁移、plug插入PDB
- PDB unplug/plug插拔迁移完整流程,non‑CDB传统数据库转换迁移为PDB
- Application Container应用容器运维,应用PDB管理
- 多租户环境数据泵expdp/impdp使用注意事项,PDB级导出导入
- CDB/PDB RMAN备份恢复体系,CDB全量备份、单PDB粒度备份恢复,PDB闪回
- 多租户补丁运维,datapatch字典升级原理,打补丁约束
- CDB资源管理器,PDB资源隔离配置实操
- 多租户日常巡检脚本,高频报错故障分析,生产运维最佳实践
一、核心理论知识
本章节为本套风哥教程理论基础,理解多租户架构模型、权限模型、各类PDB技术的适用边界,规避日常运维中的各类陷阱。风哥教程 113257174
1.1 CDB/PDB容器架构组件
- CDB$ROOT根容器(con_id=1):CDB管理根容器,存放公共元数据、公共用户SYS/SYSTEM;实例级参数、redo、控制文件、SGA/PGA全部在ROOT;不存放业务数据,DBA在此执行实例层面管理操作。
- PDB$SEED种子模板(con_id=2):只读模板PDB;新建PDB的时候,Oracle复制seed的数据文件,快速生成新PDB初始环境,不允许业务读写修改seed内容。
- 业务PDB(Pluggable Database):对应用户业务,客户端访问表现如同传统独立数据库;每个PDB具备独立SYSAUX、USERS、undo表空间(本地undo模式),独立数据字典;PDB之间数据天然隔离,需要dblink实现跨PDB访问。
本地undo模式:12.2及之后版本强烈推荐开启,每个PDB拥有独立undo表空间;支持PDB热迁移、插拔、PDB级闪回;参数undo_mode=LOCAL,修改后必须重启CDB实例生效;共享undo仅用于过渡升级场景,生产不推荐使用。网上搜索风哥教程可以学习全套数据库教程
1.2 公共用户与本地用户权限模型
- 公共用户Common User :用户名必须以C##/C##开头;在CDB$ROOT创建,
CONTAINER=ALL,该用户自动同步到CDB下所有PDB;适合监控、DBA公共账号;禁止在PDB内部创建C##公共用户,会报ORA‑65096错误。 - 本地用户Local User:仅存在于某一个PDB内部;必须切换到对应PDB容器再执行create user;业务应用账号优先使用本地用户,实现租户隔离。
- 角色:公共角色(CONTAINER=ALL)、本地角色;权限区分容器公共权限、PDB本地权限。
1.3 多租户核心视图与容器切换
show pdbs:sqlplus快捷命令,查看全部PDB名称、con_id、open_mode;dba_pdbs / cdb_pdbs:CDB级别查看全部PDB元数据;cdb_users / cdb_roles:跨容器查看全部用户,common字段区分公共/本地;gv$containers:动态性能视图查看所有容器运行状态;alter session set container=xxx:会话级切换当前容器,不会重启实例,只改变会话上下文;>
注意:alter session set container仅仅改变当前会话,不会改变其他已经存在的会话。风哥数据库教程 itpux‑com
1.4 PDB各类打开状态说明
READ WRITE:正常业务读写;READ ONLY:只读打开,可查询不可DML修改;MOUNT:挂载状态,数据文件挂载,不对外业务访问;用于备份、插拔操作;MIGRATE:迁移转换状态,non‑CDB转换PDB、升级的时候使用。
重要特性:CDB实例重启之后,所有PDB默认回到MOUNT状态;必须执行
alter pluggable database xxx save state;保存PDB开机状态,实例重启PDB自动恢复open状态。
1.5 PDB各类创建技术原理
- 基于SEED模板创建PDB:复制PDB$SEED模板,生成全新空白业务PDB。
- 本地克隆Local Clone:同一套CDB内部,从已有业务PDB克隆一份完整副本;适合测试环境复制业务库。
- 远程克隆Remote Clone:通过database link,从远端CDB的PDB直接克隆到本地CDB;源库可以保持读写运行,适合跨CDB快速迁移。
- Snapshot Copy快照克隆:基于存储稀疏快照,几乎不占用额外空间快速克隆PDB;依赖ASM稀疏磁盘或者ACFS文件系统;快照PDB存在存储依赖,可以执行materialize实体化为完整PDB。
- Unplug / Plug插拔迁移:unplug将PDB导出xml元数据文件,PDB变为unplugged状态;将数据文件与xml拷贝到目标CDB,plug接入;同大版本CDB之间迁移PDB。
- Relocate PDB在线热迁移:12.2之后支持,源PDB保持读写业务运行,在线迁移PDB到目标CDB,业务停机时间极短,适合存储迁移、资源池重组场景。
1.6 Application Container应用容器
Application Container应用容器是特殊PDB,可以管理一组应用PDB;适合一套应用有多套租户实例,公共应用元数据统一放在应用root,各个应用PDB共享应用定义。
1.7 non‑CDB迁移PDB原理
传统non‑CDB数据库,使用dbms_pdb.describe()生成xml元文件,plug进目标CDB,执行noncdb_to_pdb.sql脚本转换内部字典,完成存量传统数据库向PDB迁移改造。网上搜索风哥教程可以学习全套数据库教程
1.8 多租户备份恢复与闪回
RMAN支持两种备份粒度:①备份整个CDB容器数据库;②单独备份某一个或者多个PDB。支持PDB级别闪回数据库flashback pluggable database;注意闪回PDB不会影响其他PDB。
1.9 多租户补丁datapatch机制
CDB环境打完OPatch二进制补丁之后,不能直接使用;datapatch工具遍历CDB$ROOT以及全部PDB,依次执行字典升级脚本;如果部分PDB处于mount,datapatch执行会报错,所有PDB必须open read‑write状态,datapatch才能完整执行,否则会出现二进制版本与字典版本不一致,大量ORA报错。
1.10 CDB资源管理器
CDB Resource Manager资源管理器,可以针对不同PDB分配CPU、IO、并行度资源;防止某一个业务PDB耗尽CDB实例整体资源,影响其他租户业务。
1.11 常见故障点汇总
- 实例重启PDB全部mount,忘记save state;
- 在CDB$ROOT创建不带C##前缀用户,报ORA‑65096;
- datapatch执行失败,部分PDB没有open;
- unplug/plug版本不兼容,源与目标CDB大版本不一致;
- 数据泵操作,公共用户导出导入出现ORA‑65094,需要使用remap_schema;
- 快照PDB没有materialize,底层存储快照被删除,PDB损坏。
上51CTO搜索风哥可以学习全套数据库教程
二、实战操作演练
本套风哥教程全部实战操作,主机fgedu‑net‑cn,CDB数据库fgedudb,硬件64G内存8CPU,本地undo模式;数据库SID=fgedudb,业务用户fgedu,根目录/fgedudb。
说明:操作系统oracle用户登录,设置ORACLE_HOME、ORACLE_SID;sqlplus / as sysdba默认连接CDB$ROOT根容器。
2.1 CDB环境基础校验
#主机信息
hostname
free -h
lscpu
echo $ORACLE_SID
echo $ORACLE_HOME
登录数据库
sqlplus / as sysdba
--查看容器信息
show pdbs;
select con_id,name,open_mode,undo_mode from v$containers;
show parameter undo_mode;
show parameter memory_target;
确认
undo_mode=LOCAL本地undo模式;内存参数memory_target=48G适配64G主机。
alter system set memory_max_target=48G scope=spfile;
alter system set memory_target=48G scope=spfile;
2.2 PDB基础生命周期操作:创建、打开关闭、save state
2.2.1 基于PDB$SEED模板新建业务PDB fgedu_pdb1
create pluggable database fgedu_pdb1
admin user fgedu_pdb_admin identified by fgedudb
file_name_convert=
('/fgedudb/oradata/fgedudb/pdbseed/',
'/fgedudb/oradata/fgedudb/fgedu_pdb1/');
创建之后PDB为mount状态,需要手工打开。
2.2.2 PDB打开关闭,save state保存开机状态
--打开单个PDB
alter pluggable database fgedu_pdb1 open;
--打开全部PDB
alter pluggable database all open;
--关闭PDB
alter pluggable database fgedu_pdb1 close immediate;
alter pluggable database all close immediate;
--保存PDB状态,CDB实例重启自动open
alter pluggable database fgedu_pdb1 save state;
alter pluggable database all save state;
--清除保存状态
alter pluggable database fgedu_pdb1 discard state;
show pdbs;
2.2.3 会话容器切换,本地业务用户fgedu创建
--切换会话进入fgedu_pdb1
alter session set container=fgedu_pdb1;
show pdbs;
--创建PDB本地业务用户
create user fgedu identified by fgedudb default tablespace users temporary tablespace temp;
grant connect,resource,select_catalog_role to fgedu;
--切回CDB$ROOT
alter session set container=cdb$root;
show pdbs;
2.3 公共C##用户与权限实操
公共用户必须在CDB$ROOT创建,名字以C##开头,指定CONTAINER=ALL。
alter session set container=cdb$root;
create user c##fgedu_mon identified by fgedudb container=all;
grant connect,select_catalog_role to c##fgedu_mon container=all;
--查看公共\(ROOT、PDB\)本地用户
set linesize 220
select con_id,username,common from cdb_users where username like '%FGEDU%';
错误示范:在PDB内部执行create user c##xxx,直接报ORA‑65096;PDB内部只能创建本地用户。风哥数据库教程 itpux‑com
2.4 PDB本地克隆实操(同一CDB内部克隆fgedu_pdb1得到fgedu_pdb_clone)
alter session set container=cdb$root;
create pluggable database fgedu_pdb_clone from fgedu_pdb1
file_name_convert=
('/fgedudb/oradata/fgedudb/fgedu_pdb1/',
'/fgedudb/oradata/fgedudb/fgedu_pdb_clone/');
alter pluggable database fgedu_pdb_clone open;
show pdbs;
2.5 PDB unplug / plug插拔迁移完整实操
2.5.1 unplug拔出PDB,生成xml元数据文件
alter session set container=cdb$root;
alter pluggable database fgedu_pdb_clone close immediate;
alter pluggable database fgedu_pdb_clone
unplug into '/fgedudb/pdb_xml/fgedu_pdb_clone.xml';
此时PDB状态为UNPLUGGED;数据文件保留磁盘,xml记录PDB全部元信息。
2.5.2 drop unplugged PDB,KEEP DATAFILES保留磁盘数据文件
alter pluggable database fgedu_pdb_clone drop keep datafiles;
KEEP DATAFILES:仅仅删除CDB内部元定义,磁盘数据文件保留,用于后续plug接入目标CDB;如果写INCLUDING DATAFILES会物理删除磁盘数据文件。
2.5.3 plug重新插入PDB
create pluggable database fgedu_pdb_clone
using '/fgedudb/pdb_xml/fgedu_pdb_clone.xml'
file_name_convert=
('/fgedudb/oradata/fgedudb/fgedu_pdb_clone/',
'/fgedudb/oradata/fgedudb/fgedu_pdb_clone/');
alter pluggable database fgedu_pdb_clone open;
show pdbs;
网上搜索风哥教程可以学习全套数据库教程
2.6 non‑CDB传统数据库迁移转换为PDB实操
源端为一套non‑CDB数据库,生成xml描述文件,拷贝数据文件,plug进目标CDB,执行noncdb_to_pdb.sql脚本转换字典。
源non‑CDB库执行:
exec dbms_pdb.describe(pdb_descr_file=>'/fgedudb/pdb_xml/ncdb_fgedu.xml');
将xml以及全部数据文件拷贝到目标CDB主机对应目录。目标CDB$ROOT执行兼容性检查:
set serveroutput on
declare
v_ret boolean;
begin
v_ret:=dbms_pdb.check_plug_compatibility(pdb_descr_file=>'/fgedudb/pdb_xml/ncdb_fgedu.xml');
dbms_output.put_line('兼容性检查结果:'||to_char(v_ret));
end;
/
plug接入non‑CDB:
create pluggable database fgedu_ncdb_pdb
using '/fgedudb/pdb_xml/ncdb_fgedu.xml'
file_name_convert=
('/fgedudb/oradata/ncdb_fgedu/',
'/fgedudb/oradata/fgedudb/fgedu_ncdb_pdb/');
alter pluggable database fgedu_ncdb_pdb open restrict;
切换进入PDB,执行转换脚本:
alter session set container=fgedu_ncdb_pdb;
@?/rdbms/admin/noncdb_to_pdb.sql
脚本执行完成之后,正常open PDB。
2.7 快照PDB Snapshot Copy实操(ASM稀疏存储环境)
注意:需要设置
clonedb=true,底层存储支持稀疏快照;本示例基于fgedu_pdb1创建快照PDB。
alter system set clonedb=true scope=spfile;
shutdown immediate;
startup;
alter session set container=cdb$root;
create pluggable database fgedu_pdb_snap from fgedu_pdb1 snapshot copy
file_name_convert=
('/fgedudb/oradata/fgedudb/fgedu_pdb1/',
'/fgedudb/oradata/fgedudb/fgedu_pdb_snap/');
alter pluggable database fgedu_pdb_snap open;
show pdbs;
快照PDB存在存储依赖,如果要消除依赖,执行materialize实体化:
alter pluggable database fgedu_pdb_snap materialize;
2.8 Relocate PDB在线热迁移简要说明
Relocate PDB需要创建dblink指向远端源CDB;源PDB保持读写运行,在线迁移,业务几乎无停机。
create pluggable database fgedu_pdb_relocate relocate from fgedu_pdb1@remote_cdb_link
file_name_convert=
('/fgedudb/oradata/srcpdb/',
'/fgedudb/oradata/fgedudb/fgedu_pdb_relocate/');
relocate要求CDB为local undo模式,字符集兼容,大版本一致。
2.9 Application Container应用容器基础实操
alter session set container=cdb$root;
--创建应用根容器
create pluggable database app_root as application container
admin user app_admin identified by fgedudb
file_name_convert=
('/fgedudb/oradata/fgedudb/pdbseed/',
'/fgedudb/oradata/fgedudb/app_root/');
alter pluggable database app_root open;
alter session set container=app_root;
--在应用root内部创建应用PDB
create pluggable database app_pdb1
admin user app_pdb_admin identified by fgedudb
file_name_convert=
('/fgedudb/oradata/fgedudb/app_root/',
'/fgedudb/oradata/fgedudb/app_pdb1/');
alter pluggable database app_pdb1 open;
show pdbs;
2.10 多租户环境数据泵expdp / impdp实操
数据泵操作PDB:连接串必须指向PDB对应的service,不能连接CDB$ROOT;每个PDB拥有独立DATA_PUMP_DIR目录对象。
操作系统执行,tns别名指向PDB服务fgedu_pdb1:
#PDB内用户导出
expdp fgedu/fgedudb@FGEDU_PDB1 directory=DATA_PUMP_DIR dumpfile=fgedu_pdb.dmp schemas=fgedu logfile=exp_fgedu.log
#导入,如果源导出包含C##公共用户,使用remap_schema
impdp fgedu/fgedudb@FGEDU_PDB1 directory=DATA_PUMP_DIR dumpfile=fgedu_pdb.dmp remap_schema=c##xxx:fgedu logfile=imp_fgedu.log
常见坑:直接登录CDB$ROOT做expdp,导出的是root的对象,不是业务PDB对象;必须连接PDB服务名。网上搜索风哥教程可以学习全套数据库教程
2.11 RMAN CDB/PDB备份恢复实操
登录RMAN,连接CDB$ROOT。
2.11.1 备份整个CDB容器数据库
backup database plus archivelog tag='CDB_FULL';
2.11.2 只备份单个PDB
backup pluggable database fgedu_pdb1 plus archivelog tag='PDB_FGEDU_PDB1';
2.11.3 PDB闪回数据库,PDB级时间点恢复
alter pluggable database fgedu_pdb1 close immediate;
flashback pluggable database fgedu_pdb1 to timestamp sysdate‑1/24;
alter pluggable database fgedu_pdb1 open resetlogs;
2.12 多租户补丁datapatch完整流程
OPatch打完二进制补丁之后,所有PDB必须open read‑write状态,然后执行datapatch。
cd $ORACLE_HOME/OPatch
./opatch lsinventory
#确认全部PDB open read write
sqlplus / as sysdba <<EOF
alter pluggable database all open;
show pdbs;
exit;
EOF
./datapatch -verbose
sqlplus / as sysdba
@?/rdbms/admin/utlrp.sql
select owner,object_name,status from dba_objects where status='INVALID';
datapatch会自动遍历CDB$ROOT与每一个PDB;如果有PDB处于mount,datapatch会报错终止,补丁字典升级不完整。风哥数据库教程 itpux‑com
2.13 CDB资源管理器,PDB资源隔离实操示例
针对不同PDB设置CPU资源配额,防止单个PDB耗尽CDB实例CPU。
alter session set container=cdb$root;
--创建CDB资源计划
exec dbms_resource_manager.create_cdb_plan(plan=>'CDB_PLAN_FGEDU',comment=>'CDB多租户PDB资源管理');
--设置fgedu_pdb1最大CPU 40%,其他PDB共享剩余
exec dbms_resource_manager.create_cdb_directive(
plan=>'CDB_PLAN_FGEDU',
pluggable_database=>'FGEDU_PDB1',
shares=>2,
utilization_limit=>40,
parallel_server_limit=>20);
--启用CDB资源计划
alter system set cdb_resource_manager_plan='CDB_PLAN_FGEDU' scope=both;
--查看资源计划
select plan,status from dba_cdb_resource_plans;
2.14 CDB/PDB日常巡检脚本
set linesize 240 pagesize 120
col name for a25
col open_mode for a20
select con_id,name,open_mode,undo_mode from v$containers order by con_id;
select pdb_id,pdb_name,status,con_id from dba_pdbs order by con_id;
--检查PDB无效对象
select con_id,owner,object_name,object_type,status from cdb_objects where status='INVALID';
--查看公共/本地用户统计
select common,count(*) cnt from cdb_users group by common;
2.15 高频故障处理
- ORA‑65096:CDB$ROOT创建本地格式用户;公共用户必须C##开头,PDB内部创建业务本地用户。
- CDB重启PDB全部mount:执行
alter pluggable database all save state;。 - datapatch执行报错:确认所有PDB open read‑write;检查opatch二进制补丁完整性。
- unplug/plug兼容性报错:dbms_pdb.check_plug_compatibility做预检查;源与目标CDB大版本必须一致。
- snapshot PDB无法open:底层存储快照被删除,快照PDB损坏,快照克隆需要底层存储硬件特性支持。
上51CTO搜索风哥可以学习全套数据库教程
三、风哥针对本文总结
本套风哥教程完整讲解Oracle多租户CDB/PDB运维管理;覆盖CDBROOT、PDBROOT、PDBROOT、PDBSEED、业务PDB架构原理,本地undo模式,公共用户、本地用户权限体系;实战包含seed模板创建PDB、本地克隆、unplug/plug插拔迁移、non‑CDB迁移PDB、快照PDB、relocate在线热迁移、Application应用容器;多租户数据泵使用、RMAN CDB/PDB备份恢复、PDB闪回、datapatch补丁字典升级、CDB资源管理器PDB资源隔离,日常巡检脚本、高频故障分析。
- Oracle12.2之后生产强烈推荐undo_mode=LOCAL本地undo模式,每个PDB拥有独立undo表空间,支持PDB插拔、relocate热迁移、PDB级闪回;修改undo_mode参数需要重启CDB实例;共享undo模式只用于过渡升级,生产不建议使用。
- 用户权限区分公共用户与本地用户:公共用户在CDB$ROOT创建,名称必须C##开头,指定
CONTAINER=ALL;业务应用账号应当切换进入对应PDB创建本地用户;禁止在PDB内部创建C##公共用户,会报ORA‑65096错误。 - CDB实例重启,PDB默认进入mount挂载状态;必须执行
alter pluggable database xxx save state;保存状态,实例重启PDB自动open读写;否则每次重启之后需要手工打开全部PDB。 - PDB迁移手段:本地克隆用于同一CDB复制;远程克隆通过dblink跨CDB复制;unplug/plug适合停机迁移;relocate在线热迁移源PDB保持业务读写,停机窗口极小;non‑CDB迁移PDB,plug接入之后必须执行noncdb_to_pdb.sql完成字典转换,否则PDB无法正常使用。
- 快照PDB依赖底层存储稀疏快照能力,可以快速几乎零空间克隆,但是存在存储依赖;需要执行
alter pluggable database ... materialize实体化消除快照依赖,否则底层快照删除PDB损坏。 - 数据泵expdp/impdp操作PDB,连接串必须指向PDB的service服务名,不能直接登录CDB$ROOT根容器;导出导入如果涉及公共C##用户,需要使用remap_schema映射为本地用户,避免ORA‑65094报错。
- 多租户补丁重点:OPatch更新二进制补丁之后,全部PDB必须处于OPEN READ‑WRITE状态,再执行datapatch;datapatch自动遍历ROOT与全部PDB升级内部字典;如果有PDB处于mount状态,datapatch执行失败,二进制版本与字典版本不一致,业务会出现大量ORA错误。
- CDB资源管理器可以对不同PDB做CPU、并行度资源配额限制,防止某一个租户PDB耗尽整个CDB实例资源,实现多租户之间业务隔离,适合一套CDB托管多个业务系统的生产环境。
全部shell与SQL脚本建议读者在fgedu‑net‑cn测试主机完整复现,理解多租户各类PDB技术的适用场景与限制,再落地企业CDB/PDB生产运维工作。