git - 在 Go 语言中编写可靠的数据存储

标签 git database-design go

我一直在构建一个简单的数据存储,作为我将要构建用于教育目的的文档数据库系统模块的一部分。

为了可靠地存储数据,我必须遵守 ACID 属性。下面显示的是我的保存方法。

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
}

首先将数据(在 []byte 中)保存到一个临时文件中。然后该文件与 file.Sync() 同步,以确保将数据写入持久存储。然后将临时文件重命名为新文件。

注意: 我选择存储数据文件的方式是 spoolDir 格式。这意味着从数据生成的哈希值的前两个字符用作父目录名称。哈希的后两个字符用作后续目录名称。文件名将是剩下的 36 个字符。临时文件只有一个后缀.tmp,文件路径和文件名相同。这种设计的灵感来自 git 存储数据的方式。

问题: 我实现数据存储算法的方式是否足以确保数据可靠地持久化。

目前回答: 关于目录同步以确保数据持久性的一些事情(我不确定)

提前致谢


根据 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
}

最佳答案

你正在做的事情保证了操作系统和硬件保证它的程度的持久性(这是你能得到的最好的)。

它也是原子的;不完整的写入不会留下不完整的数据,即使 CPU 着火也是如此。

重命名失败时,您可能希望删除临时文件:

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

关于git - 在 Go 语言中编写可靠的数据存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22573274/

相关文章:

database-design - 存储多类型字段的最佳方式

php - 在 RDBMS 中将 ids 存储为逗号分隔的字符串是否有任何性能原因?

database-design - 多个多对多关系是否是糟糕设计的证据?

go - go语言解析嵌套JSON

go - 遍历go例程时数组索引错误

windows - Visual Studio git : terminal prompts disabled

git - 错误 : git checkout-index: unable to create file (Permission denied)

git - 无法从 linode 服务器克隆托管的 git 存储库

json - 不要将不需要的 JSON 键值读入内存

git - 如何将 Sonar SCM 支持与非 Git 存储库的工作空间根一起使用