误删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 ]
六、总结与注意事项
文章
阅读量
获赞
