feat: backup file rotate (#2511)

Add support for rotate backup files
This commit is contained in:
Athurg Gooth 2023-11-13 22:12:25 +08:00 committed by GitHub
parent 52fdf8bccd
commit 6814915c88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 8 deletions

View File

@ -52,8 +52,11 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
Profile: profile,
// Asynchronous runners.
backupRunner: backup.NewBackupRunner(store),
telegramBot: telegram.NewBotWithHandler(integration.NewTelegramHandler(store)),
telegramBot: telegram.NewBotWithHandler(integration.NewTelegramHandler(store)),
}
if profile.Driver == "sqlite" {
s.backupRunner = backup.NewBackupRunner(store)
}
e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
@ -112,7 +115,10 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
func (s *Server) Start(ctx context.Context) error {
go versionchecker.NewVersionChecker(s.Store, s.Profile).Start(ctx)
go s.telegramBot.Start(ctx)
go s.backupRunner.Run(ctx)
if s.backupRunner != nil {
go s.backupRunner.Run(ctx)
}
metric.Enqueue("server start")
return s.e.Start(fmt.Sprintf("%s:%d", s.Profile.Addr, s.Profile.Port))

View File

@ -3,6 +3,7 @@ package backup
import (
"context"
"fmt"
"os"
"strconv"
"time"
@ -24,6 +25,8 @@ func NewBackupRunner(store *store.Store) *BackupRunner {
}
}
const MaxBackupFiles = 5
func (r *BackupRunner) Run(ctx context.Context) {
intervalStr := r.Store.GetSystemSettingValueWithDefault(ctx, apiv1.SystemSettingAutoBackupIntervalName.String(), "")
if intervalStr == "" {
@ -46,20 +49,46 @@ func (r *BackupRunner) Run(ctx context.Context) {
ticker := time.NewTicker(time.Duration(interval) * time.Second)
defer ticker.Stop()
var t time.Time
for {
select {
case <-ctx.Done():
log.Info("stop auto backup graceful.")
return
case t = <-ticker.C:
case <-ticker.C:
}
filename := r.Store.Profile.DSN + ".bak"
if err := rotateFiles(filename, MaxBackupFiles); err != nil {
log.Error("fail to rotate backup files", zap.Error(err))
continue
}
filename := r.Store.Profile.DSN + t.Format("-20060102-150405.bak")
log.Info(fmt.Sprintf("create backup to %s", filename))
err := r.Store.BackupTo(ctx, filename)
if err != nil {
if err := r.Store.BackupTo(ctx, filename); err != nil {
log.Error("fail to create backup", zap.Error(err))
}
}
}
func rotateFiles(filename string, cnt int) error {
// Generate suffix slices of history files like "",".1",".2",".3"...
ss := make([]string, cnt-1)
for i := 1; i < len(ss); i++ {
ss[i] = fmt.Sprintf(".%d", i)
}
// Iterate through the suffix slices and rename the files
for i := len(ss) - 1; i >= 0; i-- {
from := filename + ss[i]
to := filename + "." + strconv.Itoa(i+1)
log.Info("rotate file", zap.String("from", from), zap.String("to", to))
err := os.Rename(from, to)
if err != nil && !os.IsNotExist(err) {
return err
}
}
return nil
}