Escribir una tienda de datos confiable en GoLang

He estado construyendo un almacén de datos simple como parte de mi module para un sistema de database de documentos que voy a build con fines educativos.

Para almacenar datos de manera confiable, debo cumplir con la propiedad de ACID. A continuación se muestra mi método de guardado.

func (document Document) Save() (hash string, err error) { if err := os.MkdirAll(document.FileDirectory(), 0600); err != nil { return "", err } file, err := os.Create(document.TmpFile()) if err != nil { return "", err } file.Write(document.Data) if err := file.Sync(); err != nil { return "", err } file.Close() if err := os.Rename(document.TmpFile(), document.File()); err != nil { return "", err } return document.Hash(), nil } 

Primero, los datos (en [] byte) se guardan en un file temporal. Luego, el file se sincroniza con file.Sync() para garantizar que los datos se escriben en el almacenamiento persistente. Luego, se cambia el nombre del file temporal al nuevo file.

Nota: La forma en que elegí almacenar el file de datos está en formatting spoolDir. Lo que significa que los dos primeros caracteres del hash generado a partir de los datos se utilizan como nombre principal del directory. Los siguientes dos caracteres del hash se utilizan como el nombre de directory posterior. El nombre de file será el de 36 caracteres restantes. El file temporal solo tiene un sufijo .tmp con la ruta del file y el nombre del file iguales. Este layout está inspirado en cómo los datos de la tienda git .

Pregunta: ¿Es la forma en que implemento el algorithm de almacenamiento de datos suficiente para garantizar que los datos se conservan de manera confiable?

Respuesta hasta ahora: algo sobre la synchronization de directorys para garantizar la durabilidad de los datos (no estoy seguro)

Gracias por adelantado


Código actualizado según lo sugerido por rightfold:

 func (document Document) Save() (hash string, err error) { if err := os.MkdirAll(document.FileDirectory(), 0600); err != nil { return "", err } file, err := os.Create(document.TmpFile()) if err != nil { return "", err } file.Write(document.Data) if err := file.Sync(); err != nil { return "", err } file.Close() if err := os.Rename(document.TmpFile(), document.File()); err != nil { os.Remove(document.TmpFile()) return "", err } return document.Hash(), nil } 

Solutions Collecting From Web of "Escribir una tienda de datos confiable en GoLang"

Lo que está haciendo garantiza la durabilidad en la medida en que el sistema operativo y el hardware lo garanticen (que es lo mejor que puede get).

También es atómico; las escrituras incompletas no dejan datos incompletos, incluso cuando la CPU se incendia.

Es posible que desee eliminar el file temporal cuando falla el cambio de nombre:

 if err := os.Rename(document.TmpFile(), document.File()); err != nil { os.Remove(document.TmpFile()) // ignore errors return "", err }