1. 程式人生 > >MongoDB 異常掉電後的資料打撈

MongoDB 異常掉電後的資料打撈

當異常掉電後,例項啟動會報類似如下錯誤,屬於檔案級別的損壞,這時候常規的修復方案是沒用的,可以使用 wt 進行資料打撈。

2019-07-10T21:06:05.725-0500 E STORAGE  [initandlisten] WiredTiger (0) [1454119565:724960][1745:0x7f2ac9534bc0], file:WiredTiger.wt, cursor.next: read checksum error for 4096B block at offset 6
799360: block header checksum of 1769173605 doesnt match expected checksum of 4176084783
2019-07-10T21:06:05.725-0500 E STORAGE  [initandlisten] WiredTiger (0) [1454119565:725067][1745:0x7f2ac9534bc0], file:WiredTiger.wt, cursor.next: WiredTiger.wt: encountered an illegal file format or internal value
2019-07-10T21:06:05.725-0500 E STORAGE  [initandlisten] WiredTiger (-31804) [1454119565:725088][1745:0x7f2ac9534bc0], file:WiredTiger.wt, cursor.next: the process must exit and restart: WT_PANIC: WiredTiger library panic
2019-07-10T21:06:05.725-0500 I -        [initandlisten] Fatal Assertion 28558


安裝

必要元件安裝

[centos]
yum install  snappy-devel  make gcc gcc-c++ kernel-devel

[ubuntu]
apt-get install libsnappy-dev build-essential 

 wt 安裝 

官網地址 http://source.wiredtiger.com

wget http://source.wiredtiger.com/releases/wiredtiger-3.2.0.tar.bz2
tar xvf wiredtiger-3.2.0.tar.bz2 
cd wiredtiger-3.2.0
./configure --enable-snappy
make

資料打撈過程

建立恢復目錄

切記不要在損壞的原目錄進行操作,要在工作路徑建立一個恢復路徑,將損壞的 dbpath 複製一份到此處。
比如拷貝到 /opt/5113_wechatworkpre_bak/ ,理論上只有必要的 .wt 和損壞的 collection 檔案本身就夠了,以防萬一可以拷貝整個 dbpath .

查詢損壞的 collection 的檔名

假設日誌中損壞的 collection 叫 dmeo.
執行 db.demo.stats() 定位到 uri ,拿到具體的檔名 wechatworkpre_leju_com/collection-26--7067895897049507085 

打撈

執行如下命令進行打撈作業,打撈出來的檔案將覆蓋原檔案

./wt -v -h /opt/5113_wechatworkpre_bak/ -C "extensions=[./ext/compressors/snappy/.libs/libwiredtiger_snappy.so]" -R salvage wechatworkpre_leju_com/collection-26--7067895897049507085.wt (帶.wt字尾)

dump

到此為止,不能直接將新生成的檔案拷回 datapath ,要執行一次 dump ,生成我們想要的 collection 的原始資料,如下是  demo.dump 

./wt -v -h /opt/5113_wechatworkpre_bak/ -C "extensions=[./ext/compressors/snappy/.libs/libwiredtiger_snappy.so]" -R dump -f demo.dump wechatworkpre_leju_com/collection-26--7067895897049507085 (不帶.wt字尾)


建立新備份例項

這個備份例項的作用是用於匯入用 wt dump 出來的資料,為後來的工作做準備

mkdir /opt/mongo-recovery/ -p 
mongod --dbpath mongo-recovery --storageEngine wiredTiger --nojournal
mongo --port 27017 
use recovery
db.demo.insert({test: 1})
db.demo.remove({})
db.demo.stats()

load

拿到 collection 對應的資料檔案 "uri" : "statistics:table:collection-7--5182884231633924913",將上面 wt 生成的 dump 檔案 load 到新備份例項中(需要關閉備份例項)

./wt -v -h  /opt/mongo-recovery/  -C "extensions=[./ext/compressors/snappy/.libs/libwiredtiger_snappy.so]" -R load -f demo.dump -r collection-7--5182884231633924913

重新啟動備份例項

> use recovery
switched to db recovery
> db.demo.find()
{ "_id" : ObjectId("5d270709f43c5aedc1aae7c8"), "age" : 1 }

到此為止,打撈出來的資料成功匯入備份例項
如果還有問題只需要執行次 mongodump 和 mongorestore --drop  即可。

wt 幫助

global options:
        -C      wiredtiger_open configuration
        -h      database directory
        -L      turn logging off for debug-mode
        -R      run recovery if configured
        -V      display library version and exit
        -v      verbose
commands:
        alter     alter an object
        backup    database backup
        compact   compact an object
        copyright copyright information
        create    create an object
        downgrade downgrade a database
        drop      drop an object
        dump      dump an object
        list      list database objects
        load      load an object
        loadtext  load an object from a text file
        printlog  display the database log
        read      read values from an object
        rebalance rebalance an object
        rename    rename an object
        salvage   salvage a file
        stat      display statistics for an object
        truncate  truncate an object, removing all content
        upgrade   upgrade an object
        verify    verify an object
        write     write values to an object<