天天看點

有雲存儲團隊公布 Ceph 中最嚴重資料不一緻 BUG!

目前,塊存儲服務是ceph存儲中被使用的最普遍的服務之一,通過塊存儲服務,可以向用戶端以使用塊裝置一樣通路ceph叢集。然而,目前在使用塊存儲服務時,尤其是openstack與ceph對接時,如果沒有嚴格的控制ceph端的對象大小(使用 >= 8mb對象時),将有可能導緻嚴重的資料不一緻情況,該異常由于xfs檔案系統本身對fiemap的支援特性導緻的。

xfs使用fiemap時,當extents數量大于1364時,通過ioctl的fs_ioc_fiemap接口,擷取的extents數量上限為1364,導緻超出部分extents資料擷取不到。這将導緻,在開啟fiemap時,ceph叢集進行recovery與backfill之後,産生大量資料不一緻的情況,也是迄今為止ceph中影響最大的,最嚴重的資料不一緻bug。

由于fiemap bug,碎片化對象在recovery與backfill之後(fiemap 擷取不正确的資料),進而使的恢複的對象資料與原對象資料不一緻。而恢複後的副本若成為主副本,則可能發生靜默讀錯誤,并且如果使用ceph政策自動修複對象(repair object之後),可能将錯誤資料覆寫至正确資料,資料将永遠損毀。在某些情況下,還會觸發對象永遠處于inconsistent狀态。

初始化大量extents碎片檔案test,使其成為一個擁有3999個extents的碎片檔案。

通過fiemap系統調用,擷取這些extents

有雲存儲團隊公布 Ceph 中最嚴重資料不一緻 BUG!

編譯g++ do_fiemap.cc -o do_fiemap

通過該程式可以列印出可以擷取的到fiemap extents, do_fiemap test,通過xfs_bmap test 列印出真正的extents數量後,進行比較。

有雲存儲團隊公布 Ceph 中最嚴重資料不一緻 BUG!

可以看到,我們最先寫了2000個extents,并通過xfs_bmap擷取到了 2000個有内容的extents,但是通過fiemap系統調用,隻擷取到了1364個有資料的extents,是以在ceph中使用fiemap系統調用在某些情況下導緻資料一緻性bug。

修複方案

1)目前,在使用塊存儲使用場景時,通常情況下,預設使用4mb對象。在無特殊情況下,不用使用大于4mb 對象的rbd 鏡像。

2)在i版以後,通過新的系統調用,seek_data, seek_hole,可以避免觸發該bug,防止extents過多時使用fiemap調用産生的問題

有雲存儲團隊公布 Ceph 中最嚴重資料不一緻 BUG!

這組系統調用,可以讓使用者通過while循環,反複的發現檔案中的data 與 hole,進而組織出一個檔案中真正存在的資料,能夠避免産生與fiemap系統調用類似的bug,又保證了recovery或者clone時候隻複制有用資料,而反複的系統調,應該會帶來一定性能上的影響,請讀者們自行測試。

目前,在i版本以後的ceph中,提供參數filestore_seek_data_hole,來啟用該功能。當filestore_seek_data_hole 與 filestore_fiemap同時設定時,隻用檔案系統支援seek_data_hole,那麼就會先通過seek_data_hole方式來擷取檔案的extents,是以在i版本以後的ceph中,應啟用filestore_seek_data_hole功能來替代filestore_fiemap 功能。

3)對于已經使用8mb,16mb 甚至更大對象大小的rbd鏡像,請暫時設定禁用fiemap功能,并等待後續版本修複。