MongoDB 离线提取工具—mongoext

在某些情况下,由于断电、硬件故障、软件bug等导致mongodb数据库无法正常启动,甚至使用repair依然无法启动,对于这样的情况.我专门开发了mongodb离线提取工具mongoext,在离线情况下直接提取mongodb的数据
整体命令支持

G:\mongodb\mongoext>mongoext.exe -h
usage: mongoext [-h] {scan,recover,info} ...

脱机 MongoDB 数据文件提取工具

positional arguments:
  {scan,recover,info}
    scan               扫描 dbPath 并导出
    recover            恢复孤立的单个 collection 文件(无 catalog)
    info               打印 dbPath 元信息

options:
  -h, --help           show this help message and exit

scan 是基于mongodb字典直接提取数据
recover是直接恢复单个集合文件中数据
info是获取字典信息以及集合对应关系

mongoext scan 命令介绍

G:\mongodb\mongoext>mongoext.exe scan -h
usage: mongoext scan [-h] [--db DB] [--collection COLLECTION] [--include-system] [--out OUT]
                     [--format {jsonl,sql,bson,mongo}] [--uri URI] [--batch BATCH] [--no-indexes] [--ttl-indexes]
                     [--keep-existing] [--sql-dialect {postgres,mysql}] [--dedup] [--no-progress] [--dry-run]
                     [--allocation-size ALLOCATION_SIZE]
                     dbpath

positional arguments:
  dbpath                dbPath 路径

options:
  -h, --help            show this help message and exit
  --db DB               只导出指定数据库
  --collection COLLECTION
                        只导出指定集合
  --include-system      连 admin/config/local 也一起导入(默认跳过,会污染目标实例)
  --out OUT             输出目录(--format mongo 时不需要)
  --format {jsonl,sql,bson,mongo}
                        输出格式;mongo = 直接写入运行中的 mongod(BSON 类型保真)
  --uri URI             --format mongo 的目标连接串
  --batch BATCH         --format mongo 每批 insert_many 的条数
  --no-indexes          --format mongo 导入后不重建索引
  --ttl-indexes         --format mongo 连 TTL 索引也重建(默认不建:建了会立刻按过期时间删数据)
  --keep-existing       --format mongo 不 drop 目标集合,追加写入
  --sql-dialect {postgres,mysql}
                        SQL 方言
  --dedup               按 _id 去重(多版本 leaf page 残留时开启)
  --no-progress         关闭 tqdm 进度条
  --dry-run             只统计不写盘,用于核对提取完整性与文档计数
  --allocation-size ALLOCATION_SIZE
                        手工指定块对齐粒度(默认从 turtle / 元数据读,读不到才穷举探测)

mongoext-scan


mongoext recover命令介绍

G:\mongodb\mongoext>mongoext.exe recover -h
usage: mongoext recover [-h] [--orphans DBPATH] [--db DB] [--collection COLLECTION] [--meta-dir META_DIR] [--out OUT]
                        [--format {jsonl,sql,bson,mongo}] [--uri URI] [--batch BATCH] [--no-indexes] [--ttl-indexes]
                        [--keep-existing] [--sql-dialect {postgres,mysql}] [--dedup] [--no-progress] [--dry-run]
                        [--allocation-size ALLOCATION_SIZE]
                        [wt_file]

positional arguments:
  wt_file               孤立的 collection-*.wt 文件

options:
  -h, --help            show this help message and exit
  --orphans DBPATH      批量恢复该 dbPath 里 catalog 未记录的 collection 文件
  --db DB               手工指定库名(与 --collection 一起用)
  --collection COLLECTION
                        手工指定集合名(与 --db 一起用)
  --meta-dir META_DIR   伴生文件(turtle / _mdb_catalog.wt / WiredTiger.wt)所在目录,用来反查 namespace;
                        文件已拷走但原 dbPath 还在时指过去即可
  --out OUT             输出目录(--format mongo 时不需要)
  --format {jsonl,sql,bson,mongo}
                        输出格式;mongo = 直接写入运行中的 mongod(BSON 类型保真)
  --uri URI             --format mongo 的目标连接串
  --batch BATCH         --format mongo 每批 insert_many 的条数
  --no-indexes          --format mongo 导入后不重建索引
  --ttl-indexes         --format mongo 连 TTL 索引也重建(默认不建:建了会立刻按过期时间删数据)
  --keep-existing       --format mongo 不 drop 目标集合,追加写入
  --sql-dialect {postgres,mysql}
                        SQL 方言
  --dedup               按 _id 去重(多版本 leaf page 残留时开启)
  --no-progress         关闭 tqdm 进度条
  --dry-run             只统计不写盘,用于核对提取完整性与文档计数
  --allocation-size ALLOCATION_SIZE
                        手工指定块对齐粒度(默认从 turtle / 元数据读,读不到才穷举探测)

