Milyonlarca dosyayı silmek


38

Milyonlarca gif imgesiyle dolu bir kirim vardı. Rm komutu için çok fazla.

Bul komutunu bu şekilde deniyorum:

find . -name "*.gif" -print0 | xargs -0 rm

Sorun şu ki, makinemi gerçekten fena düşürüyor ve sunucu olduğundan müşteriler için zaman aşımına uğraıyor.

Makineyi kilitlemeden tüm bu dosyaları silmenin daha hızlı bir yolu var mı?


Aşağıdaki "nice find" komutunu kullanarak yaklaşık 6 gb / saat silme oranındayım. Muhtemelen tüm dosyalardan kurtulmak için tam 48 saat sürecek. Bunun olmasının nedeni b / ca scour betiği başarısız oldu. rm komutu ile "olay ufku", sonra kaçtı

3
Tüm kiri sökmek çok daha hızlı olmaz mıydı?
Kalanları daraltmadan

Şu anda her dosya kötü, çünkü / dir_old dizinine taşındı ve ben / dir dizilimini değiştirdim. Fakat rmdir, rm * ile aynı sınırlama ile karşılaşmaz mı?

@Corepuncher: Ben olduğu gibi (dizinin tamamını çıkarmadan beklenebilir rm -rfhızlı olacaktır It adlı bir cami..
Jason R

Şu anda dir "rm-rf" çalıştırıyorum. 20 dakikadan fazla bir süredir çalışıyor ... disk boyutunda bir değişiklik yok. Ama aynı zamanda otomatik olarak "çok uzun zamandır tartışılanlar listesini" de geri vermedi. Tek sorun, makinemi gerçekten etkiliyor ve diğer şeyleri yavaş / başarısız yapıyor. Gitmesine ne kadar sürebildiğinden emin değilim.

Yanıtlar:


44

Daha hızlı istediğin her şey değildir. Gerçekten daha yavaş koşmak isteyebilirsiniz , bu nedenle silme işlemi devam ederken daha az kaynak tüketir.

Kullanım güzel (1) bir komutun önceliğini düşürmek için.

nice find . -name "*.gif" -delete

G / Ç'ye bağlı işlemler için iyi (1) yeterli olmayabilir. Linux zamanlayıcısı, yalnızca CPU'yu değil, G / Ç'yi de dikkate alır, ancak G / Ç önceliği üzerinde daha iyi kontrol sahibi olmak isteyebilirsiniz.

ionice -c 2 -n 7 find . -name "*.gif" -delete

Bu işe yaramazsa, onu yavaşlatmak için bir uyku da ekleyebilirsiniz.

find . -name "*.gif" -exec sleep 0.01 \; -delete

3
vay ... .1 s uyku ile milyonlarca dosya ... 864000 dosya için bir gün gerekiyor.
glglgl

7
@glglgl Tamam, akıllı eşek. Zaman aşımını değiştirdim. :-P
John Kugelman

28
Uyku iyi bir seçim olabilir, ancak buradaki görev işlemsel IO'ya bağlı, CPU'ya bağlı değil; bunun yerine ionice deneyebilirsiniz. Uykunun çok küçük olması durumunda işe yaramayacağına dikkat edin.
Matteo Italia

3
glglgl: Mesele şu ki, sunucuda servisin bozulmasına neden olmak istemiyorsanız yavaş gitmek zorundasınız, bu kodun uyuduğu zaman, sunucunun diskle gerçekten yararlı çalışmasına izin vermek için oradadır.
Matteo Italia

1
sleepEkleme için +1 - Kullanmama rağmen IO'da boğulan sunucularla ilgili sorun yaşıyordum ionice -c 3. Dosyaları (tabii ki) temizlemek için gereken süreye önemli ölçüde katkıda bulunur, ancak uygulamayı geri getirmek yerine beklemek isterdim ...
Ola Tuvesson

22

Linux kullanıyorsanız ve bu görev muhtemelen G / Ç bağlı olduğundan, komut boşta G / Ç zamanlayıcı önceliğini aşağıdakileri kullanarak vermenizi öneririm ionice(1):

ionice -c3 find . -name '*.gif' -delete

Orjinal komutunuzla kıyaslandığında, bunun boruyu önleyerek daha fazla CPU çevrimi bile sağlayabileceğini düşünüyorum xargs.


@Braiam Ne demek istiyorsun? Bu find ... -execanlamlı olacağı bir yer değil .

Evet, özür dilerim. Benim hatam. Bunun verimli olduğundan emin misin, tho?
Braiam

1
Peki, find(1)belgeler böyle iddia ediyor. :) Ve finddosyaları silmeye izin vermenin , bunun rmiçin bir komut yazmaktan daha etkili olduğu açık olmalı .

1
Bir yapım sunucusunda 4 milyon dosya bulunan bir klasörde önerilen birkaç sürümü denedim ve bu sistemi tıkamayan tek sürüm. ionice -c3primi sadece IO boştayken kaçması için düşürür aksi halde bu mükemmel olur. Çünkü unutmayın -deleteBulma işlemi için standart değil, bu komutu kullanarak (bunun işe yaradığını geribildirim dahil) aynı yapabilirsiniz: ionice -c 3 find . -name '*.gif' -exec echo {} \; -exec rm {} \;- Yavaş ama önemli süreçlerin hiçbir iowaits.
Christopher Lörken

13

Hayır.

