注册
DSC安装部署记录
技术分享/ 文章详情 /

DSC安装部署记录

青空 2026/07/31 170 0 0

记录一下在单机环境继续部署达梦 DSC 时执行的 Shell 操作。

尝试建立 SSH 复用连接

为了避免在自动化命令中写入 root 密码,先在外部 Git Bash 中交互式建立 SSH ControlMaster 连接。

控制连接检查返回 Master running,但实际打开命令会话时出现 Connection reset by peer,因此没有继续使用该方式。

# 在外部 Git Bash 中建立连接,并在提示时输入密码 ssh -M -S ~/.ssh/dsc-control -fNT \ -o ControlPersist=2h \ -o PreferredAuthentications=password \ -o PubkeyAuthentication=no \ -p 5218 root@10.36.41.11 # 检查控制连接 ssh -S ~/.ssh/dsc-control -O check \ -p 5218 root@10.36.41.11

异常信息如下:

mux_client_request_session: read from master failed: Connection reset by peer
Permission denied (publickey,password)

安装 SSH 公钥并验证免密登录

ControlMaster 无法稳定提供命令会话后,改为将本机已有公钥加入远端 root 的 authorized_keys

# 在外部 Git Bash 中执行 ssh-copy-id -o PreferredAuthentications=password -o PubkeyAuthentication=no -p 5218 root@10.36.41.11 # 验证公钥认证;BatchMode 可保证不会回退到密码提示 ssh -o BatchMode=yes -o ConnectTimeout=10 -p 5218 root@10.36.41.11 'date; hostname; id'

验证结果:公钥登录成功,远端主机名为 kongxianghui,执行身份为 root。

DSC 部署前检查

在修改设备规则、初始化裸设备或创建 DSC 配置前,先核验服务器资源、现有达梦服务、端口占用、磁盘分区、设备稳定标识和 DSC 工具

系统资源与网络

date hostnamectl uname -a lscpu free -h swapon --show df -hT / /dm8 ip -br addr ip route sysctl net.ipv4.ip_local_port_range

检查结果:

  • CentOS 7,内核 3.10.0-1160.el7.x86_64
  • 6 vCPU;
  • 约 13 GB 内存、2 GB swap,检查时可用内存约 10 GB;
  • /dm8 位于根文件系统,剩余空间约 31 GB;
  • 实际网卡 IP 为 192.168.200.91192.168.201.141
  • 达梦集群通信继续使用 192.168.201.141
  • 系统临时端口范围为 32768-60999

现有达梦进程、服务和端口

ps -ef | grep -E "dmserver|dmwatcher|dmmonitor|dmcss|dmasmsvr|dmcssm" | grep -v grep systemctl list-units --type=service --all | grep -i dm ss -lntup ipcs -m ipcs -s

检查结果:

  • 原有 GRP1_RT_01GRP1_RT_02 两个 dmserver 正常运行;
  • 两个 dmwatcher 正常运行;
  • 原主备端口为 5236/5237
  • MAL 端口为 61141/61142
  • watcher 端口为 52141/52142
  • 实例守护监听端口为 33141/33142
  • 原有 DmMonitorServiceMonitor 处于 failed,日志显示其进程曾被 SIGKILL,这是部署前已经存在的问题,本次暂不处理;
  • 当前没有 dmcss、dmasmsvr 或 DSC dmserver;
  • 当前 ipcs -m 没有共享内存段。

达梦版本、工具和资源占用

id dmdba ls -ld /dm8 /dm8/bin /dm8/doc ls -l /dm8/bin/dmcss /dm8/bin/dmasmsvr /dm8/bin/dmasmcmd /dm8/bin/dmasmtool /dm8/bin/dminit /dm8/bin/dmserver /dm8/bin/dmcssm strings /dm8/bin/dmserver | grep -m 5 -E "DM Database Server|V8\\.|Version" su - dmdba -c "/dm8/bin/dminit help" getcap /dm8/bin/dmserver /dm8/bin/dmasmsvr sysctl kernel.shmmax kernel.shmall kernel.shmmni kernel.sem ps -eo pid,user,comm,rss,vsz,args --sort=-rss | sed -n "1,18p"

检查结果:

  • DM 版本为 V8.1.5.60-Build(2026.07.07-335949)ENT
  • 默认许可证有效期至 2027-07-07;
  • CSS、ASM、dminit、dmserver、dmcssm 工具齐全;
  • dmdba 属于 dinstall 组;
  • 原两个 dmserver 的 RSS 各约 1.2 GB;
  • 当前没有为 dmserver、dmasmsvr 设置 capability;
  • 本版本 dminit 支持的 LOG_SIZE 范围是 256 MB 至 8 GB。

实验磁盘、分区及占用情况

blkid fdisk -l /dev/vde for d in /dev/vde1 /dev/vde2 /dev/vde3 /dev/vde5 /dev/vde6; do printf "%s " "$d" blockdev --getsize64 "$d" done findmnt swapon --show ls -l /dev/vde* lsof /dev/vde /dev/vde1 /dev/vde2 /dev/vde3 /dev/vde4 /dev/vde5 /dev/vde6 grep -E "vde|dm-dsc|asm-" /proc/mounts /etc/fstab /proc/swaps 2>/dev/null || true

确认结果:

用途 分区 字节数 约合容量
VOTE /dev/vde1 5368709120 5 GB
DCR /dev/vde2 5368709120 5 GB
DMDATA /dev/vde3 21474836480 20 GB
DMLOG /dev/vde5 5368709120 5 GB
DMARCH /dev/vde6 16102981632 15 GB

这些分区均未挂载、未用于 swap、没有文件系统签名,也没有进程打开。/dev/vde4 是扩展分区容器,不能交给 ASM。/dev/vdd 不属于本次 DSC 范围。

稳定设备标识

ls -l /dev/disk/by-id 2>&1 | grep -E "vde|virtio" || true ls -l /dev/disk/by-path | grep vde ls -l /dev/disk/by-partuuid 2>&1 || true udevadm info --attribute-walk --name=/dev/vde1 for d in \ /dev/vde1 /dev/vde2 /dev/vde3 /dev/vde5 /dev/vde6; do udevadm info --query=property --name="$d" done

