การลบไฟล์หลายพันล้านไฟล์จากไดเรกทอรีในขณะที่เห็นความคืบหน้าเช่นกัน


36

ฉันมีไดเรกทอรี 30 TB ที่มีไฟล์เป็นพันล้านไฟล์ซึ่งเป็นไฟล์ JPEG ทั้งหมด ฉันกำลังลบแต่ละไฟล์ของไฟล์ดังนี้:

sudo rm -rf bolands-mills-mhcptz

คำสั่งนี้จะทำงานและไม่แสดงอะไรเลยว่ามันทำงานหรือไม่

ฉันต้องการดูว่ามันเป็นการลบไฟล์หรือสถานะปัจจุบันของคำสั่งคืออะไร


19
ไม่ใช่คำตอบ: บางครั้งการสำรองข้อมูลที่คุณต้องการจัดรูปแบบและเรียกคืนสิ่งที่คุณต้องการเก็บไว้เร็วกว่า คำตอบอื่น ๆ : unix.stackexchange.com/questions/37329/…
Eric Towers

2
หากคุณต้องการความคิดเกี่ยวกับความคืบหน้าแทนที่จะรู้ว่าไฟล์ใดที่ถูกลบไปคุณสามารถเรียกใช้ "df / dev / sd_whething_the_drive_is"
jamesqf

11
คุณจบลงด้วยไฟล์หลายพันล้านไฟล์ในไดเรกทอรีเดียวได้อย่างไร?
การแข่งขัน Lightness กับ Monica

1
@MichaelHampton แต่ถ้าไฟล์ไม่ใช่ชุดข้อมูลแยกต่างหากมันอาจใช้เวลานาน (บน ZFS) serverfault.com/questions/801074/…
v7d8dpo4

5
พันล้านไฟล์ใช่มั้ย ลองrm -riดู มันจะสนุก!
OldBunny2800

คำตอบ:


98

คุณสามารถใช้rm -vเพื่อrmพิมพ์หนึ่งบรรทัดต่อไฟล์ที่ถูกลบ วิธีนี้คุณจะเห็นได้ว่าใช้งานrmได้จริงในการลบไฟล์ แต่ถ้าคุณมีไฟล์หลายพันล้านไฟล์คุณก็จะเห็นว่าrmมันยังใช้งานได้ คุณจะไม่ทราบว่ามีไฟล์ถูกลบไปแล้วกี่ไฟล์และเหลือกี่ไฟล์

เครื่องมือpvสามารถช่วยคุณประเมินความคืบหน้าได้

http://www.ivarch.com/programs/pv.shtml

นี่คือวิธีที่คุณจะเรียกrmด้วยpvด้วยตัวอย่างการส่งออก

$ rm -rv dirname | pv -l -s 1000 > logfile
562  0:00:07 [79,8 /s] [====================>                 ] 56% ETA 0:00:05

ในตัวอย่างที่ประดิษฐ์นี้ฉันบอกpvว่ามี1000ไฟล์ ผลลัพธ์จากการpvแสดงให้เห็นว่า 562 จะถูกลบไปแล้วเวลาที่ผ่านไปคือ 7 วินาทีและการประมาณให้เสร็จสมบูรณ์คือ 5 วินาที

คำอธิบายบางอย่าง:

  • pv -lทำให้pvนับขึ้นบรรทัดใหม่แทนไบต์
  • pv -s numberบอกpvว่ายอดรวมคือเท่าไหร่เพื่อให้การประมาณ
  • การเปลี่ยนเส้นทางไปlogfileยังจุดสิ้นสุดมีไว้เพื่อผลลัพธ์ที่สะอาด มิฉะนั้นบรรทัดสถานะจากได้รับการขึ้นผสมกับเอาท์พุทจากpv rm -vโบนัส: คุณจะมี logfile ของสิ่งที่ถูกลบ แต่ระวังไฟล์จะใหญ่ขึ้น คุณสามารถเปลี่ยนเส้นทางไปยัง/dev/nullหากคุณไม่ต้องการบันทึก

ในการรับจำนวนไฟล์คุณสามารถใช้คำสั่งนี้:

$ find dirname | wc -l

สิ่งนี้อาจใช้เวลานานหากมีไฟล์เป็นพันล้านไฟล์ คุณสามารถใช้pvที่นี่เช่นกันเพื่อดูว่ามีการนับจำนวนเท่าใด