Daha hızlı bir yol yoktur, diskin yumuşak formatındaki appart. Dosyalar bir seferde rm'ye verilir (komut satırının sınırına xargskadar, her bir dosyada rm çağırmaktan çok daha iyidir). Yani hayır, kesinlikle daha hızlı bir yol yok.

Kullanmak nice(ya da reniceçalışan bir süreçte) sadece kısmen yardımcı olur çünkü bu işlem CPU kaynağını zamanlamak içindir, diski değil! Ve CPU kullanımı çok düşük olacaktır. Bu bir linux zayıflığıdır - eğer bir işlem diski "yerse" (yani onunla çok çalışırsa), tüm makine sıkışır. Gerçek zamanlı kullanım için modifiye çekirdek bir çözüm olabilir.

Sunucuda yapacağım şey, diğer işlemlerin işlerini el ile yapmasına izin vermektir - sunucuyu "nefes almasını" sağlayacak duraklamalar içerir:

find . -name "*.gif" > files
split -l 100 files files.
for F in files.* do
    cat $F | xargs rm
    sleep 5 
done

Her 100 dosyadan sonra 5 saniye beklenir. Daha uzun sürecek, ancak müşterileriniz herhangi bir gecikme farketmemelidir.


"Dosyalar bir kerede rm'ye verilir (komut satırının sınırına kadar") - yani kabuk sipariş edildiğinde rm *, *tüm dosya adlarıyla aynı çizgiye genişler ve bunu iletir rm? İnanılmaz derecede aptal. Neden kabuk joker karakterleri genişlet

:-D @Joker_vD, adından da anlaşılacağı gibi şaka mı yapıyorsun? :-)
Tomas 23:13

2
@Joker_vD: 1970 ya da öylesine bir Unix kararıyla uyumluluk. Windows yapmaz. Orada, programlar joker karakterleri FindNextFile / FindNextFile öğesine geçirebilir, böylece sonuçları birer birer alırlar.
MSalters

@Tomas Bu durumda değil. Dürüst olmak gerekirse, hemen bu tür tasarım ile 2 sorunları görebilirsiniz: İlk olarak, komut satırı kauçuk değil; ikinci olarak, programın çağrılıp çağrılmadığını *veya /*kullanıcının bu kararına şüphe duyduğunu söyleyemez .

1
@ Joker_vD Kabuk joker genleşmesi yapan pek çok güzel şey var. Windows’tan farklı, ancak alıştığınızdan farklı olduğu için inanılmaz derecede aptal olduğu sonucuna atlamayın. Daha fazla bilgi edinmek istiyorsanız, sizi Google’a yönlendirmenizi veya ilgili Stack Exchange sitesinde bir soru göndermenizi öneririm. Bu yorum alanı için büyük bir ray.
John Kugelman

5

Silinecek dosya sayısı, geride bırakılan dosyalardan çok daha büyükse, silinecek dosya ağacında dolaşmak ve tüm bu dosya sistemi güncellemelerini yapmak en etkili yaklaşım olmayabilir. (Sakar referans sayımlı hafıza yönetimi yapmak, büyük bir ağaçtaki her nesneyi referansını bırakmak için ziyaret etmek, her şeyi tek adımda çöp içine istenmeyen hale getirmek yerine, ve temizlemek için ulaşılabilir olanı taramakla aynıdır.)

Yani, ağacın başka bir hacme tutulması gereken kısımlarını klonlayın. Orijinal birimde yeni, boş bir dosya sistemi yeniden oluşturun. Tutulan dosyaları orijinal yollarına geri kopyalayın. Bu belli belirsiz çöp toplama işlemine benzer .

Bir kesinti olacaktır, ancak sürekli kötü performans ve servis kesintisinden daha iyi olabilirdi.

Sisteminizde ve durumunuzda kullanışsız olabilir, ancak bunun nasıl gideceğine dair açık durumlar hayal etmek kolaydır.

Örneğin, bir dosya sistemindeki tüm dosyaları silmek istediğinizi varsayalım . Tek tek tekrarlama ve silme noktası ne olurdu? Boş bir dosya sistemi oluşturmak için sadece ayırın ve bölümün üstüne bir "mkfs" yapın.

Ya da yarım düzine önemli dosya dışındaki tüm dosyaları silmek istediğinizi varsayalım. Oradan yarım düzine al ve üstünden "mkfs".

Sonunda, kalması gereken yeterli sayıda dosya olduğunda, herhangi bir kesinti gibi diğer maliyetleri hesaba katarak özyinelemeli silme işleminin daha ucuz hale geldiği bazı kesinti noktaları vardır.


4

Denedin mi:

find . -name "*.gif" -exec rm {} +

Sonunda bulunan + işareti, çalıştırılacak tek rm komutu için daha fazla dosya bulunmasına neden olacaktır. Daha fazla ayrıntı için bu soruyu kontrol edin .


-Print0'dan çok daha hızlı çalışır | xargs çözümü, çünkü her işlem için rm işlemi başlatılmaz, büyük dosyalar için çalıştırılır ve bu nedenle düşük yüke neden olur.

@JohnKugelman Haklısınız, ancak her zaman yerel bulma komutuyla kullanılamayan bir GNU uzantısıdır .
CodeGnome

Tamam, ilginç, ama bu -deleteher zaman orada olmak zorunda olmayan , oldukça yeni bir şey ..
Tomas

Ancak bu kesinlikle OP'nin çözümüyle karşılaştırıldığında daha iyi bir şey getirmiyor.
Tomas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.