该 virtio 磁盘没有 serial、by-id 或 PARTUUID。可用的稳定匹配依据是:

  • PCI 父设备:0000:0a:00.0
  • 各分区的 ATTR{partition} 值。

因此后续 udev 规则同时匹配 PCI 父设备和分区号,不只依赖当前 /dev/vdeN 名称。

确定单机双节点 DSC 配置矩阵

官方双机示例允许不同 IP 使用相同端口;本实验的两个模拟节点在同一台服务器、使用同一 IP,因此每个同机监听进程必须使用不同端口。

先检查候选端口是否空闲:

for p in 5246 5247 11246 11247 11266 11267 11276 11277 11286 11287; do if ss -lntu | grep -qE ":${p}([[:space:]]|$)"; then echo "$p USED" else echo "$p FREE" fi done

检查时以上端口均未使用。最终规划如下:

层次 节点 0 节点 1
CSS endpoint 11286 11287
ASM endpoint 11276 11277
ASM MAL 11266 11267
DSC 数据库 5246 5247
DSC MAL 11246 11247

其他规划如下:

项目
通信 IP 192.168.201.141
OGUID 260723
CSS 组 GRP_CSS_SIM
ASM 组 GRP_ASM_SIM
DB 组 GRP_DSC_SIM
CSS 节点 CSS0CSS1
ASM 节点 ASM0ASM1
DB 节点 DSC0DSC1
ASM SHM key 4243442435
配置根目录 /dm8/dsc_sim

新 OGUID、名称和端口均不复用现有主备配置。

配置并验证 udev 稳定设备别名

经确认后,写入专用 udev 规则。规则只匹配 PCI 设备 0000:0a:00.0 上的 1、2、3、5、6 号分区,不匹配 vde4、vdd 或系统盘。

cat > /etc/udev/rules.d/88-dm-dsc-sim.rules <<"EOF" SUBSYSTEM=="block", KERNELS=="0000:0a:00.0", ATTR{partition}=="1", SYMLINK+="dm/asm-dmvote", OWNER="dmdba", GROUP="dinstall", MODE="0660" SUBSYSTEM=="block", KERNELS=="0000:0a:00.0", ATTR{partition}=="2", SYMLINK+="dm/asm-dmdcr", OWNER="dmdba", GROUP="dinstall", MODE="0660" SUBSYSTEM=="block", KERNELS=="0000:0a:00.0", ATTR{partition}=="3", SYMLINK+="dm/asm-dmdata", OWNER="dmdba", GROUP="dinstall", MODE="0660" SUBSYSTEM=="block", KERNELS=="0000:0a:00.0", ATTR{partition}=="5", SYMLINK+="dm/asm-dmlog", OWNER="dmdba", GROUP="dinstall", MODE="0660" SUBSYSTEM=="block", KERNELS=="0000:0a:00.0", ATTR{partition}=="6", SYMLINK+="dm/asm-dmarch", OWNER="dmdba", GROUP="dinstall", MODE="0660" EOF chmod 0644 /etc/udev/rules.d/88-dm-dsc-sim.rules udevadm control --reload-rules for n in 1 2 3 5 6; do udevadm trigger --action=change "/sys/class/block/vde${n}" done udevadm settle

验证别名、真实目标、容量和权限:

ls -l /dev/dm for d in \ /dev/dm/asm-dmvote \ /dev/dm/asm-dmdcr \ /dev/dm/asm-dmdata \ /dev/dm/asm-dmlog \ /dev/dm/asm-dmarch; do printf "%s -> %s size=" "$d" "$(readlink -f "$d")" blockdev --getsize64 "$d" done ls -l \ /dev/vde1 /dev/vde2 /dev/vde3 /dev/vde5 /dev/vde6

验证结果:五个别名分别正确指向 vde1、vde2、vde3、vde5、vde6;容量与规划一致,底层设备权限均为 dmdba:dinstall 0660

创建 DSC 静态配置

创建独立的 /dm8/dsc_sim 配置树,不修改现有 /dm8/data/DAMENG/dm8/data_standby/DAMENG。初期关闭 CSS 对 ASM 和数据库的自动拉起,便于逐层排错。

创建目录

install -d -o dmdba -g dinstall -m 0755 \ /dm8/dsc_sim/init \ /dm8/dsc_sim/DSC0 \ /dm8/dsc_sim/DSC1 \ /dm8/dsc_sim/monitor \ /dm8/dsc_sim/log/css0 \ /dm8/dsc_sim/log/css1 \ /dm8/dsc_sim/log/asm0 \ /dm8/dsc_sim/log/asm1 \ /dm8/dsc_sim/log/dsc0 \ /dm8/dsc_sim/log/dsc1 \ /dm8/dsc_sim/log/cssm

创建 dmdcr_cfg.ini

cat > /dm8/dsc_sim/init/dmdcr_cfg.ini <<'EOF' DCR_N_GRP = 3 DCR_VTD_PATH = /dev/dm/asm-dmvote DCR_OGUID = 260723 [GRP] DCR_GRP_TYPE = CSS DCR_GRP_NAME = GRP_CSS_SIM DCR_GRP_N_EP = 2 DCR_GRP_DSKCHK_CNT = 65 [GRP_CSS_SIM] DCR_EP_NAME = CSS0 DCR_EP_HOST = 192.168.201.141 DCR_EP_PORT = 11286 [GRP_CSS_SIM] DCR_EP_NAME = CSS1 DCR_EP_HOST = 192.168.201.141 DCR_EP_PORT = 11287 [GRP] DCR_GRP_TYPE = ASM DCR_GRP_NAME = GRP_ASM_SIM DCR_GRP_N_EP = 2 DCR_GRP_DSKCHK_CNT = 61 [GRP_ASM_SIM] DCR_EP_NAME = ASM0 DCR_EP_SHM_KEY = 42434 DCR_EP_SHM_SIZE = 10 DCR_EP_HOST = 192.168.201.141 DCR_EP_PORT = 11276 DCR_EP_ASM_LOAD_PATH = /dev/dm [GRP_ASM_SIM] DCR_EP_NAME = ASM1 DCR_EP_SHM_KEY = 42435 DCR_EP_SHM_SIZE = 10 DCR_EP_HOST = 192.168.201.141 DCR_EP_PORT = 11277 DCR_EP_ASM_LOAD_PATH = /dev/dm [GRP] DCR_GRP_TYPE = DB DCR_GRP_NAME = GRP_DSC_SIM DCR_GRP_N_EP = 2 DCR_GRP_DSKCHK_CNT = 57 [GRP_DSC_SIM] DCR_EP_NAME = DSC0 DCR_EP_SEQNO = 0 DCR_EP_PORT = 5246 [GRP_DSC_SIM] DCR_EP_NAME = DSC1 DCR_EP_SEQNO = 1 DCR_EP_PORT = 5247 EOF

