oracle跑批日志,Oracle ORA-06512&ORA-08103对象已不存在之查询期间表上索引被删除

最近,遇到一个很奇怪的问题。一Oracle数据库的两个存储过程,单独跑不会有问题,但是同时跑其中一个存储过程

就会遇到ORA08103报错。

一、问题报错信息如下:

8e19af69e0f8609f86f5b3424d07b1fa.png

报错

ORA-08103: 对象不再存在,ORA-06512: 在 "REPD.ETL_PPACKAGE", line 7901

--根据报错提示,报错涉及的SQL语句是一个Insert into ...... select

V_SQL2:= ' INSERT INTO DATA_T (

C1   ,

C2  ,

C3

)

SELECT

b.T1,

b.T2,

b.T3,

FROM data_b;

二、问题分析

1、第一印象,可能是跨用户数据访问,表被宿主删掉或者报错表上发生了truncate操作。于是,使用ddl审计监控数据

库发生的DDL操作。

--首先sys确认触发器相关的参数

show parameter _system_trig_enabled

--如果_system_trig_enabled参数值为false,修改为true

alter system set "_system_trig_enabled"=true;

--确认触发器相关的参数_system_trig_enabled参数值为true

show parameter _system_trig_enabled

--SYS登陆数据库创建审计表

-- Create table

create table AUDIT_DDL_OBJ

(

opr_time    DATE,

session_id  NUMBER,

os_user     VARCHAR2(200),

ip_address  VARCHAR2(200),

terminal    VARCHAR2(200),

host        VARCHAR2(200),

user_name   VARCHAR2(30),

ddl_type    VARCHAR2(30),

ddl_sql     CLOB,

object_type VARCHAR2(18),

owner       VARCHAR2(30),

object_name VARCHAR2(128)

)

tablespace USERS

pctfree 10

initrans 1

maxtrans 255

storage

(

initial 64K

next 1M

minextents 1

maxextents unlimited

);

--创建DDL审计触发器

CREATE OR REPLACE TRIGGER DDL_Audit_Trigger

AFTER drop or alter or truncate ON DATABASE

/*

||名称:DDL事件审计触发器

||说明:

*/

DECLARE

Session_Id_Var   NUMBER;          /* 会话ID */

Os_User_Var      VARCHAR2(200);   /* 终端OS用户 */

IP_Address_Var   VARCHAR2(200);   /* 终端IP */

Terminal_Var     VARCHAR2(200);   /* 终端 */

Host_Var         VARCHAR2(200);   /* 终端主机名 */

Cut              NUMBER;          /* SQL列表长度 */

Sql_Text         ORA_NAME_LIST_T; /* SQL_TEXT 列表 */

L_Trace          NUMBER;          /* 循环执行条件 */

DDL_Sql_Var      VARCHAR2(2000);  /* DDL语句 */

stmt     clob := NULL;

n        NUMBER;

BEGIN

/* 获取操作用户信息 */

SELECT   SYS_CONTEXT('USERENV','SESSIONID'),

SYS_CONTEXT('USERENV','OS_USER'),

SYS_CONTEXT('USERENV','IP_ADDRESS'),

SYS_CONTEXT('USERENV','TERMINAL'),

SYS_CONTEXT('USERENV','HOST')

INTO     Session_Id_Var,

Os_User_Var,

IP_Address_Var,

Terminal_Var,

Host_Var

FROM     DUAL;

/* 获取DDL SQL语句 */

/*BEGIN

SELECT sql_text

INTO DDL_Sql_Var

FROM sys.v_$sql a, sys.v_$session b

WHERE a.hash_value = b.sql_hash_value

AND b.status = 'active'

AND b.audsid = SYS_CONTEXT('userenv', 'sessionid');

EXCEPTION

WHEN OTHERS THEN

NULL;

END;*/

n := ora_sql_txt(sql_text);

FOR i IN 1 .. n LOOP

stmt := stmt || sql_text(i);

END LOOP;

/* 记录登陆审计信息 */

INSERT INTO Audit_DDL_OBJ(

Opr_Time,     /* 操作时间 */

Session_Id,   /* 会话ID */

OS_User,      /* 终端OS用户 */

IP_Address,   /* 终端IP地址 */

Terminal,     /* 终端 */

Host,         /* 终端主机名 */

User_Name,    /* ORACLE 用户名*/

DDL_Type,     /* DDL操作类型 */

DDL_Sql,      /* DDL语句 */

Object_Type,  /* 操作对象类型 */

Owner,        /* 对象拥有者 */

Object_Name   /* 对象名称 */

)

VALUES( SYSDATE,

Session_Id_Var,

Os_User_Var,

IP_Address_Var,

Terminal_Var,

Host_Var,

ORA_LOGIN_USER,

ORA_SYSEVENT,

stmt,

ORA_DICT_OBJ_TYPE,

ORA_DICT_OBJ_OWNER,

ORA_DICT_OBJ_NAME);

COMMIT;

EXCEPTION

WHEN OTHERS THEN

NULL;

END DDL_Audit_Trigger;

========

触发器后期清理

drop triger DDL_Audit_Trigger;

drop table AUDIT_DDL_OBJ;

alter system set "_system_trig_enabled"=false;

2、分析报错的

根据DDL审计表AUDIT_DDL_OBJ信息,没有发现DATA_T相关的DROP、TRUNCATE操作。

3、经与系统负责人沟通,采用10046跟踪执行跑批报错的会话

1 查询要跟踪的用户会话信息

select sid,serial#,username from v$session where username='REPD';

2 开启10046跟踪

exec dbms_system.set_ev(sid,serial#,10046,12,'');

3 程序抛出错误后结束10046跟踪

exec dbms_system.set_ev(sid,serial#,10046,0,'');

4 获取10046跟踪日志文件,第1步中查询到的sid号

select p.tracefile from V$PROCESS p,v$session s where s.paddr=p.addr and sid=&sid;

4、根据10046跟踪文件获取到ORA08103报错对象的数据文件号和数据块号

9175a0fd03155abacafa973644251b87.png

5、根据10046跟踪文件ORA08103提示的数据文件号和数据块号,确定到insert into ..... select相关表的一个索引对象

5c6ef2f8c176777f8b58bd92d5529b7e.png

6、再次审查DDL审计触发器,在存储过程跑批之前,确实有该索引的drop操作

19b7d654e10fc9f4ded1a9bd23d15104.png

7、至此ORA08103问题根源定位到

导致ORA08103报错的原因就是其中一个存储过程在执行insert into ..... select操作过程中,另外一个存储过程对insert

into ... select的select部分的表上的索引执行了drop,导致select查询异常报错ORA08103退出。

8、排查两个同时执行报错的存储过程,其中一个存储过程确实对审计表监控的索引执行了drop操作

25d2008b86b1b6b91aeff5fb123775d5.png

三、问题处理

经与客户沟通后,屏蔽存储过程中drop索引的操作,再执行存储过程,不再有ORA08103报错。

四、补充

导致ORA08103报错的可能原因有:

1、被操作的对象确实被其他用户删除掉

2、被操作的对象被执行了truncate操作

3、系统表空间数据块损坏导致的对象字典信息与表所在表空间数据对象信息不一致

4、被操作对象发生了DDL例如加字段操作

5、被操作对象上的索引被删除,操作使用到了对象上的索引

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值