-
Notifications
You must be signed in to change notification settings - Fork 5.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ddl, meta: clean the jobs in adding index queue #6161
Changes from all commits
a385265
d0e3bab
adce88d
739f7a2
f5c4444
4254b4e
a54cfe1
e40cd70
5659835
9d99aad
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,6 +52,9 @@ func (d *ddl) onDDLWorker() { | |
metrics.PanicCounter.WithLabelValues(metrics.LabelDDL).Inc() | ||
} | ||
}() | ||
|
||
// shouldCleanJobs is used to determine whether to clean up the job in adding index queue. | ||
shouldCleanJobs := true | ||
for { | ||
select { | ||
case <-ticker.C: | ||
|
@@ -61,9 +64,12 @@ func (d *ddl) onDDLWorker() { | |
return | ||
} | ||
|
||
err := d.handleDDLJobQueue() | ||
err := d.handleDDLJobQueue(shouldCleanJobs) | ||
if err != nil { | ||
log.Errorf("[ddl] handle ddl job err %v", errors.ErrorStack(err)) | ||
} else if shouldCleanJobs { | ||
log.Info("[ddl] cleaning jobs in the adding index queue finished.") | ||
shouldCleanJobs = false | ||
} | ||
} | ||
} | ||
|
@@ -204,7 +210,9 @@ func (d *ddl) getHistoryDDLJob(id int64) (*model.Job, error) { | |
return job, errors.Trace(err) | ||
} | ||
|
||
func (d *ddl) handleDDLJobQueue() error { | ||
// handleDDLJobQueue handles DDL jobs in DDL Job queue. | ||
// shouldCleanJobs is used to determine whether to clean up the job in adding index queue. | ||
func (d *ddl) handleDDLJobQueue(shouldCleanJobs bool) error { | ||
once := true | ||
for { | ||
if d.isClosed() { | ||
|
@@ -220,6 +228,12 @@ func (d *ddl) handleDDLJobQueue() error { | |
return nil | ||
} | ||
|
||
// It's used for clean up the job in adding index queue before we support adding index queue. | ||
// TODO: Remove this logic after we support the adding index queue. | ||
if shouldCleanJobs { | ||
return errors.Trace(d.cleanAddIndexQueueJobs(txn)) | ||
} | ||
|
||
var err error | ||
t := meta.NewMeta(txn) | ||
// We become the owner. Get the first job and run it. | ||
|
@@ -479,3 +493,66 @@ func updateSchemaVersion(t *meta.Meta, job *model.Job) (int64, error) { | |
err = t.SetSchemaDiff(diff) | ||
return schemaVersion, errors.Trace(err) | ||
} | ||
|
||
// cleanAddIndexQueueJobs cleans jobs in adding index queue. | ||
// It's only done once after the worker become the owner. | ||
// TODO: Remove this logic after we support the adding index queue. | ||
func (d *ddl) cleanAddIndexQueueJobs(txn kv.Transaction) error { | ||
startTime := time.Now() | ||
m := meta.NewMeta(txn) | ||
m.SetJobListKey(meta.AddIndexJobListKey) | ||
for { | ||
job, err := d.getFirstDDLJob(m) | ||
if err != nil { | ||
return errors.Trace(err) | ||
} | ||
if job == nil { | ||
log.Infof("[ddl] cleaning jobs in the adding index queue takes time %v.", time.Since(startTime)) | ||
return nil | ||
} | ||
log.Infof("[ddl] cleaning job %v in the adding index queue.", job) | ||
|
||
// The types of these jobs must be ActionAddIndex. | ||
if job.SchemaState == model.StatePublic || job.SchemaState == model.StateNone { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have to rollback or cancel the add index ddl job? What about enqueueing these jobs to default job list There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we just put all the add index jobs at the end of the default list, what the worst-case result would be? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @coocood |
||
if job.SchemaState == model.StateNone { | ||
job.State = model.JobStateCancelled | ||
} else { | ||
binloginfo.SetDDLBinlog(d.workerVars.BinlogClient, txn, job.ID, job.Query) | ||
job.State = model.JobStateSynced | ||
} | ||
err = d.finishDDLJob(m, job) | ||
if err != nil { | ||
return errors.Trace(err) | ||
} | ||
continue | ||
} | ||
|
||
// When the job not in "none" and "public" state, we need to rollback it. | ||
schemaID := job.SchemaID | ||
tblInfo, err := getTableInfo(m, job, schemaID) | ||
if err != nil { | ||
return errors.Trace(err) | ||
} | ||
var indexName model.CIStr | ||
var unique bool | ||
err = job.DecodeArgs(&unique, &indexName) | ||
if err != nil { | ||
return errors.Trace(err) | ||
} | ||
indexInfo := findIndexByName(indexName.L, tblInfo.Indices) | ||
_, err = d.convert2RollbackJob(m, job, tblInfo, indexInfo, nil) | ||
if err == nil { | ||
_, err = m.DeQueueDDLJob() | ||
} | ||
if err != nil { | ||
return errors.Trace(err) | ||
} | ||
// Put the job to the default job list. | ||
m.SetJobListKey(meta.DefaultJobListKey) | ||
err = m.EnQueueDDLJob(job) | ||
m.SetJobListKey(meta.AddIndexJobListKey) | ||
if err != nil { | ||
return errors.Trace(err) | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -221,6 +221,7 @@ LOOP: | |
case <-ticker.C: | ||
d.Stop() | ||
d.start(context.Background()) | ||
time.Sleep(time.Millisecond * 20) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why add sleep? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because we add check |
||
case err := <-done: | ||
c.Assert(err, IsNil) | ||
break LOOP | ||
|
@@ -239,22 +240,20 @@ func (s *testSchemaSuite) TestSchemaResume(c *C) { | |
testCheckOwner(c, d1, true) | ||
|
||
dbInfo := testSchemaInfo(c, d1, "test") | ||
|
||
job := &model.Job{ | ||
SchemaID: dbInfo.ID, | ||
Type: model.ActionCreateSchema, | ||
BinlogInfo: &model.HistoryInfo{}, | ||
Args: []interface{}{dbInfo}, | ||
} | ||
|
||
testRunInterruptedJob(c, d1, job) | ||
testCheckSchemaState(c, d1, dbInfo, model.StatePublic) | ||
|
||
job = &model.Job{ | ||
SchemaID: dbInfo.ID, | ||
Type: model.ActionDropSchema, | ||
BinlogInfo: &model.HistoryInfo{}, | ||
} | ||
|
||
testRunInterruptedJob(c, d1, job) | ||
testCheckSchemaState(c, d1, dbInfo, model.StateNone) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why remove?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make
TestCleanJobs
stable.I want to get schema version and check history job's schema version in a transaction.