最近在帮客户梳理一套核心交易系统的灾备方案,数据库用的正是DM8。客户原来的生产环境是单机实例,业务量上来之后,单点故障的影响范围已经不能接受,于是先把生产库改造成了共享集群,双节点共享存储,解决同机房内的高可用问题。但集群本质上只防机房内部的故障,机房整体断电、网络中断、物理损坏这些场景仍然没有兜底。所以就有了这个项目:在灾备中心再建一套DM8共享集群,和生产中心形成两套集群的异地灾备关系。整个方案涉及架构设计、数据同步机制、切换演练和大量细节排查,很多经验不能从单实例灾备直接照搬,也不能想当然地把Oracle RAC的思路套到DM8上。这篇文章把项目从需求摸底到切换演练的完整过程记录下来,重点说清楚共享集群做灾备时的数据同步原理、演练中的实际坑点,以及哪些参数和监控项是最容易被忽略的。
1. 立项背景:为什么单节点不行,为什么不能照搬Oracle RAC的经验
1.1 原系统的三个痛点
客户的业务系统属于典型的交易类应用,高峰期写入量不大,但每笔交易都要求强一致,不能接受丢数据,也不允许出现主库抖动导致的短暂只读。改造之前用的是单节点DM8,数据备份靠每日逻辑导出加物理备份,恢复演练基本没做过。真正推动立项的是三个痛点。
第一个痛点是计划内维护时间越来越难约。单节点做升级、打补丁、参数调整,基本都要停业务,一个月至少一次窗口,业务部门已经明确表示不能接受。第二个痛点是硬件故障的恢复时间不可控。单节点依赖服务器自身稳定性,一旦硬件异常,从告警发现、硬件更换到数据库恢复,通常要几个小时,超出业务容忍范围。第三个痛点是备份有效性问题。备份文件确实每天都在产生,但从未做过真正的恢复演练,归档日志和备份文件是否能拼出一个完整可用的库,没人敢打保票。
这些问题靠共享集群解决了大部分:两个节点共享同一套存储,任何一个节点故障,另一个节点可以继续提供服务,计划内维护也可以逐个节点滚动进行。但共享存储这套架构天然带了一个新问题——它防不住机房整体故障,因为两个节点用的是同一份存储,存储坏了、机房断电了,所有节点一起挂。
1.2 灾备目标的梳理
灾备方案设计之前,我们先和客户把目标量化了。RPO要求是分钟级,也就是灾难发生后最多丢失最近几分钟的数据;RTO要求是五分钟以内,应用能切到灾备端并恢复服务。这个目标在单实例时代根本做不到,因为数据库灾备通常依赖归档日志,日志的产生、传输、应用都有延迟,分钟级RPO已经需要非常严格的保障机制。
在架构选型上,客户第一版提了个想法:既然生产端已经是共享集群,灾备端能不能直接用一套新的DM8共享集群,然后通过某种方式让两套集群"看起来像一套"?这个想法是不成立的,DM8共享集群成员之间通过高速网络和共享存储协调事务,跨机房、跨存储的节点无法作为同一集群成员加入,强行扩展会把集群的核心通信链路拉长,性能和稳定性都不可控。所以最终确定的方向是:两套独立的共享集群,一套在生产中心,一套在灾备中心,两套集群之间通过数据同步机制保持一致,切换靠应用入口的调度完成。
这个目标定下来之后,项目的核心工作就变成了三件事:第一,灾备中心集群怎么初始化,数据怎么加载;第二,生产端到灾备端的数据同步怎么做,延迟怎么控制;第三,切换流程怎么设计,怎么验证它确实可用。
2. 两中心四节点:共享集群灾备的架构设计与实现逻辑
2.1 生产中心共享集群的部署形态
生产中心这套集群改造时已经运行了一段时间,两个节点通过共享存储挂载同一套数据文件,加上私网通信和集群心跳机制。节点对存储的并发访问由集群管理组件统一协调,确保同一个数据页不会被两个节点同时修改。这套架构在DM8里并不复杂,但有一个关键点需要特别注意:共享集群的部署依赖存储层的锁和缓存一致性,存储设备必须支持SCSI-3持久保留之类的协议能力,否则集群无法正常启动。
生产中心架构确定后,我们对存储划分做了统一规划。数据文件、联机日志、归档日志分别放在不同的共享卷组里,归档日志单独分卷的原因是为了后续灾备同步——它需要被持续读取和传输,如果和业务数据文件混在一起,既影响性能,也给备份策略增加复杂度。共享卷组按照生产和灾备两套环境分别创建,避免后面数据初始化时误操作。
2.2 灾备中心共享集群的初始化与数据加载
灾备中心的初始环境是一套全新安装的DM8共享集群,两个节点加一套共享存储,版本与生产端保持一致。版本不一致是个大坑,DM8共享集群的灾备对版本匹配要求非常严格,如果生产端已经打了补丁而灾备端没打,同步过程会出现各种莫名其妙的错误。我们专门在项目计划里加了一步:核对两端的版本号和补丁包,确保完全一致后再做数据初始化。
数据加载用的是备份还原方式。在生产中心做一个数据库级全量备份,把备份集传输到灾备中心,通过数据库的备份恢复功能还原出一套完整的数据库数据文件,再启动集群。这一步看起来简单,实际操作时要注意还原之后必须连日志一块恢复并做一致性校验,因为这个全量备份的生成时间点可能早于当前生产库的最新状态,需要通过归档日志把灾备端推进到备份结束后的某个一致点。数据加载完成后,我们记录了灾备端数据库的当前日志序列号,作为后续增量同步的起点。
2.3 写入入口与网络路径上的隔离设计
两套集群都就绪之后,兜在最外面的是应用入口的调度。生产中心和灾备中心各有一套应用连接配置,正常状态下所有读写流量都指向生产中心集群,灾备中心集群只接收数据同步,不接受业务写入。这个"写入隔离"非常关键,如果灾备端被业务误连接并产生了写操作,整个数据同步链路会立即被打断。
网络路径设计上,生产中心集群和灾备中心集群之间走的是专线,路由层面做了隔离配置,确保只有数据库同步相关的端口互通。防火墙策略只放行预定义的通信端口和备份传输端口,其他端口一律拒绝。最初我们没有对备份传输端口做带宽限制,第一次全量备份灌数据时,生产和灾备之间的专线被备份流量占满,生产中心到灾备中心的实时归档同步出现明显延迟,后来给备份传输单独划了限速策略,实时同步的稳定性才恢复正常。
两套集群都在各自中心内配置了外部访问的VIP,由负载均衡设备统一调度。灾备切换时,负载均衡的调度策略切换是分钟级的事,这比数据库层面折腾半天要可靠得多。
3. 数据同步的三种手段:实时归档、备份还原与增量追赶
3.1 实时归档同步是主力手段
共享集群灾备的数据同步,核心机制是把生产中心的联机日志以归档形式持续传递到灾备中心,由灾备集群的同步进程读取归档并重新应用。理解这套机制的关键在于:共享集群里的联机日志是在共享存储上统一管理的,实例切换或节点故障不影响日志的连续性;灾备端要做的是把生产端产生的每一段归档日志都拉过来,按顺序应用到自己的数据文件上。
项目里我们把实时归档同步设计成双链路。生产中心两个节点的实例都会产生联机日志,但需要归档时会把日志写到共享卷上的归档目录里,由统一的归档进程传输到灾备中心。传输通道独立于生产业务网段,应用了压缩和断点续传能力。网络抖动时,传输进程会自动重试,不会因为一次短暂中断就把整个同步链路打挂。
这套机制能支持分钟级RPO的前提是:归档日志的刷出频率足够高。DM8的联机日志可以配置在满足一定条件时自动归档,切换频率、写入量大小都会影响归档日志的生成节奏。交易量低的时候,可能几分钟才产生一个归档文件,这就意味着RPO可能被拉长到分钟级。为了压缩这个窗口,我们把归档触发条件调得比较激进,小事务批次也会促使归档及时生成,同时监控归档目录的产生时间戳,一旦超过阈值立即告警排查。
3.2 离线备份文件作为补齐通道
实时归档同步是增量通道,但还有一个场景必须用离线备份来兜底:灾备端集群由于长时间失联或数据异常,需要重建。比如某个版本升级失败,或者同步状态出现不可修复的错误,这时最快的恢复办法不是一点点修同步,而是重新灌一份全量备份。
我们安排每天晚上在生产中心做一次全量物理备份,备份集自动传输到灾备中心,保留最近三天的备份文件。这个策略看起来"浪费空间",实际非常实用。灾备端出问题时,只要从最近一次全量备份还原,再补上备份点之后的归档日志,就能快速对齐到比较新的时间点。相比直接从零搭建环境,这个方式能把恢复时间从小时级压缩到半小时左右。
离线备份还有一个用途:定期做灾备端的恢复验证。我们每个季度会从备份集中抽取一个时间点,在灾备端的临时实例上恢复出来并做表级数据校验,确认备份文件不是"死文件"。很多项目备份一直在做,但从没验证过恢复结果,真正灾难来临时才发现备份不可用,这是最惨的教训。
3.3 增量追赶与恢复点验证
增量追赶是实时归档同步之外的另一道保险。当灾备端出现同步中断又恢复后,传输进程会从断点重新拉取归档日志。断点位置从哪来?灾备端本地会记录已经应用到的日志序号,传输进程拿到断点后,如果本地没有对应的归档文件,就会回到备份集目录里查找历史归档。这里必须保证归档日志的保留周期足够长,至少要覆盖从全量备份时间点到当前时间的全部日志。
项目里把归档日志保留周期设成了七天,生产中心和灾备中心都做了周期性清理,但清理逻辑单独拆分,避免和备份文件的保留策略互相冲突。同步中断超过七天时,光靠增量追赶已经追不回来了,必须走备份还原重建流程。这个天数要和业务的RPO/RTO以及备份频率综合考虑,不是拍脑袋定的。
恢复点验证是整个同步方案里最容易被省略的一步。我们每周会在灾备中心做一次低峰期查询,抽取最近几张核心业务表的记录数和最大更新时间,与生产中心对比。对比结果能直观地反映同步是否有效、数据延迟是否在可接受范围内。这个验证过程不需要停业务,也不影响灾备端正常同步,但能提前暴露很多"看似在同步、实则已断裂"的问题。
4. 演练实录:从计划内切换到故障切换,我们踩过的坑
4.1 计划内切换的七个步骤与时间统计
计划内切换,也就是常说的"主动切换",通常出现在机房维护、版本升级或生产中心计划性演练时。整个流程设计成七个步骤:
- 应用侧停止写入,确认所有事务已提交完成。
- 生产中心发起日志归档切换,确保当前联机日志已全部生成归档文件。
- 传输进程将最后一批归档日志拉取到灾备中心,并完成日志应用。
- 核对灾备端数据状态,确认已追到与生产端最近的一致点。
- 负载均衡切换调度入口,把业务流量切到灾备中心的VIP。
- 灾备端集群接受业务写入,开始独立承载。
- 检查应用侧日志和核心交易成功率,确认切换完成。
第一次演练时,我们犯了一个典型错误:在第一步停了应用写入之后,没有等生产端的当前联机日志刷出归档文件就执行了切换,结果灾备端追到的数据点比生产端实际提交完的点落后了一小段。虽然只差十几秒的数据,但严格来说已经不满足RPO要求。后来把"主动切换当前联机日志并确认归档文件生成"这个动作固化成脚本,每次切换前自动检测归档日志的生产时间和大小,只有确认归档动作完成才允许进入下一步。
整体时间统计上,在我们这个环境里,从停应用到灾备端完全可写,耗时大约在90秒左右,主要时间花在找一致点和切换应用入口。90秒里有约60秒是日志应用追平的过程,剩余是切换调度和验证的时间。这个表现满足客户RTO五分钟的要求,但前提是第一步应用停得干净。
4.2 故障切换的真实场景:同步延迟抬头的处理
计划内切换演练通过之后,我们做了一次模拟故障切换:在不通知应用侧的情况下,直接断开生产中心与灾备中心的同步链路,模拟"生产中心完全失联"的状态。这次演练暴露了一个问题:同步延迟开始快速抬头时,灾备端并没有报警,直到手动查询才发现归档日志已经积压了一段时间。
原因在于最初监控项只配置了同步状态是否正常、链路是否断开、核心表数据量差值是否在阈值内,但没有监控"归档日志积压数"。链路断开后,传输进程停止拉取,生产端的归档日志还在持续生成,积压数不断上涨,但同步状态显示未断开,所以没有触发告警。把"归档日志积压数"和"最近同步完成时间"加入监控后,这个问题才算真正解决。
故障切换本身执行得比计划内切换更粗暴:直接切换应用入口到灾备中心,灾备端集群立刻进入可写状态,应用开始正常处理交易。但这里有一个必须提前处理好的矛盾:如果生产中心没有完全损坏,只是网络隔离,那么生产中心的应用实例可能仍然在访问数据库并产生写入,两端同时写入就会造成数据分叉。我们设置了一个强制保护机制:切换脚本首先在生产中心集群上执行"断开业务入口"的操作,再把灾备端切换为可写状态。只要业务入口被切断,生产端即使没坏,也不会有新的数据写入。这套机制在演练中验证有效,关键是要确保应用连接池的重连超时时间足够短,否则应用流量不会快速切到灾备端。
4.3 演练中最容易忽略的验证项
演练不只是看"应用能不能跑起来",数据一致性验证才是核心。前两次演练我们只查了核心表和整体数据量,结果在一次更深度的检查中发现,某张流水表的记录数和生产端完全一致,但部分字段的更新时间与预期不符。追查后确认是前一天该表上有一次批量数据修正,生产端执行后日志同步正常应用到了灾备端,但我们验证时只查了记录数,没有关注关键字段的内容差异。这次之后,验证项的覆盖面扩大到了核心业务表的抽样内容比对,不只是数量级对比。
另一个容易忽略的是日志应用异常。灾备端同步进程在执行某一段归档日志时,可能因为表结构变更、存储过程依赖缺失等原因产生应用错误。这类错误通常不会让整个同步链路全面报错,只会显示某一段日志应用失败。如果监控只看同步总体状态,很容易漏掉。我们在灾备端定期检查网络进程的最新日志位置,并与生产端的归档日志位置做自动比对,一旦发现某个归档文件没有正常应用就告警,确保每一条数据变更都落到了灾备数据库。
演练后的复盘同样重要。第一次故障切换演练后,我们整理出十几条改进项,其中一半是文档和流程类的问题,比如切换手册中对应的负责人信息过期、某些检查命令在灾备端执行报权限不足。这些问题不经过真实演练根本发现不了,写文档时不会有人注意到权限细节。
5. 经验总结:共享集群灾备的边界条件与后续建议
5.1 哪些场景适合这套方案,哪些不适合
这套"两中心四节点"的架构适合大多数以数据库为核心、业务写量不大、要求快速恢复的交易类系统。它解决的问题是机房级容灾,不解决应用层双活和多中心负载分担。灾备中心在正常情况下不承载业务流量,等于一套热备资源闲置在那里,从资源利用率角度看不算高,但换回来的是切换逻辑简单可靠,不需要处理复杂的数据冲突。
如果业务要求两个中心同时提供写服务,也就是应用层双活,那这套方案就不适用了。双活意味着两端同时写入,数据同步会变成双向复制,必须处理冲突检测和合并逻辑,复杂度成倍上升。DM8共享集群的灾备设计更偏向主备模式,我们在项目里明确建议客户不要轻易尝试双写架构,除非业务能接受极端复杂的改造和验证成本。
数据库版本差异、存储设备差异、网络延迟差异都会直接影响这套方案的可行性。跨机房使用普通的业务网络做同步链路,延迟会在几百毫秒甚至更高,RPO也会随之增大。这个项目的两端之间有专用传输通道,延迟保持在几毫秒级别,为了达到分钟级RPO,同步链路质量是硬前提。
5.2 运维侧的日常检查清单
项目交付后,我们把运维侧的日常检查项固化了下来。每天需要检查的包括:生产端归档日志是否持续生成、传输进程是否正常、灾备端归档应用位置是否持续前进、两端核心表数据量差值是否在阈值内、备份文件是否成功传输到灾备中心。每周检查一次归档日志积压数量和延迟时间,每月做一次灾备端数据抽样验证。
监控报警策略也做了分级。一般性告警包括归档日志积压超过阈值、同步位置长时间不前进;严重告警包括同步链路断开、灾备端数据库无法启动、备份文件校验失败。每一条告警都对应了明确的处置手册,责任到人,避免出现告警了没人知道下一步该怎么办的情况。
另外建议运维侧每月做一次"读验证":从灾备中心查询业务视图的响应时间、表空间使用率和集群节点状态。灾备端长期不承载业务流量,容易出现表空间满、归档空间不足、临时文件增长异常等"隐性故障",这些问题平时不读写根本不会暴露,一旦切换时出现,会直接导致灾备中心不可用。
5.3 后续可以考虑的扩展方向
后续如果业务规模进一步扩大,可以在这套架构之上增加一层级联体系:把灾备中心的共享集群再作为数据源,同步到更远距离的第三个中心,形成多级灾备。但级联会引入更大的延迟和更复杂的日志管理,不是所有业务都需要。
从长远看,我更看好的方向是基于备份文件加实时日志的双通道机制逐步演进,让离线备份承担更多的验证和恢复职责,实时同步专注于延迟压缩。备份验证自动化是目前最值得投入的方向——把季度级的人工恢复验证变成每周自动执行,通过脚本比对两端数据快照,可以提前发现绝大多数同步隐患。
这套共享集群灾备方案最终落地后,客户最满意的一点不是架构多复杂,而是切换流程足够简单。好的容灾方案不需要炫技,它需要的是每一天都平稳运行,并且在灾难真正来临时,每一步操作都能按预期完成。哪怕RPO和RTO指标写得再漂亮,没有反复演练过的切换流程支撑,都只是一纸空文。