创建 dmasvrmal.ini

两个节点的 ASM MAL 配置必须完全相同,并完整描述 ASM0 和 ASM1。

cat > /dm8/dsc_sim/DSC0/dmasvrmal.ini <<'EOF' [MAL_INST0] MAL_INST_NAME = ASM0 MAL_HOST = 192.168.201.141 MAL_PORT = 11266 [MAL_INST1] MAL_INST_NAME = ASM1 MAL_HOST = 192.168.201.141 MAL_PORT = 11267 EOF cp /dm8/dsc_sim/DSC0/dmasvrmal.ini \ /dm8/dsc_sim/DSC1/dmasvrmal.ini

创建两个节点的 dmdcr.ini

cat > /dm8/dsc_sim/DSC0/dmdcr.ini <<'EOF' DMDCR_PATH = /dev/dm/asm-dmdcr DMDCR_MAL_PATH = /dm8/dsc_sim/DSC0/dmasvrmal.ini DMDCR_SEQNO = 0 DMDCR_ASM_TRACE_LEVEL = 2 DMDCR_ASM_RESTART_INTERVAL = 0 DMDCR_DB_RESTART_INTERVAL = 0 EOF cat > /dm8/dsc_sim/DSC1/dmdcr.ini <<'EOF' DMDCR_PATH = /dev/dm/asm-dmdcr DMDCR_MAL_PATH = /dm8/dsc_sim/DSC1/dmasvrmal.ini DMDCR_SEQNO = 1 DMDCR_ASM_TRACE_LEVEL = 2 DMDCR_ASM_RESTART_INTERVAL = 0 DMDCR_DB_RESTART_INTERVAL = 0 EOF

创建 dmcssm.ini

cat > /dm8/dsc_sim/monitor/dmcssm.ini <<'EOF' CSSM_OGUID = 260723 CSSM_CSS_IP = 192.168.201.141:11286 CSSM_CSS_IP = 192.168.201.141:11287 CSSM_LOG_PATH = /dm8/dsc_sim/log/cssm CSSM_LOG_FILE_SIZE = 32 CSSM_LOG_SPACE_LIMIT = 256 EOF

权限和一致性检查

chown -R dmdba:dinstall /dm8/dsc_sim find /dm8/dsc_sim -type f -exec chmod 0640 {} + sha256sum /dm8/dsc_sim/DSC0/dmasvrmal.ini /dm8/dsc_sim/DSC1/dmasvrmal.ini diff -u /dm8/dsc_sim/DSC0/dmdcr.ini /dm8/dsc_sim/DSC1/dmdcr.ini

检查结果:两份 MAL 文件的 SHA-256 相同;两份 dmdcr.ini 的差异只有 DSC0/DSC1 路径和 DMDCR_SEQNO=0/1

初始化 DCR、VOTE 和 ASM 盘头

这是不可逆步骤。执行前确认分区是否存在数据:

  • vde1:VOTE;
  • vde2:DCR;
  • vde3:DATA;
  • vde5:LOG;
  • vde6:ARCH。

检查目标设备

for spec in \ "VOTE /dev/dm/asm-dmvote /dev/vde1 5368709120" \ "DCR /dev/dm/asm-dmdcr /dev/vde2 5368709120" \ "DATA /dev/dm/asm-dmdata /dev/vde3 21474836480" \ "LOG /dev/dm/asm-dmlog /dev/vde5 5368709120" \ "ARCH /dev/dm/asm-dmarch /dev/vde6 16102981632"; do set -- $spec actual=$(readlink -f "$2") size=$(blockdev --getsize64 "$2") printf "%s %s -> %s size=%s\n" \ "$1" "$2" "$actual" "$size" [ "$actual" = "$3" ] [ "$size" = "$4" ] done lsof \ /dev/vde1 /dev/vde2 /dev/vde3 /dev/vde5 /dev/vde6

检查通过,目标设备未使用。

创建并初始化 DCR

DCR 认证密码由服务器本地随机生成,只保存在 /root/.dm_dsc_dcr_password,权限为 0600。

# 创建 DCR 盘头 printf "create dcrdisk '/dev/dm/asm-dmdcr' 'DCR'\nexit\n" \ | su - dmdba -c /dm8/bin/dmasmcmd # 生成本机私密密码 umask 077 openssl rand -base64 24 \ | tr -d "=/+" \ | cut -c1-24 \ > /root/.dm_dsc_dcr_password # 初始化 DCR pw=$(cat /root/.dm_dsc_dcr_password) printf "init dcrdisk '/dev/dm/asm-dmdcr' from '/dm8/dsc_sim/init/dmdcr_cfg.ini' identified by '%s'\nexit\n" "$pw" \ | su - dmdba -c /dm8/bin/dmasmcmd # 校验 DCR printf "check dcrdisk '/dev/dm/asm-dmdcr'\nexit\n" \ | su - dmdba -c /dm8/bin/dmasmcmd

在只创建盘头、尚未执行 init dcrdisk 时运行检查曾返回 DCR磁盘校验失败。完成初始化后再次检查成功,这是正常的阶段差异。

创建并初始化 VOTE

