You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by fd...@apache.org on 2011/08/27 09:30:35 UTC

svn commit: r1162306 - in /couchdb/branches/1.1.x/src/couchdb: couch_rep_reader.erl couch_rep_writer.erl

Author: fdmanana
Date: Sat Aug 27 07:30:35 2011
New Revision: 1162306

URL: http://svn.apache.org/viewvc?rev=1162306&view=rev
Log:
Fix replication crash on database compaction

There were race conditions that made replications crash
when a local endpoint database is compacted.
Patch tested by Joan Touzet.


Modified:
    couchdb/branches/1.1.x/src/couchdb/couch_rep_reader.erl
    couchdb/branches/1.1.x/src/couchdb/couch_rep_writer.erl

Modified: couchdb/branches/1.1.x/src/couchdb/couch_rep_reader.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/src/couchdb/couch_rep_reader.erl?rev=1162306&r1=1162305&r2=1162306&view=diff
==============================================================================
--- couchdb/branches/1.1.x/src/couchdb/couch_rep_reader.erl (original)
+++ couchdb/branches/1.1.x/src/couchdb/couch_rep_reader.erl Sat Aug 27 07:30:35 2011
@@ -244,7 +244,7 @@ reader_loop(ReaderServer, Parent, Source
     case couch_rep_missing_revs:next(MissingRevsServer) of
     complete ->
         exit(complete);
-    {HighSeq, IdsRevs} ->
+    {_HighSeq, IdsRevs} ->
         % to be safe, make sure Results are sorted by source_seq
         SortedIdsRevs = lists:keysort(2, IdsRevs),
         RequestSeqs = [S || {_,S,_} <- SortedIdsRevs],
@@ -256,7 +256,8 @@ reader_loop(ReaderServer, Parent, Source
             reader_loop(ReaderServer, Parent, Source, MissingRevsServer);
         _Local ->
             {ok, Source1} = gen_server:call(Parent, get_source_db, infinity),
-            Source2 = maybe_reopen_db(Source1, HighSeq),
+            {ok, Source2} = couch_db:open(
+                Source1#db.name, [{user_ctx, Source1#db.user_ctx}]),
             lists:foreach(fun({Id,Seq,Revs}) ->
                 {ok, Docs} = couch_db:open_doc_revs(Source2, Id, Revs, [latest]),
                 JustTheDocs = [Doc || {ok, Doc} <- Docs],
@@ -268,12 +269,6 @@ reader_loop(ReaderServer, Parent, Source
         end
     end.
 
-maybe_reopen_db(#db{update_seq=OldSeq} = Db, HighSeq) when HighSeq > OldSeq ->
-    {ok, NewDb} = couch_db:open(Db#db.name, [{user_ctx, Db#db.user_ctx}]),
-    NewDb;
-maybe_reopen_db(Db, _HighSeq) ->
-    Db.
-
 spawn_document_request(Source, Id, Seq, Revs) ->
     Server = self(),
     SpawnFun = fun() ->

Modified: couchdb/branches/1.1.x/src/couchdb/couch_rep_writer.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/src/couchdb/couch_rep_writer.erl?rev=1162306&r1=1162305&r2=1162306&view=diff
==============================================================================
--- couchdb/branches/1.1.x/src/couchdb/couch_rep_writer.erl (original)
+++ couchdb/branches/1.1.x/src/couchdb/couch_rep_writer.erl Sat Aug 27 07:30:35 2011
@@ -26,7 +26,8 @@ writer_loop(Parent, Reader) ->
         ok;
     {HighSeq, Docs} ->
         DocCount = length(Docs),
-        {ok, Target} = gen_server:call(Parent, get_target_db, infinity),
+        {ok, Target0} = gen_server:call(Parent, get_target_db, infinity),
+        Target = open_db(Target0),
         try write_docs(Target, Docs) of
         {ok, []} ->
             Parent ! {update_stats, docs_written, DocCount};
@@ -38,6 +39,8 @@ writer_loop(Parent, Reader) ->
         {attachment_request_failed, Err} ->
             ?LOG_DEBUG("writer failed to write an attachment ~p", [Err]),
             exit({attachment_request_failed, Err, Docs})
+        after
+            close_db(Target)
         end,
         Parent ! {writer_checkpoint, HighSeq},
         couch_rep_att:cleanup(),
@@ -163,3 +166,14 @@ write_docs_1({Props}) ->
     ErrId = couch_util:to_existing_atom(couch_util:get_value(<<"error">>, Props)),
     Reason = couch_util:get_value(<<"reason">>, Props),
     {{Id, Rev}, {ErrId, Reason}}.
+
+open_db(#db{name = Name, user_ctx = UserCtx}) ->
+    {ok, Db} = couch_db:open(Name, [{user_ctx, UserCtx}]),
+    Db;
+open_db(HttpDb) ->
+    HttpDb.
+
+close_db(#db{} = Db) ->
+    couch_db:close(Db);
+close_db(_HttpDb) ->
+    ok.