github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/tables/base.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 tables 16 17 import ( 18 "context" 19 "fmt" 20 "sync" 21 "sync/atomic" 22 23 "github.com/matrixorigin/matrixone/pkg/fileservice" 24 "github.com/matrixorigin/matrixone/pkg/logutil" 25 26 "github.com/RoaringBitmap/roaring" 27 "github.com/matrixorigin/matrixone/pkg/common/bitmap" 28 "github.com/matrixorigin/matrixone/pkg/common/moerr" 29 "github.com/matrixorigin/matrixone/pkg/common/mpool" 30 "github.com/matrixorigin/matrixone/pkg/container/nulls" 31 "github.com/matrixorigin/matrixone/pkg/container/types" 32 "github.com/matrixorigin/matrixone/pkg/container/vector" 33 "github.com/matrixorigin/matrixone/pkg/objectio" 34 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/blockio" 35 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/catalog" 36 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common" 37 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers" 38 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/db/dbutils" 39 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/data" 40 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/handle" 41 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/txnif" 42 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/index" 43 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/tables/updates" 44 ) 45 46 type BlockT[T common.IRef] interface { 47 common.IRef 48 Pin() *common.PinnedItem[T] 49 GetID() *common.ID 50 } 51 52 func DefaultTOmbstoneFactory(meta *catalog.ObjectEntry) data.Tombstone { 53 return updates.NewObjectMVCCHandle(meta) 54 } 55 56 type baseObject struct { 57 common.RefHelper 58 *sync.RWMutex 59 rt *dbutils.Runtime 60 meta *catalog.ObjectEntry 61 appendMVCC *updates.AppendMVCCHandle 62 impl data.Object 63 64 node atomic.Pointer[Node] 65 } 66 67 func newBaseObject( 68 impl data.Object, 69 meta *catalog.ObjectEntry, 70 rt *dbutils.Runtime, 71 ) *baseObject { 72 blk := &baseObject{ 73 impl: impl, 74 rt: rt, 75 meta: meta, 76 appendMVCC: updates.NewAppendMVCCHandle(meta), 77 } 78 blk.appendMVCC.SetAppendListener(blk.OnApplyAppend) 79 blk.RWMutex = meta.RWMutex 80 return blk 81 } 82 83 func (blk *baseObject) OnApplyAppend(n txnif.AppendNode) (err error) { 84 blk.meta.GetTable().AddRows( 85 uint64(n.GetMaxRow() - n.GetStartRow()), 86 ) 87 return 88 } 89 func (blk *baseObject) Close() { 90 // TODO 91 } 92 93 func (blk *baseObject) GetRuntime() *dbutils.Runtime { 94 return blk.rt 95 } 96 97 func (blk *baseObject) PinNode() *Node { 98 n := blk.node.Load() 99 // if ref fails, reload. 100 // Note: avoid bad case where releasing happens before Ref() 101 for ; !n.RefIfHasRef(); n = blk.node.Load() { 102 } 103 return n 104 } 105 func (blk *baseObject) tryGetMVCC() *updates.ObjectMVCCHandle { 106 tombstone := blk.meta.GetTable().TryGetTombstone(blk.meta.ID) 107 if tombstone == nil { 108 return nil 109 } 110 return tombstone.(*updates.ObjectMVCCHandle) 111 } 112 func (blk *baseObject) getOrCreateMVCC() *updates.ObjectMVCCHandle { 113 return blk.meta.GetTable().GetOrCreateTombstone(blk.meta, DefaultTOmbstoneFactory).(*updates.ObjectMVCCHandle) 114 } 115 116 func (blk *baseObject) GCInMemeoryDeletesByTSForTest(ts types.TS) { 117 blk.Lock() 118 defer blk.Unlock() 119 mvcc := blk.tryGetMVCC() 120 if mvcc == nil { 121 return 122 } 123 mvcc.UpgradeDeleteChainByTSLocked(ts) 124 } 125 126 func (blk *baseObject) UpgradeAllDeleteChain() { 127 blk.Lock() 128 defer blk.Unlock() 129 mvcc := blk.tryGetMVCC() 130 if mvcc == nil { 131 return 132 } 133 mvcc.UpgradeAllDeleteChain() 134 } 135 136 func (blk *baseObject) Rows() (int, error) { 137 node := blk.PinNode() 138 defer node.Unref() 139 if !node.IsPersisted() { 140 blk.RLock() 141 defer blk.RUnlock() 142 rows, err := node.Rows() 143 return int(rows), err 144 } else { 145 rows, err := node.Rows() 146 return int(rows), err 147 } 148 } 149 func (blk *baseObject) Foreach( 150 ctx context.Context, 151 readSchema any, 152 blkID uint16, 153 colIdx int, 154 op func(v any, isNull bool, row int) error, 155 sels []uint32, 156 mp *mpool.MPool, 157 ) error { 158 node := blk.PinNode() 159 defer node.Unref() 160 schema := readSchema.(*catalog.Schema) 161 if !node.IsPersisted() { 162 blk.RLock() 163 defer blk.RUnlock() 164 return node.MustMNode().Foreach(schema, blkID, colIdx, op, sels, mp) 165 } else { 166 return node.MustPNode().Foreach(ctx, schema, blkID, colIdx, op, sels, mp) 167 } 168 } 169 170 func (blk *baseObject) TryUpgrade() (err error) { 171 node := blk.node.Load() 172 if node.IsPersisted() { 173 return 174 } 175 pnode := newPersistedNode(blk) 176 nnode := NewNode(pnode) 177 nnode.Ref() 178 179 if !blk.node.CompareAndSwap(node, nnode) { 180 nnode.Unref() 181 } else { 182 node.Unref() 183 } 184 return 185 } 186 187 func (blk *baseObject) GetMeta() any { return blk.meta } 188 func (blk *baseObject) CheckFlushTaskRetry(startts types.TS) bool { 189 if !blk.meta.IsAppendable() { 190 panic("not support") 191 } 192 if blk.meta.HasDropCommitted() { 193 panic("not support") 194 } 195 blk.RLock() 196 defer blk.RUnlock() 197 x := blk.appendMVCC.GetLatestAppendPrepareTSLocked() 198 return x.Greater(&startts) 199 } 200 func (blk *baseObject) GetFs() *objectio.ObjectFS { return blk.rt.Fs } 201 func (blk *baseObject) GetID() *common.ID { return blk.meta.AsCommonID() } 202 203 func (blk *baseObject) fillInMemoryDeletesLocked( 204 txn txnif.TxnReader, 205 blkID uint16, 206 view *containers.BaseView, 207 rwlocker *sync.RWMutex, 208 ) (err error) { 209 mvcc := blk.tryGetMVCC() 210 if mvcc == nil { 211 return 212 } 213 deleteHandle := mvcc.TryGetDeleteChain(blkID) 214 if deleteHandle == nil { 215 return 216 } 217 chain := deleteHandle.GetDeleteChain() 218 deletes, err := chain.CollectDeletesLocked(txn, rwlocker) 219 if err != nil || deletes.IsEmpty() { 220 return 221 } 222 if view.DeleteMask == nil { 223 view.DeleteMask = deletes 224 } else { 225 view.DeleteMask.Or(deletes) 226 } 227 return 228 } 229 230 func (blk *baseObject) buildMetalocation(bid uint16) (objectio.Location, error) { 231 if !blk.meta.ObjectPersisted() { 232 return nil, nil 233 } 234 stats, err := blk.meta.MustGetObjectStats() 235 if err != nil { 236 return nil, err 237 } 238 blkMaxRows := blk.meta.GetSchema().BlockMaxRows 239 blkRow := blkMaxRows 240 if bid == uint16(blk.meta.BlockCnt())-1 { 241 blkRow = stats.Rows() - uint32(bid)*blkMaxRows 242 } 243 metaloc := objectio.BuildLocation(stats.ObjectName(), stats.Extent(), blkRow, bid) 244 return metaloc, nil 245 } 246 247 func (blk *baseObject) LoadPersistedCommitTS(bid uint16) (vec containers.Vector, err error) { 248 if !blk.meta.IsAppendable() { 249 return 250 } 251 location, err := blk.buildMetalocation(bid) 252 if err != nil { 253 return 254 } 255 if location.IsEmpty() { 256 return 257 } 258 //Extend lifetime of vectors is without the function. 259 //need to copy. closeFunc will be nil. 260 vectors, _, err := blockio.LoadColumns2( 261 context.Background(), 262 []uint16{objectio.SEQNUM_COMMITTS}, 263 nil, 264 blk.rt.Fs.Service, 265 location, 266 fileservice.Policy(0), 267 true, 268 blk.rt.VectorPool.Transient, 269 ) 270 if err != nil { 271 return 272 } 273 if vectors[0].GetType().Oid != types.T_TS { 274 panic(fmt.Sprintf("%s: bad commits layout", blk.meta.ID.String())) 275 } 276 vec = vectors[0] 277 return 278 } 279 280 func (blk *baseObject) LoadPersistedColumnData( 281 ctx context.Context, schema *catalog.Schema, colIdx int, mp *mpool.MPool, blkID uint16, 282 ) (vec containers.Vector, err error) { 283 def := schema.ColDefs[colIdx] 284 location, err := blk.buildMetalocation(blkID) 285 if err != nil { 286 return nil, err 287 } 288 id := blk.meta.AsCommonID() 289 id.SetBlockOffset(blkID) 290 return LoadPersistedColumnData( 291 ctx, 292 blk.rt, 293 id, 294 def, 295 location, 296 mp, 297 ) 298 } 299 300 func (blk *baseObject) loadLatestPersistedDeletes( 301 ctx context.Context, 302 blkID uint16, 303 txn txnif.TxnReader, 304 mp *mpool.MPool, 305 ) (bat *containers.Batch, persistedByCN bool, deltalocCommitTS types.TS, visible bool, release func(), err error) { 306 blk.RLock() 307 mvcc := blk.tryGetMVCC() 308 if mvcc == nil { 309 blk.RUnlock() 310 return 311 } 312 node := mvcc.GetLatestMVCCNode(blkID) 313 if node == nil { 314 blk.RUnlock() 315 return 316 } 317 location := node.BaseNode.DeltaLoc 318 if location.IsEmpty() { 319 blk.RUnlock() 320 return 321 } 322 deltalocCommitTS = node.End 323 visible = node.IsVisible(txn) 324 blk.RUnlock() 325 pkName := blk.meta.GetSchema().GetPrimaryKey().Name 326 bat, persistedByCN, release, err = LoadPersistedDeletes( 327 ctx, 328 pkName, 329 blk.rt.Fs, 330 location, 331 mp, 332 ) 333 return 334 } 335 func (blk *baseObject) FillPersistedDeletes( 336 ctx context.Context, 337 blkID uint16, 338 txn txnif.TxnReader, 339 view *containers.BaseView, 340 mp *mpool.MPool, 341 ) (err error) { 342 return blk.foreachPersistedDeletesVisibleByTxn( 343 ctx, 344 txn, 345 blkID, 346 true, 347 func(i int, rowIdVec *vector.Vector) { 348 rowid := vector.GetFixedAt[types.Rowid](rowIdVec, i) 349 row := rowid.GetRowOffset() 350 if view.DeleteMask == nil { 351 view.DeleteMask = nulls.NewWithSize(int(row) + 1) 352 } 353 view.DeleteMask.Add(uint64(row)) 354 }, 355 nil, 356 mp, 357 ) 358 } 359 360 func (blk *baseObject) fillPersistedDeletesInRange( 361 ctx context.Context, 362 blkID uint16, 363 start, end types.TS, 364 view *containers.BaseView, 365 mp *mpool.MPool, 366 ) (err error) { 367 err = blk.foreachPersistedDeletesCommittedInRange( 368 ctx, 369 start, 370 end, 371 blkID, 372 true, 373 func(i int, rowIdVec *vector.Vector) { 374 rowid := vector.GetFixedAt[types.Rowid](rowIdVec, i) 375 row := rowid.GetRowOffset() 376 if view.DeleteMask == nil { 377 view.DeleteMask = nulls.NewWithSize(int(row) + 1) 378 } 379 view.DeleteMask.Add(uint64(row)) 380 }, 381 nil, 382 mp, 383 ) 384 return err 385 } 386 387 func (blk *baseObject) persistedCollectDeleteMaskInRange( 388 ctx context.Context, 389 blkID uint16, 390 start, end types.TS, 391 mp *mpool.MPool, 392 ) (deletes *nulls.Nulls, err error) { 393 err = blk.foreachPersistedDeletesCommittedInRange( 394 ctx, 395 start, 396 end, 397 blkID, 398 true, 399 func(i int, rowIdVec *vector.Vector) { 400 rowid := vector.GetFixedAt[types.Rowid](rowIdVec, i) 401 row := rowid.GetRowOffset() 402 if deletes == nil { 403 deletes = nulls.NewWithSize(int(row) + 1) 404 } 405 deletes.Add(uint64(row)) 406 }, 407 nil, 408 mp, 409 ) 410 return 411 } 412 413 // for each deletes in [start,end] 414 func (blk *baseObject) foreachPersistedDeletesCommittedInRange( 415 ctx context.Context, 416 start, end types.TS, 417 blkID uint16, 418 skipAbort bool, 419 loopOp func(int, *vector.Vector), 420 postOp func(*containers.Batch), 421 mp *mpool.MPool, 422 ) (err error) { 423 loadFn := func() (bat *containers.Batch, persistedByCN bool, commitTS types.TS, visible bool, release func(), err error) { 424 mvcc := blk.tryGetMVCC() 425 if mvcc == nil { 426 return 427 } 428 // commitTS of deltalocation is the commitTS of deletes persisted by CN batches 429 location, deltalocCommitTS, deltalocStartTS := mvcc.GetDeltaLocAndCommitTS(blkID) 430 if location.IsEmpty() { 431 return 432 } 433 434 // quick check for early return. 435 persistedByCN, err = blockio.IsPersistedByCN(ctx, location, blk.rt.Fs.Service) 436 if err != nil { 437 return 438 } 439 if persistedByCN { 440 if deltalocCommitTS.Equal(&txnif.UncommitTS) { 441 return 442 } 443 if deltalocCommitTS.Less(&start) || deltalocCommitTS.Greater(&end) { 444 return 445 } 446 } else if deltalocStartTS.Less(&start) { 447 return 448 } 449 450 // IO 451 visible = true 452 pkName := blk.meta.GetSchema().GetPrimaryKey().Name 453 bat, release, err = LoadPersistedDeletesBySchema( 454 ctx, 455 pkName, 456 blk.rt.Fs, 457 location, 458 persistedByCN, 459 mp, 460 ) 461 return 462 } 463 return blk.foreachPersistedDeletes(ctx, start, end, blkID, skipAbort, loadFn, loopOp, postOp, mp) 464 } 465 466 // for each deletes in [start,end] 467 func (blk *baseObject) foreachPersistedDeletesVisibleByTxn( 468 ctx context.Context, 469 txn txnif.TxnReader, 470 blkID uint16, 471 skipAbort bool, 472 loopOp func(int, *vector.Vector), 473 postOp func(*containers.Batch), 474 mp *mpool.MPool, 475 ) (err error) { 476 loadFn := func() (deletes *containers.Batch, persistedByCN bool, commitTS types.TS, visible bool, release func(), err error) { 477 // commitTS of deltalocation is the commitTS of deletes persisted by CN batches 478 return blk.loadLatestPersistedDeletes(ctx, blkID, txn, mp) 479 } 480 return blk.foreachPersistedDeletes(ctx, types.TS{}, txn.GetStartTS(), blkID, skipAbort, loadFn, loopOp, postOp, mp) 481 } 482 func (blk *baseObject) foreachPersistedDeletes( 483 ctx context.Context, 484 start, end types.TS, 485 blkID uint16, 486 skipAbort bool, 487 loadFn func() (bat *containers.Batch, persistedByCN bool, commitTS types.TS, visible bool, release func(), err error), 488 loopOp func(int, *vector.Vector), 489 postOp func(*containers.Batch), 490 mp *mpool.MPool, 491 ) (err error) { 492 // commitTS of deltalocation is the commitTS of deletes persisted by CN batches 493 deletes, persistedByCN, deltalocCommitTS, visible, release, err := loadFn() 494 if deletes == nil || err != nil { 495 return 496 } 497 defer release() 498 defer deletes.Close() 499 if persistedByCN { 500 if !visible { 501 return 502 } 503 rowIdVec := deletes.Vecs[0].GetDownstreamVector() 504 for i := 0; i < deletes.Length(); i++ { 505 loopOp(i, rowIdVec) 506 } 507 commitTSVec := containers.NewConstFixed[types.TS](types.T_TS.ToType(), deltalocCommitTS, deletes.Length()) 508 abortVec := containers.NewConstFixed[bool](types.T_bool.ToType(), false, deletes.Length()) 509 deletes.AddVector(catalog.AttrCommitTs, commitTSVec) 510 deletes.AddVector(catalog.AttrAborted, abortVec) 511 } else { 512 abortVec := deletes.Vecs[3].GetDownstreamVector() 513 commitTsVec := deletes.Vecs[1].GetDownstreamVector() 514 rowIdVec := deletes.Vecs[0].GetDownstreamVector() 515 516 rstart, rend := blockio.FindIntervalForBlock(vector.MustFixedCol[types.Rowid](rowIdVec), objectio.NewBlockidWithObjectID(&blk.meta.ID, blkID)) 517 for i := rstart; i < rend; i++ { 518 if skipAbort { 519 abort := vector.GetFixedAt[bool](abortVec, i) 520 if abort { 521 continue 522 } 523 } 524 commitTS := vector.GetFixedAt[types.TS](commitTsVec, i) 525 if commitTS.GreaterEq(&start) && commitTS.LessEq(&end) { 526 loopOp(i, rowIdVec) 527 } 528 } 529 } 530 if postOp != nil { 531 postOp(deletes) 532 } 533 return 534 } 535 func (blk *baseObject) Prefetch(idxes []uint16, blkID uint16) error { 536 node := blk.PinNode() 537 defer node.Unref() 538 if !node.IsPersisted() { 539 return nil 540 } else { 541 key, err := blk.buildMetalocation(blkID) 542 if err != nil { 543 return err 544 } 545 return blockio.Prefetch(idxes, []uint16{key.ID()}, blk.rt.Fs.Service, key) 546 } 547 } 548 549 func (blk *baseObject) ResolvePersistedColumnDatas( 550 ctx context.Context, 551 txn txnif.TxnReader, 552 readSchema *catalog.Schema, 553 blkID uint16, 554 colIdxs []int, 555 skipDeletes bool, 556 mp *mpool.MPool, 557 ) (view *containers.BlockView, err error) { 558 559 view = containers.NewBlockView() 560 location, err := blk.buildMetalocation(blkID) 561 if err != nil { 562 return nil, err 563 } 564 id := blk.meta.AsCommonID() 565 id.SetBlockOffset(blkID) 566 vecs, err := LoadPersistedColumnDatas( 567 ctx, readSchema, blk.rt, id, colIdxs, location, mp, 568 ) 569 if err != nil { 570 return nil, err 571 } 572 for i, vec := range vecs { 573 view.SetData(colIdxs[i], vec) 574 } 575 576 if skipDeletes { 577 return 578 } 579 580 defer func() { 581 if err != nil { 582 view.Close() 583 } 584 }() 585 586 blk.RLock() 587 err = blk.fillInMemoryDeletesLocked(txn, blkID, view.BaseView, blk.RWMutex) 588 blk.RUnlock() 589 590 if err = blk.FillPersistedDeletes(ctx, blkID, txn, view.BaseView, mp); err != nil { 591 return 592 } 593 return 594 } 595 596 func (blk *baseObject) ResolvePersistedColumnData( 597 ctx context.Context, 598 txn txnif.TxnReader, 599 readSchema *catalog.Schema, 600 blkID uint16, 601 colIdx int, 602 skipDeletes bool, 603 mp *mpool.MPool, 604 ) (view *containers.ColumnView, err error) { 605 view = containers.NewColumnView(colIdx) 606 vec, err := blk.LoadPersistedColumnData(context.Background(), readSchema, colIdx, mp, blkID) 607 if err != nil { 608 return 609 } 610 view.SetData(vec) 611 612 if skipDeletes { 613 return 614 } 615 616 defer func() { 617 if err != nil { 618 view.Close() 619 } 620 }() 621 622 if err = blk.FillPersistedDeletes(ctx, blkID, txn, view.BaseView, mp); err != nil { 623 return 624 } 625 626 blk.RLock() 627 err = blk.fillInMemoryDeletesLocked(txn, blkID, view.BaseView, blk.RWMutex) 628 blk.RUnlock() 629 return 630 } 631 632 func (blk *baseObject) dedupWithLoad( 633 ctx context.Context, 634 txn txnif.TxnReader, 635 keys containers.Vector, 636 sels *nulls.Bitmap, 637 rowmask *roaring.Bitmap, 638 blkOffset uint16, 639 isAblk bool, 640 mp *mpool.MPool, 641 ) (err error) { 642 schema := blk.meta.GetSchema() 643 def := schema.GetSingleSortKey() 644 view, err := blk.ResolvePersistedColumnData( 645 ctx, 646 txn, 647 schema, 648 blkOffset, 649 def.Idx, 650 false, 651 mp, 652 ) 653 if err != nil { 654 return err 655 } 656 if rowmask != nil { 657 if view.DeleteMask == nil { 658 view.DeleteMask = common.RoaringToMOBitmap(rowmask) 659 } else { 660 common.MOOrRoaringBitmap(view.DeleteMask, rowmask) 661 } 662 } 663 defer view.Close() 664 var dedupFn any 665 if isAblk { 666 dedupFn = containers.MakeForeachVectorOp( 667 keys.GetType().Oid, dedupAlkFunctions, view.GetData(), view.DeleteMask, def, blk.LoadPersistedCommitTS, txn, 668 ) 669 } else { 670 dedupFn = containers.MakeForeachVectorOp( 671 keys.GetType().Oid, dedupNABlkFunctions, view.GetData(), view.DeleteMask, def, 672 ) 673 } 674 err = containers.ForeachVector(keys, dedupFn, sels) 675 return 676 } 677 678 func (blk *baseObject) PersistedBatchDedup( 679 ctx context.Context, 680 txn txnif.TxnReader, 681 isCommitting bool, 682 keys containers.Vector, 683 keysZM index.ZM, 684 rowmask *roaring.Bitmap, 685 isAblk bool, 686 bf objectio.BloomFilter, 687 mp *mpool.MPool, 688 ) (err error) { 689 pkIndex, err := MakeImmuIndex( 690 ctx, 691 blk.meta, 692 bf, 693 blk.rt, 694 ) 695 if err != nil { 696 return 697 } 698 for i := 0; i < blk.meta.BlockCnt(); i++ { 699 sels, err := pkIndex.BatchDedup( 700 ctx, 701 keys, 702 keysZM, 703 blk.rt, 704 uint32(i), 705 ) 706 if err == nil || !moerr.IsMoErrCode(err, moerr.OkExpectedPossibleDup) { 707 continue 708 } 709 err = blk.dedupWithLoad(ctx, txn, keys, sels, rowmask, uint16(i), isAblk, mp) 710 if err != nil { 711 return err 712 } 713 } 714 return nil 715 } 716 717 func (blk *baseObject) getPersistedValue( 718 ctx context.Context, 719 txn txnif.TxnReader, 720 schema *catalog.Schema, 721 blkID uint16, 722 row, col int, 723 skipMemory bool, 724 mp *mpool.MPool, 725 ) (v any, isNull bool, err error) { 726 view := containers.NewColumnView(col) 727 if err = blk.FillPersistedDeletes(ctx, blkID, txn, view.BaseView, mp); err != nil { 728 return 729 } 730 if !skipMemory { 731 blk.RLock() 732 err = blk.fillInMemoryDeletesLocked(txn, blkID, view.BaseView, blk.RWMutex) 733 blk.RUnlock() 734 if err != nil { 735 return 736 } 737 } 738 if view.DeleteMask.Contains(uint64(row)) { 739 err = moerr.NewNotFoundNoCtx() 740 return 741 } 742 view2, err := blk.ResolvePersistedColumnData(ctx, txn, schema, blkID, col, true, mp) 743 if err != nil { 744 return 745 } 746 defer view2.Close() 747 v, isNull = view2.GetValue(row) 748 return 749 } 750 751 func (blk *baseObject) DeletesInfo() string { 752 blk.RLock() 753 defer blk.RUnlock() 754 mvcc := blk.tryGetMVCC() 755 if mvcc == nil { 756 return "" 757 } 758 return mvcc.StringLocked(1, 0, "") 759 } 760 761 func (blk *baseObject) RangeDelete( 762 txn txnif.AsyncTxn, 763 blkID uint16, 764 start, end uint32, 765 pk containers.Vector, 766 dt handle.DeleteType) (node txnif.DeleteNode, err error) { 767 blk.Lock() 768 defer blk.Unlock() 769 blkMVCC := blk.getOrCreateMVCC().GetOrCreateDeleteChainLocked(blkID) 770 if err = blkMVCC.CheckNotDeleted(start, end, txn.GetStartTS()); err != nil { 771 return 772 } 773 node = blkMVCC.CreateDeleteNode(txn, dt) 774 node.RangeDeleteLocked(start, end, pk, common.MutMemAllocator) 775 return 776 } 777 778 func (blk *baseObject) TryDeleteByDeltaloc( 779 txn txnif.AsyncTxn, 780 blkID uint16, 781 deltaLoc objectio.Location) (node txnif.TxnEntry, ok bool, err error) { 782 if blk.meta.IsAppendable() { 783 return 784 } 785 blk.Lock() 786 defer blk.Unlock() 787 blkMVCC := blk.getOrCreateMVCC().GetOrCreateDeleteChainLocked(blkID) 788 return blkMVCC.TryDeleteByDeltalocLocked(txn, deltaLoc, true) 789 } 790 791 func (blk *baseObject) PPString(level common.PPLevel, depth int, prefix string, blkid int) string { 792 rows, err := blk.Rows() 793 if err != nil { 794 logutil.Warnf("get object rows failed, obj: %v, err: %v", blk.meta.ID.String(), err) 795 } 796 s := fmt.Sprintf("%s | [Rows=%d]", blk.meta.PPString(level, depth, prefix), rows) 797 if level >= common.PPL1 { 798 blk.RLock() 799 var appendstr, deletestr string 800 if blk.appendMVCC != nil { 801 appendstr = blk.appendMVCC.StringLocked() 802 } 803 if mvcc := blk.tryGetMVCC(); mvcc != nil { 804 if blkid >= 0 { 805 deletestr = mvcc.StringBlkLocked(level, 0, "", blkid) 806 } else { 807 deletestr = mvcc.StringLocked(level, 0, "") 808 } 809 } 810 blk.RUnlock() 811 if appendstr != "" { 812 s = fmt.Sprintf("%s\n Appends: %s", s, appendstr) 813 } 814 if deletestr != "" { 815 s = fmt.Sprintf("%s\n Deletes: %s", s, deletestr) 816 } 817 } 818 return s 819 } 820 821 func (blk *baseObject) HasDeleteIntentsPreparedIn(from, to types.TS) (found, isPersist bool) { 822 blk.RLock() 823 defer blk.RUnlock() 824 mvcc := blk.tryGetMVCC() 825 if mvcc == nil { 826 return 827 } 828 return mvcc.HasDeleteIntentsPreparedIn(from, to) 829 } 830 func (blk *baseObject) HasDeleteIntentsPreparedInByBlock(blkID uint16, from, to types.TS) (found, isPersist bool) { 831 blk.RLock() 832 defer blk.RUnlock() 833 mvcc := blk.tryGetMVCC() 834 if mvcc == nil { 835 return 836 } 837 return mvcc.HasInMemoryDeleteIntentsPreparedInByBlock(blkID, from, to) 838 } 839 func (blk *baseObject) CollectChangesInRange( 840 ctx context.Context, 841 blkID uint16, 842 startTs, endTs types.TS, 843 mp *mpool.MPool, 844 ) (view *containers.BlockView, err error) { 845 view = containers.NewBlockView() 846 view.DeleteMask, err = blk.inMemoryCollectDeletesInRange(blkID, startTs, endTs) 847 blk.fillPersistedDeletesInRange(ctx, blkID, startTs, endTs, view.BaseView, mp) 848 return 849 } 850 851 func (blk *baseObject) inMemoryCollectDeletesInRange(blkID uint16, start, end types.TS) (deletes *nulls.Bitmap, err error) { 852 blk.RLock() 853 defer blk.RUnlock() 854 mvcc := blk.tryGetMVCC() 855 if mvcc == nil { 856 return 857 } 858 blkMvcc := mvcc.TryGetDeleteChain(blkID) 859 if blkMvcc == nil { 860 return 861 } 862 deleteChain := blkMvcc.GetDeleteChain() 863 deletes, err = 864 deleteChain.CollectDeletesInRangeWithLock(start, end, blk.RWMutex) 865 return 866 } 867 868 func (blk *baseObject) CollectDeleteInRange( 869 ctx context.Context, 870 start, end types.TS, 871 withAborted bool, 872 mp *mpool.MPool, 873 ) (bat *containers.Batch, emtpyDelBlkIdx *bitmap.Bitmap, err error) { 874 emtpyDelBlkIdx = &bitmap.Bitmap{} 875 emtpyDelBlkIdx.InitWithSize(int64(blk.meta.BlockCnt())) 876 for blkID := uint16(0); blkID < uint16(blk.meta.BlockCnt()); blkID++ { 877 deletes, err := blk.CollectDeleteInRangeByBlock(ctx, blkID, start, end, withAborted, mp) 878 if err != nil { 879 return nil, nil, err 880 } 881 if deletes == nil || deletes.Length() == 0 { 882 emtpyDelBlkIdx.Add(uint64(blkID)) 883 } else { 884 if bat == nil { 885 bat = containers.NewBatch() 886 bat.AddVector(catalog.AttrRowID, containers.MakeVector(types.T_Rowid.ToType(), mp)) 887 bat.AddVector(catalog.AttrCommitTs, containers.MakeVector(types.T_TS.ToType(), mp)) 888 bat.AddVector(catalog.AttrPKVal, containers.MakeVector(*deletes.GetVectorByName(catalog.AttrPKVal).GetType(), mp)) 889 if withAborted { 890 bat.AddVector(catalog.AttrAborted, containers.MakeVector(types.T_bool.ToType(), mp)) 891 } 892 } 893 bat.Extend(deletes) 894 deletes.Close() 895 } 896 } 897 return 898 } 899 900 func (blk *baseObject) CollectDeleteInRangeByBlock( 901 ctx context.Context, 902 blkID uint16, 903 start, end types.TS, 904 withAborted bool, 905 mp *mpool.MPool) (*containers.Batch, error) { 906 deletes, minTS, _, err := blk.inMemoryCollectDeleteInRange( 907 ctx, 908 blkID, 909 start, 910 end, 911 withAborted, 912 mp, 913 ) 914 if err != nil { 915 if deletes != nil { 916 deletes.Close() 917 } 918 return nil, err 919 } 920 currentEnd := end 921 if !minTS.IsEmpty() && currentEnd.Greater(&minTS) { 922 currentEnd = minTS.Prev() 923 } 924 deletes, err = blk.PersistedCollectDeleteInRange( 925 ctx, 926 deletes, 927 blkID, 928 start, 929 currentEnd, 930 withAborted, 931 mp, 932 ) 933 if err != nil { 934 if deletes != nil { 935 deletes.Close() 936 } 937 return nil, err 938 } 939 return deletes, nil 940 } 941 942 func (blk *baseObject) inMemoryCollectDeleteInRange( 943 ctx context.Context, 944 blkID uint16, 945 start, end types.TS, 946 withAborted bool, 947 mp *mpool.MPool, 948 ) (bat *containers.Batch, minTS, persistedTS types.TS, err error) { 949 blk.RLock() 950 objMVCC := blk.tryGetMVCC() 951 if objMVCC == nil { 952 blk.RUnlock() 953 return 954 } 955 mvcc := objMVCC.TryGetDeleteChain(blkID) 956 blk.RUnlock() 957 if mvcc == nil { 958 return 959 } 960 return mvcc.InMemoryCollectDeleteInRange(ctx, start, end, withAborted, mp) 961 } 962 963 // collect the row if its committs is in [start,end] 964 func (blk *baseObject) PersistedCollectDeleteInRange( 965 ctx context.Context, 966 b *containers.Batch, 967 blkID uint16, 968 start, end types.TS, 969 withAborted bool, 970 mp *mpool.MPool, 971 ) (bat *containers.Batch, err error) { 972 if b != nil { 973 bat = b 974 } 975 t := types.T_int32.ToType() 976 sels := blk.rt.VectorPool.Transient.GetVector(&t) 977 defer sels.Close() 978 selsVec := sels.GetDownstreamVector() 979 blk.foreachPersistedDeletesCommittedInRange( 980 ctx, 981 start, end, 982 blkID, 983 !withAborted, 984 func(row int, rowIdVec *vector.Vector) { 985 _ = vector.AppendFixed[int32](selsVec, int32(row), false, mp) 986 }, 987 func(delBat *containers.Batch) { 988 if sels.Length() == 0 { 989 return 990 } 991 if bat == nil { 992 bat = containers.NewBatchWithCapacity(len(delBat.Attrs)) 993 for i, name := range delBat.Attrs { 994 if !withAborted && name == catalog.AttrAborted { 995 continue 996 } 997 bat.AddVector( 998 name, 999 blk.rt.VectorPool.Transient.GetVector(delBat.Vecs[i].GetType()), 1000 ) 1001 } 1002 } 1003 for _, name := range bat.Attrs { 1004 retVec := bat.GetVectorByName(name) 1005 srcVec := delBat.GetVectorByName(name) 1006 retVec.PreExtend(sels.Length()) 1007 retVec.GetDownstreamVector().Union( 1008 srcVec.GetDownstreamVector(), 1009 vector.MustFixedCol[int32](sels.GetDownstreamVector()), 1010 retVec.GetAllocator(), 1011 ) 1012 } 1013 }, 1014 mp, 1015 ) 1016 return bat, nil 1017 } 1018 1019 func (blk *baseObject) OnReplayDelete(blkID uint16, node txnif.DeleteNode) (err error) { 1020 blk.getOrCreateMVCC().GetOrCreateDeleteChainLocked(blkID).OnReplayDeleteNode(node) 1021 err = node.OnApply() 1022 return 1023 } 1024 1025 func (blk *baseObject) OnReplayAppend(_ txnif.AppendNode) (err error) { 1026 panic("not supported") 1027 } 1028 1029 func (blk *baseObject) OnReplayAppendPayload(_ *containers.Batch) (err error) { 1030 panic("not supported") 1031 } 1032 1033 func (blk *baseObject) MakeAppender() (appender data.ObjectAppender, err error) { 1034 panic("not supported") 1035 } 1036 1037 func (blk *baseObject) GetTotalChanges() int { 1038 blk.RLock() 1039 defer blk.RUnlock() 1040 objMVCC := blk.tryGetMVCC() 1041 if objMVCC == nil { 1042 return 0 1043 } 1044 return int(objMVCC.GetDeleteCnt()) 1045 } 1046 1047 func (blk *baseObject) IsAppendable() bool { return false } 1048 1049 func (blk *baseObject) MutationInfo() string { 1050 rows, err := blk.Rows() 1051 blk.RLock() 1052 defer blk.RUnlock() 1053 if err != nil { 1054 logutil.Warnf("get object rows failed, obj: %v, err %v", blk.meta.ID.String(), err) 1055 } 1056 objMVCC := blk.tryGetMVCC() 1057 var deleteCnt uint32 1058 if objMVCC != nil { 1059 deleteCnt = objMVCC.GetDeleteCnt() 1060 } 1061 s := fmt.Sprintf("Block %s Mutation Info: Changes=%d/%d", 1062 blk.meta.AsCommonID().BlockString(), 1063 deleteCnt, 1064 rows) 1065 return s 1066 } 1067 1068 func (blk *baseObject) CollectAppendInRange( 1069 start, end types.TS, withAborted bool, mp *mpool.MPool, 1070 ) (*containers.BatchWithVersion, error) { 1071 return nil, nil 1072 } 1073 1074 func (blk *baseObject) UpdateDeltaLoc(txn txnif.TxnReader, blkID uint16, deltaLoc objectio.Location) (bool, txnif.TxnEntry, error) { 1075 blk.Lock() 1076 defer blk.Unlock() 1077 mvcc := blk.getOrCreateMVCC().GetOrCreateDeleteChainLocked(blkID) 1078 return mvcc.UpdateDeltaLocLocked(txn, deltaLoc, false) 1079 } 1080 1081 func (blk *baseObject) GetDeltaPersistedTS() types.TS { 1082 blk.RLock() 1083 defer blk.RUnlock() 1084 objMVCC := blk.tryGetMVCC() 1085 if objMVCC == nil { 1086 return types.TS{} 1087 } 1088 return objMVCC.GetDeltaPersistedTS() 1089 }