google的flush shared pool 更靠谱
Summary
CREATE INDEX <index name> ON <owner>.<table>(<column>)
INDEXTYPE IS CTXSYS.CTXCAT
NOPARALLEL
fails with the following error stack:
ORA-29855: error occurred in the execution of ODCIINDEXCREATE routine
ORA-20000: Oracle Text error:
DRG-50857: oracle error in drixmd.PurgeKGL
ORA-20000: Oracle Text error:
DRG-50857: oracle error in drdmlpo
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at "CTXSYS.DRIXMD", line 283
ORA-00942: table or view does not exist
ORA-06512: at "CTXSYS.DRIXMD", line 248
ORA-06512: at "CTXSYS.DRVXMD", line 36
ORA-06512: at li
ORA-30576: ConText Option dictionary loading error
ORA-06510: PL/SQL: unhandled user-defined exception
ORA-06512: at "CTXSYS.DRICON", line 677
ORA-06510: PL/SQL: unhandled user-defined exce
DRG-50610: internal error: kglpurge \[\]
DRG-50857: oracle error in dricon.get_data_type
ORA-00942: table or view does not exist
ORA-06512: at "CTXSYS.DRUE", line 186
ORA-06512: at "CTXSYS.CATINDEXMETHODS", line 102
- 00000 - "error occurred in the execution of ODCIINDEXCREATE routine"
*Cause: Failed to successfully execute the ODCIIndexCreate routine.
*Action: Check to see if the routine has been coded correctly.
Solution
Instead of trying to connect as ctxsys, run the following:
connect / as sysdba
alter session set current_schema = CTXSYS
@?/ctx/admin/defaults/dr0defin.sql "AMERICAN";
then DROP and CREATE the CTXCAT index.
Attachments :
Cause
The Oracle Text installation was incomplete. Default preferences for the language in use were not loaded due to an error in the install script:
connect ctxsys/ctxsys
@ /u01/app/oracle/product/19.0.0.0/ctx/admin/defaults/dr0defin.sql
The database's password profile did not accept the password matching the username so the connection failed which prevented the script from running.
ORA-29855: error occurred in the execution of ODCIINDEXCREATE routine ORA-20000: Oracle Text error: DRG-50857: oracle error in drixmd.PurgeKGL ORA-20000: Oracle Text error: DRG-50857: oracle error in drdmlpo ORA-06502: PL/SQL: numeric or value error: character to number conversion error ORA-06512: at "CTXSYS.DRIXMD", line 393 ORA-00942: table or view does not exist ORA-06512: at "CTXSYS.DRIXMD", line 358 ORA-06512: at "CTXSYS.DRVXMD", line 36 ORA-06512: at li ORA-30576: ConText Option dictionary loading error ORA-06510: PL/SQL: unhandled user-defined exception ORA-06512: at "CTXSYS.DRICON", line 550 ORA-06510: PL/SQL: unhandled user-defined exce DRG-50610: internal error: kglpurge \[\] DRG-50857: oracle error in dricon.get_data_type ORA-00942: table or view does not exist ORA-06512: at "CTXSYS.DRUE", line 192 ORA-06512: at "CTXSYS.TEXTINDEXMETHODS", line 320 View program sources of error stack?
这个异常栈显示了更为严重的 Oracle Text 元数据损毁(Metadata Corruption) 现象。核心报错包括 PurgeKGL 、drdmlpo 和 kglpurge ,这说明 Oracle 在尝试创建或重试此 Context 索引时,无法正常从库缓存(Library Cache)或共享池中清除老旧的、残留下来的索引对象映射。 [1](https://www.google.com/goto?url=CAESbwHrOzAV_R4wxDrvUf_zO0HWLFupE6yg7z97-TTkk4UmUFUFaIlNQiY83JSseJb2IhjKY9a4y-kvIb3r1L0deeMYplncWQqzOvgq3jvr7BxEnyaKP9DFIe0dbpOwOB9RDdAMw1F5wGWO7yt5eSc9dg "1"), [2](https://www.google.com/goto?url=CAESXgHrOzAV2v1W_19i_14Ef0Wr1ztLAGO4KE0JrzxHztEgEPNCytoI5WrQqCBBDRP9OQUcsI4cJKZihY1qcVHP1xXKQgEQ7POEmZPBYKTZkABdu0G9u8VDtsrLR1rgy18 "2")
对于你的问题 "View program sources of error stack?"(查看错误堆栈的程序源码):
为什么无法直接查看完整源码?
堆栈涉及的 CTXSYS.DRIXMD 、CTXSYS.DRVXMD 、CTXSYS.DRICON 和 CTXSYS.TEXTINDEXMETHODS 都是 Oracle 全文检索(Oracle Text)内置的系统核心包。
- 源码高度封装(Wrapped): Oracle 对这些包体的 PL/SQL 源码进行了二进制加密(Wrap),你无法直接通过
DBA_SOURCE查看到未加密的业务逻辑代码。 - 底层基于 C 调用: 报错中的
kglpurge []和PurgeKGL本质上是 PL/SQL 外部调用的内核级 C 语言函数。它们直接操作 Oracle SGA 的共享内存块(KGL 代表 Kernel Generic Library Cache),所以没有可以直接让你阅读的 PL/SQL 源码行。
如何排查引起错误的底层原因?
虽然无法查看 C 源码,但你可以绕过这些受损的内存映射 ,并清除导致 PurgeKGL 崩溃的"僵尸"数据。请使用 SYSDBA 账户执行以下步骤:
- 定位彻底坏掉的"孤儿(Orphan)"元数据
由于之前可能有创建或删除索引失败的记录,CTXSYS 的字典里出现了重复或失效的索引 ID(例如 DRG-10507: duplicate index )。 [1](https://www.google.com/goto?url=CAESXgHrOzAV2v1W_19i_14Ef0Wr1ztLAGO4KE0JrzxHztEgEPNCytoI5WrQqCBBDRP9OQUcsI4cJKZihY1qcVHP1xXKQgEQ7POEmZPBYKTZkABdu0G9u8VDtsrLR1rgy18 "1"), [2](https://www.google.com/goto?url=CAESbwHrOzAV_R4wxDrvUf_zO0HWLFupE6yg7z97-TTkk4UmUFUFaIlNQiY83JSseJb2IhjKY9a4y-kvIb3r1L0deeMYplncWQqzOvgq3jvr7BxEnyaKP9DFIe0dbpOwOB9RDdAMw1F5wGWO7yt5eSc9dg "2")
请替换你的索引名称执行以下查询:
sql
SELECT idx_id, idx_owner, idx_name
FROM ctxsys.dr$index
WHERE idx_name = '你的索引名称';
请谨慎使用此类代码。
- 如果此查询查出了数据: 说明它是一个残留的"鬼魂"记录。由于底层对应的真实表可能不存在(对应了你的
ORA-00942),在执行数值类型转换或清除缓存时便彻底溃败。 [1](https://www.google.com/goto?url=CAESbwHrOzAV_R4wxDrvUf_zO0HWLFupE6yg7z97-TTkk4UmUFUFaIlNQiY83JSseJb2IhjKY9a4y-kvIb3r1L0deeMYplncWQqzOvgq3jvr7BxEnyaKP9DFIe0dbpOwOB9RDdAMw1F5wGWO7yt5eSc9dg "1")
- 手动清洗 CTXSYS 字典表
如果发现残留的 IDX_ID (假设查出的 ID 是 2243 ),需要手动将其彻底清除: [1](https://www.google.com/goto?url=CAESbwHrOzAV_R4wxDrvUf_zO0HWLFupE6yg7z97-TTkk4UmUFUFaIlNQiY83JSseJb2IhjKY9a4y-kvIb3r1L0deeMYplncWQqzOvgq3jvr7BxEnyaKP9DFIe0dbpOwOB9RDdAMw1F5wGWO7yt5eSc9dg "1")
sql
DELETE FROM ctxsys.dr$index_value WHERE ivl_idx_id = 2243;
DELETE FROM ctxsys.dr$index_object WHERE iob_idx_id = 2243;
DELETE FROM ctxsys.dr$index_column WHERE ixc_idx_id = 2243;
DELETE FROM ctxsys.dr$index WHERE idx_id = 2243;
COMMIT;
请谨慎使用此类代码。
- 强制刷掉失效的 KGL 缓存
为了让刚才导致 kglpurge [] 报错的无效内存映射(Library Cache)彻底失效,你需要对共享池执行清理:
sql
ALTER SYSTEM FLUSH SHARED_POOL;
请谨慎使用此类代码。
如果你在清洗后依然遇到 ORA-00942: table or view does not exist ,请确认: [1](https://www.google.com/goto?url=CAESbwHrOzAV_R4wxDrvUf_zO0HWLFupE6yg7z97-TTkk4UmUFUFaIlNQiY83JSseJb2IhjKY9a4y-kvIb3r1L0deeMYplncWQqzOvgq3jvr7BxEnyaKP9DFIe0dbpOwOB9RDdAMw1F5wGWO7yt5eSc9dg "1")
- 当前执行索引创建的账号 对基表是否拥有直接赋予的显式权限(
GRANT SELECT, REFERENCES)?(通过角色赋予的权限在 Oracle Text 内部往往会失效)。
建议先运行第 1 步的查询,看看能抓到什么样的 idx_id 历史残留?