====== BTRFS Maintenance scripts ======
===== Defragment =====
From [[https://helmundwalter.de/blog/btrfs-finding-and-fixing-highly-fragmented-files/|BTRFS fragmentation can hurt the performance of your System]]
Find the most fragmented files on your System:
find / -xdev -type f| xargs filefrag 2>/dev/null | sed 's/^\(.*\): \([0-9]\+\) extent.*/\2 \1/' | awk -F ' ' '$1 > 500' | sort -n -r | head -30
You should review this list. If there is something with 10000+ extends, it is a candidate to be flagged as nodatacow. In my case, I have discovered that the fail2ban sqlite database was using 170k extends which is a lot!
find / -xdev -type f| xargs filefrag 2>/dev/null | sed 's/^\(.*\): \([0-9]\+\) extent.*/\2 \1/' | awk -F ' ' '$1 > 500' | cut -f ' ' -f2 2>/dev/null | xargs -r btrfs -v fi defrag -f -czstd
===== Headline =====
#!/bin/bash
[[ ! -d $1 ]] && { echo Please pass mountpoint as first argument >&2 ;
exit 1 ; }
while read x i x g x x l x p
do
volName[i]=$p
done < <(btrfs subvolume list $1)
while read g r e
do
[[ -z $name ]] && echo -e "subvol\tqgroup\ttotal\tunshared"
group=${g##*/}
[[ ! -z ${volName[group]} ]] && name=${volName[group]} || name='(unknown)'
echo $name $g `numfmt --to=iec $r` `numfmt --to=iec $e`
done < <(btrfs qgroup show --raw $1 | tail -n+3) | column -t
===== remove dangling QGroups =====
To solve ''After deleting a subvolume, you must manually delete the associated qgroup.'' mentioned here: [[https://btrfs.wiki.kernel.org/index.php/Quota_support#Known_issues]]
#!/bin/bash
[[ ! -d $1 ]] && { echo Please pass mountpoint as first argument >&2 ;
exit 1 ; }
while read x i x g x x l x p
do
volName[i]=$p
done < <(btrfs subvolume list $1)
while read g r e
do
group=${g##*/}
[[ -z ${volName[group]} ]] && [[ $r -eq 0 ]] && [[ $e -eq 0 ]] && echo $g $r $e && btrfs qgroup destroy $g $1
#name=${volName[group]} || name='(unknown)'
#echo $name $g `numfmt --to=iec $r` `numfmt --to=iec $e`
done < <(btrfs qgroup show --raw $1 | tail -n+3) | column -t
@daily /usr/local/bin/btrfsQGroupClean.sh
===== periodic scrub =====
From arch linux ''btrfs-progs''
[Unit]
Description=Btrfs scrub on %f
[Service]
Nice=19
IOSchedulingClass=idle
ExecStart=/bin/btrfs scrub start -B %f
[Unit]
Description=Monthly Btrfs scrub on %f
[Timer]
OnCalendar=monthly
AccuracySec=1d
Persistent=true
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable btrfs-scrub@-.timer
systemctl start btrfs-scrub@-.timer # to enable for /
systemctl enable btrfs-scrub@home.timer # to enable for /home
systemctl start btrfs-scrub@home.timer # to enable for /home