Le modifiche ai file in Linux vengono salvate direttamente sul disco?


57

Pensavo che le modifiche ai file venissero salvate direttamente sul disco, cioè non appena chiudo il file e decido di fare clic / selezionare Salva. Tuttavia, in una recente conversazione, un mio amico mi ha detto che di solito non è vero; il sistema operativo (in particolare stavamo parlando di sistemi Linux) mantiene le modifiche in memoria e ha un demone che scrive effettivamente il contenuto dalla memoria sul disco.

Ha anche fornito l'esempio di unità flash esterne: queste sono montate nel sistema (copiate nella memoria) e talvolta si verifica una perdita di dati perché il demone non ha ancora salvato il contenuto nella memoria flash; ecco perché smontiamo le unità flash.

Non ho conoscenza del funzionamento dei sistemi operativi, quindi non ho assolutamente idea se questo sia vero e in quali circostanze. La mia domanda principale è: questo succede come descritto nei sistemi Linux / Unix (e forse in altri sistemi operativi)? Ad esempio, ciò significa che se spengo il computer immediatamente dopo aver modificato e salvato un file, molto probabilmente le mie modifiche andranno perse? Forse dipende dal tipo di disco: dischi rigidi tradizionali rispetto a dischi a stato solido?

La domanda si riferisce specificamente ai filesystem che hanno un disco per archiviare le informazioni, anche se ogni chiarimento o confronto è ben accolto.


8
FAO: chiudi i revisori delle code di voto. Questa non è una richiesta per materiali didattici. Vedi unix.meta.stackexchange.com/q/3892/22812
Anthony G - giustizia per Monica,