printf "create votedisk '/dev/dm/asm-dmvote' 'VOTE'\nexit\n" | su - dmdba -c /dm8/bin/dmasmcmd printf "init votedisk '/dev/dm/asm-dmvote' from '/dm8/dsc_sim/init/dmdcr_cfg.ini'\nexit\n" | su - dmdba -c /dm8/bin/dmasmcmd

导出并核对 DCR 配置

printf "export dcrdisk '/dev/dm/asm-dmdcr' to '/dm8/dsc_sim/init/dmdcr_export_check.ini'\nexit\n" | su - dmdba -c /dm8/bin/dmasmcmd grep -E "DCR_(N_GRP|VTD_PATH|OGUID|GRP_NAME|EP_NAME|EP_HOST|EP_PORT|EP_SEQNO|EP_SHM_KEY)" /dm8/dsc_sim/init/dmdcr_export_check.ini

导出的 OGUID、组、节点、IP、端口和节点序号与规划一致。

创建 DATA、LOG、ARCH 盘头

printf "create asmdisk '/dev/dm/asm-dmdata' 'DATA0'\nexit\n" | su - dmdba -c /dm8/bin/dmasmcmd printf "create asmdisk '/dev/dm/asm-dmlog' 'LOG0'\nexit\n" | su - dmdba -c /dm8/bin/dmasmcmd printf "create asmdisk '/dev/dm/asm-dmarch' 'ARCH0'\nexit\n" | su - dmdba -c /dm8/bin/dmasmcmd printf "listdisks '/dev/dm/'\nexit\n" | su - dmdba -c /dm8/bin/dmasmcmd

验证结果:DCR/VOTE 显示为已使用盘;DATA、LOG、ARCH 显示为有效但尚未加入磁盘组的 ASM 盘。工具识别容量约为 DATA 20447M、LOG 5087M、ARCH 15324M。

启动 CSS 双节点

先启动 CSS0 并验证,再启动 CSS1。最初未加 -noconsole 时,后台 CSS0 不断从空 stdin 读取并输出 Invalid cmd。随后精确停止该新进程,增加 -noconsole 后重新启动,问题消失。

# CSS0 su - dmdba -c "nohup /dm8/bin/dmcss \ DCR_INI=/dm8/dsc_sim/DSC0/dmdcr.ini \ -noconsole \ > /dm8/dsc_sim/log/css0/console.log 2>&1 & \ echo \$! > /dm8/dsc_sim/log/css0/pid" sleep 5 ps -fp "$(cat /dm8/dsc_sim/log/css0/pid)" ss -lntup | grep -E ":11286([[:space:]]|$)" # CSS1 su - dmdba -c "nohup /dm8/bin/dmcss \ DCR_INI=/dm8/dsc_sim/DSC1/dmdcr.ini \ -noconsole \ > /dm8/dsc_sim/log/css1/console.log 2>&1 & \ echo \$! > /dm8/dsc_sim/log/css1/pid" sleep 7 ps -fp "$(cat /dm8/dsc_sim/log/css1/pid)" ss -lntup | grep -E ":1128[67]([[:space:]]|$)"

使用监视器检查 CSS 状态:

printf "show\nexit\n" \ | su - dmdba -c \ "/dm8/bin/dmcssm INI_PATH=/dm8/dsc_sim/monitor/dmcssm.ini"

结果:

  • CSS0:Control Node、OPEN、WORKING、OK;
  • CSS1:Normal Node、OPEN、WORKING、OK;
  • ASM/DB 自动拉起均为 FALSE。

启动 ASM 双节点

CSS 层健康后,依次启动 ASM0 和 ASM1。

# ASM0 su - dmdba -c "nohup /dm8/bin/dmasmsvr \ DCR_INI=/dm8/dsc_sim/DSC0/dmdcr.ini \ -noconsole \ > /dm8/dsc_sim/log/asm0/console.log 2>&1 & \ echo \$! > /dm8/dsc_sim/log/asm0/pid" sleep 8 ps -fp "$(cat /dm8/dsc_sim/log/asm0/pid)" ss -lntup | grep -E ":11266([[:space:]]|$)" # ASM1 su - dmdba -c "nohup /dm8/bin/dmasmsvr \ DCR_INI=/dm8/dsc_sim/DSC1/dmdcr.ini \ -noconsole \ > /dm8/dsc_sim/log/asm1/console.log 2>&1 & \ echo \$! > /dm8/dsc_sim/log/asm1/pid" sleep 10 ps -fp "$(cat /dm8/dsc_sim/log/asm1/pid)" ss -lntup | grep -E ":1126[67]([[:space:]]|$)"

检查集群状态:

printf "show\nexit\n" \ | su - dmdba -c \ "/dm8/bin/dmcssm INI_PATH=/dm8/dsc_sim/monitor/dmcssm.ini"

只启动 ASM0 时,监视器曾暂时显示 INVALID EP STATUS,因为 ASM 组尚未形成完整双节点状态。ASM1 加入后状态正常:

  • ASM0:Control Node、OPEN、WORKING、OK;
  • ASM1:Normal Node、OPEN、WORKING、OK。

创建 ASM 磁盘组

经确认后,只从 ASM0 逐个创建 DMLOG、DMDATA、DMARCH。每创建一个盘组后立即执行 lsdg,最后使用 lsdsk 核对成员路径。

# DMLOG printf "create diskgroup 'DMLOG' asmdisk '/dev/dm/asm-dmlog'\nlsdg\nexit\n" \ | su - dmdba -c \ "/dm8/bin/dmasmtool DCR_INI=/dm8/dsc_sim/DSC0/dmdcr.ini" # DMDATA printf "create diskgroup 'DMDATA' asmdisk '/dev/dm/asm-dmdata'\nlsdg\nexit\n" \ | su - dmdba -c \ "/dm8/bin/dmasmtool DCR_INI=/dm8/dsc_sim/DSC0/dmdcr.ini" # DMARCH printf "create diskgroup 'DMARCH' asmdisk '/dev/dm/asm-dmarch'\nlsdg\nlsdsk\nexit\n" \ | su - dmdba -c \ "/dm8/bin/dmasmtool DCR_INI=/dm8/dsc_sim/DSC0/dmdcr.ini"

创建后容量如下:

