达梦数据库实例迁移教学文档

适用场景:服务器根目录 / 磁盘空间不足,需要将达梦数据库实例从系统盘迁移到数据盘
数据库版本:达梦 DM8
操作系统:Linux(ARM/aarch64 或 x86 均可)
预估耗时:1–2 小时(取决于数据量)
风险等级:⚠️ 高(生产环境,需停机)

文档中所有 <占位符> 需替换为实际环境值后再执行。


目录

  1. 迁移前必读:判断你的环境
  2. 前置检查清单
  3. 方案选择:走哪条路?
  4. 方案 A:备份还原法(dmrman)
  5. 方案 B:直接拷贝法(cp)
  6. 迁移后验证
  7. 清理旧实例
  8. 常见问题与故障排查
  9. 命令速查表
  10. 回退方案

一、迁移前必读:判断你的环境

1.1 什么是"根目录满了"?

Linux 系统的 /(根目录)相当于 Windows 的 C 盘。如果根目录 100% 满,系统会:

  • 无法创建新文件(连日志都写不了)
  • 数据库可能突然崩溃
  • 无法登录或执行命令

你的根目录是不是满了?查一下:

df -h /
结果 含义 处理方式
Use% >= 95% 🚨 危险,随时可能崩溃 建议立即迁移
Use% 85%–94% ⚠️ 告警,需要尽快处理 尽快安排迁移
Use% < 85% ✅ 安全 暂时无需迁移

1.2 数据库装在哪里?

达梦数据库默认安装在 /dm8,数据文件在 /dm8/data/<实例名>/ 下。
你需要确认:数据库数据文件是否在根目录下?

# 查看数据库进程,找到 dm.ini 路径
ps -ef | grep dmserver

如果显示 path=/dm8/data/<实例名>/dm.ini,说明数据库在根目录,需要迁移。

1.3 目标盘(数据盘)空间够不够?

df -h

找到你的数据盘(通常是 /data/opt 或外挂磁盘),确认:

  • 可用空间 > 数据库数据量 × 2(比如数据库 50G,目标盘至少 100G 可用,参考 1.2 节公式)

💡 为什么 ×2? 因为迁移过程中可能同时存在旧数据 + 新数据 + 备份集。


二、前置检查清单

以下检查在迁移前完成,逐项打勾后再继续。

✅ 检查 1:确认数据库是单机还是主备集群

ps -ef | grep -E "dmserver|dmwatcher|dmmonitor"
看到什么 说明 本教程适用性
只有 dmserver 单机 ✅ 完全适用
dmserver + dmwatcher 主备集群 ⚠️ 本教程仅适用于单机部分,主备需额外配置
dmserver + dmmonitor 主备集群 ⚠️ 同上

本教程默认你是单机环境。 如果是主备集群,建议先咨询达梦技术支持。

✅ 检查 2:确认数据库参数

这些参数决定了新实例的创建方式,和原库保持一致

su - dmdba
cd /dm8/bin
./disql SYSDBA/'"<SYSDBA密码>"'

-- 在 SQL> 提示符下执行:
checkpoint(100);
select DECODE(para_value,1,'是','否') as "LENGTH_IN_CHAR",
       page as "PAGE_SIZE",
       SF_GET_EXTENT_SIZE() as "EXTENT_SIZE",
       DECODE(unicode,'1','utf8',0,'gbk','EUC-KR') as "CHARSET",
       decode(CASE_SENSITIVE,'1','敏感','不敏感') as CASE_SENSITIVE
from v$dm_ini
where para_name = 'LENGTH_IN_CHAR';

把结果记下来,后面 dminit 要用。

✅ 检查 3:确认密码格式

