diff --git a/db/background_mgr_resync_dcp.go b/db/background_mgr_resync_dcp.go index 8f80168629..2d7ddb8f5e 100644 --- a/db/background_mgr_resync_dcp.go +++ b/db/background_mgr_resync_dcp.go @@ -64,17 +64,6 @@ func (r *ResyncManagerDCP) Init(ctx context.Context, options map[string]interfac db := options["database"].(*Database) resyncCollections := options["collections"].(ResyncCollections) - newRunInit := func() error { - uniqueUUID, err := uuid.NewRandom() - if err != nil { - return err - } - - r.ResyncID = uniqueUUID.String() - base.InfofCtx(ctx, base.KeyAll, "Resync: Starting new resync run with resync ID: %q", r.ResyncID) - return nil - } - // Get collectionIds and store in manager for use in DCP client later collectionIDs, hasAllCollections, collectionNames, err := getCollectionIdsAndNames(db, resyncCollections) if err != nil { @@ -85,29 +74,33 @@ func (r *ResyncManagerDCP) Init(ctx context.Context, options map[string]interfac // add collection list to manager for use in status call r.SetCollectionStatus(collectionNames) - if clusterStatus != nil { - var statusDoc ResyncManagerStatusDocDCP - err := base.JSONUnmarshal(clusterStatus, &statusDoc) - - reset, ok := options["reset"].(bool) - if reset && ok { - base.InfofCtx(ctx, base.KeyAll, "Resync: Resetting resync process. Will not resume any partially completed process") - } - - // If the previous run completed, or there was an error during unmarshalling the status we will start the - // process from scratch with a new resync ID. Otherwise, we should resume with the resync ID, stats specified in the doc. - if statusDoc.State == BackgroundProcessStateCompleted || err != nil || (reset && ok) { - return newRunInit() - } + // If the previous run completed, or we couldn't determine, we will start the resync with a new resync ID. + // Otherwise, we should resume with the resync ID, and the previous stats specified in the doc. + var resetMsg string // an optional message about why we're resetting + var statusDoc ResyncManagerStatusDocDCP + if clusterStatus == nil { + resetMsg = "no previous run found" + } else if resetOpt, _ := options["reset"].(bool); resetOpt { + resetMsg = "reset option requested" + } else if err := base.JSONUnmarshal(clusterStatus, &statusDoc); err != nil { + resetMsg = "failed to unmarshal cluster status" + } else if statusDoc.State == BackgroundProcessStateCompleted { + resetMsg = "previous run completed" + } else { + // use the resync ID from the status doc to resume r.ResyncID = statusDoc.ResyncID r.SetStatus(statusDoc.DocsChanged, statusDoc.DocsProcessed) - - base.InfofCtx(ctx, base.KeyAll, "Resync: Attempting to resume resync with resync ID: %s", r.ResyncID) - + base.InfofCtx(ctx, base.KeyAll, "Resync: Resuming resync with ID: %q", r.ResyncID) return nil } - return newRunInit() + newID, err := uuid.NewRandom() + if err != nil { + return err + } + r.ResyncID = newID.String() + base.InfofCtx(ctx, base.KeyAll, "Resync: Running new resync process with ID: %q - %s", r.ResyncID, resetMsg) + return nil } func (r *ResyncManagerDCP) Run(ctx context.Context, options map[string]interface{}, persistClusterStatusCallback updateStatusCallbackFunc, terminator *base.SafeTerminator) error { diff --git a/docs/api/paths/admin/db-_resync.yaml b/docs/api/paths/admin/db-_resync.yaml index dd776c0986..4f23b34018 100644 --- a/docs/api/paths/admin/db-_resync.yaml +++ b/docs/api/paths/admin/db-_resync.yaml @@ -36,8 +36,6 @@ post: A resync operation cannot be run if the database is online. The database can be taken offline by calling the `POST /{db}/_offline` endpoint. - In a multi-node cluster, the resync operation *must* be run on only a single node. Therefore, users should bring other nodes offline before initiating this action. Undefined system behaviour will happen if running resync on more than 1 node. - The `requireUser()` and `requireRole()` calls in the sync function will always return `true`. - **action=start** - This is an asynchronous operation, and will start resync in the background.