package main
import (
"bytes"
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"io/ioutil"
"regexp"
"strconv"
"strings"
"sync"
)
var wg sync.WaitGroup
type DBinfo struct {
user string
pwd string
host string
port uint64
database string
}
type Checkinfo struct {
host string
port uint64
database string
table string
checksum uint64
}
func checksumTable(dbinfo *DBinfo, checkinfo *Checkinfo) {
db := getConn(dbinfo)
if db == nil {
return
}
defer db.Close()
tbuf := bytes.Buffer{}
tbuf.WriteString("checksum table ")
tbuf.WriteString(checkinfo.table)
rows, err := db.Query(tbuf.String())
if err != nil {
return
}
if rows.Next() {
var table_name string
var checksum uint64
rows.Scan(&table_name, &checksum)
checkinfo.checksum = checksum
}
}
func getConn(dbinfo *DBinfo) *sql.DB {
url := bytes.Buffer{}
url.WriteString(dbinfo.user)
url.WriteString(":")
url.WriteString(dbinfo.pwd)
url.WriteString("@tcp(")
url.WriteString(dbinfo.host)
url.WriteString(":")
url.WriteString(strconv.FormatUint(dbinfo.port, 10))
url.WriteString(")/")
url.WriteString(dbinfo.database)
url.WriteString("?charset=utf8")
db, err := sql.Open("mysql", url.String())
if err != nil {
return nil
}
return db
}
func getTables(dbinfo *DBinfo) *map[string]Checkinfo {
dict := make(map[string]Checkinfo)
db := getConn(dbinfo)
if db == nil {
return nil
}
defer db.Close()
rows, err := db.Query("show tables")
if err != nil {
return nil
}
for rows.Next() {
var table_name string
rows.Scan(&table_name)
dict[dbinfo.database+"_"+table_name] = Checkinfo{host: dbinfo.host, port: dbinfo.port, database: dbinfo.database, table: table_name}
}
return &dict
}
func getDatasource(path string) *map[string]DBinfo {
dict := make(map[string]DBinfo)
reg_coll, _ := regexp.Compile(`[/:]+`)
rf, _ := ioutil.ReadFile(path)
ar := strings.Split(string(rf), "\n")
for _, item := range ar {
ar_coll := reg_coll.Split(item, -1)
if len(ar_coll) == 5 {
port, _ := strconv.ParseUint(ar_coll[1], 10, 64)
dict[ar_coll[2]] = DBinfo{host: ar_coll[0], port: port, database: ar_coll[2], user: ar_coll[3], pwd: ar_coll[4]}
}
}
return &dict
}
func workhandle(skey string, sdbinfo DBinfo, target *map[string]DBinfo) {
dict := getTables(&sdbinfo)
if dict != nil {
for dkey, dcheckinfo := range *dict {
checksumTable(&sdbinfo, &dcheckinfo)
//fmt.Println(dkey, "source", dcheckinfo)
tdbinfo := (*target)[skey]
tcheckinfo := &Checkinfo{host: tdbinfo.host, port: tdbinfo.port, database: tdbinfo.database, table: dcheckinfo.table}
checksumTable(&tdbinfo, tcheckinfo)
//fmt.Println(dkey, "target", tcheckinfo)
if dcheckinfo.checksum != tcheckinfo.checksum {
fmt.Println(dkey, "source", dcheckinfo, "->", dkey, "target", tcheckinfo)
}
}
}
wg.Done()
}
func run() {
source := getDatasource("/home/work/etc/a.lst")
target := getDatasource("/home/work/etc/b.lst")
for skey, sdbinfo := range *source {
wg.Add(1)
go workhandle(skey, sdbinfo, target)
}
wg.Wait()
}
func main() {
run()
}
cat /home/work/etc/a.lst
127.0.0.1:3306/test/xm_dba/123456
127.0.0.1:3306/test_1/xm_dba/123456
cat /home/work/etc/b.lst
127.0.0.1:3306/test/xm_dba/123456
127.0.0.1:3306/test_1/xm_dba/123456
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)