您可能已经阅读了我之前关于将非CDB升级到Oracle Database 21c的博文。我提到了一个潜在的陷阱:当 ORDIM 存在但没有 SDO 时,升级到 21c 失败。在这篇博文中,我想解释如何事先避免这个陷阱,并解释需要做什么。

Photo by Sara Codair on Unsplash
有什么问题?
在我之前的博客文章中我向您展示了理想和正常的方式。但是在我的测试中,我遇到了一个我不知道的问题——而且我根本没有机会事先意识到它。几个问题汇集在一起。当我写这篇文章时,没有可用的修复方法。
但是没问题,我将描述解决方法。
如果您的非 CDB(以及可能是您的 PDB,以防您尝试拔出/插入/升级)在 DBA_REGISTRY 中具有以下组件设置:
- 无 SDO(空间数据选项)
- ORDIM(多媒体)与用户 MDSYS
那么你需要采取行动。
这种情况导致在 Oracle 21c 中创建了一个 Oracle Locator (LCTR) 组件。无论您是否使用过定位器。但是一些基本步骤缺失或没有发生。
在像我在将非 CDB 升级到 Oracle Database 21c 中)展示的那样的升级中,这将导致:
upg> lsj
+----+-------+---------+---------+-------+--------------+--------+---------------+
|Job#|DB_NAME| STAGE|OPERATION| STATUS| START_TIME| UPDATED| MESSAGE|
+----+-------+---------+---------+-------+--------------+--------+---------------+
| 101| DB12|DBUPGRADE|EXECUTING|RUNNING|21/08/24 10:53|10:56:43|0%Upgraded DB12|
+----+-------+---------+---------+-------+--------------+--------+---------------+
Total jobs 1
upg>
-------------------------------------------------
Errors in database [DB12]
Stage [NONCDBTOPDBXY]
Operation [STOPPED]
Status [ERROR]
Info [
Error: UPG-3009
There are plugin violations for pdb DB12 on CDB3
Cause: After running noncdb_to_pdb.sql, the pdb was closed or was opened in restricted mode
For further details, see the log file located at /home/oracle/logs/DB12/101/autoupgrade_20210824_user.log]
-------------------------------------------------
Logs: [/home/oracle/logs/DB12/101/autoupgrade_20210824_user.log]
-------------------------------------------------
这里出了什么问题?
让我首先检查日志文件。
2021-08-24 10:56:38.885 INFO Begin Upgrade on Database [DB12-DB12]
2021-08-24 10:56:43.369 INFO 0%Upgraded DB12
2021-08-24 10:59:43.653 INFO 22%Upgraded DB12
2021-08-24 11:02:43.855 INFO 22%Upgraded DB12
2021-08-24 11:05:44.255 INFO 52%Upgraded DB12
2021-08-24 11:08:44.734 INFO 67%Upgraded DB12
2021-08-24 11:09:15.995 INFO SUCCESSFULLY UPGRADED [DB12-DB12]
2021-08-24 11:09:15.995 INFO End Upgrade on Database [DB12-DB12]
2021-08-24 11:09:19.984 INFO DB12 has been successfully upgraded skipping the resume
2021-08-24 11:09:19.985 INFO SUCCESSFULLY UPGRADED [DB12]
2021-08-24 11:09:19.985 INFO End Upgrade on Database [DB12]
2021-08-24 11:09:19.986 INFO SUCCESSFULLY UPGRADED [DB12]
2021-08-24 11:09:20.008 INFO db12 Return status is SUCCESS
2021-08-24 11:18:24.533 WARNING There are plugin violations for pdb DB12 on CDB3
DB12 3 ERROR PENDING Database option LCTR mismatch: PDB installed version 12.2.0.1.0. CDB installed version NULL.
2021-08-24 11:18:24.551 ERROR NonCDBToPDB failed: oracle.upgrade.autoupgrade.utils.errors.AutoUpgException: AutoUpgException [UPG-3009#There are plugin violations for pdb DB12 on CDB3
DB12 3 ERROR PENDING Database option LCTR mismatch: PDB installed version 12.2.0.1.0. CDB installed version NULL.]
2021-08-24 11:18:24.551 ERROR Dispatcher failed: AutoUpgException [UPG-3009#There are plugin violations for pdb DB12 on CDB3
DB12 3 ERROR PENDING Database option LCTR mismatch: PDB installed version 12.2.0.1.0. CDB installed version NULL.]
2021-08-24 11:18:24.554 INFO Starting error management routine
2021-08-24 11:18:24.554 INFO Ended error management routine
2021-08-24 11:18:24.556 ERROR Error running dispatcher for job 101
Cause: After running noncdb_to_pdb.sql, the pdb was closed or was opened in restricted mode
2021-08-24 11:18:24.557 ERROR Dispatcher failed:
Error: UPG-3009
There are plugin violations for pdb DB12 on CDB3
Cause: After running noncdb_to_pdb.sql, the pdb was closed or was opened in restricted mode
所以我的新 PDB 的升级很顺利。
那是好消息。
但是PDB 不会因为插件违规而不受限制地打开。noncdb_to_pdb.sql存在问题。
违规是不好的
好吧,检查上面的日志已经告诉我问题是什么。但是让我用这个奇怪的名字检查我最喜欢的视图:PDB_PLUG_IN_VIOLATIONS:
column message format a50
column status format a9
column type format a9
column con_id format 9
select con_id, type, message, status
from PDB_PLUG_IN_VIOLATIONS
where status<>'RESOLVED'
order by time;
它给了我以下输出:
CON_ID TYPE MESSAGE STATUS
------ --------- -------------------------------------------------- ---------
2 WARNING Database option OLS mismatch: PDB installed versio PENDING
n NULL. CDB installed version 21.0.0.0.0.
2 WARNING Database option ORDIM mismatch: PDB installed vers PENDING
ion NULL. CDB installed version 21.0.0.0.0.
3 ERROR Database option LCTR mismatch: PDB installed versi PENDING
on 12.2.0.1.0. CDB installed version NULL.
虽然前两个WARNING对我来说没有任何意义(但我之前曾多次咆哮)ERROR是我的 PDB 无法无限制打开的原因。
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 DB12 READ WRITE YES
除非现在得到特殊处理,否则我的 DB12 不会打开。它错过了定位器组件。
数据库组件LCTR?
LCTR 代表定位器。定位器历来对不打算购买空间数据选项 (SDO) 许可证的客户很有意义。但 SDO于 2019 年 12 月免除额外许可。现在我们可以轻松地争辩说,你们所有人都可以安全地安装 SDO。但我知道“升级需要更长的时间”、“维护”、“安全和修补”等反驳论点。因此,我不会去那里。
但在我的情况下,问题正在发生,因为:
- 我没有安装 SDO
- 我安装了 ORDIM
- 我有 MDSYS 用户,因为有 ORDIM
这些条件触发插件期待定位器——即使我从未使用过定位器(至少在这个数据库中没有)。
当您在 21c 中打开 DBCA 时,没有这样的组件。您可以选择 ORDIM 和/或 SDO,但不能选择 LCTR。该组件似乎没有按时进入 DBCA。即使它在那里,我也不会选择它,因为我以前没有使用过定位器。
但是,如果我之前在 CDB$ROOT 中安装了定位器 (LCTR) 组件,那么我的 PDB 就会完美地打开。
所以在这里我们遇到了经典的“组件陷阱”。当您使用该组件插入非 CDB 时,该组件必须存在于 CDB$ROOT 中。否则会出现插件违规,您的新 PDB 永远不会无限制地打开。
解决方法
因此,您可能会问自己:有哪些解决方法?
首先,请在升级之前应用这些 - 无论您选择什么解决方法。这真的很重要。
- 你安装定位器——这是最好的交易
- 您安装 Spatial Data Option – 如果您想要 SDO,那也不错,但需要更多任务
- 您在插件/升级之前删除了 ORDIM – 如果您不使用它,您可以删除它
解决方法 – 在 CDB$ROOT 中安装定位器
这是最简单的解决方法。
但是 -您需要在启动插件和升级之前安装它。正如您将在下面看到的,还有更多工作要做。
在您尝试升级到 21c 之前,您需要完成以下任务:
1. 手动在 21c CDB$ROOT 中创建 Locator 组件
以 SYS 用户身份登录到您的 CDB$ROOT 并执行:
?/md/admin/mdinstlctr.sql
这将使用 21c CDB 中的所有对象创建定位器 (LCTR) 组件。
2. 调整21c home 中的?/rdbms/admin/cmpupsdo.sql脚本。
据我所知,这个脚本有一个缺陷。只有在数据库将自身标识为 XE 数据库的情况下,它才会执行定位器升级。但是它会跳过这部分你的数据库不是XE。因此将进行编辑,直到有可用的脚本的固定版本。当前脚本如下所示:
Rem =========================================================================
Rem Exit immediately if there are errors in the initial checks
Rem =========================================================================
Rem Setup component script filename variables
COLUMN dbmig_name NEW_VALUE dbmig_file NOPRINT;
set serveroutput off
Rem First check if SDO is not loaded and if an XE database
Rem where the MDSYS schema exists.
Rem If all these are true, then call locdbmig.sql
Rem to invoke locator upgrade script
VARIABLE loc_name VARCHAR2(30);
DECLARE
p_name VARCHAR(128);
p_edition VARCHAR2 (128);
BEGIN
:loc_name := '@nothing.sql';
IF dbms_registry.is_loaded('SDO') IS NOT NULL THEN
NULL; -- Loaded already just fall through and execute nothing.sql
ELSE
EXECUTE IMMEDIATE
'SELECT edition FROM registry$ WHERE cid=''CATPROC'''
INTO p_edition;
IF p_edition = 'XE' THEN
BEGIN -- is XE, check for MDSYS schema
SELECT name INTO p_name FROM user$ WHERE name='MDSYS';
:loc_name := '?/md/admin/locdbmig.sql';
EXCEPTION WHEN NO_DATA_FOUND THEN NULL; -- no MDSYS with XE;
END;
END IF;
END IF;
-- Exception handler for all other cases
-- dbms_registry.is_loaded
-- selecting edition column
-- selecting name where error is not NO_DATA_FOUND
EXCEPTION WHEN OTHERS THEN NULL;
END;
/
Rem No timestamps for locator, but errors
Rem will be associated with SDO
SET ERRORLOGGING ON TABLE SYS.REGISTRY$ERROR IDENTIFIER 'SDO';
SELECT :loc_name AS dbmig_name FROM DUAL;
@&dbmig_file
我只将 1 行更改为:
Rem =========================================================================
Rem Exit immediately if there are errors in the initial checks
Rem =========================================================================
Rem Setup component script filename variables
COLUMN dbmig_name NEW_VALUE dbmig_file NOPRINT;
set serveroutput off
Rem First check if SDO is not loaded and if an XE database
Rem where the MDSYS schema exists.
Rem If all these are true, then call locdbmig.sql
Rem to invoke locator upgrade script
VARIABLE loc_name VARCHAR2(30);
DECLARE
p_name VARCHAR(128);
p_edition VARCHAR2 (128);
BEGIN
:loc_name := '@nothing.sql';
IF dbms_registry.is_loaded('SDO') IS NOT NULL THEN
NULL; -- Loaded already just fall through and execute nothing.sql
ELSE
EXECUTE IMMEDIATE
'SELECT edition FROM registry$ WHERE cid=''CATPROC'''
INTO p_edition;
IF p_edition IS NOT NULL THEN
BEGIN -- is XE, check for MDSYS schema
SELECT name INTO p_name FROM user$ WHERE name='MDSYS';
:loc_name := '?/md/admin/locdbmig.sql';
EXCEPTION WHEN NO_DATA_FOUND THEN NULL; -- no MDSYS with XE;
END;
END IF;
END IF;
-- Exception handler for all other cases
-- dbms_registry.is_loaded
-- selecting edition column
-- selecting name where error is not NO_DATA_FOUND
EXCEPTION WHEN OTHERS THEN NULL;
END;
/
Rem No timestamps for locator, but errors
Rem will be associated with SDO
SET ERRORLOGGING ON TABLE SYS.REGISTRY$ERROR IDENTIFIER 'SDO';
SELECT :loc_name AS dbmig_name FROM DUAL;
@&dbmig_file
所以现在定位器升级脚本locdbmig.sql将被执行**,以防 SDO 不存在但 MDSYS 用户存在**。这就是我要的。不再依赖 XE。
3. 调用 AutoUpgrade 并强制执行经典模式。
我还没有写过关于它的博客,但默认情况下,在 21c 中将使用 Capture/Replay 升级。当我有更多时间时,我会在博客上更详细地介绍它。这意味着“重放”表在处于“发布”阶段的数据库中。当然,我对上面所做的升级脚本所做的更改不会被捕获/重放升级所采用。因此,当您继续进行捕获/重放升级时,这仍然会失败。所以我们需要切换到“经典”自动升级,在那里执行脚本并且一切都按照您和我们习惯的方式进行记录。 AutoUpgrade 配置文件触发经典升级:
upg1.catctl_options=-t
我在将非 CDB 升级到 Oracle Database 21c博客文章中的配置文件中已包含此内容。
不,您可以安全地升级,即使您的数据库中没有 SDO、ORDIM 和 MDSYS 用户,无论您是否曾经使用过定位器。
解决方法 B. – 在 CDB$ROOT 中安装空间数据选项
同样,在您要插入的目标 CDB 中升级到 21c 之前,也必须执行此解决方法。请记住,空间、图形和机器学习现在即使对于 11.2.0.4 数据库也是免费的。
- 在您的 21c CDB 中安装带有 DBCA 的 SDO


