重庆思庄Oracle、Redhat认证学习论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 790|回复: 0
打印 上一主题 下一主题

[Oracle] ORACLE 11G ORA-8103 错误问题处理一例

[复制链接]
跳转到指定楼层
楼主
发表于 2023-10-18 22:30:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
ORACLE 11G ORA-8103 错误问题处理一例
1.问题现象:
今天一朋友说他执行一个SQL语句,会报 ORA-08103错误,但选择其他字段不会:
select edit_time from ZLDOC.BZ_DOC_LOG where edit_time>sysdate-1;
ERROR at line 1:
ORA-08103: object no longer exists

2.问题分析:
使用
select creat_time from ZLDOC.BZ_DOC_LOG where creat_time>sysdate-1;
没有问题。
      
使用
select count(*) from ZLDOC.BZ_DOC_LOG,没有问题
导出数据
expdp \' / as sysdba\' directory=dbbak dumpfile=bz_doc_log.dmp logfile=tables.log tables=ZLDOC.BZ_DOC_Log 由于该表含有CLOB,XMLTYPE等类型,表数据只有20g,但对象有 280G,
所以,一直没有结果

使用 create table as select,会报ora-08103 错误。
3.联机文档解释:
  ORA-08103: object no longer exists
Cause: The object has been deleted by another user since the operation began, or a prior incomplete recovery restored the database to a point in time during the deletion of the object.
Action: Delete the object if this is the result of an incomplete recovery.
ORA-08103表示在进行持久操作时找不到某个对象,具体地说,就是表或视图不能因为已经丢失或被删除,但是还有指向它的对象的句柄。在开发数据库过程中,很可能会碰到这个错误,这个错误是由于表或视图被删除或不存在,但是SQL查询还是链接到该表或视图。
4.网上的解决办法:
  1.转到SYSDBA模式,连接到数据库,查看表的具体信息;
2.查看表的对象是否存在,确定表是否存在;
3.如果表不存在,要查看用户正在尝试查询哪些表,以及出现ORA-08103错误的表是哪个;
4.查看相关联的语句,调查是否有第三方程序和进程正在尝试访问ORA-08103的表;
5.查看系统中的脚本是否有问题,以及更改现有脚本来访问ORA-08103的表;
6.重新创建被删除的表,并执行必要的记录操作,重新测试语句,以确保它正确地表示被访问的表;
7.正确地应用 Oracle 支持的可选特征,以防止Oracle 数据库出现ORA-08103错误;
8.重新创建该表,重新运行SELECT语句,重新获取该表,以更正ORA-08103错误。
看起来不太靠谱,这个表含大对象有280G,不太好重建,而且我们重建也会报同样的错。
5.通过 mos:1527738.1所提供的脚本去保存好的记录,运行一段,就失败了,报:ORA-03113的错误
6.确定问题块
搜MOS,根据 Doc ID 1671518.1 跟踪SQL语句
alter session set max_dump_file_size=unlimited;
alter session set db_file_multiblock_read_count=1;
alter session set events 'immediate trace name trace_buffer_on level 1048576';
alter session set events '10200 trace name context forever, level 1';
alter session set events '10236 trace name context forever, level 1';
alter session set events '8103 trace name errorstack level 3';
alter session set tracefile_identifier='ORA8103';
----->>>> run the sql statement that causes the ORA-08103
alter session set events 'immediate trace name trace_buffer_off';
oradebug setmypid
oradebug tracefile_name
发现了错误的块是  8/2922345:
。。。
        BH (0x20f664288) file#: 8 rdba: 0x022c9769 (8/2922345) class: 1 ba: 0x200006000
        set: 171 pool: 3 bsz: 8192 bsi: 0 sflg: 1 pwc: 3690,28
        dbwrid: 2 obj: 87376 objn: 87376 tsn: 9 afn: 8 hint: f
        hash: [0x109fca6ef8,0xf9f83efb8] lru: [0x104f678dc0,0x104f6724f0]
        ckptq: [NULL] fileq: [NULL] objq: [0xcfc639f8,0xfef758a98] objaq: [0x100f710fd0,0x122f713808]
        use: [NULL] wait: [NULL] fast-cr-pins: 1
        st: XCURRENT md: NULL fpin: 'ktspbwh2: ktspfmdb' tch: 161
        flags: block_written_once redo_since_read
        LRBA: [0x0.0.0] LSCN: [0x0.0] HSCN: [0xffff.ffffffff] HSUB: [1]
        buffer tsn: 9 rdba: 0x00000000 (0/0)
        scn: 0x0000.00000000 seq: 0x00 flg: 0x00 tail: 0x220a0601
        frmt: 0x00 chkval: 0x0000 type: 0x00=unknown