$ find dirname | pv -l | wc -l
278k 0:00:04 [56,8k/s] [     <=>                                              ]
278044

นี่มันบอกว่ามันใช้เวลา 4 วินาทีในการนับ 278k ไฟล์ จำนวนที่แน่นอนในตอนท้าย ( 278044) wc -lเป็นเอาท์พุทจาก

หากคุณไม่ต้องการรอการนับคุณสามารถเดาจำนวนไฟล์หรือใช้pvโดยไม่มีการประมาณ:

$ rm -rv dirname | pv -l > logfile

เช่นนี้คุณจะไม่มีการประมาณค่าให้เสร็จ แต่อย่างน้อยคุณจะเห็นว่ามีไฟล์ถูกลบไปแล้วกี่ไฟล์ เปลี่ยนเส้นทางไปที่/dev/nullหากคุณไม่ต้องการ logfile


nitpick:

  • คุณต้องการจริงๆsudoเหรอ?
  • มักrm -rจะเพียงพอที่จะลบแบบเรียกซ้ำ rm -fไม่จำเป็นต้องให้

5
ใช้ดีโดยpvสมมติว่ามันไม่แพงเกินไปที่จะนับพันล้านไฟล์ ;-) (อาจใช้เวลาเกือบเท่าที่rmควรจะเป็นวัด!)
สตีเฟ่น Kitt

7
@StephenKitt นี่คือสิ่งที่มันทำให้ฉันรำคาญ (และคนอื่น ๆ อีกมากมาย) เกี่ยวกับโปรแกรมอรรถประโยชน์แฟ้ม Windows: มันเสมอโดยไม่ต้องล้มเหลวนับจำนวนและขนาดของไฟล์ก่อนที่จะลบซึ่งเว้นแต่ไดรฟ์มากช้ากว่าหน่วยประมวลผลจะใช้เวลาเกือบจะเป็น ตราบใดที่การลบที่แท้จริง!
wizzwizz4

@ wizzwizz4 แน่นอน! มีมากกว่านั้นแม้ว่า IIRC จะตรวจสอบว่าสามารถลบทุกอย่างก่อนที่จะลบสิ่งใด ๆเพื่อเพิ่มโอกาสในการลบที่เป็น "ทั้งหมดหรือไม่มีอะไร" หลายปีที่ผ่านมาฉันเขียนไดร์เวอร์ระบบไฟล์สำหรับ Windows มีเรื่องแปลก ๆ ที่เราต้องจัดการรวมถึงบางอย่างที่เกี่ยวข้องกับวิธีที่ Explorer ทำการลบ แต่ฉันจำรายละเอียดไม่ได้ (ฉันจำได้ว่าการสร้างโฟลเดอร์นั้นเกี่ยวข้องกับการเขียนและลบไฟล์ในโฟลเดอร์ใหม่!)
Stephen Kitt

7
@StephenKitt บางทีฉันเข้าใจผิด แต่ไม่ใช่คอขวดนอกเหนือจากการเข้าถึงดิสก์เอาต์พุตเทอร์มินัล? ฉันเชื่อว่าการpvฟื้นฟูแถบความคืบหน้าเพียงครั้งเดียวต่อวินาทีแม้จะมีการป้อนข้อมูลของมัน ดังนั้นเทอร์มินัลจะต้องแสดงเพียงหนึ่งบรรทัดแทนที่จะเป็นตันต่อวินาที pvเพียงต้องการเพิ่มตัวนับสำหรับแต่ละบรรทัดใหม่ที่พบ นั่นจะต้องเร็วกว่าการใช้การพันบรรทัดและสิ่งใดที่ไม่สามารถแสดงบรรทัดในเทอร์มินัลได้ ฉันคิดว่าการทำงานpvแบบนี้จะทำให้การลบไฟล์นั้นเร็วกว่าเพียงแค่rm -rvนั้น
JoL

1
@skywinderrm -rv dirname | pv -l -s $(find dirname | wc -l) > logfile
lesmana

28

ตรวจสอบคำตอบ Lesmana ของมันมากดีกว่าฉัน - โดยเฉพาะอย่างยิ่งที่ผ่านมาpvเช่นซึ่งจะไม่ใช้เวลานานกว่าเดิมเงียบrmหากคุณระบุแทน/dev/nulllogfile

สมมติว่าคุณrmรองรับตัวเลือก (อาจเป็นเพราะคุณใช้ Linux) คุณสามารถเรียกใช้ในโหมด verbose ด้วย-v:

sudo rm -rfv bolands-mills-mhcptz

ดังที่ได้รับการชี้ให้เห็นโดยผู้แสดงความคิดเห็นจำนวนมากสิ่งนี้อาจช้ามากเนื่องจากจำนวนเอาต์พุตที่สร้างและแสดงโดยเทอร์มินัล คุณสามารถเปลี่ยนเส้นทางไปยังไฟล์แทน:

sudo rm -rfv bolands-mills-mhcptz > rm-trace.txt

rm-trace.txtและดูขนาดของ


5
สิ่งนี้สามารถชะลอการลบได้ช้าลงเนื่องจากเอาต์พุตทั้งหมดที่สร้างขึ้นและแสดงผลไปยังเทอร์มินัล :)
rackandboneman

2
แน่นอนมันจะช้าลง การเขียนหลายพันล้านบรรทัดไปยังไฟล์จะไม่เกิดขึ้นในเวลาศูนย์
user207421

23

อีกทางเลือกหนึ่งคือการดูจำนวนไฟล์ในระบบไฟล์ที่ลดลง ในเทอร์มินัลอื่นให้รัน:

watch  df -ih   pathname

จำนวนไอโหนดที่ใช้จะลดลงเมื่อมีrmความคืบหน้า (เว้นแต่ไฟล์ส่วนใหญ่จะมีลิงค์หลายรายการเช่นถ้าสร้างด้วยcp -al) ติดตามความคืบหน้าการลบในแง่ของจำนวนไฟล์ (และไดเรกทอรี) จะdfไม่มีการ-iติดตามในแง่ของพื้นที่ที่ใช้

คุณสามารถเรียกใช้iostat -x 4เพื่อดูการดำเนินการของ I / O ต่อวินาที (เช่นเดียวกับ kiB / s แต่นั่นก็ไม่ได้เกี่ยวข้องกับ I / O ของเมตาดาต้าล้วนๆ)


หากคุณสงสัยว่าไฟล์rmใดกำลังทำงานอยู่คุณสามารถแนบstraceไฟล์และดูในขณะที่ระบบunlink()(และ getdents) โทรออกมาที่เทอร์มินัลของคุณ sudo strace -p $(pidof rm)เช่น คุณสามารถ^cstrace เพื่อแยกออกrmโดยไม่ขัดจังหวะ

ฉันลืมว่าrm -rการเปลี่ยนแปลงไดเรกทอรีในแผนผังนั้นเป็นการลบหรือไม่ /proc/<PID>/cwdถ้าเป็นเช่นนั้นคุณอาจจะมองไปที่ /proc/<PID>/fdบ่อยครั้งที่มันอาจมีไดเรกทอรี fd เปิดอยู่ดังนั้นคุณสามารถดูได้ว่าrmกระบวนการของคุณกำลังดูอะไรอยู่


2
df -ihแน่นอนเป็นวิธีที่ดีในการดูrmความคืบหน้า
Stephen Kitt

