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

Автор: | 12/18/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