mongoext-recover


常使用命令说明

# 看库结构
mongoext.exe info DBPATH

# 只统计不写盘
mongoext.exe scan DBPATH --out ./out --dry-run --dedup

# 全库导 JSON Lines(人看 / 给别的程序吃)
mongoext.exe scan DBPATH --out ./out --format jsonl --dedup

# 全库导 BSON(给 mongorestore 用)
mongoext.exe scan DBPATH --out ./out --format bson --dedup

# 全库导 SQL
mongoext.exe scan DBPATH --out ./out --format sql --sql-dialect mysql --dedup

# 保真导入运行中的 MongoDB(推荐路径)
mongoext.exe scan DBPATH --format mongo --dedup

# 只导一个集合
mongoext.exe scan DBPATH --format mongo --db mydb --collection users --dedup

# 导到远程实例
mongoext.exe scan DBPATH --format mongo \
    --uri "mongodb://user:pass@host:27017/?authSource=admin" --dedup

# 恢复孤立的单个 collection 文件(无 dbPath / 无 catalog)
mongoext.exe recover FILE.wt --dry-run --dedup          # 先看探测结论
mongoext.exe recover FILE.wt --db mydb --collection users --format mongo --dedup
mongoext.exe recover FILE.wt --meta-dir /原/dbPath --format mongo --dedup

# 批量恢复一个 dbPath 里的孤儿文件
mongoext.exe recover --orphans DBPATH --out ./out --dedup
发表在 MongoDB, MongoDB恢复 | 标签为 , , , | 留下评论

.bres勒索病毒加密数据库dmp文件可恢复

近期.bres勒索病毒较多,加密文件名称一般为:原始文件名.id.bres
bres_jm


勒索信息为:id.readme文件
bres_readme

一般是勒索5000或者7500美元.通过我们对加密的oracle数据库文件和dmp的逻辑备份分析,确认该病毒对于两种类型的文件破坏比例不一样
一、对于bres勒索病毒数据库层面恢复探讨
1. 对于dbf/ora类型文件破坏比例非常大,达到1/3左右,而且还是间隔加密,对于这种情况,基于数据库文件基本上没有太大恢复价值,但是我们也遇到一些客户,由于某些原因导致这类病毒加密文件没有全部完成(数据文件被加密中途终止),这样的情况下,可以恢复没有被破坏的block中数据.
bres_dbf

2.对于exp/expdp备份出来的dmp文件,该病毒一般只是加密前面30M的block,后续其他block全部是完整的,可以恢复出来后续数据,整体数据丢失较少,如果有历史完整的备份,可以实现较为完整的恢复效果
bres2

二、病毒入侵渠道与内网扩散逻辑
.bres病毒主要有四类入侵入口,其中内网共享权限漏洞是最高发渠道。
第一,共享存储与NAS弱口令入侵。工贸企业、工程公司大量使用NAS存放图纸、合同,为方便异地办公,直接开放外网访问,账号密码长期不修改。黑客会批量扫描公网设备,尝试默认密码登录,拿到权限后植入后门程序,长期潜伏在内网。这也是.bres最标志性的入侵方式,区别于其他病毒以钓鱼邮件为主要入口。
第二,钓鱼邮件投递。伪装成供应商对账函、项目验收单、物流通知单,压缩包内放置恶意程序。员工解压运行之后,木马悄悄植入电脑,建立持久后门,为后续内网横向扩散铺路。
第三,RDP远程桌面爆破。部分小微企业为远程管理服务器,3389端口对外暴露,使用简单密码。黑客利用工具批量爆破账号密码,登陆服务器投放病毒载荷。
第四,根据我们近期恢复的一些case,大量是同一个软件厂商的软件在不同客户现场几乎同一时间被勒索加密,怀疑可能是由于应用某组件有漏洞被黑客利用进行攻击,建议加强应用版本管理,及时更新应用修复漏洞。

发表在 勒索恢复 | 标签为 | 留下评论

ORA-600 krsm_mrp_rebuild_lf_list.lno_mismatch

客户由于断电,导致一个19c数据库无法正常启动,接手时候报错为:ORA-600 krsm_mrp_rebuild_lf_list.lno_mismatch

