SSD의 Btrfs, "장치에 남은 공간이 없습니다"; `fstrim` 및 `btrfs Balance`를 사용하여 catch-22; 회복하는 방법?

SSD의 Btrfs, "장치에 남은 공간이 없습니다"; `fstrim` 및 `btrfs Balance`를 사용하여 catch-22; 회복하는 방법?

내 쿠분투(아래에 마운트된)의 루트 파일 시스템 /은 Btrfs입니다. -o discard마운트 옵션으로 사용하지 않습니다 . 이는 다음을 의미합니다.fstrim요청 시 실행해야 합니다..

과거에는 다음과 같은 문제가 발생했습니다.btrfs, 남은 디스크 공간이 없습니다. 나는 fstrim -v /공간이 거의 잘리지 않는 것을 발견했습니다. 내 솔루션은 btrfs balance start /이전에 실행하는 것이 었습니다 fstrim. 이것이 요점이다내 대답은 거기에 있어.

오늘은 다릅니다. 어쩌면 유지 관리가 너무 늦었을 수도 있습니다. 일어나는 일은 다음과 같습니다.

# fstrim -v /
/: 24 KiB (24576 bytes) trimmed
# btrfs balance start /
ERROR: error during balancing '/': No space left on device

몇 개의 하위 볼륨(스냅샷)을 삭제했지만 btrfs subvolume delete …도움이 되지 않았습니다. 세부 사항은 잘 기억나지 않지만 이전에는 현재처럼 24KiB가 아닌 최소한 몇 MiB를 btrfs balance …미리 다듬었기 때문에 실행할 수 있었던 것 같습니다 . 이제는 상대방이 먼저 작업을 수행한 경우에만 작동하는 catch fstrim-22 상황처럼 보입니다 .fstrimbtrfs balance

참고로 다음은 실제로 공간이 충분하다는 것을 보여주는 몇 가지 통계입니다.

# df -h /
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1       112G   43G   68G  39% /

# btrfs fi df /
Data, single: total=108.73GiB, used=41.00GiB
System, single: total=64.00MiB, used=16.00KiB
Metadata, single: total=3.00GiB, used=1.02GiB
GlobalReserve, single: total=352.00MiB, used=0.00B

참고 아직 정상적인 작동 중에는 "장치에 남은 공간이 없습니다"가 없습니다. 나는 Btrfs가 이미 가져온 청크 안에 새로운 쓰기를 계속해서 맞추고 있다고 생각합니다. 그러나 과거에는 에서 "남은 공간이 없습니다..."를 눌렀다 가 및 apt-get upgrade으로 복구했습니다 . 이 일이 언제 다시 나에게 닥칠지 모르겠습니다. 중요한 일을 할 때 "남은 공간이 없어..."가 생기기 전에 유지 관리를 하고 싶습니다.btrfs balancefstrim

이 상황에서 회복 fstrim하고 btrfs balance서로를 차단하지 않는 방법은 무엇입니까?실행 중인 시스템 내에서 이 문제를 해결할 수 있나요?

사실 저는 이미 이 문제를 해결했습니다. 제 대답은 아래와 같습니다. 질문은 나중에 참조하기위한 것입니다. 다른 솔루션을 추가해 보세요.


추가 정보:

$ uname -a
Linux foobar 4.4.0-78-generic #99-Ubuntu SMP […] x86_64 x86_64 x86_64 GNU/Linux

$ cat /etc/issue
Ubuntu 16.04.3 LTS \n \l

# dpkg -l | grep btrfs
ii  btrfs-tools  4.4-1ubuntu1  amd64  Checksumming Copy on Write Filesystem utilities

답변1

예, 실행 중인 시스템 내에서 복구할 수 있습니다. 내 원래 접근 방식은 아래에 있습니다. 그러나 Zan Lynx의 의견 덕분에 더 쉬운 방법을 찾았습니다.

내 개선된 접근 방식

언급된 댓글은 다음과 같습니다.

