Featured image of post Linux перешёл в Read-only: диагностика и восстановление ext4

Linux перешёл в Read-only: диагностика и восстановление ext4

Восстановление Linux системы, после Read-only file system

Ошибка:

1
Read-only file system

не всегда означает, что сам диск физически стал доступен только для чтения.

При проблемах с I/O, storage или журналом ext4 файловая система может сама перейти в режим read-only, чтобы не продолжать запись в аварийном состоянии.

В моём случае это произошло сразу на нескольких серверах после проблем на уровне VMware/storage.

При этом ситуация была интересной:

  • SSH продолжал работать;
  • PostgreSQL был active (running);
  • использующие базу сервисы в основном продолжали отвечать;
  • некоторые системные службы уже начинали падать;
  • переставали писаться логи;
  • apt возвращал Read-only file system.

В этом гайде разберём, как последовательно понять, на каком уровне возник read-only, и безопасно восстановить файловую систему.

Важно: если причиной являются продолжающиеся проблемы со storage, сначала нужно стабилизировать нижележащую инфраструктуру. Запускать fsck на системе, которая всё ещё получает I/O errors, смысла мало и в целом опасно.

Также не запускайте fsck на смонтированной файловой системе с активной записью.

Как выглядит проблема

Например, приложение пытается создать файл:

1
touch /var/log/test

и получает:

1
touch: cannot touch '/var/log/test': Read-only file system

Или ошибка появляется при работе apt:

1
Read-only file system

Первое, что нужно понять:

Какая именно файловая система стала read-only?

Проверяем точки монтирования

Для общей картины:

1
findmnt

Для конкретного каталога:

1
findmnt /var/log

Например:

1
2
TARGET   SOURCE     FSTYPE OPTIONS
/var/log /dev/sdc1  ext4   ro,relatime

Здесь главное:

1
ro

Файловая система смонтирована только для чтения.

То же самое можно проверить для /opt:

1
findmnt /opt

и для корня:

1
findmnt /

Получаем например:

1
2
TARGET SOURCE                       FSTYPE OPTIONS
/      /dev/mapper/ubuntu--vg-root ext4   ro,relatime

Команда для просмотра дисков, файловых систем и точек монтирования:

1
lsblk -f

Для текущей проблемы лучше всего выполнить:

1
lsblk -o NAME,RO,SIZE,FSTYPE,MOUNTPOINTS

Получаем:

1
2
3
NAME   RO SIZE FSTYPE MOUNTPOINTS
sdc     0 100G
└─sdc1  0 100G ext4   /var/log

Диск или файловая система?

Нужно понять что ушло в RO. Диск или ФС.

Цепочка выглядит так:

1
Диск -> Раздел / LVM -> Файловая система ext4 -> Точки монтирования

Если файловая система, то будет так:

1
2
Disk         -> writable
ext4         -> read-only

Проверяем Диск

1
lsblk -o NAME,RO,SIZE,FSTYPE,MOUNTPOINTS

Где:

1
RO = 0

означает, что сам диск в норме не помечен как read-only.

Также проблему с диском можно отделить командой:

1
blockdev --getro /dev/sdc

Если получаем:

1
0

Понимаем, что диск в пордяке и ищем причину по которой файловая система решила запретить запись.

Смотрим dmesg

При любых проблемах с оборудованием одно из первых мест куда смотреть, это в лог ядра.

Фильтруем пайпами, чтобы не читать всё подряд:

1
dmesg -T | grep -Ei 'EXT4|JBD2|I/O error|Buffer I/O|read-only|abort'

Или можно использовать journalctl:

1
journalctl -k

При проблемах с журналом ext4 может решить, что дальнейшая запись небезопасна, и перейти в read-only.

Упрощённо на схеме:

Почему ext4 вообще уходит в RO?

ext4 - это журналируемая файловая система. Если во время изменения данных происходят серьёзные ошибки записи/чтения, то журнал больше нельзя писать, поэтому файловая система переходит в RO.

По сути логика следующая:
Я не уверен, что могу безопасно писать дальше -> лучше остановить запись чем продолжить повреждать данные

Поэтому сам факт перехода в ro не говорит, что Linux “сломал диск”. Наоборот, Linux пытается ограничить последствия уже произошедшей аварии.

Можно ли просто сделать remount в rw?

Первая очевидная идея:

1
mount -o remount,rw /opt

Иногда это работает. Например, если причина была временной, исчезла и файловая система не имеет серьёзных ошибок. Но при повреждении журнала можно получить, как было у меня:

1
cannot remount /dev/sdc1 read-write, is write-protected

или новые ошибки в dmesg.

Если ext4 сама ушла в read-only после ошибок чтения/записи, то бесконечно возвращать её в rw такое себе.

Нужно понять, почему она туда ушла.

Проверяем, не продолжаются ли I/O ошибки

Перед восстановлением нужно убедиться, что проблема на уровне ниже отсутсвует.

Проверяем свежие сообщения:

1
journalctl -kf

Если продолжают сыпаться ошибки по диску, то сначала нужно разбираться с диском или гипервизором.

Определяем, какие процессы используют файловую систему

У меня каждый диск отдельно монтируется в директорию, например opt:

1
/opt

перед размонтированием нужно понять, какая программа использует этот раздел.

1
lsof +f -- /opt

Если там находятся данные какого-то сервиса, его нужно остановить. У меня была PostgreSQL:

1
systemctl stop postgresql

Важный момент с PostgreSQL

В моём случае на /opt находился непосредственно PGDATA.

При этом:

1
systemctl status postgresql

показывал:

1
active (running)

К базе можно было подключиться и выполнять запросы. На первый взгляд можно решить, что сервис PostgreSQL здоров.

