news 2026/9/13 14:04:07

达梦数据库定时备份与自动清理完整落地指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
达梦数据库定时备份与自动清理完整落地指南

达梦数据库(DM)在国内政企、金融、能源这些行业用得越来越多,尤其信创替代的大背景下,很多同事是从 Oracle、MySQL 转到 DM 上来的。我最近在一个生产项目里把达梦的备份体系从纯手工导出 dmp,改成了定时全量备份加自动清理的完整链路,中间踩了不少坑,也把 DM 自己的调度工具、系统包、命令行工具摸了一遍。这篇文章就把整个落地过程掰开揉碎讲清楚,从备份方式的选型,到定时任务的两种主流写法,再到清理策略怎么定、脚本怎么写得安全,最后附上我实际遇到过的故障和排查思路。

如果你是正在做达梦数据库运维、或者刚接手 DM 环境准备搭备份体系的同行,这篇文章可以直接照着抄作业,能省下不少自己试错的时间。

1. 定时备份前,先把这3件事想明白

很多人一上来就写 crontab、配作业调度,结果跑两天发现备份文件把磁盘撑爆了,或者恢复的时候根本用不上。我建议动手之前,先花 10 分钟把下面三个问题理清楚,比什么都重要。

1.1 选物理备份还是逻辑备份

达梦数据库的备份体系可以分成两大类:物理备份和逻辑备份。物理备份直接从数据文件层面复制数据,恢复的时候是“整体还原”,不关心表结构、索引这些逻辑对象;逻辑备份则是用 dexp/dimp 这种工具把数据导出成 SQL 或者二进制文件,恢复的时候一条条执行建表、插数据。

如果你是为了应对“数据文件损坏、服务器磁盘故障、误删表空间”这类事故,那必须用物理备份。物理备份能够把数据库恢复到某个时间点的完整状态,包括用户、权限、表空间、数据文件、归档日志状态,这些都是逻辑备份做不到的。

如果你只是定期把某些业务表的数据导出来,给数据分析、临时环境用,逻辑备份就够了,文件小、恢复灵活。

我的建议很直接:生产环境的日常定时备份,一定以物理备份为主;逻辑备份可以作为辅助手段,比如每天导出一份业务表数据放到文件服务器上,方便开发查数,但它不能替代物理备份。

1.2 选全量备份还是增量备份

达梦的物理备份也分全量备份和增量备份。全量备份就是把整个数据库的所有数据页拷贝一份,文件大小通常是数据文件总体积的 30% 到 70% 左右,取决于数据压缩率和空闲空间。增量备份则只备份上一次备份之后发生变化的数据页,速度更快,文件更小,但恢复的时候依赖基准备份(BASE),链路越长,恢复越麻烦。

在达梦里,增量备份分为一级增量(基于全量备份)和二级增量(基于一级增量)。实际生产环境里,最常见的组合是:每周日做一次全量备份,周一到周六做增量备份。这样既能控制单次备份时长,又能把恢复的时间窗口压缩在最后一周的范围内。

不过,如果你的数据库不大(比如 200GB 以内),我建议直接用全量备份+压缩,一天一次甚至一天两次都问题不大。备份文件大点没关系,恢复简单——直接拿最新一份全量备份就能还原,不需要一连串的增量文件。

1.3 选命令行、管理工具还是系统包

达梦提供了多种执行备份的途径:disql 命令行里执行 BACKUP 语句、DM Manager 图形化管理工具、DMAP 备份恢复API、以及系统过程 DBMS_BACKUP_RESTORE。对于定时任务来说,最常用的就两条路:

第一条路是写 shell 脚本,在脚本里调用 disql 执行 BACKUP 语句,然后用系统 crontab 或者 Windows 任务计划程序来调度。这条路的优点是逻辑透明、可控制、方便集成监控告警,适合 Linux 服务器。

第二条路是使用 DM Manager 自带的“作业”功能,里面有“备份数据库”、“清理备份”这类作业步骤,通过图形界面配置好调度时间,由数据库自带的作业调度器来执行。这条路的优点是不用写脚本,鼠标点配置就可以,适合 Windows 环境或者不太熟悉命令行的同学。

