desenv-web-rp.com

As edições de arquivo no Linux são salvas diretamente no disco?

Eu costumava pensar que as alterações do arquivo são salvas diretamente no disco, ou seja, assim que eu fecho o arquivo e decido clicar/selecionar salvar. No entanto, em uma conversa recente, um amigo meu me disse que isso geralmente não é verdade; o sistema operacional (especificamente sobre os sistemas Linux) mantém as alterações na memória e possui um daemon que realmente grava o conteúdo da memória no disco.

Ele até deu o exemplo de unidades flash externas: elas são montadas no sistema (copiadas na memória) e às vezes a perda de dados ocorre porque o daemon ainda não salvou o conteúdo na memória flash; é por isso que desmontamos pen drives.

Não tenho conhecimento sobre o funcionamento de sistemas operacionais e, portanto, não tenho absolutamente nenhuma idéia se isso é verdade e em que circunstâncias. Minha principal pergunta é: isso acontece como descrito nos sistemas Linux/Unix (e talvez em outros sistemas operacionais)? Por exemplo, isso significa que se eu desligar o computador imediatamente depois de editar e salvar um arquivo, minhas alterações provavelmente serão perdidas? Talvez isso dependa do tipo de disco - discos rígidos tradicionais x discos de estado sólido?

A pergunta refere-se especificamente aos sistemas de arquivos que possuem um disco para armazenar as informações, mesmo que qualquer esclarecimento ou comparação seja bem recebido.

58
JuanRocamonde

se eu desligar o computador imediatamente após editar e salvar um arquivo, minhas alterações provavelmente serão perdidas?

Eles podem ser. Eu não diria "provavelmente", mas a probabilidade depende de muitas coisas.


Uma maneira fácil de aumentar o desempenho da gravação de arquivos é o sistema operacional apenas armazenar em cache os dados, informar (mentir para) o aplicativo pelo qual a gravação passou e, em seguida, fazer a gravação posteriormente. Isso é especialmente útil se houver outra atividade de disco acontecendo ao mesmo tempo: o sistema operacional pode priorizar as leituras e fazer as gravações posteriormente. Também pode remover completamente a necessidade de uma gravação real, por exemplo, no caso em que um arquivo temporário é removido rapidamente depois.

O problema de armazenamento em cache é mais pronunciado se o armazenamento estiver lento. Copiar arquivos de um SSD rápido para um pen drive lento provavelmente envolverá muito cache de gravação, já que o pen drive não consegue acompanhar. Mas seu comando cp retorna mais rápido, para que você possa continuar trabalhando, possivelmente até editando os arquivos que foram copiados.


É claro que o cache como esse tem o lado negativo que você observa, alguns dados podem ser perdidos antes de serem realmente salvos. O usuário ficará ofendido se o editor informar que a gravação foi bem-sucedida, mas o arquivo não estava realmente no disco. É por isso que existe a fsync() chamada do sistema , que deveria retornar somente depois que o arquivo realmente atingiu o disco. Seu editor pode usar isso para garantir que os dados estejam corretos antes de relatar ao usuário que a gravação foi bem-sucedida.

Eu disse "deveria", já que a própria unidade pode contar as mesmas mentiras para o sistema operacional e dizer que a gravação está concluída, enquanto o arquivo realmente existe apenas em um cache de gravação volátil na unidade. Dependendo da unidade, pode não haver maneira de contornar isso.

Além de fsync(), também existem as chamadas de sistema sync() e syncfs() que solicitam ao sistema que verifique se todas as gravações em todo o sistema ou todas as gravações em um determinado O sistema de arquivos atingiu o disco. O utilitário sync pode ser usado para chamá-los.

Também há o sinalizador O_DIRECT Para open() , que deveria "tentar minimizar os efeitos de cache da E/S para e deste arquivo". A remoção do armazenamento em cache reduz o desempenho; portanto, isso é usado principalmente por aplicativos (bancos de dados) que fazem seu próprio cache e desejam controlá-lo. (O_DIRECT Não deixa de ter seus problemas, os comentários sobre ele na página de manual são divertidos.)


