41

使用Golang解析读取Mysql备份文件

 4 years ago
source link: https://studygolang.com/articles/25054
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

前言

前期误操作,导致数据库表删除,虽然数据量不多,但是通过binlog恢复比较麻烦,通过备份文件来恢复,备份文件达36个G打开都是问题;

使用备份文件恢复

大文件编辑器, glogg-latest-x86_64-setup 通过该文件打开备份文件,虽然过程稍慢,但是能够打开,且正常读取编辑信息,要恢复的数据量不大时采取是没问题的,但是如果表几十万行,操作起来就比较麻烦了;

Golang读取备份文件

采用Golang读取,借助编程语言的优势来读取备份,经过测试读取指定备份文件(约36GB)表,大约需要12min,其实主要就是读取遍历备份文件的过程;

**
* @Author: ws
* @File: main
* @Date: 2019/11/16 0016 14:35
* @Remark: 
*/
var(
    _INSERT_INTO="INSERTINTO${table}VALUES"
    _Dir="temp"
)
var TABLE_CAR="T_SCM_CAR"

func ReadSqlFile(){
    t1 := time.Now() // get current time
    f, err := os.Open("E:\\update\\crm_20191112_210001.sql\\crm_20191112_210001.sql")
    defer f.Close()
    if err != nil {
    }
    buf := bufio.NewReader(f)
    nfs:=getTxtFile(TABLE_CAR)
    for {
        s, err := buf.ReadString('\n')
        if(err!=nil){
            logger.ERROR(err.Error())
            break
        }
        if err == nil {
            if s==""{
                continue
            }
            sqlstr:=getSqlStr(s,TABLE_CAR)
            if(sqlstr!=""){
                nfs.Write([]byte(sqlstr))
            }
        }
    }
    elapsed := time.Since(t1)
    fmt.Println("App elapsed: ", elapsed)
}
/**
调整验证每一行数据的格式化,并与预设是否一致,如果一致则读取加载到
 */
func getSqlStr(sqlstr,tableName string)string{
    var realTableName=strings.Replace(_INSERT_INTO,"${table}",tableName,-1)
    replaceEmptyStr:=strings.Replace(sqlstr," ","",-1)
    tempS:=strings.ToUpper(strings.Replace(replaceEmptyStr,"`","",-1))
    if(len(tempS)>=len(realTableName)) {
        tabName := tempS[0:len(realTableName)]
        if (tabName ==realTableName) {
            return sqlstr
        }
    }
    return ""
}

/**
打开txt文件
 */
func getTxtFile(fileName string)os.File{
    txtFile:=createToFile(fmt.Sprintf("%v/%v.txt",_Dir,fileName))
    nfs, err := os.OpenFile(txtFile.Name(), os.O_APPEND |os.O_RDWR|os.O_CREATE, 0644)
    if err != nil {
        logger.ERROR(fmt.Sprintf("打开文件失败:%v",err.Error()))
    }
    defer nfs.Close()
    nfs.Seek(0, io.SeekEnd)
    return *nfs
}


func readLine(r *bufio.Reader) (string, error) {
    line, isprefix, err := r.ReadLine()
    for isprefix && err == nil {
        var bs []byte
        bs, isprefix, err = r.ReadLine()
        line = append(line, bs...)
    }
    return string(line), err
}

func createToFile(fileName string)os.File{
    _, err := os.Stat(_Dir)
    if err == nil {
    }
    if os.IsNotExist(err) {
        os.MkdirAll(_Dir, os.ModePerm)
    }
    newFile, err := os.Create(fileName)
    if err != nil {
        logger.ERROR(fmt.Sprintf("文件创建失败:%v",err.Error()))
    }
    defer func() {
        newFile.Close()
    }()
    newFile.WriteString("\xEF\xBB\xBF") // 写入UTF-8 BOM,防止中文乱码
    return *newFile
}

func main() {
    ReadSqlFile()
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK