偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

山洪災(zāi)害后的 Ceph 慘案:PG incomplete 到 RBD 鏡像消失

存儲 數(shù)據(jù)管理
在一次山洪災(zāi)害后,機房的服務(wù)器全部斷電,等供電恢復(fù)后進入系統(tǒng)發(fā)現(xiàn)所有的虛擬機文件系統(tǒng)損壞了,并且查看ceph集群有個pg出現(xiàn)inactive和incomplete狀態(tài),上傳新的鏡像io也會卡住,以下是恢復(fù)過程。

背景

在一次山洪災(zāi)害后,機房的服務(wù)器全部斷電,等供電恢復(fù)后進入系統(tǒng)發(fā)現(xiàn)所有的虛擬機文件系統(tǒng)損壞了,并且查看ceph集群有個pg出現(xiàn)inactive和incomplete狀態(tài),上傳新的鏡像io也會卡住,以下是恢復(fù)過程。

圖片圖片

圖片

排查過程

incomplete和inactive狀態(tài)含義解釋

inactive
  • 含義:PG 處于不可用狀態(tài)。
  • 表現(xiàn):客戶端對這個 PG 的讀寫請求都會被阻塞。
  • 原因可能包括:

這個 PG 沒有足夠的 OSD 存活來提供服務(wù)。

PG 沒有被分配到合適的 OSD 上。

OSD 沒有完成 peering(對等協(xié)商)過程。

換句話說,inactive 就是 PG 不能對外提供正常的 IO 服務(wù)。

incomplete
  • 含義:PG 在 peering 時發(fā)現(xiàn)缺少必需的數(shù)據(jù)副本,導(dǎo)致無法達到一致性。
  • 表現(xiàn):PG 中的數(shù)據(jù)不完整,無法對外提供讀寫。
  • 常見原因:

某些 OSD 宕機或丟失數(shù)據(jù),導(dǎo)致 PG 的對象副本無法湊齊。

新 OSD 加入或者數(shù)據(jù)遷移時丟失了必要的副本。

硬盤故障或誤刪導(dǎo)致數(shù)據(jù)確實丟失。

通常 incomplete 比 inactive 更嚴重, inactive只是PG 暫時不可用,但數(shù)據(jù)可能還在,只是沒有滿足對外服務(wù)條件。  incomplete出現(xiàn)時說明peering 過程中無法收集到足夠的、權(quán)威的一致數(shù)據(jù)副本,意味著有的數(shù)據(jù)副本確實不存在了,需要人工干預(yù)才能恢復(fù)。往往出現(xiàn)在peering的過程中服務(wù)器異常斷電, 在斷電前 PG 的日志還沒來得及落盤, 所有副本上的 PG log 都不完整,導(dǎo)致無法確定哪些對象是最新的 。

嘗試對pg進行修復(fù)

查看集群所有的osd,發(fā)現(xiàn)都是up的

圖片圖片

嘗試常規(guī)修復(fù)發(fā)現(xiàn)沒什么用

ceph pg repair 2.1c

后查看pg上的對象數(shù)和丟失的對象數(shù),發(fā)現(xiàn)pg上的對象數(shù)為0

ceph pg ls | grep 2.1c
ceph pg 2.1c list_unfound

圖片圖片

嘗試回滾pg舊版本和重啟pg副本所在的osd服務(wù)后重新修復(fù)均無效

ceph pg 2.1c mark_unfound_lost revert
ceph pg repair 2.1c

將pg副本的osd out再in后狀態(tài)仍沒有變化

ceph osd out <id>
ceph osd in <id>

使用ceph-objectstore-tool操作pg副本

集群狀態(tài)一直無法恢復(fù),準備使用ceph-objectstore-tool工具操作pg副本,只保留一份pg的副本,將其他兩份的副本刪除,并基于剩余的pg副本做回填,最后將剩下的pg副本標記為complete狀態(tài)。

準備操作
#查看pg副本所在的osd
ceph pg map 2.1c
#防止副本操作期間觸發(fā)數(shù)據(jù)重新均衡
ceph osd set noout
# 臨時降低 min_size
ceph osd pool set libvirt-pool min_size 1
備份導(dǎo)出pg副本

可以看到導(dǎo)出的副本大小都是十幾K,數(shù)據(jù)基本查看其他正常的pg,對象數(shù)量平均是在6000多個

systemctl stop ceph-osd@8
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-8  --type bluestore --pgid 2.1c --op export --file /opt/2.1c.obj_osd_8
systemctl stop ceph-osd@14
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-14  --type bluestore --pgid 2.1c --op export --file /opt/2.1c.obj_osd_14
systemctl stop ceph-osd@11
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-11  --type bluestore --pgid 2.1c --op export --file /opt/2.1c.obj_osd_11