O que acontece em uma saída de energia também depende do sistema de arquivos. Não são apenas os dados do arquivo que você deve se preocupar, mas os metadados do sistema de arquivos. Ter os dados do arquivo em disco não é muito útil se você não conseguir encontrá-los. Apenas estender um arquivo para um tamanho maior exigirá a alocação de novos blocos de dados e eles deverão ser marcados em algum lugar.

O modo como um sistema de arquivos lida com as alterações de metadados e a ordem entre metadados e gravações de dados variam muito. Por exemplo, com ext4, Se você definir o sinalizador de montagem data=journal, Todas as gravações - até mesmo gravações de dados - passam pelo diário e devem ser bastante seguras. Isso também significa que eles são escritos duas vezes, então o desempenho diminui. As opções padrão tentam ordenar as gravações para que os dados estejam no disco antes da atualização dos metadados. Outras opções ou outro sistema de arquivos podem ser melhores ou piores; Nem tentarei um estudo abrangente.


Na prática, em um sistema com pouca carga, o arquivo deve atingir o disco dentro de alguns segundos. Se você estiver lidando com armazenamento removível, desmonte o sistema de arquivos antes de puxar a mídia para garantir que os dados sejam realmente enviados para a unidade e que não haja mais atividades. (Ou faça com que seu ambiente GUI faça isso por você.)

70
ilkkachu

Existe uma maneira extremamente simples de provar que não pode ser verdade que as edições dos arquivos são sempre salvas diretamente no disco, ou seja, o fato de existirem sistemas de arquivos que não são suportados por um disco em primeiro lugar . Se um sistema de arquivos não tem um disco em primeiro lugar, então não pode escreva as alterações no disco, sempre .

Alguns exemplos são:

  • tmpfs, um sistema de arquivos que existe apenas em RAM (ou mais precisamente, no cache do buffer)
  • ramfs, um sistema de arquivos que existe apenas na RAM
  • qualquer sistema de arquivos de rede (NFS, CIFS/SMB, AFS, AFP,…)
  • qualquer sistema de arquivos virtual (sysfs, procfs, devfs, shmfs, ...)

Mas mesmo para sistemas de arquivos com backup em disco, isso geralmente não é verdade. A página Como corromper um banco de dados SQLite possui um capítulo chamado Falha na sincronização que descreve muitas maneiras diferentes pelas quais as gravações (nesse caso confirmam um banco de dados SQLite) podem falhar ao chegar ao disco. O SQLite também possui um white paper explicando os muitos obstáculos que você precisa percorrer para garantir Confirmação atômica no SQLite . (Observe que Gravação atômica é muito mais difícil que o problema do que apenas Gravação , mas é claro que gravar em disco é um sub-problema da gravação atômica, e você também pode aprender muito sobre esse problema neste artigo.) Este artigo possui uma seção sobre Coisas que podem dar errado que inclui uma subseção sobre Liberações de disco incompletas = que fornecem alguns exemplos de meandros sutis que podem impedir que uma gravação chegue ao disco (como o controlador do disco rígido relatando que gravou no disco quando realmente não o fez - sim, existem fabricantes de discos rígidos que pode até ser legal de acordo com as especificações do ATA, porque é ambiguamente redigido a esse respeito).

14
Jörg W Mittag

É verdade que a maioria dos sistemas operacionais, incluindo Unix, Linux e Windows, usam um cache de gravação para acelerar as operações. Isso significa que desligar um computador sem desligá-lo é uma má ideia e pode levar à perda de dados. O mesmo acontece se você remover um armazenamento USB antes de estar pronto para ser removido.

A maioria dos sistemas também oferece a opção de fazer gravações síncronas. Isso significa que os dados estarão em disco antes que um aplicativo receba uma confirmação de sucesso, ao custo de ser mais lento.

Em suma, há uma razão pela qual você deve desligar corretamente o computador e preparar adequadamente o armazenamento USB para remoção.

11
RalfFriedl

1. Armazenamento baseado em Flash

