簡體   English   中英

如何在不干擾客戶端(golang / sqlite3)的情況下使用新版本更新我的數據庫?

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

我使用的數據庫是一個全局變量,初始化讀取文件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
}

有時,我會有這個數據庫的更新版本,我可以下載並存儲在dbDir中。

我的想法:

  • 使用ATTACH DATABASE sql-repo.db AS dbMain附加第一個數據庫的副本並默認使用它。
    當我有新的.db文件時,我也會附加它ATTACH DATABASE sql-repo-new.db AS dbNew
    然后我分離dbMain並將dbNew重命名為dbMain
  • 只需更改我的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
}

如果我的代碼中的客戶端連接到數據庫並正在查詢它,我想避免任何干擾,我該如何或應該如何使用新版本/文件更新我的globalDB

我是否應該將sync.RWMutex附加到我的LocalDB結構,然后在進行更新時鎖定/解鎖它?
或者我應該使用一個通道來要求每個客戶端停止查詢數據庫?

感謝您提供任何幫助/意見/建議!

或者您可以啟動一個單獨的 go 例程或進程,將舊數據庫與新文件同步。 對從新到舊的所有行進行插入或更新,然后刪除缺失的行。 如果全部在單個事務中完成,所有查詢將讀取所有舊數據或新數據而不會阻塞。

另一個好處是關注點分離,您的應用程序代碼不會與更新邏輯聚集在一起,在這種情況下,新文件已損壞,更新事務出錯並且不會造成任何損害。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM