共計 4849 個字符,預計需要花費 13 分鐘才能閱讀完成。
自動寫代碼機器人,免費開通
這期內容當中丸趣 TV 小編將會給大家帶來有關使用 golang 怎么實現 mysql 數據庫備份,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
map json,在處理主鍵與外鍵信息時,需要用到 json 數據結構來存儲中間結果,因為要靈活處理,在 golang 中只能用 map[string]interface{} 來處理。
interface{} 相當于 java 中的 object,能接受任意數據類型,方便但在使用時要做到心中有數,不然一旦數據類型不匹配,程序就會崩潰。
xfffd,utf8 中的占位符,超出范圍的 utf8mb4 入庫后,會被存儲為 xfffd,數據導出時,需要過濾掉。
goroutine,golang 的并發支持很獨特,我們的工具支持多個庫同時備份,很容易使用 goroutine 來實現并行。
代碼解析
按功能模塊對核心代碼進行說明
main.go,并發、命令行參數
使用命令行參數,接受一個參數,來指定備份的內容
package common
type OpFlag struct {
Tables bool // 表結構
Datum bool // 表結構和數據
Views bool // 視圖
Funcs bool // 函數與存儲過程
}
main.go,程序入口,處理命令行參數
if len(os.Args) 1 {
flag = common.OpFlag{
Tables: false,
Datum: false,
Views: false,
Funcs: false,
}
switch os.Args[1] { // 接受一個參數
case table :
flag.Tables = true // 根據參數設定標識量
case data :
flag.Tables = true
flag.Datum = true
case views :
flag.Views = true
case funcs :
flag.Funcs = true
default: // 參數不正確,報錯退出
log.Fatal(You arg must be in : table, data, views or funcs.)
}
}else{ // 無參數,默認導出所有
flag = common.OpFlag{
Tables: true,
Datum: true,
Views: true,
Funcs: true,
}
}
err := backUp.Export(flag) 根據參數進行數據庫備份
Export.go
備份主流程,根據 configs.json 生成 goroutine 來備份數據庫,并等待完成。
var configs interface{}
fr, err := os.Open(./configs.json)
if err != nil {
return err
}
decoder := json.NewDecoder(fr) // 解析配置文件
err = decoder.Decode(configs)
confs := configs.(map[string]interface{})
workDir := confs[workDir].(string)
ch := make(chan string) // 通道變量
for key, value := range confs { if strings.HasPrefix(key, db_) { dbConf := value.(map[string]interface{})
dbConn := common.DbConnFields{ // 數據庫相應配置
DbHost: dbConf[db_host].(string),
DbPort: int(dbConf[ db_port].(float64)),
DbUser: dbConf[db_user].(string),
DbPass: dbConf[db_pass].(string),
DbName: dbConf[db_name].(string),
DbCharset: dbConf[db_charset].(string),
}
if dbConf[file_alias] != nil { // 生成 sql 備份文件的命名
dbConn.FileAlias = dbConf[file_alias].(string)
}
go ExportOne(dbConn, workDir, ch, flag) // 創建協程
}
}
for key := range confs { // 阻塞主進程,待所有協程完成工作
if strings.HasPrefix(key, db_) { fmt.Print( - ch )
}
}
return nil
你需要編寫如下的配置文件來描述你要備份的數據庫:
{
db_name1 : {
db_host : 192.168.1.8 ,
db_port : 3306,
db_user : root ,
db_pass : 123456 ,
db_name : name1 ,
db_charset : utf8mb4 ,
file_alias : file name1
},
db_name2 : {
db_host : localhost ,
db_port : 3306,
db_user : root ,
db_pass : 123456 ,
db_name : name2 ,
db_charset : utf8mb4
},
database_dialect : mysql ,
workDir : /home/zhoutk/gocodes/goTools/
}
ExportOne.go
備份一個數據庫
fileName := fields.FileAlias
setSqlHeader(fields, fileName) // 設置導出文件說明
if flag.Tables { // 如果表設置為真,導出表結構
err := exportTables(fileName, fields, flag) // 具體算法請參照源代碼
if err != nil { ch - fmt.Sprintln( Error: , fields.DbName, \t export tables throw, \t , err)
return
}
}
if flag.Views { // 如果視圖設置為真,導出視圖
err := exportViews(fileName, fields)// 具體算法請參照源代碼,或 python 算法
if err != nil { ch - fmt.Sprintln( Error: , fields.DbName, \t export views throw, \t , err)
return
}
}
if flag.Funcs { // 如果函數設置為真,導出函數和存儲過程
err := exportFuncs(fileName, fields)// 具體算法請參照源代碼
if err != nil { ch - fmt.Sprintln( Error: , fields.DbName, \t export funcs throw, \t , err)
return
}
}
// 導出工作完成,向通道輸入信息
ch - fmt.Sprintln(Export , fields.DbName, \t success at \t , time.Now().Format(2006-01-02 15:04:05))
MysqlDao.go
數據庫查詢通用封裝, 此工具只使用了 ExecuteWithDbConn。靈活的使用 map 與 interface{},將結果轉化為鍵值對象返回。
func ExecuteWithDbConn(sql string, values []interface{}, fields common.DbConnFields) (map[string]interface{}, error) { rs := make(map[string]interface{})
dao, err := mysql.Open( mysql , fields.DbUser + : +fields.DbPass+ @tcp( +fields.DbHost+ : +
strconv.Itoa(fields.DbPort)+ )/ +fields.DbName+ ?charset= +fields.DbCharset)
defer dao.Close()
if err != nil { rs[ code] = 204
return rs, err
}
stmt, err := dao.Prepare(sql)
if err != nil { rs[ code] = 204
return rs, err
}
rows, err := stmt.Query(values...)
if err != nil { rs[ code] = 204
return rs, err
}
columns, err := rows.Columns() // 取出字段名稱
vs := make([]mysql.RawBytes, len(columns))
scans := make([]interface{}, len(columns))
for i := range vs { // 預設取值地址
scans[i] = vs[i]
}
var result []map[string]interface{}
for rows.Next() { _ = rows.Scan(scans...) // 塡入一列值
each := make(map[string]interface{})
for i, col := range vs {
if col != nil { each[columns[i]] = FilterHolder(string(col)) // 過濾 /xfffd
}else{ each[columns[i]] = nil
}
}
result = append(result, each)
}
rs[code] = 200
//data, _ := json.Marshal(result)
rs[rows] = result
return rs, err
}
項目地址
https://github.com/zhoutk/goTools
使用方法
git clone https://github.com/zhoutk/goTools
cd goTools
go get
go run main.go
go buid main.go
./main #export all things of database
./main table #export tables
./main data #export tables data
./main views #export views
./main funcs #export funcs stored procedures
golang 的優點
golang 是一種編譯語言,可以將代碼編譯為機器代碼,編譯后的二進制文件可以直接部署到目標機器而無需額外的依賴,所以 golang 的性能優于其他的解釋性語言,且可以在 golang 中使用 goroutine 來實現并發性,它提供了一個非常優雅的 goroutine 調度程序系統,可以很容易地生成數百萬個 goroutine。
上述就是丸趣 TV 小編為大家分享的使用 golang 怎么實現 mysql 數據庫備份了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注丸趣 TV 行業資訊頻道。
向 AI 問一下細節