Медленное завершение вкладок Bash после случайной записи (но затем удаления) миллионов файлов в каталог

Вы можете просто указать findисключить файлы, начинающиеся с pure_, а также выполнить grepс выражением -regex:

find./path -mindepth 1 -maxdepth 2 -type f ! -name 'pure_*' -regex '.*\.[0-9][0-9][0-9].txt$'

С копиями в моделируемом каталоге из вашего примера я получаю:

./path/1/file1.001.txt
./path/1/file2.001.txt
./path/2/file3.002.txt
0
19.11.2019, 10:30
3 ответа

Как упоминалось в комментариях, ваш домашний каталог сам по себе огромен и больше не сжимается. Сканирование содержимого вашего домашнего каталога потребует чтения большого количества данных каждый раз (из кеша или диска ).

Чтобы исправить это, вам нужно повторно -создать свой домашний каталог:

  • выйдите из системы, войдите в систему как root и убедитесь, что ни один запущенный процесс не ссылается на ваш домашний каталог:

    lsof /home/myname
    
  • скопируйте свой домашний каталог:

    cd /home
    cp -al myname myname.new
    
  • переименуйте свой домашний каталог в сторону:

    mv myname myname.old
    
  • переименуйте новый домашний каталог:

    mv myname.new myname
    

Теперь вы можете снова войти в систему. Ваш блестящий новый домашний каталог будет занимать ровно столько места, сколько ему действительно нужно, а операции с файлами должны выполняться так быстро, как вы ожидаете. cp -alгарантирует, что все файлы доступны в новом каталоге, но использует жесткие ссылки, чтобы не занимать никакого дополнительного пространства (помимо структуры каталога ). Из-за жестких ссылок любые изменения, внесенные в файлы в одном из каталогов, отражаются в другом каталоге, но вы можете безопасно удалить myname.old.

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

7
28.01.2020, 02:13

Ответ Стивена Китта в основном правильный подход, но это должно быть сделано с использованием mv, а неcp-нет необходимости тратить несколько минут или часов на копирование всех файлов, когда их перемещение почти не займет времени вообще. Например:

  1. выйдите из системы как ваш пользователь (ВСЕ случаи входа в систему, включая любые сеансы ssh )и войдите в систему как пользователь root.

    Если ваша система настроена на предотвращение прямого входа в систему root (, например. поскольку root имеет отключенный пароль ), войдите в систему как другой пользователь (, создайте его, если необходимо, и предоставьте ему доступ к suили sudo), затем получите корневую оболочку.

  2. Не должно быть необходимости убеждаться, что ничто не запущено от имени вашего пользователя или не имеет открытых файлов в вашем домашнем каталоге , потому что файлы обрабатывают (и номера инодов )НЕ изменятся , если только ваш домашний каталог имеет свою собственную файловую -систему (, например если /home/usernameявляется собственной точкой монтирования -, а не просто подкаталогом -каталога/home).

    Фактическое перемещение (на шаге 3 ниже )должно занять доли секунды (в зависимости от количества файлов и каталогов на верхнем уровне вашего домашнего каталога. это все, что нужно переместить ), потому что это mv, а неcp-данные не копируются, все делается очень быстро путем переименования.

    Крайне маловероятно, что что-либо создаст новые файлы (или попытается открыть еще не перемещенный файл )за это короткое время.

    Однако, если вы страдаете паранойей или вероятно, что задание cronили atи т. д. может сделать это, временно отключите их. Не забудьте перезапустить их после этого.

    То же самое для любого другого запущенного процесса (, например. NFS, или samba, или доставка почты, или ftpd, или что-то еще ), что может сделать это -, убивает их сейчас и перезапускает позже. Кстати, вы можете убить все процессы, принадлежащие пользователю -, например, pkill -u username.

  3. mvвсе в вашем домашнем каталоге в новый домашний каталог. например. если ваш домашний каталог /home/username, выполните следующее как root:

    cd /home
    mv username username.old
    mkdir username
    
    # move the files and subdirectories to the new home
    # BTW, using `find` ensures that "hidden" dotfiles and dotdirs are moved
    # along with the non-hidden files & dirs.
    cd username.old
    find. -mindepth 1 -maxdepth 1 -exec mv {}../username/ +
    cd..
    
    # fix ownership and perms of the new home dir
    gid="$(getent passwd username | cut -d: -f4)"
    perms="$(stat --printf "%a" username.old)"
    chown "username:$gid" username
    chmod "$perms" username
    
    rmdir username.old
    

Обратите внимание, :для stat --printf...выше требуется GNU stat. Вы сказали, что используете Centos 7, так что это то, что у вас есть.

Для тех, у кого похожая проблема в системе, отличной от GNU, вам придется найти какой-то другой способ продублировать разрешения. Версия statдля FreeBSD имеет аналогичные возможности, но параметры другие. Или просто установите разрешения для нового каталога вручную -, они, скорее всего, будут 775или 755(, возможно, с набором -gid, поэтому 2775или 2755), но проверьте, что с ls -ldили statили что-то еще.

0
28.01.2020, 02:13

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

В других случаях, когда количество или размер файлов в дереве каталогов затрудняет их простое копирование в новый каталог, вы также можете размонтировать файловую систему (или загрузиться с загрузочного диска, если он является корневым. filesystem )и запустите e2fsck -fD /dev/sdXдля файловой системы, чтобы оптимизировать каталоги(-Doption ). Это упакует записи каталога в минимальное количество блоков без копирования данных файла.

2
28.01.2020, 02:13

Теги

Похожие вопросы