Determine quantos arquivos de uma lista ordenada irão encher um disco

0

Isso me intrigou. Acho que deveria ser fácil, mas devo estar perdendo alguma coisa, já que os resultados não são consistentes.

Estou fazendo o backup de uma longa lista de arquivos em vários discos, usando o rsync, usando uma lista ordenada em ordem cronológica, de forma que os arquivos mais antigos entrem no primeiro disco, depois no segundo e assim por diante.

Eu passo pela lista somando os tamanhos dos arquivos, em blocos de 4k, e anoto a data do último arquivo que se encaixa. Então eu crio uma lista, usando "find -not -newer and -newer"

STARTDATE="-newer /tmp/filedate.1"
ENDDATE="-not -newer /tmp/filedate.2"
find $SRC -type f ${STARTDATE} ${ENDDATE} -printf '%P\n' | sort > ${TEMPFILE}

e alimente isso para rsync usando "--files-from" para realmente fazer a cópia.

rsync -a --progress --verbose --prune-empty-dirs --files-from=${TEMPFILE} ${SRC} ${TARGET}

Eu quero descobrir com precisão onde dividir os arquivos, para que os discos sejam preenchidos até a capacidade.

O que eu tenho no momento:

#%T is the modification time, @ is seconds, 
#%p is the path less the command line part, and %k is disk usage in 1k blocks
#MAXSIZE is number of 4k blocks available on disk
    find $SRC -printf "%T@\t%p\t%k\n" | sort -n | \
    awk -vMS="$MAXSIZE"  '
      BEGIN { FS = "\t";fnumber = 0 }
      {rtot+=int(($3+3)/4); #edit; changed to ceiling on AlexP's advice
       if (rtot<MS) {final=$2;filesize=rtot;}
       else {
            rtot=int(($3+3)/4); #edit; changed to ceiling on AlexP's advice
            fnumber++;
            printf "touch -r \"%s\" /tmp/filedate.%s\n", final, fnumber | "/bin/sh"
            print "Found point " fnumber ". (" final ") 4096 Blocks:"  filesize " Space Left:" (MS-filesize)*4
            }
      }
    '

Os detalhes do disco são:

    #tune2fs -l /dev/sdzc1
    tune2fs 1.41.4 (27-Jan-2009)
    Filesystem volume name:   <none>
    Last mounted on:          /share/external/sdzc1
    Filesystem UUID:          f3f2e855-b198-4d47-b76f-6526d16b0820
    Filesystem magic number:  0xEF53
    Filesystem revision #:    1 (dynamic)
    Filesystem features:      has_journal ext_attr resize_inode filetype needs_recovery extent flex_bg sparse_super large_file
huge_file uninit_bg dir_nlink extra_isize
    Filesystem flags:         signed_directory_hash
    Default mount options:    (none)
    Filesystem state:         clean
    Errors behavior:          Continue
    Filesystem OS type:       Linux
    Inode count:              122101760
    Block count:              488378007
    Reserved block count:     0
    Free blocks:              89451
    Free inodes:              122088914
    First block:              0
    Block size:               4096
    Fragment size:            4096
    Reserved GDT blocks:      907
    Blocks per group:         32768
    Fragments per group:      32768
    Inodes per group:         8192
    Inode blocks per group:   512
    Flex block group size:    16
    Filesystem created:       Sun May 11 13:45:08 2014
    Last mount time:          Wed Dec  7 11:44:24 2016
    Last write time:          Wed Dec  7 11:44:24 2016
    Mount count:              68
    Maximum mount count:      28
    Last checked:             Fri Feb 20 02:06:42 2015
    Check interval:           15552000 (6 months)
    Next check after:         Wed Aug 19 02:06:42 2015
    Reserved blocks uid:      0 (user admin)
    Reserved blocks gid:      0 (group administrators)
    First inode:              11
    Inode size:               256
    Required extra isize:     28
    Desired extra isize:      28
    Journal inode:            8
    First orphan inode:       75890825
    Default directory hash:   half_md4
    Directory Hash Seed:      1c7f838c-8614-4af0-8506-cd3659e1e5ac
    Directory Magic Number:   0x514E4150
    Journal backup:           inode blocks

