0 Star 0 Fork 0

fanmuyong/bingo

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
main.go 5.36 KB
一键复制 编辑 原始数据 按行查看 历史
zhf.fan 提交于 2023-07-04 17:11 . 添加日志
package main
import (
"bufio"
"encoding/csv"
"flag"
"io"
"log"
"os"
"regexp"
"strconv"
"strings"
)
type TableDMLNum struct {
Insert int
Update int
Delete int
}
func init() {
file := "./" + "bingo" + ".log"
logFile, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0766)
if err != nil {
panic(err)
}
multiWriter := io.MultiWriter(os.Stdout, logFile)
log.SetOutput(multiWriter)
log.SetFlags(log.LstdFlags | log.LUTC)
return
}
func main() {
// 配置由 mysqlbinlog 解析好的日志文件路径
binlogIn := flag.String("in", "binlog.txt", "binlog source path")
binlogOut := flag.String("out", "binlog.csv", "binlog result file")
flag.Parse()
log.Println("binlog source path: ", *binlogIn)
log.Println("binlog result file: ", *binlogOut)
file, err := os.Open(*binlogIn)
if err != nil {
log.Fatalf("open file failed: %s \n", err.Error())
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
log.Fatalf("close file failed: %s \n", err.Error())
}
}(file)
reader := bufio.NewReader(file)
tableNameNumMap := make(map[string]TableDMLNum)
tableNameNumTransMap := make(map[string]TableDMLNum)
flagInSameTrans := false
tableBeginRex := regexp.MustCompile(".*Table_map:.*mapped to number.*")
tableUpdateRex := regexp.MustCompile("^### UPDATE .*")
tableInsertRex := regexp.MustCompile("^### INSERT INTO .*")
tableDeleteRex := regexp.MustCompile("^### DELETE FROM .*")
tableCommitRex := regexp.MustCompile("^COMMIT\\/\\*\\!\\*\\/;$")
log.Println("Binlog analysis transaction results:")
log.Println("+-------------------------------------------------------------------------------------------+--------------------+--------------------+--------------------+")
for {
line, _, err := reader.ReadLine()
if err == io.EOF {
break
}
if tableBeginRex.Match(line) && !flagInSameTrans {
flagInSameTrans = true
}
if flagInSameTrans && (tableUpdateRex.Match(line) || tableInsertRex.Match(line) || tableDeleteRex.Match(line)) {
if tableUpdateRex.Match(line) {
indexS := strings.Index(string(line), "### UPDATE") + len("### UPDATE") + 1
tableName := strings.TrimSpace(string(line)[indexS:])
if _, ok := tableNameNumTransMap[tableName]; !ok {
tableNameNumTransMap[tableName] = TableDMLNum{Insert: 0, Update: 1, Delete: 0}
} else {
num := tableNameNumTransMap[tableName]
num.Update = num.Update + 1
tableNameNumTransMap[tableName] = num
}
} else if tableInsertRex.Match(line) {
indexS := strings.Index(string(line), "### INSERT INTO") + len("### INSERT INTO") + 1
tableName := strings.TrimSpace(string(line)[indexS:])
if _, ok := tableNameNumTransMap[tableName]; !ok {
tableNameNumTransMap[tableName] = TableDMLNum{Insert: 1, Update: 0, Delete: 0}
} else {
num := tableNameNumTransMap[tableName]
num.Insert = num.Insert + 1
tableNameNumTransMap[tableName] = num
}
} else if tableDeleteRex.Match(line) {
indexS := strings.Index(string(line), "### DELETE FROM") + len("### DELETE FROM") + 1
tableName := strings.TrimSpace(string(line)[indexS:])
if _, ok := tableNameNumTransMap[tableName]; !ok {
tableNameNumTransMap[tableName] = TableDMLNum{Insert: 0, Update: 0, Delete: 1}
} else {
num := tableNameNumTransMap[tableName]
num.Delete = num.Delete + 1
tableNameNumTransMap[tableName] = num
}
}
}
if tableCommitRex.Match(line) {
flagInSameTrans = false
for key, value := range tableNameNumTransMap {
log.Printf("+ Transaction table: %-70s + Insert: %-10d + Update: %-10d + Delete: %-10d + \n", key, value.Insert, value.Update, value.Delete)
if _, ok := tableNameNumMap[key]; ok {
num := tableNameNumMap[key]
num.Update = num.Update + value.Update
num.Insert = num.Insert + value.Insert
num.Delete = num.Delete + value.Delete
tableNameNumMap[key] = num
} else {
tableNameNumMap[key] = TableDMLNum{Insert: value.Insert, Update: value.Update, Delete: value.Delete}
}
}
if len(tableNameNumTransMap) > 0 {
log.Println("+-------------------------------------------------------------------------------------------+--------------------+--------------------+--------------------+")
}
tableNameNumTransMap = make(map[string]TableDMLNum)
}
}
f, err := os.OpenFile(*binlogOut, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0666)
if err != nil {
log.Fatalf("open file failed: %s \n", err.Error())
return
}
writer := csv.NewWriter(f)
var header = []string{"table", "insert", "update", "delete"}
err2 := writer.Write(header)
if err2 != nil {
log.Fatalf("write file failed: %s \n", err2.Error())
return
}
log.Println("Binlog analysis total results:")
log.Println("+--------------------------------------------------------------------------------+--------------------+--------------------+--------------------+")
for key, value := range tableNameNumMap {
log.Printf("+ Total table: %-65s + Insert: %-10d + Update: %-10d + Delete: %-10d + \n", key, value.Insert, value.Update, value.Delete)
log.Println("+--------------------------------------------------------------------------------+--------------------+--------------------+--------------------+")
var data = []string{key, strconv.Itoa(value.Insert), strconv.Itoa(value.Update), strconv.Itoa(value.Delete)}
err3 := writer.Write(data)
if err3 != nil {
log.Fatalf("write file failed: %s \n", err3.Error())
return
}
writer.Flush()
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/fanmuyong/bingo.git
git@gitee.com:fanmuyong/bingo.git
fanmuyong
bingo
bingo
master

搜索帮助