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  }