现象:

在表上面新建主键报ORA-08102的异常:
  1. SQL> alter table t add primary key(id);
  2. alter table t add primary key(id)
  3. *
  4. ERROR at line 1:
  5. ORA-00604: error occurred at recursive SQL level 1
  6. ORA-08102: index key not found, obj# 52, file 1, block 72661 (2)

重现异常:

1、查看基表CON$的_NEXT_CONSTRAINT信息和数据块:
  1. SQL> SELECT OWNER#,NAME,CON# FROM CON$ WHERE NAME='_NEXT_CONSTRAINT';
  2. OWNER# NAME CON#
  3. ---------- ------------------------------ ----------
  4. 0 _NEXT_CONSTRAINT 11222

  1. SQL> set lines 200
  2. SELECT OWNER#,NAME,CON#,
  3. dbms_rowid.ROWID_RELATIVE_FNO(rowid) fno,
  4. dbms_rowid.ROWID_BLOCK_NUMBER(rowid) bno,
  5. dbms_rowid.ROWID_ROW_NUMBER(rowid) rno FROM CON$ WHERE NAME='_NEXT_CONSTRAINT';
  6. OWNER# NAME CON# FNO BNO RNO
  7. ---------- ------------------------------ ---------- ---------- ---------- ----------
  8. 0 _NEXT_CONSTRAINT 11222 1 289 12

记录存储在1号文件、289号block、第12行。

2、使用BBED查看数据块

选择1号文件第289号block:
  1. [oracle@cqfrog bbed]$ bbed parfile=par.txt
  2. BBED> set file 1 block 289
  3. FILE# 1
  4. BLOCK# 289

打印第12行:
  1. BBED> p *kdbr[12]
  2. rowdata[0]
  3. ----------
  4. ub1 rowdata[0] @1207 0x2c

格式化显示:
  1. BBED> x /rccnn
  2. rowdata[0] @1207
  3. ----------
  4. flag@1207: 0x2c (KDRHFL, KDRHFF, KDRHFH)
  5. lock@1208: 0x02
  6. cols@1209: 4
  7. col 0[1] @1210: .
  8. col 1[16] @1212: _NEXT_CONSTRAINT
  9. col 2[4] @1229: 11222
  10. col 3[1] @1234: 0

将offset为1229的信息dump:
  1. BBED> dump /v offset 1229 count 16
  2. File: /u01/app/oracle/oradata/orcl/system01.dbf (1)
  3. Block: 289 Offsets: 1229 to 1244 Dba:0x00400121
  4. -------------------------------------------------------
  5. 04c3020d 1701802c 00040180 105f4e45 l .......,....._NE
  6. <16 bytes per line>

查看11222的16进制:
  1. SQL> select dump(11222, 16) from dual;
  2. DUMP(11222,16)
  3. ----------------------
  4. Typ=2 Len=4: c3,2,d,17
这里的c3,2,d,17对应dump出来的信息:c3020d 17。

3、关闭数据库
必须先关闭数据库, 否则修改不生效。
  1. SQL> shutdown immediate
  2. Database closed.
  3. Database dismounted.
  4. ORACLE instance shut down.
  5. SQL> exit
  6. Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
  7. With the Partitioning, OLAP, Data Mining and Real Application Testing options

4、修改数据块的值
使用bbed修改数据块的值, 将11222 改大。

移动4位, 或者使用dump /v offset 1233count 16:
  1. BBED> dump /v offset +4
  2. File: /u01/app/oracle/oradata/orcl/system01.dbf (1)
  3. Block: 289 Offsets: 1233 to 1248 Dba:0x00400121
  4. -------------------------------------------------------
  5. 1701802c 00040180 105f4e45 58545f43 l ...,....._NEXT_C
  6. <16 bytes per line>

