注册
误删redo日志恢复实践
专栏/技术分享/ 文章详情 /

误删redo日志恢复实践

du_13 2026/10/23 142 0 0
摘要

误删redo日志恢复实践——通过重建实例+修改魔数恢复
一、说明
Redo log 记录了数据库中物理数据页的变更,既包括已提交的也包括未提交事务的数据修改,在事务提交后数据库会按一定的时机进行日志归档和数据刷盘。如果 redo 日志文件被误删除,会导致数据库无法启动,严重时还会造成数据丢失。
在误删 redo 文件后,通常有两种恢复思路:
1.通过数据库备份集还原:如果生产环境开启了归档日志并配置了定时物理备份(全备+增量),优先使用备份集还原,数据最完整。
2.重新初始化实例并替换 redo 文件:如果没有备份或备份集不可用,可以新建一个同参数的实例,将其生成的 redo 日志文件拷贝到故障实例目录,再通过 dmmdf 工具修改 redo 文件中的 db_magic(数据库魔数)和 pemnt_magic(永久魔数)等参数,使其与故障库的数据文件头一致,从而绕过 redo 魔数校验完成启动。此方法可能会丢失部分已提交但未刷盘的数据。
本文采用第二种方式,完整记录一次从零开始的实操过程。
二、环境准备与问题复现
2.1 初始化第一个参考实例(DAMENG)
首先初始化一个基础实例作为后续 redo 文件的来源:

[dmdba@192 ~]$ /dmdbms/bin/dminit PATH=/dmdata PORT_NUM=15236 PAGE_SIZE=32 EXTENT_SIZE=32 LOG_SIZE=2048 CHARSET=0 CASE_SENSITIVE=Y SYSDBA_PWD=Dameng@1234 SYSAUDITOR_PWD=Dameng@1234 RLOG_POSTFIX_NAME=redo
输出如下:
initdb V8
db version: 0x7000d
Normal of FAST
Normal of DEFAULT
Normal of RECYCLE
Normal of KEEP
Normal of ROLL
 
 log file path: /dmdata/DAMENG/DAMENG01.redo
 
 
 log file path: /dmdata/DAMENG/DAMENG02.redo
 
write to dir [/dmdata/DAMENG].
create dm database success. 2026-09-18 18:16:35

2.2 初始化故障实例(DM)
再初始化一个同参数的实例,作为本次实验的“故障库”:

[dmdba@192 ~]$ /dmdbms/bin/dminit PATH=/dmdata PORT_NUM=15236 PAGE_SIZE=32 EXTENT_SIZE=32 LOG_SIZE=2048 CHARSET=0 CASE_SENSITIVE=Y SYSDBA_PWD=Dameng@1234 SYSAUDITOR_PWD=Dameng@1234 RLOG_POSTFIX_NAME=redo DB_NAME=DM INSTANCE_NAME=DM
输出如下:
initdb V8
db version: 0x7000d
Normal of FAST
Normal of DEFAULT
Normal of RECYCLE
Normal of KEEP
Normal of ROLL
 
 log file path: /dmdata/DM/DM01.redo
 
 
 log file path: /dmdata/DM/DM02.redo
 
write to dir [/dmdata/DM].
create dm database success. 2026-09-18 18:18:47

2.3 启动故障实例并注册系统服务
启动 DM 实例:

[dmdba@192 ~]$ cd /dmdbms/bin
[dmdba@192 bin]$ ./DmServiceDM start
Starting DmServiceDM:                                      [ OK ]
确认实例进程已正常拉起:
[dmdba@192 bin]$ ps ux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
dmdba       1463  0.0  0.1 144336  5080 ?        Sl   17:24   0:00 /dmdbms/bin/dmap dmap_ini=/dmdbms/bin/dmap.ini
dmdba       5250  0.1  0.1 223672  5052 pts/0    S    18:07   0:00 -bash
dmdba       5984 58.3 23.6 6702028 703932 pts/0  Sl   18:19   0:11 /dmdbms/bin/dmserver path=/dmdata/DM/dm.ini -noconsole

查看故障实例数据目录:

