@@ -607,82 +607,82 @@ func (verifier *Verifier) ProcessVerifyTask(ctx context.Context, workerNum int,
607607 )
608608
609609 if err != nil {
610- task .Status = verificationTaskFailed
611- verifier .logger .Error ().
612- Err (err ).
613- Int ("workerNum" , workerNum ).
614- Interface ("task" , task .PrimaryKey ).
615- Msg ("Failed to fetch and compare documents for document comparison task." )
616- } else {
617- task .SourceDocumentCount = docsCount
618- task .SourceByteCount = bytesCount
610+ return errors .Wrapf (
611+ err ,
612+ "worker %d failed to process document comparison task %s (namespace: %#q)" ,
613+ workerNum ,
614+ task .PrimaryKey ,
615+ task .QueryFilter .Namespace ,
616+ )
617+ }
619618
620- if len (problems ) == 0 {
621- task .Status = verificationTaskCompleted
619+ task .SourceDocumentCount = docsCount
620+ task .SourceByteCount = bytesCount
621+
622+ if len (problems ) == 0 {
623+ task .Status = verificationTaskCompleted
624+ } else {
625+ task .Status = verificationTaskFailed
626+ // We know we won't change lastGeneration while verification tasks are running, so no mutex needed here.
627+ if verifier .lastGeneration {
628+ verifier .logger .Error ().
629+ Int ("workerNum" , workerNum ).
630+ Interface ("task" , task .PrimaryKey ).
631+ Str ("namespace" , task .QueryFilter .Namespace ).
632+ Int ("mismatchesCount" , len (problems )).
633+ Msg ("Document(s) mismatched, and this is the final generation." )
622634 } else {
623- task .Status = verificationTaskFailed
624- // We know we won't change lastGeneration while verification tasks are running, so no mutex needed here.
625- if verifier .lastGeneration {
626- verifier .logger .Error ().
627- Int ("workerNum" , workerNum ).
628- Interface ("task" , task .PrimaryKey ).
629- Msg ("Document comparison task failed critical section and is a true error." )
630- } else {
631- verifier .logger .Debug ().
632- Int ("workerNum" , workerNum ).
633- Interface ("task" , task .PrimaryKey ).
634- Msg ("Document comparison task failed, but it may pass in the next generation." )
635-
636- var mismatches []VerificationResult
637- var missingIds []interface {}
638- var dataSizes []int
639-
640- // This stores all IDs for the next generation to check.
641- // Its length should equal len(mismatches) + len(missingIds).
642- var idsToRecheck []interface {}
643-
644- for _ , mismatch := range problems {
645- idsToRecheck = append (idsToRecheck , mismatch .ID )
646- dataSizes = append (dataSizes , mismatch .dataSize )
647-
648- if mismatch .Details == Missing {
649- missingIds = append (missingIds , mismatch .ID )
650- } else {
651- mismatches = append (mismatches , mismatch )
652- }
635+ verifier .logger .Debug ().
636+ Int ("workerNum" , workerNum ).
637+ Interface ("task" , task .PrimaryKey ).
638+ Str ("namespace" , task .QueryFilter .Namespace ).
639+ Int ("mismatchesCount" , len (problems )).
640+ Msg ("Document comparison task failed, but it may pass in the next generation." )
641+
642+ var mismatches []VerificationResult
643+ var missingIds []interface {}
644+ var dataSizes []int
645+
646+ // This stores all IDs for the next generation to check.
647+ // Its length should equal len(mismatches) + len(missingIds).
648+ var idsToRecheck []interface {}
649+
650+ for _ , mismatch := range problems {
651+ idsToRecheck = append (idsToRecheck , mismatch .ID )
652+ dataSizes = append (dataSizes , mismatch .dataSize )
653+
654+ if mismatch .Details == Missing {
655+ missingIds = append (missingIds , mismatch .ID )
656+ } else {
657+ mismatches = append (mismatches , mismatch )
653658 }
659+ }
654660
655- // Update ids of the failed task so that only mismatches and
656- // missing are reported. Matching documents are thus hidden
657- // from the progress report.
658- task .Ids = missingIds
659- task .FailedDocs = mismatches
660-
661- // Create a task for the next generation to recheck the
662- // mismatched & missing docs.
663- err := verifier .InsertFailedCompareRecheckDocs (ctx , task .QueryFilter .Namespace , idsToRecheck , dataSizes )
664- if err != nil {
665- verifier .logger .Error ().
666- Err (err ).
667- Int ("workerNum" , workerNum ).
668- Interface ("task" , task .PrimaryKey ).
669- Int ("rechecksCount" , len (idsToRecheck )).
670- Msg ("Failed to enqueue rechecks after document mismatches." )
671- }
661+ // Update ids of the failed task so that only mismatches and
662+ // missing are reported. Matching documents are thus hidden
663+ // from the progress report.
664+ task .Ids = missingIds
665+ task .FailedDocs = mismatches
666+
667+ // Create a task for the next generation to recheck the
668+ // mismatched & missing docs.
669+ err := verifier .InsertFailedCompareRecheckDocs (ctx , task .QueryFilter .Namespace , idsToRecheck , dataSizes )
670+ if err != nil {
671+ return errors .Wrapf (
672+ err ,
673+ "failed to enqueue %d recheck(s) of mismatched documents" ,
674+ len (idsToRecheck ),
675+ )
672676 }
673677 }
674678 }
675679
676- updateErr := verifier .UpdateVerificationTask (ctx , task )
677- if updateErr != nil {
678- verifier .logger .Error ().
679- Err (updateErr ).
680- Int ("workerNum" , workerNum ).
681- Interface ("task" , task .PrimaryKey ).
682- Msg ("Failed to update task status." )
683- }
684-
685- return err
680+ return errors .Wrapf (
681+ verifier .UpdateVerificationTask (ctx , task ),
682+ "failed to persist task %s's new status (%#q)" ,
683+ task .PrimaryKey ,
684+ task .Status ,
685+ )
686686}
687687
688688func (verifier * Verifier ) logChunkInfo (ctx context.Context , namespaceAndUUID * uuidutil.NamespaceAndUUID ) {
@@ -822,28 +822,28 @@ func (verifier *Verifier) partitionAndInspectNamespace(ctx context.Context, name
822822func (verifier * Verifier ) compareCollectionSpecifications (
823823 srcNs , dstNs string ,
824824 srcSpecOpt , dstSpecOpt option.Option [util.CollectionSpec ],
825- ) ([]VerificationResult , bool ) {
825+ ) ([]VerificationResult , bool , error ) {
826826 srcSpec , hasSrcSpec := srcSpecOpt .Get ()
827827 dstSpec , hasDstSpec := dstSpecOpt .Get ()
828828
829829 if ! hasSrcSpec {
830830 return []VerificationResult {{
831831 NameSpace : srcNs ,
832832 Cluster : ClusterSource ,
833- Details : Missing }}, false
833+ Details : Missing }}, false , nil
834834 }
835835 if ! hasDstSpec {
836836 return []VerificationResult {{
837837 NameSpace : dstNs ,
838838 Cluster : ClusterTarget ,
839- Details : Missing }}, false
839+ Details : Missing }}, false , nil
840840 }
841841 if srcSpec .Type != dstSpec .Type {
842842 return []VerificationResult {{
843843 NameSpace : srcNs ,
844844 Cluster : ClusterTarget ,
845845 Field : "Type" ,
846- Details : Mismatch + fmt .Sprintf (" : src: %v, dst: %v" , srcSpec .Type , dstSpec .Type )}}, false
846+ Details : Mismatch + fmt .Sprintf (" : src: %v, dst: %v" , srcSpec .Type , dstSpec .Type )}}, false , nil
847847 // If the types differ, the rest is not important.
848848 }
849849 var results []VerificationResult
@@ -857,13 +857,11 @@ func (verifier *Verifier) compareCollectionSpecifications(
857857 if ! bytes .Equal (srcSpec .Options , dstSpec .Options ) {
858858 mismatchDetails , err := BsonUnorderedCompareRawDocumentWithDetails (srcSpec .Options , dstSpec .Options )
859859 if err != nil {
860- verifier .logger .Error ().Msgf ("Unable to parse collection options for %s: %+v" , srcNs , err )
861- results = append (results , VerificationResult {
862- NameSpace : dstNs ,
863- Cluster : ClusterTarget ,
864- Field : "Options" ,
865- Details : "ParseError " + fmt .Sprintf ("%v" , err )})
866- return results , false
860+ return nil , false , errors .Wrapf (
861+ err ,
862+ "failed to compare namespace %#q's specifications" ,
863+ srcNs ,
864+ )
867865 }
868866 if mismatchDetails == nil {
869867 results = append (results , VerificationResult {
@@ -881,7 +879,7 @@ func (verifier *Verifier) compareCollectionSpecifications(
881879 // Do not compare data between capped and uncapped collections because the partitioning is different.
882880 canCompareData = canCompareData && srcSpec .Options .Lookup ("capped" ).Equal (dstSpec .Options .Lookup ("capped" ))
883881
884- return results , canCompareData
882+ return results , canCompareData , nil
885883}
886884
887885func (verifier * Verifier ) doIndexSpecsMatch (ctx context.Context , srcSpec bson.Raw , dstSpec bson.Raw ) (bool , error ) {
@@ -1170,7 +1168,14 @@ func (verifier *Verifier) verifyMetadataAndPartitionCollection(
11701168 // Fall through here; comparing the collection specifications will produce the correct
11711169 // failure output.
11721170 }
1173- specificationProblems , verifyData := verifier .compareCollectionSpecifications (srcNs , dstNs , srcSpecOpt , dstSpecOpt )
1171+ specificationProblems , verifyData , err := verifier .compareCollectionSpecifications (srcNs , dstNs , srcSpecOpt , dstSpecOpt )
1172+ if err != nil {
1173+ return errors .Wrapf (
1174+ err ,
1175+ "failed to compare collection %#q's specifications" ,
1176+ srcNs ,
1177+ )
1178+ }
11741179 if specificationProblems != nil {
11751180 err := insertFailedCollection ()
11761181 if err != nil {
0 commit comments