Skip to content

Commit

Permalink
server: log last executed prepared stmt when panic (#12905) (#14322)
Browse files Browse the repository at this point in the history
  • Loading branch information
lysu authored and ngaut committed Jan 2, 2020
1 parent e1d8b41 commit 81d276e
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 5 deletions.
42 changes: 37 additions & 5 deletions server/conn.go
Expand Up @@ -144,7 +144,7 @@ type clientConn struct {
dbname string // default database name.
salt []byte // random bytes used for authentication.
alloc arena.Allocator // an memory allocator for reducing memory allocation.
lastCmd string // latest sql query string, currently used for logging error.
lastPacket []byte // latest sql query string, currently used for logging error.
ctx QueryCtx // an interface to execute sql statements.
attrs map[string]string // attributes parsed from client handshake response, not used for now.
status int32 // dispatching/reading/shutdown/waitshutdown
Expand Down Expand Up @@ -612,7 +612,7 @@ func (cc *clientConn) Run(ctx context.Context) {
stackSize := runtime.Stack(buf, false)
buf = buf[:stackSize]
logutil.Logger(ctx).Error("connection running loop panic",
zap.String("lastCmd", cc.lastCmd),
zap.Stringer("lastSQL", getLastStmtInConn{cc}),
zap.Reflect("err", r),
zap.String("stack", string(buf)),
)
Expand Down Expand Up @@ -683,7 +683,7 @@ func (cc *clientConn) Run(ctx context.Context) {
zap.String("connInfo", cc.String()),
zap.String("command", mysql.Command2Str[data[0]]),
zap.String("status", cc.SessionStatusToString()),
zap.String("sql", queryStrForLog(string(data[1:]))),
zap.Stringer("sql", getLastStmtInConn{cc}),
zap.String("err", errStrForLog(err)),
)
err1 := cc.writeError(err)
Expand Down Expand Up @@ -864,9 +864,9 @@ func (cc *clientConn) dispatch(ctx context.Context, data []byte) error {
span := opentracing.StartSpan("server.dispatch")

t := time.Now()
cc.lastPacket = data
cmd := data[0]
data = data[1:]
cc.lastCmd = string(hack.String(data))
token := cc.server.getToken()
defer func() {
// if handleChangeUser failed, cc.ctx may be nil
Expand Down Expand Up @@ -1285,7 +1285,7 @@ func (cc *clientConn) writeResultset(ctx context.Context, rs ResultSet, binary b
buf := make([]byte, 4096)
stackSize := runtime.Stack(buf, false)
buf = buf[:stackSize]
logutil.Logger(ctx).Error("write query result panic", zap.String("lastCmd", cc.lastCmd), zap.String("stack", string(buf)))
logutil.Logger(ctx).Error("write query result panic", zap.Stringer("lastSQL", getLastStmtInConn{cc}), zap.String("stack", string(buf)))
}()
var err error
if mysql.HasCursorExistsFlag(serverStatus) {
Expand Down Expand Up @@ -1515,3 +1515,35 @@ func (cc *clientConn) handleChangeUser(ctx context.Context, data []byte) error {

return cc.writeOK()
}

var _ fmt.Stringer = getLastStmtInConn{}

type getLastStmtInConn struct {
*clientConn
}

func (cc getLastStmtInConn) String() string {
if len(cc.lastPacket) == 0 {
return ""
}
cmd, data := cc.lastPacket[0], cc.lastPacket[1:]
switch cmd {
case mysql.ComInitDB:
return "Use " + string(data)
case mysql.ComFieldList:
return "ListFields " + string(data)
case mysql.ComQuery, mysql.ComStmtPrepare:
return queryStrForLog(string(hack.String(data)))
case mysql.ComStmtExecute, mysql.ComStmtFetch:
stmtID := binary.LittleEndian.Uint32(data[0:4])
return queryStrForLog(cc.preparedStmt2String(stmtID))
case mysql.ComStmtClose, mysql.ComStmtReset:
stmtID := binary.LittleEndian.Uint32(data[0:4])
return mysql.Command2Str[cmd] + " " + strconv.Itoa(int(stmtID))
default:
if cmdStr, ok := mysql.Command2Str[cmd]; ok {
return cmdStr
}
return string(hack.String(data))
}
}
3 changes: 3 additions & 0 deletions server/conn_stmt.go
Expand Up @@ -581,6 +581,9 @@ func (cc *clientConn) handleSetOption(data []byte) (err error) {

func (cc *clientConn) preparedStmt2String(stmtID uint32) string {
sv := cc.ctx.GetSessionVars()
if sv == nil {
return ""
}
if prepared, ok := sv.PreparedStmts[stmtID]; ok {
return prepared.Stmt.Text() + sv.PreparedParams.String()
}
Expand Down

0 comments on commit 81d276e

Please sign in to comment.