简体   繁体   English

如何在不干扰客户端(golang / sqlite3)的情况下使用新版本更新我的数据库?

[英]How can I update my DB with a new version without interference with clients (golang / sqlite3)?

The database I am using is a global variable, initialized reading the file sql-repo.db :我使用的数据库是一个全局变量,初始化读取文件sql-repo.db

const dbFile = "sql-repo.db"

var globalDB *LocalDB

type LocalDB struct {
    Path   string
    handle *sql.DB
}

func InitSqlDB(dbDir string) error {
    if globalDB != nil {
        return nil
    }
    db := LocalDB{Path: filepath.Join(dbDir, dbFile)}
    var err error
    db.handle, err = sql.Open("sqlite3", db.Path)
    if err != nil {
        return err
    }
    globalDB = &db
    return nil
}

From time to time, I will have an updated version of this database that I can download and store in dbDir .有时,我会有这个数据库的更新版本,我可以下载并存储在dbDir中。

Ideas that I have:我的想法:

  • Use ATTACH DATABASE sql-repo.db AS dbMain to attach a copy of the first database and use it by default.使用ATTACH DATABASE sql-repo.db AS dbMain附加第一个数据库的副本并默认使用它。
    When I have my new .db file, I attach it as well ATTACH DATABASE sql-repo-new.db AS dbNew当我有新的.db文件时,我也会附加它ATTACH DATABASE sql-repo-new.db AS dbNew
    Then I detach dbMain and rename dbNew to dbMain然后我分离dbMain并将dbNew重命名为dbMain
  • Simply change the address my globalDB is pointing to:只需更改我的globalDB指向的地址:
const newDBFile = "sql-repo-new.db"

func PullNewDB(dbDir string) error {
    db := LocalDB{Path: filepath.Join(dbDir, newDBFile)}
    var err error
    db.handle, err = sql.Open("sqlite3", db.Path)
    if err != nil {
        return err
    }
    globalDB = &db
    return nil
}

How can I or how should I update my globalDB with the new version/file as I want to avoid any interference if the clients that I have in my code are connected to the DB and are querying it?如果我的代码中的客户端连接到数据库并正在查询它,我想避免任何干扰,我该如何或应该如何使用新版本/文件更新我的globalDB

Should I attach a sync.RWMutex to my LocalDB struct and then lock/unlock it when I do the update?我是否应该将sync.RWMutex附加到我的LocalDB结构,然后在进行更新时锁定/解锁它?
Or should I use a channel to ask every client to stop querying the DB?或者我应该使用一个通道来要求每个客户端停止查询数据库?

Thank you for any help / advice / suggestion !感谢您提供任何帮助/意见/建议!

Or you can start a separate go routine or process that syncs your old database with the new file.或者您可以启动一个单独的 go 例程或进程,将旧数据库与新文件同步。 Do an insert or update on all rows from new to old, then delete on missing rows.对从新到旧的所有行进行插入或更新,然后删除缺失的行。 If it's all done in a single transaction, all queries will either read all old or new data without ever blocking.如果全部在单个事务中完成,所有查询将读取所有旧数据或新数据而不会阻塞。

An additional benefit is the separation of concerns, your application code doesn't get clustered with update logic, and in the case, the new file is corrupted, the update transaction errors out and no harm is done.另一个好处是关注点分离,您的应用程序代码不会与更新逻辑聚集在一起,在这种情况下,新文件已损坏,更新事务出错并且不会造成任何损害。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM