github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/db/checkpoint/info.go (about) 1 // Copyright 2021 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 checkpoint 16 17 import ( 18 "context" 19 "github.com/matrixorigin/matrixone/pkg/container/types" 20 "github.com/matrixorigin/matrixone/pkg/logutil" 21 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers" 22 "time" 23 ) 24 25 type RunnerReader interface { 26 GetAllIncrementalCheckpoints() []*CheckpointEntry 27 GetAllGlobalCheckpoints() []*CheckpointEntry 28 GetPenddingIncrementalCount() int 29 GetGlobalCheckpointCount() int 30 CollectCheckpointsInRange(ctx context.Context, start, end types.TS) (ckpLoc string, lastEnd types.TS, err error) 31 ICKPSeekLT(ts types.TS, cnt int) []*CheckpointEntry 32 MaxGlobalCheckpoint() *CheckpointEntry 33 GetStage() types.TS 34 MaxLSN() uint64 35 } 36 37 func (r *runner) collectCheckpointMetadata(start, end types.TS, ckpLSN, truncateLSN uint64) *containers.Batch { 38 bat := makeRespBatchFromSchema(CheckpointSchema) 39 entries := r.GetAllIncrementalCheckpoints() 40 for _, entry := range entries { 41 if !entry.IsFinished() && !entry.end.Equal(&end) { 42 continue 43 } 44 bat.GetVectorByName(CheckpointAttr_StartTS).Append(entry.start, false) 45 bat.GetVectorByName(CheckpointAttr_EndTS).Append(entry.end, false) 46 bat.GetVectorByName(CheckpointAttr_MetaLocation).Append([]byte(entry.GetLocation()), false) 47 bat.GetVectorByName(CheckpointAttr_EntryType).Append(true, false) 48 bat.GetVectorByName(CheckpointAttr_Version).Append(entry.version, false) 49 bat.GetVectorByName(CheckpointAttr_AllLocations).Append([]byte(entry.tnLocation), false) 50 bat.GetVectorByName(CheckpointAttr_CheckpointLSN).Append(entry.ckpLSN, false) 51 bat.GetVectorByName(CheckpointAttr_TruncateLSN).Append(entry.truncateLSN, false) 52 bat.GetVectorByName(CheckpointAttr_Type).Append(int8(ET_Incremental), false) 53 } 54 entries = r.GetAllGlobalCheckpoints() 55 for _, entry := range entries { 56 if !entry.IsFinished() && !entry.end.Equal(&end) { 57 continue 58 } 59 bat.GetVectorByName(CheckpointAttr_StartTS).Append(entry.start, false) 60 bat.GetVectorByName(CheckpointAttr_EndTS).Append(entry.end, false) 61 bat.GetVectorByName(CheckpointAttr_MetaLocation).Append([]byte(entry.GetLocation()), false) 62 bat.GetVectorByName(CheckpointAttr_EntryType).Append(false, false) 63 bat.GetVectorByName(CheckpointAttr_Version).Append(entry.version, false) 64 bat.GetVectorByName(CheckpointAttr_AllLocations).Append([]byte(entry.tnLocation), false) 65 bat.GetVectorByName(CheckpointAttr_CheckpointLSN).Append(entry.ckpLSN, false) 66 bat.GetVectorByName(CheckpointAttr_TruncateLSN).Append(entry.truncateLSN, false) 67 bat.GetVectorByName(CheckpointAttr_Type).Append(int8(ET_Global), false) 68 } 69 return bat 70 } 71 func (r *runner) GetAllIncrementalCheckpoints() []*CheckpointEntry { 72 r.storage.Lock() 73 snapshot := r.storage.entries.Copy() 74 r.storage.Unlock() 75 return snapshot.Items() 76 } 77 func (r *runner) GetAllGlobalCheckpoints() []*CheckpointEntry { 78 r.storage.Lock() 79 snapshot := r.storage.globals.Copy() 80 r.storage.Unlock() 81 return snapshot.Items() 82 } 83 func (r *runner) MaxLSN() uint64 { 84 endTs := types.BuildTS(time.Now().UTC().UnixNano(), 0) 85 return r.source.GetMaxLSN(types.TS{}, endTs) 86 } 87 func (r *runner) MaxLSNInRange(end types.TS) uint64 { 88 return r.source.GetMaxLSN(types.TS{}, end) 89 } 90 91 func (r *runner) MaxGlobalCheckpoint() *CheckpointEntry { 92 r.storage.RLock() 93 defer r.storage.RUnlock() 94 global, _ := r.storage.globals.Max() 95 return global 96 } 97 98 func (r *runner) MaxCheckpoint() *CheckpointEntry { 99 r.storage.RLock() 100 defer r.storage.RUnlock() 101 entry, _ := r.storage.entries.Max() 102 return entry 103 } 104 105 func (r *runner) ICKPSeekLT(ts types.TS, cnt int) []*CheckpointEntry { 106 r.storage.Lock() 107 tree := r.storage.entries.Copy() 108 r.storage.Unlock() 109 it := tree.Iter() 110 ok := it.Seek(NewCheckpointEntry(ts, ts, ET_Incremental)) 111 incrementals := make([]*CheckpointEntry, 0) 112 if ok { 113 for len(incrementals) < cnt { 114 e := it.Item() 115 if !e.IsFinished() { 116 break 117 } 118 if e.start.Less(&ts) { 119 if !it.Next() { 120 break 121 } 122 continue 123 } 124 incrementals = append(incrementals, e) 125 if !it.Next() { 126 break 127 } 128 } 129 } 130 return incrementals 131 } 132 133 func (r *runner) GetStage() types.TS { 134 r.storage.RLock() 135 defer r.storage.RUnlock() 136 global, okG := r.storage.globals.Min() 137 incremental, okI := r.storage.entries.Min() 138 if !okG && !okI { 139 return types.TS{} 140 } 141 if !okG { 142 return incremental.start 143 } 144 if !okI { 145 return global.start 146 } 147 if global.end.Less(&incremental.start) { 148 return global.end 149 } 150 return incremental.start 151 } 152 153 func (r *runner) GetPenddingIncrementalCount() int { 154 entries := r.GetAllIncrementalCheckpoints() 155 global := r.MaxGlobalCheckpoint() 156 157 count := 0 158 for i := len(entries) - 1; i >= 0; i-- { 159 if global != nil && entries[i].end.LessEq(&global.end) { 160 break 161 } 162 if !entries[i].IsFinished() { 163 continue 164 } 165 count++ 166 } 167 return count 168 } 169 170 func (r *runner) GetGlobalCheckpointCount() int { 171 r.storage.RLock() 172 defer r.storage.RUnlock() 173 return r.storage.globals.Len() 174 } 175 176 func (r *runner) getLastFinishedGlobalCheckpointLocked() *CheckpointEntry { 177 g, ok := r.storage.globals.Max() 178 if !ok { 179 return nil 180 } 181 if g.IsFinished() { 182 return g 183 } 184 it := r.storage.globals.Iter() 185 it.Seek(g) 186 defer it.Release() 187 if !it.Prev() { 188 return nil 189 } 190 return it.Item() 191 } 192 193 func (r *runner) GetAllCheckpoints() []*CheckpointEntry { 194 ckps := make([]*CheckpointEntry, 0) 195 var ts types.TS 196 r.storage.Lock() 197 g := r.getLastFinishedGlobalCheckpointLocked() 198 tree := r.storage.entries.Copy() 199 r.storage.Unlock() 200 if g != nil { 201 ts = g.GetEnd() 202 ckps = append(ckps, g) 203 } 204 pivot := NewCheckpointEntry(ts.Next(), ts.Next(), ET_Incremental) 205 iter := tree.Iter() 206 defer iter.Release() 207 if ok := iter.Seek(pivot); ok { 208 for { 209 e := iter.Item() 210 if !e.IsFinished() { 211 break 212 } 213 ckps = append(ckps, e) 214 if !iter.Next() { 215 break 216 } 217 } 218 } 219 return ckps 220 } 221 222 func (r *runner) GCByTS(ctx context.Context, ts types.TS) error { 223 prev := r.gcTS.Load() 224 if prev == nil { 225 r.gcTS.Store(ts) 226 } else { 227 prevTS := prev.(types.TS) 228 if prevTS.Less(&ts) { 229 r.gcTS.Store(ts) 230 } 231 } 232 logutil.Debugf("GC %v", ts.ToString()) 233 r.gcCheckpointQueue.Enqueue(struct{}{}) 234 return nil 235 } 236 237 func (r *runner) getGCTS() types.TS { 238 prev := r.gcTS.Load() 239 if prev == nil { 240 return types.TS{} 241 } 242 return prev.(types.TS) 243 } 244 245 func (r *runner) getGCedTS() types.TS { 246 r.storage.RLock() 247 minGlobal, _ := r.storage.globals.Min() 248 minIncremental, _ := r.storage.entries.Min() 249 r.storage.RUnlock() 250 if minGlobal == nil { 251 return types.TS{} 252 } 253 if minIncremental == nil { 254 return minGlobal.end 255 } 256 if minIncremental.start.GreaterEq(&minGlobal.end) { 257 return minGlobal.end 258 } 259 return minIncremental.start 260 } 261 262 func (r *runner) getTSToGC() types.TS { 263 maxGlobal := r.MaxGlobalCheckpoint() 264 if maxGlobal == nil { 265 return types.TS{} 266 } 267 if maxGlobal.IsFinished() { 268 return maxGlobal.end.Prev() 269 } 270 globals := r.GetAllGlobalCheckpoints() 271 if len(globals) == 1 { 272 return types.TS{} 273 } 274 maxGlobal = globals[len(globals)-1] 275 return maxGlobal.end.Prev() 276 } 277 278 func (r *runner) ExistPendingEntryToGC() bool { 279 _, needGC := r.getTSTOGC() 280 return needGC 281 } 282 283 func (r *runner) IsTSStale(ts types.TS) bool { 284 gcts := r.getGCTS() 285 if gcts.IsEmpty() { 286 return false 287 } 288 minValidTS := gcts.Physical() - r.options.globalVersionInterval.Nanoseconds() 289 return ts.Physical() < minValidTS 290 }