github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/db/checkpoint/entry.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  	"fmt"
    20  	"sync"
    21  	"time"
    22  
    23  	"github.com/matrixorigin/matrixone/pkg/container/types"
    24  	"github.com/matrixorigin/matrixone/pkg/logutil"
    25  	"github.com/matrixorigin/matrixone/pkg/objectio"
    26  	"github.com/matrixorigin/matrixone/pkg/pb/api"
    27  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/catalog"
    28  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common"
    29  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/dataio/blockio"
    30  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/logtail"
    31  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/tasks"
    32  )
    33  
    34  type CheckpointEntry struct {
    35  	sync.RWMutex
    36  	start, end types.TS
    37  	state      State
    38  	entryType  EntryType
    39  	location   string
    40  }
    41  
    42  func NewCheckpointEntry(start, end types.TS, typ EntryType) *CheckpointEntry {
    43  	return &CheckpointEntry{
    44  		start:     start,
    45  		end:       end,
    46  		state:     ST_Pending,
    47  		entryType: typ,
    48  	}
    49  }
    50  
    51  func (e *CheckpointEntry) GetStart() types.TS { return e.start }
    52  func (e *CheckpointEntry) GetEnd() types.TS   { return e.end }
    53  func (e *CheckpointEntry) GetState() State {
    54  	e.RLock()
    55  	defer e.RUnlock()
    56  	return e.state
    57  }
    58  func (e *CheckpointEntry) IsCommitted() bool {
    59  	e.RLock()
    60  	defer e.RUnlock()
    61  	return e.state == ST_Finished
    62  }
    63  func (e *CheckpointEntry) HasOverlap(from, to types.TS) bool {
    64  	if e.start.Greater(to) || e.end.Less(from) {
    65  		return false
    66  	}
    67  	return true
    68  }
    69  func (e *CheckpointEntry) LessEq(ts types.TS) bool {
    70  	return e.end.LessEq(ts)
    71  }
    72  func (e *CheckpointEntry) SetLocation(location string) {
    73  	e.Lock()
    74  	defer e.Unlock()
    75  	e.location = location
    76  }
    77  
    78  func (e *CheckpointEntry) GetLocation() string {
    79  	e.RLock()
    80  	defer e.RUnlock()
    81  	return e.location
    82  }
    83  
    84  func (e *CheckpointEntry) SetState(state State) (ok bool) {
    85  	e.Lock()
    86  	defer e.Unlock()
    87  	// entry is already finished
    88  	if e.state == ST_Finished {
    89  		return
    90  	}
    91  	// entry is already running
    92  	if state == ST_Running && e.state == ST_Running {
    93  		return
    94  	}
    95  	e.state = state
    96  	ok = true
    97  	return
    98  }
    99  
   100  func (e *CheckpointEntry) IsRunning() bool {
   101  	e.RLock()
   102  	defer e.RUnlock()
   103  	return e.state == ST_Running
   104  }
   105  func (e *CheckpointEntry) IsPendding() bool {
   106  	e.RLock()
   107  	defer e.RUnlock()
   108  	return e.state == ST_Pending
   109  }
   110  func (e *CheckpointEntry) IsFinished() bool {
   111  	e.RLock()
   112  	defer e.RUnlock()
   113  	return e.state == ST_Finished
   114  }
   115  
   116  func (e *CheckpointEntry) IsIncremental() bool {
   117  	return e.entryType == ET_Incremental
   118  }
   119  
   120  func (e *CheckpointEntry) String() string {
   121  	t := "I"
   122  	if !e.IsIncremental() {
   123  		t = "G"
   124  	}
   125  	state := e.GetState()
   126  	return fmt.Sprintf("CKP[%s][%v](%s->%s)", t, state, e.start.ToString(), e.end.ToString())
   127  }
   128  
   129  func (e *CheckpointEntry) Replay(
   130  	ctx context.Context,
   131  	c *catalog.Catalog,
   132  	fs *objectio.ObjectFS,
   133  	dataFactory catalog.DataFactory) (readDuration, applyDuration time.Duration, err error) {
   134  	reader, err := blockio.NewCheckpointReader(ctx, fs.Service, e.location)
   135  	if err != nil {
   136  		return
   137  	}
   138  
   139  	data := logtail.NewCheckpointData()
   140  	defer data.Close()
   141  	t0 := time.Now()
   142  	if err = data.ReadFrom(reader, nil, common.DefaultAllocator); err != nil {
   143  		return
   144  	}
   145  	readDuration = time.Since(t0)
   146  	t0 = time.Now()
   147  	err = data.ApplyReplayTo(c, dataFactory)
   148  	applyDuration = time.Since(t0)
   149  	return
   150  }
   151  func (e *CheckpointEntry) Read(
   152  	ctx context.Context,
   153  	scheduler tasks.JobScheduler,
   154  	fs *objectio.ObjectFS,
   155  ) (data *logtail.CheckpointData, err error) {
   156  	reader, err := blockio.NewCheckpointReader(ctx, fs.Service, e.location)
   157  	if err != nil {
   158  		return
   159  	}
   160  
   161  	data = logtail.NewCheckpointData()
   162  	if err = data.ReadFrom(
   163  		reader,
   164  		scheduler,
   165  		common.DefaultAllocator,
   166  	); err != nil {
   167  		return
   168  	}
   169  	return
   170  }
   171  func (e *CheckpointEntry) GetByTableID(fs *objectio.ObjectFS, tid uint64) (ins, del, cnIns *api.Batch, err error) {
   172  	reader, err := blockio.NewCheckpointReader(context.Background(), fs.Service, e.location)
   173  	if err != nil {
   174  		return
   175  	}
   176  	data := logtail.NewCheckpointData()
   177  	defer data.Close()
   178  	if err = data.ReadFrom(reader, nil, common.DefaultAllocator); err != nil {
   179  		return
   180  	}
   181  	ins, del, cnIns, err = data.GetTableData(tid)
   182  	return
   183  }
   184  
   185  func (e *CheckpointEntry) GCMetadata(fs *objectio.ObjectFS) error {
   186  	name := blockio.EncodeCheckpointMetadataFileName(CheckpointDir, PrefixMetadata, e.start, e.end)
   187  	err := fs.Delete(name)
   188  	logutil.Infof("GC checkpoint metadata %v, err %v", e.String(), err)
   189  	return err
   190  }
   191  
   192  func (e *CheckpointEntry) GCEntry(fs *objectio.ObjectFS) error {
   193  	fileName, _, err := blockio.DecodeMetaLocToMetas(e.location)
   194  	defer logutil.Infof("GC checkpoint metadata %v, err %v", e.String(), err)
   195  	if err != nil {
   196  		return err
   197  	}
   198  	return fs.Delete(fileName)
   199  }