또는 미리 생각하고 있다면 btrfs에 최대 장치보다 적게 사용하도록 지시할 수 있습니다.btrfs filesystem resize

(원래 접근 방식과 비교할 때, 별도의 장치를 추가하는 것보다 의도적으로 이 특정 장치에 여유 공간을 확보하고 거기에서 파일 시스템을 확장하는 것이 요점입니다. 이는 쉽지 않을 수 있습니다.)

좋은 소식: 테스트 결과 미리 생각할 필요가 없다는 것이 나타났습니다! "남은 공간이 없습니다..."라는 오류가 발생 하더라도 btrfs balance start /공간만 있으면(즉, 모든 파일과 메타데이터가 새 크기에 맞는 경우) 파일 시스템을 축소할 수 있습니다. 이는 다음과 같은 해결책으로 이어집니다.

# btrfs filesystem resize -100M /  # shrink a little...
Resize '/' of '-100M'
# btrfs filesystem resize +100M /  # ... and expand back
Resize '/' of '+100M'
# btrfs balance start /            # should work now
Done, had to relocate 88 out of 88 chunks
# fstrim -v /
/: 67,8 GiB (72753831936 bytes) trimmed

내 원래 접근 방식

이것이 당신이 해야 할 일입니다(자세한 설명은 아래에 있음):

  1. Btrfs 파일 시스템에 추가 장치를 추가합니다.
  2. btrfs balance start …
  3. fstrim …
  4. Btrfs 파일 시스템에서 추가 장치를 삭제합니다.
  5. btrfs balance start …
  6. fstrim …

비결은 Btrfs 파일 시스템에 추가 장치를 추가하여 btrfs balance …추가 공간을 확보하는 것입니다. 장치는 /dev/sdb또는 와 같을 수 있습니다 /dev/sdb3. 이 예에서는 HDD에 일반 1GiB 파일을 사용하고 있습니다(매우 중요:파일이 확장하려는 Btrfs 파일 시스템에 속하지 않는지 다시 확인합니다! 치명적일 수 있습니다.) 나는 RAM에 있는 파일(예: /dev/shm/)이 괜찮을 것이라고 생각합니다.

# tmpf=/mnt/hdd/tempfile   # if this file exists, it will be overwritten!
# truncate -s 1G "$tmpf"
# extra=$(losetup -f --show "$tmpf")

지금은 뭔가와 $extra같습니다 /dev/loop0.

# btrfs device add "$extra" /

지금은 OS를 재부팅하면 안 됩니다. 그렇게 하면 루트 파일 시스템의 일부가 부족할 것입니다 . /dev/loop*왜냐하면 . /mnt/hdd/tempfile일반 장치(또는 파티션)를 추가 장치로 사용하는 경우 btrfs device scan부팅 중에 이를 감지하므로 이는 문제가 되지 않습니다.

# btrfs balance start /

제 경우에는 tempfile스파스 파일입니다. 다른 콘솔을 실행했는데 watch ls -hls /mnt/hdd/tempfile(거의) 전체 크기로 커지는 것을 확인했습니다. 이렇게 하면 일부 Btrfs 청크가 SSD에서 언제 이동되는지 알 수 있습니다. 의심스러우면 btrfs ballance …끝내겠습니다. 하지만 btrfs balance cancel /시간을 절약하기 위해 호출합니다 . 이제 메인 콘솔로 돌아가 보겠습니다.

참고: 아래 첫 번째 줄은 btrfs balance start /중단된 위 명령에서 나온 것입니다.

balance canceled by user
# fstrim -v /
/: 26,7 GiB (28696862720 bytes) trimmed

fstrim전보다 훨씬 더 잘랐다. 더 이상 추가 장치가 필요하지 않습니다.

# btrfs device delete "$extra" /   # may take a while
# btrfs balance start /            # should work now
Done, had to relocate 88 out of 88 chunks
# fstrim -v /
/: 67,8 GiB (72753831936 bytes) trimmed

그리고 이것이다. 이제 청소할 시간입니다.

# losetup -d "$extra"
# rm "$tmpf"

관련 정보