Skip to content

Commit

Permalink
feat: extended downgrade command to include sql migrations (#22813)
Browse files Browse the repository at this point in the history
* feat: extended downgrade command to include sql migrations

* feat: remove short forms in downgrade command
  • Loading branch information
williamhbaker authored Nov 2, 2021
1 parent f7573f4 commit 88d6487
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 10 deletions.
65 changes: 56 additions & 9 deletions cmd/influxd/downgrade/downgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,24 @@ import (
"github.com/influxdata/influxdb/v2/kv/migration"
"github.com/influxdata/influxdb/v2/kv/migration/all"
influxlogger "github.com/influxdata/influxdb/v2/logger"
"github.com/influxdata/influxdb/v2/sqlite"
sqliteMigrations "github.com/influxdata/influxdb/v2/sqlite/migrations"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)

var downgradeMigrationTargets = map[string]int{
"2.0": 15,
const (
backupPathFormat = "%s.%s-pre-%s-downgrade.backup"
)

type migrationTarget struct {
kvMigration, sqlMigration int
}

var downgradeMigrationTargets = map[string]migrationTarget{
"2.0": {kvMigration: 15, sqlMigration: 0},
}

func NewCommand(ctx context.Context, v *viper.Viper) (*cobra.Command, error) {
Expand All @@ -41,6 +51,7 @@ func NewCommand(ctx context.Context, v *viper.Viper) (*cobra.Command, error) {
validTargetsHelp = fmt.Sprintf("<%s>", strings.Join(validDowngradeTargets, "|"))
}

var sqlitePath string
var boltPath string
var logLevel zapcore.Level

Expand Down Expand Up @@ -69,7 +80,7 @@ The target version of the downgrade must be specified, i.e. "influxd downgrade 2
return err
}

return downgrade(ctx, boltPath, args[0], logger)
return downgrade(ctx, boltPath, sqlitePath, args[0], logger)
},
}

Expand All @@ -79,7 +90,11 @@ The target version of the downgrade must be specified, i.e. "influxd downgrade 2
Flag: "bolt-path",
Default: filepath.Join(v2dir, bolt.DefaultFilename),
Desc: "path for boltdb database",
Short: 'm',
},
{
DestP: &sqlitePath,
Flag: "sqlite-path",
Desc: fmt.Sprintf("path to sqlite database. if not set, the database is assumed to be in the bolt-path directory as %q", sqlite.DefaultFilename),
},
{
DestP: &logLevel,
Expand All @@ -92,10 +107,28 @@ The target version of the downgrade must be specified, i.e. "influxd downgrade 2
return nil, err
}

if sqlitePath == "" {
sqlitePath = filepath.Join(filepath.Dir(boltPath), sqlite.DefaultFilename)
}

return cmd, nil
}

func downgrade(ctx context.Context, boltPath string, targetVersion string, log *zap.Logger) error {
func downgrade(ctx context.Context, boltPath, sqlitePath, targetVersion string, log *zap.Logger) error {
info := influxdb.GetBuildInfo()

// Files must exist at the specified paths for the downgrade to work properly. The bolt and sqlite "open" methods will
// create files if they do not exist, so their existence must be verified here.
if _, err := os.Stat(boltPath); err != nil {
return fmt.Errorf("invalid bolt path %q: %w", boltPath, err)
}

if _, err := os.Stat(sqlitePath); err != nil {
return fmt.Errorf("invalid sqlite path %q: %w", sqlitePath, err)
}

// Initialize both migrators prior to attempting any migrations so that we can error out prior to mutating either DB
// if there are errors initializing either migrator.
boltClient := bolt.NewClient(log.With(zap.String("service", "bolt")))
boltClient.Path = boltPath

Expand All @@ -111,13 +144,27 @@ func downgrade(ctx context.Context, boltPath string, targetVersion string, log *
if err != nil {
return fmt.Errorf("failed to initialize KV migrator: %w", err)
}
info := influxdb.GetBuildInfo()
kvMigrator.SetBackupPath(fmt.Sprintf("%s.%s-pre-%s-downgrade.backup", boltPath, info.Version, targetVersion))

kvMigrator.SetBackupPath(fmt.Sprintf(backupPathFormat, boltPath, info.Version, targetVersion))
kvMigrator.AddMigrations(all.Migrations[:]...)

sqlStore, err := sqlite.NewSqlStore(sqlitePath, log.With(zap.String("service", "sqlstore-sqlite")))
if err != nil {
return fmt.Errorf("failed to initialize SQL migrator: %w", err)
}
defer sqlStore.Close()

sqlMigrator := sqlite.NewMigrator(sqlStore, log.With(zap.String("service", "sql-migrator")))
sqlMigrator.SetBackupPath(fmt.Sprintf(backupPathFormat, sqlitePath, info.Version, targetVersion))

log.Info("Downgrading KV metadata to target version", zap.String("version", targetVersion))
if err := kvMigrator.Down(ctx, downgradeMigrationTargets[targetVersion]); err != nil {
return fmt.Errorf("failed to tear down migrations: %w", err)
if err := kvMigrator.Down(ctx, downgradeMigrationTargets[targetVersion].kvMigration); err != nil {
return fmt.Errorf("failed to tear down KV migrations: %w", err)
}

log.Info("Downgrading SQL metadata to target version", zap.String("version", targetVersion))
if err := sqlMigrator.Down(ctx, downgradeMigrationTargets[targetVersion].sqlMigration, sqliteMigrations.AllDown); err != nil {
return fmt.Errorf("failed to tear down SQL migrations: %w", err)
}

log.Info("Metadata successfully downgraded, you can now safely replace this `influxd` with the target older version",
Expand Down
2 changes: 1 addition & 1 deletion cmd/influxd/launcher/launcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -986,7 +986,7 @@ func (m *Launcher) openMetaStores(ctx context.Context, opts *InfluxdOpts) (strin

// If a sqlite-path is not specified, store sqlite db in the same directory as bolt with the default filename.
if opts.SqLitePath == "" {
opts.SqLitePath = filepath.Dir(opts.BoltPath) + "/" + sqlite.DefaultFilename
opts.SqLitePath = filepath.Join(filepath.Dir(opts.BoltPath), sqlite.DefaultFilename)
}
sqlStore, err = sqlite.NewSqlStore(opts.SqLitePath, m.log.With(zap.String("service", "sqlite")))
if err != nil {
Expand Down

0 comments on commit 88d6487

Please sign in to comment.