十四、怎样在windows上用DD配合ultraEdit修改数据
BBED我相信大家都已经很熟悉它的用法了,在充分了解block结构的基础上善用BBED确实可以解决很多block内的逻辑错误,但遗憾的是windows平台上的9iR2和 10gR2并不带BBED。

如果我们想在windows平台上用BBED修改数据该怎么办?

其实这里是可以采取变通的办法的,那就是用DD和ultraEdit来替代BBED。好了,我们来看一个实际的例子。

SQL> conn scott/tiger@cuihua;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as scott

SQL> select file_name,file_id,bytes from dba_data_files where tablespace_name=’USERS’;

FILE_NAME FILE_ID BYTES
——————————————————————————– ———- ———-
D:\ORACLE\ORADATA\CUIHUA\USERS01.DBF 4 61603840

SQL> create table t2(c1 number,c2 varchar2(5));

Table created

SQL> insert into t2 values(1,’a');

1 row inserted

SQL> insert into t2 values(2,’b');

1 row inserted

SQL> insert into t2 values(3,’c');

1 row inserted

SQL> commit;

Commit complete

SQL> alter system checkpoint;

System altered

SQL> select c1,c2,dbms_rowid.rowid_relative_fno(rowid)||’_'||dbms_rowid.rowid_block_number(rowid) location from t2;

C1 C2 LOCATION
———- —– ——————————————————————————–
1 a 4_1648
2 b 4_1648
3 c 4_1648

现在我们来用DD把上述第二条记录的C2的值由b改成d。

shutdown上述数据库,把”D:\ORACLE\ORADATA\CUIHUA\USERS01.DBF”ftp到AIX上去,然后用dd把 1648这个block拷出来:

$ dd if=/iprat01/USERS01.DBF of=/iprat01/users01.dd count=1 skip=1648 bs=8192
1+0 records in.
1+0 records out.

接着把users01.dd ftp到windows上后用ultraEdit来改,ultraEdit里可以很方便的看到offset:
00001fe0h: 00 00 00 00 2C 01 02 02 C1 04 01 63 2C 01 02 02
00001ff0h: C1 03 01 62 2C 01 02 02 C1 02 01 61 01 06 E6 90

我们现在是想把t2中第二条记录的C2字段的值由b改成d,d所对应的存储格式为:
SQL> select dump(‘d’,16) from dual;

DUMP(‘D’,16)
—————-
Typ=96 Len=1: 64

所以这里我们只需要把62改成64就可以了。
当然这里改完后要把上述block的16、 17位清零,同时把15位改成0×04。这么做是为了让oracle帮我算出来上述block在更改数据后的checksum值是多少。
BBED里不用这么麻烦,因为sum apply时候BBED已经把正确的checksum值算出来并写回去了。

改完后保存,然后把修改过的users01.dd ftp到AIX上再用dd拷回去:
$ dd if=/iprat01/users01.dd of=/iprat01/USERS01.DBF bs=8192 seek=1648 count=1 conv=notrunc
1+0 records in.
1+0 records out.

拷回去后再把已经被修改过的USERS01.DBF ftp下来,然后覆盖windows上原有同名文件并startup上述数据库:
C:\Documents and Settings\cuihua>sqlplus /nolog

SQL*Plus: Release 10.2.0.1.0 – Production on 星期四 6月 4 11:26:02 2009

Copyright (c) 1982, 2005, Oracle. All rights reserved.

SQL> conn / as sysdba;
已连接到空闲例程。
SQL> startup
ORACLE 例程已经启动。

Total System Global Area 608174080 bytes
Fixed Size 1250404 bytes
Variable Size 209718172 bytes
Database Buffers 390070272 bytes
Redo Buffers 7135232 bytes
数据库装载完毕。
数据库已经打开。
SQL> select * from scott.t2;
select * from scott.t2
*
第 1 行出现错误:
ORA-01578: ORACLE 数据块损坏 (文件号 4, 块号 1648)
ORA-01110: 数据文件 4: ‘D:\ORACLE\ORADATA\CUIHUA\USERS01.DBF’

这是必然的,因为checksum值已经发生了变化。
看一下alert log:
Corrupt block relative dba: 0×01000670 (file 4, block 1648)
Bad check value found during buffer read
Data in bad block:
type: 6 format: 2 rdba: 0×01000670
last change scn: 0×0000.001590e6 seq: 0×1 flg: 0×04
spare1: 0×0 spare2: 0×0 spare3: 0×0
consistency value in tail: 0x90e60601
check value in block header: 0×0
computed block checksum: 0xd2ca
Reread of rdba: 0×01000670 (file 4, block 1648) found same corrupted data

好了,那这里我们就按照上述alert log的提示再改一次checksum值,注意这里改的时候要将第16位、第17位改成CA D2(因为windows是little endian),改完后再次startup上述数据库:

SQL> startup
ORACLE 例程已经启动。

Total System Global Area 608174080 bytes
Fixed Size 1250404 bytes
Variable Size 230689692 bytes
Database Buffers 369098752 bytes
Redo Buffers 7135232 bytes
数据库装载完毕。
数据库已经打开。

SQL> select * from scott.t2;

C1 C2
———- —–
1 a
2 d
3 c

可以看到,我们已经成功的用DD配合ultraEdit把上述第二条记录的C2的值由b改成了d。

请注意,我这次测试的结果是:一定要先把上述block的16、 17位清零,同时把15位改成0×04后alert log计算出来的checksum值才是对的,如果你不这样做,可以从alert log看到oracle这里计算出来的checksum值明显不对。

Trackback

no comment untill now

Add your comment now

切换到手机版