两条路我都会在后面展开讲,你可以根据自己的环境选。如果你有多个达梦实例需要统一管理,我强烈推荐脚本方案,因为脚本可以模板化、批量部署。

2. 手动备份基本功,定时任务的地基

定时备份本质上是把手动备份的命令包装成自动化调度。所以先把手动备份做扎实,定时任务才有意义。这里我以 DM8 为例,给你演示一遍最标准的操作流程。

2.1 联机全量备份的正确写法

达梦在联机状态下可以直接执行 BACKUP 语句,不需要停库。这在绝大多数业务场景下都是可以接受的。我常用的最简单一条命令是这样:

BACKUP DATABASE FULL BACKUPSET '/dm/backup/full_bak_20250101_000001';

执行完之后,会在/dm/backup/目录下生成一个目录(也叫备份集目录),里面包含备份文件,还有dm.ctl之类的元数据文件。注意,达梦备份集的目录名通常是以full_bak_20250101_000001这个全名命名的目录,而不是一个单独的文件,这一点和 Oracle 的 backup piece 不太一样,别搞混了。

实际生产里,我一般会加上压缩参数和并行参数:

BACKUP DATABASE FULL COMPRESSED LEVEL 5 BACKUPSET '/dm/backup/full_bak_20250101_000001' PARALLEL 4;

COMPRESSED LEVEL 5把备份文件压缩一下,能省不少磁盘空间;PARALLEL 4让备份过程用 4 个并行线程,大库能明显缩短备份时间。这两个参数尤其在数据量上百 GB 的场景下非常有用。

2.2 手动备份的常见参数与增量备份

如果你要走增量备份路线,那么全量备份是基础,然后增量备份的命令类似这样:

BACKUP DATABASE INCREMENT LEVEL 1 BACKUPSET '/dm/backup/incr_bak_20250102_000001';

这里LEVEL 1表示一级增量。执行增量备份之前,数据库必须处于归档模式,因为增量备份依赖归档日志来定位变化的数据页。如果你的数据库还没开归档,先执行下面的命令开启:

ALTER DATABASE ADD ARCHIVELOG 'DEST=/dm/arch, TYPE=LOCAL, FILE_SIZE=1024, SPACE_LIMIT=0'; ALTER DATABASE ARCHIVELOG;

注意,这两条命令执行完需要重启数据库实例才能生效。这是达梦和 Oracle 类似的地方,归档参数改完必须重启。

2.3 手动备份的验证与日志检查

备份完一定要验证,否则根本不知道备份是否可用。达梦提供了RESTORE CHECK或者BACKUPSET CHECK这类验证手段。最快速的验证方式是查询备份历史:

SELECT BACKUP_NAME, BACKUP_TYPE, BASE_NAME, START_TIME, END_TIME, TOTAL_SIZE, READ_SIZE, STATUS FROM V$BACKUP_HISTORY ORDER BY START_TIME DESC;

这条 SQL 能列出所有备份集的基本信息。我一般先看STATUS是不是正常,再看END_TIME - START_TIME之间的距离,如果一条备份跑了 3 小时,那说明数据量很大或者 IO 有瓶颈,需要关注。

另外,备份过程中产生的日志会在安装目录的log子目录下,比如dm_DMSERVER_20250101.log。备份失败时的具体报错信息,去那里查一般都能找到。千万不要只盯着屏幕输出。

3. 定时备份的落地:两种主流方案实操

手动备份验证没问题之后,就可以上定时了。这一部分我给你提供两种方案,都是我在实际项目中验证过的,你可以按自己的环境选。

3.1 方案一:Linux crontab + 备份脚本

这是我最推荐的方式,尤其适合生产环境跑在 Linux 服务器上、有多个实例要统一管理的情况。整体思路:写一个备份脚本,然后在 crontab 里配上执行时间,同时把备份日志输出到固定文件,方便排查。

先看脚本主体,我用的是 disql 执行备份语句:

