Skip to content

Commit 487492d

Browse files
authored
tso: Fix keyspace-group split causing keyspace to fallback to group 0 (#9823)
close #9822 Signed-off-by: ystaticy <y_static_y@sina.com>
1 parent 33d00c5 commit 487492d

File tree

3 files changed

+30
-6
lines changed

3 files changed

+30
-6
lines changed

pkg/keyspace/tso_keyspace_group.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -587,9 +587,6 @@ func (m *GroupManager) SplitKeyspaceGroupByID(
587587
splitSourceKg.SplitState = &endpoint.SplitState{
588588
SplitSource: splitSourceKg.ID,
589589
}
590-
if err = m.store.SaveKeyspaceGroup(txn, splitSourceKg); err != nil {
591-
return err
592-
}
593590
splitTargetKg = &endpoint.KeyspaceGroup{
594591
ID: splitTargetID,
595592
// Keep the same user kind and members as the old keyspace group.
@@ -600,8 +597,18 @@ func (m *GroupManager) SplitKeyspaceGroupByID(
600597
SplitSource: splitSourceKg.ID,
601598
},
602599
}
600+
// Save the split target keyspace group first, then save the split source keyspace group.
601+
// The order matters: if we save splitSourceKg first (which removes some keyspaces from it),
602+
// there will be a brief moment where those keyspaces don't belong to any group, causing
603+
// them to fallback to group 0. By saving splitTargetKg first (which contains the split
604+
// keyspaces), we ensure the keyspaces always belong to a valid group during the transition.
605+
603606
// Create the new split keyspace group.
604-
return m.store.SaveKeyspaceGroup(txn, splitTargetKg)
607+
if err = m.store.SaveKeyspaceGroup(txn, splitTargetKg); err != nil {
608+
return err
609+
}
610+
// Update the source keyspace group.
611+
return m.store.SaveKeyspaceGroup(txn, splitSourceKg)
605612
}); err != nil {
606613
return err
607614
}
@@ -611,9 +618,9 @@ func (m *GroupManager) SplitKeyspaceGroupByID(
611618
return nil
612619
}
613620

621+
// `old` is the original keyspace list which will be split out,
622+
// `new` is the keyspace list which will be split from the old keyspace list.
614623
func buildSplitKeyspaces(
615-
// `old` is the original keyspace list which will be split out,
616-
// `new` is the keyspace list which will be split from the old keyspace list.
617624
old, new []uint32,
618625
startKeyspaceID, endKeyspaceID uint32,
619626
) (oldSplit, newSplit []uint32, err error) {

pkg/tso/keyspace_group_manager.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,16 @@ func (kgm *KeyspaceGroupManager) updateKeyspaceGroup(group *endpoint.KeyspaceGro
686686
kgm.metrics.mergeTargetGauge.Dec()
687687
}
688688

689+
failpoint.Inject("delayBeforeCheckingElectionMember", func() {
690+
if oldAM == nil && (group.IsSplitTarget() || group.IsSplitSource()) {
691+
log.Info("INJECTED DELAY before update the keyspace group",
692+
zap.Uint32("target-group-id", group.ID),
693+
zap.Uint32("source-group-id", group.SplitState.SplitSource),
694+
zap.Int("keyspaces-count", len(group.Keyspaces)))
695+
time.Sleep(10 * time.Second) // Adjust this to match client query timing
696+
}
697+
})
698+
689699
// If this host is already assigned a replica of this keyspace group, i.e., the member
690700
// is already initialized, just update the meta.
691701
if oldAM != nil {

tests/integrations/mcs/tso/keyspace_group_manager_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,13 @@ func (suite *tsoKeyspaceGroupManagerTestSuite) TestTSOKeyspaceGroupSplitClient()
409409
re := suite.Require()
410410
// Enable the failpoint to slow down the system time to test whether the TSO is monotonic.
411411
re.NoError(failpoint.Enable("github.com/tikv/pd/pkg/tso/systemTimeSlow", `return(true)`))
412+
413+
// Enable the failpoint to delay before checking election member
414+
re.NoError(failpoint.Enable("github.com/tikv/pd/pkg/tso/delayBeforeCheckingElectionMember", `return()`))
415+
defer func() {
416+
re.NoError(failpoint.Disable("github.com/tikv/pd/pkg/tso/delayBeforeCheckingElectionMember"))
417+
}()
418+
412419
// Create the keyspace group `oldID` with keyspaces [777, 888, 999].
413420
oldID := suite.allocID()
414421
handlersutil.MustCreateKeyspaceGroup(re, suite.pdLeaderServer, &handlers.CreateKeyspaceGroupParams{

0 commit comments

Comments
 (0)