Hex dump of corrupt header 4 = CORRUPT
。。。
通过ROWID,保留 坏块:
create table bad_rows_SAMPLE  (row_id rowid, oracle_error_code number);
set serveroutput on
declare
  n number;
  error_code number;
  bad_rows number := 0;
  e_time date;
  ora1578 EXCEPTION;
  ora600 EXCEPTION;
  ora8103 EXCEPTION;
  PRAGMA EXCEPTION_INIT(ora1578, -1578);
  PRAGMA EXCEPTION_INIT(ora600, -600);
  PRAGMA EXCEPTION_INIT(ora8103, -8103);
begin
   for cursor_lob in (select rowid rid from ZLDOC.BZ_DOC_LOG ) loop
   begin
      select edit_time into e_time from ZLDOC.BZ_DOC_LOG where rowid=cursor_lob.rid ;
   exception
     when ora8103 then
     bad_rows := bad_rows + 1;
     insert into bad_rows_SAMPLE values(cursor_lob.rid,8103);
     commit;
    when ora1578 then
     bad_rows := bad_rows + 1;
     insert into bad_rows_SAMPLE values(cursor_lob.rid,1578);
     commit;
    when ora600 then
     bad_rows := bad_rows + 1;
     insert into bad_rows_SAMPLE values(cursor_lob.rid,600);
     commit;
    when others then
     error_code:=SQLCODE;
     bad_rows := bad_rows + 1;
     insert into bad_rows_SAMPLE values(cursor_lob.rid,error_code);
     commit;   
   end;
  end loop;
  dbms_output.put_line('Total Rows identified with errors in LOB column: '||bad_rows);
end;
/
SQL> select * from bad_rows_SAMPLE;
ROW_ID             ORACLE_ERROR_CODE
------------------ -----------------
AAAVVQAAIAALJdpAAA              8103
AAAVVQAAIAALJdpAAB              8103
AAAVVQAAIAALJdpAAC              8103
AAAVVQAAIAALJdpAAD              8103
AAAVVQAAIAALJdpAAE              8103
AAAVVQAAIAALJdpAAF              8103
AAAVVQAAIAALJdpAAG              8103
AAAVVQAAIAALJdpAAH              8103
AAAVVQAAIAALJdpAAI              8103
AAAVVQAAIAALJdpAAV              8103
AAAVVQAAIAALJdpAAJ              8103
ROW_ID             ORACLE_ERROR_CODE
------------------ -----------------
AAAVVQAAIAALJdpAAK              8103
AAAVVQAAIAALJdpAAL              8103
AAAVVQAAIAALJdpAAM              8103
AAAVVQAAIAALJdpAAN              8103
AAAVVQAAIAALJdpAAO              8103
AAAVVQAAIAALJdpAAP              8103
AAAVVQAAIAALJdpAAQ              8103
AAAVVQAAIAALJdpAAR              8103
AAAVVQAAIAALJdpAAS              8103
AAAVVQAAIAALJdpAAT              8103
AAAVVQAAIAALJdpAAa              8103
ROW_ID             ORACLE_ERROR_CODE
------------------ -----------------
AAAVVQAAIAALJdpAAU              8103
AAAVVQAAIAALJdpAAW              8103
AAAVVQAAIAALJdpAAX              8103
AAAVVQAAIAALJdpAAY              8103
AAAVVQAAIAALJdpAAZ              8103
AAAVVQAAIAALJdpAAb              8103
已选择28行。
SQL> r
  1  select row_id,dbms_rowid.rowid_object(row_id) "#object",
  2               dbms_rowid.rowid_relative_fno(row_id) "#file",
  3               dbms_rowid.rowid_block_number(row_id) "#block",
  4               dbms_rowid.rowid_row_number(row_id) "#row"
  5     from bad_rows_SAMPLE
  6     order by 1
  7*
