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

57

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 após 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.

JuanRocamonde
fonte
8
FAO: Feche os revisores da fila de votação. Este não é um pedido de materiais de aprendizagem. Veja unix.meta.stackexchange.com/q/3892/22812
Anthony G - justice para Monica
2
O cache é opaco para o usuário, no melhor caso sync, e os aplicativos devem flushgarantir que os caches sejam gravados novamente, mas mesmo um êxito syncnão garante a gravação de volta para o disco físico, apenas que os caches do kernel são liberados para o disco, o que pode ter latência no hardware motorista ou de disco (por exemplo, cache-drive que você perde)
crasic
11
Embora eu não concorde que seja um pedido de materiais de aprendizagem, acho que a pergunta é um pouco ampla em sua forma atual. Limite o escopo às distribuições do Linux (ou qualquer sistema operacional específico) e, possivelmente, limite a certas tecnologias de armazenamento e sistemas de arquivos.
Jeff Schaller
3
Como apontou a @AnthonyGeoghegan, não considero esta pergunta uma solicitação de materiais de aprendizagem. Eu acho que é bastante específico; Não pedi uma explicação longa e profunda ou um manual sobre sistemas de arquivos Linux; apenas sobre uma breve idéia que eu queria esclarecer.
JuanRocamonde
3
É verdade que, como está, pode ser um pouco amplo, @JeffSchaller; Vou tentar editar um pouco; no entanto, honestamente, se o site não é para esse tipo de perguntas, que aborda diretamente o funcionamento do Linux, então para que serve?
JuanRocamonde

Respostas:

70

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 cpcomando 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 deve retornar somente depois que o arquivo atingir 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, "é suposto", 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 disso fsync(), também existem 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 sistema de arquivos específico atingiram o disco. O utilitário syncpode ser usado para chamá-los.

Depois, há também o O_DIRECTsinalizador paraopen() , 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_DIRECTsem 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 - 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, para que o desempenho diminua. 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ê.)

ilkkachu
fonte
some cases whereParece que seu link não diz nada sobre esses casos - está dizendo que houve problemas quando os aplicativos não foram usados fsync. Ou devo procurar nos comentários para encontrar esses casos que você está apontando?
Ruslan
11
Você também pode usar syncdiretamente como um comando do shell do sistema para cutucar o kernel para liberar todos os caches.
crasic
3
Na prática, em um sistema com pouca carga, o arquivo atingirá o disco dentro de um momento. Somente se o seu editor usar fsync()depois de gravar o arquivo. O padrão do Linux para /proc/sys/vm/dirty_writeback_centisecsé 500 (5 segundos) e o PowerTop recomenda configurá-lo para 1500 (15 segundos). ( kernel.org/doc/Documentation/sysctl/vm.txt ). Em um sistema com pouca carga, o kernel simplesmente deixa o cache de páginas sujo por muito tempo write()antes de liberar para o disco, para otimizar o caso em que ele é excluído ou modificado novamente em breve.
Peter Cordes
2
+1, pois a própria unidade pode fazer as mesmas mentiras para o sistema operacional . Meu entendimento é que as unidades que fazem esse tipo de cache também têm capacitância de energia suficiente para permitir que seus caches sejam salvos, mesmo em caso de perda de energia catastrófica. Isso não é específico do sistema operacional; O Windows possui o mecanismo "Remover USB com segurança" para executar a limpeza do cache antes que o usuário seja desconectado.
Studog 24/08/19
11
@studog, eu não teria tanta certeza, especialmente no hardware do consumidor. Mas pode ser apenas paranóia. Seria interessante testar, no entanto.
ilkkachu
14

Existe uma maneira extremamente simples de provar que não é verdade que as edições de arquivos sempre são salvas diretamente no disco, a saber, o fato de que existem sistemas de arquivos que não são apoiados por um disco . Se um sistema de arquivos não têm um disco em primeiro lugar, então ele não pode possivelmente escrever as alterações no disco, sempre .

