Btrfs

出自 Arch Linux 中文维基

引自 Btrfs 文檔介紹

BTRFS 是一種現代的寫時複製(COW)Linux 文件系統,致力於實現一些高級功能,同時着重於容錯性、修復性以及易於管理性。
注意:

和其它一些文件系統一樣,Btrfs也在進行不斷地開發。這意味着某些功能可能還不適合用於日常使用。要確認你的用例是否受到影響,參見Btrfs的狀態文檔(英文)和本文的#已知問題部分。

準備工作[編輯 | 編輯原始碼]

安裝 基礎操作所必須的 btrfs-progs 軟件包以使用用戶空間工具。

如果需要從 Btrfs 文件系統引導啟動(比如說內核和初始內存文件系統(initramfs)駐留在 Btrfs 分區上),請檢查 啟動引導器 是否支持 Btrfs。

創建文件系統[編輯 | 編輯原始碼]

下文展示了如何創建一個新的 Btrfs 文件系統。要將一個 Ext3/4 分區轉換為 Btrfs,請參考 #從 Ext3/4 轉換。要使用無分區的配置,請參考 #無分區 Btrfs 磁盤

查閱 mkfs.btrfs(8) 以獲取更多信息。

單一設備上的文件系統[編輯 | 編輯原始碼]

要在分區 /dev/partition 上創建一個 Btrfs 文件系統,執行:

# mkfs.btrfs -L 自定义标签 /dev/分区名

Btrfs 用於元數據的默認節點大小 (nodesize) 為 16 KiB,而用於數據的默認扇區大小 (sectorsize) 等於頁面大小 (page size) 並會自動檢測。 要對元數據使用較大的節點大小 (必須為扇區大小的倍數,最大允許 64 KiB),請通過 -n 選項開關指定 nodesize 的值。如下例所示,要使用 32 KiB 大小的塊:

# mkfs.btrfs -L 自定义标签 -n 32k /dev/分区名
注意: 根據 mkfs.btrfs(8) § OPTIONS 手冊頁內容:「較小的節點大小會增加分頁,但也會讓 B 樹更高,進而減少線程鎖競爭。較高的節點大小則能更好地打包數據和減少分頁,但代價是,更新元數據塊時會使用更多的內存」。

多設備文件系統[編輯 | 編輯原始碼]

警告: Btrfs 的 RAID 5 和 RAID 6 模式存在致命缺陷,除非用來做數據丟失測試,否則不應當用於任何場景。這裏有已知問題和部分解決方法的列表。 查閱 btrfs(5) § RAID56 STATUS AND RECOMMENDED PRACTICES 以獲取最新動態。

多個設備可以用來創建一組 RAID。支持的 RAID 級別有 RAID 0、RAID 1、RAID 10、RAID 5 和 RAID 6。從 5.5 版本內核開始,新增對 RAID1c3RAID1c4 的支持,它們分別是帶 3 份冗餘和帶 4 份冗餘的 RAID 1。可以使用 -d-m 參數分別為數據和元數據配置 RAID 等級。默認情況下,數據只有一份(single),元數據則被鏡像存儲(raid1)。這就像創建一個 JBOD 配置,多個磁盤會被看做成一個文件系統,但文件不會重複。更多有關如何創建一個 Btrfs RAID 卷的信息請參閱 Btrfs Wiki:在多個設備上使用 Btrfs

# mkfs.btrfs -d single -m raid1 /dev/分区1 /dev/分区2 ...

必須在 /etc/mkinitcpio.conf 中加入 udev 鈎子或 btrfs 鈎子才能在一個池中使用多個 Btrfs 設備。查閱 Mkinitcpio#常用鈎子 以獲取更多信息。

注意:
  • 可以稍後再將設備添加到多設備文件系統中。詳情請參見 Btrfs wiki 文章
  • 多個設備可以大小各異。但是,如果在 RAID 配置中一個硬盤的大小比其他的都大,那麼它多出的空間將不會被使用。
  • 有些 引導加載程序 不支持多設備文件系統,比如 Syslinux
  • Btrfs 不會自動從速度最快的設備讀取,因此混合使用不同類型的磁盤會導致性能表現不穩定。詳情請參閱 Stack Overflow 上的這個回答

#RAID 小節中有關於維護多設備上的 Btrfs 文件系統的一些建議。

配置文件系統[編輯 | 編輯原始碼]

寫時複製 (CoW)[編輯 | 編輯原始碼]

默認情況下 Btrfs 總是對所有文件使用 寫時複製 (CoW)。寫入不會就地覆蓋數據;相反,數據塊在被複製和修改後會寫入到新的位置,元數據也會更新以指向新的位置。請參閱 Btrfs 系統管理指南相關章節 以獲取實現細節以及它的優點和缺點。

停用 CoW[編輯 | 編輯原始碼]

警告: 在 Btrfs 中禁用寫時複製會同時禁用數據校驗和。Btrfs 將無法檢測到損壞的 nodatacow 文件。與 RAID1 結合使用時,斷電或其他導致損壞的原因可能會使數據失去同步。

要對某個子卷上的新文件停用寫時複製,使用 nodatacow 掛載選項。這只會影響新創建的文件,寫時複製仍然會在已存在的文件上生效。nodatacow 參數同樣會禁用壓縮。參閱 btrfs(5) 以了解細節。

