Uploaded image for project: 'Couchbase Server'
  1. Couchbase Server
  2. MB-61194

[BP 7.2.5] XDCR: backfill spec compare logic ends up comparing same two objects

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • Major
    • 7.2.5
    • 7.2.5
    • XDCR
    • Untriaged
    • 0
    • No

    Description

      The following code Adds and Sets the backfill spec contained in b.cachedBackfillSpec

      func (b *BackfillRequestHandler) metaKvOp(op PersistType) error {
          b.logger.Infof(">> metakvOp op=%d", int(op))
          switch op {
          case AddOp:
              return b.backfillReplSvc.AddBackfillReplSpec(b.cachedBackfillSpec)
          case SetOp:
              return b.backfillReplSvc.SetBackfillReplSpec(b.cachedBackfillSpec)
          default:
              _, err := b.backfillReplSvc.DelBackfillReplSpec(b.id)
              return err
          }
      } 

       

      For new spec

      In case of new spec, its directly assigned to b.cachedBackfillSpec (in updateBackfillSpec)which is passed in AddBackfillSpec above

      backfillSpec := metadata.NewBackfillReplicationSpec(clonedSpec.Id, clonedSpec.InternalId, vbTasksMap, clonedSpec, srcManifestId)
      b.cachedBackfillSpec = backfillSpe

      This spec is upserted into the cache so now the object in cache is same as b.cachedBackfillSpec

       

      Change in spec

      In updateBackfillSpec() when spec already exists it merges the new task:

      b.cachedBackfillSpec.MergeNewTasks(vbTasksMap, shouldSkipFirst)

      This updates the object in cache as well since they are the same. Since an existing spec is being modified the cache logic does a comparison in (BackfillReplicationService.updateCacheInternalNoLock()):

      func (b *BackfillReplicationService) updateCacheInternalNoLock(specId string, newSpec *metadata.BackfillReplicationSpec) (*metadata.BackfillReplicationSpec, bool, error) {
          oldSpec, err := b.backfillSpec(specId)
          if err != nil {
              oldSpec = nil
          }
      ...
      if oldSpec == nil || !newSpec.SameAs(oldSpec) {
                  err = b.cacheSpec(b.getCache(), specId, newSpec)
                  if err == nil {
                      specId = newSpec.Id
                      updated = true
                  } else {
                      return oldSpec, updated, err
                  }
       } 

       

      The newSpec is the same b.cachedBackfillSpec passed to SetBackfillReplSpec() and oldSpec is same as this as it is fetched from the cache

      This makes the SameAs a no-op and it never detects a change in spec and it never invokes backfill spec callback handler which then invokes the backfill pipeline.

       

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              ayush.nayyar Ayush Nayyar
              sudeep.jathar Sudeep Jathar
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes

                  PagerDuty