Skip to content

Commit b4a8e8d

Browse files
committed
Update migrations to be idempotent
For Postgres we check if column exists For Mysql DDL queries are performed outside of transaction, so we are checking for duplicate error Signed-off-by: Amelia Downs <[email protected]>
1 parent ecdd1f9 commit b4a8e8d

12 files changed

+110
-55
lines changed

db/migrations/1472757022_add_placement_tags_to_desired_lrp.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,17 @@ func (e *AddPlacementTagsToDesiredLRPs) SetClock(c clock.Clock) { e.clock = c
4040
func (e *AddPlacementTagsToDesiredLRPs) SetDBFlavor(flavor string) { e.dbFlavor = flavor }
4141

4242
func (e *AddPlacementTagsToDesiredLRPs) Up(tx *sql.Tx, logger lager.Logger) error {
43+
var alterDesiredLRPAddPlacementTagSQL string
44+
if e.dbFlavor == "mysql" {
45+
alterDesiredLRPAddPlacementTagSQL = `ALTER TABLE desired_lrps
46+
ADD COLUMN placement_tags TEXT;`
47+
} else {
48+
alterDesiredLRPAddPlacementTagSQL = `ALTER TABLE desired_lrps
49+
ADD COLUMN IF NOT EXISTS placement_tags TEXT;`
50+
}
4351
logger.Info("altering the table", lager.Data{"query": alterDesiredLRPAddPlacementTagSQL})
4452
_, err := tx.Exec(alterDesiredLRPAddPlacementTagSQL)
45-
if err != nil {
53+
if err != nil && !isDuplicateColumnError(err) {
4654
logger.Error("failed-altering-tables", err)
4755
return err
4856
}

db/migrations/1481761088_add_max_pid_limit.go

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package migrations
22

33
import (
44
"database/sql"
5-
"strings"
65

76
"code.cloudfoundry.org/bbs/encryption"
87
"code.cloudfoundry.org/bbs/format"
@@ -41,22 +40,17 @@ func (e *AddMaxPidsToDesiredLRPs) SetClock(c clock.Clock) { e.clock = c }
4140
func (e *AddMaxPidsToDesiredLRPs) SetDBFlavor(flavor string) { e.dbFlavor = flavor }
4241

4342
func (e *AddMaxPidsToDesiredLRPs) Up(tx *sql.Tx, logger lager.Logger) error {
44-
_, err := tx.Exec(checkMaxPidsExistenceSQL)
45-
if err == nil {
46-
logger.Info("max-pid-already-available")
47-
return nil
48-
}
49-
50-
if err != nil {
51-
if !strings.Contains(err.Error(), postgresColumnNotExistErr) && !strings.Contains(err.Error(), mysqlColumnNotExistErr) {
52-
logger.Error("failed-querying-desired-lrps", err)
53-
return err
54-
}
43+
var alterDesiredLRPAddMaxPidsSQL string
44+
if e.dbFlavor == "mysql" {
45+
alterDesiredLRPAddMaxPidsSQL = `ALTER TABLE desired_lrps
46+
ADD COLUMN max_pids INTEGER DEFAULT 0;`
47+
} else {
48+
alterDesiredLRPAddMaxPidsSQL = `ALTER TABLE desired_lrps
49+
ADD COLUMN IF NOT EXISTS max_pids INTEGER DEFAULT 0;`
5550
}
56-
5751
logger.Info("altering the table", lager.Data{"query": alterDesiredLRPAddMaxPidsSQL})
58-
_, err = tx.Exec(alterDesiredLRPAddMaxPidsSQL)
59-
if err != nil {
52+
_, err := tx.Exec(alterDesiredLRPAddMaxPidsSQL)
53+
if err != nil && !isDuplicateColumnError(err) {
6054
logger.Error("failed-altering-tables", err)
6155
return err
6256
}
@@ -68,5 +62,3 @@ func (e *AddMaxPidsToDesiredLRPs) Up(tx *sql.Tx, logger lager.Logger) error {
6862
const postgresColumnNotExistErr = `"max_pids" does not exist`
6963
const mysqlColumnNotExistErr = `Unknown column 'max_pids'`
7064
const checkMaxPidsExistenceSQL = `SELECT count(max_pids) FROM desired_lrps`
71-
const alterDesiredLRPAddMaxPidsSQL = `ALTER TABLE desired_lrps
72-
ADD COLUMN max_pids INTEGER DEFAULT 0;`

db/migrations/1522700600_add_task_rejection_count.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,14 @@ func (e *AddTaskRejectionCount) Up(tx *sql.Tx, logger lager.Logger) error {
4444
logger.Info("starting")
4545
defer logger.Info("completed")
4646

47-
const stmt = "ALTER TABLE tasks ADD COLUMN rejection_count INTEGER NOT NULL DEFAULT 0;"
47+
var stmt string
48+
if e.dbFlavor == "mysql" {
49+
stmt = "ALTER TABLE tasks ADD COLUMN rejection_count INTEGER NOT NULL DEFAULT 0;"
50+
} else {
51+
stmt = "ALTER TABLE tasks ADD COLUMN IF NOT EXISTS rejection_count INTEGER NOT NULL DEFAULT 0;"
52+
}
4853
_, err := tx.Exec(stmt)
49-
if err != nil {
54+
if err != nil && !isDuplicateColumnError(err) {
5055
logger.Error("failed-altering-table", err)
5156
return err
5257
}

db/migrations/1523050077_add_rejection_reason_to_task.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,14 @@ func (e *AddRejectionReasonToTask) Up(tx *sql.Tx, logger lager.Logger) error {
4444
logger.Info("starting")
4545
defer logger.Info("completed")
4646

47-
const query = "ALTER TABLE tasks ADD COLUMN rejection_reason VARCHAR(255) NOT NULL DEFAULT '';"
47+
var query string
48+
if e.dbFlavor == "mysql" {
49+
query = "ALTER TABLE tasks ADD COLUMN rejection_reason VARCHAR(255) NOT NULL DEFAULT '';"
50+
} else {
51+
query = "ALTER TABLE tasks ADD COLUMN IF NOT EXISTS rejection_reason VARCHAR(255) NOT NULL DEFAULT '';"
52+
}
4853
_, err := tx.Exec(query)
49-
if err != nil {
54+
if err != nil && !isDuplicateColumnError(err) {
5055
logger.Error("failed-altering-table", err)
5156
return err
5257
}

db/migrations/1529530809_add_presence_to_actual_lrp.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,21 @@ func (e *AddPresenceToActualLrp) Up(tx *sql.Tx, logger lager.Logger) error {
5151
}
5252

5353
func (e *AddPresenceToActualLrp) alterTable(tx *sql.Tx, logger lager.Logger) error {
54-
alterTablesSQL := []string{
55-
"ALTER TABLE actual_lrps ADD COLUMN presence INT NOT NULL DEFAULT 0;",
54+
var addColumnSQL string
55+
if e.dbFlavor == "mysql" {
56+
addColumnSQL = "ALTER TABLE actual_lrps ADD COLUMN presence INT NOT NULL DEFAULT 0;"
57+
} else {
58+
addColumnSQL = "ALTER TABLE actual_lrps ADD COLUMN IF NOT EXISTS presence INT NOT NULL DEFAULT 0;"
59+
}
60+
61+
logger.Info("altering-table")
62+
_, err := tx.Exec(helpers.RebindForFlavor(addColumnSQL, e.dbFlavor))
63+
if err != nil && !isDuplicateColumnError(err) {
64+
logger.Error("failed-altering-table", err)
65+
return err
5666
}
5767

68+
alterTablesSQL := []string{}
5869
alterTablesSQL = append(alterTablesSQL, fmt.Sprintf("UPDATE actual_lrps SET presence = %d WHERE evacuating = true;", models.ActualLRP_Evacuating))
5970

6071
if e.dbFlavor == "mysql" {
@@ -67,7 +78,6 @@ func (e *AddPresenceToActualLrp) alterTable(tx *sql.Tx, logger lager.Logger) err
6778
)
6879
}
6980

70-
logger.Info("altering-table")
7181
for _, query := range alterTablesSQL {
7282
logger.Info("altering the table", lager.Data{"query": query})
7383
_, err := tx.Exec(helpers.RebindForFlavor(query, e.dbFlavor))

db/migrations/1643660541_add_internal_routes_to_actual_lrp.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,15 @@ func (e *AddInternalRoutesToActualLrp) Up(tx *sql.Tx, logger lager.Logger) error
4545
logger.Info("starting")
4646
defer logger.Info("completed")
4747

48-
alterTableSQL := "ALTER TABLE actual_lrps ADD COLUMN internal_routes MEDIUMTEXT;"
48+
var alterTableSQL string
49+
if e.dbFlavor == "mysql" {
50+
alterTableSQL = "ALTER TABLE actual_lrps ADD COLUMN internal_routes MEDIUMTEXT;"
51+
} else {
52+
alterTableSQL = "ALTER TABLE actual_lrps ADD COLUMN IF NOT EXISTS internal_routes MEDIUMTEXT;"
53+
}
4954
logger.Info("altering the table", lager.Data{"query": alterTableSQL})
5055
_, err := tx.Exec(helpers.RebindForFlavor(alterTableSQL, e.dbFlavor))
51-
if err != nil {
56+
if err != nil && !isDuplicateColumnError(err) {
5257
logger.Error("failed-altering-table", err)
5358
return err
5459
}

db/migrations/1676360874_add_metric_tags_to_actual_lrp.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,15 @@ func (e *AddMetricTagsToActualLrp) Up(tx *sql.Tx, logger lager.Logger) error {
4545
logger.Info("starting")
4646
defer logger.Info("completed")
4747

48-
alterTableSQL := "ALTER TABLE actual_lrps ADD COLUMN metric_tags MEDIUMTEXT;"
48+
var alterTableSQL string
49+
if e.dbFlavor == "mysql" {
50+
alterTableSQL = "ALTER TABLE actual_lrps ADD COLUMN metric_tags MEDIUMTEXT;"
51+
} else {
52+
alterTableSQL = "ALTER TABLE actual_lrps ADD COLUMN IF NOT EXISTS metric_tags MEDIUMTEXT;"
53+
}
4954
logger.Info("altering the table", lager.Data{"query": alterTableSQL})
5055
_, err := tx.Exec(helpers.RebindForFlavor(alterTableSQL, e.dbFlavor))
51-
if err != nil {
56+
if err != nil && !isDuplicateColumnError(err) {
5257
logger.Error("failed-altering-table", err)
5358
return err
5459
}

db/migrations/1686692176_add_routable_to_actual_lrps.go

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,25 +40,34 @@ func (e *AddRoutableToActualLrps) SetClock(c clock.Clock) { e.clock = c }
4040
func (e *AddRoutableToActualLrps) SetDBFlavor(flavor string) { e.dbFlavor = flavor }
4141

4242
func (e *AddRoutableToActualLrps) Up(tx *sql.Tx, logger lager.Logger) error {
43-
var alterTablesSQL = []string{
44-
alterActualLRPAddRoutableSQL,
45-
alterActualLRPSetRoutableForRunningSQL,
43+
var alterActualLRPAddRoutableSQL string
44+
if e.dbFlavor == "mysql" {
45+
alterActualLRPAddRoutableSQL = `ALTER TABLE actual_lrps
46+
ADD COLUMN routable BOOL DEFAULT false;`
47+
} else {
48+
alterActualLRPAddRoutableSQL = `ALTER TABLE actual_lrps
49+
ADD COLUMN IF NOT EXISTS routable BOOL DEFAULT false;`
4650
}
47-
for _, query := range alterTablesSQL {
48-
logger.Info("altering the table", lager.Data{"query": query})
49-
_, err := tx.Exec(query)
50-
if err != nil {
51-
logger.Error("failed-altering-tables", err)
52-
return err
53-
}
54-
logger.Info("altered the table", lager.Data{"query": query})
51+
52+
logger.Info("altering the table", lager.Data{"query": alterActualLRPAddRoutableSQL})
53+
_, err := tx.Exec(alterActualLRPAddRoutableSQL)
54+
if err != nil && !isDuplicateColumnError(err) {
55+
logger.Error("failed-altering-table", err)
56+
return err
5557
}
5658

59+
logger.Info("altered the table", lager.Data{"query": alterActualLRPAddRoutableSQL})
60+
61+
logger.Info("altering the table", lager.Data{"query": alterActualLRPSetRoutableForRunningSQL})
62+
_, err = tx.Exec(alterActualLRPSetRoutableForRunningSQL)
63+
if err != nil {
64+
logger.Error("failed-altering-table", err)
65+
return err
66+
}
67+
logger.Info("altered the table", lager.Data{"query": alterActualLRPSetRoutableForRunningSQL})
68+
5769
return nil
5870
}
5971

60-
const alterActualLRPAddRoutableSQL = `ALTER TABLE actual_lrps
61-
ADD COLUMN routable BOOL DEFAULT false;`
62-
6372
const alterActualLRPSetRoutableForRunningSQL = `UPDATE actual_lrps
6473
SET routable = true WHERE state = 'RUNNING';`

db/migrations/1698182853_add_availability_zone_to_actual_lrps.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,21 @@ func (e *AddAvailabilityZoneToActualLrps) SetClock(c clock.Clock) { e.clock =
4040
func (e *AddAvailabilityZoneToActualLrps) SetDBFlavor(flavor string) { e.dbFlavor = flavor }
4141

4242
func (e *AddAvailabilityZoneToActualLrps) Up(tx *sql.Tx, logger lager.Logger) error {
43+
var alterActualLRPAddAvailabilityZoneSQL string
44+
if e.dbFlavor == "mysql" {
45+
alterActualLRPAddAvailabilityZoneSQL = `ALTER TABLE actual_lrps
46+
ADD COLUMN availability_zone VARCHAR(255) NOT NULL DEFAULT '';`
47+
} else {
48+
alterActualLRPAddAvailabilityZoneSQL = `ALTER TABLE actual_lrps
49+
ADD COLUMN IF NOT EXISTS availability_zone VARCHAR(255) NOT NULL DEFAULT '';`
50+
}
4351
logger.Info("altering the table", lager.Data{"query": alterActualLRPAddAvailabilityZoneSQL})
4452
_, err := tx.Exec(alterActualLRPAddAvailabilityZoneSQL)
45-
if err != nil {
53+
if err != nil && !isDuplicateColumnError(err) {
4654
logger.Error("failed-altering-tables", err)
4755
return err
4856
}
4957
logger.Info("altered the table", lager.Data{"query": alterActualLRPAddAvailabilityZoneSQL})
5058

5159
return nil
5260
}
53-
54-
const alterActualLRPAddAvailabilityZoneSQL = `ALTER TABLE actual_lrps
55-
ADD COLUMN availability_zone VARCHAR(255) NOT NULL DEFAULT '';`

db/migrations/migrations.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"strings"
99

1010
"code.cloudfoundry.org/bbs/migration"
11+
"github.com/go-sql-driver/mysql"
12+
"github.com/jackc/pgx"
1113
)
1214

1315
var migrationsRegistry = migration.Migrations{}
@@ -35,3 +37,18 @@ func AllMigrations() migration.Migrations {
3537
}
3638
return migs
3739
}
40+
41+
func isDuplicateColumnError(err error) bool {
42+
switch err.(type) {
43+
case *mysql.MySQLError:
44+
if err.(*mysql.MySQLError).Number == 1060 {
45+
return true
46+
}
47+
case pgx.PgError:
48+
if err.(pgx.PgError).Code == "42701" {
49+
return true
50+
}
51+
}
52+
53+
return false
54+
}

0 commit comments

Comments
 (0)