ROW_ID                #object      #file     #block       #row
------------------ ---------- ---------- ---------- ----------
AAAVVQAAIAALJdpAAA      87376          8    2922345          0
AAAVVQAAIAALJdpAAB      87376          8    2922345          1
AAAVVQAAIAALJdpAAC      87376          8    2922345          2
AAAVVQAAIAALJdpAAD      87376          8    2922345          3
AAAVVQAAIAALJdpAAE      87376          8    2922345          4
AAAVVQAAIAALJdpAAF      87376          8    2922345          5
AAAVVQAAIAALJdpAAG      87376          8    2922345          6
AAAVVQAAIAALJdpAAH      87376          8    2922345          7
AAAVVQAAIAALJdpAAI      87376          8    2922345          8
AAAVVQAAIAALJdpAAJ      87376          8    2922345          9
AAAVVQAAIAALJdpAAK      87376          8    2922345         10
ROW_ID                #object      #file     #block       #row
------------------ ---------- ---------- ---------- ----------
AAAVVQAAIAALJdpAAL      87376          8    2922345         11
AAAVVQAAIAALJdpAAM      87376          8    2922345         12
AAAVVQAAIAALJdpAAN      87376          8    2922345         13
AAAVVQAAIAALJdpAAO      87376          8    2922345         14
AAAVVQAAIAALJdpAAP      87376          8    2922345         15
AAAVVQAAIAALJdpAAQ      87376          8    2922345         16
AAAVVQAAIAALJdpAAR      87376          8    2922345         17
AAAVVQAAIAALJdpAAS      87376          8    2922345         18
AAAVVQAAIAALJdpAAT      87376          8    2922345         19
AAAVVQAAIAALJdpAAU      87376          8    2922345         20
AAAVVQAAIAALJdpAAV      87376          8    2922345         21
ROW_ID                #object      #file     #block       #row
------------------ ---------- ---------- ---------- ----------
AAAVVQAAIAALJdpAAW      87376          8    2922345         22
AAAVVQAAIAALJdpAAX      87376          8    2922345         23
AAAVVQAAIAALJdpAAY      87376          8    2922345         24
AAAVVQAAIAALJdpAAZ      87376          8    2922345         25
AAAVVQAAIAALJdpAAa      87376          8    2922345         26
AAAVVQAAIAALJdpAAb      87376          8    2922345         27
已选择28行。
通过这个块分析,发现有问题的块,就是块 2922345 和上面 8103跟踪的相对应。
7.各种想法尝试
看来这个块有问题,单独去执行
select id from ZLDOC.BZ_DOC_LOG where rowid='AAAVVQAAIAALJdpAAb';
都会报 ora-8103
create index idx_doc_log on ZLDOC.BZ_DOC_LOG(edit_time);同样报错
不想要这28条记录,
delete from ZLDOC.BZ_DOC_LOG where rowid in (select row_id from bad_rows_SAMPLE);
也会报  ora-8103
本来想放弃这个28行,保存好的记录:
declare
  n number;
  error_code number;
  bad_rows number := 0;
  e_time date;
  ora1578 EXCEPTION;
  ora600 EXCEPTION;
  ora8103 EXCEPTION;
  PRAGMA EXCEPTION_INIT(ora1578, -1578);
  PRAGMA EXCEPTION_INIT(ora600, -600);
  PRAGMA EXCEPTION_INIT(ora8103, -8103);
