前一段时间,某客户反馈其达梦数据库版本在升级后,在做恢复测试时出现报错"DM[-4558]:文件已存在",导致数据库恢复失败,客户使用的第三方备份软件(云信达)定期备份达梦主备集群的备库数据库,该第三方备份软件使用的是cp备份方式。该问题在之前例行恢复测试工作中并未出现过,怀疑是版本升级引入的问题。现根据该问题进行复现验证,并分析问题原因。
1、新版本问题复现
1.1、数据库版本
--03134284368-20250728-285229-20149 Pack24
1.2、数据库目录规划
数据文件目录:/data/
归档日志目录:/dmarch/
数据库软件安装目录:/home/dmdba/dmdbms/
数据库软件已提前安装
1.3、复现步骤
1.3.1、确保相关路径下无文件
rm -rf /data/* /dmarch/*
1.3.2、初始化数据库
/home/dmdba/dmdbms/bin/dminit path=/data charset=1 extent_size=32 page_size=32 DB_NAME=DAMENG sysdba_pwd=Dameng123. SYSAUDITOR_PWD=Dameng123.
/home/dmdba/dmdbms/bin/dmserver /data/DAMENG/dm.ini
1.3.3、前台启动数据库
/home/dmdba/dmdbms/bin/dmserver /data/DAMENG/dm.ini
1.3.4、新shell窗口登录数据库
/home/dmdba/dmdbms/bin/disql SYSDBA/Dameng123.:5236
1.3.5、开启数据库归档
ALTER DATABASE MOUNT;
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE ADD ARCHIVELOG 'TYPE = local, DEST =/dmarch, FILE_SIZE = 128,SPACE_LIMIT = 1024';
alter database open;
1.3.6、手动切几个归档
select checkpoint(100);
alter database archivelog current;
alter system switch logfile;
alter system switch logfile;
1.3.7、开始备份
SP_BACKUP_COPY_BEGIN();
host rm -rf /data/DAMENG1/
host rm -rf /home/dmdba/copybak
host cp -r /data/DAMENG/ /data/DAMENG1
SP_BACKUP_COPY_END('/home/dmdba/copybak');
1.3.8、修改dm.ini和控制文件路径
/home/dmdba/dmdbms/bin/dmctlcvt TYPE=1 SRC=/data/DAMENG1/dm.ctl DEST=/data/DAMENG1/dmctl.txt
sed -i 's/\/data\/DAMENG/\/data\/DAMENG1/g' /data/DAMENG1/dmctl.txt
/home/dmdba/dmdbms/bin/dmctlcvt TYPE=2 SRC=/data/DAMENG1/dmctl.txt DEST=/data/DAMENG1/dm.ctl
sed -i 's/\/data\/DAMENG/\/data\/DAMENG1/g' /data/DAMENG1/dm.ini
1.3.9、数据库恢复还原
/home/dmdba/dmdbms/bin/dmrman CTLSTMT="restore database '/data/DAMENG1/dm.ini' from backupset '/home/dmdba/copybak'"
1.3.10、报错信息
dmrman V8
restore database '/data/DAMENG1/dm.ini' from backupset '/home/dmdba/copybak'
file dm.key not found, use default license!
==============================Error Stack==============================
DM:file /data/DAMENG1/DAMENG01.log is already exist
DM[-4558]:文件已存在
=======================================================================
2、老版本上测试
2.1、数据库版本
1-2-18-21.11.11-150669-10013-ENT Pack16
2.2、数据库目录规划
数据文件目录:/data/
归档日志目录:/dmarch/
数据库软件安装目录:/home/dmdba/dmdbms/
数据库软件已提前安装
2.3、操作步骤
2.3.1、确保相关路径下无文件
rm -rf /data/* /dmarch/*
2.3.2、初始化数据库
/home/dmdba/dmdbms/bin/dminit path=/data charset=1 extent_size=32 page_size=32 DB_NAME=DAMENG
2.3.3、前台启动数据库
/home/dmdba/dmdbms/bin/dmserver /data/DAMENG/dm.ini
2.3.4、新shell窗口登录数据库
/home/dmdba/dmdbms/bin/disql SYSDBA/SYSDBA
2.3.5、开启数据库归档
ALTER DATABASE MOUNT;
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE ADD ARCHIVELOG 'TYPE = local, DEST =/dmarch, FILE_SIZE = 128,SPACE_LIMIT = 1024';
alter database open;
2.3.6、手动切几个归档
select checkpoint(100);
alter database archivelog current;
alter system switch logfile;
alter system switch logfile;
2.3.7、开始备份
SP_BACKUP_COPY_BEGIN();
host rm -rf /data/DAMENG1/
host rm -rf /home/dmdba/copybak
host cp -r /data/DAMENG/ /data/DAMENG1
SP_BACKUP_COPY_END('/home/dmdba/copybak');
2.3.8、修改dm.ini和控制文件路径
/home/dmdba/dmdbms/bin/dmctlcvt TYPE=1 SRC=/data/DAMENG1/dm.ctl DEST=/data/DAMENG1/dmctl.txt
sed -i 's/\/data\/DAMENG/\/data\/DAMENG1/g' /data/DAMENG1/dmctl.txt
/home/dmdba/dmdbms/bin/dmctlcvt TYPE=2 SRC=/data/DAMENG1/dmctl.txt DEST=/data/DAMENG1/dm.ctl
sed -i 's/\/data\/DAMENG/\/data\/DAMENG1/g' /data/DAMENG1/dm.ini
2.3.9、数据库恢复还原
/home/dmdba/dmdbms/bin/dmrman CTLSTMT="restore database '/data/DAMENG1/dm.ini' from backupset '/home/dmdba/copybak'"
/home/dmdba/dmdbms/bin/dmrman CTLSTMT="recover database '/data/DAMENG1/dm.ini' with archivedir '/dmarch'"
/home/dmdba/dmdbms/bin/dmrman CTLSTMT="recover database '/data/DAMENG1/dm.ini' update db_magic"
2.3.10、启动数据库
#测试数据库启动成功,数据库运行正常
/home/dmdba/dmdbms/bin/dmserver /data/DAMENG1/dm.ini
3、问题处理
经过以上测试,确认在老版本上该问题不存在,应该是新版本上恢复的时候处理方式有变化。根据报错信息,进行了如下尝试, 确认问题是可以解决的。
1、根据新版本的报错,在进行restore操作之前,手动尝试删除数据库目录下的redo日志(DAMENG01.log和DAMENG02.log),然后再做restore操作,恢复正常,后续的recover操作也都正常执行,数据库正常启动,运行无异常。
#在数据库恢复还原之前,先将copy的数据库目录中redo日志删除掉(redo日志文件名默认格式"数据库名_0*.log")
rm -rf /data/DAMENG1/DAMENG0*.log
#然后再执行数据库恢复还原操作
/home/dmdba/dmdbms/bin/dmrman CTLSTMT="restore database '/data/DAMENG1/dm.ini' from backupset '/home/dmdba/copybak'"
/home/dmdba/dmdbms/bin/dmrman CTLSTMT="recover database '/data/DAMENG1/dm.ini' with archivedir '/dmarch'"
/home/dmdba/dmdbms/bin/dmrman CTLSTMT="recover database '/data/DAMENG1/dm.ini' update db_magic"
#测试数据库启动成功,数据库运行正常
/home/dmdba/dmdbms/bin/dmserver /data/DAMENG1/dm.ini
2、恢复命令使用参数OVERWRITE强制覆盖已存在的文件,同样恢复正常,后续的recover操作也都正常执行,数据库正常启动,运行无异常。
#在数据库恢复还原时,恢复命令加参数OVERWRITE
/home/dmdba/dmdbms/bin/dmrman CTLSTMT="restore database '/data/DAMENG1/dm.ini' overwrite from backupset '/home/dmdba/copybak'"
/home/dmdba/dmdbms/bin/dmrman CTLSTMT="recover database '/data/DAMENG1/dm.ini' with archivedir '/dmarch'"
/home/dmdba/dmdbms/bin/dmrman CTLSTMT="recover database '/data/DAMENG1/dm.ini' update db_magic"
#测试数据库启动成功,数据库运行正常
/home/dmdba/dmdbms/bin/dmserver /data/DAMENG1/dm.ini
4、总结分析
按照以往达梦数据库使用cp方式备份恢复的经验,我们认为无论新老版本,在备份时均为cp整个数据库目录,恢复时直接按常规方式进行恢复即可,应该无需额外操作。但目前发现在新版本上做了改动,导致出现此次的报错问题,暂不清楚具体从哪个版本开始变化的。
根据测试情况,推测原因如下:
(1)版本2.18:数据库还原时依赖备份的redo日志进行完整性校验,未拷贝则触发文件缺失报错;
(2)版本4.80:数据库还原时不再依赖redo日志,因此备份时拷贝的redo日志与还原过程中生成的日志文件冲突,数据库默认不允许覆盖已存在文件,需手动指定覆盖或提前删除冲突文件。
|--------------------------------------------|--------------|------------------------------------------------|------------------------|
| 版本信息 | 备份要求 | 还原注意事项 | 报错情况 |
| 1-2-18-21.11.11-150669-10013-ENT Pack16 | 必须拷贝redo日志 | 直接执行还原恢复即可 | [-126]:日志文件(.log)不存在 |
| --03134284368-20250728-285229-20149 Pack24 | 尽量不要拷贝redo日志 | 方法1:恢复命令加OVERWRITE参数; 方法2:恢复前删除目标目录中已拷贝的redo日志 | DM[-4558]:文件已存在 |