现象:

在表上面新建主键报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. SQL TRUNCATE TABLE 命令

    SQL TRUNCATE TABLE 命令 SQL TRUNCATE TABLE 命令用于删除现有数据表中的所有数据. 你也可以使用 DROP TABLE 命令来删除整个数据表,不过 DROP TAB ...

  2. rocketMQ部署

    rocketMQ部署(单机) 1.          环境: CentOS7 64  &  JDK1.8+ 64  & 用户:www 2.          下载binary文件包: ...

  3. v语言怎么玩

    直接上github: https://github.com/vlang/v 前戏 大概是在6月份的时候,在github上看到了这个玩意,我以为是??? 我下意识的去查了一下有没有人在讨论这个语言,但是 ...

  4. Debian下Hadoop 3.12 集群搭建

    Debian系统配置 我这里在Vmware里面虚拟4个Debian系统,一个master,三个solver.hostname分别是master.solver1.solver2.solver3.对了,下 ...

  5. Oracle面对“数据倾斜列使用绑定变量”场景的解决方案

    1.背景知识介绍 2.构造测试用例 3.场景测试 4.总结 1.背景知识介绍     我们知道,Oracle在传统的OLTP(在线事务处理)类系统中,强烈推荐使用绑定变量,这样可以有效的减少硬解析从而 ...

  6. Spring MVC内容协商实现原理及自定义配置【享学Spring MVC】

    每篇一句 在绝对力量面前,一切技巧都是浮云 前言 上文 介绍了Http内容协商的一些概念,以及Spring MVC内置的4种协商方式使用介绍.本文主要针对Spring MVC内容协商方式:从步骤.原理 ...

  7. python 29 Socket - 套接字

    目录 Socket - 套接字 Socket - 套接字 应用层与TCP/IP协议族通信层(或传输层)之间的抽象层,是一组接口()接收数据:当接口接收数据之后,交由操作系统: 如果数据与操作系统直接交 ...

  8. Java基础之String、StringBuffer、StringBuilder浅析

    Java基础之String.StringBuffer.StringBuilder浅析 一.前言: 位于java.lang包下的String.StringBuilder.StringBuffer一般都是 ...

  9. MSIL实用指南-位运算

    C#支持的位运算是与.或.异或.取反.左移.右移,它们对应的指令是And.Or.Xor.Not.Shl.Shr. 取反运算只需要一个操作数,生成步骤是1.生成加载变量2.生成取反指令实例代码: ilG ...

  10. npm init,npm -y, npm install --save,npm install --save-dev

    npm init 初始化一个简单的package.json文件,执行该命令后终端会依次询问 name, version, description 等字段 npm init --yes|-y 作用同上, ...