Skip to content

Commit fa38b94

Browse files
crazycs520bb7133
authored andcommitted
*: try to support lock/unlock tables function (pingcap#305)
1 parent 3bad507 commit fa38b94

File tree

8 files changed

+2536
-2295
lines changed

8 files changed

+2536
-2295
lines changed

ast/ddl.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,68 @@ func (n *DropIndexStmt) Accept(v Visitor) (Node, bool) {
12201220
return v.Leave(n)
12211221
}
12221222

1223+
// LockTablesStmt is a statement to lock tables.
1224+
type LockTablesStmt struct {
1225+
ddlNode
1226+
1227+
TableLocks []TableLock
1228+
}
1229+
1230+
// TableLock contains the table name and lock type.
1231+
type TableLock struct {
1232+
Table *TableName
1233+
Type model.TableLockType
1234+
}
1235+
1236+
// Accept implements Node Accept interface.
1237+
func (n *LockTablesStmt) Accept(v Visitor) (Node, bool) {
1238+
newNode, skipChildren := v.Enter(n)
1239+
if skipChildren {
1240+
return v.Leave(newNode)
1241+
}
1242+
n = newNode.(*LockTablesStmt)
1243+
for i := range n.TableLocks {
1244+
node, ok := n.TableLocks[i].Table.Accept(v)
1245+
if !ok {
1246+
return n, false
1247+
}
1248+
n.TableLocks[i].Table = node.(*TableName)
1249+
}
1250+
return v.Leave(n)
1251+
}
1252+
1253+
// Restore implements Node interface.
1254+
func (n *LockTablesStmt) Restore(ctx *RestoreCtx) error {
1255+
ctx.WriteKeyWord("LOCK TABLES ")
1256+
for i, tl := range n.TableLocks {
1257+
if i != 0 {
1258+
ctx.WritePlain(", ")
1259+
}
1260+
if err := tl.Table.Restore(ctx); err != nil {
1261+
return errors.Annotate(err, "An error occurred while add index")
1262+
}
1263+
ctx.WriteKeyWord(" " + tl.Type.String())
1264+
}
1265+
return nil
1266+
}
1267+
1268+
// UnlockTablesStmt is a statement to unlock tables.
1269+
type UnlockTablesStmt struct {
1270+
ddlNode
1271+
}
1272+
1273+
// Accept implements Node Accept interface.
1274+
func (n *UnlockTablesStmt) Accept(v Visitor) (Node, bool) {
1275+
_, _ = v.Enter(n)
1276+
return v.Leave(n)
1277+
}
1278+
1279+
// Restore implements Node interface.
1280+
func (n *UnlockTablesStmt) Restore(ctx *RestoreCtx) error {
1281+
ctx.WriteKeyWord("UNLOCK TABLES")
1282+
return nil
1283+
}
1284+
12231285
// TableOptionType is the type for TableOption
12241286
type TableOptionType int
12251287

model/ddl.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ const (
5656
ActionDropView ActionType = 24
5757
ActionRecoverTable ActionType = 25
5858
ActionModifySchemaCharsetAndCollate ActionType = 26
59+
ActionLockTable ActionType = 27
60+
ActionUnlockTable ActionType = 28
5961
)
6062

6163
// AddIndexStr is a string related to the operation of "add index".
@@ -88,6 +90,8 @@ var actionMap = map[ActionType]string{
8890
ActionDropView: "drop view",
8991
ActionRecoverTable: "recover table",
9092
ActionModifySchemaCharsetAndCollate: "modify schema charset and collate",
93+
ActionLockTable: "lock table",
94+
ActionUnlockTable: "unlock table",
9195
}
9296

9397
// String return current ddl action in string

model/model.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ package model
1515

1616
import (
1717
"encoding/json"
18+
"strconv"
1819
"strings"
1920
"time"
2021

@@ -230,11 +231,98 @@ type TableInfo struct {
230231
Compression string `json:"compression"`
231232

232233
View *ViewInfo `json:"view"`
234+
// Lock represent the table lock info.
235+
Lock *TableLockInfo `json:"Lock"`
233236

234237
// Version means the version of the table info.
235238
Version uint16 `json:"version"`
236239
}
237240

241+
// TableLockInfo provides meta data describing a table lock.
242+
type TableLockInfo struct {
243+
Tp TableLockType
244+
// Use array because there may be multiple sessions holding the same read lock.
245+
Sessions []SessionInfo
246+
State TableLockState
247+
// TS is used to record the timestamp this table lock been locked.
248+
TS uint64
249+
}
250+
251+
// SessionInfo contain the session ID and the server ID.
252+
type SessionInfo struct {
253+
ServerID string
254+
SessionID uint64
255+
}
256+
257+
func (s SessionInfo) String() string {
258+
return "server: " + s.ServerID + "_session: " + strconv.FormatUint(s.SessionID, 10)
259+
}
260+
261+
// TableLockTpInfo is composed by schema ID, table ID and table lock type.
262+
type TableLockTpInfo struct {
263+
SchemaID int64
264+
TableID int64
265+
Tp TableLockType
266+
}
267+
268+
// TableLockState is the state for table lock.
269+
type TableLockState byte
270+
271+
const (
272+
// TableLockStateNone means this table lock is absent.
273+
TableLockStateNone TableLockState = iota
274+
// TableLockStatePreLock means this table lock is pre-lock state. Other session doesn't hold this lock should't do corresponding operation according to the lock type.
275+
TableLockStatePreLock
276+
// TableLockStatePublic means this table lock is public state.
277+
TableLockStatePublic
278+
)
279+
280+
// String implements fmt.Stringer interface.
281+
func (t TableLockState) String() string {
282+
switch t {
283+
case TableLockStatePreLock:
284+
return "pre-lock"
285+
case TableLockStatePublic:
286+
return "public"
287+
default:
288+
return "none"
289+
}
290+
}
291+
292+
// TableLockType is the type of the table lock.
293+
type TableLockType byte
294+
295+
const (
296+
TableLockNone TableLockType = iota
297+
// TableLockRead means the session with this lock can read the table (but not write it).
298+
// Multiple sessions can acquire a READ lock for the table at the same time.
299+
// Other sessions can read the table without explicitly acquiring a READ lock.
300+
TableLockRead
301+
// TableLockReadLocal is not supported.
302+
TableLockReadLocal
303+
// TableLockWrite means only the session with this lock has write/read permission.
304+
// Only the session that holds the lock can access the table. No other session can access it until the lock is released.
305+
TableLockWrite
306+
// TableLockWriteLocal means the session with this lock has write/read permission, and the other session still has read permission.
307+
TableLockWriteLocal
308+
)
309+
310+
func (t TableLockType) String() string {
311+
switch t {
312+
case TableLockNone:
313+
return "NONE"
314+
case TableLockRead:
315+
return "READ"
316+
case TableLockReadLocal:
317+
return "READ LOCAL"
318+
case TableLockWriteLocal:
319+
return "WRITE LOCAL"
320+
case TableLockWrite:
321+
return "WRITE"
322+
}
323+
return ""
324+
}
325+
238326
// GetPartitionInfo returns the partition information.
239327
func (t *TableInfo) GetPartitionInfo() *PartitionInfo {
240328
if t.Partition != nil && t.Partition.Enable {
@@ -345,6 +433,11 @@ func (t *TableInfo) FindIndexByName(idxName string) *IndexInfo {
345433
return nil
346434
}
347435

436+
// IsLocked checks whether the table was locked.
437+
func (t *TableInfo) IsLocked() bool {
438+
return t.Lock != nil && len(t.Lock.Sessions) > 0
439+
}
440+
348441
// NewExtraHandleColInfo mocks a column info for extra handle column.
349442
func NewExtraHandleColInfo() *ColumnInfo {
350443
colInfo := &ColumnInfo{

mysql/errcode.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,7 @@ const (
936936
ErrRequireVersionCheckFail = 8107
937937
ErrUnsupportedReloadPlugin = 8018
938938
ErrUnsupportedReloadPluginVar = 8019
939+
ErrTableLocked = 8020
939940

940941
// TiKV/PD errors.
941942
ErrPDServerTimeout = 9001

mysql/errname.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,7 @@ var MySQLErrName = map[uint16]string{
932932
ErrRequireVersionCheckFail: "Plugin %s require %s be %v but got %v",
933933
ErrUnsupportedReloadPlugin: "Plugin %s isn't loaded so cannot be reloaded",
934934
ErrUnsupportedReloadPluginVar: "Reload plugin with different sysVar is unsupported %v",
935+
ErrTableLocked: "Table '%s' was locked in %s by %v",
935936

936937
// TiKV/PD errors.
937938
ErrPDServerTimeout: "PD server timeout",

0 commit comments

Comments
 (0)