#!/bin/bash # 达梦数据库全量备份脚本 # 定义变量 DM_HOME=/dm/dmdbms DM_USER=SYSDBA DM_PWD=SYSDBA_PASSWORD DM_SERVER=127.0.0.1 DM_PORT=5236 BACKUP_BASE=/dm/backup DATE_TAG=$(date +%Y%m%d_%H%M%S) BACKUP_DIR=$BACKUP_BASE/full_${DATE_TAG} LOG_DIR=/dm/backup/log LOG_FILE=$LOG_DIR/backup_${DATE_TAG}.log # 创建目录 mkdir -p $BACKUP_BASE mkdir -p $LOG_DIR # 执行备份 $DM_HOME/bin/disql $DM_USER/$DM_PWD@$DM_SERVER:$DM_PORT <<EOF >> $LOG_FILE 2>&1 BACKUP DATABASE FULL COMPRESSED LEVEL 5 BACKUPSET '$BACKUP_DIR' PARALLEL 4; EXIT; EOF # 检查执行结果 if [ $? -eq 0 ]; then echo "[INFO] backup success: $BACKUP_DIR" >> $LOG_FILE else echo "[ERROR] backup failed: $BACKUP_DIR" >> $LOG_FILE fi # 删除7天前的备份文件 find $BACKUP_BASE -type d -name "full_*" -mtime +7 -exec rm -rf {} \; >> $LOG_FILE 2>&1

这个脚本里我故意把备份和清理放在一起写了。原因是:清理必须在备份成功之后进行,如果单独用一个 crontab 任务做清理,很难判断上一次备份是否成功,容易把还没真正完成备份的目录删掉。放在同一脚本里,先备份,备份成功后再清理,逻辑上是闭环的。

然后设置 crontab:

0 2 * * * /bin/bash /dm/scripts/dm_full_backup.sh

每天凌晨 2 点执行一次全量备份。如果你要改成每周日 2 点全量、周一到周六 2 点增量,可以再写一个增量备份脚本,然后 crontab 里分别配:

0 2 * * 0 /bin/bash /dm/scripts/dm_full_backup.sh 0 2 * * 1-6 /bin/bash /dm/scripts/dm_incr_backup.sh

注意一下 crontab 里星期天是 0,不是 7,这个达梦和其他 Linux 工具一样。我第一次写* * 7结果周日不执行,查了半天才发现是 crontab 语法的问题。

3.2 方案二:DM Manager 自带作业调度

如果你的服务器是 Windows,或者团队里更习惯用图形界面,那 DM 自带的“作业”功能就很合适。打开 DM Manager,连接上实例后,在“对象导航”里找到“作业”节点,右键新建作业。

新建作业时,需要配置三个部分:作业步骤、调度、告警。

第一步,新建作业步骤。作业步骤类型默认是“SQL 脚本”,在里面填上备份语句。我建议分两个步骤:第一步执行备份,第二步执行清理。

备份步骤的 SQL 脚本:

BACKUP DATABASE FULL COMPRESSED LEVEL 5 BACKUPSET '/dm/backup/job_full_bak';

注意,DM 的作业步骤里执行备份语句时,BACKUPSET路径如果写死了,后一次备份会覆盖前一次吗?答案是会报错,因为备份集目录已经存在。所以路径里最好用动态变量,比如通过 SQL 拼接路径字符串的方式:

BACKUP DATABASE FULL COMPRESSED LEVEL 5 BACKUPSET '/dm/backup/job_full_bak_' || TO_CHAR(SYSDATE, 'YYYYMMDD_HH24MISS');

这个技巧我在 DM 作业里试过,是能正常执行的。日志里会记录实际生成的备份集名。

清理步骤可以调用系统过程SF_BAK_BAKSET_CLEAN或者用SP_DB_BAKSET_CLEAN来删除指定时间之前的备份集。例如删除 7 天前的备份集:

CALL SP_DB_BAKSET_CLEAN('DISK', '/dm/backup', SYSDATE - 7);

这个系统过程会扫描备份目录下所有备份集,删除创建时间早于指定时间点的备份集。比脚本里用find -exec rm更安全,因为它能识别备份集的元数据,不会误删非备份目录。

第二步,配置调度。在“调度”里填执行周期,比如每天凌晨 2 点,界面操作很直观,这里就不展开截图了。

第三步,配置告警。DM 作业支持失败告警,可以配置成发送邮件或者写日志。生产环境下一定要配,不然作业失败了没人知道,定时备份就形同虚设。

3.3 两种方案的取舍

我当时两个方案都试过,最后的结论是:单机小环境用 DM Manager 作业就够了,省事、界面直接;多实例、复杂环境还是脚本方案更灵活。因为脚本可以放到同一个 Git 仓库里管理、可以用 ansible 之类的工具批量分发、可以接入企业已有的监控平台(Zabbix、Prometheus + Alertmanager),而图形界面作业很难做到这一点。

另外,脚本方案还有个隐藏好处:备份完成后可以顺手把备份文件 rsync 到异地机器,实现异地备份。这个在 DM Manager 作业里做起来就没有脚本方便。

4. 清理备份任务怎么做才安全

清理备份文件,看起来就是删文件而已,但删错了会导致备份链断裂,恢复时抓瞎。这一部分专门讲讲清理策略和实现细节。

4.1 清理策略:按时间还是按数量?

清理备份最核心的问题是:保留多少份?

最简单粗暴的策略是按时间清理,保留最近 N 天的备份。比如find $BACKUP_BASE -type d -name "full_*" -mtime +7 -exec rm -rf {} \;,这条我前面出现过,意思就是保留最近 7 天的全量备份。优点是简单、容易理解;缺点是如果某天备份任务失败、或者备份文件特别大导致磁盘空间提前吃紧,这个策略不会自动调整。

更稳妥的策略是按数量清理,保留最近 N 份备份。比如每次都保留最近 5 份全量备份,不管每份是几天的间隔,只要超过 5 份就删最旧的那一份。这个策略在脚本里需要在执行备份之后统计备份集数量,然后删掉超出数量的旧备份。

我建议:两种策略结合。先按时间保留 7 天内的备份,再额外加一个阈值:如果备份集数量超过 14 份,也触发清理。这样既保证时间范围,又防止备份异常频繁导致的磁盘爆掉。

4.2 达梦自带清理系统过程的用法

前面提到的SP_DB_BAKSET_CLEAN是达梦提供的官方清理接口,语法是:

SP_DB_BAKSET_CLEAN(device_type, bak_dir, end_time);

其中第一个参数是备份设备类型,一般填'DISK';第二个参数是备份集所在目录;第三个参数是删除该时间之前的所有备份集。

需要注意,这个过程中end_time的类型是DATETIME,不是字符串。所以一般在 SQL 里写成SYSDATE - 7,表示 7 天之前的时间点。如果想精确控制,也可以使用TO_DATE('2025-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')

我用这个函数试过删备份集,效果比find+rm好很多。原因在于它能正确识别备份集之间的依赖关系:如果存在增量备份基于某个全量备份,那么删掉那个全量备份时,它会先把依赖它的增量备份也处理掉,不会留下孤立备份集,影响后续 RESTORE 的时候判断备份链完整性。

4.3 备份和清理的执行顺序设计

无论你用脚本还是作业,有一点必须坚持:先备份,后清理。这个顺序不能反。

如果你先清理、再备份,清理过程会删掉一部分旧备份,如果随后的备份失败了,那你手里可能只剩下一份很旧的备份,恢复数据时丢失时间长。反过来,先备份、后清理,即使新备份失败,旧备份还在,至少能恢复到一个较近的时间点。

同时,备份和清理最好放在同一个调度任务里执行,而不是拆成两个独立的定时任务。我之前见过一个方案:备份是凌晨 2 点,清理是凌晨 3 点。结果某天备份因为归档日志满了失败了,但清理任务照常把昨天的备份删了,最终磁盘上只剩下 3 天前的一份全量备份。这种问题很难发现,等到真正要恢复数据的时候才追悔莫及。

4.4 防误删设计:备份目录权限与回收站

