为什么复制会破坏一致性
数据库的一次事务提交在存储层表现为对多个卷的分散写入:数据文件、日志文件、控制文件与临时文件往往位于不同卷。存储复制按卷独立传输,卷间时间点错位时,目标端得到的镜像就会出现「日志已提交、数据文件尚未落地」这类组合。数据库能在启动时通过崩溃恢复修正这种差异,但恢复耗时与脏页和日志量相关,可能远超 RTO 承诺,严重时甚至无法正常启动。
关键概念
| 一致性组 | 把存在写依赖的卷归为一组,统一打点与统一切换 |
|---|---|
| 写顺序依赖 | 日志与数据文件之间必须保持的提交先后关系 |
| 一致性打点 | 组内所有卷在同一时刻形成可恢复的镜像 |
| 静默点 | 主机或数据库层配合刷盘,得到更干净的恢复起点 |
| 崩溃恢复 | 数据库启动时依据日志修正不一致,耗时不确定 |
| 划分原则 | 数据卷与日志卷必须同组,归档与备份卷单独考虑 |
典型使用场景
- 规划存储复制关系时,确定哪些卷必须归入同一个一致性组
- 容灾切换演练前,确认切换起点不存在卷间时间点差异
- 切换后数据库启动异常,排查是一致性问题还是配置问题
- 评估 RTO 可达性,判断崩溃恢复耗时是否会侵蚀承诺窗口
- 新增数据库实例或调整卷布局后,复核一致性组划分是否需要变更
- 多套数据库共享同一存储时,划分边界以避免相互影响
不一致来源与应对
| 不一致来源 | 目标端表现 | 应对方式 |
|---|---|---|
| 数据卷与日志卷不同组 | 启动时崩溃恢复耗时长或直接失败 | 归入同一一致性组统一打点 |
| 存储写缓存未刷盘 | 日志与数据页时间点错位 | 切换前执行刷盘或使用静默点 |
| 复制积压期间发起切换 | 目标端缺少最新提交,数据倒退 | 切换前确认积压为零 |
| 数据库未按顺序停启 | 实例挂载异常或反复重启 | 按一致性顺序执行停启操作 |
| 文件系统元数据缓存 | 挂载失败或目录结构异常 | 先冻结或卸载文件系统再切换 |
| 多实例共享卷范围重叠 | 时间点相互干扰,恢复判据混乱 | 按数据库边界重新划分一致性组 |
一致性组划分要点
一致性组划分要点
# 一、同一数据库的数据文件卷与日志卷必须归入同一一致性组
# 二、归档日志卷与备份卷单独成组,避免拖长切换整体耗时
# 三、同一业务系统内存在跨库事务的实例,考虑合并到同一组
# 四、组内卷数量影响打点性能与切换耗时,需在演练中实测确认
# 五、切换前停止业务写入,并确认复制积压已经归零
# 六、按方案要求执行数据库刷盘或主机层静默,再发起组切换崩溃恢复并不是免费的兜底手段。数据库确实能自动把镜像修正到一致状态,但恢复时间与脏页量、日志量强相关,跨度可能从几十秒到数小时。RTO 承诺很短时,不应把一致性寄托在恢复过程上,而应在切换前通过一致打点与有序停启把恢复工作量压到最小,并在演练中实测真实耗时。