@@ -378,7 +378,10 @@ func testScheduler(t *testing.T) {
378
378
ALTER TABLE t2_test ENGINE=InnoDB;
379
379
`
380
380
instantAlterT1Statement = `
381
- ALTER TABLE t1_test ADD COLUMN i0 INT NOT NULL DEFAULT 0;
381
+ ALTER TABLE t1_test ADD COLUMN i0 INT NOT NULL DEFAULT 0
382
+ `
383
+ instantUndoAlterT1Statement = `
384
+ ALTER TABLE t1_test DROP COLUMN i0
382
385
`
383
386
dropT1Statement = `
384
387
DROP TABLE IF EXISTS t1_test
@@ -399,7 +402,7 @@ func testScheduler(t *testing.T) {
399
402
ALTER TABLE nonexistent FORCE
400
403
`
401
404
populateT1Statement = `
402
- insert into t1_test values (1, 'new_row')
405
+ insert ignore into t1_test values (1, 'new_row')
403
406
`
404
407
)
405
408
@@ -792,6 +795,64 @@ func testScheduler(t *testing.T) {
792
795
})
793
796
})
794
797
}
798
+
799
+ if forceCutoverCapable {
800
+ t .Run ("force_cutover_instant" , func (t * testing.T ) {
801
+ ctx , cancel := context .WithTimeout (context .Background (), extendedWaitTime * 5 )
802
+ defer cancel ()
803
+
804
+ t .Run ("populate t1_test" , func (t * testing.T ) {
805
+ onlineddl .VtgateExecQuery (t , & vtParams , populateT1Statement , "" )
806
+ })
807
+
808
+ commitTransactionChan := make (chan any )
809
+ transactionErrorChan := make (chan error )
810
+ t .Run ("locking table rows" , func (t * testing.T ) {
811
+ go runInTransaction (t , ctx , primaryTablet , "select * from t1_test for update" , commitTransactionChan , transactionErrorChan )
812
+ })
813
+
814
+ t .Run ("execute migration" , func (t * testing.T ) {
815
+ t1uuid = testOnlineDDLStatement (t , createParams (instantAlterT1Statement , ddlStrategy + " --prefer-instant-ddl --force-cut-over-after=1ms" , "vtgate" , "" , "" , true )) // skip wait
816
+ })
817
+ t .Run ("expect completion" , func (t * testing.T ) {
818
+ status := onlineddl .WaitForMigrationStatus (t , & vtParams , shards , t1uuid , normalWaitTime , schema .OnlineDDLStatusComplete , schema .OnlineDDLStatusFailed )
819
+ fmt .Printf ("# Migration status (for debug purposes): <%s>\n " , status )
820
+ onlineddl .CheckMigrationStatus (t , & vtParams , shards , t1uuid , schema .OnlineDDLStatusComplete )
821
+ })
822
+ t .Run ("check special_plan" , func (t * testing.T ) {
823
+ rs := onlineddl .ReadMigrations (t , & vtParams , t1uuid )
824
+ require .NotNil (t , rs )
825
+ for _ , row := range rs .Named ().Rows {
826
+ specialPlan := row .AsString ("special_plan" , "" )
827
+ assert .Contains (t , specialPlan , "instant-ddl" )
828
+ }
829
+ })
830
+ t .Run ("expect transaction failure" , func (t * testing.T ) {
831
+ select {
832
+ case commitTransactionChan <- true : // good
833
+ case <- ctx .Done ():
834
+ assert .Fail (t , ctx .Err ().Error ())
835
+ }
836
+ // Transaction will now attempt to commit. But we expect our "force_cutover" to have terminated
837
+ // the transaction's connection.
838
+ select {
839
+ case err := <- transactionErrorChan :
840
+ assert .ErrorContains (t , err , "broken pipe" )
841
+ case <- ctx .Done ():
842
+ assert .Fail (t , ctx .Err ().Error ())
843
+ }
844
+ })
845
+ t .Run ("cleanup: undo migration" , func (t * testing.T ) {
846
+ t1uuid = testOnlineDDLStatement (t , createParams (instantUndoAlterT1Statement , ddlStrategy + " --prefer-instant-ddl --force-cut-over-after=1ms" , "vtgate" , "" , "" , true )) // skip wait
847
+ })
848
+ t .Run ("cleanup: expect completion" , func (t * testing.T ) {
849
+ status := onlineddl .WaitForMigrationStatus (t , & vtParams , shards , t1uuid , normalWaitTime , schema .OnlineDDLStatusComplete , schema .OnlineDDLStatusFailed )
850
+ fmt .Printf ("# Migration status (for debug purposes): <%s>\n " , status )
851
+ onlineddl .CheckMigrationStatus (t , & vtParams , shards , t1uuid , schema .OnlineDDLStatusComplete )
852
+ })
853
+ })
854
+ }
855
+
795
856
t .Run ("ALTER both tables non-concurrent" , func (t * testing.T ) {
796
857
t1uuid = testOnlineDDLStatement (t , createParams (trivialAlterT1Statement , ddlStrategy , "vtgate" , "" , "" , true )) // skip wait
797
858
t2uuid = testOnlineDDLStatement (t , createParams (trivialAlterT2Statement , ddlStrategy , "vtgate" , "" , "" , true )) // skip wait
0 commit comments