github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/catalog/catalogreplay.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 package catalog 15 16 import ( 17 pkgcatalog "github.com/matrixorigin/matrixone/pkg/catalog" 18 "github.com/matrixorigin/matrixone/pkg/common/moerr" 19 "github.com/matrixorigin/matrixone/pkg/container/types" 20 "github.com/matrixorigin/matrixone/pkg/logutil" 21 "github.com/matrixorigin/matrixone/pkg/objectio" 22 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common" 23 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers" 24 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/data" 25 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/txnif" 26 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/txn/txnbase" 27 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/wal" 28 29 "go.uber.org/zap" 30 ) 31 32 //#region Replay related 33 34 func (catalog *Catalog) ReplayCmd( 35 txncmd txnif.TxnCmd, 36 dataFactory DataFactory, 37 observer wal.ReplayObserver) { 38 switch txncmd.GetType() { 39 case txnbase.IOET_WALTxnCommand_Composed: 40 cmds := txncmd.(*txnbase.ComposedCmd) 41 for _, cmds := range cmds.Cmds { 42 catalog.ReplayCmd(cmds, dataFactory, observer) 43 } 44 case IOET_WALTxnCommand_Database: 45 cmd := txncmd.(*EntryCommand[*EmptyMVCCNode, *DBNode]) 46 catalog.onReplayUpdateDatabase(cmd, observer) 47 case IOET_WALTxnCommand_Table: 48 cmd := txncmd.(*EntryCommand[*TableMVCCNode, *TableNode]) 49 catalog.onReplayUpdateTable(cmd, dataFactory, observer) 50 case IOET_WALTxnCommand_Object: 51 cmd := txncmd.(*EntryCommand[*ObjectMVCCNode, *ObjectNode]) 52 catalog.onReplayUpdateObject(cmd, dataFactory, observer) 53 case IOET_WALTxnCommand_Block: 54 cmd := txncmd.(*EntryCommand[*MetadataMVCCNode, *BlockNode]) 55 catalog.onReplayUpdateBlock(cmd, dataFactory, observer) 56 case IOET_WALTxnCommand_Segment: 57 // segment is deprecated 58 return 59 default: 60 panic("unsupport") 61 } 62 } 63 64 func (catalog *Catalog) onReplayUpdateDatabase(cmd *EntryCommand[*EmptyMVCCNode, *DBNode], observer wal.ReplayObserver) { 65 catalog.OnReplayDBID(cmd.ID.DbID) 66 var err error 67 un := cmd.mvccNode 68 if un.Is1PC() { 69 if err := un.ApplyCommit(); err != nil { 70 panic(err) 71 } 72 } 73 74 db, err := catalog.GetDatabaseByID(cmd.ID.DbID) 75 if err != nil { 76 db = NewReplayDBEntry() 77 db.ID = cmd.ID.DbID 78 db.catalog = catalog 79 db.DBNode = cmd.node 80 db.Insert(un) 81 err = catalog.AddEntryLocked(db, un.GetTxn(), false) 82 if err != nil { 83 panic(err) 84 } 85 return 86 } 87 88 dbun := db.SearchNodeLocked(un) 89 if dbun == nil { 90 db.Insert(un) 91 } else { 92 return 93 // panic(fmt.Sprintf("logic err: duplicate node %v and %v", dbun.String(), un.String())) 94 } 95 } 96 97 func (catalog *Catalog) OnReplayDatabaseBatch(ins, insTxn, del, delTxn *containers.Batch) { 98 for i := 0; i < ins.Length(); i++ { 99 dbid := ins.GetVectorByName(pkgcatalog.SystemDBAttr_ID).Get(i).(uint64) 100 name := string(ins.GetVectorByName(pkgcatalog.SystemDBAttr_Name).Get(i).([]byte)) 101 txnNode := txnbase.ReadTuple(insTxn, i) 102 tenantID := ins.GetVectorByName(pkgcatalog.SystemDBAttr_AccID).Get(i).(uint32) 103 userID := ins.GetVectorByName(pkgcatalog.SystemDBAttr_Creator).Get(i).(uint32) 104 roleID := ins.GetVectorByName(pkgcatalog.SystemDBAttr_Owner).Get(i).(uint32) 105 createAt := ins.GetVectorByName(pkgcatalog.SystemDBAttr_CreateAt).Get(i).(types.Timestamp) 106 createSql := string(ins.GetVectorByName(pkgcatalog.SystemDBAttr_CreateSQL).Get(i).([]byte)) 107 datType := string(ins.GetVectorByName(pkgcatalog.SystemDBAttr_Type).Get(i).([]byte)) 108 catalog.onReplayCreateDB(dbid, name, txnNode, tenantID, userID, roleID, createAt, createSql, datType) 109 } 110 for i := 0; i < del.Length(); i++ { 111 dbid := delTxn.GetVectorByName(SnapshotAttr_DBID).Get(i).(uint64) 112 txnNode := txnbase.ReadTuple(delTxn, i) 113 catalog.onReplayDeleteDB(dbid, txnNode) 114 } 115 } 116 117 func (catalog *Catalog) onReplayCreateDB( 118 dbid uint64, name string, txnNode *txnbase.TxnMVCCNode, 119 tenantID, userID, roleID uint32, createAt types.Timestamp, createSql, datType string) { 120 catalog.OnReplayDBID(dbid) 121 db, _ := catalog.GetDatabaseByID(dbid) 122 if db != nil { 123 dbCreatedAt := db.GetCreatedAtLocked() 124 if !dbCreatedAt.Equal(&txnNode.End) { 125 panic(moerr.NewInternalErrorNoCtx("logic err expect %s, get %s", 126 txnNode.End.ToString(), dbCreatedAt.ToString())) 127 } 128 return 129 } 130 db = NewReplayDBEntry() 131 db.catalog = catalog 132 db.ID = dbid 133 db.DBNode = &DBNode{ 134 acInfo: accessInfo{ 135 TenantID: tenantID, 136 UserID: userID, 137 RoleID: roleID, 138 CreateAt: createAt, 139 }, 140 createSql: createSql, 141 datType: datType, 142 name: name, 143 } 144 _ = catalog.AddEntryLocked(db, nil, true) 145 un := &MVCCNode[*EmptyMVCCNode]{ 146 EntryMVCCNode: &EntryMVCCNode{ 147 CreatedAt: txnNode.End, 148 }, 149 TxnMVCCNode: txnNode, 150 } 151 db.Insert(un) 152 } 153 func (catalog *Catalog) onReplayDeleteDB(dbid uint64, txnNode *txnbase.TxnMVCCNode) { 154 catalog.OnReplayDBID(dbid) 155 db, err := catalog.GetDatabaseByID(dbid) 156 if err != nil { 157 logutil.Info("delete %d", zap.Uint64("dbid", dbid), zap.String("catalog pp", catalog.SimplePPString(common.PPL3))) 158 panic(err) 159 } 160 dbDeleteAt := db.GetDeleteAtLocked() 161 if !dbDeleteAt.IsEmpty() { 162 if !dbDeleteAt.Equal(&txnNode.End) { 163 panic(moerr.NewInternalErrorNoCtx("logic err expect %s, get %s", txnNode.End.ToString(), dbDeleteAt.ToString())) 164 } 165 return 166 } 167 prev := db.MVCCChain.GetLatestNodeLocked() 168 un := &MVCCNode[*EmptyMVCCNode]{ 169 EntryMVCCNode: &EntryMVCCNode{ 170 CreatedAt: db.GetCreatedAtLocked(), 171 DeletedAt: txnNode.End, 172 }, 173 TxnMVCCNode: txnNode, 174 BaseNode: prev.BaseNode.CloneAll(), 175 } 176 db.Insert(un) 177 } 178 func (catalog *Catalog) onReplayUpdateTable(cmd *EntryCommand[*TableMVCCNode, *TableNode], dataFactory DataFactory, observer wal.ReplayObserver) { 179 catalog.OnReplayTableID(cmd.ID.TableID) 180 // prepareTS := cmd.GetTs() 181 // if prepareTS.LessEq(catalog.GetCheckpointed().MaxTS) { 182 // if observer != nil { 183 // observer.OnStaleIndex(idx) 184 // } 185 // return 186 // } 187 db, err := catalog.GetDatabaseByID(cmd.ID.DbID) 188 if err != nil { 189 panic(err) 190 } 191 tbl, err := db.GetTableEntryByID(cmd.ID.TableID) 192 193 un := cmd.mvccNode 194 if un.Is1PC() { 195 if err := un.ApplyCommit(); err != nil { 196 panic(err) 197 } 198 } 199 200 if err != nil { 201 tbl = NewReplayTableEntry() 202 tbl.ID = cmd.ID.TableID 203 tbl.db = db 204 tbl.tableData = dataFactory.MakeTableFactory()(tbl) 205 tbl.TableNode = cmd.node 206 tbl.TableNode.schema.Store(un.BaseNode.Schema) 207 tbl.Insert(un) 208 err = db.AddEntryLocked(tbl, un.GetTxn(), true) 209 if err != nil { 210 logutil.Warn(catalog.SimplePPString(common.PPL3)) 211 panic(err) 212 } 213 return 214 } 215 tblun := tbl.SearchNodeLocked(un) 216 if tblun == nil { 217 tbl.Insert(un) //TODO isvalid 218 if tbl.isColumnChangedInSchema() { 219 tbl.FreezeAppend() 220 } 221 schema := un.BaseNode.Schema 222 tbl.TableNode.schema.Store(schema) 223 // alter table rename 224 if schema.Extra.OldName != "" && un.DeletedAt.IsEmpty() { 225 err := tbl.db.RenameTableInTxn(schema.Extra.OldName, schema.Name, tbl.ID, schema.AcInfo.TenantID, un.GetTxn(), true) 226 if err != nil { 227 logutil.Warn(schema.String()) 228 panic(err) 229 } 230 } 231 } 232 233 } 234 235 func (catalog *Catalog) OnReplayTableBatch(ins, insTxn, insCol, del, delTxn *containers.Batch, dataFactory DataFactory) { 236 schemaOffset := 0 237 for i := 0; i < ins.Length(); i++ { 238 tid := ins.GetVectorByName(pkgcatalog.SystemRelAttr_ID).Get(i).(uint64) 239 dbid := ins.GetVectorByName(pkgcatalog.SystemRelAttr_DBID).Get(i).(uint64) 240 name := string(ins.GetVectorByName(pkgcatalog.SystemRelAttr_Name).Get(i).([]byte)) 241 schema := NewEmptySchema(name) 242 schemaOffset = schema.ReadFromBatch(insCol, schemaOffset, tid) 243 schema.Comment = string(ins.GetVectorByName(pkgcatalog.SystemRelAttr_Comment).Get(i).([]byte)) 244 schema.Version = ins.GetVectorByName(pkgcatalog.SystemRelAttr_Version).Get(i).(uint32) 245 schema.CatalogVersion = ins.GetVectorByName(pkgcatalog.SystemRelAttr_CatalogVersion).Get(i).(uint32) 246 schema.Partitioned = ins.GetVectorByName(pkgcatalog.SystemRelAttr_Partitioned).Get(i).(int8) 247 schema.Partition = string(ins.GetVectorByName(pkgcatalog.SystemRelAttr_Partition).Get(i).([]byte)) 248 schema.Relkind = string(ins.GetVectorByName(pkgcatalog.SystemRelAttr_Kind).Get(i).([]byte)) 249 schema.Createsql = string(ins.GetVectorByName(pkgcatalog.SystemRelAttr_CreateSQL).Get(i).([]byte)) 250 schema.View = string(ins.GetVectorByName(pkgcatalog.SystemRelAttr_ViewDef).Get(i).([]byte)) 251 schema.Constraint = ins.GetVectorByName(pkgcatalog.SystemRelAttr_Constraint).Get(i).([]byte) 252 schema.AcInfo = accessInfo{} 253 schema.AcInfo.RoleID = ins.GetVectorByName(pkgcatalog.SystemRelAttr_Owner).Get(i).(uint32) 254 schema.AcInfo.UserID = ins.GetVectorByName(pkgcatalog.SystemRelAttr_Creator).Get(i).(uint32) 255 schema.AcInfo.CreateAt = ins.GetVectorByName(pkgcatalog.SystemRelAttr_CreateAt).Get(i).(types.Timestamp) 256 schema.AcInfo.TenantID = ins.GetVectorByName(pkgcatalog.SystemRelAttr_AccID).Get(i).(uint32) 257 schema.BlockMaxRows = insTxn.GetVectorByName(SnapshotAttr_BlockMaxRow).Get(i).(uint32) 258 schema.ObjectMaxBlocks = insTxn.GetVectorByName(SnapshotAttr_ObjectMaxBlock).Get(i).(uint16) 259 extra := insTxn.GetVectorByName(SnapshotAttr_SchemaExtra).Get(i).([]byte) 260 schema.MustRestoreExtra(extra) 261 schema.Finalize(true) 262 txnNode := txnbase.ReadTuple(insTxn, i) 263 catalog.onReplayCreateTable(dbid, tid, schema, txnNode, dataFactory) 264 } 265 for i := 0; i < del.Length(); i++ { 266 dbid := delTxn.GetVectorByName(SnapshotAttr_DBID).Get(i).(uint64) 267 tid := delTxn.GetVectorByName(SnapshotAttr_TID).Get(i).(uint64) 268 txnNode := txnbase.ReadTuple(delTxn, i) 269 catalog.onReplayDeleteTable(dbid, tid, txnNode) 270 } 271 } 272 273 func (catalog *Catalog) onReplayCreateTable(dbid, tid uint64, schema *Schema, txnNode *txnbase.TxnMVCCNode, dataFactory DataFactory) { 274 catalog.OnReplayTableID(tid) 275 db, err := catalog.GetDatabaseByID(dbid) 276 if err != nil { 277 logutil.Info(catalog.SimplePPString(common.PPL3)) 278 panic(err) 279 } 280 tbl, _ := db.GetTableEntryByID(tid) 281 if tbl != nil { 282 tblCreatedAt := tbl.GetCreatedAtLocked() 283 if tblCreatedAt.Greater(&txnNode.End) { 284 panic(moerr.NewInternalErrorNoCtx("logic err expect %s, get %s", txnNode.End.ToString(), tblCreatedAt.ToString())) 285 } 286 // alter table 287 un := &MVCCNode[*TableMVCCNode]{ 288 EntryMVCCNode: &EntryMVCCNode{ 289 CreatedAt: tblCreatedAt, 290 }, 291 TxnMVCCNode: txnNode, 292 BaseNode: &TableMVCCNode{ 293 Schema: schema, 294 }, 295 } 296 tbl.Insert(un) 297 if tbl.isColumnChangedInSchema() { 298 tbl.FreezeAppend() 299 } 300 tbl.TableNode.schema.Store(schema) 301 if schema.Extra.OldName != "" { 302 logutil.Infof("replay rename %v from %v -> %v", tid, schema.Extra.OldName, schema.Name) 303 err := tbl.db.RenameTableInTxn(schema.Extra.OldName, schema.Name, tbl.ID, schema.AcInfo.TenantID, un.GetTxn(), true) 304 if err != nil { 305 logutil.Warn(schema.String()) 306 panic(err) 307 } 308 } 309 310 return 311 } 312 tbl = NewReplayTableEntry() 313 tbl.TableNode = &TableNode{} 314 tbl.TableNode.schema.Store(schema) 315 tbl.db = db 316 tbl.ID = tid 317 tbl.tableData = dataFactory.MakeTableFactory()(tbl) 318 _ = db.AddEntryLocked(tbl, nil, true) 319 un := &MVCCNode[*TableMVCCNode]{ 320 EntryMVCCNode: &EntryMVCCNode{ 321 CreatedAt: txnNode.End, 322 }, 323 TxnMVCCNode: txnNode, 324 BaseNode: &TableMVCCNode{ 325 Schema: schema, 326 }, 327 } 328 tbl.Insert(un) 329 } 330 func (catalog *Catalog) onReplayDeleteTable(dbid, tid uint64, txnNode *txnbase.TxnMVCCNode) { 331 catalog.OnReplayTableID(tid) 332 db, err := catalog.GetDatabaseByID(dbid) 333 if err != nil { 334 logutil.Info(catalog.SimplePPString(common.PPL3)) 335 panic(err) 336 } 337 tbl, err := db.GetTableEntryByID(tid) 338 if err != nil { 339 logutil.Info(catalog.SimplePPString(common.PPL3)) 340 panic(err) 341 } 342 tableDeleteAt := tbl.GetDeleteAtLocked() 343 if !tableDeleteAt.IsEmpty() { 344 if !tableDeleteAt.Equal(&txnNode.End) { 345 panic(moerr.NewInternalErrorNoCtx("logic err expect %s, get %s", txnNode.End.ToString(), tableDeleteAt.ToString())) 346 } 347 return 348 } 349 prev := tbl.MVCCChain.GetLatestCommittedNodeLocked() 350 un := &MVCCNode[*TableMVCCNode]{ 351 EntryMVCCNode: &EntryMVCCNode{ 352 CreatedAt: prev.CreatedAt, 353 DeletedAt: txnNode.End, 354 }, 355 TxnMVCCNode: txnNode, 356 BaseNode: prev.BaseNode.CloneAll(), 357 } 358 tbl.Insert(un) 359 360 } 361 func (catalog *Catalog) onReplayUpdateObject( 362 cmd *EntryCommand[*ObjectMVCCNode, *ObjectNode], 363 dataFactory DataFactory, 364 observer wal.ReplayObserver) { 365 catalog.OnReplayObjectID(cmd.node.SortHint) 366 367 db, err := catalog.GetDatabaseByID(cmd.ID.DbID) 368 if err != nil { 369 panic(err) 370 } 371 tbl, err := db.GetTableEntryByID(cmd.ID.TableID) 372 if err != nil { 373 logutil.Debugf("tbl %d-%d", cmd.ID.DbID, cmd.ID.TableID) 374 logutil.Info(catalog.SimplePPString(3)) 375 panic(err) 376 } 377 obj, err := tbl.GetObjectByID(cmd.ID.ObjectID()) 378 un := cmd.mvccNode 379 if un.Is1PC() { 380 if err := un.ApplyCommit(); err != nil { 381 panic(err) 382 } 383 } 384 if err != nil { 385 obj = NewReplayObjectEntry() 386 obj.ID = *cmd.ID.ObjectID() 387 obj.table = tbl 388 obj.Insert(un) 389 obj.ObjectNode = cmd.node 390 tbl.AddEntryLocked(obj) 391 } else { 392 node := obj.SearchNodeLocked(un) 393 if node == nil { 394 obj.Insert(un) 395 } else { 396 node.BaseNode.Update(un.BaseNode) 397 } 398 } 399 if obj.objData == nil { 400 obj.objData = dataFactory.MakeObjectFactory()(obj) 401 } else { 402 deleteAt := obj.GetDeleteAtLocked() 403 if !obj.IsAppendable() || (obj.IsAppendable() && !deleteAt.IsEmpty()) { 404 obj.objData.TryUpgrade() 405 obj.objData.UpgradeAllDeleteChain() 406 } 407 } 408 } 409 410 func (catalog *Catalog) OnReplayObjectBatch(objectInfo *containers.Batch, dataFactory DataFactory) { 411 dbidVec := objectInfo.GetVectorByName(SnapshotAttr_DBID) 412 for i := 0; i < dbidVec.Length(); i++ { 413 dbid := objectInfo.GetVectorByName(SnapshotAttr_DBID).Get(i).(uint64) 414 tid := objectInfo.GetVectorByName(SnapshotAttr_TID).Get(i).(uint64) 415 objectNode := ReadObjectInfoTuple(objectInfo, i) 416 sid := objectNode.ObjectName().ObjectId() 417 txnNode := txnbase.ReadTuple(objectInfo, i) 418 entryNode := ReadEntryNodeTuple(objectInfo, i) 419 state := objectInfo.GetVectorByName(ObjectAttr_State).Get(i).(bool) 420 entryState := ES_Appendable 421 if !state { 422 entryState = ES_NotAppendable 423 } 424 catalog.onReplayCheckpointObject(dbid, tid, sid, objectNode, entryNode, txnNode, entryState, dataFactory) 425 } 426 } 427 428 func (catalog *Catalog) onReplayCheckpointObject( 429 dbid, tbid uint64, 430 objid *types.Objectid, 431 objNode *ObjectMVCCNode, 432 entryNode *EntryMVCCNode, 433 txnNode *txnbase.TxnMVCCNode, 434 state EntryState, 435 dataFactory DataFactory, 436 ) { 437 db, err := catalog.GetDatabaseByID(dbid) 438 if err != nil { 439 logutil.Info(catalog.SimplePPString(common.PPL3)) 440 panic(err) 441 } 442 rel, err := db.GetTableEntryByID(tbid) 443 if err != nil { 444 logutil.Info(catalog.SimplePPString(common.PPL3)) 445 panic(err) 446 } 447 obj, _ := rel.GetObjectByID(objid) 448 if obj == nil { 449 obj = NewReplayObjectEntry() 450 obj.ID = *objid 451 obj.table = rel 452 obj.ObjectNode = &ObjectNode{ 453 state: state, 454 sorted: state == ES_NotAppendable, 455 SortHint: catalog.NextObject(), 456 } 457 rel.AddEntryLocked(obj) 458 } 459 un := &MVCCNode[*ObjectMVCCNode]{ 460 EntryMVCCNode: entryNode, 461 BaseNode: objNode, 462 TxnMVCCNode: txnNode, 463 } 464 node := obj.SearchNodeLocked(un) 465 if node == nil { 466 obj.Insert(un) 467 } else { 468 node.BaseNode.Update(un.BaseNode) 469 } 470 if obj.objData == nil { 471 obj.objData = dataFactory.MakeObjectFactory()(obj) 472 } else { 473 deleteAt := obj.GetDeleteAtLocked() 474 if !obj.IsAppendable() || (obj.IsAppendable() && !deleteAt.IsEmpty()) { 475 obj.objData.TryUpgrade() 476 obj.objData.UpgradeAllDeleteChain() 477 } 478 } 479 } 480 481 // Before ckp version 10 and IOET_WALTxnCommand_Object, object info doesn't exist. 482 // Replay Object by block. 483 // Original Size, Compressed Size and Block Number is skipped. 484 func (catalog *Catalog) replayObjectByBlock( 485 tbl *TableEntry, 486 blkID types.Blockid, 487 state EntryState, 488 start, end types.TS, 489 metaLocation objectio.Location, 490 needApplyCommit bool, 491 create, delete bool, 492 txn txnif.TxnReader, 493 dataFactory DataFactory) { 494 ObjectID := blkID.Object() 495 obj, _ := tbl.GetObjectByID(ObjectID) 496 // create 497 if create { 498 if obj == nil { 499 obj = NewObjectEntryByMetaLocation( 500 tbl, 501 ObjectID, 502 start, end, state, metaLocation, dataFactory.MakeObjectFactory()) 503 tbl.AddEntryLocked(obj) 504 } 505 } 506 // delete 507 if delete { 508 node := obj.SearchNodeLocked( 509 &MVCCNode[*ObjectMVCCNode]{ 510 TxnMVCCNode: &txnbase.TxnMVCCNode{ 511 Start: start, 512 }, 513 }, 514 ) 515 if node == nil { 516 node = obj.GetLatestNodeLocked().CloneData() 517 node.Start = start 518 node.Prepare = end 519 node.End = end 520 if node.BaseNode.IsEmpty() { 521 node.BaseNode = NewObjectInfoWithMetaLocation(metaLocation, ObjectID) 522 } 523 obj.Insert(node) 524 node.DeletedAt = end 525 } 526 } 527 _, blkOffset := blkID.Offsets() 528 obj.tryUpdateBlockCnt(int(blkOffset) + 1) 529 if obj.objData == nil { 530 obj.objData = dataFactory.MakeObjectFactory()(obj) 531 } else { 532 deleteAt := obj.GetDeleteAtLocked() 533 if !obj.IsAppendable() || (obj.IsAppendable() && !deleteAt.IsEmpty()) { 534 obj.objData.TryUpgrade() 535 obj.objData.UpgradeAllDeleteChain() 536 } 537 } 538 } 539 func (catalog *Catalog) onReplayUpdateBlock( 540 cmd *EntryCommand[*MetadataMVCCNode, *BlockNode], 541 dataFactory DataFactory, 542 observer wal.ReplayObserver) { 543 // catalog.OnReplayBlockID(cmd.ID.BlockID) 544 db, err := catalog.GetDatabaseByID(cmd.ID.DbID) 545 if err != nil { 546 panic(err) 547 } 548 tbl, err := db.GetTableEntryByID(cmd.ID.TableID) 549 if err != nil { 550 panic(err) 551 } 552 catalog.replayObjectByBlock( 553 tbl, 554 cmd.ID.BlockID, 555 cmd.node.state, 556 cmd.mvccNode.Start, 557 cmd.mvccNode.Prepare, 558 cmd.mvccNode.BaseNode.MetaLoc, 559 true, 560 cmd.mvccNode.CreatedAt.Equal(&txnif.UncommitTS), 561 cmd.mvccNode.DeletedAt.Equal(&txnif.UncommitTS), 562 cmd.mvccNode.Txn, 563 dataFactory) 564 if !cmd.mvccNode.BaseNode.DeltaLoc.IsEmpty() { 565 obj, err := tbl.GetObjectByID(cmd.ID.ObjectID()) 566 if err != nil { 567 panic(err) 568 } 569 tombstone := tbl.GetOrCreateTombstone(obj, dataFactory.MakeTombstoneFactory()) 570 _, blkOffset := cmd.ID.BlockID.Offsets() 571 tombstone.ReplayDeltaLoc(cmd.mvccNode, blkOffset) 572 } 573 } 574 575 func (catalog *Catalog) OnReplayBlockBatch(ins, insTxn, del, delTxn *containers.Batch, dataFactory DataFactory) { 576 for i := 0; i < ins.Length(); i++ { 577 dbid := insTxn.GetVectorByName(SnapshotAttr_DBID).Get(i).(uint64) 578 tid := insTxn.GetVectorByName(SnapshotAttr_TID).Get(i).(uint64) 579 appendable := ins.GetVectorByName(pkgcatalog.BlockMeta_EntryState).Get(i).(bool) 580 state := ES_NotAppendable 581 if appendable { 582 state = ES_Appendable 583 } 584 blkID := ins.GetVectorByName(pkgcatalog.BlockMeta_ID).Get(i).(types.Blockid) 585 sid := blkID.Object() 586 metaLoc := ins.GetVectorByName(pkgcatalog.BlockMeta_MetaLoc).Get(i).([]byte) 587 deltaLoc := ins.GetVectorByName(pkgcatalog.BlockMeta_DeltaLoc).Get(i).([]byte) 588 txnNode := txnbase.ReadTuple(insTxn, i) 589 catalog.onReplayCreateBlock(dbid, tid, sid, &blkID, state, metaLoc, deltaLoc, txnNode, dataFactory) 590 } 591 for i := 0; i < del.Length(); i++ { 592 dbid := delTxn.GetVectorByName(SnapshotAttr_DBID).Get(i).(uint64) 593 tid := delTxn.GetVectorByName(SnapshotAttr_TID).Get(i).(uint64) 594 rid := del.GetVectorByName(AttrRowID).Get(i).(types.Rowid) 595 blkID := rid.BorrowBlockID() 596 sid := rid.BorrowObjectID() 597 un := txnbase.ReadTuple(delTxn, i) 598 metaLoc := delTxn.GetVectorByName(pkgcatalog.BlockMeta_MetaLoc).Get(i).([]byte) 599 deltaLoc := delTxn.GetVectorByName(pkgcatalog.BlockMeta_DeltaLoc).Get(i).([]byte) 600 catalog.onReplayDeleteBlock(dbid, tid, sid, blkID, metaLoc, deltaLoc, un) 601 } 602 } 603 func (catalog *Catalog) onReplayCreateBlock( 604 dbid, tid uint64, 605 objid *types.Objectid, 606 blkid *types.Blockid, 607 state EntryState, 608 metaloc, deltaloc objectio.Location, 609 txnNode *txnbase.TxnMVCCNode, 610 dataFactory DataFactory) { 611 // catalog.OnReplayBlockID(blkid) 612 db, err := catalog.GetDatabaseByID(dbid) 613 if err != nil { 614 logutil.Info(catalog.SimplePPString(common.PPL3)) 615 panic(err) 616 } 617 rel, err := db.GetTableEntryByID(tid) 618 if err != nil { 619 logutil.Info(catalog.SimplePPString(common.PPL3)) 620 panic(err) 621 } 622 catalog.replayObjectByBlock( 623 rel, 624 *blkid, 625 state, 626 txnNode.Start, 627 txnNode.End, 628 metaloc, 629 false, 630 true, 631 false, 632 nil, 633 dataFactory) 634 if !deltaloc.IsEmpty() { 635 obj, err := rel.GetObjectByID(objid) 636 if err != nil { 637 panic(err) 638 } 639 tombstone := rel.GetOrCreateTombstone(obj, dataFactory.MakeTombstoneFactory()) 640 _, blkOffset := blkid.Offsets() 641 mvccNode := &MVCCNode[*MetadataMVCCNode]{ 642 EntryMVCCNode: &EntryMVCCNode{}, 643 TxnMVCCNode: txnNode, 644 BaseNode: &MetadataMVCCNode{ 645 DeltaLoc: deltaloc, 646 }, 647 } 648 tombstone.ReplayDeltaLoc(mvccNode, blkOffset) 649 } 650 } 651 652 func (catalog *Catalog) onReplayDeleteBlock( 653 dbid, tid uint64, 654 objid *types.Objectid, 655 blkid *types.Blockid, 656 metaloc, 657 deltaloc objectio.Location, 658 txnNode *txnbase.TxnMVCCNode, 659 ) { 660 // catalog.OnReplayBlockID(blkid) 661 db, err := catalog.GetDatabaseByID(dbid) 662 if err != nil { 663 logutil.Info(catalog.SimplePPString(common.PPL3)) 664 panic(err) 665 } 666 rel, err := db.GetTableEntryByID(tid) 667 if err != nil { 668 logutil.Info(catalog.SimplePPString(common.PPL3)) 669 panic(err) 670 } 671 catalog.replayObjectByBlock( 672 rel, 673 *blkid, 674 ES_Appendable, // state is not used when delete 675 txnNode.Start, 676 txnNode.End, 677 metaloc, 678 false, 679 false, 680 true, 681 nil, 682 nil) 683 } 684 func (catalog *Catalog) ReplayTableRows() { 685 rows := uint64(0) 686 tableProcessor := new(LoopProcessor) 687 tableProcessor.ObjectFn = func(be *ObjectEntry) error { 688 if !be.IsActive() { 689 return nil 690 } 691 rows += be.GetObjectData().GetRowsOnReplay() 692 return nil 693 } 694 tableProcessor.TombstoneFn = func(t data.Tombstone) error { 695 rows -= uint64(t.GetDeleteCnt()) 696 return nil 697 } 698 processor := new(LoopProcessor) 699 processor.TableFn = func(tbl *TableEntry) error { 700 if tbl.db.name == pkgcatalog.MO_CATALOG { 701 return nil 702 } 703 rows = 0 704 err := tbl.RecurLoop(tableProcessor) 705 if err != nil { 706 panic(err) 707 } 708 tbl.rows.Store(rows) 709 return nil 710 } 711 err := catalog.RecurLoop(processor) 712 if err != nil { 713 panic(err) 714 } 715 } 716 717 //#endregion