博客园 首页 联系 订阅 管理

1. 概述

OBET 以 REPL 交互模式工作:启动后进入 OBET> 提示符,逐条执行命令。文件以 文件号 + 块号 的方式定位,可同时维护一份文件列表(来自 listfile.txt),方便在不同数据文件之间交叉读写。

功能概览

  • 十六进制查看 / 编辑数据块(自动维护 tailchk 和 checksum)
  • 打印 Oracle 内部结构(kcbh / kcvfh* / tailchk
  • 跨数据文件拷贝块 / 字节范围 / 文件头 SCN 信息
  • 整文件强制拷贝(forcecopy,绕过坏块)
  • 扩展数据文件(extend file N,按文件头记录大小补齐零块)
  • 坏块修复:corrupt / repair / merge
  • dbv 数据块物理一致性扫描
  • 导出 / 解析数据库元数据:get_dbinfo / parse_ctl / dump_undo
  • 解析 RDBA 编码(高 10 位 File#,低 22 位 Block#)
  • Linux 下 Patch Oracle 进程 SCN(patch_scn,需授权)
授权说明写操作(modify / repair / copy / merge / forcecopy / extend / patch_scn / undo 等需要修改磁盘内容的命令)依赖 license.dat 授权,绑定当前主机的硬件指纹(HWID)哈希。 backup 仅复制块到本地目录,不需授权。未授权或硬件变更时仅允许只读命令。

2. 开发者信息

姓名 XiFenFei
电话 +86-17813235971
邮箱 dba@xifenfei
QQ 107644445
微信 17813235971
网站 https://www.xifenfei.com

反馈授权 / Bug / 功能建议可通过上述任一渠道联系。

3. 启动与会话

3.1 会话命令

命令作用
help 显示完整命令清单(与本手册对应的内嵌帮助)
version 显示 OBET 版本、构建时间、开发者信息
quit / exit 退出 OBET

4. 文件 / 块设置

这一组命令负责把磁盘上的数据文件加载到 OBET 上下文。所有读写命令都依赖当前的 filenameblocksizeblockoffsetcountendian 等参数。

4.1 open <listfile>

从指定文件加载文件列表。文件每行格式:<num> <path>num 是 OBET 内部文件号,供后续 set file N / file N 使用。

OBET> open listfile.txt
路径安全.. 的路径会被拒绝。

4.2 info

显示当前已加载的文件列表(编号 / 路径)。

4.3 set <param> <value>

设置上下文参数。可用参数:

参数取值说明
filename 文件路径 当前操作的目标文件
file 整数 N 切换到已加载列表中第 N 个文件
blocksize 2048 / 4096 / 8192 / 16384 / 32768 Oracle 块大小
block 整数 当前块号
offset 整数(块内偏移) 块内起始偏移
count 整数 dump/modify 的字节数
mode browse / edit 交互模式(默认 browse)
endian big / little 多字节字段字节序
OBET> set filename /u01/oradata/users01.dbf
OBET> set blocksize 8192
OBET> set block 100
OBET> set endian big

4.4 show

显示当前上下文所有参数,包括 Modebrowse / edit)、FilenameFile#Block#BlocksizeOffsetCountEndian 等。

OBET> show
Mode: browse
Filename: /u01/oradata/users01.dbf
File#:    1
Block#:   100
Blocksize: 8192
Offset:    0
Count:     8192
Endian:    big

4.5 listfile <path | clear | edit>

扫描目录生成 listfile.txt、清空或编辑。

OBET> listfile /u01/oradata
OBET> listfile edit
OBET> listfile clear
  • listfile <path>:递归扫描目录,过滤 temp01.dbfredo*.log,写入当前目录的 listfile.txt
  • listfile clear:删除当前目录的 listfile.txt
  • listfile edit [path]:调用系统编辑器(Windows 记事本 / Linux vi)打开 listfile.txt,可指定路径
写操作保护写盘时会校验输入,避免路径穿越(../..\)。

5. 查看数据

5.1 dump / d [file N] [block X] [offset Y] [count Z]

以十六进制 + ASCII 形式显示块数据。默认使用当前文件 / 块 / 偏移。

OBET> d
OBET> dump file 1 block 100
OBET> dump offset 16 count 64
OBET> dump file 2 block 5 offset 0 count 128

5.2 print / p <kcvfh[.field] | tailchk>

解析并打印 Oracle 内部结构。仅支持一级字段。

OBET> p kcvfh
OBET> p kcvfh.kcvfhhdr
OBET> p kcvfh.kcvfhckp
OBET> p tailchk

支持的结构字段(不完整列表,p 无参数可打印完整清单):

字段含义
kcvfhhdr 文件头描述符
kcvfhrfn 相对文件号
kcvfhrdb DBID
kcvfhcrs 创建 SCN
kcvfhcrt 创建时间
kcvfhrls Resetlogs SCN
kcvfhcrs Creation SCN
kcvfhbsc Backup SCN
kcvfhbti Backup table info
kcvfhbth Backup table header
kcvfhbcp Backup Checkpoint
kcvfhbhz Backup status
kcvfhccc Change count
kcvfhckp 完整 Checkpoint
kcvfhcpc Checkpoint count
kcvfhprs / kcvfhprc / kcvfhprfs / kcvfhrfs 恢复相关字段
kcvfhtsn / kcvfhtln / kcvfhtnm 表空间号 / 名长度 / 名
kcvfhrlc / kcvfhrts / kcvfhtrt Resetlogs 计数 / 时间戳 / 总复位次数
kcvfhxcd 扩展 Checkpoint
kcvfhsta Fuzzy 状态
kcvfhofb / kcvfhnfb Offset bytes / Next offset bytes
kcvfhbfh Backup file header block
kcvfhafs Auxiliary recovery
tailchk 块尾校验
仅支持一级结构访问,如 p kcvfh.kcvfhhdr,不支持 p kcvfh.kcvfhhdr.kccfhtyp

6. 校验 / 计算

6.1 sum [apply] [file N] [block X]

校验或修复 checksum(块头 kcbh 中的 kcbh.flags/kcbh.checksum 字段)。

OBET> sum
OBET> sum apply
OBET> sum file 2
OBET> sum apply file 2 block 100

6.2 tailchk [apply] [file N] [block X]

校验或修复 tailchk(块末 4 字节与起始 SCN 比对)。

OBET> tailchk
OBET> tailchk apply
OBET> tailchk apply file 1 block 224

6.3 dbv [file N]

对当前文件或指定文件做物理一致性扫描(类似 dbv 工具),输出每块的 SCN / 类型 / tailchk / checksum 状态。字节序由 set endian 控制。

7. 修改数据

7.1 modify / m <hex> [file N] [block X] [offset Y] 需授权

写入十六进制字节。写入后会 自动重新计算 tailchkchecksum

OBET> m 0x4142 offset 16
OBET> modify 41424344 file 1 block 100 offset 32

7.2 corrupt [file N] [block X] 需授权

将指定块标记为 Oracle 意义上的损坏块(写入 seq_kcbh / type 标记,便于 Oracle 在后续扫描中跳过)。

7.3 backup [file N] [block X]

把指定块完整备份到当前目录的 backup_blk/ 子目录。备份按 fileN_blockM.bin 命名。

7.4 undo 需授权

回滚最近一次 modify / repair / copy / corrupt 等写操作。OBET 在每次写操作前保留原块内容,回滚基于这份快照。

8. 修复

8.1 repair block / blkscn [file N] [block X] 需授权

  • repair block:修复 seq_kcbhtailchkchecksum
  • repair blkscn:把块的 scn 抬到不低于 csc(解决 ORA-600 [kdddgb]] 之类 block SCN < block CSC 类报错)
