github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/rpc/rpc_test.go (about) 1 // Copyright 2021 - 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 rpc 16 17 import ( 18 "context" 19 "fmt" 20 catalog2 "github.com/matrixorigin/matrixone/pkg/catalog" 21 "github.com/matrixorigin/matrixone/pkg/container/types" 22 "github.com/matrixorigin/matrixone/pkg/defines" 23 "github.com/matrixorigin/matrixone/pkg/fileservice" 24 "github.com/matrixorigin/matrixone/pkg/objectio" 25 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/dataio/blockio" 26 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/mergesort" 27 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/tables/jobs" 28 "os" 29 "path" 30 "strconv" 31 "sync" 32 "testing" 33 "time" 34 35 "github.com/matrixorigin/matrixone/pkg/container/batch" 36 "github.com/matrixorigin/matrixone/pkg/container/vector" 37 "github.com/matrixorigin/matrixone/pkg/pb/api" 38 "github.com/matrixorigin/matrixone/pkg/pb/plan" 39 "github.com/matrixorigin/matrixone/pkg/vm/engine" 40 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/catalog" 41 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers" 42 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/moengine" 43 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/testutils" 44 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/testutils/config" 45 "github.com/stretchr/testify/assert" 46 ) 47 48 func TestHandle_HandlePreCommitWriteS3(t *testing.T) { 49 defer testutils.AfterTest(t)() 50 opts := config.WithLongScanAndCKPOpts(nil) 51 52 //create file service; 53 //dir := testutils.GetDefaultTestPath(ModuleName, t) 54 dir := "/tmp/s3" 55 dir = path.Join(dir, "/local") 56 //if dir exists, remove it. 57 os.RemoveAll(dir) 58 c := fileservice.Config{ 59 Name: defines.LocalFileServiceName, 60 Backend: "DISK", 61 DataDir: dir, 62 } 63 //create dir; 64 fs, err := fileservice.NewFileService(c) 65 assert.Nil(t, err) 66 opts.Fs = fs 67 handle := mockTAEHandle(t, opts) 68 defer handle.HandleClose(context.TODO()) 69 IDAlloc := catalog.NewIDAllocator() 70 txnEngine := handle.GetTxnEngine() 71 72 schema := catalog.MockSchema(2, 1) 73 schema.Name = "tbtest" 74 schema.BlockMaxRows = 10 75 schema.SegmentMaxBlocks = 2 76 taeBat := catalog.MockBatch(schema, 40) 77 defer taeBat.Close() 78 taeBats := taeBat.Split(4) 79 taeBats[0] = taeBats[0].CloneWindow(0, 10) 80 taeBats[1] = taeBats[1].CloneWindow(0, 10) 81 taeBats[2] = taeBats[2].CloneWindow(0, 10) 82 taeBats[3] = taeBats[3].CloneWindow(0, 10) 83 84 //sort by primary key 85 _, err = mergesort.SortBlockColumns(taeBats[0].Vecs, 1) 86 assert.Nil(t, err) 87 _, err = mergesort.SortBlockColumns(taeBats[1].Vecs, 1) 88 assert.Nil(t, err) 89 _, err = mergesort.SortBlockColumns(taeBats[2].Vecs, 1) 90 assert.Nil(t, err) 91 92 moBats := make([]*batch.Batch, 4) 93 moBats[0] = containers.CopyToMoBatch(taeBats[0]) 94 moBats[1] = containers.CopyToMoBatch(taeBats[1]) 95 moBats[2] = containers.CopyToMoBatch(taeBats[2]) 96 moBats[3] = containers.CopyToMoBatch(taeBats[3]) 97 98 //write taeBats[0], taeBats[1] two blocks into file service 99 id := 1 100 objName1 := fmt.Sprintf("%d.seg", id) 101 writer := blockio.NewWriter(context.Background(), 102 objectio.NewObjectFS(fs, "data"), objName1) 103 for i, bat := range taeBats { 104 if i == 2 { 105 break 106 } 107 block, err := writer.WriteBlock(bat) 108 assert.Nil(t, err) 109 err = jobs.BuildBlockIndex(writer.GetWriter(), block, 110 schema, bat, true) 111 assert.Nil(t, err) 112 } 113 blocks, err := writer.Sync() 114 assert.Nil(t, err) 115 assert.Equal(t, 2, len(blocks)) 116 metaLoc1, err := blockio.EncodeMetaLocWithObject( 117 blocks[0].GetExtent(), 118 uint32(taeBats[0].Vecs[0].Length()), 119 blocks, 120 ) 121 assert.Nil(t, err) 122 metaLoc2, err := blockio.EncodeMetaLocWithObject( 123 blocks[1].GetExtent(), 124 uint32(taeBats[1].Vecs[0].Length()), 125 blocks, 126 ) 127 assert.Nil(t, err) 128 129 //write taeBats[3] into file service 130 id += 1 131 objName2 := fmt.Sprintf("%d.seg", id) 132 writer = blockio.NewWriter(context.Background(), 133 objectio.NewObjectFS(fs, "data"), objName2) 134 block, err := writer.WriteBlock(taeBats[3]) 135 assert.Nil(t, err) 136 err = jobs.BuildBlockIndex(writer.GetWriter(), 137 block, schema, taeBats[3], true) 138 assert.Nil(t, err) 139 blocks, err = writer.Sync() 140 assert.Equal(t, 1, len(blocks)) 141 assert.Nil(t, err) 142 metaLoc3, err := blockio.EncodeMetaLocWithObject( 143 blocks[0].GetExtent(), 144 uint32(taeBats[3].Vecs[0].Length()), 145 blocks, 146 ) 147 assert.Nil(t, err) 148 149 //create db; 150 dbName := "dbtest" 151 ac := AccessInfo{ 152 accountId: 0, 153 userId: 0, 154 roleId: 0, 155 } 156 var entries []*api.Entry 157 txn := mock1PCTxn(txnEngine) 158 dbTestID := IDAlloc.NextDB() 159 createDbEntries, err := makeCreateDatabaseEntries( 160 "", 161 ac, 162 dbName, 163 dbTestID, 164 handle.m) 165 assert.Nil(t, err) 166 entries = append(entries, createDbEntries...) 167 //create table from "dbtest" 168 defs, err := moengine.SchemaToDefs(schema) 169 for i := 0; i < len(defs); i++ { 170 if attrdef, ok := defs[i].(*engine.AttributeDef); ok { 171 attrdef.Attr.Default = &plan.Default{ 172 NullAbility: true, 173 Expr: &plan.Expr{ 174 Expr: &plan.Expr_C{ 175 C: &plan.Const{ 176 Isnull: false, 177 Value: &plan.Const_Sval{ 178 Sval: "expr" + strconv.Itoa(i), 179 }, 180 }, 181 }, 182 }, 183 OriginString: "expr" + strconv.Itoa(i), 184 } 185 } 186 } 187 188 assert.Nil(t, err) 189 tbTestID := IDAlloc.NextTable() 190 createTbEntries, err := makeCreateTableEntries( 191 "", 192 ac, 193 schema.Name, 194 tbTestID, 195 dbTestID, 196 dbName, 197 handle.m, 198 defs, 199 ) 200 assert.Nil(t, err) 201 entries = append(entries, createTbEntries...) 202 //append data into "tbtest" table 203 insertEntry, err := makePBEntry(INSERT, dbTestID, 204 tbTestID, dbName, schema.Name, "", moBats[2]) 205 assert.NoError(t, err) 206 entries = append(entries, insertEntry) 207 208 //add two non-appendable blocks from S3 into "tbtest" table 209 attrs := []string{catalog2.BlockMeta_MetaLoc} 210 vecTypes := []types.Type{types.New(types.T_varchar, 211 types.MaxVarcharLen, 0, 0)} 212 nullable := []bool{false} 213 vecOpts := containers.Options{} 214 vecOpts.Capacity = 0 215 metaLocBat1 := containers.BuildBatch(attrs, vecTypes, nullable, vecOpts) 216 metaLocBat1.Vecs[0].Append([]byte(metaLoc1)) 217 metaLocBat1.Vecs[0].Append([]byte(metaLoc2)) 218 metaLocMoBat1 := containers.CopyToMoBatch(metaLocBat1) 219 addS3BlkEntry1, err := makePBEntry(INSERT, dbTestID, 220 tbTestID, dbName, schema.Name, objName1, metaLocMoBat1) 221 assert.NoError(t, err) 222 loc1 := vector.GetStrVectorValues(metaLocMoBat1.GetVector(0))[0] 223 loc2 := vector.GetStrVectorValues(metaLocMoBat1.GetVector(0))[1] 224 assert.Equal(t, metaLoc1, loc1) 225 assert.Equal(t, metaLoc2, loc2) 226 entries = append(entries, addS3BlkEntry1) 227 228 //add one non-appendable block from S3 into "tbtest" table 229 metaLocBat2 := containers.BuildBatch(attrs, vecTypes, nullable, vecOpts) 230 metaLocBat2.Vecs[0].Append([]byte(metaLoc3)) 231 metaLocMoBat2 := containers.CopyToMoBatch(metaLocBat2) 232 addS3BlkEntry2, err := makePBEntry(INSERT, dbTestID, 233 tbTestID, dbName, schema.Name, objName2, metaLocMoBat2) 234 assert.NoError(t, err) 235 entries = append(entries, addS3BlkEntry2) 236 237 err = handle.HandlePreCommit( 238 context.TODO(), 239 txn, 240 api.PrecommitWriteCmd{ 241 UserId: ac.userId, 242 AccountId: ac.accountId, 243 RoleId: ac.roleId, 244 EntryList: entries, 245 }, 246 new(api.SyncLogTailResp), 247 ) 248 assert.Nil(t, err) 249 //t.FailNow() 250 err = handle.HandleCommit(context.TODO(), txn) 251 assert.Nil(t, err) 252 //check rows of "tbtest" which should has three blocks. 253 txnR, err := txnEngine.StartTxn(nil) 254 assert.NoError(t, err) 255 dbHandle, err := txnEngine.GetDatabase(context.TODO(), dbName, txnR) 256 assert.NoError(t, err) 257 tbHandle, err := dbHandle.GetRelation(context.TODO(), schema.Name) 258 assert.NoError(t, err) 259 hideDef, err := tbHandle.GetHideKeys(context.TODO()) 260 assert.NoError(t, err) 261 blkReaders, _ := tbHandle.NewReader(context.TODO(), 1, nil, nil) 262 rows := 0 263 var hideBats []*batch.Batch 264 for i := 0; i < len(taeBats); i++ { 265 //read primary key column 266 bat, err := blkReaders[0].Read( 267 context.TODO(), 268 []string{schema.ColDefs[1].Name}, 269 nil, 270 handle.m) 271 assert.Nil(t, err) 272 if bat != nil { 273 rows += vector.Length(bat.Vecs[0]) 274 } 275 } 276 assert.Equal(t, taeBat.Length(), rows) 277 278 //read physical addr column 279 blkReaders, _ = tbHandle.NewReader(context.TODO(), 1, nil, nil) 280 for i := 0; i < len(taeBats); i++ { 281 hideBat, err := blkReaders[0].Read( 282 context.TODO(), 283 []string{hideDef[0].Name}, 284 nil, 285 handle.m, 286 ) 287 assert.Nil(t, err) 288 if hideBat != nil { 289 batch.SetLength(hideBat, 5) 290 hideBats = append(hideBats, hideBat) 291 } 292 } 293 assert.Equal(t, len(taeBats), len(hideBats)) 294 err = txnR.Commit() 295 assert.Nil(t, err) 296 297 //write deleted row ids into FS 298 id += 1 299 objName3 := fmt.Sprintf("%d.del", id) 300 writer = blockio.NewWriter(context.Background(), 301 objectio.NewObjectFS(fs, "data"), objName3) 302 for _, bat := range hideBats { 303 taeBat := toTAEBatchWithSharedMemory(schema, bat) 304 //defer taeBat.Close() 305 _, err := writer.WriteBlock(taeBat) 306 assert.Nil(t, err) 307 } 308 blocks, err = writer.Sync() 309 assert.Nil(t, err) 310 assert.Equal(t, len(hideBats), len(blocks)) 311 delLoc1, err := blockio.EncodeMetaLocWithObject( 312 blocks[0].GetExtent(), 313 uint32(hideBats[0].Vecs[0].Length()), 314 blocks, 315 ) 316 assert.Nil(t, err) 317 delLoc2, err := blockio.EncodeMetaLocWithObject( 318 blocks[1].GetExtent(), 319 uint32(hideBats[1].Vecs[0].Length()), 320 blocks, 321 ) 322 assert.Nil(t, err) 323 delLoc3, err := blockio.EncodeMetaLocWithObject( 324 blocks[2].GetExtent(), 325 uint32(hideBats[2].Vecs[0].Length()), 326 blocks, 327 ) 328 assert.Nil(t, err) 329 delLoc4, err := blockio.EncodeMetaLocWithObject( 330 blocks[3].GetExtent(), 331 uint32(hideBats[3].Vecs[0].Length()), 332 blocks, 333 ) 334 assert.Nil(t, err) 335 336 //prepare delete locations. 337 attrs = []string{catalog2.BlockMeta_DeltaLoc} 338 vecTypes = []types.Type{types.New(types.T_varchar, 339 types.MaxVarcharLen, 0, 0)} 340 nullable = []bool{false} 341 vecOpts = containers.Options{} 342 vecOpts.Capacity = 0 343 delLocBat := containers.BuildBatch(attrs, vecTypes, nullable, vecOpts) 344 delLocBat.Vecs[0].Append([]byte(delLoc1)) 345 delLocBat.Vecs[0].Append([]byte(delLoc2)) 346 delLocBat.Vecs[0].Append([]byte(delLoc3)) 347 delLocBat.Vecs[0].Append([]byte(delLoc4)) 348 349 delLocMoBat := containers.CopyToMoBatch(delLocBat) 350 var delApiEntries []*api.Entry 351 deleteS3BlkEntry, err := makePBEntry(DELETE, dbTestID, 352 tbTestID, dbName, schema.Name, objName3, delLocMoBat) 353 assert.NoError(t, err) 354 delApiEntries = append(delApiEntries, deleteS3BlkEntry) 355 356 txn = mock1PCTxn(txnEngine) 357 err = handle.HandlePreCommit( 358 context.TODO(), 359 txn, 360 api.PrecommitWriteCmd{ 361 UserId: ac.userId, 362 AccountId: ac.accountId, 363 RoleId: ac.roleId, 364 EntryList: delApiEntries, 365 }, 366 new(api.SyncLogTailResp), 367 ) 368 assert.Nil(t, err) 369 err = handle.HandleCommit(context.TODO(), txn) 370 assert.Nil(t, err) 371 //Now, the "tbtest" table has 20 rows left. 372 txnR, err = txnEngine.StartTxn(nil) 373 assert.NoError(t, err) 374 dbHandle, err = txnEngine.GetDatabase(context.TODO(), dbName, txnR) 375 assert.NoError(t, err) 376 tbHandle, err = dbHandle.GetRelation(context.TODO(), schema.Name) 377 assert.NoError(t, err) 378 blkReaders, _ = tbHandle.NewReader(context.TODO(), 1, nil, nil) 379 rows = 0 380 for i := 0; i < len(taeBats); i++ { 381 //read primary key column 382 bat, err := blkReaders[0].Read( 383 context.TODO(), 384 []string{schema.ColDefs[1].Name}, 385 nil, 386 handle.m) 387 assert.Nil(t, err) 388 if bat != nil { 389 rows += vector.Length(bat.Vecs[0]) 390 } 391 } 392 assert.Equal(t, len(taeBats)*taeBats[0].Length()-5*len(taeBats), rows) 393 err = txnR.Commit() 394 assert.Nil(t, err) 395 } 396 397 func TestHandle_HandlePreCommit1PC(t *testing.T) { 398 defer testutils.AfterTest(t)() 399 opts := config.WithLongScanAndCKPOpts(nil) 400 handle := mockTAEHandle(t, opts) 401 defer handle.HandleClose(context.TODO()) 402 IDAlloc := catalog.NewIDAllocator() 403 txnEngine := handle.GetTxnEngine() 404 schema := catalog.MockSchema(2, 1) 405 schema.Name = "tbtest" 406 schema.BlockMaxRows = 10 407 schema.SegmentMaxBlocks = 2 408 //DDL 409 //create db; 410 dbName := "dbtest" 411 ac := AccessInfo{ 412 accountId: 0, 413 userId: 0, 414 roleId: 0, 415 } 416 createDbEntries, err := makeCreateDatabaseEntries( 417 "", 418 ac, 419 dbName, 420 IDAlloc.NextDB(), 421 handle.m) 422 assert.Nil(t, err) 423 createDbTxn := mock1PCTxn(txnEngine) 424 err = handle.HandlePreCommit( 425 context.TODO(), 426 createDbTxn, 427 api.PrecommitWriteCmd{ 428 UserId: ac.userId, 429 AccountId: ac.accountId, 430 RoleId: ac.roleId, 431 EntryList: createDbEntries, 432 }, 433 new(api.SyncLogTailResp), 434 ) 435 assert.Nil(t, err) 436 err = handle.HandleCommit(context.TODO(), createDbTxn) 437 assert.Nil(t, err) 438 439 //start txn ,read "dbtest"'s ID 440 ctx := context.TODO() 441 txn, err := txnEngine.StartTxn(nil) 442 assert.Nil(t, err) 443 names, _ := txnEngine.DatabaseNames(ctx, txn) 444 assert.Equal(t, 2, len(names)) 445 dbHandle, err := txnEngine.GetDatabase(ctx, dbName, txn) 446 assert.Nil(t, err) 447 dbTestId := dbHandle.GetDatabaseID(ctx) 448 err = txn.Commit() 449 assert.Nil(t, err) 450 451 //create table from "dbtest" 452 defs, err := moengine.SchemaToDefs(schema) 453 for i := 0; i < len(defs); i++ { 454 if attrdef, ok := defs[i].(*engine.AttributeDef); ok { 455 attrdef.Attr.Default = &plan.Default{ 456 NullAbility: true, 457 Expr: &plan.Expr{ 458 Expr: &plan.Expr_C{ 459 C: &plan.Const{ 460 Isnull: false, 461 Value: &plan.Const_Sval{ 462 Sval: "expr" + strconv.Itoa(i), 463 }, 464 }, 465 }, 466 }, 467 OriginString: "expr" + strconv.Itoa(i), 468 } 469 } 470 } 471 assert.Nil(t, err) 472 473 createTbTxn := mock1PCTxn(txnEngine) 474 475 createTbEntries, err := makeCreateTableEntries( 476 "", 477 ac, 478 schema.Name, 479 IDAlloc.NextTable(), 480 dbTestId, 481 dbName, 482 handle.m, 483 defs, 484 ) 485 assert.Nil(t, err) 486 487 createTbEntries1, err := makeCreateTableEntries( 488 "", 489 ac, 490 "tbtest1", 491 IDAlloc.NextTable(), 492 dbTestId, 493 dbName, 494 handle.m, 495 defs, 496 ) 497 assert.Nil(t, err) 498 createTbEntries = append(createTbEntries, createTbEntries1...) 499 err = handle.HandlePreCommit( 500 context.TODO(), 501 createTbTxn, 502 api.PrecommitWriteCmd{ 503 UserId: ac.userId, 504 AccountId: ac.accountId, 505 RoleId: ac.roleId, 506 EntryList: createTbEntries, 507 }, 508 new(api.SyncLogTailResp)) 509 assert.Nil(t, err) 510 err = handle.HandleCommit(context.TODO(), createTbTxn) 511 assert.Nil(t, err) 512 //start txn ,read table ID 513 txn, err = txnEngine.StartTxn(nil) 514 assert.Nil(t, err) 515 dbHandle, err = txnEngine.GetDatabase(ctx, dbName, txn) 516 assert.NoError(t, err) 517 dbId := dbHandle.GetDatabaseID(ctx) 518 assert.True(t, dbTestId == dbId) 519 names, _ = dbHandle.RelationNames(ctx) 520 assert.Equal(t, 2, len(names)) 521 tbHandle, err := dbHandle.GetRelation(ctx, schema.Name) 522 assert.NoError(t, err) 523 tbTestId := tbHandle.GetRelationID(ctx) 524 rDefs, _ := tbHandle.TableDefs(ctx) 525 //assert.Equal(t, 3, len(rDefs)) 526 rAttr := rDefs[0].(*engine.AttributeDef).Attr 527 assert.Equal(t, true, rAttr.Default.NullAbility) 528 rAttr = rDefs[1].(*engine.AttributeDef).Attr 529 assert.Equal(t, "expr2", rAttr.Default.OriginString) 530 531 err = txn.Commit() 532 assert.NoError(t, err) 533 534 //DML: insert batch into table 535 insertTxn := mock1PCTxn(txnEngine) 536 moBat := containers.CopyToMoBatch(catalog.MockBatch(schema, 100)) 537 insertEntry, err := makePBEntry(INSERT, dbTestId, 538 tbTestId, dbName, schema.Name, "", moBat) 539 assert.NoError(t, err) 540 err = handle.HandlePreCommit( 541 context.TODO(), 542 insertTxn, 543 api.PrecommitWriteCmd{ 544 UserId: ac.userId, 545 AccountId: ac.accountId, 546 RoleId: ac.roleId, 547 EntryList: []*api.Entry{insertEntry}, 548 }, 549 new(api.SyncLogTailResp), 550 ) 551 assert.NoError(t, err) 552 // TODO:: Dml delete 553 //bat := batch.NewWithSize(1) 554 err = handle.HandleCommit(context.TODO(), insertTxn) 555 assert.NoError(t, err) 556 //TODO::DML:delete by primary key. 557 // physcial addr + primary key 558 //bat = batch.NewWithSize(2) 559 560 //start txn ,read table ID 561 txn, err = txnEngine.StartTxn(nil) 562 assert.NoError(t, err) 563 dbHandle, err = txnEngine.GetDatabase(ctx, dbName, txn) 564 assert.NoError(t, err) 565 tbHandle, err = dbHandle.GetRelation(ctx, schema.Name) 566 assert.NoError(t, err) 567 tbReaders, _ := tbHandle.NewReader(ctx, 1, nil, nil) 568 for _, reader := range tbReaders { 569 bat, err := reader.Read(ctx, []string{schema.ColDefs[1].Name}, nil, handle.m) 570 assert.Nil(t, err) 571 if bat != nil { 572 len := vector.Length(bat.Vecs[0]) 573 assert.Equal(t, 100, len) 574 } 575 } 576 // read row ids 577 hideCol, err := tbHandle.GetHideKeys(ctx) 578 assert.NoError(t, err) 579 reader, _ := tbHandle.NewReader(ctx, 1, nil, nil) 580 hideBat, err := reader[0].Read(ctx, []string{hideCol[0].Name}, nil, handle.m) 581 assert.Nil(t, err) 582 err = txn.Commit() 583 assert.Nil(t, err) 584 585 //delete 20 rows 586 deleteTxn := mock1PCTxn(handle.GetTxnEngine()) 587 batch.SetLength(hideBat, 20) 588 deleteEntry, _ := makePBEntry( 589 DELETE, 590 dbId, 591 tbTestId, 592 dbName, 593 schema.Name, 594 "", 595 hideBat, 596 ) 597 err = handle.HandlePreCommit( 598 context.TODO(), 599 deleteTxn, 600 api.PrecommitWriteCmd{ 601 UserId: ac.userId, 602 AccountId: ac.accountId, 603 RoleId: ac.roleId, 604 EntryList: append([]*api.Entry{}, deleteEntry), 605 }, 606 new(api.SyncLogTailResp), 607 ) 608 assert.Nil(t, err) 609 err = handle.HandleCommit(context.TODO(), deleteTxn) 610 assert.Nil(t, err) 611 //read, there should be 80 rows left. 612 txn, err = txnEngine.StartTxn(nil) 613 assert.NoError(t, err) 614 dbHandle, err = txnEngine.GetDatabase(ctx, dbName, txn) 615 assert.NoError(t, err) 616 tbHandle, err = dbHandle.GetRelation(ctx, schema.Name) 617 assert.NoError(t, err) 618 tbReaders, _ = tbHandle.NewReader(ctx, 2, nil, nil) 619 for _, reader := range tbReaders { 620 bat, err := reader.Read(ctx, []string{schema.ColDefs[1].Name}, nil, handle.m) 621 assert.Nil(t, err) 622 if bat != nil { 623 len := vector.Length(bat.Vecs[0]) 624 assert.Equal(t, 80, len) 625 } 626 } 627 err = txn.Commit() 628 assert.Nil(t, err) 629 } 630 631 func TestHandle_HandlePreCommit2PCForCoordinator(t *testing.T) { 632 defer testutils.AfterTest(t)() 633 opts := config.WithLongScanAndCKPOpts(nil) 634 handle := mockTAEHandle(t, opts) 635 defer handle.HandleClose(context.TODO()) 636 IDAlloc := catalog.NewIDAllocator() 637 txnEngine := handle.GetTxnEngine() 638 schema := catalog.MockSchema(2, -1) 639 schema.Name = "tbtest" 640 schema.BlockMaxRows = 10 641 schema.SegmentMaxBlocks = 2 642 dbName := "dbtest" 643 ac := AccessInfo{ 644 accountId: 0, 645 userId: 0, 646 roleId: 0, 647 } 648 //make create db cmd; 649 createDbEntries, err := makeCreateDatabaseEntries( 650 "", 651 ac, 652 dbName, 653 IDAlloc.NextDB(), 654 handle.m) 655 assert.Nil(t, err) 656 txnCmds := []txnCommand{ 657 { 658 typ: CmdPreCommitWrite, 659 cmd: api.PrecommitWriteCmd{ 660 UserId: ac.userId, 661 AccountId: ac.accountId, 662 RoleId: ac.roleId, 663 EntryList: createDbEntries}, 664 }, 665 {typ: CmdPrepare}, 666 {typ: CmdCommitting}, 667 {typ: CmdCommit}, 668 } 669 txnMeta := mock2PCTxn(txnEngine) 670 ctx := context.TODO() 671 err = handle.handleCmds(ctx, txnMeta, txnCmds) 672 assert.Nil(t, err) 673 674 //start 1pc txn ,read "dbtest"'s ID 675 ctx = context.TODO() 676 txn, err := txnEngine.StartTxn(nil) 677 assert.Nil(t, err) 678 names, _ := txnEngine.DatabaseNames(ctx, txn) 679 assert.Equal(t, 2, len(names)) 680 dbHandle, err := txnEngine.GetDatabase(ctx, dbName, txn) 681 assert.Nil(t, err) 682 dbTestId := dbHandle.GetDatabaseID(ctx) 683 err = txn.Commit() 684 assert.Nil(t, err) 685 686 //create table from "dbtest" 687 defs, err := moengine.SchemaToDefs(schema) 688 defs[0].(*engine.AttributeDef).Attr.Default = &plan.Default{ 689 NullAbility: true, 690 Expr: &plan.Expr{ 691 Expr: &plan.Expr_C{ 692 C: &plan.Const{ 693 Isnull: false, 694 Value: &plan.Const_Sval{ 695 Sval: "expr1", 696 }, 697 }, 698 }, 699 }, 700 OriginString: "expr1", 701 } 702 defs[1].(*engine.AttributeDef).Attr.Default = &plan.Default{ 703 NullAbility: false, 704 Expr: &plan.Expr{ 705 Expr: &plan.Expr_C{ 706 C: &plan.Const{ 707 Isnull: false, 708 Value: &plan.Const_Sval{ 709 Sval: "expr2", 710 }, 711 }, 712 }, 713 }, 714 OriginString: "expr2", 715 } 716 assert.Nil(t, err) 717 createTbEntries, err := makeCreateTableEntries( 718 "", 719 ac, 720 schema.Name, 721 IDAlloc.NextTable(), 722 dbTestId, 723 dbName, 724 handle.m, 725 defs, 726 ) 727 assert.Nil(t, err) 728 txnCmds = []txnCommand{ 729 { 730 typ: CmdPreCommitWrite, 731 cmd: api.PrecommitWriteCmd{ 732 UserId: ac.userId, 733 AccountId: ac.accountId, 734 RoleId: ac.roleId, 735 EntryList: createTbEntries}, 736 }, 737 {typ: CmdPrepare}, 738 {typ: CmdCommitting}, 739 {typ: CmdCommit}, 740 } 741 txnMeta = mock2PCTxn(txnEngine) 742 ctx = context.TODO() 743 err = handle.handleCmds(ctx, txnMeta, txnCmds) 744 assert.Nil(t, err) 745 746 //start 1pc txn ,read table ID 747 txn, err = txnEngine.StartTxn(nil) 748 assert.Nil(t, err) 749 dbHandle, err = txnEngine.GetDatabase(ctx, dbName, txn) 750 assert.NoError(t, err) 751 dbId := dbHandle.GetDatabaseID(ctx) 752 assert.True(t, dbTestId == dbId) 753 names, _ = dbHandle.RelationNames(ctx) 754 assert.Equal(t, 1, len(names)) 755 tbHandle, err := dbHandle.GetRelation(ctx, schema.Name) 756 assert.NoError(t, err) 757 tbTestId := tbHandle.GetRelationID(ctx) 758 rDefs, _ := tbHandle.TableDefs(ctx) 759 assert.Equal(t, 3, len(rDefs)) 760 rAttr := rDefs[0].(*engine.AttributeDef).Attr 761 assert.Equal(t, true, rAttr.Default.NullAbility) 762 rAttr = rDefs[1].(*engine.AttributeDef).Attr 763 assert.Equal(t, "expr2", rAttr.Default.OriginString) 764 err = txn.Commit() 765 assert.NoError(t, err) 766 767 //DML::insert batch into table 768 moBat := containers.CopyToMoBatch(catalog.MockBatch(schema, 100)) 769 insertEntry, err := makePBEntry(INSERT, dbTestId, 770 tbTestId, dbName, schema.Name, "", moBat) 771 assert.NoError(t, err) 772 txnCmds = []txnCommand{ 773 { 774 typ: CmdPreCommitWrite, 775 cmd: api.PrecommitWriteCmd{ 776 UserId: ac.userId, 777 AccountId: ac.accountId, 778 RoleId: ac.roleId, 779 EntryList: []*api.Entry{insertEntry}}, 780 }, 781 {typ: CmdPrepare}, 782 {typ: CmdCommitting}, 783 {typ: CmdCommit}, 784 } 785 insertTxn := mock2PCTxn(txnEngine) 786 ctx = context.TODO() 787 err = handle.handleCmds(ctx, insertTxn, txnCmds) 788 assert.Nil(t, err) 789 790 //start 2PC txn ,rollback it after prepared 791 rollbackTxn := mock2PCTxn(txnEngine) 792 //insert 20 rows, then rollback the txn 793 //FIXME::?? 794 //batch.SetLength(moBat, 20) 795 moBat = containers.CopyToMoBatch(catalog.MockBatch(schema, 20)) 796 insertEntry, err = makePBEntry(INSERT, dbTestId, 797 tbTestId, dbName, schema.Name, "", moBat) 798 assert.NoError(t, err) 799 txnCmds = []txnCommand{ 800 { 801 typ: CmdPreCommitWrite, 802 cmd: api.PrecommitWriteCmd{ 803 UserId: ac.userId, 804 AccountId: ac.accountId, 805 RoleId: ac.roleId, 806 EntryList: []*api.Entry{insertEntry}}, 807 }, 808 {typ: CmdPrepare}, 809 {typ: CmdRollback}, 810 } 811 ctx = context.TODO() 812 err = handle.handleCmds(ctx, rollbackTxn, txnCmds) 813 assert.Nil(t, err) 814 815 //start 1PC txn , read table 816 txn, err = txnEngine.StartTxn(nil) 817 assert.NoError(t, err) 818 dbHandle, err = txnEngine.GetDatabase(ctx, dbName, txn) 819 assert.NoError(t, err) 820 tbHandle, err = dbHandle.GetRelation(ctx, schema.Name) 821 assert.NoError(t, err) 822 tbReaders, _ := tbHandle.NewReader(ctx, 1, nil, nil) 823 for _, reader := range tbReaders { 824 bat, err := reader.Read(ctx, []string{schema.ColDefs[1].Name}, nil, handle.m) 825 assert.Nil(t, err) 826 if bat != nil { 827 len := vector.Length(bat.Vecs[0]) 828 assert.Equal(t, 100, len) 829 } 830 } 831 // read row ids 832 hideCol, err := tbHandle.GetHideKeys(ctx) 833 assert.NoError(t, err) 834 reader, _ := tbHandle.NewReader(ctx, 1, nil, nil) 835 hideBat, err := reader[0].Read(ctx, []string{hideCol[0].Name}, nil, handle.m) 836 assert.Nil(t, err) 837 err = txn.Commit() 838 assert.Nil(t, err) 839 840 hideBats := containers.SplitBatch(hideBat, 5) 841 //delete 20 rows by 2PC txn 842 //batch.SetLength(hideBats[0], 20) 843 deleteEntry, err := makePBEntry( 844 DELETE, 845 dbId, 846 tbTestId, 847 dbName, 848 schema.Name, 849 "", 850 hideBats[0], 851 ) 852 assert.Nil(t, err) 853 txnCmds = []txnCommand{ 854 { 855 typ: CmdPreCommitWrite, 856 cmd: api.PrecommitWriteCmd{ 857 UserId: ac.userId, 858 AccountId: ac.accountId, 859 RoleId: ac.roleId, 860 EntryList: []*api.Entry{deleteEntry}}, 861 }, 862 {typ: CmdPrepare}, 863 {typ: CmdCommitting}, 864 {typ: CmdCommit}, 865 } 866 deleteTxn := mock2PCTxn(txnEngine) 867 ctx = context.TODO() 868 err = handle.handleCmds(ctx, deleteTxn, txnCmds) 869 assert.Nil(t, err) 870 871 //start a 2PC txn ,rollback it after prepared. 872 rollbackTxn = mock2PCTxn(txnEngine) 873 deleteEntry, _ = makePBEntry( 874 DELETE, 875 dbId, 876 tbTestId, 877 dbName, 878 schema.Name, 879 "", 880 hideBats[1], 881 ) 882 txnCmds = []txnCommand{ 883 { 884 typ: CmdPreCommitWrite, 885 cmd: api.PrecommitWriteCmd{ 886 UserId: ac.userId, 887 AccountId: ac.accountId, 888 RoleId: ac.roleId, 889 EntryList: []*api.Entry{deleteEntry}}, 890 }, 891 {typ: CmdPrepare}, 892 {typ: CmdRollback}, 893 } 894 ctx = context.TODO() 895 err = handle.handleCmds(ctx, rollbackTxn, txnCmds) 896 assert.Nil(t, err) 897 898 //read, there should be 80 rows left. 899 txn, err = txnEngine.StartTxn(nil) 900 assert.NoError(t, err) 901 dbHandle, err = txnEngine.GetDatabase(ctx, dbName, txn) 902 assert.NoError(t, err) 903 tbHandle, err = dbHandle.GetRelation(ctx, schema.Name) 904 assert.NoError(t, err) 905 tbReaders, _ = tbHandle.NewReader(ctx, 2, nil, nil) 906 for _, reader := range tbReaders { 907 bat, err := reader.Read(ctx, []string{schema.ColDefs[1].Name}, nil, handle.m) 908 assert.Nil(t, err) 909 if bat != nil { 910 len := vector.Length(bat.Vecs[0]) 911 assert.Equal(t, 80, len) 912 } 913 } 914 err = txn.Commit() 915 assert.Nil(t, err) 916 } 917 918 func TestHandle_HandlePreCommit2PCForParticipant(t *testing.T) { 919 defer testutils.AfterTest(t)() 920 opts := config.WithLongScanAndCKPOpts(nil) 921 handle := mockTAEHandle(t, opts) 922 defer handle.HandleClose(context.TODO()) 923 IDAlloc := catalog.NewIDAllocator() 924 txnEngine := handle.GetTxnEngine() 925 schema := catalog.MockSchema(2, -1) 926 schema.Name = "tbtest" 927 schema.BlockMaxRows = 10 928 schema.SegmentMaxBlocks = 2 929 dbName := "dbtest" 930 ac := AccessInfo{ 931 accountId: 0, 932 userId: 0, 933 roleId: 0, 934 } 935 //make create db cmd; 936 createDbEntries, err := makeCreateDatabaseEntries( 937 "", 938 ac, 939 dbName, 940 IDAlloc.NextDB(), 941 handle.m) 942 assert.Nil(t, err) 943 txnCmds := []txnCommand{ 944 { 945 typ: CmdPreCommitWrite, 946 cmd: api.PrecommitWriteCmd{ 947 UserId: ac.userId, 948 AccountId: ac.accountId, 949 RoleId: ac.roleId, 950 EntryList: createDbEntries}, 951 }, 952 {typ: CmdPrepare}, 953 {typ: CmdCommit}, 954 } 955 txnMeta := mock2PCTxn(txnEngine) 956 ctx := context.TODO() 957 err = handle.handleCmds(ctx, txnMeta, txnCmds) 958 assert.Nil(t, err) 959 960 //start 1pc txn ,read "dbtest"'s ID 961 ctx = context.TODO() 962 txn, err := txnEngine.StartTxn(nil) 963 assert.Nil(t, err) 964 names, _ := txnEngine.DatabaseNames(ctx, txn) 965 assert.Equal(t, 2, len(names)) 966 dbHandle, err := txnEngine.GetDatabase(ctx, dbName, txn) 967 assert.Nil(t, err) 968 dbTestId := dbHandle.GetDatabaseID(ctx) 969 err = txn.Commit() 970 assert.Nil(t, err) 971 972 //create table from "dbtest" 973 defs, err := moengine.SchemaToDefs(schema) 974 defs[0].(*engine.AttributeDef).Attr.Default = &plan.Default{ 975 NullAbility: true, 976 Expr: &plan.Expr{ 977 Expr: &plan.Expr_C{ 978 C: &plan.Const{ 979 Isnull: false, 980 Value: &plan.Const_Sval{ 981 Sval: "expr1", 982 }, 983 }, 984 }, 985 }, 986 OriginString: "expr1", 987 } 988 defs[1].(*engine.AttributeDef).Attr.Default = &plan.Default{ 989 NullAbility: false, 990 Expr: &plan.Expr{ 991 Expr: &plan.Expr_C{ 992 C: &plan.Const{ 993 Isnull: false, 994 Value: &plan.Const_Sval{ 995 Sval: "expr2", 996 }, 997 }, 998 }, 999 }, 1000 OriginString: "expr2", 1001 } 1002 assert.Nil(t, err) 1003 createTbEntries, err := makeCreateTableEntries( 1004 "", 1005 ac, 1006 schema.Name, 1007 IDAlloc.NextTable(), 1008 dbTestId, 1009 dbName, 1010 handle.m, 1011 defs, 1012 ) 1013 assert.Nil(t, err) 1014 txnCmds = []txnCommand{ 1015 { 1016 typ: CmdPreCommitWrite, 1017 cmd: api.PrecommitWriteCmd{ 1018 UserId: ac.userId, 1019 AccountId: ac.accountId, 1020 RoleId: ac.roleId, 1021 EntryList: createTbEntries}, 1022 }, 1023 {typ: CmdPrepare}, 1024 {typ: CmdCommit}, 1025 } 1026 txnMeta = mock2PCTxn(txnEngine) 1027 ctx = context.TODO() 1028 err = handle.handleCmds(ctx, txnMeta, txnCmds) 1029 assert.Nil(t, err) 1030 1031 //start 1pc txn ,read table ID 1032 txn, err = txnEngine.StartTxn(nil) 1033 assert.Nil(t, err) 1034 dbHandle, err = txnEngine.GetDatabase(ctx, dbName, txn) 1035 assert.NoError(t, err) 1036 dbId := dbHandle.GetDatabaseID(ctx) 1037 assert.True(t, dbTestId == dbId) 1038 names, _ = dbHandle.RelationNames(ctx) 1039 assert.Equal(t, 1, len(names)) 1040 tbHandle, err := dbHandle.GetRelation(ctx, schema.Name) 1041 assert.NoError(t, err) 1042 tbTestId := tbHandle.GetRelationID(ctx) 1043 rDefs, _ := tbHandle.TableDefs(ctx) 1044 assert.Equal(t, 3, len(rDefs)) 1045 rAttr := rDefs[0].(*engine.AttributeDef).Attr 1046 assert.Equal(t, true, rAttr.Default.NullAbility) 1047 rAttr = rDefs[1].(*engine.AttributeDef).Attr 1048 assert.Equal(t, "expr2", rAttr.Default.OriginString) 1049 err = txn.Commit() 1050 assert.NoError(t, err) 1051 1052 //DML::insert batch into table 1053 moBat := containers.CopyToMoBatch(catalog.MockBatch(schema, 100)) 1054 insertEntry, err := makePBEntry(INSERT, dbTestId, 1055 tbTestId, dbName, schema.Name, "", moBat) 1056 assert.NoError(t, err) 1057 txnCmds = []txnCommand{ 1058 { 1059 typ: CmdPreCommitWrite, 1060 cmd: api.PrecommitWriteCmd{ 1061 UserId: ac.userId, 1062 AccountId: ac.accountId, 1063 RoleId: ac.roleId, 1064 EntryList: []*api.Entry{insertEntry}}, 1065 }, 1066 {typ: CmdPrepare}, 1067 {typ: CmdCommit}, 1068 } 1069 insertTxn := mock2PCTxn(txnEngine) 1070 ctx = context.TODO() 1071 err = handle.handleCmds(ctx, insertTxn, txnCmds) 1072 assert.Nil(t, err) 1073 1074 //start 2PC txn ,rollback it after prepared 1075 rollbackTxn := mock2PCTxn(txnEngine) 1076 //insert 20 rows ,then rollback 1077 //FIXME::?? 1078 //batch.SetLength(moBat, 20) 1079 moBat = containers.CopyToMoBatch(catalog.MockBatch(schema, 20)) 1080 insertEntry, err = makePBEntry(INSERT, dbTestId, 1081 tbTestId, dbName, schema.Name, "", moBat) 1082 assert.NoError(t, err) 1083 txnCmds = []txnCommand{ 1084 { 1085 typ: CmdPreCommitWrite, 1086 cmd: api.PrecommitWriteCmd{ 1087 UserId: ac.userId, 1088 AccountId: ac.accountId, 1089 RoleId: ac.roleId, 1090 EntryList: []*api.Entry{insertEntry}}, 1091 }, 1092 {typ: CmdPrepare}, 1093 {typ: CmdRollback}, 1094 } 1095 ctx = context.TODO() 1096 err = handle.handleCmds(ctx, rollbackTxn, txnCmds) 1097 assert.Nil(t, err) 1098 1099 //start 2PC txn , rollback it when it is ACTIVE. 1100 rollbackTxn = mock2PCTxn(txnEngine) 1101 //insert 10 rows ,then rollback 1102 //batch.SetLength(moBat, 10) 1103 moBat = containers.CopyToMoBatch(catalog.MockBatch(schema, 10)) 1104 insertEntry, err = makePBEntry(INSERT, dbTestId, 1105 tbTestId, dbName, schema.Name, "", moBat) 1106 assert.NoError(t, err) 1107 txnCmds = []txnCommand{ 1108 { 1109 typ: CmdPreCommitWrite, 1110 cmd: api.PrecommitWriteCmd{ 1111 UserId: ac.userId, 1112 AccountId: ac.accountId, 1113 RoleId: ac.roleId, 1114 EntryList: []*api.Entry{insertEntry}}, 1115 }, 1116 {typ: CmdRollback}, 1117 } 1118 ctx = context.TODO() 1119 err = handle.handleCmds(ctx, rollbackTxn, txnCmds) 1120 assert.Nil(t, err) 1121 1122 //start 1PC txn , read table 1123 txn, err = txnEngine.StartTxn(nil) 1124 assert.NoError(t, err) 1125 dbHandle, err = txnEngine.GetDatabase(ctx, dbName, txn) 1126 assert.NoError(t, err) 1127 tbHandle, err = dbHandle.GetRelation(ctx, schema.Name) 1128 assert.NoError(t, err) 1129 tbReaders, _ := tbHandle.NewReader(ctx, 1, nil, nil) 1130 for _, reader := range tbReaders { 1131 bat, err := reader.Read(ctx, []string{schema.ColDefs[1].Name}, nil, handle.m) 1132 assert.Nil(t, err) 1133 if bat != nil { 1134 len := vector.Length(bat.Vecs[0]) 1135 assert.Equal(t, 100, len) 1136 } 1137 } 1138 // read row ids 1139 hideCol, err := tbHandle.GetHideKeys(ctx) 1140 assert.NoError(t, err) 1141 reader, _ := tbHandle.NewReader(ctx, 1, nil, nil) 1142 hideBat, err := reader[0].Read(ctx, []string{hideCol[0].Name}, nil, handle.m) 1143 assert.Nil(t, err) 1144 err = txn.Commit() 1145 assert.Nil(t, err) 1146 1147 hideBats := containers.SplitBatch(hideBat, 5) 1148 //delete 20 rows by 2PC txn 1149 //batch.SetLength(hideBat, 20) 1150 deleteEntry, err := makePBEntry( 1151 DELETE, 1152 dbId, 1153 tbTestId, 1154 dbName, 1155 schema.Name, 1156 "", 1157 hideBats[0], 1158 ) 1159 assert.Nil(t, err) 1160 txnCmds = []txnCommand{ 1161 { 1162 typ: CmdPreCommitWrite, 1163 cmd: api.PrecommitWriteCmd{ 1164 UserId: ac.userId, 1165 AccountId: ac.accountId, 1166 RoleId: ac.roleId, 1167 EntryList: []*api.Entry{deleteEntry}}, 1168 }, 1169 {typ: CmdPrepare}, 1170 {typ: CmdCommitting}, 1171 {typ: CmdCommit}, 1172 } 1173 deleteTxn := mock2PCTxn(txnEngine) 1174 ctx = context.TODO() 1175 err = handle.handleCmds(ctx, deleteTxn, txnCmds) 1176 assert.Nil(t, err) 1177 1178 //start a 2PC txn ,rollback it after prepared. 1179 // delete 20 rows ,then rollback 1180 rollbackTxn = mock2PCTxn(txnEngine) 1181 deleteEntry, _ = makePBEntry( 1182 DELETE, 1183 dbId, 1184 tbTestId, 1185 dbName, 1186 schema.Name, 1187 "", 1188 hideBats[1], 1189 ) 1190 txnCmds = []txnCommand{ 1191 { 1192 typ: CmdPreCommitWrite, 1193 cmd: api.PrecommitWriteCmd{ 1194 UserId: ac.userId, 1195 AccountId: ac.accountId, 1196 RoleId: ac.roleId, 1197 EntryList: []*api.Entry{deleteEntry}}, 1198 }, 1199 {typ: CmdPrepare}, 1200 {typ: CmdRollback}, 1201 } 1202 ctx = context.TODO() 1203 err = handle.handleCmds(ctx, rollbackTxn, txnCmds) 1204 assert.Nil(t, err) 1205 1206 //read, there should be 80 rows left. 1207 txn, err = txnEngine.StartTxn(nil) 1208 assert.NoError(t, err) 1209 dbHandle, err = txnEngine.GetDatabase(ctx, dbName, txn) 1210 assert.NoError(t, err) 1211 tbHandle, err = dbHandle.GetRelation(ctx, schema.Name) 1212 assert.NoError(t, err) 1213 tbReaders, _ = tbHandle.NewReader(ctx, 2, nil, nil) 1214 for _, reader := range tbReaders { 1215 bat, err := reader.Read(ctx, []string{schema.ColDefs[1].Name}, nil, handle.m) 1216 assert.Nil(t, err) 1217 if bat != nil { 1218 len := vector.Length(bat.Vecs[0]) 1219 assert.Equal(t, 80, len) 1220 } 1221 } 1222 err = txn.Commit() 1223 assert.Nil(t, err) 1224 } 1225 1226 func TestHandle_MVCCVisibility(t *testing.T) { 1227 defer testutils.AfterTest(t)() 1228 opts := config.WithLongScanAndCKPOpts(nil) 1229 handle := mockTAEHandle(t, opts) 1230 defer handle.HandleClose(context.TODO()) 1231 IDAlloc := catalog.NewIDAllocator() 1232 txnEngine := handle.GetTxnEngine() 1233 schema := catalog.MockSchema(2, -1) 1234 schema.Name = "tbtest" 1235 schema.BlockMaxRows = 10 1236 schema.SegmentMaxBlocks = 2 1237 dbName := "dbtest" 1238 ac := AccessInfo{ 1239 accountId: 0, 1240 userId: 0, 1241 roleId: 0, 1242 } 1243 //make create db cmd; 1244 createDbEntries, err := makeCreateDatabaseEntries( 1245 "", 1246 ac, 1247 dbName, 1248 IDAlloc.NextDB(), 1249 handle.m) 1250 assert.Nil(t, err) 1251 txnCmds := []txnCommand{ 1252 { 1253 typ: CmdPreCommitWrite, 1254 cmd: api.PrecommitWriteCmd{ 1255 UserId: ac.userId, 1256 AccountId: ac.accountId, 1257 RoleId: ac.roleId, 1258 EntryList: createDbEntries}, 1259 }, 1260 } 1261 txnMeta := mock2PCTxn(txnEngine) 1262 ctx := context.TODO() 1263 err = handle.handleCmds(ctx, txnMeta, txnCmds) 1264 assert.Nil(t, err) 1265 var dbTestId uint64 1266 var dbNames []string 1267 wg := new(sync.WaitGroup) 1268 wg.Add(1) 1269 //start a db reader. 1270 go func() { 1271 //start 1pc txn ,read "dbtest"'s ID 1272 ctx := context.TODO() 1273 txn, err := txnEngine.StartTxn(nil) 1274 assert.Nil(t, err) 1275 dbNames, _ = txnEngine.DatabaseNames(ctx, txn) 1276 err = txn.Commit() 1277 assert.Nil(t, err) 1278 wg.Done() 1279 1280 }() 1281 wg.Wait() 1282 assert.Equal(t, 1, len(dbNames)) 1283 1284 err = handle.HandlePrepare(ctx, txnMeta) 1285 assert.Nil(t, err) 1286 //start reader after preparing success. 1287 startTime := time.Now() 1288 wg.Add(1) 1289 go func() { 1290 //start 1pc txn ,read "dbtest"'s ID 1291 ctx := context.TODO() 1292 txn, err := txnEngine.StartTxn(nil) 1293 assert.Nil(t, err) 1294 //reader should wait until the writer committed. 1295 dbNames, _ = txnEngine.DatabaseNames(ctx, txn) 1296 assert.Equal(t, 2, len(dbNames)) 1297 dbHandle, err := txnEngine.GetDatabase(ctx, dbName, txn) 1298 assert.Nil(t, err) 1299 dbTestId = dbHandle.GetDatabaseID(ctx) 1300 err = txn.Commit() 1301 assert.Nil(t, err) 1302 //wg.Done() 1303 //To check whether reader had waited. 1304 assert.True(t, time.Since(startTime) > 1*time.Second) 1305 wg.Done() 1306 1307 }() 1308 //sleep 1 second 1309 time.Sleep(1 * time.Second) 1310 //CommitTS = PreparedTS + 1 1311 err = handle.handleCmds(ctx, txnMeta, []txnCommand{ 1312 {typ: CmdCommitting}, {typ: CmdCommit}, 1313 }) 1314 assert.Nil(t, err) 1315 wg.Wait() 1316 1317 //create table from "dbtest" 1318 defs, err := moengine.SchemaToDefs(schema) 1319 defs[0].(*engine.AttributeDef).Attr.Default = &plan.Default{ 1320 NullAbility: true, 1321 Expr: &plan.Expr{ 1322 Expr: &plan.Expr_C{ 1323 C: &plan.Const{ 1324 Isnull: false, 1325 Value: &plan.Const_Sval{ 1326 Sval: "expr1", 1327 }, 1328 }, 1329 }, 1330 }, 1331 OriginString: "expr1", 1332 } 1333 defs[1].(*engine.AttributeDef).Attr.Default = &plan.Default{ 1334 NullAbility: false, 1335 Expr: &plan.Expr{ 1336 Expr: &plan.Expr_C{ 1337 C: &plan.Const{ 1338 Isnull: false, 1339 Value: &plan.Const_Sval{ 1340 Sval: "expr2", 1341 }, 1342 }, 1343 }, 1344 }, 1345 OriginString: "expr2", 1346 } 1347 assert.Nil(t, err) 1348 createTbEntries, err := makeCreateTableEntries( 1349 "", 1350 ac, 1351 schema.Name, 1352 IDAlloc.NextTable(), 1353 dbTestId, 1354 dbName, 1355 handle.m, 1356 defs, 1357 ) 1358 assert.Nil(t, err) 1359 txnCmds = []txnCommand{ 1360 { 1361 typ: CmdPreCommitWrite, 1362 cmd: api.PrecommitWriteCmd{ 1363 UserId: ac.userId, 1364 AccountId: ac.accountId, 1365 RoleId: ac.roleId, 1366 EntryList: createTbEntries}, 1367 }, 1368 {typ: CmdPrepare}, 1369 } 1370 txnMeta = mock2PCTxn(txnEngine) 1371 ctx = context.TODO() 1372 err = handle.handleCmds(ctx, txnMeta, txnCmds) 1373 assert.Nil(t, err) 1374 var tbTestId uint64 1375 startTime = time.Now() 1376 wg.Add(1) 1377 go func() { 1378 //start 1pc txn ,read table ID 1379 txn, err := txnEngine.StartTxn(nil) 1380 assert.Nil(t, err) 1381 ctx := context.TODO() 1382 dbHandle, err := txnEngine.GetDatabase(ctx, dbName, txn) 1383 assert.NoError(t, err) 1384 dbId := dbHandle.GetDatabaseID(ctx) 1385 assert.True(t, dbTestId == dbId) 1386 //txn should wait here. 1387 names, _ := dbHandle.RelationNames(ctx) 1388 assert.Equal(t, 1, len(names)) 1389 tbHandle, err := dbHandle.GetRelation(ctx, schema.Name) 1390 assert.NoError(t, err) 1391 tbTestId = tbHandle.GetRelationID(ctx) 1392 rDefs, _ := tbHandle.TableDefs(ctx) 1393 assert.Equal(t, 3, len(rDefs)) 1394 rAttr := rDefs[0].(*engine.AttributeDef).Attr 1395 assert.Equal(t, true, rAttr.Default.NullAbility) 1396 rAttr = rDefs[1].(*engine.AttributeDef).Attr 1397 assert.Equal(t, "expr2", rAttr.Default.OriginString) 1398 err = txn.Commit() 1399 assert.NoError(t, err) 1400 //wg.Done() 1401 //To check whether reader had waited. 1402 assert.True(t, time.Since(startTime) > 1*time.Second) 1403 wg.Done() 1404 }() 1405 time.Sleep(1 * time.Second) 1406 err = handle.handleCmds(ctx, txnMeta, []txnCommand{ 1407 {typ: CmdCommitting}, {typ: CmdCommit}, 1408 }) 1409 assert.Nil(t, err) 1410 wg.Wait() 1411 1412 //DML::insert batch into table 1413 moBat := containers.CopyToMoBatch(catalog.MockBatch(schema, 100)) 1414 insertEntry, err := makePBEntry(INSERT, dbTestId, 1415 tbTestId, dbName, schema.Name, "", moBat) 1416 assert.NoError(t, err) 1417 txnCmds = []txnCommand{ 1418 { 1419 typ: CmdPreCommitWrite, 1420 cmd: api.PrecommitWriteCmd{ 1421 UserId: ac.userId, 1422 AccountId: ac.accountId, 1423 RoleId: ac.roleId, 1424 EntryList: []*api.Entry{insertEntry}}, 1425 }, 1426 {typ: CmdPrepare}, 1427 } 1428 insertTxn := mock2PCTxn(txnEngine) 1429 ctx = context.TODO() 1430 err = handle.handleCmds(ctx, insertTxn, txnCmds) 1431 assert.Nil(t, err) 1432 startTime = time.Now() 1433 wg.Add(1) 1434 go func() { 1435 //start 1PC txn , read table 1436 txn, err := txnEngine.StartTxn(nil) 1437 assert.NoError(t, err) 1438 ctx := context.TODO() 1439 dbHandle, err := txnEngine.GetDatabase(ctx, dbName, txn) 1440 assert.NoError(t, err) 1441 tbHandle, err := dbHandle.GetRelation(ctx, schema.Name) 1442 assert.NoError(t, err) 1443 tbReaders, _ := tbHandle.NewReader(ctx, 1, nil, nil) 1444 for _, reader := range tbReaders { 1445 bat, err := reader.Read(ctx, []string{schema.ColDefs[1].Name}, nil, handle.m) 1446 assert.Nil(t, err) 1447 if bat != nil { 1448 len := vector.Length(bat.Vecs[0]) 1449 assert.Equal(t, 100, len) 1450 } 1451 } 1452 txn.Commit() 1453 //To check whether reader had waited. 1454 assert.True(t, time.Since(startTime) > 1*time.Second) 1455 wg.Done() 1456 }() 1457 time.Sleep(1 * time.Second) 1458 //insertTxn 's CommitTS = PreparedTS + 1. 1459 err = handle.handleCmds(ctx, insertTxn, []txnCommand{ 1460 {typ: CmdCommitting}, {typ: CmdCommit}, 1461 }) 1462 assert.Nil(t, err) 1463 wg.Wait() 1464 1465 //DML:delete rows 1466 //read row ids 1467 var hideBat *batch.Batch 1468 { 1469 txn, err := txnEngine.StartTxn(nil) 1470 assert.NoError(t, err) 1471 ctx = context.TODO() 1472 dbHandle, err := txnEngine.GetDatabase(ctx, dbName, txn) 1473 assert.NoError(t, err) 1474 tbHandle, err := dbHandle.GetRelation(ctx, schema.Name) 1475 assert.NoError(t, err) 1476 hideCol, err := tbHandle.GetHideKeys(ctx) 1477 assert.NoError(t, err) 1478 reader, _ := tbHandle.NewReader(ctx, 1, nil, nil) 1479 hideBat, err = reader[0].Read(ctx, []string{hideCol[0].Name}, nil, handle.m) 1480 assert.Nil(t, err) 1481 err = txn.Commit() 1482 assert.Nil(t, err) 1483 } 1484 1485 hideBats := containers.SplitBatch(hideBat, 5) 1486 //delete 20 rows by 2PC txn 1487 deleteTxn := mock2PCTxn(txnEngine) 1488 //batch.SetLength(hideBat, 20) 1489 deleteEntry, err := makePBEntry( 1490 DELETE, 1491 dbTestId, 1492 tbTestId, 1493 dbName, 1494 schema.Name, 1495 "", 1496 hideBats[0], 1497 ) 1498 assert.Nil(t, err) 1499 txnCmds = []txnCommand{ 1500 { 1501 typ: CmdPreCommitWrite, 1502 cmd: api.PrecommitWriteCmd{ 1503 UserId: ac.userId, 1504 AccountId: ac.accountId, 1505 RoleId: ac.roleId, 1506 EntryList: []*api.Entry{deleteEntry}}, 1507 }, 1508 {typ: CmdPrepare}, 1509 } 1510 ctx = context.TODO() 1511 err = handle.handleCmds(ctx, deleteTxn, txnCmds) 1512 assert.Nil(t, err) 1513 startTime = time.Now() 1514 wg.Add(1) 1515 go func() { 1516 //read, there should be 80 rows left. 1517 txn, err := txnEngine.StartTxn(nil) 1518 assert.NoError(t, err) 1519 ctx := context.TODO() 1520 dbHandle, err := txnEngine.GetDatabase(ctx, dbName, txn) 1521 assert.NoError(t, err) 1522 tbHandle, err := dbHandle.GetRelation(ctx, schema.Name) 1523 assert.NoError(t, err) 1524 tbReaders, _ := tbHandle.NewReader(ctx, 2, nil, nil) 1525 for _, reader := range tbReaders { 1526 bat, err := reader.Read(ctx, []string{schema.ColDefs[1].Name}, nil, handle.m) 1527 assert.Nil(t, err) 1528 if bat != nil { 1529 len := vector.Length(bat.Vecs[0]) 1530 assert.Equal(t, 80, len) 1531 } 1532 } 1533 err = txn.Commit() 1534 assert.Nil(t, err) 1535 //To check whether reader had waited. 1536 assert.True(t, time.Since(startTime) > 1*time.Second) 1537 wg.Done() 1538 1539 }() 1540 time.Sleep(1 * time.Second) 1541 //deleteTxn 's CommitTS = PreparedTS + 1 1542 err = handle.handleCmds(ctx, deleteTxn, []txnCommand{ 1543 {typ: CmdCommitting}, {typ: CmdCommit}, 1544 }) 1545 assert.Nil(t, err) 1546 wg.Wait() 1547 }