You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2019/09/24 06:40:02 UTC

[couchdb] branch fix-doc-counts-for-replicated-deletions created (now 8aa5798)

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

vatamane pushed a change to branch fix-doc-counts-for-replicated-deletions
in repository https://gitbox.apache.org/repos/asf/couchdb.git.


      at 8aa5798  Fix doc counts for replicated deletions

This branch includes the following new commits:

     new 8aa5798  Fix doc counts for replicated deletions

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[couchdb] 01/01: Fix doc counts for replicated deletions

Posted by va...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a commit to branch fix-doc-counts-for-replicated-deletions
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 8aa5798490edb34f1f35e05e9fd78eec39aac61c
Author: Nick Vatamaniuc <va...@apache.org>
AuthorDate: Tue Sep 24 02:25:39 2019 -0400

    Fix doc counts for replicated deletions
    
    Do not decrement `doc_count` stat if document was previosuly missing, or if it
    was already deleted.
    
    Deleted documents could be brought in by replication. In that case, if there
    were more replicated documents than the current `doc_count`, the `doc_count`
    could even underflow the 64 bit unsigned integer range and end up somewhere in
    the vicinity of 2^64. The counter, of course, would still be incorrect even if
    it didn't underflow, the huge value would just make the issue more visible.
---
 src/fabric/src/fabric2_fdb.erl              |  8 ++++++--
 src/fabric/test/fabric2_doc_count_tests.erl | 25 +++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/src/fabric/src/fabric2_fdb.erl b/src/fabric/src/fabric2_fdb.erl
index ccfeb3c..ab8f32f 100644
--- a/src/fabric/src/fabric2_fdb.erl
+++ b/src/fabric/src/fabric2_fdb.erl
@@ -556,7 +556,7 @@ write_doc(#{} = Db0, Doc, NewWinner0, OldWinner, ToUpdate, ToRemove) ->
         {not_found, #{deleted := false}} ->
             created;
         {not_found, #{deleted := true}} ->
-            deleted;
+            replicate_deleted;
         {#{deleted := true}, #{deleted := false}} ->
             recreated;
         {#{deleted := false}, #{deleted := false}} ->
@@ -564,10 +564,12 @@ write_doc(#{} = Db0, Doc, NewWinner0, OldWinner, ToUpdate, ToRemove) ->
         {#{deleted := false}, #{deleted := true}} ->
             deleted;
         {#{deleted := true}, #{deleted := true}} ->
-            deleted
+            replicate_deleted
     end,
 
     case UpdateStatus of
+        replicate_deleted ->
+            ok;
         deleted ->
             ADKey = erlfdb_tuple:pack({?DB_ALL_DOCS, DocId}, DbPrefix),
             ok = erlfdb:clear(Tx, ADKey);
@@ -614,6 +616,8 @@ write_doc(#{} = Db0, Doc, NewWinner0, OldWinner, ToUpdate, ToRemove) ->
             end,
             incr_stat(Db, <<"doc_count">>, 1),
             incr_stat(Db, <<"doc_del_count">>, -1);
+        replicate_deleted ->
+            incr_stat(Db, <<"doc_del_count">>, 1);
         deleted ->
             if not IsDDoc -> ok; true ->
                 incr_stat(Db, <<"doc_design_count">>, -1)
diff --git a/src/fabric/test/fabric2_doc_count_tests.erl b/src/fabric/test/fabric2_doc_count_tests.erl
index 37d0840..915144a 100644
--- a/src/fabric/test/fabric2_doc_count_tests.erl
+++ b/src/fabric/test/fabric2_doc_count_tests.erl
@@ -30,6 +30,7 @@ doc_count_test_() ->
             fun cleanup/1,
             {with, [
                 fun normal_docs/1,
+                fun replicated_docs/1,
                 fun design_docs/1,
                 fun local_docs/1
             ]}
@@ -109,6 +110,30 @@ normal_docs({Db, _}) ->
         ).
 
 
+replicated_docs({Db, _}) ->
+    {DocCount, DelDocCount, DDocCount, LDocCount} = get_doc_counts(Db),
+
+    Opts = [replicated_changes],
+    {R1, R2, R3} = {<<"r1">>, <<"r2">>, <<"r3">>},
+
+    % First case is a simple replicated update
+    Doc1 = #doc{id = <<"rd1">>, revs = {1, [R1]}},
+    {ok, {1, R1}} = fabric2_db:update_doc(Db, Doc1, Opts),
+    check_doc_counts(Db, DocCount + 1, DelDocCount, DDocCount, LDocCount),
+
+    % Here a deleted document is replicated into the db. Doc count should not
+    % change, only deleted doc count.
+    Doc2 = #doc{id = <<"rd2">>, revs = {1, [R2]}, deleted = true},
+    {ok, {1, R2}} = fabric2_db:update_doc(Db, Doc2, Opts),
+    check_doc_counts(Db, DocCount + 1, DelDocCount + 1, DDocCount, LDocCount),
+
+    % Here we extended the deleted document's rev path but keep it deleted.
+    % Again, only deleted doc count should be bumped.
+    Doc3 = #doc{id = <<"rd2">>, revs = {2, [R3, R2]}, deleted = true},
+    {ok, {2, R3}} = fabric2_db:update_doc(Db, Doc3, Opts),
+    check_doc_counts(Db, DocCount + 1, DelDocCount + 2 , DDocCount, LDocCount).
+
+
 design_docs({Db, _}) ->
     {DocCount, DelDocCount, DDocCount, LDocCount} = get_doc_counts(Db),