[dmdba@192 bin]$ cd /dmdata/DM/
[dmdba@192 DM]$ ll
总用量 4814956
drwxr-xr-x 2 dmdba dinstall          6  9月 18 18:18 bak
drwxr-xr-x 2 dmdba dinstall         78  9月 18 18:19 ctl_bak
-rw-r--r-- 1 dmdba dinstall 2147483648  9月 18 18:19 DM01.redo
-rw-r--r-- 1 dmdba dinstall 2147483648  9月 18 18:19 DM02.redo
-rw-r--r-- 1 dmdba dinstall       5632  9月 18 18:19 dm.ctl
-rw-r--r-- 1 dmdba dinstall      84439  9月 18 18:18 dm.ini
-rw-r--r-- 1 dmdba dinstall        903  9月 18 18:18 dminit20260918181846.log
-rw-r--r-- 1 dmdba dinstall        633  9月 18 18:18 dm_service.prikey
-rw-r--r-- 1 dmdba dinstall       3072  9月 18 18:19 dmtemp.ctl
drwxr-xr-x 2 dmdba dinstall          6  9月 18 18:18 HMAIN
-rw-r--r-- 1 dmdba dinstall  134217728  9月 18 18:18 MAIN.DBF
-rw-r--r-- 1 dmdba dinstall  134217728  9月 18 18:19 ROLL.DBF
-rw-r--r-- 1 dmdba dinstall        714  9月 18 18:18 sqllog.ini
-rw-r--r-- 1 dmdba dinstall 289406976  9月 18 18:19 SYSTEM.DBF
-rw-r--r-- 1 dmdba dinstall  77594624  9月 18 18:19 TEMP.DBF
drwxr-xr-x 2 dmdba dinstall          6  9月 18 18:19 trace

2.4 注册另一个实例的系统服务(DMSERVER)
切换到 root 用户,为 DAMENG 实例注册系统服务:

[root@192 DM]# /dmdbms/script/root/dm_service_installer.sh -t dmserver -dm_ini /dmdata/DAMENG/dm.ini -p DMSERVER
Created symlink /etc/systemd/system/multi-user.target.wants/DmServiceDMSERVER.service → /usr/lib/systemd/system/DmServiceDMSERVER.service.

创建服务(DmServiceDMSERVER)完成
2.5 模拟误删 redo 日志
先停掉 DM 实例:

[dmdba@192 ~]$ su - dmdba
[dmdba@192 ~]$ cd /dmdbms/bin
[dmdba@192 bin]$ ./DmServiceDM stop
Stopping DmServiceDM:                                   [OK]

进入故障实例目录,将 redo 日志文件移走(模拟误删):

[dmdba@192 bin]$ cd /dmdata/DM/
[dmdba@192 DM]$ mkdir -p redo
[dmdba@192 DM]$ mv DM01.redo redo/
[dmdba@192 DM]$ mv DM02.redo redo/

此时 redo 文件已不在原始位置,数据库若直接启动会因找不到 redo 日志而报错。
三、准备新的 redo 日志文件
3.1 停掉 DM 实例

[dmdba@192 DM]$ cd /dmdbms/bin
[dmdba@192 bin]$ ./DmServiceDM stop
Stopping DmServiceDM:                                  [OK ]

3.2 从参考实例拷贝 redo 文件
查看参考实例 DAMENG 目录下的 redo 文件:

[dmdba@192 bin]$ cd /dmdata/DAMENG/
[dmdba@192 DAMENG]$ ll
总用量 4814956
drwxr-xr-x 2 dmdba dinstall          6  9月 18 18:16 bak
drwxr-xr-x 2 dmdba dinstall         78  9月 18 18:21 ctl_bak
-rw-r--r-- 1 dmdba dinstall 2147483648  9月 18 18:21 DAMENG01.redo
-rw-r--r-- 1 dmdba dinstall 2147483648  9月 18 18:21 DAMENG02.redo
-rw-r--r-- 1 dmdba dinstall       5632  9月 18 18:21 dm.ctl
-rw-r--r-- 1 dmdba dinstall      84439  9月 18 18:16 dm.ini
-rw-r--r-- 1 dmdba dinstall        959  9月 18 18:16 dminit20260918181635.log
-rw-r--r-- 1 dmdba dinstall        633  9月 18 18:16 dm_service.prikey
-rw-r--r-- 1 dmdba dinstall       3072  9月 18 18:20 dmtemp.ctl
drwxr-xr-x 2 dmdba dinstall          6  9月 18 18:16 HMAIN
-rw-r--r-- 1 dmdba dinstall  134217728  9月 18 18:16 MAIN.DBF
-rw-r--r-- 1 dmdba dinstall  134217728  9月 18 18:21 ROLL.DBF
-rw-r--r-- 1 dmdba dinstall        714  9月 18 18:16 sqllog.ini
-rw-r--r-- 1 dmdba dinstall 289406976  9月 18 18:21 SYSTEM.DBF
-rw-r--r-- 1 dmdba dinstall  77594624  9月 18 18:20 TEMP.DBF
drwxr-xr-x 2 dmdba dinstall          6  9月 18 18:20 trace

将 DAMENG 实例的 redo 文件拷贝到故障实例 DM 目录下,并按故障实例的 redo 文件名命名:

