Details
-
Bug
-
Resolution: Duplicate
-
Critical
-
None
-
None
-
Untriaged
-
0
-
Unknown
Description
Consider a case where for a document, we have a non-import mutation at source and an import mutation at target.
The current implementation with revID conflict resolution in the mobile active mode is as follows:
Getting target mutation metadata for revID conflict resolution:
func (doc *TargetDocument) GetMetadata() (*CRMetadata, error) {
|
...
|
if importCas == cas { |
// This is an import mutation. cvCas represents the pre-import CAS and that is used for CR |
// Pre-import revId is not used. So we cannot use revId. set it to 0 |
meta.isImport = true |
meta.actualCas = cas
|
docMeta.Cas = cvCas
|
docMeta.RevSeq = 0 |
}
|
...
|
}
|
We set revSeq to 0 and we use this in the main conflict resolution logic to decide which mutation "wins".
We follow the same logic for getting source mutation metadata, but since in this case it is non-import mutation, revSeq is left untouched i.e. non-zero.
This implies that source mutation always "wins" in this case and potentially could break the "most-write-wins" guarantee.
Example:
Consider a one way replication from A to B:
A's doc:
|
revSeq = 1
|
CAS = 10
|
|
B's doc:
|
revSeq = 5
|
CAS = 30
|
importCAS = 30
|
cvCAS = 20
|
If now A's doc is mutated resulting in revSeq = 2 mutation, after replicating we get a convergent state of:
A's doc:
|
revSeq = 2
|
CAS = 40
|
|
B's doc:
|
revSeq = 2
|
CAS = 40
|
since A's doc.revSeq (=2) is greater than B's doc.revSeq (set to 0, since it is an import mutation), breaking the "most-write-wins" promise.
Attachments
Issue Links
- duplicates
-
MB-60897 XDCR - accomodate SGW xattr change from "import" to "_mou"
- In Progress