从主备到 DMDPC:我的 DM8 云虚拟机踩坑与验证之路
2026/7/29 14:07:11 网站建设 项目流程

一、拿到公司云虚拟机后,我先被多套环境绕晕

我最初从 Windows PowerShell 连接云虚拟机,看到提示符从PS C:\Users\31394>变成[root@liuyiwei ~]#,再切到dmdba,最后进入SQL>。这三个层次现在看起来很普通,当时却让我吃了不少亏:本该在本机执行的辅助脚本被当成远端命令,本该在 Linux 下运行的检查又粘到了 disql;有一次中文目录被错误编码成乱码,本地 Python 报“找不到脚本”,我却先去怀疑远端数据库。后来我给自己定了一个简单规则:每次执行前先看提示符,再判断这条命令属于 Windows、Linux 还是 SQL。

接着是磁盘。当前现场检查显示,根分区容量约 47 GB,已使用约 40 GB,只剩约 4.3 GB;/nas则是网络共享盘,容量和余量明显更充足。这个事实直接决定了后面的 DMDPC 目录不能继续堆在根分区。我把实验根目录放到/nas/dmdpc_lab,既避免根盘被日志、备份和实例文件写满,也尽量与已有环境隔离。这里的“隔离”只指目录和配置文件不混用,因为 CPU、内存、网络和主机端口仍然共享,测试结果依旧不能当成独立服务器性能。

真正让我绕晕的是进程。机器上同时能看到 DSC0、DSC1、单机测试库、Watcher 以及 DMDPC 的 MP、SP、BP 相关dmserver。如果只执行ps -ef | grep dmserver,屏幕上全是相似路径;如果只看/home/dmdba/dmdbms下有哪些目录,又容易把“目录存在”理解成“当前服务正在使用”。我后来不再凭目录名猜实例,而是固定核对四件事:PID、完整启动参数中的配置路径、监听端口、配置文件中的实例名。四项对应上,才确认自己连接的是哪一套环境。

目录存在只能证明文件在;进程存在只能证明程序还活着;端口监听只能证明有进程占用端口。它们都不能单独证明实例角色正确,更不能证明高可用链路成立。后面几乎每一次误判,都可以追溯到我跳过了这一步。

二、第一次搭主备:配置齐全不等于高可用成立

第一次搭单机主备时,我把注意力放在“文件有没有配齐”。dm.ini定义实例自身,dmmal.ini负责 MAL 通信,dmarch.ini决定归档和远程归档,dmwatcher.ini描述守护关系;除此之外,还要处理 MOUNT 状态、OGUID、PRIMARY/STANDBY 角色和 Watcher 启动。文件很多,但难点不是数量,而是这些文件对同一组实例、端口和目录的描述必须一致。

我最早的成功标准很低:主库能打开、备库能启动、主库插入后备库能查到。这个验证只能证明日志传输和数据同步链路在那一刻基本可用,不能证明客户端高可用。我曾经让应用分别直连主库端口和备库端口,然后把两次连接都成功写成“读写分离”。实际上,固定端口直连绕过了服务名、地址列表、连接重试和选主逻辑。备库可读也只是数据库能力,只有客户端配置真的把读请求分配过去,才谈得上业务层读写分离。

另一个容易忽略的问题是保护模式。异步备库、实时备库承担的目标并不相同,不能因为它们都显示 STANDBY,就在客户端路由中按同一种方式处理。学习环境里这样配也许暂时能连上,一旦故障或延迟出现,读一致性和写路由的语义就会变得含糊。我的做法后来改成:先写清每个备库的同步方式和用途,再设计服务名;任何直连端口的命令只用于诊断,不作为客户端自动切换证明。

三、部署 DSC:真正困难的是 DCR、CSS、ASM 和启动顺序

