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:
co-authored by
Armand Grillet
parent
1c3ce0735f
commit
63187fae0c
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user