强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Ceph 存储运维完全指南 / 11 - 数据恢复

11 - 数据恢复

11.1 数据恢复概述

Ceph 的自愈能力是其核心优势之一。当 OSD 故障时,Ceph 会自动触发数据恢复(Recovery)和回填(Backfill)过程,确保数据副本数满足要求。

恢复过程

OSD 故障
    ↓
Monitor 检测到 OSD down(心跳超时 20 秒)
    ↓
标记 OSD 为 down(但仍 in,等待恢复)
    ↓
等待 osd_mon_out_interval(默认 600 秒)
    ↓
标记 OSD 为 out
    ↓
CRUSH 重新计算受影响 PG 的映射
    ↓
触发 recovery/backfill
    ↓
数据复制到新的 OSD
    ↓
PG 恢复到 active+clean 状态

恢复与回填的区别

类型触发条件说明
RecoveryOSD 短暂故障后恢复只恢复变更的部分数据
BackfillOSD 被标记为 out全量数据复制到新 OSD

11.2 OSD 故障处理

短暂故障(OSD 重启)

# OSD 短暂故障后会自动恢复
# 查看 OSD 状态
ceph osd tree | grep down

# 手动启动故障的 OSD
systemctl start ceph-osd@5

# 查看恢复进度
ceph -w  # 实时观察

# 查看恢复速度
ceph pg dump_stuck unclean
ceph pg dump | grep -E "recovering|backfill"

永久故障(磁盘损坏)

# 步骤 1:确认 OSD 故障
ceph osd tree | grep -E "down|out"
ceph osd stat

# 步骤 2:标记 OSD 为 out(如果还未自动标记)
ceph osd out osd.5

# 步骤 3:从 CRUSH Map 中移除
ceph osd crush remove osd.5

# 步骤 4:删除 OSD 认证
ceph auth del osd.5

# 步骤 5:删除 OSD
ceph osd rm osd.5

# 步骤 6:更换物理磁盘后,添加新 OSD
ceph orch daemon add osd node3:/dev/sdd

11.3 OSD 替换

替换故障 OSD

# 方法一:使用 cephadm(推荐)

# 1. 查看故障 OSD
ceph osd tree | grep down

# 2. 销毁 OSD(保留标记以便新磁盘自动替换)
ceph orch osd rm osd.5 --replace

# 3. 更换物理磁盘

# 4. 部署新 OSD(cephadm 可能自动检测并部署)
ceph orch daemon add osd node3:/dev/sdd

# 方法二:手动替换

# 1. 标记 out
ceph osd out osd.5

# 2. 等待数据恢复完成
ceph -w  # 观察恢复进度

# 3. 移除旧 OSD
ceph osd crush remove osd.5
ceph auth del osd.5
ceph osd rm osd.5

# 4. 清理磁盘
sudo wipefs --all /dev/sdd
sudo sgdisk --zap-all /dev/sdd

# 5. 创建新 OSD
ceph-volume lvm create --data /dev/sdd

完全更换节点

# 1. 标记节点上的所有 OSD 为 out
for osd_id in $(ceph osd tree node3 | grep osd | awk '{print $1}'); do
    ceph osd out osd.$osd_id
done

# 2. 等待数据恢复
ceph -w

# 3. 从集群移除节点
ceph orch host drain node3
ceph orch host rm node3

# 4. 物理更换节点

# 5. 添加新节点
ceph orch host add node3-new 192.168.1.13

# 6. 部署 OSD
ceph orch apply osd --all-available-devices

11.4 PG 异常处理

常见 PG 异常状态

状态原因处理方法
stalePG 的 primary OSD 故障等待 OSD 恢复或手动干预
degraded副本数不足等待 backfill 完成
undersized副本数严重不足检查 OSD 状态
inconsistent副本间数据不一致执行 scrub/repair
incompletePG 无法选出 primary可能需要手动修复
inactivePG 无法提供服务检查 OSD 和网络

PG 修复操作

# 查看异常 PG
ceph pg ls | grep -v active+clean

# 1. 修复 inconsistent(数据不一致)
ceph pg scrub 0.0           # 触发轻量 scrub
ceph pg deep-scrub 0.0      # 触发深度 scrub(比较数据)

# 如果 scrub 发现不一致
ceph pg repair 0.0          # 修复不一致的 PG

# 2. 批量检查所有 PG
ceph pg dump_stuck unclean
ceph pg dump_stuck inactive
ceph pg dump_stuck stale
ceph pg dump_stuck undersized

# 3. 修复 incomplete PG
# 尝试将 PG 标记为可修复
ceph pg force-recovery 0.0
ceph pg force-backfill 0.0

# 取消强制恢复
ceph pg cancel-force-recovery 0.0
ceph pg cancel-force-backfill 0.0

PG Peer 过程问题

# 查看 PG peer 状态
ceph pg dump pgs | grep peering

# 如果 PG 长时间 stuck 在 peering 状态
# 检查 OSD 日志
journalctl -u ceph-osd@<primary-osd> | grep -i peering

