暂无图片
暂无图片
5
暂无图片
暂无图片
暂无图片

oracle容器pdb$seed损坏后的修复方法

原创 cqiwen 2023-11-12
1018

pdb$seed,即可插拔数据库模板,或者也可称为种子数据库。

Oracle 12c为Oracle数据库引入了多租户架构,其中一个容器数据库(CDB$ROOT)可以有多个可插拔数据库(PDB)。引入这种新的体系结构是为了简化Oracle数据库的管理,这样我们可以将多个Oracle数据库整合到一个容器数据库(CDB)中。在多租户架构中,理想情况下,我们可以使用种子数据库(PDB$SEED)在容器数据库(CDB$ROOT)中创建任何新的可插拔数据库。PDB$SEED作为创建新的可插拔数据库的模板,不允许我们修改它的配置(默认情况下以只读模式打开)。
image.png

由于文件系统问题或任何其他不可预见的原因,种子数据库(PDB$SEED)可能会损坏或不可用。而前段时间,笔者就刚好遇到了这种事情。起因是我在一台测试机上做磁盘数据清理时,意外地将pdb$seed所对应的数据文件全部删掉了,导致在后续使用种子模板创建数据库时报错,无法通过这种方式正常创建新的可插拔数据库。

在这种情况下,我们不能使用PDB$SEED在各自的容器中创建新的可插拔数据库,所以在本文中,我将讨论在seed处于不可用状态(损坏)的情况下,我们可以用来恢复或重新创建可插拔数据库模板(PDB$SEED)的不同方法。

方法一:使用备份恢复

备份是恢复或还原数据库的第一道防线。通过rman备份来恢复种子数据库是最简单最方便的一种方法。
image.png
以下是具体实验过程:
先备份数据库
image.png
image.png
人为删除pdb$seed的数据文件:
image.png
重新启动种子库,提示文件丢失:
image.png
如果此时通过pdb$seed创建新的可插拔数据库,则会报错:
image.png
现在,我们通过rman备份来恢复种子库pdb$seed:

RMAN> restore pluggable database "pdb$seed";

Starting restore at 2023-11-13 01:48:13
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=14 device type=DISK

channel ORA_DISK_1: starting datafile backup set restore
channel ORA_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_DISK_1: restoring datafile 00005 to /oradata/orcl/pdbseed/system01.dbf
channel ORA_DISK_1: restoring datafile 00006 to /oradata/orcl/pdbseed/sysaux01.dbf
channel ORA_DISK_1: restoring datafile 00008 to /oradata/orcl/pdbseed/undotbs01.dbf
channel ORA_DISK_1: reading from backup piece /backup/db_042bb839_1_1.bak
channel ORA_DISK_1: piece handle=/backup/db_042bb839_1_1.bak tag=TAG20231113T012208
channel ORA_DISK_1: restored backup piece 1
channel ORA_DISK_1: restore complete, elapsed time: 00:00:15
Finished restore at 2023-11-13 01:48:30

RMAN> recover pluggable database "pdb$seed";

Starting recover at 2023-11-13 01:48:49
using channel ORA_DISK_1

starting media recovery
media recovery complete, elapsed time: 00:00:00

Finished recover at 2023-11-13 01:48:50

RMAN> alter pluggable database "pdb$seed" open;

Statement processed

RMAN> 
复制

image.png

方法二:通过其它PDB来恢复种子库(没有备份)

其实,我这次遇到的情况就是这样,由于这是一台测试机,我并没有对数据库进行任何备份,因此无法通过rman进行恢复。但是,我这个容器中有其它pdb数据库。我可以通过其它pdb来恢复pdb$seed.
image.png

SQL> alter session set "_oracle_script"=true;

Session altered.

SQL> drop pluggable database "pdb$seed" including datafiles;

Pluggable database dropped.

SQL> show pdbs

    CON_ID CON_NAME			  OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
	 3 PDB1 			  READ WRITE NO

此时容器中只剩下1个pdb1可插拔数据库,种子库已经被干掉了。

SQL> alter session set "_oracle_script"=false;

Session altered.

SQL> create pluggable database "pdb$seed" from pdb1
file_name_convert=('/oradata/orcl/pdb1/','/oradata/orcl/pdbseed/');

Pluggable database created.

SQL> show pdbs

    CON_ID CON_NAME			  OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
	 2 PDB$SEED			  MOUNTED
	 3 PDB1 			  READ WRITE NO

SQL> alter pluggable database pdb$seed open read only;

Pluggable database altered.

SQL> show pdbs;

    CON_ID CON_NAME			  OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
	 2 PDB$SEED			  READ ONLY  NO
	 3 PDB1 			  READ WRITE NO
复制

现在,PDB$SEED已经被恢复回来了。

方法三:通过其它CDB中的种子库来恢复

前提条件是,对方的数据库版本和数据库补丁与目标库一致,否则不能使用此方法。
image.png

---// 创建远端数据库的dblink //---

SQL> create database link remote_seed_link
connect to system identified by oracle
using '192.168.0.16:1521/cdb1';

SQL> select name,cdb from v$database@remote_seed_link;

NAME            CDB
--------------- ---
CDB1         YES

SQL> select con_id,name,open_mode from v$pdbs@remote_seed_link where name='PDB$SEED';

    CON_ID NAME            OPEN_MODE
---------- --------------- ----------
         2 PDB$SEED        READ ONLY

---// 创建远端数据库的PDB$SEED 的XML文件 //---

SQL> exec DBMS_PDB.DESCRIBE(pdb_descr_file => '/home/oracle/seed_cdb1.xml', pdb_name => 'pdb$seed@REMOTE_SEED_LINK');

PL/SQL procedure successfully completed.


---// 查询远端数据库的PDB$SEED相关数据文件路径 //---

SQL> select name from v$datafile@REMOTE_SEED_LINK where con_id=2;

NAME
------------------------------------------------------------
/data/oracle/cdb1/pdbseed/system01.dbf
/data/oracle/cdb1/pdbseed/sysaux01.dbf
/data/oracle/cdb1/pdbseed/users01.dbf

SQL> select name from v$tempfile@REMOTE_SEED_LINK where con_id=2;

NAME
------------------------------------------------------------
/data/oracle/cdb1/pdbseed/temp01.dbf

将远端数据库的CDB$ROOT相关数据文件拷贝到目标数据库/oradata/orcl/pdbseed目录下,然后执行:

SQL> create pluggable database "pdb$seed" using '/home/oracle/seed_cdb1.xml'
source_file_name_convert=('/data/oracle/cdb1/pdbseed/','/oradata/orcl/pdbseed/')
NOCOPY TEMPFILE REUSE;

Pluggable database created.

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       MOUNTED
         3 PDB1                           READ WRITE NO
复制

方法四:重新创建CDB

当然,这是最后的方案,相当于重做了。感兴趣的朋友可以参考我的另一篇文章进行CDB的重建:oracle多租户详解

最后修改时间:2023-11-13 10:17:27
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论