Oracle Block Editor Tool

面向 Oracle 数据块的可视化 / 编辑 / 修复工具,支持十六进制查看编辑、内部结构解析(kcbh / kcvfh* / tailchk)、tailchk 与 checksum 自动修复、块复制、SCN 信息修复、坏块跨文件合并、数据文件扩展、损坏块标记、dbv 校验、undo$ 段内容提取、控制文件解析、RDBA 解析等完整功能。

1. 概述

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

功能概览

授权说明 写操作(modify / corrupt / repair / copy / merge / forcecopy / extend / patch_scn 等需要修改磁盘内容的命令)需要先 set mode edit 进入编辑模式,并在出现确认提示时输入 Y 或 YES 才会执行写入。 backup 仅复制块到本地目录,不需授权。未授权时仅允许只读命令。

2. 开发者信息

姓名XiFenFei
电话+86-17813235971
邮箱dba@xifenfei
QQ107644445
微信17813235971
网站https://www.xifenfei.com
下载地址官网下载obet

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

3. 启动与会话

3.1 help

显示完整命令清单(与本手册对应的内嵌帮助)。

OBET> help

  [File / Block Setup]
  open [path]            - Load file list (format:  ) default: listfile.txt
  info                    - Show loaded file list
  set       - Configure: filename|file |blocksize|block|offset|count|mode|endian
  show                    - Display current settings
  listfile   - Scan dir, remove, or edit listfile (path optional for remove/edit)

  [View Data]
  d/dump [file N] [block M] [offset Y] [count Z] - Display block data (default: current file/block)
  p/print 
                                   - Print Oracle structure (data blocks: kcbh/ktbbh/kdbh/kdbt/kdbr/kdxle/kdxbr;
                                     datafile header: kcvfh.*; 'p' alone prints full list)
  x/examine /X|/C|/D|/U|/O|/r[types] [OFFSET n] [COUNT n]
                                  - Interpret bytes at current offset (/X hex, /C latin-1, /D/U/O decimal/octal, /r re-print last *kdbr[n])
  find /X  | find /C   - Search for byte sequence / UTF-8 text in current block

  [Verify / Calculate]
  sum [apply] [file N] [block M]       - Verify (or apply) block checksum
  tailchk [apply] [file N] [block M]   - Verify (or apply) block tailchk
  dbv [file N [block M [blocks X]]]    - Verify data blocks for corruption

  [Modify Data]
  m/modify  [file N] [block M] [offset Y]  - Modify bytes (with auto-checksum/tailchk)
  corrupt [file N] [block M]          - Mark block as corrupted
  backup [file N] [block M]           - Backup block to backup_blk/
  restore [file N] [block M]          - Restore block from a backup_blk/ snapshot
  undo                                - Undo last modification

  [Repair]
  repair block [file N] [block M]         - Fix seq_kcbh / tailchk / checksum
  repair blkscn [file N] [block M]        - Fix block SCN lower than block CSC
  repair list [file N [block M]]          - Batch repair all bad blocks recorded by dbv
  copy data  to               - Copy byte range between files
    / format: file[,block][,offset[,count]]
    Example: copy data 1,1,16,32 to 2,5,16
  copy block  to   - Copy entire block between files
  copy chkscn file N to file M            - Copy datafile header checkpoint SCN info
  copy resetlogscn file N to file M       - Copy datafile header resetlogs info
  forcecopy file N to               - Force copy file ignoring bad blocks (damaged disks)
  forcecopy disk  to           - Force copy raw disk/partition to image (4K chunks, bad sectors zero-filled)
      examples: /dev/sda (Linux) | PhysicalDrive1 or C: (Windows, admin required)
  extend file N                          - Check and extend datafile to match header record
  merge file N from M                    - Repair N's bad blocks using M's blocks at same RDBA
  build block N,M [to file X]           - Build block (N=file#, M=block#); write build_N_M.blk; 'to file X' patch after validation

  [Database Info / Diagnostics]
  get_dhr                - Extract DB info from file headers to dhr_*.txt
  parse_ctl        - Parse Oracle control file (DB name / datafiles / tablespaces)
  dump_undo [file N] [block M] - Dump UNDO$ segment: name + status$ (default: file 1 block 224)

  [Session]
  license              - Show / manage license
  version              - Show version and developer info
  spool |off    - Start/stop logging to file
  host     - Run OS command (cmd on Windows, sh on Linux)
  tool                 - Enter TOOL> sub-mode (rdba / getrdba / rowid / getrowid / time / gettime)
  help                 - Show this help message
  quit/exit            - Exit OBET

3.2 version

显示 OBET 版本、构建时间、开发者信息。

OBET> version
=============================================
Welcome to Oracle Block Editor Tool (OBET)
=============================================
***** !!! For Oracle Internal Use only !!! *****

[Software Function Description]
- View and edit data block in hexadecimal format (d/dump, m/modify)
- Print Oracle internal structures (p/print: kcbh, ktbbh, kdbh, kdbt, kdbr/*kdbr[n], kdxle/kdxbr, kd_off/*kd_off[n]/index_entries/*index_entry[n], kcvfh*, tailchk)
- Examine bytes at offset in /X|/C|/D|/U|/O|/r[types] format (x/examine)
- Search byte sequence or UTF-8 text in current block (find /X|/C)
- Modify data block bytes (with auto tailchk/checksum)
- Copy data byte range / whole block between datafiles (copy data / copy block)
- Copy / repair datafile header SCN info (copy chkscn / copy resetlogscn)
- Force copy entire file ignoring bad blocks (forcecopy)
- Force copy raw disk/partition to image ignoring bad sectors (forcecopy disk)
- Extend datafile to expected size from file header (extend)
- Mark block as corrupted by setting kcbh.seq_kcbh=0xFF (corrupt)
- Verify data blocks for corruption; log to dbv_*.log (dbv)
- List dbv-recorded bad blocks (list corrupt [file N])
- Repair corrupted block: seq_kcbh / tailchk / checksum (repair block)
- Repair block SCN lower than block CSC (repair blkscn)
- Batch repair all dbv-recorded bad blocks (repair list)
- Calculate / apply block checksum (sum / sum apply)
- Calculate / apply block tailchk (tailchk / tailchk apply)
- Backup data block to backup_blk/ directory (backup)
- Undo last modification (undo)
- Repair bad blocks using healthy donor file at same RDBA (merge file N from M)
- Construct single-block file build_N_M.blk (build block N,M)
- Extract undo$ segment name + status$ (dump_undo)
- Extract database info from file headers to dhr_*.txt (get_dhr)
- Parse Oracle control file: DB name / datafiles / tablespaces (parse_ctl)
- Patch Oracle process SCN in memory (patch_scn, Linux only, license required)
- Scan directory / edit / remove listfile.txt (listfile / listfile edit)
- Run OS command from OBET prompt (host )
- Enter TOOL> sub-mode for rdba / getrdba / rowid / getrowid / time / gettime (tool)
- Session: license / show / spool |off / help / version / quit / exit

[Developer Information]
- Name: XiFenFei
- Phone: +86-17813235971
- Email: dba@xifenfei
- Q Q: 107644445
- WeChat: 17813235971
- Website: https://www.xifenfei.com

[Version Details]
- Software Version: 2026.08
- Build Date: 2026.08.12 17:49:27

3.3 quit / exit

退出 OBET。

4. 文件 / 块设置

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

4.1 open [path]

从指定文件加载文件列表。文件每行格式:<num> <path>,num 是 OBET 内部文件号,供后续 set file N / file N 使用。不写 path 时默认读取当前目录的 listfile.txt。

OBET> open                  # 加载 ./listfile.txt
OBET> open listfile.txt
OBET> open test_listfile.txt
Loaded 1 files from datafile list 'test_listfile.txt'.

4.2 info

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

OBET> info
----------------------------------------
No   Path
----------------------------------------
1    E:/CC/obet/dbf/SYSTEM01.DBF
----------------------------------------

4.3 set <param> <value>

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

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

4.4 show

显示当前上下文所有参数,包括 Mode(browse / edit)、Filename、File#、Block#、Blocksize、Offset、Count、Endian 等。

OBET> show
Current settings:
File: (not set)
Blocksize: 8192 bytes
Block: 1
Offset in block: 0 (file offset: 0x00002000)
Count: 32 bytes
Mode: browse
Endian: little (x86)
Loaded files: 1 (use 'info' to list)

4.5 listfile <path | remove | edit>

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

OBET> listfile /u01/oradata
OBET> listfile remove
OBET> listfile remove my_lists/test.txt
OBET> listfile edit

通配符示例:

OBET> listfile E:/oradata           # 扫描整个目录
OBET> listfile E:/dbf/system*.dbf  # 仅扫描名称以 system 开头且 .dbf 结尾的数据文件

已存在 listfile.txt 时,新扫描结果以递增编号追加写入。

写操作保护写盘时会校验输入,避免路径穿越(../、..\)。

5. 查看数据

5.1 dump / d [file N] [block M] [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
OBET> dump file 1 block 128 offset 32 count 48
File: e:/cc/obet/dbf/system01.dbf (#1 in listfile)
Block: 128                Offsets:    32 to    79
--------------------------------------------------------------------------------
00100020 00000000 01000200 00000000 04001200 43000000 B02C8000 2F001000 01200000
00100040 22120200 00015800 FFFFC200 2A046803

5.2 print / p <kcvfh[.field] | kcbh | ktbbh | kdbh | kdbt | kdbr[/n] | *kdbr[n] | kdxle | kdxbr | kd_off[/n] | *kd_off[n] | index_entries | *index_entry[n] | tailchk>

解析并打印 Oracle 内部结构。仅支持一级字段。p 不带参数可打印完整清单(含 p 单独执行时输出的两个子段):

Oracle 文件头结构显示

解析 kcvfh 块(数据文件第一块)。示例与字段列表见下方。

OBET> p kcvfh
OBET> p kcvfh.kcvfhhdr
OBET> p kcvfh.kcvfhckp
OBET> p tailchk
ub4 tailchk                                      @8188    0x00000B01

支持的全部结构字段(p 不带参数可打印完整清单):

字段含义
kcvfhhdr文件头描述符
kcvfhrfn相对文件号
kcvfhrdbDBID
kcvfhcrs创建 SCN
kcvfhcrt创建时间
kcvfhrlsResetlogs SCN
kcvfhcrsCreation SCN
kcvfhbscBackup SCN
kcvfhbtiBackup table info
kcvfhbthBackup table header
kcvfhbcpBackup Checkpoint
kcvfhbhzBackup status
kcvfhcccChange count
kcvfhckp完整 Checkpoint
kcvfhcpcCheckpoint count
kcvfhprs / kcvfhprc / kcvfhprfs / kcvfhrfs恢复相关字段
kcvfhtsn / kcvfhtln / kcvfhtnm表空间号 / 名长度 / 名
kcvfhrlc / kcvfhrts / kcvfhtrtResetlogs 计数 / 时间戳 / 总复位次数
kcvfhxcd扩展 Checkpoint
kcvfhstaFuzzy 状态
kcvfhofb / kcvfhnfbOffset bytes / Next offset bytes
kcvfhbfhBackup file header block
kcvfhafsAuxiliary recovery
tailchk块尾校验
仅支持一级结构访问,如 p kcvfh.kcvfhhdr,不支持 p kcvfh.kcvfhhdr.kccfhtyp。

Oracle 数据块结构显示

p 命令同时支持以下数据块内部结构。多字节字段按 set endian 配置解读,大写 8 位补零 hex。带索引 [n] 接受负索引(-1 表示末元素),越界返回 Error: list index out of range。

命令说明
p kcbh公共块头(type / frmt / rdba / SCN base / seq / flg / chkval 等)
p ktbbhKTB 事务头 + ITL 数组(含 raw hex 与 OBJD)
p kdbh表 / 簇数据头(仅 type=6 + subtype=1 块)
p kdbt表目录(kdbtoffs / kdbtnrow)
p kdbr / p kdbr[n]行目录(全量 / 单条)
p *kdbr[n]解码 slot n 行(flag / lock / cols / 簇键 / 簇成员 / HRID / NRID)
p kdxle / p kdxbr索引 leaf / branch 头(含 kdxcosdc / kdxconro / kdxcofbo / kdxcofeo 等)
p kd_off / p kd_off[n]索引偏移目录(全量 / 单条)
p *kd_off[n]物理索引条目 n(BBED deref 语义;零指针回 kdx 头、负 sentinel 报错)
p index_entries逻辑 leaf 条目列表(含 FEO gap 重建)
p *index_entry[n]逻辑 leaf 条目 n
p tailchk块尾校验(ub4 tailchk @8188 0xHEX)

多字节值字段同时显示磁盘字节([raw hex: XXXXXXXX])以便交叉核对大端 / 小端。OBET 字节序由 set endian big/little 控制。

5.3 examine / x /format [OFFSET n] [COUNT n]

按指定格式解读当前 offset 处的字节。OFFSET 参数持久更新 offset(与 set offset 等价),COUNT 仅本次命令生效。范围自动夹在块末(block_size − 4)。

格式含义
/X连续大写 hex(如 0x0106DD00,8 位补零)
/C按 Latin-1 原字节输出
/D有符号十进制 -128..127(空格分隔)
/U无符号十进制 0..255
/O八进制
/r[types]重打印 p *kdbr[n] 选中的行,types 逐列指定类型

/r 的 types 字符:c = Latin-1 字符串、n = Oracle NUMBER、t = DATE(7 字节)。NULL 列输出 *NULL*。无 types 时走启发式推断(DATE / NUMBER / TEXT)。x /r 忽略 set offset,重打印由 p *kdbr[n] 设置的 current_rowp;其它格式仍按 offset。

OBET> set offset 100
OBET> x /x offset 100 count 16
OBET> x /u offset 0 count 20
OBET> x /d offset 8 count 16
OBET> x /o offset 0 count 12
OBET> x /c offset 32 count 48
OBET> p *kdbr[5]
OBET> x /r
OBET> x /rncc
OBET> x /x offset 9999          # → Error: Offset must be between 0 and 8191

5.4 find /X <hex> | find /C <text>

在当前块中搜索字节序列,输出全部匹配偏移。/X 要求偶数长度 hex(奇数报 Odd-length string,非 hex 字符报 Non-hexadecimal digit found)。/C 以 UTF-8 编码搜索字符串。搜索从头到尾,不重叠。

OBET> find /x 426d1700
Found at offset: 8
Found at offset: 64

Search finished.

OBET> find /c SYSTEM
Found at offset: 32

Search finished.

OBET> find /x zz                # → Error: Non-hexadecimal digit found
OBET> find /x 426d17           # → Error: Odd-length string

6. 校验 / 计算

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

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

OBET> sum
OBET> sum apply
OBET> sum file 2
OBET> sum apply file 2 block 100
OBET> sum
Check value for File e:\cc\obet\dbf\system01.dbf, Block 2:
  current = 0xB71C, required = 0xB71C

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

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

OBET> tailchk
OBET> tailchk apply
OBET> tailchk apply file 1 block 224
OBET> tailchk apply file 1 block 224
Confirm applying tailchk:
File: e:\cc\obet\dbf\system01.dbf
Block: 224
Offset in block: 8188 (file offset: 0x00071FFC)
Original value: 0x00E03F03
New value:      0x00E03F03
Confirm? (Y/YES to proceed): Y
tailchk applied successfully.

6.3 dbv [file N [block M [blocks X]]]

对全部已加载文件或指定文件做物理一致性扫描(类似 Oracle dbv 工具)。字节序由 set endian 控制。可检测五类问题:全零块、软损坏(seq_kcbh=0xFF)、tailchk 错误、checksum 错误、rdba 错误。

块号从 0 开始。自动识别 bigfile / smallfile 数据文件,bigfile 时跳过文件头(block 0)的 rdba 校验。扫描结果自动保存到日志文件:

OBET> dbv
OBET> dbv file 1
OBET> dbv file 1 block 100
OBET> dbv file 1 block 100 blocks 500
OBET> dbv file 1 block 100 blocks 500
===============================================
DBV (Data Block Verification)
Block Size: 8192 bytes
Endian:     little-endian (x86)
Target:     file #1 (e:\cc\obet\dbf\system01.dbf)
Range:      block 100 to block 599 (500 blocks)
===============================================
Verifying file #1: e:\cc\obet\dbf\system01.dbf ...
DBV completed at: 2026-08-12 15:04:25
===============================================
DBV Summary:
Total blocks checked: 500
Total all zero blocks found: 0
Total all tailchk error blocks found: 0
Total all checksum error blocks found: 0
Total bad blocks found: 0
Execution time: 0.20 seconds
Throughput: 19.53 MB/s
===============================================
Detailed report saved to: dbv_file_1_block_100_20260812150425.log

6.4 list corrupt [file N]

列出 dbv 最近一次(或累计)扫描记录的坏块,按 file 号分组。每次 dbv 运行会把本次新发现的坏块(全零 / 软损坏 / tailchk / checksum / rdba)追加进内部表,list corrupt 直接从这张表读取。

若 dbv 尚未运行(或未发现任何坏块),打印 No corrupt blocks recorded. Run 'dbv' first.

OBET> dbv file 1
...
OBET> list corrupt
file 1 (e:\cc\obet\dbf\system01.dbf) 总坏块数: 3
block号   坏块类型
5          soft corrupted
128        tailchk error
129        checksum error

OBET> list corrupt file 1
file 1 (e:\cc\obet\dbf\system01.dbf) 总坏块数: 3
block号   坏块类型
5          soft corrupted
128        tailchk error
129        checksum error
list corrupt 不会清空已记录表;再次运行 dbv 会把新发现的坏块继续追加进来。如需重置,需重启 OBET 或另行管理表状态。

7. 修改数据

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

写入十六进制字节。写入后自动重新计算 tailchk 与 checksum。需先 set mode edit,执行时输入 Y 确认。

OBET> set mode edit
OBET> m 41424344
OBET> modify 41424344 file 1 block 100 offset 32
OBET> set mode edit
OBET> modify 41424344 file 1 block 128 offset 32
Confirm modification:
File: e:\cc\obet\dbf\system01.dbf
Block: 128
Offset: 32 (file offset: 0x00040020)
Original value: 01000200
New value:      41424344
Confirm? (Y/YES to proceed): Y
Data written successfully.

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

把指定块标记为 Oracle 意义上的软损坏:把 kcbh.seq_kcbh(块内偏移 14)置为 0xFF。该标记与 dbv 软损坏检测、repair block 行为一致。需先 set mode edit,执行时输入 Y 确认,可用 undo 回退。

OBET> corrupt file 1 block 128
Confirm marking block 128 as corrupted:
Block 128 seq_kcbh @ offset 14
Original value: 0x01
New value: 0xFF
Confirm? (Y/YES to proceed): Y
[Undo information saved - use 'undo' command to restore seq_kcbh at offset 14]
Successfully marked block 128 as corrupted.

7.3 backup [file N] [block M]

把指定块完整备份到当前目录的 backup_blk/ 子目录。备份文件名格式:backup_<filename>.<file#>_<block#>_<timestamp>.blk

OBET> backup file 1 block 128
Backing up file #1, block 128
e:\cc\obet\dbf\system01.dbf
Successfully backed up block 128 to backup_blk\system01.dbf.1_128_20260812150500.blk

7.4 restore [file N] [block M] 需授权

从 backup_blk/ 中选择某次历史备份,把内容写回 file N 的 block M。需先 set mode edit。

OBET> restore file 1 block 128

Available backups for system01.dbf block 128 (newest first):
  [1] system01.dbf.128_20260826223008.blk   (2026-08-26 22:30:08)
  [2] system01.dbf.128_20260826223006.blk   (2026-08-26 22:30:06)
  [3] system01.dbf.128_20260826223003.blk   (2026-08-26 22:30:03)
Select backup (default=1, newest; q to cancel): _
Restore from 'system01.dbf.128_20260826223008.blk' to system01.dbf block 128?
This will OVERWRITE the entire block (8192 bytes). Proceed? (Y/YES to confirm): Y
Restore successful: 8192 bytes restored from 'system01.dbf.128_20260826223008.blk' to system01.dbf block 128.
不可逆操作覆盖原文件块,恢复前请确认选择正确。

7.5 undo 需授权

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

OBET> undo
Undid 1 operation(s). Block data restored from backup.

8. 修复

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

均需先 set mode edit,执行时输入 Y 确认。

OBET> set mode edit
OBET> repair block
OBET> repair block file 2 block 100
OBET> repair blkscn file 1 block 224
OBET> repair block file 1 block 128
Repairing block 1, 128...
Current block SCN information:
  blkscn: 0x000000000278D9A3 (41663267)
  blkcsc: 0x0000000002790128 (41670952)
blkscn < blkcsc, SCN repair required.
New SCN values to write:
  base:  0x02790128 (41670952)
  wrap:  0x0000
  seq:   0x00
Confirm SCN repair operations: Operation cancelled.

8.1.1 repair list [file N [block M]] 需授权

批量修复 dbv 记录的全部坏块:先备份每个块,然后调用 repair block 修复 seq_kcbh / tailchk / checksum。每条记录独立处理,单条失败不会中断其余。需先 set mode edit。

OBET> dbv file 1
...
OBET> repair list
[1] Processing file 1 (e:\cc\obet\dbf\system01.dbf) block 5 (soft corrupted) ...
  [file 1 block 5] repaired successfully
[2] Processing file 1 (e:\cc\obet\dbf\system01.dbf) block 128 (tailchk error) ...
  [file 1 block 128] repaired successfully

Total: 2, Success: 2, Failed: 0

8.2 copy 需授权

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

子命令语法说明
copy datacopy data <src> to <dest>跨文件字节范围拷贝
copy blockcopy block <file,block> to <file,block>整块拷贝
copy chkscncopy chkscn file N to file M拷贝数据文件头 Checkpoint SCN 信息
copy resetlogscncopy 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
OBET> copy block 1,128 to 1,129
Copying block 1,128 to 1,129...
  src: file#=1 block#=128 (rdba=0x00400080)
  dest: file#=1 block#=129 (rdba=0x00400081)
Block copied successfully.

8.3 merge file N from M 需授权

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

OBET> merge file 2 from 3
OBET> merge file 2 from 3
Merging bad blocks from file 2 using healthy blocks from file 3...
File 2: scanning for bad blocks...
  Block 100: bad, searching donor...
  Block 100: rdba=0x00400064 matched, scanning file 3 for donor block...
  Block 100: donor found at file 3 block 100
  Replacing bad block 100 in file 2 with healthy block from file 3...
Merge completed. Total blocks repaired: 1
不可逆操作覆盖原文件块,请先 backup。

8.4 forcecopy 需授权

forcecopy file N to <path>

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

OBET> forcecopy file 2 to D:\rescue\users01.dbf
OBET> forcecopy file 2 to D:\rescue\users01.dbf
forcecopy: source file 2, dest D:\rescue\users01.dbf
Reading source file...
  4096 bytes read OK (block 0)
  4096 bytes read OK (block 1)
  ... (progress every 1000 blocks)
  4182831104 bytes copied (510600 blocks)
forcecopy completed. 0 bad blocks filled with zeros.

forcecopy disk <device> to <path>

把整块磁盘 / 分区 / 裸设备按 4K 颗粒拷贝成一个独立镜像文件,遇坏扇区填零后继续,整个拷贝不中断。用于磁盘出现物理坏道、需要先把整盘抢救成镜像再用 OBET 分析的场景。

设备路径(按平台自动补全):

OBET> forcecopy disk /dev/sda to /backup/sda.img
OBET> forcecopy disk PhysicalDrive1 to E:\backup\disk1.img

坏扇区降级处理(比 forcecopy file 更精细,不会为一个坏扇区丢掉整个 4K):

  1. 4K 读取,失败重试 3 次(退避 1s → 0.5s);
  2. 仍失败则按逻辑扇区(BLKSSZGET / IOCTL_DISK_GET_DRIVE_GEOMETRY_EX 探测,失败默认 512)逐扇区重试;
  3. 成功的扇区数据保留,失败的扇区填 0x00,并记录其偏移量;
  4. 整个 4K 一次性写入目标文件。

进度与汇总:每拷贝满 1GB 打印一行进度;结束后汇总总字节数、耗时、平均速率、坏扇区数,并列出坏扇区偏移量(stdout 最多 100 条,完整列表写入 forcecopy_disk_error.log,无坏块时不生成该文件)。

OBET> forcecopy disk /dev/sda to /backup/sda.img
Force copy disk: 107374182400 bytes (100.00 GB), chunk=4096, sector=512
Progress: 1073741824 / 107374182400 bytes (1.0%), bad=0
Progress: 2147483648 / 107374182400 bytes (2.0%), bad=0
...

Force copy disk completed:
  Source:       /dev/sda (107374182400 bytes)
  Destination:  /backup/sda.img
  Bytes copied: 107374182400
  Elapsed:      123.4 s (832.1 MB/s)
  Bad sectors:  2 (filled with zeros, 512 bytes each)
  Write errors: 0

  Bad offset list (max 100 shown, offset given in KB):
    0x0000000012340000  (291271 KB)
    0x0000000012346200  (291272 KB)

  Full log: forcecopy_disk_error.log
前提条件:Windows 需管理员权限、Linux 需 root;目标路径所在磁盘必须有足够空间(写失败会立即中止并报 Failed to write destination);本命令不需要 open 加载 listfile。

8.5 extend file N 需授权

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

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

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

三种结果:

前提条件:

开始写入前需输入 Y 或 YES 二次确认(忽略大小写)。

OBET> set blocksize 8192
OBET> set mode edit
OBET> extend file 1
File #1: E:\dbf\system.dbf
  BlockSize:       8192 bytes
  Header Blocks:   510600 (offset 44)
  Expected Size:   4182835200 bytes ((510600+1)*8192)
  Actual Size:     4182831104 bytes
  Status: File is smaller than header record.
  Extending file by 4096 bytes (Build Oracle block padding)...
  Confirm? (Y/yes to proceed): Y
  Done. File extended to 4182835200 bytes.
注意扩展操作不可逆,请在执行前做好文件备份。若文件实际大小大于预期,Oracle 内部可能已扩展但文件头未更新,请人工核实后处理。

8.6 build block N,M [to file X] 需授权

构造 Oracle 数据块(N=file# 1-1024,M=block#)并按需 patch 到 listfile 中的目标文件。

用法:

OBET> set endian big
OBET> build block 1,500
Created: build_1_500.blk (file#=1, block#=500, rdba=0x004001F4, tailchk=0x01000000, checksum=0x0113)

OBET> set mode edit
OBET> build block 1,500 to file 1
Created: build_1_500.blk (file#=1, block#=500, rdba=0x004001F4, tailchk=0x01000000, checksum=0x0113)
Confirm patch: File 1 Block 500 (E:\dbf\system.aix-11202)? [Y/YES]: Y
Patched: File 1 Block 500 (E:\dbf\system.aix-11202)

9. 数据库诊断

9.1 get_dhr

读取当前加载的每个数据文件的 block 1(数据文件头),解析数据库元数据并生成 数据文件头报告(Get Datafile Header Report)。报告同时输出到屏幕,并写入 dhr_<YYYYMMDD_HHMMSS>.txt。

OBET> get_dhr
===============================================
get_dhr Get Datafile Header Report
Started: 2026-08-12 15:10:00
Block Size: 8192 bytes
Endian:     little-endian (x86)
===============================================
No  Path                                         DBName/DBID    Version  Ts#/TsName     File#/Rfile#  Size(DB/OS)  Create_Info           CheckPoint_Info        Fuzzy  Thread#/Seq#  Rlogs_SCN
--  ----                                         -------------  -------- -------------  -------------  -------------  -------------  --------------------  -------------------  -----  -------------  ----------
1   e:/cc/obet/dbf/system01.dbf                  ORCL/1248591446  0A200100  0/SYSTEM         1/1           590MB/OK      2005-08-30 13:50:22   2011-04-18 14:56:29  OK     1/351          534907

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
OBET> parse_ctl E:\ORADATA\ORCL\CONTROL01.CTL
Oracle Control File Parser
==============================================
File: E:\ORADATA\ORCL\CONTROL01.CTL
Size: 9781248 bytes (597 x 16KB blocks)
==============================================
        PARSE RESULTS
==============================================
--- Database Info ---
  DB_NAME    : ORCL
  CHARSET_ID : 852 (ZHS16GBK)
--- Data Files (type=04) - 9 found ---
---------------------------------------------
  FILE#  PATH
  -----  ----
  4     E:\ORADATA\ORCL\USERS01.DBF
  3     E:\ORADATA\ORCL\UNDOTBS01.DBF
  2     E:\ORADATA\ORCL\SYSAUX01.DBF
  1     E:\ORADATA\ORCL\SYSTEM01.DBF
--- Log Files (type=03) - 3 found ---
---------------------------------------
  GROUP  PATH                                  SIZE
  -----  ----                                  ----
  1      E:\ORADATA\ORCL\REDO01.LOG         524288000
  2      E:\ORADATA\ORCL\REDO02.LOG         524288000
  3      E:\ORADATA\ORCL\REDO03.LOG         524288000
--- Tablespaces - 8 found ---

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

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

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

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

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

Control file rebuild SQL generated: rectl_ORCL_20260727151150.sql

9.3 rdba <hex> TOOL>

把 RDBA 值拆解为 Oracle File# 和 Block#(高 10 位 = File#,低 22 位 = Block#)。仅在 TOOL> 子模式下可用。

TOOL> rdba 0x00400000
rdba 0x00400000 (4194304)
File#: 1
Block#: 0

9.4 getrdba <rfile#> <block#> TOOL>

根据 rfile# 和 block# 计算 RDBA 值(rdba 的逆运算)。仅在 TOOL> 子模式下可用。

TOOL> getrdba 1 1
getrdba:
  rfile#: 1
  block#: 1
  RDBA:   0x00400001 (4194305)

9.5 tool

进入 TOOL> 子模式。提示符从 OBET> 切换为 TOOL>,接受 RDBA 编解码 + RowID 编解码 + Oracle 时间值转换六个无副作用命令。子模式下 exit / quit 返回 OBET>(不退出进程)。

OBET> tool
=============================================
Entered TOOL> sub-mode (rdba / getrdba / rowid / getrowid / time / gettime)
Type 'help' for command list, 'exit' or 'quit' to return to OBET>
=============================================
TOOL> help

  [TOOL Mode]
  rdba                           - Parse RDBA value to File# and Block# (e.g., rdba 0xFEDCBA12)
  getrdba             - Calculate RDBA from rfile# and block# (e.g., getrdba 1 500)
  rowid        - Parse 18-char Restricted RowID (e.g., rowid AAAAAB.AAB.AAAAAB.AAB)
  getrowid      - Build RowID from components (e.g., getrowid 1 1 1 1)
  time                       - Convert Oracle time value to 'yyyy-mm-dd hh:mi:ss'
                                        hex: 0x prefix required (e.g., time 0x1A2B3C4D)
                                        dec: plain number (e.g., time 1234567890)
  gettime        - Convert date string to Oracle time value
                                        outputs decimal + 0x hex (e.g., gettime 2026-08-24 12:11:38)
  help                                - Show this help message
  exit / quit                         - Return to OBET> mode (NOT exit program)

TOOL> time 0
1988-01-01 00:00:00
TOOL> gettime 2026-08-24 12:11:38
Decimal: 1242130298
Hex:     0x4A09677A
TOOL> exit
Returned to OBET> mode. Type 'quit' or 'exit' to exit OBET.
OBET>

9.6 rowid <OOOOOO.FFF.BBBBBB.RRR> TOOL>

把 18 字符 Oracle Restricted RowID 解析为各分量:data object# / relative file# / block# / slot#,并给出由 file# + block# 推导的 DBA。仅在 TOOL> 子模式下可用。

两种形式均可(回显统一为带点形式):OOOOOO.FFF.BBBBBB.RRR(21 字符,规范)或裸 OOOOOOOOOFBBBBBBBRRRR(18 字符,无点)。

编码布局(MSB-first base64,字符集 A-Za-z0-9+/):

段字符位数取值范围布局
OOOOOO636(用 32)object# 0 – 232-1高 4 bit = 0,低 32 bit = object#
FFF318(用 10)file# 0 – 1023高 8 bit = 0,低 10 bit = file#
BBBBBB636(用 22)block# 0 – 4,194,303高 14 bit = 0,低 22 bit = block#
RRR318(用 16)slot# 0 – 65535高 2 bit = 0,低 16 bit = slot#

DBA = (file# << 22) | block#,与 rdba / getrdba 一致。

TOOL> rowid AAAAAB.AAB.AAAAAB.AAB
rowid 'AAAAAB.AAB.AAAAAB.AAB':
  Object#: 1
  File#:   1  (relative file#, within tablespace)
  Block#:  1
  Slot#:   1  (row# within block)
  DBA:     0x00400001 (4194305)
Bigfile 表空间的 FFF 段恒为 AAA(file#=0)。分区表的 OOOOOO 取分区 object#(非表 object#)。IOT 溢出行的 UROWID 不是 base64,本命令不适用。

9.7 getrowid <object#> <file#> <block#> <row#> TOOL>

由各分量拼出 18 字符 Oracle Restricted RowID(rowid 的逆运算)。仅在 TOOL> 子模式下可用。

输出为裸 18 字符 base64(无点);可直接喂回 rowid 做逆运算。

TOOL> getrowid 1 1 1 1
getrowid:
  Object#: 1
  File#:   1
  Block#:  1
  Row#:    1
  RowID:   AAAAABAABAAAAABAAB

TOOL> getrowid 0 1023 4194303 65535
getrowid:
  Object#: 0
  File#:   1023
  Block#:  4194303
  Row#:    65535
  RowID:   AAAAAAAAP/AAP///P//

TOOL> getrowid 0 1024 1 1
Error: file# 1024 exceeds 10-bit limit (max 1023). For bigfile tablespace pass 0.
rowid 与 getrowid 完全互逆,getrowid O F B R → rowid → O F B R 在上述取值范围内 roundtrip 一致。

9.8 time <hex\|dec> TOOL>

把 Oracle 时间值转换为 yyyy-mm-dd hh:mi:ss。编码规则与 get_dhr 中打印的 Creation time / Checkpoint time 一致:1 年 = 12×31×86400s = 32140800s;月日固定 31 天;起点 1988-01-01 00:00:00。仅在 TOOL> 子模式下可用。

TOOL> time 0
1988-01-01 00:00:00
TOOL> time 0xFFFFFFFF
2121-08-18 06:28:15
TOOL> time 1234567890
2026-05-29 23:31:30

9.9 gettime <yyyy-mm-dd hh:mi:ss> TOOL>

把日期字符串转换为 Oracle 时间值。输出两行:十进制 + 0x 前缀十六进制。仅在 TOOL> 子模式下可用。

编码与 SQL 对齐:(year-1988)×12×31×86400 + (month-1)×31×86400 + (day-1)×86400 + hour×3600 + minute×60 + second

TOOL> gettime 2026-08-24 12:11:38
Decimal: 1242130298
Hex:     0x4A09677A
TOOL> gettime 1988-01-01 00:00:00
Decimal: 0
Hex:     0x0
time 与 gettime 完全互逆,roundtrip 测试 time V → gettime → V 在 uint32 范围内成立。

9.10 dump_undo [file N] [block M]

从 undo$ 段读取每条 UNDO 记录的 name 和 status$。默认 file 1 block 224(Oracle 某些版本 undo$ segment header 位置)。

OBET> dump_undo
OBET> dump_undo file 1 block 224
OBET> dump_undo file 1 block 224
==================================================
  DUMP UNDO$ - File#=1 (E:/CC/obet/dbf/SYSTEM01.DBF), Block=224
==================================================
Segment header kcbh.rdba=0x004000E0 => Oracle file#=1, block#=224 (listfile idx=1)
Reading undo$ segment header from file #1, block 224...
Segment header first 16 bytes (kcbh): 10 A2 00 00 E0 00 40 00 1A 02 00 00 00 00 01 04 
Found extent 0: rdba_block=225, size=7 blocks (covers blocks 225-231)
Data blocks to scan (7 total): 225 226 227 228 229 230 231 
US#=0    NAME=SYSTEM                          STATUS$=3  TS#=0   (system rollback segment)
US#=1    NAME=_SYSSMU1_3450900144$            STATUS$=2  TS#=2
US#=2    NAME=_SYSSMU2_2386332601$            STATUS$=2  TS#=2
...
Summary: scanned 7 blocks, extracted 21 rows from undo$.

9.11 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

显示当前许可证状态、硬件ID、到期时间。

OBET> license
========================================
         OBET License Information
========================================
Your Hardware ID: F443C4B31A04E56FDC6D9310C1648AC700946AC5269DF2F6DBE8507FDC704812
License Status: AUTHORIZED
Expiry Time:    2030-01-01 23:00:00

10.2 spool <file> | off

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

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

10.3 host <OS 命令>

直接在 OBET 提示符下执行操作系统命令。Windows 下走 cmd /c,Linux 下走 sh -c,不需要授权、不需要编辑模式,是便利性的"逃生口"命令。

OBET> host
Usage: host 
  host dir            - run 'dir' on Windows, 'ls' on Linux
  host ipconfig       - run network config command

OBET> host cmd /c "echo OBET_HOST_OK"
[host] running: cmd /c "echo OBET_HOST_OK"
OBET_HOST_OK
[host] exit code: 0

OBET> host dir
[host] running: dir
... (Windows dir 输出)
[host] exit code: 0
宿主命令不做 shell 转义,参数原样传给 system()。输出不写入 spool 文件(与 OBET 主进程 stdout 直通),执行完会回显退出码。

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 子句)切换。单文件调试时也可直接 set filename <path>。

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

授权与当前主机 HWID 绑定、存在有效期。用 license 命令查看当前授权状态,联系维护者重新签发 license.dat。

Q4:forcecopy 与普通拷贝区别?

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

forcecopy file 的源是已加载的数据文件(按 blocksize 分块);forcecopy disk 的源是裸设备(整盘 / 分区,按 4K 颗粒),后者在一个 4K 读失败时会拆到扇区级重试,只把真正损坏的扇区填零,数据损失更小。

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

print 仅支持一级字段访问(如 p kcvfh.kcvfhhdr),不支持二级(如 p kcvfh.kcvfhhdr.kccfhtyp)。

Q6:build block 和 repair block 区别?

build block N,M 是从无到有构造一个 Oracle 空块(填 0x00 + 初始化 kcbh/rdba),写入目标文件时需人工确认覆盖;适合块数据完全丢失的场景。

repair block 是读取目标块后原地修复 seq_kcbh、tailchk、checksum 三项,不改变块内容本身;适合块内容完好但校验值损坏的场景。