UNIX: df и du – разные значения

Автор: | 18/12/2013
 

unix-logoДля примера возьмём такой вывод:

# du -sh /var/
2G    /var/
# df -h /var/
Filesystem    Size    Used   Avail Capacity  Mounted on
/dev/da0p5    7.9G      5G    2.3G    68%    /var

Обычно (хотя не всегда), разница возникает из-за файлов, которые были удалены – но в момент удаления были “захвачены” каким-то процессом.

Что бы выяснить это – можно выполнить команду lsof:

# lsof -a +L1 / | grep var | grep httpd
httpd      8739     root   14w   REG    8,3        0     0  1835539 /var/run/wsgi.8739.16.1.lock (deleted)
httpd     21612   apache   14w   REG    8,3        0     0  1835539 /var/run/wsgi.8739.16.1.lock (deleted)
httpd     21613   apache   14w   REG    8,3        0     0  1835539 /var/run/wsgi.8739.16.1.lock (deleted)
httpd     21614   apache   14w   REG    8,3        0     0  1835539 /var/run/wsgi.8739.16.1.lock (deleted)

Или так:

# lsof +D /var/ +L1 | less

И найти файлы, для которых в колонке NLINK значение будет 0. К сожалению, этот метод корректно работает не во всех системах, например – FreeBSD так и не отобразила “удалённые” файлы.

Если попытаться открыть файл – будет сообщено об ошибке доступа к нему:

# stat /var/run/wsgi.8739.16.1.lock
stat: cannot stat `/var/run/wsgi.8739.16.1.lock': No such file or directory

Разница заключается в том, что du – выполняет запрос непосредственно к каждому найденному файлу в разделе, а df – к файловой системе.

При удалении файла, который в этот момент был “занят” процессом – его имя удаляется, но inode – остаётся в файловой системе до тех пор, пока не завершится процесс, который “держит” этот файл.

Соответственно, что бы “освободить” уже удалённые файлы – необходимо перезапустить процесс, который этот файл держит.

Ещё один пример – были удалены и пересозданы файлы логов, но сам NGINX при этом не перезапускался. Проверим разницу в свободном/занятом месте раздела /var до и после перезапуска сервера  NGINX:

# df -h /var/
Filesystem    Size    Used   Avail Capacity  Mounted on
/dev/da0p5    7.9G      5G    2.3G    68%    /var
# du -sh /var/
2G    /var/
# service nginx restart
Performing sanity check on nginx configuration:
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
Stopping nginx.
Waiting for PIDS: 1541.
Performing sanity check on nginx configuration:
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
Starting nginx.
# du -sh /var/
2G    /var/
# df -h /var/
Filesystem    Size    Used   Avail Capacity  Mounted on
/dev/da0p5    7.9G      2G    5.3G    27%    /var