2026-09-15T06:36:24.908317-07:00
ALTER DATABASE OPEN RESETLOGS
2026-09-15T06:36:24.912251-07:00
RESETLOGS is being done without consistancy checks. This may result
in a corrupted database. The database should be recreated.
RESETLOGS after incomplete recovery UNTIL CHANGE 22297188690 time 
NET  (PID:36760): Unable to create archive log file '/u19/dbs/arch1_1_1243990641.dbf'
2026-09-15T06:36:24.919696-07:00
Errors in file /u19/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_36760.trc:
ORA-19504: failed to create file "/u19/dbs/arch1_1_1243990641.dbf"
ORA-27038: created file already exists
Additional information: 1
NET  (PID:36760): Error 19504 Creating archive log file to '/u19/app/dbs/arch1_1_1243990641.dbf'
NET  (PID:36760): Archiving not possible: error count exceeded
Errors in file /u19/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_36760.trc  (incident=119876):
ORA-00600: internal error code, arguments: [krsm_mrp_rebuild_lf_list.lno_mismatch], [3], [1], [1], [0], []
Incident details in: /u19/app/oracle/diag/rdbms/orcl/orcl/incident/incdir_119876/orcl_ora_36760_i119876.trc
Use ADRCI or Support Workbench to package the incident.
See Note 411.1 at My Oracle Support for error and packaging details.
NET  (PID:36760): Archive all ORLs failed, error=600
ORA-600 signalled during: ALTER DATABASE OPEN RESETLOGS...

通过alert日志大概回溯现场人员的恢复过程,最初数据库断电重启之后报ORA-00742错误

2026-09-14T20:52:37.294285-07:00
ALTER DATABASE OPEN
Ping without log force is disabled:
  instance mounted in exclusive mode.
2026-09-14T20:52:37.313266-07:00
Beginning crash recovery of 1 threads
 Thread 1: Recovery starting at checkpoint rba (logseq 63111 block 286483), scn 0
2026-09-14T20:52:37.370330-07:00
Started redo scan
2026-09-14T20:52:37.419944-07:00
Aborting crash recovery due to error 742
2026-09-14T20:52:37.420039-07:00
Errors in file /u19/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_68055.trc:
ORA-00742: Log read detects lost write in thread 1 sequence 63111 block 326157
ORA-00312: online log 3 thread 1: '/u19/app/oracle/oradata/ORCL/redo03.log'
2026-09-14T20:52:37.420977-07:00
Errors in file /u19/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_68055.trc:
ORA-00742: Log read detects lost write in thread 1 sequence 63111 block 326157
ORA-00312: online log 3 thread 1: '/u19/app/oracle/oradata/ORCL/redo03.log'
ORA-742 signalled during: ALTER DATABASE OPEN...

现场人员加上隐含参数强制拉库,然后数据库报ORA-600 kcbzib_kcrsds_1错误

2026-09-14T21:35:21.425310-07:00
ALTER DATABASE OPEN RESETLOGS
2026-09-14T21:35:21.429136-07:00
RESETLOGS is being done without consistancy checks. This may result
in a corrupted database. The database should be recreated.
RESETLOGS after incomplete recovery UNTIL CHANGE 22297188666 time 
Resetting resetlogs activation ID 1680209845 (0x6425f7b5)
2026-09-14T21:35:34.017515-07:00
Setting recovery target incarnation to 3
2026-09-14T21:35:34.028360-07:00
Ping without log force is disabled:
  instance mounted in exclusive mode.
Endian type of dictionary set to little
2026-09-14T21:35:34.043771-07:00
Assigning activation ID 1771732361 (0x699a7d89)
2026-09-14T21:35:34.125473-07:00
TT00 (PID:47466): Gap Manager starting
2026-09-14T21:35:34.127554-07:00
Redo log for group 1, sequence 1 is not located on DAX storage
Thread 1 opened at log sequence 1
  Current log# 1 seq# 1 mem# 0: /u19/app/oracle/oradata/ORCL/redo01.log
Successful open of redo thread 1
2026-09-14T21:35:34.165332-07:00
MTTR advisory is disabled because FAST_START_MTTR_TARGET is not set
stopping change tracking
2026-09-14T21:35:35.507453-07:00
ORA-00600: internal error code, arguments: [kcbzib_kcrsds_1],  , [], [], [], [], []
Use ADRCI or Support Workbench to package the incident.
See Note 411.1 at My Oracle Support for error and packaging details.
SYSTEM DUMP REDO DBA MIN 4 128 DBA MAX 4 128 SCN MIN 1;
2026-09-14T21:35:37.154962-07:00
*****************************************************************
An internal routine has requested a dump of selected redo.
This usually happens following a specific internal error, when
analysis of the redo logs will help Oracle Support with the
diagnosis.
It is recommended that you retain all the redo logs generated (by
all the instances) during the past 12 hours, in case additional
redo dumps are required to help with the diagnosis.
*****************************************************************
Undo initialization recovery: err:600 start: 3433752 end: 3435865 diff: 2113 ms (2.1 seconds)
2026-09-14T21:35:37.475752-07:00
Errors in file /u19/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_46217.trc:
ORA-00600: internal error code, arguments: [kcbzib_kcrsds_1],  , [], [], [], [], []
2026-09-14T21:35:37.475831-07:00
Errors in file /u19/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_46217.trc:
ORA-00600: internal error code, arguments: [kcbzib_kcrsds_1],  , [], [], [], [], []
Error 600 happened during db open, shutting down database
Errors in file /u19/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_46217.trc  (incident=48128):
ORA-00603: ORACLE server session terminated by fatal error
ORA-01092: ORACLE instance terminated. Disconnection forced
ORA-00600: internal error code, arguments: [kcbzib_kcrsds_1],  , [], [], [], [], []

