Назад | Перейти на главную страницу

tmpfs заполняется, хотя почти не используется. Как мне отладить это

У меня система с / на tmpfs. В большинстве подкаталогов / есть смонтированные aufs, перекрывающие корневую файловую систему для чтения и записи с базовой файловой системой, доступной только для чтения (система загружается с носителя, доступного только для чтения). Раньше я использовал unionfs вместо aufs. Он работал нормально до недавнего времени, когда tmpfs начали заполняться. Я не уверен, что вызвало изменение. Это может быть изменение unionfs на aufs, обновление ядра или некоторые изменения в системе и способах доступа к файловым системам.

В любом случае, похоже, что это tmpfs как-то не так.

Хотя система не должна много писать в tmpfs, довольно много из них израсходовано:

# df -m /
Filesystem     1M-blocks  Used Available Use% Mounted on
tmpfs                200    50       151  25% /

пока:

# du -smx /
2       /

Это моя тестовая система, которая практически ничего не делает. В производственной системе что-то изнашивается, когда использование быстро достигает более 90% и система дает сбой.

Я подозреваю, что это удаленные файлы, которые все еще открыты, но:

# lsof | grep deleted

ничего не показывает.

Другая идея заключалась в том, что некоторые файлы в / замаскированы файловой системой, установленной поверх него, поэтому я попробовал это:

# mount --bind / /mnt
# du -sm /mnt
2       /mnt

Тем не менее, никаких следов потери 48 МБ.

Как я могу узнать, чем занята моя файловая система tmpfs?

Системная информация:

# uname -rm
3.4.6 i686

Обновление: пробовал ядра 3.4.17 и 3.6.6 - без изменений.

Я сам разгадал загадку с помощью сопровождающего aufs, Джунджиро Окадзима.

Первым шагом к устранению проблемы было ее управляемое воспроизведение. Мне потребовалось некоторое время (теперь мне интересно, почему так много), чтобы выяснить, что проблема возникает, когда файлы записываются и удаляются через aufs.

Воспроизведение проблемы

создать точки монтирования:

# cd /tmp
# mkdir rw
# mkdir mnt

смонтируйте tmpfs:

# mount -t tmpfs none /tmp/rw

смонтируйте aufs, перекрыв / usr с / tmp / rw:

# mount -t aufs  -n -o "br:/tmp/rw:/usr" none "/tmp/mnt"

теперь я могу видеть содержимое / usr в / tmp / mnt:

# ls /tmp/mnt
bin  games  include  lib  lib64  local  sbin  share  src

что меня интересует, так это используемое / доступное пространство в tmpfs ниже:

# du -sk /tmp/rw   
0   /tmp/rw
# df /tmp/rw  
Filesystem     1K-blocks  Used Available Use% Mounted on
none             1031128    24   1031104   1% /tmp/rw

В / tmp / rw файлов нет, но выделено 24 блока. Все еще не большая проблема.

Я могу записать файл в aufs, он будет храниться в tmpfs в / tmp / rw:

# dd if=/dev/zero of=/tmp/mnt/test bs=1024 count=100
100+0 records in
100+0 records out
102400 bytes (102 kB) copied, 0.000343903 s, 298 MB/s
# du -sk /tmp/rw
100 /tmp/rw
# df /tmp/rw
Filesystem     1K-blocks  Used Available Use% Mounted on
none             1031128   128   1031000   1% /tmp/rw

Обратите внимание, как изменилась статистика использования. du показать добавленные 100 КБ, как и ожидалось, но значение «Использовано» в df выпуск увеличился на 104 блока.

Когда я удаляю файл:

# du -sk /tmp/rw   
0   /tmp/rw
# df /tmp/rw
Filesystem     1K-blocks  Used Available Use% Mounted on
none             1031128    28   1031100   1% /tmp/rw

Четыре блока потеряны.

Когда я повторяю dd и rm команды несколько раз получаю:

# df /tmp/rw                                         
Filesystem     1K-blocks  Used Available Use% Mounted on
none             1031128    36   1031092   1% /tmp/rw

Все больше и больше блоков tmpfs пропадали, и я не знал, где…

Где я сделал то же самое - dd и rm непосредственно на / tmp / rw так ничего не потерялось. И после размонтирования aufs потерянное место на tmpfs было восстановлено. Так что, по крайней мере, я знал, что виноваты aufs, а не tmpfs.

Что происходило

Зная, в чем виноват, я описал свою проблему в списке рассылки aufs-users. Я быстро получил первые ответы. Один из Дж. Р. Окадзима помог мне объяснить, что происходит с отсутствующими блоками tmpfs.

Это действительно был удаленный файл. Не было показано lsof или где-нибудь в /proc/<pid>/* так как файл не был открыт или подключен каким-либо процессом пользовательского пространства. Файл, «файл xino», представляет собой внешнюю таблицу преобразования номеров inode aufs и используется внутренне модулем aufs ядра.

Путь к файлу можно прочитать из sysfs:

# cat /sys/fs/aufs/si_*/xi_path         
/tmp/rw/.aufs.xino

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

# ls -l /tmp/rw/.aufs.xino
ls: cannot access /tmp/rw/.aufs.xino: No such file or directory

Хотя информацию о его размере и размерах других специальных файлов aufs можно прочитать в debugfs:

# for f in /sys/kernel/debug/aufs/si_8c8d888a/* ; do echo -n "$f: " ; cat $f ; done 
/sys/kernel/debug/aufs/si_8c8d888a/xi0: 1, 32x4096 132416
/sys/kernel/debug/aufs/si_8c8d888a/xi1: 1, 24x4096 626868
/sys/kernel/debug/aufs/si_8c8d888a/xib: 8x4096 4096
/sys/kernel/debug/aufs/si_8c8d888a/xigen: 8x4096 88

Подробности описаны в страница руководства aufs.

Решение

Файл xino можно обрезать вручную:

# mount -o remount,itrunc_xino=0 /tmp/mnt

Автоматическое усечение файла xino можно запросить с помощью параметра trunc_xino при монтировании aufs:

# mount -t aufs -n -o "br:/tmp/rw:/usr,trunc_xino" none "/tmp/mnt"

Я до сих пор не знаю, как это повлияет на производительность файловой системы и действительно ли это решит мои проблемы с нехваткой места в tmpfs на производстве… но я многому научился.

Я видел, как это происходило, когда файлы были удалены, но процессы все еще удерживали файл, что означало, что пространство не было освобождено, пока процесс не был перезапущен. Я видел это с файлами журнала Apache. Казалось, что он продолжил запись в теперь удаленный файл журнала, и пространство не было очищено, пока он не был перезапущен.

Чтобы узнать, какой процесс может удерживать удаленные файлы, вы можете попробовать перезапустить каждый процесс и посмотреть, очищает ли это место. Если да, то вы нашли своего виновника.

HTH