tar를 실행하면 디스크가 가득 차게되는지 어떻게 알 수 있습니까?


22

tar -cvf937MB 크기의 디렉토리에서 실행 하여 깊이 중첩 된 폴더 구조의 쉽게 다운로드 할 수있는 사본을 만들면 다음과 같은 df -h출력으로 디스크를 채울 위험이 있습니다 .

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

관련 질문 :

  • 디스크가 가득 찬 경우 왜 Linux (Amazon AMI) 및 / 또는 tar후드에서 수행되고 있습니까?
  • 다시 묻지 않고이 정보를 정확하게 어떻게 확인할 수 있습니까?

아카이브를 처리하지 않고 가능한지 확실하지 않지만 --totals옵션으로 재생할 수 있습니다 . 어느 쪽이든 디스크를 채우면 간단히 아카이브를 삭제할 수 있습니다 (imho). 사용 가능한 모든 옵션을 확인하려면를 수행하십시오 tar --help.
UVV

4
탄젠트 : tar 파일을 루트로 만들지 마십시오. 디스크의 특정 공간 비율은 루트 전용으로 "디스크를 채웠으므로 이제는 쓸 수 없기 때문에 로그인 할 수 없습니다. bash_history 또는 무엇이든 "상황.
Ulrich Schwarz

답변:


24

tar -c data_dir | wc -c 압축하지 않고

또는

tar -cz data_dir | wc -c gzip 압축

또는

tar -cj data_dir | wc -c bzip2 압축

디스크에 쓰지 않고 바이트 단위로 생성 된 아카이브의 크기를 인쇄합니다. 그런 다음 대상 장치의 여유 공간과 비교할 수 있습니다.

다음 명령을 사용하여 데이터 디렉토리 크기에 대해 잘못된 가정이있는 경우 데이터 디렉토리 자체의 크기를 확인할 수 있습니다.

du -h --max-depth=1 data_dir

이미 대답했듯이 tar는 아카이브의 각 레코드에 헤더를 추가하고 각 레코드의 크기를 512 바이트의 배수로 반올림합니다 (기본값). 아카이브의 끝은 2 개 이상의 연속 0 채워진 레코드로 표시됩니다. 따라서 압축되지 않은 tar 파일이 파일 자체보다 크고, 파일 수와 512 바이트 경계에 정렬되는 방식에 따라 추가 공간이 결정되는 경우가 항상 있습니다.

물론 파일 시스템 자체는 개별 파일의 내용보다 큰 블록 크기를 사용하므로 압축을 푼 위치에주의하십시오. 파일 시스템은 tar 크기보다 큰 여유 공간이 있어도 작은 파일을 많이 보유하지 못할 수 있습니다!

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


고마워 제이미! 여기서 '-mysql'은 무엇입니까? 파일 이름이 맞습니까?
codecowboy

방금 변경했습니다 ... 데이터 디렉토리의 경로입니다.
FantasticJamieBurns

1
실제로 중요하지는 않지만 -f -tar에 인수 조합 을 사용하면 중복 -f됩니다. 결과를 stdout (예 :)에 쓰려면 인수를 모두 생략 할 수 있기 때문 tar -c data_dir입니다.

6

tar 파일의 크기는 937MB에 각 파일 또는 디렉토리에 필요한 메타 데이터 크기 (개체 당 512 바이트)와 파일을 512 바이트 경계에 맞추기 위해 추가됩니다.

매우 대략적인 계산에 따르면 데이터의 다른 사본이 3.4GB의 여유 공간을 제공합니다. 3.4GB에는 패딩이 없다고 가정 할 때 약 7 백만 개의 메타 데이터 레코드를위한 공간이 있거나 파일 당 평균 256 바이트의 패딩을 가정하면 더 적습니다. 따라서 tar에 수백만 개의 파일과 디렉토리가 있으면 문제가 발생할 수 있습니다.

당신은 문제를 완화시킬 수 있습니다

  • z또는 j옵션을 사용하여 즉시 압축tar
  • tar공간이 /부족한 경우 파티션 의 예약 된 공간 이 건드리지 않도록 일반 사용자로 수행하십시오 .

2

tar자체적으로 다음 --test옵션 을 사용하여 아카이브 크기를보고 할 수 있습니다 .

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

위의 명령은 디스크에 아무것도 쓰지 않으며 tarball에 포함 된 각 파일의 개별 파일 크기를 나열하는 이점이 있습니다. 다양한 z/j/xz피연산자를 양쪽에 추가하면 |pipe압축을 처리 할 수 ​​있습니다.

산출:

...
-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)

목적을 완전히 확신하지는 않지만 tarball을 다운로드하는 것이 더 중요 할 수 있습니다.

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

또는 단순히 다음으로 복사하십시오 tar.

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

내가하고있는 이유는 문제의 디렉토리가 df -i의 출력이 99 %에 도달했다고 생각하기 때문입니다. 추가 분석을 위해 디렉토리의 복사본을 유지하고 싶지만 공간을 정리하고 싶습니다.
codecowboy

@codecowboy이 경우에는 위와 같은 작업을 먼저 수행해야합니다. 그런 tar다음 원격 디스크에 아무 것도 저장하지 않고 스트림의 트리에서 로컬 디스크로 트리를 복사 한 후 원격 호스트에서 삭제하고 나중에 복원 할 수 있습니다. -z전송 중 대역폭을 절약하기 위해 goldilocks가 지적한대로 압축을 추가해야합니다 .
mikeserv