。
现在 SDO 存在于 CDBROOT 中。无需在 PDBSEED 中创建它(如果您勾选“包含在 PDB 中”框就会发生这种情况)。
. - 启动自动升级I
$ java -jar /u01/app/oracle/product/21/rdbms/admin/autoupgrade.jar -config DB12.cfg -mode deploy
AutoUpgrade 21.2.210721 launched with default options
Processing config file ...
+--------------------------------+
| Starting AutoUpgrade execution |
+--------------------------------+
1 databases will be processed
Type 'help' to list console commands
upg> lsj
+----+-------+---------+---------+-------+--------------+--------+-------------+
|Job#|DB_NAME| STAGE|OPERATION| STATUS| START_TIME| UPDATED| MESSAGE|
+----+-------+---------+---------+-------+--------------+--------+-------------+
| 100| DB12|PREFIXUPS|EXECUTING|RUNNING|21/08/24 20:08|20:08:22|Remaining 3/3|
+----+-------+---------+---------+-------+--------------+--------+-------------+
Total jobs 1
停止!
这行不通。您将需要与上述解决方案相同的处理方式:
在您的 21c home Call AutoUpgrade 中调整 ?/rdbms/admin/cmpupsdo.sql 脚本并强制执行经典模式
因此,通过安装 SDO,您不会赢得任何东西。
如果你不这样做,你到 PDB 的转换将永远挂起:
upg> lsj
+----+-------+-------------+---------+-------+--------------+--------+-------------------+
|Job#|DB_NAME| STAGE|OPERATION| STATUS| START_TIME| UPDATED| MESSAGE|
+----+-------+-------------+---------+-------+--------------+--------+-------------------+
| 100| DB12|NONCDBTOPDBXY|EXECUTING|RUNNING|21/08/24 20:08|20:23:21|noncdb_to_pdb - 64%|
+----+-------+-------------+---------+-------+--------------+--------+-------------------+
Total jobs 1
当您在新 PDB 中检查组件的版本时,您将看到原因:
SQL> select comp_id, version from dba_registry;
COMP_ID VERSION
------------------------------ ------------------------------
CATALOG 21.0.0.0.0
CATPROC 21.0.0.0.0
JAVAVM 21.0.0.0.0
XML 21.0.0.0.0
CATJAVA 21.0.0.0.0
RAC 21.0.0.0.0
XDB 21.0.0.0.0
OWM 21.0.0.0.0
ORDIM 21.0.0.0.0
LCTR 12.2.0.1.0
OLS 21.0.0.0.0
11 rows selected.
定位器尚未升级。也许它不仅有助于在我的 CDB$ROOT 中而且在我的非 CDB 中预先安装 SDO。但我没有尝试这个。
解决方法 C. – 删除 ORDIM
ORDIM (Oracle Multimedia) 是一个很奇怪的组件。我们宣布它在 Oracle Database 19c 中被删除,但实际上只有具有所有功能的 API 被删除,而组件仍然保留。正如您所见,它甚至存在于 Oracle 21c 中。让我们看看在 23c 中会发生什么。
无论如何,我很久以前就写了一些删除 ORDIM的说明。我也想在这里做这件事。
1. 升级前删除 ORDIM
首先,我在从 12.2.0.1 非 CDB 升级之前删除了 ORDIM,正如我在删除 ORDIM 的说明中所解释的那样。但是让我检查一下 ORDIM 是否存在:
QL> select comp_id, version from dba_registry;
COMP_ID VERSION
------------------------------ ------------------------------
CATALOG 12.2.0.1.0
CATPROC 12.2.0.1.0
JAVAVM 12.2.0.1.0
XML 12.2.0.1.0
CATJAVA 12.2.0.1.0
XDB 12.2.0.1.0
OWM 12.2.0.1.0
ORDIM 12.2.0.1.0
OLS 12.2.0.1.0
9 rows selected.
这是。
我会调用:
@?/rdbms/admin/catcmprm.sql ORDIM
并回答我是否要删除带有“Y”的 ORDIM 的问题。
2. 启动自动升级
现在 AutoUpgrade 可以在经典模式 (upg1.catctl_options=-t) 或捕获/重放升级中升级数据库。
$ java -jar /u01/app/oracle/product/21/rdbms/admin/autoupgrade.jar -config X.cfg -mode deploy
AutoUpgrade 21.2.210721 launched with default options
Processing config file ...
+--------------------------------+
| Starting AutoUpgrade execution |
+--------------------------------+
1 databases will be processed
Type 'help' to list console commands
upg> Job 100 completed
------------------- Final Summary --------------------
Number of databases [ 1 ]
Jobs finished [1]
Jobs failed [0]
Jobs pending [0]
Please check the summary report at:
/home/oracle/logs/cfgtoollogs/upgrade/auto/status/status.html
/home/oracle/logs/cfgtoollogs/upgrade/auto/status/status.log
20 分钟后,我的非 CDB 已插入并完全升级并被同化为 PDB。
SQL*Plus: Release 21.0.0.0.0 - Production on Tue Aug 24 21:19:57 2021
Version 21.3.0.0.0
Copyright (c) 1982, 2021, Oracle. All rights reserved.
Connected to:
Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 DB12 READ WRITE NO
概括
过去几天,这个问题让我花费了很多时间进行测试和发送电子邮件。我提交了 Bug# 33234414 – DBCA 不会在 21.3 中创建定位器 (LCTR) 组件 – 但插件/升级/转换会创建它,并且 PDBS 无法为此问题打开。但目前没有修复它。这就是我将解决方法放在一起的原因。
对我来说,第三个解决方法,即删除 ORDIM,最有意义,因为它很容易做到,并且不需要对升级脚本进行任何更改。但是,当然,这种解决方法仅在您不使用定位器的情况下才对您有意义。
如果您使用定位器,第一个解决方法可能是最好的选择——在 CDB 中创建定位器,调整脚本中的行——然后在经典模式下调用 AutoUpgrade。当然,您可以通过预先安装 SDO 来做同样的练习。但需要事先安装在接收CDB和非CDB(或PDB)中。因此,这是具有相同结果的更多工作。
这篇博文比我最初想象的要长得多。
请记住:Oracle 19c 是您现在将升级到的长期支持版本。Oracle 21c 只是一个创新版本。
文章来源:https://mikedietrichde.com/2021/08/25/upgrade-to-21c-fails-when-ordim-is-present-but-no-sdo/