盘组 总容量 初始空闲容量
DMLOG 4.97 GB 4.96 GB
DMDATA 19.97 GB 19.96 GB
DMARCH 14.96 GB 14.96 GB

DMLOG 不能使用官方示例中的四份 2 GB redo。本版本允许的最小 redo 为 256 MB,实验环境最终采用每实例两份 512 MB redo,共约 2 GB。

准备并执行 dminit

数据库初始化前,再次核对 ASM 空间。SYSDBA 和 SYSAUDITOR 密码在服务器上随机生成,分别保存在 root 专用的 0600 文件中,密码内容没有写入文档。

生成密码和 dminit.ini

umask 077 openssl rand -base64 24 | tr -d "=/+" | cut -c1-20 > /root/.dm_dsc_sysdba_password openssl rand -base64 24 | tr -d "=/+" | cut -c1-20 > /root/.dm_dsc_sysauditor_password sysdba=$(cat /root/.dm_dsc_sysdba_password) auditor=$(cat /root/.dm_dsc_sysauditor_password) cat > /dm8/dsc_sim/init/dminit.ini <<EOF DB_NAME = DSC_SIM SYSDBA_PWD = ${sysdba} SYSAUDITOR_PWD = ${auditor} SYSTEM_PATH = +DMDATA/data SYSTEM = +DMDATA/data/SYSTEM.dbf SYSTEM_SIZE = 512 ROLL = +DMDATA/data/ROLL.dbf ROLL_SIZE = 1024 MAIN = +DMDATA/data/MAIN.dbf MAIN_SIZE = 1024 CTL_PATH = +DMDATA/data/dm.ctl CTL_SIZE = 8 LOG_SIZE = 512 DCR_PATH = /dev/dm/asm-dmdcr DCR_SEQNO = 0 AUTO_OVERWRITE = 0 PAGE_SIZE = 32 EXTENT_SIZE = 16 CASE_SENSITIVE = 1 CHARSET = 0 BLANK_PAD_MODE = 1 AUTO_ADJ_PARA = 0 [DSC0] CONFIG_PATH = /dm8/dsc_sim/DSC0 PORT_NUM = 5246 MAL_HOST = 192.168.201.141 MAL_PORT = 11246 LOG_PATH = +DMLOG/DSC0_LOG01.log LOG_PATH = +DMLOG/DSC0_LOG02.log [DSC1] CONFIG_PATH = /dm8/dsc_sim/DSC1 PORT_NUM = 5247 MAL_HOST = 192.168.201.141 MAL_PORT = 11247 LOG_PATH = +DMLOG/DSC1_LOG01.log LOG_PATH = +DMLOG/DSC1_LOG02.log EOF chown dmdba:dinstall /dm8/dsc_sim/init/dminit.ini chmod 0600 /dm8/dsc_sim/init/dminit.ini

脱敏检查配置和密码文件权限:

sed -E \ 's/^(SYSDBA_PWD|SYSAUDITOR_PWD)[[:space:]]*=.*/\1 = <REDACTED>/' /dm8/dsc_sim/init/dminit.ini stat -c "%n mode=%a owner=%U:%G bytes=%s" /root/.dm_dsc_sysdba_password /root/.dm_dsc_sysauditor_password printf "lsdg\nexit\n" | su - dmdba -c "/dm8/bin/dmasmtool DCR_INI=/dm8/dsc_sim/DSC0/dmdcr.ini"

执行数据库初始化

操作者确认配置后执行一次 dminit,AUTO_OVERWRITE=0,不允许覆盖同名数据库对象。

su - dmdba -c "/dm8/bin/dminit CONTROL=/dm8/dsc_sim/init/dminit.ini" 2>&1 | tee /dm8/dsc_sim/log/dminit.log

执行结果:

write to dir [+DMDATA/data/DSC_SIM].
create dm database success. 2026-07-23 13:32:02

设置首次启动使用的内存参数

dminit 生成的默认值会依据整机资源设置为 BUFFER=8000MEMORY_TARGET=15000。本机还运行着原主备实例,而且接下来需要在同一台机器启动两个 DSC 实例,因此在 DSC 第一次启动前,直接将两份 dm.ini 设置为实验环境的初始小内存配置:

  • MEMORY_POOL = 300 MB;
  • MEMORY_TARGET = 2000 MB;
  • BUFFER = 1000 MB。
for f in /dm8/dsc_sim/DSC0/dm.ini /dm8/dsc_sim/DSC1/dm.ini; do perl -pi -e ' s/^(\s*MEMORY_POOL\s*=\s*)500(\s+)/${1}300${2}/; s/^(\s*MEMORY_TARGET\s*=\s*)15000(\s+)/${1}2000${2}/; s/^(\s*BUFFER\s*=\s*)8000(\s+)/${1}1000${2}/; ' "$f" done for f in \ /dm8/dsc_sim/DSC0/dm.ini \ /dm8/dsc_sim/DSC1/dm.ini; do echo "=== $f ===" grep -E \ "^[[:space:]]*(MEMORY_POOL|MEMORY_TARGET|BUFFER)[[:space:]]*=" \ "$f" done

该配置在 DSC0、DSC1 第一次启动前已经生效,所以它是本实验的初始运行参数,而不是数据库运行后的在线调参。

验证生成文件和 ASM 空间

find /dm8/dsc_sim/DSC0 /dm8/dsc_sim/DSC1 \ -maxdepth 1 -type f \ -printf "%M %u:%g %s %p\n" \ | sort grep -E \ "^[[:space:]]*(INSTANCE_NAME|PORT_NUM|DCR_PATH|DCR_SEQNO|MAL_INI|ARCH_INI|BUFFER|MEMORY_POOL|MEMORY_TARGET|AUTO_ADJ_PARA)[[:space:]]*=" \ /dm8/dsc_sim/DSC0/dm.ini \ /dm8/dsc_sim/DSC1/dm.ini printf "lsdg\nls -lr +DMDATA\nls -lr +DMLOG\nexit\n" \ | su - dmdba -c \ "/dm8/bin/dmasmtool DCR_INI=/dm8/dsc_sim/DSC0/dmdcr.ini"

