Added backup machinery
This commit is contained in:
parent
90e419f5a4
commit
206eb2f149
22
backup.go
Normal file
22
backup.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"qurl/storage"
|
||||||
|
"time"
|
||||||
|
"fmt"
|
||||||
|
"path"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func manageBackup(stor storage.Storage, dir string, interval int){
|
||||||
|
for {
|
||||||
|
time.Sleep(time.Duration(interval) * time.Second)
|
||||||
|
fname := fmt.Sprintf("qurl-%s.backup",
|
||||||
|
time.Now().Format("20060102150405"))
|
||||||
|
|
||||||
|
err := stor.Backup(path.Join(dir, fname))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Backup failure: %s\n", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
29
main.go
29
main.go
@ -8,7 +8,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"qurl/pages"
|
"qurl/pages"
|
||||||
"qurl/storage"
|
"qurl/storage"
|
||||||
"runtime"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate bindata -m Assets -r assets -p static -o static/assets.go assets
|
//go:generate bindata -m Assets -r assets -p static -o static/assets.go assets
|
||||||
@ -17,18 +16,10 @@ func main() {
|
|||||||
dburl := flag.String("u", "bolt:./qurl.db", "url to database")
|
dburl := flag.String("u", "bolt:./qurl.db", "url to database")
|
||||||
lsaddr := flag.String("l", "127.0.0.1:8080", "listen address/port")
|
lsaddr := flag.String("l", "127.0.0.1:8080", "listen address/port")
|
||||||
jsonfile := flag.String("j", "", "path to json to load into database")
|
jsonfile := flag.String("j", "", "path to json to load into database")
|
||||||
maxpro := flag.Int("m", runtime.NumCPU()+2,
|
backupint := flag.Int("i", 86400, "seconds between database backups")
|
||||||
"maximum number of threads to use")
|
backupdir := flag.String("b", "", "destination directory for database backups")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if *maxpro < 3 {
|
|
||||||
fmt.Fprintf(os.Stderr, "Thread limit too low: %d (min 3)\n", *maxpro)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Limit max processes
|
|
||||||
runtime.GOMAXPROCS(*maxpro)
|
|
||||||
|
|
||||||
// Open storage backend
|
// Open storage backend
|
||||||
stor, err := storage.NewStorage(*dburl)
|
stor, err := storage.NewStorage(*dburl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -37,6 +28,22 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer stor.Shutdown()
|
defer stor.Shutdown()
|
||||||
|
|
||||||
|
// If there's a backup dir specified, do backups
|
||||||
|
// at a specific interval
|
||||||
|
if *backupdir != "" {
|
||||||
|
stat, err := os.Stat(*backupdir)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Directory stat error: %s\n", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !stat.IsDir() {
|
||||||
|
fmt.Fprintf(os.Stderr, "Backup directory does not exist: %s\n", *backupdir)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
go manageBackup(stor, *backupdir, *backupint)
|
||||||
|
}
|
||||||
|
|
||||||
// Load data if asked
|
// Load data if asked
|
||||||
if *jsonfile != "" {
|
if *jsonfile != "" {
|
||||||
err := loadjson(stor, *jsonfile)
|
err := loadjson(stor, *jsonfile)
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
bolt "go.etcd.io/bbolt"
|
bolt "go.etcd.io/bbolt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BoltStorage struct {
|
type BoltStorage struct {
|
||||||
@ -26,3 +27,17 @@ func New(u *url.URL) (*BoltStorage, error) {
|
|||||||
}
|
}
|
||||||
return &BoltStorage{DB: db}, nil
|
return &BoltStorage{DB: db}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (stor *BoltStorage) Backup(bpath string) error {
|
||||||
|
tx, err := stor.DB.Begin(false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer tx.Rollback()
|
||||||
|
|
||||||
|
err = tx.CopyFile(bpath, os.FileMode(0600))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -13,6 +13,7 @@ type Storage interface {
|
|||||||
// GetQURL(uint64) (*qurl.QURL, error)
|
// GetQURL(uint64) (*qurl.QURL, error)
|
||||||
GetQURLByURL(string) (*qurl.QURL, error)
|
GetQURLByURL(string) (*qurl.QURL, error)
|
||||||
SetQURLSequence(uint64) error
|
SetQURLSequence(uint64) error
|
||||||
|
Backup(string) error
|
||||||
Shutdown()
|
Shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user