PG的全称为Placement Group(放置组),放置顾名思义放置Object的载体。PG的创建是在创建Pool的时候根据指定的数量进行创建。PG的数量与副本数也有关系,比如是3副本的则会有3个相同的pg存在于3个不同的osd上,以filestore为例pg其实在osd的存在形式就是一个目录。其目录的命名规则为 {pool-id}.{pg-id}_head
和 {pool-id}.{pg-id}.TEMP
。如果你想找出一个pg对应哪些个osd,可以使用ceph pg map {pgid}
的命令。
eg:
1 | [root@ceph71 ~]# ceph pg map 1.5f |
背景就是介绍这么多吧,接下来说说PG状态。
状态
状态 | 描述 |
---|---|
active | 当前拥有最新状态数据的pg正在工作中,能正常处理来自客户端的读写请求。 |
inactive | 正在等待具有最新数据的OSD出现,即当前具有最新数据的pg不在工作中,不能正常处理来自客户端的读写请求。 |
activating | Peering 已经完成,PG 正在等待所有 PG 实例同步并固化 Peering 的结果 (Info、Log 等) |
clean | pg所包含的object达到指定的副本数量,即object副本数量正常 |
unclean | PG所包含的object没有达到指定的副本数量,比如一个PG没在工作,另一个PG在工作,object没有复制到另外一个PG中。 |
peering | PG所在的OSD对PG中的对象的状态达成一个共识(维持对象一致性) |
peered | peering已经完成,但pg当前acting set规模小于存储池规定的最小副本数(min_size) |
degraded | 主osd没有收到副osd的写完成应答,比如某个osd处于down状态 |
stale | 主osd未在规定时间内向mon报告其pg状态,或者其它osd向mon报告该主osd无法通信 |
inconsistent | PG中存在某些对象的各个副本的数据不一致,原因可能是数据被修改 |
incomplete | peering过程中,由于无法选出权威日志,通过choose_acting选出的acting set不足以完成数据修复,导致peering无法正常完成 |
repair | pg在scrub过程中发现某些对象不一致,尝试自动修复 |
undersized | pg的副本数少于pg所在池所指定的副本数量,一般是由于osd down的缘故 |
scrubbing | pg对对象meta的一致性进行扫描 |
deep | pg对对象数据的一致性进行扫描 |
creating | pg正在被创建 |
recovering | pg间peering完成后,对pg中不一致的对象执行同步或修复,一般是osd down了或新加入了osd |
recovering-wait | 等待 Recovery 资源预留 |
backfilling | 一般是当新的osd加入或移除掉了某个osd后,pg进行迁移或进行全量同步 |
down | 包含必备数据的副本挂了,pg此时处理离线状态,不能正常处理来自客户端的读写请求 |
remapped | 重新映射态。PG 活动集任何的一个改变,数据发生从老活动集到新活动集的迁移。在迁移期间还是用老的活动集中的主 OSD 处理客户端请求,一旦迁移完成新活动集中的主 OSD 开始处理 |
misplaced | 有一些回填的场景:PG被临时映射到一个OSD上。而这种情况实际上不应太久,PG可能仍然处于临时位置而不是正确的位置。这种情况下个PG就是misplaced。这是因为正确的副本数存在但是有个别副本保存在错误的位置上。 |
异常
active+undersized+degraded
若发现有osd挂掉,先尝试将osd重新拉起来,拉起来后集群会自动重新恢复健康状态。
但是也有可能出现这个osd再也起不来了,比如硬盘损坏了,这时多副本就发挥作用了,因为还有其它副本在其它osd上,这时我们可以通过均衡数据的方法来将集群恢复并将该osd踢出集群。
** 解决 **
- 将osd reweight权重置0,将数据分散到其他osd上
ceph osd reweight {osd-id} 0
- 待集群rebalance后,开始删除osd
unfound objects
ceph集群知道该对象存在,但无法定位该object在哪时会报这个错误。
** 解决 **
- 尝试让失败的osd起来,如果起来后集群恢复正常,则结束
- 试将该pg的unfound对象回滚到上一个版本,
ceph pg {pgid} mark_unfound_lost revert
如果恢复正常,则结束 - 如果还是不行,那只有将该object删除掉了,注意这会导致丢失数据,执行
ceph pg {pgid} mark_unfound_lost delete
删除unfound对象
inconsistent objects
pg中保存的object中有些副本数据不一致,有些事伴随着scrub errors错误
** 解决 **
ceph health detail
找出问题pg- 尝试
ceph pg repair {pgid}
,若成功,则结束;不成功进行如下操作。 - 使用
ceph pg map {pgid}
找出主osd,打开日志查看哪个object不一致 - 找出所有该objects所有副本存放的位置,用摘要算法(md5sum,sha256)等计算出其hash值,如果是3副本,删除与其他副本不一致的;如果是2副本,则可能会误删。
- 再次执行
ceph pg repair {pgid}
stale pg
pg出现stale状态,也就是pg处于僵死状态,该状态是无法处理新的请求了的,新的请求过来只会block,这种情况一般是由于所有副本pg的osd都挂了。
Ceph使用心跳来确保主机和进程都在运行,OSD进程如果不能周期性的发送心跳包,那么PG就会变成stuck状态。默认情况下,OSD每半秒钟汇汇报一次PG,up thru,boot, failure statistics等信息,要比心跳包更会频繁一点。如果主OSD不能汇报给MON或者其他OSD汇报主OSD挂了,Monitor会将主OSD上的PG标记为stale。当启动集群后,直到peer过程完成,PG都会处于stale状态。而当集群运行了一段时间后,如果PG卡在stale状态,说明主OSD上的PG挂了或者不能给MON发送信息。
要模拟其实也很简单,比如设置2副本,然后将2个不同故障域的osd挂掉即可出现,最好的恢复方法当然是重新拉起这两个osd,但有时可能出现这样的情况,两个osd永远也拉不起来了,然后你把这两个osd清理出去了,清理完后这些pg当然就是stale的状态,这时的恢复方法只能是丢掉这个pg里的数据了,重新创建pg。
** 解决 **
- 使用命令
ceph pg dump |grep stale
找出所有的stale的pg,也可以ceph health detail | grep stale
- 执行
ceph pg force_create_pg {pgid}
命令强制重新创建pg,会看到pg转为creating状态 - 重启ceph中所有osd服务
Peered
Peering 已经完成,但是 PG 当前 Acting Set 规模小于存储池规定的最小副本数 (min_size)。
如果pool的副本数为3、min_size=2,停掉两个副本所在的osd,此时访问集群的客户端处于blocked状态。
** 解决 **
- 先尝试将down掉的两个osd恢复,或至少恢复一个。
- 若不能正常恢复,可修改
min_size=1
,解除客户端blocked状态