验证结果:

  • DSC0、DSC1 均生成了独立的 dm.inidmmal.inisqllog.ini
  • 实例名为 DSC0、DSC1;
  • 数据库端口为 5246、5247;
  • MAL 已启用,归档尚未启用;
  • 两个实例首次启动使用 MEMORY_POOL=300MEMORY_TARGET=2000BUFFER=1000
  • DMDATA 中已创建 SYSTEM 512 MB、MAIN 1 GB、ROLL 1 GB;
  • DMLOG 中创建四份 512 MB redo;
  • dminit 后 DMLOG 空闲约 2.96 GB;
  • dminit 后 DMDATA 空闲约 17.44 GB;
  • DMARCH 尚未使用,空闲约 14.96 GB。

同时复核原主备进程和端口均保持正常,swap 仍为 0。

停止并禁用原主备集群服务

为了给同机双节点 DSC 释放内存和端口,在启动 DSC 数据库实例前停止原主备集群。停止前通过 dmmonitor 核实了当前实际角色:

  • GRP1_RT_01(5236)当前是 STANDBY;
  • GRP1_RT_02(5237)当前是 PRIMARY。

因此按照“监视器 → 备库守护 → 备库实例 → 主库守护 → 主库实例”的顺序停止,再禁用五个 systemd 服务。

# 停止前确认实际主备角色 printf "show\nexit\n" | su - dmdba -c "/dm8/bin/dmmonitor /dm8/data/dmmonitor.ini" # 原监视器服务在操作前已经是 failed,stop 用于确保其不运行 systemctl stop DmMonitorServiceMonitor || true # 先停止当前备库 GRP1_RT_01 systemctl stop DmWatcherServiceWatcher_01 systemctl stop DmServiceGRP1_RT_01 # 再停止当前主库 GRP1_RT_02 systemctl stop DmWatcherServiceWatcher_02 systemctl stop DmServiceGRP1_RT_02 # 禁止五个服务开机自动启动 systemctl disable \ DmMonitorServiceMonitor \ DmWatcherServiceWatcher_01 \ DmServiceGRP1_RT_01 \ DmWatcherServiceWatcher_02 \ DmServiceGRP1_RT_02 # 清除“进程已经退出但服务脚本返回非零”留下的 failed 标记 systemctl reset-failed \ DmMonitorServiceMonitor \ DmServiceGRP1_RT_02

最终检查服务、进程、端口和内存:

for s in \ DmMonitorServiceMonitor \ DmWatcherServiceWatcher_01 \ DmServiceGRP1_RT_01 \ DmWatcherServiceWatcher_02 \ DmServiceGRP1_RT_02; do systemctl show "$s" \ -p ActiveState -p SubState -p UnitFileState \ --no-pager done ps -ef \ | grep -E "dmserver|dmwatcher|dmmonitor|dmcss|dmasmsvr" \ | grep -v grep ss -lntup \ | grep -E ":(5236|5237|61141|61142|52141|52142|33141|33142)([[:space:]]|$)" \ || true free -h

最终结果:

  • 五个原主备服务均为 inactive/deaddisabled
  • 原主备 dmserver、dmwatcher、dmmonitor 进程均已退出;
  • 原主备八个端口均已释放;
  • DSC 的 CSS0/CSS1、ASM0/ASM1 保持运行;
  • 可用内存上升到约 12 GB,swap 仍为 0。

停止当前主库实例时,dmserver 已实际退出且 systemd 记录了 Stopped,但服务脚本返回 255,使 unit 暂时显示 failed;执行 reset-failed 后已恢复为正常的 inactive/dead。这不表示数据库进程仍在运行。

配置首次启动使用的归档

检查发现数据库初始化已经完成,但 DB 组仍为 SHUTDOWN,且两份 dm.iniARCH_INI 仍为 0。因此 DSC 还不能算部署完成。在第一次启动 DSC0/DSC1 前,直接创建两份初始归档配置并启用归档。

DMARCH 总容量约 14.96 GB。实验环境为每个实例设置 3 GB 本地归档上限和 3 GB REMOTE incoming 上限;按全部配置上限计算约 12 GB,仍为 ASM 元数据和运行保留约 3 GB。归档单文件大小采用 256 MB。

cat > /dm8/dsc_sim/DSC0/dmarch.ini <<'EOF' ARCH_WAIT_APPLY = 0 [ARCHIVE_LOCAL1] ARCH_TYPE = LOCAL ARCH_DEST = +DMARCH/ARCH/DSC0/arch ARCH_FILE_SIZE = 256 ARCH_SPACE_LIMIT = 3072 [ARCHIVE_REMOTE1] ARCH_TYPE = REMOTE ARCH_DEST = DSC1 ARCH_INCOMING_PATH = +DMARCH/ARCH/DSC1/arch ARCH_FILE_SIZE = 256 ARCH_SPACE_LIMIT = 3072 EOF cat > /dm8/dsc_sim/DSC1/dmarch.ini <<'EOF' ARCH_WAIT_APPLY = 0 [ARCHIVE_LOCAL1] ARCH_TYPE = LOCAL ARCH_DEST = +DMARCH/ARCH/DSC1/arch ARCH_FILE_SIZE = 256 ARCH_SPACE_LIMIT = 3072 [ARCHIVE_REMOTE1] ARCH_TYPE = REMOTE ARCH_DEST = DSC0 ARCH_INCOMING_PATH = +DMARCH/ARCH/DSC0/arch ARCH_FILE_SIZE = 256 ARCH_SPACE_LIMIT = 3072 EOF chown dmdba:dinstall \ /dm8/dsc_sim/DSC0/dmarch.ini \ /dm8/dsc_sim/DSC1/dmarch.ini chmod 0640 \ /dm8/dsc_sim/DSC0/dmarch.ini \ /dm8/dsc_sim/DSC1/dmarch.ini for f in \ /dm8/dsc_sim/DSC0/dm.ini \ /dm8/dsc_sim/DSC1/dm.ini; do perl -pi -e \ 's/^(\s*ARCH_INI\s*=\s*)0(\s+)/${1}1${2}/' \ "$f" done cat /dm8/dsc_sim/DSC0/dmarch.ini cat /dm8/dsc_sim/DSC1/dmarch.ini grep -E \ "^[[:space:]]*(ARCH_INI|MAL_INI|MEMORY_POOL|MEMORY_TARGET|BUFFER)[[:space:]]*=" \ /dm8/dsc_sim/DSC0/dm.ini \ /dm8/dsc_sim/DSC1/dm.ini

