@@ -53,6 +53,7 @@ import (
5353 "github.com/dolthub/dolt/go/libraries/doltcore/sqle"
5454 "github.com/dolthub/dolt/go/libraries/doltcore/sqle/clusterdb"
5555 "github.com/dolthub/dolt/go/libraries/doltcore/sqle/dsess"
56+ "github.com/dolthub/dolt/go/libraries/doltcore/sqle/globalstate"
5657 "github.com/dolthub/dolt/go/libraries/utils/config"
5758 "github.com/dolthub/dolt/go/libraries/utils/filesys"
5859 "github.com/dolthub/dolt/go/libraries/utils/jwtauth"
@@ -930,6 +931,12 @@ func (c *Controller) immediateTransitionToStandby() error {
930931func (c * Controller ) transitionToPrimary (saveConnID int ) error {
931932 c .setProviderIsStandby (false )
932933 c .killRunningQueries (saveConnID )
934+ // Promotion: ensure next AUTO_INCREMENT values do not reuse existing IDs.
935+ // Refresh trackers for databases already loaded in this session so first
936+ // writes on the new primary allocate IDs at or above current table maxima.
937+ if err := c .refreshAutoIncrementTrackersForSessionDatabases (); err != nil {
938+ return err
939+ }
933940 return nil
934941}
935942
@@ -947,6 +954,69 @@ func (c *Controller) killRunningQueries(saveConnID int) {
947954 }
948955}
949956
957+ // refreshAutoIncrementTrackersForSessionDatabases re-initializes AUTO_INCREMENT
958+ // trackers for databases already loaded in the current session by using their
959+ // working sets. This immediately aligns in-memory sequences with replicated
960+ // table metadata after a promotion so the first post-promotion inserts do not
961+ // reuse primary keys. This method only refreshes session-known databases; any
962+ // database not yet loaded is skipped here and its tracker initializes lazily on
963+ // first use. Only working sets are read; branches and remotes are not scanned
964+ // as part of this promotion path.
965+ func (c * Controller ) refreshAutoIncrementTrackersForSessionDatabases () error {
966+ if c == nil || c .sqlCtxFactory == nil {
967+ return fmt .Errorf ("cluster/controller: auto-inc refresh: missing sql context factory" )
968+ }
969+
970+ // Create a SQL context to access session and provider
971+ sqlCtx , err := c .sqlCtxFactory (context .Background ())
972+ if err != nil {
973+ return fmt .Errorf ("cluster/controller: auto-inc refresh: create sql context: %w" , err )
974+ }
975+ // Ensure proper session lifecycle for any storage-layer ops
976+ defer sql .SessionEnd (sqlCtx .Session )
977+ sql .SessionCommandBegin (sqlCtx .Session )
978+ defer sql .SessionCommandEnd (sqlCtx .Session )
979+
980+ sess := dsess .DSessFromSess (sqlCtx .Session )
981+ provider := sess .Provider ()
982+
983+ for _ , sdb := range provider .DoltDatabases () {
984+ name := sdb .Name ()
985+ if name == clusterdb .DoltClusterDbName {
986+ continue
987+ }
988+
989+ // Load DB and its AI tracker
990+ db , err := provider .Database (sqlCtx , name )
991+ if err != nil {
992+ return fmt .Errorf ("cluster/controller: auto-inc refresh: %s: provider db: %w" , name , err )
993+ }
994+ gsp , ok := db .(globalstate.GlobalStateProvider )
995+ if ! ok {
996+ // Non-versioned DBs don't participate in AUTO_INCREMENT global state
997+ continue
998+ }
999+ ai , err := gsp .GetGlobalState ().AutoIncrementTracker (sqlCtx )
1000+ if err != nil {
1001+ return fmt .Errorf ("cluster/controller: auto-inc refresh: %s: tracker: %w" , name , err )
1002+ }
1003+
1004+ // Get working set roots only
1005+ state , ok , err := sess .LookupDbState (sqlCtx , name )
1006+ if err != nil {
1007+ return fmt .Errorf ("cluster/controller: auto-inc refresh: %s: lookup db state: %w" , name , err )
1008+ }
1009+ if ! ok || state .WorkingSet () == nil {
1010+ // Not loaded in session; defer to lazy initialization on first use
1011+ continue
1012+ }
1013+ if err := ai .InitWithRoots (sqlCtx , state .WorkingSet ()); err != nil {
1014+ return fmt .Errorf ("cluster/controller: auto-inc refresh: %s: init: %w" , name , err )
1015+ }
1016+ }
1017+ return nil
1018+ }
1019+
9501020// called with c.mu held
9511021func (c * Controller ) setProviderIsStandby (standby bool ) {
9521022 if c .standbyCallback != nil {
0 commit comments