Процесс продолжает:

  • читать данные
  • использовать page cache
  • работать с уже открытыми файлами
  • обслуживать операции, которым прямо сейчас не понадобилась новая запись.

Но проблмеы начнутся, когда БД понадобятся:

  • WAL
  • изменения таблиц
  • служебные файлы
  • обновление метаданных.

Поэтому база не сможет нормально работать на RO ФС продолжительное время. Состояние systemd показывает состояние процесса, а не всей инфры под ним.

Размонтируем отдельную файловую систему

Остановил базу, убил зависимости. Далее восстанавливаю:

1
umount /opt

Проверяем:

1
findmnt /opt

Если вывода нет, значит файловая система больше не смонтирована.

Проверяем ext4 через fsck

Когда filesystem размонтирована, можно запускать проверку. Например:

1
fsck.ext4 -f /dev/sdb1

Какие ошибки может найти fsck

После аварийной записи можно увидеть, например:

1
2
3
4
Free blocks count wrong
Free inodes count wrong
Inode was part of the orphaned inode list
extent tree could be shorter

или другие несоответствия.

fsck предложит исправить найденные проблемы.

Не копируйте /dev/sdb1 из этого гайда. На вашем сервере диски будут другими.

Монтируем файловую систему обратно

После успешного завершения fsck:

1
mount /opt

Проверяю:

1
findmnt /opt

Вижу:

1
2
TARGET SOURCE    FSTYPE OPTIONS
/opt   /dev/sdb1 ext4   rw,relatime

Запускаем сервисы обратно

Файловая система восстановлена, запускаем базу обратно:

1
systemctl start postgresql

Проверяем:

1
systemctl status postgresql

Проверяем остальные файловые системы

Два раздела я починил таким образом на нескольких серверах. Пробегаюсь по остальным командой:

1
findmnt -o TARGET,SOURCE,FSTYPE,OPTIONS

И на части серверов вижу, что корень тоже пострадал.

1
2
3
/         - ro
/opt      - rw
/var/log  - rw

Если в read-only ушёл корень /

С /opt всё относительно понятно:

1
остановить сервисы -> umount -> fsck -> mount

С / этот подход не работает. Нельзя на обычной загруженной системе просто выполнить размонтирование. Корень используется самой операционной системой. Поэтому rootFS нужно проверять в состоянии, когда она не используется как обычный смонтированный rw root.

Это означает, что сервак нужно перезагружать и выбирать режим:

  • recovery mode
  • initramfs

После перезагрузки появляется:

1
(initramfs)

Выглядит неприятно, особенно если это ПРОД сервак, но такое поведение как раз защищает систему от загрузки поверх файловой системы с обнаруженными ошибками.

Определяем диск с корневой ФС и восстанавливаем

1
findmnt /

Получаю:

1
2
TARGET SOURCE                       FSTYPE OPTIONS
/      /dev/mapper/ubuntu--vg-root ext4   ro,relatime

Запускаю fsck на проблменом разделе

1
fsck.ext4 -f /dev/mapper/ubuntu--vg-ubuntu--lv

Путь зависит от вашей конфигурации.

Не запускайте fsck.ext4 по целому диску, LVM PV или устройству наугад. Сначала определите слой, на котором действительно находится ext4.

Во время проверки можно увидеть:

1
2
Inodes that were part of a corrupted orphan linked list found.
Inode 7105 was part of the orphaned inode list. FIXED.

И вопросы типа:

1
Fix<y>?

После завершения проверки можно:

1
exit

и подождать перезагрузку.

После перезагрузки

Первым делом проверяем root:

1
findmnt /

Ожидаем:

1
rw

Затем остальные mount points:

1
findmnt

Проверяем, не продолжаются ли ошибки:

1
dmesg -T | grep -Ei 'EXT4|JBD2|I/O error|Buffer I/O|read-only|abort'

После этого проверяем сервисы и приложения.

Есть соблазн любой ценой избежать перезагрузки сервера. Но в случае с повреждённой rootFS перезагрузка или переход в режим восстановления может быть как раз наиболее правильным вариантом.

Что проверять в VMware

Если Linux VM получила ошибки по I/O, то со стороны Linux важно определить время появления первых ошибок.

Логами ядра:

1
dmesg -T

После этого сопоставляем время с событиями инфраструктуры.

Проверяем:

  • события виртуальной машины в vCenter;
  • свободное место;
  • storage latency;
  • ошибки ESXi;
  • vmkernel.log;
  • состояние storage paths;
  • ошибки storage controller;
  • проблемы физических дисков;

Команды в одном месте

Проверить mount points

1
findmnt /opt

Посмотреть диски и флаг RO

1
lsblk -f

Проверить Диски

1
blockdev --getro /dev/sdc

0 означает, что диск может читать/писать.

Поиск ошибок по файловой системе

1
journalctl -k -b

Найти процессы, использующие точку монтирования

1
lsof +f -- /opt

Размонтировать filesystem

1
umount /opt

Проверить ext4

1
fsck.ext4 -f /dev/sdb1

Смонтировать обратно

1
mount /opt

Проверить режим монтирования

1
findmnt /opt

Что важно не делать

Не запускать проверку, не зная что с файловой системой:

1
fsck -y /dev/sda

Не выполнять fsck на активно смонтированной и используемой ext4.

Восстановить такую систему обычно несложно.

Гораздо важнее соблюдать правильную последовательность и не пытаться решать проблему раньше, чем станет понятна причина.

И да, иногда read-only означает не то, что Linux сломался.

Иногда, это ОС вовремя поняла, что ломается что-то на уровне ниже, и просто перестала писать данные, пока ситуация не стала ещё хуже.

Информацию можно использовать в свободном доступе, с указанием ссылки на сайт
Telegram GitHub YouTube