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 }