Alerting: Improve performance of the setting GUID during migration (#101800)
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user