注意: 根據 btrfs(5) § MOUNT OPTIONS: 在單個文件系統中,無法讓某些子卷使用 nodatacow 參數掛載,而其他的使用 datacow 參數掛載。第一個被掛載子卷的掛載參數將會應用於其他所有子卷。

要單文件或目錄禁用寫時複製特性,請使用下面的命令:

$ chattr +C /目录/文件

這會為這個文件的單個引用停用寫時複製,如果這個文件不只有一個引用,比如文件有多個克隆或輕量克隆(clones / lightweight clones)或者在文件系統快照中,寫時複製依然生效。注意自coreutils 9.0版本起,cp默認使用輕量複製,更多細節參見cp(1)

注意: 引自 chattr(1) 的手冊頁:
「在 Btrfs 上,'C' 標誌應該被設置在新建的或者是空白的文件,如果被設置在已有數據的文件,當塊分配給該文件時,文件將不確定是否完全穩定。如果 'C' 標誌被設置給一個目錄,將不會影響目前的目錄,但在該目錄創建的新文件將具有 No_COW 屬性。」
提示:根據上文內容,可以用下面的方法為已存在的文件或目錄停用寫時複製:
$ mv /path/to/dir /path/to/dir_old
$ mkdir /path/to/dir
$ chattr +C /path/to/dir
$ cp -a --reflink=never /path/to/dir_old/. /path/to/dir
$ rm -rf /path/to/dir_old
需要保證這個過程中目標文件不會被使用,同時注意下面描述的 mvcp 在沒有--reflink=never時將不會生效。
對快照的影響[編輯 | 編輯原始碼]

如果一個文件禁用了寫時複製(NOCOW)並創建了一個快照,在快照後,第一次在該文件的塊寫入將會是一個COW操作,因為快照鎖定了舊文件的塊來確保內容正確。但文件依然保留了NOCOW屬性,任何後續寫入操作依然在本次快照後產生的相同文件塊中進行,直到產生下一次快照。

頻繁快照會降低NOCOW的效果,因為在每次快照後的第一次寫入都需要COW。要避免這種情況,可以把所有NOCOW文件放在一個單獨的子卷中並避免對該子卷進行快照操作。

壓縮[編輯 | 編輯原始碼]

Btrfs 支持 透明和自動壓縮。這就減小了文件的大小,通過減少文件寫入增幅來顯著延長閃存介質(flash-baesd media)的壽命 [1][2][3]。在某些特定的場景下(比如單線程、重負荷的文件 I/O))還 提高了性能。儘管在其他的場景下(比如多線程和/或大文件 I/O 高強度 CPU 任務)還是明顯影響了性能。通常使用更快的壓縮算法,比如 zstdlzo 可以獲得更好的性能,這個 性能測試 提供了詳細的對比。

LZO的壓縮等級是固定的,而ZLIB和ZSTD有從1到9(ZLIB)或15(ZSTD)的壓縮等級,等級越高壓縮率越大,參見btrfs(5) § COMPRESSION。改變壓縮等級將直接影響CPU和I/0吞吐,建議在改變壓縮等級前後進行檢查或性能測試。

compress=alg[:level] 掛載選項可自動考慮為每個文件啟用壓縮,其中的 alg 處可以選填為 zlib, lzo, zstd, 或者 no(即不壓縮)。由此,Btrfs 將檢查壓縮數據的第一部分是否能將其縮減。如果能,則會壓縮該文件的整個寫入;否則不會壓縮任何內容。所以,如果數據的第一部分沒有被縮減,那麼即使數據的其餘部分可以大大縮減,寫入時也不會被壓縮。[4]這樣做是為了防止讓磁盤一直等待寫入,直到所有要寫入的數據傳遞給 Btrfs 並被壓縮後為止。

這篇文章的某些內容需要擴充。

原因: 下文陳述的有關試驗測試的結果缺少引用來源。 (在 Talk:Btrfs 中討論)

另外可以改用 compress-force=alg[:level] 掛載選項,這會讓 Btrfs 跳過對數據第一部分的壓縮檢查,並嘗試對每個文件啟用自動壓縮。最不濟的情況,這會 (稍微) 導致 CPU 佔用率無故升高。不過,在多個混合使用系統的試驗測試顯示,與僅使用 compress=zstd (其也有 10% 的磁盤壓縮率) 相比,使用 compress-force=zstd 可以顯著提高約 10% 的磁盤壓縮率。不過,請注意官方Btrfs指導手冊不推薦使用強制壓縮。

只有在加入掛載選項後創建或修改的文件才會被壓縮。

給現存文件啟用壓縮,可使用 btrfs filesystem defragment -calg 命令,alg 處可選填為 zliblzozstd。舉例來說,要用 zstd 方式給整個文件系統重新壓縮,執行下列命令:

# btrfs filesystem defragment -r -v -czstd /
警告: 對具有 COW 副本(快照副本或使用cp或 bcp 創建的文件)進行碎片整理以及使用帶壓縮算法的 -c 開關進行碎片整理可能會導致生成兩個不相關的文件從而大幅增加磁盤使用量。

要在新的 Btrfs 分區上安裝 Arch Linux 時就啟用壓縮功能,請在 掛載 文件系統時使用 compress 選項:mount -o compress=zstd /dev/sdxY /mnt/。在配置過程中,請在 fstab 中把 compress=zstd 添加到根目錄文件系統的掛載選項裡。

