最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

golang实现mysql数据库备份的操作方法

来源:动视网 责编:小采 时间:2020-11-09 20:25:58
文档

golang实现mysql数据库备份的操作方法

golang实现mysql数据库备份的操作方法:背景 navicat是mysql可视化工具中最棒的,但是,在处理视图的导入导出方面,它是按照视图名称的字母顺序来处理的,若视图存在依赖,在导入过程中就会报错。前面已经用python写了一个,但在使用过程中,遇到xfffd编码,python的pymysql会直接崩溃。发现
推荐度:
导读golang实现mysql数据库备份的操作方法:背景 navicat是mysql可视化工具中最棒的,但是,在处理视图的导入导出方面,它是按照视图名称的字母顺序来处理的,若视图存在依赖,在导入过程中就会报错。前面已经用python写了一个,但在使用过程中,遇到xfffd编码,python的pymysql会直接崩溃。发现


背景

navicat是mysql可视化工具中最棒的,但是,在处理视图的导入导出方面,它是按照视图名称的字母顺序来处理的,若视图存在依赖,在导入过程中就会报错。前面已经用python写了一个,但在使用过程中,遇到xfffd编码,python的pymysql会直接崩溃。发现golang没有这个问题,正好用go重写,来熟悉golang。

一些关键点

  1. map & json,在处理主键与外键信息时,需要用到json数据结构来存储中间结果,因为要灵活处理,在golang中只能用map[string]interface{}来处理。
  2. interface{} 相当于java中的object,能接受任意数据类型,方便但在使用时要做到心中有数,不然一旦数据类型不匹配,程序就会崩溃。
  3. xfffd ,utf8中的占位符,超出范围的utf8mb4入库后,会被存储为xfffd,数据导出时,需要过滤掉。
  4. 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实现mysql数据库备份的操作方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

您可能感兴趣的文章:

  • Go语言操作mysql数据库简单例子
  • Go语言使用MySql的方法
  • Go语言中http和mysql的实现代码
  • Golang中如何对MySQL进行操作详解
  • golang gorm 操作mysql及gorm基本用法
  • 在golang中操作mysql数据库的实现代码
  • Go语言集成mysql驱动、调用数据库、查询数据操作示例
  • 文档

    golang实现mysql数据库备份的操作方法

    golang实现mysql数据库备份的操作方法:背景 navicat是mysql可视化工具中最棒的,但是,在处理视图的导入导出方面,它是按照视图名称的字母顺序来处理的,若视图存在依赖,在导入过程中就会报错。前面已经用python写了一个,但在使用过程中,遇到xfffd编码,python的pymysql会直接崩溃。发现
    推荐度:
    标签: 备份 步骤 实现
    • 热门焦点

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top