从主备到 DMDPC:我的 DM8 云虚拟机踩坑与验证之路

发布时间:2026/7/29 14:07:13

从主备到 DMDPC:我的 DM8 云虚拟机踩坑与验证之路 一、拿到公司云虚拟机后我先被多套环境绕晕我最初从 Windows PowerShell 连接云虚拟机看到提示符从PS C:\Users\31394变成[rootliuyiwei ~]#再切到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.V1B.V1ANDB.V21;原始数据中 V1 是 1 到 5000000V2 为随机字符串。执行计划里两个分支出现 CSCN2其中一处显示5000000-256。我一度把 256 理解成过滤结果试图“让这里变成 99”。但当时查询实际未选定行256 显然不是最终结果行数。结合执行器输出它更接近批次或向量处理中的展示值。真正应回答的是怎样让V21确实得到 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 编码错误一路排到 RAFTDMDPC 是整段学习经历里最曲折的一部分。为了不破坏已有环境我在/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 反查完整参数确保不会停止错误实例。第三层是组件依赖主备检查通信、归档、角色和 WatcherDSC 从设备、DCR/VOTE、CSS、ASM 到 dmserverDMDPC 则区分 MP、SP、BP 以及 RAFT 副本。排查顺序沿依赖从底向上恢复后再从上到下验证业务。第四层是功能验证不用“服务已启动”作终点而是执行最小业务闭环。主备要做主写备查并确认服务名行为DSC 要跨节点写入和读取DMDPC 要从 SP 写入、汇总再结合分布或 RAFT 视图。查询结果必须带固定标识避免验证器误匹配 SQL 文本。第五层是量化验证性能同时看吞吐、延迟、错误和资源稳定性看窗口、趋势、CV、P95 和最大值摸高看平台与拐点不看“最高线程还能跑”RTO 以连续业务探针为主线对齐故障和角色事件。第六层是证据闭环保存原始命令、时间戳、输出文件、环境说明和结论边界。当前检查与历史回放分开标注失败样本也保留。最后让另一条独立证据交叉验证关键数字例如 DMDPC 的分布同时由 ROWID 映射和过程统计确认故障期间的数据同时由 COUNT、SUM、角色和日志状态确认。还有一个顺序原则在下层证据没有成立前不急着讨论上层结论。SSH 都没有真正执行就不能解释远端数据库实例身份没确认就不能随意停进程业务探针不完整就不能给出 RTO样本窗口不合格就不能做容量结论。这个顺序让我少走了很多“越修越乱”的弯路。

相关新闻