github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/catalog/lease/lease_test.go (about) 1 // Copyright 2015 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 // Note that there's also lease_internal_test.go, in package sql. 12 13 package lease_test 14 15 import ( 16 "bytes" 17 "context" 18 gosql "database/sql" 19 "fmt" 20 "sync" 21 "sync/atomic" 22 "testing" 23 "time" 24 25 "github.com/cockroachdb/cockroach/pkg/base" 26 "github.com/cockroachdb/cockroach/pkg/clusterversion" 27 "github.com/cockroachdb/cockroach/pkg/keys" 28 "github.com/cockroachdb/cockroach/pkg/kv" 29 "github.com/cockroachdb/cockroach/pkg/kv/kvserver" 30 "github.com/cockroachdb/cockroach/pkg/roachpb" 31 "github.com/cockroachdb/cockroach/pkg/server" 32 "github.com/cockroachdb/cockroach/pkg/sql" 33 "github.com/cockroachdb/cockroach/pkg/sql/catalog/lease" 34 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" 35 "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" 36 "github.com/cockroachdb/cockroach/pkg/sql/sqltestutils" 37 "github.com/cockroachdb/cockroach/pkg/sql/tests" 38 "github.com/cockroachdb/cockroach/pkg/testutils" 39 "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" 40 "github.com/cockroachdb/cockroach/pkg/testutils/sqlutils" 41 "github.com/cockroachdb/cockroach/pkg/testutils/testcluster" 42 "github.com/cockroachdb/cockroach/pkg/util/hlc" 43 "github.com/cockroachdb/cockroach/pkg/util/leaktest" 44 "github.com/cockroachdb/cockroach/pkg/util/log" 45 "github.com/cockroachdb/cockroach/pkg/util/syncutil" 46 "github.com/cockroachdb/cockroach/pkg/util/timeutil" 47 "github.com/cockroachdb/cockroach/pkg/util/tracing" 48 "github.com/cockroachdb/errors" 49 "github.com/cockroachdb/logtags" 50 "github.com/lib/pq" 51 "github.com/stretchr/testify/require" 52 ) 53 54 type leaseTest struct { 55 testing.TB 56 server serverutils.TestServerInterface 57 db *gosql.DB 58 kvDB *kv.DB 59 nodes map[uint32]*lease.Manager 60 leaseManagerTestingKnobs lease.ManagerTestingKnobs 61 cfg *base.LeaseManagerConfig 62 } 63 64 func newLeaseTest(tb testing.TB, params base.TestServerArgs) *leaseTest { 65 if params.LeaseManagerConfig == nil { 66 params.LeaseManagerConfig = base.NewLeaseManagerConfig() 67 } 68 s, db, kvDB := serverutils.StartServer(tb, params) 69 leaseTest := &leaseTest{ 70 TB: tb, 71 server: s, 72 db: db, 73 kvDB: kvDB, 74 nodes: map[uint32]*lease.Manager{}, 75 cfg: params.LeaseManagerConfig, 76 } 77 if params.Knobs.SQLLeaseManager != nil { 78 leaseTest.leaseManagerTestingKnobs = 79 *params.Knobs.SQLLeaseManager.(*lease.ManagerTestingKnobs) 80 } 81 return leaseTest 82 } 83 84 func (t *leaseTest) cleanup() { 85 t.server.Stopper().Stop(context.Background()) 86 } 87 88 func (t *leaseTest) getLeases(descID sqlbase.ID) string { 89 sql := ` 90 SELECT version, "nodeID" FROM system.lease WHERE "descID" = $1 ORDER BY version, "nodeID" 91 ` 92 rows, err := t.db.Query(sql, descID) 93 if err != nil { 94 t.Fatal(err) 95 } 96 var buf bytes.Buffer 97 var prefix string 98 for rows.Next() { 99 var ( 100 version int 101 nodeID int 102 ) 103 if err := rows.Scan(&version, &nodeID); err != nil { 104 t.Fatal(err) 105 } 106 fmt.Fprintf(&buf, "%s/%d/%d", prefix, version, nodeID) 107 prefix = " " 108 } 109 if err := rows.Err(); err != nil { 110 t.Fatal(err) 111 } 112 return buf.String() 113 } 114 115 func (t *leaseTest) expectLeases(descID sqlbase.ID, expected string) { 116 testutils.SucceedsSoon(t, func() error { 117 leases := t.getLeases(descID) 118 if expected != leases { 119 return errors.Errorf("expected %s, but found %s", expected, leases) 120 } 121 return nil 122 }) 123 } 124 125 func (t *leaseTest) acquire( 126 nodeID uint32, descID sqlbase.ID, 127 ) (*sqlbase.ImmutableTableDescriptor, hlc.Timestamp, error) { 128 return t.node(nodeID).Acquire(context.Background(), t.server.Clock().Now(), descID) 129 } 130 131 func (t *leaseTest) acquireMinVersion( 132 nodeID uint32, descID sqlbase.ID, minVersion sqlbase.DescriptorVersion, 133 ) (*sqlbase.ImmutableTableDescriptor, hlc.Timestamp, error) { 134 return t.node(nodeID).TestingAcquireAndAssertMinVersion( 135 context.Background(), t.server.Clock().Now(), descID, minVersion) 136 } 137 138 func (t *leaseTest) mustAcquire( 139 nodeID uint32, descID sqlbase.ID, 140 ) (*sqlbase.ImmutableTableDescriptor, hlc.Timestamp) { 141 table, expiration, err := t.acquire(nodeID, descID) 142 if err != nil { 143 t.Fatal(err) 144 } 145 return table, expiration 146 } 147 148 func (t *leaseTest) mustAcquireMinVersion( 149 nodeID uint32, descID sqlbase.ID, minVersion sqlbase.DescriptorVersion, 150 ) (*sqlbase.ImmutableTableDescriptor, hlc.Timestamp) { 151 table, expiration, err := t.acquireMinVersion(nodeID, descID, minVersion) 152 if err != nil { 153 t.Fatal(err) 154 } 155 return table, expiration 156 } 157 158 func (t *leaseTest) release(nodeID uint32, table *sqlbase.ImmutableTableDescriptor) error { 159 return t.node(nodeID).Release(table) 160 } 161 162 // If leaseRemovalTracker is not nil, it will be used to block until the lease is 163 // released from the store. If the lease is not supposed to be released from the 164 // store (i.e. it's not expired and it's not for an old descriptor version), 165 // this shouldn't be set. 166 func (t *leaseTest) mustRelease( 167 nodeID uint32, 168 table *sqlbase.ImmutableTableDescriptor, 169 leaseRemovalTracker *lease.LeaseRemovalTracker, 170 ) { 171 var tracker lease.RemovalTracker 172 if leaseRemovalTracker != nil { 173 tracker = leaseRemovalTracker.TrackRemoval(table) 174 } 175 if err := t.release(nodeID, table); err != nil { 176 t.Fatal(err) 177 } 178 if leaseRemovalTracker != nil { 179 if err := tracker.WaitForRemoval(); err != nil { 180 t.Fatal(err) 181 } 182 } 183 } 184 185 func (t *leaseTest) publish(ctx context.Context, nodeID uint32, descID sqlbase.ID) error { 186 _, err := t.node(nodeID).Publish(ctx, descID, func(*sqlbase.MutableTableDescriptor) error { 187 return nil 188 }, nil) 189 return err 190 } 191 192 func (t *leaseTest) mustPublish(ctx context.Context, nodeID uint32, descID sqlbase.ID) { 193 if err := t.publish(ctx, nodeID, descID); err != nil { 194 t.Fatal(err) 195 } 196 } 197 198 // node gets a Manager corresponding to a mock node. A new lease 199 // manager is initialized for each node. This allows for more complex 200 // inter-node lease testing. 201 func (t *leaseTest) node(nodeID uint32) *lease.Manager { 202 mgr := t.nodes[nodeID] 203 if mgr == nil { 204 var c base.NodeIDContainer 205 c.Set(context.Background(), roachpb.NodeID(nodeID)) 206 nc := base.NewSQLIDContainer(0, &c, true /* exposed*/) 207 // Hack the ExecutorConfig that we pass to the Manager to have a 208 // different node id. 209 cfgCpy := t.server.ExecutorConfig().(sql.ExecutorConfig) 210 cfgCpy.NodeInfo.NodeID = nc 211 mgr = lease.NewLeaseManager( 212 log.AmbientContext{Tracer: tracing.NewTracer()}, 213 nc, 214 cfgCpy.DB, 215 cfgCpy.Clock, 216 cfgCpy.InternalExecutor, 217 cfgCpy.Settings, 218 cfgCpy.Codec, 219 t.leaseManagerTestingKnobs, 220 t.server.Stopper(), 221 t.cfg, 222 ) 223 ctx := logtags.AddTag(context.Background(), "leasemgr", nodeID) 224 mgr.PeriodicallyRefreshSomeLeases(ctx) 225 t.nodes[nodeID] = mgr 226 } 227 return mgr 228 } 229 230 func TestLeaseManager(testingT *testing.T) { 231 defer leaktest.AfterTest(testingT)() 232 removalTracker := lease.NewLeaseRemovalTracker() 233 params, _ := tests.CreateTestServerParams() 234 params.Knobs = base.TestingKnobs{ 235 SQLLeaseManager: &lease.ManagerTestingKnobs{ 236 LeaseStoreTestingKnobs: lease.StorageTestingKnobs{ 237 LeaseReleasedEvent: removalTracker.LeaseRemovedNotification, 238 }, 239 }, 240 } 241 t := newLeaseTest(testingT, params) 242 defer t.cleanup() 243 244 const descID = keys.LeaseTableID 245 ctx := context.Background() 246 247 // We can't acquire a lease on a non-existent table. 248 expected := "descriptor not found" 249 if _, _, err := t.acquire(1, 10000); !testutils.IsError(err, expected) { 250 t.Fatalf("expected %s, but found %v", expected, err) 251 } 252 // Acquire 2 leases from the same node. They should return the same 253 // table and expiration. 254 l1, e1 := t.mustAcquire(1, descID) 255 l2, e2 := t.mustAcquire(1, descID) 256 if l1.ID != l2.ID { 257 t.Fatalf("expected same lease, but found %v != %v", l1, l2) 258 } else if e1 != e2 { 259 t.Fatalf("expected same lease timestamps, but found %v != %v", e1, e2) 260 } 261 t.expectLeases(descID, "/1/1") 262 // Node 2 never acquired a lease on descID, so we should expect an error. 263 if err := t.release(2, l1); err == nil { 264 t.Fatalf("expected error, but found none") 265 } 266 t.mustRelease(1, l1, nil) 267 t.mustRelease(1, l2, nil) 268 t.expectLeases(descID, "/1/1") 269 270 // It is an error to acquire a lease for a specific version that doesn't 271 // exist yet. 272 expected = "version 2 for table lease does not exist yet" 273 if _, _, err := t.acquireMinVersion(1, descID, 2); !testutils.IsError(err, expected) { 274 t.Fatalf("expected %s, but found %v", expected, err) 275 } 276 t.expectLeases(descID, "/1/1") 277 278 // Publish a new version and explicitly acquire it. 279 l2, _ = t.mustAcquire(1, descID) 280 t.mustPublish(ctx, 1, descID) 281 l3, _ := t.mustAcquireMinVersion(1, descID, 2) 282 t.expectLeases(descID, "/1/1 /2/1") 283 284 // When the last local reference on the new version is released we don't 285 // release the node lease. 286 t.mustRelease(1, l3, nil) 287 t.expectLeases(descID, "/1/1 /2/1") 288 289 // We can still acquire a local reference on the old version since it hasn't 290 // expired. 291 l4, _ := t.mustAcquireMinVersion(1, descID, 1) 292 t.mustRelease(1, l4, nil) 293 t.expectLeases(descID, "/1/1 /2/1") 294 295 // When the last local reference on the old version is released the node 296 // lease is also released. 297 t.mustRelease(1, l2, removalTracker) 298 t.expectLeases(descID, "/2/1") 299 300 // Acquire 2 node leases on version 2. 301 l5, _ := t.mustAcquireMinVersion(1, descID, 2) 302 l6, _ := t.mustAcquireMinVersion(2, descID, 2) 303 // Publish version 3. This will succeed immediately. 304 t.mustPublish(ctx, 3, descID) 305 306 // Start a goroutine to publish version 4 which will block until the version 307 // 2 leases are released. 308 var wg sync.WaitGroup 309 wg.Add(1) 310 go func() { 311 t.mustPublish(ctx, 3, descID) 312 wg.Done() 313 }() 314 315 // Force both nodes ahead to version 3. 316 l7, _ := t.mustAcquireMinVersion(1, descID, 3) 317 l8, _ := t.mustAcquireMinVersion(2, descID, 3) 318 t.expectLeases(descID, "/2/1 /2/2 /3/1 /3/2") 319 320 t.mustRelease(1, l5, removalTracker) 321 t.expectLeases(descID, "/2/2 /3/1 /3/2") 322 t.mustRelease(2, l6, removalTracker) 323 t.expectLeases(descID, "/3/1 /3/2") 324 325 // Wait for version 4 to be published. 326 wg.Wait() 327 l9, _ := t.mustAcquireMinVersion(1, descID, 4) 328 t.mustRelease(1, l7, removalTracker) 329 t.mustRelease(2, l8, nil) 330 t.expectLeases(descID, "/3/2 /4/1") 331 t.mustRelease(1, l9, nil) 332 t.expectLeases(descID, "/3/2 /4/1") 333 } 334 335 func TestLeaseManagerReacquire(testingT *testing.T) { 336 defer leaktest.AfterTest(testingT)() 337 params, _ := tests.CreateTestServerParams() 338 339 params.LeaseManagerConfig = base.NewLeaseManagerConfig() 340 // Set the lease duration such that the next lease acquisition will 341 // require the lease to be reacquired. 342 params.LeaseManagerConfig.TableDescriptorLeaseDuration = 0 343 344 removalTracker := lease.NewLeaseRemovalTracker() 345 params.Knobs = base.TestingKnobs{ 346 SQLLeaseManager: &lease.ManagerTestingKnobs{ 347 LeaseStoreTestingKnobs: lease.StorageTestingKnobs{ 348 LeaseReleasedEvent: removalTracker.LeaseRemovedNotification, 349 }, 350 }, 351 } 352 t := newLeaseTest(testingT, params) 353 defer t.cleanup() 354 355 const descID = keys.LeaseTableID 356 357 l1, e1 := t.mustAcquire(1, descID) 358 t.expectLeases(descID, "/1/1") 359 360 // Another lease acquisition from the same node will result in a new lease. 361 rt := removalTracker.TrackRemoval(l1) 362 l3, e3 := t.mustAcquire(1, descID) 363 if l1.ID == l3.ID && e3.WallTime == e1.WallTime { 364 t.Fatalf("expected different leases, but found %v", l1) 365 } 366 if e3.WallTime < e1.WallTime { 367 t.Fatalf("expected new lease expiration (%s) to be after old lease expiration (%s)", 368 e3, e1) 369 } 370 // In acquiring the new lease the older lease is released. 371 if err := rt.WaitForRemoval(); err != nil { 372 t.Fatal(err) 373 } 374 // Only one actual lease. 375 t.expectLeases(descID, "/1/1") 376 377 t.mustRelease(1, l1, nil) 378 t.mustRelease(1, l3, nil) 379 } 380 381 func TestLeaseManagerPublishVersionChanged(testingT *testing.T) { 382 defer leaktest.AfterTest(testingT)() 383 params, _ := tests.CreateTestServerParams() 384 t := newLeaseTest(testingT, params) 385 defer t.cleanup() 386 387 const descID = keys.LeaseTableID 388 389 // Start two goroutines that are concurrently trying to publish a new version 390 // of the descriptor. The first goroutine progresses to the update function 391 // and then signals the second goroutine to start which is allowed to proceed 392 // through completion. The first goroutine is then signaled and when it 393 // attempts to publish the new version it will encounter an update error and 394 // retry the transaction. Upon retry it will see that the descriptor version 395 // has changed and have to proceed to its outer retry loop and wait for the 396 // number of leases on the previous version to drop to 0. 397 398 n1 := t.node(1) 399 n2 := t.node(2) 400 401 n1update := make(chan struct{}) 402 n2start := make(chan struct{}) 403 var wg sync.WaitGroup 404 wg.Add(2) 405 406 go func(n1update, n2start chan struct{}) { 407 _, err := n1.Publish(context.Background(), descID, func(*sqlbase.MutableTableDescriptor) error { 408 if n2start != nil { 409 // Signal node 2 to start. 410 close(n2start) 411 n2start = nil 412 } 413 // Wait for node 2 signal indicating that node 2 finished publication of 414 // a new version. 415 <-n1update 416 return nil 417 }, nil) 418 if err != nil { 419 panic(err) 420 } 421 wg.Done() 422 }(n1update, n2start) 423 424 go func(n1update, n2start chan struct{}) { 425 // Wait for node 1 signal indicating that node 1 is in its update() 426 // function. 427 <-n2start 428 _, err := n2.Publish(context.Background(), descID, func(*sqlbase.MutableTableDescriptor) error { 429 return nil 430 }, nil) 431 if err != nil { 432 panic(err) 433 } 434 close(n1update) 435 wg.Done() 436 }(n1update, n2start) 437 438 wg.Wait() 439 440 t.mustAcquire(1, descID) 441 t.expectLeases(descID, "/3/1") 442 } 443 444 func TestLeaseManagerPublishIllegalVersionChange(testingT *testing.T) { 445 defer leaktest.AfterTest(testingT)() 446 params, _ := tests.CreateTestServerParams() 447 t := newLeaseTest(testingT, params) 448 defer t.cleanup() 449 450 if _, err := t.node(1).Publish( 451 context.Background(), keys.LeaseTableID, func(table *sqlbase.MutableTableDescriptor) error { 452 table.Version++ 453 return nil 454 }, nil); !testutils.IsError(err, "updated version") { 455 t.Fatalf("unexpected error: %+v", err) 456 } 457 if _, err := t.node(1).Publish( 458 context.Background(), keys.LeaseTableID, func(table *sqlbase.MutableTableDescriptor) error { 459 table.Version-- 460 return nil 461 }, nil); !testutils.IsError(err, "updated version") { 462 t.Fatalf("unexpected error: %+v", err) 463 } 464 } 465 466 func TestLeaseManagerDrain(testingT *testing.T) { 467 defer leaktest.AfterTest(testingT)() 468 params, _ := tests.CreateTestServerParams() 469 leaseRemovalTracker := lease.NewLeaseRemovalTracker() 470 params.Knobs = base.TestingKnobs{ 471 SQLLeaseManager: &lease.ManagerTestingKnobs{ 472 LeaseStoreTestingKnobs: lease.StorageTestingKnobs{ 473 LeaseReleasedEvent: leaseRemovalTracker.LeaseRemovedNotification, 474 }, 475 }, 476 } 477 t := newLeaseTest(testingT, params) 478 defer t.cleanup() 479 480 const descID = keys.LeaseTableID 481 482 { 483 l1, _ := t.mustAcquire(1, descID) 484 l2, _ := t.mustAcquire(2, descID) 485 t.mustRelease(1, l1, nil) 486 t.expectLeases(descID, "/1/1 /1/2") 487 488 // Removal tracker to track for node 1's lease removal once the node 489 // starts draining. 490 l1RemovalTracker := leaseRemovalTracker.TrackRemoval(l1) 491 492 t.nodes[1].SetDraining(true, nil /* reporter */) 493 t.nodes[2].SetDraining(true, nil /* reporter */) 494 495 // Leases cannot be acquired when in draining mode. 496 if _, _, err := t.acquire(1, descID); !testutils.IsError(err, "cannot acquire lease when draining") { 497 t.Fatalf("unexpected error: %v", err) 498 } 499 500 // Node 1's lease has a refcount of 0 and should therefore be removed from 501 // the store. 502 if err := l1RemovalTracker.WaitForRemoval(); err != nil { 503 t.Fatal(err) 504 } 505 t.expectLeases(descID, "/1/2") 506 507 // Once node 2's lease is released, the lease should be removed from the 508 // store. 509 t.mustRelease(2, l2, leaseRemovalTracker) 510 t.expectLeases(descID, "") 511 } 512 513 { 514 // Check that leases with a refcount of 0 are correctly kept in the 515 // store once the drain mode has been exited. 516 t.nodes[1].SetDraining(false, nil /* reporter */) 517 l1, _ := t.mustAcquire(1, descID) 518 t.mustRelease(1, l1, nil) 519 t.expectLeases(descID, "/1/1") 520 } 521 } 522 523 // Test that we fail to lease a table that was marked for deletion. 524 func TestCantLeaseDeletedTable(testingT *testing.T) { 525 defer leaktest.AfterTest(testingT)() 526 527 var mu syncutil.Mutex 528 clearSchemaChangers := false 529 530 params, _ := tests.CreateTestServerParams() 531 params.Knobs = base.TestingKnobs{ 532 SQLSchemaChanger: &sql.SchemaChangerTestingKnobs{ 533 SchemaChangeJobNoOp: func() bool { 534 mu.Lock() 535 defer mu.Unlock() 536 return clearSchemaChangers 537 }, 538 }, 539 // Disable GC job. 540 GCJob: &sql.GCJobTestingKnobs{RunBeforeResume: func(_ int64) error { select {} }}, 541 } 542 543 t := newLeaseTest(testingT, params) 544 defer t.cleanup() 545 546 sql := ` 547 CREATE DATABASE test; 548 CREATE TABLE test.t(a INT PRIMARY KEY); 549 ` 550 _, err := t.db.Exec(sql) 551 if err != nil { 552 t.Fatal(err) 553 } 554 555 // Block schema changers so that the table we're about to DROP is not actually 556 // dropped; it will be left in a "deleted" state. 557 mu.Lock() 558 clearSchemaChangers = true 559 mu.Unlock() 560 561 // DROP the table 562 _, err = t.db.Exec(`DROP TABLE test.t`) 563 if err != nil { 564 t.Fatal(err) 565 } 566 567 // Make sure we can't get a lease on the descriptor. 568 tableDesc := sqlbase.GetTableDescriptor(t.kvDB, keys.SystemSQLCodec, "test", "t") 569 // try to acquire at a bogus version to make sure we don't get back a lease we 570 // already had. 571 _, _, err = t.acquireMinVersion(1, tableDesc.ID, tableDesc.Version+1) 572 if !testutils.IsError(err, "table is being dropped") { 573 t.Fatalf("got a different error than expected: %v", err) 574 } 575 } 576 577 func acquire( 578 ctx context.Context, s *server.TestServer, descID sqlbase.ID, 579 ) (*sqlbase.ImmutableTableDescriptor, hlc.Timestamp, error) { 580 return s.LeaseManager().(*lease.Manager).Acquire(ctx, s.Clock().Now(), descID) 581 } 582 583 // Test that once a table is marked as deleted, a lease's refcount dropping to 0 584 // means the lease is released immediately, as opposed to being released only 585 // when it expires. 586 func TestLeasesOnDeletedTableAreReleasedImmediately(t *testing.T) { 587 defer leaktest.AfterTest(t)() 588 589 var mu syncutil.Mutex 590 clearSchemaChangers := false 591 592 var waitTableID sqlbase.ID 593 deleted := make(chan bool) 594 595 params, _ := tests.CreateTestServerParams() 596 params.Knobs = base.TestingKnobs{ 597 SQLLeaseManager: &lease.ManagerTestingKnobs{ 598 TestingTableRefreshedEvent: func(table *sqlbase.TableDescriptor) { 599 mu.Lock() 600 defer mu.Unlock() 601 if waitTableID != table.ID { 602 return 603 } 604 if table.Dropped() { 605 close(deleted) 606 waitTableID = 0 607 } 608 }, 609 }, 610 SQLSchemaChanger: &sql.SchemaChangerTestingKnobs{ 611 SchemaChangeJobNoOp: func() bool { 612 mu.Lock() 613 defer mu.Unlock() 614 return clearSchemaChangers 615 }, 616 }, 617 // Disable GC job. 618 GCJob: &sql.GCJobTestingKnobs{RunBeforeResume: func(_ int64) error { select {} }}, 619 } 620 s, db, kvDB := serverutils.StartServer(t, params) 621 defer s.Stopper().Stop(context.Background()) 622 623 stmt := ` 624 CREATE DATABASE test; 625 CREATE TABLE test.t(a INT PRIMARY KEY); 626 ` 627 _, err := db.Exec(stmt) 628 if err != nil { 629 t.Fatal(err) 630 } 631 632 tableDesc := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "test", "t") 633 ctx := context.Background() 634 635 lease1, _, err := acquire(ctx, s.(*server.TestServer), tableDesc.ID) 636 if err != nil { 637 t.Fatal(err) 638 } 639 lease2, _, err := acquire(ctx, s.(*server.TestServer), tableDesc.ID) 640 if err != nil { 641 t.Fatal(err) 642 } 643 644 // Block schema changers so that the table we're about to DROP is not actually 645 // dropped; it will be left in a "deleted" state. 646 // Also install a way to wait for the config update to be processed. 647 mu.Lock() 648 clearSchemaChangers = true 649 waitTableID = tableDesc.ID 650 mu.Unlock() 651 652 // DROP the table 653 _, err = db.Exec(`DROP TABLE test.t`) 654 if err != nil { 655 t.Fatal(err) 656 } 657 658 // Block until the Manager has processed the gossip update. 659 <-deleted 660 661 // We should still be able to acquire, because we have an active lease. 662 lease3, _, err := acquire(ctx, s.(*server.TestServer), tableDesc.ID) 663 if err != nil { 664 t.Fatal(err) 665 } 666 667 // Release everything. 668 if err := s.LeaseManager().(*lease.Manager).Release(lease1); err != nil { 669 t.Fatal(err) 670 } 671 if err := s.LeaseManager().(*lease.Manager).Release(lease2); err != nil { 672 t.Fatal(err) 673 } 674 if err := s.LeaseManager().(*lease.Manager).Release(lease3); err != nil { 675 t.Fatal(err) 676 } 677 // Now we shouldn't be able to acquire any more. 678 _, _, err = acquire(ctx, s.(*server.TestServer), tableDesc.ID) 679 if !testutils.IsError(err, "table is being dropped") { 680 t.Fatalf("got a different error than expected: %v", err) 681 } 682 } 683 684 // TestSubqueryLeases tests that all leases acquired by a subquery are 685 // properly tracked and released. 686 func TestSubqueryLeases(t *testing.T) { 687 defer leaktest.AfterTest(t)() 688 params, _ := tests.CreateTestServerParams() 689 690 fooRelease := make(chan struct{}, 10) 691 fooAcquiredCount := int32(0) 692 fooReleaseCount := int32(0) 693 var tableID int64 694 695 params.Knobs = base.TestingKnobs{ 696 SQLLeaseManager: &lease.ManagerTestingKnobs{ 697 LeaseStoreTestingKnobs: lease.StorageTestingKnobs{ 698 RemoveOnceDereferenced: true, 699 LeaseAcquiredEvent: func(table sqlbase.TableDescriptor, _ error) { 700 if table.Name == "foo" { 701 atomic.AddInt32(&fooAcquiredCount, 1) 702 } 703 }, 704 LeaseReleasedEvent: func(id sqlbase.ID, _ sqlbase.DescriptorVersion, _ error) { 705 if int64(id) == atomic.LoadInt64(&tableID) { 706 // Note: we don't use close(fooRelease) here because the 707 // lease on "foo" may be re-acquired (and re-released) 708 // multiple times, at least once for the first 709 // CREATE/SELECT pair and one for the finalf DROP. 710 atomic.AddInt32(&fooReleaseCount, 1) 711 fooRelease <- struct{}{} 712 } 713 }, 714 }, 715 }, 716 } 717 s, sqlDB, kvDB := serverutils.StartServer(t, params) 718 defer s.Stopper().Stop(context.Background()) 719 720 if _, err := sqlDB.Exec(` 721 CREATE DATABASE t; 722 CREATE TABLE t.foo (v INT); 723 `); err != nil { 724 t.Fatal(err) 725 } 726 727 if atomic.LoadInt32(&fooAcquiredCount) > 0 { 728 t.Fatalf("CREATE TABLE has acquired a lease: got %d, expected 0", atomic.LoadInt32(&fooAcquiredCount)) 729 } 730 731 tableDesc := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "foo") 732 atomic.StoreInt64(&tableID, int64(tableDesc.ID)) 733 734 if _, err := sqlDB.Exec(` 735 SELECT * FROM t.foo; 736 `); err != nil { 737 t.Fatal(err) 738 } 739 740 prev := atomic.LoadInt32(&fooAcquiredCount) 741 if prev == 0 { 742 t.Fatal("plain SELECT did not get lease; got 0, expected > 0") 743 } 744 745 if _, err := sqlDB.Exec(` 746 SELECT EXISTS(SELECT * FROM t.foo); 747 `); err != nil { 748 t.Fatal(err) 749 } 750 751 if atomic.LoadInt32(&fooAcquiredCount) == prev { 752 t.Fatalf("subquery has not acquired a lease") 753 } 754 755 // Now wait for the release to happen. We use a local timer 756 // to make the test fail faster if it needs to fail. 757 timeout := time.After(5 * time.Second) 758 select { 759 case <-timeout: 760 t.Fatal("lease from sub-query was not released") 761 case <-fooRelease: 762 } 763 } 764 765 // Test that an AS OF SYSTEM TIME query uses the table cache. 766 func TestAsOfSystemTimeUsesCache(t *testing.T) { 767 defer leaktest.AfterTest(t)() 768 params, _ := tests.CreateTestServerParams() 769 770 fooAcquiredCount := int32(0) 771 772 params.Knobs = base.TestingKnobs{ 773 SQLLeaseManager: &lease.ManagerTestingKnobs{ 774 LeaseStoreTestingKnobs: lease.StorageTestingKnobs{ 775 RemoveOnceDereferenced: true, 776 LeaseAcquiredEvent: func(table sqlbase.TableDescriptor, _ error) { 777 if table.Name == "foo" { 778 atomic.AddInt32(&fooAcquiredCount, 1) 779 } 780 }, 781 }, 782 }, 783 } 784 s, sqlDB, _ := serverutils.StartServer(t, params) 785 defer s.Stopper().Stop(context.Background()) 786 787 if _, err := sqlDB.Exec(` 788 CREATE DATABASE t; 789 CREATE TABLE t.foo (v INT); 790 `); err != nil { 791 t.Fatal(err) 792 } 793 794 if atomic.LoadInt32(&fooAcquiredCount) > 0 { 795 t.Fatalf("CREATE TABLE has acquired a lease: got %d, expected 0", atomic.LoadInt32(&fooAcquiredCount)) 796 } 797 798 var tsVal string 799 if err := sqlDB.QueryRow("SELECT cluster_logical_timestamp()").Scan(&tsVal); err != nil { 800 t.Fatal(err) 801 } 802 803 if _, err := sqlDB.Exec( 804 fmt.Sprintf(`SELECT * FROM t.foo AS OF SYSTEM TIME %s;`, tsVal), 805 ); err != nil { 806 t.Fatal(err) 807 } 808 809 count := atomic.LoadInt32(&fooAcquiredCount) 810 if count == 0 { 811 t.Fatal("SELECT did not get lease; got 0, expected > 0") 812 } 813 } 814 815 // TestDescriptorRefreshOnRetry tests that all descriptors acquired by 816 // a query are properly released before the query is retried. 817 func TestDescriptorRefreshOnRetry(t *testing.T) { 818 defer leaktest.AfterTest(t)() 819 params, _ := tests.CreateTestServerParams() 820 821 fooAcquiredCount := int32(0) 822 fooReleaseCount := int32(0) 823 var tableID int64 824 825 params.Knobs = base.TestingKnobs{ 826 SQLLeaseManager: &lease.ManagerTestingKnobs{ 827 LeaseStoreTestingKnobs: lease.StorageTestingKnobs{ 828 // Set this so we observe a release event from the cache 829 // when the API releases the descriptor. 830 RemoveOnceDereferenced: true, 831 LeaseAcquiredEvent: func(table sqlbase.TableDescriptor, _ error) { 832 if table.Name == "foo" { 833 atomic.AddInt32(&fooAcquiredCount, 1) 834 } 835 }, 836 LeaseReleasedEvent: func(id sqlbase.ID, _ sqlbase.DescriptorVersion, _ error) { 837 if int64(id) == atomic.LoadInt64(&tableID) { 838 atomic.AddInt32(&fooReleaseCount, 1) 839 } 840 }, 841 }, 842 }, 843 } 844 s, sqlDB, kvDB := serverutils.StartServer(t, params) 845 defer s.Stopper().Stop(context.Background()) 846 847 if _, err := sqlDB.Exec(` 848 CREATE DATABASE t; 849 CREATE TABLE t.foo (v INT); 850 `); err != nil { 851 t.Fatal(err) 852 } 853 854 if atomic.LoadInt32(&fooAcquiredCount) > 0 { 855 t.Fatalf("CREATE TABLE has acquired a descriptor") 856 } 857 858 tableDesc := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "foo") 859 atomic.StoreInt64(&tableID, int64(tableDesc.ID)) 860 861 tx, err := sqlDB.Begin() 862 if err != nil { 863 t.Fatal(err) 864 } 865 866 _, err = tx.Exec("SAVEPOINT cockroach_restart") 867 require.NoError(t, err) 868 869 // This will acquire a descriptor. We'll check that it gets released before we retry. 870 if _, err := tx.Exec(` 871 SELECT * FROM t.foo; 872 `); err != nil { 873 t.Fatal(err) 874 } 875 876 // Descriptor has been acquired one more time than it has been released. 877 aCount, rCount := atomic.LoadInt32(&fooAcquiredCount), atomic.LoadInt32(&fooReleaseCount) 878 if aCount != rCount+1 { 879 t.Fatalf("invalid descriptor acquisition counts = %d, %d", aCount, rCount) 880 } 881 882 if _, err := tx.Exec( 883 "SELECT crdb_internal.force_retry('100s':::INTERVAL)"); !testutils.IsError( 884 err, `forced by crdb_internal\.force_retry\(\)`) { 885 t.Fatal(err) 886 } 887 888 _, err = tx.Exec("ROLLBACK TO SAVEPOINT cockroach_restart") 889 require.NoError(t, err) 890 891 testutils.SucceedsSoon(t, func() error { 892 if rCount = atomic.LoadInt32(&fooReleaseCount); rCount != aCount { 893 return errors.Errorf("didnt release descriptor, %d != %d", rCount, aCount) 894 } 895 return nil 896 }) 897 898 if err := tx.Rollback(); err != nil { 899 t.Fatal(err) 900 } 901 } 902 903 // Test that a transaction created way in the past will use the correct 904 // table descriptor and will thus obey the modification time of the 905 // table descriptor. 906 func TestTxnObeysTableModificationTime(t *testing.T) { 907 defer leaktest.AfterTest(t)() 908 params, _ := tests.CreateTestServerParams() 909 s, sqlDB, kvDB := serverutils.StartServer(t, params) 910 defer s.Stopper().Stop(context.Background()) 911 912 // Disable strict GC TTL enforcement because we're going to shove a zero-value 913 // TTL into the system with AddImmediateGCZoneConfig. 914 defer sqltestutils.DisableGCTTLStrictEnforcement(t, sqlDB)() 915 916 if _, err := sqlDB.Exec(` 917 CREATE DATABASE t; 918 CREATE TABLE t.kv (k CHAR PRIMARY KEY, v CHAR); 919 INSERT INTO t.kv VALUES ('a', 'b'); 920 `); err != nil { 921 t.Fatal(err) 922 } 923 tableDesc := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "kv") 924 925 // A read-write transaction that uses the old version of the descriptor. 926 txReadWrite, err := sqlDB.Begin() 927 if err != nil { 928 t.Fatal(err) 929 } 930 931 // A read-only transaction that uses the old version of the descriptor. 932 txRead, err := sqlDB.Begin() 933 if err != nil { 934 t.Fatal(err) 935 } 936 937 // A write-only transaction that uses the old version of the descriptor. 938 txWrite, err := sqlDB.Begin() 939 if err != nil { 940 t.Fatal(err) 941 } 942 943 // Modify the table descriptor. 944 if _, err := sqlDB.Exec(`ALTER TABLE t.kv ADD m CHAR DEFAULT 'z';`); err != nil { 945 t.Fatal(err) 946 } 947 948 rows, err := txReadWrite.Query(`SELECT * FROM t.kv`) 949 if err != nil { 950 t.Fatal(err) 951 } 952 953 checkSelectResults := func(rows *gosql.Rows) { 954 defer func() { 955 if err := rows.Close(); err != nil { 956 t.Fatal(err) 957 } 958 }() 959 for rows.Next() { 960 // The transaction is unable to see column m. 961 var k, v, m string 962 if err := rows.Scan(&k, &v, &m); !testutils.IsError( 963 err, "expected 2 destination arguments in Scan, not 3", 964 ) { 965 t.Fatalf("err = %v", err) 966 } 967 err = rows.Scan(&k, &v) 968 if err != nil { 969 t.Fatal(err) 970 } 971 if k != "a" || v != "b" { 972 t.Fatalf("didn't find expected row: %s %s", k, v) 973 } 974 } 975 } 976 977 checkSelectResults(rows) 978 979 rows, err = txRead.Query(`SELECT * FROM t.kv`) 980 if err != nil { 981 t.Fatal(err) 982 } 983 984 checkSelectResults(rows) 985 986 // Read-only transaction commits just fine. 987 if err := txRead.Commit(); err != nil { 988 t.Fatal(err) 989 } 990 991 // This INSERT will cause the transaction to be pushed, 992 // which will be detected when we attempt to Commit() below. 993 if _, err := txReadWrite.Exec(`INSERT INTO t.kv VALUES ('c', 'd');`); err != nil { 994 t.Fatal(err) 995 } 996 997 // The transaction read at one timestamp and wrote at another so it 998 // has to be restarted because the spans read were modified by the backfill. 999 if err := txReadWrite.Commit(); !testutils.IsError(err, 1000 "TransactionRetryError: retry txn \\(RETRY_SERIALIZABLE\\)") { 1001 t.Fatalf("err = %v", err) 1002 } 1003 1004 // This INSERT will cause the transaction to be pushed transparently, 1005 // which will be detected when we attempt to Commit() below only because 1006 // a deadline has been set. 1007 if _, err := txWrite.Exec(`INSERT INTO t.kv VALUES ('c', 'd');`); err != nil { 1008 t.Fatal(err) 1009 } 1010 1011 checkDeadlineErr := func(err error, t *testing.T) { 1012 var pqe (*pq.Error) 1013 if !errors.As(err, &pqe) || pqe.Code != pgcode.SerializationFailure || 1014 !testutils.IsError(err, "RETRY_COMMIT_DEADLINE_EXCEEDED") { 1015 t.Fatalf("expected deadline exceeded, got: %v", err) 1016 } 1017 } 1018 checkDeadlineErr(txWrite.Commit(), t) 1019 1020 // Test the deadline exceeded error with a CREATE/DROP INDEX. 1021 txWrite, err = sqlDB.Begin() 1022 if err != nil { 1023 t.Fatal(err) 1024 } 1025 txUpdate, err := sqlDB.Begin() 1026 if err != nil { 1027 t.Fatal(err) 1028 } 1029 1030 // Modify the table descriptor. 1031 if _, err := sqlDB.Exec(`CREATE INDEX foo ON t.kv (v)`); err != nil { 1032 t.Fatal(err) 1033 } 1034 1035 // This INSERT will cause the transaction to be pushed transparently, 1036 // which will be detected when we attempt to Commit() below only because 1037 // a deadline has been set. 1038 if _, err := txWrite.Exec(`INSERT INTO t.kv VALUES ('c', 'd');`); err != nil { 1039 t.Fatal(err) 1040 } 1041 1042 checkDeadlineErr(txWrite.Commit(), t) 1043 1044 if _, err := txUpdate.Exec(`UPDATE t.kv SET v = 'c' WHERE k = 'a';`); err != nil { 1045 t.Fatal(err) 1046 } 1047 1048 checkDeadlineErr(txUpdate.Commit(), t) 1049 1050 txWrite, err = sqlDB.Begin() 1051 if err != nil { 1052 t.Fatal(err) 1053 } 1054 txRead, err = sqlDB.Begin() 1055 if err != nil { 1056 t.Fatal(err) 1057 } 1058 1059 // Modify the table descriptor. 1060 if _, err := sqlDB.Exec(`DROP INDEX t.kv@foo`); err != nil { 1061 t.Fatal(err) 1062 } 1063 1064 rows, err = txRead.Query(`SELECT k, v FROM t.kv@foo`) 1065 if err != nil { 1066 t.Fatal(err) 1067 } 1068 checkSelectResults(rows) 1069 1070 // Uses old descriptor and inserts values into index span which 1071 // will be cleaned up. 1072 if _, err := txWrite.Exec(`INSERT INTO t.kv VALUES ('c', 'd');`); err != nil { 1073 t.Fatal(err) 1074 } 1075 1076 if err := txRead.Commit(); err != nil { 1077 t.Fatal(err) 1078 } 1079 if err := txWrite.Commit(); err != nil { 1080 t.Fatal(err) 1081 } 1082 1083 tableSpan := tableDesc.TableSpan(keys.SystemSQLCodec) 1084 tests.CheckKeyCount(t, kvDB, tableSpan, 4) 1085 1086 // Allow async schema change waiting for GC to complete (when dropping an 1087 // index) and clear the index keys. 1088 if _, err := sqltestutils.AddImmediateGCZoneConfig(sqlDB, tableDesc.ID); err != nil { 1089 t.Fatal(err) 1090 } 1091 1092 testutils.SucceedsSoon(t, func() error { 1093 if tableDesc := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "kv"); len(tableDesc.GCMutations) != 0 { 1094 return errors.Errorf("%d gc mutations remaining", len(tableDesc.GCMutations)) 1095 } 1096 return nil 1097 }) 1098 1099 tests.CheckKeyCount(t, kvDB, tableSpan, 2) 1100 1101 // TODO(erik, vivek): Transactions using old descriptors should fail and 1102 // rollback when the index keys have been removed by ClearRange 1103 // and the consistency issue is resolved. See #31563. 1104 } 1105 1106 // Test that a lease on a table descriptor is always acquired on the latest 1107 // version of a descriptor. 1108 func TestLeaseAtLatestVersion(t *testing.T) { 1109 defer leaktest.AfterTest(t)() 1110 params, _ := tests.CreateTestServerParams() 1111 errChan := make(chan error, 1) 1112 params.Knobs = base.TestingKnobs{ 1113 SQLLeaseManager: &lease.ManagerTestingKnobs{ 1114 LeaseStoreTestingKnobs: lease.StorageTestingKnobs{ 1115 LeaseAcquiredEvent: func(table sqlbase.TableDescriptor, _ error) { 1116 if table.Name == "kv" { 1117 var err error 1118 if table.Version != 2 { 1119 err = errors.Errorf("not seeing latest version") 1120 } 1121 errChan <- err 1122 } 1123 }, 1124 }, 1125 }, 1126 } 1127 s, sqlDB, kvDB := serverutils.StartServer(t, params) 1128 defer s.Stopper().Stop(context.Background()) 1129 1130 if _, err := sqlDB.Exec(` 1131 BEGIN; 1132 CREATE DATABASE t; 1133 CREATE TABLE t.kv (k CHAR PRIMARY KEY, v CHAR); 1134 CREATE TABLE t.timestamp (k CHAR PRIMARY KEY, v CHAR); 1135 INSERT INTO t.kv VALUES ('a', 'b'); 1136 COMMIT; 1137 `); err != nil { 1138 t.Fatal(err) 1139 } 1140 1141 tableDesc := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "kv") 1142 1143 tx, err := sqlDB.Begin() 1144 if err != nil { 1145 t.Fatal(err) 1146 } 1147 1148 // Insert an entry so that the transaction is guaranteed to be 1149 // assigned a timestamp. 1150 if _, err := tx.Exec(` 1151 INSERT INTO t.timestamp VALUES ('a', 'b'); 1152 `); err != nil { 1153 t.Fatal(err) 1154 } 1155 1156 // Increment the table version after the txn has started. 1157 leaseMgr := s.LeaseManager().(*lease.Manager) 1158 if _, err := leaseMgr.Publish( 1159 context.Background(), tableDesc.ID, func(table *sqlbase.MutableTableDescriptor) error { 1160 // Do nothing: increments the version. 1161 return nil 1162 }, nil); err != nil { 1163 t.Error(err) 1164 } 1165 1166 // This select will see version 1 of the table. It will first 1167 // acquire a lease on version 2 and note that the table descriptor is 1168 // invalid for the transaction, so it will read the previous version 1169 // and use it. 1170 rows, err := tx.Query(`SELECT * FROM t.kv`) 1171 if err != nil { 1172 t.Fatal(err) 1173 } 1174 rows.Close() 1175 1176 if err := tx.Commit(); err != nil { 1177 t.Fatal(err) 1178 } 1179 1180 if err := <-errChan; err != nil { 1181 t.Fatal(err) 1182 } 1183 } 1184 1185 // BenchmarkLeaseAcquireByNameCached benchmarks the AcquireByName 1186 // acquisition code path if a valid lease exists and is contained in 1187 // tableNameCache. In particular this benchmark is done with 1188 // parallelism, which is important to also benchmark locking. 1189 func BenchmarkLeaseAcquireByNameCached(b *testing.B) { 1190 defer leaktest.AfterTest(b)() 1191 params, _ := tests.CreateTestServerParams() 1192 1193 t := newLeaseTest(b, params) 1194 defer t.cleanup() 1195 1196 if _, err := t.db.Exec(` 1197 CREATE DATABASE t; 1198 CREATE TABLE t.test (k CHAR PRIMARY KEY, v CHAR); 1199 `); err != nil { 1200 t.Fatal(err) 1201 } 1202 1203 tableDesc := sqlbase.GetTableDescriptor(t.kvDB, keys.SystemSQLCodec, "t", "test") 1204 dbID := tableDesc.ParentID 1205 tableName := tableDesc.Name 1206 leaseManager := t.node(1) 1207 1208 // Acquire the lease so it is put into the tableNameCache. 1209 _, _, err := leaseManager.AcquireByName( 1210 context.Background(), 1211 t.server.Clock().Now(), 1212 dbID, 1213 tableDesc.GetParentSchemaID(), 1214 tableName, 1215 ) 1216 if err != nil { 1217 t.Fatal(err) 1218 } 1219 1220 b.ResetTimer() 1221 1222 b.RunParallel(func(pb *testing.PB) { 1223 for pb.Next() { 1224 _, _, err := leaseManager.AcquireByName( 1225 context.Background(), 1226 t.server.Clock().Now(), 1227 dbID, 1228 tableDesc.GetParentSchemaID(), 1229 tableName, 1230 ) 1231 if err != nil { 1232 b.Fatal(err) 1233 } 1234 } 1235 }) 1236 1237 } 1238 1239 // This test makes sure leases get renewed automatically in the 1240 // background if the lease is about to expire, without blocking. We 1241 // first acquire a lease, then continue to re-acquire it until another 1242 // lease is renewed. 1243 func TestLeaseRenewedAutomatically(testingT *testing.T) { 1244 defer leaktest.AfterTest(testingT)() 1245 1246 var testAcquiredCount int32 1247 var testAcquisitionBlockCount int32 1248 1249 params, _ := tests.CreateTestServerParams() 1250 params.Knobs = base.TestingKnobs{ 1251 SQLLeaseManager: &lease.ManagerTestingKnobs{ 1252 LeaseStoreTestingKnobs: lease.StorageTestingKnobs{ 1253 // We want to track when leases get acquired and when they are renewed. 1254 // We also want to know when acquiring blocks to test lease renewal. 1255 LeaseAcquiredEvent: func(table sqlbase.TableDescriptor, _ error) { 1256 if table.ID > keys.MaxReservedDescID { 1257 atomic.AddInt32(&testAcquiredCount, 1) 1258 } 1259 }, 1260 LeaseAcquireResultBlockEvent: func(_ lease.AcquireBlockType) { 1261 atomic.AddInt32(&testAcquisitionBlockCount, 1) 1262 }, 1263 }, 1264 }, 1265 } 1266 params.LeaseManagerConfig = base.NewLeaseManagerConfig() 1267 // The lease jitter is set to ensure newer leases have higher 1268 // expiration timestamps. 1269 params.LeaseManagerConfig.TableDescriptorLeaseJitterFraction = 0.0 1270 // The renewal timeout is set to be the duration, so background 1271 // renewal should begin immediately after accessing a lease. 1272 params.LeaseManagerConfig.TableDescriptorLeaseRenewalTimeout = 1273 params.LeaseManagerConfig.TableDescriptorLeaseDuration 1274 1275 ctx := context.Background() 1276 t := newLeaseTest(testingT, params) 1277 defer t.cleanup() 1278 1279 if _, err := t.db.Exec(` 1280 CREATE DATABASE t; 1281 CREATE TABLE t.test1 (k CHAR PRIMARY KEY, v CHAR); 1282 CREATE TABLE t.test2 (); 1283 `); err != nil { 1284 t.Fatal(err) 1285 } 1286 1287 test1Desc := sqlbase.GetTableDescriptor(t.kvDB, keys.SystemSQLCodec, "t", "test1") 1288 test2Desc := sqlbase.GetTableDescriptor(t.kvDB, keys.SystemSQLCodec, "t", "test2") 1289 dbID := test2Desc.ParentID 1290 1291 // Acquire a lease on test1 by name. 1292 ts1, eo1, err := t.node(1).AcquireByName( 1293 ctx, 1294 t.server.Clock().Now(), 1295 dbID, 1296 test1Desc.GetParentSchemaID(), 1297 "test1", 1298 ) 1299 if err != nil { 1300 t.Fatal(err) 1301 } else if err := t.release(1, ts1); err != nil { 1302 t.Fatal(err) 1303 } else if count := atomic.LoadInt32(&testAcquiredCount); count != 1 { 1304 t.Fatalf("expected 1 lease to be acquired, but acquired %d times", 1305 count) 1306 } 1307 1308 // Acquire a lease on test2 by ID. 1309 ts2, eo2, err := t.node(1).Acquire(ctx, t.server.Clock().Now(), test2Desc.ID) 1310 if err != nil { 1311 t.Fatal(err) 1312 } else if err := t.release(1, ts2); err != nil { 1313 t.Fatal(err) 1314 } else if count := atomic.LoadInt32(&testAcquiredCount); count != 2 { 1315 t.Fatalf("expected 2 leases to be acquired, but acquired %d times", 1316 count) 1317 } 1318 1319 // Reset testAcquisitionBlockCount as the first acqusition will always block. 1320 atomic.StoreInt32(&testAcquisitionBlockCount, 0) 1321 1322 testutils.SucceedsSoon(t, func() error { 1323 // Acquire another lease by name on test1. At first this will be the 1324 // same lease, but eventually we will asynchronously renew a lease and 1325 // our acquire will get a newer lease. 1326 ts1, en1, err := t.node(1).AcquireByName( 1327 ctx, 1328 t.server.Clock().Now(), 1329 dbID, 1330 test1Desc.GetParentSchemaID(), 1331 "test1", 1332 ) 1333 if err != nil { 1334 t.Fatal(err) 1335 } 1336 defer func() { 1337 if err := t.release(1, ts1); err != nil { 1338 t.Fatal(err) 1339 } 1340 }() 1341 1342 // We check for the new expiry time because if our past acquire triggered 1343 // the background renewal, the next lease we get will be the result of the 1344 // background renewal. 1345 if en1.WallTime <= eo1.WallTime { 1346 return errors.Errorf("expected new lease expiration (%s) to be after old lease expiration (%s)", 1347 en1, eo1) 1348 } else if count := atomic.LoadInt32(&testAcquiredCount); count < 2 { 1349 return errors.Errorf("expected at least 2 leases to be acquired, but acquired %d times", 1350 count) 1351 } else if blockCount := atomic.LoadInt32(&testAcquisitionBlockCount); blockCount > 0 { 1352 t.Fatalf("expected repeated lease acquisition to not block, but blockCount is: %d", blockCount) 1353 } 1354 1355 // Acquire another lease by ID on test2. At first this will be the same 1356 // lease, but eventually we will asynchronously renew a lease and our 1357 // acquire will get a newer lease. 1358 ts2, en2, err := t.node(1).Acquire(ctx, t.server.Clock().Now(), test2Desc.ID) 1359 if err != nil { 1360 t.Fatal(err) 1361 } 1362 defer func() { 1363 if err := t.release(1, ts2); err != nil { 1364 t.Fatal(err) 1365 } 1366 }() 1367 1368 // We check for the new expiry time because if our past acquire triggered 1369 // the background renewal, the next lease we get will be the result of the 1370 // background renewal. 1371 if en2.WallTime <= eo2.WallTime { 1372 return errors.Errorf("expected new lease expiration (%s) to be after old lease expiration (%s)", 1373 en2, eo2) 1374 } else if count := atomic.LoadInt32(&testAcquiredCount); count < 3 { 1375 return errors.Errorf("expected at least 3 leases to be acquired, but acquired %d times", 1376 count) 1377 } else if blockCount := atomic.LoadInt32(&testAcquisitionBlockCount); blockCount > 0 { 1378 t.Fatalf("expected repeated lease acquisition to not block, but blockCount is: %d", blockCount) 1379 } 1380 1381 return nil 1382 }) 1383 } 1384 1385 // Check that the table version is incremented with every schema change. 1386 // The test also verifies that when a lease is in use, the first schema 1387 // change can proceed, but the next one will wait until the lease is 1388 // released. Furthermore, this also tests that the schema change transaction 1389 // will rollback a transaction that violates the two version invariant 1390 // thereby not blocking any table lease transaction trying to acquire a 1391 // table lease. 1392 func TestIncrementTableVersion(t *testing.T) { 1393 defer leaktest.AfterTest(t)() 1394 var violations int64 1395 params, _ := tests.CreateTestServerParams() 1396 params.Knobs = base.TestingKnobs{ 1397 // Disable execution of schema changers after the schema change 1398 // transaction commits. This is to prevent executing the default 1399 // WaitForOneVersion() code that holds up a schema change 1400 // transaction until the new version has been published to the 1401 // entire cluster. 1402 SQLSchemaChanger: &sql.SchemaChangerTestingKnobs{ 1403 SchemaChangeJobNoOp: func() bool { 1404 return true 1405 }, 1406 TwoVersionLeaseViolation: func() { 1407 atomic.AddInt64(&violations, 1) 1408 }, 1409 }, 1410 } 1411 s, sqlDB, kvDB := serverutils.StartServer(t, params) 1412 defer s.Stopper().Stop(context.Background()) 1413 1414 if _, err := sqlDB.Exec(` 1415 CREATE DATABASE t; 1416 CREATE TABLE t.kv (k CHAR PRIMARY KEY, v CHAR); 1417 `); err != nil { 1418 t.Fatal(err) 1419 } 1420 1421 tableDesc := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "kv") 1422 if tableDesc.Version != 1 { 1423 t.Fatalf("invalid version %d", tableDesc.Version) 1424 } 1425 1426 tx, err := sqlDB.Begin() 1427 if err != nil { 1428 t.Fatal(err) 1429 } 1430 1431 // Grab a lease on the table. 1432 if _, err := tx.Exec("INSERT INTO t.kv VALUES ('a', 'b');"); err != nil { 1433 t.Fatal(err) 1434 } 1435 1436 // Modify the table descriptor. 1437 if _, err := sqlDB.Exec(`ALTER TABLE t.kv RENAME to t.kv1`); err != nil { 1438 t.Fatal(err) 1439 } 1440 1441 // The first schema change will succeed and increment the version. 1442 tableDesc = sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "kv") 1443 if tableDesc.Version != 2 { 1444 t.Fatalf("invalid version %d", tableDesc.Version) 1445 } 1446 1447 if l := atomic.LoadInt64(&violations); l > 0 { 1448 t.Fatalf("violations = %d", l) 1449 } 1450 var wg sync.WaitGroup 1451 wg.Add(1) 1452 go func() { 1453 if _, err := sqlDB.Exec(`ALTER TABLE t.kv1 RENAME TO t.kv2`); err != nil { 1454 t.Error(err) 1455 } 1456 wg.Done() 1457 }() 1458 1459 // Let the second schema change hit a retry because of a two version 1460 // lease violation. 1461 testutils.SucceedsSoon(t, func() error { 1462 if atomic.LoadInt64(&violations) == 0 { 1463 return errors.Errorf("didnt retry schema change") 1464 } 1465 return nil 1466 }) 1467 // The second schema change doesn't increment the table descriptor 1468 // version. Furthermore, it also doesn't block any reads on 1469 // the table descriptor. If the schema change transaction 1470 // doesn't rollback the transaction this descriptor read will 1471 // hang. 1472 tableDesc = sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "kv") 1473 if tableDesc.Version != 2 { 1474 t.Fatalf("invalid version %d", tableDesc.Version) 1475 } 1476 1477 // Transaction successfully used the old version. 1478 if err := tx.Commit(); err != nil { 1479 t.Fatal(err) 1480 } 1481 1482 wg.Wait() 1483 tableDesc = sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "kv") 1484 if tableDesc.Version != 3 { 1485 t.Fatalf("invalid version %d", tableDesc.Version) 1486 } 1487 } 1488 1489 // Tests that when a transaction has already returned results 1490 // to the user and the transaction continues on to make a schema change, 1491 // whenever the table lease two version invariant is violated and the 1492 // transaction needs to be restarted, a retryable error is returned to the 1493 // user. 1494 func TestTwoVersionInvariantRetryError(t *testing.T) { 1495 defer leaktest.AfterTest(t)() 1496 var violations int64 1497 params, _ := tests.CreateTestServerParams() 1498 params.Knobs = base.TestingKnobs{ 1499 // Disable execution of schema changers after the schema change 1500 // transaction commits. This is to prevent executing the default 1501 // WaitForOneVersion() code that holds up a schema change 1502 // transaction until the new version has been published to the 1503 // entire cluster. 1504 SQLSchemaChanger: &sql.SchemaChangerTestingKnobs{ 1505 SchemaChangeJobNoOp: func() bool { 1506 return true 1507 }, 1508 TwoVersionLeaseViolation: func() { 1509 atomic.AddInt64(&violations, 1) 1510 }, 1511 }, 1512 } 1513 s, sqlDB, kvDB := serverutils.StartServer(t, params) 1514 defer s.Stopper().Stop(context.Background()) 1515 1516 if _, err := sqlDB.Exec(` 1517 CREATE DATABASE t; 1518 CREATE TABLE t.kv (k CHAR PRIMARY KEY, v CHAR); 1519 INSERT INTO t.kv VALUES ('a', 'b'); 1520 `); err != nil { 1521 t.Fatal(err) 1522 } 1523 1524 tableDesc := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "kv") 1525 if tableDesc.Version != 1 { 1526 t.Fatalf("invalid version %d", tableDesc.Version) 1527 } 1528 1529 tx, err := sqlDB.Begin() 1530 if err != nil { 1531 t.Fatal(err) 1532 } 1533 1534 // Grab a lease on the table. 1535 rows, err := tx.Query("SELECT * FROM t.kv") 1536 if err != nil { 1537 t.Fatal(err) 1538 } 1539 if err := rows.Close(); err != nil { 1540 t.Fatal(err) 1541 } 1542 1543 // Modify the table descriptor increments the version. 1544 if _, err := sqlDB.Exec(`ALTER TABLE t.kv RENAME to t.kv1`); err != nil { 1545 t.Fatal(err) 1546 } 1547 1548 txRetry, err := sqlDB.Begin() 1549 if err != nil { 1550 t.Fatal(err) 1551 } 1552 1553 // Read some data using the transaction so that it cannot be 1554 // retried internally 1555 rows, err = txRetry.Query(`SELECT 1`) 1556 if err != nil { 1557 t.Fatal(err) 1558 } 1559 if err := rows.Close(); err != nil { 1560 t.Fatal(err) 1561 } 1562 1563 if _, err := txRetry.Exec(`ALTER TABLE t.kv1 RENAME TO t.kv2`); err != nil { 1564 t.Fatal(err) 1565 } 1566 1567 var wg sync.WaitGroup 1568 wg.Add(1) 1569 go func() { 1570 // This can hang waiting for one version before tx.Commit() is 1571 // called below, so it is executed in another goroutine 1572 if err := txRetry.Commit(); !testutils.IsError(err, 1573 `TransactionRetryWithProtoRefreshError: cannot publish new versions for tables: \[\{kv1 53 1\}\], old versions still in use`, 1574 ) { 1575 t.Errorf("err = %v", err) 1576 } 1577 wg.Done() 1578 }() 1579 1580 // Make sure that txRetry does violate the two version lease invariant. 1581 testutils.SucceedsSoon(t, func() error { 1582 if atomic.LoadInt64(&violations) == 0 { 1583 return errors.Errorf("didnt retry schema change") 1584 } 1585 return nil 1586 }) 1587 // Commit the first transaction, unblocking txRetry. 1588 if err := tx.Commit(); err != nil { 1589 t.Fatal(err) 1590 } 1591 wg.Wait() 1592 } 1593 1594 func TestModificationTimeTxnOrdering(testingT *testing.T) { 1595 defer leaktest.AfterTest(testingT)() 1596 1597 testingT.Skip("#22479") 1598 1599 // Decide how long we should run this. 1600 maxTime := time.Duration(5) * time.Second 1601 if testutils.NightlyStress() { 1602 maxTime = time.Duration(2) * time.Minute 1603 } 1604 1605 // Which table to exercise the test against. 1606 const descID = keys.LeaseTableID 1607 1608 params, _ := tests.CreateTestServerParams() 1609 t := newLeaseTest(testingT, params) 1610 defer t.cleanup() 1611 1612 if _, err := t.db.Exec(` 1613 CREATE DATABASE t; 1614 CREATE TABLE t.test0 (k CHAR PRIMARY KEY, v CHAR); 1615 `); err != nil { 1616 t.Fatal(err) 1617 } 1618 1619 ctx := context.Background() 1620 1621 // When to end the test. 1622 end := timeutil.Now().Add(maxTime) 1623 var wg sync.WaitGroup 1624 wg.Add(2) 1625 1626 log.Infof(ctx, "until %s", end) 1627 1628 go func() { 1629 for count := 0; timeutil.Now().Before(end); count++ { 1630 log.Infof(ctx, "renaming test%d to test%d", count, count+1) 1631 if _, err := t.db.Exec(fmt.Sprintf(`ALTER TABLE t.test%d RENAME TO t.test%d`, count, count+1)); err != nil { 1632 t.Fatal(err) 1633 } 1634 } 1635 wg.Done() 1636 }() 1637 1638 go func() { 1639 leaseMgr := t.node(1) 1640 for timeutil.Now().Before(end) { 1641 log.Infof(ctx, "publishing new descriptor") 1642 table, err := leaseMgr.Publish(ctx, descID, func(*sqlbase.MutableTableDescriptor) error { return nil }, nil) 1643 if err != nil { 1644 t.Fatalf("error while publishing: %v", err) 1645 } 1646 1647 // Wait a little time to give a chance to other goroutines to 1648 // race past. 1649 time.Sleep(20 * time.Millisecond) 1650 1651 // Now check that the version that was updated is indeed observable 1652 // in the database at the time it says it was modified. 1653 // 1654 // This checks that the modification timestamp is not lying about 1655 // the transaction commit time (and that the txn commit time wasn't 1656 // bumped past it). 1657 log.Infof(ctx, "checking version %d", table.Version) 1658 txn := kv.NewTxn(ctx, t.kvDB, roachpb.NodeID(0)) 1659 // Make the txn look back at the known modification timestamp. 1660 txn.SetFixedTimestamp(ctx, table.ModificationTime) 1661 1662 // Look up the descriptor. 1663 descKey := sqlbase.MakeDescMetadataKey(keys.SystemSQLCodec, descID) 1664 dbDesc := &sqlbase.Descriptor{} 1665 ts, err := txn.GetProtoTs(ctx, descKey, dbDesc) 1666 if err != nil { 1667 t.Fatalf("error while reading proto: %v", err) 1668 } 1669 // Look at the descriptor that comes back from the database. 1670 dbTable := dbDesc.Table(ts) 1671 1672 if dbTable.Version != table.Version || dbTable.ModificationTime != table.ModificationTime { 1673 t.Fatalf("db has version %d at ts %s, expected version %d at ts %s", 1674 dbTable.Version, dbTable.ModificationTime, table.Version, table.ModificationTime) 1675 } 1676 } 1677 wg.Done() 1678 }() 1679 1680 wg.Wait() 1681 } 1682 1683 // This test makes sure leases get renewed periodically. 1684 // TODO(vivek): remove once epoch based leases is implemented. 1685 func TestLeaseRenewedPeriodically(testingT *testing.T) { 1686 defer leaktest.AfterTest(testingT)() 1687 1688 var mu syncutil.Mutex 1689 releasedIDs := make(map[sqlbase.ID]struct{}) 1690 1691 var testAcquiredCount int32 1692 var testAcquisitionBlockCount int32 1693 1694 params, _ := tests.CreateTestServerParams() 1695 params.Knobs = base.TestingKnobs{ 1696 SQLLeaseManager: &lease.ManagerTestingKnobs{ 1697 LeaseStoreTestingKnobs: lease.StorageTestingKnobs{ 1698 // We want to track when leases get acquired and when they are renewed. 1699 // We also want to know when acquiring blocks to test lease renewal. 1700 LeaseAcquiredEvent: func(table sqlbase.TableDescriptor, _ error) { 1701 if table.ID > keys.MaxReservedDescID { 1702 atomic.AddInt32(&testAcquiredCount, 1) 1703 } 1704 }, 1705 LeaseReleasedEvent: func(id sqlbase.ID, _ sqlbase.DescriptorVersion, _ error) { 1706 if id < keys.MaxReservedDescID { 1707 return 1708 } 1709 mu.Lock() 1710 defer mu.Unlock() 1711 releasedIDs[id] = struct{}{} 1712 }, 1713 LeaseAcquireResultBlockEvent: func(_ lease.AcquireBlockType) { 1714 atomic.AddInt32(&testAcquisitionBlockCount, 1) 1715 }, 1716 }, 1717 TestingTableUpdateEvent: func(_ *sqlbase.TableDescriptor) error { 1718 return errors.Errorf("ignore gossip update") 1719 }, 1720 }, 1721 } 1722 params.LeaseManagerConfig = base.NewLeaseManagerConfig() 1723 // The lease jitter is set to ensure newer leases have higher 1724 // expiration timestamps. 1725 params.LeaseManagerConfig.TableDescriptorLeaseJitterFraction = 0.0 1726 // Lease duration to something small. 1727 params.LeaseManagerConfig.TableDescriptorLeaseDuration = 50 * time.Millisecond 1728 // Renewal timeout to 0 saying that the lease will get renewed only 1729 // after the lease expires when a request requests the descriptor. 1730 params.LeaseManagerConfig.TableDescriptorLeaseRenewalTimeout = 0 1731 1732 ctx := context.Background() 1733 t := newLeaseTest(testingT, params) 1734 defer t.cleanup() 1735 1736 if _, err := t.db.Exec(` 1737 CREATE DATABASE t; 1738 CREATE TABLE t.test1 (k CHAR PRIMARY KEY, v CHAR); 1739 CREATE TABLE t.test2 (); 1740 `); err != nil { 1741 t.Fatal(err) 1742 } 1743 1744 test1Desc := sqlbase.GetTableDescriptor(t.kvDB, keys.SystemSQLCodec, "t", "test2") 1745 test2Desc := sqlbase.GetTableDescriptor(t.kvDB, keys.SystemSQLCodec, "t", "test2") 1746 dbID := test2Desc.ParentID 1747 1748 atomic.StoreInt32(&testAcquisitionBlockCount, 0) 1749 1750 numReleasedLeases := func() int { 1751 mu.Lock() 1752 defer mu.Unlock() 1753 return len(releasedIDs) 1754 } 1755 if count := numReleasedLeases(); count != 0 { 1756 t.Fatalf("expected no leases to be releases, released %d", count) 1757 } 1758 1759 // Acquire a lease on test1 by name. 1760 ts1, _, err := t.node(1).AcquireByName( 1761 ctx, 1762 t.server.Clock().Now(), 1763 dbID, 1764 test1Desc.GetParentSchemaID(), 1765 "test1", 1766 ) 1767 if err != nil { 1768 t.Fatal(err) 1769 } else if err := t.release(1, ts1); err != nil { 1770 t.Fatal(err) 1771 } else if count := atomic.LoadInt32(&testAcquisitionBlockCount); count != 1 { 1772 t.Fatalf("expected 1 lease to be acquired, but acquired %d times", 1773 count) 1774 } 1775 1776 // Acquire a lease on test2 by ID. 1777 ts2, _, err := t.node(1).Acquire(ctx, t.server.Clock().Now(), test2Desc.ID) 1778 if err != nil { 1779 t.Fatal(err) 1780 } else if err := t.release(1, ts2); err != nil { 1781 t.Fatal(err) 1782 } else if count := atomic.LoadInt32(&testAcquisitionBlockCount); count != 2 { 1783 t.Fatalf("expected 2 leases to be acquired, but acquired %d times", 1784 count) 1785 } 1786 1787 // From now on henceforth do not acquire a lease, so any renewals can only 1788 // happen through the periodic lease renewal mechanism. 1789 1790 // Reset testAcquisitionBlockCount as the first acqusitions will always block. 1791 atomic.StoreInt32(&testAcquisitionBlockCount, 0) 1792 1793 // Check that lease acquisition happens independent of lease being requested. 1794 testutils.SucceedsSoon(t, func() error { 1795 if count := atomic.LoadInt32(&testAcquiredCount); count <= 4 { 1796 return errors.Errorf("expected more than 4 leases to be acquired, but acquired %d times", count) 1797 } 1798 1799 if count := numReleasedLeases(); count != 2 { 1800 return errors.Errorf("expected 2 leases to be releases, released %d", count) 1801 } 1802 return nil 1803 }) 1804 1805 // No blocked acquisitions. 1806 if blockCount := atomic.LoadInt32(&testAcquisitionBlockCount); blockCount > 0 { 1807 t.Fatalf("expected lease acquisition to not block, but blockCount is: %d", blockCount) 1808 } 1809 } 1810 1811 // TestReadBeforeDrop tests that a read over a table from a transaction 1812 // initiated before the table is dropped succeeds. 1813 func TestReadBeforeDrop(t *testing.T) { 1814 defer leaktest.AfterTest(t)() 1815 params, _ := tests.CreateTestServerParams() 1816 s, sqlDB, _ := serverutils.StartServer(t, params) 1817 defer s.Stopper().Stop(context.Background()) 1818 1819 if _, err := sqlDB.Exec(` 1820 CREATE DATABASE t; 1821 CREATE TABLE t.kv (k CHAR PRIMARY KEY, v CHAR); 1822 INSERT INTO t.kv VALUES ('a', 'b'); 1823 `); err != nil { 1824 t.Fatal(err) 1825 } 1826 // Test that once a table is dropped it cannot be used even when 1827 // a transaction is using a timestamp from the past. 1828 tx, err := sqlDB.Begin() 1829 if err != nil { 1830 t.Fatal(err) 1831 } 1832 1833 if _, err := sqlDB.Exec(`DROP TABLE t.kv`); err != nil { 1834 t.Fatal(err) 1835 } 1836 1837 rows, err := tx.Query(`SELECT * FROM t.kv`) 1838 if err != nil { 1839 t.Fatal(err) 1840 } 1841 defer rows.Close() 1842 1843 for rows.Next() { 1844 var k, v string 1845 err := rows.Scan(&k, &v) 1846 if err != nil { 1847 t.Fatal(err) 1848 } 1849 if k != "a" || v != "b" { 1850 t.Fatalf("didn't find expected row: %s %s", k, v) 1851 } 1852 } 1853 1854 if err := tx.Commit(); err != nil { 1855 t.Fatal(err) 1856 } 1857 } 1858 1859 // Tests that transactions with timestamps within the uncertainty interval 1860 // of a TABLE CREATE are pushed to allow them to observe the created table. 1861 func TestTableCreationPushesTxnsInRecentPast(t *testing.T) { 1862 defer leaktest.AfterTest(t)() 1863 params, _ := tests.CreateTestServerParams() 1864 tc := serverutils.StartTestCluster(t, 3, base.TestClusterArgs{ 1865 ReplicationMode: base.ReplicationManual, 1866 ServerArgs: params, 1867 }) 1868 defer tc.Stopper().Stop(context.Background()) 1869 sqlDB := tc.ServerConn(0) 1870 1871 if _, err := sqlDB.Exec(` 1872 CREATE DATABASE t; 1873 CREATE TABLE t.timestamp (k CHAR PRIMARY KEY, v CHAR); 1874 `); err != nil { 1875 t.Fatal(err) 1876 } 1877 1878 // Create a transaction before the table is created. 1879 tx, err := sqlDB.Begin() 1880 if err != nil { 1881 t.Fatal(err) 1882 } 1883 1884 // Create a transaction before the table is created. Use a different 1885 // node so that clock uncertainty is presumed and it gets pushed. 1886 tx1, err := tc.ServerConn(1).Begin() 1887 if err != nil { 1888 t.Fatal(err) 1889 } 1890 1891 if _, err := sqlDB.Exec(` 1892 CREATE TABLE t.kv (k CHAR PRIMARY KEY, v CHAR); 1893 `); err != nil { 1894 t.Fatal(err) 1895 } 1896 1897 // Was actually run in the past and so doesn't see the table. 1898 if _, err := tx.Exec(` 1899 INSERT INTO t.kv VALUES ('a', 'b'); 1900 `); !testutils.IsError(err, "does not exist") { 1901 t.Fatal(err) 1902 } 1903 1904 // Not sure whether run in the past and so sees clock uncertainty push. 1905 if _, err := tx1.Exec(` 1906 INSERT INTO t.kv VALUES ('c', 'd'); 1907 `); err != nil { 1908 t.Fatal(err) 1909 } 1910 1911 if err := tx.Rollback(); err != nil { 1912 t.Fatal(err) 1913 } 1914 1915 if err := tx1.Commit(); err != nil { 1916 t.Fatal(err) 1917 } 1918 } 1919 1920 // Tests that DeleteOrphanedLeases() deletes only orphaned leases. 1921 func TestDeleteOrphanedLeases(testingT *testing.T) { 1922 defer leaktest.AfterTest(testingT)() 1923 1924 params, _ := tests.CreateTestServerParams() 1925 params.Knobs = base.TestingKnobs{ 1926 SQLLeaseManager: &lease.ManagerTestingKnobs{}, 1927 } 1928 1929 ctx := context.Background() 1930 t := newLeaseTest(testingT, params) 1931 defer t.cleanup() 1932 1933 if _, err := t.db.Exec(` 1934 CREATE DATABASE t; 1935 CREATE TABLE t.before (k CHAR PRIMARY KEY, v CHAR); 1936 CREATE TABLE t.after (k CHAR PRIMARY KEY, v CHAR); 1937 `); err != nil { 1938 t.Fatal(err) 1939 } 1940 1941 beforeDesc := sqlbase.GetTableDescriptor(t.kvDB, keys.SystemSQLCodec, "t", "before") 1942 afterDesc := sqlbase.GetTableDescriptor(t.kvDB, keys.SystemSQLCodec, "t", "after") 1943 dbID := beforeDesc.ParentID 1944 1945 // Acquire a lease on "before" by name. 1946 beforeTable, _, err := t.node(1).AcquireByName( 1947 ctx, 1948 t.server.Clock().Now(), 1949 dbID, 1950 beforeDesc.GetParentSchemaID(), 1951 "before", 1952 ) 1953 if err != nil { 1954 t.Fatal(err) 1955 } else if err := t.release(1, beforeTable); err != nil { 1956 t.Fatal(err) 1957 } 1958 1959 // Assume server shuts down here and a new instance of the server starts up. 1960 // All leases created prior to this time are declared orphaned. 1961 now := timeutil.Now().UnixNano() 1962 1963 // Acquire a lease on "after" by name after server startup. 1964 afterTable, _, err := t.node(1).AcquireByName( 1965 ctx, 1966 t.server.Clock().Now(), 1967 dbID, 1968 afterDesc.GetParentSchemaID(), 1969 "after", 1970 ) 1971 if err != nil { 1972 t.Fatal(err) 1973 } else if err := t.release(1, afterTable); err != nil { 1974 t.Fatal(err) 1975 } 1976 t.expectLeases(beforeDesc.ID, "/1/1") 1977 t.expectLeases(afterDesc.ID, "/1/1") 1978 1979 // Call DeleteOrphanedLeases() with the server startup time. 1980 t.node(1).DeleteOrphanedLeases(now) 1981 // Orphaned lease is gone. 1982 t.expectLeases(beforeDesc.ID, "") 1983 t.expectLeases(afterDesc.ID, "/1/1") 1984 } 1985 1986 // Test that acquiring a lease doesn't block on other transactions performing 1987 // schema changes. Lease acquisitions run in high-priority transactions, thereby 1988 // pushing any locks held by schema-changing transactions out of their ways. 1989 func TestLeaseAcquisitionDoesntBlock(t *testing.T) { 1990 defer leaktest.AfterTest(t)() 1991 ctx := context.Background() 1992 params, _ := tests.CreateTestServerParams() 1993 s, db, _ := serverutils.StartServer(t, params) 1994 defer s.Stopper().Stop(ctx) 1995 1996 _, err := db.Exec(`CREATE DATABASE t; CREATE TABLE t.test(k CHAR PRIMARY KEY, v CHAR);`) 1997 require.NoError(t, err) 1998 1999 // Figure out the table ID. 2000 row := db.QueryRow("SELECT id FROM system.namespace WHERE name='test'") 2001 var descID sqlbase.ID 2002 require.NoError(t, row.Scan(&descID)) 2003 2004 // Spin up another goroutine performing a schema change. We'll suspend its 2005 // execution until the main goroutine is able to acquire its lease. 2006 schemaCh := make(chan error) 2007 schemaUnblock := make(chan struct{}) 2008 go func() { 2009 tx, err := db.BeginTx(ctx, nil) 2010 if err != nil { 2011 schemaCh <- err 2012 return 2013 } 2014 _, err = tx.Exec("ALTER TABLE t.test ADD COLUMN v2 CHAR") 2015 schemaCh <- err 2016 if err != nil { 2017 return 2018 } 2019 2020 <-schemaUnblock 2021 schemaCh <- tx.Commit() 2022 }() 2023 2024 require.NoError(t, <-schemaCh) 2025 2026 l, _, err := s.LeaseManager().(*lease.Manager).Acquire(ctx, s.Clock().Now(), descID) 2027 require.NoError(t, err) 2028 2029 // Release the lease so that the schema change can proceed. 2030 require.NoError(t, s.LeaseManager().(*lease.Manager).Release(l)) 2031 // Unblock the schema change. 2032 close(schemaUnblock) 2033 2034 // Wait for the schema change to finish. 2035 require.NoError(t, <-schemaCh) 2036 } 2037 2038 // Test that acquiring a lease doesn't block on other transactions performing 2039 // schema changes. This is similar to the previous test, except it acquires a 2040 // lease by table name instead of ID, and correspondingly the schema change 2041 // touches the namespace table. 2042 func TestLeaseAcquisitionByNameDoesntBlock(t *testing.T) { 2043 defer leaktest.AfterTest(t)() 2044 ctx := context.Background() 2045 params, _ := tests.CreateTestServerParams() 2046 s, db, _ := serverutils.StartServer(t, params) 2047 defer s.Stopper().Stop(ctx) 2048 2049 _, err := db.Exec(`CREATE DATABASE t`) 2050 require.NoError(t, err) 2051 2052 // Spin up another goroutine performing a schema change - creating a table. 2053 // We'll suspend its execution until the main goroutine is able to acquire its 2054 // lease. The idea is that, before being suspended, this transaction has put 2055 // down locks on the system.namespace table. The point of the test is to check 2056 // that a lease acquisition pushes these locks out of its way. 2057 schemaCh := make(chan error) 2058 schemaUnblock := make(chan struct{}) 2059 go func() { 2060 tx, err := db.BeginTx(ctx, nil) 2061 if err != nil { 2062 schemaCh <- err 2063 return 2064 } 2065 _, err = tx.Exec("CREATE TABLE t.test()") 2066 schemaCh <- err 2067 if err != nil { 2068 return 2069 } 2070 2071 <-schemaUnblock 2072 schemaCh <- tx.Commit() 2073 }() 2074 2075 require.NoError(t, <-schemaCh) 2076 _, err = db.Exec("SELECT * from t.test") 2077 require.Regexp(t, `pq: relation "t\.test" does not exist`, err) 2078 close(schemaUnblock) 2079 2080 // Wait for the schema change to finish. 2081 require.NoError(t, <-schemaCh) 2082 } 2083 2084 // TestIntentOnSystemConfigDoesNotPreventSchemaChange tests that failures to 2085 // gossip the system config due to intents are rectified when later intents 2086 // are aborted. 2087 func TestIntentOnSystemConfigDoesNotPreventSchemaChange(t *testing.T) { 2088 defer leaktest.AfterTest(t)() 2089 2090 ctx := context.Background() 2091 tc := testcluster.StartTestCluster(t, 1, base.TestClusterArgs{}) 2092 defer tc.Stopper().Stop(ctx) 2093 2094 db := tc.ServerConn(0) 2095 tdb := sqlutils.MakeSQLRunner(db) 2096 tdb.Exec(t, "CREATE TABLE foo (i INT PRIMARY KEY)") 2097 2098 connA, err := db.Conn(ctx) 2099 require.NoError(t, err) 2100 connB, err := db.Conn(ctx) 2101 require.NoError(t, err) 2102 2103 txA, err := connA.BeginTx(ctx, &gosql.TxOptions{}) 2104 require.NoError(t, err) 2105 txB, err := connB.BeginTx(ctx, &gosql.TxOptions{}) 2106 require.NoError(t, err) 2107 2108 // Lay down an intent on the system config span. 2109 _, err = txA.Exec("CREATE TABLE bar (i INT PRIMARY KEY)") 2110 require.NoError(t, err) 2111 2112 _, err = txB.Exec("ALTER TABLE foo ADD COLUMN j INT NOT NULL DEFAULT 2") 2113 require.NoError(t, err) 2114 2115 getFooVersion := func() (version int) { 2116 tx, err := db.Begin() 2117 require.NoError(t, err) 2118 // Prevent this transaction from blocking on intents. 2119 _, err = tx.Exec("SET TRANSACTION PRIORITY HIGH") 2120 require.NoError(t, err) 2121 require.NoError(t, tx.QueryRow( 2122 "SELECT version FROM crdb_internal.tables WHERE name = 'foo'"). 2123 Scan(&version)) 2124 require.NoError(t, tx.Commit()) 2125 return version 2126 } 2127 2128 // Fire off the commit. In order to return, the table descriptor will need 2129 // to make it through several versions. We wait until the version has been 2130 // incremented once before we rollback txA. 2131 origVersion := getFooVersion() 2132 errCh := make(chan error) 2133 go func() { errCh <- txB.Commit() }() 2134 testutils.SucceedsSoon(t, func() error { 2135 if got := getFooVersion(); got <= origVersion { 2136 return fmt.Errorf("got %d, expected greater", got) 2137 } 2138 return nil 2139 }) 2140 2141 // Roll back txA which had left an intent on the system config span which 2142 // prevented the leaseholders of origVersion of foo from being notified. 2143 // Ensure that those leaseholders are notified in a timely manner. 2144 require.NoError(t, txA.Rollback()) 2145 2146 const extremelyLongTime = 10 * time.Second 2147 select { 2148 case <-time.After(extremelyLongTime): 2149 t.Fatalf("schema change did not complete in %v", extremelyLongTime) 2150 case err := <-errCh: 2151 require.NoError(t, err) 2152 } 2153 } 2154 2155 // TestFinalizeVersionEnablesRangefeedUpdates ensures that gossip is used when 2156 // the version is initialized to something prior to VersionRangefeedLeases and 2157 // then that rangefeeds are adopted once that version is finalized. 2158 // 2159 // TODO(ajwerner): Remove this test in 21.1 as it is no longer relevant. 2160 func TestFinalizeVersionEnablesRangefeedUpdates(t *testing.T) { 2161 defer leaktest.AfterTest(t)() 2162 2163 // The test first starts a cluster at a version below VersionRangefeedLeases 2164 // and ensure that schema changes don't block for too long. Meanwhile ensure 2165 // that no rangefeed has been created on the system config span. Then finalize 2166 // the version upgrade and ensure that a rangefeed is created and that 2167 // schema changes still work. 2168 2169 ctx := context.Background() 2170 var rangefeedsCreated int64 2171 descriptorTablePrefix := keys.SystemSQLCodec.TablePrefix(keys.DescriptorTableID) 2172 descriptorTableSpan := roachpb.Span{ 2173 Key: descriptorTablePrefix, 2174 EndKey: descriptorTablePrefix.PrefixEnd(), 2175 } 2176 tc := testcluster.StartTestCluster(t, 2, base.TestClusterArgs{ 2177 ServerArgs: base.TestServerArgs{ 2178 Knobs: base.TestingKnobs{ 2179 SQLLeaseManager: &lease.ManagerTestingKnobs{ 2180 VersionPollIntervalForRangefeeds: time.Millisecond, 2181 }, 2182 Store: &kvserver.StoreTestingKnobs{ 2183 // Add a filter to detect the creation of a rangefeed over the 2184 // descriptor table. 2185 TestingRangefeedFilter: func( 2186 args *roachpb.RangeFeedRequest, _ roachpb.Internal_RangeFeedServer, 2187 ) *roachpb.Error { 2188 if args.Span.Overlaps(descriptorTableSpan) { 2189 atomic.AddInt64(&rangefeedsCreated, 1) 2190 } 2191 return nil 2192 }, 2193 }, 2194 Server: &server.TestingKnobs{ 2195 // We're going to manually control when the upgrade takes place below 2196 // so disable the automatic upgrade. 2197 DisableAutomaticVersionUpgrade: 1, 2198 // Bootstrap the cluster at something below VersionRangefeedLeases so 2199 // that we can test the upgrade. 2200 BootstrapVersionOverride: clusterversion.VersionByKey(clusterversion.Version20_1), 2201 }, 2202 }, 2203 }, 2204 }) 2205 defer tc.Stopper().Stop(ctx) 2206 2207 tdb := sqlutils.MakeSQLRunner(tc.ServerConn(0)) 2208 tdb.Exec(t, "CREATE TABLE foo (i INT PRIMARY KEY)") 2209 // Lease table foo on node 2. 2210 db2 := tc.ServerConn(1) 2211 var junk int 2212 require.EqualValues(t, gosql.ErrNoRows, db2.QueryRow("SELECT * FROM foo").Scan(&junk)) 2213 2214 // Run a schema change which will require a notification to finish. 2215 tdb.Exec(t, "ALTER TABLE foo ADD COLUMN j INT NOT NULL DEFAULT 2") 2216 require.Equal(t, int64(0), atomic.LoadInt64(&rangefeedsCreated)) 2217 2218 // Upgrade to after VersionRangefeedLeases and ensure that a rangefeed is created. 2219 tdb.Exec(t, "SET CLUSTER SETTING version = crdb_internal.node_executable_version();") 2220 testutils.SucceedsSoon(t, func() error { 2221 if atomic.LoadInt64(&rangefeedsCreated) == 0 { 2222 return errors.New("no rangefeeds created") 2223 } 2224 return nil 2225 }) 2226 tdb.Exec(t, "ALTER TABLE foo ADD COLUMN k INT NOT NULL DEFAULT 2") 2227 } 2228 2229 func ensureTestTakesLessThan(t *testing.T, allowed time.Duration) func() { 2230 start := timeutil.Now() 2231 return func() { 2232 if t.Failed() { 2233 return 2234 } 2235 if took := timeutil.Since(start); took > allowed { 2236 t.Fatalf("test took %v which is greater than %v", took, allowed) 2237 } 2238 } 2239 } 2240 2241 // TestRangefeedUpdatesHandledProperlyInTheFaceOfRaces deals with the case where 2242 // we have a request to lease a table descriptor, we read version 1 and prior to 2243 // adding that to the state, we get an update indicating that that version is 2244 // too old. 2245 func TestRangefeedUpdatesHandledProperlyInTheFaceOfRaces(t *testing.T) { 2246 defer leaktest.AfterTest(t)() 2247 defer ensureTestTakesLessThan(t, 30*time.Second)() 2248 2249 ctx := context.Background() 2250 var interestingTable atomic.Value 2251 interestingTable.Store(sqlbase.ID(0)) 2252 blockLeaseAcquisitionOfInterestingTable := make(chan chan struct{}) 2253 unblockAll := make(chan struct{}) 2254 args := base.TestServerArgs{ 2255 Knobs: base.TestingKnobs{ 2256 SQLLeaseManager: &lease.ManagerTestingKnobs{ 2257 AlwaysUseRangefeeds: true, 2258 }, 2259 }, 2260 } 2261 tc := testcluster.StartTestCluster(t, 1, base.TestClusterArgs{ 2262 ServerArgs: args, 2263 }) 2264 tableUpdateChan := make(chan *sqlbase.TableDescriptor) 2265 args.Knobs.SQLLeaseManager = &lease.ManagerTestingKnobs{ 2266 TestingTableUpdateEvent: func(table *sqlbase.TableDescriptor) error { 2267 // Use this testing knob to ensure that we see an update for the table 2268 // in question. We don't care about events to refresh the first version 2269 // which can happen under rare stress scenarios. 2270 if table.ID == interestingTable.Load().(sqlbase.ID) && table.Version >= 2 { 2271 select { 2272 case tableUpdateChan <- table: 2273 case <-unblockAll: 2274 } 2275 } 2276 return nil 2277 }, 2278 LeaseStoreTestingKnobs: lease.StorageTestingKnobs{ 2279 LeaseAcquiredEvent: func(table sqlbase.TableDescriptor, err error) { 2280 // Block the lease acquisition for the table after the leasing 2281 // transaction has been issued. We'll wait to unblock it until after 2282 // the new version has been published and that even has been received. 2283 if table.ID != interestingTable.Load().(sqlbase.ID) { 2284 return 2285 } 2286 blocked := make(chan struct{}) 2287 select { 2288 case blockLeaseAcquisitionOfInterestingTable <- blocked: 2289 <-blocked 2290 case <-unblockAll: 2291 } 2292 }, 2293 }, 2294 } 2295 // Start a second server with our knobs. 2296 tc.AddServer(t, args) 2297 defer tc.Stopper().Stop(ctx) 2298 2299 db1 := tc.ServerConn(0) 2300 tdb1 := sqlutils.MakeSQLRunner(db1) 2301 db2 := tc.ServerConn(1) 2302 2303 // Create a couple of tables. 2304 tdb1.Exec(t, "CREATE TABLE foo (i INT PRIMARY KEY)") 2305 2306 // Find the table ID for the table we'll be mucking with. 2307 var tableID sqlbase.ID 2308 tdb1.QueryRow(t, "SELECT table_id FROM crdb_internal.tables WHERE name = $1 AND database_name = current_database()", 2309 "foo").Scan(&tableID) 2310 interestingTable.Store(tableID) 2311 2312 // Launch a goroutine to query foo. It will be blocked in lease acquisition. 2313 selectDone := make(chan error) 2314 go func() { 2315 var count int 2316 selectDone <- db2.QueryRow("SELECT count(*) FROM foo").Scan(&count) 2317 }() 2318 2319 // Make sure it got blocked. 2320 toUnblockForLeaseAcquisition := <-blockLeaseAcquisitionOfInterestingTable 2321 2322 // Launch a goroutine to perform a schema change which will lead to new 2323 // versions. 2324 alterErrCh := make(chan error) 2325 go func() { 2326 _, err := db1.Exec("ALTER TABLE foo ADD COLUMN j INT DEFAULT 1") 2327 alterErrCh <- err 2328 }() 2329 2330 // Make sure we get an update. Note that this is after we have already 2331 // acquired a lease on the old version but have not yet recorded that fact. 2332 table := <-tableUpdateChan 2333 require.Equal(t, sqlbase.DescriptorVersion(2), table.Version) 2334 2335 // Allow the original lease acquisition to proceed. 2336 close(toUnblockForLeaseAcquisition) 2337 2338 // Ensure the query completes. 2339 <-selectDone 2340 2341 // Allow everything to proceed as usual. 2342 close(unblockAll) 2343 // Ensure the schema change completes. 2344 <-alterErrCh 2345 2346 // Ensure that the new schema is in use on n2. 2347 var i, j int 2348 require.Equal(t, gosql.ErrNoRows, db2.QueryRow("SELECT i, j FROM foo").Scan(&i, &j)) 2349 }