是否可以交换 oracle 12c PDB
Is it possible to swap oracle 12c PDBs
我们在同一个 cdb 中有 2 个可插入数据库。让我们称它们为 pdb1 和 pdb2。这些在测试环境中,您可以将 thwm 视为单独的 uat 环境。每个 pdb 都有默认服务 (pdb1/pdb2) 以及我创建的 1 个服务 (pdb1_s1/pdb2_s2)。几个 java 应用程序指向其中一个 pdb(uat1 应用服务器指向 pdb1 服务,uat2 服务器指向 pdb2)。 Pbd1 和 pdb2 具有相同的表,但具有不同的数据。
我想 'swap' pdbs 这样 uat1 服务器仍然使用 pdb_s1 服务,但该服务确实指向 pdb2。为什么?假设 uat1 是我们测试的主要环境,但该数据库 (pdb1) 中的数据是 old/corrupted。我们无法切换到 uat2 进行测试,因为 java 服务器中存在其他问题。
我在本地安装了 12c 来测试解决方案。我正在使用 dbms_services,因为 srvctl 似乎不适用于非集群环境(但最终需要使用 srvctl 获得此解决方案,因为 uat 是集群的)。
我发现完成服务交换的唯一方法是从两个 pdb 中删除服务,然后将它们添加回对面的 pdb(在 pdb2 中创建 pdb1_s1 并在 pdb1 中创建 pdb2_s1) .然后我重命名 pdb(pdb1-> pdb2 和 pdb2->pdb1)。有点效果。
问题是默认服务 (pdb1) 仍然指向 pdb1。我尝试从 pdb1 中删除 pdb1 服务并在 pdb1 中创建 pdb2 服务但是导致了问题(并且当我重新启动数据库时该服务没有启动)。
是否可以删除默认服务并使用新名称创建新的默认服务?
如何在服务器启动时启动非默认服务?我试过保存状态,但这似乎不起作用。
正在将 PDBFRED 重命名为 PDBBURT。
对于 OP 的问题,因为他想进行交换,他将使用以下内容来构建一个过程:
- 将 PDB1 重命名为 PDB0
- 将 PDB2 重命名为 PDB1
- 将 PDB0 重命名为 PDB2
这还没有经过测试...基于来自 MOS 的 Doc ID 2439885.1:
从 CDB 检查 PDB 状态:
select name, open_mode, restricted from v$pdbs;
select name, con_id, dbid, con_uid, guid from v$containers order by con_id;
select service_id, name, network_name, creation_date, pdb, con_id from cdb_services;
假设我们将 PDBFRED
重命名为 PDBBURT
:
将 PDB 置于 RESTRICTED 模式以进行重命名操作:
alter pluggable database PDBFRED close;
alter pluggable database PDBFRED open restricted;
select name, open_mode, restricted from v$pdbs;
然后连接到PDBFRED
并重命名:
alter session set container=PDBFRED;
alter pluggable database rename global_name to PDBBURT;
非常重要:Oracle数据库必须关闭PDB并以read/write模式打开,才能完成新的PDB服务名集成到CDB中。
关闭 PDB。
alter pluggable database close immediate;
以read/write模式打开PDB。
alter pluggable database open;
连接到 CDB 并再次检查 PDB:
alter session set container=CDB$ROOT;
select name, open_mode, restricted from v$pdbs;
select name, con_id, dbid, con_uid, guid from v$containers order by con_id;
select service_id, name, network_name, creation_date, pdb, con_id from cdb_services;
PDB 的数据文件仍将使用原始名称,例如:
/u03/oradata/CDB1/PDBFRED
如果您想将文件移动到与 PDBBURT
名称匹配的新目录,则必须手动创建新目录,然后使用在线移动工具移动文件12c 数据库:
$ mkdir '/u03/oradata/CDB1/PDBBURT
然后移动每个数据文件(从 dba_data_files
生成):
SQL> alter database move datafile '/u03/oradata/CDB1/PDBFRED/system01.dbf' to '/u03/oradata/CDB1/PDBBURT/system01.dbf'
要重命名 Oracle 托管文件 (OMF),请遵循文档 "How to rename Oracle-Managed Files (OMFs) (Doc ID 191574.1) "。
虽然'online move'命令无法移动临时表空间的临时文件,因此您必须删除与临时表空间关联的临时文件并在新目录中重新创建一个新的临时文件。
SQL> alter database tempfile '/u03/oradata/CDB1/pdb1/temp01.dbf' drop including datafiles;
SQL> alter tablespace TEMP add tempfile '/u03/oradata/CDB1/PDBBURST/temp01.dbf' size 10M reuse;
问题是我们的 DBA 试图将服务重命名为已经存在的服务而不删除那些服务
现有服务:
- PDB1 / PBD1_S1
- PDB2/PBD2_S1
因此,如果您将 PBD1_S1 命名为 PBD2_S1,则会失败,因为该服务已存在于另一个 PBD 中。
解决方案是同时为服务和 pbds 使用临时名称。
- 重命名服务:PBD1_S1 至 PBD1_S1_TEMP
- 重命名服务:PBD2_S1 至 PBD1_S1
- 重命名服务:PBD1_S1_TEMP 到 PBD2_S1
- 将 pbd : PBD1 重命名为 PBD1_TEMP
- 重命名 pbd:PBD2 为 PBD1
- 重命名 pbd : PBD1_TEMP 至 PBD2
当然,这花了我(不是 DBA)一个星期的时间才意识到问题所在。我们的 DBA 在一个单独的团队中,似乎不关心我们正在尝试做什么,主要在 IST 时间(10 小时时差)工作,不回复电子邮件或聊天,产品支持问题超载,因此所有其他请求都需要永远,不会分享错误日志或他们试图解决问题的任何东西,主要回应他们正在等待 oracle 支持并且他们自己被阻止了。
我们在同一个 cdb 中有 2 个可插入数据库。让我们称它们为 pdb1 和 pdb2。这些在测试环境中,您可以将 thwm 视为单独的 uat 环境。每个 pdb 都有默认服务 (pdb1/pdb2) 以及我创建的 1 个服务 (pdb1_s1/pdb2_s2)。几个 java 应用程序指向其中一个 pdb(uat1 应用服务器指向 pdb1 服务,uat2 服务器指向 pdb2)。 Pbd1 和 pdb2 具有相同的表,但具有不同的数据。
我想 'swap' pdbs 这样 uat1 服务器仍然使用 pdb_s1 服务,但该服务确实指向 pdb2。为什么?假设 uat1 是我们测试的主要环境,但该数据库 (pdb1) 中的数据是 old/corrupted。我们无法切换到 uat2 进行测试,因为 java 服务器中存在其他问题。
我在本地安装了 12c 来测试解决方案。我正在使用 dbms_services,因为 srvctl 似乎不适用于非集群环境(但最终需要使用 srvctl 获得此解决方案,因为 uat 是集群的)。
我发现完成服务交换的唯一方法是从两个 pdb 中删除服务,然后将它们添加回对面的 pdb(在 pdb2 中创建 pdb1_s1 并在 pdb1 中创建 pdb2_s1) .然后我重命名 pdb(pdb1-> pdb2 和 pdb2->pdb1)。有点效果。
问题是默认服务 (pdb1) 仍然指向 pdb1。我尝试从 pdb1 中删除 pdb1 服务并在 pdb1 中创建 pdb2 服务但是导致了问题(并且当我重新启动数据库时该服务没有启动)。
是否可以删除默认服务并使用新名称创建新的默认服务?
如何在服务器启动时启动非默认服务?我试过保存状态,但这似乎不起作用。
正在将 PDBFRED 重命名为 PDBBURT。
对于 OP 的问题,因为他想进行交换,他将使用以下内容来构建一个过程:
- 将 PDB1 重命名为 PDB0
- 将 PDB2 重命名为 PDB1
- 将 PDB0 重命名为 PDB2
这还没有经过测试...基于来自 MOS 的 Doc ID 2439885.1:
从 CDB 检查 PDB 状态:
select name, open_mode, restricted from v$pdbs;
select name, con_id, dbid, con_uid, guid from v$containers order by con_id;
select service_id, name, network_name, creation_date, pdb, con_id from cdb_services;
假设我们将 PDBFRED
重命名为 PDBBURT
:
将 PDB 置于 RESTRICTED 模式以进行重命名操作:
alter pluggable database PDBFRED close;
alter pluggable database PDBFRED open restricted;
select name, open_mode, restricted from v$pdbs;
然后连接到PDBFRED
并重命名:
alter session set container=PDBFRED;
alter pluggable database rename global_name to PDBBURT;
非常重要:Oracle数据库必须关闭PDB并以read/write模式打开,才能完成新的PDB服务名集成到CDB中。
关闭 PDB。
alter pluggable database close immediate;
以read/write模式打开PDB。
alter pluggable database open;
连接到 CDB 并再次检查 PDB:
alter session set container=CDB$ROOT;
select name, open_mode, restricted from v$pdbs;
select name, con_id, dbid, con_uid, guid from v$containers order by con_id;
select service_id, name, network_name, creation_date, pdb, con_id from cdb_services;
PDB 的数据文件仍将使用原始名称,例如:
/u03/oradata/CDB1/PDBFRED
如果您想将文件移动到与 PDBBURT
名称匹配的新目录,则必须手动创建新目录,然后使用在线移动工具移动文件12c 数据库:
$ mkdir '/u03/oradata/CDB1/PDBBURT
然后移动每个数据文件(从 dba_data_files
生成):
SQL> alter database move datafile '/u03/oradata/CDB1/PDBFRED/system01.dbf' to '/u03/oradata/CDB1/PDBBURT/system01.dbf'
要重命名 Oracle 托管文件 (OMF),请遵循文档 "How to rename Oracle-Managed Files (OMFs) (Doc ID 191574.1) "。
虽然'online move'命令无法移动临时表空间的临时文件,因此您必须删除与临时表空间关联的临时文件并在新目录中重新创建一个新的临时文件。
SQL> alter database tempfile '/u03/oradata/CDB1/pdb1/temp01.dbf' drop including datafiles;
SQL> alter tablespace TEMP add tempfile '/u03/oradata/CDB1/PDBBURST/temp01.dbf' size 10M reuse;
问题是我们的 DBA 试图将服务重命名为已经存在的服务而不删除那些服务
现有服务:
- PDB1 / PBD1_S1
- PDB2/PBD2_S1
因此,如果您将 PBD1_S1 命名为 PBD2_S1,则会失败,因为该服务已存在于另一个 PBD 中。
解决方案是同时为服务和 pbds 使用临时名称。
- 重命名服务:PBD1_S1 至 PBD1_S1_TEMP
- 重命名服务:PBD2_S1 至 PBD1_S1
- 重命名服务:PBD1_S1_TEMP 到 PBD2_S1
- 将 pbd : PBD1 重命名为 PBD1_TEMP
- 重命名 pbd:PBD2 为 PBD1
- 重命名 pbd : PBD1_TEMP 至 PBD2
当然,这花了我(不是 DBA)一个星期的时间才意识到问题所在。我们的 DBA 在一个单独的团队中,似乎不关心我们正在尝试做什么,主要在 IST 时间(10 小时时差)工作,不回复电子邮件或聊天,产品支持问题超载,因此所有其他请求都需要永远,不会分享错误日志或他们试图解决问题的任何东西,主要回应他们正在等待 oracle 支持并且他们自己被阻止了。