运维管理30 分钟阅读
Oracle CDB/PDB 运维与故障排查 100 条命令
Oracle 多租户架构把实例和控制文件放在 CDB,业务数据则放在各个 PDB。日常碰到“数据库已启动,应用却连不上”时,先分清 CDB 是否正常、目标 PDB 是否打开,以及服务究竟指向哪个容器。
2026年9月16日阅读—点赞—收藏—
dba100oraclescenario
100 条命令系列文章专栏
Oracle 多租户架构把实例和控制文件放在 CDB,业务数据则放在各个 PDB。日常碰到“数据库已启动,应用却连不上”时,先分清 CDB 是否正常、目标 PDB 是否打开,以及服务究竟指向哪个容器。
Oracle 多租户架构把实例和控制文件放在 CDB,业务数据则放在各个 PDB。日常碰到“数据库已启动,应用却连不上”时,先分清 CDB 是否正常、目标 PDB 是否打开,以及服务究竟指向哪个容器。
这篇按容器状态、服务、空间、参数和 PDB 生命周期整理常用命令。巡检和故障排查先看状态,克隆、插拔及恢复操作再单独核对前提。建议收藏;同事遇到连接或 PDB 打不开的问题,也可以转给他直接查。
示例以 Oracle Database 19c 为准,先从 CDB 根容器检查。SALES_PDB 是示例名称,执行时换成自己的 PDB;在单个 PDB 执行的命令会标出位置。RAC 中同一个 PDB 在不同实例上的打开状态可能不同,不能只查当前实例。
Oracle CDB/PDB 多租户架构示意图
图里业务服务分别进入对应 PDB,管理连接进入 CDB$ROOT。根容器、种子库和业务 PDB 共用 CDB 实例与 redo,但各自有独立的数据文件。
1SELECT cdb FROM v$database;返回 YES 才继续查 PDB。NO 是非 CDB,后面的多租户命令不适用。
1SELECT SYS_CONTEXT('USERENV', 'CON_NAME') AS con_name2FROM dual;查全库时应在 CDB$ROOT。已经切到某个 PDB 的会话,看不到其他 PDB 的完整状态。
1SELECT con_id, name, open_mode, restricted2FROM v$containers3ORDER BY con_id;在根容器执行。CON_ID=1 是根容器,2 是 PDB$SEED;业务 PDB 从后面的编号找。OPEN_MODE 与 RESTRICTED 要一起看。
1SELECT con_id, name, open_mode, restricted, open_time2FROM v$pdbs3ORDER BY con_id;MOUNTED 表示 PDB 还没有打开;READ WRITE 表示可读写。RESTRICTED=YES 时,普通业务账号未必能连接。这个视图显示当前实例;RAC 不能用单节点结果代表全群。
1SELECT name, open_mode, restricted2FROM v$pdbs3WHERE name = 'SALES_PDB';应用连接失败时先用这个查询确认目标 PDB。没有记录时核对名字和当前容器,别直接开库或重启实例。
1SELECT pdb_id, pdb_name, status2FROM dba_pdbs3ORDER BY pdb_id;DBA_PDBS.STATUS 是 PDB 元数据状态,不能替代第 4 条的 OPEN_MODE。PDB 是否可接业务连接,仍要看打开模式和服务。
1SELECT name, open_mode, open_time2FROM v$pdbs3WHERE name = 'SALES_PDB';OPEN_TIME 是当前实例上的上次打开时间。若应用告警发生后 PDB 被重新打开过,需继续核对重启或关闭记录;单凭时间不能推断是谁操作的。
1SELECT name, restricted2FROM v$pdbs3WHERE restricted = 'YES';限制模式常见于维护或兼容性处理阶段。遇到 YES,先查为什么被限制,再决定是否开放业务连接。
1SELECT con_name, instance_name, state, restricted2FROM dba_pdb_saved_states3ORDER BY con_name, instance_name;这张视图记录 SAVE STATE 保存的状态。RAC 中记录按实例区分;某个节点没有对应记录,不能假定它会在重启后自动打开目标 PDB。
1SELECT name, recovery_status2FROM v$pdbs3ORDER BY name;RECOVERY_STATUS 显示 ENABLED 或 DISABLED。看到 DISABLED 时不要继续按普通恢复流程照搬命令,先确认是不是备库或迁移阶段的特殊安排。
1SELECT pdb, network_name, con_id2FROM cdb_services3WHERE pdb IS NOT NULL4AND con_id > 25ORDER BY pdb, network_name;在根容器执行。NETWORK_NAME 是客户端实际使用的网络服务名,不要仅凭 PDB 名称猜连接串。CDB_ 视图受容器可见性影响,关闭或限制模式的 PDB 可能不返回相应行;名单不完整时再查服务定义与 PDB 状态。
1SELECT name, network_name, pdb2FROM dba_services3WHERE pdb = 'SALES_PDB'4ORDER BY name;服务定义存在,不等于服务已经在当前实例运行。下一条再看运行中的服务;RAC 中还要查目标实例。
1SELECT name, network_name, con_name, blocked2FROM v$active_services3WHERE con_name = 'SALES_PDB'4ORDER BY name;这里看的是当前实例的活动服务。BLOCKED=YES 表示该实例不接收该服务的新连接;找不到预期服务时,结合第 4 条看 PDB 有没有打开,再核对集群配置和监听注册。
1SELECT name, network_name, pdb2FROM dba_services3WHERE network_name = 'sales-app.example.com';把示例网络名换成应用连接串里使用的服务名。PDB 不是 SALES_PDB 时,连接成功也可能落进了错误容器。
1SELECT service_name, COUNT(*) AS sessions2FROM v$session3WHERE con_id = (SELECT con_id FROM v$pdbs WHERE name = 'SALES_PDB')4AND username IS NOT NULL5GROUP BY service_name6ORDER BY sessions DESC;这是当前实例的会话快照。只统计有数据库用户名的会话;连接池可能保留空闲连接,所以会话数不等于当前请求数。RAC 需要到各实例核对。
1SELECT sid, username, service_name, con_id2FROM v$session3WHERE service_name = 'sales-app'4AND username IS NOT NULL;sales-app 是示例短服务名,不一定等于第 14 条的网络名称。服务配置看起来正确时,用会话的 CON_ID 再确认。结果只覆盖当前实例、当前存活的会话;没有记录不等于客户端完全无法连接。
1SELECT name, ROUND(total_size / 1024 / 1024 / 1024, 2) AS total_gb,2 ROUND(max_size / 1024 / 1024 / 1024, 2) AS max_gb3FROM v$pdbs4ORDER BY total_size DESC;TOTAL_SIZE 包括数据文件和临时文件,不是对象段的实际已用空间。MAX_SIZE 是 PDB 文件可用的最大空间;未配置限制时,不能把这个数当作底层存储的真实剩余容量。
1SELECT con_id, file_id, tablespace_name, file_name2FROM cdb_data_files3WHERE con_id = (SELECT pdb_id FROM dba_pdbs WHERE pdb_name = 'SALES_PDB')4ORDER BY tablespace_name, file_id;在根容器执行。查表空间告警时先把文件定位到容器,避免把同名表空间的文件认错。CDB_ 视图可能不返回关闭或限制模式 PDB 的行;加密表空间的字典查询还可能要求 keystore 已打开。
1SELECT con_id, file_id, tablespace_name, file_name2FROM cdb_temp_files3WHERE con_id = (SELECT pdb_id FROM dba_pdbs WHERE pdb_name = 'SALES_PDB')4ORDER BY tablespace_name, file_id;临时文件与数据文件要分开看。找不到文件时先确认 PDB 是否打开,以及当前账号是否能看到对应容器的数据;不能直接断定临时文件丢失。
1-- 先切到 SALES_PDB,再执行2SELECT tablespace_name, used_percent,3 used_space, tablespace_size4FROM dba_tablespace_usage_metrics5ORDER BY used_percent DESC;USED_PERCENT 以可达到的最大表空间大小为分母。自动扩展文件、底层存储剩余空间和 PDB 空间上限都可能影响这个分母;高使用率要结合数据文件与配额一起判断。
1-- 在 SALES_PDB 执行2SELECT tablespace_name, file_name,3 ROUND(bytes / 1024 / 1024) AS current_mb,4 autoextensible,5 ROUND(maxbytes / 1024 / 1024) AS max_mb6FROM dba_data_files7ORDER BY tablespace_name, file_name;AUTOEXTENSIBLE=NO 时文件不会自己增长;为 YES 也要检查 MAXBYTES 和底层空间。若文件已逼近上限,后续扩容方案应先确认 ASM 或文件系统还有容量。
1-- 在 SALES_PDB 执行2SELECT tablespace_name, file_name,3 ROUND(bytes / 1024 / 1024) AS current_mb,4 autoextensible,5 ROUND(maxbytes / 1024 / 1024) AS max_mb6FROM dba_temp_files7ORDER BY tablespace_name, file_name;排序或哈希操作报临时空间不足时,先看临时文件有无自动扩展及剩余增长空间,再查正在占用 TEMP 的会话。只加大文件,不处理异常 SQL,告警可能很快回来。
1-- 在 SALES_PDB 执行2SELECT file_id, file_name, status, online_status3FROM dba_data_files4WHERE online_status <> 'ONLINE'5ORDER BY file_id;ONLINE_STATUS 可能显示 OFFLINE、RECOVER、SYSTEM 或 SYSOFF;这里筛出的记录不一定都是故障。结合表空间和数据文件告警判断,不能按“非 ONLINE”统一执行恢复。
1SELECT name,2 ROUND(diagnostics_size / 1024 / 1024) AS diagnostics_mb,3 ROUND(max_diagnostics_size / 1024 / 1024) AS max_mb4FROM v$pdbs5ORDER BY diagnostics_size DESC;DIAGNOSTICS_SIZE 是该 PDB 诊断 trace 的磁盘占用,不计入第 17 条的 TOTAL_SIZE。如果 trace 异常增长,要查对应 incident 和诊断日志,不能直接把文件当普通缓存清掉。
1-- 在 SALES_PDB 执行2SELECT name, value, ispdb_modifiable3FROM v$system_parameter4WHERE ispdb_modifiable = 'TRUE'5ORDER BY name;不能在 PDB 里任意修改实例参数。ISPDB_MODIFIABLE=TRUE 是一个必要条件,真正改之前还要核对参数的动态/静态性质以及根容器的资源余量。
1-- 在 SALES_PDB 执行2SELECT name, value, ismodified3FROM v$parameter4WHERE name IN ('optimizer_mode', 'nls_date_format')5ORDER BY name;V$PARAMETER 是当前会话看到的值。某个应用会话用 ALTER SESSION 改了参数,DBA 会话的查询不会替它显示那个会话的值;要和 V$SYSTEM_PARAMETER 的系统值区分。
1-- 在 SALES_PDB 执行2SELECT username, account_status, common, authentication_type3FROM dba_users4WHERE oracle_maintained = 'N'5ORDER BY username;应用登录失败时先看账号是否锁定或密码过期。COMMON=YES 是公共用户,NO 是本地用户;别把根容器里同名或公共账号的状态当成当前 PDB 的业务账号状态。
1-- 在 SALES_PDB 执行2SELECT username, default_tablespace, temporary_tablespace3FROM dba_users4WHERE oracle_maintained = 'N'5ORDER BY username;用户报建表或排序失败时,用这条先确认它实际落在哪个表空间。下一步再查对应文件、配额和空间,不要先给账号扩大权限。
1SELECT name, cause, type, status, message2FROM pdb_plug_in_violations3WHERE status = 'PENDING'4ORDER BY name, type, cause;新 PDB 打不开或升级后进入限制模式时先查这里。TYPE=ERROR 与 WARNING 要分开处理,MESSAGE 只给原因线索;修复动作还要对照版本和具体 ACTION,不能批量忽略待处理记录。
1SELECT time, cause, type, status, message, action2FROM pdb_plug_in_violations3WHERE name = 'SALES_PDB'4AND status = 'PENDING'5ORDER BY time DESC;ACTION 是 Oracle 给出的处理建议,不代表现场已满足执行前提。尤其是组件版本、字符集或参数不一致的错误,先核对源库与目标 CDB 的差异,再安排修复窗口。
1SELECT pdb_name, status, refresh_mode, refresh_interval2FROM dba_pdbs3WHERE refresh_mode IS NOT NULL4ORDER BY pdb_name;REFRESH_MODE=MANUAL 需要人工刷新;AUTO 才有自动刷新间隔。克隆即使打开为只读,数据也可能落后于源 PDB,别把“可以连接”理解为“已经追平”。
1SELECT pdb_name, refresh_mode, last_refresh_scn2FROM dba_pdbs3WHERE refresh_mode IS NOT NULL4ORDER BY pdb_name;LAST_REFRESH_SCN 是上次刷新的 SCN,不是以秒计的延迟。要判断克隆落后多少,还需对照源端 SCN、redo 传输和实际刷新记录。
1SELECT con_id, pdb_name, op_timestamp, operation,2 cloned_from_pdb_name, db_unique_name3FROM cdb_pdb_history4WHERE con_id = (SELECT pdb_id FROM dba_pdbs WHERE pdb_name = 'SALES_PDB')5ORDER BY op_timestamp DESC;在根容器查询 PDB 历史。用当前 PDB_ID 找记录,同时核对历史的 PDB_DBID、旧名称和来源 PDB;克隆后只凭名称推断来源容易认错。
1SELECT name, snapshot_parent_con_id2FROM v$pdbs3WHERE snapshot_parent_con_id <> 04ORDER BY name;非零值指向快照克隆的父 PDB 容器编号。后续移动或删除源 PDB 前,先查这种依赖;普通完整克隆这里是 0。
1SELECT pdb_name, status, creation_time2FROM dba_pdbs3WHERE status IN ('NEW', 'UNUSABLE')4ORDER BY creation_time DESC;NEW 表示创建后还没在读写模式完成首次整合;UNUSABLE 需要先看创建过程和 alert log,不能直接用 ALTER PLUGGABLE DATABASE OPEN 反复重试。
1SELECT pdb_name, status, foreign_cdb_dbid,2 foreign_pdb_id, unplug_scn3FROM dba_pdbs4WHERE status IN ('RELOCATING', 'RELOCATED', 'UNPLUGGED')5ORDER BY pdb_name;这种状态通常出现在跨 CDB 迁移或插拔流程里。查源库记录时还要对照目标 CDB 的 PDB 和服务;源端显示 RELOCATED,不等于目标端业务连接已经恢复。
以下 RMAN 命令,未另行注明时都以 SYSBACKUP 或 SYSDBA 连接 CDB 根容器的 TARGET。备份列表来自 RMAN repository,不能代替恢复演练。
1LIST BACKUP OF PLUGGABLE DATABASE SALES_PDB;看备份完成时间、设备类型、备份片状态和包含的数据文件。列表中有 PDB 备份,不等于恢复所需归档齐全;PDB 单独备份默认不自动带上归档日志。
1LIST BACKUP SUMMARY;从根容器看到的是整个 CDB 的备份摘要。遇到 PDB 恢复需求,要继续用第 37 条确认目标 PDB 文件确实在备份中,不要只看全库作业名称。
1-- RMAN TARGET 连接 SALES_PDB2REPORT SCHEMA;直接连接 PDB 时,报告只列该 PDB 的永久和临时文件。恢复前把文件编号、表空间和路径与第 18、19 条对照;迁移后路径变化要另核对目标端文件转换设置。
1-- RMAN TARGET 连接 SALES_PDB2REPORT NEED BACKUP;报告按当前 RMAN 保留策略判断数据文件是否需要备份。保留策略设为 NONE 时,这条可能报错;它也不检查归档文件是否已真正可读。
1LIST ARCHIVELOG ALL;PDB 的变化依靠 CDB redo 与归档日志恢复,归档文件不属于某个 PDB 独有。先看对应时间段、RAC 各 thread 和归档状态;LIST 只说明 repository 有记录,文件可读取还需交叉检查或恢复预演。
1SHOW ALL;核对保留策略、控制文件自动备份、归档删除策略、通道和设备类型。PDB 单独备份与 CDB 归档备份若由不同作业负责,故障前应明确两条作业的衔接方式。
1SELECT con_id, pdb_incarnation#, status,2 incarnation_scn, incarnation_time3FROM v$pdb_incarnation4WHERE con_id = (SELECT con_id FROM v$pdbs WHERE name = 'SALES_PDB')5ORDER BY pdb_incarnation# DESC;PDB 做过时间点恢复并 OPEN RESETLOGS 后会出现新的 incarnation。准备使用旧备份或旧归档时,先查当前分支与目标恢复时间,不能把不同分支的备份链直接拼接。
1SET PREPLUGIN CONTAINER = SALES_PDB;2LIST PREPLUGIN BACKUP OF PLUGGABLE DATABASE SALES_PDB;仅在 PDB 从别的 CDB 插入当前 CDB、且现场计划使用迁移前备份时执行。RMAN 连接目标 CDB 根容器,COMPATIBLE 至少为 18.0;这两条是查看 repository,不是把源端备份自动复制到目标端。
1-- 承接第 44 条的 PREPLUGIN CONTAINER 设置2LIST PREPLUGIN ARCHIVELOG ALL;恢复迁移前的数据时还要看源 CDB 的归档范围。名单里缺日志就不能假定 PDB 文件备份能完成恢复;同时核对目标端是否已正确纳入这些备份与归档。
PDB 迁到另一个 CDB,不能只拷数据文件。先看源端文件、钱包和业务连接,再拿 XML 描述文件在目标端做兼容性检查。下面各条默认在 CDB 根容器执行;需要切到 PDB 的地方单独注明。
1SELECT c.name, w.status, w.wallet_type, w.wrl_type, w.wrl_parameter2FROM v$encryption_wallet w3JOIN v$containers c ON c.con_id = w.con_id4WHERE c.name = 'SALES_PDB';如果 PDB 用了 TDE,加密数据文件跟着搬走还不够,目标端必须能使用相应的钱包和主密钥。OPEN 是钱包可用的一个前提;具体密钥迁移还要按现场的 united 或 isolated keystore 配置处理。
1-- 当前会话连接 SALES_PDB2SELECT tablespace_name, encrypted3FROM dba_tablespaces4WHERE encrypted = 'YES'5ORDER BY tablespace_name;这条比只看钱包状态更直接:能找出需要随 PDB 一起核对密钥的表空间。空结果不等于所有列都未加密,使用 TDE 列加密的库还要另查加密列。
1SELECT s.service_name, s.status, COUNT(*) sessions2FROM v$session s3WHERE s.con_id = (SELECT con_id FROM v$pdbs WHERE name = 'SALES_PDB')4AND s.type = 'USER'5GROUP BY s.service_name, s.status6ORDER BY sessions DESC;关闭或拔出 PDB 前,先和业务确认这些会话能否断开。INACTIVE 只代表当时没有执行 SQL,不代表连接池已停止向这个 PDB 建新连接。
1SELECT file_type, file_name2FROM (3 SELECT 'DATAFILE' file_type, file_name4 FROM cdb_data_files5 WHERE con_id = (SELECT con_id FROM v$pdbs WHERE name = 'SALES_PDB')6 UNION ALL7 SELECT 'TEMPFILE', file_name8 FROM cdb_temp_files9 WHERE con_id = (SELECT con_id FROM v$pdbs WHERE name = 'SALES_PDB')10)11ORDER BY file_type, file_name;XML 描述文件只有元数据,不会替你复制这些文件。插入目标 CDB 前要确认文件已经能从目标端访问,或准备好 COPY / MOVE 和文件名转换方案;临时文件在目标端也要复核。
1-- 在目标 CDB 根容器执行2SELECT banner_full FROM v$version WHERE banner_full LIKE 'Oracle Database%';3SELECT value FROM nls_database_parameters4WHERE parameter IN ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET');先记录目标端的版本和字符集,再执行第 51 条正式兼容性检查。单看这两项不能判定可插入:组件、选项、补丁及 PDB 元数据也可能形成插件冲突。
1-- 在目标 CDB 根容器执行;XML 路径须由目标端数据库进程读取2SET SERVEROUTPUT ON3DECLARE4 compatible VARCHAR2(3);5BEGIN6 compatible := CASE DBMS_PDB.CHECK_PLUG_COMPATIBILITY(7 pdb_descr_file => '/u01/pdb_meta/sales_pdb.xml',8 pdb_name => 'SALES_PDB')9 WHEN TRUE THEN 'YES' ELSE 'NO' END;10 DBMS_OUTPUT.PUT_LINE('Compatible: ' || compatible);11END;12/YES 表示这次检查没有发现阻止插入的兼容性问题,随后仍要验证文件、钱包和服务。NO 时查第 52 条,不要凭 XML 文件存在就执行 CREATE PLUGGABLE DATABASE ... USING。
1-- 承接第 51 条,在目标 CDB 根容器执行2SELECT time, name, cause, type, status, message, action3FROM pdb_plug_in_violations4WHERE name = 'SALES_PDB'5AND status = 'PENDING'6ORDER BY time DESC;先处理 ERROR,再评估 WARNING。这个视图也会保留旧检查记录,所以要结合 TIME 对上本次检查;修好源端或目标端条件后重新运行兼容性检查。
以下是建库和状态变更命令,执行账号为目标 CDB 的 SYSDBA。命令里的 PDB 名、数据库链路和文件目录必须先在测试环境对过;生产库要确认源端负载、归档保留、目标端容量及业务服务名称。
1-- 源 CDB 根容器2SELECT log_mode FROM v$database;源 PDB 若要保持读写状态进行热克隆,CDB 需要 ARCHIVELOG 和 local undo。克隆期间生成的归档不能被清理;否则复制文件虽完成,也可能无法把副本推进到一致的 SCN。
1-- 目标 CDB 根容器2SHOW PARAMETER db_create_file_dest3SHOW PARAMETER pdb_file_name_convert目标文件必须落在新位置。示例后续使用 CREATE_FILE_DEST 明确指定目录;若改用 FILE_NAME_CONVERT,先确认每个源文件路径都能匹配且不会撞上现有文件。
1-- 目标 CDB 根容器;本例使用目标端 OMF 文件目录2CREATE PLUGGABLE DATABASE SALES_PDB_TEST FROM SALES_PDB3 CREATE_FILE_DEST = '/u02/oradata/sales_pdb_test';这条会复制 PDB 文件并创建一个新容器,不是创建指向源库的别名。热克隆须符合第 53 条条件;若源 PDB 含 TDE 加密数据,还要按目标 keystore 配置补齐 KEYSTORE IDENTIFIED BY 要求。
1SELECT p.pdb_name, p.status, v.open_mode2FROM dba_pdbs p3JOIN v$pdbs v ON v.name = p.pdb_name4WHERE p.pdb_name = 'SALES_PDB_TEST';正常创建后通常先是 NEW、MOUNTED;建库报错时可能留下 UNUSABLE 的同名 PDB。不要仅凭 SQL*Plus 最后一行判断成功,先查状态和告警日志。
1-- 目标 CDB 根容器;确认建库检查无未处理 ERROR 后执行2ALTER PLUGGABLE DATABASE SALES_PDB_TEST OPEN READ WRITE;普通克隆需要首次读写打开以完成与 CDB 的整合。打开后再回读 DBA_PDBS.STATUS、服务与文件清单;不能把 NEW 状态的 PDB 当作已经可供业务连接。
1-- RMAN TARGET 连接目标 CDB 根容器2BACKUP PLUGGABLE DATABASE SALES_PDB_TEST;新 PDB 的备份计划要在交付前建立。这条备份 PDB 数据文件,不自动带入故障恢复所需的 CDB 归档;归档备份、保留策略和实际恢复预演还要另做。
1-- 目标 CDB 根容器;sales_pdb_link 指向源 PDB2CREATE PLUGGABLE DATABASE SALES_PDB_REF FROM SALES_PDB@sales_pdb_link3 CREATE_FILE_DEST = '/u02/oradata/sales_pdb_ref'4 REFRESH MODE MANUAL;可刷新克隆依赖源端数据库链路;源 CDB 要使用 ARCHIVELOG 与 local undo。它是只读副本,不能在副本上做与源端不一致的业务写入。源端后续新增数据文件,还要核对目标端路径转换参数。
1SELECT pdb_name, refresh_mode, refresh_interval, last_refresh_scn2FROM dba_pdbs3WHERE pdb_name = 'SALES_PDB_REF';MANUAL 表示不会按时自动刷新;LAST_REFRESH_SCN 只说明最近刷新到哪个位置,业务验证仍要比对源、副本的数据时间点和关键对象。
1-- 目标 CDB 根容器;先确认副本上的查询业务允许中断2ALTER PLUGGABLE DATABASE SALES_PDB_REF CLOSE IMMEDIATE;刷新时 PDB 必须处于关闭状态。CLOSE IMMEDIATE 会中断副本上的会话;如果要把只读副本提供给报表业务,先安排刷新窗口。
1-- 连接目标 CDB 后切到已关闭的刷新克隆 PDB2ALTER SESSION SET CONTAINER = SALES_PDB_REF;3ALTER PLUGGABLE DATABASE REFRESH;刷新会经源端链路应用增量变化。完成后回到根容器核对第 60 条的 SCN,并查看插件冲突和告警日志;命令成功也不能替代报表侧抽样校验。
1-- 当前容器为 SALES_PDB_REF2ALTER PLUGGABLE DATABASE OPEN READ ONLY;刷新克隆继续用于查询时应保持只读。重新开放后核对业务服务是否注册到这个 PDB,报表连接是否恢复,并记录本次刷新后的数据时间点。
以下以 SALES_PDB 从源 CDB 迁到目标 CDB 为例。拔出后源端连接立即不可用;目标端打开、校验并完成首次备份之前,不应清除唯一可用的数据文件和 XML 元数据。RAC 要确认源 PDB 在所有实例上都已关闭。
1-- 源 CDB 根容器;目录须允许数据库进程写入2BEGIN3 DBMS_PDB.DESCRIBE(4 pdb_descr_file => '/u01/pdb_meta/sales_pdb_check.xml',5 pdb_name => 'SALES_PDB');6END;7/迁移评估阶段可先生成 XML,交给目标端运行第 51 条兼容性检查,不必立即停库。XML 是描述文件,不包含数据文件;若源端随后改了组件或文件位置,应重新生成并检查。
1-- 源 CDB 根容器;业务连接已切走后执行2ALTER PLUGGABLE DATABASE SALES_PDB CLOSE IMMEDIATE;先让应用停连或迁走服务,再执行关闭。RAC 场景要在所有实例确认 SALES_PDB 已 MOUNTED;只关当前实例就执行拔出会失败。
1-- 源 CDB 根容器;第 65 条已完成,路径留在可控目录2ALTER PLUGGABLE DATABASE SALES_PDB3 UNPLUG INTO '/u01/pdb_meta/sales_pdb.xml';拔出会把 PDB 与源 CDB 脱离,源库业务无法再连这个 PDB。XML 只记录插入所需元数据;数据文件、TDE 钱包和恢复所需备份仍需单独迁移与核对。
1-- 源 CDB 根容器2SELECT pdb_name, status3FROM dba_pdbs4WHERE pdb_name = 'SALES_PDB';UNPLUGGED 表示源 CDB 还保留这个 PDB 的记录,不能在同一个 CDB 直接用它的 XML 再插入同名 PDB。下一条用于迁移时移除该记录,同时保留数据文件。
1-- 仅在第 66、67 条确认完成且 XML、数据文件均已留存后执行2DROP PLUGGABLE DATABASE SALES_PDB KEEP DATAFILES;这是破坏性元数据操作,只允许已拔出的 PDB 使用 KEEP DATAFILES。它会删除源 CDB 控制文件中的 PDB 引用;永久数据文件保留,临时文件会被移除。执行前记录文件路径和备份,目标端迁移成功后仍需重新备份。
1-- 目标 CDB 根容器;已完成兼容性、文件、钱包与容量检查2CREATE PLUGGABLE DATABASE SALES_PDB3 USING '/u01/pdb_meta/sales_pdb.xml'4 COPY5 FILE_NAME_CONVERT = ('/u01/oradata/sales_pdb/',6 '/u02/oradata/sales_pdb/');COPY 保留源文件,FILE_NAME_CONVERT 指定目标文件位置。前提是目标端能读取 XML 中记录的源文件路径;若文件先搬到了另一目录,还要另配 SOURCE_FILE_NAME_CONVERT。不要把 NOCOPY 用在实际需要复制的现场。
1-- 目标 CDB 根容器2SELECT p.pdb_name, p.status, v.open_mode3FROM dba_pdbs p4JOIN v$pdbs v ON v.name = p.pdb_name5WHERE p.pdb_name = 'SALES_PDB';刚插入时通常仍是 NEW、MOUNTED。先查目标文件是否落在预定路径,再处理本次 PDB_PLUG_IN_VIOLATIONS 的待处理项;UNUSABLE 要看告警日志,不应直接反复创建同名 PDB。
1-- 目标 CDB 根容器;文件、钱包及未处理 ERROR 已复核2ALTER PLUGGABLE DATABASE SALES_PDB OPEN READ WRITE;首次读写打开完成 PDB 与目标 CDB 的整合。随后确认 DBA_PDBS.STATUS=NORMAL、业务服务的 PDB 属性、实际会话容器和目标端备份计划;数据库能打开不代表迁移交付已完成。
以下恢复命令不是日常巡检操作。生产库先在隔离环境用同一备份链演练,核对目标 SCN、归档、CDB 根容器和 PDB 钱包;执行恢复时由 SYSBACKUP 或 SYSDBA 连接正确的 CDB 根容器。
1-- 源 CDB 根容器;迁移前完成2BACKUP PLUGGABLE DATABASE SALES_PDB PLUS ARCHIVELOG ALL3 TAG 'SALES_PDB_MIGRATION';预迁移备份要带上恢复所需归档。Oracle 19c 在 local undo 条件下才能保证这条语法备齐对应归档;备份后还要记录源 CDB 控制文件、XML 和目标端实际能读到的备份片。
1-- 目标 CDB 根容器;第 71 条首次打开并核对完成后2BACKUP PLUGGABLE DATABASE SALES_PDB;目标端首次备份是迁移交付的一部分。它不会自动包含 CDB 归档,所以还要确认全库归档作业与保留策略,不能把第 72 条源端备份当成目标端长期备份计划。
1-- 目标 CDB 根容器;只读校验,不写数据文件2RESTORE PLUGGABLE DATABASE SALES_PDB VALIDATE;RMAN 会按 repository 选择恢复所需备份并读备份内容,但不会还原目标数据文件。它能发现备份片不可读的问题;完整恢复仍需要可用归档和实际恢复演练。
1-- RMAN TARGET 连接 SALES_PDB2VALIDATE DATABASE;连接 PDB 后 DATABASE 只覆盖该 PDB。校验会消耗 I/O,最好错开高峰;通过也只说明当前文件块检查结果,不代表未来能从备份恢复。
1-- 目标 CDB 根容器2LIST BACKUP OF ARCHIVELOG ALL;按目标恢复时段和 RAC 每个 redo thread 查归档是否被备份。只有 PDB 数据文件备份、没有对应 CDB 归档,通常无法完成所需的介质恢复。
1-- 目标 CDB 根容器2LIST BACKUP OF DATABASE ROOT;PDB 时间点恢复会用到 CDB 根容器的元数据。若考虑恢复已删除 PDB,Oracle 还要求可用的控制文件、根容器和原 PDB 备份;不能只保留单独的 PDB 备份片。
1-- 目标 CDB 根容器2SELECT name, scn, time, guarantee_flashback_database,3 pdb_restore_point, clean_pdb_restore_point4FROM v$restore_point5WHERE con_id = (SELECT con_id FROM v$pdbs WHERE name = 'SALES_PDB')6ORDER BY time DESC;先分清是普通还原点、PDB 还原点还是 clean PDB 还原点;保证型还原点还会占用 flashback 空间。查到一个名字,不等于所需 flashback log 仍在或恢复目标与当前 incarnation 一致。
1-- 目标 CDB 根容器2SELECT flashback_on FROM v$database;想用 PDB flashback 时,先确认 CDB flashback 状态和实际可回退范围。PDB 使用 local undo 与 shared undo 时所需辅助文件不同,不能只因 FLASHBACK_ON=YES 就直接执行回退。
1-- 目标 CDB 根容器;已有经演练的恢复方案2ALTER PLUGGABLE DATABASE SALES_PDB CLOSE IMMEDIATE;这会中断该 PDB 的业务会话,其他 PDB 可以继续运行。关闭后确认 MOUNTED;若丢失文件导致无法正常关闭,要按缺失数据文件的处理流程先使文件离线,不要反复尝试强制关闭。
1-- RMAN TARGET 连接目标 CDB 根容器;仅在恢复窗口执行2RESTORE PLUGGABLE DATABASE SALES_PDB;真正的 RESTORE 会写数据文件,与第 74 条 VALIDATE 不同。执行前核对目标路径、备份类型、可读备份片和空间;若数据文件有新的目标位置,还须设置文件新名并准备切换步骤。
1-- 承接第 81 条,目标 CDB 根容器2RECOVER PLUGGABLE DATABASE SALES_PDB;完全恢复需要 PDB 数据文件及对应的 CDB redo/归档。RMAN 报缺归档时先查备份链和 thread,不应把不完整恢复误报成完全恢复。成功后先核对错误输出与文件状态,再开放 PDB。
1-- 目标 CDB 根容器;第 81、82 条均成功2ALTER PLUGGABLE DATABASE SALES_PDB OPEN READ WRITE;完全恢复通常不需要 RESETLOGS。开放后检查业务服务、核心对象与数据时间点,并把本次恢复的备份片和归档清单留在故障记录中。
1-- CDB 根容器;示例用事故前已创建的还原点2SELECT name, scn, time, pdb_incarnation#3FROM v$restore_point4WHERE name = 'SALES_BEFORE_CHANGE';目标要落在误操作之前,同时确认它属于要恢复的 PDB 分支。若没有还原点,应从审计、告警日志和业务事件时间线确定 SCN;不能随手填一个比报错时间早的数字。
1-- CDB 根容器;业务已确认会丢弃目标 SCN 之后的 PDB 变更2ALTER PLUGGABLE DATABASE SALES_PDB CLOSE IMMEDIATE;恢复该 PDB 时其他 PDB 可以保持运行。先备份当前状态、记录目标 SCN 并确认归档齐全;这一步会断开 SALES_PDB 的用户连接。
1-- RMAN TARGET 连接 CDB 根容器;示例 SCN 必须改成已确认的目标值2RUN {3 SET UNTIL SCN 123456789;4 RESTORE PLUGGABLE DATABASE SALES_PDB;5 RECOVER PLUGGABLE DATABASE SALES_PDB;6}这不是预演命令,会改写 PDB 数据文件,并放弃目标 SCN 之后的业务变更。没有 FRA 时可能需要 AUXILIARY DESTINATION 供辅助实例使用;先在隔离环境把同一备份链跑通。
1-- 第 86 条恢复成功后,在 CDB 根容器执行2ALTER PLUGGABLE DATABASE SALES_PDB OPEN RESETLOGS;这会为 PDB 创建新的恢复分支,不是普通完全恢复的打开方式。开放前确认恢复报告和业务验收目标;开放后立即保存新的 incarnation 与备份计划。
1SELECT con_id, pdb_incarnation#, status,2 incarnation_scn, incarnation_time3FROM v$pdb_incarnation4WHERE con_id = (SELECT con_id FROM v$pdbs WHERE name = 'SALES_PDB')5ORDER BY pdb_incarnation# DESC;OPEN RESETLOGS 后先辨认当前分支,再追踪旧备份能否用于后续恢复。若库同时有 Data Guard,主备对 PDB 分支的跟随也需要单独核对。
1-- RMAN TARGET 连接 CDB 根容器2BACKUP PLUGGABLE DATABASE SALES_PDB;恢复后尽快建立当前分支的新基线,不能一直依赖恢复前的备份。归档备份仍由 CDB 作业负责,还要验证新备份片能读取。
下面几条用于日常变更。PDB 状态与服务可用性不是同一件事,操作前后都要查监听注册和实际连接。
1-- CDB 根容器;PDB 已以期望模式打开2ALTER PLUGGABLE DATABASE SALES_PDB SAVE STATE;保存后实例重启会尝试恢复当前打开模式。在 RAC 中,这个操作只影响当前实例的保存状态;各实例都要核对,不能把一条命令当成全群设置。
1-- CDB 根容器;确实不希望实例重启时自动开放此 PDB2ALTER PLUGGABLE DATABASE SALES_PDB DISCARD STATE;这是撤销重启自动开放设置,不会立即关闭 PDB。变更后查第 92 条,确认目标实例的记录是否已移除。
1SELECT con_name, instance_name, state, restricted2FROM dba_pdb_saved_states3WHERE con_name = 'SALES_PDB'4ORDER BY instance_name;RAC 每个实例可以有不同的保存状态。若业务只应在部分实例开放,逐一比对预期实例与这里的记录;没有记录的实例重启后不会因为别的实例保存了状态而自动开放。
1-- CDB 根容器;PDB 已关闭,且业务连接已切走2ALTER PLUGGABLE DATABASE SALES_PDB OPEN READ WRITE RESTRICTED;限制模式只允许具备 RESTRICTED SESSION 权限的用户进入 PDB。适合迁移后检查和受控维护;结束前要正常重新开放,不要让业务持续收到连接拒绝。
1SELECT name, total_size, max_size2FROM v$pdbs3WHERE name = 'SALES_PDB';TOTAL_SIZE 包含该 PDB 的数据和临时文件大小,MAX_SIZE 是 PDB 设置的容量上限;这里不是业务段的已用空间。容量不足时还要看底层文件系统或 ASM 可用空间。
1-- 当前容器为 SALES_PDB;示例 200G 按现场容量规划替换2ALTER PLUGGABLE DATABASE STORAGE (MAXSIZE 200G);上限会约束 PDB 文件增长,不能把它当成底层磁盘扩容。调整前查第 94 条和表空间自动扩展设置;上限低于业务实际需求时,写入和文件扩展会报错。
1-- 当前容器为 SALES_PDB2SELECT property_name, property_value3FROM database_properties4WHERE property_name IN ('DEFAULT_PERMANENT_TABLESPACE',5 'DEFAULT_TEMP_TABLESPACE');迁移后先核对默认永久和临时表空间。用户单独指定的默认表空间不会因这里的值改变;还要回看业务用户配置。
1-- 当前容器为 SALES_PDB;SALES_TEMP 已存在且容量足够2ALTER PLUGGABLE DATABASE DEFAULT TEMPORARY TABLESPACE SALES_TEMP;这会影响未显式指定临时表空间的用户后续分配。大排序作业前查临时文件位置、空间与自动扩展,避免在迁移后把默认值指向过小的临时表空间。
1-- 当前容器为 SALES_PDB;先与备库/复制方案核对2ALTER PLUGGABLE DATABASE ENABLE FORCE LOGGING;对有 Data Guard 或增量复制要求的 PDB,先评估现有 NOLOGGING 作业和写入开销,再设置强制日志。命令执行后还需核对数据库与 PDB 层的实际 logging 状态。
1SELECT inst_id, name, open_mode, restricted2FROM gv$pdbs3WHERE name = 'SALES_PDB'4ORDER BY inst_id;单查 V$PDBS 只能看到当前实例。迁服务、保存状态或关闭 PDB 后,各实例都要确认打开模式与业务部署一致;非 RAC 库也可以用它查看当前实例。
1SELECT s.inst_id, s.service_name, c.name pdb_name,2 COUNT(*) user_sessions3FROM gv$session s4JOIN v$containers c ON c.con_id = s.con_id5WHERE s.type = 'USER'6AND c.name = 'SALES_PDB'7GROUP BY s.inst_id, s.service_name, c.name8ORDER BY s.inst_id, user_sessions DESC;最后让业务从正式服务名重新连接,核对新会话所在实例和容器。PDB 打开、服务已注册和客户端真正连进目标 PDB,是三项不同的检查;都对上再结束迁移或恢复。
查 CDB/PDB 问题,先确认会话所在容器,再看 PDB 打开状态和服务指向。克隆、插拔与恢复涉及的不只是一个 PDB 名称:文件、钱包、CDB 归档和根容器备份都要对齐。状态变更后还要用实际连接验证,别只看 ALTER PLUGGABLE DATABASE 返回成功。
ORA100 DBA100 系列海报
更多场景命令收录在 ORA100 · DBA100:
微信里也可以搜索小程序 「三笠的百令册」。