summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Joseph Davis <davisp@apache.org>2010-02-18 19:55:55 +0000
committerPaul Joseph Davis <davisp@apache.org>2010-02-18 19:55:55 +0000
commit0f3bc594c57d048d329708a6c91edf5bb5be3719 (patch)
tree8cf5a900df7fa783b8ce174dc5df57ead6bd750e /src
parent6c2f190d314c3894a9fddb4c1c3a65f5ddca3060 (diff)
Fixes COUCHDB-640 - Reset views with invalid update seqs.
If a database is restored to a previous version, and the view files are not updated appropriately they will contain data from the database after the reverted-to-update_seq. This patch checks that the update sequence recorded in a view is less than or equal to the update sequence of the database. Patch is by Filipe Manana. Execellent work once again. git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@911544 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/couchdb/couch_view.erl16
-rw-r--r--src/couchdb/couch_view_group.erl30
2 files changed, 33 insertions, 13 deletions
diff --git a/src/couchdb/couch_view.erl b/src/couchdb/couch_view.erl
index f80ce434..cbbbd4ac 100644
--- a/src/couchdb/couch_view.erl
+++ b/src/couchdb/couch_view.erl
@@ -284,6 +284,15 @@ handle_call({get_group_server, DbName,
{ok, NewPid} ->
add_to_ets(NewPid, DbName, Sig),
{reply, {ok, NewPid}, Server};
+ {error, invalid_view_seq} ->
+ do_reset_indexes(DbName, Root),
+ case (catch couch_view_group:start_link({Root, DbName, Group})) of
+ {ok, NewPid} ->
+ add_to_ets(NewPid, DbName, Sig),
+ {reply, {ok, NewPid}, Server};
+ Error ->
+ {reply, Error, Server}
+ end;
Error ->
{reply, Error, Server}
end;
@@ -292,6 +301,10 @@ handle_call({get_group_server, DbName,
end.
handle_cast({reset_indexes, DbName}, #server{root_dir=Root}=Server) ->
+ do_reset_indexes(DbName, Root),
+ {noreply, Server}.
+
+do_reset_indexes(DbName, Root) ->
% shutdown all the updaters and clear the files, the db got changed
Names = ets:lookup(couch_groups_by_db, DbName),
lists:foreach(
@@ -304,8 +317,7 @@ handle_cast({reset_indexes, DbName}, #server{root_dir=Root}=Server) ->
end
end, Names),
delete_index_dir(Root, DbName),
- file:delete(Root ++ "/." ++ binary_to_list(DbName) ++ "_temp"),
- {noreply, Server}.
+ file:delete(Root ++ "/." ++ ?b2l(DbName) ++ "_temp").
handle_info({'EXIT', FromPid, Reason}, Server) ->
case ets:lookup(couch_groups_by_updater, FromPid) of
diff --git a/src/couchdb/couch_view_group.erl b/src/couchdb/couch_view_group.erl
index 6589bc6a..8439304d 100644
--- a/src/couchdb/couch_view_group.erl
+++ b/src/couchdb/couch_view_group.erl
@@ -78,17 +78,25 @@ start_link(InitArgs) ->
init({InitArgs, ReturnPid, Ref}) ->
process_flag(trap_exit, true),
case prepare_group(InitArgs, false) of
- {ok, #group{db=Db, fd=Fd}=Group} ->
- couch_db:monitor(Db),
- Owner = self(),
- Pid = spawn_link(fun()-> couch_view_updater:update(Owner, Group) end),
- {ok, RefCounter} = couch_ref_counter:start([Fd]),
- {ok, #group_state{
- db_name=couch_db:name(Db),
- init_args=InitArgs,
- updater_pid = Pid,
- group=Group,
- ref_counter=RefCounter}};
+ {ok, #group{db=Db, fd=Fd, current_seq=Seq}=Group} ->
+ case Seq > couch_db:get_update_seq(Db) of
+ true ->
+ ReturnPid ! {Ref, self(), {error, invalid_view_seq}},
+ ignore;
+ _ ->
+ couch_db:monitor(Db),
+ Owner = self(),
+ Pid = spawn_link(
+ fun()-> couch_view_updater:update(Owner, Group) end
+ ),
+ {ok, RefCounter} = couch_ref_counter:start([Fd]),
+ {ok, #group_state{
+ db_name=couch_db:name(Db),
+ init_args=InitArgs,
+ updater_pid = Pid,
+ group=Group,
+ ref_counter=RefCounter}}
+ end;
Error ->
ReturnPid ! {Ref, self(), Error},
ignore