Depende do tipo de disco (discos rígidos tradicionais versus discos de estado sólido) ou de qualquer outra variável que eu talvez não saiba? Isso acontece (se acontecer) apenas no Linux ou está presente em outros sistemas operacionais?

Quando você tem uma opção, não deve permitir que o armazenamento baseado em flash perca energia sem um desligamento limpo.

Em armazenamento de baixo custo, como cartões SD, você pode perder blocos de apagamento inteiros (várias vezes maiores que 4KB), perdendo dados que podem pertencer a arquivos diferentes ou estruturas essenciais do sistema de arquivos.

Alguns SSDs caros podem alegar oferecer melhores garantias em caso de falha de energia. No entanto, testes de terceiros sugerem que muitos SSDs caros não conseguem fazer isso. A camada que remapeia os blocos para "nivelamento de desgaste" é complexa e proprietária. As possíveis falhas incluem a perda de todos os dados na unidade.

Aplicando nossa estrutura de teste, testamos 17 SSDs de commodities de seis fornecedores diferentes, usando mais de três mil ciclos de injeção de falhas no total. Nossos resultados experimentais revelam que 14 dos 17 dispositivos SSD testados exibem comportamentos surpreendentes de falha sob falhas de energia, incluindo corrupção de bits, gravações cortadas, gravações não serializáveis, corrupção de metadados e falha total do dispositivo.

2017: https://dl.acm.org/citation.cfm?id=2992782&preflayout=flat

2013: https://www.usenix.org/system/files/conference/fast13/fast13-final80.pdf?wptouch_preview_theme=enabled

2. Girando unidades de disco rígido

Os HDDs giratórios têm características diferentes. Por segurança e simplicidade, recomendo que eles tenham a mesma incerteza prática que o armazenamento baseado em flash.

A menos que você tenha evidências específicas, o que você claramente não tem. Não tenho números comparativos para girar HDDs.

Um HDD pode deixar um setor incompletamente escrito com uma soma de verificação ruim, o que nos dará uma falha de leitura agradável mais tarde. De um modo geral, esse modo de falha dos HDDs é totalmente esperado; sistemas de arquivos Linux nativos são projetados com isso em mente. Eles visam preservar o contrato de fsync() diante desse tipo de falha de perda de energia. (Gostaríamos muito de ver isso garantido nos SSDs).

No entanto, não tenho certeza se os sistemas de arquivos Linux conseguem isso em todos os casos ou se isso é possível.

A próxima inicialização após esse tipo de falha pode exigir um reparo no sistema de arquivos. Sendo o Linux, é possível que o reparo do sistema de arquivos faça algumas perguntas que você não entende, onde você pode apenas pressionar Y e esperar que ele se resolva.

2.1 Se você não sabe qual é o contrato fsync ()

O contrato fsync () é uma fonte de boas e más notícias. Você deve entender as boas novas primeiro.

Boas notícias: fsync() está bem documentada como a maneira correta de gravar dados do arquivo, por exemplo. quando você clica em "salvar". E é amplamente entendido que p. os editores de texto devem substituir os arquivos existentes atomicamente usando rename(). Isso visa garantir que você sempre mantenha o arquivo antigo ou obtenha o novo arquivo (que foi fsync() ed antes da renomeação). Você não quer ficar com uma versão semi-escrita do novo arquivo.

Más notícias: por muitos anos, chamar fsync () no sistema de arquivos Linux mais popular poderia efetivamente deixar todo o sistema travado por dezenas de segundos. Como os aplicativos não podem fazer nada sobre isso, era muito comum usar de maneira otimista rename () sem fsync (), que parecia ser relativamente confiável nesse sistema de arquivos.

Portanto, existem aplicativos que não usam fsync () corretamente.

A próxima versão deste sistema de arquivos geralmente evitava o travamento do fsync () - ao mesmo tempo em que começava a confiar no uso correto do fsync ().

Tudo isso é muito ruim. A compreensão dessa história provavelmente não é ajudada pelo tom desdenhoso e invectivo que foi usado por muitos dos desenvolvedores conflitantes do kernel.

