2010-09-21 13 views
10

Si leo y escribo un solo archivo con las API IO normales, se garantiza que las escrituras serán atómicas por bloque. Es decir, si mi escritura solo modifica un bloque único, el sistema operativo garantiza que todo el bloque está escrito, o nada en absoluto.Memoria Archivos asignados y escrituras atómicas de bloques individuales

¿Cómo obtengo el mismo efecto en un archivo mapeado en memoria?

Los archivos mapeados en memoria son simplemente matrices de bytes, así que si modifico la matriz de bytes, el sistema operativo no tiene forma de saber cuándo considero que una escritura está "lista", por lo que podría (aunque sea poco probable) cambiar el memoria justo en el medio de mi operación de escritura de bloques, y en efecto, escribo medio bloque.

Necesitaría una especie de "entrar/salir de la sección crítica", o algún método para "fijar" la página de un archivo en la memoria mientras escribo. Algo como eso existe? Si es así, ¿es eso portable en los sistemas POSIX comunes? & Windows?

+0

¿Cuántas aplicaciones están interactuando con su archivo asignado? – Justin

+0

Solo un proceso, es decir, el servidor de la base de datos. –

Respuesta

4

La técnica de mantener un journal parece ser la única. No sé cómo funciona esto con varias aplicaciones que escriben en el mismo archivo. El proyecto Cassandra tiene un good article sobre cómo obtener rendimiento con un diario. La clave es asegurarse de que el diario solo registre acciones positivas (mi primer enfoque fue escribir la imagen previa de cada escritura en el diario, lo que le permitió deshacer, pero se volvió demasiado complicado).

Así que, básicamente, su archivo mapeado en memoria tiene un transactionId en el encabezado, si su encabezado cabe en un bloque, sabe que no se corrompe, aunque mucha gente parece escribirlo dos veces con una suma de comprobación: [header[cksum]] [header[cksum]]. Si la primera suma de comprobación falla, use la segunda.

La revista es como la siguiente:

[beginTxn[txnid]] [offset, length, data...] [commitTxn[txnid]] 

Usted acaba de seguir añadiendo registros de diario hasta que se hace demasiado grande, entonces lo transfiere en algún momento. Cuando inicie su programa, verifique si la identificación de la transacción para el archivo está en la última identificación de transacción del diario; si no, reproduce todas las transacciones en el diario para sincronizar.

+0

Sí, el diario es el camino a seguir, soy consciente de esos algoritmos. Pero el problema es que incluso cuando se utiliza un diario, debe garantizar que las páginas individuales de los archivos de datos solo se escriban de manera completa, de lo contrario corre el riesgo de tener una página "a medio escribir" y no puede detectar si esta corrupto o no Es por eso que estoy buscando una forma de hacer escrituras atómicas de páginas en archivos mapeados. –

+1

¿Por qué esto no funciona ?: partialWrite = (file.transaction-id Justin

+0

@MartinProbst: no puede hacer escrituras atómicas de páginas en absoluto. Es una operación fundamentalmente asincrónica para el kernel de Windows, creo. Probablemente quiera verificar la función de API Win de 'FlushFileBuffers'. – Noldorin

Cuestiones relacionadas