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.
fonte
sync
, e os aplicativos devemflush
garantir que os caches sejam gravados novamente, mas mesmo um êxitosync
nã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)Respostas:
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
cp
comando 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 sistemasync()
esyncfs()
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áriosync
pode ser usado para chamá-los.Depois, há também o
O_DIRECT
sinalizador 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_DIRECT
sem 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 montagemdata=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ê.)
fonte
some cases where
Parece que seu link não diz nada sobre esses casos - está dizendo que houve problemas quando os aplicativos não foram usadosfsync
. Ou devo procurar nos comentários para encontrar esses casos que você está apontando?sync
diretamente como um comando do shell do sistema para cutucar o kernel para liberar todos os caches.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 tempowrite()
antes de liberar para o disco, para otimizar o caso em que ele é excluído ou modificado novamente em breve.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 RAMsysfs
,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).
fonte
É 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.
fonte
fsync()
syscall de um programa. Em um shell, basta usar osync
comandosync
foi implementado como não operacional. E mesmo para sistemas de arquivos que não implementam corretamentesync
, ainda há o problema de que alguns firmwares de disco implementarFLUSH CACHE
como um não-op ou imediatamente voltar com ele e executá-lo em segundo plano.1. Armazenamento baseado em Flash
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.
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 atomicamenterename()
. Isso visa garantir que você sempre mantenha o arquivo antigo ou obtenha o novo arquivo (que foifsync()
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 montagemnoauto_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.
fonte
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_centisecs
padrã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. (Efsync
nã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.)
fonte