diff options
author | Juanjo Rodriguez <jjrodrig@gmail.com> | 2019-10-02 23:34:30 +0200 |
---|---|---|
committer | Juanjo Rodriguez <jjrodrig@gmail.com> | 2019-10-02 23:34:30 +0200 |
commit | 0afab3bc2cbe92f3d1ab987c8061ef40d23c7706 (patch) | |
tree | 8d760c4c47928f56415914ad1f5ff36b7bc4bfc7 | |
parent | 746d66098942eb67c09f102a600b8cc763ce666f (diff) | |
parent | dc054e7ddcc3ea059e1f86a7039cf86912ab1052 (diff) | |
download | couchdb-0afab3bc2cbe92f3d1ab987c8061ef40d23c7706.tar.gz |
Merge branch 'master' of https://github.com/apache/couchdb into port-elixir-auth
39 files changed, 78 insertions, 291 deletions
diff --git a/rel/overlay/etc/default.ini b/rel/overlay/etc/default.ini index dbb0744b9..3a363947b 100644 --- a/rel/overlay/etc/default.ini +++ b/rel/overlay/etc/default.ini @@ -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: ; diff --git a/rel/reltool.config b/rel/reltool.config index da85f36bc..512e45c44 100644 --- a/rel/reltool.config +++ b/rel/reltool.config @@ -12,7 +12,7 @@ {sys, [ {lib_dirs, ["../src"]}, - {rel, "couchdb", "2.3.0", [ + {rel, "couchdb", "3.0.0", [ %% stdlib asn1, compiler, diff --git a/src/chttpd/src/chttpd_misc.erl b/src/chttpd/src/chttpd_misc.erl index 819d7820e..17122bf85 100644 --- a/src/chttpd/src/chttpd_misc.erl +++ b/src/chttpd/src/chttpd_misc.erl @@ -51,7 +51,7 @@ handle_welcome_req(#httpd{method='GET'}=Req, WelcomeMessage) -> {version, list_to_binary(couch_server:get_version())}, {git_sha, list_to_binary(couch_server:get_git_sha())}, {uuid, couch_server:get_uuid()}, - {features, config:features()} + {features, get_features()} ] ++ case config:get("vendor") of [] -> []; @@ -62,6 +62,14 @@ handle_welcome_req(#httpd{method='GET'}=Req, WelcomeMessage) -> handle_welcome_req(Req, _) -> send_method_not_allowed(Req, "GET,HEAD"). +get_features() -> + case clouseau_rpc:connected() of + true -> + [search | config:features()]; + false -> + config:features() + end. + handle_favicon_req(Req) -> handle_favicon_req(Req, get_docroot()). diff --git a/src/chttpd/src/chttpd_view.erl b/src/chttpd/src/chttpd_view.erl index 26107d7c5..0d3d86d1a 100644 --- a/src/chttpd/src/chttpd_view.erl +++ b/src/chttpd/src/chttpd_view.erl @@ -88,22 +88,16 @@ handle_view_req(#httpd{method='POST', path_parts=[_, _, _, _, ViewName]}=Req, Db, DDoc) -> chttpd:validate_ctype(Req, "application/json"), Props = couch_httpd:json_body_obj(Req), - Keys = couch_mrview_util:get_view_keys(Props), - Queries = couch_mrview_util:get_view_queries(Props), - case {Queries, Keys} of - {Queries, undefined} when is_list(Queries) -> - [couch_stats:increment_counter([couchdb, httpd, view_reads]) || _I <- Queries], - multi_query_view(Req, Db, DDoc, ViewName, Queries); - {undefined, Keys} when is_list(Keys) -> + assert_no_queries_param(couch_mrview_util:get_view_queries(Props)), + case couch_mrview_util:get_view_keys(Props) of + Keys when is_list(Keys) -> couch_stats:increment_counter([couchdb, httpd, view_reads]), design_doc_view(Req, Db, DDoc, ViewName, Keys); - {undefined, undefined} -> + _ -> throw({ bad_request, - "POST body must contain `keys` or `queries` field" - }); - {_, _} -> - throw({bad_request, "`keys` and `queries` are mutually exclusive"}) + "POST body must contain an array called `keys`" + }) end; handle_view_req(Req, _Db, _DDoc) -> @@ -113,6 +107,14 @@ handle_temp_view_req(Req, _Db) -> Msg = <<"Temporary views are not supported in CouchDB">>, chttpd:send_error(Req, 410, gone, Msg). +% See https://github.com/apache/couchdb/issues/2168 +assert_no_queries_param(undefined) -> + ok; +assert_no_queries_param(_) -> + throw({ + bad_request, + "The `queries` parameter is no longer supported at this endpoint" + }). -ifdef(TEST). diff --git a/src/couch/src/couch_bt_engine.erl b/src/couch/src/couch_bt_engine.erl index f4ff9a8d3..e3e4d0d32 100644 --- a/src/couch/src/couch_bt_engine.erl +++ b/src/couch/src/couch_bt_engine.erl @@ -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, @@ -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 @@ -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(), @@ -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, diff --git a/src/couch/src/couch_bt_engine.hrl b/src/couch/src/couch_bt_engine.hrl index 1f5bcc9df..e3c1d4983 100644 --- a/src/couch/src/couch_bt_engine.hrl +++ b/src/couch/src/couch_bt_engine.hrl @@ -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, diff --git a/src/couch/src/couch_db.erl b/src/couch/src/couch_db.erl index 6135813ae..1e09b9e74 100644 --- a/src/couch/src/couch_db.erl +++ b/src/couch/src/couch_db.erl @@ -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, @@ -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. @@ -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). @@ -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 @@ -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 -> @@ -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}) diff --git a/src/couch/src/couch_db_int.hrl b/src/couch/src/couch_db_int.hrl index a412b338b..7da0ce5df 100644 --- a/src/couch/src/couch_db_int.hrl +++ b/src/couch/src/couch_db_int.hrl @@ -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 diff --git a/src/couch/src/couch_db_split.erl b/src/couch/src/couch_db_split.erl index b9c23a998..5bf98b6fd 100644 --- a/src/couch/src/couch_db_split.erl +++ b/src/couch/src/couch_db_split.erl @@ -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), diff --git a/src/couch/src/couch_db_updater.erl b/src/couch/src/couch_db_updater.erl index 4227ff036..6e164e536 100644 --- a/src/couch/src/couch_db_updater.erl +++ b/src/couch/src/couch_db_updater.erl @@ -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()}; @@ -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 @@ -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) -> @@ -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. @@ -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), @@ -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) -> @@ -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) }. diff --git a/src/couch/src/couch_httpd_db.erl b/src/couch/src/couch_httpd_db.erl index 6cfae9610..1a07b202c 100644 --- a/src/couch/src/couch_httpd_db.erl +++ b/src/couch/src/couch_httpd_db.erl @@ -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} diff --git a/src/couch/test/eunit/couch_auth_cache_tests.erl b/src/couch/test/eunit/couch_auth_cache_tests.erl index 706c0cee9..5439dd7b9 100644 --- a/src/couch/test/eunit/couch_auth_cache_tests.erl +++ b/src/couch/test/eunit/couch_auth_cache_tests.erl @@ -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")) @@ -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), @@ -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")) @@ -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()], diff --git a/src/couch/test/eunit/couch_bt_engine_compactor_tests.erl b/src/couch/test/eunit/couch_bt_engine_compactor_tests.erl index 6c99ceb73..4c4c43958 100644 --- a/src/couch/test/eunit/couch_bt_engine_compactor_tests.erl +++ b/src/couch/test/eunit/couch_bt_engine_compactor_tests.erl @@ -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). diff --git a/src/couch/test/eunit/couch_changes_tests.erl b/src/couch/test/eunit/couch_changes_tests.erl index 0c2f5f91f..10cd56cee 100644 --- a/src/couch/test/eunit/couch_changes_tests.erl +++ b/src/couch/test/eunit/couch_changes_tests.erl @@ -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}]}), diff --git a/src/couch/test/eunit/couch_db_doc_tests.erl b/src/couch/test/eunit/couch_db_doc_tests.erl index cdcf81d15..1de26c768 100644 --- a/src/couch/test/eunit/couch_db_doc_tests.erl +++ b/src/couch/test/eunit/couch_db_doc_tests.erl @@ -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). diff --git a/src/couch/test/eunit/couch_db_split_tests.erl b/src/couch/test/eunit/couch_db_split_tests.erl index 312b5f84d..8e64c39ee 100644 --- a/src/couch/test/eunit/couch_db_split_tests.erl +++ b/src/couch/test/eunit/couch_db_split_tests.erl @@ -277,7 +277,6 @@ create_docs(DbName, DocNum) -> end, [], lists:seq(DocNum, 1, -1)), couch_util:with_db(DbName, fun(Db) -> {ok, _Result} = couch_db:update_docs(Db, Docs), - {ok, _StartTime} = couch_db:ensure_full_commit(Db), {ok, Db1} = couch_db:reopen(Db), UpdateSeq = couch_db:get_update_seq(Db1), {ok, UpdateSeq} diff --git a/src/couch/test/eunit/couch_index_tests.erl b/src/couch/test/eunit/couch_index_tests.erl index fab3806d0..23c857d6c 100644 --- a/src/couch/test/eunit/couch_index_tests.erl +++ b/src/couch/test/eunit/couch_index_tests.erl @@ -113,7 +113,6 @@ create_docs(DbName) -> ]}), {ok, _} = couch_db:update_docs(Db, [Doc1, Doc2, Doc3]), - couch_db:ensure_full_commit(Db), couch_db:close(Db). create_design_doc(DbName, DDName, ViewName) -> @@ -128,7 +127,6 @@ create_design_doc(DbName, DDName, ViewName) -> ]}} ]}), {ok, Rev} = couch_db:update_doc(Db, DDoc, []), - couch_db:ensure_full_commit(Db), couch_db:close(Db), Rev. diff --git a/src/couch/test/eunit/couchdb_design_doc_tests.erl b/src/couch/test/eunit/couchdb_design_doc_tests.erl index eef12e039..653a6cb17 100644 --- a/src/couch/test/eunit/couchdb_design_doc_tests.erl +++ b/src/couch/test/eunit/couchdb_design_doc_tests.erl @@ -77,7 +77,6 @@ create_design_doc(DbName, DDName) -> ]}} ]}), {ok, Rev} = couch_db:update_doc(Db, DDoc, []), - couch_db:ensure_full_commit(Db), couch_db:close(Db), Rev. diff --git a/src/couch/test/eunit/couchdb_mrview_tests.erl b/src/couch/test/eunit/couchdb_mrview_tests.erl index 1c96a0ae0..f5bad7321 100644 --- a/src/couch/test/eunit/couchdb_mrview_tests.erl +++ b/src/couch/test/eunit/couchdb_mrview_tests.erl @@ -187,7 +187,6 @@ create_doc(backdoor, DbName, Id, Body) -> Doc = couch_doc:from_json_obj(JsonDoc), {ok, Db} = couch_db:open(DbName, [?ADMIN_CTX]), {ok, _} = couch_db:update_docs(Db, [Doc]), - couch_db:ensure_full_commit(Db), couch_db:close(Db); create_doc(clustered, DbName, Id, Body) -> JsonDoc = couch_util:json_apply_field({<<"_id">>, Id}, Body), diff --git a/src/couch/test/eunit/couchdb_update_conflicts_tests.erl b/src/couch/test/eunit/couchdb_update_conflicts_tests.erl index e92c73856..1329aba27 100644 --- a/src/couch/test/eunit/couchdb_update_conflicts_tests.erl +++ b/src/couch/test/eunit/couchdb_update_conflicts_tests.erl @@ -22,9 +22,8 @@ -define(TIMEOUT, 20000). start() -> - Ctx = test_util:start_couch(), - config:set("couchdb", "delayed_commits", "true", false), - Ctx. + test_util:start_couch(). + setup() -> DbName = ?tempdb(), diff --git a/src/couch/test/eunit/couchdb_vhosts_tests.erl b/src/couch/test/eunit/couchdb_vhosts_tests.erl index 1c4117215..fbe5579cd 100644 --- a/src/couch/test/eunit/couchdb_vhosts_tests.erl +++ b/src/couch/test/eunit/couchdb_vhosts_tests.erl @@ -43,7 +43,6 @@ setup() -> ]} ]}), {ok, _} = couch_db:update_docs(Db, [Doc, Doc1]), - couch_db:ensure_full_commit(Db), couch_db:close(Db), Addr = config:get("httpd", "bind_address", "127.0.0.1"), diff --git a/src/couch/test/eunit/couchdb_views_tests.erl b/src/couch/test/eunit/couchdb_views_tests.erl index 60bb5c975..d1aba8fd5 100644 --- a/src/couch/test/eunit/couchdb_views_tests.erl +++ b/src/couch/test/eunit/couchdb_views_tests.erl @@ -322,7 +322,6 @@ couchdb_1309(DbName) -> couchdb_1283() -> ?_test(begin ok = config:set("couchdb", "max_dbs_open", "3", false), - ok = config:set("couchdb", "delayed_commits", "false", false), {ok, MDb1} = couch_db:create(?tempdb(), [?ADMIN_CTX]), DDoc = couch_doc:from_json_obj({[ @@ -406,7 +405,6 @@ create_doc(DbName, DocId) when is_binary(DocId) -> {<<"value">>, 999} ]}), {ok, _} = couch_db:update_docs(Db, [Doc666]), - couch_db:ensure_full_commit(Db), couch_db:close(Db). create_docs(DbName) -> @@ -427,7 +425,6 @@ create_docs(DbName) -> ]}), {ok, _} = couch_db:update_docs(Db, [Doc1, Doc2, Doc3]), - couch_db:ensure_full_commit(Db), couch_db:close(Db). populate_db(Db, BatchSize, N) when N > 0 -> @@ -456,7 +453,6 @@ create_design_doc(DbName, DDName, ViewName) -> ]}} ]}), {ok, Rev} = couch_db:update_doc(Db, DDoc, []), - couch_db:ensure_full_commit(Db), couch_db:close(Db), Rev. @@ -476,7 +472,6 @@ update_design_doc(DbName, DDName, ViewName) -> ]}} ]}), {ok, NewRev} = couch_db:update_doc(Db, DDoc, [?ADMIN_CTX]), - couch_db:ensure_full_commit(Db), couch_db:close(Db), NewRev. diff --git a/src/couch_index/src/couch_index.erl b/src/couch_index/src/couch_index.erl index cae95779e..ab6deae59 100644 --- a/src/couch_index/src/couch_index.erl +++ b/src/couch_index/src/couch_index.erl @@ -377,17 +377,7 @@ code_change(_OldVsn, State, _Extra) -> maybe_restart_updater(#st{waiters=[]}) -> ok; -maybe_restart_updater(#st{mod=Mod, idx_state=IdxState}=State) -> - couch_util:with_db(Mod:get(db_name, IdxState), fun(Db) -> - UpdateSeq = couch_db:get_update_seq(Db), - CommittedSeq = couch_db:get_committed_update_seq(Db), - CanUpdate = UpdateSeq > CommittedSeq, - UOpts = Mod:get(update_options, IdxState), - case CanUpdate and lists:member(committed_only, UOpts) of - true -> couch_db:ensure_full_commit(Db); - false -> ok - end - end), +maybe_restart_updater(#st{idx_state=IdxState}=State) -> couch_index_updater:run(State#st.updater, IdxState). diff --git a/src/couch_mrview/test/eunit/couch_mrview_changes_since_tests.erl b/src/couch_mrview/test/eunit/couch_mrview_changes_since_tests.erl index d670e109b..67106419f 100644 --- a/src/couch_mrview/test/eunit/couch_mrview_changes_since_tests.erl +++ b/src/couch_mrview/test/eunit/couch_mrview_changes_since_tests.erl @@ -168,7 +168,6 @@ test_remove_key(Db) -> Doc = couch_mrview_test_util:doc(11), {ok, Rev} = couch_db:update_doc(Db, Doc, []), RevStr = couch_doc:rev_to_str(Rev), - {ok, _} = couch_db:ensure_full_commit(Db), {ok, Db1} = couch_db:reopen(Db), Result = run_count_query(Db1, 0, []), %% check new view key diff --git a/src/couch_mrview/test/eunit/couch_mrview_index_changes_tests.erl b/src/couch_mrview/test/eunit/couch_mrview_index_changes_tests.erl index f0be1b9b1..d8dd28773 100644 --- a/src/couch_mrview/test/eunit/couch_mrview_index_changes_tests.erl +++ b/src/couch_mrview/test/eunit/couch_mrview_index_changes_tests.erl @@ -198,7 +198,6 @@ test_indexer(Db) -> save_doc(Db, Id) -> Doc = couch_mrview_test_util:doc(Id), {ok, _Rev} = couch_db:update_doc(Db, Doc, []), - {ok, _} = couch_db:ensure_full_commit(Db), couch_db:reopen(Db). run_query(Db, Opts) -> diff --git a/src/couch_pse_tests/src/cpse_test_attachments.erl b/src/couch_pse_tests/src/cpse_test_attachments.erl index 8c454ecb6..ddd1077d1 100644 --- a/src/couch_pse_tests/src/cpse_test_attachments.erl +++ b/src/couch_pse_tests/src/cpse_test_attachments.erl @@ -41,7 +41,6 @@ cpse_write_attachment(Db1) -> Actions = [{create, {<<"first">>, {[]}, [Att0]}}], {ok, Db2} = cpse_util:apply_actions(Db1, Actions), - {ok, _} = couch_db:ensure_full_commit(Db2), cpse_util:shutdown_db(Db2), {ok, Db3} = couch_db:reopen(Db2), diff --git a/src/couch_pse_tests/src/cpse_test_compaction.erl b/src/couch_pse_tests/src/cpse_test_compaction.erl index c8a2c1a7d..6bc470b2f 100644 --- a/src/couch_pse_tests/src/cpse_test_compaction.erl +++ b/src/couch_pse_tests/src/cpse_test_compaction.erl @@ -131,7 +131,6 @@ cpse_compact_with_everything(Db1) -> catch throw:not_supported -> {ok, Db4} end, - {ok, _} = couch_db:ensure_full_commit(Db5), {ok, Db6} = couch_db:reopen(Db5), Term1 = cpse_util:db_as_term(Db6), diff --git a/src/couch_pse_tests/src/cpse_test_get_set_props.erl b/src/couch_pse_tests/src/cpse_test_get_set_props.erl index 02f0eb531..d49f67f49 100644 --- a/src/couch_pse_tests/src/cpse_test_get_set_props.erl +++ b/src/couch_pse_tests/src/cpse_test_get_set_props.erl @@ -89,7 +89,6 @@ check_prop_set(DbName, GetFun, SetFun, Default, Value) -> {ok, Db1} = couch_db:reopen(Db0), ?assertEqual(Value, couch_db:GetFun(Db1)), - ?assertMatch({ok, _}, couch_db:ensure_full_commit(Db1)), cpse_util:shutdown_db(Db1), {ok, Db2} = couch_db:reopen(Db1), diff --git a/src/couch_pse_tests/src/cpse_test_read_write_docs.erl b/src/couch_pse_tests/src/cpse_test_read_write_docs.erl index fd830d812..a2151340a 100644 --- a/src/couch_pse_tests/src/cpse_test_read_write_docs.erl +++ b/src/couch_pse_tests/src/cpse_test_read_write_docs.erl @@ -56,7 +56,6 @@ cpse_write_one_doc(Db1) -> {ok, Db2} = cpse_util:apply_actions(Db1, Actions), ?assertEqual(1, couch_db_engine:get_doc_count(Db2)), - {ok, _} = couch_db:ensure_full_commit(Db2), cpse_util:shutdown_db(Db2), {ok, Db3} = couch_db:reopen(Db2), @@ -96,7 +95,6 @@ cpse_write_two_docs(Db1) -> {create, {<<"bar">>, {[{<<"stuff">>, true}]}}} ], {ok, Db2} = cpse_util:apply_actions(Db1, Actions), - {ok, _} = couch_db:ensure_full_commit(Db2), cpse_util:shutdown_db(Db2), {ok, Db3} = couch_db:reopen(Db2), @@ -122,7 +120,6 @@ cpse_write_three_doc_batch(Db1) -> ]} ], {ok, Db2} = cpse_util:apply_actions(Db1, Actions), - {ok, _} = couch_db:ensure_full_commit(Db2), cpse_util:shutdown_db(Db2), {ok, Db3} = couch_db:reopen(Db2), @@ -145,7 +142,7 @@ cpse_update_doc(Db1) -> {update, {<<"foo">>, {[{<<"vsn">>, 2}]}}} ], {ok, Db2} = cpse_util:apply_actions(Db1, Actions), - {ok, _} = couch_db:ensure_full_commit(Db2), + cpse_util:shutdown_db(Db2), {ok, Db3} = couch_db:reopen(Db2), @@ -187,7 +184,6 @@ cpse_delete_doc(Db1) -> {delete, {<<"foo">>, {[]}}} ], {ok, Db2} = cpse_util:apply_actions(Db1, Actions), - {ok, _} = couch_db:ensure_full_commit(Db2), cpse_util:shutdown_db(Db2), {ok, Db3} = couch_db:reopen(Db2), @@ -227,7 +223,6 @@ cpse_write_local_doc(Db1) -> {create, {<<"_local/foo">>, {[{<<"yay">>, false}]}}} ], {ok, Db2} = cpse_util:apply_actions(Db1, Actions), - {ok, _} = couch_db:ensure_full_commit(Db2), cpse_util:shutdown_db(Db2), {ok, Db3} = couch_db:reopen(Db2), @@ -253,7 +248,6 @@ cpse_write_mixed_batch(Db1) -> ]} ], {ok, Db2} = cpse_util:apply_actions(Db1, Actions), - {ok, _} = couch_db:ensure_full_commit(Db2), cpse_util:shutdown_db(Db2), {ok, Db3} = couch_db:reopen(Db2), @@ -279,7 +273,6 @@ cpse_update_local_doc(Db1) -> {update, {<<"_local/foo">>, {[{<<"stuff">>, null}]}}} ], {ok, Db2} = cpse_util:apply_actions(Db1, Actions), - {ok, _} = couch_db:ensure_full_commit(Db1), cpse_util:shutdown_db(Db2), {ok, Db3} = couch_db:reopen(Db2), @@ -303,7 +296,6 @@ cpse_delete_local_doc(Db1) -> {delete, {<<"_local/foo">>, []}} ], {ok, Db2} = cpse_util:apply_actions(Db1, Actions), - {ok, _} = couch_db:ensure_full_commit(Db2), cpse_util:shutdown_db(Db2), {ok, Db3} = couch_db:reopen(Db2), diff --git a/src/couch_replicator/src/couch_replicator_docs.erl b/src/couch_replicator/src/couch_replicator_docs.erl index 81685cd48..e23344122 100644 --- a/src/couch_replicator/src/couch_replicator_docs.erl +++ b/src/couch_replicator/src/couch_replicator_docs.erl @@ -805,8 +805,7 @@ create_vdu(DbName) -> id = <<"_design/vdu">>, body = {[{<<"validate_doc_update">>, VduFun}]} }, - {ok, _} = couch_db:update_docs(Db, [Doc]), - couch_db:ensure_full_commit(Db) + {ok, _} = couch_db:update_docs(Db, [Doc]) end). diff --git a/src/couch_replicator/test/eunit/couch_replicator_filtered_tests.erl b/src/couch_replicator/test/eunit/couch_replicator_filtered_tests.erl index 70b25a31b..7ac9a4d71 100644 --- a/src/couch_replicator/test/eunit/couch_replicator_filtered_tests.erl +++ b/src/couch_replicator/test/eunit/couch_replicator_filtered_tests.erl @@ -228,7 +228,6 @@ create_docs(DbName) -> ]}), {ok, _} = couch_db:update_docs(Db, [DDoc, Doc1, Doc2, Doc3, Doc4]), - couch_db:ensure_full_commit(Db), couch_db:close(Db). delete_db(DbName) -> diff --git a/src/couch_replicator/test/eunit/couch_replicator_id_too_long_tests.erl b/src/couch_replicator/test/eunit/couch_replicator_id_too_long_tests.erl index 1447acfa7..a4696c4b8 100644 --- a/src/couch_replicator/test/eunit/couch_replicator_id_too_long_tests.erl +++ b/src/couch_replicator/test/eunit/couch_replicator_id_too_long_tests.erl @@ -77,7 +77,6 @@ create_doc(DbName) -> {ok, Db} = couch_db:open(DbName, [?ADMIN_CTX]), Doc = couch_doc:from_json_obj({[{<<"_id">>, <<"12345">>}]}), {ok, _} = couch_db:update_doc(Db, Doc, []), - couch_db:ensure_full_commit(Db), couch_db:close(Db). diff --git a/src/couch_replicator/test/eunit/couch_replicator_selector_tests.erl b/src/couch_replicator/test/eunit/couch_replicator_selector_tests.erl index 7d92bdcb1..5026c1435 100644 --- a/src/couch_replicator/test/eunit/couch_replicator_selector_tests.erl +++ b/src/couch_replicator/test/eunit/couch_replicator_selector_tests.erl @@ -106,7 +106,6 @@ create_docs(DbName) -> {<<"_id">>, <<"doc2">>} ]}), {ok, _} = couch_db:update_docs(Db, [Doc1, Doc2]), - couch_db:ensure_full_commit(Db), couch_db:close(Db). delete_db(DbName) -> diff --git a/src/couch_stats/src/couch_stats_aggregator.erl b/src/couch_stats/src/couch_stats_aggregator.erl index 17bd6fc33..8aef3d02d 100644 --- a/src/couch_stats/src/couch_stats_aggregator.erl +++ b/src/couch_stats/src/couch_stats_aggregator.erl @@ -55,18 +55,19 @@ start_link() -> init([]) -> {ok, Descs} = reload_metrics(), - Interval = config:get_integer("stats", "interval", ?DEFAULT_INTERVAL), - {ok, CT} = timer:send_interval(Interval * 1000, self(), collect), - {ok, RT} = timer:send_interval(?RELOAD_INTERVAL * 1000, self(), reload), + {ok, CT} = timer:send_after(get_interval(collect), self(), collect), + {ok, RT} = timer:send_after(get_interval(reload), self(), reload), {ok, #st{descriptions=Descs, stats=[], collect_timer=CT, reload_timer=RT}}. handle_call(fetch, _from, #st{stats = Stats}=State) -> {reply, {ok, Stats}, State}; handle_call(flush, _From, State) -> {reply, ok, collect(State)}; -handle_call(reload, _from, State) -> +handle_call(reload, _from, #st{reload_timer=OldRT} = State) -> + timer:cancel(OldRT), {ok, Descriptions} = reload_metrics(), - {reply, ok, State#st{descriptions=Descriptions}}; + {ok, RT} = update_timer(reload), + {reply, ok, State#st{descriptions=Descriptions, reload_timer=RT}}; handle_call(Msg, _From, State) -> {stop, {unknown_call, Msg}, error, State}. @@ -140,11 +141,23 @@ load_metrics_for_application(AppName) -> end end. -collect(State) -> +collect(#st{collect_timer=OldCT} = State) -> + timer:cancel(OldCT), Stats = lists:map( fun({Name, Props}) -> {Name, [{value, couch_stats:sample(Name)}|Props]} end, State#st.descriptions ), - State#st{stats=Stats}. + {ok, CT} = update_timer(collect), + State#st{stats=Stats, collect_timer=CT}. + +update_timer(collect) -> + Interval = get_interval(collect), + timer:send_after(Interval, self(), collect); +update_timer(reload) -> + Interval = get_interval(reload), + timer:send_after(Interval, self(), reload). + +get_interval(reload) -> 1000 * ?RELOAD_INTERVAL; +get_interval(collect) -> 1000 * config:get_integer("stats", "interval", ?DEFAULT_INTERVAL). diff --git a/src/mem3/src/mem3_reshard_store.erl b/src/mem3/src/mem3_reshard_store.erl index a1e00544a..c3534b374 100644 --- a/src/mem3/src/mem3_reshard_store.erl +++ b/src/mem3/src/mem3_reshard_store.erl @@ -169,7 +169,6 @@ delete_doc(Db, DocId) -> case couch_db:open_doc(Db, DocId, []) of {ok, #doc{revs = {_, Revs}}} -> {ok, _} = couch_db:delete_doc(Db, DocId, Revs), - {ok, _} = couch_db:ensure_full_commit(Db), ok; {not_found, _} -> ok @@ -190,7 +189,6 @@ update_doc(Db, DocId, Body) -> true -> {ok, _} = couch_db:update_doc(Db, Doc, []), couch_log:debug("~p updated doc ~p ~p", [?MODULE, DocId, Body]), - {ok, _} = couch_db:ensure_full_commit(Db), ok; false -> couch_log:debug("~p not storing state in ~p", [?MODULE, DocId]), diff --git a/test/elixir/README.md b/test/elixir/README.md index 9483e00c9..c0764baa4 100644 --- a/test/elixir/README.md +++ b/test/elixir/README.md @@ -42,7 +42,6 @@ X means done, - means partially - [X] Port conflicts.js - [X] Port cookie_auth.js - [X] Port copy_doc.js - - [X] Port delayed_commits.js - [ ] Port design_docs.js - [ ] Port design_options.js - [ ] Port design_paths.js @@ -253,4 +252,4 @@ defmodule Couch.Test.CRUD do end end end -```
\ No newline at end of file +``` diff --git a/test/elixir/test/delayed_commits_test.exs b/test/elixir/test/delayed_commits_test.exs deleted file mode 100644 index 9b00a5916..000000000 --- a/test/elixir/test/delayed_commits_test.exs +++ /dev/null @@ -1,35 +0,0 @@ -defmodule DelayedCommitsTest do - use CouchTestCase - - @moduledoc """ - Test CouchDB delayed commits - This is a port of the delayed_commits.js suite - - Note that delayed_commits is deprecated in 2.0, so this is a minimal - test to show it still works. delayed_commits will be removed in 3.0. - - This test is now skipped. Its a bit of a flaky test so no point running it - since we are removing this feature. - """ - - @tag :pending - @tag config: [ - {"couchdb", "delayed_commits", "true"} - ] - @tag :with_db - test "delayed commit", context do - db_name = context[:db_name] - doc_id = "doc-1" - resp = Couch.put("/#{db_name}/#{doc_id}", body: %{a: 2, b: 4}) - assert resp.status_code in 201..204 - assert resp.body["ok"] - - resp = Couch.get("/#{db_name}/#{doc_id}") - assert resp.status_code == 200, "The new doc should be in the database" - - restart_cluster() - - resp = Couch.get("/#{db_name}/#{doc_id}") - assert resp.status_code == 404, "The new doc should be missing" - end -end diff --git a/test/javascript/tests/delayed_commits.js b/test/javascript/tests/delayed_commits.js deleted file mode 100644 index cfb59d11e..000000000 --- a/test/javascript/tests/delayed_commits.js +++ /dev/null @@ -1,50 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -couchTests.delayed_commits = function(debug) { - - // Note that delayed_commits is deprecated in 2.0, so this is a minimal - // test to show it still works. delayed_commits will be removed in 3.0. - - db_name = get_random_db_name(); - var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"}); - db.deleteDb(); - db.createDb(); - if (debug) debugger; - - run_on_modified_server( - [{section: "couchdb", - key: "delayed_commits", - value: "true"}], - - function () { - // By default, couchdb doesn't fully commit documents to disk right away, - // it waits about a second to batch the full commit flush along with any - // other updates. If it crashes or is restarted you may lose the most - // recent commits. - - // restartServer() requires a server to be up 15s before it restarts - sleep(15000); - - T(db.save({_id:"1",a:2,b:4}).ok); - T(db.open("1") != null); - - restartServer(); - - T(db.open("1") == null); // lost the update. - // note if we waited > 1 sec before the restart, the doc would likely - // commit. - }); - - // cleanup - db.deleteDb(); -}; diff --git a/version.mk b/version.mk index a93c9b198..9ca09ab11 100644 --- a/version.mk +++ b/version.mk @@ -1,3 +1,3 @@ -vsn_major=2 -vsn_minor=3 +vsn_major=3 +vsn_minor=0 vsn_patch=0 |