Bulk remove um diretório grande em um ZFS sem atravessá-lo recursivamente

6

Eu quero remover um diretório que tenha grandes quantidades de dados. Esta é a minha matriz de backup, que é um sistema de arquivos ZFS , span linear, pool único chamado "san". San está montado em /san por isso quero remover / san / thispc / certainFolder em massa

$ du -h -d 1 certainFolder/
1.2T    certainFolder/

Em vez de eu ter que esperar por rm -rf certainFolder/ , não posso simplesmente destruir o identificador para esse diretório para que ele seja sobrescrito (mesmo pelo mesmo nome do diretório se eu o recriou)?

Então, por exemplo não sabendo muito sobre o zfs fs interno mgmnt especificamente como ele mapeia diretórios, mas se eu descobrisse que o mapa dizia por exemplo, e removesse as entradas corretas para, por exemplo, o diretório não seria mais exibido, e aquele espaço que o diretório anteriormente possuía deveria ser removido de algum tipo de auditoria também.

Existe uma maneira fácil de fazer isso, mesmo que em um ext3 fs, ou já é o que o comando recursive remove tem que fazer em primeiro lugar, ou seja, furtar e editar periódicos?

Eu só estou esperando para fazer algo dos gostos de kill thisDir para onde ele simplesmente remove algum tipo de ID, e poof o diretório não aparece mais em ls -la e os dados ainda estão lá na unidade, obviamente , mas o espaço será agora reutilizado (sobrescrito), porque o ZFS é tão legal assim?

Quer dizer, acho que zfs é realmente legal, como podemos fazer isso? Idealmente? esfregando as mãos juntas: -)

Meu caso de uso específico (além do meu amor pelo zfs) é o gerenciamento do meu arquivo de backup. Esse diretório de backup é enviado por meio do freefilesync (AWESOME PROG) na minha caixa do Windows para um compartilhamento de arquivo smb, mas também possui um diretório de versão para o qual os arquivos antigos são enviados. Estou excluindo os diretórios de nível superior que residem no backup principal, que foram copiados para a versão - por exemplo, /san/version/someStuff , como uma limpeza bimestral de rm -rf /san/version/someStuff/* de um terminal de massa, agora tenho que abrir outro terminal; Não quero fazer isso todas as vezes, estou cansado de ter que monitorar o rm-rf.

Quero dizer, talvez eu deva definir o comando para liberar o identificador, depois imprimir para std out, isso pode ser bom. Mais realisticamente , recrie o conjunto de dados em alguns segundos zfs destroy san/version; zfs create -p -o compression=on san/version após os pensamentos da resposta do @Gilles.

    
por Brian Thomas 02.08.2015 / 19:57

3 respostas

9

O rastreamento de blocos liberados é inevitável em qualquer sistema de arquivos decente e o ZFS não é uma exceção . No entanto, há uma maneira simples no ZFS de ter uma exclusão de diretório quase instantânea ao "adiar" a limpeza subjacente. É tecnicamente muito semelhante à sugestão de Gilles, mas é inerentemente confiável sem exigir código extra.

Se você criar um instantâneo do seu sistema de arquivos antes de remover o diretório, a remoção do diretório será muito rápida, pois nada precisará ser explorado / liberado sob ele, sendo que todos ainda são referenciados pelo instantâneo. Você pode então destruir o instantâneo em segundo plano para que o espaço seja gradualmente recuperado.

d=yourPoolName/BackupRootDir/hostNameYourPc/somesubdir
zfs snapshot ${d}@quickdelete && { 
    rm -rf /${d}/certainFolder
    zfs destroy ${d}@quickdelete & 
}
    
por 03.08.2015 / 01:48
6

O que você está pedindo é impossível. Ou, mais precisamente, há um custo a pagar ao excluir um diretório e seus arquivos; se você não pagar no momento da exclusão, terá que pagá-lo em outro lugar.

Você não está apenas removendo um diretório - isso seria quase instantâneo. Você está removendo um diretório e todos os arquivos dentro dele e também recursivamente removendo também todos os seus subdiretórios. Remover um arquivo significa decrementar sua contagem de links e, em seguida, marcar seus recursos (os blocos usados para o conteúdo de arquivos e metadados de arquivos e o inode se o sistema de arquivos usar uma tabela de inode) como livres se a contagem de links atingir 0 e o arquivo não for abrir. Essa é uma operação que precisa ser feita para cada arquivo na árvore de diretórios, portanto, o tempo que leva é pelo menos proporcional ao número de arquivos.

Você pode atrasar o custo de marcar os recursos como gratuitos. Por exemplo, existem sistemas de arquivos coletados por coleta de lixo, nos quais é possível remover um diretório sem remover os arquivos contidos nele. Uma execução do coletor de lixo detectará os arquivos que não podem ser acessados através da estrutura de diretórios e os marcará como livres. Fazer rm -f directory; garbage-collect em um sistema de arquivos garbage collected faz as mesmas coisas que rm -rf em um sistema de arquivos tradicional, com diferentes triggers. Existem poucos sistemas de arquivos coletados por coleta de lixo porque o GC é uma complexidade adicional que raramente é necessária. O tempo do CG pode chegar a qualquer momento, quando o sistema de arquivos precisa de alguns blocos livres e não encontra nenhum, então o desempenho de uma operação seria dependente do histórico passado, não apenas da operação, o que geralmente é indesejável. Você precisaria executar o coletor de lixo apenas para obter a quantidade real de espaço livre.

Se você quiser simular o comportamento do GC em um sistema de arquivos normal, você pode fazê-lo:

mv directory .DELETING; rm -rf .DELETING &

(omiti muitos detalhes importantes, como verificação de erros, como resiliência à perda de energia, etc.) O nome do diretório torna-se inexistente imediatamente; o espaço é recuperado progressivamente.

Uma abordagem diferente para evitar o pagamento do custo durante a remoção sem GC seria pagá-lo durante a alocação. Marque a árvore de diretórios como excluída e passe pelos diretórios excluídos ao alocar blocos. Isso seria difícil de conciliar com hard links, mas em um sistema de arquivos sem hard links, isso pode ser feito com O (1) aumento de custos na alocação. No entanto, isso tornaria a operação mais comum (criação ou ampliação de um arquivo) mais cara, com o único benefício de ser uma operação relativamente rara (remover uma árvore de diretórios grande) mais barata.

Você poderia remover em massa uma árvore de diretórios se essa árvore fosse armazenada como seu próprio conjunto de blocos. (Nota: estou usando a palavra "pool" em um significado diferente do "pool de armazenamento" do ZFS. Não sei qual a terminologia correta.) Isso pode ser muito rápido. Mas o que você faz com o espaço livre? Se você reatribui-lo a outro pool, isso tem um custo, embora muito menos do que excluir arquivos individualmente. Se você deixar o espaço como espaço de reserva não utilizado, não poderá recuperá-lo imediatamente. Ter um pool individual para uma árvore de diretórios significa custos adicionais para aumentar ou reduzir o tamanho desse pool (seja de forma dinâmica ou explicitamente). Tornar a árvore seu próprio conjunto de armazenamento também aumenta o custo de mover arquivos para dentro e fora da árvore.

    
por 02.08.2015 / 21:17
1

Se tiver que ser rápido, eu gero um novo diretório temporário, mv o diretório abaixo dele e depois recursivamente excluo o temporário:

t='mktemp -d'
mv certainFolder $t/
rm -rf $t &
    
por 03.08.2015 / 05:08