提示:通過執行 chattr +c,也可以在不使用 compress 選項的情況下為每個單文件啟用壓縮屬性。對目錄執行會使這個目錄下新文件自動被壓縮。
警告:
  • 如果使用 zstd 參數,使用較舊版本內核或者尚不支持 zstdbtrfs-progs 的系統可能不能讀取或修復您的文件系統。
  • GRUB 在 2.04 版本中引入了對 zstd 的支持。使用此後版本時,請通過手動運行 grub-install(需添加適用於機器 BIOS/UEFI 設置的選項參數)確保安裝在 MBR/ESP 中的引導加載程序已確實升級,因為這些事情不會自動完成。可參閱 FS#63235

查看壓縮類型和壓縮比[編輯 | 編輯原始碼]

compsize 軟件包能獲取一個文件列表 (或一整個 Btrfs 文件系統),並測量出它們使用的壓縮類型和其有效壓縮比。不過,其給出的未壓縮時大小數值不一定能和其他程序 (比如 du) 給出的數值吻合,因為每一文件所佔空間範圍都會計數一次,即使文件被連結了多次,即使文件的一部分不再被使用 (但其未被垃圾回收)。 -x 選項可讓程序運行保持在單一個文件系統上,這在 compsize -x / (檢查根目錄) 之類的情況下很有用,可以避免程序去嘗試訪問非 Btrfs 子目錄從而導致整個程序運行失敗。

子卷[編輯 | 編輯原始碼]

"btrfs 子卷不是(也不能看作)塊設備,一個子卷可以看作 POSIX 文件名字空間.這個名字空間可以通過子卷上層訪問,也可以獨立掛載。"[5]

每個 Btrfs 文件系統都有一個 ID 為 5 的頂層子卷,該子卷不能刪除或被其他子卷替代。頂層子卷在文件系統中的路徑為/,其他子卷嵌套在頂層子卷下。其他子卷能夠在文件系統中移動,改變路徑,但不能改變他們的ID.

默認情況下,頂層子卷會隨着文件系統一塊掛載,當然也可以掛載一個特定子卷

子卷的一個主要使用場景是#快照

參閱下面的連結獲得更多信息:

創建子卷[編輯 | 編輯原始碼]

要創建一個子卷,btrfs文件系統必須先掛載。子卷名通過最後一個參數設置。

# btrfs subvolume create /path/to/subvolume

列出子卷列表[編輯 | 編輯原始碼]

要列出當前路徑 (path) 下的子卷和它們的 ID:

# btrfs subvolume list -p path

刪除子卷[編輯 | 編輯原始碼]

要刪除一個子卷:

# btrfs subvolume delete /path/to/subvolume

用戶也可以像移除常規目錄一樣刪除一個子卷 (用 rm -r, rmdir 命令)。

掛載子卷[編輯 | 編輯原始碼]

可以使用 subvol=/path/to/subvolumesubvolid=objectid 掛載標誌來安裝子卷,就像文件系統分區一樣。例如,您可以擁有一個名為 subvol_root 的子卷,並將其掛載為 /。通過在文件系統的頂層創建各種子卷,然後將它們掛載到適當的掛載點,可以模仿傳統的文件系統分區。建議使用subvol=/path/to/subvolume而不是子卷ID(subvolid)掛載,因為在恢復#快照時子卷ID可能會變化,需要修改掛載配置。

提示:不使用頂層子卷 (ID=5) 掛載為根目錄,可以更方便地修改子卷的佈局結構。相反,可考慮創建新的子卷,然後掛載為 /
注意: 引自 btrfs(5) § MOUNT OPTIONS:
「大多數掛載選項適用於整個文件系統,並且只有要掛載的第一個子卷的選項才會生效。 這是因為沒有實現,未來可能會發生變化。」

可參閱 Btrfs Wiki FAQ 以了解哪些掛載參數能夠被用於獨立的子卷。

參閱 Snapper#推薦文件系統佈局, Btrfs SysadminGuide#Managing SnapshotsBtrfs SysadminGuide#Layout 獲得子卷應用的示例。

有關 Btrfs 特定的掛載選項的完整列表,請參閱 btrfs(5)

掛載子卷為根掛載點[編輯 | 編輯原始碼]

要使用一個子卷作為根掛載點,可以通過設置默認子卷或指定 rootflags=subvol=/path/to/subvolume 內核參數。在 /etc/fstab 中編輯根掛載點並指定掛載選項 subvol=。或者可以在 /etc/fstab 中用 ID 指定子卷:用 rootflags=subvolid=objectid 作為內核參數並用 subvolid=objectid 作為掛載選項。建議使用subvol=/path/to/subvolume而不是子卷ID,因為在恢復#快照時子卷ID可能會變化,需要修改掛載配置,否則系統可能不會正確啟動。

改變默認子卷[編輯 | 編輯原始碼]

如果掛載時不指定 subvol= 選項便會掛載默認子卷。要改變默認子卷,執行:

# btrfs subvolume set-default subvolume-id /

subvolume-id 可以通過#列出子卷列表獲得。

注意: 在安裝了 GRUB 的系統上,在改變默認子卷以後不要忘記運行 grub-install ,讓引導加載器發現默認子卷的變化。參見 這個論壇帖子

