Alerting: Improve performance of the setting GUID during migration (#101800)

This commit is contained in:
Yuri Tseretyan
2025-03-07 12:28:07 -05:00
committed by GitHub
parent 8f6dcd01d6
commit dc75b454f5
@@ -1,9 +1,13 @@
package ualert
import (
"fmt"
"strings"
"github.com/google/uuid"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
"github.com/grafana/grafana/pkg/util"
"xorm.io/xorm"
)
@@ -58,26 +62,59 @@ func (c setRuleGuidMigration) SQL(migrator.Dialect) string {
}
func (c setRuleGuidMigration) Exec(sess *xorm.Session, mg *migrator.Migrator) error {
var results []string
if err := sess.SQL("SELECT uid FROM alert_rule").Find(&results); err != nil {
return err
}
if len(results) == 0 {
mg.Logger.Debug("no rules found")
return nil
}
for _, uid := range results {
u := uuid.NewString()
_, err := sess.Exec("UPDATE alert_rule_version SET rule_guid = ? WHERE rule_uid = ?", u, uid)
if err != nil {
mg.Logger.Error("Failed to update alert_rule_version table", "error", err)
var lastId *int64
for {
var results []int64
qq := sess.Table(`alert_rule`).Select("id").OrderBy("id").Limit(500)
if lastId != nil {
qq = qq.Where("id > ?", lastId)
}
if err := qq.Find(&results); err != nil {
return err
}
_, err = sess.Exec("UPDATE alert_rule SET guid = ? WHERE uid = ?", u, uid)
if len(results) == 0 {
break
}
bd := strings.Builder{}
for idx, id := range results {
u := uuid.NewString()
if idx == 0 {
bd.WriteString(fmt.Sprintf("SELECT %d as id, '%s' as guid", id, u))
continue
}
bd.WriteString(fmt.Sprintf(" UNION ALL SELECT %d, '%s' ", id, u))
}
var q string
if mg.Dialect.DriverName() == migrator.MySQL {
q = fmt.Sprintf(`UPDATE alert_rule AS ar
INNER JOIN (%s) AS t ON ar.id = t.id
SET ar.guid = t.guid;`, bd.String())
} else {
q = fmt.Sprintf(`UPDATE alert_rule SET guid = t.guid FROM (%s) AS t WHERE alert_rule.id = t.id`, bd.String())
}
_, err := sess.Exec(q)
if err != nil {
mg.Logger.Error("Failed to update alert_rule table", "error", err)
return err
}
lastId = util.Pointer(results[len(results)-1])
}
q := `UPDATE alert_rule_version
SET rule_guid = alert_rule.guid
FROM alert_rule
WHERE alert_rule.uid = alert_rule_version.rule_uid
AND alert_rule.org_id = alert_rule_version.rule_org_id;`
if mg.Dialect.DriverName() == migrator.MySQL {
q = `UPDATE alert_rule_version AS arv
INNER JOIN alert_rule AS ar ON arv.rule_uid = ar.uid AND arv.rule_org_id = ar.org_id
SET arv.rule_guid = ar.guid;`
}
_, err := sess.Exec(q)
if err != nil {
mg.Logger.Error("Failed to update alert_rule_version table with GUIDs from alert_rule table", "error", err)
return err
}
return nil
}