数据恢复 - ORA-600 18018错误的重现和修复

小心,有一个ORA-600的错误正在靠近。

对于Oracle的管理员来说,600是一个熟悉而陌生的数字,熟悉的是很多的用户都会遇到几次,陌生的是绝大数情况下都束手无策。这类错误一般oracle程序异常的内部错误,它表明一个进程遇到了一个低级的、意外的情况。今天我们通过实例剖析,当遇到一个ORA-600的错误,除了重启重装的二重唱法,我们还能做些什么?

一、案例描述

某客户的数据库在一个用户表空间上create table、insert 等操作报ORA-00600: internal error code, arguments: [kdBlkCheckError], [X], [X],[18018]错误,导致对该表空间上任何需要分配存储空间的操作全部失败。

二、相关知识点

ORA-00600 18018错误表示数据文件头部记录文件内空间使用的BitMap Control数据结构出现损坏。BitMap Control数据结构中记录了文件内所有空闲空间(已用空间)的信息。其位于每个数据文件中第三个block开始的连续几个block内,每个block内包含63488个二进制比特位。

BitMap Control中的信息分两种情况:

1、在表空间指定uniform size为固定值的情况下,1个二进制位表示一个extent 2、在未指定uniform size,即autoallocate(默认值)情况下,一个二进制位表示64K的空间(与db block size无关)

ORA-00600: internal error code, arguments: [kdBlkCheckError], [X], [X],[18018]错误一般指记录的free的bitmap位的个数与bitmap中实际为“0”的二进制位的个数不符。

三、错误重现

1、建立一个新表空间添加一个数据文件并dump第三个块

SQL> alter system dump datafile 8 block3;

截取dump如下:

其中的Free: 63488 表示该块中共有63488 个为0二进制位,这里需要注意的是dump文件中全部以16进制表示,因此下面的很多0实际每一位表示4位二进制数字

2、填充数据并再次观察

Free变为63474,bitmap中相应变为FF3F000000000000,将其转化为2进制等于:1111111100111111,其中有11个1,由于这里建立的表空间使用了默认的autoallocate并未指定uniform size,因此表示共有11个64K的空间被分配

再次填充数据并观察

Free: 63446Bitmap变为FFFFFFFFFF03转换为二进制:111111111111111111111111111111111111111100000011共42个1。

可以总结为dump文件中bitmap转换为二进制后1的个数加free中的数值等于63488,也就是建立空数据文件后该块中bitmap的总位数。

3、模拟破坏并修复

BitMap Control block的type为30,bbed中并未收录该类型数据块的结构体定义信息,因此使用bbed进行观察会报错:

dd出该块并使用ue进行修改:

使用ue(或其他任何支持进制转换的文本编辑器)搜索“FF FF FF FF FF 03”。其中加粗的 D6 F7 经过小头转换并转换为十进制后等于63446, FF FF FF FF FF 03对应bitmap开头的部分。

将其修改为FF FF FF FF FFF3,对应free的D6 F7不动。将破坏后的块dd回文件中:

dd if=/home/oracle/02.log of=/home/oracle/oradata/ora1/bt01.dbf seek=2 bs=8192

由于我们修改了块内的数据,因此该块的校验位与块内数据已经不匹配,需要使用bbed重新生成该块的校验位,否则后续操作会直接报坏块错误:

此时所有需要在该文件上分配空间的操作将全部报错:

至此,错误重现完成。修复过程实际上就是前述破坏操作的逆过程:

修改为正确的值:

dd回文件:

dd if=/home/oracle/02.logof=/home/oracle/oradata/ora1/bt01.dbf seek=2 bs=8192

使用bbed生成checksum:

BBED> sum apply

Check value for File 5, Block 3:

current = 0xbe8e, required = 0xbe8e

再次测试建表操作:

SQL> create table bt4 tablespace bt as select * from dba_tables a;

Table created

四、后续

在实际生产环境的故障中bitmap control的损坏往往比上述测试复杂很多,涉及到以下几种情况:

1、free比bitmap中0的个数少 这种情况表示文件内的某些数据块已经被分配,但free未正确更新,这种情况较为简单,直接修改free变量的值与bitmap相等即可。 2、free比bitmap中0的个数多 这种情况表示文件内的某些数据块“可能”已经被分配,或某些数据块被回收但bitmap本身未更新,这时我们无法确定具体是哪些数据块已经被分配,因此不能通过简单修改bitmap或free进行修复,如果强行修改free值可能会造成业务数据被覆盖。

在上述案例中,经过我方内部沟通,最终建议客户将该表空间中涉及该文件的对象全部移出并drop该文件。

面对日常的oracle数据库故障恢复,我们修复目的是让客户能够尽快的恢复正常生产,因此在客户数据库能打开并正常访问业务数据的情况下,尽量不考虑使用bbed、隐含参数等特殊恢复手段

作者介绍

谢浩 云和恩墨技术专家

具有多年oracle数据库企业级运维经验,擅长结合业务、硬件系统制定各种项目方案。曾服务的客户涉及金融保险、电信运营商、政府等行业。

原文发布于微信公众号 - 数据和云(OraNews)

原文发表时间:2017-12-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏网络

中国黑客六道:网络基础学习篇-获取天气信息

无论是获取网络上的天气信息或者其它的信息,首先要做的,就是访问对方的服务器,向服务器发送请求,然后接收数据。 这里也是一样的,也是向服务器发送一个GET请求,然...

1786
来自专栏小李刀刀的专栏

[译]Laravel 5.0 之路由缓存

本文译自 Matt Stauffer 的系列文章. ---- 在 PHP 代码中进行性能优化并非总是我们优先考虑的问题. 但是我们对后端代码的性能优化--特别是...

3628
来自专栏noteless

[零] Java 语言运行原理 JVM原理浅析 入门了解简介 Java语言组成部分 javap命令使用

https://docs.oracle.com/javase/specs/index.html

702
来自专栏walterlv - 吕毅的博客

在编写异步方法时,使用 ConfigureAwait(false) 避免使用者死锁

发布于 2018-03-23 13:54 更新于 2018-03...

351
来自专栏java架构师

各浏览器对页面外部资源加载的策略

各浏览器对页面外部资源加载的策略        这个总结来源于一次优化的请求,最初某个页面的加载十分缓慢,load事件迟迟无法触发,因此希望可以通过对静态文件...

2627
来自专栏张善友的专栏

支持Visual Studio 2008和.NET 3.5的企业类库4.0

企业类库4.0(EntLib 4)发布了,采用的是Microsoft Public License (Ms-PL)协议发布,和之前的版本的相比较更开放,微软的各...

1679
来自专栏从ORACLE起航,领略精彩的IT技术。

记录一则enq: TX - row lock contention的分析过程

2885
来自专栏IMWeb前端团队

降级那些事情

降级那些事情 页面上线的时候,偶尔会有些特殊或者比较极端的情况,导致页面报错。 小的错误可能只是console控制台上的一个error提示,大的错误可能会导致页...

1850
来自专栏宋凯伦的技术小栈

【Node.js】初识Node.js

  因组里项目需要,我和另外一名同事要学习Node.js。之前接触过Javascript,都是前台处理html时用到,现在要用Javascript做后端,学习N...

1799
来自专栏程序员的SOD蜜

分布式计算,WCF+JSON+实体对象与WebService+DataSet效率大比拼

最近做公司项目,我们要整合所有业务系统的客户数据,各业务系统的数据库有的Oracle,有的是SQLSERVER,而且表结构也不相同,如何整合不同系统之间的客户数...

20810

扫码关注云+社区