begin
   for cursor_lob in (select rowid rid from ZLDOC.BZ_DOC_LOG ) loop
   begin
      insert into ZLDOC.BZ_DOC_LOG_Norm  select /*+ ROWID(A) */ * from ZLDOC.BZ_DOC_LOG A where rowid=cursor_lob.rid ;
   exception
     when ora8103 then
     bad_rows := bad_rows + 1;
     insert into bad_rows_SAMPLE values(cursor_lob.rid,8103);
     commit;
    when ora1578 then
     bad_rows := bad_rows + 1;
     insert into bad_rows_SAMPLE values(cursor_lob.rid,1578);
     commit;
    when ora600 then
     bad_rows := bad_rows + 1;
     insert into bad_rows_SAMPLE values(cursor_lob.rid,600);
     commit;
    when others then
     error_code:=SQLCODE;
     bad_rows := bad_rows + 1;
     insert into bad_rows_SAMPLE values(cursor_lob.rid,error_code);
     commit;   
   end;
  end loop;
  dbms_output.put_line('Total Rows identified with errors in LOB column: '||bad_rows);
end;
/
这个很快就会报0RA-03113的错误,没有看到好的解释,有点奇怪 ,看来想保存好的数据,都存在问题。
看来这样搞,还是有问题,
继续网上搜,发现一个方法,可以把 8103变成真正的坏块,然后再跳过这些坏块。
在bbed设置坏块看看.
BBED> set dba 8,2922345
        DBA             0x022c9769 (25166083 8,2922345)
BBED> corrupt
Block marked media corrupt.
BBED> sum apply ;
Check value for File 8, Block 2922345:
current = 0xa683, required = 0xa683
SQL>ALTER SESSION SET EVENTS '10231 TRACE NAME CONTEXT FOREVER, LEVEL 10';
8.最终解决
但想到按这样处理,就要丢数据了.
但真的没有办法了吗
还是不太甘心,中午了,想到还是要赶紧把这个问题处理了,再去吃饭,再网上搜了一些,看到有人,直接把数据缓冲去刷一下,就可以了
想到已经是13:00,现在用的人少,赶紧试一下,
alter system flush buffer_cache;
再去看原来要报错的地方:
select edit_time from ZLDOC.BZ_DOC_LOG where edit_time>sysdate-1;
尽然真的不报错了,
赶紧看看直接有报错的块,
select id,edit_time from ZLDOC.BZ_DOC_LOG where rowid in (select row_id from bad_rows_SAMPLE);
确实不报错了
再让朋友检查应用,说修改时间不报错了,但创建时间要报错了,
听到这里,吓我一跳,难倒还有问题,让对方把错误图片贴一个出来,结果是报 " ORA-00920 无效的关系运算符", 明显是SQL语句的问题,让对方看一下,结果是对方SQL语句搞掉了一段。重新运行,问题解决。

到这里,问题已经解决。
9.反思
但反过来想,怎么最终这么简单的问题,最后,花了这么多功夫呢,可能还是被网络误导了,看到网络上都把这个问题夸大了,导致一心也想到问题不会很简单,需要使用高大上的工具才能解决,反而把自己带偏了。
后来,回过头来再次搜MOS,结果上面本来就有一篇文章:
Query from subscriber errors with Ora-8103 (Doc ID 1365868.1)
这个文章说了原因,以及给了一个链接:
OERR: ORA-8103 "object no longer exists" / Troubleshooting, Diagnostic and Solution (Doc ID 8103.1)
这篇文章中,说了各种可能,里面就有一个说可能只在BUFFER CACHE 存在损坏,直接刷一下缓冲区即可
看来这次问题处理,确实是事情多了,简单的问题,复杂化了。
今后解决问题,首先还是要相信官方的知识库.
最后感谢:DBA 札记1群的群主,及小伙伴们,谢谢你们提供思路,让我快速找到问题的解决之道。

参考文档:
      ORA-08103: Object No Longer Exists (Doc ID 1465978.1)
      SRDC - Required Diagnostic Data Collection for ORA-08103 (Doc ID 1671518.1)
      OERR: ORA-8103 "Object No Longer Exists" Primary Note / Troubleshooting, Diagnostic and Solution (Doc ID 8103.1)

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 支持支持 反对反对
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|重庆思庄Oracle、Redhat认证学习论坛 ( 渝ICP备12004239号-4 )

GMT+8, 2024-5-3 05:10 , Processed in 0.087698 second(s), 20 queries .

重庆思庄学习中心论坛-重庆思庄科技有限公司论坛

© 2001-2020

快速回复 返回顶部 返回列表