ORA-08102异常重现及恢复

现象:

在表上面新建主键报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. [[email protected] 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. [email protected]: 0x2c (KDRHFL, KDRHFF, KDRHFH)
  5. [email protected]: 0x02
  6. [email protected]: 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.
时间: 2024-10-25 17:44:16

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

【公告】博客数据异常已全部恢复

亲爱的CSDN博主们, 大家好,由于23日晚上-24日凌晨的博客进行了博客服务器维护,造成了用户访问量.积分和排名的异常情况,截至此刻已全部修复,望相互转告.给大家带来的不便深感抱歉,同时也感谢大家对CSDN的理解与支持~ 如有问题请及时联系客服: 客服微博:@CSDN产品客服 客服QQ:2355263776 客服邮箱:[email protected] 我们将在第一时间为您解决,再次感谢您的支持和理解~ [公告]博客数据异常已全部恢复,码迷,mamicode.com

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

Go语言 异常panic和恢复recover用法 背景:Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱.因为开发者很容易滥用异常,甚至一个小小的错误都抛出一个异常.在Go语言中,使用多值返回来返回错误.不要用异常代替错误,更不要用来控制流程.在极个别的情况下,才使用Go中引入的Exception处理:defer, panic, recover. panic: 1.内建函数

【3】JVM-OutOfMemory异常重现

JVM中常见的OOM,那么如何通过自己编写代码产生这些OOM异常呢?通过写代码重现异常,是为了避免在工作中写出有OOM BUG的代码.之前虽然看过相关文章,但是没自己写过这些代码,这次在编写的实际过程中,由于和书本使用的JDK版本不一致,也会有点问题.其中印象最深刻的就是从JDK1.7开始常量池就已经不放在方法区了,而是改到了Java堆中,所以<深入理解JAVA虚拟机>中的有些知识也需要更新了.下面的代码基于JDK1.7来的.并且在运行程序的时候需要设置JVM参数,如果不设置,轻则需要等待很长

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

mysql数据库做主从复制,不仅可以为数据库的数据做实时备份,保证数据的完整性,还能做为读写分离,提升数据库的整体性能.但是,mysql主从复制经常会因为某些原因使主从数据同步出现异常.因此,下面介绍的是mysql主从同步异常的原因及恢复的方法. 这个问题是在部署主从复制的时候,可能会遇到的 回到顶部 Last_IO_Error: Fatal error: The slave I/O thread stops because master and slave have equal MySQL s

Oracle数据库在线重做日志被删除的几种恢复方法

Oracle数据库的在线重做日志中包含了数据库中所有数据的操作记录,我们可以利用重做日志做很多的操作,例如日志挖掘. 有时候,因为种种原因,我们的在线日志被人误删除或者意外损坏掉,我们应该如何进行恢复呢,其实很简单,看下面内容: 我们通过删除在线日志模拟日志被误删除的情况: [[email protected] orcl]$ rm redo* [[email protected] orcl]$ ls -l redo* ls: 无法访问redo*: 没有那个文件或目录 [[email protec

ORACLE11gR2-RAC之OCR无备份情况下损坏恢复

情景介绍:做OCR备份恢复实验,OCR有4份自动备份.将OCR磁盘从+DATA替换为+OCR2(/dev/raw/raw4) 完成之后使用ocrconfig -manualbackup手动备份OCR,完成之后对/dev/raw/raw4执行dd操作.关闭集群,启动集群,发现集群不能启动. 问题分析(假设不知道问题出在哪里,先分析):1.检查集群服务,发现CRS和CSS服务未能正常启动crsctl check crs2.检查CRS和CSS日志,发现OCR磁盘异常3.恢复OCR(其实就是使用root

Java基础------异常的简易资料

一.异常的定义 异常是因编程错误或外在因素导致程序在运行期无法运行的事件.(它会打断指令的正常秩序流程) 二.异常的分类 1.Error 动态链接错误,比如JVM系统内部错误或资源耗尽,这一类异常事件无法恢复或不可能捕获,将导致应用程序中断. 2.Exception 其他因编程错误或偶然的外在因素导致的一般性问题,这类异常得到恰当处理时,程序有机会恢复至正常运行状态 ①非受检(uncheched)异常 就是程序运行时出现的错误,这种错误是认为造成的,比如1/0,空指针异常等 错误类型转换:jav

8.0 异常控制流 第8章 《深入理解计算机系统 原书第2版》

异常控制流 定义:现代操作系统对于控制流发生突变所作出的反应 全称:Exception Control Flow 缩写:ECF 各层形态: 1.硬件层:硬件检测到的事件会触发控制突然转移到异常处理程序: 2.操作系统层:在操作系统层,内核通过上下文转换,将控制从一个用户进程转移到另外一个用户进程: 3.应用层:一个进程可以发信号到另外一个进程,而接收者会将控制突然转移到它的一个信号处理程序. 描述:一个程序可以通过回避通常的栈规则,并执行到其他函数中任意位置的非本地跳转来对错误做出的反应. 工作

【转】Java异常:选择Checked Exception还是Unchecked Exception?

Java包含两种异常:checked异常和unchecked异常.C#只有unchecked异常.checked和unchecked异常之间的区别是: Checked异常必须被显式地捕获或者传递,如Basic try-catch-finally Exception Handling一文中所说.而unchecked异常则可以不必捕获或抛出. Checked异常继承java.lang.Exception类.Unchecked异常继承自java.lang.RuntimeException类. 有许多支