github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/txn/txnimpl/txndb.go (about) 1 // Copyright 2022 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 txnimpl 16 17 import ( 18 "context" 19 "sync" 20 "time" 21 22 "github.com/matrixorigin/matrixone/pkg/common/moerr" 23 "github.com/matrixorigin/matrixone/pkg/logutil" 24 "github.com/matrixorigin/matrixone/pkg/objectio" 25 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/catalog" 26 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common" 27 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers" 28 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/handle" 29 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/txnif" 30 ) 31 32 type txnDB struct { 33 store *txnStore 34 tables map[uint64]*txnTable 35 mu sync.RWMutex 36 entry *catalog.DBEntry 37 createEntry txnif.TxnEntry 38 dropEntry txnif.TxnEntry 39 ddlCSN uint32 40 idx int 41 } 42 43 func newTxnDB(store *txnStore, entry *catalog.DBEntry) *txnDB { 44 db := &txnDB{ 45 store: store, 46 tables: make(map[uint64]*txnTable), 47 entry: entry, 48 } 49 return db 50 } 51 52 func (db *txnDB) SetCreateEntry(e txnif.TxnEntry) error { 53 if db.createEntry != nil { 54 panic("logic error") 55 } 56 db.store.IncreateWriteCnt() 57 db.store.txn.GetMemo().AddCatalogChange() 58 db.createEntry = e 59 return nil 60 } 61 62 func (db *txnDB) SetDropEntry(e txnif.TxnEntry) error { 63 if db.dropEntry != nil { 64 panic("logic error") 65 } 66 db.store.IncreateWriteCnt() 67 db.store.txn.GetMemo().AddCatalogChange() 68 db.dropEntry = e 69 return nil 70 } 71 72 func (db *txnDB) LogTxnEntry(tableId uint64, entry txnif.TxnEntry, readed []*common.ID) (err error) { 73 table, err := db.getOrSetTable(tableId) 74 if err != nil { 75 return 76 } 77 return table.LogTxnEntry(entry, readed) 78 } 79 80 func (db *txnDB) Close() error { 81 var err error 82 for _, table := range db.tables { 83 if err = table.Close(); err != nil { 84 break 85 } 86 } 87 db.tables = nil 88 db.createEntry = nil 89 db.dropEntry = nil 90 return err 91 } 92 93 func (db *txnDB) BatchDedup(id uint64, pk containers.Vector) (err error) { 94 table, err := db.getOrSetTable(id) 95 if err != nil { 96 return err 97 } 98 if table.IsDeleted() { 99 return moerr.NewNotFoundNoCtx() 100 } 101 102 return table.DoBatchDedup(pk) 103 } 104 105 func (db *txnDB) Append(ctx context.Context, id uint64, bat *containers.Batch) error { 106 table, err := db.getOrSetTable(id) 107 if err != nil { 108 return err 109 } 110 if table.IsDeleted() { 111 return moerr.NewNotFoundNoCtx() 112 } 113 return table.Append(ctx, bat) 114 } 115 116 func (db *txnDB) AddObjsWithMetaLoc( 117 ctx context.Context, 118 tid uint64, 119 stats containers.Vector) error { 120 table, err := db.getOrSetTable(tid) 121 if err != nil { 122 return err 123 } 124 if table.IsDeleted() { 125 return moerr.NewNotFoundNoCtx() 126 } 127 return table.AddObjsWithMetaLoc(ctx, stats) 128 } 129 130 // func (db *txnDB) DeleteOne(table *txnTable, id *common.ID, row uint32, dt handle.DeleteType) (err error) { 131 // changed, nid, nrow, err := table.TransferDeleteIntent(id, row) 132 // if err != nil { 133 // return err 134 // } 135 // if !changed { 136 // return table.RangeDelete(id, row, row, dt) 137 // } 138 // return table.RangeDelete(nid, nrow, nrow, dt) 139 // } 140 141 func (db *txnDB) RangeDelete( 142 id *common.ID, start, end uint32, 143 pkVec containers.Vector, dt handle.DeleteType, 144 ) (err error) { 145 table, err := db.getOrSetTable(id.TableID) 146 if err != nil { 147 return err 148 } 149 if table.IsDeleted() { 150 return moerr.NewNotFoundNoCtx() 151 } 152 return table.RangeDelete(id, start, end, pkVec, dt) 153 } 154 155 func (db *txnDB) TryDeleteByDeltaloc( 156 id *common.ID, deltaloc objectio.Location, 157 ) (ok bool, err error) { 158 table, err := db.getOrSetTable(id.TableID) 159 if err != nil { 160 return 161 } 162 if table.IsDeleted() { 163 return false, moerr.NewNotFoundNoCtx() 164 } 165 return table.TryDeleteByDeltaloc(id, deltaloc) 166 } 167 168 func (db *txnDB) GetByFilter(ctx context.Context, tid uint64, filter *handle.Filter) (id *common.ID, offset uint32, err error) { 169 table, err := db.getOrSetTable(tid) 170 if err != nil { 171 return 172 } 173 if table.IsDeleted() { 174 err = moerr.NewNotFoundNoCtx() 175 return 176 } 177 return table.GetByFilter(ctx, filter) 178 } 179 180 func (db *txnDB) GetValue(id *common.ID, row uint32, colIdx uint16) (v any, isNull bool, err error) { 181 table, err := db.getOrSetTable(id.TableID) 182 if err != nil { 183 return 184 } 185 if table.IsDeleted() { 186 err = moerr.NewNotFoundNoCtx() 187 return 188 } 189 return table.GetValue(context.Background(), id, row, colIdx) 190 } 191 192 func (db *txnDB) CreateRelation(def any) (relation handle.Relation, err error) { 193 schema := def.(*catalog.Schema) 194 var factory catalog.TableDataFactory 195 if db.store.dataFactory != nil { 196 factory = db.store.dataFactory.MakeTableFactory() 197 } 198 meta, err := db.entry.CreateTableEntry(schema, db.store.txn, factory) 199 if err != nil { 200 return 201 } 202 table, err := db.getOrSetTable(meta.GetID()) 203 if err != nil { 204 return 205 } 206 relation = newRelation(table) 207 table.SetCreateEntry(meta) 208 return 209 } 210 211 func (db *txnDB) CreateRelationWithTableId(tableId uint64, def any) (relation handle.Relation, err error) { 212 schema := def.(*catalog.Schema) 213 var factory catalog.TableDataFactory 214 if db.store.dataFactory != nil { 215 factory = db.store.dataFactory.MakeTableFactory() 216 } 217 meta, err := db.entry.CreateTableEntryWithTableId(schema, db.store.txn, factory, tableId) 218 if err != nil { 219 return 220 } 221 table, err := db.getOrSetTable(meta.GetID()) 222 if err != nil { 223 return 224 } 225 relation = newRelation(table) 226 table.SetCreateEntry(meta) 227 return 228 } 229 230 func (db *txnDB) DropRelationByName(name string) (relation handle.Relation, err error) { 231 hasNewTxnEntry, meta, err := db.entry.DropTableEntry(name, db.store.txn) 232 if err != nil { 233 return nil, err 234 } 235 table, err := db.getOrSetTable(meta.GetID()) 236 if err != nil { 237 return nil, err 238 } 239 relation = newRelation(table) 240 if hasNewTxnEntry { 241 err = table.SetDropEntry(meta) 242 } 243 return 244 } 245 246 func (db *txnDB) DropRelationByID(id uint64) (relation handle.Relation, err error) { 247 hasNewTxnEntry, meta, err := db.entry.DropTableEntryByID(id, db.store.txn) 248 if err != nil { 249 return nil, err 250 } 251 table, err := db.getOrSetTable(meta.GetID()) 252 if err != nil { 253 return nil, err 254 } 255 relation = newRelation(table) 256 if hasNewTxnEntry { 257 err = table.SetDropEntry(meta) 258 } 259 return 260 } 261 262 func (db *txnDB) UnsafeGetRelation(id uint64) (relation handle.Relation, err error) { 263 meta, err := db.entry.GetTableEntryByID(id) 264 if err != nil { 265 return 266 } 267 table, err := db.getOrSetTable(meta.GetID()) 268 if err != nil { 269 return 270 } 271 relation = newRelation(table) 272 return 273 } 274 275 func (db *txnDB) GetRelationByName(name string) (relation handle.Relation, err error) { 276 meta, err := db.entry.TxnGetTableEntryByName(name, db.store.txn) 277 if err != nil { 278 return 279 } 280 table, err := db.getOrSetTable(meta.GetID()) 281 if err != nil { 282 return 283 } 284 relation = newRelation(table) 285 return 286 } 287 288 func (db *txnDB) GetRelationByID(id uint64) (relation handle.Relation, err error) { 289 meta, err := db.entry.TxnGetTableEntryByID(id, db.store.txn) 290 if err != nil { 291 return 292 } 293 table, err := db.getOrSetTable(meta.GetID()) 294 if err != nil { 295 return 296 } 297 relation = newRelation(table) 298 return 299 } 300 301 func (db *txnDB) GetObject(id *common.ID) (obj handle.Object, err error) { 302 var table *txnTable 303 if table, err = db.getOrSetTable(id.TableID); err != nil { 304 return 305 } 306 return table.GetObject(id.ObjectID()) 307 } 308 309 func (db *txnDB) CreateObject(tid uint64, is1PC bool) (obj handle.Object, err error) { 310 var table *txnTable 311 if table, err = db.getOrSetTable(tid); err != nil { 312 return 313 } 314 return table.CreateObject(is1PC) 315 } 316 func (db *txnDB) CreateNonAppendableObject(tid uint64, is1PC bool, opt *objectio.CreateObjOpt) (obj handle.Object, err error) { 317 var table *txnTable 318 if table, err = db.getOrSetTable(tid); err != nil { 319 return 320 } 321 return table.CreateNonAppendableObject(is1PC, opt) 322 } 323 324 func (db *txnDB) UpdateObjectStats(id *common.ID, stats *objectio.ObjectStats) error { 325 table, err := db.getOrSetTable(id.TableID) 326 if err != nil { 327 return err 328 } 329 table.UpdateObjectStats(id, stats) 330 return nil 331 } 332 func (db *txnDB) getOrSetTable(id uint64) (table *txnTable, err error) { 333 db.mu.RLock() 334 table = db.tables[id] 335 db.mu.RUnlock() 336 if table != nil { 337 return 338 } 339 var entry *catalog.TableEntry 340 if entry, err = db.entry.GetTableEntryByID(id); err != nil { 341 return 342 } 343 db.mu.Lock() 344 defer db.mu.Unlock() 345 table = db.tables[id] 346 if table != nil { 347 return 348 } 349 if db.store.warChecker == nil { 350 db.store.warChecker = newWarChecker(db.store.txn, db.store.catalog) 351 } 352 table, err = newTxnTable(db.store, entry) 353 if err != nil { 354 return 355 } 356 table.idx = len(db.tables) 357 db.tables[id] = table 358 return 359 } 360 361 func (db *txnDB) UpdateDeltaLoc(id *common.ID, deltaLoc objectio.Location) (err error) { 362 var table *txnTable 363 if table, err = db.getOrSetTable(id.TableID); err != nil { 364 return 365 } 366 return table.UpdateDeltaLoc(id, deltaLoc) 367 } 368 func (db *txnDB) SoftDeleteObject(id *common.ID) (err error) { 369 var table *txnTable 370 if table, err = db.getOrSetTable(id.TableID); err != nil { 371 return 372 } 373 return table.SoftDeleteObject(id.ObjectID()) 374 } 375 func (db *txnDB) NeedRollback() bool { 376 return db.createEntry != nil && db.dropEntry != nil 377 } 378 func (db *txnDB) ApplyRollback() (err error) { 379 if db.createEntry != nil { 380 if err = db.createEntry.ApplyRollback(); err != nil { 381 return 382 } 383 } 384 for _, table := range db.tables { 385 if err = table.ApplyRollback(); err != nil { 386 break 387 } 388 } 389 if db.dropEntry != nil { 390 if err = db.dropEntry.ApplyRollback(); err != nil { 391 return 392 } 393 } 394 return 395 } 396 397 func (db *txnDB) WaitPrepared() (err error) { 398 for _, table := range db.tables { 399 table.WaitSynced() 400 } 401 return 402 } 403 func (db *txnDB) Apply1PCCommit() (err error) { 404 if db.createEntry != nil && db.createEntry.Is1PC() { 405 if err = db.createEntry.ApplyCommit(); err != nil { 406 return 407 } 408 } 409 for _, table := range db.tables { 410 if err = table.Apply1PCCommit(); err != nil { 411 break 412 } 413 } 414 if db.dropEntry != nil && db.dropEntry.Is1PC() { 415 if err = db.dropEntry.ApplyCommit(); err != nil { 416 return 417 } 418 } 419 return 420 } 421 func (db *txnDB) ApplyCommit() (err error) { 422 now := time.Now() 423 if db.createEntry != nil && !db.createEntry.Is1PC() { 424 if err = db.createEntry.ApplyCommit(); err != nil { 425 return 426 } 427 } 428 for _, table := range db.tables { 429 if err = table.ApplyCommit(); err != nil { 430 break 431 } 432 } 433 if db.dropEntry != nil && !db.dropEntry.Is1PC() { 434 if err = db.dropEntry.ApplyCommit(); err != nil { 435 return 436 } 437 } 438 common.DoIfDebugEnabled(func() { 439 logutil.Debugf("Txn-%X ApplyCommit Takes %s", db.store.txn.GetID(), time.Since(now)) 440 }) 441 return 442 } 443 444 func (db *txnDB) Freeze() (err error) { 445 for _, table := range db.tables { 446 if table.NeedRollback() { 447 if err = table.PrepareRollback(); err != nil { 448 return 449 } 450 delete(db.tables, table.GetID()) 451 } 452 } 453 for _, table := range db.tables { 454 if err = table.PrePreareTransfer(txnif.FreezePhase, table.store.rt.Now()); err != nil { 455 return 456 } 457 } 458 return 459 } 460 461 func (db *txnDB) PrePrepare(ctx context.Context) (err error) { 462 for _, table := range db.tables { 463 if err = table.PrePreareTransfer(txnif.PrePreparePhase, table.store.rt.Now()); err != nil { 464 return 465 } 466 } 467 for _, table := range db.tables { 468 if err = table.PrePrepareDedup(ctx); err != nil { 469 return 470 } 471 } 472 for _, table := range db.tables { 473 if err = table.PrePrepare(); err != nil { 474 return 475 } 476 } 477 return 478 } 479 480 func (db *txnDB) PrepareCommit() (err error) { 481 now := time.Now() 482 if db.createEntry != nil { 483 if err = db.createEntry.PrepareCommit(); err != nil { 484 return 485 } 486 } 487 for _, table := range db.tables { 488 if err = table.PrepareCommit(); err != nil { 489 break 490 } 491 } 492 if db.dropEntry != nil { 493 if err = db.dropEntry.PrepareCommit(); err != nil { 494 return 495 } 496 } 497 498 common.DoIfDebugEnabled(func() { 499 logutil.Debugf("Txn-%X PrepareCommit Takes %s", db.store.txn.GetID(), time.Since(now)) 500 }) 501 502 return 503 } 504 505 func (db *txnDB) PreApplyCommit() (err error) { 506 for _, table := range db.tables { 507 // table.ApplyAppend() 508 if err = table.PreApplyCommit(); err != nil { 509 return 510 } 511 } 512 return 513 } 514 515 func (db *txnDB) CollectCmd(cmdMgr *commandManager) (err error) { 516 if db.createEntry != nil { 517 csn := cmdMgr.GetCSN() 518 entry := db.createEntry 519 cmd, err := entry.MakeCommand(csn) 520 if err != nil { 521 panic(err) 522 } 523 cmdMgr.AddCmd(cmd) 524 db.ddlCSN = csn 525 } 526 tables := make([]*txnTable, len(db.tables)) 527 for _, table := range db.tables { 528 tables[table.idx] = table 529 } 530 for _, table := range tables { 531 if err = table.CollectCmd(cmdMgr); err != nil { 532 return 533 } 534 } 535 if db.dropEntry != nil { 536 csn := cmdMgr.GetCSN() 537 cmd, err := db.dropEntry.MakeCommand(csn) 538 if err != nil { 539 panic(err) 540 } 541 cmdMgr.AddCmd(cmd) 542 db.ddlCSN = csn 543 } 544 return 545 } 546 547 func (db *txnDB) AddTxnEntry(t txnif.TxnEntryType, entry txnif.TxnEntry) { 548 // TODO 549 } 550 551 func (db *txnDB) PrepareRollback() error { 552 var err error 553 if db.createEntry != nil { 554 if err := db.createEntry.PrepareRollback(); err != nil { 555 return err 556 } 557 } 558 for _, table := range db.tables { 559 if err = table.PrepareRollback(); err != nil { 560 break 561 } 562 } 563 if db.dropEntry != nil { 564 if err := db.dropEntry.PrepareRollback(); err != nil { 565 return err 566 } 567 } 568 569 return err 570 } 571 572 func (db *txnDB) CleanUp() { 573 for _, tbl := range db.tables { 574 tbl.CleanUp() 575 } 576 }