1. 程式人生 > 資料庫 >如何利用Golang解析讀取Mysql備份檔案

如何利用Golang解析讀取Mysql備份檔案

前言

前期誤操作,導致資料庫表刪除,雖然資料量不多,但是通過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,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()
}

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對我們的支援。