目录

一、 核心架构:达梦备份还原全景图

二、 基石配置:开启归档模式全流程

2.1 归档模式的重要性

2.2 开启归档实战步骤

三、 备份实战:多种场景详细操作

3.1 联机全量备份(生产环境首选)

3.2 增量备份策略

3.3 表空间与表级备份

四、 恢复演练:真实故障场景复原

4.1 完整数据库恢复流程

4.2 时间点恢复(PITR)

4.3 表空间级恢复(不影响其他业务)

五、 自动化备份脚本示例

六、 监控与优化

6.1 备份性能监控视图

6.2 常见问题排查表

七、 最佳实践总结

写在最后


上周五下午,财务系统误操作导致一张关键表数据被清空,我们利用凌晨的完整备份和实时归档,15分钟内将数据恢复到故障前1秒的状态,业务团队甚至没察觉到异常——这就是备份还原的价值所在。

一、 核心架构:达梦备份还原全景图

达梦数据库采用物理备份为主、逻辑备份为辅的多层保护架构。下图展示了完整的备份还原体系:

二、 基石配置:开启归档模式全流程

没有归档 = 没有真正的热备,这是达梦备份的第一铁律。

2.1 归档模式的重要性

归档日志是数据库的“时间机器”,记录了每一次数据变更。下图为归档日志在备份恢复中的关键作用:

正常业务运行流程:
应用请求 → 数据库 → 重做日志(内存) → 事务提交 → 归档日志(磁盘)

备份恢复流程:
备份集 + 归档日志 → 恢复 → 任意时间点状态

2.2 开启归档实战步骤

步骤1:检查当前状态

-- 查询是否已开启归档
SELECT name 数据库名, 
       arch_mode 归档模式,
       (CASE WHEN arch_mode='Y' THEN '已开启' ELSE '未开启' END) 状态
FROM v$database;

步骤2:编辑配置文件

创建/dm8/data/DAMENG/dmarch.ini

[ARCHIVE_LOCAL1]
ARCH_TYPE = LOCAL
ARCH_DEST = /dm8/arch      # 归档目录,建议与数据文件分开存储
ARCH_FILE_SIZE = 1024      # 单个归档文件大小1024MB
ARCH_SPACE_LIMIT = 204800  # 归档空间限制200GB,0表示无限制
ARCH_HANG_FLAG = 1         # 归档空间满时是否挂起

步骤3:执行开启命令

-- 1. 连接数据库(使用SYSDBA)
./disql SYSDBA/SYSDBA@localhost:5236

-- 2. 挂载数据库
ALTER DATABASE MOUNT;

-- 3. 配置归档
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE ADD ARCHIVELOG 
    'DEST = /dm8/arch, 
     TYPE = local, 
     FILE_SIZE = 1024, 
     SPACE_LIMIT = 204800';

-- 4. 打开数据库
ALTER DATABASE OPEN;

-- 5. 验证配置
SELECT arch_name, arch_type, arch_dest, arch_file_size
FROM v$dm_arch_ini;

步骤4:监控归档状态

-- 查看归档实时状态
SELECT arch_dest 归档路径,
       ROUND(arch_space_limit/1024, 2) 总空间GB,
       ROUND(arch_space_used/1024, 2) 已用GB,
       ROUND((arch_space_used/arch_space_limit)*100, 2) 使用率百分比,
       arch_current_file 当前归档文件
FROM v$arch_status;

三、 备份实战:多种场景详细操作

3.1 联机全量备份(生产环境首选)

-- 基础全量备份(耗时较长但最可靠)
BACKUP DATABASE FULL 
BACKUPSET '/dm8/backup/full_20231201'
DEVICE TYPE DISK
PARALLEL 4;  -- 并行度,根据CPU核心数调整

-- 压缩备份(节省60-70%空间,适合网络传输)
BACKUP DATABASE FULL 
BACKUPSET '/dm8/backup/full_compressed'
COMPRESSED LEVEL 5  -- 压缩级别1-9,越高压缩率越大但CPU消耗越多
DEVICE TYPE DISK;

-- 带校验的备份(提前发现数据页损坏)
BACKUP DATABASE FULL 
BACKUPSET '/dm8/backup/full_with_check'
DEVICE TYPE DISK
WITH BACKUPDIR '/dm8/backup'
BACKUPINFO '月度完整备份-生产库'
MAXPIECESIZE 2048;  -- 单个备份片大小2GB

3.2 增量备份策略

实际生产环境一般采用混合备份策略

-- 周一:完整备份
BACKUP DATABASE FULL BACKUPSET '/dm8/backup/full_monday';

