deal uncached prepare qps
This commit is contained in:
parent
92e592ed73
commit
a9f0ee309e
|
@ -1 +1,3 @@
|
||||||
package capture
|
package capture
|
||||||
|
|
||||||
|
const checkCount = 30
|
|
@ -106,20 +106,22 @@ func (nc *networkCard) Listen() (receiver chan model.QueryPiece) {
|
||||||
// Listen get a connection.
|
// Listen get a connection.
|
||||||
func (nc *networkCard) listenNormal() {
|
func (nc *networkCard) listenNormal() {
|
||||||
go func() {
|
go func() {
|
||||||
|
aliveCounter := 0
|
||||||
handler := initEthernetHandlerFromPacpgo()
|
handler := initEthernetHandlerFromPacpgo()
|
||||||
for {
|
for {
|
||||||
var data []byte
|
var data []byte
|
||||||
data, ci, err := handler.ZeroCopyReadPacketData()
|
var ci gopacket.CaptureInfo
|
||||||
if err != nil {
|
var err error
|
||||||
log.Error(err.Error())
|
|
||||||
time.Sleep(time.Second*3)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// capture packets according to a certain probability
|
// capture packets according to a certain probability
|
||||||
capturePacketRate := communicator.GetTCPCapturePacketRate()
|
capturePacketRate := communicator.GetTCPCapturePacketRate()
|
||||||
if capturePacketRate <= 0 {
|
if capturePacketRate <= 0 {
|
||||||
time.Sleep(time.Second*3)
|
time.Sleep(time.Second*1)
|
||||||
|
aliveCounter += 1
|
||||||
|
if aliveCounter >= checkCount {
|
||||||
|
aliveCounter = 0
|
||||||
|
nc.receiver <- model.NewBaseQueryPiece(localIPAddr, nc.listenPort, capturePacketRate)
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
|
|
||||||
} else if 0 < capturePacketRate && capturePacketRate < 1.0 {
|
} else if 0 < capturePacketRate && capturePacketRate < 1.0 {
|
||||||
|
@ -130,6 +132,14 @@ func (nc *networkCard) listenNormal() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aliveCounter = 0
|
||||||
|
data, ci, err = handler.ZeroCopyReadPacketData()
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err.Error())
|
||||||
|
time.Sleep(time.Second*3)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
packet := gopacket.NewPacket(data, layers.LayerTypeEthernet, gopacket.NoCopy)
|
packet := gopacket.NewPacket(data, layers.LayerTypeEthernet, gopacket.NoCopy)
|
||||||
m := packet.Metadata()
|
m := packet.Metadata()
|
||||||
m.CaptureInfo = ci
|
m.CaptureInfo = ci
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pingcap/tidb/util/hack"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MysqlQueryPiece 查询信息
|
||||||
|
type MysqlQueryPiece struct {
|
||||||
|
BaseQueryPiece
|
||||||
|
|
||||||
|
SessionID *string `json:"cid"`
|
||||||
|
ClientHost *string `json:"-"`
|
||||||
|
ClientPort int `json:"-"`
|
||||||
|
|
||||||
|
VisitUser *string `json:"user"`
|
||||||
|
VisitDB *string `json:"db"`
|
||||||
|
QuerySQL *string `json:"sql"`
|
||||||
|
CostTimeInMS int64 `json:"cms"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PooledMysqlQueryPiece struct {
|
||||||
|
MysqlQueryPiece
|
||||||
|
recoverPool *mysqlQueryPiecePool
|
||||||
|
sliceBufferPool *sliceBufferPool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPooledMysqlQueryPiece(
|
||||||
|
sessionID, clientIP, visitUser, visitDB, clientHost, serverIP *string,
|
||||||
|
clientPort, serverPort int, throwPacketRate float64, stmtBeginTime int64) (
|
||||||
|
mqp *PooledMysqlQueryPiece) {
|
||||||
|
mqp = mqpp.Dequeue()
|
||||||
|
|
||||||
|
nowInMS := time.Now().UnixNano() / millSecondUnit
|
||||||
|
mqp.SessionID = sessionID
|
||||||
|
mqp.ClientHost = clientIP
|
||||||
|
mqp.ClientPort = clientPort
|
||||||
|
mqp.ClientHost = clientHost
|
||||||
|
mqp.ServerIP = serverIP
|
||||||
|
mqp.ServerPort = serverPort
|
||||||
|
mqp.VisitUser = visitUser
|
||||||
|
mqp.VisitDB = visitDB
|
||||||
|
mqp.SyncSend = false
|
||||||
|
mqp.ThrowPacketRate = throwPacketRate
|
||||||
|
mqp.BeginTime = stmtBeginTime
|
||||||
|
mqp.CostTimeInMS = nowInMS - stmtBeginTime
|
||||||
|
mqp.recoverPool = mqpp
|
||||||
|
mqp.sliceBufferPool = localSliceBufferPool
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mqp *MysqlQueryPiece) String() (*string) {
|
||||||
|
content := mqp.Bytes()
|
||||||
|
contentStr := hack.String(content)
|
||||||
|
return &contentStr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mqp *MysqlQueryPiece) Bytes() (content []byte) {
|
||||||
|
// content, err := json.Marshal(mqp)
|
||||||
|
if len(mqp.jsonContent) > 0 {
|
||||||
|
return mqp.jsonContent
|
||||||
|
}
|
||||||
|
|
||||||
|
mqp.jsonContent = marsharQueryPiece(mqp)
|
||||||
|
return mqp.jsonContent
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mqp *MysqlQueryPiece) GetSQL() (str *string) {
|
||||||
|
return mqp.QuerySQL
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pmqp *PooledMysqlQueryPiece) Recovery() {
|
||||||
|
pmqp.recoverPool.Enqueue(pmqp)
|
||||||
|
pmqp.sliceBufferPool.Enqueue(pmqp.jsonContent[:0])
|
||||||
|
pmqp.jsonContent = nil
|
||||||
|
}
|
|
@ -1,13 +1,11 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
|
|
||||||
"encoding/json"
|
|
||||||
// "github.com/json-iterator/go"
|
// "github.com/json-iterator/go"
|
||||||
"time"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"github.com/pingcap/tidb/util/hack"
|
"github.com/pingcap/tidb/util/hack"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type QueryPiece interface {
|
type QueryPiece interface {
|
||||||
|
@ -18,28 +16,14 @@ type QueryPiece interface {
|
||||||
Recovery()
|
Recovery()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MysqlQueryPiece 查询信息
|
// BaseQueryPiece 查询信息
|
||||||
type MysqlQueryPiece struct {
|
type BaseQueryPiece struct {
|
||||||
SessionID *string `json:"cid"`
|
SyncSend bool `json:"-"`
|
||||||
ClientHost *string `json:"-"`
|
ServerIP *string `json:"sip"`
|
||||||
ClientPort int `json:"-"`
|
ServerPort int `json:"sport"`
|
||||||
SyncSend bool `json:"-"`
|
ThrowPacketRate float64 `json:"tpr"`
|
||||||
ServerIP *string `json:"sip"`
|
BeginTime int64 `json:"bt"`
|
||||||
ServerPort int `json:"sport"`
|
jsonContent []byte `json:"-"`
|
||||||
VisitUser *string `json:"user"`
|
|
||||||
VisitDB *string `json:"db"`
|
|
||||||
QuerySQL *string `json:"sql"`
|
|
||||||
ThrowPacketRate float64 `json:"tpr"`
|
|
||||||
BeginTime int64 `json:"bt"`
|
|
||||||
CostTimeInMS int64 `json:"cms"`
|
|
||||||
|
|
||||||
jsonContent []byte `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type PooledMysqlQueryPiece struct {
|
|
||||||
MysqlQueryPiece
|
|
||||||
recoverPool *mysqlQueryPiecePool
|
|
||||||
sliceBufferPool *sliceBufferPool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -47,74 +31,63 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
mqpp = NewMysqlQueryPiecePool()
|
mqpp = NewMysqlQueryPiecePool()
|
||||||
localSliceBufferPool = NewSliceBufferPool("json cache", 2*1024*1024)
|
localSliceBufferPool = NewSliceBufferPool("json cache", 2*1024*1024)
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewPooledMysqlQueryPiece(
|
var commonBaseQueryPiece = &BaseQueryPiece{}
|
||||||
sessionID, clientIP, visitUser, visitDB, clientHost, serverIP *string,
|
|
||||||
clientPort, serverPort int, throwPacketRate float64, stmtBeginTime int64) (
|
|
||||||
mqp *PooledMysqlQueryPiece) {
|
|
||||||
mqp = mqpp.Dequeue()
|
|
||||||
|
|
||||||
nowInMS := time.Now().UnixNano() / millSecondUnit
|
func NewBaseQueryPiece(
|
||||||
mqp.SessionID = sessionID
|
serverIP *string, serverPort int, throwPacketRate float64) (
|
||||||
mqp.ClientHost = clientIP
|
bqp *BaseQueryPiece) {
|
||||||
mqp.ClientPort = clientPort
|
bqp = commonBaseQueryPiece
|
||||||
mqp.ClientHost = clientHost
|
bqp.ServerIP = serverIP
|
||||||
mqp.ServerIP = serverIP
|
bqp.ServerPort = serverPort
|
||||||
mqp.ServerPort = serverPort
|
bqp.SyncSend = false
|
||||||
mqp.VisitUser = visitUser
|
bqp.ThrowPacketRate = throwPacketRate
|
||||||
mqp.VisitDB = visitDB
|
bqp.BeginTime = time.Now().UnixNano() / millSecondUnit
|
||||||
mqp.SyncSend = false
|
|
||||||
mqp.ThrowPacketRate = throwPacketRate
|
|
||||||
mqp.BeginTime = stmtBeginTime
|
|
||||||
mqp.CostTimeInMS = nowInMS - stmtBeginTime
|
|
||||||
mqp.recoverPool = mqpp
|
|
||||||
mqp.sliceBufferPool = localSliceBufferPool
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mqp *MysqlQueryPiece) String() (*string) {
|
func (bqp *BaseQueryPiece) NeedSyncSend() (bool) {
|
||||||
content := mqp.Bytes()
|
return bqp.SyncSend
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bqp *BaseQueryPiece) SetNeedSyncSend(syncSend bool) {
|
||||||
|
bqp.SyncSend = syncSend
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bqp *BaseQueryPiece) String() (*string) {
|
||||||
|
content := bqp.Bytes()
|
||||||
contentStr := hack.String(content)
|
contentStr := hack.String(content)
|
||||||
return &contentStr
|
return &contentStr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mqp *MysqlQueryPiece) Bytes() (content []byte) {
|
func (bqp *BaseQueryPiece) Bytes() (content []byte) {
|
||||||
// content, err := json.Marshal(mqp)
|
// content, err := json.Marshal(bqp)
|
||||||
if len(mqp.jsonContent) > 0 {
|
if bqp.jsonContent != nil && len(bqp.jsonContent) > 0 {
|
||||||
return mqp.jsonContent
|
return bqp.jsonContent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bqp.jsonContent = marsharQueryPiece(bqp)
|
||||||
|
return bqp.jsonContent
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bqp *BaseQueryPiece) GetSQL() (*string) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bqp *BaseQueryPiece) Recovery() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func marsharQueryPiece(qp interface{}) []byte {
|
||||||
var cacheBuffer = localSliceBufferPool.Dequeue()
|
var cacheBuffer = localSliceBufferPool.Dequeue()
|
||||||
buffer := bytes.NewBuffer(cacheBuffer)
|
buffer := bytes.NewBuffer(cacheBuffer)
|
||||||
err := json.NewEncoder(buffer).Encode(mqp)
|
err := json.NewEncoder(buffer).Encode(qp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
mqp.jsonContent = []byte(err.Error())
|
return []byte(err.Error())
|
||||||
|
|
||||||
} else {
|
|
||||||
mqp.jsonContent = buffer.Bytes()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mqp.jsonContent
|
return buffer.Bytes()
|
||||||
}
|
|
||||||
|
|
||||||
func (mqp *MysqlQueryPiece) GetSQL() (str *string) {
|
|
||||||
return mqp.QuerySQL
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mqp *MysqlQueryPiece) NeedSyncSend() (bool) {
|
|
||||||
return mqp.SyncSend
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mqp *MysqlQueryPiece) SetNeedSyncSend(syncSend bool) {
|
|
||||||
mqp.SyncSend = syncSend
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pmqp *PooledMysqlQueryPiece) Recovery() {
|
|
||||||
pmqp.recoverPool.Enqueue(pmqp)
|
|
||||||
pmqp.sliceBufferPool.Enqueue(pmqp.jsonContent[:0])
|
|
||||||
pmqp.jsonContent = nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ var (
|
||||||
|
|
||||||
coverRangePool = NewCoveragePool()
|
coverRangePool = NewCoveragePool()
|
||||||
localStmtCache = model.NewSliceBufferPool("statement cache", MaxMysqlPacketLen)
|
localStmtCache = model.NewSliceBufferPool("statement cache", MaxMysqlPacketLen)
|
||||||
|
|
||||||
|
PrepareStatement = []byte(":prepare")
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
@ -258,7 +258,8 @@ func (ms *MysqlSession) GenerateQueryPiece() (qp model.QueryPiece) {
|
||||||
|
|
||||||
case ComStmtPrepare:
|
case ComStmtPrepare:
|
||||||
mqp = ms.composeQueryPiece()
|
mqp = ms.composeQueryPiece()
|
||||||
querySQLInBytes = ms.cachedStmtBytes[1:]
|
querySQLInBytes = make([]byte, len(ms.cachedStmtBytes[1:]))
|
||||||
|
copy(querySQLInBytes, ms.cachedStmtBytes[1:])
|
||||||
querySQL := hack.String(querySQLInBytes)
|
querySQL := hack.String(querySQLInBytes)
|
||||||
mqp.QuerySQL = &querySQL
|
mqp.QuerySQL = &querySQL
|
||||||
ms.cachedPrepareStmt[ms.prepareInfo.prepareStmtID] = querySQLInBytes
|
ms.cachedPrepareStmt[ms.prepareInfo.prepareStmtID] = querySQLInBytes
|
||||||
|
@ -267,10 +268,15 @@ func (ms *MysqlSession) GenerateQueryPiece() (qp model.QueryPiece) {
|
||||||
case ComStmtExecute:
|
case ComStmtExecute:
|
||||||
prepareStmtID := bytesToInt(ms.cachedStmtBytes[1:5])
|
prepareStmtID := bytesToInt(ms.cachedStmtBytes[1:5])
|
||||||
mqp = ms.composeQueryPiece()
|
mqp = ms.composeQueryPiece()
|
||||||
querySQLInBytes = ms.cachedPrepareStmt[prepareStmtID]
|
var ok bool
|
||||||
|
querySQLInBytes, ok = ms.cachedPrepareStmt[prepareStmtID]
|
||||||
|
if !ok {
|
||||||
|
querySQLInBytes = PrepareStatement
|
||||||
|
}
|
||||||
querySQL := hack.String(querySQLInBytes)
|
querySQL := hack.String(querySQLInBytes)
|
||||||
mqp.QuerySQL = &querySQL
|
mqp.QuerySQL = &querySQL
|
||||||
log.Debugf("execute prepare statement:%d", prepareStmtID)
|
|
||||||
|
// log.Debugf("execute prepare statement:%d", prepareStmtID)
|
||||||
|
|
||||||
case ComStmtClose:
|
case ComStmtClose:
|
||||||
prepareStmtID := bytesToInt(ms.cachedStmtBytes[1:5])
|
prepareStmtID := bytesToInt(ms.cachedStmtBytes[1:5])
|
||||||
|
|
Loading…
Reference in New Issue