du ให้ผลลัพธ์ที่แตกต่างกันสองไฟล์สำหรับไฟล์เดียวกัน


23

ฉันเป็นนักศึกษาระดับบัณฑิตศึกษาสาขาเคมีเชิงคอมพิวเตอร์ที่มีการเข้าถึงคลัสเตอร์ Linux คลัสเตอร์ประกอบด้วยเซิร์ฟเวอร์ไฟล์ที่มีขนาดใหญ่มาก (25 TB) ซึ่งมีการเชื่อมต่อโหนดการคำนวณหลายโหล แต่ละโหนดการประมวลผลประกอบด้วยคอร์ Intel Xeon 8 ถึง 24 แกน แต่ละโหนดการคำนวณยังมีดิสก์ภายในตัวประมาณ 365 TB

เนื่องจาก fileserver มีการเข้าถึงเป็นประจำโดยผู้ใช้โหลหรือมากกว่านั้นในกลุ่มการวิจัยดังนั้นจึงมีการใช้ fileserver เป็นหลักสำหรับการจัดเก็บไฟล์ระยะยาว (มันถูกสำรองข้อมูลทุกคืน ดังนั้นผู้ดูแลระบบได้สั่งให้เรารันการจำลองบนดิสก์ภายในเครื่อง - ซึ่งมี I / O ที่เร็วกว่า fileserver - เพื่อไม่ให้ช้าลง fileserver สำหรับผู้ใช้รายอื่น

ดังนั้นฉันรันการจำลองบนดิสก์ภายในแล้วหลังจากเสร็จสิ้นฉันคัดลอกไฟล์วิถี - ฉันใช้การจำลองโมเลกุล (MD) - ไปยังไฟล์เซิร์ฟเวอร์เพื่อเก็บข้อมูล สมมติว่าฉันมีไฟล์ที่เรียกว่าวิถีในไดเรกทอรีบนดิสก์ท้องถิ่นของโหนดtraj.trr /home/myusername/mysimulation1/traj.trrสำหรับการจัดเก็บระยะยาวผมมักจะคัดลอกtraj.trrไปยังไดเรกทอรีใน fileserver ที่เป็น~/mysimulation1/traj.trrที่~หมายถึงไดเรกทอรีของฉันใน fileserver /export/home/myusernameที่ หลังจากคัดลอกแล้วฉันเป็นปกติวิสัยใช้du -hเพื่อตรวจสอบว่ามีขนาดของไฟล์เช่นเดียวกับ/home/myusername/mysimulation1/traj.trr ~/mysimulation1/traj.trrด้วยวิธีนี้ฉันอย่างน้อยก็สามารถมั่นใจได้ว่าการถ่ายโอนไปยัง fileserver สำเร็จ ตัวอย่างเช่น:

cd /home/myusername/mysimulation1/
cp -v traj.trr ~/mysimulation1/
du /home/myusername/mysimulation1/traj.trr -h
du ~/mysimulation1/traj.trr -h

หากการเรียกสองสายdu -hให้ขนาดไฟล์ที่มนุษย์อ่านได้เหมือนกันฉันก็มั่นใจได้ว่าการถ่ายโอน / การคัดลอกนั้นประสบความสำเร็จ ( traj.trrไฟล์ทั่วไปของฉันมีขนาดตั้งแต่ประมาณ 15 ถึง 20 GB ขึ้นอยู่กับการจำลองที่แน่นอนที่ฉันใช้) ถ้าฉันเรียกใช้du(เช่นไม่มี-hสวิตช์) บนtraj.trrไฟล์ทั้งสองขนาดของพวกเขาเป็นไบต์มักจะคล้ายกันมาก - - ปกติภายในไม่กี่ไบต์ ฉันใช้วิธีโดยรวมนี้ในปีครึ่งที่ผ่านมาโดยไม่มีปัญหา

อย่างไรก็ตามเมื่อเร็ว ๆ นี้ฉันพบปัญหาต่อไปนี้: บางครั้งdu -hรายงานว่าtraj.trrไฟล์ทั้งสองมีขนาดต่างกันหลาย GB นี่คือตัวอย่าง:

cd /home/myusername/mysimulation1/            # this is the local disk
cp -v traj.trr ~/mysimulation1/
du traj.trr -h
cd ~/mysimulation1/                           # this is the fileserver
du traj.trr -h

เอาต์พุตจากการเรียกทั้งสองไปdu -hเป็นดังนี้ตามลำดับ:

20G     traj.trr
28G     traj.trr

ฉันเชื่อว่าอดีต (เช่นtraj.trrในดิสก์ภายในเครื่อง/home/myusername/mysimulation1/) เป็นขนาดไฟล์ที่ถูกต้องเนื่องจากเส้นทางการจำลองของฉันคาดว่าจะมีขนาดประมาณ 15 ถึง 20 GB แต่แล้วไฟล์บนเซิร์ฟเวอร์ไฟล์จะมีขนาดใหญ่ขึ้นได้อย่างไร? ฉันสามารถดูว่ามันจะเล็กลงได้อย่างไรถ้าการcpถ่ายโอนล้มเหลว แต่ฉันไม่เห็นว่ามันจะใหญ่ขึ้นได้อย่างไร

ฉันได้รับเอาต์พุตที่คล้ายกันเมื่อฉันเรียกใช้คำสั่งเดียวกันกับข้างบน แต่ไม่มี-hสวิตช์ให้du:

20717480        traj.trr
28666688        traj.trr

คุณคิดด้วยเหตุผลต่าง ๆ กันไหม?

หากมีโอกาสที่ไม่น่าจะduเกิดขึ้นฉันก็โอเคกับเรื่องนั้นได้ แต่ฉันแค่ต้องตรวจสอบให้แน่ใจว่าสำเนาของtraj.trrบน fileserver นั้นสมบูรณ์และเหมือนกับเวอร์ชั่นต้นฉบับในโลคัลดิสก์ ฉันจำเป็นต้องลบไฟล์โลคัลเพื่อให้มีพื้นที่ดิสก์ในตัวเครื่องเพียงพอที่จะเรียกใช้การจำลองใหม่ แต่ฉันไม่สามารถที่จะมีรุ่นของtraj.trrไฟล์เซิร์ฟเวอร์เสียหาย

รูปแบบไฟล์ .trr (จากแพคเกจ Gromacs กลศาสตร์โมเลกุล)เป็นรูปแบบไบนารีไม่ข้อความ diffดังนั้นผมไม่แน่ใจว่าถ้าไฟล์ที่สามารถนำมาเปรียบเทียบได้อย่างน่าเชื่อถือโดยโปรแกรมเช่น


5
ลองเรียกใช้md5sumหรือsha1sumบนไฟล์ พวกเขาตรงกันหรือไม่
cjm

2
@cjm ฉันเพิ่งรันmd5sumไฟล์ทั้งสอง เช็คซัมทั้งสองตรงกัน ดังนั้นฉันเดาว่านี่หมายความว่าทั้งสองไฟล์เหมือนกันหรือไม่
แอนดรู

3
รายงานขนาดls -lใด คำสั่งduรายงานจำนวนพื้นที่บนดิสก์ที่ใช้สำหรับไฟล์ของคุณไม่ใช่ขนาดไฟล์ของคุณ ขนาดของดิสก์จะขึ้นอยู่กับระบบไฟล์และกลยุทธ์การจัดสรรของมัน
casey

2
@casey ls -l -hบอกว่าทั้งสองไฟล์มีขนาด 20 GB เช่นเดียวกันls -lกล่าวว่าทั้งสองไฟล์มีขนาด 21214683940 ไบต์ ดังนั้นฉันคิดว่าไฟล์มีขนาดเท่ากัน แต่อย่าใช้พื้นที่ดิสก์ในปริมาณเท่ากัน (ตามdu)
แอนดรู

2
@Andrew ระบุขนาดรายงานโดย ls เหมือนกันและแฮชเหมือนกันคุณสามารถสรุปไฟล์เหมือนกันได้ เครื่องมือเหล่านี้เป็นสิ่งที่ให้ความมั่นใจกับคุณและแสดงให้คุณเห็นว่า du ไม่ใช่เครื่องมือที่จะตอบสนองความต้องการของคุณ
casey

คำตอบ:


32

คุณควรใช้สิ่งที่ชอบmd5sumหรือsha1sumเพื่อตรวจสอบความสมบูรณ์

ถ้าคุณอยากที่จะใช้การใช้งานขนาดหรือls -ldu -b

โดยduปกติยูทิลิตี้จะแสดงการใช้งานดิสก์ของไฟล์เท่านั้นนั่นคือจะใช้ระบบไฟล์ในปริมาณเท่าใด ค่านี้ขึ้นอยู่กับระบบไฟล์สำรองและปัจจัยอื่น ๆ เช่นไฟล์แบบกระจาย

ตัวอย่าง:

$ truncate -s 512M foo
$ cat foo >bar
$ ls -l foo bar
-rw-r--r-- 1 michas users 536870912 23. Dez 00:06 bar
-rw-r--r-- 1 michas users 536870912 23. Dez 00:03 foo
$ du foo bar
0       foo
524288  bar
$ du -b foo bar
536870912       foo
536870912       bar

เรามีสองไฟล์ทั้งคู่มีค่าศูนย์ 512MB อันแรกจะถูกจัดเก็บกระจัดกระจายและไม่ได้ใช้พื้นที่ดิสก์ใด ๆ ในขณะที่สองเก็บแต่ละไบต์บนดิสก์อย่างชัดเจน - ไฟล์เดียวกัน แต่การใช้งานดิสก์แตกต่างกันโดยสิ้นเชิง

-bตัวเลือกที่อาจจะดีสำหรับคุณ:

   -b, --bytes
          equivalent to '--apparent-size --block-size=1'

   --apparent-size
          print apparent sizes, rather than disk usage; although the apparent
          size is  usually  smaller,  it  may  be  larger  due  to  holes  in
          ('sparse')  files, internal fragmentation, indirect blocks, and the
          like

8

นี่เป็นปัญหาที่พบบ่อยเมื่อคุณใส่ข้อมูลเดียวกันลงใน HDD ที่ต่างกัน 2 ตัว คุณจะต้องเรียกใช้duคำสั่งด้วยและสวิตช์เพิ่มเติมโดยสมมติว่ามี - ซึ่งควรให้สิ่งเหล่านี้คือโหนด Linux

สวิตช์?

   --apparent-size
          print  apparent  sizes,  rather  than  disk  usage;  although the 
          apparent size is usually smaller, it may be larger due to holes in
          ('sparse') files, internal fragmentation, indirect blocks, and the 
          like

ตัวอย่าง

$ du -sh --apparent-size /home/sam/scsconfig.log ~/scsconfig.log 
93K /home/sam/scsconfig.log
93K /root/scsconfig.log

ระบบไฟล์ข้างต้นเป็นดิสก์ภายในเครื่อง ( /root) ในขณะที่อีก/home/samระบบหนึ่งใช้ NFS ร่วมกันจาก NAS ของฉัน

$ df -h . /home/sam
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
                      222G  118G   92G  57% /
mulder:/export/raid1/home/sam
                      917G  566G  305G  65% /home/sam

เป็นยังไงบ้าง?

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

ใช้ checksum แทนหรือไม่

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

$ cd /some/dir
$ find . -type f \( -exec sha1sum "{}" \; \) | sort -k2,2 | sha1sum

ตัวอย่าง

$ cd ~/dir1
$ find . -type f \( -exec sha1sum "{}" \; \) | sort -k2,2 | sha1sum
55e2672f8d6fccff6d83f0bffba1b67aeab87911  -

$ cd ~/dir2
$ find . -type f \( -exec sha1sum "{}" \; \) | sort -k2,2 | sha1sum
55e2672f8d6fccff6d83f0bffba1b67aeab87911  -

ดังนั้นเราจะเห็นได้ว่าต้นไม้ 2 ต้นนั้นเหมือนกัน

(หมายเหตุ: คำสั่ง find จะแสดงรายการไฟล์ตามที่ปรากฏในระบบไฟล์ดังนั้นหากคุณเปรียบเทียบสองไดเรกทอรีจากระบบไฟล์ที่แตกต่างกัน (เช่น Ext3 กับ APFS) คุณจะต้องเรียงลำดับก่อน sha1sum ขั้นสุดท้าย (เพิ่มโดย เซียนจุนตง)


5

คำตอบสั้น ๆ : อย่าทดสอบขนาดไฟล์ทดสอบสถานะการส่งคืนของคำสั่ง สถานะการส่งคืนเป็นเพียงตัวบ่งชี้ที่เชื่อถือได้ว่าการคัดลอกนั้นประสบความสำเร็จหรือไม่ (เปรียบเทียบจากสองไฟล์ไบต์ต่อไบต์โดยตรงโดยอ้อม - ซึ่งซ้ำซ้อนหากสำเนาสำเร็จ)

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

คำสั่ง Unix ทั้งหมดส่งคืนสถานะเพื่อบ่งชี้ว่าสำเร็จ: 0 สำหรับความสำเร็จ, 1 ข้อขึ้นไปสำหรับข้อผิดพลาด cpเพื่อตรวจสอบสถานะออกจาก cpโดยปกติจะพิมพ์ข้อความแสดงข้อผิดพลาดหากไม่สามารถระบุได้ว่าเป็นข้อผิดพลาด $?ในสคริปต์ออกจากสถานะของคำสั่งสุดท้ายที่อยู่ในตัวแปรมายากล

cp -v traj.trr ~/mysimulation1/
if [ $? -ne 0 ]; then
  echo 1>&2 "cp failed due to the error above"
  exit 2
 fi

แทนที่จะตรวจสอบว่า$?เป็นศูนย์หรือไม่คุณสามารถใช้โอเปอเรเตอร์บูลีนได้

cp -v traj.trr ~/mysimulation1/ || exit 2

set -eหากคุณกำลังใช้สคริปต์และต้องการสคริปต์เพื่อหยุดถ้าคำสั่งใดไม่วิ่ง หากคำสั่งใด ๆ ล้มเหลว (เช่นส่งคืนสถานะที่ไม่เป็นศูนย์) สคริปต์จะออกทันทีพร้อมสถานะเดียวกับคำสั่ง

set -e
…
cp -v traj.trr ~/mysimulation1/

สำหรับเหตุผลที่ไฟล์คัดลอกของคุณมีขนาดใหญ่ก็ต้องเป็นเพราะมันเป็นไฟล์เบาบาง ไฟล์กระจัดกระจายเป็นรูปแบบดิบของการบีบอัดที่บล็อกที่มีเพียง null ไบต์จะไม่ถูกเก็บไว้ เมื่อคุณคัดลอกไฟล์cpคำสั่งจะอ่านและเขียนไบต์ว่างดังนั้นที่ต้นฉบับมีบล็อกที่ขาดหายไปสำเนาจะมีบล็อกเต็มไปด้วยไบต์ว่าง ภายใต้ Linux cpคำสั่งจะพยายามตรวจหาไฟล์ที่กระจัดกระจาย แต่ไม่ประสบความสำเร็จเสมอไป cp --sparse=alwaysทำให้ลองได้ยากขึ้นโดยเสียเวลาเพิ่มขึ้นเล็กน้อยของ CPU

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


ขอบคุณมาก! คุณรู้หรือไม่ว่ามียูทิลิตี้ (แยกต่างหาก) ที่สามารถบอกฉันได้ว่าไฟล์ของฉันกระจัดกระจายหรือไม่?
แอนดรู

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