OBET> repair block
OBET> repair block file 2 block 100
OBET> repair blkscn file 1 block 224

8.2 copy 需授权

多种拷贝语义,全部写盘需授权。

子命令语法说明
copy data copy data <src> to <dest> 跨文件字节范围拷贝
copy block copy block <file,block> to <file,block> 整块拷贝
copy chkscn copy chkscn file N to file M 拷贝数据文件头 Checkpoint SCN 信息
copy resetlogscn copy resetlogscn file N to file M 拷贝 Resetlogs 信息

<src> / <dest> 格式:file[,block][,offset[,count]]。缺省 block 沿用当前块,缺省 offset = 0,缺省 count = blocksize。

OBET> copy data 1,1,16,32 to 2,5,16
OBET> copy block 1,100 to 2,100
OBET> copy chkscn file 1 to file 2
OBET> copy resetlogscn file 1 to file 2

8.3 merge file N from M 需授权

M 文件中 RDBA 一致的健康块替换 N 文件中的坏块。执行前 OBET 会要求输入 YES 二次确认。

OBET> merge file 2 from 3
不可逆操作覆盖原文件块,请先 backup

8.4 forcecopy file N to <path> 需授权

整文件级别强制拷贝,忽略坏块(按 blocksize 步长逐块读取;坏块读到 0 字节时填充全 0x00 写入目标)。用于磁盘扇区部分损坏但仍能部分读取的应急场景。

OBET> forcecopy file 2 to D:\rescue\users01.dbf

8.5 extend file N 需授权

比较 Oracle 数据文件实际大小与文件头记录的预期大小,在不一致时将文件扩展至正确大小(尾部填零)。

判定规则:读取 block 1 内部偏移 44 处的块计数字段,计算出预期大小:

预期大小 = (块计数 + 1) × blocksize

三种结果:

  • 相等——文件大小与预期一致,无需操作;
  • 预期 > 实际(文件偏小)——自动在文件尾部以零块补齐至预期大小;
  • 预期 < 实际(文件偏大)——输出提示,要求人工介入,不自动截断。

前提条件

  • 需先 set blocksize 设置正确的 Oracle 块大小(4096 / 8192 / 16384 / 32768)
  • 需先 set endian big|little 设置正确的字节序
  • 需先 set mode edit 进入编辑模式

