使用golang怎么实现mysql数据库备份
这期内容当中小编将会给大家带来有关使用golang怎么实现mysql数据库备份,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
map & json,在处理主键与外键信息时,需要用到json数据结构来存储中间结果,因为要灵活处理,在golang中只能用map[string]interface{}来处理。
interface{} 相当于java中的object,能接受任意数据类型,方便但在使用时要做到心中有数,不然一旦数据类型不匹配,程序就会崩溃。
xfffd ,utf8中的占位符,超出范围的utf8mb4入库后,会被存储为xfffd,数据导出时,需要过滤掉。
goroutine, golang的并发支持很独特,我们的工具支持多个库同时备份,很容易使用goroutine来实现并行。
代码解析
按功能模块对核心代码进行说明
main.go,并发、命令行参数
使用命令行参数,接受一个参数,来指定备份的内容
package common
typeOpFlagstruct{Tablesbool//表结构Datumbool//表结构和数据Viewsbool//视图Funcsbool//函数与存储过程}
main.go,程序入口,处理命令行参数
iflen(os.Args)>1{flag=common.OpFlag{Tables:false,Datum:false,Views:false,Funcs:false,}switchos.Args[1]{//接受一个参数case"table":flag.Tables=true//根据参数设定标识量case"data":flag.Tables=trueflag.Datum=truecase"views":flag.Views=truecase"funcs":flag.Funcs=truedefault://参数不正确,报错退出log.Fatal("Youargmustbein:table,data,viewsorfuncs.")}}else{//无参数,默认导出所有flag=common.OpFlag{Tables:true,Datum:true,Views:true,Funcs:true,}}err:=backUp.Export(flag)根据参数进行数据库备份
Export.go
备份主流程,根据configs.json生成goroutine来备份数据库,并等待完成。
varconfigsinterface{}fr,err:=os.Open("./configs.json")iferr!=nil{returnerr}decoder:=json.NewDecoder(fr)//解析配置文件err=decoder.Decode(&configs)confs:=configs.(map[string]interface{})workDir:=confs["workDir"].(string)ch:=make(chanstring)//通道变量forkey,value:=rangeconfs{ifstrings.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),}ifdbConf["file_alias"]!=nil{//生成sql备份文件的命名dbConn.FileAlias=dbConf["file_alias"].(string)}goExportOne(dbConn,workDir,ch,flag)//创建协程}}forkey:=rangeconfs{//阻塞主进程,待所有协程完成工作ifstrings.HasPrefix(key,"db_"){fmt.Print(<-ch)}}returnnil
你需要编写如下的配置文件来描述你要备份的数据库:
{"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":"filename1"},"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.FileAliassetSqlHeader(fields,fileName)//设置导出文件说明ifflag.Tables{//如果表设置为真,导出表结构err:=exportTables(fileName,fields,flag)//具体算法请参照源代码iferr!=nil{ch<-fmt.Sprintln("Error:",fields.DbName,"\texporttablesthrow,\t",err)return}}ifflag.Views{//如果视图设置为真,导出视图err:=exportViews(fileName,fields)//具体算法请参照源代码,或python算法iferr!=nil{ch<-fmt.Sprintln("Error:",fields.DbName,"\texportviewsthrow,\t",err)return}}ifflag.Funcs{//如果函数设置为真,导出函数和存储过程err:=exportFuncs(fileName,fields)//具体算法请参照源代码iferr!=nil{ch<-fmt.Sprintln("Error:",fields.DbName,"\texportfuncsthrow,\t",err)return}}//导出工作完成,向通道输入信息ch<-fmt.Sprintln("Export",fields.DbName,"\tsuccessat\t",time.Now().Format("2006-01-0215:04:05"))
MysqlDao.go
数据库查询通用封装,此工具只使用了ExecuteWithDbConn。灵活的使用map与interface{},将结果转化为键值对象返回。
funcExecuteWithDbConn(sqlstring,values[]interface{},fieldscommon.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)deferdao.Close()iferr!=nil{rs["code"]=204returnrs,err}stmt,err:=dao.Prepare(sql)iferr!=nil{rs["code"]=204returnrs,err}rows,err:=stmt.Query(values...)iferr!=nil{rs["code"]=204returnrs,err}columns,err:=rows.Columns()//取出字段名称vs:=make([]mysql.RawBytes,len(columns))scans:=make([]interface{},len(columns))fori:=rangevs{//预设取值地址scans[i]=&vs[i]}varresult[]map[string]interface{}forrows.Next(){_=rows.Scan(scans...)//塡入一列值each:=make(map[string]interface{})fori,col:=rangevs{ifcol!=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"]=resultreturnrs,err}
项目地址
https://github.com/zhoutk/goTools
使用方法
gitclonehttps://github.com/zhoutk/goToolscdgoToolsgogetgorunmain.gogobuidmain.go./main#exportallthingsofdatabase./maintable#exporttables./maindata#exporttables&data./mainviews#exportviews./mainfuncs#exportfuncs&storedproceduresgolang的优点
golang是一种编译语言,可以将代码编译为机器代码,编译后的二进制文件可以直接部署到目标机器而无需额外的依赖,所以golang的性能优于其他的解释性语言,且可以在golang中使用goroutine来实现并发性,它提供了一个非常优雅的goroutine调度程序系统,可以很容易地生成数百万个goroutine。
上述就是小编为大家分享的使用golang怎么实现mysql数据库备份了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。