Alerting: Remove and revert flag alertingBigTransactions (#65976)

* Alerting: Remove and revert flag alertingBigTransactions

This is a partial revert of #56575 and a removal of the `alertingBigTransactions` flag.

Real-word use has seen no clear performance incentive to maintain this flag. Lowered db connection count
came at the cost of significant increase in CPU usage and query latency.

* Fix lint backend

* Removed last bits of alertingBigTransactions

---------

Co-authored-by: Armand Grillet <2117580+armandgrillet@users.noreply.github.com>
This commit is contained in:
Matthew Jacobson
2023-04-06 18:06:25 +02:00
committed by GitHub
co-authored by Armand Grillet
parent 1c3ce0735f
commit 63187fae0c
11 changed files with 42 additions and 218 deletions
@@ -43,99 +43,6 @@ func (st DBstore) ListAlertInstances(ctx context.Context, cmd *models.ListAlertI
return result, err
}
// SaveAlertInstances saves all the provided alert instances to the store.
func (st DBstore) SaveAlertInstances(ctx context.Context, cmd ...models.AlertInstance) error {
if !st.FeatureToggles.IsEnabled(featuremgmt.FlagAlertingBigTransactions) {
// This mimics the replace code-path by calling SaveAlertInstance in a loop, with a transaction per call.
for _, c := range cmd {
err := st.SaveAlertInstance(ctx, c)
if err != nil {
return err
}
}
return nil
} else {
// Batches write into statements with `maxRows` instances per statements.
// This makes sure we don't create statements that are too long for some
// databases to process. For example, SQLite has a limit of 999 variables
// per write.
keyNames := []string{"rule_org_id", "rule_uid", "labels_hash"}
fieldNames := []string{
"rule_org_id", "rule_uid", "labels", "labels_hash", "current_state",
"current_reason", "current_state_since", "current_state_end", "last_eval_time",
}
fieldsPerRow := len(fieldNames)
maxRows := 20
maxArgs := maxRows * fieldsPerRow
bigUpsertSQL, err := st.SQLStore.GetDialect().UpsertMultipleSQL(
"alert_instance", keyNames, fieldNames, maxRows)
if err != nil {
return err
}
// Args contains the SQL statement, and the values to fill into the SQL statement.
args := make([]interface{}, 0, maxArgs)
args = append(args, bigUpsertSQL)
values := func(a []interface{}) int {
return len(a) - 1
}
// Generate batches of `maxRows` and write the statements when full.
for _, alertInstance := range cmd {
labelTupleJSON, err := alertInstance.Labels.StringKey()
if err != nil {
return err
}
if err := models.ValidateAlertInstance(alertInstance); err != nil {
return err
}
args = append(args,
alertInstance.RuleOrgID, alertInstance.RuleUID, labelTupleJSON, alertInstance.LabelsHash,
alertInstance.CurrentState, alertInstance.CurrentReason, alertInstance.CurrentStateSince.Unix(),
alertInstance.CurrentStateEnd.Unix(), alertInstance.LastEvalTime.Unix())
// If we've reached the maximum batch size, write to the database.
if values(args) >= maxArgs {
err = st.SQLStore.WithDbSession(ctx, func(sess *db.Session) error {
_, err := sess.Exec(args...)
return err
})
if err != nil {
return fmt.Errorf("failed to save alert instances: %w", err)
}
// Reset args so we can re-use the allocated interface pointers.
args = args[:1]
}
}
// Write the final batch of up to maxRows in size.
if values(args) != 0 && values(args)%fieldsPerRow == 0 {
upsertSQL, err := st.SQLStore.GetDialect().UpsertMultipleSQL(
"alert_instance", keyNames, fieldNames, values(args)/fieldsPerRow)
if err != nil {
return err
}
args[0] = upsertSQL
err = st.SQLStore.WithDbSession(ctx, func(sess *db.Session) error {
_, err := sess.Exec(args...)
return err
})
if err != nil {
return fmt.Errorf("failed to save alert instances: %w", err)
}
} else if values(args) != 0 {
return fmt.Errorf("failed to upsert alert instances. Last statements had %v fields, which is not a multiple of the number of fields, %v", len(args), fieldsPerRow)
}
return nil
}
}
// SaveAlertInstance is a handler for saving a new alert instance.
func (st DBstore) SaveAlertInstance(ctx context.Context, alertInstance models.AlertInstance) error {
return st.SQLStore.WithDbSession(ctx, func(sess *db.Session) error {