最近遇到一个问题:本应该在页面上操作删除分区,但是有人直接关闭数据库,删除分区所属表空间的数据文件,导致数据库无法启动,报下面错: SYS >startup; ORA-01157: 无法标识/锁定数据文件 31 - 请参阅 DBWR 跟踪文件 ORA-01110: 数据文件 31: 'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCLJJYF2\TA\SIM20130701.DBF' 于是,我尝试复制另外一个数据文件过来,修改文件名,企图骗过oracle: SYS >alter database open; alter database open * ERROR at line 1: ORA-01122: 数据库文件 31 验证失败 ORA-01110: 数据文件 31: 'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCLJJYF2\TA\SIM20130701.DBF' ORA-01251: 读取了文件号 31 的未知文件标头版本 未成功!! 把文件离线后启动: SYS >alter database datafile 'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCLJJYF2\TA\SIM20130701.DBF' offline drop; Database altered. SYS >alter database open; Database altered. 尝试删除表的分区: SYS >alter table sim.sim_event drop partition p20130701 2 ; alter table sim.sim_event drop partition p20130701 * ERROR at line 1: ORA-00376: 此时无法读取文件 31 ORA-01110: 数据文件 31: 'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCLJJYF2\TA\SIM20130701.DBF' 经测试,在oracle 11.2.0.3下,模拟同样的错误环境,上面删除分区的命令是可以成功的,但是11.2.0.1和10.2.0.5都报上面那个错。 由于数据文件离线,查询sim_event表,扫描这个分区时候,页面上报了一堆错,应用系统已经无法正常使用了。所以,要么从备份中恢复,要么复制一个文件过来,修改文件头信息,与控制文件一致,把文件上线后,alter table sim.sim_event drop partition p20130701 命令或许能执行成功。由于没有归档,而且文件被彻底删除,常规恢复是不大可能了,现在暂时就采用后面的办法了。 我把文件E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCLJJYF2\TA\SIM20130630.DBF(30号文件)拷出来,传输到linux上,命名为SIM20130701.DBF,尝试用bbed修改文件头信息,使它与控制文件信息一致,这样oracle可能可以把他识别成正常的31号文件了。 动态性能视图v$datafile记录了控制文件中的文件头信息,修改时候就以这个视图为准吧: select FILE#,CREATION_CHANGE#,CREATION_TIME,TS#,RFILE#,CHECKPOINT_CHANGE#,CHECKPOINT_TIME,LAST_CHANGE#,LAST_TIME,NAME from v$datafile where file# in (30,31); FILE# CREATION_CHANGE# CREATION_TIME TS# RFILE# CHECKPOINT_CHANGE# CHECKPOINT_TIME LAST_CHANGE# LAST_TIME NAME ---------- ---------------- ------------- ---------- ---------- ------------------ --------------- ------------ ------------ -------------------------------------------------------------- 30 6009133 2013/6/27 0:0 34 30 6331996 2013/7/2 20:03: 6331996 2013/7/2 20 E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCLJJYF2\TA\SIM20130630.DBF 31 6064427 2013/6/28 0:0 35 31 6329590 2013/7/2 18:12: 6329590 2013/7/2 18 E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCLJJYF2\TA\SIM20130701.DBF oracle[~/mysql/bbed]$cat sim.bbd blocksize=8192 listfile=file.lst mode=edit oracle[~/mysql/bbed]$cat file.lst 31 /u01/mysql/bbed/SIM20130710.DBF oracle[~/mysql/bbed]$bbed parfile=sim.bbd BBED> map File: /u01/mysql/bbed/SIM20130701.DBF (31) Block: 1 Dba:0x07c00001 ------------------------------------------------------------ Data File Header struct kcvfh, 860 bytes @0 ub4 tailchk @8188 BBED> p kcvfh --省略不重要的东西 struct kcvfh, 860 bytes @0 struct kcvfhbfh, 20 bytes @0 ………………………………………………………………………………………………………………………………………… ub4 rdba_kcbh @4 0x07800001 --》block_address ub4 bas_kcbh @8 0x00000000 ub2 wrp_kcbh @12 0x0000 ub1 seq_kcbh @14 0x01 ub1 flg_kcbh @15 0x04 (KCBHFCKV) ub2 chkval_kcbh @16 0xaed2 ub2 spare3_kcbh @18 0x0000 struct kcvfhhdr, 76 bytes @20 ub4 kccfhswv @20 0x00000000 ub4 kccfhcvn @24 0x0a200300 ub4 kccfhdbi @28 0x67c747a9 text kccfhdbn[0] @32 O text kccfhdbn[1] @33 R text kccfhdbn[2] @34 C text kccfhdbn[3] @35 L text kccfhdbn[4] @36 J text kccfhdbn[5] @37 J text kccfhdbn[6] @38 Y text kccfhdbn[7] @39 F ub4 kccfhcsq @40 0x00000eac ub4 kccfhfsz @44 0x00000900 s_blkz kccfhbsz @48 0x00 ub2 kccfhfno @52 0x001e --》文件号 ………………………………………………………………………………………………………………………… ub4 kcvfhrdb @96 0x00000000 struct kcvfhcrs, 8 bytes @100 ub4 kscnbas @100 0x005bb12d --》文件创建时间的scn ub2 kscnwrp @104 0x0000 ub4 kcvfhcrt @108 0x30d35d89 --》文件创建时间 ub4 kcvfhrlc @112 0x2ffac6ab struct kcvfhrls, 8 bytes @116 ub4 kscnbas @116 0x00093009 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 @484 struct kcvcpscn, 8 bytes @484 ub4 kscnbas @484 0x00609e5c --》最后一次检查点的scn ub2 kscnwrp @488 0x0000 ub4 kcvcptim @492 0x30dc6079 --》最后一次检查点时间 ub2 kcvcpthr @496 0x0001 union u, 12 bytes @500 struct kcvcprba, 12 bytes @500 ub4 kcrbaseq @500 0x00000082 ub4 kcrbabno @504 0x00013bd8 ub2 kcrbabof @508 0x0010 ub4 kcvfhcpc @140 0x0000001d --》检查点计数 ub4 kcvfhrts @144 0x30d5e278 ub4 kcvfhccc @148 0x0000001c --》比检查点计数少1 ……………………………………………………………………………………………………………………………………… sword kcvfhtsn @332 34 --》表空间号 ub2 kcvfhtln @336 0x000b text kcvfhtnm[0] @338 S text kcvfhtnm[1] @339 I text kcvfhtnm[2] @340 M text kcvfhtnm[3] @341 2 text kcvfhtnm[4] @342 0 text kcvfhtnm[5] @343 1 text kcvfhtnm[6] @344 3 text kcvfhtnm[7] @345 0 text kcvfhtnm[8] @346 6 text kcvfhtnm[9] @347 3 text kcvfhtnm[10] @348 0 --》表空间名 ……………………………………………………………………………………………………………………………………… ub4 kcvfhrfn @368 0x0000001e --》相对文件号 struct kcvfhrfs, 8 bytes @372 ub4 kscnbas @372 0x00000000 ub2 kscnwrp @376 0x0000 ub4 kcvfhrft @380 0x00000000 struct kcvfhafs, 8 bytes @384 ub4 kscnbas @384 0x00000000 ub2 kscnwrp @388 0x0000 ub4 kcvfhbbc @392 0x00000000 ub4 kcvfhncb @396 0x00000000 ub4 kcvfhmcb @400 0x00000000 ub4 kcvfhlcb @404 0x00000000 ub4 kcvfhbcs @408 0x00000000 ub2 kcvfhofb @412 0x0000 ub2 kcvfhnfb @414 0x0000 ub4 kcvfhprc @416 0x2790538b struct kcvfhprs, 8 bytes @420 ub4 kscnbas @420 0x00000001 ub2 kscnwrp @424 0x0000 struct kcvfhprfs, 8 bytes @428 需要修改的信息包括: 1. ub4 rdba_kcbh @4 0x07800001 --》data block address 2. ub2 kccfhfno @52 0x001e --》文件号 3. ub4 kcvfhrfn @368 0x0000001e --》相对文件号 4. sword kcvfhtsn @332 34 --》表空间号 5.表空间名字,修改为sim20120701(16进制ASCII编码) --》表空间名字 6. ub4 kscnbas @100 0x005bb12d --》文件创建时间的scn 7. ub4 kscnbas @484 0x00609e5c --》最后一次检查点的scn 8. ub4 kcvfhcpc @140 0x0000001d --》检查点计数 9.ub4 kcvfhccc @148 0x0000001c --》比检查点计数少1 10. ub4 kcvcptim @492 0x30dc6079 --》最后一次检查点时间 11. ub4 kcvfhcrt @108 0x30d35d89 --》文件创建时间 开始: 1. ub4 rdba_kcbh @4 0x07800001 --》data block address,修改为第31号文件第1个块0x07c00001(linux和windows都是小端字节序) BBED> set offset 4 BBED> dump File: /u01/mysql/bbed/SIM20130701.DBF (31) Block: 1 Offsets: 4 to 515 Dba:0x07c00001 ------------------------------------------------------------------------ 01008007 00000000 00000104 d2ae0000 00000000 0003200a a947c767 4f52434c BBED> modify /x 0100c0 2. ub2 kccfhfno @52 0x001e --》文件号,修改为31,即0x001f BBED> set offset 368 OFFSET 368 BBED> modify /x 1f Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y 3. ub4 kcvfhrfn @368 0x0000001e --》相对文件号,修改为31,即0x0000001f BBED> set offset 52 OFFSET 52 kccfhfno 1e000300-->> BBED> modify /x 1f Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y 4. sword kcvfhtsn @332 34 --》表空间号,修改为35,即0x00000023 BBED> set offset 332 BBED> modify /x 23 5.修改表空间名字,修改为sim20120701(16进制ASCII编码) --》修改表空间名字 text kcvfhtnm[0] @338 S text kcvfhtnm[1] @339 I text kcvfhtnm[2] @340 M text kcvfhtnm[3] @341 2 text kcvfhtnm[4] @342 0 text kcvfhtnm[5] @343 1 text kcvfhtnm[6] @344 3 text kcvfhtnm[7] @345 0 text kcvfhtnm[8] @346 6 text kcvfhtnm[9] @347 3 text kcvfhtnm[10] @348 0 BBED> set offset 346 BBED> modify /x 37 BBED> set offset 347 BBED> modify 30 BBED> set offset 348 BBED> modify /x 31 6. ub4 kscnbas @100 0x005bb12d --》文件创建时间的scn,修改为0x005C892B BBED> set offset 100 BBED> modify /x 2b895c 7. ub4 kscnbas @484 0x00609e5c --》最后一次检查点的scn,修改为6329590,即0x006094F6 BBED> set offset 484 BBED> modify /x f69460 由于v$datafile没有记录数据文件的cnt,可以转储控制文件观察; SYS >alter session set events 'immediate trace name CONTROLF level 8'; Session altered. DATA FILE #30: (name #5) E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCLJJYF2\TA\SIM20130630.DBF creation size=0 block size=8192 status=0xe head=5 tail=5 dup=1 tablespace 34, index=20 krfil=30 prev_file=0 unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00 Checkpoint cnt:29 scn: 0x0000.00609e5c 07/02/2013 20:03:05 Stop scn: 0x0000.00609e5c 07/02/2013 20:03:05 Creation Checkpointed at scn: 0x0000.005bb12d 06/27/2013 00:00:09 thread:0 rba0x0.0.0) DATA FILE #31: (name #4) E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCLJJYF2\TA\SIM20130701.DBF creation size=0 block size=8192 status=0x80c head=4 tail=4 dup=1 tablespace 35, index=21 krfil=31 prev_file=0 unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00 Checkpoint cnt:21 scn: 0x0000.006094f6 07/02/2013 18:12:12 Stop scn: 0x0000.006094f6 07/02/2013 18:12:12 Creation Checkpointed at scn: 0x0000.005c892b 06/28/2013 00:00:03 thread:0 rba0x0.0.0) enabled threads: 00000000 00000000 00000000 00000000 00000000 00000000 8. ub4 kcvfhcpc @140 0x0000001d --》检查点计数,修改为21,即0x00000015 BBED> set offset 140 BBED> modify /x 15 Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y 9.ub4 kcvfhccc @148 0x0000001c --》比检查点计数少1,修改为20,即0x00000014 BBED> set offset 148 BBED> modify /x 14 10. ub4 kcvfhcrt @108 0x30d35d89 --》修改文件创建时间 需要把时间从06/27/2013 00:00:09修改为06/28/2013 00:00:03 有文章说create time的计算方法为:文件建立时间-1988年1月1日0时的秒数,其中每个月都按31天计算(没验证这个说法是否靠谱,暂时这样吧)。由于我这里两个文件创建时间是在同一个月,所以可以用to_timestamp函数相减了,否则得按照每个月31天来计算了。
select to_timestamp('2013-06-28 00:00:03', 'yyyy-mm-dd hh24:mi:ss') - to_timestamp('2013-06-27 00:00:09', 'yyyy-mm-dd hh24:mi:ss') diff from dual; SYS >select to_timestamp('2013-06-28 00:00:03', 'yyyy-mm-dd hh24:mi:ss') - to_timestamp('2013-06-27 00:00:09', 'yyyy-mm-dd hh24:mi:ss') diff from dual;; DIFF --------------------------------------------------------------------------- +000000000 23:59:54.000000000 1 row selected. SYS >select to_char(23*3600+59*60+54,'xxxxx') from dual; TO_CHA ------ 1517a 于是0x30d35d89加1517a即可 --》》0x30D4AF03
kcvfhcrt计算方法如下:
时间:06/28/2013 11:02:38 SYS >select 25*12*31*86400+5*31*86400+27*86400+11*3600+2*60+38 kcvfhcrt from dual;
BBED> modify /x 03afd4 File: /u01/mysql/bbed/SIM20130701.DBF (31) Block: 1 Offsets: 108 to 139 Dba:0x07c00001 ------------------------------------------------------------------------ 03afd430 abc6fa2f 09300900 00000000 00000000 00000000 00000000 00000000 <32 bytes per line> 11. ub4 kcvcptim @492 0x30dc6079 --》修改最后一次检查点时间 需要把checkpoint时间从07/02/2013 20:03:05修改为07/02/2013 18:12:12 SYS >select to_timestamp('2013-07-02 20:03:05', 'yyyy-mm-dd hh24:mi:ss') - to_timestamp('2013-07-02 18:12:12', 'yyyy-mm-dd hh24:mi:ss') diff from dual;; DIFF --------------------------------------------------------------------------- +000000000 01:50:53.000000000 SYS >select to_char(3600+50*60+53,'xxxxxx') from dual; TO_CHAR ------- 19fd 于是0x30dc6079减去0x19fd即可 --》0x30DC467C BBED> set offset 492 BBED> modify /x 7c46 File: /u01/mysql/bbed/SIM20130701.DBF (31) Block: 1 Offsets: 492 to 523 Dba:0x07c00001 ------------------------------------------------------------------------ 7c46dc30 01000100 82000000 d83b0100 10000000 02000000 00000000 00000000 BBED> sum dba 31,1 apply --》更新校验和,完事。 Check value for File 31, Block 1: current = 0x4bb0, required = 0x4bb0 好了,现在把文件拷回去吧 然后: SYS >alter database datafile 'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCLJJYF2\TA\SIM20130701.DBF' online; Database altered. SYS >alter database open; Database altered. 现在删除分区和表空间: SYS >alter table sim.sim_event drop partition p20130701; Table altered. SYS >drop tablespace sim20130701 including contents and datafiles; Tablespace dropped. 成功完成!! 没用过更高效的东西,暂时只会bbed,欢迎各位提出更好的建议!! |
误删数据文件后,使用bbed修改数据文件头,启动数据库
最新推荐文章于 2024-05-25 19:38:08 发布