เหตุใดการย้ายไฟล์บางไฟล์ในโฟลเดอร์จึงใช้เวลานานกว่าการย้ายทั้งโฟลเดอร์


21

ฉันมีรูปภาพนับล้านบนเซิร์ฟเวอร์คลาวด์ Ubuntu ของฉัน เมื่อฉันย้ายโฟลเดอร์ทั้งหมดที่มีmvคำสั่ง12 ล้านภาพโดยใช้คำสั่งมันจะเกิดขึ้นเกือบจะทันที อย่างไรก็ตามเมื่อฉันmvมีเพียงภาพ (ไม่ใช่โฟลเดอร์) ก็ใช้เวลาพอสมควร มีวิธีในการย้ายภาพทั้งหมดอย่างรวดเร็วเท่ากับโฟลเดอร์หรือไม่?

นี่คือสิ่งที่เกิดขึ้น:

  1. โฟลเดอร์ src มีภาพ 12 ล้านภาพและฉันย้ายมันไปยังโฟลเดอร์ dst โดยใช้

    $ mv  src ../dst
    

    เกิดขึ้นทันที

  2. ภายในโฟลเดอร์ src ฉันทำสิ่งนี้เพื่อย้าย:

    find -maxdepth 1 -name '*.jpg' -exec mv -t ../../dst/ {} +
    

    ใช้เวลาพอสมควร

มีวิธีเร่งกระบวนการที่สองหรือไม่?


1
ไม่ใช่วิธีแก้ปัญหา - แต่เพื่อชี้แจง: cmd2 จะต้องช้ากว่าแล้วจึงใช้ cmd1 เนื่องจากใช้ find แล้วจึงทำการย้ายเพื่อให้ได้ผลลัพธ์ สิ่งนี้ไม่สามารถทำได้เร็วเท่ากับการเคลื่อนที่โดยตรงโดยไม่ต้องทำการค้นหาล่วงหน้า
dufte

อาจdstอยู่ในพาร์ติชันในขณะที่../../dstอยู่ในอีก
phuclv

ตามที่เขียนไว้นี้ไม่ได้ดูเหมือนคำค้นหาที่ถูกต้อง มันไม่มี{}ข้อโต้แย้งใด ๆที่ชื่อไฟล์จะถูกขยาย
. ..

ฉันส่งการแก้ไขที่เปลี่ยนแปลงชื่อโดยลบการอ้างอิงถึง "รูปภาพ" และแทนที่ด้วยหมายเลขของเรื่อง - มันเป็นการย้ายไฟล์แต่ละไฟล์เทียบกับการย้ายทั้งโฟลเดอร์ ฉันหวังว่ามันจะเป็นที่ยอมรับของใครบางคนพร้อมตัวแทนที่จะทำ
Monty Harder

1
findมันไม่ได้เป็นที่ถูกต้องของการภาวนา find ... -exec mv -t ../../dst/ {} \;จะเรียกmvหนึ่งครั้งต่อไฟล์; find ... -exec mv -t ../../dest {} +จะได้เร็วขึ้นมาก, การคัดลอกไฟล์จำนวนมากต่อการโทรที่เป็นไปได้ แต่ก็ยังไม่เป็นอย่างที่ย้ายไดเรกทอรีตัวเองเป็นที่อธิบายไว้โดย dadexix86
chepner

คำตอบ:


50

TL; DR : ไม่

สำหรับไฟล์จำนวนน้อยคุณไม่จำเป็นต้องใช้findแม้ในกรณีที่ง่ายและเล็กกว่านี้หากคุณต้องการ

mv *.jpg ../../dst/

จะใช้เวลามากกว่าการย้ายไดเรกทอรีทั้งหมดในครั้งเดียว


ทำไม? ประเด็นคือต้องเข้าใจสิ่งที่mvไม่

