达梦DSC集群架构原理与运维实战全解析
搞过共享存储集群的人都知道DM8的DSC集群管理一直是运维体系里的硬骨头。它不是装完就能撒手不管的东西从架构选型、部署规划到日常巡检、故障恢复每一步都藏着值得记下来的实战细节。这篇文章就把DSC集群从底层逻辑到落地操作完整捋一遍适合正在调研高可用方案、准备搭建DSC环境或者已经在运维但想系统补一补管理思路的朋友。1. DSC集群到底是干什么的架构选型与适用边界1.1 共享存储方案的核心逻辑DSC全称是DM Shared Cluster也就是达梦数据库的共享存储集群方案。理解它之前你得先放下“主备复制”那套思维。主备架构是各写各的盘、靠日志同步数据而DSC是多个数据库实例共享同一份物理存储所有节点直接读写同一套数据文件。这套方案在业界并不新鲜跟Oracle RAC走的是同一条技术路线。它的核心价值在于多个节点同时对外提供服务任何一个节点宕机业务连接自动切换到存活节点数据库服务不中断。对于核心业务系统来说这种“无感知故障切换”的能力是普通主备架构给不了的。我见过不少人在选型时踩坑拿着主备方案的思路去评估DSC结果发现完全不是一回事。DSC解决的是“高可用高性能”的组合问题而不是单纯的“数据不丢”。两者侧重点不同适用场景自然也不同。1.2 什么时候该上DSC适用场景与约束按我的经验真正适合上DSC的场合主要有三类第一类是核心交易类系统比如银行核心账务、电信计费、政务一体化平台这类系统对连续性要求极高停机窗口几乎为零。主备架构切换至少需要几十秒甚至几分钟而DSC可以在秒级完成节点切换业务无感知。第二类是读多写少但并发压力大的系统。DSC多节点分摊查询负载写操作通过高速互连和全局缓存协调机制保证一致性整体吞吐量比单节点有质的提升。第三类是在已有小型机或高性能存储设备基础上做数据库升级的场景。这类场景往往对硬件投入有预算但对停机时间零容忍DSC是在不改变存储架构的前提下提升数据库服务能力的最优解。但DSC也有明确的约束条件。它强制要求共享存储必须使用支持SCSI-3 Persistent Reservation的存储设备各节点必须通过专用高速网络互联千兆网勉强能跑万兆才叫合格节点数在范围内建议控制在2到4个太多了缓存协调开销会吃掉扩展收益。对比维度DSC集群主备高可用方案存储要求强制共享存储各节点直接访问同一份数据各节点独立存储通过日志同步切换时间秒级节点故障业务无感知分钟级需要手工或脚本触发切换扩展能力在线扩展节点提升整体吞吐扩展受限于主库单点能力一致性保障全局缓存协调强一致依赖日志同步备库可能延迟硬件要求高需要共享盘阵和高速互连相对较低普通网络即可还有一个比较隐蔽的坑DSC对应用连接方式有要求。应用必须配置多个连接地址或者通过连接池配置多个IP。有些旧系统硬编码了单个数据库IP改造起来工作量比建集群本身还大。这一点在立项前就一定要想清楚不然后面全是泪。2. 核心机制拆解DSC凭什么能多节点同时读写2.1 四个关键组件各司其职DSC集群的架构可以拆成四个层次每一层都有明确的职责分工理解它们之后日常管理就有章可循了。CSSCluster Synchronization Service是集群的大脑统一管理节点状态、保存集群配置信息、协调节点加入和退出。所有节点启动时都必须先找CSS注册CSS确认集群法定人数后才允许数据服务对外启动。CSS通常部署在两个节点上形成冗余一个为主一个为备主CSS故障时备CSS接替管理职责。DMServer是实际承载业务的数据库实例每个节点跑一个独立分配内存和进程资源共享底层存储。这也是DSC“多实例”的直观体现。Watcher监视器负责数据库实例的健康监控和故障处理。它持续监控实例状态一旦判定某个实例故障就会通知其他节点执行恢复或隔离操作。Watcher本身也是一个进程需要独立部署通常与CSS复用节点或单独分配机器。DCRDM Cluster Repository是集群配置信息的持久化存储记录节点列表、ASM磁盘组、数据库信息、实例配置等元数据。DCR通常存放在共享磁盘的特定分区上被所有节点共同访问。一个形象的类比是CSS是公司的行政中枢负责员工登记和考勤DMServer是各业务部门的办公区大家共用一间大办公室共享存储Watcher是保安盯着各部门是否正常运转出问题就报警并按预案处理DCR则是公司的档案室所有人的档案和规章制度都存在那里谁入职都要先查档案。每个组件都是独立进程这也是DSC管理的一个特点你管理的不只是一个数据库而是一套多进程协作的系统。2.2 缓存一致性DSC的核心难点DSC面临的最大技术难题是缓存一致性。多个实例同时读写同一份数据文件如果各节点在自己的缓冲区里缓存了同一份数据的不同版本读出来的结果就不一致整个数据库的语义就崩了。DSC采用基于数据页的锁机制来解决这个问题。每个节点在读写某个数据页之前必须先在全局锁管理器中申请对应的锁。锁分为读锁和写锁多个节点可以同时持有同一数据页的读锁但写锁是独占的。某节点要修改数据页时必须先持有写锁持有写锁期间其他节点既不能读也不能写这一页。这就像图书馆里的一本热门参考书所有人都可以同时看读锁但谁要带走这本书写锁其他人就得等着。DSC里的锁管理就干这个事。为了减少跨节点锁请求带来的性能开销DSC引入了亲和关系机制。数据页被分配到特定节点时该节点优先在本地处理这些页面的事务减少全局锁的申请频率。运维中可以通过参数调整负载分布策略让不同节点的热点数据尽量分离这是DSC性能调优的一个重要方向。DSC还维护了一个类似多版本并发控制的机制处理读写并发时的阻塞问题。读操作可以读取提交前的历史版本不必等待写锁释放这能显著降低读写冲突时的等待时间。我在实际调优时发现针对报表和OLTP混合负载通过合理配置多版本参数整体响应时间能缩短近三成。2.3 事务协调、故障转移与序列管理DSC的每个节点都能独立提交事务不需要像某些分布式数据库那样做全局协调者。但跨节点的全局事务必须保证原子性这就依赖全局事务管理机制。节点间通过高速互连网络进行事务状态同步任何一个节点提交事务时相关参与节点会记录事务状态日志一旦中途出现故障恢复时通过状态日志完成回滚或提交。这种机制在正常运行时开销很小但故障恢复时能保证所有节点数据一致性。故障转移是DSC的核心卖点。实例故障后Watcher会通过CSS将故障节点从可用节点列表中剔除并通知存活节点接管锁信息和未完成事务。存活节点会重新申请故障节点的锁资源同时通过日志追平故障节点已完成事务产生的数据变化整个过程不需要人工干预。序列管理这块容易被忽略。DSC集群中多个实例对主键序列的获取必须全局唯一不能各发各的导致冲突。DSC通过集中式的序列值分配机制保证序列的全局唯一性同时做了性能优化每节点可缓存一段序列值避免频繁访问全局序列管理模块。但这带来一个坑节点故障时该节点缓存但未使用的序列值会作废可能导致应用中主键出现明显跳跃。业务上对主键连续性有严格要求的系统设计时要提前留出余地。3. 部署实操两节点DSC环境从零到可用的完整落地下面进入最有价值的环节。我以两节点DSC集群为例完整的走一遍部署过程所有关键配置和步骤都展开说明。这里面踩坑的地方非常多我会把注意事项单独标出来。先给硬件规划定个调项目节点1节点2共享存储IP地址192.168.10.11业务/ 10.0.1.11私网192.168.10.12业务/ 10.0.1.12私网-操作系统Linux x86_64Linux x86_64-数据盘--共享LUN划分5个分区角色CSS DMServer WatcherCSS备 DMServer WatcherDCR存储3.1 共享存储准备与分区DSC要求共享存储这一步是整个部署的基础也是出错高发区。首先用存储管理软件把LUN映射给两台主机。映射完成后两台机器上执行multipath -ll确认多路径识别状态。如果没看到设备或者链路显示不完整先别往下走修好多路径配置。然后进行分区操作。我习惯用fdisk把共享盘划成5个分区分配如下分区大小用途/dev/mapper/data1100MBDCR存储器/dev/mapper/data250MB日志磁盘组的一部分/dev/mapper/data350MB日志磁盘组的另一部分/dev/mapper/data4剩余数据磁盘组/dev/mapper/data5剩余备份或扩展预留分区之后还要用udevadm settle刷新设备再确认两边的设备符一致。这一步有坑多路径设备符在两台机器上不一致后面配置会全部乱套所以务必在两台机器上同时执行ls -l /dev/mapper/对比确认。注意分区和格式化只在一台机器上执行操作完成后另一台机器刷新设备即可看到千万不要两边都初始化文件系统会导致元数据错乱。3.2 配置文件逐个拆解dmdcr_cfg.ini、dmcss.ini、dmwatcher.iniDSC部署的核心是三个配置文件的正确编写。以其中最关键的一个文件为例dmdcr_cfg.ini是DCR的配置源文件所有节点信息都写在这里DCR_N_GRP 2 DCR_N_EP 2 DCR_EP_NAME DSC0 DCR_EP_HOST 192.168.10.11 DCR_EP_PORT 9341 DCR_EP_SEQNO 0 DCR_EP_NAME DSC1 DCR_EP_HOST 192.168.10.12 DCR_EP_PORT 9341 DCR_EP_SEQNO 1 DCR_GRP_DSKNAME /dev/mapper/data1 DCR_GRP_DSKSIZE 100 DCR_GRP_DSKSSLIST 50 DCR_ASM_DSKNAME /dev/mapper/data4 DCR_ASM_DSKSIZE 2048 DCR_ASM_DSKNAME /dev/mapper/data5 DCR_ASM_DSKSIZE 2048 DCR_ASM_DSKNAME /dev/mapper/data2 DCR_ASM_DSKSIZE 512 DCR_ASM_DSKNAME /dev/mapper/data3 DCR_ASM_DSKSIZE 512DCR_N_EP定义了集群的节点数量。这个参数后面想改很麻烦一定要提前确定。DCR_EP_SEQNO是节点序号CSS选举和DCR定位都要用到两个节点的序号必须从0开始递增。DCR_ASM_DSKNAME定义了ASM磁盘组使用的物理设备DSC的存储管理还是走ASM这套机制数据、日志、DCR各自独立避免相互干扰。接着是dmcss.ini这是CSS进程的配置CSS_DCR_DSKNAME /dev/mapper/data1 CSS_DCR_DSKSS_SIZE 100 CSS_DCR_DSKSSLIST 50 CSS_LOG_FLUSH_NUM 1 CSS_LOG_FILE_PATH /data/dm/css_log CSS_PREF_EP 0这里最值得说明的是CSS_PREF_EP它指定了优先的CSS主节点序号。这里写0表示默认让DSC0当主CSS如果DSC0故障CSS自动切换到DSC1上。这个配置决定了CSS的运行倾向规划时不指定可能会在两个节点间反复切换引发不必要的集群抖动。Watcher的配置dmwatcher.ini如下DW_P 1 DW_SERVERID 1 DW_PORT 9343 DW_EP_NAME DSC0 DW_EP_FREQ 10 DW_LOG_FILE_PATH /data/dm/watcher_logDW_P表示启动方式1为自动0为手动。DW_EP_FREQ是探测间隔单位是秒。时间设得太短会增加无谓的状态探测流量设得太长会导致故障发现延迟实际经验是5到10秒比较合适。3.3 初始化DCR、启动服务与建库注册配置文件准备好之后按顺序执行以下步骤。第一步在两台机器上分别执行DCR初始化命令。需要特别注意这一步只需要在其中一个节点上执行一次初始化完成后DCR存储就写好了另一台节点直接读取。dmasmcmd create dcr /data/config/dmdcr_cfg.ini命令执行后会出现初始化成功的提示同时输出DCR存储的路径和分配信息。此时在另一台机器上执行dmasmcmd read dcr如果能看到同样的内容说明DCR共享正常。第二步启动各节点的CSS进程。两个节点都要执行dmserver /data/config/dmcss.ini严格来说CSS的启动方式是dmcss这个独立程序启动后它会读取dmcss.ini并尝试连接DCR。启动日志里会出现CSS is ready for cluster service字样代表CSS注册成功。第三步启动数据库实例并完成建库。在各节点分别启动数据服务先做初始化库dminit PATH/data/data DB_NAMEDSC0 INSTANCE_NAMEDSC0 PORT_NUM5236两节点数据目录是共享的所以只需在第一个节点执行一次dminit。第二个节点启动时直接从DCR读取集群信息并挂载数据文件即可是根据集群元数据自动完成的不需要再次初始化和创建数据库。这里有一个很关键的步骤初始化完成之后还要将数据库注册到集群中dmserver /data/config/dm.ini然后把实例注册到DCR和CSS中让DSC集群认为这个实例是集群的合法成员。具体操作是通过DM管理工具执行ALTER DATABASE MOUNT和ALTER DATABASE OPEN完成数据库由非集群模式切换为集群模式同时写入集群元数据。这一步看似简单做错会导致节点加入集群失败启动后其他节点报“EP状态不一致”错误。最后启动Watcher进程在三台机器上都要执行dmwatcher /data/config/dmwatcher.ini启动完成后通过ps -ef | grep dm*查看进程状态应该在每台机器上看到CSS、Watcher、DMServer三个进程都在运行。两节点的业务IP都能正常登录数据库集群就算建起来了。4. 日常管理状态巡检与集群变更操作4.1 状态巡检这些命令和视图要刻进脑子里DSC部署完成后日常管理是重头戏。我平时巡检主要靠三个手段SQL查询、管理工具命令和日志分析。通过数据库视图查看集群状态是最直观的方式。登录任一节点执行SELECT * FROM V$DSC_CLUSTER_INFO;这个视图会列出集群内所有节点的基本信息包括EP序号、节点名、状态、角色、IP和端口。状态字段如果是OPEN说明节点正常提供服务如果是MOUNT说明节点处于挂载状态可能是在做恢复或维护如果是SUSPEND要高度重视节点已处于瘫痪状态。再配合这个查询SELECT * FROM V$DSC_EP_INFO;V$DSC_EP_INFO能直接查看当前会话所在节点的EP编号这对判断会话是否发生了节点漂移非常有用。还有V$DSC_LOCK_INFO视图可以看到锁的分布情况某个节点的锁数量异常暴涨往往意味着该节点存在未释放的大事务或者应用存在锁竞争问题。管理工具层面CSS和Watcher都自带了命令行监控界面可以通过dmcss的交互命令查看集群状态。在CSS启动的终端按下CtrlC进入交互模式输入show命令会展示集群状态、节点信息和DCR信息。Watcher交互界面里也可以输入show命令查看监控状态包括每个节点的LSN、连接状态、事务状态等。日志方面各进程的日志文件路径都由配置文件指定。日常巡检重点看CSS日志中的状态变化记录、DMServer日志中的出现INSTANCE OPEN SUCCESS或SWITCH OVER字样、Watcher日志中是否存在异常退出信息。巡检对象关键指标正常参考值 / 状态CSS节点是否全部在线所有EP ONLINEDMServer实例状态OPEN状态为正常WatcherLSN是否持续增长各节点LSN接近或一致锁各节点锁数量平稳无异常积压网络私网丢包率0%延迟不超过1msLSN的差异是一个关键指标。多个节点的LSN如果长时间维持较大差距说明某个节点已经落后了这往往是网络不稳定或节点压力过大造成的需要尽早介入。4.2 节点重启与实例故障后的处置流程节点重启是运维中最高频的操作。很多人以为直接执行systemctl restart就行结果造成集群出现不必要的隔离或切换。正确的重启流程应该是这样的先把要重启节点的业务连接切走减轻节点上的活跃事务压力然后通过管理工具执行ALTER DATABASE SUSPEND;ALTER DATABASE SUSPEND的作用是把该节点上的写操作停掉只保留读操作让正在执行的事务尽快结束。等活跃事务清零后执行ALTER DATABASE SHUTDOWN;执行完确认数据库进程退出再重启节点。重启后进程会自动根据DCR信息重新加入集群加入完成后通过SELECT * FROM V$DSC_CLUSTER_INFO;确认节点状态恢复为OPEN。如果不是主动重启而是实例故障无法自行恢复就需要走故障处置流程。先通过Watcher日志确认故障原因判断是网络中断、存储链路故障还是进程崩溃。然后在一台存活节点上执行节点剔除操作后再对故障节点进行修复和重新加入整个过程尽量让存活节点持续提供服务。有一种坑是故障节点硬盘出现问题恢复时不断加入又不断掉线形成抖动循环这时候必须彻底排查存储链路而不是反复重启。4.3 备份恢复与节点扩展DSC的备份恢复会走ASM或第三方工具来完成但无论怎么做都必须在备份之前确认集群处于一致性状态。最稳妥的做法是在业务低峰期通过在任一节点执行ALTER DATABASE BACKUP生成一致性备份。需要注意的是DSC的备份文件是全集群级数据的一致性快照概念恢复时必须使用备份集的完整内容单独拿一个数据文件出来恢复是不行的。节点扩展是DSC的加分项过程相对可控。先规划新节点的IP、端口和存储映射在共享存储上为新节点准备专门的DCR空间条目。然后在配置文件中增加新节点的EP定义但不能直接在正在运行的DCR上改需要通过工具重新生成并分发DCR。新节点启动后先以MOUNT状态加入确认加入成功后执行ALTER DATABASE OPEN节点就正式对外服务了。整个过程中新节点需要从其他节点同步自己的缓冲区这几个会明显增加私网流量所以扩容操作尽量安排在业务低峰期。5. 常见故障与排查实录真实场景复盘5.1 CSS状态异常节点被隔离的真实场景某个项目里出现过这样的情况某两个节点的CSS全部显示ONLINE但DMServer状态却一直处于SUSPEND业务报错无法写入。查日志发现Watcher在检测到某实例两轮心跳超时后自动发起了故障隔离把该实例从可用节点集合中剔除了。排查过程先检查私网心跳用ping -f做连续丢包测试当时是10.0.1.11到10.0.1.12之间隔了三层交换机某台交换机高峰期丢包率到了2%。心跳探测在这种丢包率下确实会出现超时误判导致Watcher做出隔离决策。坐实网络问题后对两台交换机之间的链路做了调整把DSC私网流量独立到专用VLAN并配置了端口优先级。网络恢复后在存活节点上执行节点重新加入操作把正常节点重新纳入集群集群恢复正常。这次故障给我最直接的教训就是DSC私网必须跟业务网完全隔离而且要冗余互联单条链路、共享交换机都是安全隐患。最好用两台交换机做堆叠或独立链路保证单点网络故障不影响心跳。5.2 控制文件与日志不同步还有一次故障比较隐蔽。某节点重启后一直无法加入集群报错提示控制信息与集群不一致。初步判断是重启前该节点没有执行正常的SHUTDOWN流程而是直接被强制关闭导致数据库控制信息里的SCN与集群元数据里的SCN不一致。处理方法也不复杂重启后该节点会自动进入恢复模式从其他节点的联机日志中追平到一致的SCN。当时遇到的问题是因为磁盘空间不足导致恢复日志写入失败扩容磁盘之后重新启动节点就顺利追平并加入了集群。这里有个重要提示所有节点正常关闭都必须走ALTER DATABASE SHUTDOWN或SHUTDOWN命令绝对不能直接kill -9。非正常关闭对单机库影响有限但在DSC集群里可能引发SCN不一致的连带问题。谁图省事直接kill后面恢复的时间一定把前面的“省时”加倍还回来。5.3 LSN异常追平与脑裂场景的处理LSN差异问题是DSC运行中比较容易遇到的异常。正常运行的集群各节点LSN应该非常接近。如果某个节点落后了通常是因为它断开了私网或者经历了短时暂停恢复后会自动追平。追平过程需要在存活节点上接受落后节点重新加入落后节点启动后会自动从其他节点请求缺失的日志。我曾遇到一个场景某节点落后了约两千多万条LSN记录追平过程持续了十几分钟期间该节点CPU和IO都飙到高位。此时不要干预更不要去重启节点等它自己追平即可。如果追了很久还没完成需要检查私网带宽确认是否被其它业务占满。脑裂是更极端的情况私网完全断开后两个节点各自认为自己是集群的合法成员同时对外提供写服务。DSC通过Quorum算法来避免这种情况没有法定多数超过一半节点共识节点会主动退出集群拒绝对外服务。这会造成一个现象私网断开后其中一个节点会自动关闭数据库服务防止数据分叉。出现脑裂后的恢复顺序很关键先恢复私网让两个节点恢复心跳然后以拥有最新LSN的节点为准启动服务落后节点追平到同一位置再加入集群不能在没有确认哪个节点更新的情况下直接启动旧节点那样一定会出现数据不一致。5.4 故障排查速查表故障现象可能原因优先排查命令 / 动作节点状态一直MOUNT控制信息不同步或未完成正常关闭检查SCN差异等待自动恢复Watcher日志频繁报超时私网丢包、负载过高ping -f测试丢包检查CPU使用率节点反复加入再退出存储链路不稳定检查多路径链路状态multipath -ll确认无单点故障集群脑裂私网全部断开恢复私网比较LSN选择基准节点业务连接超时锁竞争过大或节点不堪重负查询V$DSC_LOCK_INFO分析活跃SQL扩容后新节点无法OPENDCR配置未同步或ASM磁盘权限不足重新分发DCR检查新节点ASM设备权限写在最后的运维心得DSC集群的管理说到底是三个层面的持续关注网络质量、进程协作、元数据一致性。网络层面私网通道的稳定性和隔离程度直接决定集群的健壮性这块投入再多都不为过进程层面CSS、Watcher、DMServer三者协作的日志是排障的第一现场养成定期翻日志的习惯能帮你提前嗅到问题元数据层面DCR就是全集群的命根子任何涉及DCR的操作都必须在规划后才动手。我个人的习惯是给每个DSC集群建立一份专属运维手册里面记录节点基础信息、DCR配置备份、每次变更的操作记录以及各阶段日志的归档路径。这份手册在一次故障恢复中帮我快速定位了该用哪份配置省掉了大量排查时间。你们如果在DSC上踩过什么不一样的坑欢迎拿出来一起交流毕竟这种系统的经验都是一次次故障换来的踩过的人越少越好。