Skip to content
This repository was archived by the owner on Jan 28, 2021. It is now read-only.

Commit 239b2af

Browse files
authored
Merge pull request #636 from kuba--/fix-635/kill
KILL query always takes processlist_id
2 parents b829206 + 416e225 commit 239b2af

File tree

3 files changed

+47
-20
lines changed

3 files changed

+47
-20
lines changed

Diff for: server/handler.go

+21-9
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"time"
1010

1111
errors "gopkg.in/src-d/go-errors.v1"
12-
"gopkg.in/src-d/go-mysql-server.v0"
12+
sqle "gopkg.in/src-d/go-mysql-server.v0"
1313
"gopkg.in/src-d/go-mysql-server.v0/auth"
1414
"gopkg.in/src-d/go-mysql-server.v0/sql"
1515

@@ -173,23 +173,35 @@ func (h *Handler) handleKill(conn *mysql.Conn, query string) (bool, error) {
173173
// KILL CONNECTION and KILL should close the connection. KILL QUERY only
174174
// cancels the query.
175175
//
176-
// https://dev.mysql.com/doc/refman/5.7/en/kill.html
176+
// https://dev.mysql.com/doc/refman/8.0/en/kill.html
177+
//
178+
// KILL [CONNECTION | QUERY] processlist_id
179+
// - KILL QUERY terminates the statement the connection is currently executing,
180+
// but leaves the connection itself intact.
177181

182+
// - KILL CONNECTION is the same as KILL with no modifier:
183+
// It terminates the connection associated with the given processlist_id,
184+
// after terminating any statement the connection is executing.
178185
if s[1] == "query" {
179-
logrus.Infof("kill query: id %v", id)
186+
logrus.Infof("kill query: id %d", id)
180187
h.e.Catalog.Kill(id)
181188
} else {
182-
logrus.Infof("kill connection: id %v, pid: %v", conn.ConnectionID, id)
189+
connID, ok := h.e.Catalog.KillConnection(id)
190+
if !ok {
191+
return false, errConnectionNotFound.New(connID)
192+
}
193+
logrus.Infof("kill connection: id %d, pid: %d", connID, id)
194+
183195
h.mu.Lock()
184-
c, ok := h.c[conn.ConnectionID]
185-
delete(h.c, conn.ConnectionID)
196+
c, ok := h.c[connID]
197+
if ok {
198+
delete(h.c, connID)
199+
}
186200
h.mu.Unlock()
187-
188201
if !ok {
189-
return false, errConnectionNotFound.New(conn.ConnectionID)
202+
return false, errConnectionNotFound.New(connID)
190203
}
191204

192-
h.e.Catalog.KillConnection(uint32(id))
193205
h.sm.CloseConn(c)
194206
c.Close()
195207
}

Diff for: server/handler_test.go

+12-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package server
22

33
import (
4+
"fmt"
45
"net"
56
"reflect"
67
"testing"
78
"unsafe"
89

9-
"gopkg.in/src-d/go-mysql-server.v0"
10+
sqle "gopkg.in/src-d/go-mysql-server.v0"
1011
"gopkg.in/src-d/go-mysql-server.v0/mem"
1112
"gopkg.in/src-d/go-mysql-server.v0/sql"
1213
"gopkg.in/src-d/go-vitess.v1/mysql"
@@ -167,7 +168,7 @@ func TestHandlerKill(t *testing.T) {
167168
e,
168169
NewSessionManager(
169170
func(conn *mysql.Conn, addr string) sql.Session {
170-
return sql.NewBaseSession()
171+
return sql.NewSession(addr, "", "", conn.ConnectionID)
171172
},
172173
opentracing.NoopTracer{},
173174
"foo",
@@ -197,15 +198,20 @@ func TestHandlerKill(t *testing.T) {
197198

198199
assertNoConnProcesses(t, e, conn2.ConnectionID)
199200

200-
err = handler.ComQuery(conn2, "KILL 1", func(res *sqltypes.Result) error {
201+
ctx1 := handler.sm.NewContextWithQuery(conn1, "SELECT 1")
202+
ctx1, err = handler.e.Catalog.AddProcess(ctx1, sql.QueryProcess, "SELECT 1")
203+
require.NoError(err)
204+
205+
err = handler.ComQuery(conn2, "KILL "+fmt.Sprint(ctx1.Pid()), func(res *sqltypes.Result) error {
201206
return nil
202207
})
203208
require.NoError(err)
204209

205-
require.Len(handler.sm.sessions, 0)
210+
require.Len(handler.sm.sessions, 1)
206211
require.Len(handler.c, 1)
207-
require.Equal(conn1, handler.c[1])
208-
assertNoConnProcesses(t, e, conn2.ConnectionID)
212+
_, ok := handler.c[1]
213+
require.False(ok)
214+
assertNoConnProcesses(t, e, conn1.ConnectionID)
209215
}
210216

211217
func assertNoConnProcesses(t *testing.T, e *sqle.Engine, conn uint32) {

Diff for: sql/processlist.go

+14-5
Original file line numberDiff line numberDiff line change
@@ -160,17 +160,26 @@ func (pl *ProcessList) Kill(pid uint64) {
160160
pl.Done(pid)
161161
}
162162

163-
// KillConnection kills all processes from the given connection.
164-
func (pl *ProcessList) KillConnection(conn uint32) {
163+
// KillConnection terminates the connection associated with the given processlist_id,
164+
// after terminating any statement the connection is executing.
165+
func (pl *ProcessList) KillConnection(pid uint64) (uint32, bool) {
165166
pl.mu.Lock()
166167
defer pl.mu.Unlock()
167168

168-
for pid, proc := range pl.procs {
169-
if proc.Connection == conn {
169+
p, ok := pl.procs[pid]
170+
if !ok {
171+
return 0, false
172+
}
173+
174+
connID := p.Connection
175+
for id, proc := range pl.procs {
176+
if proc.Connection == connID {
170177
proc.Done()
171-
delete(pl.procs, pid)
178+
delete(pl.procs, id)
172179
}
173180
}
181+
182+
return connID, ok
174183
}
175184

176185
// Done removes the finished process with the given pid from the process list.

0 commit comments

Comments
 (0)