พูดสั้น ๆmvย้ายตัวเลข (ที่ระบุไดเรกทอรีหรือไฟล์) จาก inode (ไดเรกทอรีที่มีมัน) ไปยังอีกและดัชนีเหล่านี้มีการปรับปรุงในวารสารของระบบไฟล์หรือใน FAT (ถ้าระบบไฟล์ ถูกนำไปใช้ในทางดังกล่าว)

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

ดังนั้นเมื่อคุณmv หนึ่งไดเรกทอรีคุณกำลังทำการดำเนินการนี้ในครั้งเดียว

แต่เมื่อคุณย้าย1,000,000ไฟล์ที่คุณกำลังทำดำเนินการนี้1,000,000 ครั้ง

เพื่อให้เป็นตัวอย่างในทางปฏิบัติคุณมีต้นไม้ที่มีกิ่งไม้มากมาย โดยเฉพาะอย่างยิ่งมีโหนดหนึ่งโหนดที่เชื่อมต่อกับ 1 ล้านสาขา
หากต้องการลดกิ่งเหล่านี้และย้ายไปที่อื่นคุณสามารถตัดแต่ละอันเพื่อให้คุณตัด 1 ล้านหรือตัดก่อนโหนดจึงตัดเพียงครั้งเดียว (นี่คือความแตกต่างระหว่างการย้ายไฟล์และ ไดเรกทอรี)


4
คุณควรรวมไว้ว่าmvในระบบไฟล์เดียวกันเป็นเพียงการเขียนรายการ TOC
Videonauth

ฉันไม่แน่ใจว่าฉันเข้าใจความหมายของ TOC เท่าที่ฉันรู้ไม่มีตารางในระบบไฟล์ ext หรือ NTFS หรือ btrfs และอื่น ๆ FAT มีตาราง (ซึ่งใช้ชื่อ) แต่ยกตัวอย่างชื่อร้านค้าและบล็อกและผู้ปกครองเด็กและข้อมูลอื่น ๆ ใน inodes หากคุณสามารถชี้ให้ฉันดูที่การอ้างอิงซึ่งมีการอธิบายว่าส่วนขยายของ FS มี TOC ของพวกเขาที่ไหนและใช้สำหรับอะไรฉันยินดีที่จะอ่านและอัปเดตคำตอบ :)
dadexix86

10
หนอ mv *.jpgมีแนวโน้มที่จะล้มเหลว 12 ล้านไฟล์ซึ่งเป็นสาเหตุที่เขาใช้ค้นหา ส่วนใหญ่ Unixes, Linux รวมอยู่ด้วยฉันเชื่อว่า (ยกเว้นบางคนเปลี่ยนไปในช่วง 5-10 ปีที่ผ่านมา) มีความยาวสูงสุดของบรรทัดคำสั่ง จำกัด ฉันคิดว่ามันเป็น 64K สำหรับ Linux มาเป็นเวลานาน ข้อ จำกัด เดียวกันนี้ใช้กับตัวแปรสภาพแวดล้อมฉันค่อนข้างแน่ใจ
Zan Lynx

1
ย้ายไฟล์ที่มีมากขึ้นเกี่ยวกับการย้ายของชื่อ รายการไดเรกทอรีที่คล้าย Unix จะมีชื่อไฟล์และหมายเลข inode ซึ่งเป็นตัวชี้ไปยังส่วนที่เหลือของข้อมูลเมตา ไดเรกทอรีเป็นไฟล์ชนิดพิเศษ ไอโหนดนั้นไม่มีข้อมูลจริงของไฟล์เพียงชี้ไปที่มันดังนั้นจึงมีความเข้าใจผิดเล็กน้อยที่จะบอกว่ามีอะไรที่ถูกย้ายจากไอโหนด ในทางตรงกันข้ามวารสารระบบไฟล์มักจะอ้างถึงประเภทของบันทึกข้อมูลเมตาส่วนใหญ่ที่ใช้สำหรับการพิสูจน์อักษรผิดพลาด
ilkkachu

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

13