现场人员重建控制文件,然后启动库报ORA-600 krsm_mrp_rebuild_lf_list.lno_mismatch

2026-09-15T04:26:41.297637-07:00
Successful mount of redo thread 1, with mount id 1771762176
Completed: CREATE CONTROLFILE REUSE SET DATABASE "ORCL" RESETLOGS ARCHIVELOG
    MAXLOGFILES 16
    MAXLOGMEMBERS 3
    MAXDATAFILES 100
    MAXINSTANCES 1
    MAXLOGHISTORY 16
LOGFILE
  GROUP 1 '/u19/app/oracle/oradata/ORCL_NEW/redo01.log' SIZE 200M,
  GROUP 2 '/u19/app/oracle/oradata/ORCL_NEW/redo02.log' SIZE 200M
DATAFILE
  '/u19/app/oracle/oradata/ORCL_NEW/system01.dbf',
  '/u19/app/oracle/oradata/ORCL_NEW/sysaux01.dbf',
  '/u19/app/oracle/oradata/ORCL_NEW/undotbs01.dbf',
…………
2026-09-15T04:26:52.121793-07:00
ALTER DATABASE OPEN RESETLOGS
2026-09-15T04:26:52.126848-07:00
RESETLOGS is being done without consistancy checks. This may result
in a corrupted database. The database should be recreated.
RESETLOGS after incomplete recovery UNTIL CHANGE 22297188686 time 
NET  (PID:27130): Unable to create archive log file '/u19/dbs/arch1_1_1243990641.dbf'
2026-09-15T04:26:52.233538-07:00
Errors in file /u19/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_27130.trc:
ORA-19504: failed to create file "/u19/dbs/arch1_1_1243990641.dbf"
ORA-27038: created file already exists
Additional information: 1
NET  (PID:27130): Error 19504 Creating archive log file to '/u19/dbs/arch1_1_1243990641.dbf'
NET  (PID:27130): Archiving not possible: error count exceeded
Errors in file /u19/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_27130.trc  (incident=102102):
ORA-00600: internal error code, arguments: [krsm_mrp_rebuild_lf_list.lno_mismatch], [2], [1], [1], [0], []
Incident details in: /u19/app/oracle/diag/rdbms/orcl/orcl/incident/incdir_102102/orcl_ora_27130_i102102.trc

接手故障开始处理,尝试open库,重现ORA-600 krsm_mrp_rebuild_lf_list.lno_mismatch错误

SQL> recover database using backup controlfile;
ORA-00279: change 22297188689 generated at 09/15/2026 00:57:22 needed for thread 1
ORA-00289: suggestion : /u19/dbs/arch/1_1_1243990641.dbf
ORA-00280: change 22297188689 for thread 1 is in sequence #1


Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/u19/app/oracle/oradata/ORCL/redo01.log
Log applied.
Media recovery complete.
SQL>        
SQL> 
SQL> alter database open resetlogs;
alter database open resetlogs
*
ERROR at line 1:
ORA-00600: internal error code, arguments: [krsm_mrp_rebuild_lf_list.lno_mismatch], [3], [1], [1], [0]

分析alert日志,是由于归档无法被正常创建导致该问题,对/u19/dbs/arch/进行创建并授权之后,再次尝试打开数据库,数据库报ORA-600 kcbzib_kcrsds_1错误

SQL> startup nomount pfile='/tmp/pfile';
ORACLE instance started.

Total System Global Area       6442448984 bytes
Fixed Size			  8910936 bytes
Variable Size		       3858759680 bytes
Database Buffers	       2566914048 bytes
Redo Buffers			  7864320 bytes
SQL> alter database mount;

Database altered.

SQL> alter database open resetlogs;
alter database open resetlogs
*
ERROR at line 1:
ORA-00603: ORACLE server session terminated by fatal error
ORA-01092: ORACLE instance terminated. Disconnection forced
ORA-00600: internal error code, arguments: [kcbzib_kcrsds_1], [], [], [], []
Process ID: 42259
Session ID: 1 Serial number: 19675

使用obet的patch scn功能修改scn之后(obet patch_scn使用说明),顺利打开库
patch_scn
open


发表在 Oracle备份恢复 | 标签为 , , | 留下评论