สร้างไฟล์ขนาดใหญ่อย่างรวดเร็วบนระบบ Linux


438

ฉันจะสร้างไฟล์ขนาดใหญ่บนระบบ Linux ( Red Hat Linux ) ได้อย่างรวดเร็วได้อย่างไร

ddจะทำงานได้ แต่การอ่าน/dev/zeroและเขียนจากไดรฟ์อาจใช้เวลานานเมื่อคุณต้องการไฟล์ที่มีขนาดหลายร้อย GB สำหรับการทดสอบ ... หากคุณต้องทำซ้ำหลาย ๆ ครั้งเวลาจะเพิ่มขึ้นอย่างแท้จริง

ฉันไม่สนใจเนื้อหาของไฟล์ฉันแค่อยากให้มันสร้างขึ้นอย่างรวดเร็ว สิ่งนี้สามารถทำได้?

การใช้ไฟล์ sparse จะไม่ทำงานสำหรับสิ่งนี้ ฉันต้องการไฟล์เพื่อจัดสรรพื้นที่ดิสก์


1
Ext4 มีประสิทธิภาพการจัดสรรไฟล์ที่ดีกว่ามากเนื่องจากบล็อกทั้งหมดที่มีขนาดสูงสุด 100MB สามารถจัดสรรได้ในครั้งเดียว
martinus

5
คำสั่ง 'truncate' จะสร้างไฟล์แบบเบาบาง เช่นดูen.wikipedia.org/wiki/Sparse_file
Jason Drew

2
ดูเหมือนว่าผู้คนจะมองข้าม "ไฟล์ที่กระจัดกระจายจะไม่สามารถใช้งานได้" โดยที่ไม่มีการตัดทอนและค้นหา DD ด้านล่าง
hpavc

1
คุณควรกำหนดสิ่งที่คุณหมายถึงโดย "สำหรับการทดสอบ" ทดสอบความเร็วในการเขียนของฮาร์ดดิสก์ของคุณ? ทดสอบสิ่งที่dfจะรายงาน ทดสอบแอพที่ทำบางสิ่งโดยเฉพาะ คำตอบขึ้นอยู่กับสิ่งที่คุณต้องการทดสอบ อย่างไรก็ตามฉันสายไปหน่อย - ฉันเห็นแล้วว่ามันเป็นเวลาหลายปีแล้วตั้งแต่คำถามของคุณ :-)
ndemou

1
ในกรณีที่คุณกำลังมองหาวิธีจำลองพาร์ติชันเต็มรูปแบบเหมือนฉันไม่ต้องมองไกล/ dev / full
Julian

คำตอบ:


509

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

ตัวอย่างเช่น:

fallocate -l 10G gentoo_root.img

5
เป็นไปได้ไหมที่ dd ใช้งานภายในแล้ว? ถ้าฉันทำ 'dd if = / dev / zero of = zerofile bs = 1G count = 1' บนเคอร์เนล 3.0.0 การเขียนจะเสร็จสิ้นภายใน 2 วินาทีโดยมีอัตราการเขียนข้อมูลมากกว่า 500 เมกะไบต์ต่อวินาที เห็นได้ชัดว่าเป็นไปไม่ได้ใน
ฮาร์ดไดรฟ์

21
fallocateเป็นสิ่งที่ฉันกำลังมองหา
AB

7
( fallocate) นี้จะไม่ทำงานบนระบบไฟล์ Linux ZFS ด้วย - github.com/zfsonlinux/zfs/issues/326
Joe

5
fallocate ไม่รองรับ ext3 เช่นกัน bugzilla.redhat.com/show_bug.cgi?id=563492
Eddie

3
ใน Debian GNU / Linux fallocateเป็นส่วนหนึ่งของutil-linuxแพ็คเกจ เครื่องมือนี้เขียนโดย Karel Zak จาก RedHat และซอร์สโค้ดสามารถพบได้ที่นี่: kernel.org/pub/linux/utils/util-linux
Franta

295

นี่เป็นคำถามที่พบบ่อยโดยเฉพาะในสภาพแวดล้อมปัจจุบันของสภาพแวดล้อมเสมือน น่าเสียดายที่คำตอบนั้นไม่ตรงไปตรงมาอย่างที่ใคร ๆ คิด