Alguns exemplos são:

  • tmpfs, um sistema de arquivos que existe apenas na 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 não chegar ao disco. O SQLite também possui um white paper explicando os muitos obstáculos que você precisa para garantir o Atomic Commit In SQLite . (Observe que a Gravação atômica é muito mais difícil do que o problema do que apenas a gravação , mas é claro que gravar em disco é um subproblema da gravação atômica, e você também pode aprender muito sobre esse problema neste artigo.) seção sobre coisas que podem dar errado, que inclui uma subseção sobreLiberaçõ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 HDD que relata que gravou no disco quando realmente não o fez - sim, existem fabricantes de HDD que fazem isso, e pode até ser legal de acordo com as especificações do ATA, porque é ambiguamente redigido a esse respeito).

Jörg W Mittag
fonte
10
A primeira parte desta resposta é apenas desconcertante sobre a palavra exata usada. Não vejo como isso serve a outro propósito que não seja ridicularizar o usuário. Obviamente, um sistema de arquivos de rede não grava em um disco local, mas a questão ainda permanece lá.
pipe
3
Como o @pipe apontou, o fato de existirem sistemas de arquivos que não salvam dados em um disco porque eles não usam um disco para armazenar dados, não decide se quem os possui pode ou não salvá-los diretamente. No entanto, a resposta parece interessante
JuanRocamonde
11
@pipe Tenho certeza de que usar o termo "besserwissering" é besserwissering! Dizendo isso como um alemão Besserwisser com autoridade.
Volker Siegel
11

É verdade que a maioria dos sistemas operacionais, incluindo Unix, Linux e Windows, usa 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 resumo, há uma razão pela qual você deve desligar corretamente o computador e preparar adequadamente o armazenamento USB para remoção.

RalfFriedl
fonte
Obrigado por sua resposta! Existe uma maneira de forçar a gravação em disco de um arquivo específico no Linux? Talvez um link para um tutorial ou uma página docs, mesmo uma pergunta SE só iria ficar bem :)
JuanRocamonde
4
Você pode forçar a gravação do arquivo com o fsync()syscall de um programa. Em um shell, basta usar o synccomando
RalfFriedl
2
Existem (ou pelo menos havia) alguns sistemas de arquivos em algumas versões do Linux, onde syncfoi implementado como não operacional. E mesmo para sistemas de arquivos que não implementam corretamente sync, ainda há o problema de que alguns firmwares de disco implementar FLUSH CACHEcomo um não-op ou imediatamente voltar com ele e executá-lo em segundo plano.
Jörg W Mittag
9

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 possa não estar ciente? 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 disco rígido pode deixar um setor incompletamente escrito com uma soma de verificação inválida, o que nos dará uma boa falha de leitura posteriormente. 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 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 documentado como a maneira correta de gravar dados do arquivo, por exemplo, quando você clica em "salvar". E é amplamente entendido que, por exemplo, editores de texto devem substituir os arquivos existentes usando atomicamente rename(). Isso visa garantir que você sempre mantenha o arquivo antigo ou obtenha o novo arquivo (que foi fsync()editado 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 o uso otimizado de 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 de renomear (), 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 falhas ao substituir um arquivo existente por rename ()?

Alguns sistemas de arquivos menos populares não fornecem proteção. O XFS se recusa a fazê-lo. E o UBIFS também não o implementou, aparentemente poderia 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, incluindo 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.

sourcejedi
fonte
5

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

O dirty_expire_centisecspadrão do Linux é 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 on dirty_writeback_centisecs).

O padrão do Linux para /proc/sys/vm/dirty_writeback_centisecsé 500 (5 segundos) e o 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 podem estar 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 fsyncnão retornará até que os dados tenham sido realmente enviados para o disco).


O cache de gravação no 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.)

Peter Cordes
fonte