-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(storage): implement backup and restore (#16504)
* feat(backup): `influx backup` creates data backup * feat(backup): initial restore work * feat(restore): initial restore impl Adds a restore tool which does offline restore of data and metadata. * fix(restore): pr cleanup * fix(restore): fix data dir creation * fix(restore): pr cleanup * chore: amend CHANGELOG * fix: restore to empty dir fails differently * feat(backup): backup and restore credentials Saves the credentials file to backups and restores it from backups. Additionally adds some logging for errors when fetching backup files. * fix(restore): add missed commit * fix(restore): pr cleanup * fix(restore): fix default credentials restore path * fix(backup): actually copy the credentials file for the backup * fix: dirs get 0777, files get 0666 * fix: small review feedback Co-authored-by: tmgordeeva <tanya@influxdata.com>
- Loading branch information
Jacob Marble
and
tmgordeeva
authored
Jan 21, 2020
1 parent
9d7f6a5
commit b836ab9
Showing
26 changed files
with
966 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package authorizer | ||
|
||
import ( | ||
"context" | ||
"io" | ||
|
||
"github.com/influxdata/influxdb" | ||
"github.com/influxdata/influxdb/kit/tracing" | ||
) | ||
|
||
var _ influxdb.BackupService = (*BackupService)(nil) | ||
|
||
// BackupService wraps a influxdb.BackupService and authorizes actions | ||
// against it appropriately. | ||
type BackupService struct { | ||
s influxdb.BackupService | ||
} | ||
|
||
// NewBackupService constructs an instance of an authorizing backup service. | ||
func NewBackupService(s influxdb.BackupService) *BackupService { | ||
return &BackupService{ | ||
s: s, | ||
} | ||
} | ||
|
||
func (b BackupService) CreateBackup(ctx context.Context) (int, []string, error) { | ||
span, ctx := tracing.StartSpanFromContext(ctx) | ||
defer span.Finish() | ||
|
||
if err := IsAllowedAll(ctx, influxdb.ReadAllPermissions()); err != nil { | ||
return 0, nil, err | ||
} | ||
return b.s.CreateBackup(ctx) | ||
} | ||
|
||
func (b BackupService) FetchBackupFile(ctx context.Context, backupID int, backupFile string, w io.Writer) error { | ||
span, ctx := tracing.StartSpanFromContext(ctx) | ||
defer span.Finish() | ||
|
||
if err := IsAllowedAll(ctx, influxdb.ReadAllPermissions()); err != nil { | ||
return err | ||
} | ||
return b.s.FetchBackupFile(ctx, backupID, backupFile, w) | ||
} | ||
|
||
func (b BackupService) InternalBackupPath(backupID int) string { | ||
return b.s.InternalBackupPath(backupID) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package influxdb | ||
|
||
import ( | ||
"context" | ||
"io" | ||
) | ||
|
||
// BackupService represents the data backup functions of InfluxDB. | ||
type BackupService interface { | ||
// CreateBackup creates a local copy (hard links) of the TSM data for all orgs and buckets. | ||
// The return values are used to download each backup file. | ||
CreateBackup(context.Context) (backupID int, backupFiles []string, err error) | ||
// FetchBackupFile downloads one backup file, data or metadata. | ||
FetchBackupFile(ctx context.Context, backupID int, backupFile string, w io.Writer) error | ||
// InternalBackupPath is a utility to determine the on-disk location of a backup fileset. | ||
InternalBackupPath(backupID int) string | ||
} | ||
|
||
// KVBackupService represents the meta data backup functions of InfluxDB. | ||
type KVBackupService interface { | ||
// Backup creates a live backup copy of the metadata database. | ||
Backup(ctx context.Context, w io.Writer) error | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/influxdata/influxdb" | ||
"github.com/influxdata/influxdb/bolt" | ||
"github.com/influxdata/influxdb/http" | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/viper" | ||
"go.uber.org/multierr" | ||
) | ||
|
||
func cmdBackup() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "backup", | ||
Short: "Backup the data in InfluxDB", | ||
Long: fmt.Sprintf( | ||
`Backs up data and meta data for the running InfluxDB instance. | ||
Downloaded files are written to the directory indicated by --path. | ||
The target directory, and any parent directories, are created automatically. | ||
Data file have extension .tsm; meta data is written to %s in the same directory.`, | ||
bolt.DefaultFilename), | ||
RunE: backupF, | ||
} | ||
opts := flagOpts{ | ||
{ | ||
DestP: &backupFlags.Path, | ||
Flag: "path", | ||
Short: 'p', | ||
EnvVar: "PATH", | ||
Desc: "directory path to write backup files to", | ||
Required: true, | ||
}, | ||
} | ||
opts.mustRegister(cmd) | ||
|
||
return cmd | ||
} | ||
|
||
var backupFlags struct { | ||
Path string | ||
} | ||
|
||
func init() { | ||
err := viper.BindEnv("PATH") | ||
if err != nil { | ||
panic(err) | ||
} | ||
if h := viper.GetString("PATH"); h != "" { | ||
backupFlags.Path = h | ||
} | ||
} | ||
|
||
func newBackupService() (influxdb.BackupService, error) { | ||
return &http.BackupService{ | ||
Addr: flags.host, | ||
Token: flags.token, | ||
}, nil | ||
} | ||
|
||
func backupF(cmd *cobra.Command, args []string) error { | ||
ctx := context.Background() | ||
|
||
if flags.local { | ||
return fmt.Errorf("local flag not supported for backup command") | ||
} | ||
|
||
if backupFlags.Path == "" { | ||
return fmt.Errorf("must specify path") | ||
} | ||
|
||
err := os.MkdirAll(backupFlags.Path, 0777) | ||
if err != nil && !os.IsExist(err) { | ||
return err | ||
} | ||
|
||
backupService, err := newBackupService() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
id, backupFilenames, err := backupService.CreateBackup(ctx) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
fmt.Printf("Backup ID %d contains %d files\n", id, len(backupFilenames)) | ||
|
||
for _, backupFilename := range backupFilenames { | ||
dest := filepath.Join(backupFlags.Path, backupFilename) | ||
w, err := os.OpenFile(dest, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666) | ||
if err != nil { | ||
return err | ||
} | ||
err = backupService.FetchBackupFile(ctx, id, backupFilename, w) | ||
if err != nil { | ||
return multierr.Append(fmt.Errorf("error fetching file %s: %v", backupFilename, err), w.Close()) | ||
} | ||
if err = w.Close(); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
fmt.Printf("Backup complete") | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.