コード例 #1
0
ファイル: index.go プロジェクト: jmptrader/tidb
// How to add index in reorganization state?
//  1. Generate a snapshot with special version.
//  2. Traverse the snapshot, get every row in the table.
//  3. For one row, if the row has been already deleted, skip to next row.
//  4. If not deleted, check whether index has existed, if existed, skip to next row.
//  5. If index doesn't exist, create the index and then continue to handle next row.
func (d *ddl) addTableIndex(t table.Table, indexInfo *model.IndexInfo, reorgInfo *reorgInfo, job *model.Job) error {
	seekHandle := reorgInfo.Handle
	version := reorgInfo.SnapshotVer
	count := job.GetRowCount()

	for {
		startTS := time.Now()
		handles, err := d.getSnapshotRows(t, version, seekHandle)
		if err != nil {
			return errors.Trace(err)
		} else if len(handles) == 0 {
			return nil
		}

		count += int64(len(handles))
		seekHandle = handles[len(handles)-1] + 1
		err = d.backfillTableIndex(t, indexInfo, handles, reorgInfo)
		sub := time.Since(startTS).Seconds()
		if err != nil {
			log.Warnf("[ddl] added index for %v rows failed, take time %v", count, sub)
			return errors.Trace(err)
		}

		job.SetRowCount(count)
		batchHandleDataHistogram.WithLabelValues(batchAddIdx).Observe(sub)
		log.Infof("[ddl] added index for %v rows, take time %v", count, sub)

	}
}
コード例 #2
0
ファイル: reorg.go プロジェクト: jmptrader/tidb
// delKeysWithStartKey deletes keys with start key in a limited number. If limit < 0, deletes all keys.
// It returns the number of rows deleted, next start key and the error.
func (d *ddl) delKeysWithStartKey(prefix, startKey kv.Key, jobType JobType, job *model.Job, limit int) (int, kv.Key, error) {
	limitedDel := limit >= 0

	var count int
	total := job.GetRowCount()
	keys := make([]kv.Key, 0, defaultBatchSize)
	for {
		if limitedDel && count >= limit {
			break
		}
		batch := defaultBatchSize
		if limitedDel && count+batch > limit {
			batch = limit - count
		}
		startTS := time.Now()
		err := kv.RunInNewTxn(d.store, true, func(txn kv.Transaction) error {
			if err1 := d.isReorgRunnable(txn, jobType); err1 != nil {
				return errors.Trace(err1)
			}

			iter, err := txn.Seek(startKey)
			if err != nil {
				return errors.Trace(err)
			}
			defer iter.Close()

			for i := 0; i < batch; i++ {
				if iter.Valid() && iter.Key().HasPrefix(prefix) {
					keys = append(keys, iter.Key().Clone())
					err = iter.Next()
					if err != nil {
						return errors.Trace(err)
					}
				} else {
					break
				}
			}

			for _, key := range keys {
				err := txn.Delete(key)
				// must skip ErrNotExist
				// if key doesn't exist, skip this error.
				if err != nil && !terror.ErrorEqual(err, kv.ErrNotExist) {
					return errors.Trace(err)
				}
			}

			count += len(keys)
			total += int64(len(keys))
			return nil
		})
		sub := time.Since(startTS).Seconds()
		if err != nil {
			log.Warnf("[ddl] deleted %d keys failed, take time %v, deleted %d keys in total", len(keys), sub, total)
			return 0, startKey, errors.Trace(err)
		}

		job.SetRowCount(total)
		batchHandleDataHistogram.WithLabelValues(batchDelData).Observe(sub)
		log.Infof("[ddl] deleted %d keys take time %v, deleted %d keys in total", len(keys), sub, total)

		if len(keys) > 0 {
			startKey = keys[len(keys)-1]
		}

		if noMoreKeysToDelete := len(keys) < batch; noMoreKeysToDelete {
			break
		}

		keys = keys[:0]
	}

	return count, startKey, nil
}