dd เป็นตัวเลือกแรกที่เห็นได้ชัด แต่ dd เป็นตัวคัดลอกและบังคับให้คุณเขียนบล็อกข้อมูลทุกอัน (เช่นการเริ่มต้นเนื้อหาไฟล์) ... และการเริ่มต้นนั้นเป็นสิ่งที่ใช้เวลา I / O มาก (ต้องการทำให้ใช้เวลานานขึ้นหรือไม่ใช้/ dev / randomแทน/ dev / ศูนย์ ! จากนั้นคุณจะใช้ CPU เช่นเดียวกับเวลา I / O!) ในที่สุดแม้ว่า dd เป็นตัวเลือกที่ไม่ดี ค่าเริ่มต้นที่ใช้โดย VM "สร้าง" GUIs) เช่น:

dd if=/dev/zero of=./gentoo_root.img bs=4k iflag=fullblock,count_bytes count=10G

truncateเป็นอีกทางเลือก - และน่าจะเร็วที่สุด ... แต่นั่นเป็นเพราะมันสร้าง "ไฟล์กระจัดกระจาย" โดยพื้นฐานแล้วไฟล์ที่กระจัดกระจายเป็นส่วนหนึ่งของดิสก์ที่มีข้อมูลจำนวนมากและระบบไฟล์พื้นฐาน "กลโกง" โดยไม่ได้เก็บข้อมูลทั้งหมดจริงๆ แต่เพียง "แกล้ง" ว่ามีทั้งหมด ดังนั้นเมื่อคุณใช้ truncate เพื่อสร้างไดรฟ์ 20 GB สำหรับ VM ของคุณระบบไฟล์จะไม่จัดสรร 20 GB แต่จะโกงและบอกว่ามีศูนย์ 20 GB ที่นั่นแม้ว่าจะมีแทร็กเดียวบนดิสก์เพียงเล็กน้อย อาจมีการใช้งานจริง ๆ เช่น:

 truncate -s 10G gentoo_root.img

