Skip to content

Commit

Permalink
Handle db deletion in couch_db:load_validation_funs
Browse files Browse the repository at this point in the history
Previously there were few problems with load_validation_funs
in the case when clustered database is deleted.

- the calls to load_validation_funs were failing with `internal_server` error [1]
- the deleted database stayed opened because:
  - the caller of the load_validation_funs (update_doc) stayed alive
  - the main_pid of the deleted database wasn't killed either
- there was an infinite loop in ddoc_cache_entry trying to recover ddoc from deleted database

The solution is:
- do not call `recover` for deleted database
- close `main_pid`
- use `erlang:error` to crash the caller

[1] - The stack trace was:
```
{database_does_not_exist,[
    {mem3_shards,load_shards_from_db,"bailey/meta",[
        {file,"src/mem3_shards.erl"},{line,394}]},
    {mem3_shards,load_shards_from_disk,1,[
        {file,"src/mem3_shards.erl"},{line,369}]},
    {mem3_shards,for_db,2,[
        {file,"src/mem3_shards.erl"},{line,54}]},
    {fabric_view_all_docs,go,5,[
        {file,"src/fabric_view_all_docs.erl"},{line,24}]},
    {ddoc_cache_entry_validation_funs,recover,1,[
        {file,"src/ddoc_cache_entry_validation_funs.erl"},{line,33}]},
    {ddoc_cache_entry,do_open,1,[
        {file,"src/ddoc_cache_entry.erl"},{line,294}]}]}
```
  • Loading branch information
iilyak committed Oct 12, 2018
1 parent adebd38 commit 9872b97
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 5 deletions.
3 changes: 3 additions & 0 deletions src/couch/src/couch_db.erl
Expand Up @@ -864,6 +864,9 @@ load_validation_funs(#db{main_pid=Pid, name = <<"shards/", _/binary>>}=Db) ->
{'DOWN', Ref, _, _, {ok, Funs}} ->
gen_server:cast(Pid, {load_validation_funs, Funs}),
Funs;
{'DOWN', Ref, _, _, {database_does_not_exist, _StackTrace}} ->
ok = couch_server:close_db_if_idle(Db#db.name),
erlang:error(database_does_not_exist);
{'DOWN', Ref, _, _, Reason} ->
couch_log:error("could not load validation funs ~p", [Reason]),
throw(internal_server_error)
Expand Down
13 changes: 8 additions & 5 deletions src/ddoc_cache/src/ddoc_cache_entry.erl
Expand Up @@ -106,11 +106,14 @@ open(Pid, Key) ->
{open_error, {T, R, S}} ->
erlang:raise(T, R, S)
end
catch exit:_ ->
% Its possible that this process was evicted just
% before we tried talking to it. Just fallback
% to a standard recovery
recover(Key)
catch
error:database_does_not_exist ->
erlang:error(database_does_not_exist);
exit:_ ->
% Its possible that this process was evicted just
% before we tried talking to it. Just fallback
% to a standard recovery
recover(Key)
end.


Expand Down

0 comments on commit 9872b97

Please sign in to comment.