导读
本文主要介绍如何借助 TiDB SQL 解析自定义生成 SQL 指纹,采用了一种有别于 pt-fingerprint
(https://www.percona.com/doc/percona-toolkit/3.0/pt-fingerprint.html) 的方式。
介绍:
承接上篇文章:
golang mysql 慢日志解析工具_雨丶花丶石的博客-CSDN博客
之前做了一个mysql slowlog的解析工具,那么有时候需要将慢查询进行入库,然后进行分析、或者制作报表、趋势图等;如将慢查询入库后,可以使用SQL指纹的进行统计分析(统计相同指纹语句的在某段时间范围的查询次数、最大查询时间、平均查询时间等)
这时候就需要把对SQL文件进行指纹输出,例如pt-fingerprint工具:
pt-fingerprint[1]工具提供将SQL语句转换为指纹,支持以下的功能:
多值INSERT语句缩减为单个VALUES()列表
删除语句注释
替换可选参数,如带引号的字符串
可以将分库分表名中的数字进行替换
缩减空格的数量,统一格式
将语句全部进行小写,替换IN()和VALUES()中的值
将UNION语句合并为一个语句
那么如何使用go语言去实现了,这里就介绍 如何使用go实现对SQL进行解析指纹输出
功能展示:
这里面使用了tidb 的SQL Parse 解析,参考:
tidb/quickstart.md at master · pingcap/tidb · GitHub具体功能展示如下:
代码展示:
之前在go1.14版本中有个exp/constraints包编译报错,后来把go升级到1.18+以上版本就搞定了,原理是exp/constraints 使用了泛型,这种语法在go1.8 才支持。
具体代码如下:
package main
import (
"bytes"
"flag"
"github.com/fatih/color"
"github.com/pingcap/tidb/parser"
"github.com/pingcap/tidb/parser/ast"
"github.com/pingcap/tidb/parser/format"
driver "github.com/pingcap/tidb/types/parser_driver"
)
// 定义一个 FingerprintVisitor 使其实现 Visitor 接口
type FingerprintVisitor struct{}
func (f *FingerprintVisitor) Enter(n ast.Node) (node ast.Node, skipChildren bool) {
// 当访问到ValueExpr 时,只需要将ValueExpr的值替换掉就行
if v, ok := n.(*driver.ValueExpr); ok {
//v.Type.Charset = ""
v.SetValue([]byte("?"))
}
return n, false
}
func (f *FingerprintVisitor) Leave(n ast.Node) (node ast.Node, ok bool) {
return n, true
}
var (
Success *color.Color
Err *color.Color
sql string
)
func main() {
Success=color.New(color.FgHiGreen,color.Bold,color.Underline)
Err=color.New(color.FgHiRed, color.Bold)
flag.StringVar(&sql, "sql", "", "SQL语句")
p := parser.New()
flag.Parse()
stmt, err := p.ParseOneStmt(sql, "", "")
if err != nil {
// 省略错误处理
Err.Println("解析错误:"+err.Error())
return
}
stmt.Accept(&FingerprintVisitor{})
buf := new(bytes.Buffer)
restoreCtx := format.NewRestoreCtx(format.RestoreKeyWordUppercase|format.RestoreNameBackQuotes, buf)
err = stmt.Restore(restoreCtx)
if nil != err {
// 省略错误处理
Err.Println("解析错误:"+err.Error())
return
}
Success.Println(buf.String())
}
本文含有隐藏内容,请 开通VIP 后查看