มันจะยังคงช้าเพราะตามที่ระบุไว้ระบบไฟล์จะต้องเชื่อมโยงชื่อไฟล์แต่ละไฟล์ไปยังตำแหน่งใหม่

อย่างไรก็ตามคุณสามารถเร่งความเร็วได้จากสิ่งที่คุณมีตอนนี้

คำสั่ง find ของคุณรัน exec หนึ่งครั้งสำหรับแต่ละไฟล์ ดังนั้นจึงเรียกใช้mvคำสั่ง 12 ล้านครั้งสำหรับไฟล์ 12 ล้านไฟล์ สามารถปรับปรุงได้สองวิธี

  • เพิ่มเครื่องหมายบวกท้าย:
    find -maxdepth 1 -name '*.jpg' -exec mv -t ../../dst/ +
    ตรวจสอบ man-page เพื่อให้แน่ใจว่ารองรับในเวอร์ชันของfindคุณ ผลที่ได้คือควรเรียกใช้ชุดmvคำสั่งที่มีชื่อไฟล์มากที่สุดเท่าที่จะพอดีกับแต่ละบรรทัดคำสั่ง

  • ใช้findและxargsร่วมกัน จะใช้ NUL อาคาศูนย์ไบต์จะแยกชื่อไฟล์ บวกนี้แก้ไขปัญหาใด ๆ ที่จะมีช่องว่างในชื่อไฟล์ คำสั่งจะอ่านรายชื่อไฟล์จากคำสั่งและเรียกใช้คำสั่งบนเป็นชื่อไฟล์มากที่สุดเท่าที่จะพอดี
    find -maxdepth 1 -name '*.jpg' -print0 | xargs -0 mv -t ../../dst/
    -print0xargs -0xargsxargsfindmv


7

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

เมื่อคุณ "ย้าย" ไฟล์ภายในระบบไฟล์ไฟล์จริงจะไม่ไปไหน ค่อนข้างรายการภายในไดเรกทอรีได้รับการปรับปรุงเพื่อสะท้อนการเปลี่ยนแปลง

mv src ../dstย้ายรายการเดียวจากไดเรกทอรี.ไปยังไดเรกทอรี../dstดังนั้นจึงรวดเร็ว

find -maxdepth 1 -name '*.jpg' -exec mv -t ../../dst/ต้องย้ายรายการหลายล้านรายการดังนั้นจึงช้ากว่า อาจเพิ่มความเร็วได้ถ้าคุณโทรmvเพียงครั้งเดียวและไม่ใช่หนึ่งครั้งต่อหนึ่งไฟล์และmvคำสั่งนั้นอาจถูกปรับให้เหมาะสมเพื่อย้ายรายการไดเรกทอรีหลายรายการในขั้นตอนเดียว แต่ไม่มีวิธีที่จะทำให้มันเร็วเท่าเมื่อคุณย้ายไดเรกทอรีเดียว .


4

คำตอบที่ง่าย

การย้ายไฟล์ทำได้ 3 ขั้นตอน:

  • เพิ่ม () ลิงค์ไปยังไฟล์ไปยังรายการ inode ของโฟลเดอร์ปลายทาง
  • ตรวจสอบว่าลิงค์ถูกเพิ่มเรียบร้อยแล้ว
  • ลบ () ลิงค์จากรายการ inodes ของโฟลเดอร์ต้นทางหากการตรวจสอบข้างต้นประสบความสำเร็จ

กระบวนการนี้เหมือนกันสำหรับไฟล์หรือโฟลเดอร์
และแน่นอนว่าการทำเช่นนี้สำหรับ 1 ไฟล์นั้นเร็วกว่าการทำ 100 ไฟล์สำหรับ 100 ไฟล์

man link คือการเพิ่ม ()
man unlinkคือการลบ ()
mvเพียงแค่ใช้สองคำสั่งข้างต้นและเพิ่มการตรวจสอบในระหว่างเพื่อป้องกันข้อมูลสูญหาย


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