达梦密码如果包含特殊字符(如 @!#),登录时需要特殊引号:

# 假设密码是 <密码样例>
./disql SYSDBA/'"<密码样例>"'
# 外层单引号,内层双引号,密码包在双引号里

如果密码是纯字母数字,可以直接:

./disql SYSDBA/<密码>

✅ 检查 4:通知业务方停写数据

迁移过程需要停库,期间数据库无法提供服务。提前通知:

  • 应用开发团队
  • 业务使用方
  • 数据同步/ETL 任务负责人

三、方案选择:走哪条路?

根据你的磁盘空间情况,选择方案:

                    开始
                     │
                     ▼
            目标盘可用空间 > 数据量 × 2 ?
                     │
           ┌─────────┴─────────┐
           │                   │
          是                  否
           │                   │
           ▼                   ▼
    走【方案 A】          走【方案 B】
    备份还原法            直接拷贝法
    (dmrman)              (cp)
    更规范,有备份集      更省空间,无备份集
对比项 方案 A:备份还原 方案 B:直接拷贝
适用条件 目标盘空间 > 数据量 × 2 目标盘空间 > 数据量 × 1.2
优点 有完整备份集,可回退 不占用额外空间,速度较快
缺点 备份集占用较多空间 无独立备份集,回退依赖旧实例
停机时间 较长(备份 + 还原) 较短(仅拷贝时间)
推荐度 ⭐⭐⭐ ⭐⭐⭐⭐⭐(空间紧张时)

本案例实际采用方案 B,因为数据盘空间紧张,备份集较大导致还原失败。


四、方案 A:备份还原法(dmrman)

⚠️ 注意:如果目标盘空间不足,此方案会失败。建议先评估空间,或直接跳到【方案 B】。

步骤 1:创建备份目录

# root 执行
mkdir -p /data/dmbak
mkdir -p /data/dmdb
chown -R dmdba:dinstall /data/dmbak /data/dmdb
chmod 755 /data/dmbak /data/dmdb

步骤 2:停库

su - dmdba
cd /dm8/bin

# 停库(服务名格式为 DmService<实例名>,下面以常见命名示例,请替换为你的实际值)
./DmService<实例服务名> stop

# 确认已停(应该看不到 dmserver 进程)
ps -ef | grep dmserver

服务名确认方式:ls /dm8/bin/DmService*,参见 Q2。

步骤 3:冷备(dmrman)

./dmrman use_ap=2

# 在 RMAN> 提示符下执行:
backup database '/dm8/data/<实例名>/dm.ini'
  backupset '/data/dmbak/bakfull_YYYYMMDD'
  compressed level 1 parallel 4;

参数说明

  • compressed level 1:压缩级别 1(1–9,数字越大压缩率越高,耗时越长)
  • parallel 4:4 线程并行(根据 CPU 核数调整)

等待备份完成,看到 backup successfully!exit 退出。

步骤 4:创建新实例

用【检查 2】查到的参数替换下面的值:

cd /dm8/bin
./dminit path=/data db_name=<实例名> instance_name=<实例名> \
  EXTENT_SIZE=<值> PAGE_SIZE=<值> CASE_SENSITIVE=<Y/N> CHARSET=<值> LENGTH_IN_CHAR=<值>

参数和原库保持一致,特别是 PAGE_SIZECASE_SENSITIVE,不一致会导致还原失败。

步骤 5:拷贝并修改 dm.ini

# 拷贝原配置文件
cp -f /dm8/data/<实例名>/dm.ini /data/<实例名>/dm.ini

# 批量替换所有路径
sed -i 's|/dm8/data/<实例名>|/data/<实例名>|g' /data/<实例名>/dm.ini

# 验证(应该无输出)
grep -n "/dm8/data/<实例名>" /data/<实例名>/dm.ini

步骤 6:还原数据库

./dmrman use_ap=2

# 依次执行三条命令:
restore database '/data/<实例名>/dm.ini' from backupset '/data/dmbak/bakfull_YYYYMMDD';
recover database '/data/<实例名>/dm.ini' from backupset '/data/dmbak/bakfull_YYYYMMDD';
recover database '/data/<实例名>/dm.ini' update db_magic;

如果报错 [-523]:磁盘空间不足 → 说明目标盘不够,建议改用方案 B 或先扩容。

步骤 7:修改服务脚本并启动

# root 执行
sed -i 's|/dm8/data/<实例名>/dm.ini|/data/<实例名>/dm.ini|g' /dm8/bin/DmService<实例服务名>

# dmdba 执行启动
su - dmdba
cd /dm8/bin
./DmService<实例服务名> start

五、方案 B:直接拷贝法(cp)⭐ 推荐

适用场景:目标盘空间紧张,无法容纳备份集 + 原数据两份拷贝。
原理:直接复制原库数据文件到新位置,不经过备份集,节省空间。

步骤 1:确认目标盘空间

df -h /data
# 确认可用空间 > 原库数据量 × 1.2

du -sh /dm8/data/<实例名>
# 记录原库大小

步骤 2:停库

su - dmdba
cd /dm8/bin
./DmService<实例服务名> stop

# 确认已停
ps -ef | grep dmserver

步骤 3:直接拷贝数据文件(关键步骤)

# 必须用 dmdba 用户执行,保留文件权限!
su - dmdba
cp -rp /dm8/data/<实例名> /data/<实例名>

⚠️ 重要提醒

  • 不要用 root 执行 cp,否则文件所有者变成 root,数据库无法启动。
  • 拷贝时间取决于数据量(如示例规模约 5–10 分钟量级),不要按 Ctrl+C 中断
  • 如果中断了,需要删除不完整拷贝后重新来:
    rm -rf /data/<实例名>
    cp -rp /dm8/data/<实例名> /data/<实例名>
    

步骤 4:验证拷贝完整性

# 检查大小是否和原库一致
du -sh /data/<实例名>
# 应该和原库大小一致

# 检查文件所有者
ls -la /data/<实例名> | head -5
# 应该显示 dmdba:dinstall

步骤 5:修改 dm.ini 路径

# 批量替换所有旧路径为新路径
sed -i 's|/dm8/data/<实例名>|/data/<实例名>|g' /data/<实例名>/dm.ini

# 验证替换干净(应该无输出)
grep -n "/dm8/data/<实例名>" /data/<实例名>/dm.ini

步骤 6:修改服务启动脚本

# root 执行
sed -i 's|/dm8/data/<实例名>/dm.ini|/data/<实例名>/dm.ini|g' /dm8/bin/DmService<实例服务名>

# 验证修改
grep "INI_PATH" /dm8/bin/DmService<实例服务名>
# 应显示:INI_PATH="/data/<实例名>/dm.ini"

步骤 7:启动并验证

su - dmdba
cd /dm8/bin
./DmService<实例服务名> start

# 登录验证
./disql SYSDBA/'"<SYSDBA密码>"'

# 检查状态
select status$ from v$instance;
-- 预期:OPEN

六、迁移后验证

6.1 验证数据库状态

./disql SYSDBA/'"<SYSDBA密码>"'

-- 检查实例状态
select status$ from v$instance;
-- 预期:OPEN

-- 检查数据库角色
select name, role$, mode$ from v$instance;
-- 预期:name=<实例名>, role$=NORMAL, mode$=NORMAL

6.2 验证数据完整性

-- 查看有哪些业务用户(排除系统用户)
select owner, table_name from dba_tables
where owner not in ('SYS', 'SYSDBA', 'SYSAUDITOR')
and rownum < 50;

-- 抽查几个关键表的数据量
select count(*) from <业务用户>.<业务表>;

6.3 验证应用连接

让业务方测试:

  • 应用能否正常连接数据库?
  • 数据查询是否正常?
  • 写入操作是否正常?

全部通过后再继续下一步。


七、清理旧实例

7.1 第一步:保留旧实例(保险做法)

# 不要直接删除!先重命名保留
mv /dm8/data/<实例名> /dm8/data/<实例名>.bak.YYYYMMDD

建议保留 1–2 天,确认新实例完全稳定后再删除。

7.2 第二步:真正释放空间(关键!)

# 注意:mv 在同一磁盘内只是重命名,不释放空间!
# 必须 rm 删除才能真正释放根目录空间
rm -rf /dm8/data/<实例名>.bak.YYYYMMDD

# 验证空间释放
df -h /

7.3 清理后的空间检查

du -sh /* 2>/dev/null | sort -rh | head -10

如果根目录使用率仍然偏高,检查是否有其他大文件可以清理(如旧日志、安装包等)。


八、常见问题与故障排查

Q1:disql 登录报错"用户名或密码错误"

原因:密码包含特殊字符,引号格式不对。

解决

# 错误写法
./disql SYSDBA/"<含特殊字符的密码>"

# 正确写法(外层单引号,内层双引号)
./disql SYSDBA/'"<含特殊字符的密码>"'

Q2:服务名找不到(No such file or directory

原因:服务名写错了。达梦服务名格式是 DmService<实例名>

解决

# 查看 bin 目录下有哪些服务脚本
ls /dm8/bin/DmService*

# 用 ls 列出的实际服务名替换下面命令
./DmService<实际服务名> stop
./DmService<实际服务名> start

Q3:还原报错"磁盘空间不足"

原因:目标盘空间不够容纳备份集 + 解压后的数据。

解决

  • 如果目标盘空间 > 数据量 × 1.2,改用【方案 B:直接拷贝法】
  • 如果目标盘空间 < 数据量 × 1.2,联系管理员扩容磁盘

Q4:启动后数据库状态是 MOUNT,不是 OPEN

原因

  1. dm.ini 路径修改不完整,某些文件指向旧位置
  2. 数据文件权限不对(所有者不是 dmdba)

解决

# 检查 dm.ini 中是否还有旧路径
grep "/dm8/data/<实例名>" /data/<实例名>/dm.ini
# 如果有输出,说明路径没替换干净

# 检查文件权限
ls -la /data/<实例名>
# 应该都是 dmdba:dinstall,如果显示 root,说明拷贝时用户不对

Q5:查询表名报错"无效的表或视图名"

原因:数据库开启了大小写敏感(CASE_SENSITIVE=Y),表名包含小写字母。

解决

-- 错误
select * from <业务用户>.t_sys_role;

-- 正确(加双引号)
select * from <业务用户>."t_sys_role";

Q6:根目录使用率仍然偏高,mv 后没释放空间

原因mv 在同一磁盘分区(如都在 / 下)只是重命名,不释放空间。

解决:需要使用 rm -rf 删除才能真正释放空间。


九、命令速查表

目的 命令
查看磁盘空间 df -h
查看目录大小 du -sh /path
查看文件/目录详情 ls -la /path
查看达梦版本 cat /dm8/bin/version.txt
登录 disql ./disql SYSDBA/'"<密码>"'
查询实例参数 select * from v$dm_ini;
查询版本号 select id_code();
停库 ./DmService<实例服务名> stop
启动库 ./DmService<实例服务名> start
查看进程 ps -ef | grep dmserver
冷备(dmrman) backup database '/path/dm.ini' backupset '/path' compressed level 1 parallel 4;
还原(dmrman) restore database '/path/dm.ini' from backupset '/path';
创建实例 ./dminit path=/data db_name=<实例名> ...
批量替换路径 sed -i 's|旧路径|新路径|g' 文件
递归拷贝保留权限 cp -rp 源目录 目标目录
查找大文件 du -sh /path/* 2>/dev/null | sort -rh | head -10
删除旧日志 find /dm8/log -name "*.log" -mtime +90 -exec rm -f {} \;

十、回退方案

如果迁移后发现问题(数据库无法启动、数据丢失等),按以下步骤回退:

10.1 情况一:新实例还没启动,或启动失败

# 1. 删除新实例
rm -rf /data/<实例名>

# 2. 恢复服务脚本指向旧路径
sed -i 's|/data/<实例名>/dm.ini|/dm8/data/<实例名>/dm.ini|g' /dm8/bin/DmService<实例服务名>

# 3. 启动旧实例
su - dmdba
cd /dm8/bin
./DmService<实例服务名> start

10.2 情况二:新实例已启动,但数据有问题

# 1. 停掉新实例
./DmService<实例服务名> stop

# 2. 如果旧实例还在(没删),直接恢复
# 如果旧实例已删,但有备份集,用 dmrman 还原到旧路径

# 3. 恢复服务脚本
sed -i 's|/data/<实例名>/dm.ini|/dm8/data/<实例名>/dm.ini|g' /dm8/bin/DmService<实例服务名>

# 4. 启动旧实例
./DmService<实例服务名> start

10.3 情况三:旧实例已删,且无备份集

⚠️ 这是较坏的情况。如果采用方案 B(直接拷贝)且旧实例已删除,没有备份集,数据无法回退。

预防措施

  • 迁移前保留旧实例至少 1–2 天
  • 或先用方案 A 做一份备份集,即使方案 B 失败也有退路

文档状态:✅ 教学文档,可按步骤执行(替换占位符后)
最后更新:2026-07-10

posted @ 2026-07-10 18:13  RK5123153  阅读(34)  评论(0)    收藏  举报