主备的核心是两个数据副本之间传输日志,而 DSC 是多个数据库节点共同访问共享存储。刚接触时,我只看见“都是两个节点”,一度把两套体系的概念混在一起。真正开始部署后才发现,DSC 前面还有一条更长的依赖链:裸设备或共享块设备要先可见,DCR 和 VOTE 信息要正确,CSS 要建立集群成员关系,ASM 要提供共享磁盘管理,最后才轮到 DSC0、DSC1 的数据库进程。

这意味着上层报错不一定是上层参数错。例如 dmserver 启动失败,根因可能是 ASM 没准备好;ASM 异常,可能是 CSS 未形成预期成员;CSS 异常,又可能落到 DCR 路径、设备权限或残留进程。最开始我从最末端反复改dm.ini,越改越乱。后来我改成按依赖从下往上检查:设备是否存在且权限一致,DCR/VOTE 是否指向正确介质,CSS 节点是否加入,ASM 是否就绪,最后才检查数据库节点。

同机部署还带来端口冲突。当前机器上的 DSC 相关监听并不是一两个端口:数据库、ASM、CSS、Watcher 各有自己的通信入口。只要旧实验残留一个进程,下一次启动就可能表现为“配置读取失败”或“节点无法加入”,而真正原因只是端口已被占用。现在我会先把端口反查到 PID,再把 PID 的完整启动参数反查到配置路径,而不是看到Address already in use就随手换一个端口。随手换端口会让节点间配置失去对应关系,短期避开冲突,长期增加隐患。

我还踩过一个概念坑:共享磁盘“能看到”并不等于 DSC 已经正常。操作系统能列出设备,只证明块设备对当前主机可见;只有 DCR、CSS、ASM 和数据库节点状态都相互一致,并通过跨节点写入、查询验证,才能说明共享数据路径工作。相反,主备中的 OGUID、Watcher 组关系,也不能直接套进 DSC 的 CSS 体系。字段名称相似,不代表它们属于同一协议。

最终我把 DSC 启动流程理解成一个状态机,而不是一串命令。每启动一层,都要保存该层的成功证据,再进入下一层;停止时则反向处理。这样做看起来慢,实际比“全部启动后看谁报错”快得多,因为错误被限制在刚刚变化的那一层。

四、开始压测:零错误不等于曲线稳定

集群能运行后,我开始适配 BenchmarkSQL。原以为只要换 JDBC 驱动和连接串,实际先后遇到了 CentOS 7 软件源失效、Ant 构建、DM8 SQL 兼容、驱动目录中存在重复 JAR 等问题。工具链的每一层都可能改变结果:驱动加载错版本,连接行为会变;初始化数据不完整,事务比例会变;采集脚本漏列,后面生成的曲线再漂亮也没有分析价值。

因此我先做小规模冒烟,确认能产生事务、延迟和错误记录,再进入阶梯并发和长稳测试。这里也有一个教训:冒烟只用于验证流程,不能拿来评估容量。样本过短、CSV 不完整或预热不足的轮次,应明确标成无效或仅供诊断,不能与正式结果放在同一张“能力表”里。

最初我回答“曲线稳定吗”时,主要依据是错误数为 0。老师追问以后,我才重新检查窗口内吞吐。主备长稳测试的吞吐变异系数 CV 为 12.47%,DSC 长稳为 11.55%。这两个数说明对应窗口存在可量化波动,最多可以说“整体可运行、无持续失控,但并非完全平稳”,不能简单写“性能曲线稳定”。稳定性至少要联合平均吞吐、CV、时间趋势、P95、最大延迟和错误率,最好还要排除预热与收尾窗口。

摸高测试暴露了另一个误区。DSC 测到 80 线程时错误数仍为 0,这只能证明在已测试到的 80 线程范围内没有记录到事务错误,不能证明 80 线程就是容量上限。实际吞吐在较低并发后已经进入平台,没有随线程数持续线性增长。此时继续加线程,可能只是增加排队与尾延迟,而不是提升有效处理能力。所谓“摸高”不是找到一个还能跑的最大线程数,而是识别吞吐拐点、延迟恶化点和错误出现点。

