github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/logtail/utils.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 logtail 16 17 import ( 18 "fmt" 19 "time" 20 21 pkgcatalog "github.com/matrixorigin/matrixone/pkg/catalog" 22 "github.com/matrixorigin/matrixone/pkg/common/moerr" 23 "github.com/matrixorigin/matrixone/pkg/common/mpool" 24 "github.com/matrixorigin/matrixone/pkg/container/types" 25 "github.com/matrixorigin/matrixone/pkg/logutil" 26 "github.com/matrixorigin/matrixone/pkg/objectio" 27 "github.com/matrixorigin/matrixone/pkg/pb/api" 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/tasks" 33 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/txn/txnimpl" 34 ) 35 36 const ( 37 MetaIDX uint16 = iota 38 39 DBInsertIDX 40 DBInsertTxnIDX 41 DBDeleteIDX 42 DBDeleteTxnIDX 43 44 TBLInsertIDX 45 TBLInsertTxnIDX 46 TBLDeleteIDX 47 TBLDeleteTxnIDX 48 TBLColInsertIDX 49 TBLColDeleteIDX 50 51 SEGInsertIDX 52 SEGInsertTxnIDX 53 SEGDeleteIDX 54 SEGDeleteTxnIDX 55 56 BLKMetaInsertIDX 57 BLKMetaInsertTxnIDX 58 BLKMetaDeleteIDX 59 BLKMetaDeleteTxnIDX 60 61 BLKDNMetaInsertIDX 62 BLKDNMetaInsertTxnIDX 63 BLKDNMetaDeleteIDX 64 BLKDNMetaDeleteTxnIDX 65 66 BLKCNMetaInsertIDX 67 68 BLKInsertIDX 69 BLKInsertTxnIDX 70 BLKDeleteIDX 71 BLKDeleteTxnIDX 72 ) 73 74 const MaxIDX = BLKCNMetaInsertIDX + 1 75 76 type checkpointDataItem struct { 77 schema *catalog.Schema 78 types []types.Type 79 attrs []string 80 nullables []bool 81 } 82 83 var checkpointDataSchemas [MaxIDX]*catalog.Schema 84 85 var checkpointDataRefer [MaxIDX]*checkpointDataItem 86 87 func init() { 88 checkpointDataSchemas = [MaxIDX]*catalog.Schema{ 89 MetaSchema, 90 catalog.SystemDBSchema, 91 TxnNodeSchema, 92 DelSchema, 93 DBDNSchema, 94 catalog.SystemTableSchema, 95 TblDNSchema, 96 DelSchema, 97 TblDNSchema, 98 catalog.SystemColumnSchema, 99 DelSchema, 100 SegSchema, 101 SegDNSchema, 102 DelSchema, 103 SegDNSchema, 104 BlkMetaSchema, 105 BlkDNSchema, 106 DelSchema, 107 BlkDNSchema, 108 BlkMetaSchema, 109 BlkDNSchema, 110 DelSchema, 111 BlkDNSchema, 112 BlkMetaSchema, 113 } 114 for idx, schema := range checkpointDataSchemas { 115 checkpointDataRefer[idx] = &checkpointDataItem{ 116 schema, 117 append(BaseTypes, schema.Types()...), 118 append(BaseAttr, schema.AllNames()...), 119 append([]bool{false, false}, schema.AllNullables()...), 120 } 121 } 122 } 123 124 func IncrementalCheckpointDataFactory(start, end types.TS) func(c *catalog.Catalog) (*CheckpointData, error) { 125 return func(c *catalog.Catalog) (data *CheckpointData, err error) { 126 collector := NewIncrementalCollector(start, end) 127 defer collector.Close() 128 err = c.RecurLoop(collector) 129 if moerr.IsMoErrCode(err, moerr.OkStopCurrRecur) { 130 err = nil 131 } 132 collector.data.prepareMeta() 133 if err != nil { 134 return 135 } 136 data = collector.OrphanData() 137 return 138 } 139 } 140 141 func GlobalCheckpointDataFactory(end types.TS, versionInterval time.Duration) func(c *catalog.Catalog) (*CheckpointData, error) { 142 return func(c *catalog.Catalog) (data *CheckpointData, err error) { 143 collector := NewGlobalCollector(end, versionInterval) 144 defer collector.Close() 145 err = c.RecurLoop(collector) 146 if moerr.IsMoErrCode(err, moerr.OkStopCurrRecur) { 147 err = nil 148 } 149 collector.data.prepareMeta() 150 if err != nil { 151 return 152 } 153 data = collector.OrphanData() 154 return 155 } 156 } 157 158 type CheckpointMeta struct { 159 blkInsertOffset *common.ClosedInterval 160 blkDeleteOffset *common.ClosedInterval 161 } 162 163 func NewCheckpointMeta() *CheckpointMeta { 164 return &CheckpointMeta{} 165 } 166 167 type CheckpointData struct { 168 meta map[uint64]*CheckpointMeta 169 bats [MaxIDX]*containers.Batch 170 } 171 172 func NewCheckpointData() *CheckpointData { 173 data := &CheckpointData{ 174 meta: make(map[uint64]*CheckpointMeta), 175 } 176 for idx, schema := range checkpointDataSchemas { 177 data.bats[idx] = makeRespBatchFromSchema(schema) 178 } 179 return data 180 } 181 182 type BaseCollector struct { 183 *catalog.LoopProcessor 184 start, end types.TS 185 186 data *CheckpointData 187 } 188 189 type IncrementalCollector struct { 190 *BaseCollector 191 } 192 193 func NewIncrementalCollector(start, end types.TS) *IncrementalCollector { 194 collector := &IncrementalCollector{ 195 BaseCollector: &BaseCollector{ 196 LoopProcessor: new(catalog.LoopProcessor), 197 data: NewCheckpointData(), 198 start: start, 199 end: end, 200 }, 201 } 202 collector.DatabaseFn = collector.VisitDB 203 collector.TableFn = collector.VisitTable 204 collector.SegmentFn = collector.VisitSeg 205 collector.BlockFn = collector.VisitBlk 206 return collector 207 } 208 209 type GlobalCollector struct { 210 *BaseCollector 211 versionThershold types.TS 212 } 213 214 func NewGlobalCollector(end types.TS, versionInterval time.Duration) *GlobalCollector { 215 versionThresholdTS := types.BuildTS(end.Physical()-versionInterval.Nanoseconds(), end.Logical()) 216 collector := &GlobalCollector{ 217 BaseCollector: &BaseCollector{ 218 LoopProcessor: new(catalog.LoopProcessor), 219 data: NewCheckpointData(), 220 end: end, 221 }, 222 versionThershold: versionThresholdTS, 223 } 224 collector.DatabaseFn = collector.VisitDB 225 collector.TableFn = collector.VisitTable 226 collector.SegmentFn = collector.VisitSeg 227 collector.BlockFn = collector.VisitBlk 228 return collector 229 } 230 231 func (data *CheckpointData) ApplyReplayTo( 232 c *catalog.Catalog, 233 dataFactory catalog.DataFactory) (err error) { 234 c.OnReplayDatabaseBatch(data.GetDBBatchs()) 235 ins, colins, dnins, del, dndel := data.GetTblBatchs() 236 c.OnReplayTableBatch(ins, colins, dnins, del, dndel, dataFactory) 237 ins, dnins, del, dndel = data.GetSegBatchs() 238 c.OnReplaySegmentBatch(ins, dnins, del, dndel, dataFactory) 239 ins, dnins, del, dndel = data.GetDNBlkBatchs() 240 c.OnReplayBlockBatch(ins, dnins, del, dndel, dataFactory) 241 ins, dnins, del, dndel = data.GetBlkBatchs() 242 c.OnReplayBlockBatch(ins, dnins, del, dndel, dataFactory) 243 return 244 } 245 func (data *CheckpointData) GetTableMeta(tableID uint64) (meta *CheckpointMeta) { 246 if len(data.meta) != 0 { 247 meta = data.meta[tableID] 248 return 249 } 250 for i := 0; i < data.bats[MetaIDX].GetVectorByName(SnapshotMetaAttr_Tid).Length(); i++ { 251 tid := data.bats[MetaIDX].GetVectorByName(SnapshotMetaAttr_Tid).Get(i).(uint64) 252 insStart := data.bats[MetaIDX].GetVectorByName(SnapshotMetaAttr_BlockInsertBatchStart).Get(i).(int32) 253 insEnd := data.bats[MetaIDX].GetVectorByName(SnapshotMetaAttr_BlockInsertBatchEnd).Get(i).(int32) 254 delStart := data.bats[MetaIDX].GetVectorByName(SnapshotMetaAttr_BlockDeleteBatchStart).Get(i).(int32) 255 delEnd := data.bats[MetaIDX].GetVectorByName(SnapshotMetaAttr_BlockDeleteBatchEnd).Get(i).(int32) 256 meta := new(CheckpointMeta) 257 if insStart != -1 { 258 meta.blkInsertOffset = &common.ClosedInterval{ 259 Start: uint64(insStart), 260 End: uint64(insEnd), 261 } 262 } 263 if delStart != -1 { 264 meta.blkDeleteOffset = &common.ClosedInterval{ 265 Start: uint64(delStart), 266 End: uint64(delEnd), 267 } 268 } 269 data.meta[tid] = meta 270 // logutil.Infof("GetTableMeta TID=%d, INTERVAL=%s", tid, meta.blkInsertOffset.String()) 271 } 272 meta = data.meta[tableID] 273 return 274 } 275 func (data *CheckpointData) GetTableData(tid uint64) (ins, del, cnIns *api.Batch, err error) { 276 var insTaeBat, delTaeBat, cnInsTaeBat *containers.Batch 277 switch tid { 278 case pkgcatalog.MO_DATABASE_ID: 279 insTaeBat = data.bats[DBInsertIDX] 280 delTaeBat = data.bats[DBDeleteIDX] 281 if insTaeBat != nil { 282 ins, err = containersBatchToProtoBatch(insTaeBat) 283 if err != nil { 284 return 285 } 286 } 287 if delTaeBat != nil { 288 del, err = containersBatchToProtoBatch(delTaeBat) 289 if err != nil { 290 return 291 } 292 } 293 return 294 case pkgcatalog.MO_TABLES_ID: 295 insTaeBat = data.bats[TBLInsertIDX] 296 delTaeBat = data.bats[TBLDeleteIDX] 297 if insTaeBat != nil { 298 ins, err = containersBatchToProtoBatch(insTaeBat) 299 if err != nil { 300 return 301 } 302 } 303 if delTaeBat != nil { 304 del, err = containersBatchToProtoBatch(delTaeBat) 305 if err != nil { 306 return 307 } 308 } 309 return 310 case pkgcatalog.MO_COLUMNS_ID: 311 insTaeBat = data.bats[TBLColInsertIDX] 312 delTaeBat = data.bats[TBLColDeleteIDX] 313 if insTaeBat != nil { 314 ins, err = containersBatchToProtoBatch(insTaeBat) 315 if err != nil { 316 return 317 } 318 } 319 if delTaeBat != nil { 320 del, err = containersBatchToProtoBatch(delTaeBat) 321 if err != nil { 322 return 323 } 324 } 325 return 326 } 327 328 // For Debug 329 // if insTaeBat != nil { 330 // logutil.Infof("GetTableData: TID=%d %s", tid, BatchToString("INS-DATA", insTaeBat, true)) 331 // } 332 // if delTaeBat != nil { 333 // logutil.Infof("GetTableData: TID=%d %s", tid, BatchToString("DEL-DATA", delTaeBat, true)) 334 // } 335 336 meta := data.GetTableMeta(tid) 337 if meta == nil { 338 return nil, nil, nil, nil 339 } 340 341 insInterval := meta.blkInsertOffset 342 if insInterval != nil { 343 insOffset := insInterval.Start 344 insLength := insInterval.End - insInterval.Start 345 insTaeBat = data.bats[BLKMetaInsertIDX].Window(int(insOffset), int(insLength)) 346 } 347 348 delInterval := meta.blkDeleteOffset 349 if delInterval != nil { 350 delOffset := delInterval.Start 351 delLength := delInterval.End - delInterval.Start 352 delTaeBat = data.bats[BLKMetaDeleteIDX].Window(int(delOffset), int(delLength)) 353 cnInsTaeBat = data.bats[BLKCNMetaInsertIDX].Window(int(delOffset), int(delLength)) 354 } 355 356 if insTaeBat != nil { 357 ins, err = containersBatchToProtoBatch(insTaeBat) 358 if err != nil { 359 return 360 } 361 } 362 if delTaeBat != nil { 363 del, err = containersBatchToProtoBatch(delTaeBat) 364 if err != nil { 365 return 366 } 367 cnIns, err = containersBatchToProtoBatch(cnInsTaeBat) 368 if err != nil { 369 return 370 } 371 } 372 373 // For debug 374 // if insTaeBat != nil { 375 // logutil.Infof("GetTableData: TID=%d %s", tid, BatchToString("INS-BLK-DATA", insTaeBat, true)) 376 // } 377 // if delTaeBat != nil { 378 // logutil.Infof("GetTableData: TID=%d %s", tid, BatchToString("DEL-BLK-DATA", delTaeBat, true)) 379 // } 380 // if cnInsTaeBat != nil { 381 // logutil.Infof("GetTableData: TID=%d %s", tid, BatchToString("CN-INS-DATA", cnInsTaeBat, true)) 382 // } 383 return 384 } 385 386 func (data *CheckpointData) prepareMeta() { 387 bat := data.bats[MetaIDX] 388 for tid, meta := range data.meta { 389 bat.GetVectorByName(SnapshotMetaAttr_Tid).Append(tid) 390 if meta.blkInsertOffset == nil { 391 bat.GetVectorByName(SnapshotMetaAttr_BlockInsertBatchStart).Append(int32(-1)) 392 bat.GetVectorByName(SnapshotMetaAttr_BlockInsertBatchEnd).Append(int32(-1)) 393 } else { 394 bat.GetVectorByName(SnapshotMetaAttr_BlockInsertBatchStart).Append(int32(meta.blkInsertOffset.Start)) 395 bat.GetVectorByName(SnapshotMetaAttr_BlockInsertBatchEnd).Append(int32(meta.blkInsertOffset.End)) 396 } 397 if meta.blkDeleteOffset == nil { 398 bat.GetVectorByName(SnapshotMetaAttr_BlockDeleteBatchStart).Append(int32(-1)) 399 bat.GetVectorByName(SnapshotMetaAttr_BlockDeleteBatchEnd).Append(int32(-1)) 400 } else { 401 bat.GetVectorByName(SnapshotMetaAttr_BlockDeleteBatchStart).Append(int32(meta.blkDeleteOffset.Start)) 402 bat.GetVectorByName(SnapshotMetaAttr_BlockDeleteBatchEnd).Append(int32(meta.blkDeleteOffset.End)) 403 } 404 } 405 } 406 407 func (data *CheckpointData) UpdateBlkMeta(tid uint64, insStart, insEnd, delStart, delEnd int32) { 408 if delEnd < delStart && insEnd < insStart { 409 return 410 } 411 meta, ok := data.meta[tid] 412 if !ok { 413 meta = NewCheckpointMeta() 414 data.meta[tid] = meta 415 } 416 if delEnd >= delStart { 417 if meta.blkDeleteOffset == nil { 418 meta.blkDeleteOffset = &common.ClosedInterval{Start: uint64(delStart), End: uint64(delEnd)} 419 } else { 420 if !meta.blkDeleteOffset.TryMerge(common.ClosedInterval{Start: uint64(delStart), End: uint64(delEnd)}) { 421 panic(fmt.Sprintf("logic error interval %v, start %d, end %d", meta.blkDeleteOffset, delStart, delEnd)) 422 } 423 } 424 } 425 if insEnd >= insStart { 426 if meta.blkInsertOffset == nil { 427 meta.blkInsertOffset = &common.ClosedInterval{Start: uint64(insStart), End: uint64(insEnd)} 428 } else { 429 if !meta.blkInsertOffset.TryMerge(common.ClosedInterval{Start: uint64(insStart), End: uint64(insEnd)}) { 430 panic(fmt.Sprintf("logic error interval %v, start %d, end %d", meta.blkInsertOffset, insStart, insEnd)) 431 } 432 } 433 } 434 } 435 436 func (data *CheckpointData) PrintData() { 437 logutil.Info(BatchToString("BLK-META-DEL-BAT", data.bats[BLKMetaDeleteIDX], true)) 438 logutil.Info(BatchToString("BLK-META-INS-BAT", data.bats[BLKMetaInsertIDX], true)) 439 } 440 441 func (data *CheckpointData) WriteTo( 442 writer *blockio.Writer) (blks []objectio.BlockObject, err error) { 443 for _, bat := range data.bats { 444 if _, err = writer.WriteBlock(bat); err != nil { 445 return 446 } 447 } 448 blks, err = writer.Sync() 449 return 450 } 451 452 // TODO: 453 // There need a global io pool 454 func (data *CheckpointData) ReadFrom( 455 reader *blockio.Reader, 456 scheduler tasks.JobScheduler, 457 m *mpool.MPool) (err error) { 458 metas, err := reader.ReadMetas(m) 459 if err != nil { 460 return 461 } 462 463 if scheduler == nil { 464 scheduler = tasks.NewParallelJobScheduler(100) 465 defer scheduler.Stop() 466 } 467 468 jobs := make([]*tasks.Job, MaxIDX) 469 470 for idx, item := range checkpointDataRefer { 471 job := reader.BlkColumnByMetaLoadJob( 472 item.types, 473 item.attrs, 474 item.nullables, 475 metas[idx], 476 ) 477 if err = scheduler.Schedule(job); err != nil { 478 break 479 } 480 jobs[idx] = job 481 } 482 483 cleanJobs := func() { 484 for _, job := range jobs { 485 if job == nil { 486 continue 487 } 488 result := job.WaitDone() 489 defer job.Close() 490 if result != nil && result.Res != nil { 491 result.Res.(*containers.Batch).Close() 492 result.Res = nil 493 } 494 } 495 } 496 497 if err != nil { 498 go cleanJobs() 499 return 500 } 501 502 for _, job := range jobs { 503 result := job.WaitDone() 504 if err = result.Err; err != nil { 505 break 506 } 507 } 508 509 if err != nil { 510 go cleanJobs() 511 return 512 } 513 514 for idx, job := range jobs { 515 result := job.GetResult() 516 data.bats[idx] = result.Res.(*containers.Batch) 517 } 518 519 return 520 } 521 522 func (data *CheckpointData) Close() { 523 for idx := range data.bats { 524 if data.bats[idx] != nil { 525 data.bats[idx].Close() 526 data.bats[idx] = nil 527 } 528 } 529 } 530 func (data *CheckpointData) GetDBBatchs() ( 531 *containers.Batch, 532 *containers.Batch, 533 *containers.Batch, 534 *containers.Batch) { 535 return data.bats[DBInsertIDX], 536 data.bats[DBInsertTxnIDX], 537 data.bats[DBDeleteIDX], 538 data.bats[DBDeleteTxnIDX] 539 } 540 func (data *CheckpointData) GetTblBatchs() ( 541 *containers.Batch, 542 *containers.Batch, 543 *containers.Batch, 544 *containers.Batch, 545 *containers.Batch) { 546 return data.bats[TBLInsertIDX], 547 data.bats[TBLInsertTxnIDX], 548 data.bats[TBLColInsertIDX], 549 data.bats[TBLDeleteIDX], 550 data.bats[TBLDeleteTxnIDX] 551 } 552 func (data *CheckpointData) GetSegBatchs() ( 553 *containers.Batch, 554 *containers.Batch, 555 *containers.Batch, 556 *containers.Batch) { 557 return data.bats[SEGInsertIDX], 558 data.bats[SEGInsertTxnIDX], 559 data.bats[SEGDeleteIDX], 560 data.bats[SEGDeleteTxnIDX] 561 } 562 func (data *CheckpointData) GetBlkBatchs() ( 563 *containers.Batch, 564 *containers.Batch, 565 *containers.Batch, 566 *containers.Batch) { 567 return data.bats[BLKMetaInsertIDX], 568 data.bats[BLKMetaInsertTxnIDX], 569 data.bats[BLKMetaDeleteIDX], 570 data.bats[BLKMetaDeleteTxnIDX] 571 } 572 func (data *CheckpointData) GetDNBlkBatchs() ( 573 *containers.Batch, 574 *containers.Batch, 575 *containers.Batch, 576 *containers.Batch) { 577 return data.bats[BLKDNMetaInsertIDX], 578 data.bats[BLKDNMetaInsertTxnIDX], 579 data.bats[BLKDNMetaDeleteIDX], 580 data.bats[BLKDNMetaDeleteTxnIDX] 581 } 582 583 func (collector *BaseCollector) VisitDB(entry *catalog.DBEntry) error { 584 if shouldIgnoreDBInLogtail(entry.ID) { 585 return nil 586 } 587 entry.RLock() 588 mvccNodes := entry.ClonePreparedInRange(collector.start, collector.end) 589 entry.RUnlock() 590 for _, node := range mvccNodes { 591 if node.IsAborted() { 592 continue 593 } 594 dbNode := node.(*catalog.DBMVCCNode) 595 if dbNode.HasDropCommitted() { 596 // delScehma is empty, it will just fill rowid / commit ts 597 catalogEntry2Batch( 598 collector.data.bats[DBDeleteIDX], 599 entry, DelSchema, 600 txnimpl.FillDBRow, 601 u64ToRowID(entry.GetID()), 602 dbNode.GetEnd()) 603 dbNode.TxnMVCCNode.AppendTuple(collector.data.bats[DBDeleteTxnIDX]) 604 collector.data.bats[DBDeleteTxnIDX].GetVectorByName(SnapshotAttr_DBID).Append(entry.GetID()) 605 } else { 606 catalogEntry2Batch(collector.data.bats[DBInsertIDX], 607 entry, 608 catalog.SystemDBSchema, 609 txnimpl.FillDBRow, 610 u64ToRowID(entry.GetID()), 611 dbNode.GetEnd()) 612 dbNode.TxnMVCCNode.AppendTuple(collector.data.bats[DBInsertTxnIDX]) 613 } 614 } 615 return nil 616 } 617 func (collector *GlobalCollector) isEntryDeletedBeforeThreshold(entry catalog.BaseEntry) bool { 618 entry.RLock() 619 defer entry.RUnlock() 620 return entry.DeleteBefore(collector.versionThershold) 621 } 622 func (collector *GlobalCollector) VisitDB(entry *catalog.DBEntry) error { 623 if collector.isEntryDeletedBeforeThreshold(entry.DBBaseEntry) { 624 return nil 625 } 626 return collector.BaseCollector.VisitDB(entry) 627 } 628 629 func (collector *BaseCollector) VisitTable(entry *catalog.TableEntry) (err error) { 630 if shouldIgnoreTblInLogtail(entry.ID) { 631 return nil 632 } 633 entry.RLock() 634 mvccNodes := entry.ClonePreparedInRange(collector.start, collector.end) 635 entry.RUnlock() 636 for _, node := range mvccNodes { 637 if node.IsAborted() { 638 continue 639 } 640 tblNode := node.(*catalog.TableMVCCNode) 641 if !tblNode.HasDropCommitted() { 642 for _, syscol := range catalog.SystemColumnSchema.ColDefs { 643 txnimpl.FillColumnRow( 644 entry, 645 syscol.Name, 646 collector.data.bats[TBLColInsertIDX].GetVectorByName(syscol.Name), 647 ) 648 } 649 rowidVec := collector.data.bats[TBLColInsertIDX].GetVectorByName(catalog.AttrRowID) 650 commitVec := collector.data.bats[TBLColInsertIDX].GetVectorByName(catalog.AttrCommitTs) 651 for _, usercol := range entry.GetSchema().ColDefs { 652 rowidVec.Append(bytesToRowID([]byte(fmt.Sprintf("%d-%s", entry.GetID(), usercol.Name)))) 653 commitVec.Append(tblNode.GetEnd()) 654 } 655 656 collector.data.bats[TBLInsertTxnIDX].GetVectorByName( 657 SnapshotAttr_BlockMaxRow).Append(entry.GetSchema().BlockMaxRows) 658 collector.data.bats[TBLInsertTxnIDX].GetVectorByName( 659 SnapshotAttr_SegmentMaxBlock).Append(entry.GetSchema().SegmentMaxBlocks) 660 661 catalogEntry2Batch( 662 collector.data.bats[TBLInsertIDX], 663 entry, 664 catalog.SystemTableSchema, 665 txnimpl.FillTableRow, 666 u64ToRowID(entry.GetID()), 667 tblNode.GetEnd(), 668 ) 669 670 tblNode.TxnMVCCNode.AppendTuple(collector.data.bats[TBLInsertTxnIDX]) 671 } else { 672 collector.data.bats[TBLDeleteTxnIDX].GetVectorByName( 673 SnapshotAttr_DBID).Append(entry.GetDB().GetID()) 674 collector.data.bats[TBLDeleteTxnIDX].GetVectorByName( 675 SnapshotAttr_TID).Append(entry.GetID()) 676 677 rowidVec := collector.data.bats[TBLColDeleteIDX].GetVectorByName(catalog.AttrRowID) 678 commitVec := collector.data.bats[TBLColDeleteIDX].GetVectorByName(catalog.AttrCommitTs) 679 for _, usercol := range entry.GetSchema().ColDefs { 680 rowidVec.Append( 681 bytesToRowID([]byte(fmt.Sprintf("%d-%s", entry.GetID(), usercol.Name))), 682 ) 683 commitVec.Append(tblNode.GetEnd()) 684 } 685 686 catalogEntry2Batch( 687 collector.data.bats[TBLDeleteIDX], 688 entry, DelSchema, 689 txnimpl.FillTableRow, 690 u64ToRowID(entry.GetID()), 691 tblNode.GetEnd(), 692 ) 693 tblNode.TxnMVCCNode.AppendTuple(collector.data.bats[TBLDeleteTxnIDX]) 694 } 695 } 696 return nil 697 } 698 699 func (collector *GlobalCollector) VisitTable(entry *catalog.TableEntry) error { 700 if collector.isEntryDeletedBeforeThreshold(entry.TableBaseEntry) { 701 return nil 702 } 703 if collector.isEntryDeletedBeforeThreshold(entry.GetDB().DBBaseEntry) { 704 return nil 705 } 706 return collector.BaseCollector.VisitTable(entry) 707 } 708 709 func (collector *BaseCollector) VisitSeg(entry *catalog.SegmentEntry) (err error) { 710 entry.RLock() 711 mvccNodes := entry.ClonePreparedInRange(collector.start, collector.end) 712 entry.RUnlock() 713 if len(mvccNodes) == 0 { 714 return nil 715 } 716 for _, node := range mvccNodes { 717 if node.IsAborted() { 718 continue 719 } 720 segNode := node.(*catalog.MetadataMVCCNode) 721 if segNode.HasDropCommitted() { 722 collector.data.bats[SEGDeleteIDX].GetVectorByName(catalog.AttrRowID).Append(u64ToRowID(entry.ID)) 723 collector.data.bats[SEGDeleteIDX].GetVectorByName(catalog.AttrCommitTs).Append(segNode.GetEnd()) 724 collector.data.bats[SEGDeleteTxnIDX].GetVectorByName(SnapshotAttr_DBID).Append(entry.GetTable().GetDB().GetID()) 725 collector.data.bats[SEGDeleteTxnIDX].GetVectorByName(SnapshotAttr_TID).Append(entry.GetTable().GetID()) 726 segNode.TxnMVCCNode.AppendTuple(collector.data.bats[SEGDeleteTxnIDX]) 727 } else { 728 collector.data.bats[SEGInsertIDX].GetVectorByName(SegmentAttr_ID).Append(entry.GetID()) 729 collector.data.bats[SEGInsertIDX].GetVectorByName(SegmentAttr_CreateAt).Append(segNode.GetEnd()) 730 collector.data.bats[SEGInsertIDX].GetVectorByName(SegmentAttr_State).Append(entry.IsAppendable()) 731 collector.data.bats[SEGInsertIDX].GetVectorByName(SegmentAttr_Sorted).Append(entry.IsSorted()) 732 collector.data.bats[SEGInsertTxnIDX].GetVectorByName(SnapshotAttr_DBID).Append(entry.GetTable().GetDB().GetID()) 733 collector.data.bats[SEGInsertTxnIDX].GetVectorByName(SnapshotAttr_TID).Append(entry.GetTable().GetID()) 734 segNode.TxnMVCCNode.AppendTuple(collector.data.bats[SEGInsertTxnIDX]) 735 } 736 } 737 return nil 738 } 739 740 func (collector *GlobalCollector) VisitSeg(entry *catalog.SegmentEntry) error { 741 if collector.isEntryDeletedBeforeThreshold(entry.MetaBaseEntry) { 742 return nil 743 } 744 if collector.isEntryDeletedBeforeThreshold(entry.GetTable().TableBaseEntry) { 745 return nil 746 } 747 if collector.isEntryDeletedBeforeThreshold(entry.GetTable().GetDB().DBBaseEntry) { 748 return nil 749 } 750 return collector.BaseCollector.VisitSeg(entry) 751 } 752 753 func (collector *BaseCollector) VisitBlk(entry *catalog.BlockEntry) (err error) { 754 entry.RLock() 755 mvccNodes := entry.ClonePreparedInRange(collector.start, collector.end) 756 entry.RUnlock() 757 if len(mvccNodes) == 0 { 758 return nil 759 } 760 insStart := collector.data.bats[BLKMetaInsertIDX].GetVectorByName(catalog.AttrRowID).Length() 761 delStart := collector.data.bats[BLKMetaDeleteIDX].GetVectorByName(catalog.AttrRowID).Length() 762 for _, node := range mvccNodes { 763 if node.IsAborted() { 764 continue 765 } 766 metaNode := node.(*catalog.MetadataMVCCNode) 767 if metaNode.MetaLoc == "" || metaNode.Aborted { 768 if metaNode.HasDropCommitted() { 769 collector.data.bats[BLKDNMetaDeleteIDX].GetVectorByName(catalog.AttrRowID).Append(u64ToRowID(entry.ID)) 770 collector.data.bats[BLKDNMetaDeleteIDX].GetVectorByName(catalog.AttrCommitTs).Append(metaNode.GetEnd()) 771 collector.data.bats[BLKDNMetaDeleteTxnIDX].GetVectorByName(SnapshotAttr_DBID).Append(entry.GetSegment().GetTable().GetDB().GetID()) 772 collector.data.bats[BLKDNMetaDeleteTxnIDX].GetVectorByName(SnapshotAttr_TID).Append(entry.GetSegment().GetTable().GetID()) 773 collector.data.bats[BLKDNMetaDeleteTxnIDX].GetVectorByName(SnapshotAttr_SegID).Append(entry.GetSegment().GetID()) 774 metaNode.TxnMVCCNode.AppendTuple(collector.data.bats[BLKDNMetaDeleteTxnIDX]) 775 collector.data.bats[BLKDNMetaDeleteTxnIDX].GetVectorByName(pkgcatalog.BlockMeta_MetaLoc).Append([]byte(metaNode.MetaLoc)) 776 collector.data.bats[BLKDNMetaDeleteTxnIDX].GetVectorByName(pkgcatalog.BlockMeta_DeltaLoc).Append([]byte(metaNode.DeltaLoc)) 777 } else { 778 collector.data.bats[BLKDNMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_ID).Append(entry.ID) 779 collector.data.bats[BLKDNMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_EntryState).Append(entry.IsAppendable()) 780 collector.data.bats[BLKDNMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_MetaLoc).Append([]byte(metaNode.MetaLoc)) 781 collector.data.bats[BLKDNMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_DeltaLoc).Append([]byte(metaNode.DeltaLoc)) 782 collector.data.bats[BLKDNMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_CommitTs).Append(metaNode.GetEnd()) 783 is_sorted := false 784 if !entry.IsAppendable() && entry.GetSchema().HasSortKey() { 785 is_sorted = true 786 } 787 collector.data.bats[BLKDNMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_Sorted).Append(is_sorted) 788 collector.data.bats[BLKDNMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_SegmentID).Append(entry.GetSegment().ID) 789 collector.data.bats[BLKDNMetaInsertIDX].GetVectorByName(catalog.AttrCommitTs).Append(metaNode.CreatedAt) 790 collector.data.bats[BLKDNMetaInsertIDX].GetVectorByName(catalog.AttrRowID).Append(u64ToRowID(entry.ID)) 791 collector.data.bats[BLKDNMetaInsertTxnIDX].GetVectorByName(SnapshotAttr_DBID).Append(entry.GetSegment().GetTable().GetDB().GetID()) 792 collector.data.bats[BLKDNMetaInsertTxnIDX].GetVectorByName(SnapshotAttr_TID).Append(entry.GetSegment().GetTable().GetID()) 793 collector.data.bats[BLKDNMetaInsertTxnIDX].GetVectorByName(SnapshotAttr_SegID).Append(entry.GetSegment().GetID()) 794 metaNode.TxnMVCCNode.AppendTuple(collector.data.bats[BLKDNMetaInsertTxnIDX]) 795 collector.data.bats[BLKDNMetaInsertTxnIDX].GetVectorByName(pkgcatalog.BlockMeta_MetaLoc).Append([]byte(metaNode.MetaLoc)) 796 collector.data.bats[BLKDNMetaInsertTxnIDX].GetVectorByName(pkgcatalog.BlockMeta_DeltaLoc).Append([]byte(metaNode.DeltaLoc)) 797 } 798 } else { 799 if metaNode.HasDropCommitted() { 800 collector.data.bats[BLKMetaDeleteIDX].GetVectorByName(catalog.AttrRowID).Append(u64ToRowID(entry.ID)) 801 collector.data.bats[BLKMetaDeleteIDX].GetVectorByName(catalog.AttrCommitTs).Append(metaNode.GetEnd()) 802 collector.data.bats[BLKMetaDeleteTxnIDX].GetVectorByName(SnapshotAttr_DBID).Append(entry.GetSegment().GetTable().GetDB().GetID()) 803 collector.data.bats[BLKMetaDeleteTxnIDX].GetVectorByName(SnapshotAttr_TID).Append(entry.GetSegment().GetTable().GetID()) 804 collector.data.bats[BLKMetaDeleteTxnIDX].GetVectorByName(SnapshotAttr_SegID).Append(entry.GetSegment().GetID()) 805 metaNode.TxnMVCCNode.AppendTuple(collector.data.bats[BLKMetaDeleteTxnIDX]) 806 collector.data.bats[BLKMetaDeleteTxnIDX].GetVectorByName(pkgcatalog.BlockMeta_MetaLoc).Append([]byte(metaNode.MetaLoc)) 807 collector.data.bats[BLKMetaDeleteTxnIDX].GetVectorByName(pkgcatalog.BlockMeta_DeltaLoc).Append([]byte(metaNode.DeltaLoc)) 808 809 collector.data.bats[BLKCNMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_ID).Append(entry.ID) 810 collector.data.bats[BLKCNMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_EntryState).Append(entry.IsAppendable()) 811 collector.data.bats[BLKCNMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_MetaLoc).Append([]byte(metaNode.MetaLoc)) 812 collector.data.bats[BLKCNMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_DeltaLoc).Append([]byte(metaNode.DeltaLoc)) 813 collector.data.bats[BLKCNMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_CommitTs).Append(metaNode.GetEnd()) 814 is_sorted := false 815 if !entry.IsAppendable() && entry.GetSchema().HasSortKey() { 816 is_sorted = true 817 } 818 collector.data.bats[BLKCNMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_Sorted).Append(is_sorted) 819 collector.data.bats[BLKCNMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_SegmentID).Append(entry.GetSegment().ID) 820 collector.data.bats[BLKCNMetaInsertIDX].GetVectorByName(catalog.AttrCommitTs).Append(metaNode.CreatedAt) 821 collector.data.bats[BLKCNMetaInsertIDX].GetVectorByName(catalog.AttrRowID).Append(u64ToRowID(entry.ID)) 822 } else { 823 collector.data.bats[BLKMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_ID).Append(entry.ID) 824 collector.data.bats[BLKMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_EntryState).Append(entry.IsAppendable()) 825 collector.data.bats[BLKMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_MetaLoc).Append([]byte(metaNode.MetaLoc)) 826 collector.data.bats[BLKMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_DeltaLoc).Append([]byte(metaNode.DeltaLoc)) 827 collector.data.bats[BLKMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_CommitTs).Append(metaNode.GetEnd()) 828 is_sorted := false 829 if !entry.IsAppendable() && entry.GetSchema().HasSortKey() { 830 is_sorted = true 831 } 832 collector.data.bats[BLKMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_Sorted).Append(is_sorted) 833 collector.data.bats[BLKMetaInsertIDX].GetVectorByName(pkgcatalog.BlockMeta_SegmentID).Append(entry.GetSegment().ID) 834 collector.data.bats[BLKMetaInsertIDX].GetVectorByName(catalog.AttrCommitTs).Append(metaNode.CreatedAt) 835 collector.data.bats[BLKMetaInsertIDX].GetVectorByName(catalog.AttrRowID).Append(u64ToRowID(entry.ID)) 836 collector.data.bats[BLKMetaInsertTxnIDX].GetVectorByName(SnapshotAttr_DBID).Append(entry.GetSegment().GetTable().GetDB().GetID()) 837 collector.data.bats[BLKMetaInsertTxnIDX].GetVectorByName(SnapshotAttr_TID).Append(entry.GetSegment().GetTable().GetID()) 838 collector.data.bats[BLKMetaInsertTxnIDX].GetVectorByName(SnapshotAttr_SegID).Append(entry.GetSegment().GetID()) 839 metaNode.TxnMVCCNode.AppendTuple(collector.data.bats[BLKMetaInsertTxnIDX]) 840 collector.data.bats[BLKMetaInsertTxnIDX].GetVectorByName(pkgcatalog.BlockMeta_MetaLoc).Append([]byte(metaNode.MetaLoc)) 841 collector.data.bats[BLKMetaInsertTxnIDX].GetVectorByName(pkgcatalog.BlockMeta_DeltaLoc).Append([]byte(metaNode.DeltaLoc)) 842 } 843 } 844 } 845 insEnd := collector.data.bats[BLKMetaInsertIDX].GetVectorByName(catalog.AttrRowID).Length() 846 delEnd := collector.data.bats[BLKMetaDeleteIDX].GetVectorByName(catalog.AttrRowID).Length() 847 collector.data.UpdateBlkMeta(entry.GetSegment().GetTable().ID, int32(insStart), int32(insEnd), int32(delStart), int32(delEnd)) 848 return nil 849 } 850 851 func (collector *GlobalCollector) VisitBlk(entry *catalog.BlockEntry) error { 852 if collector.isEntryDeletedBeforeThreshold(entry.MetaBaseEntry) { 853 return nil 854 } 855 if collector.isEntryDeletedBeforeThreshold(entry.GetSegment().MetaBaseEntry) { 856 return nil 857 } 858 if collector.isEntryDeletedBeforeThreshold(entry.GetSegment().GetTable().TableBaseEntry) { 859 return nil 860 } 861 if collector.isEntryDeletedBeforeThreshold(entry.GetSegment().GetTable().GetDB().DBBaseEntry) { 862 return nil 863 } 864 return collector.BaseCollector.VisitBlk(entry) 865 } 866 867 func (collector *BaseCollector) OrphanData() *CheckpointData { 868 data := collector.data 869 collector.data = nil 870 return data 871 } 872 873 func (collector *BaseCollector) Close() { 874 if collector.data != nil { 875 collector.data.Close() 876 } 877 }