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 状态
恢复与回填的区别
| 类型 | 触发条件 | 说明 |
|---|---|---|
| Recovery | OSD 短暂故障后恢复 | 只恢复变更的部分数据 |
| Backfill | OSD 被标记为 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 异常状态
| 状态 | 原因 | 处理方法 |
|---|---|---|
| stale | PG 的 primary OSD 故障 | 等待 OSD 恢复或手动干预 |
| degraded | 副本数不足 | 等待 backfill 完成 |
| undersized | 副本数严重不足 | 检查 OSD 状态 |
| inconsistent | 副本间数据不一致 | 执行 scrub/repair |
| incomplete | PG 无法选出 primary | 可能需要手动修复 |
| inactive | PG 无法提供服务 | 检查 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
扩展阅读
下一章:12 - 安全加固 — 学习 CephX 认证、传输加密、静态加密和授权管理。