У нас есть сервер Linux с файловой системой 4 ТБ, который используется для хранения репозиториев подрывной деятельности. Существует множество репозиториев, некоторые из которых используются уже несколько лет.
Изначально на диске было около 1 ТБ, но нам стало не хватать места и около года назад он увеличился до 4 ТБ. Теперь люди сообщают, что не могут вернуть файлы в свои репозитории. Сообщение об ошибке No space left on device
.
На диске свободно около 1,5 ТБ, а также сообщается о свободных индексных дескрипторах - но создать на нем новый файл невозможно. По-прежнему можно обновлять старые файлы, и периодически будут обновляться некоторые репозитории, но тот же репозиторий может выйти из строя при следующей попытке.
Проблема заключается в том, как XFS выделяет inodes. В отличие от большинства файловых систем, распределение происходит динамически по мере создания новых файлов. Однако, если вы не укажете иное, inodes ограничены 32-битными значениями, что означает, что они должны уместиться в пределах первого терабайта хранилища в файловой системе. Поэтому, если вы полностью заполнили этот первый терабайт, а затем увеличили диск, вы все равно не сможете создавать новые файлы, поскольку inodes не могут быть созданы в новом пространстве.
Одно из решений - перемонтировать файловую систему с опцией монтирования. inode64
. Однако некоторые приложения при этом будут вести себя странно (например, MySQL), и NFS будет очень запутан. Поэтому, если вы не уверены, что ваша система будет работать с этим вариантом, вы можете перейти к следующему варианту.
Второе решение - найти некоторые файлы, которые в настоящее время хранятся в первом терабайте, и переместить их в другую область файловой системы.
В нашем случае это было просто - файловая система использовалась годами, поэтому мы могли просто найти самые старые файлы и переместить их из файловой системы, а затем переместить обратно. Это было легко сделать с помощью find:
find /extra -mindepth 3 -maxdepth 3 -type d -mtime +730 -exec du -sh {} \; > /tmp/olddirs.txt
предоставил нам список, содержащий размер и имя каталога для всех каталогов ровно на 3 уровня ниже точки монтирования, которые были старше 2 лет. Затем мы могли бы отсортировать список, чтобы найти самые большие каталоги, и использовать mv
чтобы переместить их в другую файловую систему и обратно.
Если вы не можете просто пойти по возрасту, например когда много файлов было создано одновременно, вы все равно можете найти нужные файлы для перемещения, но это займет немного больше времени.
XFS имеет группы распределения (также известные как AGs), начиная с 0. Вы можете проверить размер блока и количество блоков каждой группы AG, чтобы определить, какие группы находятся в первом терабайте, используя xfs_info /path/to/mountpoint
. Или вы можете просто проверить несколько первых групп AG, чтобы увидеть, какие из них заполнены, а затем очистить их.
for ag in `seq 0 1 5`; do echo freespace in AG $ag; xfs_db -r -c "freesp -s -a $ag" /dev/CACHE/CACHE ; grep "total free"; done
Если общее количество свободного места в любой группе меньше 40, вы не сможете создавать в ней новые файлы.
Это требует проверки метаданных для каждого файла в файловой системе. Это займет длинный время ... Вот предложение:
find /extra -mindepth 3 -type f -exec xfs_bmap -v {} \; > /tmp/agfilelist.txt
Затем вы можете использовать grep для " 0 "
(это пробел, ноль и еще один пробел), чтобы найти все файлы на AG 0, grep для " 1 "
чтобы найти файлы на AG 1 и т. д. Начните с AG 0, удалите самые большие файлы (используя mv
не cp
!), а затем обратно. Повторяйте, пока у вас не будет достаточно свободного места.
Как только мы переместили достаточно файлов из / extra, а затем обратно, в AG 0 стало много места, и снова появилась возможность создавать новые файлы.