Skip to content

Commit 94e5872

Browse files
craig[bot]kyle-a-wongpav-kv
committed
156572: server: fix admin v1 health endpoint r=kyle-a-wong a=kyle-a-wong PR #153929 migrated admin RPC use DRPC http instead of the grpc-gateway. This introduced a bug that made the admin/v1/health endpoint require authentication when it previously did not require this. This PR changes it to use an unauthenticated internal server. Fixes: #155052 Epic: None Release note: None 156639: kvstorage: separate engines in replica destruction r=arulajmani a=pav-kv This PR decomposes clearing the unreplicated RangeID-local span in replica destruction funcs, and annotates them with the raft/state engine types. Part of #152845 Epic: CRDB-55220 Co-authored-by: Kyle Wong <[email protected]> Co-authored-by: Pavel Kalinnikov <[email protected]>
3 parents c9d9621 + a5b7cd3 + 72d87ce commit 94e5872

File tree

11 files changed

+79
-53
lines changed

11 files changed

+79
-53
lines changed

pkg/kv/kvserver/client_merge_test.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3963,25 +3963,27 @@ func TestStoreRangeMergeRaftSnapshot(t *testing.T) {
39633963
// doesn't yet exist in the engine, so we set it manually.
39643964
//
39653965
// The deletion also extends to the RangeTombstoneKey.
3966+
sl := kvstorage.MakeStateLoader(rangeID)
39663967
require.NoError(t, sst.ClearRawRange(
39673968
keys.RangeGCThresholdKey(rangeID),
3968-
keys.RangeTombstoneKey(rangeID),
3969+
sl.RangeTombstoneKey(),
39693970
true, false,
39703971
))
3971-
require.NoError(t, kvstorage.MakeStateLoader(rangeID).SetRangeTombstone(
3972+
require.NoError(t, sl.SetRangeTombstone(
39723973
context.Background(), &sst,
39733974
kvserverpb.RangeTombstone{NextReplicaID: math.MaxInt32},
39743975
))
3975-
{
3976-
// Ditto for the unreplicated version, where the first key happens to
3977-
// be the HardState.
3978-
sl := rditer.Select(rangeID, rditer.SelectOpts{
3979-
UnreplicatedByRangeID: true,
3980-
})
3981-
require.Len(t, sl, 1)
3982-
s := sl[0]
3983-
require.NoError(t, sst.ClearRawRange(keys.RaftHardStateKey(rangeID), s.EndKey, true, false))
3984-
}
3976+
// Ditto for the unreplicated RangeID keys. Note that it is also split
3977+
// into two range clears, to work around the RaftReplicaID key.
3978+
require.NoError(t, sst.ClearRawRange(
3979+
keys.RaftHardStateKey(rangeID), sl.RaftReplicaIDKey(), true, false,
3980+
))
3981+
require.NoError(t, sl.ClearRaftReplicaID(&sst))
3982+
require.NoError(t, sst.ClearRawRange(
3983+
sl.RaftTruncatedStateKey(),
3984+
keys.MakeRangeIDUnreplicatedPrefix(rangeID).PrefixEnd(),
3985+
true, false,
3986+
))
39853987

39863988
require.NoError(t, sst.Finish())
39873989
expectedSSTs = append(expectedSSTs, sstFile.Data())

pkg/kv/kvserver/kvstorage/destroy.go

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -82,35 +82,27 @@ type DestroyReplicaInfo struct {
8282
// This call issues all writes ordered by key. This is to support a large
8383
// variety of uses, including SSTable generation for snapshot application.
8484
func DestroyReplica(
85-
ctx context.Context,
86-
reader storage.Reader,
87-
writer storage.Writer,
88-
info DestroyReplicaInfo,
89-
next roachpb.ReplicaID,
85+
ctx context.Context, rw ReadWriter, info DestroyReplicaInfo, next roachpb.ReplicaID,
9086
) error {
91-
return destroyReplicaImpl(ctx, reader, writer, info, next)
87+
return destroyReplicaImpl(ctx, rw, info, next)
9288
}
9389

9490
func destroyReplicaImpl(
95-
ctx context.Context,
96-
reader storage.Reader,
97-
writer storage.Writer,
98-
info DestroyReplicaInfo,
99-
next roachpb.ReplicaID,
91+
ctx context.Context, rw ReadWriter, info DestroyReplicaInfo, next roachpb.ReplicaID,
10092
) error {
10193
if next <= info.ReplicaID {
10294
return errors.AssertionFailedf("%v must not survive its own tombstone", info.FullReplicaID)
10395
}
10496
sl := MakeStateLoader(info.RangeID)
10597
// Assert that the ReplicaID in storage matches the one being removed.
106-
if loaded, err := sl.LoadRaftReplicaID(ctx, reader); err != nil {
98+
if loaded, err := sl.LoadRaftReplicaID(ctx, rw.State.RO); err != nil {
10799
return err
108100
} else if id := loaded.ReplicaID; id != info.ReplicaID {
109101
return errors.AssertionFailedf("%v has a mismatching ID %d", info.FullReplicaID, id)
110102
}
111103
// Assert that the provided tombstone moves the existing one strictly forward.
112104
// A failure would indicate that something is wrong in the replica lifecycle.
113-
if ts, err := sl.LoadRangeTombstone(ctx, reader); err != nil {
105+
if ts, err := sl.LoadRangeTombstone(ctx, rw.State.RO); err != nil {
114106
return err
115107
} else if next <= ts.NextReplicaID {
116108
return errors.AssertionFailedf("%v cannot rewind tombstone from %d to %d",
@@ -136,40 +128,64 @@ func destroyReplicaImpl(
136128
// First, clear all RangeID-local replicated keys. Also, include all
137129
// RangeID-local unreplicated keys < RangeTombstoneKey as a drive-by, since we
138130
// decided that these (currently none) belong to the state machine engine.
139-
tombstoneKey := keys.RangeTombstoneKey(info.RangeID)
131+
span := roachpb.Span{
132+
Key: keys.MakeRangeIDReplicatedPrefix(info.RangeID),
133+
EndKey: keys.RangeTombstoneKey(info.RangeID),
134+
}
140135
if err := storage.ClearRangeWithHeuristic(
141-
ctx, reader, writer,
142-
keys.MakeRangeIDReplicatedPrefix(info.RangeID),
143-
tombstoneKey,
144-
ClearRangeThresholdPointKeys(),
136+
ctx, rw.State.RO, rw.State.WO,
137+
span.Key, span.EndKey, ClearRangeThresholdPointKeys(),
145138
); err != nil {
146139
return err
147140
}
148141
// Save a tombstone to ensure that replica IDs never get reused.
149-
if err := sl.SetRangeTombstone(ctx, writer, kvserverpb.RangeTombstone{
142+
if err := sl.SetRangeTombstone(ctx, rw.State.WO, kvserverpb.RangeTombstone{
150143
NextReplicaID: next, // NB: NextReplicaID > 0
151144
}); err != nil {
152145
return err
153146
}
154-
// Clear the rest of the RangeID-local unreplicated keys.
155-
// TODO(pav-kv): decompose this further to delete raft and state machine keys
156-
// separately. Currently, all the remaining keys in this span belong to the
157-
// raft engine except the RaftReplicaID.
147+
148+
// Clear the rest of the RangeID-local unreplicated keys. These are all raft
149+
// engine keys, except for RaftReplicaIDKey. Make a stop at the latter, and
150+
// clear it manually (note that it always exists for an existing replica, and
151+
// we have asserted that above).
152+
//
153+
// TODO(pav-kv): make a helper for piece-wise clearing, instead of using a
154+
// series of ClearRangeWithHeuristic.
155+
span = roachpb.Span{
156+
Key: span.EndKey.Next(), // RangeTombstoneKey.Next()
157+
EndKey: keys.RaftReplicaIDKey(info.RangeID),
158+
}
159+
// TODO(#152845): with separated raft storage, clear only the unapplied suffix
160+
// of the raft log, which is in this span.
161+
if err := storage.ClearRangeWithHeuristic(
162+
ctx, rw.Raft.RO, rw.Raft.WO,
163+
span.Key, span.EndKey, ClearRangeThresholdPointKeys(),
164+
); err != nil {
165+
return err
166+
}
167+
if err := sl.ClearRaftReplicaID(rw.State.WO); err != nil {
168+
return err
169+
}
170+
span = roachpb.Span{
171+
Key: span.EndKey.Next(), // RaftReplicaIDKey.Next()
172+
EndKey: keys.MakeRangeIDUnreplicatedPrefix(info.RangeID).PrefixEnd(),
173+
}
158174
if err := storage.ClearRangeWithHeuristic(
159-
ctx, reader, writer,
160-
tombstoneKey.Next(),
161-
keys.MakeRangeIDUnreplicatedPrefix(info.RangeID).PrefixEnd(),
162-
ClearRangeThresholdPointKeys(),
175+
ctx, rw.Raft.RO, rw.Raft.WO,
176+
span.Key, span.EndKey, ClearRangeThresholdPointKeys(),
163177
); err != nil {
164178
return err
165179
}
180+
166181
// Finally, clear all the user keys (MVCC keyspace and the corresponding
167182
// system and lock table keys), if info.Keys is not empty.
168183
for _, span := range rditer.Select(info.RangeID, rditer.SelectOpts{
169184
Ranged: rditer.SelectAllRanged(info.Keys),
170185
}) {
171186
if err := storage.ClearRangeWithHeuristic(
172-
ctx, reader, writer, span.Key, span.EndKey, ClearRangeThresholdPointKeys(),
187+
ctx, rw.State.RO, rw.State.WO,
188+
span.Key, span.EndKey, ClearRangeThresholdPointKeys(),
173189
); err != nil {
174190
return err
175191
}
@@ -185,14 +201,14 @@ func destroyReplicaImpl(
185201
// function clears.
186202
// TODO(pav-kv): get rid of SelectOpts.
187203
func SubsumeReplica(
188-
ctx context.Context, reader storage.Reader, writer storage.Writer, info DestroyReplicaInfo,
204+
ctx context.Context, rw ReadWriter, info DestroyReplicaInfo,
189205
) (rditer.SelectOpts, error) {
190206
// Forget about the user keys.
191207
info.Keys = roachpb.RSpan{}
192208
return rditer.SelectOpts{
193209
ReplicatedByRangeID: true,
194210
UnreplicatedByRangeID: true,
195-
}, destroyReplicaImpl(ctx, reader, writer, info, MergedTombstoneReplicaID)
211+
}, destroyReplicaImpl(ctx, rw, info, MergedTombstoneReplicaID)
196212
}
197213

198214
// RemoveStaleRHSFromSplit removes all replicated data for the RHS replica of a

pkg/kv/kvserver/kvstorage/destroy_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ func TestDestroyReplica(t *testing.T) {
6868
})
6969
mutate("destroy", func(rw storage.ReadWriter) {
7070
require.NoError(t, DestroyReplica(
71-
ctx, rw, rw, DestroyReplicaInfo{FullReplicaID: r.id, Keys: r.keys}, r.id.ReplicaID+1,
71+
ctx, TODOReadWriter(rw),
72+
DestroyReplicaInfo{FullReplicaID: r.id, Keys: r.keys}, r.id.ReplicaID+1,
7273
))
7374
})
7475

pkg/kv/kvserver/kvstorage/stateloader.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,11 @@ func (s StateLoader) SetRaftReplicaID(
352352
)
353353
}
354354

355+
// ClearRaftReplicaID clears the RaftReplicaID key.
356+
func (s StateLoader) ClearRaftReplicaID(stateWO StateWO) error {
357+
return stateWO.ClearUnversioned(s.RaftReplicaIDKey(), storage.ClearOptions{})
358+
}
359+
355360
// LoadRangeTombstone loads the RangeTombstone of the range.
356361
func (s StateLoader) LoadRangeTombstone(
357362
ctx context.Context, stateRO StateRO,

pkg/kv/kvserver/kvstorage/testdata/TestDestroyReplica.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Delete (Sized at 43): 0,0 /Local/RangeID/123/u/RaftLog/logIndex:12 (0x0169f67b75
2626
Delete (Sized at 43): 0,0 /Local/RangeID/123/u/RaftLog/logIndex:13 (0x0169f67b757266746c000000000000000d00):
2727
Delete (Sized at 43): 0,0 /Local/RangeID/123/u/RaftLog/logIndex:14 (0x0169f67b757266746c000000000000000e00):
2828
Delete (Sized at 43): 0,0 /Local/RangeID/123/u/RaftLog/logIndex:15 (0x0169f67b757266746c000000000000000f00):
29-
Delete (Sized at 31): 0,0 /Local/RangeID/123/u/RaftReplicaID (0x0169f67b757266747200):
29+
Delete: 0,0 /Local/RangeID/123/u/RaftReplicaID (0x0169f67b757266747200):
3030
Delete (Sized at 33): 0,0 /Local/RangeID/123/u/RaftTruncatedState (0x0169f67b757266747400):
3131
Delete (Sized at 34): 0,0 /Local/RangeID/123/u/RangeLastReplicaGCTimestamp (0x0169f67b75726c727400):
3232
Delete (Sized at 20): 0.000000001,0 /Local/Range"a"/RangeDescriptor (0x016b126100017264736300000000000000000109):

pkg/kv/kvserver/replica_app_batch.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ func (b *replicaAppBatch) runPostAddTriggersReplicaOnly(
364364
rhsRepl.readOnlyCmdMu.Unlock()
365365

366366
if _, err := kvstorage.SubsumeReplica(
367-
ctx, b.batch, b.batch, rhsRepl.destroyInfoRaftMuLocked(),
367+
ctx, kvstorage.TODOReadWriter(b.batch), rhsRepl.destroyInfoRaftMuLocked(),
368368
); err != nil {
369369
return errors.Wrapf(err, "unable to subsume replica before merge")
370370
}
@@ -453,7 +453,8 @@ func (b *replicaAppBatch) runPostAddTriggersReplicaOnly(
453453
// above, and DestroyReplica will also add a range tombstone to the
454454
// batch, so that when we commit it, the removal is finalized.
455455
if err := kvstorage.DestroyReplica(
456-
ctx, b.batch, b.batch, b.r.destroyInfoRaftMuLocked(), change.NextReplicaID(),
456+
ctx, kvstorage.TODOReadWriter(b.batch),
457+
b.r.destroyInfoRaftMuLocked(), change.NextReplicaID(),
457458
); err != nil {
458459
return errors.Wrapf(err, "unable to destroy replica before removal")
459460
}

pkg/kv/kvserver/replica_destroy.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ func (r *Replica) destroyRaftMuLocked(ctx context.Context, nextReplicaID roachpb
9191

9292
// TODO(sep-raft-log): need both engines separately here.
9393
if err := kvstorage.DestroyReplica(
94-
ctx, r.store.TODOEngine(), batch, r.destroyInfoRaftMuLocked(), nextReplicaID,
94+
ctx, kvstorage.TODOReaderWriter(r.store.TODOEngine(), batch),
95+
r.destroyInfoRaftMuLocked(), nextReplicaID,
9596
); err != nil {
9697
return err
9798
}

pkg/kv/kvserver/snapshot_apply_prepare.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,9 @@ func (s *snapWriteBuilder) clearSubsumedReplicaDiskData(ctx context.Context) err
149149
for _, sub := range s.subsume {
150150
// We have to create an SST for the subsumed replica's range-id local keys.
151151
if err := s.writeSST(ctx, func(ctx context.Context, w storage.Writer) error {
152-
opts, err := kvstorage.SubsumeReplica(ctx, reader, w, sub)
152+
opts, err := kvstorage.SubsumeReplica(
153+
ctx, kvstorage.TODOReaderWriter(reader, w), sub,
154+
)
153155
s.cleared = append(s.cleared, rditer.Select(sub.RangeID, opts)...)
154156
return err
155157
}); err != nil {

pkg/kv/kvserver/testdata/TestPrepareSnapApply.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ Put: 0,0 /Local/RangeID/123/u/RaftReplicaID (0x0169f67b757266747200): replica_id
77
Put: 0,0 /Local/RangeID/123/u/RaftTruncatedState (0x0169f67b757266747400): index:100 term:20
88
>> sst:
99
Put: 0,0 /Local/RangeID/101/u/RangeTombstone (0x0169ed757266746200): next_replica_id:2147483647
10-
Delete (Sized at 30): 0,0 /Local/RangeID/101/u/RaftReplicaID (0x0169ed757266747200):
10+
Delete: 0,0 /Local/RangeID/101/u/RaftReplicaID (0x0169ed757266747200):
1111
>> sst:
1212
Put: 0,0 /Local/RangeID/102/u/RangeTombstone (0x0169ee757266746200): next_replica_id:2147483647
13-
Delete (Sized at 30): 0,0 /Local/RangeID/102/u/RaftReplicaID (0x0169ee757266747200):
13+
Delete: 0,0 /Local/RangeID/102/u/RaftReplicaID (0x0169ee757266747200):
1414
>> sst:
1515
Delete (Sized at 27): /Local/Lock"y\xff" 0300000000000000000000000000000000 (0x017a6b1279ff000100030000000000000000000000000000000012):
1616
>> sst:

pkg/server/server_http.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ func (s *httpServer) setupRoutes(
237237

238238
// Exempt the 2nd health check endpoint from authentication.
239239
// (This simply mirrors /health and exists for backward compatibility.)
240-
s.mux.Handle(apiconstants.AdminHealth, authenticatedAPIInternalServer)
240+
s.mux.Handle(apiconstants.AdminHealth, unauthenticatedAPIInternalServer)
241241
// The /_status/vars and /metrics endpoint is not authenticated either. Useful for monitoring.
242242
s.mux.Handle(apiconstants.StatusVars, http.HandlerFunc(varsHandler{metricSource, s.cfg.Settings, false /* useStaticLabels */}.handleVars))
243243
s.mux.Handle(apiconstants.MetricsPath, http.HandlerFunc(varsHandler{metricSource, s.cfg.Settings, true /* useStaticLabels */}.handleVars))

0 commit comments

Comments
 (0)