Skip to content

Commit cac1c7b

Browse files
fix drop database without lock table (#19698)
fix drop database without lock table Approved by: @qingxinhome, @zhangxu19830126, @m-schen, @ouyuanning, @daviszhen, @sukki37, @aunjgr
1 parent 54f89ee commit cac1c7b

File tree

9 files changed

+117
-12
lines changed

9 files changed

+117
-12
lines changed

pkg/defines/type.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ type IsMoLogger struct{}
227227

228228
type SourceScanResKey struct{}
229229

230+
type IgnoreForeignKey struct{}
231+
230232
// Determine if now is a bg sql.
231233
type BgKey struct{}
232234

pkg/sql/compile/compile.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4801,6 +4801,12 @@ func (c *Compile) runSqlWithResult(sql string, accountId int32) (executor.Result
48014801
WithTimeZone(c.proc.GetSessionInfo().TimeZone).
48024802
WithLowerCaseTableNames(&lower)
48034803

4804+
if qry, ok := c.pn.Plan.(*plan.Plan_Ddl); ok {
4805+
if qry.Ddl.DdlType == plan.DataDefinition_DROP_DATABASE {
4806+
opts = opts.WithStatementOption(executor.StatementOption{}.WithIgnoreForeignKey())
4807+
}
4808+
}
4809+
48044810
ctx := c.proc.Ctx
48054811
if accountId >= 0 {
48064812
ctx = defines.AttachAccountId(c.proc.Ctx, uint32(accountId))

pkg/sql/compile/ddl.go

Lines changed: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,19 +130,84 @@ func (s *Scope) DropDatabase(c *Compile) error {
130130
}
131131
}
132132

133+
// whether foreign_key_checks = 0 or 1
134+
err = s.removeFkeysRelationships(c, dbName)
135+
if err != nil {
136+
return err
137+
}
138+
139+
database, err := c.e.Database(c.proc.Ctx, dbName, c.proc.GetTxnOperator())
140+
if err != nil {
141+
return err
142+
}
143+
relations, err := database.Relations(c.proc.Ctx)
144+
if err != nil {
145+
return err
146+
}
147+
var ignoreTables []string
148+
for _, r := range relations {
149+
t, err := database.Relation(c.proc.Ctx, r, nil)
150+
if err != nil {
151+
return err
152+
}
153+
defs, err := t.TableDefs(c.proc.Ctx)
154+
if err != nil {
155+
return err
156+
}
157+
158+
constrain := GetConstraintDefFromTableDefs(defs)
159+
for _, ct := range constrain.Cts {
160+
if ds, ok := ct.(*engine.IndexDef); ok {
161+
for _, d := range ds.Indexes {
162+
ignoreTables = append(ignoreTables, d.IndexTableName)
163+
}
164+
}
165+
}
166+
167+
for _, def := range defs {
168+
if partitionDef, ok := def.(*engine.PartitionDef); ok {
169+
if partitionDef.Partitioned > 0 {
170+
p := &plan.PartitionByDef{}
171+
err = p.UnMarshalPartitionInfo(([]byte)(partitionDef.Partition))
172+
if err != nil {
173+
return err
174+
}
175+
ignoreTables = append(ignoreTables, p.PartitionTableNames...)
176+
}
177+
break
178+
}
179+
}
180+
}
181+
182+
deleteTables := make([]string, 0, len(relations)-len(ignoreTables))
183+
for _, r := range relations {
184+
isIndexTable := false
185+
for _, d := range ignoreTables {
186+
if d == r {
187+
isIndexTable = true
188+
break
189+
}
190+
}
191+
if !isIndexTable {
192+
deleteTables = append(deleteTables, r)
193+
}
194+
}
195+
196+
for _, t := range deleteTables {
197+
dropSql := fmt.Sprintf(dropTableBeforeDropDatabase, dbName, t)
198+
err = c.runSql(dropSql)
199+
if err != nil {
200+
return err
201+
}
202+
}
203+
133204
sql := s.Plan.GetDdl().GetDropDatabase().GetCheckFKSql()
134205
if len(sql) != 0 {
135206
if err = runDetectFkReferToDBSql(c, sql); err != nil {
136207
return err
137208
}
138209
}
139210

140-
// whether foreign_key_checks = 0 or 1
141-
err = s.removeFkeysRelationships(c, dbName)
142-
if err != nil {
143-
return err
144-
}
145-
146211
err = c.e.Delete(c.proc.Ctx, dbName, c.proc.GetTxnOperator())
147212
if err != nil {
148213
return err

pkg/sql/compile/sql_executor.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,11 @@ func (exec *txnExecutor) Exec(
262262
defer recoverAccount(exec, originAccountID)
263263
}
264264
//-----------------------------------------------------------------------------------------
265+
if statementOption.IgnoreForeignKey() {
266+
exec.ctx = context.WithValue(exec.ctx,
267+
defines.IgnoreForeignKey{},
268+
true)
269+
}
265270

266271
receiveAt := time.Now()
267272
lower := exec.opts.LowerCaseTableNames()

pkg/sql/compile/util.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ var (
9595
updateMoIndexesAlgoParams = `update mo_catalog.mo_indexes set algo_params = '%s' where table_id = %v and name = '%s';`
9696
)
9797

98+
var (
99+
dropTableBeforeDropDatabase = "drop table if exists `%v`.`%v`;"
100+
)
101+
98102
var (
99103
deleteMoTablePartitionsWithDatabaseIdFormat = `delete from mo_catalog.mo_table_partitions where database_id = %v;`
100104
deleteMoTablePartitionsWithTableIdFormat = `delete from mo_catalog.mo_table_partitions where table_id = %v;`

pkg/sql/plan/build_ddl.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2656,8 +2656,14 @@ func buildDropTable(stmt *tree.DropTable, ctx CompilerContext) (*Plan, error) {
26562656
return nil, moerr.NewInternalError(ctx.GetContext(), "only the sys account can drop the cluster table")
26572657
}
26582658

2659+
ignore := false
2660+
val := ctx.GetContext().Value(defines.IgnoreForeignKey{})
2661+
if val != nil {
2662+
ignore = val.(bool)
2663+
}
2664+
26592665
dropTable.TableId = tableDef.TblId
2660-
if tableDef.Fkeys != nil {
2666+
if tableDef.Fkeys != nil && !ignore {
26612667
for _, fk := range tableDef.Fkeys {
26622668
if fk.ForeignTbl == 0 {
26632669
continue
@@ -2668,7 +2674,7 @@ func buildDropTable(stmt *tree.DropTable, ctx CompilerContext) (*Plan, error) {
26682674

26692675
// collect child tables that needs remove fk relationships
26702676
// with the table
2671-
if tableDef.RefChildTbls != nil {
2677+
if tableDef.RefChildTbls != nil && !ignore {
26722678
for _, childTbl := range tableDef.RefChildTbls {
26732679
if childTbl == 0 {
26742680
continue

pkg/sql/plan/build_dml_util.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3552,7 +3552,13 @@ func IsFkBannedDatabase(db string) bool {
35523552

35533553
// IsForeignKeyChecksEnabled returns the system variable foreign_key_checks is true or false
35543554
func IsForeignKeyChecksEnabled(ctx CompilerContext) (bool, error) {
3555-
if disable := ctx.GetContext().Value(defines.DisableFkCheck{}); disable != nil {
3555+
ignore := ctx.GetContext().Value(defines.IgnoreForeignKey{})
3556+
if ignore != nil {
3557+
return !ignore.(bool), nil
3558+
}
3559+
3560+
disable := ctx.GetContext().Value(defines.DisableFkCheck{})
3561+
if disable != nil {
35563562
return !disable.(bool), nil
35573563
}
35583564

pkg/util/executor/options.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ func (opts Options) WithDisableIncrStatement() Options {
2828
return opts
2929
}
3030

31+
// WithDisableIncrStatement disable incr statement
32+
func (opts StatementOption) WithIgnoreForeignKey() StatementOption {
33+
opts.ignoreForeignKey = true
34+
return opts
35+
}
36+
3137
// WithTxn exec sql in a exists txn
3238
func (opts Options) WithTxn(txnOp client.TxnOperator) Options {
3339
opts.txnOp = txnOp
@@ -172,6 +178,10 @@ func (opts StatementOption) DisableLog() bool {
172178
return opts.disableLog
173179
}
174180

181+
func (opts StatementOption) IgnoreForeignKey() bool {
182+
return opts.ignoreForeignKey
183+
}
184+
175185
func (opts Options) WithDisableTrace() Options {
176186
opts.txnOpts = append(opts.txnOpts, client.WithDisableTrace(true))
177187
return opts

pkg/util/executor/types.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,10 @@ type Options struct {
6666

6767
// StatementOption statement execute option.
6868
type StatementOption struct {
69-
waitPolicy lock.WaitPolicy
70-
accountId uint32
71-
disableLog bool
69+
waitPolicy lock.WaitPolicy
70+
accountId uint32
71+
disableLog bool
72+
ignoreForeignKey bool
7273
}
7374

7475
// Result exec sql result

0 commit comments

Comments
 (0)