最后一个点,也是很多人忽略的点:清理脚本一定要对“被删除的目标”做二次检查。比如find ... -exec rm -rf {}这条命令,如果变量$BACKUP_BASE为空,那就会执行成find -type d -name "full_*" -exec rm -rf {},当场把所有匹配的目录全删了,非常危险。

我习惯在脚本开头加一层保护:

if [ -z "$BACKUP_BASE" ]; then echo "[ERROR] BACKUP_BASE is empty, skip clean." exit 1 fi # 只清理 full_ 开头的目录 find $BACKUP_BASE -type d -name "full_*" -mtime +7 -exec rm -rf {} \;

另外,生产环境的备份目录用户权限要严格限制,比如用专门的备份账号运行脚本,不要用 root 跑定时任务。否则一旦脚本有 bug,影响面会很大。

5. 我实测踩过的高频故障与排查办法

这个环节直接上干货。下面这些故障我在实际测试和项目里都遇到过,有的很隐蔽,不仔细查真看不出问题。

5.1 crontab 里脚本不执行

现象:手动执行/bin/bash /dm/scripts/dm_full_backup.sh没问题,但 crontab 到点不跑。排查下来发现,大概率是下面两个原因之一:

第一个原因是脚本没有执行权限。给脚本加一下:

chmod +x /dm/scripts/dm_full_backup.sh

第二个原因是 crontab 里的环境变量和手动执行时不一样。crontab 默认不加载用户的.bash_profile,所以脚本里用到的PATHLD_LIBRARY_PATH可能找不到。达梦的 disql 依赖LD_LIBRARY_PATH指向安装目录的bin目录,如果这个变量没设置,disql 会直接报error while loading shared libraries。解决办法是在脚本开头显式设置:

export DM_HOME=/dm/dmdbms export PATH=$DM_HOME/bin:$PATH export LD_LIBRARY_PATH=$DM_HOME/bin:$LD_LIBRARY_PATH

5.2 备份报“归档日志不连续”

现象:增量备份时报错,提示归档日志缺失或者不连续。原因通常是归档日志被手动删过,或者归档空间满了导致部分日志没有归档成功。

解决办法:一套针对性的恢复策略是,先做一次全量备份,然后重新拉通归档。如果归档空间频繁满,要提前调整arch_ini.ini里的SPACE_LIMIT,或者把归档日志放到独立的大容量磁盘。另外,如果数据库已经处于非正常状态,可以查询V$ARCHIVED_LOG看看归档日志的实际状态。

实际上这个问题提醒我们:增量备份的链路非常依赖归档完整性。定期做全量备份不仅仅是为了全量恢复,更是为了切断增量链,减少对增量日志的依赖。所以哪怕数据量不大,我也建议至少一周一次全量。

5.3 清理脚本误删了正在写入的备份目录

现象:备份还没执行完,清理任务就把正在生成的备份目录删掉了,导致备份失败。这种情况在备份和清理拆成两个任务时最容易出现。

解决办法:回到我之前强调的原则——把备份和清理放在同一个脚本或作业里,严格按顺序执行。如果确实要拆开跑(比如备份任务跨天未完成),清理任务不要用固定时间阈值,最好是检测“当前是否有备份进程在写”,如果没有再执行清理。检测方式可以简单点,用pgrep -f disql或者pgrep -f dmrman,只要发现备份进程还在,就直接退出清理脚本:

if pgrep -f "disql.*BACKUP" > /dev/null 2>&1; then echo "[WARN] backup process is running, skip clean." exit 0 fi

5.4 DM Manager 作业报“无效的备份目录”

现象:配置好的 DM 作业在备份步骤报错,提示备份目录无效或权限不足。排查时发现,DM 作业默认以数据库服务进程的账号来执行,如果备份目录的权限是 700 且属主是 root,那么服务账号就无法写入。

解决办法:把备份目录属主改成运行数据库实例的系统账号,比如:

chown dmdba:dinstall /dm/backup chmod 755 /dm/backup

顺便提醒一句,当你用 DM Manager 远程连接数据库配置作业时,要注意图形工具本身的网络权限。之前有个同事在 Windows 上用 DM Manager 连远程达梦,作业一直配置失败,最后发现是防火墙把 5236 端口之外的一个内部管理端口封了。端口不通,作业管理相关信息同步不全,界面表现就是“能连上但作业配置保存总失败”。

