Alerting: Store alertmanager configuration history in a separate table in the database (#60197)
* Update config store to split between active and history tables * Migrations to fix up indexes * Implement migration from old format to new * Move add migrations call * Delete duplicated rows * Explicitly map fields * Quote the column name because it's a reserved word * Lift migrations to top
This commit is contained in:
@@ -35,6 +35,9 @@ func AddTablesMigrations(mg *migrator.Migrator) {
|
||||
AddAlertImageMigrations(mg)
|
||||
|
||||
AddAlertmanagerConfigHistoryMigrations(mg)
|
||||
ExtractAlertmanagerConfigurationHistoryMigration(mg)
|
||||
mg.AddMigration("drop non-unique orgID index", migrator.NewDropIndexMigration(migrator.Table{Name: "alert_configuration"}, &migrator.Index{Cols: []string{"org_id"}}))
|
||||
mg.AddMigration("add unique index on orgID", migrator.NewAddIndexMigration(migrator.Table{Name: "alert_configuration"}, &migrator.Index{Type: migrator.UniqueIndex, Cols: []string{"org_id"}}))
|
||||
}
|
||||
|
||||
// AddAlertDefinitionMigrations should not be modified.
|
||||
|
||||
@@ -878,3 +878,44 @@ func (c updateRulesOrderInGroup) Exec(sess *xorm.Session, migrator *migrator.Mig
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ExtractAlertmanagerConfigurationHistoryMigration(mg *migrator.Migrator) {
|
||||
if !mg.Cfg.UnifiedAlerting.IsEnabled() {
|
||||
return
|
||||
}
|
||||
mg.AddMigration("extract alertmanager configuration history to separate table", &extractAlertmanagerConfigurationHistory{})
|
||||
}
|
||||
|
||||
type extractAlertmanagerConfigurationHistory struct {
|
||||
migrator.MigrationBase
|
||||
}
|
||||
|
||||
func (c extractAlertmanagerConfigurationHistory) SQL(migrator.Dialect) string {
|
||||
return codeMigration
|
||||
}
|
||||
|
||||
func (c extractAlertmanagerConfigurationHistory) Exec(sess *xorm.Session, migrator *migrator.Migrator) error {
|
||||
var orgs []int64
|
||||
if err := sess.Table("alert_configuration").Distinct("org_id").Find(&orgs); err != nil {
|
||||
return fmt.Errorf("failed to retrieve the organizations with alerting configurations: %w", err)
|
||||
}
|
||||
|
||||
// Quote the column called "default" because it's a reserved keyword in SQL.
|
||||
fields := fmt.Sprintf("org_id, alertmanager_configuration, configuration_hash, configuration_version, created_at, %s", migrator.Dialect.Quote("default"))
|
||||
for _, orgID := range orgs {
|
||||
_, err := sess.Exec(`
|
||||
INSERT INTO alert_configuration_history (`+fields+`)
|
||||
SELECT `+fields+`
|
||||
FROM alert_configuration
|
||||
WHERE org_id = ? AND id != (SELECT MAX(id) FROM alert_configuration WHERE org_id = ?)`,
|
||||
orgID, orgID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to move old configurations to history table: %w", err)
|
||||
}
|
||||
_, err = sess.Exec("DELETE FROM alert_configuration WHERE org_id = ? AND id != (SELECT MAX(id) FROM alert_configuration WHERE org_id = ?)", orgID, orgID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to evict old configurations after moving to history table: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user