You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by wo...@apache.org on 2019/05/07 20:39:26 UTC

[couchdb] branch 2.3.x updated: Fix epoch mismatch errors (#2027)

This is an automated email from the ASF dual-hosted git repository.

wohali pushed a commit to branch 2.3.x
in repository https://gitbox.apache.org/repos/asf/couchdb.git


The following commit(s) were added to refs/heads/2.3.x by this push:
     new 17f8c22  Fix epoch mismatch errors (#2027)
17f8c22 is described below

commit 17f8c22657fc0e582d5fe55244eed93824679482
Author: Paul J. Davis <pa...@gmail.com>
AuthorDate: Tue May 7 15:06:06 2019 -0500

    Fix epoch mismatch errors (#2027)
    
    Originally we posited that duplicate UUIDs could never be created.
    However due to operations interventions its possible to unintentionally
    copy UUIDs in ways that violate this assumption. Instead of crashing the
    process we just reset the seq to zero and log a warning as was done in
    the other instances when we have mismatches in the epoch history.
---
 src/couch/src/couch_db.erl | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/src/couch/src/couch_db.erl b/src/couch/src/couch_db.erl
index 0ae164d..2cbc297 100644
--- a/src/couch/src/couch_db.erl
+++ b/src/couch/src/couch_db.erl
@@ -1491,7 +1491,14 @@ calculate_start_seq(Db, _Node, {Seq, Uuid, EpochNode}) ->
 calculate_start_seq(Db, _Node, {replace, OriginalNode, Uuid, Seq}) ->
     case is_prefix(Uuid, couch_db:get_uuid(Db)) of
         true ->
-            start_seq(get_epochs(Db), OriginalNode, Seq);
+            try
+                start_seq(get_epochs(Db), OriginalNode, Seq)
+            catch throw:epoch_mismatch ->
+                couch_log:warning("~p start_seq duplicate uuid on node: ~p "
+                    "db: ~p, seq: ~p, uuid: ~p, epoch_node: ~p",
+                    [?MODULE, node(), Db#db.name, Seq, Uuid, OriginalNode]),
+                0
+            end;
         false ->
             {replace, OriginalNode, Uuid, Seq}
     end.
@@ -1538,8 +1545,8 @@ start_seq([{_, NewSeq}, {OrigNode, _} | _], OrigNode, Seq) when Seq > NewSeq ->
     NewSeq;
 start_seq([_ | Rest], OrigNode, Seq) ->
     start_seq(Rest, OrigNode, Seq);
-start_seq([], OrigNode, Seq) ->
-    erlang:error({epoch_mismatch, OrigNode, Seq}).
+start_seq([], _OrigNode, _Seq) ->
+    throw(epoch_mismatch).
 
 
 fold_docs(Db, UserFun, UserAcc) ->
@@ -1917,7 +1924,8 @@ calculate_start_seq_test_() ->
             t_calculate_start_seq_uuid_mismatch(),
             t_calculate_start_seq_is_owner(),
             t_calculate_start_seq_not_owner(),
-            t_calculate_start_seq_raw()
+            t_calculate_start_seq_raw(),
+            t_calculate_start_seq_epoch_mismatch()
         ]
     }.
 
@@ -1962,6 +1970,14 @@ t_calculate_start_seq_raw() ->
         ?assertEqual(13, Seq)
     end).
 
+t_calculate_start_seq_epoch_mismatch() ->
+    ?_test(begin
+        Db = test_util:fake_db([]),
+        SeqIn = {replace, not_this_node, get_uuid(Db), 42},
+        Seq = calculate_start_seq(Db, node1, SeqIn),
+        ?assertEqual(0, Seq)
+    end).
+
 is_owner_test() ->
     ?assertNot(is_owner(foo, 1, [])),
     ?assertNot(is_owner(foo, 1, [{foo, 1}])),