5.5 高频问题速查表

现象可能原因处理方向
备份脚本 crontab 不执行环境变量、权限脚本里显式 export 路径,chmod +x
备份报“归档不连续”归档缺失或归档空间满先做全量备份,调整归档参数
备份目录写入权限失败目录属主和实例账号不一致chown 到 dmdba 或对应实例用户
清理删掉了备份中的目录备份和清理分开执行改为同一任务内串行执行
备份集验证失败备份目录损坏或空间不够执行 BACKUPSET CHECK,修复文件系统
DM 作业保存失败网络端口或权限问题检查实例监听、内部管理端口、防火墙
备份文件占用空间过大未开压缩加 COMPRESSED LEVEL 参数

6. 备份体系落地后,我的一点个人习惯

最后分享几个我自己在实际操作里积累的小习惯,不一定写在哪本手册里,但对长期运维很有帮助:

第一,备份日志一定要留够时间。我备份脚本的日志目录只清理 30 天前的日志,而备份文件只保留 7 天。这样出了问题,可以回溯至少一个月的备份记录,定位是哪一天的任务异常、当时的磁盘容量是多少、归档日志状态是什么。

第二,把备份文件的异地拷贝纳入日常。数据库服务器本身磁盘坏了,备份文件放在同一块磁盘上是没用的。我习惯在备份完成后,用 rsync 把当天的备份集增量同步到另一台存储服务器。这一步在脚本里加一行就能实现,但很多人会漏掉。

第三,每个月做一次备份恢复演练。看起来和定时备份、清理没直接关系,但如果你从来没试过把备份集恢复到一台新环境,那这套备份配置就是纸面功夫。我自己的做法是,每个月选一个周末,在测试服务器上把最新备份集恢复起来,跑几个关键 SQL,确认数据可用性。这件事看起来麻烦,但真到事故发生时,你会感谢自己做过演练。

达梦的定时备份加清理任务,本质上不复杂,但生产环境里能持续稳定跑半年不出岔子的,基本都做到了三件事:选对了备份方式、把备份和清理放到同一个执行链里、对日志有足够的可观测性。你按照这个思路把环境搭起来,再结合自己的业务窗口调整备份频率和保留周期,整套体系就算立住了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 14:02:48

硬件自学实战指南:从故障排查到可交付作品集

1. 从“拆旧路由器”开始的硬件自学路&#xff1a;不是学完再找工作&#xff0c;而是边学边造“敲门砖” “自学硬件3个月&#xff0c;我最后找到工作了吗&#xff1f;”——这个问题我被问了至少47次&#xff0c;每次都在面试结束后的电梯里、咖啡馆结账时&#xff0c;甚至朋友…

作者头像 李华
网站建设 2026/9/13 14:02:42

Java开发环境配置全攻略:JDK、IDEA与Maven从零到跑通Hello World

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 14:01:17

老番高清修复全流程实战:从480i隔行源到1080p AI超分

前两天整理移动硬盘&#xff0c;在一堆下载文件里翻出来一个叫 dragonballz_e233-2 的视频文件。这个命名我太眼熟了——以整理动漫资源多年的习惯&#xff0c;这基本就是《龙珠Z》某一集的压制源&#xff0c; e233 指第 233 集&#xff0c; -2 表示这一集被拆成了两个部…

作者头像 李华
网站建设 2026/9/13 13:58:20

跨境电商核心竞争力构建与本地化运营实践

1. 跨境增长能力的核心价值构建 山东闪洋作为一家深耕跨境领域多年的企业&#xff0c;其核心竞争力的构建路径值得深入剖析。跨境业务不同于传统贸易&#xff0c;需要企业在文化适应、合规运营、本地化服务等方面具备独特能力。长期经验积累形成的know-how体系&#xff0c;正是…

作者头像 李华
网站建设 2026/9/13 13:58:18

PyCharm文件头模板深度实践:从静态填充到工程元数据治理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华