github.com/prysmaticlabs/prysm@v1.4.4/slasher/db/kv/backup.go (about)

     1  package kv
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"path"
     7  	"time"
     8  
     9  	"github.com/prysmaticlabs/prysm/shared/fileutil"
    10  	"github.com/prysmaticlabs/prysm/shared/params"
    11  	bolt "go.etcd.io/bbolt"
    12  	"go.opencensus.io/trace"
    13  )
    14  
    15  const backupsDirectoryName = "backups"
    16  
    17  // Backup the database to the datadir backup directory.
    18  // Example for backup: $DATADIR/backups/prysm_slasherdb_10291092.backup
    19  func (s *Store) Backup(ctx context.Context, outputDir string, overridePermission bool) error {
    20  	ctx, span := trace.StartSpan(ctx, "SlasherDB.Backup")
    21  	defer span.End()
    22  
    23  	var backupsDir string
    24  	var err error
    25  	if outputDir != "" {
    26  		backupsDir, err = fileutil.ExpandPath(outputDir)
    27  		if err != nil {
    28  			return err
    29  		}
    30  	} else {
    31  		backupsDir = path.Join(s.databasePath, backupsDirectoryName)
    32  	}
    33  	// Ensure the backups directory exists.
    34  	if err := fileutil.HandleBackupDir(backupsDir, overridePermission); err != nil {
    35  		return err
    36  	}
    37  	backupPath := path.Join(backupsDir, fmt.Sprintf("prysm_slasherdb_%d.backup", time.Now().Unix()))
    38  	log.WithField("backup", backupPath).Info("Writing backup database")
    39  
    40  	copyDB, err := bolt.Open(
    41  		backupPath,
    42  		params.BeaconIoConfig().ReadWritePermissions,
    43  		&bolt.Options{Timeout: params.BeaconIoConfig().BoltTimeout},
    44  	)
    45  	if err != nil {
    46  		return err
    47  	}
    48  	defer func() {
    49  		if err := copyDB.Close(); err != nil {
    50  			log.WithError(err).Error("Failed to close backup database")
    51  		}
    52  	}()
    53  
    54  	return s.db.View(func(tx *bolt.Tx) error {
    55  		return tx.ForEach(func(name []byte, b *bolt.Bucket) error {
    56  			log.Debugf("Copying bucket %s\n", name)
    57  			return copyDB.Update(func(tx2 *bolt.Tx) error {
    58  				b2, err := tx2.CreateBucketIfNotExists(name)
    59  				if err != nil {
    60  					return err
    61  				}
    62  				return b.ForEach(b2.Put)
    63  			})
    64  		})
    65  	})
    66  }