达梦数据库主备集群故障恢复笔记

涉及节点: dm-node-01(10.20.12.A)、dm-node-02(10.20.12.B)
数据库版本: DM8 V8
集群类型: 实时主备(Data Watch)


一、故障现象

1.1 节点状态

🖥️ 节点 🌐 IP 🎯 角色 📊 状态
dm-node-01 10.20.12.A 原主库 ❌ dmserver 进程消失,完全宕机
dm-node-02 10.20.12.B 原备库 ✅ 自动升主,PRIMARY OPEN

1.2 进程检查

dm-node-01(宕机):

[root@dm-node-01 ~]# ps -ef | grep dameng
root     2380664 2380570  0 21:41 pts/0    00:00:00 grep dameng
# 无任何达梦进程

dm-node-02(正常):

[root@dm-node-02 ~]# ps -ef | grep dameng
root     1153776       1  0 18:54 ?        00:00:00 su - dmdba -c ... dmserver mount
dmdba    1153777 1153776  0 18:54 ?        00:00:00 -bash -c ...
dmdba    1153824 1153777  0 18:54 ?        00:00:15 /data/DM/dameng/bin/dmserver ... mount
dmdba    2596764       1  0  2025 ?        00:19:26 /data/DM/dameng/bin/dmap

二、根因定位

2.1 OOM Killer 杀死 dmserver

通过 dmesg 确认 dm-node-01 被系统 OOM Killer 强制终止:

[root@dm-node-01 ~]# dmesg -T | grep -i "kill\|oom\|dameng\|dmserver" | tail -50
[Thu May 28 17:37:18] dexp invoked oom-killer
[Thu May 28 17:37:18] Out of memory: Kill process 3185146 (dmserver) score 421
[Thu May 28 17:37:18] Killed process 3185146 (dmserver) total-vm:6477440kB, anon-rss:2609216kB

结论: dexp 逻辑导出工具消耗大量内存,触发系统 OOM,内核选择杀死内存占用最大的 dmserver 进程。

2.2 重做日志损坏

OOM 导致 dmserver 异常退出,重做日志文件头损坏:

[WARNING] arch file(/data/DM/data/DAMENG/DAMENG02.log) version check fail
[ERROR] rfil grp init log file /data/DM/data/DAMENG/DAMENG02.log error, code = -717
[FATAL] /data/DM/data/DAMENG/DAMENG01.log not exist,can not startup

2.3 集群自动切换

dm-node-02 检测到 dm-node-01 故障后,dmwatcher 自动将备库提升为主库:

-- dm-node-02 查询
SQL> SELECT instance_name, host_name, mode$, status$ FROM v$instance;
INSTANCE_NAME  HOST_NAME                  MODE$    STATUS$
-------------- -------------------------- -------- -------
GRP1_RT_02     dm-node-02                 PRIMARY  OPEN

三、恢复方案概述

采用 主库备份 + 备库重建 方案:

  1. dm-node-02 主库: 执行联机全库备份
  2. dm-node-01 备库: 清理损坏环境 → 传输备份 → 脱机还原 → 恢复配置 → 启动为备库 → 加入集群
  3. 主备切换: 将 dm-node-01 提升为主库,dm-node-02 降为备库(满足业务连接需求)

四、详细恢复步骤

阶段一:dm-node-02 防护与备份

4.1.1 OOM 豁免(防止再次被杀)

# root 执行
pid=$(pgrep -x dmserver)
echo -1000 > /proc/$pid/oom_score_adj
cat /proc/$pid/oom_score_adj   # 输出应为 -1000

4.1.2 Swap 扩容(紧急)

原 Swap 仅 1GB,且已使用 742MB,极易再次触发 OOM:

# root 执行
dd if=/dev/zero of=/swapfile2 bs=1M count=4096
chmod 600 /swapfile2
mkswap /swapfile2
swapon /swapfile2
echo "/swapfile2 swap swap defaults 0 0" >> /etc/fstab
free -h   # 确认 Swap 扩容至 5GB

4.1.3 联机全库备份

# dmdba 执行
su - dmdba
mkdir -p /data/DM/backup
cd /data/DM/dameng/bin
./disql sysdba/********@localhost:5236
SQL> BACKUP DATABASE FULL BACKUPSET '/data/DM/backup/rebuild_dm-node-01';
# 耗时约 4 分钟,备份集大小约 12GB

4.1.4 传输备份到 dm-node-01

# dm-node-02 节点 root 执行
scp -r /data/DM/backup/rebuild_dm-node-01 root@10.20.12.A:/data/DM/backup/

阶段二:dm-node-01 重建备库

4.2.1 环境清理

# dm-node-01 节点 root 执行
# 1. 停止残留进程
ps -ef | grep dmwatcher | grep -v grep
kill -9 <pid>

# 2. 备份关键配置文件(必须保留)
mkdir -p /data/DM/conf_bak_<故障日期>
cp /data/DM/data/DAMENG/dm.ini /data/DM/conf_bak_20260528/
cp /data/DM/data/DAMENG/dmmal.ini /data/DM/conf_bak_20260528/
cp /data/DM/data/DAMENG/dmarch.ini /data/DM/conf_bak_20260528/
cp /data/DM/data/DAMENG/dmwatcher.ini /data/DM/conf_bak_20260528/

# 3. 清理损坏数据目录(⚠️ 注意:不要删除整个 DAMENG 目录,只清理内部文件)
rm -rf /data/DM/data/DAMENG/*

# 4. 创建必要子目录
mkdir -p /data/DM/data/DAMENG/ctl_bak
mkdir -p /data/DM/data/DAMENG/bak
mkdir -p /data/DM/data/DAMENG/arch
chown -R dmdba:dinstall /data/DM/data/DAMENG/

⚠️ 踩坑记录: rm -rf /data/DM/data/DAMENG/* 会删除 dm.ctl 控制文件和所有数据文件,后续还原时需要从主库复制 dm.ctl 和数据文件占位,否则 dmrman 会报 [-803][-124] 等错误。

4.2.2 还原数据库

# dm-node-01 节点 dmdba 执行
su - dmdba
cd /data/DM/dameng/bin

# 1. 启动 dmap 辅助进程
nohup ./dmap > /data/DM/dmap.log 2>&1 &

# 2. 还原数据库
./dmrman CTLSTMT="RESTORE DATABASE '/data/DM/data/DAMENG/dm.ini' FROM BACKUPSET '/data/DM/backup/rebuild_dm-node-01'"
# 输出: restore successfully. time used: 00:01:29

# 3. 恢复数据库
./dmrman CTLSTMT="RECOVER DATABASE '/data/DM/data/DAMENG/dm.ini' FROM BACKUPSET '/data/DM/backup/rebuild_dm-node-01'"
# 输出: recover successfully!

# 4. 更新 DB_MAGIC
./dmrman CTLSTMT="RECOVER DATABASE '/data/DM/data/DAMENG/dm.ini' UPDATE DB_MAGIC"
# 输出: recover successfully!

4.2.3 启动并配置备库

# 1. 后台启动 dmserver(mount 模式)
nohup ./dmserver /data/DM/data/DAMENG/dm.ini mount > /data/DM/dmserver.log 2>&1 &

# 2. 连接 SQL 设置备库模式
./disql sysdba/********@localhost:5236
SQL> SP_SET_PARA_VALUE(1, 'ALTER_MODE_STATUS', 1);
SQL> ALTER DATABASE STANDBY;
SQL> SP_SET_PARA_VALUE(1, 'ALTER_MODE_STATUS', 0);
SQL> SELECT instance_name, mode$, status$ FROM v$instance;
# 预期: STANDBY, OPEN

4.2.4 启动守护进程

# dm-node-01 节点 dmdba
nohup ./dmwatcher /data/DM/data/DAMENG/dmwatcher.ini > /data/DM/dmwatcher.log 2>&1 &

4.2.5 OOM 防护(dm-node-01 节点)

# root 执行
pid=$(pgrep -x dmserver)
echo -1000 > /proc/$pid/oom_score_adj
cat /proc/$pid/oom_score_adj   # 输出应为 -1000

# Swap 扩容(同 dm-node-02 节点步骤)
dd if=/dev/zero of=/swapfile2 bs=1M count=4096
chmod 600 /swapfile2
mkswap /swapfile2
swapon /swapfile2
echo "/swapfile2 swap swap defaults 0 0" >> /etc/fstab

阶段三:dm-node-02 启动守护进程

dm-node-01 重建后,dm-node-02 节点必须启动 dmwatcher 才能接受备库加入:

# dm-node-02 节点 dmdba
nohup ./dmwatcher /data/DM/data/DAMENG/dmwatcher.ini > /data/DM/dmwatcher.log 2>&1 &

验证集群状态:

-- dm-node-02 节点
SQL> SELECT * FROM v$dm_arch_ini;
-- ARCHIVE_REALTIME1 的 ARCH_IS_VALID 应为 Y

阶段四:主备切换(dm-node-01 升主)

业务应用配置连接的是 dm-node-01,因此需要将 dm-node-01 提升为主库。

4.4.1 dm-node-02 节点降为备库

# dm-node-02 节点
# 1. 停止 dmwatcher(否则 ALTER DATABASE 会被拒绝)
ps -ef | grep dmwatcher | grep -v grep
kill -9 <pid>

# 2. 连接 SQL 降备
./disql sysdba/********@localhost:5236
SQL> SP_SET_PARA_VALUE(1, 'ALTER_MODE_STATUS', 1);
SQL> ALTER DATABASE STANDBY;
SQL> SP_SET_PARA_VALUE(1, 'ALTER_MODE_STATUS', 0);
SQL> SELECT instance_name, mode$, status$ FROM v$instance;
# 预期: STANDBY, OPEN

4.4.2 dm-node-01 节点升为主库

# dm-node-01 节点
# 1. 停止 dmwatcher
ps -ef | grep dmwatcher | grep -v grep
kill -9 <pid>

# 2. 关闭 dmserver
ps -ef | grep dmserver | grep -v grep
kill -9 <pid>

# 3. 以 mount 模式重新启动
nohup ./dmserver /data/DM/data/DAMENG/dm.ini mount > /data/DM/dmserver.log 2>&1 &
sleep 5

# 4. 连接 SQL 升主
./disql sysdba/********@localhost:5236
SQL> SP_SET_PARA_VALUE(1, 'ALTER_MODE_STATUS', 1);
SQL> ALTER DATABASE PRIMARY;
SQL> ALTER DATABASE OPEN FORCE;   # 如果提示非 NORMAL 模式
SQL> SP_SET_PARA_VALUE(1, 'ALTER_MODE_STATUS', 0);
SQL> SELECT instance_name, mode$, status$ FROM v$instance;
# 预期: PRIMARY, OPEN

4.4.3 重启守护进程

# dm-node-01 节点
nohup ./dmwatcher /data/DM/data/DAMENG/dmwatcher.ini > /data/DM/dmwatcher.log 2>&1 &

# dm-node-02 节点
nohup ./dmwatcher /data/DM/data/DAMENG/dmwatcher.ini > /data/DM/dmwatcher.log 2>&1 &

五、最终集群状态

🖥️ 节点 🌐 IP 📝 实例名 🎯 角色 📊 状态 🔗 归档链路
dm-node-01 10.20.12.A GRP1_RT_01 PRIMARY OPEN ✅ VALID
dm-node-02 10.20.12.B GRP1_RT_02 STANDBY OPEN ✅ VALID

六、关键教训与规范

6.1 OOM 防护(强烈建议)

两台节点建议都给 dmserver 设置 OOM 豁免,避免在内存压力下被内核优先杀掉:

pid=$(pgrep -x dmserver)
echo -1000 > /proc/$pid/oom_score_adj

适用场景: 物理内存较小(≤ 8GB)或同机部署其他大内存消耗进程(如 dexp/dimp)的环境。

6.2 Swap 空间

生产环境 6.6GB 内存 + 1GB Swap 配置偏紧,建议根据实际情况调整:

🖥️ 物理内存 💾 Swap 建议
≥ 16GB ≥ 物理内存的 50%
8GB ~ 16GB 与物理内存相当
< 8GB 至少为物理内存的 1.5 倍

6.3 dexp 使用规范

建议在数据库服务器本机执行 dexp 时限制并行度,或改在独立客户端执行:

# ❌ 不推荐:在服务器本机执行,未限制资源
dexp sysdba/********@localhost:5236 file=full.dmp full=y

# ✅ 推荐:限制并行度,或在独立客户端执行
dexp sysdba/********@10.20.12.A:5236 file=full.dmp full=y PARALLEL=1 TABLE_PARALLEL=1 BUFFER_NODE_SIZE=16

适用场景: 物理内存偏紧或大库导出场景。

6.4 备份集还原注意事项

rm -rf 清理数据目录前,建议保留以下文件/目录:

📂 保留项 📝 用途
dm.ini 数据库主配置
dmmal.ini MAL 通信配置
dmarch.ini 归档配置
dmwatcher.ini 守护进程配置
dm.ctl 控制文件
ctl_bak/bak/ dm.ini 中配置的路径

如果已删除,需要从主库复制 dm.ctl 和数据文件(或创建占位文件),否则 dmrman 会报 [-803][-124] 等错误。

6.5 主备切换前提

执行 ALTER DATABASE PRIMARY/STANDBY 前需要先停止本节点的 dmwatcher,否则会报 [-720]: 守护进程处于活动状态

适用场景: 任何涉及主备角色调整的操作(手动切换、故障演练)。


七、常用验证命令

-- 查看实例状态
SELECT instance_name, mode$, status$ FROM v$instance;

-- 查看归档链路
SELECT * FROM v$dm_arch_ini;

-- 查看会话
SELECT * FROM v$sessions;

-- 查看数据库信息
SELECT * FROM v$database;

八、相关文件路径

🗂️ 类型 📁 路径
安装目录 /data/DM/dameng/
数据目录 /data/DM/data/DAMENG/
日志目录 /data/DM/dameng/log/
备份目录 /data/DM/backup/
配置文件 /data/DM/data/DAMENG/dm.ini
守护配置 /data/DM/data/DAMENG/dmwatcher.ini
归档配置 /data/DM/data/DAMENG/dmarch.ini
MAL 配置 /data/DM/data/DAMENG/dmmal.ini
posted @ 2026-07-10 18:05  RK5123153  阅读(34)  评论(0)    收藏  举报