当前位置:首页>Linux>Linux Btrfs文件系统之

Linux Btrfs文件系统之

  • 2026-10-11 06:13:34
Linux Btrfs文件系统之

字数 1530,阅读大约需 8 分钟

Btrfs 的压缩、配额、属性是日常运维必会。本篇讲清三件套的配置、调优和踩坑。

一、压缩(Compression)

1.1 压缩算法对比

算法
速度
压缩比
适用
zstd
(推荐)
快
高
通用
zstd:1
 ~ zstd:15
可调
越慢越高
灵活
lzo
极快
中
旧版本(现已被 zstd 取代)
zlib
慢
高
极少见
no
 / none
-
-
关闭

经验:zstd:3 是默认值(不显式写时用)。

1.2 启用压缩

# 挂载时启用
$ mount -o compress=zstd /dev/sdb /mnt

# remount

$ mount -o remount,compress=zstd /mnt

1.3 性能影响

误解:压缩 = CPU 开销 = 慢

事实:

  • • zstd 在现代 CPU 上极快(超过磁盘 IO 速度)
  • • 实际经常提升顺序 IO 性能(写更少)
  • • 随机读:CPU 解压开销可见,但有 ARC 后影响小

1.4 已有数据怎么办?

挂载压缩选项后:

  • • 新写入的数据会被压缩
  • • 已有数据不自动重压

重压已存在数据:

# defragment + compress(会重写所有文件!)
$ btrfs filesystem defragment -r -czstd /mnt
#                              ^^^^-zstd 压缩

#                              ^^-r 递归

#                              ^-c 压缩

警告:这个操作会写时复制所有文件,要确保空间够。

1.5 各场景推荐

场景
推荐
通用
zstd
(默认 zstd:3)
高频写
zstd:1
(最快)
冷数据
zstd:9
 或 zstd:15(最高压缩比)
视频/媒体(已压缩)
no
(没必要)
数据库
no
(数据已压缩,浪费时间)
容器镜像
zstd
(高压缩比)

二、Quota(配额)

Btrfs 配额通过 qgroup 实现。

2.1 启用 qgroup

# 启用
$ btrfs quota enable /mnt

# 看是否启用

$ btrfs qgroup show /mnt

2.2 配额类型

# 限制"引用"(含子卷)
$ btrfs qgroup limit 5G /mnt/home

# 限制"独占"(不含子卷)

$ btrfs qgroup limit -e 5G /mnt/home

2.3 实战

# 1. 启用
$ btrfs quota enable /mnt

# 2. 给每个用户限制

$ btrfs qgroup limit 10G /mnt/home/alice
$ btrfs qgroup limit 20G /mnt/home/bob

# 3. 查看

$ btrfs qgroup show -reF /mnt
qgroupid    rfer    excl    max_rfer    max_excl
--------  ----    ----    ---------    --------
0/5         16KiB   16KiB    none        none
0/300      1.2GiB  1.2GiB   10.00GiB    10.00GiB   ← alice
0/301      800MiB  800MiB   20.00GiB    20.00GiB   ← bob

2.4 qgroup 的性能问题

重要警告:Btrfs 的 qgroup 有严重的性能陷阱。

症状:

  • • qgroup 多时,写性能下降 30~50%
  • • 子卷多时更明显
  • • Linux 内核 5.10 之前严重

解决方案:

  • • 用 Linux 内核 ≥ 5.10
  • • qgroup 数量控制在 < 100
  • • 监控:btrfs qgroup show 看延迟

生产建议:

  • • 个人桌面:qgroup 可用
  • • 服务器:谨慎使用
  • • NAS:可考虑 ZFS(quota 更稳)

三、属性(Properties)

Btrfs 有 对象属性(object-level properties),比 ZFS 少一些,但够用。

3.1 挂载选项

主要属性都是挂载选项:

# /etc/fstab
UUID=...  /  btrfs  subvol=@,compress=zstd,noatime,autodefrag  0 0

3.2 常用挂载选项

选项
含义
推荐
compress=algo
启用压缩
zstd
noatime
不更新访问时间
✅ 性能
nodatacow
关闭 COW(写密集)
数据库
autodefrag
自动碎片整理
频繁写
subvol=path
挂载指定 subvolume
标准
subvolid=N
挂载指定 ID
稳定
device=path
多设备文件系统的特定设备
多盘
degraded
允许降级挂载(缺盘)
应急
ro
只读
恢复
nospace_cache
缓存时不预留空间
大文件
clear_cache
挂载时清空缓存
性能
commit=N
每 N 秒 commit
性能/安全
space_cache=v2
空间缓存 v2
必加
usebackuproot
用 backup root
损坏修复
recovery
尝试自动恢复
损坏修复
usrquota
启用用户配额
类似 qgroup
grpquota
启用组配额
类似 qgroup