圖片圖片

圖片圖片

圖片

刪除兩個osd節(jié)點上的故障pg副本
systemctl stop ceph-osd@8
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-8/ --type bluestore --pgid 2.1c --op remove --force
systemctl stop ceph-osd@11
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-11/ --type bluestore --pgid 2.1c --op remove --force

圖片圖片

從剩余節(jié)點導(dǎo)入pg副本到其他兩個osd節(jié)點
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-11/ --type bluestore --pgid 2.1c --op import --file /opt/2.1c.obj_osd.14
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-8/ --type bluestore --pgid 2.1c --op import --file /opt/2.1c.obj_osd.14
systemctl start ceph-osd@11
systemctl start ceph-osd@8

圖片圖片

將剩余節(jié)點的pg副本標記為complete

執(zhí)行常規(guī)恢復(fù)操作發(fā)現(xiàn)集群還是處于incomplete狀態(tài)

ceph pg repair 2.1c

將剩余節(jié)點的pg副本標記為complete

systemctl stop ceph-osd@14
# 標記 complete
ceph-objectstore-tool --type bluestore --data-path /var/lib/ceph/osd/ceph-14 --pgid 2.1c --op mark-complete
ceph osd pool set libvirt-pool min_size 2
ceph osd unset noout
systemctl start ceph-osd@14

之后集群顯示健康狀態(tài)正常了

圖片圖片

但是發(fā)現(xiàn)rbd查看鏡像發(fā)現(xiàn)全沒了,存儲大小沒有變化

圖片圖片

對rbd鏡像列表數(shù)據(jù)進行恢復(fù)

查看鏡像頭對象,發(fā)現(xiàn)還在,但是根據(jù)ID查詢存儲池中的鏡像已經(jīng)查不到了

rados -p libvirt-pool ls | grep '^rbd_header\.' | head
rbd -p libvirt-pool --image-id <id> info

圖片圖片

檢查header對象的元數(shù)據(jù),發(fā)現(xiàn)還在,說明只是目錄對象丟失了

rados -p libvirt-pool listomapkeys rbd_header.d8b1996ee6b524 | head

圖片圖片

使用rados查看鏡像發(fā)現(xiàn)能查詢到

rados -p libvirt-pool stat rbd_header.d8b1996ee6b524

圖片圖片

搭建測試環(huán)境復(fù)現(xiàn)

搭建好測試環(huán)境后修復(fù)好后再在生產(chǎn)環(huán)境修復(fù),先設(shè)置osd暫?;謴?fù)/回填,且把存儲池 min_size 暫時降到 1

ceph osd set noout
ceph osd set norecover
ceph osd set nobackfill
ceph osd pool set libvirt-pool min_size 1

只保留 主副本 的osd在線,停掉另外兩個副本

systemctl stop ceph-osd@4
systemctl stop ceph-osd@5

刪除總目錄對象,再刪每個鏡像的 id 映射條目

rados -p libvirt-pool rm rbd_directory
for img in $(rbd ls -p libvirt-pool 2>/dev/null); do
  rados -p libvirt-pool rm rbd_id.$img || true
done

讓另外兩個副本上線并恢復(fù)回填

systemctl start ceph-osd@4
systemctl start ceph-osd@5

ceph osd unset noout
ceph osd unset norecover
ceph osd unset nobackfill

驗證復(fù)現(xiàn)結(jié)果,目錄對象確實丟了,但是數(shù)據(jù)還在

rados -p libvirt-pool stat rbd_directory
rbd ls -p libvirt-pool
rados -p libvirt-pool ls | grep '^rbd_header\.' | head

圖片圖片

圖片圖片

恢復(fù)rbd的目錄對象

從網(wǎng)上找了兩個腳本,一個腳本可以根據(jù)header的ID反查鏡像名,另一個是根據(jù)鏡像名和header的ID來恢復(fù)rbd鏡像目錄

#!/bin/bash
# 用法: ./find_rbd_name.sh <IMAGE_ID>
# 例子: ./find_rbd_name.sh 3c456b8b4567

set -euo pipefail

POOL="libvirt-pool"