检查结果:两份归档配置的本地路径分离、REMOTE 目标互相对称;两份 dm.ini 均已设置 ARCH_INI=1MAL_INI=1,首次启动内存参数保持不变。

启动 DSC0 和 DSC1

在 CSS、ASM 均为 OPEN/WORKING/OK,数据库端口和 MAL 端口均未占用的前提下,先启动 DSC0。单独启动 DSC0 时,DB 组处于 STARTUP,这是因为另一节点尚未加入;随后启动 DSC1,两个实例均完成首次 OPEN。

# DSC0 su - dmdba -c "nohup /dm8/bin/dmserver \ /dm8/dsc_sim/DSC0/dm.ini \ dcr_ini=/dm8/dsc_sim/DSC0/dmdcr.ini \ -noconsole \ > /dm8/dsc_sim/log/dsc0/console.log 2>&1 & \ echo \$! > /dm8/dsc_sim/log/dsc0/pid" # 等待并检查 DSC0 sleep 30 ps -fp "$(cat /dm8/dsc_sim/log/dsc0/pid)" tail -200 /dm8/dsc_sim/log/dsc0/console.log # DSC1 su - dmdba -c "nohup /dm8/bin/dmserver \ /dm8/dsc_sim/DSC1/dm.ini \ dcr_ini=/dm8/dsc_sim/DSC1/dmdcr.ini \ -noconsole \ > /dm8/dsc_sim/log/dsc1/console.log 2>&1 & \ echo \$! > /dm8/dsc_sim/log/dsc1/pid" # 等待并检查两个实例 sleep 30 ps -fp "$(cat /dm8/dsc_sim/log/dsc0/pid)" ps -fp "$(cat /dm8/dsc_sim/log/dsc1/pid)" ss -lntup \ | grep -E ":(5246|5247|11246|11247)([[:space:]]|$)" tail -200 /dm8/dsc_sim/log/dsc0/console.log tail -200 /dm8/dsc_sim/log/dsc1/console.log

两个实例日志均出现 SYSTEM IS READY。DSC0 监听 5246/11246,DSC1 监听 5247/11247。

使用 dmcssm 验证三层集群

printf "show\nexit\n" \ | su - dmdba -c \ "/dm8/bin/dmcssm INI_PATH=/dm8/dsc_sim/monitor/dmcssm.ini"

最终状态:

  • CSS0:Control Node、OPEN、WORKING、OK;
  • CSS1:Normal Node、OPEN、WORKING、OK;
  • ASM0:Control Node、OPEN、WORKING、OK;
  • ASM1:Normal Node、OPEN、WORKING、OK;
  • DSC0:Control Node、OPEN、WORKING、OK;
  • DSC1:Normal Node、OPEN、WORKING、OK;
  • CSS、ASM、DB 三个组均只有一个 Control Node;
  • 集群模式为 FULL;
  • 自动拉起仍保持关闭。

SQL、共享存储和归档验证

验证两个实例和归档状态

pw=$(cat /root/.dm_dsc_sysdba_password) printf "select NAME,INSTANCE_NAME,STATUS\$,MODE\$ from V\$INSTANCE;\nselect ARCH_TYPE,ARCH_DEST,ARCH_STATUS from V\$ARCH_STATUS;\nexit;\n" \ | su - dmdba -c \ "/dm8/bin/disql SYSDBA/${pw}@192.168.201.141:5246" printf "select NAME,INSTANCE_NAME,STATUS\$,MODE\$ from V\$INSTANCE;\nselect ARCH_TYPE,ARCH_DEST,ARCH_STATUS from V\$ARCH_STATUS;\nexit;\n" \ | su - dmdba -c \ "/dm8/bin/disql SYSDBA/${pw}@192.168.201.141:5247"

查询结果:

  • DSC0:OPEN、NORMAL;
  • DSC1:OPEN、NORMAL;
  • 两节点 LOCAL 和 REMOTE 归档状态均为 VALID。

验证双节点共享读写

在 DSC0 创建测试表并写入第一行;首次执行 DROP TABLE 时因表尚不存在返回“无效的表或视图名”,随后建表和验证均正常。

# DSC0 建表并写入 printf "drop table DSC_VERIFY purge;\ncreate table DSC_VERIFY(ID int primary key, NODE_NAME varchar(20), CREATED_AT datetime);\ninsert into DSC_VERIFY values(1, 'DSC0', sysdate);\ncommit;\nselect * from DSC_VERIFY;\nexit;\n" \ | su - dmdba -c \ "/dm8/bin/disql SYSDBA/${pw}@192.168.201.141:5246" # DSC1 读取 DSC0 的数据,再写入第二行 printf "select * from DSC_VERIFY;\ninsert into DSC_VERIFY values(2, 'DSC1', sysdate);\ncommit;\nselect * from DSC_VERIFY order by ID;\nexit;\n" \ | su - dmdba -c \ "/dm8/bin/disql SYSDBA/${pw}@192.168.201.141:5247" # 回到 DSC0 查询两行并切换日志 printf "select * from DSC_VERIFY order by ID;\nalter system switch logfile;\nselect ARCH_TYPE,ARCH_DEST,ARCH_STATUS from V\$ARCH_STATUS;\nexit;\n" \ | su - dmdba -c \ "/dm8/bin/disql SYSDBA/${pw}@192.168.201.141:5246"

验证结果:

  • DSC1 能立即查询到 DSC0 写入的 ID=1;
  • DSC1 写入 ID=2 后,DSC0 能立即查询到两行;
  • 证明两个实例访问的是同一套共享数据库;
  • 日志切换成功;
  • 归档状态仍为 VALID。

验证 ASM 归档文件、进程、端口和资源

