2012-04-04 3 views
5

У меня есть 8 миллионов файлов в моем/tmp, и мне нужно их удалить. На этом сервере также работает довольно важное приложение, и я не могу его перегрузить.Удалить огромное количество файлов

Я использую небольшой PHP скрипт:

<?php 
$dir = "/tmp"; 
$dh = opendir($dir); 
$i = 0; 
while (($file = readdir($dh)) !== false) { 
    $file = "$dir/$file"; 
    if (is_file($file) && (preg_match("/open/", $file))) { 
    unlink($file); 
    #echo $file; 
    if (!(++$i % 10000)) { 
     echo "$i files removed\n"; 
    } 
    } 
} 
?> 

но это делает мое приложение недостижимым, даже с: $ ionice -c 3 PHP ./tmp_files_killer.php $ хороший -n 20 PHP ./ tmp_files_killer.php

Я изменил мой сценарий, так что не будет читать/TMP реж все время:

$ ls -1 /tmp > tmp_files_list.txt 

<?php 
$file = "tmp_files_list.txt"; 
$infile = fopen($file, "r"); 

while (!feof($infile)) { 
    $line = rtrim(fgets($infile), "\n\r"); 
    if ($line != null){ 
    $file = "$dir/$line"; 
    unlink($file); 
    if (!(++$i % 10000)) { 
     echo "$i files removed\n"; 
    } 
# echo $line + "\n"; 
    } 
} 
?> 

но работает этот сценарий также замедляет мое приложение. Процесс не загружает CPU, и у меня достаточно памяти.

Ребята, как удалить эти файлы?

+0

Не можете ли вы сделать это в командной строке? Нужно ли их удалять только один раз или через определенные промежутки времени? Возможно создание cronjob, который удаляет фиксированное количество файлов через регулярные промежутки времени. – pritaeas

ответ

0

Я сделал такие вещи, когда захотел очистить загружаемый каталог для галереи. Это было очень долго ... Поэтому я решил попробовать exec() как команды с командой rm /path/to/clean/*, и это получилось очень быстро.

Не очень чистый, но, по крайней мере, он работал хорошо для меня.

3

, если вы можете непосредственно выполнять команды на Linux терминал, то это будет очень простой процесс, непосредственно выполнить эту команду

find /tmp -type f -exec rm -v {} \; 

дополнительно, если вы хотите, чтобы выполнить этот процесс периодически после этого вы можете настроить cronjob для запуска в полночь, где ваш сервер будет почти бездействовать

+0

Я бы тоже попробовал это первым - но он все равно может забить сервер. –

+0

Обратите внимание, что это пропустит файлы, у которых нет имени. '. – sarnold

+1

.. Кроме того, '-exec' вызовет около тысячи раз или больше 'execve (2)' системных вызовов, чем нужно. 'find ... -print0 | xargs -0 rm' будет выполнять 'rm' значительно реже. И выход ('-v') просто вызовет ненужный ввод-вывод, который часто является самой медленной частью программ ... – sarnold

0

Нужно ли выполнять очистку с помощью php-скрипта?

Если нет, посмотрите на эту article ... вы должны получить несколько идей

4

Вы можете получить скрипт для работы в «куски», то спать между каждой порции.

В вашей второй версии вы можете добавить sleep() после эха, скажем, 30 секунд. Если вы настроили количество удаленных файлов и время спало, оно должно поддерживать реакцию сервера, сохраняя при этом адекватное выполнение.

В будущем вы должны регулярно запускать работу по очистке от cron, чтобы не допустить этого.

1

Я бы решил это по-другому: уничтожить всю файловую систему за один раз.

Создайте новую файловую систему - это может быть простая файловая система tmpfs, это может быть файловая система ext2 или ext3, живущая в файле, который установлен на петле, это может быть новый диск (USB-накопитель?), Что угодно.

Тогда mv/tmp точку монтирования на другое имя, смонтировать новую файловую систему на /tmp, а затем запустить mke2fs на раздела, который имел обыкновение быть /tmp и написать совершенно новую чистую файловую систему с нуля.

После того, как ваш старый TMP устройство повторно создан, вы можете выполнить шаги снова - mv /tmp /new-tmp, списывать данные, которые должны быть стойкими, mount повторное отформатирован устройство обратно на /tmp, и скопировать обратно данные, которые должны сохраняются.

0

Это, вероятно, еще быстрее стандартный способ, чтобы удалить все файлы в/TMP:

find /tmp -type f -exec rm {} + 

С Gnu найти, это может быть немного быстрее:

find /tmp -type f -delete 

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