Skip to content
This repository has been archived by the owner. It is now read-only.
Browse files
Chunk missing revisions before attempting to save on target
In cases with pathological documents revision patterns (e.g., 10000 open
conflicts and tree depth of 300000 on a single document), attempting to
replicate the full revision tree in one batch causes the system to crash by
attempting to send an oversized message. We've observed messages of > 4GB in the

This patch divides the set of revisions-to-replicate for a single document into
chunks of a configurable size, thereby allowing operators to keep the system
stable when attempting to replicate these troublesome documents.

BugzID: 37676
  • Loading branch information
b20n authored and eiri committed Nov 24, 2016
1 parent 252467c commit c4da61c8eb98cedd3cf7a28c293cb1f6d3ec8571
Showing 1 changed file with 30 additions and 2 deletions.
@@ -252,8 +252,10 @@ replicate_batch(#acc{target = #shard{node=Node, name=Name}} = Acc) ->
[] ->
Missing ->
Docs = open_docs(Acc, Missing),
ok = save_on_target(Node, Name, Docs)
lists:map(fun(Chunk) ->
Docs = open_docs(Acc, Chunk),
ok = save_on_target(Node, Name, Docs)
end, chunk_revs(Missing))
{ok, Acc#acc{revcount=0, infos=[]}}.
@@ -271,6 +273,32 @@ find_missing_revs(Acc) ->

chunk_revs(Revs) ->
Limit = list_to_integer(config:get("mem3", "rev_chunk_size", "5000")),
chunk_revs(Revs, Limit).

chunk_revs(Revs, Limit) ->
chunk_revs(Revs, {0, []}, [], Limit).

chunk_revs([], {_Count, Chunk}, Chunks, _Limit) ->
chunk_revs([{Id, R, A}|Revs], {Count, Chunk}, Chunks, Limit) when length(R) =< Limit - Count ->
{Count + length(R), [{Id, R, A}|Chunk]},
chunk_revs([{Id, R, A}|Revs], {Count, Chunk}, Chunks, Limit) ->
{This, Next} = lists:split(Limit - Count, R),
[{Id, Next, A}|Revs],
{0, []},
[[{Id, This, A}|Chunk]|Chunks],

open_docs(#acc{source=Source, infos=Infos}, Missing) ->
lists:flatmap(fun({Id, Revs, _}) ->
FDI = lists:keyfind(Id,, Infos),

0 comments on commit c4da61c

Please sign in to comment.