通過 btrfs subvolume set-default 修改默認子卷將會導致文件系統的最頂層無法訪問,除非使用 subvol=/ 或者 subvolid=5 掛載參數。[6]

配額[編輯 | 編輯原始碼]

警告: Qgroup 尚且不穩定且在有(過多)快照的子卷上應用配額可能會導致性能問題,比如在刪除快照的時候。 此外,這裏還有更多 已知問題.

Btrfs中的配額支持是通過使用配額組或 qgroup 在子卷級別實現的:默認情況下,每個子卷都以 0/subvolume_id 的形式分配配額組。 但是,如果需要的話,可以使用任意數字創建配額組。

要使用 Qgroup,你首先需要啟用它:

# btrfs quota enable path

從此時開始,新創建的子卷將由這些配額組控制。 為了能夠為已創建的子卷啟用配額,首先正常啟用配額,然後使用它們的 subvolume_id 為每個子卷創建一個配額組,再重新掃描它們:

# btrfs subvolume list path | cut -d' ' -f2 | xargs -I{} -n1 btrfs qgroup create 0/{} path
# btrfs quota rescan path

Btrfs 中的配額組形成樹層次結構,其中 Qgroup 附加到子卷。大小限制由每個 Qgroup 獨立配置且在並在包含給定子卷的樹中達到任何限制時應用。

配額組的限制可以應用於總數據使用,非共享數據使用,壓縮數據使用或全部。文件複製和文件刪除可能都會影響限制,因為如果刪除原始卷的文件並且只剩下一個副本,則另一個 Qgroup 的非共享限制可能會更改。例如,新快照幾乎與原始子卷共享所有塊,對子卷的新寫入將向專用限制提升,一個卷中的公共數據的刪除將升高到另一個卷中的專用限制。

要對 Qgroup 應用限制,請使用命令 btrfs qgroup limit。根據你的使用情況,使用總限制,非共享限制( -e)或壓縮限制( -c)。

顯示文件系統使用中給定路徑的使用情況和限制:

# btrfs qgroup show -reF path

提交間隔[編輯 | 編輯原始碼]

將數據寫入文件系統的頻率由 Btrfs 本身和系統的設置決定。Btrfs 默認設置為 30 秒檢查點間隔,新數據將在 30 秒內被提交到文件系統。 這可以通過在 /etc/fstab 增加 commit 掛載參數來修改:

LABEL=arch64 / btrfs defaults,noatime,compress=lzo,commit=120 0 0

