上周三中午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登录正常,没有数据丢失。

介质恢复失败,所以依靠备份来恢复是不可能的,

  1. RMAN> run{
  2. 2> restore datafile 14;
  3. 3> recover datafile 14;
  4. 4> sql 'alter database datafile 14 online';
  5. 5> }
  6.  
  7. 启动 restore 2013-08-29 18:42:45
  8.  
  9. 正在使用目标数据库控制文件替代恢复目录
  10. 分配的通道: ORA_DISK_1
  11. 通道 ORA_DISK_1: sid=14 devtype=DISK
  12. 通道 ORA_DISK_1: 正在开始恢复数据文件备份集
  13. 通道 ORA_DISK_1: 正在指定从备份集恢复的数据文件
  14. 正将数据文件00014恢复到D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_02.DBF
  15. 通道 ORA_DISK_1: 已恢复备份段 1
  16. handle=D:\CQ_BACKUP\DISK1\BAK_45OIH7KG_1_1 tag=TAG20130829T160016 params=NULL
  17. 通道 ORA_DISK_1: 恢复完成
  18. 完成 restore 2013-08-29 19:16:08
  19.  
  20. 启动 recover 2013-08-29 19:16:08
  21. 使用通道 ORA_DISK_1
  22.  
  23. 正在开始介质的恢复
  24. 无法恢复介质
  25. RMAN-00571: ===========================================================
  26. RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
  27. RMAN-00571: ===========================================================
  28. RMAN-03002: failure of recover command at 08/29/2013 19:16:21
  29. ORA-00283: recovery session canceled due to errors
  30. RMAN-11003: failure during parse/execution of SQL statement: alter database recover if needed
  31. datafile 14
  32. ORA-00283: 恢复会话因错误而取消
  33. ORA-01115: 从文件 14 读取块时出现 IO 错误 (块 # 502078)
  34. ORA-01110: 数据文件 14: 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_02.DBF'
  35. ORA-27069: skgfdisp: 尝试在文件范围外执行 I/O
  36. OSD-04026: 传递的参数无效。 (OS 502078)

其实此时数据文件是好的,只是介质恢复时,有对数据文件范围外的地址进行读写,导致oracle无法访问而报错,因为dbv检查并没有坏块,所以不进行介质恢复,将14号文件先restore出来:

  1. RMAN> restore datafile 14;
  2.  
  3. 启动 restore 2013-08-29 19:16:49
  4.  
  5. 使用通道 ORA_DISK_1
  6. 通道 ORA_DISK_1: 正在开始恢复数据文件备份集
  7. 通道 ORA_DISK_1: 正在指定从备份集恢复的数据文件
  8. 正将数据文件00014恢复到D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_02.DBF
  9. 通道 ORA_DISK_1: 已恢复备份段 1
  10. handle=D:\CQ_BACKUP\DISK1\BAK_45OIH7KG_1_1 tag=TAG20130829T160016 params=NULL
  11. 通道 ORA_DISK_1: 恢复完成
  12. 完成 restore 2013-08-29 19:54:21

将其offline后open,查询scn:

  1. SQL> select checkpoint_change# from v$datafile;
  2.  
  3. CHECKPOINT_CHANGE#
  4. ------------------
  5. 432908646
  6. 432908646
  7. 432908646
  8. 432908646
  9. 432908646
  10. 432908646
  11. 432908646
  12. 432908646
  13. 432908646
  14. 432908646
  15. 432908646
  16.  
  17. CHECKPOINT_CHANGE#
  18. ------------------
  19. 432908646
  20. 432908646
  21. 432893942
  22. 432908646
  23. 432908646
  24. 432908646
  25. 432908646
  26. 432908646
  27. 432908646
  28.  
  29. 已选择20行。
  30.  
  31. SQL> select change# from v$recover_file;
  32.  
  33. CHANGE#
  34. ----------
  35. 432893942

14号文件的scn为432893942,而正常文件的scn是432908646,基于前面的推测,我断定这个文件只是header不一致,数据文件并无损坏,只是对该文件进行了超出控制范围外地址的读写而已,所以想使用隐含参数直接打开库,忽略一致性检查,但是最终失败。
因此果断直接使用bbed修改数据文件头,绕过介质恢复。

首先关库,TBS_CQSCHEMA_USE_02.DBF文件(14号坏文件)的1块信息:

  1. struct kcvfh, 360 bytes @0
  2. struct kcvfhbfh, 20 bytes @0
  3. ub1 type_kcbh @0 0x0b
  4. ub1 frmt_kcbh @1 0x02
  5. ub1 spare1_kcbh @2 0x00
  6. ub1 spare2_kcbh @3 0x00
  7. ub4 rdba_kcbh @4 0x03800001
  8. ub4 bas_kcbh @8 0x00000000
  9. ub2 wrp_kcbh @12 0x0000
  10. ub1 seq_kcbh @14 0x01
  11. ub1 flg_kcbh @15 0x04 (KCBHFC
  12. ub2 chkval_kcbh @16 0x1be2
  13. ub2 spare3_kcbh @18 0x0000
  14. struct kcvfhhdr, 76 bytes @20
  15. ub4 kccfhswv @20 0x09200000
  16. ub4 kccfhcvn @24 0x08000000
  17. ub4 kccfhdbi @28 0x8a4b9dc5
  18. text kccfhdbn[] @32 D
  19. text kccfhdbn[] @33 S
  20. text kccfhdbn[] @34 _
  21. text kccfhdbn[] @35 T
  22. text kccfhdbn[] @36 H
  23. text kccfhdbn[] @37 C
  24. text kccfhdbn[] @38 Q
  25. text kccfhdbn[] @39
  26. ub4 kccfhcsq @40 0x00003061
  27. ub4 kccfhfsz @44 0x0007c000
  28. s_blkz kccfhbsz @48 0x00
  29. ub2 kccfhfno @52 0x000e
  30. ub2 kccfhtyp @54 0x0003
  31. ub4 kccfhacid @56 0x00000000
  32. ub4 kccfhcks @60 0x00000000
  33. text kccfhtag[] @64
  34. text kccfhtag[] @65
  35. text kccfhtag[] @66
  36. text kccfhtag[] @67
  37. text kccfhtag[] @68
  38. text kccfhtag[] @69
  39. text kccfhtag[] @70
  40. text kccfhtag[] @71
  41. text kccfhtag[] @72
  42. text kccfhtag[] @73
  43. text kccfhtag[] @74
  44. text kccfhtag[] @75
  45. text kccfhtag[] @76
  46. text kccfhtag[] @77
  47. text kccfhtag[] @78
  48. text kccfhtag[] @79
  49. text kccfhtag[] @80
  50. text kccfhtag[] @81
  51. text kccfhtag[] @82
  52. text kccfhtag[] @83
  53. text kccfhtag[] @84
  54. text kccfhtag[] @85
  55. text kccfhtag[] @86
  56. text kccfhtag[] @87
  57. text kccfhtag[] @88
  58. text kccfhtag[] @89
  59. text kccfhtag[] @90
  60. text kccfhtag[] @91
  61. text kccfhtag[] @92
  62. text kccfhtag[] @93
  63. text kccfhtag[] @94
  64. text kccfhtag[] @95
  65. ub4 kcvfhrdb @96 0x00000000
  66. struct kcvfhcrs, 8 bytes @100
  67. ub4 kscnbas @100 0x127c90e6
  68. ub2 kscnwrp @104 0x0000
  69. ub4 kcvfhcrt @108 0x2eb8d8e1
  70. ub4 kcvfhrlc @112 0x3128954b
  71. struct kcvfhrls, 8 bytes @116
  72. ub4 kscnbas @116 0x19cd392a
  73. ub2 kscnwrp @120 0x0000
  74. ub4 kcvfhbti @124 0x00000000
  75. struct kcvfhbsc, 8 bytes @128
  76. ub4 kscnbas @128 0x00000000
  77. ub2 kscnwrp @132 0x0000
  78. ub2 kcvfhbth @136 0x0000
  79. ub2 kcvfhsta @138 0x0000 (NONE
  80. struct kcvfhckp, 36 bytes @140
  81. struct kcvcpscn, 8 bytes @140
  82. ub4 kscnbas @140 0x19cd6ff6 --
  83. ub2 kscnwrp @144 0x0000
  84. ub4 kcvcptim @148 0x31289e91
  85. ub2 kcvcpthr @152 0x0001
  86. union u, 12 bytes @156
  87. struct kcvcprba, 12 bytes @156
  88. ub4 kcrbaseq @156 0x00000003
  89. ub4 kcrbabno @160 0x00000002
  90. ub2 kcrbabof @164 0x0010
  91. struct kcvcptr, 12 bytes @156
  92. struct kcrtrscn, 8 bytes @156
  93. ub4 kscnbas @156 0x00000003
  94. ub2 kscnwrp @160 0x0002
  95. ub4 kcrtrtim @164 0x5f540010
  96. ub1 kcvcpetb[] @168 0x02
  97. ub1 kcvcpetb[] @169 0x00
  98. ub1 kcvcpetb[] @170 0x00
  99. ub1 kcvcpetb[] @171 0x00
  100. ub1 kcvcpetb[] @172 0x00
  101. ub1 kcvcpetb[] @173 0x00
  102. ub1 kcvcpetb[] @174 0x00
  103. ub1 kcvcpetb[] @175 0x00
  104. ub4 kcvfhcpc @176 0x00000381
  105. ub4 kcvfhrts @180 0x3128945b
  106. ub4 kcvfhccc @184 0x00000380
  107. struct kcvfhbcp, 36 bytes @188
  108. struct kcvcpscn, 8 bytes @188
  109. ub4 kscnbas @188 0x00000000
  110. ub2 kscnwrp @192 0x0000
  111. ub4 kcvcptim @196 0x00000000
  112. ub2 kcvcpthr @200 0x0000
  113. union u, 12 bytes @204
  114. struct kcvcprba, 12 bytes @204
  115. ub4 kcrbaseq @204 0x00000000
  116. ub4 kcrbabno @208 0x00000000
  117. ub2 kcrbabof @212 0x0000
  118. struct kcvcptr, 12 bytes @204
  119. struct kcrtrscn, 8 bytes @204
  120. ub4 kscnbas @204 0x00000000
  121. ub2 kscnwrp @208 0x0000
  122. ub4 kcrtrtim @212 0x00000000
  123. ub1 kcvcpetb[] @216 0x00
  124. ub1 kcvcpetb[] @217 0x00
  125. ub1 kcvcpetb[] @218 0x00
  126. ub1 kcvcpetb[] @219 0x00
  127. ub1 kcvcpetb[] @220 0x00
  128. ub1 kcvcpetb[] @221 0x00
  129. ub1 kcvcpetb[] @222 0x00
  130. ub1 kcvcpetb[] @223 0x00
  131. ub4 kcvfhbhz @224 0x00000000
  132. struct kcvfhxcd, 16 bytes @228
  133. ub4 space_kcvmxcd[] @228 0x00000000
  134. ub4 space_kcvmxcd[] @232 0x00000000
  135. ub4 space_kcvmxcd[] @236 0x00000000
  136. ub4 space_kcvmxcd[] @240 0x00000000
  137. word kcvfhtsn @244 14
  138. ub2 kcvfhtln @248 0x0010
  139. text kcvfhtnm[] @250 T
  140. text kcvfhtnm[] @251 B
  141. text kcvfhtnm[] @252 S
  142. text kcvfhtnm[] @253 _
  143. text kcvfhtnm[] @254 C
  144. text kcvfhtnm[] @255 Q
  145. text kcvfhtnm[] @256 S
  146. text kcvfhtnm[] @257 C
  147. text kcvfhtnm[] @258 H
  148. text kcvfhtnm[] @259 E
  149. text kcvfhtnm[] @260 M
  150. text kcvfhtnm[] @261 A
  151. text kcvfhtnm[] @262 _
  152. text kcvfhtnm[] @263 U
  153. text kcvfhtnm[] @264 S
  154. text kcvfhtnm[] @265 E
  155. text kcvfhtnm[] @266
  156. text kcvfhtnm[] @267
  157. text kcvfhtnm[] @268
  158. text kcvfhtnm[] @269
  159. text kcvfhtnm[] @270
  160. text kcvfhtnm[] @271
  161. text kcvfhtnm[] @272
  162. text kcvfhtnm[] @273
  163. text kcvfhtnm[] @274
  164. text kcvfhtnm[] @275
  165. text kcvfhtnm[] @276
  166. text kcvfhtnm[] @277
  167. text kcvfhtnm[] @278
  168. text kcvfhtnm[] @279
  169. ub4 kcvfhrfn @280 0x0000000e
  170. struct kcvfhrfs, 8 bytes @284
  171. ub4 kscnbas @284 0x00000000
  172. ub2 kscnwrp @288 0x0000
  173. ub4 kcvfhrft @292 0x00000000
  174. struct kcvfhafs, 8 bytes @296
  175. ub4 kscnbas @296 0x00000000
  176. ub2 kscnwrp @300 0x0000
  177. ub4 kcvfhbbc @304 0x00000000
  178. ub4 kcvfhncb @308 0x00000000
  179. ub4 kcvfhmcb @312 0x00000000
  180. ub4 kcvfhlcb @316 0x00000000
  181. ub4 kcvfhbcs @320 0x00000000
  182. ub2 kcvfhofb @324 0x0000
  183. ub2 kcvfhnfb @326 0x0000
  184. ub4 kcvfhprc @328 0x00000000
  185. struct kcvfhprs, 8 bytes @332
  186. ub4 kscnbas @332 0x00000000
  187. ub2 kscnwrp @336 0x0000
  188. struct kcvfhprfs, 8 bytes @340
  189. ub4 kscnbas @340 0x00000000
  190. ub2 kscnwrp @344 0x0000
  191. ub4 kcvfhtrt @356 0x00000000

找一个好的数据文件,同样print一下:

  1. struct kcvfh, 360 bytes @0
  2. struct kcvfhbfh, 20 bytes @0
  3. ub1 type_kcbh @0 0x0b
  4. ub1 frmt_kcbh @1 0x02
  5. ub1 spare1_kcbh @2 0x00
  6. ub1 spare2_kcbh @3 0x00
  7. ub4 rdba_kcbh @4 0x04c00001
  8. ub4 bas_kcbh @8 0x00000000
  9. ub2 wrp_kcbh @12 0x0000
  10. ub1 seq_kcbh @14 0x01
  11. ub1 flg_kcbh @15 0x04 (KCBHFCK
  12. ub2 chkval_kcbh @16 0xe33e
  13. ub2 spare3_kcbh @18 0x0000
  14. struct kcvfhhdr, 76 bytes @20
  15. ub4 kccfhswv @20 0x09200000
  16. ub4 kccfhcvn @24 0x08000000
  17. ub4 kccfhdbi @28 0x8a4b9dc5
  18. text kccfhdbn[] @32 D
  19. text kccfhdbn[] @33 S
  20. text kccfhdbn[] @34 _
  21. text kccfhdbn[] @35 T
  22. text kccfhdbn[] @36 H
  23. text kccfhdbn[] @37 C
  24. text kccfhdbn[] @38 Q
  25. text kccfhdbn[] @39
  26. ub4 kccfhcsq @40 0x00003134
  27. ub4 kccfhfsz @44 0x0000fa00
  28. s_blkz kccfhbsz @48 0x00
  29. ub2 kccfhfno @52 0x0013
  30. ub2 kccfhtyp @54 0x0003
  31. ub4 kccfhacid @56 0x00000000
  32. ub4 kccfhcks @60 0x00000000
  33. text kccfhtag[] @64
  34. text kccfhtag[] @65
  35. text kccfhtag[] @66
  36. text kccfhtag[] @67
  37. text kccfhtag[] @68
  38. text kccfhtag[] @69
  39. text kccfhtag[] @70
  40. text kccfhtag[] @71
  41. text kccfhtag[] @72
  42. text kccfhtag[] @73
  43. text kccfhtag[] @74
  44. text kccfhtag[] @75
  45. text kccfhtag[] @76
  46. text kccfhtag[] @77
  47. text kccfhtag[] @78
  48. text kccfhtag[] @79
  49. text kccfhtag[] @80
  50. text kccfhtag[] @81
  51. text kccfhtag[] @82
  52. text kccfhtag[] @83
  53. text kccfhtag[] @84
  54. text kccfhtag[] @85
  55. text kccfhtag[] @86
  56. text kccfhtag[] @87
  57. text kccfhtag[] @88
  58. text kccfhtag[] @89
  59. text kccfhtag[] @90
  60. text kccfhtag[] @91
  61. text kccfhtag[] @92
  62. text kccfhtag[] @93
  63. text kccfhtag[] @94
  64. text kccfhtag[] @95
  65. ub4 kcvfhrdb @96 0x00000000
  66. struct kcvfhcrs, 8 bytes @100
  67. ub4 kscnbas @100 0x19504563
  68. ub2 kscnwrp @104 0x0000
  69. ub4 kcvfhcrt @108 0x30f78f0e
  70. ub4 kcvfhrlc @112 0x3128954b
  71. struct kcvfhrls, 8 bytes @116
  72. ub4 kscnbas @116 0x19cd392a
  73. ub2 kscnwrp @120 0x0000
  74. ub4 kcvfhbti @124 0x00000000
  75. struct kcvfhbsc, 8 bytes @128
  76. ub4 kscnbas @128 0x00000000
  77. ub2 kscnwrp @132 0x0000
  78. ub2 kcvfhbth @136 0x0000
  79. ub2 kcvfhsta @138 0x0000 (NONE)
  80. struct kcvfhckp, 36 bytes @140
  81. struct kcvcpscn, 8 bytes @140
  82. ub4 kscnbas @140 0x19cda316
  83. ub2 kscnwrp @144 0x0000
  84. ub4 kcvcptim @148 0x3128c136
  85. ub2 kcvcpthr @152 0x0001
  86. union u, 12 bytes @156
  87. struct kcvcprba, 12 bytes @156
  88. ub4 kcrbaseq @156 0x00000004
  89. ub4 kcrbabno @160 0x000020b9
  90. ub2 kcrbabof @164 0x0010
  91. struct kcvcptr, 12 bytes @156
  92. struct kcrtrscn, 8 bytes @156
  93. ub4 kscnbas @156 0x00000004
  94. ub2 kscnwrp @160 0x20b9
  95. ub4 kcrtrtim @164 0x03970010
  96. ub1 kcvcpetb[] @168 0x02
  97. ub1 kcvcpetb[] @169 0x00
  98. ub1 kcvcpetb[] @170 0x00
  99. ub1 kcvcpetb[] @171 0x00
  100. ub1 kcvcpetb[] @172 0x00
  101. ub1 kcvcpetb[] @173 0x00
  102. ub1 kcvcpetb[] @174 0x00
  103. ub1 kcvcpetb[] @175 0x00
  104. ub4 kcvfhcpc @176 0x000000bb
  105. ub4 kcvfhrts @180 0x3128b5d6
  106. ub4 kcvfhccc @184 0x000000ba
  107. struct kcvfhbcp, 36 bytes @188
  108. struct kcvcpscn, 8 bytes @188
  109. ub4 kscnbas @188 0x00000000
  110. ub2 kscnwrp @192 0x0000
  111. ub4 kcvcptim @196 0x00000000
  112. ub2 kcvcpthr @200 0x0000
  113. union u, 12 bytes @204
  114. struct kcvcprba, 12 bytes @204
  115. ub4 kcrbaseq @204 0x00000000
  116. ub4 kcrbabno @208 0x00000000
  117. ub2 kcrbabof @212 0x0000
  118. struct kcvcptr, 12 bytes @204
  119. struct kcrtrscn, 8 bytes @204
  120. ub4 kscnbas @204 0x00000000
  121. ub2 kscnwrp @208 0x0000
  122. ub4 kcrtrtim @212 0x00000000
  123. ub1 kcvcpetb[] @216 0x00
  124. ub1 kcvcpetb[] @217 0x00
  125. ub1 kcvcpetb[] @218 0x00
  126. ub1 kcvcpetb[] @219 0x00
  127. ub1 kcvcpetb[] @220 0x00
  128. ub1 kcvcpetb[] @221 0x00
  129. ub1 kcvcpetb[] @222 0x00
  130. ub1 kcvcpetb[] @223 0x00
  131. ub4 kcvfhbhz @224 0x00000000
  132. struct kcvfhxcd, 16 bytes @228
  133. ub4 space_kcvmxcd[] @228 0x00000000
  134. ub4 space_kcvmxcd[] @232 0x00000000
  135. ub4 space_kcvmxcd[] @236 0x00000000
  136. ub4 space_kcvmxcd[] @240 0x00000000
  137. word kcvfhtsn @244 14
  138. ub2 kcvfhtln @248 0x0010
  139. text kcvfhtnm[] @250 T
  140. text kcvfhtnm[] @251 B
  141. text kcvfhtnm[] @252 S
  142. text kcvfhtnm[] @253 _
  143. text kcvfhtnm[] @254 C
  144. text kcvfhtnm[] @255 Q
  145. text kcvfhtnm[] @256 S
  146. text kcvfhtnm[] @257 C
  147. text kcvfhtnm[] @258 H
  148. text kcvfhtnm[] @259 E
  149. text kcvfhtnm[] @260 M
  150. text kcvfhtnm[] @261 A
  151. text kcvfhtnm[] @262 _
  152. text kcvfhtnm[] @263 U
  153. text kcvfhtnm[] @264 S
  154. text kcvfhtnm[] @265 E
  155. text kcvfhtnm[] @266
  156. text kcvfhtnm[] @267
  157. text kcvfhtnm[] @268
  158. text kcvfhtnm[] @269
  159. text kcvfhtnm[] @270
  160. text kcvfhtnm[] @271
  161. text kcvfhtnm[] @272
  162. text kcvfhtnm[] @273
  163. text kcvfhtnm[] @274
  164. text kcvfhtnm[] @275
  165. text kcvfhtnm[] @276
  166. text kcvfhtnm[] @277
  167. text kcvfhtnm[] @278
  168. text kcvfhtnm[] @279
  169. ub4 kcvfhrfn @280 0x00000013
  170. struct kcvfhrfs, 8 bytes @284
  171. ub4 kscnbas @284 0x00000000
  172. ub2 kscnwrp @288 0x0000
  173. ub4 kcvfhrft @292 0x3128ac64
  174. struct kcvfhafs, 8 bytes @296
  175. ub4 kscnbas @296 0x00000000
  176. ub2 kscnwrp @300 0x0000
  177. ub4 kcvfhbbc @304 0x00000000
  178. ub4 kcvfhncb @308 0x00000000
  179. ub4 kcvfhmcb @312 0x00000000
  180. ub4 kcvfhlcb @316 0x00000000
  181. ub4 kcvfhbcs @320 0x00000000
  182. ub2 kcvfhofb @324 0x0000
  183. ub2 kcvfhnfb @326 0x0000
  184. ub4 kcvfhprc @328 0x00000000
  185. struct kcvfhprs, 8 bytes @332
  186. ub4 kscnbas @332 0x00000000
  187. ub2 kscnwrp @336 0x0000
  188. struct kcvfhprfs, 8 bytes @340
  189. ub4 kscnbas @340 0x00000000
  190. ub2 kscnwrp @344 0x0000
  191. ub4 kcvfhtrt @356 0x00000000

此处简单的解释一下,以上信息就是数据文件头部第一个block的信息,这360个字节存储了数据文件至关重要的一些信息,如32到第39共8个字节存储的是实例名(9i最大支持8个字符?),第250-279字节存储的是表空间名,可见是30个字节,的确,9i的表空间名最大只支持30个字符。以下是关键信息:

  1. ub4 kscnbas @140 0x19cdab15432909077
  2. ub4 kcvcptim @148 0x3128df56
  3. ub4 kcvfhcpc @176 0x000000bf
  4. ub4 kcvfhccc @184 0x000000be

当open的时候,smon会检查数据文件的以上信息是否和控制文件中的一致,如果不一致,这个文件就需要恢复,实际上一方面恢复数据,如撤销或者重做事务;一方面一致文件头等,否则这个文件就进入recover状态无法读取也无法open。我下面要做的就是手动修改这些字节区间的数据,将其同步,骗过smon进程打开文件。
对比损坏文件的头信息:

  1. ub4 kscnbas @140 0x19cd6ff6--
  2. ub4 kcvcptim @148 0x31289e91
  3. ub4 kcvfhcpc @176 0x00000381
  4. ub4 kcvfhccc @184 0x00000380

修改之前,我需要确认正常的文件中,数据是如何存储的:

  1. d /v dba 14,1 offset 140 count 16
  2. File: D:\oracle\oradata\DS_THCQ\TBS_CQSCHEMA_USE_06.DBF (14)
  3. Block: 1 Offsets: 140 to 155 Dba:0x03800001
  4. -------------------------------------------------------
  5. 15abcd19 00000000 56df2831 01000000 l ........V.(1....
  6.  
  7. <16 bytes per line>

由此可看出,在140个偏移处,scn其实是0x19cdab15,但是存储居然是15abcd19 ,看到不同了吗?是反向存储的(因为低位的字节存储在内存中的低地址处),注意15abcd19 是16进制,一位4bit,2位代表一个字节,共存储4个字节。同样可以看出,oracle中的scn的最大值是ffffffffffff,大小正好是6字节,48个bit,后面的2字节没有用到可能是留着扩展吧?很有趣吧?这就是oracle的最低层的存储结构啦。

下面进行修改:

  1. BBED> modify /x 15abcd19 dba 14,1 offset 140
  2. File: D:\oracle\oradata\DS_THCQ\TBS_CQSCHEMA_USE_02.DBF (14)
  3. Block: 1 Offsets: 140 to 651 Dba:0x03800001
  4. ------------------------------------------------------------------------
  5. 15abcd19 00000000 919e2831 01000000 03000000 02000000 1000545f 02000000
  6. 00000000 81030000 5b942831 80030000 00000000 00000000 00000000 00000000
  7. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  8. 00000000 00000000 0e000000 10005442 535f4351 53434845 4d415f55 53450000
  9. 00000000 00000000 00000000 0e000000 00000000 00000000 00000000 00000000
  10. 0000505f 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  11. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  12. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  13. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  14. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  15. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  16. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  17. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  18. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  19. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  20. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  21.  
  22. <32 bytes per line>
  23.  
  24. BBED> modify /x 56df2831 dba 14,1 offset 148
  25. File: D:\oracle\oradata\DS_THCQ\TBS_CQSCHEMA_USE_02.DBF (14)
  26. Block: 1 Offsets: 148 to 659 Dba:0x03800001
  27. ------------------------------------------------------------------------
  28. 56df2831 01000000 03000000 02000000 1000545f 02000000 00000000 81030000
  29. 5b942831 80030000 00000000 00000000 00000000 00000000 00000000 00000000
  30. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  31. 0e000000 10005442 535f4351 53434845 4d415f55 53450000 00000000 00000000
  32. 00000000 0e000000 00000000 00000000 00000000 00000000 0000505f 00000000
  33. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  34. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  35. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  36. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  37. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  38. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  39. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  40. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  41. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  42. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  43. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  44.  
  45. <32 bytes per line>
  46.  
  47. BBED> modify /x bf dba 14,1 offset 176
  48. File: D:\oracle\oradata\DS_THCQ\TBS_CQSCHEMA_USE_02.DBF (14)
  49. Block: 1 Offsets: 176 to 687 Dba:0x03800001
  50. ------------------------------------------------------------------------
  51. bf030000 5b942831 80030000 00000000 00000000 00000000 00000000 00000000
  52. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  53. 00000000 0e000000 10005442 535f4351 53434845 4d415f55 53450000 00000000
  54. 00000000 00000000 0e000000 00000000 00000000 00000000 00000000 0000505f
  55. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  56. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  57. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  58. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  59. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  60. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  61. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  62. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  63. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  64. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  65. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  66. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  67.  
  68. <32 bytes per line>
  69.  
  70. BBED> modify /x b3 dba 14,1 offset 184
  71. File: D:\oracle\oradata\DS_THCQ\TBS_CQSCHEMA_USE_02.DBF (14)
  72. Block: 1 Offsets: 184 to 695 Dba:0x03800001
  73. ------------------------------------------------------------------------
  74. b3030000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  75. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0e000000
  76. 10005442 535f4351 53434845 4d415f55 53450000 00000000 00000000 00000000
  77. 0e000000 00000000 00000000 00000000 00000000 0000505f 00000000 00000000
  78. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  79. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  80. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  81. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  82. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  83. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  84. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  85. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  86. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  87. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  88. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  89. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  90.  
  91. <32 bytes per line>

修改完成后保存校验一下,然后打开库:

  1. SQL> shu immediate
  2. 数据库已经关闭。
  3. 已经卸载数据库。
  4. ORACLE 例程已经关闭。
  5. SQL> startup mount
  6. ORACLE 例程已经启动。
  7.  
  8. Total System Global Area 1368466872 bytes
  9. Fixed Size 456120 bytes
  10. Variable Size 713031680 bytes
  11. Database Buffers 654311424 bytes
  12. Redo Buffers 667648 bytes
  13. 数据库装载完毕。
  14. SQL> alter database datafile 14 online;
  15.  
  16. 数据库已更改。
  17.  
  18. SQL> alter database open;
  19. alter database open
  20. *
  21. ERROR 位于第 1 行:
  22. ORA-01122: 数据库文件 14 验证失败
  23. ORA-01110: 数据文件 14: 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_02.DBF'
  24. ORA-01207: 文件比控制文件更新 - 旧的控制文件

由于14号文件一直无法online,所以控制文件中的检查点是旧的,smon此时发现这个数据文件太超前了 ,也不能打开,分析后决定重建控制文件。重建后无需recover,直接open即可:

  1. SQL> shu abort
  2. ORACLE 例程已经关闭。
  3. SQL> startup nomount;
  4. ORACLE 例程已经启动。
  5.  
  6. Total System Global Area 1368466872 bytes
  7. Fixed Size 456120 bytes
  8. Variable Size 713031680 bytes
  9. Database Buffers 654311424 bytes
  10. Redo Buffers 667648 bytes
  11. SQL> CREATE CONTROLFILE REUSE DATABASE "DS_THCQ" NORESETLOGS
  12. 2 -- SET STANDBY TO MAXIMIZE PERFORMANCE
  13. 3 MAXLOGFILES 50
  14. 4 MAXLOGMEMBERS 5
  15. 5 MAXDATAFILES 100
  16. 6 MAXINSTANCES 1
  17. 7 MAXLOGHISTORY 453
  18. 8 LOGFILE
  19. 9 GROUP 1 'D:\ORACLE\ORADATA\DS_THCQ\REDO01.LOG' SIZE
  20. 10 GROUP 2 'D:\ORACLE\ORADATA\DS_THCQ\REDO02.LOG' SIZE
  21. 11 GROUP 3 'D:\ORACLE\ORADATA\DS_THCQ\REDO03.LOG' SIZE
  22. 12 -- STANDBY LOGFILE
  23. 13 DATAFILE
  24. 14 'D:\ORACLE\ORADATA\DS_THCQ\SYSTEM01.DBF',
  25. 15 'D:\ORACLE\ORADATA\DS_THCQ\UNDOTBS01.DBF',
  26. 16 'D:\ORACLE\ORADATA\DS_THCQ\CWMLITE01.DBF',
  27. 17 'D:\ORACLE\ORADATA\DS_THCQ\DRSYS01.DBF',
  28. 18 'D:\ORACLE\ORADATA\DS_THCQ\EXAMPLE01.DBF',
  29. 19 'D:\ORACLE\ORADATA\DS_THCQ\INDX01.DBF',
  30. 20 'D:\ORACLE\ORADATA\DS_THCQ\ODM01.DBF',
  31. 21 'D:\ORACLE\ORADATA\DS_THCQ\TOOLS01.DBF',
  32. 22 'D:\ORACLE\ORADATA\DS_THCQ\USERS01.DBF',
  33. 23 'D:\ORACLE\ORADATA\DS_THCQ\XDB01.DBF',
  34. 24 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQMODEL.ORA',
  35. 25 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_01.DBF',
  36. 26 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_01.DBF',
  37. 27 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_02.DBF',
  38. 28 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_03.DBF',
  39. 29 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_04.DBF',
  40. 30 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_05.DBF',
  41. 31 'D:\ORACLE\ORADATA\DS_THCQ\TBS_STATS.DBF',
  42. 32 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_06.DBF',
  43. 33 'D:\ORACLE\ORADATA\DS_THCQ\TBS_CQSCHEMA_USE_08.DBF'
  44. 34 CHARACTER SET ZHS16GBK
  45. 35 ;
  46.  
  47. 控制文件已创建
  48. SQL> RECOVER DATABASE
  49. ORA-00283: ??????????
  50. ORA-00264: ?????
  51. SQL> alter database open;
  52. 数据库已更改。

由此也看出,oracle的数据文件其实没什么神秘的,也不过是按照自己的规则存储的一些二进制数据,而且都是明文未加密的。
1号块供8KB的空间可以存储很多数据,了解了1号块的数据结构后,通过修改诸如实例名,表空间名、数据头等信息,可以将任何一个库的任何一个时期的任何文件挂到其他的库上打开,说不定还能读出数据。oracle的sga其实就是一个大的阅读器而已。
其实这和外部表是很相似的,外部表其实就是没有data header的数据文件而已,oracle在读之前并不判断该文件是否有效合法,以高度容错性的方法去读取;而标准的dbf文件则不是,Oracle读取之前要经过严格的校验和检查,有一点不对的地方都认为它是损坏的。而通过对header进行修复甚至伪造即可以骗过oracle去读取。
所以,其实能允许一定的数据丢失的话,其实没有备份也是可以将数据文件一致并打开的,这可以用于数据库无备份时的灾难恢复抢救数据,如本案例。
而且如直接修改数据,修复坏块,撤销删除的数据等,包括本案例直接修改文件头等块级操作都可以实现,如果熟悉oracle底层存储结构的话自己写程序修改都不是难事。

【原创】CQ数据库损坏修复的更多相关文章

  1. Sql server Compact 小型数据库损坏修复

    之前碰到过小型数据库损坏打不开的问题,一直没有理会,今天生产上客户本地小库产生这样的问题,已经修复         SqlCeEngine engine = new SqlCeEngine(" ...

  2. SQL Server数据库损坏、检测以及简单的修复办法

    简介     在一个理想的世界中,不会存在任何数据库的损坏,就像我们不会将一些严重意外情况列入我们生活中的日常一样,而一旦这类事情发生,一定会对我们的生活造成非常显著的影响,在SQL Server中也 ...

  3. sql2005数据库置疑修复断电崩溃索引损坏 数据库索引错误修复/数据库表损坏/索引损坏/系统表混乱等问题修复

    sql2005数据库置疑修复断电崩溃索引损坏 数据库索引错误修复/数据库表损坏/索引损坏/系统表混乱等问题修复 客 户 名 称 济南某电子商务公司 数 据 类 型 SQL2005数据库 故 障 检 测 ...

  4. 思迅/泰格/科脉/收银软件/商超软件数据库修复解决断电造成损坏的mdb\dat文件SQL数据库 置疑 修复 恢复

    拥有专业管理软件数据库修复技术工程师,专业提供管家婆.美萍.思迅.科脉等管理软件技术服务,电脑维修\重装系统技 术服务.无法登陆打不开等出错问题处理(连接失败,请输入正确的服务器名,SQL Serve ...

  5. 讨论SQLite数据库损坏与修复

      版权声明:博客将逐步迁移到 http://cwqqq.com https://blog.csdn.net/cwqcwk1/article/details/45541409 昨晚,朋友和我反馈SQL ...

  6. MySQL数据库INNODB 表损坏修复处理过程

    MySQL数据库INNODB 表损坏修复处理过程 博客分类: mysql tomcatmysql  最近mysql数据库经常死掉,用命令net stop mysql命令也无法停掉,关闭Tomcat的时 ...

  7. SQLite数据库损坏及其修复探究

    数据库如何发生损坏   SQLite 数据库具有很强的抗损坏能力.在执行事务时如果发生应用程序崩溃.操作系统崩溃甚至电源故障,那么在下次访问数据库文件时,会自动回滚部分写入的事务.恢复过程是全自动的, ...

  8. 运维案例 | Exchange2010数据库损坏的紧急修复思路

    ​​关注嘉为科技,获取运维新知 Exchange后端数据库故障,一般都会是比较严重的紧急故障,因为这会直接影响到大面积用户的正常使用,而且涉及到用户数据.一旦遇到这种级别的故障,管理员往往都是在非常紧 ...

  9. SQL Server 损坏修复

    目录: 一. 常见错误解读 二. DBCC CHECKDB 三 .不同部位损坏的应对 四. Database Mirroring和AlwaysOn的页面自动修复功能 一 常见错误解读 SQL Serv ...

随机推荐

  1. Response.Redirect 打开新窗体的两种方法

    普通情况下,Response.Redirect 方法是在server端进行转向,因此,除非使用 Response.Write("<script>window.location=' ...

  2. 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 ...

  3. 在android market发布个人免费应用的步骤

    写了一段时间的android应用了,只是在自己手机上面安装. 上周申请了android developer,需要一次性25美元的程序开发注册费用.费用需要用google checkout,所以还要先申 ...

  4. ios开发——错误总结篇&开发中常见错误和警告总结(四)

    ios开发——开发总结&开发中常见错误和警告总结(四) 网易彩票实战总结(错误) 错误总结之类的实现 经典错误之重复定义与导入错误 经典错误关于父类的实现 通知对象: 控制器的定义 Xcode ...

  5. C++ SFINAE

    1. 什么是SFINAE 在C++中有很多的编程技巧(Trick), SFINAE就是其中一种, 他的全义可以翻译为”匹配失败并不是一个错误(Substitution failure is not a ...

  6. fcitx的安装_配置

    sudo apt-get purger ibus 安装Fcitx:sudo apt-get install im-switch fcitx #修改当前用户的默认输入法, 具体看man im-switc ...

  7. 检测MYSQL不同步发邮件通知的脚本

    脚本代码如下:#!/bin/bash                                                                                   ...

  8. WPF之基于路径的动画

    不是突然想到要做一个路径动画的,是今天谈业务需求的时候偶然谈到的, 一艘船从一个国家到另外一个国家,沿着一条固定的路线前进,就是一个简单的动画效果,以前貌似在书上看到过,所以自己也来做一个. 在网上搜 ...

  9. Eclipse中配置Tomcat碰到Server Tomcat v6.0 Server at localhost failed to start问题

    控制台打印异常如下: Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/juli/logg ...

  10. IOS 视图切换动画

    我在网上找到的这个小方法,被我举一反三使用的屡试不爽.比如用在,当视图需要执行某一方法跳转到新的一个UIView上,从底层渐变浮到最上层.就是一个不错的视觉效果或者当需要类似keyboard的效果从底 ...