# 可能需要手动标记 PG 的权威版本
# 谨慎操作,可能导致数据丢失
ceph pg <pgid> mark_unfound_lost revert

11.5 降级状态处理

集群降级

# 查看降级原因
ceph health detail

# 典型降级场景:
# 1. OSD down(自动恢复)
HEALTH_WARN 1 osds down

# 2. PG 降级
HEALTH_WARN Degraded data redundancy: 2/6 objects degraded (33.333%), 1 pg degraded

# 3. 副本数不足
HEALTH_WARN Reduced data availability: 1 pg undersized

降级期间的操作

# 查看恢复进度
ceph -w
# 输出会显示:
# recovery io 100 MiB/s, 25 objects/s
# recovery [1/1000 objects]

# 控制恢复速度(避免影响业务 I/O)
ceph config set osd osd_recovery_max_active 3           # 限制并发恢复数
ceph config set osd osd_recovery_sleep_hdd 0.1          # HDD 恢复间隔
ceph config set osd osd_recovery_op_priority 3          # 低优先级
ceph config set osd osd_max_backfills 1                  # 限制 backfill 并发

# 如果需要加速恢复(暂时提高优先级)
ceph config set osd osd_recovery_max_active 10
ceph config set osd osd_recovery_op_priority 63
ceph config set osd osd_max_backfills 4

11.6 数据迁移

池间数据迁移

# 方法一:rados cp(复制对象)
rados cp oldpool/obj1 newpool/obj1

# 方法二:批量迁移脚本
#!/bin/bash
SRC_POOL="oldpool"
DST_POOL="newpool"

for obj in $(rados ls -p $SRC_POOL); do
    rados cp $obj -p $SRC_POOL $DST_POOL
done

# 方法三:使用 rados import/export
rados export --pool=oldpool /tmp/oldpool.export
rados import --pool=newpool /tmp/oldpool.export

# 方法四:RBD 镜像迁移
rbd export rbd/oldimage /tmp/oldimage.img
rbd import /tmp/oldimage.img rbd/newimage

OSD 间数据迁移(再平衡)

# 调整 OSD 权重(控制数据分布)
ceph osd crush reweight osd.5 0.8    # 降低权重(减少数据)
ceph osd crush reweight osd.5 1.2    # 增加权重(接收更多数据)

# 完全移除 OSD(触发数据迁移)
ceph osd out osd.5

# 控制迁移速度
ceph config set osd osd_max_backfills 2
ceph config set osd osd_recovery_max_active 5

# 恢复速度设置(低优先级)
ceph tell 'osd.*' injectargs --osd-recovery-sleep 0.1

11.7 灾难恢复

Monitor 数据损坏

# 1. 停止所有 Monitor
systemctl stop ceph-mon.target

# 2. 从健康的 Monitor 复制数据
# 选择一个数据最新的 Monitor
scp -r /var/lib/ceph/mon/ceph-node1/* node2:/var/lib/ceph/mon/ceph-node2/

# 3. 重启 Monitor
systemctl start ceph-mon@node1
systemctl start ceph-mon@node2
systemctl start ceph-mon@node3

集群完全重建

# 在灾难性故障后(如所有 OSD 数据丢失)
# 需要从备份恢复

# 1. 检查是否有 RBD 快照备份
# 2. 检查 RGW 数据是否有跨站点复制
# 3. 从外部备份恢复

# 如果只有部分 OSD 损坏
# 可以尝试强制创建 PG
ceph pg force-creating-pg <pgid>   # 危险操作!仅限紧急情况

11.8 恢复监控

# 查看恢复进度
ceph -w

# 查看详细恢复状态
ceph pg dump pgs | grep -E "recovering|backfill"

# 查看 OSD 恢复状态
ceph osd tree | grep -E "recovery|backfill"

# 查看恢复速度
ceph daemon osd.0 perf dump | jq '.recovery'

# Prometheus 指标
# ceph_pg_recovery_ops - 恢复操作数
# ceph_pg_backfilling - 回填中的 PG 数
# ceph_osd_recovery_ops - OSD 恢复操作数

11.9 业务场景:计划性维护

# 计划性停机维护步骤

# 1. 提前通知集群(防止自动标记 out)
ceph osd set noout

# 2. 停止目标节点上的 OSD
systemctl stop ceph-osd@{5,6,7}

# 3. 执行维护(更换硬件等)

# 4. 恢复 OSD
systemctl start ceph-osd@{5,6,7}

# 5. 确认 OSD 状态正常
ceph osd tree

# 6. 取消 noout 标记
ceph osd unset noout

# 7. 检查集群健康
ceph -s

注意事项

  • 设置 noout 后,如果其他 OSD 也故障,可能导致数据丢失
  • 维护窗口期不宜过长(建议不超过几小时)
  • 维护前确保集群处于 HEALTH_OK 状态
  • 维护前确认所有 PG 都是 active+clean

扩展阅读

  1. 数据恢复文档
  2. PG 状态详解
  3. OSD 替换

下一章12 - 安全加固 — 学习 CephX 认证、传输加密、静态加密和授权管理。