Удаление большого дерева с низким приоритетом: ionice + nice

ionice -c3 nice -n19 rm -rf /путь/к/дереву

Команда удаляет дерево так, чтобы не отбирать диск и процессор у остальных — удаление получает ввод-вывод только когда диск никому больше не нужен. Она не замедляет удаление на свободном диске и не бережёт больной или горячий диск: это вежливость к соседям, а не ограничитель скорости. Проверено на kot и stakan 2026-09-19 (ядро 7.2, mq-deadline).

Часть

Что делает

ionice -c3

Класс ввода-вывода idle: запросы процесса к диску обслуживаются, только когда нет запросов классов best-effort и realtime (обычные процессы — best-effort). Запрос, прождавший дольше prio_aging_expire (у нас 10 000 мс), всё же пройдёт — полного голодания нет.

nice -n19

Минимальный приоритет CPU. Для rm почти не важен (упирается в диск), но и не вредит; нужен, когда вместо rm стоит что-то считающее (du по миллионам файлов, tar, rsync со сжатием).

rm -rf

Собственно удаление. Префиксы наследуются дочерними процессами, поэтому так же оборачивают du, find, rsync, tar.

Когда помогает

  • Диск общий и медленный, на нём одновременно работают другие: SMR storage1 на kot (сборки, агентские grep, syncthing) — без префикса большой rm/du даёт task … blocked for more than 61 seconds у соседей.

  • Фоновая уборка на сервере, где отклик важнее скорости уборки.

Когда НЕ помогает

Important

  • Нагрев и износ не уменьшаются. Если диском в этот момент никто не пользуется, idle-процесс идёт на полной скорости. 2026-09-19 мой «щадящий» du с этим префиксом по /shared на stakan догрел больной sdc до 63 °C — торможения не было, потому что конкурентов не было.

  • Отложенная запись не покрывается. Приоритет действует на чтения и синхронные записи процесса. rm лишь помечает метаданные в памяти, а на диск их пишут потоки ядра (у btrfs — транзакция btrfs-transaction, под LUKS ещё и dmcrypt_write) со своим приоритетом. На холодном кэше основная нагрузка rm — чтение каталогов и inode, оно под приоритет попадает.

  • Зависит от планировщика диска. Классы I/O понимают bfq и mq-deadline (с ядра 5.14; признак — файл prio_aging_expire). При none (типично для NVMe) ionice не действует.

Проверить, что приоритет вообще работает:

cat /sys/block/sdX/queue/scheduler            # активный — в [скобках]
ls  /sys/block/sdX/queue/iosched/prio_aging_expire   # есть → mq-deadline с приоритетами
ionice -p <pid>                               # idle — класс применился

Состояние на 2026-09-19: kot sda и nvme0n1, stakan sda/sdb/sdc — mq-deadline c prio_aging_expire=10000; модуль bfq в ядре есть (CONFIG_IOSCHED_BFQ=m), не включён.

Если нужно именно ограничить скорость (горячий или умирающий диск)

Надёжный способ — задать темп самому: удалять порциями с паузой и смотреть температуру между порциями:

DISK=/dev/disk/by-id/ata-…            # не /dev/sdX
for d in /путь/к/дереву/*/; do
    t=$(smartctl -A "$DISK" | awk '/Temperature_Celsius/{print $10}')
    [ "${t:-0}" -ge 62 ] && { echo "стоп: $t °C"; break; }
    ionice -c3 nice -n19 rm -rf -- "$d"
    sleep 60
done

Ограничение через cgroup v2 (systemd-run --scope -p IOReadIOPSMax="/dev/sdX 200" -p IOWriteIOPSMax="/dev/sdX 200" rm -rf …) технически доступно (контроллер io включён, CONFIG_BLK_DEV_THROTTLING=y), но на btrfs поверх LUKS не проверено: записи уходят из потоков ядра и к cgroup процесса могут не относиться — не полагаться, пока не замерено iostat -x рядом.

See also

  • it.tool.btrfs (btrfs.rst) — почему удаление на btrfs заканчивается не в момент выхода rm.

  • host.stakan (stakan.rst) — диск sdc с FAILING_NOW.

Log

2026-09-19

Страница заведена. Поводом была чистка /shared на stakan. Команду сначала записали в рекомендации как «щадящую диск» — неверно: она уступает соседям, но не тормозит на свободном диске. Затем была обратная ошибка — «на mq-deadline ionice не действует»: тоже неверно для ядер ≥5.14, проверено по prio_aging_expire на kot и stakan. В тело вошли только проверенные на машинах утверждения; cgroup-ограничение помечено как непроверенное.