summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriilyak <iilyak@ca.ibm.com>2017-04-28 12:28:03 -0700
committerGitHub <noreply@github.com>2017-04-28 12:28:03 -0700
commit350a67b3bc2372b4a88649768805deb896c86451 (patch)
treea8598c61e6b97ecbcb9b33735685fcca6145e97a
parent28dd801810b991d06d2c8d86687176e48eb55108 (diff)
parent8d888d76f26726c1da3e97384e9ecedd8ef077f8 (diff)
downloadcouchdb-350a67b3bc2372b4a88649768805deb896c86451.tar.gz
Merge pull request #490 from cloudant/revert-Add-sys_dbs-to-LRU
Revert add sys dbs to lru
-rw-r--r--src/couch/src/couch_db_updater.erl7
-rw-r--r--src/couch/src/couch_file.erl22
-rw-r--r--src/couch/src/couch_server.erl93
-rw-r--r--src/couch/test/couchdb_views_tests.erl2
4 files changed, 88 insertions, 36 deletions
diff --git a/src/couch/src/couch_db_updater.erl b/src/couch/src/couch_db_updater.erl
index 270fffe46..78726358e 100644
--- a/src/couch/src/couch_db_updater.erl
+++ b/src/couch/src/couch_db_updater.erl
@@ -61,7 +61,12 @@ init({DbName, Filepath, Fd, Options}) ->
end
end,
Db = init_db(DbName, Filepath, Fd, Header, Options),
- couch_stats_process_tracker:track([couchdb, open_databases]),
+ case lists:member(sys_db, Options) of
+ false ->
+ couch_stats_process_tracker:track([couchdb, open_databases]);
+ true ->
+ ok
+ end,
% we don't load validation funs here because the fabric query is liable to
% race conditions. Instead see couch_db:validate_doc_update, which loads
% them lazily
diff --git a/src/couch/src/couch_file.erl b/src/couch/src/couch_file.erl
index d7b176e98..d40c525f2 100644
--- a/src/couch/src/couch_file.erl
+++ b/src/couch/src/couch_file.erl
@@ -362,7 +362,7 @@ init({Filepath, Options, ReturnPid, Ref}) ->
{ok, 0} = file:position(Fd, 0),
ok = file:truncate(Fd),
ok = file:sync(Fd),
- couch_stats_process_tracker:track([couchdb, open_os_files]),
+ maybe_track_open_os_files(Options),
erlang:send_after(?INITIAL_WAIT, self(), maybe_close),
{ok, #file{fd=Fd, is_sys=IsSys, pread_limit=Limit}};
false ->
@@ -370,7 +370,7 @@ init({Filepath, Options, ReturnPid, Ref}) ->
init_status_error(ReturnPid, Ref, {error, eexist})
end;
false ->
- couch_stats_process_tracker:track([couchdb, open_os_files]),
+ maybe_track_open_os_files(Options),
erlang:send_after(?INITIAL_WAIT, self(), maybe_close),
{ok, #file{fd=Fd, is_sys=IsSys, pread_limit=Limit}}
end;
@@ -385,7 +385,7 @@ init({Filepath, Options, ReturnPid, Ref}) ->
%% Save Fd in process dictionary for debugging purposes
put(couch_file_fd, {Fd, Filepath}),
ok = file:close(Fd_Read),
- couch_stats_process_tracker:track([couchdb, open_os_files]),
+ maybe_track_open_os_files(Options),
{ok, Eof} = file:position(Fd, eof),
erlang:send_after(?INITIAL_WAIT, self(), maybe_close),
{ok, #file{fd=Fd, eof=Eof, is_sys=IsSys, pread_limit=Limit}};
@@ -402,6 +402,14 @@ file_open_options(Options) ->
[append]
end.
+maybe_track_open_os_files(Options) ->
+ case not lists:member(sys_db, Options) of
+ true ->
+ couch_stats_process_tracker:track([couchdb, open_os_files]);
+ false ->
+ ok
+ end.
+
terminate(_Reason, #file{fd = nil}) ->
ok;
terminate(_Reason, #file{fd = Fd}) ->
@@ -668,7 +676,13 @@ split_iolist([Byte | Rest], SplitAt, BeginAcc) when is_integer(Byte) ->
split_iolist(Rest, SplitAt - 1, [Byte | BeginAcc]).
-is_idle(#file{}) ->
+% System dbs aren't monitored by couch_stats_process_tracker
+is_idle(#file{is_sys=true}) ->
+ case process_info(self(), monitored_by) of
+ {monitored_by, []} -> true;
+ _ -> false
+ end;
+is_idle(#file{is_sys=false}) ->
Tracker = whereis(couch_stats_process_tracker),
case process_info(self(), monitored_by) of
{monitored_by, []} -> true;
diff --git a/src/couch/src/couch_server.erl b/src/couch/src/couch_server.erl
index 115230029..ad2a5f0ec 100644
--- a/src/couch/src/couch_server.erl
+++ b/src/couch/src/couch_server.erl
@@ -73,8 +73,8 @@ sup_start_link() ->
open(DbName, Options0) ->
Ctx = couch_util:get_value(user_ctx, Options0, #user_ctx{}),
case ets:lookup(couch_dbs, DbName) of
- [#db{fd=Fd, fd_monitor=Lock} = Db] when Lock =/= locked ->
- update_lru(DbName),
+ [#db{fd=Fd, fd_monitor=Lock, options=Options} = Db] when Lock =/= locked ->
+ update_lru(DbName, Options),
{ok, Db#db{user_ctx=Ctx, fd_monitor=erlang:monitor(process,Fd)}};
_ ->
Options = maybe_add_sys_db_callbacks(DbName, Options0),
@@ -91,8 +91,11 @@ open(DbName, Options0) ->
end
end.
-update_lru(DbName) ->
- gen_server:cast(couch_server, {update_lru, DbName}).
+update_lru(DbName, Options) ->
+ case lists:member(sys_db, Options) of
+ false -> gen_server:cast(couch_server, {update_lru, DbName});
+ true -> ok
+ end.
close_lru() ->
gen_server:call(couch_server, close_lru).
@@ -268,15 +271,21 @@ all_databases(Fun, Acc0) ->
{ok, FinalAcc}.
+make_room(Server, Options) ->
+ case lists:member(sys_db, Options) of
+ false -> maybe_close_lru_db(Server);
+ true -> {ok, Server}
+ end.
+
maybe_close_lru_db(#server{dbs_open=NumOpen, max_dbs_open=MaxOpen}=Server)
when NumOpen < MaxOpen ->
{ok, Server};
maybe_close_lru_db(#server{lru=Lru}=Server) ->
case couch_lru:close(Lru) of
- false ->
- {ok, Server};
{true, NewLru} ->
- maybe_close_lru_db(db_closed(Server#server{lru = NewLru}))
+ {ok, db_closed(Server#server{lru = NewLru}, [])};
+ false ->
+ {error, all_dbs_active}
end.
open_async(Server, From, DbName, Filepath, Options) ->
@@ -308,14 +317,14 @@ open_async(Server, From, DbName, Filepath, Options) ->
options = Options
}),
true = ets:insert(couch_dbs_pid_to_name, {Opener, DbName}),
- db_opened(Server).
+ db_opened(Server, Options).
handle_call(close_lru, _From, #server{lru=Lru} = Server) ->
case couch_lru:close(Lru) of
- false ->
- {reply, ok, Server};
{true, NewLru} ->
- {reply, ok, db_closed(Server#server{lru = NewLru})}
+ {reply, ok, db_closed(Server#server{lru = NewLru}, [])};
+ false ->
+ {reply, {error, all_dbs_active}, Server}
end;
handle_call(open_dbs_count, _From, Server) ->
{reply, Server#server.dbs_open, Server};
@@ -348,7 +357,12 @@ handle_call({open_result, T0, DbName, {ok, Db}}, {FromPid, _Tag}, Server) ->
end,
true = ets:insert(couch_dbs, Db),
true = ets:insert(couch_dbs_pid_to_name, {Db#db.main_pid, DbName}),
- Lru = couch_lru:insert(DbName, Server#server.lru),
+ Lru = case couch_db:is_system_db(Db) of
+ false ->
+ couch_lru:insert(DbName, Server#server.lru);
+ true ->
+ Server#server.lru
+ end,
{reply, ok, Server#server{lru = Lru}}
end;
handle_call({open_result, T0, DbName, {error, eexist}}, From, Server) ->
@@ -359,7 +373,7 @@ handle_call({open_result, _T0, DbName, Error}, {FromPid, _Tag}, Server) ->
[] ->
% db was deleted during async open
{reply, ok, Server};
- [#db{fd=ReqType, compactor_pid=Froms}] ->
+ [#db{fd=ReqType, compactor_pid=Froms}=Db] ->
[gen_server:reply(From, Error) || From <- Froms],
couch_log:info("open_result error ~p for ~s", [Error, DbName]),
true = ets:delete(couch_dbs, DbName),
@@ -370,7 +384,7 @@ handle_call({open_result, _T0, DbName, Error}, {FromPid, _Tag}, Server) ->
_ ->
Server
end,
- {reply, ok, db_closed(NewServer)}
+ {reply, ok, db_closed(NewServer, Db#db.options)}
end;
handle_call({open, DbName, Options}, From, Server) ->
case ets:lookup(couch_dbs, DbName) of
@@ -378,9 +392,13 @@ handle_call({open, DbName, Options}, From, Server) ->
DbNameList = binary_to_list(DbName),
case check_dbname(Server, DbNameList) of
ok ->
- {ok, Server2} = maybe_close_lru_db(Server),
- Filepath = get_full_filename(Server, DbNameList),
- {noreply, open_async(Server2, From, DbName, Filepath, Options)};
+ case make_room(Server, Options) of
+ {ok, Server2} ->
+ Filepath = get_full_filename(Server, DbNameList),
+ {noreply, open_async(Server2, From, DbName, Filepath, Options)};
+ CloseError ->
+ {reply, CloseError, Server}
+ end;
Error ->
{reply, Error, Server}
end;
@@ -402,9 +420,13 @@ handle_call({create, DbName, Options}, From, Server) ->
ok ->
case ets:lookup(couch_dbs, DbName) of
[] ->
- {ok, Server2} = maybe_close_lru_db(Server),
- {noreply, open_async(Server2, From, DbName, Filepath,
- [create | Options])};
+ case make_room(Server, Options) of
+ {ok, Server2} ->
+ {noreply, open_async(Server2, From, DbName, Filepath,
+ [create | Options])};
+ CloseError ->
+ {reply, CloseError, Server}
+ end;
[#db{fd=open}=Db] ->
% We're trying to create a database while someone is in
% the middle of trying to open it. We allow one creator
@@ -428,18 +450,18 @@ handle_call({delete, DbName, Options}, _From, Server) ->
Server2 =
case ets:lookup(couch_dbs, DbName) of
[] -> Server;
- [#db{main_pid=Pid, compactor_pid=Froms}] when is_list(Froms) ->
+ [#db{main_pid=Pid, compactor_pid=Froms} = Db] when is_list(Froms) ->
% icky hack of field values - compactor_pid used to store clients
true = ets:delete(couch_dbs, DbName),
true = ets:delete(couch_dbs_pid_to_name, Pid),
exit(Pid, kill),
[gen_server:reply(F, not_found) || F <- Froms],
- db_closed(Server);
- [#db{main_pid=Pid}] ->
+ db_closed(Server, Db#db.options);
+ [#db{main_pid=Pid} = Db] ->
true = ets:delete(couch_dbs, DbName),
true = ets:delete(couch_dbs_pid_to_name, Pid),
exit(Pid, kill),
- db_closed(Server)
+ db_closed(Server, Db#db.options)
end,
%% Delete any leftover compaction files. If we don't do this a
@@ -470,7 +492,10 @@ handle_call({db_updated, #db{}=Db}, _From, Server0) ->
Server = try ets:lookup_element(couch_dbs, DbName, #db.instance_start_time) of
StartTime ->
true = ets:insert(couch_dbs, Db),
- Lru = couch_lru:update(DbName, Server0#server.lru),
+ Lru = case couch_db:is_system_db(Db) of
+ false -> couch_lru:update(DbName, Server0#server.lru);
+ true -> Server0#server.lru
+ end,
Server0#server{lru = Lru};
_ ->
Server0
@@ -494,7 +519,7 @@ handle_info({'EXIT', _Pid, config_change}, Server) ->
handle_info({'EXIT', Pid, Reason}, Server) ->
case ets:lookup(couch_dbs_pid_to_name, Pid) of
[{Pid, DbName}] ->
- [#db{compactor_pid=Froms}] = ets:lookup(couch_dbs, DbName),
+ [#db{compactor_pid=Froms}=Db] = ets:lookup(couch_dbs, DbName),
if Reason /= snappy_nif_not_loaded -> ok; true ->
Msg = io_lib:format("To open the database `~s`, Apache CouchDB "
"must be built with Erlang OTP R13B04 or higher.", [DbName]),
@@ -509,7 +534,7 @@ handle_info({'EXIT', Pid, Reason}, Server) ->
end,
true = ets:delete(couch_dbs, DbName),
true = ets:delete(couch_dbs_pid_to_name, Pid),
- {noreply, db_closed(Server)};
+ {noreply, db_closed(Server, Db#db.options)};
[] ->
{noreply, Server}
end;
@@ -519,11 +544,17 @@ handle_info(restart_config_listener, State) ->
handle_info(Info, Server) ->
{stop, {unknown_message, Info}, Server}.
-db_opened(Server) ->
- Server#server{dbs_open=Server#server.dbs_open + 1}.
+db_opened(Server, Options) ->
+ case lists:member(sys_db, Options) of
+ false -> Server#server{dbs_open=Server#server.dbs_open + 1};
+ true -> Server
+ end.
-db_closed(Server) ->
- Server#server{dbs_open=Server#server.dbs_open - 1}.
+db_closed(Server, Options) ->
+ case lists:member(sys_db, Options) of
+ false -> Server#server{dbs_open=Server#server.dbs_open - 1};
+ true -> Server
+ end.
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
diff --git a/src/couch/test/couchdb_views_tests.erl b/src/couch/test/couchdb_views_tests.erl
index f1fddfc1b..7b04e8527 100644
--- a/src/couch/test/couchdb_views_tests.erl
+++ b/src/couch/test/couchdb_views_tests.erl
@@ -372,6 +372,7 @@ couchdb_1283() ->
MonRef = erlang:monitor(process, CPid),
Writer3 = spawn_writer(Db3#db.name),
?assert(is_process_alive(Writer3)),
+ ?assertEqual({error, all_dbs_active}, get_writer_status(Writer3)),
?assert(is_process_alive(Writer1)),
?assert(is_process_alive(Writer2)),
@@ -390,6 +391,7 @@ couchdb_1283() ->
{reason, "Failure compacting view group"}]})
end,
+ ?assertEqual(ok, writer_try_again(Writer3)),
?assertEqual(ok, get_writer_status(Writer3)),
?assert(is_process_alive(Writer1)),