今天在生产库调试一sql脚本时报出ORA-600:internal error code:argument:[xtydty2ldi][][][][]错误, 还没明白为什么会产生ora-600,运维人员轰然而至,又打电话联系开发又联系DBA,又是给领导汇报,说是发生了告警,这是什么阵仗,把我都搞蒙了,一查说是一条sql触发,一读那sql,我这一听,这不我刚刚执行的吗,我这是惹上什么麻烦了吗,我只是再调试一个select sql啊。
百度ora-600[xtydty2ldi],第一条就是我们墨天轮上的文章
确认下是否有虚拟列或者函数索引,
1、如果有函数索引,可以尝试在会话设置参数再运行SQL
alter session set “_disable_function_based_index”=true;
2、如果有虚拟列,去掉虚拟列再尝试查询
没有印象有函数索引,查询一下表上的索引类型
示例:select index_type,index_name from dba_indexes where table_name=‘TEST’;
确实找到一条函数索引
INDEX_TYPE INDEX_NAME
FUNCTION-BASED NORMAL IDX_TEST_1
查询索引定义
示例:select dbms_metadata.get_ddl(‘INDEX’,‘IDX_TEST_1’,‘SCOTT’)from dual;
结果是一条类似这样的降序组合索引
示例:CREATE INDEX “SCOTT”.“IDX_TEST_1” ON “SCOTT”.“TEST” (“OWNER”, “CREATED” DESC,
“LAST_DDL_TIME” DESC)…
原来函数索引不一定是对列施加函数创建的索引,这种降序索引产生的索引类型也是FUNCTION-BASED 索引。
查看索引列,发现其使用的索引列不是指定的列
SELECT COLUMN_NAME,COLUMN_POSITION,DESCEND FROM dba_ind_columns where INDEX_OWNER=‘SCOTT’ AND table_name=‘TEST’ AND INDEX_NAME=‘IDX_TEST_1’;
COLUMN_NAME COLUMN_POSITION DESC
OWNER 1 ASC
SYS_NC00016$ 2 DESC
SYS_NC00017$ 3 DESC
查看表的列信息,发现多了虚拟列
select column_name,virtual_column,hidden_column from dba_tab_cols where owner=‘SCOTT’ AND table_name=‘TEST’;
COLUMN_NAME VIR HID
SYS_NC00016$ YES YES
SYS_NC00017$ YES YES
OWNER NO NO
总结:oracle会自动为降序索引列建立虚拟列,将降序索引标为函数类型索引。
oracle在使用函数索引或虚拟列时存在bug,但是不是使用函数索引一定会触发bug,我在自己虚机上想按照原sql样子重现ora-600无论如何尝试也重现不了,这也得讲究天时地利啊。
像墨天轮文章中提到的设置隐含参数,禁用函数索引,再去执行原sql就不会报ora-600了。
alter session set “_disable_function_based_index”=true;
但是不能全局禁用函数索引呀,只能是调整自己的sql,调整其执行计划,或是判断原降序索引是否有真正存在的意义,因为oracle是可以对索引反序检索的。