### golang sqlite主從數據同步插件開發
思路
參考Mysql的主從同步機制,Mysql是產生binlog,然后把binlog日志同步到從服務上。
同理,我們按sql執行順序記錄所有的增刪改查的sql語句,然后調用接口把sql語句傳到從服務上執行。
數據庫驅動使用的是 GORM。
編寫gorm插件
type Plugin interface {Name() stringInitialize(*gorm.DB) error
}
type TracePlugin struct {
}func (op *TracePlugin) Name() string {return "tracePlugin"
}func (op *TracePlugin) Initialize(db *gorm.DB) (err error) {// 在這些sql操作后執行after方法,只記錄增 刪 改的語句_ = db.Callback().Create().After("gorm:after_create").Register("after_create", after)_ = db.Callback().Delete().After("gorm:after_delete").Register("after_delete", after)_ = db.Callback().Update().After("gorm:after_update").Register("after_update", after)return
}func after(db *gorm.DB) {err := db.Error//sql執行成功if err == nil {//獲取sqlsql := db.Dialector.Explain(db.Statement.SQL.String(), db.Statement.Vars...)if strings.Contains(sql, "refresh_token") {//過濾不需要的sqlreturn}//遠程調用執行sql語句sendExecSql(sql)}return
}
使用插件
var SqliteDb *gorm.DBfunc init() {var err errorSqliteDb, err = gorm.Open(sqlite.Open("sqlite.db"), &gorm.Config{NamingStrategy: schema.NamingStrategy{SingularTable: true, // 不要復數表名},Logger: logger.Default.LogMode(logger.Info), // 打印 SQL 語句PrepareStmt: true,})if err != nil {fmt.Printf("connect DB failed, err:%v\n", err)return}fmt.Println("connect DB success")db, err := SqliteDb.DB()// 空閑狀態下的最大連接數,默認的最大空閑連接數為2db.SetMaxIdleConns(10)// 最大打開連接數, 默認值為0(無限制)db.SetMaxOpenConns(100)// 設置連接可以重復使用的最長時間db.SetConnMaxLifetime(time.Hour)//使用插件SqliteDb.Use(&plugins.TracePlugin{})
}
注意
sql要按順序發送給從庫執行,執行后要返回結果,返回成功后在發送下一條執行。
參考鏈接:
https://gorm.io/zh_CN/docs/write_plugins.html
https://studygolang.com/articles/32886?fr=sidebar