资讯动态

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

发布时间:2026/9/13 14:04:25 来源:尧图企业网站定制
达梦数据库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, TYPELOCAL, FILE_SIZE1024, SPACE_LIMIT0; 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_USERSYSDBA DM_PWDSYSDBA_PASSWORD DM_SERVER127.0.0.1 DM_PORT5236 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 21 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 21这个脚本里我故意把备份和清理放在一起写了。原因是清理必须在备份成功之后进行如果单独用一个 crontab 任务做清理很难判断上一次备份是否成功容易把还没真正完成备份的目录删掉。放在同一脚本里先备份备份成功后再清理逻辑上是闭环的。然后设置 crontab0 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)。我用这个函数试过删备份集效果比findrm好很多。原因在于它能正确识别备份集之间的依赖关系如果存在增量备份基于某个全量备份那么删掉那个全量备份时它会先把依赖它的增量备份也处理掉不会留下孤立备份集影响后续 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所以脚本里用到的PATH、LD_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_PATH5.2 备份报“归档日志不连续”现象增量备份时报错提示归档日志缺失或者不连续。原因通常是归档日志被手动删过或者归档空间满了导致部分日志没有归档成功。解决办法一套针对性的恢复策略是先做一次全量备份然后重新拉通归档。如果归档空间频繁满要提前调整arch_ini.ini里的SPACE_LIMIT或者把归档日志放到独立的大容量磁盘。另外如果数据库已经处于非正常状态可以查询V$ARCHIVED_LOG看看归档日志的实际状态。实际上这个问题提醒我们增量备份的链路非常依赖归档完整性。定期做全量备份不仅仅是为了全量恢复更是为了切断增量链减少对增量日志的依赖。所以哪怕数据量不大我也建议至少一周一次全量。5.3 清理脚本误删了正在写入的备份目录现象备份还没执行完清理任务就把正在生成的备份目录删掉了导致备份失败。这种情况在备份和清理拆成两个任务时最容易出现。解决办法回到我之前强调的原则——把备份和清理放在同一个脚本或作业里严格按顺序执行。如果确实要拆开跑比如备份任务跨天未完成清理任务不要用固定时间阈值最好是检测“当前是否有备份进程在写”如果没有再执行清理。检测方式可以简单点用pgrep -f disql或者pgrep -f dmrman只要发现备份进程还在就直接退出清理脚本if pgrep -f disql.*BACKUP /dev/null 21; then echo [WARN] backup process is running, skip clean. exit 0 fi5.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确认数据可用性。这件事看起来麻烦但真到事故发生时你会感谢自己做过演练。达梦的定时备份加清理任务本质上不复杂但生产环境里能持续稳定跑半年不出岔子的基本都做到了三件事选对了备份方式、把备份和清理放到同一个执行链里、对日志有足够的可观测性。你按照这个思路把环境搭起来再结合自己的业务窗口调整备份频率和保留周期整套体系就算立住了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价