Làm thế nào tôi có thể xác định nếu chạy tar sẽ làm cho đĩa đầy


22

Nếu tôi chạy tar -cvftrên một thư mục có kích thước 937MB để tạo một bản sao có thể tải xuống dễ dàng của cấu trúc thư mục được lồng sâu, tôi có nguy cơ lấp đầy đĩa được cung cấp df -hđầu ra sau không :

/dev/xvda1            7.9G  3.6G  4.3G  46% /
tmpfs                 298M     0  298M   0% /dev/shm

Câu hỏi liên quan:

  • Nếu đĩa có thể lấp đầy, tại sao tức là Linux (Amazon AMI) và / hoặc tarsẽ làm gì dưới mui xe?
  • Làm thế nào tôi có thể tự xác định chính xác thông tin này mà không cần hỏi lại?

Tôi không chắc nếu có thể mà không xử lý kho lưu trữ, nhưng bạn có thể chơi xung quanh với --totalstùy chọn. Dù bằng cách nào, nếu bạn lấp đầy đĩa, bạn chỉ cần xóa kho lưu trữ, imho. Để kiểm tra tất cả các tùy chọn có sẵn, bạn có thể đi qua tar --help.
UVV

4
Tiếp theo: không tạo tarfile dưới dạng root, một phần trăm không gian nhất định trên đĩa được dành riêng cho root, chính xác là kiểu "Tôi đã lấp đầy đĩa và bây giờ tôi không thể đăng nhập vì điều đó sẽ ghi. bash_history hoặc bất cứ điều gì "tình huống.
Ulrich Schwarz

Câu trả lời:


24

tar -c data_dir | wc -c không nén

hoặc là

tar -cz data_dir | wc -c với nén gzip

hoặc là

tar -cj data_dir | wc -c với nén bzip2

sẽ in kích thước của kho lưu trữ sẽ được tạo bằng byte, mà không ghi vào đĩa. Sau đó, bạn có thể so sánh với lượng không gian trống trên thiết bị mục tiêu của mình.

Bạn có thể kiểm tra kích thước của chính thư mục dữ liệu, trong trường hợp giả định không chính xác được thực hiện về kích thước của nó, bằng lệnh sau:

du -h --max-depth=1 data_dir

Như đã trả lời, tar thêm một tiêu đề cho mỗi bản ghi trong kho lưu trữ và cũng làm tròn kích thước của mỗi bản ghi thành bội số 512 byte (theo mặc định). Sự kết thúc của một kho lưu trữ được đánh dấu bằng ít nhất hai bản ghi không đầy liên tiếp. Vì vậy, luôn luôn có trường hợp bạn sẽ có một tệp tar không nén lớn hơn chính các tệp, số lượng tệp và cách chúng căn chỉnh theo ranh giới 512 byte xác định không gian thêm được sử dụng.

Tất nhiên, bản thân các hệ thống tệp sử dụng kích thước khối có thể lớn hơn nội dung của một tệp riêng lẻ, vì vậy hãy cẩn thận khi bạn gỡ bỏ nó, hệ thống tệp có thể không chứa được nhiều tệp nhỏ mặc dù nó có không gian trống lớn hơn kích thước tar!

https://en.wikipedia.org/wiki/Tar_(computing)#Format_details


Cảm ơn Jamie! '- mysql' đang làm gì ở đây? Đó có phải là tên tệp của bạn?
codecowboy

Chỉ cần thay đổi rằng ... đó là đường dẫn đến thư mục dữ liệu của bạn.
FantasticJamieBurns

1
Không phải là nó thực sự quan trọng, nhưng sử dụng kết hợp đối số -f -để tar là dư thừa, vì bạn có thể chỉ cần bỏ -fhoàn toàn đối số để viết kết quả vào thiết bị xuất chuẩn (tức là tar -c data_dir).

6

Kích thước của tệp tar của bạn sẽ là 937 MB cộng với kích thước của siêu dữ liệu cần thiết cho mỗi tệp hoặc thư mục (512 byte cho mỗi đối tượng) và đệm được thêm vào để căn chỉnh các tệp theo ranh giới 512 byte.

Một tính toán rất sơ bộ cho chúng tôi biết rằng một bản sao khác của dữ liệu của bạn sẽ để lại cho bạn 3,4 GB miễn phí. Trong 3,4 GB, chúng tôi có chỗ cho khoảng 7 triệu bản ghi siêu dữ liệu, giả sử không có phần đệm hoặc ít hơn nếu bạn giả sử trung bình 256 byte cho mỗi tệp. Vì vậy, nếu bạn có hàng triệu tệp và thư mục để tar, bạn có thể gặp vấn đề.

Bạn có thể giảm thiểu vấn đề bằng cách

  • nén khi đang bay bằng cách sử dụng zhoặc jtùy chọn đểtar
  • làm tarnhư một người dùng bình thường để không gian dành riêng trên /phân vùng sẽ không bị chạm nếu bạn hết dung lượng.

2

tarchính nó có thể báo cáo về kích thước của tài liệu lưu trữ của nó với --testtùy chọn:

tar -cf - ./* | tar --totals -tvf -

Lệnh trên không ghi gì vào đĩa và có thêm lợi ích của việc liệt kê các tệp riêng lẻ của từng tệp có trong tarball. Thêm các z/j/xztoán hạng khác nhau vào một trong hai bên |pipesẽ xử lý nén như bạn muốn.

ĐẦU RA:

...
-rwxr-xr-x mikeserv/mikeserv         8 2014-03-13 20:58 ./somefile.sh
-rwxr-xr-x mikeserv/mikeserv        62 2014-03-13 20:53 ./somefile.txt
-rw-r--r-- mikeserv/mikeserv       574 2014-02-19 16:57 ./squash.sh
-rwxr-xr-x mikeserv/mikeserv        35 2014-01-28 17:25 ./ssh.shortcut
-rw-r--r-- mikeserv/mikeserv        51 2014-01-04 08:43 ./tab1.link
-rw-r--r-- mikeserv/mikeserv         0 2014-03-16 05:40 ./tee
-rw-r--r-- mikeserv/mikeserv         0 2014-04-08 10:00 ./typescript
-rw-r--r-- mikeserv/mikeserv       159 2014-02-26 18:32 ./vlc_out.sh
Total bytes read: 4300943360 (4.1GiB, 475MiB/s)

Không hoàn toàn chắc chắn về mục đích của bạn, nhưng nếu đó là để tải tarball, thì điều này có thể đúng hơn:

ssh you@host 'tar -cf - ./* | cat' | cat >./path/to/saved/local/tarball.tar

Hoặc đơn giản là sao chép bằng tar:

ssh you@host 'tar -cf - ./* | cat' | tar -C/path/to/download/tree/destination -vxf -

Lý do tôi làm điều này là vì tôi tin rằng thư mục trong câu hỏi đã khiến đầu ra của df -i đạt 99%. Tôi muốn giữ một bản sao của thư mục để phân tích thêm nhưng muốn xóa khoảng trống
codecowboy

@codecowboy Trong trường hợp đó, bạn chắc chắn nên làm một cái gì đó như trên trước. Sau đó, nó sẽ tarsao chép cây vào đĩa cục bộ của bạn trong một luồng mà không lưu bất cứ thứ gì vào đĩa từ xa, sau đó bạn có thể xóa nó khỏi máy chủ từ xa và khôi phục nó sau. Có lẽ bạn nên thêm -zđể nén khi goldilocks chỉ ra, để tiết kiệm cho việc chuyển giữa băng thông.
mikeerv

@ TAFKA'goldilocks 'Không, bởi vì đó là 99% số nút, không phải 99% dung lượng.
Gilles 'SO- ngừng trở nên xấu xa'

-iđúng rồi, xin lỗi
goldilocks

@mikeserv dòng mở đầu của bạn đề cập đến tùy chọn --test nhưng sau đó bạn dường như không sử dụng nó trong lệnh của bạn mà ngay lập tức sau (nó sử dụng --totals)
codecowboy

2

Tôi đã thực hiện rất nhiều nghiên cứu về điều này. Bạn có thể làm một bài kiểm tra trên tệp với số từ nhưng nó sẽ không cung cấp cho bạn số thứ tự giống như a du -sb adir.

tar -tvOf afile.tar | wc -c

duđếm mỗi thư mục là 4096 byte và tarđếm các thư mục là 0 byte. Bạn phải thêm 4096 vào mỗi thư mục:

$(( $(tar -tvOf afile.tar 2>&1 | grep '^d' | wc -l) * 4096)))

sau đó bạn phải thêm tất cả các ký tự. Đối với một cái gì đó trông như thế này:

$(( $(tar -tvOf afile.tar 2>&1 | grep '^d' | wc -l) * 4096 + $(tar -xOf afile.tar | wc -c) ))

Tôi không chắc liệu điều này có hoàn hảo hay không vì tôi đã không thử các tệp đã bị chạm (các tệp 0 byte) hoặc các tệp có 1 ký tự. Điều này sẽ giúp bạn gần gũi hơn.


1

-cvfkhông bao gồm bất kỳ nén nào, do đó, việc thực hiện trên thư mục ~ 1 GB sẽ dẫn đến tệp tar ~ 1 GB (câu trả lời của Flub có nhiều chi tiết hơn về kích thước bổ sung trong tệp tar, nhưng lưu ý ngay cả khi có 10.000 tệp, đây chỉ là 5 MB). Vì bạn có hơn 4 GB miễn phí, nên bạn sẽ không điền vào phân vùng.

một bản sao dễ tải về

Hầu hết mọi người sẽ xem xét "dễ dàng hơn" đồng nghĩa với "nhỏ hơn" về mặt tải xuống, vì vậy bạn nên sử dụng một số nén ở đây. bzip2Tôi nghĩ bây giờ nên có sẵn trên bất kỳ hệ thống nào, tôi nghĩ, vì vậy bao gồm jtrong các thiết bị chuyển mạch của bạn có lẽ là sự lựa chọn tốt nhất. z( gzip) có lẽ thậm chí còn phổ biến hơn, và có những khả năng khác (ít phổ biến hơn) với nhiều bí đao hơn.

Nếu bạn có nghĩa là, tartạm thời sử dụng không gian đĩa bổ sung để thực hiện tác vụ, tôi khá chắc chắn rằng nó không vì một vài lý do, một là nó có từ thời ổ đĩa băng là một dạng lưu trữ chính và hai là nó có đã có nhiều thập kỷ để phát triển (và tôi chắc chắn không cần thiết phải sử dụng không gian trung gian tạm thời, ngay cả khi có liên quan đến việc nén).


0

Nếu tốc độ là quan trọng và không cần nén, bạn có thể móc các hàm bao của tòa nhà được sử dụng bằng tarcách sử dụng LD_PRELOAD, để thay đổi tarđể tính toán cho chúng tôi. Bằng cách thực hiện lại một vài trong số các chức năng này để phù hợp với nhu cầu của chúng tôi (tính toán kích thước của dữ liệu tar đầu ra tiềm năng), chúng tôi có thể loại bỏ rất nhiều readwriteđiều đó được thực hiện trong hoạt động bình thường tar. Điều này làm cho tarnhanh hơn nhiều vì nó không cần phải chuyển ngữ cảnh qua lại vào kernel ở bất kỳ đâu gần như và chỉ statcần đọc (các) tệp / thư mục đầu vào được yêu cầu từ đĩa thay vì dữ liệu tệp thực tế.

Đoạn code dưới đây bao gồm việc triển khai của close, readwritecác chức năng POSIX. Macro OUT_FDkiểm soát mô tả tệp mà chúng tôi dự kiến tarsẽ sử dụng làm tệp đầu ra. Hiện tại nó được đặt thành thiết bị xuất chuẩn.

readđã được thay đổi thành chỉ trả về giá trị thành công của countbyte thay vì điền dữ liệu vào buf, với điều kiện là dữ liệu thực tế không được đọc buf sẽ không chứa dữ liệu hợp lệ để chuyển sang nén và do đó, nếu sử dụng nén, chúng tôi sẽ tính toán không chính xác kích thước.

writeđược thay đổi để tổng hợp các đầu vào countbyte vào biến toàn cầu totalvà trả về giá trị thành công của countbyte chỉ nếu trận mô tả tập tin OUT_FD, nếu không nó gọi wrapper gốc mua qua dlsymđể thực hiện các syscall cùng tên.

closevẫn tạo ra tất cả các chức năng ban đầu của nó, nhưng nếu bộ mô tả tệp khớp với OUT_FD, nó biết rằng đã tarhoàn thành việc cố gắng ghi một tệp tar, vì vậy totalsố này là cuối cùng và nó in ra thiết bị xuất chuẩn.

#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdlib.h>
#include <errno.h>
#include <dlfcn.h>
#include <string.h>

#define OUT_FD 1
uint64_t total = 0;
ssize_t (*original_write)(int, const void *, size_t) = NULL;
int (*original_close)(int) = NULL;
void print_total(void)
{
    printf("%" PRIu64 "\n", total);
}

int close(int fd)
{
    if(! original_close)
    {
        original_close = dlsym(RTLD_NEXT, "close");
    }
    if(fd == OUT_FD)
    {
        print_total();
    }
    return original_close(fd);
}

ssize_t read(int fd, void *buf, size_t count)
{
    return count;
}

ssize_t write(int fd, const void *buf, size_t count)
{
    if(!original_write)
    {
        original_write = dlsym(RTLD_NEXT, "write");
    }
    if(fd == OUT_FD)
    {
        total += count;
        return count;
    }
    return original_write(fd, buf, count);
}

Điểm chuẩn so sánh một giải pháp trong đó truy cập đĩa đọc và tất cả các tòa nhà của hoạt động tar bình thường được thực hiện đối với LD_PRELOADgiải pháp.

$ time tar -c /media/storage/music/Macintosh\ Plus-\ Floral\ Shoppe\ \(2011\)\ \[Flac\]/ | wc -c
332308480
real    0m0.457s
user    0m0.064s
sys     0m0.772s
tarsize$ time ./tarsize.sh -c /media/storage/music/Macintosh\ Plus-\ Floral\ Shoppe\ \(2011\)\ \[Flac\]/
332308480
real    0m0.016s
user    0m0.004s
sys     0m0.008s

Mã ở trên, tập lệnh xây dựng cơ bản để xây dựng ở trên dưới dạng thư viện dùng chung và tập lệnh có " LD_PRELOADkỹ thuật" sử dụng được cung cấp trong repo: https://github.com/G4Vi/tarsize

Một số thông tin về việc sử dụng LD_PRELOAD: https://rafalcieslak.wordpress.com/2013/04/02/dynamic-linker-tricks-USE-ld_preload-to-cheat-inject-features-and-investigate-programs/


Mã là tốt, nếu nó hoạt động, nhưng bạn có thể mô tả những gì nó làm? Xin vui lòng không trả lời trong các ý kiến; chỉnh sửa  câu trả lời của bạn để làm cho nó rõ ràng và đầy đủ hơn.
G-Man nói 'Phục hồi Monica'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.