printf "lsdg\nls -lr +DMARCH\nexit\n" \ | su - dmdba -c \ "/dm8/bin/dmasmtool DCR_INI=/dm8/dsc_sim/DSC0/dmdcr.ini" ps -eo pid,user,rss,comm,args --sort=pid \ | grep -E "dmcss|dmasmsvr|/dm8/dsc_sim/.*/dm.ini" \ | grep -v grep ss -lntup \ | grep -E ":(5246|5247|11246|11247|11266|11267|11276|11277|11286|11287)([[:space:]]|$)" free -h swapon --show

验证结果:

  • +DMARCH/ARCH/DSC0/arch 已生成 DSC0 本地归档文件;
  • +DMARCH/ARCH/DSC1/arch 已生成 DSC1 本地归档文件;
  • DMARCH 空闲约 14.94 GB;
  • 六个 DSC 核心进程全部运行;
  • 十个规划端口全部由预期进程监听;
  • 系统可用内存约 9.6 GB;
  • swap 使用量仍为 0。

注册 DSC systemd 服务

使用达梦安装目录自带的 dm_service_installer.sh 注册七个唯一命名的服务。注册时统一指定 -auto false,所以只创建服务脚本和 systemd unit,不启用开机自启,也不接管当前由 nohup 启动的进程。

节点依赖关系按同节点配置:

  • ASM0 在 CSS0 之后启动;
  • ASM1 在 CSS1 之后启动;
  • DSC0 在 ASM0 之后启动;
  • DSC1 在 ASM1 之后启动。
inst=/dm8/script/root/dm_service_installer.sh # CSS "$inst" \ -t dmcss \ -dcr_ini /dm8/dsc_sim/DSC0/dmdcr.ini \ -p DSC_SIM0 \ -auto false "$inst" \ -t dmcss \ -dcr_ini /dm8/dsc_sim/DSC1/dmdcr.ini \ -p DSC_SIM1 \ -auto false # ASM,分别依赖同节点 CSS "$inst" \ -t dmasmsvr \ -dcr_ini /dm8/dsc_sim/DSC0/dmdcr.ini \ -y DmCSSServiceDSC_SIM0.service \ -p DSC_SIM0 \ -auto false "$inst" \ -t dmasmsvr \ -dcr_ini /dm8/dsc_sim/DSC1/dmdcr.ini \ -y DmCSSServiceDSC_SIM1.service \ -p DSC_SIM1 \ -auto false # dmserver,分别依赖同节点 ASM "$inst" \ -t dmserver \ -dm_ini /dm8/dsc_sim/DSC0/dm.ini \ -dcr_ini /dm8/dsc_sim/DSC0/dmdcr.ini \ -y DmASMSvrServiceDSC_SIM0.service \ -p DSC_SIM0 \ -auto false "$inst" \ -t dmserver \ -dm_ini /dm8/dsc_sim/DSC1/dm.ini \ -dcr_ini /dm8/dsc_sim/DSC1/dmdcr.ini \ -y DmASMSvrServiceDSC_SIM1.service \ -p DSC_SIM1 \ -auto false # DSC 监视器 "$inst" \ -t dmcssm \ -cssm_ini /dm8/dsc_sim/monitor/dmcssm.ini \ -p DSC_SIM \ -auto false systemctl daemon-reload

注册出的服务名:

层次 节点 0 节点 1
CSS DmCSSServiceDSC_SIM0 DmCSSServiceDSC_SIM1
ASM DmASMSvrServiceDSC_SIM0 DmASMSvrServiceDSC_SIM1
DB DmServiceDSC_SIM0 DmServiceDSC_SIM1
监视器 DmCSSMonitorServiceDSC_SIM

检查 unit 状态、依赖和启动参数:

systemctl list-unit-files \ | grep -E \ "Dm(CSSServiceDSC_SIM[01]|ASMSvrServiceDSC_SIM[01]|ServiceDSC_SIM[01]|CSSMonitorServiceDSC_SIM)" for s in \ DmCSSServiceDSC_SIM0 \ DmCSSServiceDSC_SIM1 \ DmASMSvrServiceDSC_SIM0 \ DmASMSvrServiceDSC_SIM1 \ DmServiceDSC_SIM0 \ DmServiceDSC_SIM1 \ DmCSSMonitorServiceDSC_SIM; do systemctl show "$s" \ -p LoadState -p ActiveState -p SubState -p UnitFileState \ --no-pager done

检查结果:

  • 七个 unit 均已加载;
  • 七个 unit 均为 disabled;
  • 注册完成时均显示 inactive/dead,因为当前进程仍是此前手动启动的,不是由 systemd 启动;
  • CSS、ASM、DB 的服务脚本都指向正确的 DSC0/DSC1 配置;
  • dmserver 的 START_MODE=open
  • 两个 ASM unit 的 After 指向同节点 CSS;
  • 两个 DB unit 的 After 指向同节点 ASM;
  • 当前运行中的 DSC 集群没有因注册操作而中断。

当前进度

已完成:

  • SSH 公钥登录;
  • 环境和磁盘只读检查;
  • 单机双节点端口与名称规划;
  • udev 稳定设备绑定;
  • DCR、VOTE 和 ASM 盘头初始化;
  • CSS0/CSS1 启动;
  • ASM0/ASM1 启动;
  • DMLOG、DMDATA、DMARCH 盘组创建;
  • DSC_SIM 数据库初始化;
  • 设置 DSC 两实例首次启动的内存参数;
  • 停止并禁用原主备五个服务;
  • 配置 DSC0、DSC1 归档;
  • 启动 DSC0、DSC1;
  • dmcssm 三层状态验证;
  • 双端口 SQL 共享读写验证;
  • 本地和 REMOTE 归档状态验证;
  • 注册 CSS0/CSS1、ASM0/ASM1、DSC0/DSC1 和 dmcssm 的 systemd 服务。

尚未完成:

  • 让 systemd 接管当前 DSC 进程,并验证完整的服务停止、启动和重启顺序;
  • 决定是否启用开机自启;
  • 可选:设计单进程故障演练。单机实验不能代表真实双机高可用。
评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服