BTW สิ่งนี้ใช้ไม่ได้กับ BTRFS ที่จำนวนการใช้ inode นั้นเป็นศูนย์เสมอ :( เดียวกันสำหรับ FAT32, แต่คุณอาจไม่ได้พันล้านไฟล์บน/bootพาร์ติชันระบบ EFI.
ปีเตอร์ Cordes

4

ในขณะที่คำตอบข้างต้นการใช้งานทั้งหมดrm, rmสามารถจริงจะค่อนข้างช้าในการลบจำนวนมากของไฟล์ที่ผมเพิ่งสังเกตเห็นเมื่อแยก ~ 100K ไฟล์จาก .tar เก็บจริงเอาเวลาน้อยกว่าการลบพวกเขา แม้ว่าสิ่งนี้จะไม่ตอบคำถามที่คุณถาม แต่ทางออกที่ดีกว่าสำหรับปัญหาของคุณคือการใช้วิธีอื่นในการลบไฟล์ของคุณเช่นหนึ่งในคำตอบที่ขึ้นทะเบียนของคำถามนี้

rsync -a --deleteวิธีการที่ชื่นชอบส่วนตัวของฉันคือการใช้งาน ฉันพบว่าวิธีนี้ทำงานได้เร็วพอที่จะคุ้มค่ากับความสะดวกในการใช้งานมากกว่าคำตอบ upvoted ที่สุดสำหรับคำถามนั้นซึ่งผู้เขียนเขียนโปรแกรม C ที่คุณจะต้องรวบรวม (โปรดทราบว่าสิ่งนี้จะส่งออกทุกไฟล์ที่กำลังประมวลผลเพื่อ stdout เช่นrm -rvนี้สามารถทำให้กระบวนการช้าลงด้วยจำนวนที่น่าแปลกใจหากคุณไม่ต้องการเอาท์พุทนี้ให้ใช้rsync -aq --deleteหรือเปลี่ยนเส้นทางไปยังไฟล์แทน)

ผู้เขียนคำตอบนั้นพูดว่า:

ตอนนี้โปรแกรมจะ (ลบไฟล์ในระบบของฉัน) ออก 1000000 ไฟล์ใน 43 วินาที โปรแกรมที่ใกล้เคียงที่สุดคือ rsync -a --delete ซึ่งใช้เวลา 60 วินาที (ซึ่งทำการลบตามลำดับเช่นกัน แต่ไม่ได้ทำการค้นหาไดเรกทอรีที่มีประสิทธิภาพ)

ฉันพบว่าสิ่งนี้ดีพอสำหรับวัตถุประสงค์ของฉัน อย่างน้อยก็อาจสำคัญจากคำตอบนั้นอย่างน้อยถ้าคุณใช้ ext4:

ด้วยความคิดล่วงหน้าเราควรลบไดเรกทอรีที่ได้รับผลกระทบและสร้างใหม่อีกครั้งหลังจาก ไดเรกทอรีมีขนาดเพิ่มขึ้นเรื่อย ๆ และยังคงทำงานได้ไม่ดีแม้จะมีไฟล์อยู่สองสามอันเนื่องจากขนาดของไดเรกทอรี


ฉันจะคาดหวังrmและ / หรือfind --deleteมีประสิทธิภาพ จุดที่น่าสนใจเกี่ยวกับการลบเพื่อเรียงลำดับเพื่อหลีกเลี่ยงการปรับสมดุล b-tree ในขณะที่ลบ ไม่แน่ใจว่ามีจำนวนเท่าใดที่นำไปใช้กับระบบไฟล์อื่น ๆ XFS ยังไม่ดีกับไฟล์นับล้านต่อไดเรกทอรี IDK เกี่ยวกับ BTRFS แต่ฉันรู้สึกว่ามันอาจจะดีสำหรับสิ่งนั้น
Peter Cordes

ไม่ว่าคำพูดที่สองขึ้นอยู่กับชนิดของระบบแฟ้ม ...
Menasheh

@ Menasheh จุดที่ดีฉันแก้ไขที่เป็นคำตอบของฉัน
Hitechcomputergeek

3

สิ่งหนึ่งที่คุณสามารถทำได้คือเริ่มrmกระบวนการในเบื้องหลัง (โดยไม่มีเอาต์พุตดังนั้นจะไม่ทำให้ช้าลง) จากนั้นตรวจสอบในเบื้องหน้าด้วยคำสั่งง่าย ๆ(a) :

pax> ( D=/path/to/dir ; rm -rf $D & while true ; do
...>   if [[ -d $D ]] ; then
...>     echo "$(find $D | wc -l) items left"
...>   else
...>     echo "No items left"
...>     break
...>   fi
...>   sleep 5
...> done )

27912 items left
224 items left
No items left

pax> _

find/wcคำสั่งผสมจะถูกแทนที่ด้วยเครื่องมือใดสามารถให้หน่วยงานที่คุณต้องการ


(ก)ดีค่อนข้างง่ายเมื่อเทียบกับการพูด, ฟิสิกส์นิวเคลียร์ Riemann สมมติฐานหรือสิ่งที่จะซื้อภรรยาของฉันสำหรับคริสต์มาส :-)


0

ไม่นานมานี้ฉันเขียนบางอย่างเพื่อพิมพ์อัตราที่บรรทัดถูกพิมพ์ คุณสามารถเรียกใช้rm -rfv | ./counterและมันจะพิมพ์บรรทัดต่อวินาที / นาที แม้ว่าจะไม่ใช่ความคืบหน้าโดยตรง แต่ก็จะให้ข้อเสนอแนะเกี่ยวกับอัตราความคืบหน้าบางทีคุณอาจrmหลงทางในระบบไฟล์เครือข่ายหรืออาจคล้ายกัน?

ลิงก์ไปที่รหัสอยู่ที่นี่:

http://www.usenix.org.uk/code/counter-0.01.tar.gz

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.