扩展时若空白间隙超过 1GB,为防止误操作导致的长时间填零,OBET 会跳过自动扩展并输出提示由人工处理。开始写入零之前需输入 Yyes 二次确认。

OBET> set blocksize 8192
OBET> set mode edit
OBET> extend file 1
File#1: expected 4182835200 bytes (510600 blocks), actual 4182831104 bytes
Difference: 4096 bytes (1 block)
  Extending file with zero-filled blocks...
  Confirm? (Y/yes to proceed): Y
File successfully extended to 4182835200 bytes.
注意扩展操作不可逆,请在执行前做好文件备份。若文件实际大小大于预期,Oracle 内部可能已扩展但文件头未更新,请人工核实后处理。

9. 数据库诊断

9.1 get_dbinfo

扫描当前已加载的所有数据文件,提取头部元数据(DBID、创建 SCN、Checkpoint SCN、表空间号 / 名、文件大小等),写入 dbinfo_<timestamp>.txt

9.2 parse_ctl <path>

解析 Oracle 控制文件(control01.ctl / control02.ctl 等),输出 DB 名称、字符集、所有数据文件(type=04)、临时文件(type=07)、日志文件(type=03)、表空间清单。日志文件 SIZE 列由三级回退得到:

  1. 操作系统上读取到的 redo 文件大小减去 512 字节(Oracle redo 文件尾部的 512 字节 footer);
  2. 若 OS 文件无法访问(文件丢失 / 不可读),从控制文件第 21 / 22 块中 redo 记录(72 字节 / 条)的块数 × 512 字节取得;
  3. 上述两者都不可用时显示 0(对应记录仍会显示,便于人工干预)。

PATH 列宽按当前解析结果中最长路径动态收紧;SIZE 数值右对齐。

OBET> parse_ctl E:\ORADATA\ORCL\CONTROL01.CTL

9.2.1 自动生成的重建控制文件脚本

完成屏幕输出后,OBET 会在当前工作目录生成 rectl_<DB_NAME>_<YYYYMMDDHHMMSS>.sql,可作为 CREATE CONTROLFILE 重建命令的参考模板。

文件包含 CREATE CONTROLFILE 头、LOGFILE(同 group 多成员合并为 GROUP N (m1, m2) 元组写法)、DATAFILECHARACTER SET 与结尾分号 ;

无法自动获取 SIZE 的 redo 文件仍写入记录,并在文件尾部追加英文提示,便于人工干预。

生成成功时屏幕输出形如:

Control file rebuild SQL generated: rectl_ORCL_20260727151150.sql

9.3 rdba <hex>

把 RDBA 值拆解为 Oracle File# 和 Block#(高 10 位 = File#,低 22 位 = Block#)。

OBET> rdba 0x0040019A

输出形如:

RDBA:   0x0040019A
  File#:  1   (0x001)
  Block#: 410 (0x19A)

9.4 dump_undo [file N] [block M]

undo$ 段读取每条 UNDO 记录的 namestatus$。默认 file 1 block 224

OBET> dump_undo
OBET> dump_undo file 2 block 225

9.5 patch_scn Linux 需授权

直接修改 Oracle 进程内存中的 SCN 字段。仅在 Linux 构建中可用。

用法作用
patch_scn spid 列出本机 Oracle LOCAL=YES 进程
patch_scn addr 通过 sqlplus 辅助获取 SCN 在进程内存中的地址
patch_scn [<spid>] [<addr>] <newval> 把目标进程 SCN 改写为 newval

10. 会话 / 杂项

10.1 license

管理 / 查看授权信息。

OBET> license show
OBET> license load /path/to/license.dat

10.2 spool <file> | off

把后续输出同时写入指定文件;spool off 停止。

OBET> spool dbv_session.log
OBET> dbv
OBET> spool off

11. 常见问题

Q1:Oracle 正在使用时能不能直接读取数据文件?

可以。Windows 下 OBET 以 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE 共享模式打开文件,Oracle 进程独占持有时 OBET 仍能读取。

Q2:如何切换数据文件?

open listfile.txt 加载列表,再用 set file N(或任意命令中的 file N 子句)切换。

Q3:写命令报 “license invalid / expired / hwid mismatch”?

授权与当前主机 HWID 绑定、存在有效期。请用 license show 查看具体错误码,联系维护者重新签发 license.dat

Q4:corruptmerge 顺序?

坏块诊断顺序建议:dbv 定位 → corrupt 标记 → merge 用健康文件修复。修复前用 backup 留底。

Q5:forcecopy 与普通拷贝区别?

普通跨文件操作要求源块能正常读取;forcecopy 跳过 IO 失败的位置并填 0,专为磁盘部分损坏的应急场景设计,目标文件保持原始 blocksize 和块数。

Q6:p kcvfh.kcvfhhdr.kccfhtyp 为什么报错?

当前 print 仅支持一级字段访问。多级字段需要从一级结构中继续解析(暂未实现)。