【原创】CQ数据库损坏修复
上周三中午CQ数据库数据文件损坏,导致登录时一张关键的表无法查询报错从而cq无法登录,此次故障和上次的一样,不过恢复的非常曲折,导致停机两天,现简单的通报下恢复过程:
故障原因:
oracle-902版本的一个BUG,数据文件大小逼近4G、8G临界点时无法自动扩展,该bug在903版本后得到修复,但是公司cq库迟迟未升级,14号数据文件上保存了大量的大对象数据以及大部分cq系统表,在执行修改操作段扩张时逼近4G大小临界点从而报错,导致数据文件头不一致,数据文件被offline。。。上次故障也是同样的问题。
解决方案:
最终的解决方案为重建14号数据文件所在的表空间,全部使用小数据文件(1.9G+10M增长)避免bug的触发。(当然中间经历千辛万苦,不得已才这么办)。
恢复过程:
l 28号下午3点20时就恢复了,对全库做备份时发现磁盘空间不足,考虑到库已恢复成功,因此将历史备份全部删除释放磁盘空间,4:30左右备份完成。
l 再次登录cq,发现又报错,14号文件又坏了,其实在15:20时库已经恢复成功,由于印象中第一次故障时库只要重启后即无法再使用cq连接,基于这样一种经验,我将库打开后直接开始备份,我认为此时就我一个用户连在库上,但是其实已经很多同事悄悄连到该库开始使用,大约在4:10分左右14号文件就悄悄的坏了。。。
l 使用刚完成的rman恢复,发现14号文件已然损坏,原来在备份中间就损坏了。(28号下午5点半)
l 此时的状况是除了一个坏的备份没有其他备份,无法通过rman进行恢复。尝试隐含参数用尽各种常规办法均告失败,14号文件仍然无法open(28号晚9点)。
l 进行数据文件头伪造,手动修改header的scn等信息、重建控制文件等,骗过smon成功将库打开(29号晚11点)。
l 历尽千辛万苦,30号升级至11gR2,连接测试时却震精的发现,cq不支持11gR2.
l 于是准备重新升级至10g,并着手准备。但肖飒告知,之前升级过多次,每次导出导入到新库后,cq都无法录入缺陷,而且不知道什么原因。
l 考虑rman异机恢复,不使用exp,但是担心备份、搭建环境、异机恢复的过程较长,而且恢复后不一定能用,放弃异机恢复。
l 决定仍然使用该库,不过需要对该库大清洗,14号数据文件所在的表空间保存了大量数据,该表空间共8个数据文件,其中有5个已经快逼近4G,未来损坏的隐患很大,考虑到不能升级,决定将该表空间重建,摒弃大文件,共使用了13个1.9G的数据文件来接收迁移的段,而且10M增长。迁移中处理各种报错、约束等问题,迁移完后将原表空间和数据文件删除,顺便把表和索引碎片、高水位线问题解决了。共花了1天半时间,服务器太慢。
l 经测试cq登录正常,没有数据丢失。
介质恢复失败,所以依靠备份来恢复是不可能的,
- RMAN> run{
- 2> restore datafile 14;
- 3> recover datafile 14;
- 4> sql 'alter database datafile 14 online';
- 5> }
- 启动 restore 于 2013-08-29 18:42:45
- 正在使用目标数据库控制文件替代恢复目录
- 分配的通道: ORA_DISK_1
- 通道 ORA_DISK_1: sid=14 devtype=DISK
- 通道 ORA_DISK_1: 正在开始恢复数据文件备份集
- 通道 ORA_DISK_1: 正在指定从备份集恢复的数据文件
- 正将数据文件00014恢复到D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_02.DBF
- 通道 ORA_DISK_1: 已恢复备份段 1
- 段 handle=D:\CQ_BACKUP\DISK1\BAK_45OIH7KG_1_1 tag=TAG20130829T160016 params=NULL
- 通道 ORA_DISK_1: 恢复完成
- 完成 restore 于 2013-08-29 19:16:08
- 启动 recover 于 2013-08-29 19:16:08
- 使用通道 ORA_DISK_1
- 正在开始介质的恢复
- 无法恢复介质
- RMAN-00571: ===========================================================
- RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
- RMAN-00571: ===========================================================
- RMAN-03002: failure of recover command at 08/29/2013 19:16:21
- ORA-00283: recovery session canceled due to errors
- RMAN-11003: failure during parse/execution of SQL statement: alter database recover if needed
- datafile 14
- ORA-00283: 恢复会话因错误而取消
- ORA-01115: 从文件 14 读取块时出现 IO 错误 (块 # 502078)
- ORA-01110: 数据文件 14: 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_02.DBF'
- ORA-27069: skgfdisp: 尝试在文件范围外执行 I/O
- OSD-04026: 传递的参数无效。 (OS 502078)
其实此时数据文件是好的,只是介质恢复时,有对数据文件范围外的地址进行读写,导致oracle无法访问而报错,因为dbv检查并没有坏块,所以不进行介质恢复,将14号文件先restore出来:
- RMAN> restore datafile 14;
- 启动 restore 于 2013-08-29 19:16:49
- 使用通道 ORA_DISK_1
- 通道 ORA_DISK_1: 正在开始恢复数据文件备份集
- 通道 ORA_DISK_1: 正在指定从备份集恢复的数据文件
- 正将数据文件00014恢复到D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_02.DBF
- 通道 ORA_DISK_1: 已恢复备份段 1
- 段 handle=D:\CQ_BACKUP\DISK1\BAK_45OIH7KG_1_1 tag=TAG20130829T160016 params=NULL
- 通道 ORA_DISK_1: 恢复完成
- 完成 restore 于 2013-08-29 19:54:21
将其offline后open,查询scn:
- SQL> select checkpoint_change# from v$datafile;
- CHECKPOINT_CHANGE#
- ------------------
- 432908646
- 432908646
- 432908646
- 432908646
- 432908646
- 432908646
- 432908646
- 432908646
- 432908646
- 432908646
- 432908646
- CHECKPOINT_CHANGE#
- ------------------
- 432908646
- 432908646
- 432893942
- 432908646
- 432908646
- 432908646
- 432908646
- 432908646
- 432908646
- 已选择20行。
- SQL> select change# from v$recover_file;
- CHANGE#
- ----------
- 432893942
14号文件的scn为432893942,而正常文件的scn是432908646,基于前面的推测,我断定这个文件只是header不一致,数据文件并无损坏,只是对该文件进行了超出控制范围外地址的读写而已,所以想使用隐含参数直接打开库,忽略一致性检查,但是最终失败。
因此果断直接使用bbed修改数据文件头,绕过介质恢复。
首先关库,TBS_CQSCHEMA_USE_02.DBF文件(14号坏文件)的1块信息:
- struct kcvfh, 360 bytes @0
- struct kcvfhbfh, 20 bytes @0
- ub1 type_kcbh @0 0x0b
- ub1 frmt_kcbh @1 0x02
- ub1 spare1_kcbh @2 0x00
- ub1 spare2_kcbh @3 0x00
- ub4 rdba_kcbh @4 0x03800001
- ub4 bas_kcbh @8 0x00000000
- ub2 wrp_kcbh @12 0x0000
- ub1 seq_kcbh @14 0x01
- ub1 flg_kcbh @15 0x04 (KCBHFC
- ub2 chkval_kcbh @16 0x1be2
- ub2 spare3_kcbh @18 0x0000
- struct kcvfhhdr, 76 bytes @20
- ub4 kccfhswv @20 0x09200000
- ub4 kccfhcvn @24 0x08000000
- ub4 kccfhdbi @28 0x8a4b9dc5
- text kccfhdbn[] @32 D
- text kccfhdbn[] @33 S
- text kccfhdbn[] @34 _
- text kccfhdbn[] @35 T
- text kccfhdbn[] @36 H
- text kccfhdbn[] @37 C
- text kccfhdbn[] @38 Q
- text kccfhdbn[] @39
- ub4 kccfhcsq @40 0x00003061
- ub4 kccfhfsz @44 0x0007c000
- s_blkz kccfhbsz @48 0x00
- ub2 kccfhfno @52 0x000e
- ub2 kccfhtyp @54 0x0003
- ub4 kccfhacid @56 0x00000000
- ub4 kccfhcks @60 0x00000000
- text kccfhtag[] @64
- text kccfhtag[] @65
- text kccfhtag[] @66
- text kccfhtag[] @67
- text kccfhtag[] @68
- text kccfhtag[] @69
- text kccfhtag[] @70
- text kccfhtag[] @71
- text kccfhtag[] @72
- text kccfhtag[] @73
- text kccfhtag[] @74
- text kccfhtag[] @75
- text kccfhtag[] @76
- text kccfhtag[] @77
- text kccfhtag[] @78
- text kccfhtag[] @79
- text kccfhtag[] @80
- text kccfhtag[] @81
- text kccfhtag[] @82
- text kccfhtag[] @83
- text kccfhtag[] @84
- text kccfhtag[] @85
- text kccfhtag[] @86
- text kccfhtag[] @87
- text kccfhtag[] @88
- text kccfhtag[] @89
- text kccfhtag[] @90
- text kccfhtag[] @91
- text kccfhtag[] @92
- text kccfhtag[] @93
- text kccfhtag[] @94
- text kccfhtag[] @95
- ub4 kcvfhrdb @96 0x00000000
- struct kcvfhcrs, 8 bytes @100
- ub4 kscnbas @100 0x127c90e6
- ub2 kscnwrp @104 0x0000
- ub4 kcvfhcrt @108 0x2eb8d8e1
- ub4 kcvfhrlc @112 0x3128954b
- struct kcvfhrls, 8 bytes @116
- ub4 kscnbas @116 0x19cd392a
- ub2 kscnwrp @120 0x0000
- ub4 kcvfhbti @124 0x00000000
- struct kcvfhbsc, 8 bytes @128
- ub4 kscnbas @128 0x00000000
- ub2 kscnwrp @132 0x0000
- ub2 kcvfhbth @136 0x0000
- ub2 kcvfhsta @138 0x0000 (NONE
- struct kcvfhckp, 36 bytes @140
- struct kcvcpscn, 8 bytes @140
- ub4 kscnbas @140 0x19cd6ff6 --
- ub2 kscnwrp @144 0x0000
- ub4 kcvcptim @148 0x31289e91
- ub2 kcvcpthr @152 0x0001
- union u, 12 bytes @156
- struct kcvcprba, 12 bytes @156
- ub4 kcrbaseq @156 0x00000003
- ub4 kcrbabno @160 0x00000002
- ub2 kcrbabof @164 0x0010
- struct kcvcptr, 12 bytes @156
- struct kcrtrscn, 8 bytes @156
- ub4 kscnbas @156 0x00000003
- ub2 kscnwrp @160 0x0002
- ub4 kcrtrtim @164 0x5f540010
- ub1 kcvcpetb[] @168 0x02
- ub1 kcvcpetb[] @169 0x00
- ub1 kcvcpetb[] @170 0x00
- ub1 kcvcpetb[] @171 0x00
- ub1 kcvcpetb[] @172 0x00
- ub1 kcvcpetb[] @173 0x00
- ub1 kcvcpetb[] @174 0x00
- ub1 kcvcpetb[] @175 0x00
- ub4 kcvfhcpc @176 0x00000381
- ub4 kcvfhrts @180 0x3128945b
- ub4 kcvfhccc @184 0x00000380
- struct kcvfhbcp, 36 bytes @188
- struct kcvcpscn, 8 bytes @188
- ub4 kscnbas @188 0x00000000
- ub2 kscnwrp @192 0x0000
- ub4 kcvcptim @196 0x00000000
- ub2 kcvcpthr @200 0x0000
- union u, 12 bytes @204
- struct kcvcprba, 12 bytes @204
- ub4 kcrbaseq @204 0x00000000
- ub4 kcrbabno @208 0x00000000
- ub2 kcrbabof @212 0x0000
- struct kcvcptr, 12 bytes @204
- struct kcrtrscn, 8 bytes @204
- ub4 kscnbas @204 0x00000000
- ub2 kscnwrp @208 0x0000
- ub4 kcrtrtim @212 0x00000000
- ub1 kcvcpetb[] @216 0x00
- ub1 kcvcpetb[] @217 0x00
- ub1 kcvcpetb[] @218 0x00
- ub1 kcvcpetb[] @219 0x00
- ub1 kcvcpetb[] @220 0x00
- ub1 kcvcpetb[] @221 0x00
- ub1 kcvcpetb[] @222 0x00
- ub1 kcvcpetb[] @223 0x00
- ub4 kcvfhbhz @224 0x00000000
- struct kcvfhxcd, 16 bytes @228
- ub4 space_kcvmxcd[] @228 0x00000000
- ub4 space_kcvmxcd[] @232 0x00000000
- ub4 space_kcvmxcd[] @236 0x00000000
- ub4 space_kcvmxcd[] @240 0x00000000
- word kcvfhtsn @244 14
- ub2 kcvfhtln @248 0x0010
- text kcvfhtnm[] @250 T
- text kcvfhtnm[] @251 B
- text kcvfhtnm[] @252 S
- text kcvfhtnm[] @253 _
- text kcvfhtnm[] @254 C
- text kcvfhtnm[] @255 Q
- text kcvfhtnm[] @256 S
- text kcvfhtnm[] @257 C
- text kcvfhtnm[] @258 H
- text kcvfhtnm[] @259 E
- text kcvfhtnm[] @260 M
- text kcvfhtnm[] @261 A
- text kcvfhtnm[] @262 _
- text kcvfhtnm[] @263 U
- text kcvfhtnm[] @264 S
- text kcvfhtnm[] @265 E
- text kcvfhtnm[] @266
- text kcvfhtnm[] @267
- text kcvfhtnm[] @268
- text kcvfhtnm[] @269
- text kcvfhtnm[] @270
- text kcvfhtnm[] @271
- text kcvfhtnm[] @272
- text kcvfhtnm[] @273
- text kcvfhtnm[] @274
- text kcvfhtnm[] @275
- text kcvfhtnm[] @276
- text kcvfhtnm[] @277
- text kcvfhtnm[] @278
- text kcvfhtnm[] @279
- ub4 kcvfhrfn @280 0x0000000e
- struct kcvfhrfs, 8 bytes @284
- ub4 kscnbas @284 0x00000000
- ub2 kscnwrp @288 0x0000
- ub4 kcvfhrft @292 0x00000000
- struct kcvfhafs, 8 bytes @296
- ub4 kscnbas @296 0x00000000
- ub2 kscnwrp @300 0x0000
- ub4 kcvfhbbc @304 0x00000000
- ub4 kcvfhncb @308 0x00000000
- ub4 kcvfhmcb @312 0x00000000
- ub4 kcvfhlcb @316 0x00000000
- ub4 kcvfhbcs @320 0x00000000
- ub2 kcvfhofb @324 0x0000
- ub2 kcvfhnfb @326 0x0000
- ub4 kcvfhprc @328 0x00000000
- struct kcvfhprs, 8 bytes @332
- ub4 kscnbas @332 0x00000000
- ub2 kscnwrp @336 0x0000
- struct kcvfhprfs, 8 bytes @340
- ub4 kscnbas @340 0x00000000
- ub2 kscnwrp @344 0x0000
- ub4 kcvfhtrt @356 0x00000000
找一个好的数据文件,同样print一下:
- struct kcvfh, 360 bytes @0
- struct kcvfhbfh, 20 bytes @0
- ub1 type_kcbh @0 0x0b
- ub1 frmt_kcbh @1 0x02
- ub1 spare1_kcbh @2 0x00
- ub1 spare2_kcbh @3 0x00
- ub4 rdba_kcbh @4 0x04c00001
- ub4 bas_kcbh @8 0x00000000
- ub2 wrp_kcbh @12 0x0000
- ub1 seq_kcbh @14 0x01
- ub1 flg_kcbh @15 0x04 (KCBHFCK
- ub2 chkval_kcbh @16 0xe33e
- ub2 spare3_kcbh @18 0x0000
- struct kcvfhhdr, 76 bytes @20
- ub4 kccfhswv @20 0x09200000
- ub4 kccfhcvn @24 0x08000000
- ub4 kccfhdbi @28 0x8a4b9dc5
- text kccfhdbn[] @32 D
- text kccfhdbn[] @33 S
- text kccfhdbn[] @34 _
- text kccfhdbn[] @35 T
- text kccfhdbn[] @36 H
- text kccfhdbn[] @37 C
- text kccfhdbn[] @38 Q
- text kccfhdbn[] @39
- ub4 kccfhcsq @40 0x00003134
- ub4 kccfhfsz @44 0x0000fa00
- s_blkz kccfhbsz @48 0x00
- ub2 kccfhfno @52 0x0013
- ub2 kccfhtyp @54 0x0003
- ub4 kccfhacid @56 0x00000000
- ub4 kccfhcks @60 0x00000000
- text kccfhtag[] @64
- text kccfhtag[] @65
- text kccfhtag[] @66
- text kccfhtag[] @67
- text kccfhtag[] @68
- text kccfhtag[] @69
- text kccfhtag[] @70
- text kccfhtag[] @71
- text kccfhtag[] @72
- text kccfhtag[] @73
- text kccfhtag[] @74
- text kccfhtag[] @75
- text kccfhtag[] @76
- text kccfhtag[] @77
- text kccfhtag[] @78
- text kccfhtag[] @79
- text kccfhtag[] @80
- text kccfhtag[] @81
- text kccfhtag[] @82
- text kccfhtag[] @83
- text kccfhtag[] @84
- text kccfhtag[] @85
- text kccfhtag[] @86
- text kccfhtag[] @87
- text kccfhtag[] @88
- text kccfhtag[] @89
- text kccfhtag[] @90
- text kccfhtag[] @91
- text kccfhtag[] @92
- text kccfhtag[] @93
- text kccfhtag[] @94
- text kccfhtag[] @95
- ub4 kcvfhrdb @96 0x00000000
- struct kcvfhcrs, 8 bytes @100
- ub4 kscnbas @100 0x19504563
- ub2 kscnwrp @104 0x0000
- ub4 kcvfhcrt @108 0x30f78f0e
- ub4 kcvfhrlc @112 0x3128954b
- struct kcvfhrls, 8 bytes @116
- ub4 kscnbas @116 0x19cd392a
- ub2 kscnwrp @120 0x0000
- ub4 kcvfhbti @124 0x00000000
- struct kcvfhbsc, 8 bytes @128
- ub4 kscnbas @128 0x00000000
- ub2 kscnwrp @132 0x0000
- ub2 kcvfhbth @136 0x0000
- ub2 kcvfhsta @138 0x0000 (NONE)
- struct kcvfhckp, 36 bytes @140
- struct kcvcpscn, 8 bytes @140
- ub4 kscnbas @140 0x19cda316
- ub2 kscnwrp @144 0x0000
- ub4 kcvcptim @148 0x3128c136
- ub2 kcvcpthr @152 0x0001
- union u, 12 bytes @156
- struct kcvcprba, 12 bytes @156
- ub4 kcrbaseq @156 0x00000004
- ub4 kcrbabno @160 0x000020b9
- ub2 kcrbabof @164 0x0010
- struct kcvcptr, 12 bytes @156
- struct kcrtrscn, 8 bytes @156
- ub4 kscnbas @156 0x00000004
- ub2 kscnwrp @160 0x20b9
- ub4 kcrtrtim @164 0x03970010
- ub1 kcvcpetb[] @168 0x02
- ub1 kcvcpetb[] @169 0x00
- ub1 kcvcpetb[] @170 0x00
- ub1 kcvcpetb[] @171 0x00
- ub1 kcvcpetb[] @172 0x00
- ub1 kcvcpetb[] @173 0x00
- ub1 kcvcpetb[] @174 0x00
- ub1 kcvcpetb[] @175 0x00
- ub4 kcvfhcpc @176 0x000000bb
- ub4 kcvfhrts @180 0x3128b5d6
- ub4 kcvfhccc @184 0x000000ba
- struct kcvfhbcp, 36 bytes @188
- struct kcvcpscn, 8 bytes @188
- ub4 kscnbas @188 0x00000000
- ub2 kscnwrp @192 0x0000
- ub4 kcvcptim @196 0x00000000
- ub2 kcvcpthr @200 0x0000
- union u, 12 bytes @204
- struct kcvcprba, 12 bytes @204
- ub4 kcrbaseq @204 0x00000000
- ub4 kcrbabno @208 0x00000000
- ub2 kcrbabof @212 0x0000
- struct kcvcptr, 12 bytes @204
- struct kcrtrscn, 8 bytes @204
- ub4 kscnbas @204 0x00000000
- ub2 kscnwrp @208 0x0000
- ub4 kcrtrtim @212 0x00000000
- ub1 kcvcpetb[] @216 0x00
- ub1 kcvcpetb[] @217 0x00
- ub1 kcvcpetb[] @218 0x00
- ub1 kcvcpetb[] @219 0x00
- ub1 kcvcpetb[] @220 0x00
- ub1 kcvcpetb[] @221 0x00
- ub1 kcvcpetb[] @222 0x00
- ub1 kcvcpetb[] @223 0x00
- ub4 kcvfhbhz @224 0x00000000
- struct kcvfhxcd, 16 bytes @228
- ub4 space_kcvmxcd[] @228 0x00000000
- ub4 space_kcvmxcd[] @232 0x00000000
- ub4 space_kcvmxcd[] @236 0x00000000
- ub4 space_kcvmxcd[] @240 0x00000000
- word kcvfhtsn @244 14
- ub2 kcvfhtln @248 0x0010
- text kcvfhtnm[] @250 T
- text kcvfhtnm[] @251 B
- text kcvfhtnm[] @252 S
- text kcvfhtnm[] @253 _
- text kcvfhtnm[] @254 C
- text kcvfhtnm[] @255 Q
- text kcvfhtnm[] @256 S
- text kcvfhtnm[] @257 C
- text kcvfhtnm[] @258 H
- text kcvfhtnm[] @259 E
- text kcvfhtnm[] @260 M
- text kcvfhtnm[] @261 A
- text kcvfhtnm[] @262 _
- text kcvfhtnm[] @263 U
- text kcvfhtnm[] @264 S
- text kcvfhtnm[] @265 E
- text kcvfhtnm[] @266
- text kcvfhtnm[] @267
- text kcvfhtnm[] @268
- text kcvfhtnm[] @269
- text kcvfhtnm[] @270
- text kcvfhtnm[] @271
- text kcvfhtnm[] @272
- text kcvfhtnm[] @273
- text kcvfhtnm[] @274
- text kcvfhtnm[] @275
- text kcvfhtnm[] @276
- text kcvfhtnm[] @277
- text kcvfhtnm[] @278
- text kcvfhtnm[] @279
- ub4 kcvfhrfn @280 0x00000013
- struct kcvfhrfs, 8 bytes @284
- ub4 kscnbas @284 0x00000000
- ub2 kscnwrp @288 0x0000
- ub4 kcvfhrft @292 0x3128ac64
- struct kcvfhafs, 8 bytes @296
- ub4 kscnbas @296 0x00000000
- ub2 kscnwrp @300 0x0000
- ub4 kcvfhbbc @304 0x00000000
- ub4 kcvfhncb @308 0x00000000
- ub4 kcvfhmcb @312 0x00000000
- ub4 kcvfhlcb @316 0x00000000
- ub4 kcvfhbcs @320 0x00000000
- ub2 kcvfhofb @324 0x0000
- ub2 kcvfhnfb @326 0x0000
- ub4 kcvfhprc @328 0x00000000
- struct kcvfhprs, 8 bytes @332
- ub4 kscnbas @332 0x00000000
- ub2 kscnwrp @336 0x0000
- struct kcvfhprfs, 8 bytes @340
- ub4 kscnbas @340 0x00000000
- ub2 kscnwrp @344 0x0000
- ub4 kcvfhtrt @356 0x00000000
此处简单的解释一下,以上信息就是数据文件头部第一个block的信息,这360个字节存储了数据文件至关重要的一些信息,如32到第39共8个字节存储的是实例名(9i最大支持8个字符?),第250-279字节存储的是表空间名,可见是30个字节,的确,9i的表空间名最大只支持30个字符。以下是关键信息:
- ub4 kscnbas @140 0x19cdab15(432909077)
- ub4 kcvcptim @148 0x3128df56
- ub4 kcvfhcpc @176 0x000000bf
- ub4 kcvfhccc @184 0x000000be
当open的时候,smon会检查数据文件的以上信息是否和控制文件中的一致,如果不一致,这个文件就需要恢复,实际上一方面恢复数据,如撤销或者重做事务;一方面一致文件头等,否则这个文件就进入recover状态无法读取也无法open。我下面要做的就是手动修改这些字节区间的数据,将其同步,骗过smon进程打开文件。
对比损坏文件的头信息:
- ub4 kscnbas @140 0x19cd6ff6--
- ub4 kcvcptim @148 0x31289e91
- ub4 kcvfhcpc @176 0x00000381
- ub4 kcvfhccc @184 0x00000380
修改之前,我需要确认正常的文件中,数据是如何存储的:
- d /v dba 14,1 offset 140 count 16
- File: D:\oracle\oradata\DS_THCQ\TBS_CQSCHEMA_USE_06.DBF (14)
- Block: 1 Offsets: 140 to 155 Dba:0x03800001
- -------------------------------------------------------
- 15abcd19 00000000 56df2831 01000000 l ........V.(1....
- <16 bytes per line>
由此可看出,在140个偏移处,scn其实是0x19cdab15,但是存储居然是15abcd19 ,看到不同了吗?是反向存储的(因为低位的字节存储在内存中的低地址处),注意15abcd19 是16进制,一位4bit,2位代表一个字节,共存储4个字节。同样可以看出,oracle中的scn的最大值是ffffffffffff,大小正好是6字节,48个bit,后面的2字节没有用到可能是留着扩展吧?很有趣吧?这就是oracle的最低层的存储结构啦。
下面进行修改:
- BBED> modify /x 15abcd19 dba 14,1 offset 140
- File: D:\oracle\oradata\DS_THCQ\TBS_CQSCHEMA_USE_02.DBF (14)
- Block: 1 Offsets: 140 to 651 Dba:0x03800001
- ------------------------------------------------------------------------
- 15abcd19 00000000 919e2831 01000000 03000000 02000000 1000545f 02000000
- 00000000 81030000 5b942831 80030000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 0e000000 10005442 535f4351 53434845 4d415f55 53450000
- 00000000 00000000 00000000 0e000000 00000000 00000000 00000000 00000000
- 0000505f 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- <32 bytes per line>
- BBED> modify /x 56df2831 dba 14,1 offset 148
- File: D:\oracle\oradata\DS_THCQ\TBS_CQSCHEMA_USE_02.DBF (14)
- Block: 1 Offsets: 148 to 659 Dba:0x03800001
- ------------------------------------------------------------------------
- 56df2831 01000000 03000000 02000000 1000545f 02000000 00000000 81030000
- 5b942831 80030000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 0e000000 10005442 535f4351 53434845 4d415f55 53450000 00000000 00000000
- 00000000 0e000000 00000000 00000000 00000000 00000000 0000505f 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- <32 bytes per line>
- BBED> modify /x bf dba 14,1 offset 176
- File: D:\oracle\oradata\DS_THCQ\TBS_CQSCHEMA_USE_02.DBF (14)
- Block: 1 Offsets: 176 to 687 Dba:0x03800001
- ------------------------------------------------------------------------
- bf030000 5b942831 80030000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 0e000000 10005442 535f4351 53434845 4d415f55 53450000 00000000
- 00000000 00000000 0e000000 00000000 00000000 00000000 00000000 0000505f
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- <32 bytes per line>
- BBED> modify /x b3 dba 14,1 offset 184
- File: D:\oracle\oradata\DS_THCQ\TBS_CQSCHEMA_USE_02.DBF (14)
- Block: 1 Offsets: 184 to 695 Dba:0x03800001
- ------------------------------------------------------------------------
- b3030000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0e000000
- 10005442 535f4351 53434845 4d415f55 53450000 00000000 00000000 00000000
- 0e000000 00000000 00000000 00000000 00000000 0000505f 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- <32 bytes per line>
修改完成后保存校验一下,然后打开库:
- SQL> shu immediate
- 数据库已经关闭。
- 已经卸载数据库。
- ORACLE 例程已经关闭。
- SQL> startup mount
- ORACLE 例程已经启动。
- Total System Global Area 1368466872 bytes
- Fixed Size 456120 bytes
- Variable Size 713031680 bytes
- Database Buffers 654311424 bytes
- Redo Buffers 667648 bytes
- 数据库装载完毕。
- SQL> alter database datafile 14 online;
- 数据库已更改。
- SQL> alter database open;
- alter database open
- *
- ERROR 位于第 1 行:
- ORA-01122: 数据库文件 14 验证失败
- ORA-01110: 数据文件 14: 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_02.DBF'
- ORA-01207: 文件比控制文件更新 - 旧的控制文件
由于14号文件一直无法online,所以控制文件中的检查点是旧的,smon此时发现这个数据文件太超前了 ,也不能打开,分析后决定重建控制文件。重建后无需recover,直接open即可:
- SQL> shu abort
- ORACLE 例程已经关闭。
- SQL> startup nomount;
- ORACLE 例程已经启动。
- Total System Global Area 1368466872 bytes
- Fixed Size 456120 bytes
- Variable Size 713031680 bytes
- Database Buffers 654311424 bytes
- Redo Buffers 667648 bytes
- SQL> CREATE CONTROLFILE REUSE DATABASE "DS_THCQ" NORESETLOGS
- 2 -- SET STANDBY TO MAXIMIZE PERFORMANCE
- 3 MAXLOGFILES 50
- 4 MAXLOGMEMBERS 5
- 5 MAXDATAFILES 100
- 6 MAXINSTANCES 1
- 7 MAXLOGHISTORY 453
- 8 LOGFILE
- 9 GROUP 1 'D:\ORACLE\ORADATA\DS_THCQ\REDO01.LOG' SIZE
- 10 GROUP 2 'D:\ORACLE\ORADATA\DS_THCQ\REDO02.LOG' SIZE
- 11 GROUP 3 'D:\ORACLE\ORADATA\DS_THCQ\REDO03.LOG' SIZE
- 12 -- STANDBY LOGFILE
- 13 DATAFILE
- 14 'D:\ORACLE\ORADATA\DS_THCQ\SYSTEM01.DBF',
- 15 'D:\ORACLE\ORADATA\DS_THCQ\UNDOTBS01.DBF',
- 16 'D:\ORACLE\ORADATA\DS_THCQ\CWMLITE01.DBF',
- 17 'D:\ORACLE\ORADATA\DS_THCQ\DRSYS01.DBF',
- 18 'D:\ORACLE\ORADATA\DS_THCQ\EXAMPLE01.DBF',
- 19 'D:\ORACLE\ORADATA\DS_THCQ\INDX01.DBF',
- 20 'D:\ORACLE\ORADATA\DS_THCQ\ODM01.DBF',
- 21 'D:\ORACLE\ORADATA\DS_THCQ\TOOLS01.DBF',
- 22 'D:\ORACLE\ORADATA\DS_THCQ\USERS01.DBF',
- 23 'D:\ORACLE\ORADATA\DS_THCQ\XDB01.DBF',
- 24 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQMODEL.ORA',
- 25 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_01.DBF',
- 26 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_01.DBF',
- 27 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_02.DBF',
- 28 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_03.DBF',
- 29 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_04.DBF',
- 30 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_05.DBF',
- 31 'D:\ORACLE\ORADATA\DS_THCQ\TBS_STATS.DBF',
- 32 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_06.DBF',
- 33 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_08.DBF'
- 34 CHARACTER SET ZHS16GBK
- 35 ;
- 控制文件已创建
- SQL> RECOVER DATABASE
- ORA-00283: ??????????
- ORA-00264: ?????
- SQL> alter database open;
- 数据库已更改。
由此也看出,oracle的数据文件其实没什么神秘的,也不过是按照自己的规则存储的一些二进制数据,而且都是明文未加密的。
1号块供8KB的空间可以存储很多数据,了解了1号块的数据结构后,通过修改诸如实例名,表空间名、数据头等信息,可以将任何一个库的任何一个时期的任何文件挂到其他的库上打开,说不定还能读出数据。oracle的sga其实就是一个大的阅读器而已。
其实这和外部表是很相似的,外部表其实就是没有data header的数据文件而已,oracle在读之前并不判断该文件是否有效合法,以高度容错性的方法去读取;而标准的dbf文件则不是,Oracle读取之前要经过严格的校验和检查,有一点不对的地方都认为它是损坏的。而通过对header进行修复甚至伪造即可以骗过oracle去读取。
所以,其实能允许一定的数据丢失的话,其实没有备份也是可以将数据文件一致并打开的,这可以用于数据库无备份时的灾难恢复抢救数据,如本案例。
而且如直接修改数据,修复坏块,撤销删除的数据等,包括本案例直接修改文件头等块级操作都可以实现,如果熟悉oracle底层存储结构的话自己写程序修改都不是难事。
【原创】CQ数据库损坏修复的更多相关文章
- Sql server Compact 小型数据库损坏修复
之前碰到过小型数据库损坏打不开的问题,一直没有理会,今天生产上客户本地小库产生这样的问题,已经修复 SqlCeEngine engine = new SqlCeEngine(" ...
- SQL Server数据库损坏、检测以及简单的修复办法
简介 在一个理想的世界中,不会存在任何数据库的损坏,就像我们不会将一些严重意外情况列入我们生活中的日常一样,而一旦这类事情发生,一定会对我们的生活造成非常显著的影响,在SQL Server中也 ...
- sql2005数据库置疑修复断电崩溃索引损坏 数据库索引错误修复/数据库表损坏/索引损坏/系统表混乱等问题修复
sql2005数据库置疑修复断电崩溃索引损坏 数据库索引错误修复/数据库表损坏/索引损坏/系统表混乱等问题修复 客 户 名 称 济南某电子商务公司 数 据 类 型 SQL2005数据库 故 障 检 测 ...
- 思迅/泰格/科脉/收银软件/商超软件数据库修复解决断电造成损坏的mdb\dat文件SQL数据库 置疑 修复 恢复
拥有专业管理软件数据库修复技术工程师,专业提供管家婆.美萍.思迅.科脉等管理软件技术服务,电脑维修\重装系统技 术服务.无法登陆打不开等出错问题处理(连接失败,请输入正确的服务器名,SQL Serve ...
- 讨论SQLite数据库损坏与修复
版权声明:博客将逐步迁移到 http://cwqqq.com https://blog.csdn.net/cwqcwk1/article/details/45541409 昨晚,朋友和我反馈SQL ...
- MySQL数据库INNODB 表损坏修复处理过程
MySQL数据库INNODB 表损坏修复处理过程 博客分类: mysql tomcatmysql 最近mysql数据库经常死掉,用命令net stop mysql命令也无法停掉,关闭Tomcat的时 ...
- SQLite数据库损坏及其修复探究
数据库如何发生损坏 SQLite 数据库具有很强的抗损坏能力.在执行事务时如果发生应用程序崩溃.操作系统崩溃甚至电源故障,那么在下次访问数据库文件时,会自动回滚部分写入的事务.恢复过程是全自动的, ...
- 运维案例 | Exchange2010数据库损坏的紧急修复思路
关注嘉为科技,获取运维新知 Exchange后端数据库故障,一般都会是比较严重的紧急故障,因为这会直接影响到大面积用户的正常使用,而且涉及到用户数据.一旦遇到这种级别的故障,管理员往往都是在非常紧 ...
- SQL Server 损坏修复
目录: 一. 常见错误解读 二. DBCC CHECKDB 三 .不同部位损坏的应对 四. Database Mirroring和AlwaysOn的页面自动修复功能 一 常见错误解读 SQL Serv ...
随机推荐
- Response.Redirect 打开新窗体的两种方法
普通情况下,Response.Redirect 方法是在server端进行转向,因此,除非使用 Response.Write("<script>window.location=' ...
- Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+树状数组
C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...
- 在android market发布个人免费应用的步骤
写了一段时间的android应用了,只是在自己手机上面安装. 上周申请了android developer,需要一次性25美元的程序开发注册费用.费用需要用google checkout,所以还要先申 ...
- ios开发——错误总结篇&开发中常见错误和警告总结(四)
ios开发——开发总结&开发中常见错误和警告总结(四) 网易彩票实战总结(错误) 错误总结之类的实现 经典错误之重复定义与导入错误 经典错误关于父类的实现 通知对象: 控制器的定义 Xcode ...
- C++ SFINAE
1. 什么是SFINAE 在C++中有很多的编程技巧(Trick), SFINAE就是其中一种, 他的全义可以翻译为”匹配失败并不是一个错误(Substitution failure is not a ...
- fcitx的安装_配置
sudo apt-get purger ibus 安装Fcitx:sudo apt-get install im-switch fcitx #修改当前用户的默认输入法, 具体看man im-switc ...
- 检测MYSQL不同步发邮件通知的脚本
脚本代码如下:#!/bin/bash ...
- WPF之基于路径的动画
不是突然想到要做一个路径动画的,是今天谈业务需求的时候偶然谈到的, 一艘船从一个国家到另外一个国家,沿着一条固定的路线前进,就是一个简单的动画效果,以前貌似在书上看到过,所以自己也来做一个. 在网上搜 ...
- Eclipse中配置Tomcat碰到Server Tomcat v6.0 Server at localhost failed to start问题
控制台打印异常如下: Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/juli/logg ...
- IOS 视图切换动画
我在网上找到的这个小方法,被我举一反三使用的屡试不爽.比如用在,当视图需要执行某一方法跳转到新的一个UIView上,从底层渐变浮到最上层.就是一个不错的视觉效果或者当需要类似keyboard的效果从底 ...