2010-08-27 15 views
5

En el SQLite documentation en la función de escritura anticipada de registro presentada en la versión 3.7, hay algunos comentarios que me confundieron un poco.¿Qué tan seguro es SQLite WAL en fallas de energía?

La página enlazada dice que "no es necesario sincronizar el contenido con el disco, siempre que la aplicación esté dispuesta a sacrificar la durabilidad después de una pérdida de potencia". Luego, un par de párrafos abajo, dice "Checkpointing requiere operaciones de sincronización para evitar la posibilidad de corrupción de la base de datos después de una pérdida de energía o un reinicio" ".

Mi base de datos está en mayor riesgo de corrupción en la pérdida de potencia si uso WAL?

Respuesta

4

no hay aumento del riesgo de corrupción con WAL (ya que utiliza las operaciones de sincronización cuando los puntos de control).

sin embargo, si hay un accidente (pérdida de energía o reinicio duro) se perderá cualquier transacciones desde el último punto de control; eso es lo que significa "sacrificar la durabilidad".

+3

Sé que esta respuesta es antigua, pero tiene un error bastante importante. No perderá transacciones desde el último punto de control, perderá transacciones que aún no se han escrito completamente en el WAL. Si synchronous = NORMAL, no espera un fsync() cuando escribe la transacción en el WAL, por lo que puede perder esa transacción si pierde potencia antes de que esté completamente escrita. Una vez que esté en el WAL, no se perderá, independientemente del punto de control. –

+1

Hasta 2016-02-17 https://www.sqlite.org/docsrc/info/3540d671bcc4835c la documentación SQLite decía que synchronous = NORMAL por defecto en modo WAL ... ahora dice synchronous = FULL - mucho más safe default. Por lo tanto, perderá transacciones antes del punto de control solo si establece el modo sincrónico = NORMAL –

5

Para responder completamente, necesitamos saber en qué tiene configurado PRAGMA synchronous, ya que esto afecta cuando se llama a fdatasync() y, por lo tanto, cuando los búferes se vacían en el disco físico.

Cuando cita "siempre que la aplicación esté dispuesta a sacrificar la durabilidad después de una pérdida de potencia", esto se refiere a tener synchronous=NORMAL. Aquí, el WAL solo se sincroniza en el disco cuando ocurre el punto de referencia (un fdatasync() para el WAL y otro para el DB principal después de fusionarse). Debería estar protegido contra la corrupción bastante bien, pero puede haber algunas escrituras que nunca llegaron a la fuente y por lo tanto se pierden: de ahí la perdida de durabilidad. Sin embargo, la ventaja es mucho menor que la fdatasync lenta() para sincronizar los datos.

Para tener la mejor resiliencia contra la pérdida de datos, es posible que desee synchronous=FULL. Esto vuelve a ganar durabilidad, pero el costo es uno fdatasync() por transacción de escritura. Sin embargo, esto es aún mejor que el modo no WAL donde habría dos llamadas fdatasync(), una para el diario de transacciones y otra para el DB principal.

0

Siempre que las llamadas de sincronización a su sistema operativo funcionen perfectamente, no hay riesgo de una base de datos corrupta. Sin embargo, este puede ser el caso o no: consulte la documentación de sqlite para obtener una explicación más detallada al respecto.

Para corregir Doug Currie (consulte la publicación de MattR): solo corre el riesgo de perder transacciones si @ synchronous = NORMAL @. Si @ synchronous = FULL @ (que es el valor predeterminado), no sacrifica la durabilidad. Vea http://www.sqlite.org/draft/wal.html para más detalles sobre esto.

Creo que el diario WAL es de hecho más seguro que el diario clásico (en caso de sincronización imperfecta del sistema), porque la probabilidad de que el db haga algo crítico en un momento dado es menor según entiendo el diario WAL. Sin embargo, actualmente no tengo datos duros para respaldar esto.

Cuestiones relacionadas