将17修改为19:
  1. BBED> modify /x 1901802c
  2. File: /u01/app/oracle/oradata/orcl/system01.dbf (1)
  3. Block: 289 Offsets: 1233 to 1248 Dba:0x00400121
  4. ------------------------------------------------------------------------
  5. 1901802c 00040180 105f4e45 58545f43
  6. <32 bytes per line>
  7. BBED> sum apply
  8. Check value for File 1, Block 289:
  9. current = 0x7fca, required = 0x7fca
  10. BBED> dump /v offset 1233
  11. File: /u01/app/oracle/oradata/orcl/system01.dbf (1)
  12. Block: 289 Offsets: 1233 to 1248 Dba:0x00400121
  13. -------------------------------------------------------
  14. 1901802c 00040180 105f4e45 58545f43 l ...,....._NEXT_C
  15. <16 bytes per line>

5、启动数据库
  1. SQL> startup
  2. ORACLE instance started.
  3. Total System Global Area 835104768 bytes
  4. Fixed Size 2217952 bytes
  5. Variable Size 549455904 bytes
  6. Database Buffers 276824064 bytes
  7. Redo Buffers 6606848 bytes
  8. Database mounted.
  9. Database opened.


6、查看con$表的信息

使用全表扫描方式:
  1. SQL> select /*+ FULL(t1) */ name,con# from con$ t1 where name='_NEXT_CONSTRAINT';
  2. NAME CON#
  3. ------------------------------ ----------
  4. _NEXT_CONSTRAINT 11224

使用索引方式:
  1. SQL> select /*+ index(t1 I_CON2) */ name,con# from con$ t1 where name='_NEXT_CONSTRAINT';
  2. NAME CON#
  3. ------------------------------ ----------
  4. _NEXT_CONSTRAINT 11222


使用全表扫描和使用索引方式的值相差2。