[dmdba@192 DAMENG]$ cp DAMENG01.redo /dmdata/DM/DM01.redo
[dmdba@192 DAMENG]$ cp DAMENG02.redo /dmdata/DM/DM02.redo
确认文件已就位:
[dmdba@192 DAMENG]$ cd /dmdata/DM/
[dmdba@192 DM]$ ll
总用量 4814956
...
-rw-r--r-- 1 dmdba dinstall 2147483648  9月 18 18:24 DM01.redo
-rw-r--r-- 1 dmdba dinstall 2147483648  9月 18 18:24 DM02.redo
...

四、使用 dmmdf 工具修改 redo 魔数
4.1 查看故障库数据文件头,获取正确的 db_magic 和 pemnt_magic
新拷贝过来的 redo 文件来自另一个实例,其 db_magic 和 pemnt_magic 与故障库不一致,直接启动会因魔数校验失败而报错。首先用 dmmdf type=1 查看故障库 SYSTEM.DBF 头部信息,拿到故障库自身的魔数值:

[dmdba@192 DM]$ /dmdbms/bin/dmmdf type=1 file=/dmdata/DM/SYSTEM.DBF
dmmdf V8
**********************************************************
1 db_magic=2120165964
2 next_trxid=8009
3 pemnt_magic=897598736
4 enable_page_check=3
**********************************************************
Please input which parameter you want to change(1-4), q to quit: Q
从输出中记录两个关键值:
db_magic(数据库魔数)= 2120165964
pemnt_magic(永久魔数)= 897598736

4.2 修改 DM01.redo 的 db_magic
查看新拷贝过来的 DM01.redo 头部信息:

[dmdba@192 DM]$ /dmdbms/bin/dmmdf type=2 file=/dmdata/DM/DM01.redo
dmmdf V8
**********************************************************
1 sig = DMRLOG
2 ver = 7007
3 chksum = 63378478
4 sta = 1
5 n_magic = 7
6 db_magic = 2037500904
7 len = 2147483648
8 free = 14381056
9 clsn = 45738
10 clsn_fil = 0
11 clsn_off = 14381056
12 pemnt_magic = 58458131
13 fil_id = 0
15 next_seq = 3177
16 g_next_seq = 3177
17 arch_lsn = 0
18 arch_seq = 0
19 dbversion = 0x7000d
20 min_exec_version = V8.1.1.1
21 min_dct_version  = 4
22 p_db_magic = 0
23 n_apply_ep = 0
...
**********************************************************
可以看到新 redo 文件的 db_magic = 2037500904,与故障库的 2120165964 不一致,需要修改。选择参数 6(db_magic):
Please input the num which one you want to change, q to quit: 6
Input the new value: 2120165964
修改后再次确认:
6 db_magic = 2120165964
保存退出:
Do you want to quit and save the change to file (y/n): y
Save to file success!

4.3 修改 DM01.redo 的 pemnt_magic
接着修改 DM01.redo 的 pemnt_magic(参数 12):

[dmdba@192 DM]$ /dmdbms/bin/dmmdf type=2 file=/dmdata/DM/DM01.redo
...
Please input the num which one you want to change, q to quit: 12
Input the new value: 897598736
修改后确认:
12 pemnt_magic = 897598736
保存退出:
Do you want to quit and save the change to file (y/n): y
Save to file success!

注意:第一次修改 pemnt_magic 时如果未正确保存(未输入 y 直接回车),修改不会写入文件,需要重新进入工具再执行一次。确认保存后再次进入查看,pemnt_magic 应为 897598736。
4.4 修改 DM02.redo 的 pemnt_magic
对第二个 redo 文件 DM02.redo 执行同样的操作。先查看其头部信息:

[dmdba@192 DM]$ /dmdbms/bin/dmmdf type=2 file=/dmdata/DM/DM02.redo
dmmdf V8
**********************************************************
1 sig = DMRLOG
2 ver = 7007
3 chksum = 331851396
4 sta = 0
5 n_magic = 7
6 db_magic = 2037500904
7 len = 2147483648
8 free = 4096
9 clsn = 0
10 clsn_fil = 0
11 clsn_off = 0
12 pemnt_magic = 58458131
13 fil_id = 1
15 next_seq = 0
16 g_next_seq = 0
...
**********************************************************
修改 pemnt_magic(参数 12)为 897598736:
Please input the num which one you want to change, q to quit: 12
Input the new value: 897598736
保存退出:
Do you want to quit and save the change to file (y/n): y
Save to file success!

4.5 修改 DM02.redo 的 db_magic
再次进入 DM02.redo,修改 db_magic(参数 6)为 2120165964:

