@@ -59,7 +59,7 @@ type reorgCtx struct {
5959 // If the reorganization job is done, we will use this channel to notify outer.
6060 // TODO: Now we use goroutine to simulate reorganization jobs, later we may
6161 // use a persistent job list.
62- doneCh chan error
62+ doneCh chan reorgFnResult
6363 // rowCount is used to simulate a job's row count.
6464 rowCount int64
6565 jobState model.JobState
@@ -74,6 +74,13 @@ type reorgCtx struct {
7474 references atomicutil.Int32
7575}
7676
77+ // reorgFnResult records the DDL owner TS before executing reorg function, in order to help
78+ // receiver determine if the result is from reorg function of previous DDL owner in this instance.
79+ type reorgFnResult struct {
80+ ownerTS int64
81+ err error
82+ }
83+
7784// newContext gets a context. It is only used for adding column in reorganization state.
7885func newContext (store kv.Storage ) sessionctx.Context {
7986 c := mock .NewContext ()
@@ -200,11 +207,13 @@ func (w *worker) runReorgJob(reorgInfo *reorgInfo, tblInfo *model.TableInfo,
200207 return dbterror .ErrCancelledDDLJob
201208 }
202209
210+ beOwnerTS := w .ddlCtx .reorgCtx .getOwnerTS ()
203211 rc = w .newReorgCtx (reorgInfo .Job .ID , reorgInfo .Job .GetRowCount ())
204212 w .wg .Add (1 )
205213 go func () {
206214 defer w .wg .Done ()
207- rc .doneCh <- f ()
215+ err := f ()
216+ rc .doneCh <- reorgFnResult {ownerTS : beOwnerTS , err : err }
208217 }()
209218 }
210219
@@ -220,7 +229,16 @@ func (w *worker) runReorgJob(reorgInfo *reorgInfo, tblInfo *model.TableInfo,
220229
221230 // wait reorganization job done or timeout
222231 select {
223- case err := <- rc .doneCh :
232+ case res := <- rc .doneCh :
233+ err := res .err
234+ curTS := w .ddlCtx .reorgCtx .getOwnerTS ()
235+ if res .ownerTS != curTS {
236+ d .removeReorgCtx (job .ID )
237+ logutil .BgLogger ().Warn ("owner ts mismatch, return timeout error and retry" ,
238+ zap .Int64 ("prevTS" , res .ownerTS ),
239+ zap .Int64 ("curTS" , curTS ))
240+ return dbterror .ErrWaitReorgTimeout
241+ }
224242 // Since job is cancelled,we don't care about its partial counts.
225243 if rc .isReorgCanceled () || terror .ErrorEqual (err , dbterror .ErrCancelledDDLJob ) {
226244 d .removeReorgCtx (job .ID )
0 commit comments