github.com/matrixorigin/matrixone@v1.2.0/pkg/incrservice/types.go (about)

     1  // Copyright 2023 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package incrservice
    16  
    17  import (
    18  	"context"
    19  
    20  	"github.com/matrixorigin/matrixone/pkg/common/runtime"
    21  	"github.com/matrixorigin/matrixone/pkg/container/batch"
    22  	"github.com/matrixorigin/matrixone/pkg/defines"
    23  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    24  	"github.com/matrixorigin/matrixone/pkg/txn/client"
    25  )
    26  
    27  // GetAutoIncrementService get increment service from process level runtime
    28  func GetAutoIncrementService(ctx context.Context) AutoIncrementService {
    29  	v, ok := runtime.ProcessLevelRuntime().GetGlobalVariables(runtime.AutoIncrementService)
    30  	if !ok {
    31  		return nil
    32  	}
    33  	s := v.(AutoIncrementService)
    34  	uuid, ok := ctx.Value(defines.NodeIDKey{}).(string)
    35  	if !ok || uuid == "" {
    36  		return s
    37  	}
    38  	if s.UUID() != uuid {
    39  		v, ok := runtime.ProcessLevelRuntime().GetGlobalVariables(runtime.AutoIncrementService + "_" + uuid)
    40  		if !ok {
    41  			panic("cannot get the appropriate AutoIncrementService")
    42  		}
    43  		s = v.(AutoIncrementService)
    44  	}
    45  	return s
    46  }
    47  
    48  // SetAutoIncrementServiceByID set auto increment service instance into process level runtime.
    49  func SetAutoIncrementServiceByID(id string, v AutoIncrementService) {
    50  	runtime.ProcessLevelRuntime().SetGlobalVariables(runtime.AutoIncrementService+"_"+id, v)
    51  }
    52  
    53  // AutoIncrementService provides data service for the columns of auto-increment.
    54  // Each CN contains a service instance. Whenever a table containing an auto-increment
    55  // column is created, the service internally creates a data cache for the auto-increment
    56  // column to avoid updating the sequence values of these auto-increment columns each
    57  // time data is inserted.
    58  type AutoIncrementService interface {
    59  	// UUID returns the uuid of this increment service, which comes from CN service.
    60  	UUID() string
    61  	// Create a separate transaction is used to create the cache service and insert records
    62  	// into catalog.AutoIncrTableName before the transaction that created the table is committed.
    63  	// When the transaction that created the table is rolled back, the corresponding records in
    64  	// catalog.AutoIncrTableName are deleted.
    65  	Create(ctx context.Context, tableID uint64, caches []AutoColumn, txn client.TxnOperator) error
    66  	// Reset consists of delete+create, if keep is true, then the new self-incrementing column cache
    67  	// will retain the value of the old cache
    68  	Reset(ctx context.Context, oldTableID, newTableID uint64, keep bool, txn client.TxnOperator) error
    69  	// Delete until the delete table transaction is committed, no operation is performed, only the
    70  	// records to be deleted are recorded. When the delete table transaction is committed, the
    71  	// delete operation is triggered.
    72  	Delete(ctx context.Context, tableID uint64, txn client.TxnOperator) error
    73  	// InsertValues insert auto columns values into bat.
    74  	InsertValues(ctx context.Context, tableID uint64, bat *batch.Batch, estimate int64) (uint64, error)
    75  	// CurrentValue return current incr column value.
    76  	CurrentValue(ctx context.Context, tableID uint64, col string) (uint64, error)
    77  	// Close close the auto increment service
    78  	Close()
    79  }
    80  
    81  // incrTableCache a cache containing auto-incremented columns of a table, an incrCache may
    82  // contain multiple cacheItem, each cacheItem corresponds to a auto-incremented column.
    83  //
    84  // The cache of each column's auto-incrementing column is updated independently, without
    85  // interfering with each other.
    86  //
    87  // The incrCache is created at table creation time and, by design, will be initialized by
    88  // inserting multiple rows to catalog.AutoIncrTableName in the same transaction.
    89  //
    90  // A cacheItem will appear on any CN whenever a CN needs to insert a auto-incrementing
    91  // value. The cacheItem on each CN uses its own independent transaction to modify the
    92  // record corresponding to catalog.AutoIncrTableName to pre-apply a Range cache locally.
    93  // Most of the values for each request for a auto-incrementing column on CN are allocated
    94  // on the local cache until the local cache is allocated.
    95  //
    96  // Once the local cache has been allocated, a transaction needs to be started to go to
    97  // the corresponding record of catalog.AutoIncrTableName and continue to allocate the next
    98  // Range. we certainly don't want this to happen when the value actually needs to be allocated,
    99  // as this would affect write performance.
   100  //
   101  // Each CacheItem will have a low-water alert, and when the margin of the locally cached Range
   102  // falls below this realm, an asynchronous task will be started to advance the allocation of
   103  // the next Range.
   104  //
   105  // In addition to passively assigning the next Range in advance, we are going to need to have
   106  // the ability to actively assign it in advance. Each allocated Range has a size, if the
   107  // allocated Range is not enough to meet the demand of one write, it will cause a delayed
   108  // wait for a write process that needs to go to allocate multiple Ranges. So when the amount
   109  // of data written at one time is particularly large, such as load, you need to actively tell
   110  // the cacheItem the approximate amount of data to be written, to avoid the scenario of multiple
   111  // allocations for one write.
   112  type incrTableCache interface {
   113  	table() uint64
   114  	commit()
   115  	columns() []AutoColumn
   116  	insertAutoValues(ctx context.Context, tableID uint64, bat *batch.Batch, estimate int64) (uint64, error)
   117  	currentValue(ctx context.Context, tableID uint64, col string) (uint64, error)
   118  	close() error
   119  	adjust(ctx context.Context, cols []AutoColumn) error
   120  }
   121  
   122  type valueAllocator interface {
   123  	allocate(ctx context.Context, tableID uint64, col string, count int, txnOp client.TxnOperator) (uint64, uint64, error)
   124  	asyncAllocate(ctx context.Context, tableID uint64, col string, count int, txnOp client.TxnOperator, cb func(uint64, uint64, error)) error
   125  	updateMinValue(ctx context.Context, tableID uint64, col string, minValue uint64, txnOp client.TxnOperator) error
   126  	close()
   127  }
   128  
   129  // IncrValueStore is used to add and delete metadata records for auto-increment columns.
   130  type IncrValueStore interface {
   131  	// Exec new a txn operator, used for debug.
   132  	NewTxnOperator(ctx context.Context) client.TxnOperator
   133  	// SelectAll return all auto increment metadata records from catalog.AutoIncrTableName.
   134  	SelectAll(ctx context.Context, tableID uint64, txnOp client.TxnOperator) (string, error)
   135  	// GetColumns return auto columns of table.
   136  	GetColumns(ctx context.Context, tableID uint64, txnOp client.TxnOperator) ([]AutoColumn, error)
   137  	// Create add metadata records into catalog.AutoIncrTableName.
   138  	Create(ctx context.Context, tableID uint64, cols []AutoColumn, txnOp client.TxnOperator) error
   139  	// Allocate allocate new range for auto-increment column.
   140  	Allocate(ctx context.Context, tableID uint64, col string, count int, txnOp client.TxnOperator) (uint64, uint64, error)
   141  	// UpdateMinValue update auto column min value to specified value.
   142  	UpdateMinValue(ctx context.Context, tableID uint64, col string, minValue uint64, txnOp client.TxnOperator) error
   143  	// Delete remove metadata records from catalog.AutoIncrTableName.
   144  	Delete(ctx context.Context, tableID uint64) error
   145  	// Close the store
   146  	Close()
   147  }
   148  
   149  // AutoColumn model
   150  type AutoColumn struct {
   151  	TableID  uint64
   152  	ColName  string
   153  	ColIndex int
   154  	Offset   uint64
   155  	Step     uint64
   156  }
   157  
   158  // GetAutoColumnFromDef get auto columns from table def
   159  func GetAutoColumnFromDef(def *plan.TableDef) []AutoColumn {
   160  	var cols []AutoColumn
   161  	for i, col := range def.Cols {
   162  		if col.Typ.AutoIncr {
   163  			cols = append(cols, AutoColumn{
   164  				ColName:  col.Name,
   165  				TableID:  def.TblId,
   166  				Step:     1,
   167  				Offset:   def.AutoIncrOffset,
   168  				ColIndex: i,
   169  			})
   170  		}
   171  	}
   172  	return cols
   173  }