Удаление очень большого файла без зависания веб-сервера

11

На моем веб-сервере (работает Apache, Linux CentOS) есть очень большой файл журнала ( 50 Гбайт ). Этот веб-сервер имеет несколько веб-сервисов в производстве.

Когда я попытался удалить файл журнала, веб-сервер не получил ответа около 10 секунд. (Время обслуживания.)

rm -f monthly.log

Есть ли способ удалить этот большой файл без зависания apache?

Джинбом Хо
источник

Ответы:

23

Сначала поверните его logrotate, используя конфигурацию, подобную этой:

/path/to/the/log {
    missingok
    notifempty
    sharedscripts
    daily   
    rotate 7
    postrotate
        /sbin/service httpd reload > /dev/null 2>/dev/null || true
    endscript
    compress
}

затем создайте задание cron в полночь, чтобы удалить повернутый файл:

30 2 * * * nice -n 19 ionice -c2 -n7 rm -f /path/to/the/log/file.1
кванты
источник
Можете ли вы объяснить, что это значит / делает?
Mowwwalker
1
Вы «замечаете» и «очищаете» удаление. Ницца, вероятно, использовалась для предотвращения перегрузки процессора, но самым важным здесь является ionice, где вы фактически указываете планировщику удалить файл с более низким приоритетом. -c для класса, где 1 в режиме реального времени, 2 в нормальном режиме и 3 в режиме ожидания. В классе 2 у вас есть от 0 до 7 (IRRC), где 7 является самым низким. Если это все еще создает проблемы, запустите его с 'ionice -c3', и все должно быть в порядке.
Голаны
5

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

 truncate -s 0  monthly.log && rm -f monthly.log

Как и было рекомендовано квантами, сначала необходимо войти в систему.

Даниил Т.
источник
Чем truncateотличается от >?
Кодзиро
хм хороший вопрос. Результат тот же, но у меня нет ответа, как они отличаются в реализации.
Даниил Т.
Чем truncateпроще в использовании, sudoчем >. Это также проще с find -exec.
kubanczyk
3
echo "0" > monthly.log && rm -f monthly.log
Амит Бияни
источник
3
Вы можете просто >logfileне нуждаться в эхе
user9517
3

Я бы обрезать / обнулить файл с : > /path/to/monthly.logоперацией. Затем, возможно, перезапустите процесс Apache и настройте ротацию журналов, чтобы предотвратить это в будущем ...

Это часто возникает, хотя:

Смотрите: есть ли способ удалить файл 100 ГБ в Linux без перегрузки ввода-вывода / загрузки?

В Unix, как лучше всего уменьшить размер массивного файла журнала, в который активно записывается?

На сервере Linux не хватает места

ewwhite
источник
Нет необходимости в :. Вы можете просто сделать> /path/to/monthly.log
Кодзиро
Я знаю, что это так noop, но это имеет больше смысла с точки зрения обучения.
ewwhite
... но потом какой-то будущий инструктор должен исправить это заблуждение. О, хорошо, я думаю, это безопасность работы.
Кодзиро
Не true > /path/to/monthly.logсделал бы то же самое, и это менее архаично тогда :?
Стефан Ласевски,
Вероятно, правда ...
Ewwhite
3

Если вам не нужны данные, обрежьте их, используя / dev / null:

cat /dev/null > monthly.log

Веб-сервер будет продолжать записывать данные в файл после усечения, что исключает необходимость перезапуска веб-сервера (в отличие от того rm monthly.log, который удаляет файл).

После урегулирования непосредственного кризиса, рассмотрите logrotation, как предложил Quanta. Вы не хотите, чтобы это повторилось. Обратите внимание, что лог-файлы Apache уже повернуты по умолчанию в CentOS

Также рассмотрите возможность отправки логов через syslog ( /usr/bin/loggerнапример, используя). Журналы, которые создаются с использованием syslog, также обычно уже настроены.

Стефан Ласевский
источник
5
Вы можете просто >logfileне нуждаться в кошке
user9517
2

Если вы используете файловую систему ext3, рассмотрите возможность перехода на ext4.

Ext3 может медленно удалять большие файлы, поскольку в нем хранится местоположение каждого отдельного блока 4 КБ: файл размером 50 ГБ (50 * 1024 ^ 3 байта) занимает 13107200 блоков, каждый из которых записывается в таблицу индексов как 32-битный номер блока. , в общей сложности 50MiB бухгалтерских данных только для отслеживания того, где содержимое файла находится на диске. Этот большой список блоков может быть разбросан по многим косвенным блокам , которые должны быть обновлены при удалении файла. Поиск диска для доступа ко всем этим косвенным блокам, вероятно, и является причиной задержки.

Ext4, с другой стороны, распределяет файлы в «экстентах» до 128 МБ. Этот файл размером 50 ГБ может быть записан в таблице inode, используя только 400 записей экстентов, а не 13107200 отдельных номеров блоков, что значительно сокращает объем дискового ввода-вывода, необходимый при удалении файла.

Обратите внимание, что если вы конвертируете существующую файловую систему ext3 на месте в ext4, новые файлы будут распределяться с использованием экстентов, но существующие файлы будут по-прежнему использовать списки блокировки. Вы можете использовать chattr +eкоманду для перераспределения существующего файла с использованием экстентов; с точки зрения производительности это сопоставимо с созданием копии файла и последующим удалением оригинала.

Wyzard
источник
1

Это сводится к проблеме производительности файловой системы. На этот SO вопрос есть интересный ответ, но это скорее зависит от того, какую файловую систему вы используете. Я использовал XFS при создании файловой системы для хранения сотен мультигигабайтных файлов MPEG2 для MythTV, потому что в то время производительность удаления XFS была намного выше, чем у ext3. Вещи, возможно, значительно изменились за прошедшие годы.

Мне действительно нравится ответ @ кванты. Разделение файла на более мелкие части приведет к более быстрому удалению.

Тим Поттер
источник
1

Проблема, я полагаю, заключается в том, что вы удаляете файл от привилегированного пользователя, который имеет больший приоритет для операций с диском, чем пользователь веб-сервера apache. Независимо от того, каким способом вы решите удалить файл журнала (rm -f или усечь по>), вы должны уменьшить приоритет операций с дисками до минимума:

  ionice -c3 rm -f filename.log
Андрей Михальцов
источник