-- 周二至周日:差异增量
BACKUP DATABASE INCREMENT 
WITH BACKUPDIR '/dm8/backup'  -- 指定基备份搜索目录
BACKUPSET '/dm8/backup/incr_tuesday';

-- 月末:累积增量备份
BACKUP DATABASE INCREMENT CUMULATIVE
WITH BACKUPDIR '/dm8/backup'
BACKUPSET '/dm8/backup/cumul_month_end';

下表对比了不同备份策略的特点:

备份类型 备份大小 恢复时间 存储要求 适用场景
完整备份 每周基线、灾备
差异增量 每日备份
累积增量 较大 较快 每周或每月
压缩备份 慢(需解压) 网络传输、长期归档

3.3 表空间与表级备份

-- 备份指定表空间(如业务数据表空间)
BACKUP TABLESPACE TS_FINANCE 
BACKUPSET '/dm8/backup/ts_finance_bak'
DEVICE TYPE DISK;

-- 备份单张重要表
BACKUP TABLE "FINANCE"."ACCOUNT_TRANS" 
BACKUPSET '/dm8/backup/tab_account_bak'
DEVICE TYPE DISK;

-- 查看备份集信息
SELECT backup_name, 
       backup_type,
       begin_time,
       end_time,
       elapsed_seconds 耗时秒数,
       ROUND(backup_size/1024/1024, 2) 大小MB
FROM v$backupset 
WHERE backup_path LIKE '%finance%'
ORDER BY begin_time DESC;

四、 恢复演练:真实故障场景复原

4.1 完整数据库恢复流程

场景:存储损坏导致数据库无法启动

# 1. 关闭数据库服务
systemctl stop DmServiceDMSERVER

# 2. 使用DMRMAN执行恢复
cd /dm8/bin
./dmrman

# DMRMAN命令行中依次执行:
# 2.1 校验备份集完整性
RMAN> check backupset '/dm8/backup/full_20231201';

# 2.2 还原数据库文件
RMAN> restore database '/dm8/data/DAMENG/dm.ini' 
      from backupset '/dm8/backup/full_20231201';

# 2.3 应用归档日志恢复
RMAN> recover database '/dm8/data/DAMENG/dm.ini' 
      with archivedir '/dm8/arch';

# 2.4 更新数据库魔数(关键!)
RMAN> recover database '/dm8/data/DAMENG/dm.ini' 
      update db_magic;

# 3. 重新启动数据库
systemctl start DmServiceDMSERVER

4.2 时间点恢复(PITR)

场景:下午2:30误删除重要数据,需要恢复到2:29

# 恢复到特定时间点
RMAN> restore database '/dm8/data/DAMENG/dm.ini' 
      from backupset '/dm8/backup/full_20231201';
      
RMAN> recover database '/dm8/data/DAMENG/dm.ini' 
      with archivedir '/dm8/arch'
      until time '2023-12-01 14:29:00';
      
RMAN> recover database '/dm8/data/DAMENG/dm.ini' 
      update db_magic;

# 或者恢复到指定LSN(更精确)
RMAN> recover database '/dm8/data/DAMENG/dm.ini' 
      with archivedir '/dm8/arch'
      until lsn 12345678;

4.3 表空间级恢复(不影响其他业务)

场景:TS_FINANCE表空间文件损坏

# 仅恢复单个表空间
RMAN> restore database '/dm8/data/DAMENG/dm.ini' 
      tablespace TS_FINANCE
      from backupset '/dm8/backup/full_20231201';
      
RMAN> recover database '/dm8/data/DAMENG/dm.ini' 
      tablespace TS_FINANCE;

# 验证恢复结果
./disql SYSDBA/SYSDBA
SQL> select tablespace_name, status 
     from dba_tablespaces 
     where tablespace_name = 'TS_FINANCE';

五、 自动化备份脚本示例

#!/bin/bash
# 文件名:auto_backup_dm.sh
# 描述:达梦数据库自动备份脚本
# 作者:DBA团队
# 版本:v2.0

# 配置区域
DB_USER="SYSDBA"
DB_PASS="SYSDBA"
DB_INST="localhost:5236"
BACKUP_BASE="/dm8/backup"
ARCH_DIR="/dm8/arch"
RETENTION_DAYS=30  # 备份保留天数

# 日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> /var/log/dm_backup.log
}

