域索引导致提交报错
最近处理了一个网省的问题,现场反馈提交报错 ,报错如下:
COMMIT;
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20000: Oracle Text error:
DRG-50610: internal error: drexdsync
DRG-50857: oracle error in drekrtd (reselect rowid row locator)
ORA-00942: table or view does not exist
ORA-06512: at "CTXSYS.SYNCRN", line 1
ORA-06512: at line 1
看到这个错误,我们获取到如下信息
1、这个是关于域索引的报错
2、这个是递归SQL导致的报错
3、这个是报表或者视图不存在(最大可能是权限 或者可能就是真不存在)
见到这个错误,首先找现场核实下权限问题,包括操作用户的权限
核查结果并没有异常。
进一步分析:
1、查询域索引信息
Select * from ctxsys.ctx_indexes
2、创建一个域索引会自动创建属性为BASIC_STORAGE的四个二级表对象和一个索引对象出来
BASIC_STORAGE has the following attributes:
i_table_clause Parameter clause for dr$<indexname>$I table creation.
The I table is the index data table.
k_table_clause Parameter clause for dr$<indexname>$K table creation.
The K table is the keymap table.
r_table_clause Parameter clause for dr$<indexname>$R table creation.
The R table is the rowid table.
n_table_clause Parameter clause for dr$<indexname>$N table creation.
The N table is the negative list table.
i_index_clause Parameter clause for dr$<indexname>$X index creation.
大家可以在自己的环境中使用如下SQL查询
Select owner,object_name,object_type,secondary,status
from dba_objects
where owner ='SGPM'
and object_name like 'DR$INDEX_NAME$%' --INDEX_NAME修改为你实际的名称
现场查询结果为空,说明域索引已经不存在了,从而导致提交报错,也就是递归执行域索引的SQL报错。
问题定位到,解决问题的办法很容易:
重建域索引即可。
我这里给出的例子指出了域索引的实际存储表空间位置,目的就是可控,如果不指定就是创建用户所在默认的表空间。
begin
--创建词法分析
--ctx_ddl.create_preference ('chinese_lexer', 'chinese_lexer');
--存储参数
ctx_ddl.create_preference('t1_stor','BASIC_STORAGE');
ctx_ddl.set_attribute('t1_stor','I_TABLE_CLAUSE','tablespace TEST');
ctx_ddl.set_attribute('t1_stor','I_INDEX_CLAUSE','tablespace TEST');
ctx_ddl.set_attribute('t1_stor','K_TABLE_CLAUSE','tablespace TEST');
ctx_ddl.set_attribute('t1_stor','R_TABLE_CLAUSE','tablespace TEST');
ctx_ddl.set_attribute('t1_stor','N_TABLE_CLAUSE','tablespace TEST');
end;
--创建域索引 指定storage参数和lexer词法分析器参数
create index idx1_t1 on t1(object_name) indextype is ctxsys.context parameters ('lexer chinese_lexer storage t1_stor');
--同步域索引数据:(该操作有风险业务低估操作)
查询确认域索引是否需要同步
select u.username, i.idx_name
from ctxsys.dr$index i, dba_users u
where u.user_id=i.idx_owner#
and idx_id in (select pnd_cid from ctxsys.dr$pending);
exec ctx_ddl.sync_index('IDX1_T1');
--优化域索引数据(该操作有风险业务低估操作)
exec ctx_ddl.optimize_index ('IDX1_T1', 'full');