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  }