You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2014/08/28 14:21:12 UTC

[37/50] fabric commit: updated refs/heads/master to a71701c

Include epoch node in seqs and replacement logic

The {Seq, UUID, Node} triplet uniquely identifies an update in a
cluster.  Including the node that originally accepted the update in
sequences allows us to defend against byzantine cases of shards moving
back and forth between the nodes in a cluster.

This patch updates the sequence generation to include the full triplet
in each element of the _changes sequence.  It also uses the epoch node
instead of the node currently hosting the shard when determining the
safe replacement sequence.

BugzID: 27193


Project: http://git-wip-us.apache.org/repos/asf/couchdb-fabric/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-fabric/commit/74e4a791
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-fabric/tree/74e4a791
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-fabric/diff/74e4a791

Branch: refs/heads/master
Commit: 74e4a7916da5e3c7400e6d0affd39482647be8b7
Parents: 8cefcd8
Author: Adam Kocoloski <ad...@cloudant.com>
Authored: Thu Jan 16 17:32:48 2014 -0800
Committer: Robert Newson <rn...@apache.org>
Committed: Fri Aug 1 15:33:43 2014 +0100

----------------------------------------------------------------------
 src/fabric_rpc.erl          | 18 +++++++++++-------
 src/fabric_view_changes.erl | 11 ++++++-----
 2 files changed, 17 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-fabric/blob/74e4a791/src/fabric_rpc.erl
----------------------------------------------------------------------
diff --git a/src/fabric_rpc.erl b/src/fabric_rpc.erl
index b398969..6c0d47a 100644
--- a/src/fabric_rpc.erl
+++ b/src/fabric_rpc.erl
@@ -32,7 +32,8 @@
     seq,
     args,
     options,
-    pending
+    pending,
+    epochs
 }).
 
 %% rpc endpoints
@@ -57,7 +58,8 @@ changes(DbName, Options, StartVector, DbOptions) ->
           seq = StartSeq,
           args = Args,
           options = Options,
-          pending = couch_db:count_changes_since(Db, StartSeq)
+          pending = couch_db:count_changes_since(Db, StartSeq),
+          epochs = get_epochs(Db)
         },
         try
             {ok, #cacc{seq=LastSeq, pending=Pending}} =
@@ -321,7 +323,8 @@ changes_enumerator(DocInfo, Acc) ->
         db = Db,
         args = #changes_args{include_docs = IncludeDocs, filter = Filter},
         options = Options,
-        pending = Pending
+        pending = Pending,
+        epochs = Epochs
     } = Acc,
     Conflicts = proplists:get_value(conflicts, Options, false),
     #doc_info{id=Id, high_seq=Seq, revs=[#rev_info{deleted=Del}|_]} = DocInfo,
@@ -332,7 +335,7 @@ changes_enumerator(DocInfo, Acc) ->
         Opts = if Conflicts -> [conflicts]; true -> [] end,
         ChangesRow = {change, [
 	    {pending, Pending-1},
-            {seq, {Seq, uuid(Db)}},
+            {seq, {Seq, uuid(Db), owner_of(Seq, Epochs)}},
             {id, Id},
             {changes, Results},
             {deleted, Del} |
@@ -424,12 +427,13 @@ set_io_priority(DbName, Options) ->
 
 calculate_start_seq(_Db, _Node, Seq) when is_integer(Seq) ->
     Seq;
-calculate_start_seq(Db, Node, {Seq, Uuid, _}) -> % downgrade clause
-    calculate_start_seq(Db, Node, {Seq, Uuid});
 calculate_start_seq(Db, Node, {Seq, Uuid}) ->
+    % Treat the current node as the epoch node
+    calculate_start_seq(Db, Node, {Seq, Uuid, Node});
+calculate_start_seq(Db, Node, {Seq, Uuid, EpochNode}) ->
     case is_prefix(Uuid, couch_db:get_uuid(Db)) of
         true ->
-            case is_owner(Node, Seq, couch_db:get_epochs(Db)) of
+            case is_owner(EpochNode, Seq, couch_db:get_epochs(Db)) of
                 true -> Seq;
                 false -> 0
             end;

http://git-wip-us.apache.org/repos/asf/couchdb-fabric/blob/74e4a791/src/fabric_view_changes.erl
----------------------------------------------------------------------
diff --git a/src/fabric_view_changes.erl b/src/fabric_view_changes.erl
index c4eab22..34670c9 100644
--- a/src/fabric_view_changes.erl
+++ b/src/fabric_view_changes.erl
@@ -305,10 +305,11 @@ handle_message({complete, Props}, Worker, State) ->
 
 make_replacement_arg(Node, {Seq, Uuid}) ->
     {replace, Node, Uuid, Seq};
-make_replacement_arg(Node, {Seq, Uuid, _}) ->
-    %% TODO Deprecated, remove when we're confident no seqs with this format
-    %% are in the wild
-    {replace, Node, Uuid, Seq};
+make_replacement_arg(_Node, {Seq, Uuid, EpochNode}) ->
+    % The replacement should properly be computed aginst the node that owned
+    % the sequence when it was written to disk (the EpochNode) rather than the
+    % node we're trying to replace.
+    {replace, EpochNode, Uuid, Seq};
 make_replacement_arg(_, _) ->
     0.
 
@@ -347,7 +348,7 @@ pack_seqs(Workers) ->
     Opaque = couch_util:encodeBase64Url(term_to_binary(SeqList, [compressed])),
     [SeqSum, Opaque].
 
-seq({Seq, _Uuid, _Node}) -> Seq; % downgrade clause
+seq({Seq, _Uuid, _Node}) -> Seq;
 seq({Seq, _Uuid}) -> Seq;
 seq(Seq)          -> Seq.