3.3 完整推荐配置

# 根分区
UUID=...  /  btrfs  subvol=@,compress=zstd,noatime,space_cache=v2,commit=120  0 0

# 数据

UUID=...  /data  btrfs  subvol=data,compress=zstd:3,noatime,space_cache=v2  0 0

# 数据库(关 COW,关压缩)

UUID=...  /var/lib/postgresql  btrfs  subvol=db,nodatacow,noatime  0 0

四、CoW 与 nodatacow

4.1 CoW 控制的两种方式

方式
范围
推荐
nodatacow 挂载
整个 subvolume
✅ 数据库
chattr +C
单个文件/目录
✅ 灵活

4.2 nodatacow

# 挂载时
$ mount -o nodatacow /dev/sdb /mnt/db

# 整 subvolume 不 COW(写密集性能 ↑)

# 代价:失去快照、scrub 能力

4.3 chattr +C(更灵活)

# 关闭文件的 COW
$ chattr +C /mnt/db/postgresql.conf

# 看 COW 状态

$ lsattr /mnt/db/postgresql.conf
----C----- /mnt/db/postgresql.conf
#         ^ C = nocow


# 恢复 COW

$ chattr -C /mnt/db/postgresql.conf

使用场景:

  • • 数据库文件(MySQL InnoDB、PostgreSQL)
  • • 虚拟机磁盘镜像
  • • 大型文件 / 视频

五、defragment(碎片整理)

5.1 何时整理

  • • 大文件频繁删除后产生碎片
  • • 性能下降时
  • • 一般不用(COW 自然会有碎片)

5.2 整理命令

# 整理单个文件
$ btrfs filesystem defragment /mnt/data/bigfile

# 整理整个目录

$ btrfs filesystem defragment -r /mnt/data

# 整理 + 压缩

$ btrfs filesystem defragment -r -czstd /mnt/data

注意:defragment 实际上是写时复制(把碎片文件重新连续写)。会消耗空间。

5.3 autodefrag(自动模式)

# 挂载时启用
$ mount -o autodefrag /dev/sdb /mnt
# 或

$ mount -o remount,autodefrag /mnt

不建议对所有数据启用(可能影响性能)。一般用于 reflink/稀疏文件 场景。

六、scrub(自愈)

6.1 什么是 scrub

  • • 遍历所有 extent,校验 checksum
  • • 不一致 → 用副本修复
  • • ZFS 也有,但叫法不同

6.2 命令

# 启动 scrub
$ btrfs scrub start /mnt

# 看状态

$ btrfs scrub status /mnt
scrub status for /mnt
        scrub started at Mon Jan 15 03:00:00 2024
        scrub running for 02:30:00
        ...
        data_extents_scanned:    1234567
        tree_extents_scanned:     12345
        data_extents_skipped:        0
        data_bytes_scanned:        5.0GiB
        tree_bytes_scanned:        1.2GiB
        read_errors:                  0
        verify_errors:               0
        csum_errors:                 0
        ...

# 取消

$ btrfs scrub cancel /mnt

6.3 scrub 频率

场景
频率
家用
每月
服务器
每周
大容量
每月(限速)

七、设备使用情况

# 看文件系统使用
$ btrfs filesystem usage /mnt
Overall:
    Device size:                  10.00GiB
    Device allocated:              1.50GiB
    Device unallocated:            8.50GiB
    Used:                          1.20GiB
    Free (estimated):              7.80GiB (min: 7.80GiB)
    Data ratio:                       1.00
    Metadata ratio:                   2.00
    Global reserve:               3.50MiB (used: 0)
    ...

# 看分配

$ btrfs filesystem df /mnt

八、生成代(Generation)

# 看 generation
$ btrfs subvolume show /mnt/data
        Generation:    12

# generation 是 Btrfs 的"事务号"

# 每次 commit 递增

# 损坏时用于推断

九、本篇小结

特性
推荐
备注
压缩zstd
 或 zstd:3
性能/容量平衡
配额
慎用
Linux 5.10 前慢
nodatacow
数据库
用 chattr +C
autodefrag
极少用
性能陷阱
scrub
每月
类似 ZFS
mount 选项noatime,space_cache=v2
性能基础

最佳实践:

  • • 挂载时启用 compress=zstd(几乎免费)
  • • 数据库单独子卷 + nodatacow
  • • 定期 scrub(早期发现损坏)
  • • 不滥用 qgroup(性能陷阱)

最新文章

随机文章