Довідка: фізичний сервер, близько двох років, 7200-RPM SATA-накопичувачі, підключені до 3Ware RAID-картки, ext3 FS, встановлений у режимі часу та дані = замовлені, не з розуму навантаження, ядро 2.6.18-92.1.22.el5, час роботи 545 днів . Каталог не містить жодних підкаталогів, лише мільйони невеликих (~ 100 байт) файлів, а також декілька більших (декілька КБ).
У нас є сервер, який за останні кілька місяців пішов трохи зозулею, але ми помітили це лише днями, коли він не зміг записатись у каталог через те, що він містить занадто багато файлів. Зокрема, ця помилка почала видавати в / var / log / messages:
ext3_dx_add_entry: Directory index full!
На диску, що залишився, є багато:
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda3 60719104 3465660 57253444 6% /
Тому я здогадуюсь, що це означає, що ми досягли межі кількості записів у самому файлі каталогу. Не знаю, скільки файлів було б, але, як бачите, це не може бути більше, ніж три мільйони. Не те, що це добре, зауважте! Але це частина мого запитання: яка саме ця верхня межа? Це налаштовується? Перш ніж я кричав на-я хочу , щоб налаштувати його вниз ; цей величезний каталог викликав всілякі проблеми.
У будь-якому випадку ми відстежили проблему в коді, який генерував усі ці файли, і ми її виправили. Тепер я застряг із видаленням каталогу.
Тут є кілька варіантів:
rm -rf (dir)
Я спробував це спочатку. Я здався і вбив його після того, як він пробіг півтора дня без помітного впливу.
- unlink (2) у каталозі: Безумовно, варто розглянути, але питання полягає в тому, чи було б швидше видалити файли всередині каталогу через fsck, ніж видалити через unlink (2). Тобто, так чи інакше, я маю позначати ці вставки як невикористані. Це, звичайно, передбачає, що я можу сказати fsck не відкидати записи до файлів у / lost + found; в іншому випадку я просто перенесла свою проблему. На додаток до всіх інших проблем, прочитавши про це трохи більше, виявляється, що, мабуть, мені доведеться викликати деякі внутрішні функції FS, оскільки жоден із варіантів відключення (2), які я можу знайти, не дозволив би мені просто видалити каталог із записами в ньому. Пух.
while [ true ]; do ls -Uf | head -n 10000 | xargs rm -f 2>/dev/null; done )
Це фактично скорочена версія; справжній, який я працюю, який просто додає деякий звіт про прогрес і чисту зупинку, коли у нас закінчуються файли для видалення, це:
експорт i = 0; час (поки [правда]; робити ls -Uf | голова -n 3 | grep -qF '.png' || перерва; ls -Uf | голова -n 10000 | xargs rm -f 2> / dev / null; експорт i = $ (($ i + 10000)); відлуння "$ i ..."; зроблено)
Це, здається, працює досить добре. Коли я це пишу, він видалив 260 000 файлів за останні тридцять хвилин.
- Як було сказано вище, чи може бути налаштована межа входу в каталог?
- Чому для видалення одного файлу, який був першим у списку, який повернув
ls -U
, і знадобилося, можливо, десять хвилин, щоб видалити перші 10 000 записів із записом "real 7m9.561s / user 0m0.001s / sys 0m0.001s". команда в №3, але тепер вона тягнеться цілком щасливо? З цього приводу він видалив 260 000 приблизно за тридцять хвилин, але зараз потрібно ще п’ятнадцять хвилин, щоб видалити ще 60000. Чому величезні гойдалки в швидкості? - Чи є кращий спосіб зробити подібні речі? Не зберігати мільйони файлів у каталозі; Я знаю, що це нерозумно, і це не сталося б на моєму годиннику. Перебіг проблеми та перегляд SF та SO пропонує безліч варіацій
find
, які не будуть значно швидшими, ніж мій підхід з кількох очевидних причин. Але чи має ідея delete-via-fsck ноги? Або щось інше цілком? Мені дуже хочеться почути нестандартне (або все-таки не добре відоме) мислення.
Кінцевий вихід сценарію !:
2970000...
2980000...
2990000...
3000000...
3010000...
real 253m59.331s
user 0m6.061s
sys 5m4.019s
Отже, три мільйони файлів видалено за трохи більше чотирьох годин.
rm -rfv | pv -l >/dev/null
. pv має бути доступним у сховищі EPEL .