fallocate เป็นครั้งสุดท้าย - และที่ดีที่สุด - ทางเลือกสำหรับการใช้งานกับการจัดสรรดิสก์ VM เพราะมันเป็นหลัก "สำรอง" (หรือ "จัดสรร" ทุกพื้นที่ที่คุณกำลังมองหา แต่ก็ไม่ได้รำคาญที่จะเขียนอะไรดังนั้น. เมื่อคุณใช้ fallocate เพื่อสร้างพื้นที่ว่างบนไดรฟ์เสมือน 20 GB คุณจะได้รับไฟล์ 20 GB (ไม่ใช่ "ไฟล์ที่กระจัดกระจาย" และคุณจะไม่ต้องกังวลที่จะเขียนอะไรลงไปซึ่งหมายความว่าทุกอย่างจะอยู่ใน มี - เช่นดิสก์ใหม่เอี่ยม!) เช่น:

fallocate -l 10G gentoo_root.img

4
+1 truncateทำงานบน JFS; fallocate, ไม่มากนัก. จุดหนึ่งที่คุณไม่สามารถรวมถึงทศนิยมในจำนวนที่ฉันต้องการที่จะระบุไม่ได้1536G 1.5T
Calrion

1
ตามที่ของฉันfallocateหน้าคนนี้ได้รับการสนับสนุนเฉพาะในbtrfs, ext4, ocfs2และxfsระบบไฟล์
นาธานเอสวัตสัน-Haigh

หมายเหตุswaponน่าเสียดายที่ใช้งานไม่ได้กับ extents ที่จัดสรรไว้ล่าสุดฉันก็ตรวจสอบแล้ว มีการถกเถียงในรายชื่อผู้รับจดหมาย XFS เกี่ยวกับการมีตัวเลือกการจัดสรรเพื่อเปิดเผยข้อมูลฟรีสปอตเก่าแทนและไม่มีขอบเขตที่ระบุว่าเป็นการจัดสรรล่วงหน้าดังนั้น swapon จะทำงานได้ แต่ฉันไม่คิดว่าจะมีอะไรเกิดขึ้น
Peter Cordes

1
FYI การพยายามอ่านข้อมูลมากเกินไปอาจ/dev/randomส่งผลให้ข้อมูลแบบสุ่มหมดและ"เมื่อพูลเอนโทรปีว่างเปล่าการอ่านจาก / dev / Random จะปิดกั้นจนกว่าจะมีการรวบรวมเสียงรบกวนจากสิ่งแวดล้อมเพิ่มเติม"ดังนั้นอาจต้องใช้เวลานานมากเวลานาน
Xen2050

154

Linux & ระบบไฟล์ทั้งหมด

xfs_mkfile 10240m 10Gigfile

Linux และระบบไฟล์บางส่วน (ext4, xfs, btrfs และ ocfs2)

fallocate -l 10G 10Gigfile

OS X, Solaris, SunOS และ UNIX อื่น ๆ

mkfile 10240m 10Gigfile

HP-UX

prealloc 10Gigfile 10737418240

คำอธิบาย

ลองmkfile <size>myfile ddเป็นทางเลือกของ ด้วย-nตัวเลือกขนาดจะถูกบันทึกไว้ แต่บล็อกดิสก์จะไม่ถูกจัดสรรจนกว่าข้อมูลจะถูกเขียนลงไป หากไม่มี-nตัวเลือกพื้นที่นั้นจะเต็มไปด้วยศูนย์ซึ่งหมายถึงการเขียนลงดิสก์ซึ่งหมายถึงการใช้เวลา

mkfileมาจาก SunOS และไม่สามารถใช้ได้ทุกที่ ระบบลีนุกซ์ส่วนใหญ่มีวิธีการxfs_mkfileทำงานที่เหมือนกันทุกประการและไม่ใช่แค่ในระบบไฟล์ XFS แม้จะมีชื่อก็ตาม มันรวมอยู่ในxfsprogs (สำหรับ Debian / Ubuntu) หรือแพ็คเกจที่มีชื่อคล้ายกัน

ระบบลีนุกซ์ส่วนใหญ่มีfallocate, ซึ่งทำงานบนระบบไฟล์บางระบบเท่านั้น (เช่น btrfs, ext4, ocfs2, และ xfs), แต่มันเร็วที่สุด, เพราะมันจัดสรรพื้นที่ทั้งหมดของไฟล์ (สร้างไฟล์ที่ไม่ใช่ช่องว่าง) แต่ไม่เริ่มต้นใด ๆ ของมัน


5
mkfile นี้คุณพูดอยู่ที่ไหนคนแปลกหน้า? มันไม่ได้อยู่ในการติดตั้ง RHEL เริ่มต้น
paxdiablo

2
มันเป็นโปรแกรมโซลาริส หากคุณค้นหา gpl mkfile คุณจะพบตัวอย่างซอร์สโค้ด
Martin Beckett

5
ทำงานเป็น charme บน OS X:mkfile 1g DELETE_IF_LOW_ON_SSD_SPACE.img
Volker Rose

2
xfs_mkfileรวมอยู่ในxfsprogsบน Ubuntu และใช้งานได้ดีใน ext3 fs ของฉัน :)
Greg Dubicki

97
truncate -s 10M output.file

จะสร้างไฟล์ 10 M ทันที (M หมายถึง 1024 * 1024 ไบต์, MB ย่อมาจาก 1,000 * 1,000 - เหมือนกับ K, KB, G, GB ... )

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

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

แต่นี่ก็ยังเป็นคำสั่งที่มีประโยชน์ที่ต้องรู้


1
พยายามทำสิ่งนี้ แต่ไม่มีผลกับพื้นที่ว่างในดิสก์ ต้องเพราะมันเป็นไฟล์กระจัดกระจายตามที่อธิบายไว้ก่อนหน้า
Gringo Suave

7
นี่ไม่ควรเป็นคำตอบอันดับต้นเนื่องจากไม่สามารถแก้ปัญหาfallocateได้
Gringo Suave

4
@GringoSuave แต่นี่ก็ยังมีประโยชน์สำหรับบางคนที่อาจมีปัญหาคล้ายกัน แต่แตกต่างกันเล็กน้อย
AJMansfield

@GringoSuave: ดูเหมือนว่าจะสร้างไฟล์ขนาดใหญ่ตามที่ร้องขอทำไมมันไม่แก้ปัญหา? นอกจากนี้ยังมีบันทึกย่อภายใต้คำตอบที่ล้มเหลวซึ่งส่วนใหญ่จะไม่ทำงาน
Pavel Šimerda

1
ทำไมแนะนำให้สร้างไฟล์แบบเบาบางเมื่อเขาบอกว่ามันใช้ไม่ได้
hpavc

44

โดยที่ find คือขนาดของไฟล์ที่คุณต้องการเป็นไบต์ - 1

