代码拉取完成,页面将自动刷新
package main
import (
"database/sql"
"flag"
"fmt"
_ "github.com/go-sql-driver/mysql"
"io/ioutil"
"os"
"os/exec"
"regexp"
"strconv"
"strings"
"sync"
)
var DB *sql.DB
var err error
func InitDB(userName string, password string, ip string, port string, dbName string) error {
//构建连接:"用户名:密码@tcp(IP:端口)/数据库?charset=utf8"
path := strings.Join([]string{userName, ":", password, "@tcp(", ip, ":", port, ")/", dbName, "?charset=utf8"}, "")
//打开数据库,前者是驱动名,所以要导入: _ "github.com/go-sql-driver/mysql"
DB, err = sql.Open("mysql", path)
if err != nil {
return err
}
//设置数据库最大连接数
DB.SetConnMaxLifetime(100)
//设置上数据库最大闲置连接数
DB.SetMaxIdleConns(10)
//验证连接
if err := DB.Ping(); err != nil {
return err
}
return nil
}
func getFields(tablename string, dbname string) []string {
var a []string
rows, err := DB.Query("SELECT COLUMN_NAME FROM COLUMNS WHERE TABLE_NAME = ? and TABLE_SCHEMA=?", tablename, dbname)
if err != nil {
fmt.Println("查询出错了")
}
for rows.Next() {
var feild string
rows.Scan(&feild)
a = append(a, feild)
}
return a
}
func getBinLogPath() string {
var BinLogPath string
var Name string
err = DB.QueryRow("SHOW VARIABLES LIKE \"log_bin_basename\"").Scan(&Name, &BinLogPath)
if err != nil {
panic(err)
}
BinLogPath = BinLogPath[0 : strings.LastIndex(BinLogPath, "/")+1]
return BinLogPath
}
func ExecCommand(strCommand string) (string, error) {
cmd := exec.Command("/bin/bash", "-c", strCommand)
stdout, _ := cmd.StdoutPipe()
if err := cmd.Start(); err != nil {
fmt.Println("Execute failed when Start:" + err.Error())
return "", err
}
out_bytes, _ := ioutil.ReadAll(stdout)
stdout.Close()
if err := cmd.Wait(); err != nil {
fmt.Println("Execute failed when Wait:" + err.Error())
return "", err
}
return string(out_bytes), nil
}
func writeFile(data string, f os.File, f1 os.File, reg string, flag string) {
dataReg := regexp.MustCompile(reg)
dataArr := dataReg.FindAllString(data, -1)
fmt.Println(flag + " 正在处理中......")
var sqlSentence string
var s1 string
for index, v := range dataArr {
if flag == "insert" || flag == "delete" {
if flag == "insert" {
sqlSentence = strings.Replace(v, "\n### SET\n", " SET ", -1)
} else {
sqlSentence = strings.Replace(v, "\n### WHERE\n", " WHERE ", -1)
}
sqlSentence = strings.Replace(sqlSentence, "###", "", -1)
sqlSentence = strings.Replace(sqlSentence, "# at", "", -1)
if flag == "insert" {
sqlSentence = strings.Replace(sqlSentence, "\n", ",", -1)
sqlSentence = strings.Replace(sqlSentence, ", INSERT INTO", "; INSERT INTO", -1)
} else {
sqlSentence = strings.Replace(sqlSentence, "\n", " AND ", -1)
sqlSentence = strings.Replace(sqlSentence, "AND DELETE FROM", "; DELETE FROM", -1)
sqlSentence = sqlSentence[0 : len(sqlSentence)-4]
}
sqlSentence = regexp.MustCompile(`\s+`).ReplaceAllString(sqlSentence, " ")
//sqlSentence = strings.Replace(v, "DELETE FROM", "\nDELETE FROM", -1)
sqlSentence = sqlSentence[0 : len(sqlSentence)-1]
t := regexp.MustCompile("(`\\w+`\\.`\\w+`*?)")
dbTable := strings.Replace(string(t.Find([]byte(sqlSentence))), "`", "", -1)
db := strings.Split(dbTable, ".")[0]
table := strings.Split(dbTable, ".")[1]
arr := getFields(table, db)
length := len(arr)
if length <= 0 {
continue
}
for k, _ := range arr {
sqlSentence = strings.Replace(sqlSentence, "@"+strconv.Itoa(length-k), arr[length-k-1], -1)
}
if flag == "delete" {
s1 = strings.Replace(sqlSentence, "DELETE FROM", "INSERT INTO", -1)
s1 = strings.Replace(s1, "WHERE", "SET", -1)
s1 = strings.Replace(s1, "AND", ",", -1)
//sqlSentence += "\nDELETE反向解析后的sql==========\n" + s1 + "\n=============\n"
} else {
s1 = strings.Replace(sqlSentence, "INSERT INTO", "DELETE FROM", -1)
s1 = strings.Replace(s1, "SET", "WHERE", -1)
s1 = strings.Replace(s1, ",", " AND", -1)
//sqlSentence += "\nINSERT反向解析后的sql==========\n" + s1 + "\n=============\n"
}
} else if flag == "update" {
sqlSentence = strings.Replace(v, "###", "", -1)
sqlSentence = strings.Replace(sqlSentence, "# at", "", -1)
sqlSentence = strings.Replace(sqlSentence, "/*!*/;", "", -1)
where := regexp.MustCompile("\\s+").ReplaceAllString(strings.Replace(strings.Replace(sqlSentence[strings.LastIndex(sqlSentence, "WHERE"):strings.LastIndex(sqlSentence, "SET")], "WHERE\n", "WHERE", -1), "\n", " AND", -1), " ")
where = where[0 : len(where)-4]
where1 := regexp.MustCompile("\\s+").ReplaceAllString(strings.Replace(strings.Replace(sqlSentence[strings.LastIndex(sqlSentence, "WHERE"):strings.LastIndex(sqlSentence, "SET")], "WHERE\n", "SET", -1), "\n", " ,", -1), " ")
where1 = where1[0 : len(where1)-2]
upTable := sqlSentence[0:strings.LastIndex(sqlSentence, "WHERE")]
set := regexp.MustCompile("\\s+").ReplaceAllString(strings.Replace(strings.Replace(sqlSentence[strings.LastIndex(sqlSentence, "SET"):], "SET\n", "SET", -1), "\n", ",", -1), " ")
set = set[0 : len(set)-1]
set1 := regexp.MustCompile("\\s+").ReplaceAllString(strings.Replace(strings.Replace(sqlSentence[strings.LastIndex(sqlSentence, "SET"):], "SET\n", "WHERE", -1), "\n", " AND", -1), " ")
set1 = set1[0 : len(set1)-4]
sqlSentence = upTable + " " + set + " " + where
s1 = upTable + " " + where1 + " " + set1
t := regexp.MustCompile("`.+`\\.`.+`*?")
dbTable1 := strings.Replace(string(t.Find([]byte(sqlSentence))), "`", "", -1)
db1 := strings.Split(dbTable1, ".")[0]
table1 := strings.Split(dbTable1, ".")[1]
arr := getFields(table1, db1)
lenth := len(arr)
if lenth <= 0 {
continue
}
for k1, _ := range arr {
sqlSentence = strings.Replace(sqlSentence, "@"+strconv.Itoa(lenth-k1), arr[lenth-k1-1], -1)
s1 = strings.Replace(s1, "@"+strconv.Itoa(lenth-k1), arr[lenth-k1-1], -1)
}
} else if flag == "create" {
sqlSentence = strings.Replace(v, "/*!*/;", "", -1)
s1 = ""
} else {
sqlSentence = strings.Replace(v, "\n", "", -1)
sqlSentence = strings.Replace(sqlSentence, "/*!*/;", ";", -1)
s1 = ""
}
f1.WriteString("(" + flag + strconv.Itoa(index+1) + ")\t" + s1)
f1.WriteString("\n")
f.WriteString("(" + flag + strconv.Itoa(index+1) + ")\t" + sqlSentence)
f.WriteString("\n")
}
wg.Done()
}
var wg sync.WaitGroup
func main() {
var binLogPath string
var binLogName string
var mysqlHost string
var mysqlPort string
var mysqlUser string
var mysqlPass string
var saveFile string
var start string
var end string
var startDate string
var endDate string
flag.StringVar(&binLogName, "bin-log-name", "", "--bin-log-name bin-log文件名称")
flag.StringVar(&mysqlPort, "P", "3306", "-P 数据库端口号")
flag.StringVar(&mysqlHost, "h", "127.0.0.1", "-h 数据库IP")
flag.StringVar(&mysqlUser, "u", "root", "-u 数据库用户名")
flag.StringVar(&mysqlPass, "p", "123456", "-p 数据库密码")
flag.StringVar(&saveFile, "save-path", "./bin2sql.sql", "-save-path 保存解析后的文件")
flag.StringVar(&start, "start", "", "--start-position 开始位置")
flag.StringVar(&end, "end", "", "--end-position 结束位置")
flag.StringVar(&startDate, "start-date", "", "--start-date 结束位置")
flag.StringVar(&endDate, "end-date", "", "--end-date 结束位置")
flag.Parse()
var command = "mysqlbinlog -v --base64-output=decode-rows "
if binLogName == "" {
fmt.Println("请输入binlog文件名")
os.Exit(-1)
}
connectStatus := InitDB(mysqlUser, mysqlPass, mysqlHost, mysqlPort, "information_schema")
if connectStatus != nil {
fmt.Println(connectStatus)
os.Exit(-3)
}
binLogPath = getBinLogPath() + binLogName
if start != "" {
command += " --start-position=" + start
}
if end != "" {
command += " --end-position=" + end
}
if startDate != "" {
command += " --start-datetime='" + startDate + "'"
}
if endDate != "" {
command += " --stop-datetime='" + endDate + "'"
}
command += " " + binLogPath
fmt.Println("执行命令为:" + command)
//os.Exit(-1)
if _, err := os.Stat(binLogPath); os.IsNotExist(err) {
fmt.Println(binLogPath + ":文件不存在")
os.Exit(-2)
}
strData, err1 := ExecCommand(command)
if err1 != nil {
fmt.Println(err1)
os.Exit(-4)
}
f, err := os.Create(saveFile)
f1, err1 := os.Create("./tun.sql")
defer f.Close()
defer f1.Close()
if err != nil {
fmt.Println(err)
}
if err1 != nil {
fmt.Println(err1)
}
sqlArr := map[string]string{
"create": `(?msi:CREATE TABLE [a-z]+[a-z].*?/*!*/;)+`,
"insert": `(?msi:INSERT [a-z]+[a-z].*?# at)+`,
"delete": `(?msi:DELETE [a-z]+[a-z].*?# at)+`,
"update": "(?msi:UPDATE `.[a-z].*?# at)+",
"alter": `(?msi:ALTER [a-z]+((\s+))[a-z].*?/*!*/;)+`,
}
for k, v := range sqlArr {
wg.Add(1)
go writeFile(strData, *f, *f1, v, k)
}
wg.Wait()
fmt.Println("解析完成,binlog解析sql保存文件为:" + saveFile)
fmt.Println("\t 反解析后的文件保存为::./tun.sql")
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。