Add unifiedStorageKVBackend feature toggle

- Introduced the `unifiedStorageKVBackend` feature toggle to enable the use of a KV-backed SQL storage backend instead of direct SQL queries.
- Updated relevant files to include the new feature toggle in the registry, CSV, JSON, and Go definitions.
- Enhanced the resource server logic to conditionally use the KV backend based on the feature flag.

This change expands the storage options available for the application, improving flexibility in data management.
This commit is contained in:
Georges Chaudy
2025-11-18 11:35:17 +01:00
parent a8c86de2d6
commit fa3d906d41
6 changed files with 70 additions and 14 deletions
+4
View File
@@ -912,6 +912,10 @@ export interface FeatureToggles {
*/
unifiedStorageGrpcConnectionPool?: boolean;
/**
* Use KV-backed SQL storage backend instead of direct SQL queries
*/
unifiedStorageKVBackend?: boolean;
/**
* Enables UI functionality to permanently delete alert rules
* @default true
*/
+8
View File
@@ -1580,6 +1580,14 @@ var (
HideFromAdminPage: true,
HideFromDocs: true,
},
{
Name: "unifiedStorageKVBackend",
Description: "Use KV-backed SQL storage backend instead of direct SQL queries",
Stage: FeatureStageExperimental,
Owner: grafanaSearchAndStorageSquad,
HideFromAdminPage: true,
HideFromDocs: true,
},
{
Name: "alertingRulePermanentlyDelete",
Description: "Enables UI functionality to permanently delete alert rules",
+1
View File
@@ -205,6 +205,7 @@ unifiedStorageHistoryPruner,GA,@grafana/search-and-storage,false,false,false
azureMonitorLogsBuilderEditor,preview,@grafana/partner-datasources,false,false,false
localeFormatPreference,preview,@grafana/grafana-frontend-platform,false,false,false
unifiedStorageGrpcConnectionPool,experimental,@grafana/search-and-storage,false,false,false
unifiedStorageKVBackend,experimental,@grafana/search-and-storage,false,false,false
alertingRulePermanentlyDelete,GA,@grafana/alerting-squad,false,false,true
alertingRuleRecoverDeleted,GA,@grafana/alerting-squad,false,false,true
multiTenantTempCredentials,experimental,@grafana/aws-datasources,false,false,false
1 Name Stage Owner requiresDevMode RequiresRestart FrontendOnly
205 azureMonitorLogsBuilderEditor preview @grafana/partner-datasources false false false
206 localeFormatPreference preview @grafana/grafana-frontend-platform false false false
207 unifiedStorageGrpcConnectionPool experimental @grafana/search-and-storage false false false
208 unifiedStorageKVBackend experimental @grafana/search-and-storage false false false
209 alertingRulePermanentlyDelete GA @grafana/alerting-squad false false true
210 alertingRuleRecoverDeleted GA @grafana/alerting-squad false false true
211 multiTenantTempCredentials experimental @grafana/aws-datasources false false false
+4
View File
@@ -830,6 +830,10 @@ const (
// Enables the unified storage grpc connection pool
FlagUnifiedStorageGrpcConnectionPool = "unifiedStorageGrpcConnectionPool"
// FlagUnifiedStorageKVBackend
// Use KV-backed SQL storage backend instead of direct SQL queries
FlagUnifiedStorageKVBackend = "unifiedStorageKVBackend"
// FlagAlertingRulePermanentlyDelete
// Enables UI functionality to permanently delete alert rules
FlagAlertingRulePermanentlyDelete = "alertingRulePermanentlyDelete"
+14
View File
@@ -4208,6 +4208,20 @@
"expression": "true"
}
},
{
"metadata": {
"name": "unifiedStorageKVBackend",
"resourceVersion": "1763461706359",
"creationTimestamp": "2025-11-18T10:28:26Z"
},
"spec": {
"description": "Use KV-backed SQL storage backend instead of direct SQL queries",
"stage": "experimental",
"codeowner": "@grafana/search-and-storage",
"hideFromAdminPage": true,
"hideFromDocs": true
}
},
{
"metadata": {
"name": "unifiedStorageSearch",
+39 -14
View File
@@ -101,21 +101,46 @@ func NewResourceServer(opts ServerOptions) (resource.ResourceServer, error) {
//nolint:staticcheck // not yet migrated to OpenFeature
withPruner := opts.Features.IsEnabledGlobally(featuremgmt.FlagUnifiedStorageHistoryPruner)
backend, err := NewBackend(BackendOptions{
DBProvider: eDB,
Tracer: opts.Tracer,
Reg: opts.Reg,
IsHA: isHA,
withPruner: withPruner,
storageMetrics: opts.StorageMetrics,
LastImportTimeMaxAge: opts.SearchOptions.MaxIndexAge, // No need to keep last_import_times older than max index age.
})
if err != nil {
return nil, err
// Check if KV backend is enabled via feature flag
//nolint:staticcheck // not yet migrated to OpenFeature
if opts.Features.IsEnabledGlobally(featuremgmt.FlagUnifiedStorageKVBackend) {
// Create SQL KV instance
sqlKV, err := resource.NewSQLKV(eDB)
if err != nil {
return nil, fmt.Errorf("create SQL KV: %w", err)
}
// Use existing KV storage backend (already implements StorageBackend interface)
kvBackend, err := resource.NewKVStorageBackend(resource.KVBackendOptions{
KvStore: sqlKV,
WithPruner: withPruner,
Tracer: opts.Tracer,
Reg: opts.Reg,
})
if err != nil {
return nil, fmt.Errorf("create KV backend: %w", err)
}
serverOptions.Backend = kvBackend
// Note: kvStorageBackend doesn't implement Diagnostics/Lifecycle yet
// For now, we'll leave these nil and they will be handled by the server
} else {
// Use existing SQL backend
backend, err := NewBackend(BackendOptions{
DBProvider: eDB,
Tracer: opts.Tracer,
Reg: opts.Reg,
IsHA: isHA,
withPruner: withPruner,
storageMetrics: opts.StorageMetrics,
LastImportTimeMaxAge: opts.SearchOptions.MaxIndexAge, // No need to keep last_import_times older than max index age.
})
if err != nil {
return nil, err
}
serverOptions.Backend = backend
serverOptions.Diagnostics = backend
serverOptions.Lifecycle = backend
}
serverOptions.Backend = backend
serverOptions.Diagnostics = backend
serverOptions.Lifecycle = backend
}
serverOptions.Search = opts.SearchOptions