A resolução atual é que o sistema de arquivos Linux mais popular atualmente o padrão é dar suporte ao padrão rename () sem exigir fsync () implementa "compatibilidade de bug por bug" com a versão anterior. Isso pode ser desativado com a opção de montagem noauto_da_alloc.

Esta não é uma proteção completa. Basicamente, ele libera o IO pendente no momento da renomeação (), mas não espera que o IO seja concluído antes de renomear. Isso é muito melhor do que por exemplo, uma janela de perigo de 60 segundos! Consulte também a resposta para Quais sistemas de arquivos exigem fsync () para segurança contra acidentes ao substituir um arquivo existente por rename ()?

Alguns sistemas de arquivos menos populares não fornecem proteção. XFS recusa para fazer isso. E UBIFS também não o implementou, aparentemente pode ser aceito, mas precisa de muito trabalho para torná-lo possível. A mesma página indica que o UBIFS possui vários outros problemas "TODO" para integridade de dados, inclusive sobre perda de energia. O UBIFS é um sistema de arquivos usado diretamente no armazenamento flash. Imagino que algumas das dificuldades mencionadas pelo UBIFS no armazenamento flash possam ser relevantes para os erros do SSD.

9
sourcejedi

Em um sistema com pouca carga, o kernel permitirá que os dados do arquivo recém-gravados permaneçam no cache da página por talvez 30 segundos após uma write(), antes de liberá-lo no disco, para otimizar o caso em que foram excluídos ou modificado novamente em breve.

dirty_expire_centisecs Do Linux é padronizado como 3000 (30 segundos) e controla quanto tempo antes dos dados recém-gravados "expirarem". (Veja https://lwn.net/Articles/322823/ ).

Veja https://www.kernel.org/doc/Documentation/sysctl/vm.txt para obter mais tunables relacionados, e google para muito mais. (por exemplo, google em dirty_writeback_centisecs).

O padrão do Linux para /proc/sys/vm/dirty_writeback_centisecs É 500 (5 segundos) , e a PowerTop recomenda configurá-lo para 1500 (15 segundos) para reduzir o consumo de energia .


A gravação atrasada também dá tempo para o kernel ver o tamanho de um arquivo antes de começar a gravá-lo no disco. Os sistemas de arquivos com alocação atrasada (como o XFS e provavelmente outros atualmente) nem sequer escolhem onde no disco colocar os dados de um arquivo recém-gravado até que seja necessário, separadamente da alocação de espaço para o próprio inode. Isso reduz a fragmentação, permitindo que eles evitem colocar o início de um arquivo grande em um espaço de 1 meg entre outros arquivos, por exemplo.

Se muitos dados estiverem sendo gravados, o write-back no disco poderá ser acionado por um limite para a quantidade de dados sujos (ainda não sincronizados com o disco) que pode haver no pagecache.

Se você não estiver fazendo muito mais, sua luz de atividade no disco rígido não acenderá por 5 (ou 15) segundos após pressionar Salvar em um arquivo pequeno.


Se o seu editor usou fsync() depois de gravar o arquivo, o kernel o gravará no disco sem demora. (E fsync não retornará até que os dados tenham sido realmente enviados para o disco).


Cache de gravação dentro o disco também pode ser uma coisa, mas os discos normalmente tentam confirmar seu cache de gravação no armazenamento permanente o mais rápido possível, ao contrário dos algoritmos de cache de página do Linux. Os caches de gravação em disco são mais um buffer de armazenamento para absorver pequenas rajadas de gravação, mas talvez também para atrasar gravações em favor de leituras e dar espaço ao firmware dos discos para otimizar um padrão de busca (por exemplo, faça duas gravações ou leituras próximas em vez de fazer uma , depois procurando longe, depois procurando de volta.)

Em um disco rotativo (magnético), você poderá observar alguns atrasos de busca de 7 a 10 ms cada, antes que os dados de um comando de gravação SATA estejam realmente seguros de desligar, se houver leituras/gravações pendentes antes da gravação. (Algumas outras respostas sobre essa pergunta entram em mais detalhes sobre caches de gravação em disco e barreiras de gravação que os FSes rotulados podem usar para evitar corrupção.)

5
Peter Cordes