Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion rel/overlay/etc/default.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ view_index_dir = {{view_index_dir}}
; plugin_dir =
os_process_timeout = 5000 ; 5 seconds. for view servers.
max_dbs_open = 500
delayed_commits = false
; Method used to compress everything that is appended to database and view index files, except
; for attachments (see the attachments section). Available methods are:
;
Expand Down
19 changes: 3 additions & 16 deletions src/couch/src/couch_bt_engine.erl
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,6 @@ copy_purge_infos(#st{} = St, PurgeInfos) ->
commit_data(St) ->
#st{
fd = Fd,
fsync_options = FsyncOptions,
header = OldHeader,
needs_commit = NeedsCommit
} = St,
Expand All @@ -576,13 +575,9 @@ commit_data(St) ->

case NewHeader /= OldHeader orelse NeedsCommit of
true ->
Before = lists:member(before_header, FsyncOptions),
After = lists:member(after_header, FsyncOptions),

if Before -> couch_file:sync(Fd); true -> ok end,
couch_file:sync(Fd),
ok = couch_file:write_header(Fd, NewHeader),
if After -> couch_file:sync(Fd); true -> ok end,

couch_file:sync(Fd),
{ok, St#st{
header = NewHeader,
needs_commit = false
Expand Down Expand Up @@ -872,14 +867,7 @@ open_db_file(FilePath, Options) ->


init_state(FilePath, Fd, Header0, Options) ->
DefaultFSync = "[before_header, after_header, on_file_open]",
FsyncStr = config:get("couchdb", "fsync_options", DefaultFSync),
{ok, FsyncOptions} = couch_util:parse_term(FsyncStr),

case lists:member(on_file_open, FsyncOptions) of
true -> ok = couch_file:sync(Fd);
_ -> ok
end,
ok = couch_file:sync(Fd),

Compression = couch_compress:get_compression_method(),

Expand Down Expand Up @@ -930,7 +918,6 @@ init_state(FilePath, Fd, Header0, Options) ->
filepath = FilePath,
fd = Fd,
fd_monitor = erlang:monitor(process, Fd),
fsync_options = FsyncOptions,
header = Header,
needs_commit = false,
id_tree = IdTree,
Expand Down
3 changes: 2 additions & 1 deletion src/couch/src/couch_bt_engine.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
filepath,
fd,
fd_monitor,
fsync_options,
% deprecated but keeping it here to avoid altering the record size
fsync_options_deprecated,
header,
needs_commit,
id_tree,
Expand Down
44 changes: 5 additions & 39 deletions src/couch/src/couch_db.erl
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,6 @@
set_security/2,
set_user_ctx/2,

ensure_full_commit/1,
ensure_full_commit/2,

load_validation_funs/1,
reload_validation_funs/1,

Expand Down Expand Up @@ -226,21 +223,12 @@ is_partitioned(#db{options = Options}) ->
Props = couch_util:get_value(props, Options, []),
couch_util:get_value(partitioned, Props, false).

ensure_full_commit(#db{main_pid=Pid, instance_start_time=StartTime}) ->
ok = gen_server:call(Pid, full_commit, infinity),
{ok, StartTime}.

ensure_full_commit(Db, RequiredSeq) ->
#db{main_pid=Pid, instance_start_time=StartTime} = Db,
ok = gen_server:call(Pid, {full_commit, RequiredSeq}, infinity),
{ok, StartTime}.

close(#db{} = Db) ->
ok = couch_db_engine:decref(Db);
close(?OLD_DB_REC) ->
ok.

is_idle(#db{compactor_pid=nil, waiting_delayed_commit=nil} = Db) ->
is_idle(#db{compactor_pid=nil} = Db) ->
monitored_by(Db) == [];
is_idle(_Db) ->
false.
Expand Down Expand Up @@ -753,9 +741,7 @@ get_security(?OLD_DB_REC = Db) ->
set_security(#db{main_pid=Pid}=Db, {NewSecProps}) when is_list(NewSecProps) ->
check_is_admin(Db),
ok = validate_security_object(NewSecProps),
ok = gen_server:call(Pid, {set_security, NewSecProps}, infinity),
{ok, _} = ensure_full_commit(Db),
ok;
gen_server:call(Pid, {set_security, NewSecProps}, infinity);
set_security(_, _) ->
throw(bad_request).

Expand Down Expand Up @@ -1256,24 +1242,6 @@ make_first_doc_on_disk(Db, Id, Pos, [{_Rev, #leaf{deleted=IsDel, ptr=Sp}} |_]=Do
Revs = [Rev || {Rev, _} <- DocPath],
make_doc(Db, Id, IsDel, Sp, {Pos, Revs}).

set_commit_option(Options) ->
CommitSettings = {
[true || O <- Options, O==full_commit orelse O==delay_commit],
config:get("couchdb", "delayed_commits", "false")
},
case CommitSettings of
{[true], _} ->
Options; % user requested explicit commit setting, do not change it
{_, "true"} ->
Options; % delayed commits are enabled, do nothing
{_, "false"} ->
[full_commit|Options];
{_, Else} ->
couch_log:error("[couchdb] delayed_commits setting must be true/false,"
" not ~p", [Else]),
[full_commit|Options]
end.

collect_results_with_metrics(Pid, MRef, []) ->
Begin = os:timestamp(),
try
Expand All @@ -1299,14 +1267,12 @@ collect_results(Pid, MRef, ResultsAcc) ->
end.

write_and_commit(#db{main_pid=Pid, user_ctx=Ctx}=Db, DocBuckets1,
NonRepDocs, Options0) ->
NonRepDocs, Options) ->
DocBuckets = prepare_doc_summaries(Db, DocBuckets1),
Options = set_commit_option(Options0),
MergeConflicts = lists:member(merge_conflicts, Options),
FullCommit = lists:member(full_commit, Options),
MRef = erlang:monitor(process, Pid),
try
Pid ! {update_docs, self(), DocBuckets, NonRepDocs, MergeConflicts, FullCommit},
Pid ! {update_docs, self(), DocBuckets, NonRepDocs, MergeConflicts},
case collect_results_with_metrics(Pid, MRef, []) of
{ok, Results} -> {ok, Results};
retry ->
Expand All @@ -1320,7 +1286,7 @@ write_and_commit(#db{main_pid=Pid, user_ctx=Ctx}=Db, DocBuckets1,
% We only retry once
DocBuckets3 = prepare_doc_summaries(Db2, DocBuckets2),
close(Db2),
Pid ! {update_docs, self(), DocBuckets3, NonRepDocs, MergeConflicts, FullCommit},
Pid ! {update_docs, self(), DocBuckets3, NonRepDocs, MergeConflicts},
case collect_results_with_metrics(Pid, MRef, []) of
{ok, Results} -> {ok, Results};
retry -> throw({update_error, compaction_retry})
Expand Down
4 changes: 3 additions & 1 deletion src/couch/src/couch_db_int.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
before_doc_update = nil, % nil | fun(Doc, Db) -> NewDoc
after_doc_read = nil, % nil | fun(Doc, Db) -> NewDoc

waiting_delayed_commit = nil,
% feature removed in 3.x, but field kept to avoid changing db record size
% and breaking rolling cluster upgrade
waiting_delayed_commit_deprecated,

options = [],
compression
Expand Down
1 change: 0 additions & 1 deletion src/couch/src/couch_db_split.erl
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,6 @@ copy_local_docs(#state{source_db = Db, targets = Targets} = State) ->
[_ | _] ->
Docs1 = lists:reverse(Docs),
{ok, _} = couch_db:update_docs(TDb, Docs1),
{ok, _} = couch_db:ensure_full_commit(TDb),
T#target{buffer = []}
end
end, Targets1),
Expand Down
57 changes: 11 additions & 46 deletions src/couch/src/couch_db_updater.erl
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,6 @@ terminate(Reason, Db) ->

handle_call(get_db, _From, Db) ->
{reply, {ok, Db}, Db, idle_limit()};
handle_call(full_commit, _From, #db{waiting_delayed_commit=nil}=Db) ->
{reply, ok, Db, idle_limit()}; % no data waiting, return ok immediately
handle_call(full_commit, _From, Db) ->
{reply, ok, commit_data(Db), idle_limit()};
handle_call({full_commit, RequiredSeq}, _From, Db)
when RequiredSeq =< Db#db.committed_update_seq ->
{reply, ok, Db, idle_limit()};
handle_call({full_commit, _}, _, Db) ->
{reply, ok, commit_data(Db), idle_limit()}; % commit the data and return ok
handle_call(start_compact, _From, Db) ->
{noreply, NewDb, _Timeout} = handle_cast(start_compact, Db),
{reply, {ok, NewDb#db.compactor_pid}, NewDb, idle_limit()};
Expand Down Expand Up @@ -171,20 +162,18 @@ handle_cast(Msg, #db{name = Name} = Db) ->
{stop, Msg, Db}.


handle_info({update_docs, Client, GroupedDocs, NonRepDocs, MergeConflicts,
FullCommit}, Db) ->
handle_info({update_docs, Client, GroupedDocs, NonRepDocs, MergeConflicts},
Db) ->
GroupedDocs2 = sort_and_tag_grouped_docs(Client, GroupedDocs),
if NonRepDocs == [] ->
{GroupedDocs3, Clients, FullCommit2} = collect_updates(GroupedDocs2,
[Client], MergeConflicts, FullCommit);
{GroupedDocs3, Clients} = collect_updates(GroupedDocs2,
[Client], MergeConflicts);
true ->
GroupedDocs3 = GroupedDocs2,
FullCommit2 = FullCommit,
Clients = [Client]
end,
NonRepDocs2 = [{Client, NRDoc} || NRDoc <- NonRepDocs],
try update_docs_int(Db, GroupedDocs3, NonRepDocs2, MergeConflicts,
FullCommit2) of
try update_docs_int(Db, GroupedDocs3, NonRepDocs2, MergeConflicts) of
{ok, Db2, UpdatedDDocIds} ->
ok = gen_server:call(couch_server, {db_updated, Db2}, infinity),
case {couch_db:get_update_seq(Db), couch_db:get_update_seq(Db2)} of
Expand Down Expand Up @@ -217,17 +206,6 @@ handle_info({update_docs, Client, GroupedDocs, NonRepDocs, MergeConflicts,
[catch(ClientPid ! {retry, self()}) || ClientPid <- Clients],
{noreply, Db, hibernate_if_no_idle_limit()}
end;
handle_info(delayed_commit, #db{waiting_delayed_commit=nil}=Db) ->
%no outstanding delayed commits, ignore
{noreply, Db, idle_limit()};
handle_info(delayed_commit, Db) ->
case commit_data(Db) of
Db ->
{noreply, Db, idle_limit()};
Db2 ->
ok = gen_server:call(couch_server, {db_updated, Db2}, infinity),
{noreply, Db2, idle_limit()}
end;
handle_info({'EXIT', _Pid, normal}, Db) ->
{noreply, Db, idle_limit()};
handle_info({'EXIT', _Pid, Reason}, Db) ->
Expand Down Expand Up @@ -295,20 +273,20 @@ merge_updates([], RestB) ->
merge_updates(RestA, []) ->
RestA.

collect_updates(GroupedDocsAcc, ClientsAcc, MergeConflicts, FullCommit) ->
collect_updates(GroupedDocsAcc, ClientsAcc, MergeConflicts) ->
receive
% Only collect updates with the same MergeConflicts flag and without
% local docs. It's easier to just avoid multiple _local doc
% updaters than deal with their possible conflicts, and local docs
% writes are relatively rare. Can be optmized later if really needed.
{update_docs, Client, GroupedDocs, [], MergeConflicts, FullCommit2} ->
{update_docs, Client, GroupedDocs, [], MergeConflicts} ->
GroupedDocs2 = sort_and_tag_grouped_docs(Client, GroupedDocs),
GroupedDocsAcc2 =
merge_updates(GroupedDocsAcc, GroupedDocs2),
collect_updates(GroupedDocsAcc2, [Client | ClientsAcc],
MergeConflicts, (FullCommit or FullCommit2))
MergeConflicts)
after 0 ->
{GroupedDocsAcc, ClientsAcc, FullCommit}
{GroupedDocsAcc, ClientsAcc}
end.


Expand Down Expand Up @@ -633,7 +611,7 @@ maybe_stem_full_doc_info(#full_doc_info{rev_tree = Tree} = Info, Limit) ->
Info
end.

update_docs_int(Db, DocsList, LocalDocs, MergeConflicts, FullCommit) ->
update_docs_int(Db, DocsList, LocalDocs, MergeConflicts) ->
UpdateSeq = couch_db_engine:get_update_seq(Db),
RevsLimit = couch_db_engine:get_revs_limit(Db),

Expand Down Expand Up @@ -705,7 +683,7 @@ update_docs_int(Db, DocsList, LocalDocs, MergeConflicts, FullCommit) ->
(_) -> []
end, Ids),

{ok, commit_data(Db1, not FullCommit), UpdatedDDocIds}.
{ok, commit_data(Db1), UpdatedDDocIds}.


update_local_doc_revs(Docs) ->
Expand Down Expand Up @@ -852,21 +830,8 @@ apply_purge_reqs([Req | RestReqs], IdFDIs, USeq, Replies) ->


commit_data(Db) ->
commit_data(Db, false).

commit_data(#db{waiting_delayed_commit=nil} = Db, true) ->
TRef = erlang:send_after(1000,self(),delayed_commit),
Db#db{waiting_delayed_commit=TRef};
commit_data(Db, true) ->
Db;
commit_data(Db, _) ->
#db{
waiting_delayed_commit = Timer
} = Db,
if is_reference(Timer) -> erlang:cancel_timer(Timer); true -> ok end,
{ok, Db1} = couch_db_engine:commit_data(Db),
Db1#db{
waiting_delayed_commit = nil,
committed_update_seq = couch_db_engine:get_update_seq(Db)
}.

Expand Down
18 changes: 1 addition & 17 deletions src/couch/src/couch_httpd_db.erl
Original file line number Diff line number Diff line change
Expand Up @@ -283,23 +283,7 @@ db_req(#httpd{path_parts=[_DbName]}=Req, _Db) ->
db_req(#httpd{method='POST',path_parts=[_,<<"_ensure_full_commit">>]}=Req, Db) ->
couch_httpd:validate_ctype(Req, "application/json"),
_ = couch_httpd:body(Req),
UpdateSeq = couch_db:get_update_seq(Db),
CommittedSeq = couch_db:get_committed_update_seq(Db),
{ok, StartTime} =
case couch_httpd:qs_value(Req, "seq") of
undefined ->
couch_db:ensure_full_commit(Db);
RequiredStr ->
RequiredSeq = list_to_integer(RequiredStr),
if RequiredSeq > UpdateSeq ->
throw({bad_request,
"can't do a full commit ahead of current update_seq"});
RequiredSeq > CommittedSeq ->
couch_db:ensure_full_commit(Db);
true ->
{ok, couch_db:get_instance_start_time(Db)}
end
end,
StartTime = couch_db:get_instance_start_time(Db),
send_json(Req, 201, {[
{ok, true},
{instance_start_time, StartTime}
Expand Down
9 changes: 0 additions & 9 deletions src/couch/test/eunit/couch_auth_cache_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,6 @@ should_restore_cache_after_userdoc_recreation(DbName) ->
should_drop_cache_on_auth_db_change(DbName) ->
?_test(begin
{ok, _} = update_user_doc(DbName, "joe", "pass1"),
full_commit(DbName),
config:set("couch_httpd_auth", "authentication_db",
?b2l(?tempdb()), false),
?assertEqual(nil, couch_auth_cache:get_user_creds("joe"))
Expand All @@ -202,14 +201,12 @@ should_restore_cache_on_auth_db_change(DbName) ->
PasswordHash = hash_password("pass1"),
{ok, _} = update_user_doc(DbName, "joe", "pass1"),
{ok, Creds, _} = couch_auth_cache:get_user_creds("joe"),
full_commit(DbName),

DbName1 = ?tempdb(),
config:set("couch_httpd_auth", "authentication_db",
?b2l(DbName1), false),

{ok, _} = update_user_doc(DbName1, "joe", "pass5"),
full_commit(DbName1),

config:set("couch_httpd_auth", "authentication_db",
?b2l(DbName), false),
Expand All @@ -224,7 +221,6 @@ should_recover_cache_after_shutdown(DbName) ->
PasswordHash = hash_password("pass2"),
{ok, Rev0} = update_user_doc(DbName, "joe", "pass1"),
{ok, Rev1} = update_user_doc(DbName, "joe", "pass2", Rev0),
full_commit(DbName),
shutdown_db(DbName),
{ok, Rev1} = get_doc_rev(DbName, "joe"),
?assertEqual(PasswordHash, get_user_doc_password_sha(DbName, "joe"))
Expand Down Expand Up @@ -328,11 +324,6 @@ delete_user_doc(DbName, UserName) ->
{ok, _} = couch_db:update_doc(AuthDb, DeletedDoc, []),
ok = couch_db:close(AuthDb).

full_commit(DbName) ->
{ok, AuthDb} = couch_db:open_int(DbName, [?ADMIN_CTX]),
{ok, _} = couch_db:ensure_full_commit(AuthDb),
ok = couch_db:close(AuthDb).

is_opened(DbName) ->
{ok, AuthDb} = couch_db:open_int(DbName, [?ADMIN_CTX]),
Monitors = couch_db:monitored_by(AuthDb) -- [self()],
Expand Down
3 changes: 1 addition & 2 deletions src/couch/test/eunit/couch_bt_engine_compactor_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,7 @@ create_docs(DbName) ->
{<<"value">>, 3}

]}),
{ok, _} = couch_db:update_docs(Db, [Doc1, Doc2, Doc3]),
couch_db:ensure_full_commit(Db)
{ok, _} = couch_db:update_docs(Db, [Doc1, Doc2, Doc3])
end).


Expand Down
1 change: 0 additions & 1 deletion src/couch/test/eunit/couch_changes_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ setup() ->
save_doc(Db, {[{<<"_id">>, <<"doc5">>}]})
]],
Rev = lists:nth(3, Revs),
couch_db:ensure_full_commit(Db),
{ok, Db1} = couch_db:reopen(Db),

{ok, Rev1} = save_doc(Db1, {[{<<"_id">>, <<"doc3">>}, {<<"_rev">>, Rev}]}),
Expand Down
1 change: 0 additions & 1 deletion src/couch/test/eunit/couch_db_doc_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ add_revision(Db0, DocId, Rev) ->
{<<"value">>, DocId}
] ++ Rev}),
{ok, NewRev} = couch_db:update_doc(Db, Doc, []),
{ok, _} = couch_db:ensure_full_commit(Db),
couch_doc:rev_to_str(NewRev).


Expand Down
Loading