@@ -612,7 +612,7 @@ func TestRescheduleJobsAfterTableDropped(t *testing.T) {
612
612
tk .MustExec (rb .resume )
613
613
table , err = dom .InfoSchema ().TableByName (context .Background (), pmodel .NewCIStr ("test" ), pmodel .NewCIStr ("t" ))
614
614
require .NoError (t , err )
615
- m .DoGC (context .TODO (), se )
615
+ m .DoGC (context .TODO (), se , now )
616
616
}
617
617
}
618
618
@@ -775,7 +775,7 @@ func TestGCScanTasks(t *testing.T) {
775
775
return true
776
776
})
777
777
se := session .NewSession (tk .Session (), tk .Session (), func (_ session.Session ) {})
778
- m .DoGC (context .TODO (), se )
778
+ m .DoGC (context .TODO (), se , se . Now () )
779
779
tk .MustQuery ("select job_id, scan_id from mysql.tidb_ttl_task order by job_id, scan_id asc" ).Check (testkit .Rows ("1 1" , "1 2" ))
780
780
}
781
781
@@ -794,7 +794,7 @@ func TestGCTableStatus(t *testing.T) {
794
794
return true
795
795
})
796
796
se := session .NewSession (tk .Session (), tk .Session (), func (_ session.Session ) {})
797
- m .DoGC (context .TODO (), se )
797
+ m .DoGC (context .TODO (), se , se . Now () )
798
798
tk .MustQuery ("select * from mysql.tidb_ttl_table_status" ).Check (nil )
799
799
800
800
// insert a running table status without corresponding table
@@ -808,7 +808,7 @@ func TestGCTableStatus(t *testing.T) {
808
808
current_job_ttl_expire = NOW(),
809
809
current_job_owner_hb_time = NOW()
810
810
WHERE table_id = ?` , 1 , 2024 )
811
- m .DoGC (context .TODO (), se )
811
+ m .DoGC (context .TODO (), se , se . Now () )
812
812
// it'll not be removed
813
813
tk .MustQuery ("select current_job_id from mysql.tidb_ttl_table_status" ).Check (testkit .Rows ("1" ))
814
814
}
@@ -855,7 +855,7 @@ func TestGCTTLHistory(t *testing.T) {
855
855
return true
856
856
})
857
857
se := session .NewSession (tk .Session (), tk .Session (), func (_ session.Session ) {})
858
- m .DoGC (context .TODO (), se )
858
+ m .DoGC (context .TODO (), se , se . Now () )
859
859
tk .MustQuery ("select job_id from mysql.tidb_ttl_job_history order by job_id asc" ).Check (testkit .Rows ("1" , "2" , "3" , "4" , "5" ))
860
860
}
861
861
@@ -1475,27 +1475,93 @@ func TestDisableTTLAfterLoseHeartbeat(t *testing.T) {
1475
1475
1476
1476
ctx := context .Background ()
1477
1477
m1 := ttlworker .NewJobManager ("test-ttl-job-manager-1" , nil , store , nil , nil )
1478
- require .NoError (t , m1 .InfoSchemaCache ().Update (se ))
1479
- require .NoError (t , m1 .TableStatusCache ().Update (ctx , se ))
1478
+ m2 := ttlworker .NewJobManager ("test-ttl-job-manager-2" , nil , store , nil , nil )
1480
1479
1481
1480
now := se .Now ()
1482
- _ , err = m1 .LockJob (context .Background (), se , m1 .InfoSchemaCache ().Tables [testTable .Meta ().ID ], now , uuid .NewString (), false )
1483
- require .NoError (t , err )
1484
- tk .MustQuery ("select current_job_status from mysql.tidb_ttl_table_status" ).Check (testkit .Rows ("running" ))
1485
1481
1486
- // lose heartbeat. Simulate the situation that m1 doesn't update the hearbeat for 8 hours.
1487
- now = now .Add (time .Hour * 8 )
1482
+ acquireJob := func (now time.Time ) {
1483
+ require .NoError (t , m1 .InfoSchemaCache ().Update (se ))
1484
+ require .NoError (t , m1 .TableStatusCache ().Update (ctx , se ))
1485
+ require .NoError (t , m2 .InfoSchemaCache ().Update (se ))
1486
+ require .NoError (t , m2 .TableStatusCache ().Update (ctx , se ))
1487
+ _ , err = m1 .LockJob (context .Background (), se , m1 .InfoSchemaCache ().Tables [testTable .Meta ().ID ], now , uuid .NewString (), false )
1488
+ require .NoError (t , err )
1489
+ tk .MustQuery ("select current_job_status from mysql.tidb_ttl_table_status" ).Check (testkit .Rows ("running" ))
1490
+ }
1491
+ t .Run ("disable TTL globally after losing heartbeat" , func (t * testing.T ) {
1492
+ // now the TTL job should be scheduled again
1493
+ now = now .Add (time .Hour * 8 )
1494
+ acquireJob (now )
1488
1495
1489
- // stop the tidb_ttl_job_enable
1490
- tk .MustExec ("set global tidb_ttl_job_enable = 'OFF'" )
1491
- defer tk .MustExec ("set global tidb_ttl_job_enable = 'ON'" )
1496
+ // lose heartbeat. Simulate the situation that m1 doesn't update the hearbeat for 8 hours.
1497
+ now = now .Add (time .Hour * 8 )
1492
1498
1493
- // reschedule and try to get the job
1494
- m2 := ttlworker .NewJobManager ("test-ttl-job-manager-2" , nil , store , nil , nil )
1495
- require .NoError (t , m2 .InfoSchemaCache ().Update (se ))
1496
- require .NoError (t , m2 .TableStatusCache ().Update (ctx , se ))
1497
- m2 .RescheduleJobs (se , now )
1499
+ // stop the tidb_ttl_job_enable
1500
+ tk .MustExec ("set global tidb_ttl_job_enable = 'OFF'" )
1501
+ defer tk .MustExec ("set global tidb_ttl_job_enable = 'ON'" )
1502
+
1503
+ // reschedule and try to get the job
1504
+ require .NoError (t , m2 .InfoSchemaCache ().Update (se ))
1505
+ require .NoError (t , m2 .TableStatusCache ().Update (ctx , se ))
1506
+ m2 .RescheduleJobs (se , now )
1507
+
1508
+ // the job should have been cancelled
1509
+ tk .MustQuery ("select current_job_status from mysql.tidb_ttl_table_status" ).Check (testkit .Rows ("<nil>" ))
1510
+ })
1511
+
1512
+ t .Run ("disable TTL for a table after losing heartbeat" , func (t * testing.T ) {
1513
+ // now the TTL job should be scheduled again
1514
+ now = now .Add (time .Hour * 8 )
1515
+ acquireJob (now )
1498
1516
1499
- // the job should have been cancelled
1500
- tk .MustQuery ("select current_job_status from mysql.tidb_ttl_table_status" ).Check (testkit .Rows ("<nil>" ))
1517
+ // lose heartbeat. Simulate the situation that m1 doesn't update the hearbeat for 8 hours.
1518
+ now = now .Add (time .Hour * 8 )
1519
+
1520
+ tk .MustExec ("ALTER TABLE t TTL_ENABLE = 'OFF'" )
1521
+ defer tk .MustExec ("ALTER TABLE t TTL_ENABLE = 'ON'" )
1522
+
1523
+ // reschedule and try to get the job
1524
+ require .NoError (t , m2 .InfoSchemaCache ().Update (se ))
1525
+ require .NoError (t , m2 .TableStatusCache ().Update (ctx , se ))
1526
+ m2 .RescheduleJobs (se , now )
1527
+
1528
+ // the job cannot be cancelled, because it doesn't exist in the infoschema cache.
1529
+ tk .MustQuery ("select current_job_status from mysql.tidb_ttl_table_status" ).Check (testkit .Rows ("running" ))
1530
+
1531
+ // run GC
1532
+ m2 .DoGC (ctx , se , now )
1533
+
1534
+ // the job should have been cancelled
1535
+ tk .MustQuery ("select current_job_status, current_job_owner_hb_time from mysql.tidb_ttl_table_status" ).Check (testkit .Rows ())
1536
+ })
1537
+
1538
+ t .Run ("drop a TTL table after losing heartbeat" , func (t * testing.T ) {
1539
+ // now the TTL job should be scheduled again
1540
+ now = now .Add (time .Hour * 8 )
1541
+ acquireJob (now )
1542
+
1543
+ // lose heartbeat. Simulate the situation that m1 doesn't update the hearbeat for 8 hours.
1544
+ now = now .Add (time .Hour * 8 )
1545
+
1546
+ tk .MustExec ("DROP TABLE t" )
1547
+ defer func () {
1548
+ tk .MustExec ("CREATE TABLE t (id INT PRIMARY KEY, created_at DATETIME) TTL = created_at + INTERVAL 1 HOUR" )
1549
+ testTable , err = dom .InfoSchema ().TableByName (context .Background (), pmodel .NewCIStr ("test" ), pmodel .NewCIStr ("t" ))
1550
+ require .NoError (t , err )
1551
+ }()
1552
+
1553
+ // reschedule and try to get the job
1554
+ require .NoError (t , m2 .InfoSchemaCache ().Update (se ))
1555
+ require .NoError (t , m2 .TableStatusCache ().Update (ctx , se ))
1556
+ m2 .RescheduleJobs (se , now )
1557
+
1558
+ // the job cannot be cancelled, because it doesn't exist in the infoschema cache.
1559
+ tk .MustQuery ("select current_job_status from mysql.tidb_ttl_table_status" ).Check (testkit .Rows ("running" ))
1560
+
1561
+ // run GC
1562
+ m2 .DoGC (ctx , se , now )
1563
+
1564
+ // the job should have been cancelled
1565
+ tk .MustQuery ("select current_job_status, current_job_owner_hb_time from mysql.tidb_ttl_table_status" ).Check (testkit .Rows ())
1566
+ })
1501
1567
}
0 commit comments