Btrfs修复
看到这篇文章,大概都是看到这条错误开始的
wrong fs type, bad option, bad superblock on /dev/sdx, missing codepage or helper program, or other error.
因为nas电源可能不太够,在插入硬盘的时候导致正在读写的主硬盘掉盘了,重启后群辉报错,存储空间只读,ssh上去重新挂载了下是可以挂读写的,因为不可能吧数据全部拷贝出来格式化,因为网上几乎0资料,摸索到凌晨3点,下面记录一下修复操作
ssh上去,换成root权限来执行
sudo su
检查一下错误日志
dmesg | grep BTRFS
发现有以下错误
btrfs error (device dm-2): qgroup generation mismatch, marked as inconsistent
卸载分区
df -h
umount -fl /dev/mapper/cachedev_2
进行分区修复,需要一会
btrfs check --repair /dev/mapper/cachedev_2
如果上面那条秒退出,那么可以试试下面这两条再去试试上一条
btrfs check --clear-space-cache v1 /dev/mapper/cachedev_2
btrfs check --clear-space-cache v2 /dev/mapper/cachedev_2
修超级快,不需要修会自动跳过的
btrfs rescue super-recover -v /dev/mapper/cachedev_2
计算校验,需要很长时间,没有输出,处理完会退出
btrfs scrub start -Bf /dev/mapper/cachedev_2
可以开一个新终端用这条命令检查计算校验的进度
btrfs scrub status /dev/mapper/cachedev_2
最后,清错误记录
btrfs rescue zero-log /dev/mapper/cachedev_2
清错误计数器
btrfs dev stats -z /dev/mapper/cachedev_0
重启nas
明明都没有错误了,还是只读?不要慌
点开存储管理器,点报警的存储空间右边三个点,转换为读/写
然后无论再怎么重启都能正常读写了
2022年3月9日,Pve的Btrfs突然提示空间不足,df -h显示还有4G可用,重启了一下,就显示可用0了,实际上总空间减去已用还有4G
Filesystem Size Used Available Use% Mounted on
/dev/sdb3 29.3G 25.9G 0 100% /mnt/sdb3
看了一下 btrfs fi df /mnt/sdb3 发现Metadata要满了,那么怎么扩展Btrfs的Metadata呢?
尝试了一下 btrfs bal start /mnt/sdb3 进行清理优化,提示空间不足,无法进行
建一个5G的文件在另一个硬盘,并用 losetup 把它挂成一个虚拟硬盘
dd if=/dev/zero of=/mnt/sda1/tmpBtrfs.img bs=1G count=5
losetup -v -f /mnt/sda1/tmpBtrfs.img
把这个虚拟盘加到当前有问题的存储空间中
btrfs device add /dev/loop1 /mnt/sdb3
如果无法操作显示只读,那么需要这样清掉缓存
btrfs check --clear-space-cache v1 /dev/sdb3
btrfs check --clear-space-cache v2 /dev/sdb3
这时候去 df -h显示已经正常了,只要进行一下清理优化,Metdata就会自动扩展(不需要跑完全程,跑一会Ctrl + C掐掉再去看其实已经增加了)
btrfs bal start /mnt/sdb3
这时候这5G虚拟盘就已经完成他的使命了,把它卸掉
btrfs device delete /dev/loop1 /mnt/sdb3
losetup -d /mnt/sda1/tmpBtrfs.img
rm /mnt/sda1/tmpBtrfs.img
用btrfs组raid的时候有时莫名奇妙就挂不上去了,明明盘都在线却显示
BTRFS warning : devid 2 uuid 43870ae8-44c9-4f4d-9463-0917b94bc581 is missing
这时候只要运行一下 blkid
显示一下所有分区的uuid,就能正常挂载了,咩咩也不知道是什么原理
这是一些额外的内容
压缩
挂载时-o
加上参数compress=zlib
手动压缩(空间回收 清理)
btrfs filesystem defragment -r -v -czstd 挂载点
子卷
# 创建
btrfs subvolume create 路径
# 删除
btrfs subvolume delete 路径
# 显示所有
btrfs subvolume show
# 显示单个
btrfs subvolume show 路径
# 挂载成压缩的
mount -o compress=zlib,subvol=子卷名字 主盘的设备 路径
快照
需要先创建一个子卷来存储快照,比如/opt
是一个btrfs分区的挂载点
btrfs subvol create /opt/.snapshots
照个快照(只读的,去掉-r
可以变成读写的)
btrfs subvol snapshot -r /opt /opt/.snapshots/`date +%Y-%m-%d`
删除快照
btrfs subvol delete /opt/.snapshots/快照的那个目录
备份到其他地方(只支持只读快照)这里使用zstd快速压缩
btrfs send /opt/.snapshots/快照的那个目录 | zstd -T0 -9 -c > 保存路径
还原
zstd -d 备份文件 -c | btrfs receive 保存路径
增量拷贝
btrfs send -p /opt/.snapshots/旧快照 /opt/.snapshots/新快照 | btrfs receive 保存路径
空间限制
有个问题,就是程序拿不到这个限制后的剩余空间,而是拿到全部的
# 开启功能
btrfs quota enable 路径
# 设置限制最大占10G 解除限制设置成none
btrfs qgroup limit 10G 路径
raid
使用btrfs,可以实现多盘raid0并且空间利用率100%,当然了数据火葬场(
直接多盘格式化的话就像是jbod那样连在一起的
可以看这个视频,也可以看下面的内容 https://www.bilibili.com/video/BV1g14y1h7B3
先给大盘sdg分区,第一个分区从2048到+按第二块盘sdh的block数-1,剩下的分一个区
格式化
mkfs.btrfs -L wxr0 -m raid0 -d raid0 /dev/sdh /dev/sdg1
给他挂载到一个目录,然后
btrfs device add /dev/sdg2 挂载点
这样就得到了一个空间利用率100%的raid0,前面的部分是两个盘的raid0,后面连接着大盘剩下的空间
简单点说,就相当于在两块盘上做了一个两盘raid0和一个单盘raid1,再把这两做个jbod,但这个过程无需系统内核软raid参与,如你所见,视频是在openwrt上进行这种神仙操作的
作为缓存盘,速度和容量优先,要说安全性,btrfs有crc校验能告诉你哪些文件坏了
恢复被误删但还打开着的文件
lsof | grep deleted | awk '!a[$2]++{print("deleted /proc/"$2"/fd"); system("ls -l /proc/"$2"/fd")}' | grep deleted
deleted开头的行则为上方文件指针所在路径
说人话就是这样恢复 cp 要恢复的文件上面deleted开头右侧的路径
/要恢复的文件箭头左侧的那一个数字
保存的文件名
比如
deleted /proc/673140/fd
lrwx------ 1 root root 64 Apr 27 09:22 35 -> /var/lib/pve/local-btrfs/images/103/vm-103-disk-0/disk.raw (deleted)
恢复到/var/lib/pve/local-btrfs/images/103/vm-103-disk-0/disk.raw1
cp /proc/673140/fd/35 /var/lib/pve/local-btrfs/images/103/vm-103-disk-0/disk.raw1
关于DUP
目前默认btrfs会将元数据(Metadata记录了文件存在哪里)和文件系统数据(System)使用DUP存储,哪怕你是单盘,DUP会在同一块盘上存储两份一样的数据,以保证在一份坏的时候还可以读取零一份,这会比raid1更加自由和安全,但是会影响性能,或是让本就拮据的空间更加雪上加霜,可以在格式化时指定为single模式(只存一份),在使用btrfs作为pve的虚拟硬盘空间的时候,建议使用single
mkfs.btrfs -m single -d single -L 卷标 硬盘或分区的设备路径
其中,当前文件系统的配置可以这样查看(还能查看uuid用于写fstab)
btrfs filesystem show
btrfs filesystem usage 挂载点
调整大小
是的,分区不只是可以放大,还能缩小
当然了,gparted
确实可以实现调整大小(并且和命令一样)但是他不会维护你的分区uuid,会导致系统盘直接无法启动,所以需要用gisk
操作一下
先换成root
,开始操作,我这需要操作的分区为/dev/sdb
的第4个分区,也就是/dev/sdb4
,请举一反三
gdisk /dev/sdb
# 查看分区
p
i
# 输入你希望修改的分区号,并记录输出的Partition unique GUID
4
# 退出
q
此时可以用gparted
去调分区大小,或者按下面操作,要是出错,那就是缩太小了,调大点即可
# 先把分区挂在到一个地方
mkdir sparkle
mount /dev/sdb4 sparkle
# 调整btrfs大小到5100M 可以带单位,最大就写max
btrfs filesystem resize 5100M sparkle
# 卸载,调整分区大小
umount /dev/sdb4
gdisk /dev/sdb
# 记住你要修改的分区的Start和Code
p
i
# 为了避免你刚才没有记录Partition unique GUID,现在可以记录一下
4
d
# 输入你希望修改的分区号
4
n
# 输入你希望修改的分区号
4
# 输入你刚记录的Start
1187840
# 输入分区大小,为了保险可以比btrfs的大小稍微大一点, 扩大到最大直接回车就行
+5200M
# 输入你刚记录的Code
8300
x
c
# 输入你希望修改的分区号
4
# 输入你之前记录的Partition unique GUID
B0B70132-B2DA-0941-9E7E-F57B87585945
m
# 这一步会写入磁盘,如果前面做错了可以直接按Ctrl+C退出
w
y
如果你用gparted调好了,那就按照下面的步骤来
# 卸载分区
umount /dev/sdb4
gdisk /dev/sdb
x
c
# 输入你希望修改的分区号
4
# 输入你之前记录的Partition unique GUID
B0B70132-B2DA-0941-9E7E-F57B87585945
m
# 这一步会写入磁盘,如果前面做错了可以直接按Ctrl+C退出
w
y
这样就调整完毕了
另外提醒一下,如果你dd到另一个盘,要调大,需要在gdisk里先执行x
,e
,m
来把分区表调整到实际大小,然后再执行分区大小调整,再执行btrfs调整,请举一反三
检查并修复文件损坏
如果因为意外断电或是其他原因导致文件系统读写出现io错误或是其他的问题,并且在硬盘smart报告正常没有坏道的情况下,可以使用校验对损坏的部分进行修复,如果smart报告有坏道,建议是先全盘dump或是备份能复制出来的文件
比如在 dmesg
时出现像这样的错误
[7773336.920021] BTRFS warning (device nvme0n1p3): csum failed root 256 ino 358 off 60783452160 csum 0x6a963d6c expected csum 0x9af01a40 mirror 1
[7773336.920029] BTRFS error (device nvme0n1p3): bdev /dev/nvme0n1p3 errs: wr 0, rd 0, flush 0, corrupt 11518, gen 0
[7773336.920031] BTRFS warning (device nvme0n1p3): direct IO failed ino 358 op 0x0 offset 0xe26f9e000 len 4096 err no 10
首先先将分区挂载,这个检查的过程可以在线进行
# 开始检查
btrfs scrub start 挂载点位置
# 查看检查的进度
btrfs scrub status 挂载点位置
这是一条用于PVE服务器的sn770 2T,写入478T,虽然smart没有报告任何错误,但看起来已有大量无法修复的错误
UUID: 47102369-5280-47ee-8f3e-62030bf039e6
Scrub started: Mon Aug 26 15:05:50 2024
Status: finished
Duration: 0:08:57
Total to scrub: 1.23TiB
Rate: 2.15GiB/s
Error summary: csum=9609
Corrected: 0
Uncorrectable: 9609
Unverified: 0
如果咩咩的文章对你有帮助,您可以 请我喝牛奶
黑裙吗?正常白裙怎么会电源不够
求联系 。。这个方法行不通啊。机器现在只读。但是硬盘那边没有警告。也没又给修复按钮
已成功联系,另外各位不要尝试给虚拟机的群晖虚拟硬盘扩容,它不支持这样直接扩大硬盘的
你现在咋样了。我6.2系统,我通过他视频里面强制读写代码,我发现,可以读写了,但是不允许共享文件夹搬存储池,此时提示只读。但是lun可以通过backup对外备份了。只读的情况下会直接告知完成。我还在测试中。如果成功了,我也去发个视频,并且好好感谢up主
先修好了,再去点读写那才是真正的读写,你点了读写你倒是把它修好啊
求救,我的在运行btrfs scrub start -Bf/dev/mapper/cachedev_0时没反应,只显示了一堆
btrfs scrub start: invalid option -- '/'
usage: btrfs scrub start [-BdqrRf] [-c ioprio_class -n ioprio_classdata] |
Start a new scrub. If a scrub is already running, the new one fails.
-B do not background
-d stats per device (-B only)
-q be quiet
-r read only mode
-R raw print mode, print full data instead of summary
-c set ioprio class (see ionice(1) manpage)
-n set ioprio classdata (see ionice(1) manpage)
-f force starting new scrub even if a scrub is already running
this is useful when scrub stats record file is damaged
求联系
这问题也太明显了吧,你少了一个空格
-Bf /dev
我是直接复制的,你能联系我的邮箱吗,我返回去看运行记录时,在repair那一步就出现了enabling repair mode
Couldn't open file system的情况,想请教一下
我也是返回 Couldn't open file system,后来怎么样了