Skip to content

Commit f80e487

Browse files
Remove whole stream deletion mode (#6435)
* Remove whole-stream-deletion mode Signed-off-by: Michel Hollands <[email protected]> * Remove whole-stream-deletion from docs Signed-off-by: Michel Hollands <[email protected]> * Update the changelog Signed-off-by: Michel Hollands <[email protected]> * Sort changelog entries Signed-off-by: Michel Hollands <[email protected]> * Remove link to wrong configuration Signed-off-by: Michel Hollands <[email protected]> * Fix integration test Signed-off-by: Michel Hollands <[email protected]> * Set default deletion mode to disabled Signed-off-by: Michel Hollands <[email protected]> * Remove extra white line in documentation Signed-off-by: Michel Hollands <[email protected]> * Fix default value in docs Signed-off-by: Michel Hollands <[email protected]> * Fix changelog Signed-off-by: Michel Hollands <[email protected]> * Add DeletionEnabled method on mode Signed-off-by: Michel Hollands <[email protected]> * Rename test Signed-off-by: Michel Hollands <[email protected]>
1 parent 798677a commit f80e487

File tree

9 files changed

+53
-50
lines changed

9 files changed

+53
-50
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
## Main
22

33
* [6444](https://github.com/grafana/loki/pull/6444) **aminesnow** Add TLS config to query frontend.
4+
* [6435](https://github.com/grafana/loki/pull/6430) **MichelHollands**: Remove the `whole-stream-deletion` mode.
45
* [6415](https://github.com/grafana/loki/pull/6415) **salvacorts** Evenly spread queriers across kubernetes nodes.
56
* [6410](https://github.com/grafana/loki/pull/6410) **MichelHollands**: Add support for per tenant delete API access enabling.
67
* [6372](https://github.com/grafana/loki/pull/6372) **splitice**: Add support for numbers in JSON fields.

docs/sources/configuration/_index.md

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2109,23 +2109,18 @@ compacts index shards to more performant forms.
21092109
# CLI flag: -boltdb.shipper.compactor.delete-request-cancel-period
21102110
[delete_request_cancel_period: <duration> | default = 24h]
21112111
2112-
# Which deletion mode to use. Supported values are: disabled,
2113-
# whole-stream-deletion, filter-only, and filter-and-delete.
2114-
# CLI flag: -boltdb.shipper.compactor.deletion-mode
2115-
[deletion_mode: <string> | default = "whole-stream-deletion"]
2116-
21172112
# Maximum number of tables to compact in parallel.
21182113
# While increasing this value, please make sure compactor has enough disk space
21192114
# allocated to be able to store and compact as many tables.
21202115
# CLI flag: -boltdb.shipper.compactor.max-compaction-parallelism
21212116
[max_compaction_parallelism: <int> | default = 1]
21222117
21232118
# Deletion mode.
2124-
# Can be one of "disabled", "whole-stream-deletion", "filter-only", or "filter-and-delete".
2125-
# When set to the default value of "whole-stream-deletion", and if
2119+
# Can be one of "disabled", "filter-only", or "filter-and-delete".
2120+
# When set to "filter-only" or "filter-and-delete", and if
21262121
# retention_enabled is true, then the log entry deletion API endpoints are available.
21272122
# CLI flag: -boltdb.shipper.compactor.deletion-mode
2128-
[deletion_mode: <string> | default = "whole-stream-deletion"]
2123+
[deletion_mode: <string> | default = "disabled"]
21292124
21302125
# The hash ring configuration used by compactors to elect a single instance for running compactions
21312126
# The CLI flags prefix for this block config is: boltdb.shipper.compactor.ring

docs/sources/operations/storage/logs-deletion.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ Log entry deletion is supported _only_ for the BoltDB Shipper index store.
99
Grafana Loki supports the deletion of log entries from a specified stream.
1010
Log entries that fall within a specified time window and match an optional line filter are those that will be deleted.
1111

12-
1312
The Compactor component exposes REST endpoints that process delete requests.
1413
Hitting the endpoint specifies the streams and the time window.
1514
The deletion of the log entries takes place after a configurable cancellation time period expires.
@@ -18,9 +17,8 @@ Log entry deletion relies on configuration of the custom logs retention workflow
1817

1918
## Configuration
2019

21-
Enable log entry deletion by setting `retention_enabled` to true and `deletion_mode` to `whole-stream-deletion`, `filter-only`, or `filter-and-delete` in the compactor's configuration. See the example in [Retention configuration](../retention#retention-configuration).
20+
Enable log entry deletion by setting `retention_enabled` to true and `deletion_mode` to `filter-only` or `filter-and-delete` in the compactor's configuration.
2221

23-
With `whole-stream-deletion`, all the log entries matching the query given in the delete request are removed.
2422
With `filter-only`, log lines matching the query in the delete request are filtered out when querying Loki. They are not removed from the on-disk chunks.
2523
With `filter-and-delete`, log lines matching the query in the delete request are filtered out when querying Loki, and they are also removed from the on-disk chunks.
2624

integration/loki_micro_services_delete_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,14 @@ func TestMicroServicesDeleteRequest(t *testing.T) {
5252
"-frontend.scheduler-address="+tQueryScheduler.GRPCURL().Host,
5353
"-frontend.default-validity=0s",
5454
"-boltdb.shipper.index-gateway-client.server-address="+tIndexGateway.GRPCURL().Host,
55+
"-common.compactor-address="+tCompactor.HTTPURL().String(),
5556
)
5657
_ = clu.AddComponent(
5758
"querier",
5859
"-target=querier",
5960
"-querier.scheduler-address="+tQueryScheduler.GRPCURL().Host,
6061
"-boltdb.shipper.index-gateway-client.server-address="+tIndexGateway.GRPCURL().Host,
62+
"-common.compactor-address="+tCompactor.HTTPURL().String(),
6163
)
6264
)
6365

pkg/loki/modules.go

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ func (t *Loki) initQueryFrontendTripperware() (_ services.Service, err error) {
575575
}
576576

577577
func (t *Loki) cacheGenClient() (generationnumber.CacheGenClient, error) {
578-
filteringEnabled, err := deletion.FilteringEnabled(t.Cfg.CompactorConfig.DeletionMode)
578+
filteringEnabled, err := deletion.DeleteEnabled(t.Cfg.CompactorConfig.DeletionMode)
579579
if err != nil {
580580
return nil, err
581581
}
@@ -880,16 +880,11 @@ func (t *Loki) initCompactor() (services.Service, error) {
880880

881881
t.Server.HTTP.Path("/compactor/ring").Methods("GET", "POST").Handler(t.compactor)
882882

883-
if t.Cfg.CompactorConfig.RetentionEnabled {
884-
switch t.compactor.DeleteMode() {
885-
case deletion.WholeStreamDeletion, deletion.FilterOnly, deletion.FilterAndDelete:
886-
t.Server.HTTP.Path("/loki/api/v1/delete").Methods("PUT", "POST").Handler(t.HTTPAuthMiddleware.Wrap(t.compactor.DeleteRequestsHandler.AddDeleteRequestHandler()))
887-
t.Server.HTTP.Path("/loki/api/v1/delete").Methods("GET").Handler(t.HTTPAuthMiddleware.Wrap(t.compactor.DeleteRequestsHandler.GetAllDeleteRequestsHandler()))
888-
t.Server.HTTP.Path("/loki/api/v1/delete").Methods("DELETE").Handler(t.HTTPAuthMiddleware.Wrap(t.compactor.DeleteRequestsHandler.CancelDeleteRequestHandler()))
889-
t.Server.HTTP.Path("/loki/api/v1/cache/generation_numbers").Methods("GET").Handler(t.HTTPAuthMiddleware.Wrap(t.compactor.DeleteRequestsHandler.GetCacheGenerationNumberHandler()))
890-
default:
891-
break
892-
}
883+
if t.Cfg.CompactorConfig.RetentionEnabled && t.compactor.DeleteMode().DeleteEnabled() {
884+
t.Server.HTTP.Path("/loki/api/v1/delete").Methods("PUT", "POST").Handler(t.HTTPAuthMiddleware.Wrap(t.compactor.DeleteRequestsHandler.AddDeleteRequestHandler()))
885+
t.Server.HTTP.Path("/loki/api/v1/delete").Methods("GET").Handler(t.HTTPAuthMiddleware.Wrap(t.compactor.DeleteRequestsHandler.GetAllDeleteRequestsHandler()))
886+
t.Server.HTTP.Path("/loki/api/v1/delete").Methods("DELETE").Handler(t.HTTPAuthMiddleware.Wrap(t.compactor.DeleteRequestsHandler.CancelDeleteRequestHandler()))
887+
t.Server.HTTP.Path("/loki/api/v1/cache/generation_numbers").Methods("GET").Handler(t.HTTPAuthMiddleware.Wrap(t.compactor.DeleteRequestsHandler.GetCacheGenerationNumberHandler()))
893888
}
894889

895890
return t.compactor, nil
@@ -993,12 +988,12 @@ func (t *Loki) deleteRequestsClient() (deletion.DeleteRequestsClient, error) {
993988
return deletion.NewNoOpDeleteRequestsStore(), nil
994989
}
995990

996-
filteringEnabled, err := deletion.FilteringEnabled(t.Cfg.CompactorConfig.DeletionMode)
991+
deleteEnabled, err := deletion.DeleteEnabled(t.Cfg.CompactorConfig.DeletionMode)
997992
if err != nil {
998993
return nil, err
999994
}
1000995

1001-
if !config.UsingBoltdbShipper(t.Cfg.SchemaConfig.Configs) || !filteringEnabled {
996+
if !config.UsingBoltdbShipper(t.Cfg.SchemaConfig.Configs) || !deleteEnabled {
1002997
return deletion.NewNoOpDeleteRequestsStore(), nil
1003998
}
1004999

pkg/storage/stores/shipper/compactor/compactor.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func (cfg *Config) RegisterFlags(f *flag.FlagSet) {
8787
f.IntVar(&cfg.RetentionDeleteWorkCount, "boltdb.shipper.compactor.retention-delete-worker-count", 150, "The total amount of worker to use to delete chunks.")
8888
f.DurationVar(&cfg.DeleteRequestCancelPeriod, "boltdb.shipper.compactor.delete-request-cancel-period", 24*time.Hour, "Allow cancellation of delete request until duration after they are created. Data would be deleted only after delete requests have been older than this duration. Ideally this should be set to at least 24h.")
8989
f.IntVar(&cfg.MaxCompactionParallelism, "boltdb.shipper.compactor.max-compaction-parallelism", 1, "Maximum number of tables to compact in parallel. While increasing this value, please make sure compactor has enough disk space allocated to be able to store and compact as many tables.")
90-
f.StringVar(&cfg.DeletionMode, "boltdb.shipper.compactor.deletion-mode", "whole-stream-deletion", fmt.Sprintf("(Experimental) Deletion mode. Can be one of %v", strings.Join(deletion.AllModes(), "|")))
90+
f.StringVar(&cfg.DeletionMode, "boltdb.shipper.compactor.deletion-mode", "disabled", fmt.Sprintf("Deletion mode. Can be one of %v", strings.Join(deletion.AllModes(), "|")))
9191
cfg.CompactorRing.RegisterFlagsWithPrefix("boltdb.shipper.compactor.", "collectors/", f)
9292
f.BoolVar(&cfg.RunOnce, "boltdb.shipper.compactor.run-once", false, "Run the compactor one time to cleanup and compact index files only (no retention applied)")
9393
}
@@ -231,12 +231,11 @@ func (c *Compactor) init(storageConfig storage.Config, schemaConfig config.Schem
231231
return err
232232
}
233233

234-
switch c.deleteMode {
235-
case deletion.WholeStreamDeletion, deletion.FilterOnly, deletion.FilterAndDelete:
234+
if c.deleteMode.DeleteEnabled() {
236235
if err := c.initDeletes(r, limits); err != nil {
237236
return err
238237
}
239-
default:
238+
} else {
240239
c.expirationChecker = newExpirationChecker(
241240
retention.NewExpirationChecker(limits),
242241
// This is a dummy deletion ExpirationChecker that never expires anything

pkg/storage/stores/shipper/compactor/deletion/delete_requests_manager_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,15 @@ func TestDeleteRequestsManager_Expired(t *testing.T) {
4141
}{
4242
{
4343
name: "no delete requests",
44-
deletionMode: WholeStreamDeletion,
44+
deletionMode: FilterAndDelete,
4545
expectedResp: resp{
4646
isExpired: false,
4747
nonDeletedIntervals: nil,
4848
},
4949
},
5050
{
5151
name: "no relevant delete requests",
52-
deletionMode: WholeStreamDeletion,
52+
deletionMode: FilterAndDelete,
5353
deleteRequestsFromStore: []DeleteRequest{
5454
{
5555
UserID: "different-user",
@@ -65,7 +65,7 @@ func TestDeleteRequestsManager_Expired(t *testing.T) {
6565
},
6666
{
6767
name: "whole chunk deleted by single request",
68-
deletionMode: WholeStreamDeletion,
68+
deletionMode: FilterAndDelete,
6969
deleteRequestsFromStore: []DeleteRequest{
7070
{
7171
UserID: testUserID,
@@ -81,7 +81,7 @@ func TestDeleteRequestsManager_Expired(t *testing.T) {
8181
},
8282
{
8383
name: "deleted interval out of range",
84-
deletionMode: WholeStreamDeletion,
84+
deletionMode: FilterAndDelete,
8585
deleteRequestsFromStore: []DeleteRequest{
8686
{
8787
UserID: testUserID,
@@ -97,7 +97,7 @@ func TestDeleteRequestsManager_Expired(t *testing.T) {
9797
},
9898
{
9999
name: "multiple delete requests with one deleting the whole chunk",
100-
deletionMode: WholeStreamDeletion,
100+
deletionMode: FilterAndDelete,
101101
deleteRequestsFromStore: []DeleteRequest{
102102
{
103103
UserID: testUserID,
@@ -119,7 +119,7 @@ func TestDeleteRequestsManager_Expired(t *testing.T) {
119119
},
120120
{
121121
name: "multiple delete requests causing multiple holes",
122-
deletionMode: WholeStreamDeletion,
122+
deletionMode: FilterAndDelete,
123123
deleteRequestsFromStore: []DeleteRequest{
124124
{
125125
UserID: testUserID,
@@ -172,7 +172,7 @@ func TestDeleteRequestsManager_Expired(t *testing.T) {
172172
},
173173
{
174174
name: "multiple overlapping requests deleting the whole chunk",
175-
deletionMode: WholeStreamDeletion,
175+
deletionMode: FilterAndDelete,
176176
deleteRequestsFromStore: []DeleteRequest{
177177
{
178178
UserID: testUserID,
@@ -194,7 +194,7 @@ func TestDeleteRequestsManager_Expired(t *testing.T) {
194194
},
195195
{
196196
name: "multiple non-overlapping requests deleting the whole chunk",
197-
deletionMode: WholeStreamDeletion,
197+
deletionMode: FilterAndDelete,
198198
deleteRequestsFromStore: []DeleteRequest{
199199
{
200200
UserID: testUserID,

pkg/storage/stores/shipper/compactor/deletion/mode.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ var (
1111
)
1212

1313
const (
14-
Disabled Mode = iota
15-
WholeStreamDeletion // The existing log deletion that removes whole streams.
14+
Disabled Mode = iota
1615
FilterOnly
1716
FilterAndDelete
1817
)
@@ -21,8 +20,6 @@ func (m Mode) String() string {
2120
switch m {
2221
case Disabled:
2322
return "disabled"
24-
case WholeStreamDeletion:
25-
return "whole-stream-deletion"
2623
case FilterOnly:
2724
return "filter-only"
2825
case FilterAndDelete:
@@ -31,16 +28,18 @@ func (m Mode) String() string {
3128
return "unknown"
3229
}
3330

31+
func (m Mode) DeleteEnabled() bool {
32+
return m == FilterOnly || m == FilterAndDelete
33+
}
34+
3435
func AllModes() []string {
35-
return []string{Disabled.String(), WholeStreamDeletion.String(), FilterOnly.String(), FilterAndDelete.String()}
36+
return []string{Disabled.String(), FilterOnly.String(), FilterAndDelete.String()}
3637
}
3738

3839
func ParseMode(in string) (Mode, error) {
3940
switch in {
4041
case "disabled":
4142
return Disabled, nil
42-
case "whole-stream-deletion":
43-
return WholeStreamDeletion, nil
4443
case "filter-only":
4544
return FilterOnly, nil
4645
case "filter-and-delete":
@@ -49,11 +48,11 @@ func ParseMode(in string) (Mode, error) {
4948
return 0, errUnknownMode
5049
}
5150

52-
func FilteringEnabled(in string) (bool, error) {
51+
func DeleteEnabled(in string) (bool, error) {
5352
deleteMode, err := ParseMode(in)
5453
if err != nil {
5554
return false, err
5655
}
5756

58-
return deleteMode == FilterOnly || deleteMode == FilterAndDelete, nil
57+
return deleteMode.DeleteEnabled(), nil
5958
}

pkg/storage/stores/shipper/compactor/deletion/mode_test.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,14 @@ import (
88

99
func TestAllModes(t *testing.T) {
1010
modes := AllModes()
11-
require.ElementsMatch(t, []string{"disabled", "whole-stream-deletion", "filter-only", "filter-and-delete"}, modes)
11+
require.ElementsMatch(t, []string{"disabled", "filter-only", "filter-and-delete"}, modes)
1212
}
1313

1414
func TestParseMode(t *testing.T) {
1515
mode, err := ParseMode("disabled")
1616
require.NoError(t, err)
1717
require.Equal(t, Disabled, mode)
1818

19-
mode, err = ParseMode("whole-stream-deletion")
20-
require.NoError(t, err)
21-
require.Equal(t, WholeStreamDeletion, mode)
22-
2319
mode, err = ParseMode("filter-only")
2420
require.NoError(t, err)
2521
require.Equal(t, FilterOnly, mode)
@@ -31,3 +27,21 @@ func TestParseMode(t *testing.T) {
3127
_, err = ParseMode("something-else")
3228
require.ErrorIs(t, errUnknownMode, err)
3329
}
30+
31+
func TestDeleteEnabled(t *testing.T) {
32+
enabled, err := DeleteEnabled("disabled")
33+
require.NoError(t, err)
34+
require.False(t, enabled)
35+
36+
enabled, err = DeleteEnabled("filter-only")
37+
require.NoError(t, err)
38+
require.True(t, enabled)
39+
40+
enabled, err = DeleteEnabled("filter-and-delete")
41+
require.NoError(t, err)
42+
require.True(t, enabled)
43+
44+
enabled, err = DeleteEnabled("some other value")
45+
require.Error(t, err)
46+
require.False(t, enabled)
47+
}

0 commit comments

Comments
 (0)