github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/gcjob/index_garbage_collection.go (about)

     1  // Copyright 2020 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package gcjob
    12  
    13  import (
    14  	"context"
    15  
    16  	"github.com/cockroachdb/cockroach/pkg/jobs/jobspb"
    17  	"github.com/cockroachdb/cockroach/pkg/kv"
    18  	"github.com/cockroachdb/cockroach/pkg/roachpb"
    19  	"github.com/cockroachdb/cockroach/pkg/sql"
    20  	"github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
    21  	"github.com/cockroachdb/cockroach/pkg/util/log"
    22  	"github.com/cockroachdb/errors"
    23  )
    24  
    25  // gcIndexes find the indexes that need to be GC'd, GC's them, and then updates
    26  // the cleans up the table descriptor, zone configs and job payload to indicate
    27  // the work that it did.
    28  func gcIndexes(
    29  	ctx context.Context,
    30  	execCfg *sql.ExecutorConfig,
    31  	parentID sqlbase.ID,
    32  	progress *jobspb.SchemaChangeGCProgress,
    33  ) (bool, error) {
    34  	didGC := false
    35  	droppedIndexes := progress.Indexes
    36  	if log.V(2) {
    37  		log.Infof(ctx, "GC is being considered on table %d for indexes indexes: %+v", parentID, droppedIndexes)
    38  	}
    39  
    40  	var parentTable *sqlbase.TableDescriptor
    41  	if err := execCfg.DB.Txn(ctx, func(ctx context.Context, txn *kv.Txn) error {
    42  		var err error
    43  		parentTable, err = sqlbase.GetTableDescFromID(ctx, txn, execCfg.Codec, parentID)
    44  		return err
    45  	}); err != nil {
    46  		return false, errors.Wrapf(err, "fetching parent table %d", parentID)
    47  	}
    48  
    49  	for _, index := range droppedIndexes {
    50  		if index.Status != jobspb.SchemaChangeGCProgress_DELETING {
    51  			continue
    52  		}
    53  
    54  		indexDesc := sqlbase.IndexDescriptor{ID: index.IndexID}
    55  		if err := clearIndex(ctx, execCfg, parentTable, indexDesc); err != nil {
    56  			return false, errors.Wrapf(err, "clearing index %d", indexDesc.ID)
    57  		}
    58  
    59  		// All the data chunks have been removed. Now also removed the
    60  		// zone configs for the dropped indexes, if any.
    61  		if err := execCfg.DB.Txn(ctx, func(ctx context.Context, txn *kv.Txn) error {
    62  			return sql.RemoveIndexZoneConfigs(ctx, txn, execCfg, parentTable.GetID(), []sqlbase.IndexDescriptor{indexDesc})
    63  		}); err != nil {
    64  			return false, errors.Wrapf(err, "removing index %d zone configs", indexDesc.ID)
    65  		}
    66  
    67  		if err := completeDroppedIndex(ctx, execCfg, parentTable, index.IndexID, progress); err != nil {
    68  			return false, err
    69  		}
    70  
    71  		didGC = true
    72  	}
    73  
    74  	return didGC, nil
    75  }
    76  
    77  // clearIndexes issues Clear Range requests over all specified indexes.
    78  func clearIndex(
    79  	ctx context.Context,
    80  	execCfg *sql.ExecutorConfig,
    81  	tableDesc *sqlbase.TableDescriptor,
    82  	index sqlbase.IndexDescriptor,
    83  ) error {
    84  	log.Infof(ctx, "clearing index %d from table %d", index.ID, tableDesc.ID)
    85  	if index.IsInterleaved() {
    86  		return errors.Errorf("unexpected interleaved index %d", index.ID)
    87  	}
    88  
    89  	sp := tableDesc.IndexSpan(execCfg.Codec, index.ID)
    90  
    91  	// ClearRange cannot be run in a transaction, so create a
    92  	// non-transactional batch to send the request.
    93  	b := &kv.Batch{}
    94  	b.AddRawRequest(&roachpb.ClearRangeRequest{
    95  		RequestHeader: roachpb.RequestHeader{
    96  			Key:    sp.Key,
    97  			EndKey: sp.EndKey,
    98  		},
    99  	})
   100  	return execCfg.DB.Run(ctx, b)
   101  }
   102  
   103  // completeDroppedIndexes updates the mutations of the table descriptor to
   104  // indicate that the index was dropped, as well as the job detail payload.
   105  func completeDroppedIndex(
   106  	ctx context.Context,
   107  	execCfg *sql.ExecutorConfig,
   108  	table *sqlbase.TableDescriptor,
   109  	indexID sqlbase.IndexID,
   110  	progress *jobspb.SchemaChangeGCProgress,
   111  ) error {
   112  	if err := updateDescriptorGCMutations(ctx, execCfg, table, indexID); err != nil {
   113  		return errors.Wrapf(err, "updating GC mutations")
   114  	}
   115  
   116  	markIndexGCed(ctx, indexID, progress)
   117  
   118  	return nil
   119  }