去年参与了一个同城容灾改造项目,客户要求主中心故障时备中心能在15分钟内接管核心业务,数据不允许丢失。最初大家想得很简单,以为远程复制就是把数据多存一份,后来真到了方案选型阶段,才意识到HDS高端存储的TC(TrueCopy)同步复制里全是细节:状态机有五种,一致性组要按业务维度设计,带宽估算差一个数量级就可能导致主机写超时。这篇文章我想把TrueCopy的原理和配置过程完整梳理一遍,重点放在原理背后的“为什么”和实际配置时文档里不会写的那些约束。适合正在做存储双活或同城容灾的存储管理员、灾备架构师,以及需要理解底层数据保护机制的DBA参考。
1. 从一次容灾改造说起:TrueCopy到底解决了什么问题
1.1 容灾需求里的两种复制路线
做容灾首先得选复制模式。存储复制大体分两类:同步复制和异步复制。同步复制的典型特征是主存储收到主机写请求后,必须先把数据复制到远端存储,等远端确认写成功,才向主机返回“写完成”。这就是TrueCopy的工作模式,它天然保证了主备两端数据在任何一个时刻都处于一致状态。
异步复制则相反,主存储先把数据落到本地,再通过日志或位图机制异步传到远端,主机完全感知不到复制延迟,但远端数据在时间上会落后主端一小段窗口。不要小看这个差别,它直接决定了容灾的RPO(恢复点目标)是零还是秒级。
1.2 场景选型:什么时候该用TC
如果一个业务系统要求RPO为零,比如账务类、订单类核心数据库,那同城范围首选就是同步复制。TrueCopy的设计目标就是满足这种场景:两站点间距离通常几十公里以内,业务高峰期主机写入性能可以接受额外增加的复制时延,主备存储数据完全一致。
我在项目中常用的选型判断表格大致如下:
| 需求特征 | TrueCopy(同步) | 异步复制(如UR) |
|---|---|---|
| RPO | 严格为零 | 秒级 |
| RTO | 分钟级,需配合切换流程 | 分钟级 |
| 站点距离 | 同城,建议20-50km内 | 可跨省,数百公里 |
| 网络带宽要求 | 高,需覆盖峰值写吞吐 | 相对低 |
| 主机性能影响 | 增加约2倍链路RTT时延 | 几乎无感知 |
如果客户说“我们跨了500公里”,那直接放弃TrueCopy选异步方案,同步复制在那种距离下会让数据库事务卡到不可接受。同样道理,如果链路带宽不够,同步复制会反噬业务性能,这种场景也不能将就。
2. 数据通路拆解:一次普通写IO在TC下的完整旅程
2.1 一个写请求如何在两台存储间流转
理解了选型逻辑,还得把数据通路彻底弄明白。我经常用一条完整链路来向新人说明TrueCopy的工作过程,这里不涉及深奥理论,就是把一次写IO从头走到尾:
主机发出写请求,到达主存储(Primary)的控制器后,首先写入主存储的缓存(Cache);主存储控制器识别出该LUN配了TrueCopy复制关系,于是将这笔数据通过远程复制端口发送到备存储(Secondary);备存储控制器收到数据,写入备存储的缓存,随后向主存储返回“写成功”的确认;主存储收到确认后,才向主机返回“写完成”。
注意关键点:主存储不会提前向主机确认。这意味着主机看到的每一次“写成功”,都代表这笔数据同时存在于两边的缓存里。如果备存储不可达,主存储会进入等待超时状态,最终把复制对搞成暂停(PSUS),这时主机写IO就可能会被挂起或报错。
2.2 为什么同步复制会引入“可计算”的延迟
既然要等远端确认,延迟自然变高。这个附加延迟大约等于两倍的链路单向传输时间(RTT),再叠加两台存储各自的控制器处理时间。举例来说,假设同城链路单向传输时间为1ms,那么同步复制给主机带来的额外写入延迟大约是2ms起步。
看起来2ms很小,但对延迟敏感的高并发OLTP系统来说,这2ms就是实打实的性能损耗。如果链路质量差、有拥塞或抖动,这个数值会翻倍甚至恶化。这也是我在项目规划阶段反复强调链路质量的原因——链路不只是“能通”就行,而是要测试端到端延迟和丢包率。
用一个生活类比:同步复制就像要求快递员把包裹送到收件人手里,让对方签收后再回来告诉你“送到了”。你等的是“签收”这个确认,不是“包裹已出库”。这个签收过程天然带着往返路程的时间。
2.3 一致性组:让多块盘像一笔转账一样“原子”
TrueCopy有一个容易忽略但极其重要的设计——一致性组(C/T Group)。单块LUN的复制关系好理解,但一个数据库的数据文件、日志文件、系统表空间通常分布在多块LUN上。如果每块LUN各自独立复制,主端数据库可能先写了A卷再写B卷,复制到备端时,A卷和B卷的数据就可能不属于同一个时间点,备端拼出来的数据库就是损坏的。
一致性组的价值在于,把多个复制对编入同一个C/T组,存储控制器会保证组内所有LUN在复制过程中的时间点是一致的。就好比转账时扣款和入账必须同时成功或同时失败,不能出现“扣了钱但没到账”的中间状态。实际配置里,核心数据库的所有数据卷和日志卷都应放入同一个C/T组。
3. 动手配置前必须想清楚:容量、链路与Pair规划
3.1 容量规划:不是“一样大”那么简单
TrueCopy要求主备LUN容量一致,这是硬件层面的约束,但规划时还要考虑以下几个容易被忽视的细节:
第一,备端LUN的实际可用容量建议比主端数据量多预留10%-20%,因为切换后备端要承担生产业务,如果备端存储本身空间紧张,后续扩容窗口会很被动。第二,如果使用Thin Provisioning(自动精简配置),要确认两端存储的池化属性兼容,很多版本对精简卷和实体卷的复制组合有限制。第三,同一台存储上如果还跑了其他复制任务(比如快照、异步复制),还要考虑控制器后端带宽和缓存资源的竞争,不要只按单个复制对去估算。
我在一个项目里吃过亏:主备LUN容量一致,但备端存储池当时只剩30%剩余空间,初始全量复制跑完后进行切换演练,备端卷要挂载到主机并承担业务,结果业务库往里写了一批归档数据后池空间告急。所以规划备端容量时,一定要把“切换后业务留存数据增长”考虑进去。
3.2 链路规划:独立端口不是建议而是要求
TrueCopy链路最好使用专用的远程复制端口,不要和其他业务共用数据端口。同步复制对链路质量极其敏感,如果远程复制流量和业务流量混跑,高峰期很容易出现排队,导致复制确认超时,Pair状态异常。
距离和延时方面,我建议全链路规划设计时把单向RTT控制在1-2ms以内,总体距离控制在50公里内。越长的链路不光延时高,故障域也更大。如果站点间通过租用光纤或DWDM设备,要协调线路提供商一并测试端口光功率、丢包率和误码率,这些指标都会直接体现在TrueCopy的稳定性上。
配好链路端口后,还要确认两端存储的远程复制端口配对关系正确。我习惯给每个远程复制端口命名标注“TC-A站点-Target”“TC-B站点-Initiator”之类的标识,否则时间久了端口对应关系很难追溯。
3.3 命名与设备ID规划
这个看起来不起眼,但真实运维中影响很大。TrueCopy的复制对、C/T组、LUN ID都需要全局规划。我一般建议按业务系统编码来命名,比如“CORE_DB_CTG_01”,LUN ID则按站点统一分段,A站点用1000-1999段,B站点用2000-2999段。
设备ID一旦创建后要修改非常麻烦,后续排障和变更都靠这些编号识别。如果命名混乱,出现Pair异常时会在两个站点之间反复比对卷映射,浪费大量宝贵的故障恢复时间。
4. 配置实操:从创建复制对到一致性组上线的操作清单
4.1 基线检查与前置条件
正式配置前,先系统性地检查一遍前置条件。微码版本必须满足TrueCopy功能的支持列表,License要确认已经激活,光纤端口要能看到对端WWN,主机多路径软件要能识别两端LUN。很多人忽略的是,备端S-VOL在未激活前通常处于“仅设备”或特殊状态,主机如果提前扫描到备端卷,多路径软件可能会产生冲突配置,建议在创建复制对之前先在主机侧屏蔽备端LUN扫描。
4.2 创建Pair并完成初始全量复制
前置条件确认无误后,创建复制对的大致流程如下:先在主备两端分别划分好容量一致的LUN,然后在主存储侧配置远程复制端口角色,再在存储管理界面或命令行中定义C/T组,最后将主端P-VOL和备端S-VOL加入该C/T组建立复制对。
命令行配置一般使用类似以下的命令序列(不同微码版本略有差异,以现场实际版本为准):
# 在备端定义远程复制关系并指定S-VOL raidcom addpair -cmd TrueCopy -pvol <主端设备ID> -svol <备端设备ID> -group <一致性组编号> # 查看复制对状态 raidcom getpair -ldev <主端设备ID> # 将复制对的状态切到PAIR,触发初始全量复制 raidcom modifypair -ldev <主端设备ID> -command create初始全量复制会把主端LUN的所有数据复制到备端,这个过程对生产IO有影响,尤其数据量大的LUN可能要持续数小时。此时生产IO和复制IO都在消耗同一套存储后端资源,最好安排在业务低峰期执行,并持续观察复制进度和主机IO延迟。
4.3 加入一致性组与验证
复制对建立后,必须确认它已经加入了正确的一致性组。这一点我的经验是:先建组,再建对,建对时直接指定组号,避免后期再修改分组导致短暂的重同步。
初始复制完成后,Pair状态进入PAIR,此时可以开始业务验证。验证分两步:第一,在备端将S-VOL临时切换为可挂载状态(Split/暂停方式),挂载到隔离测试主机上检查文件系统和数据库一致性;第二,在主端正常写入一笔测试数据,确认备端对应LUN能看到这笔数据。
上线前的检查清单我会逐项打钩:Pair状态是PAIR、C/T组内所有Pair都在线、远程复制端口无丢包计数、主机多路径能看到主端优化路径、备端S-VOL处于不可写状态。
5. 故障复盘:Pair状态机与恢复顺序
5.1 状态机是排错的第一入口
TrueCopy的复制对状态是运维排障的起点。常用状态包括:
| 状态 | 含义 | 常见触发原因 |
|---|---|---|
| SMPL | 单卷,无复制关系 | 刚创建LUN或Pair已删除 |
| PAIR | 正常复制中 | 正常运行态 |
| PSUS | 暂停复制,但数据点保留 | 链路中断、手动Split、灾备演练 |
| PDUB | 复制过程中出现疑似故障 | 链路抖动但未完全中断 |
| PFUL | 主备一致性已丧失 | 严重链路故障或主端异常 |
很多管理员一看到PSUS就慌,其实PSUS是TrueCopy的安全保护状态:复制暂停,但两端的配对关系和一致性点保留,数据依然可以追溯。真正要小心的是PFUL和PDUB,这两种状态说明一致性保障已经失守了。
5.2 一次链路抖动导致的PSUS恢复过程
我曾经处理过一次典型故障:站点间的光纤链路出现短暂抖动,远程复制端口连续发生多次超时,Pair状态从PAIR掉到PSUS。当时第一反应不是直接恢复Pair,而是先停下所有主机IO确认业务侧没有报错,再检查链路光功率和端口错误计数。
链路确认恢复稳定后,才开始执行Pair的重新同步,大致命令如下:
# 恢复复制,触发增量数据同步 raidcom modifypair -ldev <主端设备ID> -command resync # 再次确认状态回到PAIR raidcom getpair -ldev <主端设备ID>恢复顺序极其重要:先恢复链路物理层,再确认主机IO正常,最后才做Pair的resync。如果反着来,链路还没稳就开始重同步,可能再次触发超时,甚至把状态推到PDUB,造成不必要的停机窗口。
5.3 PDUB场景:看起来还能用,但不能掉以轻心
PDUB是状态机里最容易被忽视的。它表示复制过程发生了异常,主备两端数据可能不一致,但复制进程还没有完全停下来。我在实际运维中遇到过一次:光纤丢包率轻微升高,Pair没有掉到PSUS,而是进了PDUB,主端业务完全正常,备端数据却可能和主端时间点对不齐。
这种情况下必须立刻排查,标准操作是:停止业务IO,确认主备两端卷的时间点是否可以接受,如果无法确认一致性,就将Pair停掉并重新执行全量复制。很多人想省事只做增量resync,结果备端留下一块“时间点错位”的数据,灾备切换时才发现数据库起不来,那才是真正的灾难。
6. 长期运维的几条实在建议
6.1 切换演练不能等事故
TrueCopy的切换流程如果不演练,真正出故障时一定手忙脚乱。我负责的项目里,半年至少一次计划内切换演练,演练内容不是简单拆Pair再恢复,而是要让备端真正接管业务一小段时间,验证备端数据库能正常启动、业务能完整跑通、回切流程也能顺畅执行。
切换演练的完整流程大致是:先停止生产IO,将Pair状态改为Split(PSUS),把备端S-VOL激活为可读可写并挂载到备用主机,启动数据库并执行事务验证,然后反向操作回切。每一步都要有操作人和复核人,演练报告里记录每个步骤的耗时。
6.2 变更管理的血泪教训
存储维护窗口和链路割接是TrueCopy故障的高发期。一次割接光纤时,施工人员拔错了一根纤,远程复制链路闪断,Pair掉到PSUS。由于割接前没有提前把Pair停掉并通知存储管理员,整个过程全靠告警才发现,白白增加了一次风险处置。
正确的做法是:任何涉及远程复制链路的变更,提前一天将Pair平滑暂停(Split),变更完成后再恢复(resync)。不要让复制对在链路割接期间“裸奔”,哪怕只是几分钟。
6.3 监控与告警
远程复制相关的监控项必须到位。我常用的监控清单包括:Pair状态(PAIR为正常)、链路端口光功率和CRC错误计数、C/T组内所有Pair成员状态、以及主机侧存储IO延迟指标。告警级别上,Pair掉到PSUS必须立刻响应,PDUB更是要最高优先级处理。
最后再分享一个个人体会:TrueCopy本身不复杂,复杂的是它和业务、链路、主机路径交织在一起的那些边界场景。真正管好一套同步复制,不是学会几条命令就够,而是要对状态机、链路质量、业务切换顺序都有完整的理解。我建议所有做存储容灾的朋友,先花一周时间把自己环境里的Pair状态、C/T组构成、链路拓扑彻底摸一遍,再针对每个状态写一份相应的操作预案。这样事故来临时,才能按预案走,而不是临时翻文档。