mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-25 03:40:10 +01:00
79 lines
2.3 KiB
Go
79 lines
2.3 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/backup/actions"
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/backup/common"
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/backup/fslocal"
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/buildinfo"
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
|
)
|
|
|
|
var (
|
|
src = flag.String("src", "", "Source path with backup on the remote storage. "+
|
|
"Example: gcs://bucket/path/to/backup/dir, s3://bucket/path/to/backup/dir or fs:///path/to/local/backup/dir")
|
|
storageDataPath = flag.String("storageDataPath", "victoria-metrics-data", "Destination path where backup must be restored. "+
|
|
"VictoriaMetrics must be stopped when restoring from backup. -storageDataPath dir can be non-empty. In this case only missing data is downloaded from backup")
|
|
concurrency = flag.Int("concurrency", 10, "The number of concurrent workers. Higher concurrency may reduce restore duration")
|
|
maxBytesPerSecond = flag.Int("maxBytesPerSecond", 0, "The maximum download speed. There is no limit if it is set to 0")
|
|
)
|
|
|
|
func main() {
|
|
flag.Usage = usage
|
|
flag.Parse()
|
|
buildinfo.Init()
|
|
|
|
srcFS, err := newSrcFS()
|
|
if err != nil {
|
|
logger.Fatalf("%s", err)
|
|
}
|
|
dstFS, err := newDstFS()
|
|
if err != nil {
|
|
logger.Fatalf("%s", err)
|
|
}
|
|
a := &actions.Restore{
|
|
Concurrency: *concurrency,
|
|
Src: srcFS,
|
|
Dst: dstFS,
|
|
}
|
|
if err := a.Run(); err != nil {
|
|
logger.Fatalf("cannot restore from backup: %s", err)
|
|
}
|
|
}
|
|
|
|
func usage() {
|
|
const s = `
|
|
vmrestore restores VictoriaMetrics data from backups made by vmbackup.
|
|
|
|
See the docs at https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/app/vmrestore/README.md .
|
|
`
|
|
|
|
f := flag.CommandLine.Output()
|
|
fmt.Fprintf(f, "%s\n", s)
|
|
flag.PrintDefaults()
|
|
}
|
|
|
|
func newDstFS() (*fslocal.FS, error) {
|
|
if len(*storageDataPath) == 0 {
|
|
return nil, fmt.Errorf("`-storageDataPath` cannot be empty")
|
|
}
|
|
fs := &fslocal.FS{
|
|
Dir: *storageDataPath,
|
|
MaxBytesPerSecond: *maxBytesPerSecond,
|
|
}
|
|
if err := fs.Init(); err != nil {
|
|
return nil, fmt.Errorf("cannot initialize local fs: %s", err)
|
|
}
|
|
return fs, nil
|
|
}
|
|
|
|
func newSrcFS() (common.RemoteFS, error) {
|
|
fs, err := actions.NewRemoteFS(*src)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("cannot parse `-src`=%q: %s", *src, err)
|
|
}
|
|
return fs, nil
|
|
}
|