if [ $# -ne 1 ]; then
  echo "用法: $0 <IMAGE_ID>"
  exit 1
fi

ID="$1"

found=0
for obj in $(rados -p "$POOL" ls | grep '^rbd_id\.'); do
  got=$(rados -p "$POOL" get "$obj" - 2>/dev/null | tr -d '\n\r')
  if [ "$got" = "$ID" ]; then
    echo "發(fā)現(xiàn): $obj  -> name = ${obj#rbd_id.}"
    found=1
  fi
done

if [ $found -eq 0 ]; then
  echo "未找到 ID=$ID 對應(yīng)的鏡像"
  exit 2
fi

通過直接改寫 pool 里的 rbd_directory 對象的 OMAP 鍵值 來恢復(fù)

  • 每個 RBD 鏡像都有一個頭對象:rbd_header.<ID>,鏡像的各種元數(shù)據(jù)都掛在它的 omap 上。
  • rbd ls 并不是去遍歷所有 rbd_header.*,而是讀 **rbd_directory** 這個對象的 omap

name_<NAME> → 值為 <ID>

id_<ID> → 值為 <NAME>

  • 值的編碼不是裸字符串,而是:小端 4 字節(jié)長度(LE uint32) + 字符串本體。
    例如 name_foo 的值若為 "abc123",實際二進制是:06 00 00 00 61 62 63 31 32 33
  • 只要把這兩條映射補上,rbd ls 就能重新列出 <NAME>rbd info <NAME> 也能通過目錄映射定位到頭對象 <ID>。
#!/usr/bin/env bash
# 用法: ./fix_rbd_mapping.sh <NAME> <ID>
# 例子: ./fix_rbd_mapping.sh windows_7sp1_x86_dvd677486.img 2557396b8b4567

set -euo pipefail

POOL="libvirt-pool"

if [ $# -ne 2 ]; then
  echo "用法: $0 <NAME> <ID>"
  exit 1
fi

NAME="$1"
ID="$2"

# 0)(可選)先確保池已初始化過 RBD 目錄對象;冪等,安全
rbd pool init "$POOL"

# 1) 備份一下目前這兩條(如果不存在會報錯但不影響繼續(xù))
rados -p "$POOL" getomapval rbd_directory "name_$NAME" /tmp/old_name_val.bin 2>/dev/null || true
rados -p "$POOL" getomapval rbd_directory "id_$ID"   /tmp/old_id_val.bin   2>/dev/null || true

# 2) name_<name> -> <id> (值為:LE4長度 + 字符串ID)
python3 - <<'PY' | rados -p "$POOL" setomapval rbd_directory "name_$NAME"
import sys,struct
img_id="$ID"
sys.stdout.buffer.write(struct.pack("<I", len(img_id)))
sys.stdout.buffer.write(img_id.encode())
PY

# 3) id_<id> -> <name> (值為:LE4長度 + 字符串NAME)
python3 - <<'PY' | rados -p "$POOL" setomapval rbd_directory "id_$ID"
import sys,struct
name="$NAME"
sys.stdout.buffer.write(struct.pack("<I", len(name)))
sys.stdout.buffer.write(name.encode())
PY

# 4) 校驗兩條鍵寫好了
rados -p "$POOL" listomapvals rbd_directory | egrep 'name_$NAME|id_$ID' -n

# 5) 看列表與信息
rbd -p "$POOL" ls | grep -F -- "$NAME" || true
rbd -p "$POOL" info "$NAME"

圖片圖片

查看恢復(fù)后的鏡像列表發(fā)現(xiàn)已經(jīng)恢復(fù)

圖片圖片


責任編輯:武曉燕 來源: 運維開發(fā)故事
相關(guān)推薦

2017-04-19 15:57:21

Ceph RBD mi原理分析

2023-05-16 08:30:53

QuincyReef

2018-07-19 15:00:41

衛(wèi)星圖像

2021-01-12 05:06:35

存儲Kubernetes鏡像

2022-06-06 07:56:12

LUKSLUKS2PBKDF2

2023-12-01 08:01:59

鏡像Ceph

2022-05-27 14:06:43

kvm虛擬機磁盤LUKS

2015-10-23 10:47:35

喬布斯蘋果

2021-02-01 09:00:34

Ceph octopu集群運維

2018-08-02 08:42:57

分布式存儲Ceph

2017-08-22 15:58:56

2021-11-01 17:29:02

Windows系統(tǒng)Fork

2022-10-19 08:01:17

QuincyCephPG

2017-08-24 17:37:18

DNS緩存分析

2018-10-08 15:08:42

物聯(lián)網(wǎng)水災(zāi)害IOT

2021-04-30 17:24:35

人工智能AI深度學(xué)習(xí)

2018-05-03 07:44:33

物聯(lián)網(wǎng)災(zāi)害預(yù)防傳感器

2013-11-27 09:25:04

IBMSDN災(zāi)害預(yù)防

2021-08-06 22:43:54

中斷架構(gòu)傳遞
點贊
收藏

51CTO技術(shù)棧公眾號