удаление большого количества файлов

mcfalu

Новичок
удаление большого количества файлов

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

Файлы лежат на сервере в директориях определённой структуры, иформация где лежат эти файлы в БД.
Есть 100 000 файлов. Из них 50 000 нужно удалить. Как правильно сделать так, чтобы скрипт удалил все эти файлы, при этом не оказалось ситуации когда появляются битые записи в БД - тоесть запись о файле есть, а файл с сервера был удален.

Сейчас как работает:
Происходит выборка тех файлов с БД, которые нужно удалить. Поочередно каждый файл удаляется с БД. В конце одним запросом удаляются те записи с БД, файлы которых были удалены физически.

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

Как можно еще поступить?
 

Mr_Max

Первый класс. Зимние каникулы ^_^
Команда форума
Хранить данные, в директориях по датам.
Тупо грохать всю директорию.

-~{}~ 01.08.10 17:57:

Вообще какой принцип определения
нужен/не нужен
?
 

mcfalu

Новичок
Автор оригинала: Mr_Max
Хранить данные, в директориях по датам.
Тупо грохать всю директорию.
а если есть уже такая ситуация как описана? Когда инфа хранится в БД

-~{}~ 01.08.10 19:00:

Автор оригинала: Mr_Max

Вообще какой принцип определения
нужен/не нужен
?
в БД фиксируется дата загрузки файла, +хранится количество запросов к данному файлу.
Если файл был загружен определённое время назад(месяц, пол года) и количесто запросов N (0, до 10, до 100) - то удалять.
Такие файлы считаются мусором.
 

vovanium

Новичок
mcfalu
как вариант, пиши в файл лог, какие файлы были удалены, а потом по нему удаляй из базы.
 

lart

Guest
В базе создаешь поле - дата и время начала удаления файлов, когда делается выборка ненужных файлов им ставиться дата когда они были выбраны, а когда все файлы были удалены записи тоже удаляются. Если скрипт прервался и файлы удалились а записи в БД нет, то у тебя есть метка что файлы должны быть удалены, и их использовать нельзя. Когда скрипт запускается второй раз он при выборке проверяет это поле, если время начала предыдущего удаления старше 2-3 часов значит надо их удалят повторно (при этом не забывать что при первом запуске файлы уже могли быть удалены и делать проверку на существование файла). Таким образом в базе могут лежать записи файлок которых уже нет на сервере, но твоя система об этом знает и юзать их не будет, а при повторном запуске и успешном выполнении записи в базе будут дочищены.

P.S. Не плохо бы при такой системе сделать запись ошибок выполнения в лог файл, что бы ты мог видеть на каком файле валиться скрипт, если это будет происходить систематически
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
а чем плохо удалять каждую запись из базы сразу после удаления файла с диска?
 

lart

Guest
а чем плохо удалять каждую запись из базы сразу после удаления файла с диска?
Большой нагрузкой на базу, и как следствие медленная работа всей системы.
 

AmdY

Пью пиво
Команда форума
lart
это разовая операция, можно не париться над оптимизацией.
кстати, есть ещё транзакции, удалили записи, удалили файлы, зафиксировали. хотя, главное из базы удалить, потом можно поиск с удалением по времени последнего доступа.
 

lart

Guest
это разовая операция, можно не париться над оптимизацией.
кстати, есть ещё транзакции, удалили записи, удалили файлы, зафиксировали. хотя, главное из базы удалить, потом можно поиск с удалением по времени последнего доступа.
Если это разовая операция, то к чему вообще вопрос? Тогда можно удалять как хочешь... Но по моему автор писал что это не разовая а периодическая операция
в БД фиксируется дата загрузки файла, +хранится количество запросов к данному файлу.
Если файл был загружен определённое время назад(месяц, пол года) и количесто запросов N (0, до 10, до 100) - то удалять.
Такие файлы считаются мусором.
 

mcfalu

Новичок
да, операция периодическая.
Можно по простому сделать удалил файл - удалил запись с БД. Но зачем к пример 100 запросов к БД делать, если это все можно сделать одни запросом?
 

vovanium

Новичок
mcfalu
чем не устраивает мой вариант? пишешь в файл id для удаления, потом по этому файлу удаляешь из базы.
запись в файл значительно быстрее операций с бд, и если скрипт незапланировано прекратит работу в файле будут все нужные id для удаления
 

kabachok

Новичок
Автор оригинала: mcfalu
да, операция периодическая.
Можно по простому сделать удалил файл - удалил запись с БД. Но зачем к пример 100 запросов к БД делать, если это все можно сделать одни запросом?
запускай эту процедуру ночью с маленьким приоритетом запросов, тогда нагрузка будет не очень заметна и меньше гемороя над псевдо-оптимизациями.

Я так же больше склоняюсь к тому, что нужно грохать запись в базе после удаления файла, а не пачками.

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

grigori

( ͡° ͜ʖ ͡°)
Команда форума
>Большой нагрузкой на базу, и как следствие медленная работа всей системы.

какой у вас сейчас LA, потребление CPU, и disk io, как нагрузка распределена по времени?

какие требования к скорости исполнения задачи - за какое время какое количество файлов и записей должно быть удалено?
сколько на сервере винтов?

-~{}~ 02.08.10 17:10:

а если это медленная работа абстрактного коня в вакууме - иди лучше пей пиво и не засоряй эфир
 

Aleks

Новичок
DirectoryInfo di = new DirectoryInfo(Server.MapPath("analysis"));
DirectoryInfo[] dirs = di.GetDirectories("a*"); // из всего количество
// директорий выбераем только те которые заканчиваются на букву a, так мы уменьшаем количество директорий , сами составте алгоритм перебора всего алфавита

foreach (DirectoryInfo diNext in dirs)
{
diNext.Delete(true);
}
 

DYPA

Настоящая dypa (c)
1) перемещаем записи во временную таблицу
2) удаляем файлы (rm -rf 1.file && rm - rf ........)
3) проверяем что их не существует и ставим флаг во временной таблице что файл удалён
4) удаляем запись
 

Alien85

I like my cat
да, операция периодическая.
Но зачем к пример 100 запросов к БД делать, если это все можно сделать одни запросом?
ты платишь за каждый запрос к БД?

идеальный случай:
1. в таблице базы данных находим устаревшие файлы и выставляем им метку "удалить", всё, теперь к этим файлам доступа больше не должно быть;
2. ищем все записи с меткой "удалить", удаляем файл, удаляем запись (или ставим метку "удалено").

если система не очень большая, можно эти пункты совместить.

я бы вообще тупо сделал:
select * from table where 'условие устаревания' limit 1
remove 'найденный файл'
delete from table where id='ID'

и все это завернуть в непрерывный цикл, пока не вернется false.
То, что этот скрипт будет запускаться 1 раз в день, систему не затормозит.

больше интересно, как ты будешь искать файлы, который на диске есть, а в БД нет? :) а такие у тебя по любому есть...
 
Сверху