@@ -17,14 +17,25 @@ import (
1717 "github.com/cockroachdb/cockroach/pkg/util/syncutil"
1818)
1919
20+ // supportState contains state pertaining to support provided to a single remote
21+ // store.
22+ type supportState struct {
23+ // SupportState contains all fields that must be persisted to disk.
24+ slpb.SupportState
25+
26+ // lastSupportWithdrawnTime is the timestamp at which support was last
27+ // withdrawn for the remote store.
28+ lastSupportWithdrawnTime hlc.Timestamp
29+ }
30+
2031// supporterState stores the core data structures for providing support.
2132type supporterState struct {
2233 // meta stores the SupporterMeta, including the max timestamp at which this
2334 // store has withdrawn support.
2435 meta slpb.SupporterMeta
25- // supportFor stores the SupportState for each remote store for which this
36+ // supportFor stores the supportState for each remote store for which this
2637 // store has provided support.
27- supportFor map [slpb.StoreIdent ]slpb. SupportState
38+ supportFor map [slpb.StoreIdent ]supportState
2839}
2940
3041// supporterStateHandler is the main interface for handling support for other
@@ -64,15 +75,15 @@ func newSupporterStateHandler() *supporterStateHandler {
6475 ssh := & supporterStateHandler {
6576 supporterState : supporterState {
6677 meta : slpb.SupporterMeta {},
67- supportFor : make (map [slpb.StoreIdent ]slpb. SupportState ),
78+ supportFor : make (map [slpb.StoreIdent ]supportState ),
6879 },
6980 }
7081 ssh .update .Store (
7182 & supporterStateForUpdate {
7283 checkedIn : & ssh .supporterState ,
7384 inProgress : supporterState {
7485 meta : slpb.SupporterMeta {},
75- supportFor : make (map [slpb.StoreIdent ]slpb. SupportState ),
86+ supportFor : make (map [slpb.StoreIdent ]supportState ),
7687 },
7788 },
7889 )
@@ -101,7 +112,7 @@ type supporterStateForUpdate struct {
101112func (ssh * supporterStateHandler ) getSupportFor (id slpb.StoreIdent ) slpb.SupportState {
102113 ssh .mu .RLock ()
103114 defer ssh .mu .RUnlock ()
104- return ssh .supporterState .supportFor [id ]
115+ return ssh .supporterState .supportFor [id ]. SupportState
105116}
106117
107118// getNumSupportFor returns the size of the supporterState.supportFor map.
@@ -111,16 +122,19 @@ func (ssh *supporterStateHandler) getNumSupportFor() int {
111122 return len (ssh .supporterState .supportFor )
112123}
113124
114- // exportAllSupportFor exports a copy of all SupportStates from the
125+ // exportAllSupportFor exports a copy of all InspectSupportForStates from the
115126// supporterState.supportFor map.
116- func (ssh * supporterStateHandler ) exportAllSupportFor () []slpb.SupportState {
127+ func (ssh * supporterStateHandler ) exportAllSupportFor () []slpb.InspectSupportForState {
117128 ssh .mu .RLock ()
118129 defer ssh .mu .RUnlock ()
119- supportStates := make ([]slpb.SupportState , len (ssh .supporterState .supportFor ))
130+ supportForStates := make ([]slpb.InspectSupportForState , 0 , len (ssh .supporterState .supportFor ))
120131 for _ , ss := range ssh .supporterState .supportFor {
121- supportStates = append (supportStates , ss )
132+ supportForStates = append (supportForStates , slpb.InspectSupportForState {
133+ SupportState : ss .SupportState ,
134+ LastSupportWithdrawnTime : ss .lastSupportWithdrawnTime ,
135+ })
122136 }
123- return supportStates
137+ return supportForStates
124138}
125139
126140// Functions for handling supporterState updates.
@@ -146,13 +160,11 @@ func (ssfu *supporterStateForUpdate) getMeta() slpb.SupporterMeta {
146160 return ssfu .checkedIn .meta
147161}
148162
149- // getSupportFor returns the SupportState from the inProgress view; if not
150- // present, it falls back to the SupportState from the checkedIn view.
163+ // getSupportFor returns the supportState from the inProgress view; if not
164+ // present, it falls back to the supportState from the checkedIn view.
151165// The returned boolean indicates whether the store is present in the supportFor
152166// map; it does NOT indicate whether support is provided.
153- func (ssfu * supporterStateForUpdate ) getSupportFor (
154- storeID slpb.StoreIdent ,
155- ) (slpb.SupportState , bool ) {
167+ func (ssfu * supporterStateForUpdate ) getSupportFor (storeID slpb.StoreIdent ) (supportState , bool ) {
156168 ss , ok := ssfu .inProgress .supportFor [storeID ]
157169 if ! ok {
158170 ss , ok = ssfu .checkedIn .supportFor [storeID ]
@@ -180,7 +192,8 @@ func (ssfu *supporterStateForUpdate) write(ctx context.Context, b storage.Batch)
180192 }
181193 }
182194 for _ , ss := range ssfu .inProgress .supportFor {
183- if err := writeSupportForState (ctx , b , ss ); err != nil {
195+ // Only write the persistent SupportState to disk.
196+ if err := writeSupportForState (ctx , b , ss .SupportState ); err != nil {
184197 return err
185198 }
186199 }
@@ -201,9 +214,9 @@ func (ssh *supporterStateHandler) read(ctx context.Context, r storage.Reader) er
201214 ssh .mu .Lock ()
202215 defer ssh .mu .Unlock ()
203216 ssh .supporterState .meta = meta
204- ssh .supporterState .supportFor = make (map [slpb.StoreIdent ]slpb. SupportState , len (supportFor ))
217+ ssh .supporterState .supportFor = make (map [slpb.StoreIdent ]supportState , len (supportFor ))
205218 for _ , s := range supportFor {
206- ssh .supporterState .supportFor [s .Target ] = s
219+ ssh .supporterState .supportFor [s .Target ] = supportState { SupportState : s }
207220 }
208221 return nil
209222}
@@ -256,12 +269,15 @@ func (ssfu *supporterStateForUpdate) handleHeartbeat(
256269 from := msg .From
257270 ss , ok := ssfu .getSupportFor (from )
258271 if ! ok {
259- ss = slpb.SupportState {Target : from }
272+ ss = supportState { SupportState : slpb.SupportState {Target : from } }
260273 }
261274 ssNew := handleHeartbeat (ss , msg )
275+ assert (ss .lastSupportWithdrawnTime == ssNew .lastSupportWithdrawnTime ,
276+ "lastSupportWithdrawnTime changed on successful heartbeat" ,
277+ )
262278 if ss != ssNew {
263279 ssfu .inProgress .supportFor [from ] = ssNew
264- logSupportForChange (ctx , ss , ssNew )
280+ logSupportForChange (ctx , ss . SupportState , ssNew . SupportState )
265281 }
266282 return slpb.Message {
267283 Type : slpb .MsgHeartbeatResp ,
@@ -274,7 +290,7 @@ func (ssfu *supporterStateForUpdate) handleHeartbeat(
274290
275291// handleHeartbeat contains the core logic for updating the epoch and expiration
276292// of a support requester upon receiving a heartbeat.
277- func handleHeartbeat (ss slpb. SupportState , msg * slpb.Message ) slpb. SupportState {
293+ func handleHeartbeat (ss supportState , msg * slpb.Message ) supportState {
278294 assert (! msg .Expiration .IsEmpty (), "requested support with zero expiration" )
279295 if ss .Epoch == msg .Epoch {
280296 ss .Expiration .Forward (msg .Expiration )
@@ -315,10 +331,10 @@ func (ssfu *supporterStateForUpdate) withdrawSupport(
315331 )
316332 supportWithdrawnForStoreIDs = make (map [roachpb.StoreID ]struct {})
317333 for id , ss := range ssfu .checkedIn .supportFor {
318- ssNew := maybeWithdrawSupport (ss , now )
319- if ss != ssNew {
334+ ssNew , withdrawn := maybeWithdrawSupport (ss , now )
335+ if withdrawn {
320336 ssfu .inProgress .supportFor [id ] = ssNew
321- log .KvExec .Infof (ctx , "withdrew support for %s" , supportChangeStr (ss , ssNew ))
337+ log .KvExec .Infof (ctx , "withdrew support for %s" , supportChangeStr (ss . SupportState , ssNew . SupportState ))
322338 meta := ssfu .getMeta ()
323339 if meta .MaxWithdrawn .Forward (now ) {
324340 ssfu .inProgress .meta = meta
@@ -330,11 +346,15 @@ func (ssfu *supporterStateForUpdate) withdrawSupport(
330346}
331347
332348// maybeWithdrawSupport contains the core logic for updating the epoch and
333- // expiration of a support requester when withdrawing support.
334- func maybeWithdrawSupport (ss slpb.SupportState , now hlc.ClockTimestamp ) slpb.SupportState {
349+ // expiration of a support requester when withdrawing support. If support is
350+ // withdrawn, lastSupportWithdrawnTime is updated to the current timestamp and
351+ // a boolean indicating as such is returned.
352+ func maybeWithdrawSupport (ss supportState , now hlc.ClockTimestamp ) (supportState , bool ) {
335353 if ! ss .Expiration .IsEmpty () && ss .Expiration .LessEq (now .ToTimestamp ()) {
336354 ss .Epoch ++
337355 ss .Expiration = hlc.Timestamp {}
356+ ss .lastSupportWithdrawnTime = now .ToTimestamp ()
357+ return ss , true
338358 }
339- return ss
359+ return ss , false
340360}
0 commit comments