github.com/matrixorigin/matrixone@v0.7.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  	"time"
    20  
    21  	"github.com/matrixorigin/matrixone/pkg/container/types"
    22  	"github.com/matrixorigin/matrixone/pkg/logutil"
    23  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers"
    24  )
    25  
    26  type RunnerReader interface {
    27  	GetAllIncrementalCheckpoints() []*CheckpointEntry
    28  	GetAllGlobalCheckpoints() []*CheckpointEntry
    29  	GetPenddingIncrementalCount() int
    30  	GetGlobalCheckpointCount() int
    31  	CollectCheckpointsInRange(ctx context.Context, start, end types.TS) (ckpLoc string, lastEnd types.TS, err error)
    32  	ICKPSeekLT(ts types.TS, cnt int) []*CheckpointEntry
    33  	MaxLSN() uint64
    34  }
    35  
    36  func (r *runner) collectCheckpointMetadata(start, end types.TS) *containers.Batch {
    37  	bat := makeRespBatchFromSchema(CheckpointSchema)
    38  	entries := r.GetAllIncrementalCheckpoints()
    39  	for _, entry := range entries {
    40  		if !entry.IsFinished() && !entry.end.Equal(end) {
    41  			continue
    42  		}
    43  		bat.GetVectorByName(CheckpointAttr_StartTS).Append(entry.start)
    44  		bat.GetVectorByName(CheckpointAttr_EndTS).Append(entry.end)
    45  		bat.GetVectorByName(CheckpointAttr_MetaLocation).Append([]byte(entry.GetLocation()))
    46  		bat.GetVectorByName(CheckpointAttr_EntryType).Append(true)
    47  	}
    48  	entries = r.GetAllGlobalCheckpoints()
    49  	for _, entry := range entries {
    50  		if !entry.IsFinished() && !entry.end.Equal(end) {
    51  			continue
    52  		}
    53  		bat.GetVectorByName(CheckpointAttr_StartTS).Append(entry.start)
    54  		bat.GetVectorByName(CheckpointAttr_EndTS).Append(entry.end)
    55  		bat.GetVectorByName(CheckpointAttr_MetaLocation).Append([]byte(entry.GetLocation()))
    56  		bat.GetVectorByName(CheckpointAttr_EntryType).Append(false)
    57  	}
    58  	return bat
    59  }
    60  func (r *runner) GetAllIncrementalCheckpoints() []*CheckpointEntry {
    61  	r.storage.Lock()
    62  	snapshot := r.storage.entries.Copy()
    63  	r.storage.Unlock()
    64  	return snapshot.Items()
    65  }
    66  func (r *runner) GetAllGlobalCheckpoints() []*CheckpointEntry {
    67  	r.storage.Lock()
    68  	snapshot := r.storage.globals.Copy()
    69  	r.storage.Unlock()
    70  	return snapshot.Items()
    71  }
    72  func (r *runner) MaxLSN() uint64 {
    73  	endTs := types.BuildTS(time.Now().UTC().UnixNano(), 0)
    74  	return r.source.GetMaxLSN(types.TS{}, endTs)
    75  }
    76  func (r *runner) MaxLSNInRange(end types.TS) uint64 {
    77  	return r.source.GetMaxLSN(types.TS{}, end)
    78  }
    79  
    80  func (r *runner) MaxGlobalCheckpoint() *CheckpointEntry {
    81  	r.storage.RLock()
    82  	defer r.storage.RUnlock()
    83  	global, _ := r.storage.globals.Max()
    84  	return global
    85  }
    86  
    87  func (r *runner) MaxCheckpoint() *CheckpointEntry {
    88  	r.storage.RLock()
    89  	defer r.storage.RUnlock()
    90  	entry, _ := r.storage.entries.Max()
    91  	return entry
    92  }
    93  
    94  func (r *runner) ICKPSeekLT(ts types.TS, cnt int) []*CheckpointEntry {
    95  	r.storage.Lock()
    96  	tree := r.storage.entries.Copy()
    97  	r.storage.Unlock()
    98  	it := tree.Iter()
    99  	ok := it.Seek(NewCheckpointEntry(ts, ts, ET_Incremental))
   100  	incrementals := make([]*CheckpointEntry, 0)
   101  	if ok {
   102  		for len(incrementals) < cnt {
   103  			e := it.Item()
   104  			if !e.IsFinished() {
   105  				break
   106  			}
   107  			if e.start.Less(ts) {
   108  				if !it.Next() {
   109  					break
   110  				}
   111  				continue
   112  			}
   113  			incrementals = append(incrementals, e)
   114  			if !it.Next() {
   115  				break
   116  			}
   117  		}
   118  	}
   119  	return incrementals
   120  }
   121  
   122  func (r *runner) GetPenddingIncrementalCount() int {
   123  	entries := r.GetAllIncrementalCheckpoints()
   124  	global := r.MaxGlobalCheckpoint()
   125  
   126  	count := 0
   127  	for i := len(entries) - 1; i >= 0; i-- {
   128  		if global != nil && entries[i].end.LessEq(global.end) {
   129  			break
   130  		}
   131  		if !entries[i].IsFinished() {
   132  			continue
   133  		}
   134  		count++
   135  	}
   136  	return count
   137  }
   138  
   139  func (r *runner) GetGlobalCheckpointCount() int {
   140  	r.storage.RLock()
   141  	defer r.storage.RUnlock()
   142  	return r.storage.globals.Len()
   143  }
   144  
   145  func (r *runner) GCByTS(ctx context.Context, ts types.TS) error {
   146  	prev := r.gcTS.Load()
   147  	if prev == nil {
   148  		r.gcTS.Store(ts)
   149  	} else {
   150  		prevTS := prev.(types.TS)
   151  		if prevTS.Less(ts) {
   152  			r.gcTS.Store(ts)
   153  		}
   154  	}
   155  	logutil.Infof("GC %v", ts.ToString())
   156  	r.gcCheckpointQueue.Enqueue(struct{}{})
   157  	return nil
   158  }
   159  
   160  func (r *runner) getGCTS() types.TS {
   161  	prev := r.gcTS.Load()
   162  	if prev == nil {
   163  		return types.TS{}
   164  	}
   165  	return prev.(types.TS)
   166  }
   167  
   168  func (r *runner) getGCedTS() types.TS {
   169  	r.storage.RLock()
   170  	minGlobal, _ := r.storage.globals.Min()
   171  	minIncremental, _ := r.storage.entries.Min()
   172  	r.storage.RUnlock()
   173  	if minGlobal == nil {
   174  		return types.TS{}
   175  	}
   176  	if minIncremental == nil {
   177  		return minGlobal.end
   178  	}
   179  	if minIncremental.start.GreaterEq(minGlobal.end) {
   180  		return minGlobal.end
   181  	}
   182  	return minIncremental.start
   183  }
   184  
   185  func (r *runner) getTSToGC() types.TS {
   186  	maxGlobal := r.MaxGlobalCheckpoint()
   187  	if maxGlobal == nil {
   188  		return types.TS{}
   189  	}
   190  	if maxGlobal.IsFinished() {
   191  		return maxGlobal.end.Prev()
   192  	}
   193  	globals := r.GetAllGlobalCheckpoints()
   194  	if len(globals) == 1 {
   195  		return types.TS{}
   196  	}
   197  	maxGlobal = globals[len(globals)-1]
   198  	return maxGlobal.end.Prev()
   199  }
   200  
   201  func (r *runner) ExistPendingEntryToGC() bool {
   202  	_, needGC := r.getTSTOGC()
   203  	return needGC
   204  }
   205  
   206  func (r *runner) IsTSStale(ts types.TS) bool {
   207  	gcts := r.getGCTS()
   208  	if gcts.IsEmpty() {
   209  		return false
   210  	}
   211  	minValidTS := gcts.Physical() - r.options.globalVersionInterval.Nanoseconds()
   212  	return ts.Physical() < minValidTS
   213  }