github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/db/checkpoint/replay.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 "sort" 20 "sync" 21 "time" 22 23 "github.com/matrixorigin/matrixone/pkg/common/moerr" 24 "github.com/matrixorigin/matrixone/pkg/container/types" 25 "github.com/matrixorigin/matrixone/pkg/container/vector" 26 "github.com/matrixorigin/matrixone/pkg/logutil" 27 "github.com/matrixorigin/matrixone/pkg/objectio" 28 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/catalog" 29 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common" 30 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers" 31 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/dataio/blockio" 32 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/logtail" 33 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/tasks" 34 ) 35 36 type metaFile struct { 37 index int 38 start types.TS 39 end types.TS 40 } 41 42 func (r *runner) Replay(dataFactory catalog.DataFactory) (maxTs types.TS, err error) { 43 ctx := context.Background() 44 dirs, err := r.fs.ListDir(CheckpointDir) 45 if err != nil { 46 return 47 } 48 if len(dirs) == 0 { 49 return 50 } 51 metaFiles := make([]*metaFile, 0) 52 var readDuration, applyDuration time.Duration 53 for i, dir := range dirs { 54 start, end := blockio.DecodeCheckpointMetadataFileName(dir.Name) 55 metaFiles = append(metaFiles, &metaFile{ 56 start: start, 57 end: end, 58 index: i, 59 }) 60 } 61 sort.Slice(metaFiles, func(i, j int) bool { 62 return metaFiles[i].end.Less(metaFiles[j].end) 63 }) 64 targetIdx := metaFiles[len(metaFiles)-1].index 65 dir := dirs[targetIdx] 66 reader, err := objectio.NewObjectReader(CheckpointDir+dir.Name, r.fs.Service) 67 if err != nil { 68 return 69 } 70 bs, err := reader.ReadAllMeta(ctx, dir.Size, common.DefaultAllocator) 71 if err != nil { 72 return 73 } 74 bat := containers.NewBatch() 75 defer bat.Close() 76 colNames := CheckpointSchema.Attrs() 77 colTypes := CheckpointSchema.Types() 78 nullables := CheckpointSchema.Nullables() 79 t0 := time.Now() 80 for i := range colNames { 81 if bs[0].GetExtent().End() == 0 { 82 continue 83 } 84 col, err2 := bs[0].GetColumn(uint16(i)) 85 if err2 != nil { 86 return types.TS{}, err2 87 } 88 data, err2 := col.GetData(ctx, nil) 89 if err2 != nil { 90 return types.TS{}, err2 91 } 92 pkgVec := vector.New(colTypes[i]) 93 v := make([]byte, len(data.Entries[0].Object.([]byte))) 94 copy(v, data.Entries[0].Object.([]byte)) 95 if err = pkgVec.Read(v); err != nil { 96 return 97 } 98 var vec containers.Vector 99 if pkgVec.Length() == 0 { 100 vec = containers.MakeVector(colTypes[i], nullables[i]) 101 } else { 102 vec = containers.NewVectorWithSharedMemory(pkgVec, nullables[i]) 103 } 104 bat.AddVector(colNames[i], vec) 105 } 106 readDuration += time.Since(t0) 107 datas := make([]*logtail.CheckpointData, bat.Length()) 108 defer func() { 109 for _, data := range datas { 110 if data != nil { 111 data.Close() 112 } 113 } 114 }() 115 116 jobScheduler := tasks.NewParallelJobScheduler(200) 117 defer jobScheduler.Stop() 118 entries := make([]*CheckpointEntry, bat.Length()) 119 emptyFile := make([]*CheckpointEntry, 0) 120 var emptyFileMu sync.RWMutex 121 var wg sync.WaitGroup 122 readfn := func(i int) { 123 defer wg.Done() 124 start := bat.GetVectorByName(CheckpointAttr_StartTS).Get(i).(types.TS) 125 end := bat.GetVectorByName(CheckpointAttr_EndTS).Get(i).(types.TS) 126 metaloc := string(bat.GetVectorByName(CheckpointAttr_MetaLocation).Get(i).([]byte)) 127 isIncremental := bat.GetVectorByName(CheckpointAttr_EntryType).Get(i).(bool) 128 typ := ET_Global 129 if isIncremental { 130 typ = ET_Incremental 131 } 132 checkpointEntry := &CheckpointEntry{ 133 start: start, 134 end: end, 135 location: metaloc, 136 state: ST_Finished, 137 entryType: typ, 138 } 139 var err2 error 140 if datas[i], err2 = checkpointEntry.Read(ctx, jobScheduler, r.fs); err2 != nil { 141 logutil.Warnf("read %v failed: %v", checkpointEntry.String(), err2) 142 emptyFileMu.Lock() 143 emptyFile = append(emptyFile, checkpointEntry) 144 emptyFileMu.Unlock() 145 } else { 146 entries[i] = checkpointEntry 147 } 148 } 149 wg.Add(bat.Length()) 150 t0 = time.Now() 151 for i := 0; i < bat.Length(); i++ { 152 go readfn(i) 153 } 154 wg.Wait() 155 readDuration += time.Since(t0) 156 if err != nil { 157 return 158 } 159 t0 = time.Now() 160 globalIdx := 0 161 for i := 0; i < bat.Length(); i++ { 162 checkpointEntry := entries[i] 163 if checkpointEntry == nil { 164 continue 165 } 166 if !checkpointEntry.IsIncremental() { 167 globalIdx = i 168 r.tryAddNewGlobalCheckpointEntry(checkpointEntry) 169 } else { 170 r.tryAddNewIncrementalCheckpointEntry(checkpointEntry) 171 } 172 } 173 maxGlobal := r.MaxGlobalCheckpoint() 174 if maxGlobal != nil { 175 logutil.Infof("replay checkpoint %v", maxGlobal) 176 err = datas[globalIdx].ApplyReplayTo(r.catalog, dataFactory) 177 if err != nil { 178 return 179 } 180 if maxTs.Less(maxGlobal.end) { 181 maxTs = maxGlobal.end 182 } 183 } 184 for _, e := range emptyFile { 185 if e.end.GreaterEq(maxTs) { 186 return types.TS{}, 187 moerr.NewInternalError(ctx, 188 "read checkpoint %v failed", 189 e.String()) 190 } 191 } 192 for i := 0; i < bat.Length(); i++ { 193 checkpointEntry := entries[i] 194 if checkpointEntry == nil { 195 continue 196 } 197 if checkpointEntry.end.LessEq(maxTs) { 198 continue 199 } 200 logutil.Infof("replay checkpoint %v", checkpointEntry) 201 err = datas[i].ApplyReplayTo(r.catalog, dataFactory) 202 if err != nil { 203 return 204 } 205 if maxTs.Less(checkpointEntry.end) { 206 maxTs = checkpointEntry.end 207 } 208 } 209 applyDuration = time.Since(t0) 210 logutil.Info("open-tae", common.OperationField("replay"), 211 common.OperandField("checkpoint"), 212 common.AnyField("apply cost", applyDuration), 213 common.AnyField("read cost", readDuration)) 214 r.source.Init(maxTs) 215 return 216 }