dd if=/dev/zero of=filename bs=1 count=1 seek=1048575

6
ฉันชอบวิธีนี้ แต่ผู้วิจารณ์ไม่ต้องการไฟล์ที่กระจัดกระจายด้วยเหตุผลบางอย่าง :(
ephemient

3
dd if = / dev / zero of = 1GBfile bs = 1,000 count = 1000000
ดาเมียน

7
dd if = / dev / zero of = 01GBfile bs = 1024 count = $ ((1024 * 1024))
Xavier Decoret

1
สำหรับไฟล์ที่กระจัดกระจายtruncateดูเหมือนว่าจะดีขึ้นมาก
Pavel Šimerda

36

ตัวอย่างที่ค้นหาคือขนาดของไฟล์ที่คุณต้องการในหน่วยไบต์

#kilobytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200K

#megabytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200M

#gigabytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200G

#terabytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200T


จาก dd manpage:

บล็อกและ BYTES อาจตามด้วยคำต่อท้ายแบบคูณต่อไปนี้: c = 1, w = 2, b = 512, kB = 1000, K = 1024, MB = 1000 * 1000, M = 1024 * 1024, GB = 1000 * 1000 * 1,000, G = 1024 * 1024 * 1024 และอื่น ๆ สำหรับ T, P, E, Z, Y


ลักษณะนี้ดีกว่าn-1truncateวิธีจึงเป็นพื้นเทียบเท่ากับ
Pavel Šimerda

19

วิธีสร้างไฟล์ 1 GB:

dd if=/dev/zero of=filename bs=1G count=1

7
ฉันเชื่อว่าการนับจะต้องเป็น 1 (ทดสอบกับ centos)
SvennD

dd if=/dev/zero of=filename bs=20G count=1จะสร้างไฟล์ 2GB เท่านั้น! ไม่ใช่ 20GB
Maulik Gangani

18

ฉันไม่รู้มากเกี่ยวกับลีนุกซ์ แต่นี่คือรหัส C ที่ฉันเขียนลงไฟล์ปลอมขนาดใหญ่ใน DC Share เมื่อหลายปีก่อน

#include < stdio.h >
#include < stdlib.h >

int main() {
    int i;
    FILE *fp;

    fp=fopen("bigfakefile.txt","w");

    for(i=0;i<(1024*1024);i++) {
        fseek(fp,(1024*1024),SEEK_CUR);
        fprintf(fp,"C");
    }
}

จะต้องมีวิธีการที่ดีกว่าใน C. คุณต้องปิดไฟล์ด้วย วนซ้ำเป็นล้านเขียนครั้งละ 1 ตัวอักษร ...
ACV

10

คุณสามารถใช้คำสั่ง "ใช่" ได้เช่นกัน ไวยากรณ์ค่อนข้างง่าย:

#yes >> myfile

กด "Ctrl + C" เพื่อหยุดสิ่งนี้มิฉะนั้นจะหมดพื้นที่ว่างของคุณ

เพื่อล้างไฟล์นี้ให้เรียกใช้:

#>myfile

จะล้างไฟล์นี้


7

ฉันไม่คิดว่าคุณจะได้เร็วกว่า dd มากนัก คอขวดคือดิสก์ การเขียนข้อมูลหลายร้อย GB ลงไปนั้นใช้เวลานานไม่ว่าคุณจะทำอะไร

แต่นี่เป็นความเป็นไปได้ที่อาจใช้ได้กับแอปพลิเคชันของคุณ หากคุณไม่สนใจเกี่ยวกับเนื้อหาของไฟล์วิธีการเกี่ยวกับการสร้างไฟล์ "เสมือน" ที่มีเนื้อหาเป็นเอาท์พุทแบบไดนามิกของโปรแกรม? แทนที่จะเปิด () ไอเอ็นจีไฟล์ให้ใช้ popen () เพื่อเปิดไพพ์ไปยังโปรแกรมภายนอก โปรแกรมภายนอกสร้างข้อมูลทุกครั้งที่จำเป็น เมื่อไพพ์เปิดแล้วมันจะทำหน้าที่เหมือนกับไฟล์ปกติที่โปรแกรมที่เปิดไพพ์นั้นสามารถ fseek () ย้อนกลับ () ฯลฯ คุณจะต้องใช้ pclose () แทนที่จะปิด () เมื่อคุณ ทำกับท่อ

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


4

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

ตัวอย่างเช่นมีกลุ่มของไฟล์ที่เรียกว่า:

  • / home / bigfiles / 512M-A
  • / home / bigfiles / 512M-B
  • / home / bigfiles / 1024M-A
  • / home / bigfiles / 1024M-B

จากนั้นหากคุณมีแอปพลิเคชันที่ต้องการไฟล์ 1G ชื่อ / home / oracle / logfile ให้รัน "ln /home/bigfiles/1024M-A /home/oracle/logfile "

หากอยู่ในระบบไฟล์แยกต่างหากคุณจะต้องใช้ลิงก์สัญลักษณ์

ไฟล์ A / B / etc สามารถใช้เพื่อให้แน่ใจว่าไม่มีการใช้ที่ขัดแย้งกันระหว่างแอปพลิเคชันที่ไม่เกี่ยวข้อง

การดำเนินการเชื่อมโยงนั้นเร็วพอ ๆ กับที่คุณจะได้รับ


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

3

GPL mkfile เป็นเพียง wrapper สคริปต์ (ba) sh รอบ dd; mkfile ของ BSD เพียงแค่จดจำบัฟเฟอร์ด้วย non-zero และเขียนมันซ้ำ ๆ ฉันจะไม่คาดหวังว่าอดีตที่จะออกเดท dd หลังอาจขอบออก dd ถ้า = / dev / ศูนย์เล็กน้อยเนื่องจากละเว้นการอ่าน แต่สิ่งที่ไม่ดีขึ้นอย่างมีนัยสำคัญอาจเป็นเพียงการสร้างไฟล์กระจัดกระจาย

ขาดการเรียกระบบที่จัดสรรพื้นที่สำหรับไฟล์โดยไม่ต้องเขียนข้อมูล (และ Linux และ BSD ขาดสิ่งนี้อาจเป็น Solaris เช่นกัน) คุณอาจได้รับการปรับปรุงประสิทธิภาพเล็กน้อยโดยใช้ ftrunc (2) / truncate (1) เพื่อขยายไฟล์ ตามขนาดที่ต้องการให้ mmap ไฟล์ลงในหน่วยความจำแล้วเขียนข้อมูลที่ไม่เป็นศูนย์ไปยังไบต์แรกของทุกบล็อกดิสก์ (ใช้ fgetconf เพื่อค้นหาขนาดบล็อกดิสก์)


4
BSD และ Linux มี fallocate จริง ๆ (แก้ไข: ตอนนี้ POSIX และวางจำหน่ายอย่างกว้างขวาง)
Tobu

3

ปลั๊กไร้ยางอาย: OTFFS จัดให้มีระบบไฟล์ที่มีขนาดใหญ่ตามอำเภอใจ (ดีเกือบ Exabytes เป็นขีด จำกัด ปัจจุบัน) ของเนื้อหาที่สร้างขึ้น มันเป็น Linux เท่านั้น, C ธรรมดาและในช่วงต้นอัลฟา

ดูhttps://github.com/s5k6/otffs


3

นี่เป็นวิธีที่เร็วที่สุดที่ฉันสามารถทำได้ (ซึ่งไม่เร็ว) ด้วยข้อ จำกัด ดังต่อไปนี้:

  • เป้าหมายของไฟล์ขนาดใหญ่คือการเติมดิสก์ดังนั้นจึงไม่สามารถบีบอัดได้
  • การใช้ระบบไฟล์ ext3 ( fallocateไม่พร้อมใช้งาน)

นี่คือส่วนสำคัญของมัน ...

// include stdlib.h, stdio.h, and stdint.h
int32_t buf[256]; // Block size.
for (int i = 0; i < 256; ++i)
{
    buf[i] = rand(); // random to be non-compressible.
}
FILE* file = fopen("/file/on/your/system", "wb");
int blocksToWrite = 1024 * 1024; // 1 GB
for (int i = 0; i < blocksToWrite; ++i)
{
   fwrite(buf, sizeof(int32_t), 256, file);
}

ในกรณีของเรานี่เป็นระบบลินุกซ์ในตัวและทำงานได้ดี แต่จะต้องการอะไรที่เร็วกว่า

FYI คำสั่งdd if=/dev/urandom of=outputfile bs=1024 count = XXช้ามากจนใช้ไม่ได้

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