원문 보기: https://dawoum.duckdns.org/wiki/Btrfs
Original article: w:Btrfs
Btrfs ("better F S",[8] "butter F S",[11][12] "b-tree F S"[12]으로 발음하거나, 단순히 철자로 발음함)은 함께 개발된 논리적 볼륨 관리자 (리눅스의 LVM과 혼동하지 말 것)를 갖는 copy-on-write (COW) 원리를 기반으로 하는 파일 시스템을 결합하는 컴퓨터 저장 형식입니다. 그것은 2007년 Oracle Corporation에서 리눅스에서 사용하기 위해 처음 설계되었고, 2013년 11월부터, 파일 시스템의 온-디스크 형식이 리눅스 커널에서 안정적이라고 선언되었습니다.[13] Oracle에 따르면, Btrfs는 "진정한 약어가 아닙니다".[14]
Btrfs는 리눅스 파일 시스템에서 풀링, 스냅샷, 체크섬 및 통합 다중-장치 스패닝의 부족을 해결하기 의도되었습니다.[8] Btrfs의 주요 개발자, Chris Mason은 "[리눅스]가 사용 가능한 저장 장치에 맞게 확장할 수 있도록 하는 것. 확장은 저장 장치 문제를 해결하는 것뿐만 아니라 사람들이 무엇을 사용하고 있는지 볼 수 있고 그것을 보다 안정적으로 만드는 깨끗한 인터페이스와 함께 관리하고 유지-보수할 수 있음을 의미하는 것"을 목표로 합니다.[15]
Installation
Kernel config
리눅스 커널이 Btrfs를 지원하기 위해, 해당 파일 시스템이 활성화되어 있어야 합니다:
Versions < 6.14.0
File systems --->
<*> Btrfs filesystem support
-*- Cryptographic API --->
Accelerated Cryptographic Algorithms for CPU (x86) --->
<*> CRC32c (SSE4.2/PCLMULQDQ)
Version >= 6.14.0
File systems --->
<*> Btrfs filesystem support
Library routines --->
[*] Enable optimized CRC implementations
이때, 옵션이 보이지 않으면, CONFIG_EXPERT=y를 먼저 설정하십시오.
man 5 btrfs
를 확인하십시오).다음을 통해 Btrfs가 가속 버전을 사용하고 있는지 확인할 수 있습니다:
- cat /sys/fs/btrfs/<UUID of partition formatted with btrfs>/checksum
- crc32c (crc32c-generic)
결과가 (*-generic)이면 Btrfs는 일반 소프트웨어 구현을 사용하고 있습니다. 이는 btrfs 커널 모듈이 관련 체크섬 커널 모듈보다 먼저 로드되기 때문일 수 있습니다. 이 문제를 해결하기 위해, 체크섬 모듈이 btrfs 전에 로드되었는지 확인하십시오; 이것은 다음을 통해 수행될 수 있습니다:
- 체크섬 모듈을 모듈이 아니라 커널에 포함하십시오 (<M> 대신에 <*>).
- initramfs에 모듈을 추가하십시오 (Dracut에서 자동으로 수행될 수 있음).
위 과정을 거친 후에 다시 확인해 보십시오:
cat /sys/fs/btrfs/<UUID of partition formatted with btrfs>/checksum
- crc32c (crc32c-x86)
결과는 다를 수 있지만 중요한 부분은 (*-generic)이 아니다라고 말한다는 것입니다!
Snippet
커널 설정 파일 .config 파일에서 확인해 보십시오:
CONFIG_BTRFS_FS=y
CONFIG_XOR_BLOCKS=y
CONFIG_RAID6_PQ=y
CONFIG_RAID6_PQ_BENCHMARK=y
CONFIG_ZSTD_COMPRESS=y
Debian package
데비안 저장소에서 다음 패키지를 설치할 수 있습니다:
- sudo apt install btrfs-progs
Informations
Compress level
보통, 마운트 옵션에서 compress=zstd를 사용할 경우에 압축 레벨 3를 사용하고, HDD와 느린 플래시 스토리지에 적합하다고 알려져 있습니다. 좀 더 빠른 SATA SSD는 압축 레벨 2가 적당하고, NVME는 압축 레벨 1이 적당하다고 합니다:
Yup, this is it. On slow storage higher compression levels tend to yield higher total storage throughput because you spend less time bound by slow storage bandwidth, instead you spend CPU time compressing/decompressing that data. The rick is to pick a compression level that yields greater total throughput than storage bandwidth can accommodate on its own. This approach works well on bandwidth limited storage like HDD pools, slow flash nand, flash nand attached to the system via slow USB, etc.
On the flip side you don't want to constrain high bandwidth storage by sending data through a compression algorithm that limits throughput so lower compression levels (like zstd:1 on nvme storage, or zstd:2 on fast SATA SSDs) are usually safe choices.— seaQueue, Btrfs compress level, https://www.reddit.com/r/btrfs/comments/15i0psb/which_compression_level_should_i_choose/
Convert to btrfs from ext4
디바이스의 포맷 없이 변환하기 위해, ssd와 hdd에 대해 수행했습니다.
- ssd : 변환 후, 파일 시스템에 오류가 있다면서 마운트가 되지 않습니다. 역 변환이 되지 않을 가능성이 있어서, repair 과정은 수행하지 않았습니다.
- hdd : 변환 후, 마운트는 잘 됩니다. 문제는 성능이 많이 떨어진다는 것입니다. 예를 들어, 특정 디렉토리에서 du 명령을 수행한 결과입니다:
- ext4 : 3분 8초
- btrfs : 5분 넘게 걸림 (이것은 기록을 해 두지 않아서 정확한 값은 아니지만, 5분 후반대로 기억납니다)
- 조각화가 발생하므로, 마운트 옵션에 autodefrag를 줄 수 있지만, 성능에 문제를 발생시킬 수 있습니다.
- 따라서, hdd는 체크섬이 필요한 경우 등과 같이 반드시 필요한 경우가 아니면 ext4를 사용하거나, xfs를 사용하는 것이 바람직해 보입니다.
Make filesystem & Mount
기존에 ext4로 포맷되어 있다는 경고 메시지가 나옵니다. 강제 진행 -f 옵션으로 가능하지만, 문제를 만나지 않기 위해, 기존 파티션을 지우고 새롭게 만들어서 포맷을 진행했습니다.
- sudo fdisk /dev/sdc
- sudo mkfs.btrfs /dev/sdc1
- sudo blkid /dev/sdc1
- sudo vi /etc/fstab
UUID=... Mount_point btrfs defaults,noatime,commit=60,compress=zstd:2 0 2
Copying
먼저, 기존의 데이터 백업을 위해, ssd->ssd, ext4->ext4에 비해, ext4->btrfs가 꽤 빠르게 느껴지는 경우가 있습니다 (어떤 데이터 포맷인지 확인하지 않았습니다). 대체로 크게 차이를 느끼지 못할 정도입니다.
case2
- ext4(sata pcie3.0)->ext4(nvme pcie4.0) : 174.1G, 13분 54초
- ext4(nvme pcie4.0)->btrfs(sata pcie3.0) : 166.7G, 11분 17초
Distro default filesystem btrfs
- openSUSE
- /boot 파티션은 별도로 존재하지 않습니다.
- vda1: 8M BIOS boot,
- vda2: btrfs / 파티션,
- vda3: swap
- Fedora
- /boot 파티션 존재, zram으로 스왑 대체
- vda1: /boot 파티션
- vda2: btrfs / 파티션
부트로더
오픈수저에서 아래에 소개된 그럽 메뉴 만드는 명령을 수행해야 한다고 명시적으로 /etc/default/grub에 쓰여 있습니다: rootflags는 요구하지 않습니다!!
- grub2-mkconfig -o /boot/grub2/grub.cfg
- 우분투 20.04
- grub-mkconfig -o /boot/grub/grub.cfg
- 우분투 22.04
- grub-mkconfig -o /boot/efi/EFI/ubuntu/grub.cfg
Swapflie
커널 버전 5.0 이전에는 btrfs에서 swapfile을 지원하지 않습니다.
Partitionless
Manjaro, EndeavourOS 등은 BIOS boot, /boot 파티션이 별도로 존재하지 않고, 모든 파일들이 하나의 파티션 아래에 놓이도록 설치됩니다. 이때, 파티션을 그대로 유지하려면, grub을 설치하는데 약간의 수고가 필요합니다:
그렇지 않으면, Manjaro#Resize_root_partition를 통해, /boot 파티션을 나누는 것도 고려해 볼 수 있습니다.
Prerequisites
먼저, / 파티션이 60% 이상 사용되고 있는지 확인을 하십시오. 파일시스템 전환에서 롤백을 위해 ext2_saved 서브 볼륨을 만들어야 하기 때문에, 여유 공간이 필요합니다.
- df
만약 그렇다면, 파티션을 늘리든지, 불필요한 파일들을 지우십시오.
그런-다음 관련된 툴을 설치하십시오:
- sudo apt install btrfs-progs
Convert Ext File Systems to Btrfs
먼저, 루트 파일 시스템이 아닌 특정 위치에 마운트되어 있는 ext4 파일 시스템을 btrfs으로 옮겨보고자 합니다. 해당 파티션은 /dev/nvme0n1p1입니다.
- 해당 파티션을 접근하는 모든 프로세서를 종료합니다.
- sudo umount /dev/nvme0n1p1
- sudo fsck.ext4 -fyv /dev/nvme0n1p1
- 최적화 과정을 거칩니다.
- sudo fsck.ext4 -fyv /dev/nvme0n1p1
- 아무런 작업을 하지 않는지 확인을 합니다.
- sudo btrfs-convert /dev/nvme0n1p1
해당 파티션은 256G, pci3.0, nvme 타입의 SSD로써, 복원을 위한 ext2_saved 이미지를 생성하기 위해 생각보다 시간이 꽤 걸립니다.
- blkid /dev/nvme0n1p1
- sudo vi /etc/fstab
UUID=xxxx mount_point btrfs compress=zstd:1 0 2
무슨 설정을 추가해야 할까요? 가상 기계를 종료할 때 꽤 오래 기다려야 합니다.
Some tweak
해당 파티션의 조각 모음을 수행할 수 있습니다. SSD는 안하는 것을 추천합니다. 수명이 짧아집니다.
- sudo btrfs filesystem defragment -v -r -f mount_point
QEMU/KVM 이미지 디렉토리는 “no copy-on-write” 속성을 설정할 수 있습니다:
- sudo chattr +C image_directory
Roll back
위에서 만든 복원 이미지를 지우지 않았다면, 다음과 같이 복원할 수 있습니다:
- sudo umount /dev/nvme0n1p1
- sudo btrfs-convert -r /dev/nvme0n1p1
- sudo vi /etc/fstab
이전에 주석처리해 둔 줄에서 주석해제를 하고, 새롭게 만든 btrfs 줄을 주석처리합니다.
- sudo mount /dev/nvme0n1p1
Convert root filesystem ext4 to btrfs
가상 기계로 테스트를 진행하는데, 우분투 20.04가 설치되어 있습니다.
먼저, 가상 시디롬에 우분투 20.04 설치 이미지를 마운트하고 그것으로 부팅합니다.
부팅 후에 Try Ubuntu를 누릅니다.
터미널을 실행합니다.
- sudo su
- lsblk
- /dev/vda1 /boot/efi, /dev/vda5 /
- fsck.ext4 -fyv /dev/vda5
- btrfs-convert /dev/vda5
- mount /dev/vda5 /mnt
- mount -t vfat /dev/vda1 /mnt/boot/efi
- for fs in proc sys dev dev/pts; do mount --bind /$fs /mnt/$fs; done
- chroot /mnt
- blkid /dev/vda5
- vi /etc/fstab
UUID=..... / btrfs noatime,compress=zstd:1 0 1
- grub-mkconfig -o /boot/grub/grub.cfg
- update-initramfs -u
- grub-install /dev/vda
- update-grub
- exit
- 맨자로우
- /boot 파티션이 별도로 존재하지 않아서, 부팅에 문제가 발생할 수 있습니다. 우분투는 /boot/efi를 vfat로 나누었고, 페도라는 /boot 파티션을 ext4로 만들었습니다.
- 이것을 위해, Manjaro_Linux#Resize_root_partition를 진행하고, 파일 시스템 전환을 했습니다. 위의 과정에서 chroot 한 후에, /etc/default/grub 파일을 수정합니다:
GRUB_DEFAULT=0 #GRUB_SAVEDEFAULT=true
그런-다음
- grub2-mkconfig -o /boot/grub2/grub.cfg
- mkinitcpio -P
- grub-install /dev/vda
- update-grub
Roll back
- 우분투-계열 배포판
- /dev/vda5 /, /dev/vda1 /boot/efi로 파티션 되어 있으면, 똑같이 시디롬으로 부팅 후에,
- sudo su
- btrfs-convert -r /dev/vda5
- mount /dev/vda5 /mnt
- mount /dev/vda1 /mnt/boot/efi
- for fs in proc sys dev dev/pts; do mount --bind /$fs /mnt/$fs; done
- chroot /mnt
- grub-mkconfig -o /boot/grub/grub.cfg
- update-initramfs -u
- grub-install /dev/vda
- update-grub
- exit
- 아치-계열 배포판
- /dev/vda1 /, /dev/vda2 /boot로 파티션 되어 있으면, 똑같이 시디롬으로 부팅 후에,
- sudo su
- btrfs-convert -r /dev/vda1
- mount /dev/vda1 /mnt
- mount /dev/vda2 /mnt/boot
- for fs in proc sys dev dev/pts; do mount --bind /$fs /mnt/$fs; done
- chroot /mnt
- grub-mkconfig -o /boot/grub/grub.cfg
- mkinitcpio -P
- grub-install /dev/vda
- update-grub
- exit
Make sub volume
간혹, 부팅이 되지 않는 경우가 있는데, grub이 바뀌는 과정이 끝나기 전에 가상 기계를 강제 부팅해서 그런 것으로 판단됩니다. 따라서, 마지막 update-grub을 수행한 후에, grub.cfg에서 UUID가 새로운 것으로 바뀌었는지 확인을 하시기 바랍니다. 아니면, 라이브시디로 부팅한 것을 정상적으로 종료하고, 하드디스크로 부팅을 시도해 보시기 바랍니다!!
가상 기계에 설치된 우분투 22.04에서, 하나의 ext4 / 파티션을 /, /home 2개의 서브 파티션으로 나누는 과정입니다.
- sudo su
- lsblk
- /dev/vda2 /boot/efi vfat, /dev/vda3 / ext4
- fsck.ext4 -fyv /dev/vda3
- btrfs-convert /dev/vda3
- mount /dev/vda3 /mnt
- btrfs subvolume list /mnt
- cd /mnt
- btrfs subvolume snapshot ./ ./root2
- btrfs subvolume create home2
- cp -a home/* home2/
- /mnt 아래에 root2, home2 및 ext2_saved를 제외한 모든 디렉토리와 파일을 제거
- mv root2 root
- rm -rf root/home/*
- mv home2 home
- cd
- umount /mnt
- mount -o subvol=root /dev/vda3 /mnt
- mount -o subvol=home /dev/vda3 /mnt/home
- mount -t vfat /dev/vda2 /mnt/boot/efi
- for fs in proc sys dev dev/pts; do mount --bind /$fs /mnt/$fs; done
- chroot /mnt /bin/bash
- blkid /dev/vda3
- nano /etc/fstab
UUID=..... / btrfs noatime,subvol=root,compress=zstd:1 0 1
UUID=..... /home btrfs noatime,subvol=home,compress=zstd:1 0 1
- grub-mkconfig -o /boot/efi/EFI/ubuntu/grub.cfg
- update-initramfs -u
- grub-install /dev/vda
- update-grub
- 확인
- cat /boot/efi/EFI/ubuntu/grub.cfg
swapfile
SSD를 가진 분들은 스왑보다는 zram을 고려해 보시기 바랍니다.
우분투 라이브시디로 부팅해서, 터미널을 열고
- sudo su
- mount /dev/vda3 /mnt
- btrfs subvolume create /mnt/swap
- mount -o subvol=swap /dev/vda3 /mnt/swap
- touch /mnt/swap/swapfile
- chmod 600 /mnt/swap/swapfile
- chattr +C /mnt/swap/swapfile
- dd if=/dev/zero of=/mnt/swap/swapfile bs=1M count=2084
- 스왑으로 2G의 swapfile을 만듭니다. (count=... 숫자로 조절하십시오)
- sudo mkswap /mnt/swap/swapfile
- nano /etc/fstab
UUID=..... /swap btrfs subvol=swap 0 1
/swap/swapfile none swap sw 0 0
Rename subvolume
페도라는 /root, /home과 같은 형식으로 서브 볼륨을 만들 수 있고, 롤백이 작동합니다.
반면에, 우분투는 /root, /home과 같은 형식으로 서브 볼륨을 만들 수 있지만, 롤백이 동작하지 않습니다.
그래서, /root를 @로, /home @home로 바꾸고, 롤백이 동작하는지 확인하려 합니다.
그러기 위해, 기존의 서브 볼륨, /root, /home을 각각 @, @home으로 바꾸어야 합니다.
이 작업은 단순히 mv 명령을 사용해서 이루어지지만, 문제는 Fedora_(operating_system)#Manage btrfs을 적용해 두었으므로, /dev/vda3를 마운트해도 서브 볼륨이 나타나지 않게 됩니다.
따라서, 이전 과정을 되돌리는 과정이 필요합니다.
원래 시스템, 우분투 22.04로 부팅한 후에, (위에서 id를 확인하십시오):
- sudo btrfs subvolume set-default 5 /
- sudo btrfs subvolume get-default /
그런-다음 라이브시디로 부팅을 합니다:
- mount /dev/vda3 /mnt
- btrfs subvolume list /mnt
- cd /mnt
- mv root @
- mv home @home
- mv snapshots @snapshots
- cd
- umount /mnt
- mount -o subvol=@ /dev/vda3 /mnt
- mount -o subvol=@home /dev/vda3 /mnt/home
- mount -t vfat /dev/vda2 /mnt/boot/efi
- mount -o subvol=@snapshots /dev/vda3 /mnt/.snapshots
- for fs in proc sys dev dev/pts; do mount --bind /$fs /mnt/$fs; done
- chroot /mnt /bin/bash
- blkid /dev/vda3
- nano /etc/fstab
UUID=..... / btrfs noatime,subvol=@,compress=zstd:1 0 0
UUID=..... /home btrfs noatime,subvol=@home,compress=zstd:1 0 0
UUID=..... /.snapshots btrfs noatime,subvol=@snapshots,compress=zstd:1 0 0
- grub-mkconfig -o /boot/efi/EFI/ubuntu/grub.cfg
- update-initramfs -u
- grub-install /dev/vda
- update-grub
이제 정상적으로 부팅이 되었으니, 다시 256번 서브 볼륨을 /로 보이도록 조작하고, 부트로더를 수정해야 합니다. 그런-다음 롤백이 동작하는지 확인할 수 있습니다.
Troubleshootings
apt 설치 오류
다음과 같은 오류가 발생합니다:
ERROR: Could not statfs: No such file or directory
- /etc/apt/apt.conf.d/80-btrfs-snapshot 파일을 제거하고, 리부팅하십시오.
롤백이 되지 않음
External links
- Official website
- I Can't Believe This is Butter! A tour of btrfs on YouTube – a conference presentation by Avi Miller, an Oracle engineer
- Btrfs: Working with multiple devices – LWN.net, December 2013, by Jonathan Corbet
- Marc's Linux Btrfs posts – detailed insights into various Btrfs features
- Btrfs overview, LinuxCon 2014, by Marc Merlin
- File System Evangelist and Thought Leader: An Interview with Valerie Aurora, Linux Magazine, 14 July 2009, by Jeffrey B. Layton
- 페도라 매거진 기사
댓글
댓글 쓰기