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 }