Skip to content

Commit

Permalink
fix bug so that we actually do incremental restore
Browse files Browse the repository at this point in the history
  • Loading branch information
mangalaman93 committed Mar 10, 2023
1 parent b103574 commit ade6f7f
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 30 deletions.
9 changes: 6 additions & 3 deletions graphql/admin/endpoints_ee.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,16 @@ const adminTypes = `
backupId: String
"""
Number of backups within the backup series to be restored. Backups outside this range
will be ignored. If the value is zero or missing, the entire series will be restored.
If backupNum is 0 or missing, the entire series will be restored i.e all the incremental
backups available in the series as well as the full backup will be restored. If backupNum is
non-zero, we restore all the backups in the series that have backupNum smaller or equal to
the backupNum provided here. Backups that have backupNum higher than this will be ignored.
In simple words, all the backups with backupNum of backup <= backupNum will be restored.
"""
backupNum: Int
"""
All the backups with num >= incrementalFrom will be restored.
All the backups with backupNum >= incrementalFrom will be restored.
"""
incrementalFrom: Int
Expand Down
2 changes: 0 additions & 2 deletions graphql/e2e/multi_tenancy/multi_tenancy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ var (
// Whenever schema is updated in a dgraph alpha for one group for any namespace,
// that update should also be propagated to alpha nodes in other groups.
func TestSchemaSubscribe(t *testing.T) {
// TODO: need to fix the race condition for license propagation, the sleep helps propagate the EE license correctly
time.Sleep(time.Second * 10)
header := http.Header{}
header.Set(accessJwtHeader, testutil.GrootHttpLogin(groupOneAdminServer).AccessJwt)
schema := `
Expand Down
29 changes: 14 additions & 15 deletions worker/backup_manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"sort"
"strings"

"github.com/golang/glog"
"github.com/pkg/errors"

"github.com/dgraph-io/dgraph/protos/pb"
Expand Down Expand Up @@ -56,33 +57,28 @@ func verifyManifests(manifests []*Manifest) error {
return nil
}

func getManifestsToRestore(
h UriHandler, uri *url.URL, req *pb.RestoreRequest) ([]*Manifest, error) {
func getManifestsToRestore(h UriHandler, uri *url.URL, req *pb.RestoreRequest) ([]*Manifest, error) {
manifest, err := GetManifest(h, uri)
if err != nil {
return manifest.Manifests, err
return nil, err
}
return getFilteredManifests(h, manifest.Manifests, req)
}

func getFilteredManifests(h UriHandler, manifests []*Manifest,
req *pb.RestoreRequest) ([]*Manifest, error) {
manifests := manifest.Manifests

// filter takes a list of manifests and returns the list of manifests
// that should be considered during a restore.
filter := func(manifests []*Manifest, backupId string) ([]*Manifest, error) {
filter := func(mfs []*Manifest, backupId string) ([]*Manifest, error) {
// Go through the files in reverse order and stop when the latest full backup is found.
var out []*Manifest
for i := len(manifests) - 1; i >= 0; i-- {
for i := len(mfs) - 1; i >= 0; i-- {
// If backupId is not empty, skip all the manifests that do not match the given
// backupId. If it's empty, do not skip any manifests as the default behavior is
// backupId. If it's empty, do not skip any mfs manifests the default behavior is
// to restore the latest series of backups.
if len(backupId) > 0 && manifests[i].BackupId != backupId {
if len(backupId) > 0 && mfs[i].BackupId != backupId {
continue
}

out = append(out, manifests[i])
if manifests[i].Type == "full" {
out = append(out, mfs[i])
if mfs[i].Type == "full" {
break
}
}
Expand All @@ -100,6 +96,8 @@ func getFilteredManifests(h UriHandler, manifests []*Manifest,
for g := range m.Groups {
path := filepath.Join(m.Path, backupName(m.ValidReadTs(), g))
if !h.FileExists(path) {
glog.Warningf("backup file [%v] missing for backupId [%v] and backupNum [%v]",
path, m.BackupId, m.BackupNum)
missingFiles = true
break
}
Expand All @@ -108,7 +106,8 @@ func getFilteredManifests(h UriHandler, manifests []*Manifest,
validManifests = append(validManifests, m)
}
}
manifests, err := filter(validManifests, req.BackupId)

manifests, err = filter(validManifests, req.BackupId)
if err != nil {
return nil, err
}
Expand Down
3 changes: 1 addition & 2 deletions worker/multi_tenancy_ee.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ import (
"github.com/dgraph-io/dgraph/x"
)

func (w *grpcWorker) DeleteNamespace(ctx context.Context,
req *pb.DeleteNsRequest) (*pb.Status, error) {
func (w *grpcWorker) DeleteNamespace(ctx context.Context, req *pb.DeleteNsRequest) (*pb.Status, error) {
var emptyRes pb.Status
if !groups().ServesGroup(req.GroupId) {
return &emptyRes, errors.Errorf("The server doesn't serve group id: %v", req.GroupId)
Expand Down
25 changes: 17 additions & 8 deletions worker/online_restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@ const (

// verifyRequest verifies that the manifest satisfies the requirements to process the given
// restore request.
func verifyRequest(h UriHandler, uri *url.URL, req *pb.RestoreRequest,
currentGroups []uint32) error {

func verifyRequest(h UriHandler, uri *url.URL, req *pb.RestoreRequest, currentGroups []uint32) error {
manifests, err := getManifestsToRestore(h, uri, req)
if err != nil {
return errors.Wrapf(err, "while retrieving manifests")
Expand Down Expand Up @@ -287,20 +285,31 @@ func handleRestoreProposal(ctx context.Context, req *pb.RestoreRequest, pidx uin
if err != nil {
return errors.Wrapf(err, "cannot get backup manifests")
}

// filter manifests that needs to be restored
mfsToRestore := manifests[:0]
for _, m := range manifests {
if (req.BackupNum == 0 || m.BackupNum <= req.BackupNum) &&
(req.IncrementalFrom == 0 || m.BackupNum >= req.IncrementalFrom) {

mfsToRestore = append(mfsToRestore, m)
}
}
manifests = mfsToRestore

if len(manifests) == 0 {
return errors.Errorf("no backup manifests found at location %s", req.Location)
}

lastManifest := manifests[0]
restorePreds, ok := lastManifest.Groups[req.GroupId]

if !ok {
return errors.Errorf("backup manifest does not contain information for group ID %d",
req.GroupId)
return errors.Errorf("backup manifest does not contain information for group ID %d", req.GroupId)
}

for _, pred := range restorePreds {
// Force the tablet to be moved to this group, even if it's currently being served
// by another group.
// Force the tablet to be moved to this group, even
// if it's currently being served by another group.
tablet, err := groups().ForceTablet(pred)
if err != nil {
return errors.Wrapf(err, "cannot create tablet for restored predicate %s", pred)
Expand Down

0 comments on commit ade6f7f

Please sign in to comment.