code: func (w *worker) start(d *ddlCtx) {
  	logutil.Logger(w.logCtx).Info("[ddl] start DDL worker")
  	defer w.wg.Done()
  
  	// We use 4 * lease time to check owner's timeout, so here, we will update owner's status
  	// every 2 * lease time. If lease is 0, we will use default 1s.
  	// But we use etcd to speed up, normally it takes less than 1s now, so we use 1s as the max value.
  	checkTime := chooseLeaseTime(2*d.lease, 1*time.Second)
  
  	ticker := time.NewTicker(checkTime)
  	defer ticker.Stop()
  
  	for {
  		select {
  		case <-ticker.C:
  			logutil.Logger(w.logCtx).Debug("[ddl] wait to check DDL status again", zap.Duration("interval", checkTime))
  		case <-w.ddlJobCh:
  		case <-w.quitCh:
  			return
  		}
  
  		err := w.handleDDLJobQueue(d)
  		if err != nil {
  			logutil.Logger(w.logCtx).Error("[ddl] handle DDL job failed", zap.Error(err))
  		}
  	}
  }
docs: // start is used for async online schema changing, it will try to become the owner firstly,
  // then wait or pull the job queue to handle a schema change job.