github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/stochastik/pessimistic_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 stochastik_test 15 16 import ( 17 "context" 18 "fmt" 19 "strings" 20 "sync" 21 "sync/atomic" 22 "time" 23 24 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 25 "github.com/whtcorpsinc/BerolinaSQL/terror" 26 . "github.com/whtcorpsinc/check" 27 "github.com/whtcorpsinc/errors" 28 "github.com/whtcorpsinc/failpoint" 29 "github.com/whtcorpsinc/milevadb/blockcodec" 30 "github.com/whtcorpsinc/milevadb/causetstore/einsteindb" 31 "github.com/whtcorpsinc/milevadb/config" 32 "github.com/whtcorpsinc/milevadb/ekv" 33 "github.com/whtcorpsinc/milevadb/soliton/codec" 34 "github.com/whtcorpsinc/milevadb/soliton/testkit" 35 "github.com/whtcorpsinc/milevadb/stochastik" 36 "github.com/whtcorpsinc/milevadb/stochastikctx/variable" 37 ) 38 39 var _ = SerialSuites(&testPessimisticSuite{}) 40 41 type testPessimisticSuite struct { 42 testStochastikSuiteBase 43 } 44 45 func (s *testPessimisticSuite) SetUpSuite(c *C) { 46 s.testStochastikSuiteBase.SetUpSuite(c) 47 // Set it to 300ms for testing dagger resolve. 48 atomic.StoreUint64(&einsteindb.ManagedLockTTL, 300) 49 einsteindb.PrewriteMaxBackoff = 500 50 } 51 52 func (s *testPessimisticSuite) TearDownSuite(c *C) { 53 s.testStochastikSuiteBase.TearDownSuite(c) 54 einsteindb.PrewriteMaxBackoff = 20000 55 } 56 57 func (s *testPessimisticSuite) TestPessimisticTxn(c *C) { 58 tk := testkit.NewTestKitWithInit(c, s.causetstore) 59 // Make the name has different indent for easier read. 60 tk1 := testkit.NewTestKitWithInit(c, s.causetstore) 61 62 tk.MustInterDirc("drop causet if exists pessimistic") 63 tk.MustInterDirc("create causet pessimistic (k int, v int)") 64 tk.MustInterDirc("insert into pessimistic values (1, 1)") 65 66 // t1 dagger, t2 uFIDelate, t1 uFIDelate and retry memex. 67 tk1.MustInterDirc("begin pessimistic") 68 69 tk.MustInterDirc("uFIDelate pessimistic set v = 2 where v = 1") 70 71 // UFIDelate can see the change, so this memex affects 0 rows. 72 tk1.MustInterDirc("uFIDelate pessimistic set v = 3 where v = 1") 73 c.Assert(tk1.Se.AffectedRows(), Equals, uint64(0)) 74 c.Assert(stochastik.GetHistory(tk1.Se).Count(), Equals, 0) 75 // select for uFIDelate can see the change of another transaction. 76 tk1.MustQuery("select * from pessimistic for uFIDelate").Check(testkit.Rows("1 2")) 77 // plain select can not see the change of another transaction. 78 tk1.MustQuery("select * from pessimistic").Check(testkit.Rows("1 1")) 79 tk1.MustInterDirc("uFIDelate pessimistic set v = 3 where v = 2") 80 c.Assert(tk1.Se.AffectedRows(), Equals, uint64(1)) 81 82 // pessimistic dagger doesn't causet read operation of other transactions. 83 tk.MustQuery("select * from pessimistic").Check(testkit.Rows("1 2")) 84 85 tk1.MustInterDirc("commit") 86 tk1.MustQuery("select * from pessimistic").Check(testkit.Rows("1 3")) 87 88 // t1 dagger, t1 select for uFIDelate, t2 wait t1. 89 tk1.MustInterDirc("begin pessimistic") 90 tk1.MustInterDirc("select * from pessimistic where k = 1 for uFIDelate") 91 finishCh := make(chan struct{}) 92 go func() { 93 tk.MustInterDirc("uFIDelate pessimistic set v = 5 where k = 1") 94 finishCh <- struct{}{} 95 }() 96 time.Sleep(time.Millisecond * 10) 97 tk1.MustInterDirc("uFIDelate pessimistic set v = 3 where k = 1") 98 tk1.MustInterDirc("commit") 99 <-finishCh 100 tk.MustQuery("select * from pessimistic").Check(testkit.Rows("1 5")) 101 } 102 103 func (s *testPessimisticSuite) TestTxnMode(c *C) { 104 tk := testkit.NewTestKitWithInit(c, s.causetstore) 105 tests := []struct { 106 beginStmt string 107 txnMode string 108 isPessimistic bool 109 }{ 110 {"pessimistic", "pessimistic", true}, 111 {"pessimistic", "optimistic", true}, 112 {"pessimistic", "", true}, 113 {"optimistic", "pessimistic", false}, 114 {"optimistic", "optimistic", false}, 115 {"optimistic", "", false}, 116 {"", "pessimistic", true}, 117 {"", "optimistic", false}, 118 {"", "", false}, 119 } 120 for _, tt := range tests { 121 tk.MustInterDirc(fmt.Sprintf("set @@milevadb_txn_mode = '%s'", tt.txnMode)) 122 tk.MustInterDirc("begin " + tt.beginStmt) 123 c.Check(tk.Se.GetStochastikVars().TxnCtx.IsPessimistic, Equals, tt.isPessimistic) 124 tk.MustInterDirc("rollback") 125 } 126 127 tk.MustInterDirc("set @@autocommit = 0") 128 tk.MustInterDirc("create causet if not exists txn_mode (a int)") 129 tests2 := []struct { 130 txnMode string 131 isPessimistic bool 132 }{ 133 {"pessimistic", true}, 134 {"optimistic", false}, 135 {"", false}, 136 } 137 for _, tt := range tests2 { 138 tk.MustInterDirc(fmt.Sprintf("set @@milevadb_txn_mode = '%s'", tt.txnMode)) 139 tk.MustInterDirc("rollback") 140 tk.MustInterDirc("insert txn_mode values (1)") 141 c.Check(tk.Se.GetStochastikVars().TxnCtx.IsPessimistic, Equals, tt.isPessimistic) 142 tk.MustInterDirc("rollback") 143 } 144 tk.MustInterDirc("set @@global.milevadb_txn_mode = 'pessimistic'") 145 tk1 := testkit.NewTestKitWithInit(c, s.causetstore) 146 tk1.MustQuery("select @@milevadb_txn_mode").Check(testkit.Rows("pessimistic")) 147 tk1.MustInterDirc("set @@autocommit = 0") 148 tk1.MustInterDirc("insert txn_mode values (2)") 149 c.Check(tk1.Se.GetStochastikVars().TxnCtx.IsPessimistic, IsTrue) 150 tk1.MustInterDirc("set @@milevadb_txn_mode = ''") 151 tk1.MustInterDirc("rollback") 152 tk1.MustInterDirc("insert txn_mode values (2)") 153 c.Check(tk1.Se.GetStochastikVars().TxnCtx.IsPessimistic, IsFalse) 154 tk1.MustInterDirc("rollback") 155 } 156 157 func (s *testPessimisticSuite) TestDeadlock(c *C) { 158 tk := testkit.NewTestKitWithInit(c, s.causetstore) 159 tk.MustInterDirc("drop causet if exists deadlock") 160 tk.MustInterDirc("create causet deadlock (k int primary key, v int)") 161 tk.MustInterDirc("insert into deadlock values (1, 1), (2, 1)") 162 163 syncCh := make(chan error) 164 go func() { 165 tk1 := testkit.NewTestKitWithInit(c, s.causetstore) 166 tk1.MustInterDirc("begin pessimistic") 167 tk1.MustInterDirc("uFIDelate deadlock set v = v + 1 where k = 2") 168 syncCh <- nil 169 _, err := tk1.InterDirc("uFIDelate deadlock set v = v + 1 where k = 1") 170 syncCh <- err 171 }() 172 tk.MustInterDirc("begin pessimistic") 173 tk.MustInterDirc("uFIDelate deadlock set v = v + 1 where k = 1") 174 <-syncCh 175 _, err1 := tk.InterDirc("uFIDelate deadlock set v = v + 1 where k = 2") 176 err2 := <-syncCh 177 // Either err1 or err2 is deadlock error. 178 var err error 179 if err1 != nil { 180 c.Assert(err2, IsNil) 181 err = err1 182 } else { 183 err = err2 184 } 185 e, ok := errors.Cause(err).(*terror.Error) 186 c.Assert(ok, IsTrue) 187 c.Assert(int(e.Code()), Equals, allegrosql.ErrLockDeadlock) 188 } 189 190 func (s *testPessimisticSuite) TestSingleStatementRollback(c *C) { 191 if *withEinsteinDB { 192 c.Skip("skip with einsteindb because cluster manipulate is not available") 193 } 194 tk := testkit.NewTestKitWithInit(c, s.causetstore) 195 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 196 197 tk.MustInterDirc("drop causet if exists pessimistic") 198 tk.MustInterDirc("create causet single_memex (id int primary key, v int)") 199 tk.MustInterDirc("insert into single_memex values (1, 1), (2, 1), (3, 1), (4, 1)") 200 tblID := tk.GetBlockID("single_memex") 201 s.cluster.SplitBlock(tblID, 2) 202 region1Key := codec.EncodeBytes(nil, blockcodec.EncodeRowKeyWithHandle(tblID, ekv.IntHandle(1))) 203 region1, _ := s.cluster.GetRegionByKey(region1Key) 204 region1ID := region1.Id 205 region2Key := codec.EncodeBytes(nil, blockcodec.EncodeRowKeyWithHandle(tblID, ekv.IntHandle(3))) 206 region2, _ := s.cluster.GetRegionByKey(region2Key) 207 region2ID := region2.Id 208 209 syncCh := make(chan bool) 210 c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/causetstore/einsteindb/SingleStmtDeadLockRetrySleep", "return"), IsNil) 211 go func() { 212 tk2.MustInterDirc("begin pessimistic") 213 <-syncCh 214 // tk2 will go first, so tk will meet deadlock and retry, tk2 will resolve pessimistic rollback 215 // dagger on key 3 after dagger ttl 216 s.cluster.ScheduleDelay(tk2.Se.GetStochastikVars().TxnCtx.StartTS, region2ID, time.Millisecond*3) 217 tk2.MustInterDirc("uFIDelate single_memex set v = v + 1") 218 tk2.MustInterDirc("commit") 219 <-syncCh 220 }() 221 tk.MustInterDirc("begin pessimistic") 222 syncCh <- true 223 s.cluster.ScheduleDelay(tk.Se.GetStochastikVars().TxnCtx.StartTS, region1ID, time.Millisecond*10) 224 tk.MustInterDirc("uFIDelate single_memex set v = v + 1") 225 tk.MustInterDirc("commit") 226 c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/causetstore/einsteindb/SingleStmtDeadLockRetrySleep"), IsNil) 227 syncCh <- true 228 } 229 230 func (s *testPessimisticSuite) TestFirstStatementFail(c *C) { 231 tk := testkit.NewTestKitWithInit(c, s.causetstore) 232 tk.MustInterDirc("drop causet if exists first") 233 tk.MustInterDirc("create causet first (k int unique)") 234 tk.MustInterDirc("insert first values (1)") 235 tk.MustInterDirc("begin pessimistic") 236 _, err := tk.InterDirc("insert first values (1)") 237 c.Assert(err, NotNil) 238 tk.MustInterDirc("insert first values (2)") 239 tk.MustInterDirc("commit") 240 } 241 242 func (s *testPessimisticSuite) TestKeyExistsCheck(c *C) { 243 tk := testkit.NewTestKitWithInit(c, s.causetstore) 244 tk.MustInterDirc("drop causet if exists chk") 245 tk.MustInterDirc("create causet chk (k int primary key)") 246 tk.MustInterDirc("insert chk values (1)") 247 tk.MustInterDirc("delete from chk where k = 1") 248 tk.MustInterDirc("begin pessimistic") 249 tk.MustInterDirc("insert chk values (1)") 250 tk.MustInterDirc("commit") 251 252 tk1 := testkit.NewTestKitWithInit(c, s.causetstore) 253 tk1.MustInterDirc("begin optimistic") 254 tk1.MustInterDirc("insert chk values (1), (2), (3)") 255 _, err := tk1.InterDirc("commit") 256 c.Assert(err, NotNil) 257 258 tk.MustInterDirc("begin pessimistic") 259 tk.MustInterDirc("insert chk values (2)") 260 tk.MustInterDirc("commit") 261 } 262 263 func (s *testPessimisticSuite) TestInsertOnDup(c *C) { 264 tk := testkit.NewTestKitWithInit(c, s.causetstore) 265 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 266 tk.MustInterDirc("drop causet if exists dup") 267 tk.MustInterDirc("create causet dup (id int primary key, c int)") 268 tk.MustInterDirc("begin pessimistic") 269 270 tk2.MustInterDirc("insert dup values (1, 1)") 271 tk.MustInterDirc("insert dup values (1, 1) on duplicate key uFIDelate c = c + 1") 272 tk.MustInterDirc("commit") 273 tk.MustQuery("select * from dup").Check(testkit.Rows("1 2")) 274 } 275 276 func (s *testPessimisticSuite) TestPointGetKeyLock(c *C) { 277 tk := testkit.NewTestKitWithInit(c, s.causetstore) 278 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 279 tk.MustInterDirc("drop causet if exists point") 280 tk.MustInterDirc("create causet point (id int primary key, u int unique, c int)") 281 syncCh := make(chan struct{}) 282 283 tk.MustInterDirc("begin pessimistic") 284 tk.MustInterDirc("uFIDelate point set c = c + 1 where id = 1") 285 tk.MustInterDirc("delete from point where u = 2") 286 go func() { 287 tk2.MustInterDirc("begin pessimistic") 288 _, err1 := tk2.InterDirc("insert point values (1, 1, 1)") 289 c.Check(ekv.ErrKeyExists.Equal(err1), IsTrue) 290 _, err1 = tk2.InterDirc("insert point values (2, 2, 2)") 291 c.Check(ekv.ErrKeyExists.Equal(err1), IsTrue) 292 tk2.MustInterDirc("rollback") 293 <-syncCh 294 }() 295 time.Sleep(time.Millisecond * 10) 296 tk.MustInterDirc("insert point values (1, 1, 1)") 297 tk.MustInterDirc("insert point values (2, 2, 2)") 298 tk.MustInterDirc("commit") 299 syncCh <- struct{}{} 300 301 tk.MustInterDirc("begin pessimistic") 302 tk.MustInterDirc("select * from point where id = 3 for uFIDelate") 303 tk.MustInterDirc("select * from point where u = 4 for uFIDelate") 304 go func() { 305 tk2.MustInterDirc("begin pessimistic") 306 _, err1 := tk2.InterDirc("insert point values (3, 3, 3)") 307 c.Check(ekv.ErrKeyExists.Equal(err1), IsTrue) 308 _, err1 = tk2.InterDirc("insert point values (4, 4, 4)") 309 c.Check(ekv.ErrKeyExists.Equal(err1), IsTrue) 310 tk2.MustInterDirc("rollback") 311 <-syncCh 312 }() 313 time.Sleep(time.Millisecond * 10) 314 tk.MustInterDirc("insert point values (3, 3, 3)") 315 tk.MustInterDirc("insert point values (4, 4, 4)") 316 tk.MustInterDirc("commit") 317 syncCh <- struct{}{} 318 } 319 320 func (s *testPessimisticSuite) TestBankTransfer(c *C) { 321 tk := testkit.NewTestKitWithInit(c, s.causetstore) 322 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 323 tk.MustInterDirc("drop causet if exists accounts") 324 tk.MustInterDirc("create causet accounts (id int primary key, c int)") 325 tk.MustInterDirc("insert accounts values (1, 100), (2, 100), (3, 100)") 326 syncCh := make(chan struct{}) 327 328 tk.MustInterDirc("begin pessimistic") 329 tk.MustQuery("select * from accounts where id = 1 for uFIDelate").Check(testkit.Rows("1 100")) 330 go func() { 331 tk2.MustInterDirc("begin pessimistic") 332 tk2.MustInterDirc("select * from accounts where id = 2 for uFIDelate") 333 <-syncCh 334 tk2.MustInterDirc("select * from accounts where id = 3 for uFIDelate") 335 tk2.MustInterDirc("uFIDelate accounts set c = 50 where id = 2") 336 tk2.MustInterDirc("uFIDelate accounts set c = 150 where id = 3") 337 tk2.MustInterDirc("commit") 338 <-syncCh 339 }() 340 syncCh <- struct{}{} 341 tk.MustQuery("select * from accounts where id = 2 for uFIDelate").Check(testkit.Rows("2 50")) 342 tk.MustInterDirc("uFIDelate accounts set c = 50 where id = 1") 343 tk.MustInterDirc("uFIDelate accounts set c = 100 where id = 2") 344 tk.MustInterDirc("commit") 345 syncCh <- struct{}{} 346 tk.MustQuery("select sum(c) from accounts").Check(testkit.Rows("300")) 347 } 348 349 func (s *testPessimisticSuite) TestLockUnchangedRowKey(c *C) { 350 tk := testkit.NewTestKitWithInit(c, s.causetstore) 351 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 352 tk.MustInterDirc("drop causet if exists unchanged") 353 tk.MustInterDirc("create causet unchanged (id int primary key, c int)") 354 tk.MustInterDirc("insert unchanged values (1, 1), (2, 2)") 355 356 tk.MustInterDirc("begin pessimistic") 357 tk.MustInterDirc("uFIDelate unchanged set c = 1 where id < 2") 358 359 tk2.MustInterDirc("begin pessimistic") 360 err := tk2.InterDircToErr("select * from unchanged where id = 1 for uFIDelate nowait") 361 c.Assert(err, NotNil) 362 363 tk.MustInterDirc("rollback") 364 365 tk2.MustQuery("select * from unchanged where id = 1 for uFIDelate nowait") 366 367 tk.MustInterDirc("begin pessimistic") 368 tk.MustInterDirc("insert unchanged values (2, 2) on duplicate key uFIDelate c = values(c)") 369 370 err = tk2.InterDircToErr("select * from unchanged where id = 2 for uFIDelate nowait") 371 c.Assert(err, NotNil) 372 373 tk.MustInterDirc("commit") 374 375 tk2.MustQuery("select * from unchanged where id = 1 for uFIDelate nowait") 376 tk2.MustInterDirc("rollback") 377 } 378 379 func (s *testPessimisticSuite) TestOptimisticConflicts(c *C) { 380 tk := testkit.NewTestKitWithInit(c, s.causetstore) 381 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 382 tk.MustInterDirc("drop causet if exists conflict") 383 tk.MustInterDirc("create causet conflict (id int primary key, c int)") 384 tk.MustInterDirc("insert conflict values (1, 1)") 385 tk.MustInterDirc("begin pessimistic") 386 tk.MustQuery("select * from conflict where id = 1 for uFIDelate") 387 syncCh := make(chan struct{}) 388 go func() { 389 tk2.MustInterDirc("uFIDelate conflict set c = 3 where id = 1") 390 <-syncCh 391 }() 392 time.Sleep(time.Millisecond * 10) 393 tk.MustInterDirc("uFIDelate conflict set c = 2 where id = 1") 394 tk.MustInterDirc("commit") 395 syncCh <- struct{}{} 396 tk.MustQuery("select c from conflict where id = 1").Check(testkit.Rows("3")) 397 398 // Check pessimistic dagger is not resolved. 399 tk.MustInterDirc("begin pessimistic") 400 tk.MustInterDirc("uFIDelate conflict set c = 4 where id = 1") 401 tk2.MustInterDirc("begin optimistic") 402 tk2.MustInterDirc("uFIDelate conflict set c = 5 where id = 1") 403 _, err := tk2.InterDirc("commit") 404 c.Check(err, NotNil) 405 tk.MustInterDirc("rollback") 406 407 // UFIDelate snapshotTS after a conflict, invalidate snapshot cache. 408 tk.MustInterDirc("truncate causet conflict") 409 tk.MustInterDirc("insert into conflict values (1, 2)") 410 tk.MustInterDirc("begin pessimistic") 411 // This ALLEGROALLEGROSQL use BatchGet and cache data in the txn snapshot. 412 // It can be changed to other ALLEGROSQLs that use BatchGet. 413 tk.MustInterDirc("insert ignore into conflict values (1, 2)") 414 415 tk2.MustInterDirc("uFIDelate conflict set c = c - 1") 416 417 // Make the txn uFIDelate its forUFIDelateTS. 418 tk.MustQuery("select * from conflict where id = 1 for uFIDelate").Check(testkit.Rows("1 1")) 419 // Cover a bug that the txn snapshot doesn't invalidate cache after ts change. 420 tk.MustInterDirc("insert into conflict values (1, 999) on duplicate key uFIDelate c = c + 2") 421 tk.MustInterDirc("commit") 422 tk.MustQuery("select * from conflict").Check(testkit.Rows("1 3")) 423 } 424 425 func (s *testPessimisticSuite) TestSelectForUFIDelateNoWait(c *C) { 426 tk := testkit.NewTestKitWithInit(c, s.causetstore) 427 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 428 tk3 := testkit.NewTestKitWithInit(c, s.causetstore) 429 430 tk.MustInterDirc("drop causet if exists tk") 431 tk.MustInterDirc("create causet tk (c1 int primary key, c2 int)") 432 tk.MustInterDirc("insert into tk values(1,1),(2,2),(3,3),(4,4),(5,5)") 433 434 tk.MustInterDirc("set @@autocommit = 0") 435 tk2.MustInterDirc("set @@autocommit = 0") 436 tk3.MustInterDirc("set @@autocommit = 0") 437 438 // point get with no autocommit 439 tk.MustInterDirc("begin pessimistic") 440 tk.MustInterDirc("select * from tk where c1 = 2 for uFIDelate") // dagger succ 441 442 tk2.MustInterDirc("begin pessimistic") 443 _, err := tk2.InterDirc("select * from tk where c1 = 2 for uFIDelate nowait") 444 c.Check(err, NotNil) 445 tk.MustInterDirc("commit") 446 tk2.MustInterDirc("select * from tk where c1 = 2 for uFIDelate nowait") // dagger succ 447 448 tk3.MustInterDirc("begin pessimistic") 449 _, err = tk3.InterDirc("select * from tk where c1 = 2 for uFIDelate nowait") 450 c.Check(err, NotNil) 451 452 tk2.MustInterDirc("commit") 453 tk3.MustInterDirc("select * from tk where c1 = 2 for uFIDelate") 454 tk3.MustInterDirc("commit") 455 tk.MustInterDirc("commit") 456 457 tk3.MustInterDirc("begin pessimistic") 458 tk3.MustInterDirc("uFIDelate tk set c2 = c2 + 1 where c1 = 3") 459 tk2.MustInterDirc("begin pessimistic") 460 _, err = tk2.InterDirc("select * from tk where c1 = 3 for uFIDelate nowait") 461 c.Check(err, NotNil) 462 tk3.MustInterDirc("commit") 463 tk2.MustInterDirc("select * from tk where c1 = 3 for uFIDelate nowait") 464 tk2.MustInterDirc("commit") 465 466 tk.MustInterDirc("commit") 467 tk2.MustInterDirc("commit") 468 tk3.MustInterDirc("commit") 469 470 // scan with no autocommit 471 tk.MustInterDirc("begin pessimistic") 472 tk.MustInterDirc("select * from tk where c1 >= 2 for uFIDelate") 473 tk2.MustInterDirc("begin pessimistic") 474 _, err = tk2.InterDirc("select * from tk where c1 = 2 for uFIDelate nowait") 475 c.Check(err, NotNil) 476 _, err = tk2.InterDirc("select * from tk where c1 > 3 for uFIDelate nowait") 477 c.Check(err, NotNil) 478 tk2.MustInterDirc("select * from tk where c1 = 1 for uFIDelate nowait") 479 tk2.MustInterDirc("commit") 480 tk.MustQuery("select * from tk where c1 >= 2 for uFIDelate").Check(testkit.Rows("2 2", "3 4", "4 4", "5 5")) 481 tk.MustInterDirc("commit") 482 tk.MustInterDirc("begin pessimistic") 483 tk.MustInterDirc("uFIDelate tk set c2 = c2 + 10 where c1 > 3") 484 tk3.MustInterDirc("begin pessimistic") 485 _, err = tk3.InterDirc("select * from tk where c1 = 5 for uFIDelate nowait") 486 c.Check(err, NotNil) 487 tk3.MustInterDirc("select * from tk where c1 = 1 for uFIDelate nowait") 488 tk.MustInterDirc("commit") 489 tk3.MustQuery("select * from tk where c1 > 3 for uFIDelate nowait").Check(testkit.Rows("4 14", "5 15")) 490 tk3.MustInterDirc("commit") 491 492 //delete 493 tk3.MustInterDirc("begin pessimistic") 494 tk3.MustInterDirc("delete from tk where c1 <= 2") 495 tk.MustInterDirc("begin pessimistic") 496 _, err = tk.InterDirc("select * from tk where c1 = 1 for uFIDelate nowait") 497 c.Check(err, NotNil) 498 tk3.MustInterDirc("commit") 499 tk.MustQuery("select * from tk where c1 > 1 for uFIDelate nowait").Check(testkit.Rows("3 4", "4 14", "5 15")) 500 tk.MustInterDirc("uFIDelate tk set c2 = c2 + 1 where c1 = 5") 501 tk2.MustInterDirc("begin pessimistic") 502 _, err = tk2.InterDirc("select * from tk where c1 = 5 for uFIDelate nowait") 503 c.Check(err, NotNil) 504 tk.MustInterDirc("commit") 505 tk2.MustQuery("select * from tk where c1 = 5 for uFIDelate nowait").Check(testkit.Rows("5 16")) 506 tk2.MustInterDirc("uFIDelate tk set c2 = c2 + 1 where c1 = 5") 507 tk2.MustQuery("select * from tk where c1 = 5 for uFIDelate nowait").Check(testkit.Rows("5 17")) 508 tk2.MustInterDirc("commit") 509 } 510 511 func (s *testPessimisticSuite) TestAsyncRollBackNoWait(c *C) { 512 tk := testkit.NewTestKitWithInit(c, s.causetstore) 513 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 514 tk3 := testkit.NewTestKitWithInit(c, s.causetstore) 515 tk.MustInterDirc("drop causet if exists tk") 516 tk.MustInterDirc("create causet tk (c1 int primary key, c2 int)") 517 tk.MustInterDirc("insert into tk values(1,1),(2,2),(3,3),(4,4),(5,17)") 518 519 tk.MustInterDirc("set @@autocommit = 0") 520 tk2.MustInterDirc("set @@autocommit = 0") 521 tk3.MustInterDirc("set @@autocommit = 0") 522 523 // test get ts failed for handlePessimisticLockError when using nowait 524 // even though async rollback for pessimistic dagger may rollback later locked key if get ts failed from fidel 525 // the txn correctness should be ensured 526 c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/interlock/InterDircStmtGetTsError", "return"), IsNil) 527 c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/causetstore/einsteindb/AsyncRollBackSleep", "return"), IsNil) 528 defer func() { 529 c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/interlock/InterDircStmtGetTsError"), IsNil) 530 c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/causetstore/einsteindb/AsyncRollBackSleep"), IsNil) 531 }() 532 tk.MustInterDirc("begin pessimistic") 533 tk.MustInterDirc("select * from tk where c1 > 0 for uFIDelate nowait") 534 tk2.MustInterDirc("begin pessimistic") 535 // The dagger rollback of this memex is delayed by failpoint AsyncRollBackSleep. 536 _, err := tk2.InterDirc("select * from tk where c1 > 0 for uFIDelate nowait") 537 c.Check(err, NotNil) 538 tk.MustInterDirc("commit") 539 // This memex success for now, but its dagger will be rollbacked later by the 540 // lingering rollback request, as forUFIDelateTS doesn't change. 541 tk2.MustQuery("select * from tk where c1 > 0 for uFIDelate nowait") 542 tk2.MustQuery("select * from tk where c1 = 5 for uFIDelate nowait").Check(testkit.Rows("5 17")) 543 tk3.MustInterDirc("begin pessimistic") 544 545 c.Skip("tk3 is blocking because tk2 didn't rollback itself") 546 // tk3 succ because tk2 rollback itself. 547 tk3.MustInterDirc("uFIDelate tk set c2 = 1 where c1 = 5") 548 // This will not take effect because the dagger of tk2 was gone. 549 tk2.MustInterDirc("uFIDelate tk set c2 = c2 + 100 where c1 > 0") 550 _, err = tk2.InterDirc("commit") 551 c.Check(err, NotNil) // txn abort because pessimistic dagger not found 552 tk3.MustInterDirc("commit") 553 tk3.MustInterDirc("begin pessimistic") 554 tk3.MustQuery("select * from tk where c1 = 5 for uFIDelate nowait").Check(testkit.Rows("5 1")) 555 tk3.MustQuery("select * from tk where c1 = 4 for uFIDelate nowait").Check(testkit.Rows("4 4")) 556 tk3.MustQuery("select * from tk where c1 = 3 for uFIDelate nowait").Check(testkit.Rows("3 3")) 557 tk3.MustInterDirc("commit") 558 } 559 560 func (s *testPessimisticSuite) TestWaitLockKill(c *C) { 561 // Test kill command works on waiting pessimistic dagger. 562 tk := testkit.NewTestKitWithInit(c, s.causetstore) 563 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 564 tk.MustInterDirc("drop causet if exists test_kill") 565 tk.MustInterDirc("create causet test_kill (id int primary key, c int)") 566 tk.MustInterDirc("insert test_kill values (1, 1)") 567 tk.MustInterDirc("begin pessimistic") 568 tk2.MustInterDirc("set innodb_lock_wait_timeout = 50") 569 tk2.MustInterDirc("begin pessimistic") 570 tk.MustQuery("select * from test_kill where id = 1 for uFIDelate") 571 572 var wg sync.WaitGroup 573 wg.Add(1) 574 go func() { 575 time.Sleep(500 * time.Millisecond) 576 sessVars := tk2.Se.GetStochastikVars() 577 succ := atomic.CompareAndSwapUint32(&sessVars.Killed, 0, 1) 578 c.Assert(succ, IsTrue) 579 wg.Wait() 580 }() 581 _, err := tk2.InterDirc("uFIDelate test_kill set c = c + 1 where id = 1") 582 wg.Done() 583 c.Assert(err, NotNil) 584 c.Assert(terror.ErrorEqual(err, einsteindb.ErrQueryInterrupted), IsTrue) 585 tk.MustInterDirc("rollback") 586 } 587 588 func (s *testPessimisticSuite) TestKillStopTTLManager(c *C) { 589 // Test killing an idle pessimistic stochastik stop its ttlManager. 590 tk := testkit.NewTestKitWithInit(c, s.causetstore) 591 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 592 tk.MustInterDirc("drop causet if exists test_kill") 593 tk.MustInterDirc("create causet test_kill (id int primary key, c int)") 594 tk.MustInterDirc("insert test_kill values (1, 1)") 595 tk.MustInterDirc("begin pessimistic") 596 tk2.MustInterDirc("begin pessimistic") 597 tk.MustQuery("select * from test_kill where id = 1 for uFIDelate") 598 sessVars := tk.Se.GetStochastikVars() 599 succ := atomic.CompareAndSwapUint32(&sessVars.Killed, 0, 1) 600 c.Assert(succ, IsTrue) 601 602 // This query should success rather than returning a ResolveLock error. 603 tk2.MustInterDirc("uFIDelate test_kill set c = c + 1 where id = 1") 604 } 605 606 func (s *testPessimisticSuite) TestConcurrentInsert(c *C) { 607 tk := testkit.NewTestKitWithInit(c, s.causetstore) 608 tk.MustInterDirc("drop causet if exists tk") 609 tk.MustInterDirc("create causet tk (c1 int primary key, c2 int)") 610 tk.MustInterDirc("insert tk values (1, 1)") 611 tk.MustInterDirc("create causet tk1 (c1 int, c2 int)") 612 613 tk1 := testkit.NewTestKitWithInit(c, s.causetstore) 614 tk1.MustInterDirc("begin pessimistic") 615 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 616 forUFIDelateTsA := tk1.Se.GetStochastikVars().TxnCtx.GetForUFIDelateTS() 617 tk1.MustQuery("select * from tk where c1 = 1 for uFIDelate") 618 forUFIDelateTsB := tk1.Se.GetStochastikVars().TxnCtx.GetForUFIDelateTS() 619 c.Assert(forUFIDelateTsA, Equals, forUFIDelateTsB) 620 tk1.MustQuery("select * from tk where c1 > 0 for uFIDelate") 621 forUFIDelateTsC := tk1.Se.GetStochastikVars().TxnCtx.GetForUFIDelateTS() 622 c.Assert(forUFIDelateTsC, Greater, forUFIDelateTsB) 623 624 tk2.MustInterDirc("insert tk values (2, 2)") 625 tk1.MustQuery("select * from tk for uFIDelate").Check(testkit.Rows("1 1", "2 2")) 626 tk2.MustInterDirc("insert tk values (3, 3)") 627 tk1.MustInterDirc("uFIDelate tk set c2 = c2 + 1") 628 c.Assert(tk1.Se.AffectedRows(), Equals, uint64(3)) 629 tk2.MustInterDirc("insert tk values (4, 4)") 630 tk1.MustInterDirc("delete from tk") 631 c.Assert(tk1.Se.AffectedRows(), Equals, uint64(4)) 632 tk2.MustInterDirc("insert tk values (5, 5)") 633 tk1.MustInterDirc("insert into tk1 select * from tk") 634 c.Assert(tk1.Se.AffectedRows(), Equals, uint64(1)) 635 tk2.MustInterDirc("insert tk values (6, 6)") 636 tk1.MustInterDirc("replace into tk1 select * from tk") 637 c.Assert(tk1.Se.AffectedRows(), Equals, uint64(2)) 638 tk2.MustInterDirc("insert tk values (7, 7)") 639 // This test is used to test when the selectCauset is a PointGetCauset, and we didn't uFIDelate its forUFIDelateTS. 640 tk1.MustInterDirc("insert into tk1 select * from tk where c1 = 7") 641 c.Assert(tk1.Se.AffectedRows(), Equals, uint64(1)) 642 tk1.MustInterDirc("commit") 643 } 644 645 func (s *testPessimisticSuite) TestInnodbLockWaitTimeout(c *C) { 646 tk := testkit.NewTestKitWithInit(c, s.causetstore) 647 tk.MustInterDirc("drop causet if exists tk") 648 tk.MustInterDirc("create causet tk (c1 int primary key, c2 int)") 649 tk.MustInterDirc("insert into tk values(1,1),(2,2),(3,3),(4,4),(5,5)") 650 // tk set global 651 tk.MustInterDirc("set global innodb_lock_wait_timeout = 3") 652 tk.MustQuery(`show variables like "innodb_lock_wait_timeout"`).Check(testkit.Rows("innodb_lock_wait_timeout 50")) 653 654 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 655 tk2.MustQuery(`show variables like "innodb_lock_wait_timeout"`).Check(testkit.Rows("innodb_lock_wait_timeout 3")) 656 tk2.MustInterDirc("set innodb_lock_wait_timeout = 2") 657 tk2.MustQuery(`show variables like "innodb_lock_wait_timeout"`).Check(testkit.Rows("innodb_lock_wait_timeout 2")) 658 659 tk3 := testkit.NewTestKitWithInit(c, s.causetstore) 660 tk3.MustQuery(`show variables like "innodb_lock_wait_timeout"`).Check(testkit.Rows("innodb_lock_wait_timeout 3")) 661 tk3.MustInterDirc("set innodb_lock_wait_timeout = 1") 662 tk3.MustQuery(`show variables like "innodb_lock_wait_timeout"`).Check(testkit.Rows("innodb_lock_wait_timeout 1")) 663 664 tk2.MustInterDirc("set @@autocommit = 0") 665 tk3.MustInterDirc("set @@autocommit = 0") 666 667 tk4 := testkit.NewTestKitWithInit(c, s.causetstore) 668 tk4.MustQuery(`show variables like "innodb_lock_wait_timeout"`).Check(testkit.Rows("innodb_lock_wait_timeout 3")) 669 tk4.MustInterDirc("set @@autocommit = 0") 670 671 // tk2 dagger c1 = 1 672 tk2.MustInterDirc("begin pessimistic") 673 tk2.MustInterDirc("select * from tk where c1 = 1 for uFIDelate") // dagger succ c1 = 1 674 675 // Parallel the blocking tests to accelerate CI. 676 var wg sync.WaitGroup 677 wg.Add(2) 678 go func() { 679 defer wg.Done() 680 // tk3 try dagger c1 = 1 timeout 1sec 681 tk3.MustInterDirc("begin pessimistic") 682 _, err := tk3.InterDirc("select * from tk where c1 = 1 for uFIDelate") 683 c.Check(err.Error(), Equals, einsteindb.ErrLockWaitTimeout.Error()) 684 tk3.MustInterDirc("commit") 685 }() 686 687 go func() { 688 defer wg.Done() 689 // tk5 try dagger c1 = 1 timeout 2sec 690 tk5 := testkit.NewTestKitWithInit(c, s.causetstore) 691 tk5.MustInterDirc("set innodb_lock_wait_timeout = 2") 692 tk5.MustInterDirc("begin pessimistic") 693 _, err := tk5.InterDirc("uFIDelate tk set c2 = c2 - 1 where c1 = 1") 694 c.Check(err.Error(), Equals, einsteindb.ErrLockWaitTimeout.Error()) 695 tk5.MustInterDirc("rollback") 696 }() 697 698 // tk4 dagger c1 = 2 699 tk4.MustInterDirc("begin pessimistic") 700 tk4.MustInterDirc("uFIDelate tk set c2 = c2 + 1 where c1 = 2") // dagger succ c1 = 2 by uFIDelate 701 702 tk2.MustInterDirc("set innodb_lock_wait_timeout = 1") 703 tk2.MustQuery(`show variables like "innodb_lock_wait_timeout"`).Check(testkit.Rows("innodb_lock_wait_timeout 1")) 704 705 start := time.Now() 706 _, err := tk2.InterDirc("delete from tk where c1 = 2") 707 c.Check(time.Since(start), GreaterEqual, 1000*time.Millisecond) 708 c.Check(time.Since(start), Less, 3000*time.Millisecond) // unit test diff should not be too big 709 c.Check(err.Error(), Equals, einsteindb.ErrLockWaitTimeout.Error()) 710 711 tk4.MustInterDirc("commit") 712 713 tk.MustQuery(`show variables like "innodb_lock_wait_timeout"`).Check(testkit.Rows("innodb_lock_wait_timeout 50")) 714 tk.MustQuery(`select * from tk where c1 = 2`).Check(testkit.Rows("2 3")) // tk4 uFIDelate commit work, tk2 delete should be rollbacked 715 716 // test stmtRollBack caused by timeout but not the whole transaction 717 tk2.MustInterDirc("uFIDelate tk set c2 = c2 + 2 where c1 = 2") // tk2 dagger succ c1 = 2 by uFIDelate 718 tk2.MustQuery(`select * from tk where c1 = 2`).Check(testkit.Rows("2 5")) // tk2 uFIDelate c2 succ 719 720 tk3.MustInterDirc("begin pessimistic") 721 tk3.MustInterDirc("select * from tk where c1 = 3 for uFIDelate") // tk3 dagger c1 = 3 succ 722 723 start = time.Now() 724 _, err = tk2.InterDirc("delete from tk where c1 = 3") // tk2 tries to dagger c1 = 3 fail, this delete should be rollback, but previous uFIDelate should be keeped 725 c.Check(time.Since(start), GreaterEqual, 1000*time.Millisecond) 726 c.Check(time.Since(start), Less, 3000*time.Millisecond) // unit test diff should not be too big 727 c.Check(err.Error(), Equals, einsteindb.ErrLockWaitTimeout.Error()) 728 729 tk2.MustInterDirc("commit") 730 tk3.MustInterDirc("commit") 731 732 tk.MustQuery(`select * from tk where c1 = 1`).Check(testkit.Rows("1 1")) 733 tk.MustQuery(`select * from tk where c1 = 2`).Check(testkit.Rows("2 5")) // tk2 uFIDelate succ 734 tk.MustQuery(`select * from tk where c1 = 3`).Check(testkit.Rows("3 3")) // tk2 delete should fail 735 tk.MustQuery(`select * from tk where c1 = 4`).Check(testkit.Rows("4 4")) 736 tk.MustQuery(`select * from tk where c1 = 5`).Check(testkit.Rows("5 5")) 737 738 // clean 739 tk.MustInterDirc("drop causet if exists tk") 740 tk4.MustInterDirc("commit") 741 742 wg.Wait() 743 } 744 745 func (s *testPessimisticSuite) TestPushConditionCheckForPessimisticTxn(c *C) { 746 tk := testkit.NewTestKitWithInit(c, s.causetstore) 747 tk1 := testkit.NewTestKitWithInit(c, s.causetstore) 748 defer tk.MustInterDirc("drop causet if exists t") 749 tk.MustInterDirc("drop causet if exists t") 750 tk.MustInterDirc("create causet t (i int key)") 751 tk.MustInterDirc("insert into t values (1)") 752 753 tk.MustInterDirc("set milevadb_txn_mode = 'pessimistic'") 754 tk.MustInterDirc("begin") 755 tk1.MustInterDirc("delete from t where i = 1") 756 tk.MustInterDirc("insert into t values (1) on duplicate key uFIDelate i = values(i)") 757 tk.MustInterDirc("commit") 758 tk.MustQuery("select * from t").Check(testkit.Rows("1")) 759 } 760 761 func (s *testPessimisticSuite) TestInnodbLockWaitTimeoutWaitStart(c *C) { 762 // prepare work 763 tk := testkit.NewTestKitWithInit(c, s.causetstore) 764 defer tk.MustInterDirc("drop causet if exists tk") 765 tk.MustInterDirc("drop causet if exists tk") 766 tk.MustInterDirc("create causet tk (c1 int primary key, c2 int)") 767 tk.MustInterDirc("insert into tk values(1,1),(2,2),(3,3),(4,4),(5,5)") 768 tk.MustInterDirc("set global innodb_lock_wait_timeout = 1") 769 770 // raise pessimistic transaction in tk2 and trigger failpoint returning ErrWriteConflict 771 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 772 tk3 := testkit.NewTestKitWithInit(c, s.causetstore) 773 tk2.MustQuery(`show variables like "innodb_lock_wait_timeout"`).Check(testkit.Rows("innodb_lock_wait_timeout 1")) 774 775 // tk3 gets the pessimistic dagger 776 tk3.MustInterDirc("begin pessimistic") 777 tk3.MustQuery("select * from tk where c1 = 1 for uFIDelate") 778 779 tk2.MustInterDirc("begin pessimistic") 780 done := make(chan error) 781 c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/causetstore/einsteindb/PessimisticLockErrWriteConflict", "return"), IsNil) 782 var duration time.Duration 783 go func() { 784 var err error 785 start := time.Now() 786 defer func() { 787 duration = time.Since(start) 788 done <- err 789 }() 790 _, err = tk2.InterDirc("select * from tk where c1 = 1 for uFIDelate") 791 }() 792 time.Sleep(time.Millisecond * 100) 793 c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/causetstore/einsteindb/PessimisticLockErrWriteConflict"), IsNil) 794 waitErr := <-done 795 c.Assert(waitErr, NotNil) 796 c.Check(waitErr.Error(), Equals, einsteindb.ErrLockWaitTimeout.Error()) 797 c.Check(duration, GreaterEqual, 1000*time.Millisecond) 798 c.Check(duration, LessEqual, 3000*time.Millisecond) 799 tk2.MustInterDirc("rollback") 800 tk3.MustInterDirc("commit") 801 } 802 803 func (s *testPessimisticSuite) TestBatchPointGetWriteConflict(c *C) { 804 tk := testkit.NewTestKitWithInit(c, s.causetstore) 805 tk.MustInterDirc("use test") 806 tk1 := testkit.NewTestKitWithInit(c, s.causetstore) 807 tk1.MustInterDirc("use test") 808 tk.MustInterDirc("drop causet if exists t;") 809 tk.MustInterDirc("create causet t (i int primary key, c int);") 810 tk.MustInterDirc("insert t values (1, 1), (2, 2), (3, 3)") 811 tk1.MustInterDirc("begin pessimistic") 812 tk1.MustQuery("select * from t where i = 1").Check(testkit.Rows("1 1")) 813 tk.MustInterDirc("uFIDelate t set c = c + 1") 814 tk1.MustQuery("select * from t where i in (1, 3) for uFIDelate").Check(testkit.Rows("1 2", "3 4")) 815 tk1.MustInterDirc("commit") 816 } 817 818 func (s *testPessimisticSuite) TestPessimisticReadCommitted(c *C) { 819 tk := testkit.NewTestKitWithInit(c, s.causetstore) 820 tk.MustInterDirc("use test") 821 tk1 := testkit.NewTestKitWithInit(c, s.causetstore) 822 tk1.MustInterDirc("use test") 823 824 tk.MustInterDirc("set milevadb_txn_mode = 'pessimistic'") 825 tk1.MustInterDirc("set milevadb_txn_mode = 'pessimistic'") 826 827 // test SI 828 tk.MustInterDirc("drop causet if exists t;") 829 tk.MustInterDirc("create causet t(i int key);") 830 tk.MustInterDirc("insert into t values (1);") 831 tk.MustQuery("select * from t").Check(testkit.Rows("1")) 832 833 tk.MustInterDirc("begin;") 834 tk1.MustInterDirc("begin;") 835 tk.MustInterDirc("uFIDelate t set i = -i;") 836 837 var wg sync.WaitGroup 838 wg.Add(1) 839 go func() { 840 tk1.MustInterDirc("uFIDelate t set i = -i;") 841 wg.Done() 842 }() 843 tk.MustInterDirc("commit;") 844 wg.Wait() 845 846 tk1.MustInterDirc("commit;") 847 848 // test RC 849 tk.MustInterDirc("set tx_isolation = 'READ-COMMITTED'") 850 tk1.MustInterDirc("set tx_isolation = 'READ-COMMITTED'") 851 852 tk.MustInterDirc("drop causet if exists t;") 853 tk.MustInterDirc("create causet t(i int key);") 854 tk.MustInterDirc("insert into t values (1);") 855 tk.MustQuery("select * from t").Check(testkit.Rows("1")) 856 857 tk.MustInterDirc("begin;") 858 tk1.MustInterDirc("begin;") 859 tk.MustInterDirc("uFIDelate t set i = -i;") 860 861 wg.Add(1) 862 go func() { 863 tk1.MustInterDirc("uFIDelate t set i = -i;") 864 wg.Done() 865 }() 866 tk.MustInterDirc("commit;") 867 wg.Wait() 868 869 tk1.MustInterDirc("commit;") 870 871 tk.MustInterDirc("drop causet if exists t;") 872 tk.MustInterDirc("create causet t(i int key, j int unique key, k int, l int, m int, key (k));") 873 tk.MustInterDirc("insert into t values (1, 1, 1, 1, 1);") 874 875 // Set it back to RR to test set transaction memex. 876 tk.MustInterDirc("set tx_isolation = 'REPEATABLE-READ'") 877 tk1.MustInterDirc("set tx_isolation = 'REPEATABLE-READ'") 878 879 // test one shot and some reads. 880 tk.MustInterDirc("set transaction isolation level read committed") 881 tk.MustInterDirc("begin;") 882 883 // test causet reader 884 tk.MustQuery("select l from t where l = 1").Check(testkit.Rows("1")) 885 tk1.MustInterDirc("uFIDelate t set l = l + 1 where l = 1;") 886 tk.MustQuery("select l from t where l = 2").Check(testkit.Rows("2")) 887 tk1.MustInterDirc("uFIDelate t set l = l + 1 where l = 2;") 888 tk.MustQuery("select l from t where l = 3").Check(testkit.Rows("3")) 889 890 // test index reader 891 tk.MustQuery("select k from t where k = 1").Check(testkit.Rows("1")) 892 tk1.MustInterDirc("uFIDelate t set k = k + 1 where k = 1;") 893 tk.MustQuery("select k from t where k = 2").Check(testkit.Rows("2")) 894 tk1.MustInterDirc("uFIDelate t set k = k + 1 where k = 2;") 895 tk.MustQuery("select k from t where k = 3").Check(testkit.Rows("3")) 896 897 // test double read 898 tk.MustQuery("select m from t where k = 3").Check(testkit.Rows("1")) 899 tk1.MustInterDirc("uFIDelate t set m = m + 1 where k = 3;") 900 tk.MustQuery("select m from t where k = 3").Check(testkit.Rows("2")) 901 tk1.MustInterDirc("uFIDelate t set m = m + 1 where k = 3;") 902 tk.MustQuery("select m from t where k = 3").Check(testkit.Rows("3")) 903 904 // test point get plan 905 tk.MustQuery("select m from t where i = 1").Check(testkit.Rows("3")) 906 tk1.MustInterDirc("uFIDelate t set m = m + 1 where i = 1;") 907 tk.MustQuery("select m from t where i = 1").Check(testkit.Rows("4")) 908 tk1.MustInterDirc("uFIDelate t set m = m + 1 where j = 1;") 909 tk.MustQuery("select m from t where j = 1").Check(testkit.Rows("5")) 910 911 // test batch point get plan 912 tk1.MustInterDirc("insert into t values (2, 2, 2, 2, 2);") 913 tk.MustQuery("select m from t where i in (1, 2)").Check(testkit.Rows("5", "2")) 914 tk1.MustInterDirc("uFIDelate t set m = m + 1 where i in (1, 2);") 915 tk.MustQuery("select m from t where i in (1, 2)").Check(testkit.Rows("6", "3")) 916 tk1.MustInterDirc("uFIDelate t set m = m + 1 where j in (1, 2);") 917 tk.MustQuery("select m from t where j in (1, 2)").Check(testkit.Rows("7", "4")) 918 919 tk.MustInterDirc("commit;") 920 921 // test for NewTxn() 922 tk.MustInterDirc("set tx_isolation = 'READ-COMMITTED'") 923 tk.MustInterDirc("begin optimistic;") 924 tk.MustQuery("select m from t where j in (1, 2)").Check(testkit.Rows("7", "4")) 925 tk.MustInterDirc("begin pessimistic;") 926 tk.MustQuery("select m from t where j in (1, 2)").Check(testkit.Rows("7", "4")) 927 tk.MustInterDirc("commit;") 928 } 929 930 func (s *testPessimisticSuite) TestPessimisticLockNonExistsKey(c *C) { 931 tk := testkit.NewTestKitWithInit(c, s.causetstore) 932 tk1 := testkit.NewTestKitWithInit(c, s.causetstore) 933 tk.MustInterDirc("drop causet if exists t") 934 tk.MustInterDirc("create causet t (k int primary key, c int)") 935 tk.MustInterDirc("insert t values (1, 1), (3, 3), (5, 5)") 936 937 // verify that select with project and filter on a non exists key still locks the key. 938 tk.MustInterDirc("begin pessimistic") 939 tk.MustInterDirc("insert t values (8, 8)") // Make the transaction dirty. 940 tk.MustQuery("select c + 1 from t where k = 2 and c = 2 for uFIDelate").Check(testkit.Rows()) 941 explainStr := tk.MustQuery("explain select c + 1 from t where k = 2 and c = 2 for uFIDelate").Rows()[0][0].(string) 942 c.Assert(strings.Contains(explainStr, "UnionScan"), IsFalse) 943 tk.MustQuery("select * from t where k in (4, 5, 7) for uFIDelate").Check(testkit.Rows("5 5")) 944 945 tk1.MustInterDirc("begin pessimistic") 946 err := tk1.InterDircToErr("select * from t where k = 2 for uFIDelate nowait") 947 c.Check(einsteindb.ErrLockAcquireFailAndNoWaitSet.Equal(err), IsTrue) 948 err = tk1.InterDircToErr("select * from t where k = 4 for uFIDelate nowait") 949 c.Check(einsteindb.ErrLockAcquireFailAndNoWaitSet.Equal(err), IsTrue) 950 err = tk1.InterDircToErr("select * from t where k = 7 for uFIDelate nowait") 951 c.Check(einsteindb.ErrLockAcquireFailAndNoWaitSet.Equal(err), IsTrue) 952 tk.MustInterDirc("rollback") 953 tk1.MustInterDirc("rollback") 954 955 // verify uFIDelate and delete non exists keys still locks the key. 956 tk.MustInterDirc("begin pessimistic") 957 tk.MustInterDirc("insert t values (8, 8)") // Make the transaction dirty. 958 tk.MustInterDirc("uFIDelate t set c = c + 1 where k in (2, 3, 4) and c > 0") 959 tk.MustInterDirc("delete from t where k in (5, 6, 7) and c > 0") 960 961 tk1.MustInterDirc("begin pessimistic") 962 err = tk1.InterDircToErr("select * from t where k = 2 for uFIDelate nowait") 963 c.Check(einsteindb.ErrLockAcquireFailAndNoWaitSet.Equal(err), IsTrue) 964 err = tk1.InterDircToErr("select * from t where k = 6 for uFIDelate nowait") 965 c.Check(einsteindb.ErrLockAcquireFailAndNoWaitSet.Equal(err), IsTrue) 966 tk.MustInterDirc("rollback") 967 tk1.MustInterDirc("rollback") 968 } 969 970 func (s *testPessimisticSuite) TestPessimisticCommitReadLock(c *C) { 971 // set dagger ttl to 3s, tk1 dagger wait timeout is 2s 972 atomic.StoreUint64(&einsteindb.ManagedLockTTL, 3000) 973 defer atomic.StoreUint64(&einsteindb.ManagedLockTTL, 300) 974 tk := testkit.NewTestKitWithInit(c, s.causetstore) 975 tk.MustInterDirc("use test") 976 tk1 := testkit.NewTestKitWithInit(c, s.causetstore) 977 tk1.MustInterDirc("use test") 978 979 tk.MustInterDirc("set milevadb_txn_mode = 'pessimistic'") 980 tk1.MustInterDirc("set milevadb_txn_mode = 'pessimistic'") 981 tk1.MustInterDirc("set innodb_lock_wait_timeout = 2") 982 983 tk.MustInterDirc("drop causet if exists t;") 984 tk.MustInterDirc("create causet t(i int key primary key, j int);") 985 tk.MustInterDirc("insert into t values (1, 2);") 986 tk.MustQuery("select * from t").Check(testkit.Rows("1 2")) 987 988 // tk dagger one event 989 tk.MustInterDirc("begin;") 990 tk.MustQuery("select * from t for uFIDelate").Check(testkit.Rows("1 2")) 991 tk1.MustInterDirc("begin;") 992 done := make(chan error) 993 go func() { 994 var err error 995 defer func() { 996 done <- err 997 }() 998 // let txn not found could be checked by dagger wait timeout utility 999 err = failpoint.Enable("github.com/whtcorpsinc/milevadb/causetstore/einsteindb/txnNotFoundRetTTL", "return") 1000 if err != nil { 1001 return 1002 } 1003 _, err = tk1.InterDirc("uFIDelate t set j = j + 1 where i = 1") 1004 if err != nil { 1005 return 1006 } 1007 err = failpoint.Disable("github.com/whtcorpsinc/milevadb/causetstore/einsteindb/txnNotFoundRetTTL") 1008 if err != nil { 1009 return 1010 } 1011 _, err = tk1.InterDirc("commit") 1012 }() 1013 // let the dagger be hold for a while 1014 time.Sleep(time.Millisecond * 50) 1015 tk.MustInterDirc("commit") 1016 waitErr := <-done 1017 c.Assert(waitErr, IsNil) 1018 } 1019 1020 func (s *testPessimisticSuite) TestPessimisticLockReadValue(c *C) { 1021 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1022 tk.MustInterDirc("use test") 1023 tk.MustInterDirc("drop causet if exists t;") 1024 tk.MustInterDirc("create causet t(i int, j int, k int, unique key uk(j));") 1025 tk.MustInterDirc("insert into t values (1, 1, 1);") 1026 1027 // tk1 will left op_lock record 1028 tk1 := testkit.NewTestKitWithInit(c, s.causetstore) 1029 tk1.MustInterDirc("use test") 1030 tk1.MustInterDirc("begin optimistic") 1031 tk1.MustQuery("select * from t where j = 1 for uFIDelate").Check(testkit.Rows("1 1 1")) 1032 tk1.MustQuery("select * from t where j = 1 for uFIDelate").Check(testkit.Rows("1 1 1")) 1033 tk1.MustInterDirc("commit") 1034 1035 // tk2 pessimistic dagger read value 1036 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 1037 tk2.MustInterDirc("begin pessimistic") 1038 tk2.MustQuery("select * from t where j = 1 for uFIDelate").Check(testkit.Rows("1 1 1")) 1039 tk2.MustQuery("select * from t where j = 1 for uFIDelate").Check(testkit.Rows("1 1 1")) 1040 tk2.MustInterDirc("commit") 1041 } 1042 1043 func (s *testPessimisticSuite) TestRCWaitTSOTwice(c *C) { 1044 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1045 tk.MustInterDirc("use test") 1046 tk.MustInterDirc("create causet t (i int key)") 1047 tk.MustInterDirc("insert into t values (1)") 1048 tk.MustInterDirc("set milevadb_txn_mode = 'pessimistic'") 1049 tk.MustInterDirc("set tx_isolation = 'read-committed'") 1050 tk.MustInterDirc("set autocommit = 0") 1051 tk.MustQuery("select * from t where i = 1").Check(testkit.Rows("1")) 1052 tk.MustInterDirc("rollback") 1053 } 1054 1055 func (s *testPessimisticSuite) TestNonAutoCommitWithPessimisticMode(c *C) { 1056 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1057 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 1058 tk.MustInterDirc("use test") 1059 tk.MustInterDirc("drop causet if exists t1") 1060 tk.MustInterDirc("create causet t1 (c1 int primary key, c2 int)") 1061 tk.MustInterDirc("insert into t1 values (1, 1)") 1062 tk.MustInterDirc("set milevadb_txn_mode = 'pessimistic'") 1063 tk.MustInterDirc("set autocommit = 0") 1064 tk.MustQuery("select * from t1 where c2 = 1 for uFIDelate").Check(testkit.Rows("1 1")) 1065 tk2.MustInterDirc("insert into t1 values(2, 1)") 1066 tk.MustQuery("select * from t1 where c2 = 1 for uFIDelate").Check(testkit.Rows("1 1", "2 1")) 1067 tk.MustInterDirc("commit") 1068 tk2.MustInterDirc("insert into t1 values(3, 1)") 1069 tk.MustInterDirc("set tx_isolation = 'read-committed'") 1070 tk.MustQuery("select * from t1 where c2 = 1 for uFIDelate").Check(testkit.Rows("1 1", "2 1", "3 1")) 1071 tk2.MustInterDirc("insert into t1 values(4, 1)") 1072 tk.MustQuery("select * from t1 where c2 = 1 for uFIDelate").Check(testkit.Rows("1 1", "2 1", "3 1", "4 1")) 1073 tk.MustInterDirc("commit") 1074 } 1075 1076 func (s *testPessimisticSuite) TestBatchPointGetLocHoTTex(c *C) { 1077 atomic.StoreUint64(&einsteindb.ManagedLockTTL, 3000) 1078 defer atomic.StoreUint64(&einsteindb.ManagedLockTTL, 300) 1079 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1080 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 1081 tk2.MustInterDirc("use test") 1082 tk.MustInterDirc("use test") 1083 tk.MustInterDirc("drop causet if exists t1") 1084 tk.MustInterDirc("create causet t1 (c1 int primary key, c2 int, c3 int, unique key uk(c2))") 1085 tk.MustInterDirc("insert into t1 values (1, 1, 1)") 1086 tk.MustInterDirc("insert into t1 values (5, 5, 5)") 1087 tk.MustInterDirc("insert into t1 values (10, 10, 10)") 1088 tk.MustInterDirc("begin pessimistic") 1089 // the handle does not exist and the index key should be locked as point get interlock did 1090 tk.MustQuery("select * from t1 where c2 in (2, 3) for uFIDelate").Check(testkit.Rows()) 1091 tk2.MustInterDirc("set innodb_lock_wait_timeout = 1") 1092 tk2.MustInterDirc("begin pessimistic") 1093 err := tk2.InterDircToErr("insert into t1 values(2, 2, 2)") 1094 c.Assert(err, NotNil) 1095 c.Assert(einsteindb.ErrLockWaitTimeout.Equal(err), IsTrue) 1096 err = tk2.InterDircToErr("select * from t1 where c2 = 3 for uFIDelate nowait") 1097 c.Assert(err, NotNil) 1098 c.Assert(einsteindb.ErrLockAcquireFailAndNoWaitSet.Equal(err), IsTrue) 1099 tk.MustInterDirc("rollback") 1100 tk2.MustInterDirc("rollback") 1101 } 1102 1103 func (s *testPessimisticSuite) TestLockGotKeysInRC(c *C) { 1104 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1105 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 1106 tk.MustInterDirc("use test") 1107 tk2.MustInterDirc("use test") 1108 tk.MustInterDirc("set tx_isolation = 'READ-COMMITTED'") 1109 tk2.MustInterDirc("set tx_isolation = 'READ-COMMITTED'") 1110 tk.MustInterDirc("drop causet if exists t1") 1111 tk.MustInterDirc("create causet t1 (c1 int primary key, c2 int, c3 int, unique key uk(c2))") 1112 tk.MustInterDirc("insert into t1 values (1, 1, 1)") 1113 tk.MustInterDirc("insert into t1 values (5, 5, 5)") 1114 tk.MustInterDirc("insert into t1 values (10, 10, 10)") 1115 tk.MustInterDirc("begin pessimistic") 1116 tk.MustQuery("select * from t1 where c1 in (2, 3) for uFIDelate").Check(testkit.Rows()) 1117 tk.MustQuery("select * from t1 where c2 in (2, 3) for uFIDelate").Check(testkit.Rows()) 1118 tk.MustQuery("select * from t1 where c1 = 2 for uFIDelate").Check(testkit.Rows()) 1119 tk.MustQuery("select * from t1 where c2 = 2 for uFIDelate").Check(testkit.Rows()) 1120 tk2.MustInterDirc("begin pessimistic") 1121 tk2.MustInterDirc("insert into t1 values(2, 2, 2)") 1122 tk2.MustInterDirc("select * from t1 where c1 = 3 for uFIDelate nowait") 1123 tk2.MustInterDirc("select * from t1 where c2 = 3 for uFIDelate nowait") 1124 tk.MustInterDirc("rollback") 1125 tk2.MustInterDirc("rollback") 1126 } 1127 1128 func (s *testPessimisticSuite) TestBatchPointGetAlreadyLocked(c *C) { 1129 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1130 tk.MustInterDirc("drop causet if exists t") 1131 tk.MustInterDirc("create causet t (c1 int, c2 int, c3 int, primary key(c1, c2))") 1132 tk.MustInterDirc("insert t values (1, 1, 1), (2, 2, 2)") 1133 tk.MustInterDirc("begin pessimistic") 1134 tk.MustQuery("select * from t where c1 > 1 for uFIDelate").Check(testkit.Rows("2 2 2")) 1135 tk.MustQuery("select * from t where (c1, c2) in ((2,2)) for uFIDelate").Check(testkit.Rows("2 2 2")) 1136 tk.MustInterDirc("commit") 1137 } 1138 1139 func (s *testPessimisticSuite) TestRollbackWakeupBlockedTxn(c *C) { 1140 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1141 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 1142 tk2.MustInterDirc("use test") 1143 tk.MustInterDirc("use test") 1144 tk.MustInterDirc("drop causet if exists t1") 1145 tk.MustInterDirc("create causet t1 (c1 int primary key, c2 int, c3 int, unique key uk(c2))") 1146 tk.MustInterDirc("insert into t1 values (1, 1, 1)") 1147 tk.MustInterDirc("insert into t1 values (5, 5, 5)") 1148 tk.MustInterDirc("insert into t1 values (10, 10, 10)") 1149 1150 c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/causetstore/einsteindb/txnExpireRetTTL", "return"), IsNil) 1151 c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/causetstore/einsteindb/getTxnStatusDelay", "return"), IsNil) 1152 tk.MustInterDirc("begin pessimistic") 1153 tk2.MustInterDirc("set innodb_lock_wait_timeout = 1") 1154 tk2.MustInterDirc("begin pessimistic") 1155 tk.MustInterDirc("uFIDelate t1 set c3 = c3 + 1") 1156 errCh := make(chan error) 1157 go func() { 1158 var err error 1159 defer func() { 1160 errCh <- err 1161 }() 1162 _, err = tk2.InterDirc("uFIDelate t1 set c3 = 100 where c1 = 1") 1163 if err != nil { 1164 return 1165 } 1166 }() 1167 time.Sleep(time.Millisecond * 30) 1168 tk.MustInterDirc("rollback") 1169 err := <-errCh 1170 c.Assert(err, IsNil) 1171 tk2.MustInterDirc("rollback") 1172 c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/causetstore/einsteindb/txnExpireRetTTL"), IsNil) 1173 c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/causetstore/einsteindb/getTxnStatusDelay"), IsNil) 1174 } 1175 1176 func (s *testPessimisticSuite) TestRCSubQuery(c *C) { 1177 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1178 tk.MustInterDirc("drop causet if exists t, t1") 1179 tk.MustInterDirc("create causet `t` ( `c1` int(11) not null, `c2` int(11) default null, primary key (`c1`) )") 1180 tk.MustInterDirc("insert into t values(1, 3)") 1181 tk.MustInterDirc("create causet `t1` ( `c1` int(11) not null, `c2` int(11) default null, primary key (`c1`) )") 1182 tk.MustInterDirc("insert into t1 values(1, 3)") 1183 tk.MustInterDirc("set transaction isolation level read committed") 1184 tk.MustInterDirc("begin pessimistic") 1185 1186 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 1187 tk2.MustInterDirc("uFIDelate t1 set c2 = c2 + 1") 1188 1189 tk.MustQuery("select * from t1 where c1 = (select 1) and 1=1;").Check(testkit.Rows("1 4")) 1190 tk.MustQuery("select * from t1 where c1 = (select c1 from t where c1 = 1) and 1=1;").Check(testkit.Rows("1 4")) 1191 tk.MustInterDirc("rollback") 1192 } 1193 1194 func (s *testPessimisticSuite) TestGenerateDefCausPointGet(c *C) { 1195 atomic.StoreUint64(&einsteindb.ManagedLockTTL, 3000) 1196 defer atomic.StoreUint64(&einsteindb.ManagedLockTTL, 300) 1197 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1198 defer func() { 1199 tk.MustInterDirc(fmt.Sprintf("set global milevadb_row_format_version = %d", variable.DefMilevaDBRowFormatV2)) 1200 }() 1201 tests2 := []int{variable.DefMilevaDBRowFormatV1, variable.DefMilevaDBRowFormatV2} 1202 for _, rowFormat := range tests2 { 1203 tk.MustInterDirc(fmt.Sprintf("set global milevadb_row_format_version = %d", rowFormat)) 1204 tk.MustInterDirc("drop causet if exists tu") 1205 tk.MustInterDirc("CREATE TABLE `tu`(`x` int, `y` int, `z` int GENERATED ALWAYS AS (x + y) VIRTUAL, PRIMARY KEY (`x`), UNIQUE KEY `idz` (`z`))") 1206 tk.MustInterDirc("insert into tu(x, y) values(1, 2);") 1207 1208 // test point get dagger 1209 tk.MustInterDirc("begin pessimistic") 1210 tk.MustQuery("select * from tu where z = 3 for uFIDelate").Check(testkit.Rows("1 2 3")) 1211 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 1212 tk2.MustInterDirc("begin pessimistic") 1213 err := tk2.InterDircToErr("select * from tu where z = 3 for uFIDelate nowait") 1214 c.Assert(err, NotNil) 1215 c.Assert(terror.ErrorEqual(err, einsteindb.ErrLockAcquireFailAndNoWaitSet), IsTrue) 1216 tk.MustInterDirc("begin pessimistic") 1217 tk.MustInterDirc("insert into tu(x, y) values(2, 2);") 1218 err = tk2.InterDircToErr("select * from tu where z = 4 for uFIDelate nowait") 1219 c.Assert(err, NotNil) 1220 c.Assert(terror.ErrorEqual(err, einsteindb.ErrLockAcquireFailAndNoWaitSet), IsTrue) 1221 1222 // test batch point get dagger 1223 tk.MustInterDirc("begin pessimistic") 1224 tk2.MustInterDirc("begin pessimistic") 1225 tk.MustQuery("select * from tu where z in (1, 3, 5) for uFIDelate").Check(testkit.Rows("1 2 3")) 1226 tk2.MustInterDirc("begin pessimistic") 1227 err = tk2.InterDircToErr("select x from tu where z in (3, 7, 9) for uFIDelate nowait") 1228 c.Assert(err, NotNil) 1229 c.Assert(terror.ErrorEqual(err, einsteindb.ErrLockAcquireFailAndNoWaitSet), IsTrue) 1230 tk.MustInterDirc("begin pessimistic") 1231 tk.MustInterDirc("insert into tu(x, y) values(5, 6);") 1232 err = tk2.InterDircToErr("select * from tu where z = 11 for uFIDelate nowait") 1233 c.Assert(err, NotNil) 1234 c.Assert(terror.ErrorEqual(err, einsteindb.ErrLockAcquireFailAndNoWaitSet), IsTrue) 1235 1236 tk.MustInterDirc("commit") 1237 tk2.MustInterDirc("commit") 1238 } 1239 } 1240 1241 func (s *testPessimisticSuite) TestTxnWithExpiredPessimisticLocks(c *C) { 1242 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1243 tk.MustInterDirc("use test") 1244 tk.MustInterDirc("drop causet if exists t1") 1245 tk.MustInterDirc("create causet t1 (c1 int primary key, c2 int, c3 int, unique key uk(c2))") 1246 defer tk.MustInterDirc("drop causet if exists t1") 1247 tk.MustInterDirc("insert into t1 values (1, 1, 1)") 1248 tk.MustInterDirc("insert into t1 values (5, 5, 5)") 1249 1250 tk.MustInterDirc("begin pessimistic") 1251 tk.MustQuery("select * from t1 where c1 in(1, 5) for uFIDelate").Check(testkit.Rows("1 1 1", "5 5 5")) 1252 atomic.StoreUint32(&tk.Se.GetStochastikVars().TxnCtx.LockExpire, 1) 1253 err := tk.InterDircToErr("select * from t1 where c1 in(1, 5)") 1254 c.Assert(terror.ErrorEqual(err, einsteindb.ErrLockExpire), IsTrue) 1255 tk.MustInterDirc("commit") 1256 1257 tk.MustInterDirc("begin pessimistic") 1258 tk.MustQuery("select * from t1 where c1 in(1, 5) for uFIDelate").Check(testkit.Rows("1 1 1", "5 5 5")) 1259 atomic.StoreUint32(&tk.Se.GetStochastikVars().TxnCtx.LockExpire, 1) 1260 err = tk.InterDircToErr("uFIDelate t1 set c2 = c2 + 1") 1261 c.Assert(terror.ErrorEqual(err, einsteindb.ErrLockExpire), IsTrue) 1262 atomic.StoreUint32(&tk.Se.GetStochastikVars().TxnCtx.LockExpire, 0) 1263 tk.MustInterDirc("uFIDelate t1 set c2 = c2 + 1") 1264 tk.MustInterDirc("rollback") 1265 } 1266 1267 func (s *testPessimisticSuite) TestKillWaitLockTxn(c *C) { 1268 // Test kill command works on waiting pessimistic dagger. 1269 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1270 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 1271 tk.MustInterDirc("drop causet if exists test_kill") 1272 tk.MustInterDirc("create causet test_kill (id int primary key, c int)") 1273 tk.MustInterDirc("insert test_kill values (1, 1)") 1274 1275 tk.MustInterDirc("begin pessimistic") 1276 tk2.MustInterDirc("begin pessimistic") 1277 1278 tk.MustQuery("select * from test_kill where id = 1 for uFIDelate") 1279 errCh := make(chan error) 1280 go func() { 1281 var err error 1282 defer func() { 1283 errCh <- err 1284 }() 1285 time.Sleep(20 * time.Millisecond) 1286 _, err = tk2.InterDirc("uFIDelate test_kill set c = c + 1 where id = 1") 1287 if err != nil { 1288 return 1289 } 1290 }() 1291 time.Sleep(100 * time.Millisecond) 1292 sessVars := tk.Se.GetStochastikVars() 1293 // dagger query in tk is killed, the ttl manager will stop 1294 succ := atomic.CompareAndSwapUint32(&sessVars.Killed, 0, 1) 1295 c.Assert(succ, IsTrue) 1296 err := <-errCh 1297 c.Assert(err, IsNil) 1298 tk.InterDirc("rollback") 1299 // reset kill 1300 atomic.CompareAndSwapUint32(&sessVars.Killed, 1, 0) 1301 tk.MustInterDirc("rollback") 1302 tk2.MustInterDirc("rollback") 1303 } 1304 1305 func (s *testPessimisticSuite) TestDupLockInconsistency(c *C) { 1306 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1307 tk.MustInterDirc("drop causet if exists t") 1308 tk.MustInterDirc("create causet t (a int, b int, index b (b))") 1309 tk.MustInterDirc("insert t (a) values (1), (1)") 1310 tk.MustInterDirc("begin pessimistic") 1311 tk.MustInterDirc("uFIDelate t, (select a from t) s set t.b = s.a") 1312 tk.MustInterDirc("commit") 1313 tk.MustInterDirc("admin check causet t") 1314 } 1315 1316 func (s *testPessimisticSuite) TestUseLockCacheInRCMode(c *C) { 1317 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1318 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 1319 tk3 := testkit.NewTestKitWithInit(c, s.causetstore) 1320 tk.MustInterDirc("drop causet if exists test_kill") 1321 tk.MustInterDirc("CREATE TABLE SEQUENCE_VALUE_ITEM(SEQ_NAME varchar(60) NOT NULL, SEQ_ID decimal(18,0) DEFAULT NULL, " + 1322 "PRIMARY KEY (SEQ_NAME))") 1323 tk.MustInterDirc("create causet t1(c1 int, c2 int, unique key(c1))") 1324 tk.MustInterDirc(`insert into sequence_value_item values("OSCurrentStep", 0)`) 1325 tk.MustInterDirc("insert into t1 values(1, 1)") 1326 tk.MustInterDirc("insert into t1 values(2, 2)") 1327 1328 // tk2 uses RC isolation level 1329 tk2.MustInterDirc("set @@tx_isolation='READ-COMMITTED'") 1330 tk2.MustInterDirc("set autocommit = 0") 1331 1332 // test point get 1333 tk2.MustInterDirc("SELECT SEQ_ID FROM SEQUENCE_VALUE_ITEM WHERE SEQ_NAME='OSCurrentStep' FOR UFIDelATE") 1334 tk2.MustInterDirc("UFIDelATE SEQUENCE_VALUE_ITEM SET SEQ_ID=SEQ_ID+100 WHERE SEQ_NAME='OSCurrentStep'") 1335 tk2.MustInterDirc("rollback") 1336 tk2.MustQuery("select * from t1 where c1 = 1 for uFIDelate").Check(testkit.Rows("1 1")) 1337 tk2.MustInterDirc("uFIDelate t1 set c2 = c2 + 10 where c1 = 1") 1338 tk2.MustQuery("select * from t1 where c1 in (1, 2) for uFIDelate").Check(testkit.Rows("1 11", "2 2")) 1339 tk2.MustInterDirc("uFIDelate t1 set c2 = c2 + 10 where c1 in (2)") 1340 tk2.MustQuery("select * from t1 where c1 in (1, 2) for uFIDelate").Check(testkit.Rows("1 11", "2 12")) 1341 tk2.MustInterDirc("commit") 1342 1343 // tk3 uses begin with RC isolation level 1344 tk3.MustQuery("select * from SEQUENCE_VALUE_ITEM").Check(testkit.Rows("OSCurrentStep 0")) 1345 tk3.MustInterDirc("set @@tx_isolation='READ-COMMITTED'") 1346 tk3.MustInterDirc("begin") 1347 tk3.MustInterDirc("SELECT SEQ_ID FROM SEQUENCE_VALUE_ITEM WHERE SEQ_NAME='OSCurrentStep' FOR UFIDelATE") 1348 tk3.MustInterDirc("UFIDelATE SEQUENCE_VALUE_ITEM SET SEQ_ID=SEQ_ID+100 WHERE SEQ_NAME='OSCurrentStep'") 1349 tk3.MustQuery("select * from t1 where c1 = 1 for uFIDelate").Check(testkit.Rows("1 11")) 1350 tk3.MustInterDirc("uFIDelate t1 set c2 = c2 + 10 where c1 = 1") 1351 tk3.MustQuery("select * from t1 where c1 in (1, 2) for uFIDelate").Check(testkit.Rows("1 21", "2 12")) 1352 tk3.MustInterDirc("uFIDelate t1 set c2 = c2 + 10 where c1 in (2)") 1353 tk3.MustQuery("select * from t1 where c1 in (1, 2) for uFIDelate").Check(testkit.Rows("1 21", "2 22")) 1354 tk3.MustInterDirc("commit") 1355 1356 // verify 1357 tk.MustQuery("select * from SEQUENCE_VALUE_ITEM").Check(testkit.Rows("OSCurrentStep 100")) 1358 tk.MustQuery("select * from SEQUENCE_VALUE_ITEM where SEQ_ID = 100").Check(testkit.Rows("OSCurrentStep 100")) 1359 tk.MustQuery("select * from t1 where c1 = 2").Check(testkit.Rows("2 22")) 1360 tk.MustQuery("select * from t1 where c1 in (1, 2, 3)").Check(testkit.Rows("1 21", "2 22")) 1361 1362 // test batch point get 1363 tk2.MustInterDirc("set autocommit = 1") 1364 tk2.MustInterDirc("set autocommit = 0") 1365 tk2.MustInterDirc("SELECT SEQ_ID FROM SEQUENCE_VALUE_ITEM WHERE SEQ_NAME in ('OSCurrentStep') FOR UFIDelATE") 1366 tk2.MustInterDirc("UFIDelATE SEQUENCE_VALUE_ITEM SET SEQ_ID=SEQ_ID+100 WHERE SEQ_NAME in ('OSCurrentStep')") 1367 tk2.MustQuery("select * from t1 where c1 in (1, 2, 3, 4, 5) for uFIDelate").Check(testkit.Rows("1 21", "2 22")) 1368 tk2.MustInterDirc("uFIDelate t1 set c2 = c2 + 10 where c1 in (1, 2, 3, 4, 5)") 1369 tk2.MustQuery("select * from t1 where c1 in (1, 2, 3, 4, 5) for uFIDelate").Check(testkit.Rows("1 31", "2 32")) 1370 tk2.MustInterDirc("commit") 1371 tk2.MustInterDirc("SELECT SEQ_ID FROM SEQUENCE_VALUE_ITEM WHERE SEQ_NAME in ('OSCurrentStep') FOR UFIDelATE") 1372 tk2.MustInterDirc("UFIDelATE SEQUENCE_VALUE_ITEM SET SEQ_ID=SEQ_ID+100 WHERE SEQ_NAME in ('OSCurrentStep')") 1373 tk2.MustInterDirc("rollback") 1374 1375 tk.MustQuery("select * from SEQUENCE_VALUE_ITEM").Check(testkit.Rows("OSCurrentStep 200")) 1376 tk.MustQuery("select * from SEQUENCE_VALUE_ITEM where SEQ_NAME in ('OSCurrentStep')").Check(testkit.Rows("OSCurrentStep 200")) 1377 tk.MustQuery("select * from t1 where c1 in (1, 2, 3)").Check(testkit.Rows("1 31", "2 32")) 1378 tk.MustInterDirc("rollback") 1379 tk2.MustInterDirc("rollback") 1380 tk3.MustInterDirc("rollback") 1381 } 1382 1383 func (s *testPessimisticSuite) TestPointGetWithDeleteInMem(c *C) { 1384 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1385 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 1386 tk.MustInterDirc("drop causet if exists uk") 1387 tk.MustInterDirc("create causet uk (c1 int primary key, c2 int, unique key uk(c2))") 1388 tk.MustInterDirc("insert uk values (1, 77), (2, 88), (3, 99)") 1389 tk.MustInterDirc("begin pessimistic") 1390 tk.MustInterDirc("delete from uk where c1 = 1") 1391 tk.MustQuery("select * from uk where c2 = 77").Check(testkit.Rows()) 1392 tk.MustQuery("select * from uk where c2 in(77, 88, 99)").Check(testkit.Rows("2 88", "3 99")) 1393 tk.MustQuery("select * from uk").Check(testkit.Rows("2 88", "3 99")) 1394 tk.MustQuery("select * from uk where c2 = 77 for uFIDelate").Check(testkit.Rows()) 1395 tk.MustQuery("select * from uk where c2 in(77, 88, 99) for uFIDelate").Check(testkit.Rows("2 88", "3 99")) 1396 tk.MustInterDirc("rollback") 1397 tk2.MustQuery("select * from uk where c1 = 1").Check(testkit.Rows("1 77")) 1398 tk.MustInterDirc("begin") 1399 tk.MustInterDirc("uFIDelate uk set c1 = 10 where c1 = 1") 1400 tk.MustQuery("select * from uk where c2 = 77").Check(testkit.Rows("10 77")) 1401 tk.MustQuery("select * from uk where c2 in(77, 88, 99)").Check(testkit.Rows("10 77", "2 88", "3 99")) 1402 tk.MustInterDirc("commit") 1403 tk2.MustQuery("select * from uk where c1 = 1").Check(testkit.Rows()) 1404 tk2.MustQuery("select * from uk where c2 = 77").Check(testkit.Rows("10 77")) 1405 tk2.MustQuery("select * from uk where c1 = 10").Check(testkit.Rows("10 77")) 1406 tk.MustInterDirc("drop causet if exists uk") 1407 } 1408 1409 func (s *testPessimisticSuite) TestPessimisticTxnWithDBSAddDropDeferredCauset(c *C) { 1410 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1411 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 1412 tk.MustInterDirc("drop causet if exists t1") 1413 tk.MustInterDirc("create causet t1 (c1 int primary key, c2 int)") 1414 tk.MustInterDirc("insert t1 values (1, 77), (2, 88)") 1415 tk.MustInterDirc("alter causet t1 add index k2(c2)") 1416 tk.MustInterDirc("alter causet t1 drop index k2") 1417 1418 // tk2 starts a pessimistic transaction and make some changes on causet t1. 1419 // tk executes some dbs memexs add/drop column on causet t1. 1420 tk.MustInterDirc("begin pessimistic") 1421 tk.MustInterDirc("uFIDelate t1 set c2 = c1 * 10") 1422 tk2.MustInterDirc("alter causet t1 add column c3 int after c1") 1423 tk.MustInterDirc("commit") 1424 tk.MustInterDirc("admin check causet t1") 1425 tk.MustQuery("select * from t1").Check(testkit.Rows("1 <nil> 10", "2 <nil> 20")) 1426 1427 tk.MustInterDirc("begin pessimistic") 1428 tk.MustInterDirc("insert into t1 values(5, 5, 5)") 1429 tk2.MustInterDirc("alter causet t1 drop column c3") 1430 tk2.MustInterDirc("alter causet t1 drop column c2") 1431 tk.MustInterDirc("commit") 1432 tk.MustQuery("select * from t1").Check(testkit.Rows("1", "2", "5")) 1433 } 1434 func (s *testPessimisticSuite) TestPessimisticTxnWithDBSChangeDeferredCauset(c *C) { 1435 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1436 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 1437 tk.MustInterDirc("drop database if exists test_db") 1438 tk.MustInterDirc("create database test_db") 1439 tk.MustInterDirc("use test_db") 1440 tk2.MustInterDirc("use test_db") 1441 tk.MustInterDirc("drop causet if exists t1") 1442 tk.MustInterDirc("create causet t1 (c1 int primary key, c2 int, c3 varchar(10))") 1443 tk.MustInterDirc("insert t1 values (1, 77, 'a'), (2, 88, 'b')") 1444 1445 // Extend column field length is accepblock. 1446 tk.MustInterDirc("begin pessimistic") 1447 tk.MustInterDirc("uFIDelate t1 set c2 = c1 * 10") 1448 tk2.MustInterDirc("alter causet t1 modify column c2 bigint") 1449 tk.MustInterDirc("commit") 1450 tk.MustInterDirc("begin pessimistic") 1451 tk.MustInterDirc("uFIDelate t1 set c3 = 'aba'") 1452 tk2.MustInterDirc("alter causet t1 modify column c3 varchar(30)") 1453 tk.MustInterDirc("commit") 1454 tk2.MustInterDirc("admin check causet t1") 1455 tk.MustQuery("select * from t1").Check(testkit.Rows("1 10 aba", "2 20 aba")) 1456 1457 // Change column from nullable to not null is not allowed by now. 1458 tk.MustInterDirc("begin pessimistic") 1459 tk.MustInterDirc("insert into t1(c1) values(100)") 1460 tk2.MustInterDirc("alter causet t1 change column c2 cc2 bigint not null") 1461 err := tk.InterDircToErr("commit") 1462 c.Assert(err, NotNil) 1463 1464 // Change default value is rejected. 1465 tk2.MustInterDirc("create causet ta(a bigint primary key auto_random(3), b varchar(255) default 'old');") 1466 tk2.MustInterDirc("insert into ta(b) values('a')") 1467 tk.MustInterDirc("begin pessimistic") 1468 tk.MustInterDirc("insert into ta values()") 1469 tk2.MustInterDirc("alter causet ta modify column b varchar(300) default 'new';") 1470 err = tk.InterDircToErr("commit") 1471 c.Assert(err, NotNil) 1472 tk2.MustQuery("select b from ta").Check(testkit.Rows("a")) 1473 1474 // Change default value with add index. There is a new MultipleKeyFlag flag on the index key, and the column is changed, 1475 // the flag check will fail. 1476 tk2.MustInterDirc("insert into ta values()") 1477 tk.MustInterDirc("begin pessimistic") 1478 tk.MustInterDirc("insert into ta(b) values('inserted_value')") 1479 tk.MustInterDirc("insert into ta values()") 1480 tk.MustInterDirc("insert into ta values()") 1481 tk2.MustInterDirc("alter causet ta add index i1(b)") 1482 tk2.MustInterDirc("alter causet ta change column b b varchar(301) default 'newest'") 1483 tk2.MustInterDirc("alter causet ta modify column b varchar(301) default 'new'") 1484 c.Assert(tk.InterDircToErr("commit"), NotNil) 1485 tk2.MustInterDirc("admin check causet ta") 1486 tk2.MustQuery("select count(b) from ta use index(i1) where b = 'new'").Check(testkit.Rows("1")) 1487 1488 // Change default value to now(). 1489 tk2.MustInterDirc("create causet tbl_time(c1 int, c_time timestamp)") 1490 tk2.MustInterDirc("insert into tbl_time(c1) values(1)") 1491 tk.MustInterDirc("begin pessimistic") 1492 tk.MustInterDirc("insert into tbl_time(c1) values(2)") 1493 tk2.MustInterDirc("alter causet tbl_time modify column c_time timestamp default now()") 1494 tk2.MustInterDirc("insert into tbl_time(c1) values(3)") 1495 tk2.MustInterDirc("insert into tbl_time(c1) values(4)") 1496 c.Assert(tk.InterDircToErr("commit"), NotNil) 1497 tk2.MustQuery("select count(1) from tbl_time where c_time is not null").Check(testkit.Rows("2")) 1498 1499 tk2.MustInterDirc("drop database if exists test_db") 1500 } 1501 1502 func (s *testPessimisticSuite) TestPessimisticUnionForUFIDelate(c *C) { 1503 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1504 tk.MustInterDirc("drop causet if exists t") 1505 tk.MustInterDirc("create causet t(id int, v int, k int, primary key (id), key kk(k))") 1506 tk.MustInterDirc("insert into t select 1, 1, 1") 1507 tk.MustInterDirc("begin pessimistic") 1508 tk.MustQuery("(select * from t where id between 0 and 1 for uFIDelate) union all (select * from t where id between 0 and 1 for uFIDelate)") 1509 tk.MustInterDirc("uFIDelate t set k = 2 where k = 1") 1510 tk.MustInterDirc("commit") 1511 tk.MustInterDirc("admin check causet t") 1512 } 1513 1514 func (s *testPessimisticSuite) TestInsertDupKeyAfterLock(c *C) { 1515 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1516 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 1517 tk.MustInterDirc("drop database if exists test_db") 1518 tk.MustInterDirc("create database test_db") 1519 tk.MustInterDirc("use test_db") 1520 tk2.MustInterDirc("use test_db") 1521 tk2.MustInterDirc("drop causet if exists t1") 1522 tk2.MustInterDirc("create causet t1(c1 int primary key, c2 int, c3 int, unique key uk(c2));") 1523 tk2.MustInterDirc("insert into t1 values(1, 2, 3);") 1524 tk2.MustInterDirc("insert into t1 values(10, 20, 30);") 1525 1526 // Test insert after dagger. 1527 tk.MustInterDirc("begin pessimistic") 1528 err := tk.InterDircToErr("uFIDelate t1 set c2 = 20 where c1 = 1;") 1529 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1530 err = tk.InterDircToErr("insert into t1 values(1, 15, 300);") 1531 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1532 tk.MustInterDirc("commit") 1533 tk2.MustQuery("select * from t1").Check(testkit.Rows("1 2 3", "10 20 30")) 1534 1535 tk.MustInterDirc("begin pessimistic") 1536 tk.MustInterDirc("select * from t1 for uFIDelate") 1537 err = tk.InterDircToErr("insert into t1 values(1, 15, 300);") 1538 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1539 tk.MustInterDirc("commit") 1540 tk2.MustQuery("select * from t1").Check(testkit.Rows("1 2 3", "10 20 30")) 1541 1542 tk.MustInterDirc("begin pessimistic") 1543 tk.MustInterDirc("select * from t1 where c2 = 2 for uFIDelate") 1544 err = tk.InterDircToErr("insert into t1 values(1, 15, 300);") 1545 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1546 tk.MustInterDirc("commit") 1547 tk2.MustQuery("select * from t1").Check(testkit.Rows("1 2 3", "10 20 30")) 1548 1549 // Test insert after insert. 1550 tk.MustInterDirc("begin pessimistic") 1551 err = tk.InterDircToErr("insert into t1 values(1, 15, 300);") 1552 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1553 tk.MustInterDirc("insert into t1 values(5, 6, 7)") 1554 err = tk.InterDircToErr("insert into t1 values(6, 6, 7);") 1555 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1556 tk.MustInterDirc("commit") 1557 tk2.MustQuery("select * from t1").Check(testkit.Rows("1 2 3", "5 6 7", "10 20 30")) 1558 1559 // Test insert after delete. 1560 tk.MustInterDirc("begin pessimistic") 1561 tk.MustInterDirc("delete from t1 where c2 > 2") 1562 tk.MustInterDirc("insert into t1 values(10, 20, 500);") 1563 err = tk.InterDircToErr("insert into t1 values(20, 20, 30);") 1564 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1565 err = tk.InterDircToErr("insert into t1 values(1, 20, 30);") 1566 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1567 tk.MustInterDirc("commit") 1568 tk2.MustQuery("select * from t1").Check(testkit.Rows("1 2 3", "10 20 500")) 1569 1570 // Test range. 1571 tk.MustInterDirc("begin pessimistic") 1572 err = tk.InterDircToErr("uFIDelate t1 set c2 = 20 where c1 >= 1 and c1 < 5;") 1573 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1574 err = tk.InterDircToErr("uFIDelate t1 set c2 = 20 where c1 >= 1 and c1 < 50;") 1575 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1576 err = tk.InterDircToErr("insert into t1 values(1, 15, 300);") 1577 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1578 tk.MustInterDirc("commit") 1579 tk2.MustQuery("select * from t1").Check(testkit.Rows("1 2 3", "10 20 500")) 1580 1581 // Test select for uFIDelate after dml. 1582 tk.MustInterDirc("begin pessimistic") 1583 tk.MustInterDirc("insert into t1 values(5, 6, 7)") 1584 tk.MustInterDirc("select * from t1 where c1 = 5 for uFIDelate") 1585 tk.MustInterDirc("select * from t1 where c1 = 6 for uFIDelate") 1586 tk.MustInterDirc("select * from t1 for uFIDelate") 1587 err = tk.InterDircToErr("insert into t1 values(7, 6, 7)") 1588 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1589 err = tk.InterDircToErr("insert into t1 values(5, 8, 6)") 1590 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1591 tk.MustInterDirc("select * from t1 where c1 = 5 for uFIDelate") 1592 tk.MustInterDirc("select * from t1 where c2 = 8 for uFIDelate") 1593 tk.MustInterDirc("select * from t1 for uFIDelate") 1594 tk.MustInterDirc("commit") 1595 tk2.MustQuery("select * from t1").Check(testkit.Rows("1 2 3", "5 6 7", "10 20 500")) 1596 1597 // Test optimistic for uFIDelate. 1598 tk.MustInterDirc("begin optimistic") 1599 tk.MustQuery("select * from t1 where c1 = 1 for uFIDelate").Check(testkit.Rows("1 2 3")) 1600 tk.MustInterDirc("insert into t1 values(10, 10, 10)") 1601 err = tk.InterDircToErr("commit") 1602 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1603 } 1604 1605 func (s *testPessimisticSuite) TestInsertDupKeyAfterLockBatchPointGet(c *C) { 1606 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1607 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 1608 tk.MustInterDirc("drop database if exists test_db") 1609 tk.MustInterDirc("create database test_db") 1610 tk.MustInterDirc("use test_db") 1611 tk2.MustInterDirc("use test_db") 1612 tk2.MustInterDirc("drop causet if exists t1") 1613 tk2.MustInterDirc("create causet t1(c1 int primary key, c2 int, c3 int, unique key uk(c2));") 1614 tk2.MustInterDirc("insert into t1 values(1, 2, 3);") 1615 tk2.MustInterDirc("insert into t1 values(10, 20, 30);") 1616 1617 // Test insert after dagger. 1618 tk.MustInterDirc("begin pessimistic") 1619 err := tk.InterDircToErr("uFIDelate t1 set c2 = 20 where c1 in (1);") 1620 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1621 err = tk.InterDircToErr("insert into t1 values(1, 15, 300);") 1622 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1623 tk.MustInterDirc("commit") 1624 tk2.MustQuery("select * from t1").Check(testkit.Rows("1 2 3", "10 20 30")) 1625 1626 tk.MustInterDirc("begin pessimistic") 1627 tk.MustInterDirc("select * from t1 for uFIDelate") 1628 err = tk.InterDircToErr("insert into t1 values(1, 15, 300);") 1629 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1630 tk.MustInterDirc("commit") 1631 tk2.MustQuery("select * from t1").Check(testkit.Rows("1 2 3", "10 20 30")) 1632 1633 tk.MustInterDirc("begin pessimistic") 1634 tk.MustInterDirc("select * from t1 where c2 in (2) for uFIDelate") 1635 err = tk.InterDircToErr("insert into t1 values(1, 15, 300);") 1636 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1637 tk.MustInterDirc("commit") 1638 tk2.MustQuery("select * from t1").Check(testkit.Rows("1 2 3", "10 20 30")) 1639 1640 // Test insert after insert. 1641 tk.MustInterDirc("begin pessimistic") 1642 err = tk.InterDircToErr("insert into t1 values(1, 15, 300);") 1643 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1644 tk.MustInterDirc("insert into t1 values(5, 6, 7)") 1645 err = tk.InterDircToErr("insert into t1 values(6, 6, 7);") 1646 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1647 tk.MustInterDirc("commit") 1648 tk2.MustQuery("select * from t1").Check(testkit.Rows("1 2 3", "5 6 7", "10 20 30")) 1649 1650 // Test insert after delete. 1651 tk.MustInterDirc("begin pessimistic") 1652 tk.MustInterDirc("delete from t1 where c2 > 2") 1653 tk.MustInterDirc("insert into t1 values(10, 20, 500);") 1654 err = tk.InterDircToErr("insert into t1 values(20, 20, 30);") 1655 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1656 err = tk.InterDircToErr("insert into t1 values(1, 20, 30);") 1657 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1658 tk.MustInterDirc("commit") 1659 tk2.MustQuery("select * from t1").Check(testkit.Rows("1 2 3", "10 20 500")) 1660 1661 // Test range. 1662 tk.MustInterDirc("begin pessimistic") 1663 err = tk.InterDircToErr("uFIDelate t1 set c2 = 20 where c1 >= 1 and c1 < 5;") 1664 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1665 err = tk.InterDircToErr("uFIDelate t1 set c2 = 20 where c1 >= 1 and c1 < 50;") 1666 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1667 err = tk.InterDircToErr("insert into t1 values(1, 15, 300);") 1668 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1669 tk.MustInterDirc("commit") 1670 tk2.MustQuery("select * from t1").Check(testkit.Rows("1 2 3", "10 20 500")) 1671 1672 // Test select for uFIDelate after dml. 1673 tk.MustInterDirc("begin pessimistic") 1674 tk.MustInterDirc("insert into t1 values(5, 6, 7)") 1675 tk.MustInterDirc("select * from t1 where c1 in (5, 6) for uFIDelate") 1676 tk.MustInterDirc("select * from t1 where c1 = 6 for uFIDelate") 1677 tk.MustInterDirc("select * from t1 for uFIDelate") 1678 err = tk.InterDircToErr("insert into t1 values(7, 6, 7)") 1679 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1680 err = tk.InterDircToErr("insert into t1 values(5, 8, 6)") 1681 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1682 tk.MustInterDirc("select * from t1 where c2 = 8 for uFIDelate") 1683 tk.MustInterDirc("select * from t1 where c1 in (5, 8) for uFIDelate") 1684 tk.MustInterDirc("select * from t1 for uFIDelate") 1685 tk.MustInterDirc("commit") 1686 tk2.MustQuery("select * from t1").Check(testkit.Rows("1 2 3", "5 6 7", "10 20 500")) 1687 1688 // Test optimistic for uFIDelate. 1689 tk.MustInterDirc("begin optimistic") 1690 tk.MustQuery("select * from t1 where c1 in (1) for uFIDelate").Check(testkit.Rows("1 2 3")) 1691 tk.MustInterDirc("insert into t1 values(10, 10, 10)") 1692 err = tk.InterDircToErr("commit") 1693 c.Assert(terror.ErrorEqual(err, ekv.ErrKeyExists), IsTrue) 1694 } 1695 1696 func (s *testPessimisticSuite) TestAmendTxnVariable(c *C) { 1697 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1698 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 1699 tk3 := testkit.NewTestKitWithInit(c, s.causetstore) 1700 tk.MustInterDirc("drop database if exists test_db") 1701 tk.MustInterDirc("create database test_db") 1702 tk.MustInterDirc("use test_db") 1703 tk2.MustInterDirc("use test_db") 1704 tk2.MustInterDirc("drop causet if exists t1") 1705 tk2.MustInterDirc("create causet t1(c1 int primary key, c2 int, c3 int, unique key uk(c2));") 1706 tk2.MustInterDirc("insert into t1 values(1, 1, 1);") 1707 tk2.MustInterDirc("insert into t1 values(2, 2, 2);") 1708 tk3.MustInterDirc("use test_db") 1709 1710 // Set off the stochastik variable. 1711 tk3.MustInterDirc("set milevadb_enable_amend_pessimistic_txn = 0;") 1712 tk3.MustInterDirc("begin pessimistic") 1713 tk3.MustInterDirc("insert into t1 values(3, 3, 3)") 1714 tk.MustInterDirc("begin pessimistic") 1715 tk.MustInterDirc("insert into t1 values(4, 4, 4)") 1716 tk2.MustInterDirc("alter causet t1 add column new_col int") 1717 err := tk3.InterDircToErr("commit") 1718 c.Assert(err, NotNil) 1719 tk.MustInterDirc("commit") 1720 tk2.MustQuery("select * from t1").Check(testkit.Rows("1 1 1 <nil>", "2 2 2 <nil>", "4 4 4 <nil>")) 1721 1722 // Set off the global variable. 1723 tk2.MustInterDirc("set global milevadb_enable_amend_pessimistic_txn = 0;") 1724 tk4 := testkit.NewTestKitWithInit(c, s.causetstore) 1725 tk4.MustQuery(`show variables like "milevadb_enable_amend_pessimistic_txn"`).Check(testkit.Rows("milevadb_enable_amend_pessimistic_txn 0")) 1726 tk4.MustInterDirc("use test_db") 1727 tk4.MustInterDirc("begin pessimistic") 1728 tk4.MustInterDirc("insert into t1 values(5, 5, 5, 5)") 1729 tk2.MustInterDirc("alter causet t1 drop column new_col") 1730 err = tk4.InterDircToErr("commit") 1731 c.Assert(err, NotNil) 1732 tk4.MustInterDirc("set milevadb_enable_amend_pessimistic_txn = 1;") 1733 tk4.MustInterDirc("begin pessimistic") 1734 tk4.MustInterDirc("insert into t1 values(5, 5, 5)") 1735 tk2.MustInterDirc("alter causet t1 add column new_col2 int") 1736 tk4.MustInterDirc("commit") 1737 tk2.MustQuery("select * from t1").Check(testkit.Rows("1 1 1 <nil>", "2 2 2 <nil>", "4 4 4 <nil>", "5 5 5 <nil>")) 1738 1739 // Restore. 1740 tk2.MustInterDirc("set global milevadb_enable_amend_pessimistic_txn = 1;") 1741 } 1742 1743 func (s *testPessimisticSuite) TestSelectForUFIDelateWaitSeconds(c *C) { 1744 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1745 tk.MustInterDirc("drop causet if exists tk") 1746 tk.MustInterDirc("create causet tk (c1 int primary key, c2 int)") 1747 tk.MustInterDirc("insert into tk values(1,1),(2,2),(3,3),(4,4),(5,5)") 1748 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 1749 tk3 := testkit.NewTestKitWithInit(c, s.causetstore) 1750 tk4 := testkit.NewTestKitWithInit(c, s.causetstore) 1751 tk5 := testkit.NewTestKitWithInit(c, s.causetstore) 1752 1753 // tk2 dagger c1 = 5 1754 tk2.MustInterDirc("begin pessimistic") 1755 tk3.MustInterDirc("begin pessimistic") 1756 tk4.MustInterDirc("begin pessimistic") 1757 tk5.MustInterDirc("begin pessimistic") 1758 tk2.MustInterDirc("select * from tk where c1 = 5 or c1 = 1 for uFIDelate") 1759 start := time.Now() 1760 errCh := make(chan error, 3) 1761 go func() { 1762 // tk3 try dagger c1 = 1 timeout 1sec, the default innodb_lock_wait_timeout value is 50s. 1763 err := tk3.InterDircToErr("select * from tk where c1 = 1 for uFIDelate wait 1") 1764 errCh <- err 1765 }() 1766 go func() { 1767 // Lock use selectLockInterDirc. 1768 err := tk4.InterDircToErr("select * from tk where c1 >= 1 for uFIDelate wait 1") 1769 errCh <- err 1770 }() 1771 go func() { 1772 // Lock use batchPointGetInterDirc. 1773 err := tk5.InterDircToErr("select c2 from tk where c1 in (1, 5) for uFIDelate wait 1") 1774 errCh <- err 1775 }() 1776 waitErr := <-errCh 1777 waitErr2 := <-errCh 1778 waitErr3 := <-errCh 1779 c.Assert(waitErr, NotNil) 1780 c.Check(waitErr.Error(), Equals, einsteindb.ErrLockWaitTimeout.Error()) 1781 c.Assert(waitErr2, NotNil) 1782 c.Check(waitErr2.Error(), Equals, einsteindb.ErrLockWaitTimeout.Error()) 1783 c.Assert(waitErr3, NotNil) 1784 c.Check(waitErr3.Error(), Equals, einsteindb.ErrLockWaitTimeout.Error()) 1785 c.Assert(time.Since(start).Seconds(), Less, 45.0) 1786 tk2.MustInterDirc("commit") 1787 tk3.MustInterDirc("rollback") 1788 tk4.MustInterDirc("rollback") 1789 tk5.MustInterDirc("rollback") 1790 } 1791 1792 func (s *testPessimisticSuite) TestSelectForUFIDelateConflictRetry(c *C) { 1793 defer config.RestoreFunc()() 1794 config.UFIDelateGlobal(func(conf *config.Config) { 1795 conf.EinsteinDBClient.EnableAsyncCommit = true 1796 }) 1797 1798 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1799 tk.MustInterDirc("drop causet if exists tk") 1800 tk.MustInterDirc("create causet tk (c1 int primary key, c2 int)") 1801 tk.MustInterDirc("insert into tk values(1,1),(2,2)") 1802 tk2 := testkit.NewTestKitWithInit(c, s.causetstore) 1803 tk3 := testkit.NewTestKitWithInit(c, s.causetstore) 1804 1805 tk2.MustInterDirc("begin pessimistic") 1806 tk3.MustInterDirc("begin pessimistic") 1807 tk2.MustInterDirc("uFIDelate tk set c2 = c2 + 1 where c1 = 1") 1808 tk3.MustInterDirc("uFIDelate tk set c2 = c2 + 1 where c2 = 2") 1809 tsCh := make(chan uint64) 1810 go func() { 1811 tk3.MustInterDirc("uFIDelate tk set c2 = c2 + 1 where c1 = 1") 1812 lastTS, err := s.causetstore.GetOracle().GetLowResolutionTimestamp(context.Background()) 1813 c.Assert(err, IsNil) 1814 tsCh <- lastTS 1815 tk3.MustInterDirc("commit") 1816 }() 1817 // tk2LastTS should be its forUFIDelateTS 1818 tk2LastTS, err := s.causetstore.GetOracle().GetLowResolutionTimestamp(context.Background()) 1819 c.Assert(err, IsNil) 1820 tk2.MustInterDirc("commit") 1821 1822 tk3LastTs := <-tsCh 1823 // it must get a new ts on pessimistic write conflict so the latest timestamp 1824 // should increase 1825 c.Assert(tk3LastTs, Greater, tk2LastTS) 1826 }