2
La cache è opaca per l'utente, nel migliore dei casi è necessario sync, e le applicazioni devono flushgarantire che le cache siano riscritte, ma anche un successo syncnon garantisce di riscrivere sul disco fisico solo che le cache del kernel sono scaricate sul disco, che può avere latenza nell'hardware del driver o del disco (ad es. cache sull'unità che si perde)
crasic

1
Anche se non sono d'accordo sul fatto che si tratti di una richiesta di materiale didattico, penso che la domanda sia un po 'ampia nella sua forma attuale. Limitare l'ambito alle distribuzioni Linux (o qualunque sistema operativo specifico) e possibilmente limitarlo a determinate tecnologie di archiviazione e filesystem.
Jeff Schaller

3
Come ha sottolineato @AnthonyGeoghegan, non considero questa domanda una richiesta di materiale didattico. Penso che sia piuttosto specifico; Non ho chiesto una spiegazione lunga e profonda o un manuale sui filesystem Linux; solo per una breve idea che volevo chiarire.
JuanRocamonde,

3
È vero che così com'è potrebbe essere un po 'ampio, @JeffSchaller; Proverò a modificarlo un po '; tuttavia, onestamente, se il sito non è per questo tipo di domande, che riguardano direttamente il funzionamento di Linux, a cosa serve?
JuanRocamonde,

Risposte:


70

se spengo il computer immediatamente dopo aver modificato e salvato un file, molto probabilmente le mie modifiche andranno perse?

Potrebbero essere. Non direi "molto probabilmente", ma la probabilità dipende da molte cose.


Un modo semplice per aumentare le prestazioni delle scritture di file è che il sistema operativo memorizzi semplicemente nella cache i dati, indichi (mentire) l'applicazione che ha attraversato la scrittura e poi effettivamente scriva più tardi. Ciò è particolarmente utile se ci sono altre attività su disco in corso contemporaneamente: il sistema operativo può dare priorità alle letture ed eseguire le scritture in un secondo momento. Può anche rimuovere completamente la necessità di una vera e propria scrittura, ad esempio nel caso in cui un file temporaneo venga rimosso rapidamente in seguito.

Il problema di memorizzazione nella cache è più pronunciato se l'archiviazione è lenta. La copia di file da un SSD veloce a una chiavetta USB lenta probabilmente richiederà molta memorizzazione nella cache di scrittura, dal momento che la chiavetta USB non riesce a tenere il passo. Ma il tuo cpcomando ritorna più velocemente, quindi puoi continuare a lavorare, possibilmente anche modificando i file che sono stati appena copiati.


Naturalmente la memorizzazione nella cache in questo modo ha il rovescio della medaglia che si nota, alcuni dati potrebbero andare persi prima di essere effettivamente salvati. L'utente sarà seccato se il suo editor ha detto loro che la scrittura è andata a buon fine, ma il file non era effettivamente sul disco. Ecco perché c'è la fsync()chiamata di sistema , che dovrebbe tornare solo dopo che il file ha effettivamente colpito il disco. Il tuo editor può utilizzarlo per assicurarsi che i dati siano corretti prima di segnalare all'utente che la scrittura è riuscita.

Ho detto "si suppone", poiché l'unità stessa potrebbe dire le stesse bugie al sistema operativo e dire che la scrittura è completa, mentre il file esiste davvero solo in una cache di scrittura volatile all'interno dell'unità. A seconda dell'unità, potrebbe non esserci alcun modo per aggirare questo.

Inoltre fsync(), ci sono anche le chiamate di sistema sync()e syncfs()che chiedono al sistema di assicurarsi che tutte le scritture a livello di sistema o tutte le scritture su un particolare filesystem abbiano colpito il disco. L'utilità syncpuò essere utilizzata per chiamare quelli.

Poi c'è anche il O_DIRECTflag toopen() , che dovrebbe "provare a minimizzare gli effetti cache dell'I / O verso e da questo file". La rimozione della memorizzazione nella cache riduce le prestazioni, quindi viene utilizzata principalmente dalle applicazioni (database) che eseguono la propria memorizzazione nella cache e vogliono controllarne il controllo. ( O_DIRECTnon è privo di problemi, i commenti al riguardo nella pagina man sono in qualche modo divertenti.)


Ciò che accade in caso di spegnimento dipende anche dal filesystem. Non dovresti preoccuparti solo dei dati dei file, ma dei metadati del filesystem. Avere i dati del file su disco non è molto utile se non riesci a trovarli. La semplice estensione di un file a dimensioni maggiori richiede l'allocazione di nuovi blocchi di dati e devono essere contrassegnati da qualche parte.

Il modo in cui un filesystem gestisce le modifiche ai metadati e l'ordinamento tra metadati e scritture di dati varia molto. Ad esempio, con ext4, se si imposta il flag mount data=journal, tutte le scritture - anche le scritture dei dati - passano attraverso il journal e dovrebbero essere piuttosto sicure. Ciò significa anche che vengono scritti due volte, quindi le prestazioni diminuiscono. Le opzioni predefinite tentano di ordinare le scritture in modo che i dati si trovino sul disco prima dell'aggiornamento dei metadati. Altre opzioni o altri filesystem possono essere migliori o peggiori; Non proverò nemmeno uno studio completo.


In pratica, su un sistema leggermente caricato, il file dovrebbe colpire il disco entro pochi secondi. Se hai a che fare con una memoria rimovibile, smonta il filesystem prima di estrarre il supporto per assicurarti che i dati vengano effettivamente inviati all'unità e non ci siano ulteriori attività. (O fai in modo che il tuo ambiente GUI lo faccia per te.)


Il tuo some cases wherelink non sembra dire su tali casi - sta invece dicendo che c'erano problemi quando le app non usavano fsync. O dovrei guardare nei commenti per trovare questi casi che stai indicando?
Ruslan,

1
Puoi anche usare syncdirettamente come comando shell di sistema per colpire il kernel per svuotare tutte le cache.
crasic

3
In pratica, su un sistema leggermente caricato, il file colpirà il disco in un attimo. Solo se il tuo editor usa fsync()dopo aver scritto il file. L'impostazione predefinita di Linux /proc/sys/vm/dirty_writeback_centisecsè 500 (5 secondi) e PowerTop consiglia di impostarlo su 1500 (15 secondi). ( kernel.org/doc/Documentation/sysctl/vm.txt ). Su un sistema leggermente caricato, il kernel lo lascerà semplicemente sporco nella cache della pagina molto tempo write()prima di svuotare il disco, per ottimizzare il caso in cui viene eliminato o modificato di nuovo presto.
Peter Cordes,

2
+1 per poiché l'unità stessa potrebbe fare le stesse bugie al sistema operativo . La mia comprensione è che le unità che eseguono quel tipo di memorizzazione nella cache hanno anche una capacità di alimentazione sufficiente per consentire il salvataggio delle loro cache anche in caso di perdita di potenza catastrofica. Questo non è specifico del sistema operativo; Windows ha il meccanismo "Rimozione sicura dell'USB" per eseguire lo svuotamento della cache prima che l'utente venga disconnesso.
Studog

1
@studog, non ne sarei così sicuro, specialmente sull'hardware consumer. Ma potrebbe essere solo paranoia. Sarebbe interessante testarlo, però.
ilkkachu,

14

Esiste un modo estremamente semplice per dimostrare che non può essere vero che le modifiche ai file vengono sempre salvate direttamente su disco, in particolare il fatto che ci sono file system che non sono supportati da un disco in primo luogo . Se un filesystem non ha un disco in primo luogo, non può mai scrivere le modifiche sul disco, mai .

Alcuni esempi sono:

  • tmpfs, un file system che esiste solo nella RAM (o più precisamente, nella cache del buffer)
  • ramfs, un file system che esiste solo nella RAM
  • qualsiasi file system di rete (NFS, CIFS / SMB, AFS, AFP, ...)
  • qualsiasi filesystem virtuale ( sysfs, procfs, devfs, shmfs, ...)

Ma anche per i file system supportati da disco questo di solito non è vero. La pagina Come corrompere un database SQLite ha un capitolo chiamato Mancata sincronizzazione che descrive molti modi diversi in cui le scritture (in questo caso si impegnano in un database SQLite) non possono arrivare sul disco. SQLite ha anche un white paper che spiega i numerosi cerchi che devi saltare per garantire Atomic Commit in SQLite . (Nota che Atomic Write è un problema molto più difficile del semplice Write , ma ovviamente scrivere su disco è un sotto-problema della scrittura atomica, e puoi anche imparare molto su questo problema da questo documento.) sezione su Cose che possono andare storte che include una sottosezione suFlush del disco incompleti che forniscono alcuni esempi di complessità complesse che potrebbero impedire a una scrittura di raggiungere il disco (come il controller dell'HDD che segnala che ha scritto sul disco quando non lo è - sì, ci sono produttori di HDD che lo fanno, e potrebbe anche essere legale secondo le specifiche ATA, perché è formulato in modo ambiguo in questo senso).


10
La prima parte di questa risposta è solo una riflessione sull'esatta parola utilizzata. Non vedo come serva a nessuno scopo se non quello di ridicolizzare l'utente. Ovviamente un file system di rete non scriverà su un disco locale ma la domanda è ancora valida.
pipe

3
Come ha sottolineato @pipe, il fatto che ci siano filesystem che non salvano i dati su un disco perché non usano un disco per archiviare i dati, non decide se chi li possiede può o meno salvarli direttamente. Tuttavia, la risposta sembra interessante
JuanRocamonde,

1
@pipe Sono abbastanza sicuro che usare il termine "besserwissering" sia besserwissering! Detto questo come un tedesco Besserwisser con autorità.
Volker Siegel,

11

È vero che la maggior parte dei sistemi operativi, inclusi Unix, Linux e Windows utilizzano una cache di scrittura per accelerare le operazioni. Ciò significa che spegnere un computer senza spegnerlo è una cattiva idea e può portare alla perdita di dati. Lo stesso vale se si rimuove una memoria USB prima che sia pronta per essere rimossa.

La maggior parte dei sistemi offre anche l'opzione per rendere le scritture sincrone. Ciò significa che i dati saranno su disco prima che un'applicazione riceva una conferma di successo, a costo di essere più lenta.

In breve, c'è un motivo per cui è necessario arrestare correttamente il computer e preparare correttamente l'archiviazione USB per la rimozione.


Grazie per la risposta! C'è un modo per forzare la scrittura su disco di un file specifico in Linux? Forse un link a un tutorial o una pagina di documenti, anche una domanda SE andrebbe bene :)
JuanRocamonde

4
È possibile forzare la scrittura del file con la fsync()syscall da un programma. Da una shell, basta usare il synccomando.
RalfFriedl,

2
Esistono (o almeno esistevano) alcuni filesystem in alcune versioni di Linux, dove è syncstato implementato come no-op. E anche per i filesystem che si implementano correttamente sync, c'è ancora il problema che alcuni firmware del disco implementano FLUSH CACHEcome no-op o ritornano immediatamente da esso ed eseguono in background.
Jörg W Mittag,

9

1. Archiviazione basata su Flash

Dipende dal tipo di disco (dischi rigidi tradizionali vs. dischi a stato solido) o da qualsiasi altra variabile di cui potrei non essere a conoscenza? Succede (se succede) solo in Linux o è presente in altri sistemi operativi?

Quando hai una scelta, non dovresti permettere allo storage basato su flash di perdere energia senza un arresto pulito.

Su storage a basso costo come le schede SD, puoi aspettarti di perdere interi blocchi di cancellazione (diverse volte più grandi di 4KB), perdendo dati che potrebbero appartenere a diversi file o strutture essenziali del filesystem.

Alcuni costosi SSD potrebbero pretendere di offrire migliori garanzie in caso di mancanza di corrente. Tuttavia, test di terze parti suggeriscono che molti SSD costosi non riescono a farlo. Lo strato che rimappa i blocchi per il "livellamento dell'usura" è complesso e proprietario. I possibili guasti includono la perdita di tutti i dati sull'unità.

Applicando il nostro framework di test, testiamo 17 SSD di materie prime di sei diversi fornitori utilizzando in totale più di tremila cicli di iniezione di guasti. I nostri risultati sperimentali rivelano che 14 dei 17 dispositivi SSD testati presentano comportamenti di guasto sorprendenti in caso di interruzioni dell'alimentazione, tra cui corruzione dei bit, scritture rasate, scritture non serializzabili, corruzione dei metadati e guasti totali del 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. Unità disco rigido rotanti

Gli HDD rotanti hanno caratteristiche diverse. Per sicurezza e semplicità, consiglio di presumere che abbiano la stessa incertezza pratica dello storage basato su flash.

A meno che tu non abbia prove specifiche, cosa che chiaramente non hai. Non ho dati comparativi per la rotazione degli HDD.

Un HDD potrebbe lasciare un settore scritto in modo incompleto con un checksum errato, il che ci darà un buon errore di lettura in seguito. In generale, questa modalità di guasto degli HDD è del tutto prevista; i filesystem nativi di Linux sono progettati pensando a questo. Mirano a preservare il contratto di fsync()fronte a questo tipo di guasto di perdita di potenza. (Vorremmo davvero vederlo garantito su SSD).

Tuttavia non sono sicuro se i filesystem Linux riescano a raggiungere questo obiettivo in tutti i casi o se ciò sia persino possibile.

Il prossimo avvio dopo questo tipo di errore potrebbe richiedere una riparazione del filesystem. Essendo Linux, è possibile che la riparazione del filesystem ponga alcune domande che non capisci, dove puoi solo premere Y e sperare che si risolva da solo.

2.1 Se non sai qual è il contratto fsync ()

Il contratto fsync () è una fonte di buone e cattive notizie. Devi prima capire la buona notizia.

Buone notizie: fsync()è ben documentato come il modo corretto di scrivere i dati del file, ad esempio quando si preme "salva". È risaputo che, ad esempio, gli editor di testo devono sostituire atomicamente i file esistenti rename(). Questo ha lo scopo di assicurarsi di mantenere sempre il vecchio file o di ottenere il nuovo file (che è stato fsync()editato prima della ridenominazione). Non vuoi essere lasciato con una versione scritta a metà del nuovo file.

Cattive notizie: per molti anni, chiamare fsync () sul filesystem Linux più popolare potrebbe effettivamente lasciare l'intero sistema in sospeso per decine di secondi. Dato che le applicazioni non possono fare nulla al riguardo, era molto comune usare in modo ottimistico rename () senza fsync (), che sembrava essere relativamente affidabile su questo filesystem.

Pertanto, esistono applicazioni che non utilizzano correttamente fsync ().

La prossima versione di questo filesystem generalmente evitava il blocco di fsync (), mentre iniziava a fare affidamento sull'uso corretto di fsync ().

È tutto piuttosto male. La comprensione di questa storia non è probabilmente aiutata dal tono sprezzante e dall'invettiva che è stata usata da molti sviluppatori del kernel in conflitto.

L'attuale risoluzione è che l'attuale filesystem Linux più popolare per impostazione predefinita supporta il modello rename () senza richiedere fsync ()implementa la "compatibilità bug-for-bug" con la versione precedente. Questo può essere disabilitato con l'opzione mount noauto_da_alloc.

Questa non è una protezione completa. Fondamentalmente scarica l'IO in sospeso al momento della ridenominazione (), ma non attende il completamento dell'IO prima di rinominare. Tuttavia, è molto meglio di una finestra di pericolo di 60 secondi! Vedi anche la risposta a Quali filesystem richiedono fsync () per la sicurezza in caso di crash quando si sostituisce un file esistente con rename ()?

Alcuni filesystem meno popolari non offrono protezione. XFS si rifiuta di farlo. E UBIFS non lo ha nemmeno implementato, a quanto pare potrebbe essere accettato ma ha bisogno di molto lavoro per renderlo possibile. La stessa pagina sottolinea che UBIFS ha diversi altri problemi "TODO" per l'integrità dei dati, incluso in caso di perdita di potenza. UBIFS è un filesystem utilizzato direttamente su memoria flash. Immagino che alcune delle difficoltà che UBIFS menziona con l'archiviazione flash possano essere rilevanti per i bug dell'SSD.


5

Su un sistema leggermente caricato, il kernel lascerà i dati dei file appena scritti nella cache della pagina per circa 30 secondi dopo a write(), prima di scaricarli su disco, per ottimizzare il caso in cui vengono eliminati o modificati di nuovo presto.

Il dirty_expire_centisecsvalore predefinito di Linux è 3000 (30 secondi) e controlla quanto tempo "scade" i dati appena scritti. (Vedi https://lwn.net/Articles/322823/ ).

Vedi https://www.kernel.org/doc/Documentation/sysctl/vm.txt per ulteriori parametri sintonizzabili e google per molti altri. (ad esempio google on dirty_writeback_centisecs).

L'impostazione predefinita di Linux /proc/sys/vm/dirty_writeback_centisecsè 500 (5 secondi) e PowerTop consiglia di impostarlo su 1500 (15 secondi) per ridurre il consumo energetico.


La riscrittura ritardata dà anche tempo al kernel di vedere quanto sarà grande un file, prima di iniziare a scriverlo su disco. I filesystem con allocazione ritardata (come XFS, e probabilmente altri al giorno d'oggi) non scelgono nemmeno dove sul disco mettere i dati di un file appena scritto fino a quando necessario, separatamente dall'allocazione dello spazio per l'inode stesso. Ciò riduce la frammentazione, consentendo loro di evitare l'inizio di un file di grandi dimensioni in uno spazio di 1 megapixel tra altri file, ad esempio.

Se vengono scritti molti dati, il writeback su disco può essere attivato da una soglia per la quantità di dati sporchi (non ancora sincronizzati su disco) nella pagecache.

Se non stai facendo molto altro, tuttavia, la spia di attività del disco rigido non si accende per 5 (o 15) secondi dopo aver eseguito il salvataggio su un piccolo file.


Se il tuo editor ha usato fsync()dopo aver scritto il file, il kernel lo scriverà su disco senza indugio. (E fsyncnon tornerà fino a quando i dati non saranno stati effettivamente inviati al disco).


Anche la cache di scrittura all'interno del disco può essere una cosa, ma i dischi normalmente provano a trasferire la loro cache di scrittura nello storage permanente al più presto, a differenza degli algoritmi di cache di pagina di Linux. Le cache di scrittura su disco sono più un buffer di archivio per assorbire piccole esplosioni di scritture, ma forse anche per ritardare le scritture a favore delle letture e dare spazio al firmware dei dischi per ottimizzare un modello di ricerca (ad esempio fare due scritture o letture vicine invece di fare una , poi cerca lontano, poi cerca indietro.)

Su un disco rotante (magnetico), potresti vedere alcuni ritardi di ricerca da 7 a 10 ms ciascuno prima che i dati da un comando di scrittura SATA siano effettivamente al sicuro dallo spegnimento, se c'erano delle letture / scritture in sospeso prima della tua scrittura. (Alcune altre risposte a questa domanda entrano più nel dettaglio nella cache di scrittura su disco e scrivono le barriere che gli FS di giornali possono usare per evitare la corruzione.)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.