Então, pelo meu pensamento, existem 488378007 blocos de 4096 bytes e 122101760 inodes de 256 bytes. Portanto, deve haver (488378007 x 4096) - (122101760 x 256) bytes disponíveis para serem gravados. i.e. 1,969,138,264,064 que é 1,922,986,586 kB.

df mostra um total de 1.922.858.380 blocos de 1k, (128.206 de diferença), = 480.714.595 blocos de 4k.

Desconsiderando isso, o resultado final é que quando eu realmente copio os arquivos, mesmo usando o valor mais baixo como um ponto inicial, o "Espaço à Esquerda" relatado a partir da saída do awk não é igual ao espaço real restante, por < quantidades strongs <> variadas , às vezes até mesmo ficando sem espaço completamente.

Onde eu errei a lógica? Eu sei que posso falsificar apenas diminuindo o MAXSIZE, mas eu realmente gostaria de entender o que estou perdendo!

ps. Estou executando isso como root, portanto, o espaço reservado não é relevante.

Só para esclarecer a questão: devo conseguir somar os tamanhos de arquivos e diretórios (em blocos inteiros de 4k) para obter o uso total do disco?

Edição adicional: apenas para confundir mais eu acabei de preencher (?) uma unidade e estou recebendo isso do df -k:

Filesystem      1K-blocks       Used Available Use% Mounted on
/dev/sdzb1     2927209048 2925317912         0 100% /share/external/sdzb1

2927209048-2925317912 = 1891136, ou quando eu estava na escola!

    
por u628898 10.12.2016 / 03:52

2 respostas

1

Duas observações:

  • Você precisa arredondar o número de blocos usados por um arquivo, não para baixo; se um arquivo tiver 8192 + 1 bytes, esse último byte alocará um bloco de 4 KiB. (Porque o "tamanho do fragmento" é 4 KiB.)

  • O espaço em disco necessário para um arquivo não é necessariamente igual ao número de blocos de dados necessários para manter o número de bytes no arquivo. Ele pode ser um pouco maior (para arquivos maiores que precisam de mais metadados para mapear seus blocos alocados) ou menor (para arquivos muito pequenos, que podem ser totalmente armazenados em seu inode). Além disso, como o usuário Stephen Kitt menciona, há toda a edição de arquivos esparsos , que podem têm tamanhos muito maiores do que o espaço que ocupam no disco e que podem causar problemas interessantes quando arquivados ou copiados para um sistema de arquivos diferente.

  • Alguns sistemas de arquivos podem usar algum espaço em disco para seus próprios propósitos. Além disso, os sistemas de arquivos tendem a se comportar mal quando o espaço em disco utilizado se aproxima da capacidade. Você deve planejar encher seus discos não mais que 98% ou 99%.

por 10.12.2016 / 07:57
0

Vou responder à minha pergunta, agradecendo a todos que contribuíram e direcionaram meus pensamentos:

Devido à forma como o espaço é alocado à medida que o disco é gravado, dependendo do tamanho e do tipo do arquivo, arquivos esparsos, etc., é realmente muito difícil, se não impossível, prever com precisão quanto espaço será ocupado. antecipadamente.

Os diretórios que tiveram arquivos excluídos deles podem ser maiores do que quando criados pela primeira vez, e esse espaço não será recuperado. (a menos que o diretório seja excluído e recriado) Diretórios vazios ocupam espaço.

'Encontrar' não reporta diretórios, a menos que seja especificamente solicitado.

O espaço é escrito em blocos completos, o tamanho do bloco pode variar entre os discos e pode ser lido a partir do e2fsdump.

'df' não reporta espaço disponível após cerca de 98%, apesar de reportar menos blocos usados do que os disponíveis:

# df -B4k --sync
Filesystem      4K-blocks       Used Available Use% Mounted on
/dev/sdzb1      731802262  731493169         0 100% /share/external/sdzb1
/dev/sdzc1      731802262  717225328         0 100% /share/external/sdzc1

'du' reporta uso diferente para 'df':

# du -B4k -s /share/external/sdzb1 /share/external/sdzc1
731441722       /share/external/sdzb1
717173881       /share/external/sdzc1

No entanto, é possível, usando o ponto de partida inicial para o espaço disponível:

Space = (Total blocks x blocksize) - (Total inodes x inode size)

e permitindo uma margem de 300.000 a 500.000 blocos, para chegar a um resultado razoavelmente preciso. (dentro de 1%)

    
por 12.12.2016 / 04:19