Remoção em massa de um diretório grande em um ZFS sem percorrê-lo recursivamente

9

Eu quero remover um diretório que possui grandes quantidades de dados. Esta é minha matriz de backup, que é um sistema de arquivos ZFS , alcance linear e pool único chamado "san". San está montado, /san então eu quero remover em massa / san / thispc / certosFolder

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

Em vez de eu ter que esperar, rm -rf certainFolder/não posso simplesmente destruir o identificador desse diretório para que ele possa ser substituído (mesmo com o mesmo nome de diretório se eu optar por recriá-lo)?

Portanto, por exemplo, por não saber muito sobre o zfs fs mgmnt internal, especificamente como ele mapeia diretórios, mas se eu encontrasse esse mapa digamos por exemplo e removesse as entradas corretas, por exemplo, o diretório não seria mais exibido e o espaço que o diretório anteriormente ocupava também precisa ser removido de algum tipo de auditoria.

Existe uma maneira fácil de fazer isso, mesmo em um ext3 fs, ou já é isso que o comando de remoção recursiva deve fazer em primeiro lugar, ou seja, vasculhar e editar periódicos?

Eu só espero fazer algo do tipo kill thisDirpara onde ele simplesmente remove algum tipo de ID, e poof o diretório não aparece mais ls -lae os dados ainda estão lá na unidade, obviamente, mas o espaço agora será reutilizado ( sobrescrito), porque o ZFS é legal?