部分组别的 t20、t30、t40 还出现过非单调变化:并发增加,吞吐反而下降或又回升。这个现象不能只挑最高的一次解释为能力提升。它可能来自同机其他实例争用、缓存冷热、检查点、日志刷盘、网络抖动或测试轮次不一致。严谨做法是重复关键档位,固定预热、持续时间和数据规模,同时采集 CPU、I/O、内存、锁等待和日志指标。如果没有这些旁证,结论应停在“发现异常,需要复测”,而不是编造一个确定瓶颈。

、五百万行 SQL:我一度把 256 当成结果行数

之后遇到的 SQL 题目是创建五百万行表 T1,执行自连接:

SELECT*FROMT1 A,T1 BWHEREA.V1=B.V1ANDB.V2='1';

原始数据中 V1 是 1 到 5000000,V2 为随机字符串。执行计划里两个分支出现 CSCN2,其中一处显示5000000->256。我一度把 256 理解成过滤结果,试图“让这里变成 99”。但当时查询实际未选定行,256 显然不是最终结果行数。结合执行器输出,它更接近批次或向量处理中的展示值。真正应回答的是:怎样让V2='1'确实得到 99 条数据,以及怎样避免扫描五百万行。

我先构造 99 条满足条件的记录,再在 V1 上建立索引,并在(V2,V1)上建立组合覆盖索引;随后重新收集统计信息。索引顺序有明确目的:谓词先按 V2 等值定位,再从同一索引取得 V1 参与连接。若 V1 的唯一性能够被优化器利用,冗余自连接还有机会被消除或短路。原始轮次约有 15060 次逻辑读,执行时间约 222.407 ms;优化后的不同验证轮次中逻辑读出现 36 和 64,最终返回 99 行的一轮约为 4.784 ms。

这里有两个必须说明的边界。第一,36 和 64 来自不同验证情形,缓存状态和执行路径可能不同,不能拼成一个固定性能数字。第二,DM8 不同版本的优化规则和执行计划展示可能不同。有的版本能明显显示SSEK2(V2,V1)索引做范围定位,有的版本还会对冗余连接做短路;因此没有必要为了让截图出现某个指定的->99而修改或伪造输出,最终行数、访问路径和逻辑读才是更可靠的证据。

实验脚本还重复执行过CREATE INDEX,得到“索引已存在”。这不是优化器问题,而是脚本缺少幂等检查。现在我会先查USER_INDEXES、数据分布和统计信息更新时间,再决定是否建索引。优化也不能只谈查询变快:额外索引会增加写入、空间和维护成本。这个题目验证的是选择性、索引顺序和执行计划,不足以推出真实业务应该无条件增加两棵索引。

六、部署 DMDPC:从 PowerShell 编码错误一路排到 RAFT

DMDPC 是整段学习经历里最曲折的一部分。为了不破坏已有环境,我在/nas/dmdpc_lab下新建独立实验目录,先做三 BP 的单副本分布验证,再做带 RAFT 副本的故障验证。计划本身清楚,真正执行时却先被本地工具卡住:PowerShell 5.1 对无 BOM 的 UTF-8 中文脚本解析异常,中文路径变成乱码;SSH 包装窗口又只显示“执行结束”,把远端真实错误遮住;跨 PowerShell、SSH、Bash 三层传递复杂引号时,还出现过unexpected EOF

这些问题让我重新安排自动化顺序。长命令不再塞进多层引号,而是拆成可单独执行、可保存输出的步骤;本地脚本尽量避免中文硬编码,通过脚本自身位置推导目录;SSH 必须保留原始标准输出和错误输出。今天重新制作本文截图时,我甚至再次触发了同一种中文路径问题,也再次证明:如果没有看到原始错误,人很容易把本地脚本失败误判成远端数据库失败。

