2024-08-05 23:54:27 +00:00
|
|
|
Scrub is a validation pass over all filesystem data and metadata that detects
|
|
|
|
data checksum errors, basic super block errors, basic metadata block header errors,
|
|
|
|
and disk read errors.
|
|
|
|
|
|
|
|
Scrub is done on a per-device base, if a device is specified to `btrfs scrub`, then
|
|
|
|
only that device will be scrubbed. Although btrfs will also try to read other device
|
|
|
|
to find a good copy, if the mirror on that specified device failed to be read or pass
|
|
|
|
verification.
|
|
|
|
|
|
|
|
If a path of btrfs is specified to `btrfs scrub`, btrfs will scrub all devices
|
|
|
|
in parallel.
|
|
|
|
|
|
|
|
On filesystems that use replicated block group profiles (e.g. raid1), read-write
|
|
|
|
scrub will also automatically repair any damage by copying verified good data
|
|
|
|
from one of the other replicas.
|
|
|
|
|
|
|
|
Such automatic repair is also carried out when reading metadata or data from a
|
|
|
|
read-write mounted btrfs.
|
|
|
|
|
|
|
|
.. warning::
|
|
|
|
Setting the ``No_COW`` (``chattr +C``) attribute on a file implicitly enables
|
|
|
|
``nodatasum``. This means that while metadata for these files continues to
|
|
|
|
be validated and corrected by scrub, the actual file data is not.
|
|
|
|
|
|
|
|
Furthermore, btrfs does not currently mark missing or failed disks as
|
|
|
|
unreliable, so will continue to load-balance reads to potentially damaged
|
|
|
|
replicas. This is not a problem normally because damage is detected by
|
|
|
|
checksum validation, but because ``No_COW`` files are
|
|
|
|
not protected by checksum, btrfs has no idea which mirror is good thus it can
|
|
|
|
return the bad contents to the user space tool.
|
|
|
|
|
|
|
|
Detecting and recovering from such failure requires manual intervention.
|
|
|
|
|
|
|
|
Notably, `systemd sets +C on journals by default <https://github.com/systemd/systemd/commit/11689d2a021d95a8447d938180e0962cd9439763>`_,
|
|
|
|
and `libvirt ≥ 6.6 sets +C on storage pool directories by default <https://www.libvirt.org/news.html#v6-6-0-2020-08-02>`_.
|
|
|
|
Other applications or distributions may also set +C to try to improve
|
|
|
|
performance.
|
2021-12-09 19:46:42 +00:00
|
|
|
|
|
|
|
.. note::
|
2024-08-05 23:54:27 +00:00
|
|
|
Scrub is not a filesystem checker (fsck). It can only detect filesystem damage
|
|
|
|
using the checksum validation, and it can only repair
|
|
|
|
filesystem damage by copying from other known good replicas.
|
|
|
|
|
|
|
|
:doc:`btrfs-check` performs more exhaustive checking and can sometimes be
|
|
|
|
used, with expert guidance, to rebuild certain corrupted filesystem structures
|
|
|
|
in the absence of any good replica.
|
2021-12-09 19:46:42 +00:00
|
|
|
|
|
|
|
The user is supposed to run it manually or via a periodic system service. The
|
2023-12-08 17:01:42 +00:00
|
|
|
recommended period is a month but it could be less. The estimated device bandwidth
|
|
|
|
utilization is about 80% on an idle filesystem.
|
2021-12-09 19:46:42 +00:00
|
|
|
|
2023-06-28 17:55:08 +00:00
|
|
|
The scrubbing status is recorded in :file:`/var/lib/btrfs/` in textual files named
|
2021-12-09 19:46:42 +00:00
|
|
|
*scrub.status.UUID* for a filesystem identified by the given UUID. (Progress
|
|
|
|
state is communicated through a named pipe in file *scrub.progress.UUID* in the
|
|
|
|
same directory.) The status file is updated every 5 seconds. A resumed scrub
|
|
|
|
will continue from the last saved position.
|
|
|
|
|
|
|
|
Scrub can be started only on a mounted filesystem, though it's possible to
|
2023-06-28 17:55:08 +00:00
|
|
|
scrub only a selected device. See :ref:`btrfs scrub start<man-scrub-start>` for more.
|
2023-12-08 17:01:42 +00:00
|
|
|
|
2024-02-13 17:07:26 +00:00
|
|
|
.. duplabel:: scrub-io-limiting
|
2023-12-08 17:01:42 +00:00
|
|
|
|
|
|
|
Bandwidth and IO limiting
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
.. note::
|
2024-02-16 08:37:55 +00:00
|
|
|
The :manref:`ionice(1)` may not be generally supported by all IO schedulers and
|
2023-12-08 17:01:42 +00:00
|
|
|
the options to :command:`btrfs scrub start` may not work as expected.
|
|
|
|
|
|
|
|
In the past when the `CFQ IO scheduler
|
|
|
|
<https://en.wikipedia.org/wiki/Completely_fair_queueing>`__ was generally used
|
2024-02-16 08:37:55 +00:00
|
|
|
the :manref:`ionice(1)` syscalls set the priority to *idle* so the IO would not
|
2023-12-08 17:01:42 +00:00
|
|
|
interfere with regular IO. Since the kernel 5.0 the CFQ is not available.
|
|
|
|
|
|
|
|
The IO scheduler known to support that is `BFQ
|
|
|
|
<https://docs.kernel.org/block/bfq-iosched.html>`__, but first read the
|
|
|
|
documentation before using it!
|
|
|
|
|
|
|
|
For other commonly used schedulers like `mq-deadline
|
|
|
|
<https://docs.kernel.org/block/blk-mq.html>`__ it's recommended to use
|
|
|
|
*cgroup2 IO controller* which could be managed by e.g. *systemd*
|
|
|
|
(documented in ``systemd.resource-control``). However, starting scrub like that
|
|
|
|
is not yet completely straightforward. The IO controller must know the physical
|
|
|
|
device of the filesystem and create a slice so all processes started from that
|
|
|
|
belong to the same accounting group.
|
|
|
|
|
|
|
|
.. code-block:: bash
|
|
|
|
|
2024-02-16 13:33:53 +00:00
|
|
|
$ systemd-run -p "IOReadBandwidthMax=/dev/sdx 10M" btrfs scrub start -B /
|
2023-12-08 17:01:42 +00:00
|
|
|
|
|
|
|
Since linux 5.14 it's possible to set the per-device bandwidth limits in a
|
|
|
|
BTRFS-specific way using files :file:`/sys/fs/btrfs/FSID/devinfo/DEVID/scrub_speed_max`.
|
|
|
|
This setting is not persistent, lasts until the filesystem is unmounted.
|
|
|
|
Currently set limits can be displayed by command :ref:`btrfs scrub
|
|
|
|
limit<man-scrub-limit>`.
|
|
|
|
|
|
|
|
.. code-block:: bash
|
|
|
|
|
|
|
|
$ echo 100m > /sys/fs/btrfs/9b5fd16e-1b64-4f9b-904a-74e74c0bbadc/devinfo/1/scrub_speed_max
|
|
|
|
$ btrfs scrub limit /
|
|
|
|
UUID: 9b5fd16e-1b64-4f9b-904a-74e74c0bbadc
|
|
|
|
Id Limit Path
|
|
|
|
-- --------- --------
|
|
|
|
1 100.00MiB /dev/sdx
|