github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/db/open.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 db 16 17 import ( 18 "context" 19 "path" 20 "sync/atomic" 21 "time" 22 23 "github.com/matrixorigin/matrixone/pkg/container/types" 24 gc2 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/db/gc" 25 26 "github.com/matrixorigin/matrixone/pkg/logutil" 27 "github.com/matrixorigin/matrixone/pkg/objectio" 28 29 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common" 30 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/gc" 31 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/logtail" 32 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/model" 33 34 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/buffer" 35 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/catalog" 36 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/db/checkpoint" 37 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/options" 38 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/tables" 39 w "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/tasks/worker" 40 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/txn/txnbase" 41 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/txn/txnimpl" 42 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/wal" 43 ) 44 45 const ( 46 WALDir = "wal" 47 CATALOGDir = "catalog" 48 ) 49 50 func Open(dirname string, opts *options.Options) (db *DB, err error) { 51 dbLocker, err := createDBLock(dirname) 52 53 logutil.Info("open-tae", common.OperationField("Start"), 54 common.OperandField("open")) 55 totalTime := time.Now() 56 57 if err != nil { 58 return nil, err 59 } 60 defer func() { 61 if dbLocker != nil { 62 dbLocker.Close() 63 } 64 logutil.Info("open-tae", common.OperationField("End"), 65 common.OperandField("open"), 66 common.AnyField("cost", time.Since(totalTime)), 67 common.AnyField("err", err)) 68 }() 69 70 opts = opts.FillDefaults(dirname) 71 72 mutBufMgr := buffer.NewNodeManager(opts.CacheCfg.InsertCapacity, nil) 73 txnBufMgr := buffer.NewNodeManager(opts.CacheCfg.TxnCapacity, nil) 74 75 serviceDir := path.Join(dirname, "data") 76 if opts.Fs == nil { 77 // TODO:fileservice needs to be passed in as a parameter 78 opts.Fs = objectio.TmpNewFileservice(path.Join(dirname, "data")) 79 } 80 fs := objectio.NewObjectFS(opts.Fs, serviceDir) 81 82 db = &DB{ 83 Dir: dirname, 84 Opts: opts, 85 MTBufMgr: mutBufMgr, 86 TxnBufMgr: txnBufMgr, 87 Fs: fs, 88 Closed: new(atomic.Value), 89 } 90 91 switch opts.LogStoreT { 92 case options.LogstoreBatchStore: 93 db.Wal = wal.NewDriverWithBatchStore(dirname, WALDir, nil) 94 case options.LogstoreLogservice: 95 db.Wal = wal.NewDriverWithLogservice(opts.Lc) 96 } 97 db.Scheduler = newTaskScheduler(db, db.Opts.SchedulerCfg.AsyncWorkers, db.Opts.SchedulerCfg.IOWorkers) 98 dataFactory := tables.NewDataFactory( 99 db.Fs, mutBufMgr, db.Scheduler, db.Dir) 100 if db.Opts.Catalog, err = catalog.OpenCatalog(db.Scheduler, dataFactory); err != nil { 101 return 102 } 103 db.Catalog = db.Opts.Catalog 104 105 // Init and start txn manager 106 db.TransferTable = model.NewTransferTable[*model.TransferHashPage](db.Opts.TransferTableTTL) 107 txnStoreFactory := txnimpl.TxnStoreFactory( 108 db.Opts.Catalog, 109 db.Wal, 110 db.TransferTable, 111 txnBufMgr, 112 dataFactory) 113 txnFactory := txnimpl.TxnFactory(db.Opts.Catalog) 114 db.TxnMgr = txnbase.NewTxnManager(txnStoreFactory, txnFactory, db.Opts.Clock) 115 db.LogtailMgr = logtail.NewManager( 116 int(db.Opts.LogtailCfg.PageSize), 117 db.Opts.Clock, 118 ) 119 db.TxnMgr.CommitListener.AddTxnCommitListener(db.LogtailMgr) 120 db.TxnMgr.Start() 121 db.BGCheckpointRunner = checkpoint.NewRunner( 122 db.Fs, 123 db.Catalog, 124 db.Scheduler, 125 logtail.NewDirtyCollector(db.LogtailMgr, db.Opts.Clock, db.Catalog, new(catalog.LoopProcessor)), 126 db.Wal, 127 checkpoint.WithFlushInterval(opts.CheckpointCfg.FlushInterval), 128 checkpoint.WithCollectInterval(opts.CheckpointCfg.ScanInterval), 129 checkpoint.WithMinCount(int(opts.CheckpointCfg.MinCount)), 130 checkpoint.WithMinIncrementalInterval(opts.CheckpointCfg.IncrementalInterval), 131 checkpoint.WithGlobalMinCount(int(opts.CheckpointCfg.GlobalMinCount)), 132 checkpoint.WithGlobalVersionInterval(opts.CheckpointCfg.GlobalVersionInterval)) 133 134 now := time.Now() 135 checkpointed, err := db.BGCheckpointRunner.Replay(dataFactory) 136 if err != nil { 137 panic(err) 138 } 139 logutil.Info("open-tae", common.OperationField("replay"), 140 common.OperandField("checkpoints"), 141 common.AnyField("cost", time.Since(now)), 142 common.AnyField("checkpointed", checkpointed.ToString())) 143 144 now = time.Now() 145 db.Replay(dataFactory, checkpointed) 146 db.Catalog.ReplayTableRows() 147 logutil.Info("open-tae", common.OperationField("replay"), 148 common.OperandField("wal"), 149 common.AnyField("cost", time.Since(now))) 150 151 db.DBLocker, dbLocker = dbLocker, nil 152 153 // Init timed scanner 154 scanner := NewDBScanner(db, nil) 155 mergeOp := newMergeTaskBuiler(db) 156 scanner.RegisterOp(mergeOp) 157 db.Wal.Start() 158 db.BGCheckpointRunner.Start() 159 160 db.BGScanner = w.NewHeartBeater( 161 opts.CheckpointCfg.ScanInterval, 162 scanner) 163 db.BGScanner.Start() 164 // TODO: WithGCInterval requires configuration parameters 165 db.DiskCleaner = gc2.NewDiskCleaner(db.Fs, db.BGCheckpointRunner, db.Catalog) 166 db.DiskCleaner.Start() 167 db.DiskCleaner.AddChecker( 168 func(item any) bool { 169 checkpoint := item.(*checkpoint.CheckpointEntry) 170 ts := types.BuildTS(time.Now().UTC().UnixNano()-int64(opts.GCCfg.GCTTL), 0) 171 return !checkpoint.GetEnd().GreaterEq(ts) 172 }) 173 // Init gc manager at last 174 // TODO: clean-try-gc requires configuration parameters 175 db.GCManager = gc.NewManager( 176 gc.WithCronJob( 177 "clean-transfer-table", 178 opts.CheckpointCfg.FlushInterval, 179 func(_ context.Context) (err error) { 180 db.TransferTable.RunTTL(time.Now()) 181 return 182 }), 183 184 gc.WithCronJob( 185 "disk-gc", 186 opts.GCCfg.ScanGCInterval, 187 func(ctx context.Context) (err error) { 188 db.DiskCleaner.GC(ctx) 189 return 190 }), 191 gc.WithCronJob( 192 "checkpoint-gc", 193 opts.CheckpointCfg.GCCheckpointInterval, 194 func(ctx context.Context) error { 195 if opts.CheckpointCfg.DisableGCCheckpoint { 196 return nil 197 } 198 consumed := db.DiskCleaner.GetMaxConsumed() 199 if consumed == nil { 200 return nil 201 } 202 return db.BGCheckpointRunner.GCByTS(ctx, consumed.GetEnd()) 203 }), 204 gc.WithCronJob( 205 "catalog-gc", 206 opts.CatalogCfg.GCInterval, 207 func(ctx context.Context) error { 208 // if opts.CatalogCfg.DisableGC { 209 // return nil 210 // } 211 // consumed := db.DiskCleaner.GetMaxConsumed() 212 // if consumed == nil { 213 // return nil 214 // } 215 // db.Catalog.GCByTS(ctx, consumed.GetEnd()) 216 return nil 217 }), 218 gc.WithCronJob( 219 "logtail-gc", 220 opts.CheckpointCfg.GCCheckpointInterval, 221 func(ctx context.Context) error { 222 global := db.BGCheckpointRunner.MaxGlobalCheckpoint() 223 if global != nil { 224 db.LogtailMgr.GCByTS(ctx, global.GetEnd()) 225 } 226 return nil 227 }, 228 ), 229 ) 230 231 db.GCManager.Start() 232 233 // For debug or test 234 // logutil.Info(db.Catalog.SimplePPString(common.PPL2)) 235 return 236 }