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

У меня есть система с / на tmpfs. Большинство / подкаталогов имеют встроенные aufs, перекрывающие корневую файловую систему для чтения и записи с базовой файловой системой только для чтения (система загружается с носителя только для чтения). Ранее я использовал unionfs вместо aufs. Он работал правильно до недавнего времени, tmpfs начал заполняться. Я не уверен, что вызвало изменение. Это может быть изменение unionfs to 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

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

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

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

# uname -rm
3.4.6 i686

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

2 ответа

Решение

Я сам разгадал тайну с помощью помощника aufs, Junjiro Okajima.

Первым шагом, чтобы отладить проблему, было воспроизвести ее контролируемым образом. Мне потребовалось некоторое время (теперь я удивляюсь, почему так много), чтобы выяснить, что проблема возникает, когда файлы записываются и удаляются через 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-users. Я быстро получил первые ответы. Один из JR Okajima помог мне объяснить, что происходит с пропавшими блоками tmpfs.

Это был действительно удаленный файл. Это не было показано lsof или где-нибудь в /proc/<pid>/* поскольку файл не был открыт или преобразован каким-либо процессом пользовательского пространства. Файл, 'xino file', является внешней таблицей преобразования номеров инодов 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

Однако информацию о его размере и размерах других специальных auf-файлов можно прочитать из 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-space на производстве… но я многому научился.

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

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

НТН

Другие вопросы по тегам