[dmdba@192 DM]$ /dmdbms/bin/dmmdf type=2 file=/dmdata/DM/DM02.redo
...
Please input the num which one you want to change, q to quit: 6
Input the new value: 2120165964
修改后确认:
6 db_magic = 2120165964
12 pemnt_magic = 897598736
保存退出:
Do you want to quit and save the change to file (y/n): y
Save to file success!

至此,两个 redo 文件的 db_magic 和 pemnt_magic 均已修改为与故障库 SYSTEM.DBF 一致的值。
五、修改 dm.ini 并启动数据库
5.1 编辑 dm.ini
根据实际需要调整 dm.ini 中的相关参数(如 PSEG_RECV、RLOG_CHECK_SPACE 等):

[dmdba@192 DM]$ vi dm.ini

5.2 前台启动数据库实例
通过前台方式启动,便于观察启动日志:

[dmdba@192 DM]$ cd /dmdbms/bin
[dmdba@192 bin]$ ./dmserver /dmdata/DM/dm.ini
version info: enterprise
csek2_vm_t = 9448
nsql_vm_t = 328
prjt2_vm_t = 176
ltid_vm_t = 216
nins2_vm_t = 1144
nset2_vm_t = 272
ndlck_vm_t = 192
ndel2_vm_t = 768
slct2_vm_t = 352
nli2_vm_t = 200
aagr2_vm_t = 304
pscn_vm_t = 416
dist_vm_t = 992
DM Database Server 64 V8 03134284368-20251209-306150-20149 startup...
Normal of FAST
Normal of DEFAULT
Normal of RECYCLE
Normal of KEEP
Normal of ROLL
Database mode = 0, oguid = 0
file lsn: 45738
ndct db load finished, code:100
ndct second level fill fast pool finished
ndct third level fill fast pool finished
ndct second level fill fast pool finished
ndct third level fill fast pool finished
ndct fill fast pool finished
pseg_set_gtv_trxid_low next_trxid in mem:[10010]
pseg recv finished
nsvr_startup end.
uthr_pipe_create, create pipe[read:11, write:12]
uthr_pipe_create, create pipe[read:13, write:14]
aud sys init success.
aud rt sys init success.
systables desc init success.
ndct_db_load_info finished, code:100.
nsvr_process_before_open begin.
nsvr_process_before_open success.
SYSTEM IS READY.

看到 SYSTEM IS READY. 即表示数据库已成功打开,redo 魔数修改生效,实例恢复完成。
5.3 前台关闭与服务方式启动
在前台启动状态下按 Ctrl+C 关闭实例,本次实验中关闭时出现了一次“非法指令 (核心已转储)”的异常:

Server is stopping...
listener closed and all sessions disconnected
adjust undo_retention & wakeup purge thread...full check point starting...
generate force checkpoint, rlog free space[4294942720], used space[16384]
checkpoint begin, used_space[16384], free_space[4294942720]...

非法指令 (核心已转储)
随后通过系统服务方式重新启动实例,验证实例可正常拉起:

[dmdba@192 bin]$ ./DmServiceDM start
Starting DmServiceDM:                                      [ OK ]

六、总结与注意事项

  1. 适用场景:本方法适用于误删/丢失 redo 日志文件、且没有可用备份集的应急恢复场景,属于“不得已”的恢复手段。
  2. 核心原理:用同参数新建实例的 redo 文件替换故障库丢失的 redo 文件,再通过 dmmdf 修改 redo 头部的 db_magic 和 pemnt_magic,使其与故障库 SYSTEM.DBF 数据文件头一致,绕过魔数一致性校验。
  3. 参数必须一致:新建实例的初始化参数(页大小 PAGE_SIZE、簇大小 EXTENT_SIZE、字符集 CHARSET、大小写敏感 CASE_SENSITIVE、REDO 大小 LOG_SIZE 等)必须与故障库完全一致,否则数据文件与日志文件格式不匹配仍无法启动。
  4. 数据丢失风险:此方法绕过了正常的日志回放与事务回滚流程,未 checkpoint 的数据、未提交事务的修改都可能丢失,仅适用于可接受少量数据丢失的应急场景。生产环境务必定期开启归档并做物理备份。
  5. 新版达梦的额外参数:对于较新版本的达梦数据库,除了修改 db_magic 和 pemnt_magic,可能还需要调整 clsn、sta 等字段,以及在 dm.ini 中临时设置 PSEG_RECV=0、RLOG_CHECK_SPACE=2 等参数辅助启动;成功启动后应将这些临时参数恢复为原值。
  6. 操作前备份:修改 redo 文件头之前,务必备份原始 redo 文件和数据文件,防止操作失误导致二次损坏。
评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服