Domanda

diciamo Let si sta costruendo un sistema di stoccaggio journaling / write-ahead-logging. Si può semplicemente implementare questo (per ogni transazione) aggiungendo i dati (con write (2)), aggiungendo un commit marcatore, e quindi fsync-ing?

Lo scenario da considerare è se si fa un grande insieme di scritture a questo registro, allora fsync esso, e c'è un fallimento durante il fsync . Sono i diretti / puntatori blocco indiretto inode lavati solo dopo che tutti i blocchi di dati vengono cancellate, o ci sono garanzie che i blocchi vengono lavati in ordine? In quest'ultimo caso, poi durante il recupero, se si vede un commit marcatore alla fine del file, non è possibile fidarsi che i dati tra questa e la precedente commettono marcatore è significativo. Così si deve fare affidamento su un altro meccanismo (che coinvolgono almeno un'altra fsync) per determinare in che misura del file di log è coerente (ad esempio, la scrittura / fsyncing i dati, quindi scrivendo / fsyncing il marcatore commit).

Se si fa la differenza, chiedendosi soprattutto di ext3 / ext4 a seconda del contesto.

È stato utile?

Soluzione

Si noti che fsync e fdatasync di Linux e Mac OS sono corretti per impostazione predefinita. Windows è corretta per impostazione predefinita, ma in grado di emulare Linux per fini di benchmarking.

Inoltre, le questioni fdatasync dischi multipli scrive se si aggiunge alla fine di un file, in quanto ha bisogno di aggiornare l'inode file con la nuova lunghezza. Se si desidera avere una scrittura per commettere, la cosa migliore è quello di pre-allocare spazio di log, memorizzare una CRC delle voci di registro nel marcatore commit, ed emettere un unico fdatasync () in fase di commit. In questo modo, non importa quanto il sistema operativo / hardware di riordino dietro la schiena, è possibile trovare un prefisso di registro che in realtà ha colpito disco.

Se si desidera utilizzare il registro per commit durevoli o scrittura avanti, le cose si fanno più difficili, in quanto è necessario fare in modo che fsync funziona realmente. Sotto Linux, ti consigliamo di disabilitare la cache di scrittura del disco con hdparm, o montare la partizione con barriera impostata su true. [Edit: mi trovo corretto, la barriera non sembra dare la semantica corretta. SATA e SCSI introducono una serie di primitive, come le barriere di scrittura e Native Command Queuing, che rendono possibile per i sistemi operativi di esportare primitive che permettono la registrazione write-ahead. Da quello che posso dire da pagine di manuale e on-line, Linux espone solo questi sviluppatori al filesystem, non userspace.]

Paradossalmente, disabilitando la cache di scrittura del disco a volte porta a prestazioni migliori, dato che si ottiene un maggiore controllo sulla pianificazione di scrittura nello spazio utente; se le code del disco un mucchio di richieste di scrittura sincrone, si finisce per esporre strani picchi di latenza per l'applicazione. La disattivazione cache di scrittura impedisce che ciò accada.

Infine, i sistemi reali d'uso commettere, e fanno <1 sincronizzazione di scrittura per commettere con carichi di lavoro simultanei.

Altri suggerimenti

Non c'è alcuna garanzia sul l'ordine in cui i blocchi vengono scaricati su disco. In questi giorni anche l'unità stessa può riordinare blocchi nel loro cammino verso i piatti.

Se si desidera applicare l'ordinazione, è necessario almeno fdatasync() tra le operazioni di scrittura che si desidera ordinato. Tutte le promesse di una sincronizzazione è che quando ritorna di archiviazione, tutte le cose scritte prima che la sincronizzazione ha colpito.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top