系統範圍的設置也會影響提交間隔。它們包括 /proc/sys/vm/* 下的文件,這超出了本文的範圍,因此不再贅述。 它們的內核文檔位於 https://docs.kernel.org/admin-guide/sysctl/vm.html

固態硬盤 TRIM[編輯 | 編輯原始碼]

Btrfs 文件系統能夠從支持 TRIM 命令的 SSD 驅動器中釋放未使用的塊。可使用掛載參數 discard=async 啟用異步丟棄(asynchronous discard)支持,linux 6.2 版本已經默認啟用該功能。已釋放的空間範圍不會被馬上丟棄,它們會被集中起來並在稍後由一個單獨的工作線程進行 TRIM,這將能改善提交延遲。

異步丟棄可以安全地同定期TRIM使用[7]

有關啟用和使用 TRIM 的更多信息,請參閱 固態硬盤#TRIM

使用[編輯 | 編輯原始碼]

交換文件[編輯 | 編輯原始碼]

注意: 跨設備文件系統上的交換文件不受支持,參見btrfs(5) § SWAPFILE SUPPORT以了解所有限制。

創建交換文件的正確方法是首先創建一個非快照子卷以存儲交換文件,

# btrfs subvolume create /swap 
提示:考慮直接在頂層子卷上創建子卷,例如@swap。然後將子卷掛載/swap(或其他可訪問路徑)。

創建交換文件:

# btrfs filesystem mkswapfile --size 4g --uuid clear /swap/swapfile

如果未指定 --size 選項,交換文件默認大小為2 GiB。

啟用交換文件:

# swapon /swap/swapfile

最後編輯fstab,添加交換文件的配置:

/etc/fstab
/swap/swapfile none swap defaults 0 0

更多信息參見Fstab#用法

注意: 也可以手動創建交換文件,通過chattr設置整個子卷的No_COW屬性,然後按照Swap#建立交換文件的內容創建交換文件。參見btrfs(5) § SWAPFILE SUPPORT

休眠到交換文件的配置方法在電源管理/掛起與休眠#休眠到交換文件中描述。

顯示已使用的/空閒空間[編輯 | 編輯原始碼]

df(1) 這樣的用戶空間工具可能不會準確的計算剩餘空間 (因為並沒有分別計算文件和元數據的使用情況) 。推薦使用 btrfs filesystem usage 來查看使用情況。比如說:

# btrfs filesystem usage /
注意: btrfs filesystem usageRAID5/RAID6 設備上可能無法正常工作。

或者使用btrfs filesystem df在非root權限下快速檢查已分配空間的使用情況:

$ btrfs filesystem df /

請參閱 [8] 以獲取更多信息。

du(1)ncdu(1) 這類分析文件系統子集空間使用的工具同樣受到影響,因為其沒有考慮reflink,快照和壓縮。可以考慮使用btduAURcompsize這類可識別btrfs特性的工具。

碎片整理[編輯 | 編輯原始碼]

Btrfs 支持通過配置掛載參數 autodefrag 來實現在線的碎片整理,參見 btrfs(5) § MOUNT OPTIONS 。要手動整理你的根目錄的話,可以使用:

# btrfs filesystem defragment -r /

使用不帶 -r 開關的上述命令將導致僅整理該目錄的子卷所擁有的元數據。這允許通過簡單地指定路徑進行單個文件碎片整理。

警告: 對具有 CoW 副本(快照副本或使用cp或 bcp 創建的文件)進行碎片整理以及使用帶壓縮算法的 -c 開關進行碎片整理可能會導致生成兩個不相關的文件從而大幅增加磁盤使用量。

RAID[編輯 | 編輯原始碼]

Btrfs 提供對 RAID 一類的 #多設備文件系統的原生支持。自修復冗餘陣列和在線數據在線平衡是使btrfs RAID 與mdadm區分開來的重要特性。參閱 the Btrfs wiki page 獲得更多信息。Btrfs 管理員手冊 提供了一些額外技術背景信息。

警告: 奇偶校驗 RAID(RAID 5/6)代碼中存在多個嚴重的數據丟失錯誤。 檢查 Btrfs 文檔的 RAID5/6 頁面 (英文) 和 BUG 匯報 (linux-btrfs 郵件列表 (英文)) 以獲取更多信息。2020 年 6 月, 有人提出了一個 通俗易懂的現存問題列表 (英文) 和一個 有用的恢復指南 (英文)

檢修 (Scrub)[編輯 | 編輯原始碼]

這篇文章的某些內容需要擴充。

Btrfs Wiki 術語表中寫到,Scrub 是一種"在線文件系統檢查工具"。它能讀取文件系統中的文件和元數據,並使用校驗值和 RAID 存儲上的鏡像區分並修復損壞的數據。

注意: 運行 scrub 會阻止系統待機, 詳見 這個討論
手動啟動[編輯 | 編輯原始碼]

啟動一個(後台運行的)包含 / 目錄的文件系統在線檢查任務:

# btrfs scrub start /

檢查該任務的運行狀態:

# btrfs scrub status /
通過服務或者定時器啟動[編輯 | 編輯原始碼]

btrfs-progs 軟件包帶有 btrfs-scrub@.timer 系統單元,用來每月運行 scrub 命令。通過添加掛載點的參數來啟用它,例如btrfs-scrub@-.timer (/) 或者 btrfs-scrub@home.timer (/home)。你可以使用systemd-escape -p /path/to/mountpoint來轉義路徑,參見systemd-escape(1)

也可以通過啟動 btrfs-scrub@.service 來手動運行 scrub (使用同樣的轉移後路徑),相較 (以 root 用戶身份運行) btrfs scrub,這麼做的優點是輸出內容會記錄在 Systemd 日誌中。

數據平衡 (Balance)[編輯 | 編輯原始碼]

"Balance 將會通過分配器再次傳遞文件系統中的所有數據。它主要用於在添加或刪除設備時跨設備重新平衡文件系統中的數據。如果設備出現故障,餘額將為冗餘 RAID 級別重新生成缺失的副本。"[9]。參閱上游的 FAQ.

在單設備文件系統上,數據平衡對於(臨時)減少分配但未使用(元)數據塊的數量也是有用的。有時候這對於解決 "filesystem full" 故障 來說也是必須的。

# btrfs balance start --bg /
# btrfs balance status /

快照[編輯 | 編輯原始碼]

"快照是和其它子卷共享數據和元數據的簡單子卷, 利用了 btrfs 的寫時複製特性。" 詳見 Btrfs Wiki SysadminGuide#Snapshots

要創建一個快照:

# btrfs subvolume snapshot source [dest/]name

source為要創建快照的對象,[dest/]name為快照安放路徑。

加入 -r 參數可以創建一個只讀快照. 為只讀快照創建一個快照可以獲得一個只讀快照的可寫入版本.

注意:
  • 將一個只讀快照通過btrfs property set -f -ts '/path/to/snapshot' ro false原位轉換為可寫快照是可能的。但並不推薦這樣做,因為之後任何增量發送/接受(send/receive)操作會造成問題。創建一個新的可寫快照可以預防這類問題。
  • 快照不是遞歸包含的,這意味着子卷內的子卷在快照裡是空目錄。

發送和接收[編輯 | 編輯原始碼]

可以通過 send 命令發送一個快照,通常會與 btrfs 中的 receive 組成管道.例如將快照 /root_backup (也許是/的備份) 發送到 /backup:

 # btrfs send /root_backup | btrfs receive /backup

只能發送只讀快照,上面的命令在將子卷複製到外部設備 (例如備份驅動器) 時會很有用。

接受結束後將創建對應子卷,無需手動再創建。

還有一個例子創建了/mnt/arch-v2/subvolumes/@var子卷:

# btrfs send --proto 2 --compressed-data '/mnt/arch/snapshots/@var' | btrfs receive '/mnt/arch-v2/subvolumes/'

參數--proto 2--compressed-data在本例中能夠更有效地發送快照(假設數據可壓縮)。

也可以只發送兩個快照間發生變化的部分,例如如果你已經發送了快照 root_backup ,然後又建立了一個新的只讀快照 root_backup_new ,可以這樣完成增量發送:

 # btrfs send -p /root_backup /root_backup_new | btrfs receive /backup

現在你 /backup 的快照會是 root_backup_new

參閱 Btrfs Wiki 上關於增量備份的頁面 (英文) 獲得更多信息 (例如使用工具自動化這一過程)。

去重[編輯 | 編輯原始碼]

使用寫時複製,Btrfs 能夠複製文件或整個子卷而無需實際複製數據。但是,無論何時更改文件,都會創建一個新的「真正的」副本。重複數據刪除更進一步,通過主動識別含有相同內容的數據塊並將它們通過COW合併到同一個區(extend)內。

專用於 Btrfs 分區去重的工具包括 duperemovebees。也許你還希望基於文件的級別對數據進行重複數據刪除,比如 rmlintjdupesAUR 或者 dduper-gitAUR。有關這些程序的可用功能的概述和其他信息,請參閱 上游 Wiki 條目 (英文)

調整大小[編輯 | 編輯原始碼]

警告: 為避免數據丟失,確保在調整大小前備份好你的數據。

你可以增加文件系統的大小到設備的最大可用空間,或到一個指定大小。確保你在嘗試增加文件系統大小前設備或邏輯卷有足夠空間。 當指定一個設備上的文件系統到指定大小時,不論增加或減少,確保新的大小滿足下面的條件:

  • 新的大小必須大於已有數據的大小,否則會導致數據損失。
  • 新的大小必須等於或小於當前設備的可用空間。
注意: 如果你還計劃減小文件系統所在的邏輯卷大小,請先減小文件系統大後再嘗試減小邏輯卷的大小。

將文件系統擴展到設備的最大可用大小:

# btrfs filesystem resize max /

將文件系統擴展到特定大小:

# btrfs filesystem resize size /

size 替換為你需要的大小(按字節計算)。也可以為大小指定單位,如K(千字節),M(兆字節)或G(吉字節)。 或者也可以通過在大小前添加前綴指定增加(+)或減少(-)的變化量:

# btrfs filesystem resize +size /
# btrfs filesystem resize -size /

已知問題[編輯 | 編輯原始碼]

一些在嘗試之前應該知道的限制。

加密[編輯 | 編輯原始碼]

Btrfs 目前還沒有內建的加密支持,但未來可能加入此功能。可以在運行mkfs.btrfs前加密分區,參閱dm-crypt/Encrypting an entire system英語dm-crypt/Encrypting an entire system

(如果已經創建了文件系統,可以使用EncFS英語EncFSTrueCrypt英語TrueCrypt,但是這樣會無法使用 btrfs 的一些功能。)

檢查 btrfs 文件系統問題[編輯 | 編輯原始碼]

btrfs check 工具目前有一些已知問題,在繼續深入閱讀了解之前,您不應該直接運行它, 參見 #檢查 Btrfs 文件系統 小節。

提示和技巧[編輯 | 編輯原始碼]

無分區 Btrfs 磁盤[編輯 | 編輯原始碼]

警告: 大多數用戶不會使用這種類型的配置,應該在常規分區上安裝 Btrfs。 此外,GRUB 強烈建議不要安裝到無分區磁盤。

Btrfs 能佔用整個存儲設備,使用子卷模擬分區表來替代 MBRGPT 分區表。雖然無分區磁盤不需要使用其它方法創建分區,然後在一個分區上創建 Btrfs 文件系統,但在單個磁盤上使用無分區配置存在一些限制:

  • 不能在同一磁盤上的不同分區上創建其它的 文件系統
  • 受上一條影響,無法在該磁盤上創建EFI 系統分區。需要額外的儲存設備用於 UEFI 啟動。

運行下面的命令把整個設備的分區表替換成 Btrfs:

# mkfs.btrfs /dev/sdX

如果設備上存在分區表,則需要使用:

# mkfs.btrfs -f /dev/sdX

例如, 指定/dev/sda 而不是 /dev/sda1。後一種形式會格式化現有的分區而不是替換掉原有的分區表。由於根分區是 Btrfs 文件系統,請確保已將 btrfs 編譯進內核, 或者將 btrfs 放入 Mkinitcpio#模塊(MODULES) 中並且 重新生成 initramfs

像使用普通的 MBR 分區表存儲設備一樣安裝 引導加載器, 參考 Syslinux#手動安裝GRUB/技巧和竅門#安裝到分區上或者無分區磁盤上。 如果你的內核因為 Failed to mount /sysroot. 錯誤無法啟動, 請在 /etc/default/grub 裡添加 GRUB_PRELOAD_MODULES="btrfs" 並重新生成 GRUB 配置文件 。

從 Ext3/4 轉換[編輯 | 編輯原始碼]

警告: Btrfs 的郵件列表中報告了多起轉換不完整/損壞/失敗的案例。在開始之前請確定您有可用的備份並且願意承擔丟失數據的風險。 詳見 Btrfs Wiki:從 Ext3 文件系統轉換 (英文)

從安裝 CD 啟動,然後轉化分區:

# btrfs-convert /dev/partition

掛載轉換後的分區並修改 /etc/fstab 文件,指定分區類型 (type 為 btrfs,並且 fs_passno[最後一列] 要修改為0,因為 Btrfs 在啟動時並不進行磁盤檢查)。 還要注意的是分區的 UUID 將有改變,所以使用 UUID (指定分區) 時,請更新 fstab 中相應的條目。 chroot 到系統並重建你的引導加載器(如果對此過程不熟悉,參考從現有 Linux 發行版安裝 Arch Linux )。 如果轉換了根文件系統,還需要在 chroot 環境中重建初始化內存盤 (mkinitcpio -p linux)以確保系統正確啟動。

注意: 如果轉換過程中有任何異樣,不管是無法掛載新轉換的 Btrfs 文件系統或是無法往其中寫入數據,只要備份子卷 /ext2_saved 還在,就可以進行回滾。請使用 btrfs-convert -r /dev/partition 命令進行回滾,這將會丟棄任何對新轉換 Btrfs 文件系統的更改。

確認沒有問題後,通過刪除 ext2_saved 備份子卷完成轉換的最後一步。請注意,如果沒了它 (備份子卷),你將沒辦法還原回 ext3/4 文件系統。

# btrfs subvolume delete /ext2_saved

最後通過 數據平衡 回收空間。

別忘了先前安裝的一些應用需要額外設置來適配Btrfs。

注意: Ext3/4 轉換到 Btrfs 的過程很耗時。一個普通機械硬盤上的4TB文件系統轉換耗時可高達10小時。

損壞恢復[編輯 | 編輯原始碼]

警告: btrfs check 工具有一些已知問題,參見 #檢查 Btrfs 文件系統 小節。

btrfs-check 不能在一個已掛載的文件系統上工作。為了能夠在不從 Live USB 啟動的情況下使用 btrfs-check,需要將其添加到初始內存盤:

/etc/mkinitcpio.conf
BINARIES=(btrfs)

然後 重新生成 initramfs

之後如果啟動時出現問題,則可以使用該實用程序進行修復。

注意: 如果 fsck 進程必須使空間緩存 (和/或其他緩存?) 無效 (invalidate cache),那麼隨後的引導會掛起一段時間,這是正常的(進程可能會給出關於 btrfs-transaction 掛起的控制台消息)。系統應該在一段時間後從中恢復正常。

查閱 btrfs-check(8) 以獲取更多信息。

引導進入快照[編輯 | 編輯原始碼]

要引導進入快照,因為快照可以像子卷那樣被掛載,所以請像掛載子卷為根分區那樣進行同樣的流程 (已交代於#掛載子卷為根掛載點的一段中)。

如果使用 GRUB,則可以在 grub-btrfsgrub-btrfs-gitAUR 的幫助下,在重新生成配置文件時使用 Btrfs 快照自動填充啟動菜單。

如果使用 rEFInd,則可以在 refind-btrfsAUR 的幫助下,啟用refind-btrfs.service後,在重新生成配置文件時使用 Btrfs 快照自動填充啟動菜單。

搭配 systemd-nspawn 使用 Btrfs 子卷[編輯 | 編輯原始碼]

可查閱 Systemd-nspawn#使用Btrfs子卷作為容器的根Systemd-nspawn#在 systemd-nspawn 中運行 docker 等文章。

減少訪問時間元數據的更新[編輯 | 編輯原始碼]

由於Btrfs的寫時複製性質,訪問文件就能夠觸發元數據的寫時複製。減少訪問時間的更新頻率可能會消除這種不希望的硬盤使用並提高性能。參見Fstab#atime 參數

增量備份到外置設備[編輯 | 編輯原始碼]

下列包利用 btrfs sendbtrfs receive 將備份增量發送到外置設備上。 參考它們的文檔來查看實現,功能和需求的不同。

  • btrbk — Btrfs子卷的快照和遠程備份工具
https://github.com/digint/btrbk || btrbk
  • snap-sync — 使用Snapper快照並備份到外置設備或遠程機器
https://github.com/wesbarnett/snap-sync || snap-sync
  • snapsyncSnapper的同步工具
https://github.com/doudou/snapsync || ruby-snapsyncAUR

下列工具運行備份snapper快照到非Btrfs文件系統。

  • snapborg — 一個類似borgmatic的工具,將snapper快照與borg整合起來
https://github.com/enzingerm/snapborg || snapborgAUR

自動快照[編輯 | 編輯原始碼]

要管理並自動創建快照,你可以使用像SnapperYabsnap英語Yabsnap這樣的快照管理器。

疑難解答[編輯 | 編輯原始碼]

請查閱 Btrfs 疑難解答Btrfs 常見問答集(英文) 以獲得排除一般問題的信息。

GRUB[編輯 | 編輯原始碼]

分區偏移[編輯 | 編輯原始碼]

注意: 當您試圖將 core.img 嵌入到已分區磁盤上時,可能會發生偏移問題。這意味着可以將 GRUB 的 corg.img 直接嵌入到無分區磁盤 (例如 /dev/sdX) 上的 Btrfs 存儲池中。

GRUB 可以引導啟動 Btrfs 分區,但是因為模塊可能會比其它文件系統大,grub-install 生成的 core.img 文件超過了 MBR 與第一個分區之間的空間大小 (63 扇區/31.5KiB)。最新版的 fdiskgdisk 等磁盤工具會通過第一個分區前空出 1-2MiB 的空間來避免此問題。

根丟失[編輯 | 編輯原始碼]

本文或本章節的事實準確性存在爭議。

原因: Suggests editing a non-configuration file manually.(在 Talk:Btrfs#Should not suggest to edit files in /usr/share 中討論)


當從一個RAID配置的系統中啟動用戶可能會遇到錯誤:error no such device: root。編輯/usr/share/grub/grub-mkconfig_lib,移除行echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}"中的兩個引號。重新生成grub的配置文件,後系統應該能夠正常啟動。

掛載超時[編輯 | 編輯原始碼]

有時(尤其在大型 RAID1 陣列上)系統啟動時會出現掛載超時的現象,並帶有如下日誌信息:

Jan 25 18:05:12 host systemd[1]: storage.mount: Mounting timed out. Terminating.
Jan 25 18:05:46 host systemd[1]: storage.mount: Mount process exited, code=killed, status=15/TERM
Jan 25 18:05:46 host systemd[1]: storage.mount: Failed with result 'timeout'.
Jan 25 18:05:46 host systemd[1]: Failed to mount /storage.
Jan 25 18:05:46 host systemd[1]: Startup finished in 32.943s (firmware) + 3.097s (loader) + 7.247s (kernel)>
Jan 25 18:05:46 host kernel: BTRFS error (device sda): open_ctree failed

這可以通過 fstab 中特定的 systemd 掛載選項 x-systemd.mount-timeout 提供系統以更長的超時時間來輕鬆解決。例如:

/dev/sda                /storage    btrfs       rw,relatime,x-systemd.mount-timeout=5min  0 0

出現 BTRFS: open_ctree failed 錯誤[編輯 | 編輯原始碼]

截至 2014 年 11 月,一個似乎存在於 systemdmkinitcpio 中的 Bug 可能會導致在 mkinitcpio.conf 中使用 btrfs 鈎子(hook)的用戶在啟動多設備文件系統的 Btrfs 卷時遇到以下錯誤:

BTRFS: open_ctree failed
mount: wrong fs type, bad option, bad superblock on /dev/sdb2, missing codepage or helper program, or other error

In some cases useful info is found in syslog - try dmesg|tail or so.

You are now being dropped into an emergency shell.

一種解決辦法是,在/etc/mkinitcpio.conf中,將 HOOKS 中的 btrfs 移入 MODULES 中,然後重新生成 initramfs 並重新啟動。

另外,如果在掛載 RAID 卷組缺少某個卷時,也有可能會發生這個錯誤。這種情況下,需要把 degraded 加入到 /etc/fstab 中;如果根目錄在卷組上,需要同時加入內核參數 rootflags=degraded

接上文,截至 2016 年 8 月,針對這一問題,一個可能的解決方案是在 /etc/fstab 中僅靠單個硬盤來掛載陣列,然後讓 Btrfs 自動發現並追加其它硬盤。UUID 和 LABEL 等基於組的標識符似乎是導致出現錯誤的原因。比如說,由「disk1」(磁盤 1) 和「disk2」(磁盤 2)組成的雙設備 RAID1 陣列會被分配到一個 UUID。但是請在 /etc/fstab 中只使用 /dev/mapper/disk1 來指定磁盤陣列,而不要使用 UUID。更多解釋,參見這個博客文章

另一個可能的解決方法是在 mkinitcpio.conf 中移除 udev 鈎子並替換為 systemd 鈎子。此時 btrfs 不應出現在 HOOKSMODULES 列表中。

請查閱 原論壇討論FS#42884 獲得更多的討論內容和信息。

檢查 Btrfs 文件系統[編輯 | 編輯原始碼]

本文內容或本節內容已經過期。

原因: "大開發階段"狀態已經過時。 (在Talk:Btrfs討論)
警告: Btrfs(特別是 btrfs check 命令工具)仍處在大開發階段,強烈建議在加上 --repair 參數運行 btrfs check 前先做一個備份,並提前查閱 btrfs-check(8)

btrfs-check(8) 可以檢查並修復一個未掛載的 Btrfs 文件系統。但是由於它尚未開發完成,它並不能修復某些錯誤(即使這些錯誤沒有導致文件系統無法掛載)。

持續的硬盤活動[編輯 | 編輯原始碼]

內核版本6.2開始, mount(8) 默認啟用 discard=async 選項。 這個設置被報告會造成硬盤的持續活動(甚至是待機狀態下),因為丟棄隊列填充的速度快於其處理速度。這會造成電源使用增加,特別是NVMe設備。

到了內核版本6.3後,問題的解決辦法是將iops_limit默認值從100改為1000。在舊版內核上,你可以手動設置到一個需要的值,例如:

# echo 1000 > /sys/fs/btrfs/uuid/discard/iops_limit

其中uuid是btrfs文件系統的UUID。限制值1000需要通過實驗進行調整。

要在啟動時設置該參數,可能要用到Systemd#systemd-tmpfiles - 臨時文件,例如創建下列文件:

/etc/tmpfiles.d/btrfs-discard.conf
w /sys/fs/btrfs/uuid/discard/iops_limit - - - - 1000

或者在fstab中使用nodiscard掛載選項禁用異步丟棄功能,使用定期TRIM來替代。

另請參閱[編輯 | 編輯原始碼]