# 备份函数
perform_backup() {
    local backup_type=$1
    local backup_dir="${BACKUP_BASE}/$(date +%Y%m%d_%H%M%S)_${backup_type}"
    
    mkdir -p ${backup_dir}
    
    case ${backup_type} in
        "full")
            log "开始完整备份..."
            ./disql ${DB_USER}/${DB_PASS}@${DB_INST} <<EOF
            BACKUP DATABASE FULL 
            BACKUPSET '${backup_dir}/full_bak'
            COMPRESSED LEVEL 5
            PARALLEL 4
            BACKUPINFO '自动完整备份_$(date +%Y%m%d)';
            exit;
EOF
            ;;
        "incremental")
            log "开始增量备份..."
            ./disql ${DB_USER}/${DB_PASS}@${DB_INST} <<EOF
            BACKUP DATABASE INCREMENT 
            WITH BACKUPDIR '${BACKUP_BASE}'
            BACKUPSET '${backup_dir}/incr_bak';
            exit;
EOF
            ;;
    esac
    
    # 备份归档日志
    log "备份归档日志..."
    cp -r ${ARCH_DIR}/* ${backup_dir}/arch/
    
    log "${backup_type}备份完成,位置:${backup_dir}"
}

# 清理旧备份
clean_old_backups() {
    log "清理${RETENTION_DAYS}天前的备份..."
    find ${BACKUP_BASE} -name "*_full" -o -name "*_incremental" | \
    while read dir; do
        if [ -d "$dir" ]; then
            dir_date=$(basename $dir | cut -d_ -f1)
            if [ $(date -d "$dir_date" +%s 2>/dev/null) -lt \
                 $(date -d "${RETENTION_DAYS} days ago" +%s) ]; then
                rm -rf "$dir"
                log "删除旧备份:$dir"
            fi
        fi
    done
}

# 主程序
main() {
    log "========== 备份任务开始 =========="
    
    # 判断备份类型(周日全备,其他日增量)
    if [ $(date +%u) -eq 7 ]; then
        perform_backup "full"
    else
        perform_backup "incremental"
    fi
    
    # 清理旧备份
    clean_old_backups
    
    # 检查备份完整性
    ./dmrman <<EOF
    check backupset directory '${BACKUP_BASE}' 
    with backupdir '${BACKUP_BASE}';
    exit;
EOF
    
    log "========== 备份任务完成 =========="
}

# 执行主函数
main

六、 监控与优化

6.1 备份性能监控视图

-- 实时监控备份进度
SELECT sess_id 会话ID,
       sql_text 备份语句,
       start_time 开始时间,
       ROUND((current_time - start_time) * 1440, 2) 已运行分钟,
       state 状态
FROM v$sessions 
WHERE sql_text LIKE '%BACKUP%' 
   OR sql_text LIKE '%RESTORE%';

-- 备份历史分析
SELECT TO_CHAR(begin_time, 'YYYY-MM-DD') 备份日期,
       backup_type 类型,
       COUNT(*) 次数,
       ROUND(AVG(elapsed_seconds)/60, 2) 平均分钟,
       ROUND(SUM(backup_size)/1024/1024/1024, 2) 总大小GB
FROM v$backupset 
WHERE begin_time > SYSDATE - 30
GROUP BY TO_CHAR(begin_time, 'YYYY-MM-DD'), backup_type
ORDER BY 备份日期 DESC;

6.2 常见问题排查表

故障现象 可能原因 解决方案
备份失败:归档不连续 归档被手动删除或损坏 1. 检查归档间隙
2. 执行新的完整备份
恢复失败:魔数不匹配 忘记执行update db_magic 恢复后必须执行更新魔数操作
备份缓慢:I/O瓶颈 备份目录与数据文件同盘 分离备份存储,使用SSD或高速盘
归档空间满 未设置空间限制或业务激增 1. 增加arch_space_limit
2. 清理过期归档
3. 启用归档压缩
增量备份失败 找不到基备份 指定正确的WITH BACKUPDIR路径

七、 最佳实践总结

  1. 3-2-1备份原则:至少3份副本,2种不同介质,1份异地保存

  2. 定期恢复演练:每季度至少一次真实环境恢复测试

  3. 监控告警:对备份失败、空间不足设置实时告警

  4. 文档化流程:编写详细的恢复手册,包括联系人、步骤、预期时间

  5. 性能基准测试:记录正常情况下的备份恢复时间,建立性能基线

写在最后

达梦数据库的备份还原功能在国产数据库中已相当成熟,但工具再强大,也比不上规范的流程和定期的演练。建议将备份恢复作为DBA的核心技能持续打磨,毕竟在真正发生故障时,唯一能依靠的就是你平时的备份和恢复能力。

记住:没有测试过的备份等于没有备份!


本文基于DM8版本编写,实际操作前请在测试环境验证。欢迎在评论区分享你的备份恢复经验或遇到的问题!

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