github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/meta/meta_test.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 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 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package spacetime_test 15 16 import ( 17 "context" 18 "math" 19 "strconv" 20 "sync" 21 "testing" 22 "time" 23 24 "github.com/whtcorpsinc/BerolinaSQL/perceptron" 25 . "github.com/whtcorpsinc/check" 26 "github.com/whtcorpsinc/milevadb/causetstore/mockstore" 27 "github.com/whtcorpsinc/milevadb/ekv" 28 "github.com/whtcorpsinc/milevadb/soliton/codec" 29 . "github.com/whtcorpsinc/milevadb/soliton/solitonutil" 30 "github.com/whtcorpsinc/milevadb/soliton/testleak" 31 "github.com/whtcorpsinc/milevadb/spacetime" 32 "github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx" 33 "github.com/whtcorpsinc/milevadb/types" 34 ) 35 36 func TestT(t *testing.T) { 37 CustomVerboseFlag = true 38 TestingT(t) 39 } 40 41 var _ = Suite(&testSuite{}) 42 43 type testSuite struct { 44 CommonHandleSuite 45 } 46 47 func (s *testSuite) TestMeta(c *C) { 48 defer testleak.AfterTest(c)() 49 causetstore, err := mockstore.NewMockStore() 50 c.Assert(err, IsNil) 51 defer causetstore.Close() 52 53 txn, err := causetstore.Begin() 54 c.Assert(err, IsNil) 55 defer txn.Rollback() 56 57 t := spacetime.NewMeta(txn) 58 59 n, err := t.GenGlobalID() 60 c.Assert(err, IsNil) 61 c.Assert(n, Equals, int64(1)) 62 63 n, err = t.GetGlobalID() 64 c.Assert(err, IsNil) 65 c.Assert(n, Equals, int64(1)) 66 67 var wg sync.WaitGroup 68 wg.Add(1) 69 go func() { 70 defer wg.Done() 71 ids, err := t.GenGlobalIDs(3) 72 c.Assert(err, IsNil) 73 anyMatch(c, ids, []int64{2, 3, 4}, []int64{6, 7, 8}) 74 }() 75 76 wg.Add(1) 77 go func() { 78 defer wg.Done() 79 ids, err := t.GenGlobalIDs(4) 80 c.Assert(err, IsNil) 81 anyMatch(c, ids, []int64{5, 6, 7, 8}, []int64{2, 3, 4, 5}) 82 }() 83 wg.Wait() 84 85 n, err = t.GetSchemaVersion() 86 c.Assert(err, IsNil) 87 c.Assert(n, Equals, int64(0)) 88 89 n, err = t.GenSchemaVersion() 90 c.Assert(err, IsNil) 91 c.Assert(n, Equals, int64(1)) 92 93 n, err = t.GetSchemaVersion() 94 c.Assert(err, IsNil) 95 c.Assert(n, Equals, int64(1)) 96 97 dbInfo := &perceptron.DBInfo{ 98 ID: 1, 99 Name: perceptron.NewCIStr("a"), 100 } 101 err = t.CreateDatabase(dbInfo) 102 c.Assert(err, IsNil) 103 104 err = t.CreateDatabase(dbInfo) 105 c.Assert(err, NotNil) 106 c.Assert(spacetime.ErrDBExists.Equal(err), IsTrue) 107 108 v, err := t.GetDatabase(1) 109 c.Assert(err, IsNil) 110 c.Assert(v, DeepEquals, dbInfo) 111 112 dbInfo.Name = perceptron.NewCIStr("aa") 113 err = t.UFIDelateDatabase(dbInfo) 114 c.Assert(err, IsNil) 115 116 v, err = t.GetDatabase(1) 117 c.Assert(err, IsNil) 118 c.Assert(v, DeepEquals, dbInfo) 119 120 dbs, err := t.ListDatabases() 121 c.Assert(err, IsNil) 122 c.Assert(dbs, DeepEquals, []*perceptron.DBInfo{dbInfo}) 123 124 tbInfo := &perceptron.BlockInfo{ 125 ID: 1, 126 Name: perceptron.NewCIStr("t"), 127 } 128 err = t.CreateBlockOrView(1, tbInfo) 129 c.Assert(err, IsNil) 130 131 n, err = t.GenAutoBlockID(1, 1, 10) 132 c.Assert(err, IsNil) 133 c.Assert(n, Equals, int64(10)) 134 135 n, err = t.GetAutoBlockID(1, 1) 136 c.Assert(err, IsNil) 137 c.Assert(n, Equals, int64(10)) 138 139 err = t.CreateBlockOrView(1, tbInfo) 140 c.Assert(err, NotNil) 141 c.Assert(spacetime.ErrBlockExists.Equal(err), IsTrue) 142 143 tbInfo.Name = perceptron.NewCIStr("tt") 144 err = t.UFIDelateBlock(1, tbInfo) 145 c.Assert(err, IsNil) 146 147 causet, err := t.GetBlock(1, 1) 148 c.Assert(err, IsNil) 149 c.Assert(causet, DeepEquals, tbInfo) 150 151 causet, err = t.GetBlock(1, 2) 152 c.Assert(err, IsNil) 153 c.Assert(causet, IsNil) 154 155 tbInfo2 := &perceptron.BlockInfo{ 156 ID: 2, 157 Name: perceptron.NewCIStr("bb"), 158 } 159 err = t.CreateBlockOrView(1, tbInfo2) 160 c.Assert(err, IsNil) 161 162 blocks, err := t.ListBlocks(1) 163 c.Assert(err, IsNil) 164 c.Assert(blocks, DeepEquals, []*perceptron.BlockInfo{tbInfo, tbInfo2}) 165 // Generate an auto id. 166 n, err = t.GenAutoBlockID(1, 2, 10) 167 c.Assert(err, IsNil) 168 c.Assert(n, Equals, int64(10)) 169 // Make sure the auto id key-value entry is there. 170 n, err = t.GetAutoBlockID(1, 2) 171 c.Assert(err, IsNil) 172 c.Assert(n, Equals, int64(10)) 173 174 err = t.DropBlockOrView(1, tbInfo2.ID, true) 175 c.Assert(err, IsNil) 176 // Make sure auto id key-value entry is gone. 177 n, err = t.GetAutoBlockID(1, 2) 178 c.Assert(err, IsNil) 179 c.Assert(n, Equals, int64(0)) 180 181 blocks, err = t.ListBlocks(1) 182 c.Assert(err, IsNil) 183 c.Assert(blocks, DeepEquals, []*perceptron.BlockInfo{tbInfo}) 184 185 // Test case for drop a causet without delete auto id key-value entry. 186 tid := int64(100) 187 tbInfo100 := &perceptron.BlockInfo{ 188 ID: tid, 189 Name: perceptron.NewCIStr("t_rename"), 190 } 191 // Create causet. 192 err = t.CreateBlockOrView(1, tbInfo100) 193 c.Assert(err, IsNil) 194 // UFIDelate auto ID. 195 currentDBID := int64(1) 196 n, err = t.GenAutoBlockID(currentDBID, tid, 10) 197 c.Assert(err, IsNil) 198 c.Assert(n, Equals, int64(10)) 199 // Fail to uFIDelate auto ID. 200 // The causet ID doesn't exist. 201 nonExistentID := int64(1234) 202 _, err = t.GenAutoBlockID(currentDBID, nonExistentID, 10) 203 c.Assert(err, NotNil) 204 c.Assert(spacetime.ErrBlockNotExists.Equal(err), IsTrue) 205 // Fail to uFIDelate auto ID. 206 // The current database ID doesn't exist. 207 currentDBID = nonExistentID 208 _, err = t.GenAutoBlockID(currentDBID, tid, 10) 209 c.Assert(err, NotNil) 210 c.Assert(spacetime.ErrDBNotExists.Equal(err), IsTrue) 211 // Test case for CreateBlockAndSetAutoID. 212 tbInfo3 := &perceptron.BlockInfo{ 213 ID: 3, 214 Name: perceptron.NewCIStr("tbl3"), 215 } 216 err = t.CreateBlockAndSetAutoID(1, tbInfo3, 123, 0) 217 c.Assert(err, IsNil) 218 id, err := t.GetAutoBlockID(1, tbInfo3.ID) 219 c.Assert(err, IsNil) 220 c.Assert(id, Equals, int64(123)) 221 // Test case for GenAutoBlockIDKeyValue. 222 key, val := t.GenAutoBlockIDKeyValue(1, tbInfo3.ID, 1234) 223 c.Assert(val, DeepEquals, []byte(strconv.FormatInt(1234, 10))) 224 c.Assert(key, DeepEquals, []byte{0x6d, 0x44, 0x42, 0x3a, 0x31, 0x0, 0x0, 0x0, 0x0, 0xfb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, 0x54, 0x49, 0x44, 0x3a, 0x33, 0x0, 0x0, 0x0, 0xfc}) 225 226 err = t.DroFIDelatabase(1) 227 c.Assert(err, IsNil) 228 err = t.DroFIDelatabase(currentDBID) 229 c.Assert(err, IsNil) 230 231 dbs, err = t.ListDatabases() 232 c.Assert(err, IsNil) 233 c.Assert(dbs, HasLen, 0) 234 235 bootstrapVer, err := t.GetBootstrapVersion() 236 c.Assert(err, IsNil) 237 c.Assert(bootstrapVer, Equals, int64(0)) 238 239 err = t.FinishBootstrap(int64(1)) 240 c.Assert(err, IsNil) 241 242 bootstrapVer, err = t.GetBootstrapVersion() 243 c.Assert(err, IsNil) 244 c.Assert(bootstrapVer, Equals, int64(1)) 245 246 // Test case for spacetime.FinishBootstrap with a version. 247 err = t.FinishBootstrap(int64(10)) 248 c.Assert(err, IsNil) 249 bootstrapVer, err = t.GetBootstrapVersion() 250 c.Assert(err, IsNil) 251 c.Assert(bootstrapVer, Equals, int64(10)) 252 253 // Test case for SchemaDiff. 254 schemaDiff := &perceptron.SchemaDiff{ 255 Version: 100, 256 SchemaID: 1, 257 Type: perceptron.CausetActionTruncateBlock, 258 BlockID: 2, 259 OldBlockID: 3, 260 } 261 err = t.SetSchemaDiff(schemaDiff) 262 c.Assert(err, IsNil) 263 readDiff, err := t.GetSchemaDiff(schemaDiff.Version) 264 c.Assert(err, IsNil) 265 c.Assert(readDiff, DeepEquals, schemaDiff) 266 267 err = txn.Commit(context.Background()) 268 c.Assert(err, IsNil) 269 270 // Test for DBSJobHistoryKey. 271 key = spacetime.DBSJobHistoryKey(t, 888) 272 c.Assert(key, DeepEquals, []byte{0x6d, 0x44, 0x44, 0x4c, 0x4a, 0x6f, 0x62, 0x48, 0x69, 0xff, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x0, 0x0, 0x0, 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x78, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf7}) 273 } 274 275 func (s *testSuite) TestSnapshot(c *C) { 276 defer testleak.AfterTest(c)() 277 causetstore, err := mockstore.NewMockStore() 278 c.Assert(err, IsNil) 279 defer causetstore.Close() 280 281 txn, _ := causetstore.Begin() 282 m := spacetime.NewMeta(txn) 283 m.GenGlobalID() 284 n, _ := m.GetGlobalID() 285 c.Assert(n, Equals, int64(1)) 286 txn.Commit(context.Background()) 287 288 ver1, _ := causetstore.CurrentVersion() 289 time.Sleep(time.Millisecond) 290 txn, _ = causetstore.Begin() 291 m = spacetime.NewMeta(txn) 292 m.GenGlobalID() 293 n, _ = m.GetGlobalID() 294 c.Assert(n, Equals, int64(2)) 295 txn.Commit(context.Background()) 296 297 snapshot, _ := causetstore.GetSnapshot(ver1) 298 snapMeta := spacetime.NewSnapshotMeta(snapshot) 299 n, _ = snapMeta.GetGlobalID() 300 c.Assert(n, Equals, int64(1)) 301 _, err = snapMeta.GenGlobalID() 302 c.Assert(err, NotNil) 303 c.Assert(err.Error(), Equals, "[structure:8220]write on snapshot") 304 } 305 306 func (s *testSuite) TestDBS(c *C) { 307 defer testleak.AfterTest(c)() 308 causetstore, err := mockstore.NewMockStore() 309 c.Assert(err, IsNil) 310 defer causetstore.Close() 311 312 txn, err := causetstore.Begin() 313 c.Assert(err, IsNil) 314 315 defer txn.Rollback() 316 317 t := spacetime.NewMeta(txn) 318 319 job := &perceptron.Job{ID: 1} 320 err = t.EnQueueDBSJob(job) 321 c.Assert(err, IsNil) 322 n, err := t.DBSJobQueueLen() 323 c.Assert(err, IsNil) 324 c.Assert(n, Equals, int64(1)) 325 326 v, err := t.GetDBSJobByIdx(0) 327 c.Assert(err, IsNil) 328 c.Assert(v, DeepEquals, job) 329 v, err = t.GetDBSJobByIdx(1) 330 c.Assert(err, IsNil) 331 c.Assert(v, IsNil) 332 job.ID = 2 333 err = t.UFIDelateDBSJob(0, job, true) 334 c.Assert(err, IsNil) 335 336 // There are 3 spacetime key relate to index reorganization: 337 // start_handle, end_handle and physical_block_id. 338 // Only start_handle is initialized. 339 err = t.UFIDelateDBSReorgStartHandle(job, ekv.IntHandle(1)) 340 c.Assert(err, IsNil) 341 342 // Since physical_block_id is uninitialized, we simulate older MilevaDB version that doesn't causetstore them. 343 // In this case GetDBSReorgHandle always return maxInt64 as end_handle. 344 i, j, k, err := t.GetDBSReorgHandle(job, false) 345 c.Assert(err, IsNil) 346 c.Assert(i, HandleEquals, ekv.IntHandle(1)) 347 c.Assert(j, HandleEquals, ekv.IntHandle(math.MaxInt64)) 348 c.Assert(k, Equals, int64(0)) 349 350 startHandle := s.NewHandle().Int(1).Common("abc", 1222, "string") 351 endHandle := s.NewHandle().Int(2).Common("dddd", 1222, "string") 352 err = t.UFIDelateDBSReorgHandle(job, startHandle, endHandle, 3) 353 c.Assert(err, IsNil) 354 355 i, j, k, err = t.GetDBSReorgHandle(job, s.IsCommonHandle) 356 c.Assert(err, IsNil) 357 c.Assert(i, HandleEquals, startHandle) 358 c.Assert(j, HandleEquals, endHandle) 359 c.Assert(k, Equals, int64(3)) 360 361 err = t.RemoveDBSReorgHandle(job) 362 c.Assert(err, IsNil) 363 364 // new MilevaDB binary running on old MilevaDB DBS reorg data. 365 i, j, k, err = t.GetDBSReorgHandle(job, s.IsCommonHandle) 366 c.Assert(err, IsNil) 367 c.Assert(i, IsNil) 368 // The default value for endHandle is MaxInt64, not 0. 369 c.Assert(j, HandleEquals, ekv.IntHandle(math.MaxInt64)) 370 c.Assert(k, Equals, int64(0)) 371 372 // Test GetDBSReorgHandle failed. 373 _, _, _, err = t.GetDBSReorgHandle(job, s.IsCommonHandle) 374 c.Assert(err, IsNil) 375 376 v, err = t.DeQueueDBSJob() 377 c.Assert(err, IsNil) 378 c.Assert(v, DeepEquals, job) 379 380 err = t.AddHistoryDBSJob(job, true) 381 c.Assert(err, IsNil) 382 v, err = t.GetHistoryDBSJob(2) 383 c.Assert(err, IsNil) 384 c.Assert(v, DeepEquals, job) 385 386 // Add multiple history jobs. 387 arg := "test arg" 388 historyJob1 := &perceptron.Job{ID: 1234} 389 historyJob1.Args = append(job.Args, arg) 390 err = t.AddHistoryDBSJob(historyJob1, true) 391 c.Assert(err, IsNil) 392 historyJob2 := &perceptron.Job{ID: 123} 393 historyJob2.Args = append(job.Args, arg) 394 err = t.AddHistoryDBSJob(historyJob2, false) 395 c.Assert(err, IsNil) 396 all, err := t.GetAllHistoryDBSJobs() 397 c.Assert(err, IsNil) 398 var lastID int64 399 for _, job := range all { 400 c.Assert(job.ID, Greater, lastID) 401 lastID = job.ID 402 arg1 := "" 403 job.DecodeArgs(&arg1) 404 if job.ID == historyJob1.ID { 405 c.Assert(*(job.Args[0].(*string)), Equals, historyJob1.Args[0]) 406 } else { 407 c.Assert(job.Args, HasLen, 0) 408 } 409 } 410 411 // Test for get last N history dbs jobs. 412 historyJobs, err := t.GetLastNHistoryDBSJobs(2) 413 c.Assert(err, IsNil) 414 c.Assert(len(historyJobs), Equals, 2) 415 c.Assert(historyJobs[0].ID == 1234, IsTrue) 416 c.Assert(historyJobs[1].ID == 123, IsTrue) 417 418 // Test GetAllDBSJobsInQueue. 419 err = t.EnQueueDBSJob(job) 420 c.Assert(err, IsNil) 421 job1 := &perceptron.Job{ID: 2} 422 err = t.EnQueueDBSJob(job1) 423 c.Assert(err, IsNil) 424 jobs, err := t.GetAllDBSJobsInQueue() 425 c.Assert(err, IsNil) 426 expectJobs := []*perceptron.Job{job, job1} 427 c.Assert(jobs, DeepEquals, expectJobs) 428 429 err = txn.Commit(context.Background()) 430 c.Assert(err, IsNil) 431 432 // Test for add index job. 433 txn1, err := causetstore.Begin() 434 c.Assert(err, IsNil) 435 defer txn1.Rollback() 436 437 m := spacetime.NewMeta(txn1, spacetime.AddIndexJobListKey) 438 err = m.EnQueueDBSJob(job) 439 c.Assert(err, IsNil) 440 job.ID = 123 441 err = m.UFIDelateDBSJob(0, job, true, spacetime.AddIndexJobListKey) 442 c.Assert(err, IsNil) 443 v, err = m.GetDBSJobByIdx(0, spacetime.AddIndexJobListKey) 444 c.Assert(err, IsNil) 445 c.Assert(v, DeepEquals, job) 446 l, err := m.DBSJobQueueLen(spacetime.AddIndexJobListKey) 447 c.Assert(err, IsNil) 448 c.Assert(l, Equals, int64(1)) 449 jobs, err = m.GetAllDBSJobsInQueue(spacetime.AddIndexJobListKey) 450 c.Assert(err, IsNil) 451 expectJobs = []*perceptron.Job{job} 452 c.Assert(jobs, DeepEquals, expectJobs) 453 454 err = txn1.Commit(context.Background()) 455 c.Assert(err, IsNil) 456 457 s.RerunWithCommonHandleEnabled(c, s.TestDBS) 458 } 459 460 func (s *testSuite) BenchmarkGenGlobalIDs(c *C) { 461 defer testleak.AfterTest(c)() 462 causetstore, err := mockstore.NewMockStore() 463 c.Assert(err, IsNil) 464 defer causetstore.Close() 465 466 txn, err := causetstore.Begin() 467 c.Assert(err, IsNil) 468 defer txn.Rollback() 469 470 t := spacetime.NewMeta(txn) 471 472 c.ResetTimer() 473 var ids []int64 474 for i := 0; i < c.N; i++ { 475 ids, _ = t.GenGlobalIDs(10) 476 } 477 c.Assert(ids, HasLen, 10) 478 c.Assert(ids[9], Equals, int64(c.N)*10) 479 } 480 481 func (s *testSuite) BenchmarkGenGlobalIDOneByOne(c *C) { 482 defer testleak.AfterTest(c)() 483 causetstore, err := mockstore.NewMockStore() 484 c.Assert(err, IsNil) 485 defer causetstore.Close() 486 487 txn, err := causetstore.Begin() 488 c.Assert(err, IsNil) 489 defer txn.Rollback() 490 491 t := spacetime.NewMeta(txn) 492 493 c.ResetTimer() 494 var id int64 495 for i := 0; i < c.N; i++ { 496 for j := 0; j < 10; j++ { 497 id, _ = t.GenGlobalID() 498 } 499 } 500 c.Assert(id, Equals, int64(c.N)*10) 501 } 502 503 func anyMatch(c *C, ids []int64, candidates ...[]int64) { 504 var match bool 505 OUTER: 506 for _, cand := range candidates { 507 if len(ids) != len(cand) { 508 continue 509 } 510 for i, v := range cand { 511 if ids[i] != v { 512 continue OUTER 513 } 514 } 515 match = true 516 break 517 } 518 c.Assert(match, IsTrue) 519 } 520 521 func mustNewCommonHandle(c *C, values ...interface{}) *ekv.CommonHandle { 522 encoded, err := codec.EncodeKey(new(stmtctx.StatementContext), nil, types.MakeCausets(values...)...) 523 c.Assert(err, IsNil) 524 ch, err := ekv.NewCommonHandle(encoded) 525 c.Assert(err, IsNil) 526 return ch 527 }