@ TAFKA'goldilocks '아니요, 99 %의 공간이 아니라 inode의 99 %이기 때문입니다.
Gilles 'SO- 악마 그만해'

-i알았어, 미안해
goldilocks

@mikeserv 오프닝 라인은 --test 옵션을 언급하지만 바로 다음 명령 (--totals 사용)에서 명령을 사용하지 않는 것 같습니다.
codecowboy

2

나는 이것에 대해 많은 연구를 해왔다. 단어 개수를 사용하여 파일에서 테스트를 수행 할 수 있지만 a와 같은 숫자를 제공하지는 않습니다 du -sb adir.

tar -tvOf afile.tar | wc -c

du모든 디렉토리를 4096 바이트로 tar계산하고 디렉토리를 0 바이트로 계산합니다. 각 디렉토리에 4096을 추가해야합니다.

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

그런 다음 모든 문자를 추가해야합니다. 다음과 같은 것 :

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

터치 된 파일 (0 바이트 파일) 또는 1 문자 파일을 시도하지 않았기 때문에 이것이 완벽한 지 확실하지 않습니다. 좀 더 가까이 와야합니다.


1

-cvf압축을 포함하지 않으므로 ~ 1GB 폴더에서 압축하면 ~ 1GB tar 파일이 생성됩니다 (Flub의 답변에는 tar 파일의 추가 크기에 대한 자세한 내용이 있지만 10,000 개의 파일이 있어도이 파일은 5MB). 4GB 이상의 여유 공간이 있으므로 파티션을 채우지 않습니다.

쉽게 다운로드 할 수있는 사본

대부분의 사람들은 다운로드 측면에서 "보다 작은"과 "더 작은"의 동의어를 고려하므로 여기에서 약간의 압축을 사용해야합니다. bzip2타르가있는 모든 시스템에서 현재 하루를 사용할 수 있어야한다고 생각 j합니다. 스위치에 포함 시키는 것이 최선의 선택 일 것입니다. z(gzip )가 더 일반적 일 수 있으며 스쿼시가 더 많은 다른 (유비쿼터스) 가능성이 있습니다.

당신이 의미 tar하는 경우, 작업을 수행 할 때 일시적으로 추가 디스크 공간을 사용합니까, 나는 몇 가지 이유가 아니라고 확신합니다. 하나는 테이프 드라이브가 기본 스토리지의 한 유형으로 거슬러 올라 갔으며 두 가지는 수십 년 동안 진화했습니다 (그리고 압축이 관련되어 있어도 임시 중간 공간을 사용할 필요는 없습니다).


0

속도가 중요하고 압축이 필요하지 않은 경우을 사용 tar하여 사용 된 syscall 랩퍼를 후크하여 계산 LD_PRELOAD하도록 변경할 tar수 있습니다. 잠재적 인 출력 타르 데이터의 크기를 계산하는 우리의 요구에 맞게 이러한 기능 중 일부를 다시 구현함으로써 많은 작업을 제거 할 수 read있으며 write이는 정상 작동시 수행됩니다 tar. 이것은 tar컨텍스트에서 커널로 앞뒤로 전환 할 필요가 없기 때문에 훨씬 빠릅니다.stat 요청 된 입력 파일 / 폴더 만 실제 파일 데이터 대신 디스크에서 읽어야하기 .

아래의 코드는 구현 포함 close, readwritePOSIX 기능. 매크로 OUT_FDtar출력 파일로 사용할 파일 설명자를 제어 합니다. 현재는 표준 출력으로 설정되어 있습니다.

readcount실제 데이터를 읽지 않은 경우 buf에 데이터를 채우지 않고 바이트 의 성공 값을 반환하도록 변경되었습니다. buf는 압축으로 전달하기위한 유효한 데이터를 포함하지 않으므로 압축을 사용하면 잘못된 값을 계산합니다 크기.

write입력 count바이트를 전역 변수 에 합산하고 파일 디스크립터가 일치하는 경우 에만 바이트 total의 성공 값을 리턴하도록 변경되었습니다 . 그렇지 않으면 동일한 이름의 syscall을 수행하기 위해 획득 한 원래 랩퍼를 호출합니다 .countOUT_FDdlsym

close여전히 원래 기능을 모두 수행하지만 파일 디스크립터가 OUT_FD와 일치 tar하면 tar 파일을 작성하려고 시도한 것으로 알고 있으므로 total숫자가 최종이고 stdout에 인쇄합니다.

#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);
}

읽기 디스크 액세스 및 일반 tar 조작의 모든 시스템 호출이 LD_PRELOAD솔루션 에 대해 수행되는 솔루션을 비교하는 벤치 마크 입니다.

$ 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

위의 코드, 위의 코드를 공유 라이브러리로 빌드하는 기본 빌드 스크립트 및이를 사용하는 " LD_PRELOAD기술" 스크립트가 리포지토리에 제공됩니다. https://github.com/G4Vi/tarsize

LD_PRELOAD 사용에 대한 일부 정보 : https://rafalcieslak.wordpress.com/2013/04/02/dynamic-linker-tricks-using-ld_preload-to-cheat-inject-features-and-investigate-programs/


작동한다면 코드는 좋지만, 그 기능을 설명 할 수 있습니까? 의견에 응답하지 마십시오.  명확하고 완전하게 답변을 편집 하십시오.
G-Man, 'Reinstate Monica'1
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.