Skip to content

Commit a446cdc

Browse files
committed
Use dreyfus checkpoint for purge_seq
Previously, in the index updater we used the purge_seq value from clouseau. In some cases that can return an older value (0 on a new index) than what is in the purge checkpoint doc created in `maybe_create_local_purge_doc/2`. (In that function we initialize the checkpoint with the db purge sequence and call `clouseau_rpc:set_purge_seq/1` to also set the clouseau purge seq value). An older purge sequence than the current minimum db purge sequence would result in an `invalid_start_purge_seq` being thrown during purged infos folding. In general, if a client updates a purge checkpoint, then it should not query purged infos with a sequence value below that, since if that is the lowest current purge checkpoint value and compaction runs, it could have removed all the purged infos below that.
1 parent 3afc6fd commit a446cdc

1 file changed

Lines changed: 17 additions & 9 deletions

File tree

src/dreyfus/src/dreyfus_index_updater.erl

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ update(IndexPid, Index) ->
3030
erlang:put(io_priority, {search, DbName, IndexName}),
3131
{ok, Db} = couch_db:open_int(DbName, []),
3232
try
33+
IdxPurgeSeq = get_local_doc_purge_seq(Db, Index),
34+
DbPurgeSeq = couch_db:get_purge_seq(Db),
35+
TotalPurgeChanges = DbPurgeSeq - IdxPurgeSeq,
3336
TotalUpdateChanges = couch_db:count_changes_since(Db, CurSeq),
34-
TotalPurgeChanges = count_pending_purged_docs_since(Db, IndexPid),
3537
TotalChanges = TotalUpdateChanges + TotalPurgeChanges,
3638

3739
couch_task_status:add_task([
@@ -49,7 +51,7 @@ update(IndexPid, Index) ->
4951

5052
%ExcludeIdRevs is [{Id1, Rev1}, {Id2, Rev2}, ...]
5153
%The Rev is the final Rev, not purged Rev.
52-
{ok, ExcludeIdRevs} = purge_index(Db, IndexPid, Index),
54+
{ok, ExcludeIdRevs} = purge_index(Db, IndexPid, Index, IdxPurgeSeq),
5355
%% compute on all docs modified since we last computed.
5456

5557
NewCurSeq = couch_db:get_update_seq(Db),
@@ -87,8 +89,12 @@ load_docs(FDI, {I, IndexPid, Db, Proc, Total, LastCommitTime, ExcludeIdRevs} = A
8789
{ok, setelement(1, Acc, I + 1)}
8890
end.
8991

90-
purge_index(Db, IndexPid, Index) ->
91-
{ok, IdxPurgeSeq} = clouseau_rpc:get_purge_seq(IndexPid),
92+
purge_index(Db, IndexPid, Index, IdxPurgeSeq) ->
93+
% Note: we're not using IdxPurgeSeq = clouseau_rpc:get_purge_seq/1 as that
94+
% might return the stale (committed) value and not the newly updated purge
95+
% seq we just set in maybe_create_local_purge_doc/3 on new doc creation.
96+
% Using an old value could result in the invalid_start_purge_seq exception
97+
% being raised when folding over purged infos.
9298
Proc = get_os_process(Index#index.def_lang),
9399
try
94100
true = proc_prompt(Proc, [<<"add_fun">>, Index#index.def]),
@@ -120,11 +126,6 @@ purge_index(Db, IndexPid, Index) ->
120126
ret_os_process(Proc)
121127
end.
122128

123-
count_pending_purged_docs_since(Db, IndexPid) ->
124-
DbPurgeSeq = couch_db:get_purge_seq(Db),
125-
{ok, IdxPurgeSeq} = clouseau_rpc:get_purge_seq(IndexPid),
126-
DbPurgeSeq - IdxPurgeSeq.
127-
128129
update_or_delete_index(IndexPid, Db, DI, Proc) ->
129130
#doc_info{id = Id, revs = [#rev_info{deleted = Del} | _]} = DI,
130131
case Del of
@@ -152,6 +153,13 @@ update_local_doc(Db, Index, PurgeSeq) ->
152153
DocContent = dreyfus_util:get_local_purge_doc_body(Db, DocId, PurgeSeq, Index),
153154
couch_db:update_doc(Db, DocContent, []).
154155

156+
get_local_doc_purge_seq(Db, Index) ->
157+
DocId = dreyfus_util:get_local_purge_doc_id(Index#index.sig),
158+
% We're implicitly asserting this purge checkpoint doc should exist. This is
159+
% created either on open or during compaction in on_compact handler
160+
{ok, #doc{body = {[_ | _] = Props}}} = couch_db:open_doc(Db, DocId),
161+
couch_util:get_value(<<"purge_seq">>, Props).
162+
155163
update_task(NumChanges) ->
156164
[Changes, Total] = couch_task_status:get([changes_done, total_changes]),
157165
Changes2 = Changes + NumChanges,

0 commit comments

Comments
 (0)