7、新建测试表并增加主键

  1. SQL> create table t as select * from test where rownum<10;
  2. Table created.
  3. SQL> desc t;
  4. Name Null? Type
  5. ----------------------------------------- -------- ----------------------------
  6. ID NUMBER
  7. NAME VARCHAR2(128


  1. SQL> alter table t add primary key(id);
  2. alter table t add primary key(id)
  3. *
  4. ERROR at line 1:
  5. ORA-00604: error occurred at recursive SQL level 1
  6. ORA-08102: index key not found, obj# 52, file 1, block 72661 (2)

观察发现, 有ORA-8102异常。


修复ORA-08102异常:

1、根据报错信息定位数据块
  1. SQL> alter table t add primary key(id);
  2. alter table t add primary key(id)
  3. *
  4. ERROR at line 1:
  5. ORA-00604: error occurred at recursive SQL level 1
  6. ORA-08102: index key not found, obj# 52, file 1, block 72661 (2)

位置:file 1, block 72661

2、查看索引和全表扫描的信息
  1. SQL> select /*+ FULL(t1) */ name,con# from con$ t1 where name='_NEXT_CONSTRAINT';
  2. NAME CON#
  3. ------------------------------ ----------
  4. _NEXT_CONSTRAINT 11224
  5. SQL> select /*+ index(t1 I_CON2) */ name,con# from con$ t1 where name='_NEXT_CONSTRAINT';
  6. NAME CON#
  7. ------------------------------ ----------
  8. _NEXT_CONSTRAINT 11222


3、dump报错的数据块

根据alert日志或者dump数据块:

  1. SQL> alter system dump datafile 1 block 72661;
  2. System altered.
  3. SQL> select * from v$diag_info; 1 Default Trace File /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_6051.trc

在dump文件搜索8102错误:
 可以看到数据块期望的值是:c3 02 0d 19 。11224。
  1. SQL> select UTL_RAW.CAST_TO_NUMBER(replace('c3 02 0d 19',' ','')) from dual;
  2. UTL_RAW.CAST_TO_NUMBER(REPLACE('C3020D19','',''))
  3. -------------------------------------------------
  4. 11224


查看dump的文件:
  1. row#198[3566] flag: ---D--, lock: 2, len=13, data:(6): 00 41 38 6c 00 ad
  2. col 0; len 4; (4): c3 02 0d 15
  3. row#199[3540] flag: ---D--, lock: 2, len=13, data:(6): 00 41 38 6c 00 af
  4. col 0; len 4; (4): c3 02 0d 16
  5. row#200[3553] flag: ------, lock: 0, len=13, data:(6): 00 40 01 21 00 0c
  6. col 0; len 4; (4): c3 02 0d 17
  7. ----- end of leaf block dump -----
  8. End dump data blocks tsn: 0 file#: 1 minblk 72661 maxblk 72661

找到最后, 图上的红色部分:
00 40 01 21 00 0c 是rowid信息:
文件号:00 40  (取前十位,1)
块号:    01 21  (289)
行号:    00 0c   (12)

注意:这里dump的索引的块, 可以看到对应的数据块的rowid。
我们使用bbed可以看到文件1、数据块289、12行的数据是多少, 这里省略了。
我们看到索引存储的值为: c3 02 0d 17。转换为10进制为11222。
  1. SQL> select UTL_RAW.CAST_TO_NUMBER(replace('c3 02 0d 17',' ','')) from dual;
  2. UTL_RAW.CAST_TO_NUMBER(REPLACE('C3020D17','',''))
  3. -------------------------------------------------
  4. 11222
从前面的全表扫描的结果, 期望值应该为11224, 因此只需要将索引块值修改为c3 02 0d 19。 即可与数据块保持一致。



4、使用BBED修复

查找offset的值:
查看dump的信息, 索引块的ITL槽位有3个, 可以计算offset如下:
offset = 3553+44+8+24*ITL_CNT
= 3553+44+8+24*3= 3677

指定文件和块:
  1. BBED> set file 1 block 72661;
  2. FILE# 1
  3. BLOCK# 72661

定位到行:
  1. BBED> dump offset 3677 count 16
  2. File: /u01/app/oracle/oradata/orcl/system01.dbf (1)
  3. Block: 72661 Offsets: 3677 to 3692 Dba:0x00411bd5
  4. ------------------------------------------------------------------------
  5. 04c3020d 17010200 41386c00 ad04c302

修改:
  1. BBED> modify /x 19 offset 3681
  2. File: /u01/app/oracle/oradata/orcl/system01.dbf (1)
  3. Block: 72661 Offsets: 3681 to 3696 Dba:0x00411bd5
  4. ------------------------------------------------------------------------
  5. 19010200 41386c00 ad04c302 0d150100
  6. <32 bytes per line>
  7. BBED> sum apply
  8. Check value for File 1, Block 72661:
  9. current = 0x1fa3, required = 0x1fa3
  10. BBED> dump offset 3677 count 16
  11. File: /u01/app/oracle/oradata/orcl/system01.dbf (1)
  12. Block: 72661 Offsets: 3677 to 3692 Dba:0x00411bd5
  13. ------------------------------------------------------------------------
  14. 04c3020d 19010200 41386c00 ad04c302
  15. <32 bytes per line>

5、打开数据库验证

查看全表扫描和索引扫描的值是否一致:
  1. SQL> select /*+ FULL(t1) */ name,con# from con$ t1 where name='_NEXT_CONSTRAINT';
  2. NAME CON#
  3. ------------------------------ ----------
  4. _NEXT_CONSTRAINT 11224
  5. SQL> select /*+ index(t1 I_CON2) */ name,con# from con$ t1 where name='_NEXT_CONSTRAINT';
  6. NAME CON#
  7. ------------------------------ ----------
  8. _NEXT_CONSTRAINT 11224

验证增加主键能成功:
  1. SQL> alter table t add primary key(id);
  2. Table altered.

















ORA-08102异常重现及恢复的更多相关文章

  1. Go语言 异常panic和恢复recover用法

    Go语言 异常panic和恢复recover用法 背景:Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在 ...

  2. mysql主从同步异常原因及恢复

    mysql主从同步异常原因及恢复 前言 mysql数据库做主从复制,不仅可以为数据库的数据做实时备份,保证数据的完整性,还能做为读写分离,提升数据库的整体性能.但是,mysql主从复制经常会因为某些原 ...

  3. 【3】JVM-OutOfMemory异常重现

    JVM中常见的OOM,那么如何通过自己编写代码产生这些OOM异常呢?通过写代码重现异常,是为了避免在工作中写出有OOM BUG的代码.之前虽然看过相关文章,但是没自己写过这些代码,这次在编写的实际过程 ...

  4. 通过NBU还原数据库提示LINKING异常,无法恢复数据

    错误提示: 解决方法:

  5. Java中的受检异常

    Java中的受检异常 Java提供了三种异常类型,受检异常(checked exception).运行时异常(runtime exception).错误(error).那么这受检异常在实际开发中又有什 ...

  6. SQL Server数据库的三种恢复模式:简单恢复模式、完整恢复模式和大容量日志恢复模式(转载)

    SQL Server数据库有三种恢复模式:简单恢复模式.完整恢复模式和大容量日志恢复模式: 1.Simple 简单恢复模式, Simple模式的旧称叫”Checkpoint with truncate ...

  7. [Effective Java]第九章 异常

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  8. Win32环境下的程序崩溃异常定位

    1       案例描述 作为Windows程序员,平时最担心见到的事情可能就是程序发生了崩溃(异常),这时Windows会提示该程序执行了非法操作,即将关闭.请与您的供应商联系.呵呵,这句微软的“名 ...

  9. 云计算之路-阿里云上:3个manager节点异常造成 docker swarm 集群宕机

    今天 11:29 - 11:39 左右,docker swarm 集群 3 个 manager 节点同时出现异常,造成整个集群宕机,由此给您带来很大的麻烦,请您谅解. 受此次故障影响的站点有:博问,闪 ...

随机推荐

  1. 2015-11-17 linux基础笔记

    21. 可执行权限不代表能够执行,这得看文件内容 22. 还是可以用适当的拓展名表示该文件是什么种类的*.sh  脚本或批处理文件 *Z.*.tar.*.tar.gz.*.zip.*.tgz 压缩文件 ...

  2. Spring源码剖析开篇:什么是Spring?

    在讲源码之前,先让我们回顾一下一下Spring的基本概念,当然,在看源码之前你需要使用过spring或者spirngmvc. Spring是什么 Spring是一个开源的轻量级Java SE(Java ...

  3. springboot的整合springMvc中的postman的post中的form-data和raw区别

    package com.example.demomap.Controller; import com.example.demomap.pojo.ParaEntity; import org.sprin ...

  4. Leetcode之深度优先搜索(DFS)专题-200. 岛屿数量(Number of Islands)

    Leetcode之深度优先搜索(DFS)专题-200. 岛屿数量(Number of Islands) 深度优先搜索的解题详细介绍,点击 给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计 ...

  5. Leetcode之回溯法专题-39. 组合总数(Combination Sum)

    Leetcode之回溯法专题-39. 组合总数(Combination Sum) 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使 ...

  6. JavaScript 数据结构与算法之美 - 你可能真的不懂递归

    1. 前言 算法为王. 排序算法博大精深,前辈们用了数年甚至一辈子的心血研究出来的算法,更值得我们学习与推敲. 因为之后要讲有内容和算法,其代码的实现都要用到递归,所以,搞懂递归非常重要. 2. 定义 ...

  7. centos7.2+jdk7.9搭建haddoop2.7.0伪分布式环境(亲测成功)

    最近想研究下hadoop,玩一玩大数据,废话不多说,就此开始! 所用环境:   xshell 5.0(ssh连接工具,支持ftp,可向虚拟机传文件) CentOS-7-x86_64-DVD-1511. ...

  8. Linux中mysql5.7主从配置

    MySQL主从配置(两台Linux之间) 简介 Linux下MySQL数据库的主从同步用来实现读写分离.主数据库进行数据的插入,删除与更新:从数据库专门用来查询操作,缓解数据库的压力.让运行海量数据的 ...

  9. 【CF 1059C】 Sequence Transformation 数学

    C. Sequence Transformation:http://codeforces.com/contest/1059/problem/C 题意 给你一个n,第一次输出1-n个数的gcd,然后你可 ...

  10. CodeForces 639C Bear and Polynomials

    Bear and Polynomials 题解: 如果改变一个其中的一个数,那么需要知道的是,前面的数都可以进到当前位来,如果过不来的话,那么就会因为前面有数导致无法变成0. 所以我们将前面的数不断向 ...