Quero dizer, acho o zfs realmente muito 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 via freefilesync (AWESOME PROG) na caixa do Windows para um compartilhamento de arquivo smb, mas também possui um diretório de versão para onde os arquivos antigos vão. Estou excluindo 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 bimensal de rm -rf /san/version/someStuff/*um terminal de massa, agora tenho que abrir outro terminal; não quero fazer isso toda vez, estou cansado de inutilmente ter que monitorar rm -rf.

Quero dizer, talvez eu deva definir o comando para soltar a alça e depois imprimir em std, 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/versionapós os pensamentos da resposta do @Gilles.

Brian Thomas
fonte
FYI, eu corri esse comando para fazer os conjuntos de dados que im usando atualmente .. `zfs create dataset -p -o compression=on yourPoolName/BackupRootDir/hostNameYourPc/somesubdir
Brian Thomas
Aceite uma resposta se tiver resolvido o problema descrito na sua pergunta original. O problema que você acabou de anexar à sua pergunta parece ser bem diferente; portanto, você deve realmente fazer uma nova pergunta.
Jlliagre 28/08/2015

Respostas:

12

O rastreamento de blocos liberados é inevitável em qualquer sistema de arquivos decente e o ZFS não é exceção . No entanto, existe uma maneira simples no ZFS de excluir um diretório quase instantaneamente "adiando" 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, porque nada precisará ser explorado / liberado sob ele, todos ainda referenciados pelo instantâneo. Você pode destruir o instantâneo em segundo plano para que o espaço seja recuperado gradualmente.

d=yourPoolName/BackupRootDir/hostNameYourPc/somesubdir
zfs snapshot ${d}@quickdelete && { 
    rm -rf /${d}/certainFolder
    zfs destroy ${d}@quickdelete & 
}
jlliagre
fonte
ok, eu não estou familiarizado com os instantâneos. isso pode me ajudar. Eu tenho excluído / movido o dia todo ainda. Criei conjuntos de dados não apenas para o diretório principal de backup, mas também para os diretórios de nível superior, cada um começando com o nome do host e alguns níveis superiores ..., por isso tenho um pouco de flexibilidade para destruir e recriar um pool, mas não é perfeito , porque eu sempre não quero excluir todo esse diretório de pool, eu teria que criar ainda mais e isso é um monte de criação de conjuntos de dados, por isso, gosto da sua sugestão por esse motivo!
Brian Thomas
4
Se disponível, feature@async_destroytambém pode ajudar a acelerar isso (da perspectiva de um usuário ou administrador), se ativado; veja zpool get all $pool. Observe que pelo menos eu procurei, se houver uma destruição pendente em andamento na importação de conjuntos , essa destruição se tornará síncrona e a importação de conjuntos não será concluída até que a destruição seja concluída. Cuidado se você precisar reiniciar!
um CVn
Tenho cliente com uma frequência que perdeu a conexão SMB em grandes exclusões. Depois de ativar os instantâneos periódicos (e a remoção automática), o problema "desapareceu". a liberação do espaço leva mais tempo em segundo plano, mas o SMB-Share permanece acessível o tempo todo.
Martin Seitl
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 pagar 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 todos os seus subdiretórios. Remover um arquivo significa diminuir sua contagem de links e, em seguida, marcar seus recursos (os blocos usam para o conteúdo e os metadados do arquivo, e o inode se o sistema de arquivos usar uma tabela de inodes) como livre se a contagem de links atingir 0 e o arquivo não estiver aberto. Esta é uma operação que deve ser realizada para cada arquivo na árvore de diretórios, portanto, o tempo necessário é 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 lixo, nos quais você pode remover um diretório sem remover os arquivos que ele contém. Uma execução do coletor de lixo detectará os arquivos inacessíveis por meio da estrutura de diretórios e os marcará como livres. Executar rm -f directory; garbage-collectem um sistema de arquivos coletados de lixo faz o mesmo querm -rfem um sistema de arquivos tradicional, com diferentes gatilhos. Existem poucos sistemas de arquivos coletados pelo lixo porque o GC é uma complexidade adicional que raramente é necessária. O tempo do GC pode chegar a qualquer momento, quando o sistema de arquivos precisa de alguns blocos livres e não encontra nenhum, portanto o desempenho de uma operação depende 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ê deseja simular o comportamento do GC em um sistema de arquivos normal, é possível:

mv directory .DELETING; rm -rf .DELETING &

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

Uma abordagem diferente para evitar o pagamento do custo durante a remoção sem o 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. Seria difícil conciliar com links físicos, mas em um sistema de arquivos sem links físicos, isso pode ser feito com o aumento de custos O (1) na alocação. No entanto, isso tornaria uma operação muito comum (criar ou ampliar um arquivo) mais cara, com o único benefício sendo uma operação relativamente rara (remover uma grande árvore de diretórios) mais barata.

Você poderia remover em massa uma árvore de diretórios se ela 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 adequada.) Isso pode ser muito rápido. Mas o que você faz com o espaço livre? Se você o redesignar para outro pool, isso terá um custo, 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 (em tempo real ou explicitamente). Tornar a árvore seu próprio pool de armazenamento também aumenta o custo de mover arquivos para dentro e para fora da árvore.

Gilles 'SO- parar de ser mau'
fonte
Ok, ótima resposta! A primeira metade é completamente satisfatória em um sistema normal. O ZFS tem alguns truques na manga, por exemplo, não há necessidade de formatá-lo, por isso, se eu destruí a piscina, o que eu acho que vou fazer da próxima vez, é só fazer a piscina (plural) como eu deveria, então desaparece o radar instantaneamente e esse espaço está disponível imediatamente. Acho que estou tentando recriar isso no zfs, em um diretório dentro de um pool, e acho que, como não é um pool em si, a natureza dele se torna mais padrão e o método que você mencionou parece aplicar nesse caso. interessante.
Brian Thomas
Eu acho que foi onde eu cometi meu erro, li um artigo ontem à noite, vou ver se consigo encontrá-lo, que demonstra que as piscinas devem ser usadas como diretórios limitados a ~ 18.446.744 trilhões de piscinas no máximo no FS. se eu criar meus diretórios de backup superiores como conjuntos cada um, quando o backup for gravado neles, o dir já estará intacto, que é um conjunto facilmente deletável. Se o conjunto não existisse, o backup criaria o diretório e a piscina não será vista no zfs list. Até lá, esperamos que outra pessoa tenha alguma entrada sobre como delte em massa no ZFS em um subdiretório de um pool. :-)
Brian Thomas
Além disso, ao ler sua primeira resposta, meu primeiro pensamento foi; "CERTO!", "O custo"! era isso que eu tocava quando falava em excluir entradas de diário. Então, como eu suspeitava. danado! No entanto, você está no caminho certo. Permite chegar a algo aqui, para que possamos obter um conjunto de script que vai fazer isso talvez ... um pensamento :-)
Brian Thomas
Brian, cuidado para não confundir zpools e conjuntos de dados. Embora não exista realmente um limite codificado acessível para o número de zpools que você pode criar, você será rapidamente limitado pelo número de dispositivos subjacentes (por exemplo, partições) disponíveis em sua máquina. Além disso, ter pools dedicados a diretórios únicos anulará alguns recursos valiosos do zfs e tornará as operações de movimentação muito mais lentas.
Jlliagre
neste comentário que você fez aqui @ Gilles "Mas o que você faz com o espaço livre? Se você o atribuir a outro pool, isso terá um custo, embora muito menos do que excluir arquivos individualmente" não tenho certeza, mas acho que não é uma penalidade na criação de um novo pool, acho que lida com ele apenas durante o tempo de gravação. nunca precisa ser dividido pela mesma razão .. Eu acredito que este é o mesmo mecanismo ..
Brian Thomas
1

Se precisar ser rápido, gerei um novo diretório temporário, mvo diretório abaixo dele, e excluo recursivamente o temporário:

t=`mktemp -d`
mv certainFolder $t/
rm -rf $t &
Simon Richter
fonte
o & remove identificador, ou erros de squash?
Brian Thomas
1
Isso não é realmente diferente da sugestão de Gilles e tem a mesma falha. Se o sistema operacional for reiniciado ou o rmcomando não for concluído por algum outro motivo, o diretório fantasma ficará com a exclusão não excluída.
Jlliagre
ahh certo, mas o & é novo para mim, isso faz parte do quebra-cabeça ... eu queria me livrar da alça. no entanto sim o seu direito, não quer que o lixo se houver um problema ..
Brian Thomas
O @BrianThomas &simplesmente coloca o processo em segundo plano, para que você possa continuar fazendo outras coisas no mesmo shell enquanto a exclusão estiver em execução (sujeita a penalidades de desempenho relevantes).
a CVn