Вот моя проблема, видимая в диаграмме Мунина:
Количество используемых / открытых инодов "внезапно" постоянно увеличивается.
Есть ли способ определить, какой процесс сохраняет самые открытые в данный момент inode? Я использовал подход https://unix.stackexchange.com/questions/117093/find-where-inodes-are-being-used и нашел и очистил некоторые папки с почтой и журналами, от которых я мог избавиться ... Тем не менее, если inodes ОТКРЫТЫ, должен быть какой-то процесс, поддерживающий их использование, верно? Это может не обязательно быть папка с наибольшим количеством файлов, из-за которой происходит увеличение - или я ошибаюсь?
Поэтому я хотел бы увидеть, кто держит их открытыми, а затем отслеживать использование, чтобы увидеть, откуда исходит увеличение.
Обновить
На основе сценария Эндрю я создал его версию, которая также показывает имя процесса. Поскольку у меня работает несколько процессов nginx / apache, которые могут возродиться, я хотел бы увидеть результаты по имени процесса.
for dir in /proc/*/fd;
do
echo -n "$dir ";
pid=`expr "$dir" : '\/proc\/\(.*\)\/.*'`; # extract the pid
pname=`ps -p $pid -o comm=`; # grab process name
echo -n "$pname ";
ls $dir 2>/dev/null | wc -l;
done | sort -n -k 3
Пример вывода:
/proc/4612/fd sshd 49
/proc/46470/fd node 60
/proc/5655/fd nginx 66
/proc/6656/fd nginx 76
/proc/7654/fd nginx 81
/proc/8578/fd dovecot 107
/proc/9657/fd nginx 117
/proc/3495/fd java 146
/proc/4785/fd mysqld 382
Таким образом, следующий тест будет регистрировать распределение с течением времени, чтобы увидеть, какие изменения и как они соотносятся с количеством / proc / sys / fs / inode-nr, которое упомянул Морган.
Год спустя...
Прошло какое-то время, вот и новый график
И угадайте, в конце сентября произошла замена неисправного привода. Похоже, весь беспорядок возник из-за ошибки диска. Тем не менее, скрипты все равно пригодятся!
Подсчитайте количество записей в каждом /proc/[PID]/fd
каталог. Это даст вам количество файловых дескрипторов, открытых каждым процессом. Хотя для перечисления всех процессов потребуется время, отсутствие процессов, которые запускаются или останавливаются во время вашего подсчета, не должно быть проблемой, поскольку вы ищете долгоживущий процесс с большим количеством открытых файловых дескрипторов.
Что-то вроде этого:
for dir in /proc/*/fd;
do
echo -n "$dir "; #need a space to get real columns for the sort
ls $dir 2>/dev/null | wc -l;
done | sort -n -k 2
В последних строках вывода будет показан каталог / proc / [PID] / fd с количеством дескрипторов открытых файлов для каждого процесса. Виновные процессы должны быть внизу.
Обратите внимание, что каждая запись в / proc / [PID] / fd технически является дескриптором файла, а не отдельным открытым индексным дескриптором, каждый отдельный открытый индексный дескриптор должен иметь как минимум один отдельный файловый дескриптор в каталоге / proc / [PID] / fd где-нибудь.
Я думаю, что проблема здесь отчасти в том, что munin подразумевает под "открытыми индексными дескрипторами". В моей стандартной установке munin есть два плагина для получения количества выделенных inodes:
"/ etc / munin / plugins / open_inodes", который получает метрику inode из "/ proc / sys / fs / inode-nr"
и
"/ etc / munin / plugins / df_inode", который получает метрику из вывода "df -i".
Эти числа отражают количество существующих файлов, а НЕ количество файлов / индексов, используемых всеми процессами в системе.
Например, этот скрипт создает десять файлов, и после его завершения мы можем увидеть увеличение распределения inode как в "df -i", так и в inode-nr.
#!/usr/bin/python
f0 = open("foo0", "w")
f1 = open("foo1", "w")
f2 = open("foo2", "w")
f3 = open("foo3", "w")
f4 = open("foo4", "w")
f5 = open("foo5", "w")
f6 = open("foo6", "w")
f7 = open("foo7", "w")
f8 = open("foo8", "w")
f9 = open("foo9", "w")
Однако, если я настрою это, чтобы предотвратить завершение программы (а файлы уже существуют) ... файлы остаются «открытыми» и «используемыми» процессом.
#!/usr/bin/python
import time
f0 = open("foo0", "w")
f1 = open("foo1", "w")
f2 = open("foo2", "w")
f3 = open("foo3", "w")
f4 = open("foo4", "w")
f5 = open("foo5", "w")
f6 = open("foo6", "w")
f7 = open("foo7", "w")
f8 = open("foo8", "w")
f9 = open("foo9", "w")
time.sleep(600)
что мы видим в выводе "lsof -p PID"
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
...
open_some 6602 morgan 3w REG 254,1 0 262198 /home/morgan/src/foo0
open_some 6602 morgan 4w REG 254,1 0 262273 /home/morgan/src/foo1
open_some 6602 morgan 5w REG 254,1 0 262284 /home/morgan/src/foo2
open_some 6602 morgan 6w REG 254,1 0 262287 /home/morgan/src/foo3
open_some 6602 morgan 7w REG 254,1 0 262289 /home/morgan/src/foo4
open_some 6602 morgan 8w REG 254,1 0 262301 /home/morgan/src/foo5
open_some 6602 morgan 9w REG 254,1 0 262302 /home/morgan/src/foo6
open_some 6602 morgan 10w REG 254,1 0 262309 /home/morgan/src/foo7
open_some 6602 morgan 11w REG 254,1 0 262457 /home/morgan/src/foo8
open_some 6602 morgan 12w REG 254,1 0 268672 /home/morgan/src/foo9
Но я могу запускать этот сценарий «открыть и оставаться открытым» столько раз, сколько захочу, и он не изменит числа в df / inode-nr.
Короче говоря, munin сообщает количество выделенных inodes, а не количество всех inodes, используемых всеми процессами. Если после того, как вы удалили кучу файлов, график munin не отражает свободные inodes, это может быть просто потому, что график не был повторно сгенерирован или, в показанном примере, шкала времени графика слишком длинная, чтобы отразить неожиданное изменение.
Возможно, если бы это было из-за файлов журнала, inodes не были выпущены, когда вы их очистили. Попробуйте либо перезапустить службы, в которых были открыты эти файлы журналов, либо вы сможете по-настоящему стереть файлы журналов без перезапуска, выполнив echo "" > logfilenamegoeshere
после того, как вы создадите резервную копию любых данных, которые хотите сохранить из журнала.
Нашел утилиту "fatrace" для "трассировки доступа к файлам" от автора Сообщение блога доступно для скачивания Вот. Он отобразит все процессы, обращающиеся к любым файлам в системе.