再记一次ceph object unfound的艰辛历程
文章目錄
- 先說問題:
- 再說解決
- 嘗試1:
- 嘗試2(該嘗試建議先在自己環境搭配對應業務測試通過后再現場嘗試):
感謝 學無止境996同學的陪伴和vigourtyy美麗女友的支持,直到這個解決問題的深夜
先說問題:
ceph 12.2.1生產環境:3副本 tier + 3副本data
機房在擁有業務的情況下重啟集群交換機,產生如下場景:
- time 1: osd.1 down, osd.2 osd.3 up
此時數據先落到2,3上(2為primary) - time 2: osd.1 osd.2 osd.3 up
此時狀態機觸發peering,根據pg_info和pg_log,構建missing列表,依據此列表進行后續的recovery(默認此時僅pg部分數據有變化,可通過權威日志恢復),但此時recovery并未完全恢復 - time 3: osd.1 osd.2 up, osd.3 down
根據此時osd的狀態,因為上一個時間點osd.3上部分數據并未完全recover到osd.1上,此時osd.3就down了,但是對于osd.1來說已經獲取到了missing列表并且將該列表中的對象操作數據追加到了pg_log_entry中,依此來pull或者push數據。但是此時osd.3已經down,這一些數據無法成功獲取到osd.1上。此時集群的狀態就會出現object unfound的情況,如下圖:
我們的生產環境更是異常問題的疊加,因為出現unfound的對象,同時又出現osd無法成功Recover而報出的段錯誤無法啟動,此時丟掉的對象如果想要恢復,貌似只有revert或者delete了
關于PGlog的相關描述以及pg_log和pg_info如何參與到狀態機中進行peer,recover和backfill的相關過程可以參考PGlog寫流程梳理
知道了問題,并且能夠復現問題,接下來就是如何解決的過程了。
再說解決
首先我們知道部分數據并未完全丟失,它可能是存在于down掉的osd中,為了后續的恢復,我們先將down掉的osd進行數據備份。
使用dd將down掉的osd所在的磁盤數據備份到一塊空的磁盤上即可。
操作前先分析當前異常環境的處境以及我們想要達到的最終目標:
我們擁有的資源:備份完好的osd磁盤(數據未丟失)
我們的處境:對象丟失,深層含義就是當前環境沒有任何一個up的osd承載該對象,但是該對象的操作版本被pg_log記錄,環境曾經有過該對象。
分析:加入我們沒有備份好的數據資源,遇到這樣的情況貌似只能對unfound對象所在pg進行revert和delete了,但是我們備份了數據
最終要做的就是盡可能完整得將我們備份的數據遷移至現有集群,讓改集群unfound的對象一一恢復
嘗試1:
對象級別的操作工具我們能夠想到的ceph-object-tool,rados這兩個利器
對象的構成我們宏觀來看:即數據+元數據
剛好,ceph-object-tool工具擁有參數get-bytes,set-bytes,get-attr,set-attr這樣的子命令。
于是我們嘗試將備份的磁盤數據中將對應的丟失對象使用get-bytes獲取出來,然后再使用set-bytes將該對象的數據寫回集群,同時將對應對象的屬性也設置回集群,這樣我們猜想,osd起來之后有了對象以及對象的元數據,即可成功恢復。操作如下:
-
掛載備份數據的磁盤分區
a.mkdir /ceph-0
b.mount /dev/sdb1 /ceph-0 -
查看丟失的對象
a.ceph health detail獲取丟失對象的pg id
b.ceph pg 14.20 list_missing列出丟失對象的pg 14.20的丟失對象信息 -
從備份的磁盤分區中獲取丟失的對象數據和元數據
a.ceph-objectstore-tool --data-path /ceph-0/ --type bluestore obj470 get-bytes obj470.txt獲取對象obj470的數據,并放入到obj470.txt文件
關于ceph-object-tool工具的使用可以參考ceph-object-tool使用詳解
b.ceph-objectstore-tool --data-path /ceph-0/ --type bluestore obj470 get-attrs _ > obj470.attr獲取對象obj470的屬性數據,即元數據信息到obj470.attr中
src/common/ceph_objectstore_tool.cc中可以看到該屬性信息為object_info_t數據
則我們可以通過命令ceph-dencoder來解碼查看,關于ceph-dencoder命令的使用可以參考文檔ceph-dencoder使用詳解
ceph-dencoder type object_info_t import obj470.attr decode dump_json
-
將獲取到的數據設置到集群osd中,此時需要osd的狀態為down,能夠操作
/var/lib/ceph/osd/ceph-id目錄
a.ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-0/ --type bluestore obj470 set-attrs _ obj470.attr設置對象屬性
b.ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-0/ --type bluestore obj470 set-bytes obj470.txt設置對象數據信息
此時有兩種情況:
如果對象的have版本為0'0,即對象當前并不存在于集群中,集群只有一個初始的空版本對象,執行以上命令會有如下輸出
No object id 'get-bytes' found or invalid JSON specified
顯然該方案走到這里即出現阻塞性的情況,對應對象版本為0'0的對象該如何修復?
嘗試2(該嘗試建議先在自己環境搭配對應業務測試通過后再現場嘗試):
至此我們已經能夠獲取到對象的數據,但是因為集群中對象版本為0'0的對象是不存在的,所以無法設置這樣的對象
那么我們可以嘗試如下操作,首先對象在其未加入集群時會通過crush算法計算好自己即將映射到的osd以及對應的pg
ceph osd map pool_name obj_name命令可以看到該映射關系,那么我們可以認為只要知道對象的名字,那么它的映射關系實不會變化的。
依據以上過程,我們即可嘗試這樣的方案:
- 先從備份的磁盤上獲取對應丟失對象的數據,通過
ceph-objectstore-tool的get-bytes參數來獲取 - 從備份的磁盤雙獲取對應丟失對象的元數據,通過
ceph-objectstore-tool的get-attr _獲取object_info_t屬性,通過get-attr snapset獲取快照屬性 - 每獲取完一個pg上所有的unfound對象之后,即將該pg上的unfound對象都delete掉
ceph pg 8.32 mark_unfound_lost delete - 使用
rados命令,重新put同一個對象名,并指定我們第一步獲取到的對象文件 - 將備份好的對象的oi屬性和ss屬性在osd down掉的情況設置進去
以上步驟可以簡化為如下腳本:
#!/bin/bash
tier_pool=$1pg_list=`ceph health detail |grep unfound|grep has|awk '{print $2}'`for i in ${pg_list}
do# 按照PG編號,獲取丟失對象列表ceph pg $i list_missing|grep "rbd_dat"|sed 's/"/ /g'|awk -F: '{print $2}'|awk '{print $1}' > "$i".txt#以PG為編號,從備份的磁盤掛載點獲取丟失對象的數據for j in `cat "$i".txt` doceph-objectstore-tool --data-path /test_ceph0/ --type bluestore --pgid $i $j get-bytes "$i"/"$j".txtceph-objectstore-tool --data-path /test_ceph0/ --type bluestore --pgid $i $j get-attr _ > "$i"/"$j".oiceph-objectstore-tool --data-path /test_ceph0/ --type bluestore --pgid $i $j get-attr snapset > "$i"/"$j".ssecho $i $jdoneif [ -e "$i".txt ];then #檢測到按PG編號 存儲對象列表的文件存在,則進行pg的delete操作ceph pg $i mark_unfound_lost deleteelseecho "$i.txt is not exists,please check"exit 1fiecho $ifor k in `cat "$i".txt` #將拷貝出來的對象文件,按照對象名重新put到資源池dorados -p $tier_pool put $k "$i"/"$k".txt;echo $kdonesleep 100 #處理完一個pg,睡眠100秒,讓上一個PG數據重構一會
done
該嘗試能夠將對象最原本的數據恢復到集群異常前的最新狀態,目前在使用rbd-nbd命令掛載的rbd塊設備復現對象丟失的情況能夠正?;謴?。
總結
以上是生活随笔為你收集整理的再记一次ceph object unfound的艰辛历程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux进程间通信:无名管道 pipe
- 下一篇: 苹果6s电池多少钱啊?