进入数据库层后,问题继续出现。目标版本的 disql 参数顺序与我参考的示例存在差异;业务用户缺少合适的默认表空间;一个校验脚本还把 SQL 文本中的“1200”误当作查询结果。后来我把校验条件收紧,只匹配带有固定前缀的结果字段,并同时检查命令退出状态和结果文件。连接成功、SQL 被打印出来、文件中出现数字,三者都不等于业务验证成功。

单副本实验最终写入 1200 行,通过SF_GET_EP_SEQNO(ROWID)SP_GET_EP_COUNT交叉检查,三个 BP 的实际分布为 450、375、375。这个分布不是平均的 400/400/400,但三种查询口径一致,说明结果是真实分区分配,而不是统计脚本算错。它只能证明这张表、这个哈希键和这批数据的分布,不能外推为所有 DPC 表都按同样比例落盘。

多副本验证又碰到版本兼容。参考资料中的GV$RLOG_RAFT_INFO在目标环境不可用,直接到 BP 查询业务表还返回[-3818]。我最初担心副本没有数据,后来才明确:BP 在这套架构和版本中不是普通业务查询入口。正确的证据链应从 SP 执行业务查询,再用目标版本支持的V$视图检查 RAFT 角色、状态和 F_LSN,同时检查 SHADOW 等副本状态,而不是强行把 BP 当作单机库验证。

故障注入时,我停止原主副本 R_BP1。随后 R_BP2 显示为 PRIMARY/OPEN;从 SP 继续插入 100 行后,业务表共 1100 行,SUM(ID)=605550。恢复原副本后再次查询,1100 行和求和结果保持一致,角色及日志位置重新收敛。这条证据能证明本次单副本故障期间业务入口仍可完成写入和完整性校验,也能证明恢复后副本重新加入;它不能证明任意双故障都可用,更不能在缺少连续探针的情况下给出毫秒级 RTO。

七、最后形成的排障经验

经历这些问题后,我把自己的排障方式归纳了如下

第一层是执行上下文:我当前在 Windows、远端 Linux,还是 disql?路径、编码、用户和环境变量是否属于这一层?这一步能提前挡住中文路径、脚本缺失、权限和引号错误。

第二层是资源身份:目标目录、配置文件、PID 和端口是否指向同一个实例?同机多套环境时,任何一个名字都不够,必须交叉核对。对危险操作还要先由 PID 反查完整参数,确保不会停止错误实例。

第三层是组件依赖:主备检查通信、归档、角色和 Watcher;DSC 从设备、DCR/VOTE、CSS、ASM 到 dmserver;DMDPC 则区分 MP、SP、BP 以及 RAFT 副本。排查顺序沿依赖从底向上,恢复后再从上到下验证业务。

第四层是功能验证:不用“服务已启动”作终点,而是执行最小业务闭环。主备要做主写备查并确认服务名行为;DSC 要跨节点写入和读取;DMDPC 要从 SP 写入、汇总,再结合分布或 RAFT 视图。查询结果必须带固定标识,避免验证器误匹配 SQL 文本。

第五层是量化验证:性能同时看吞吐、延迟、错误和资源;稳定性看窗口、趋势、CV、P95 和最大值;摸高看平台与拐点,不看“最高线程还能跑”;RTO 以连续业务探针为主线,对齐故障和角色事件。

第六层是证据闭环:保存原始命令、时间戳、输出文件、环境说明和结论边界。当前检查与历史回放分开标注,失败样本也保留。最后让另一条独立证据交叉验证关键数字,例如 DMDPC 的分布同时由 ROWID 映射和过程统计确认,故障期间的数据同时由 COUNT、SUM、角色和日志状态确认。

还有一个顺序原则:在下层证据没有成立前,不急着讨论上层结论。SSH 都没有真正执行,就不能解释远端数据库;实例身份没确认,就不能随意停进程;业务探针不完整,就不能给出 RTO;样本窗口不合格,就不能做容量结论。这个顺序让我少走了很多“越修越乱”的弯路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询