This is an automated email from the ASF dual-hosted git repository. vatamane pushed a commit to branch prototype/fdb-layer-custom-dir-prefix in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 84e6a87761464f1549382393ae8883ca4fb3cdab Author: Nick Vatamaniuc <[email protected]> AuthorDate: Mon Aug 12 14:40:59 2019 -0400 Add configurable FDB directory prefixes for CouchDB instances Specifying a custom prefix for CouchDB instances allow having multiple CouchDB instances on a single FDB cluser. This can also be used for integration testing by creating a temporary prefix, them deleting all data in that directory. --- rel/overlay/etc/default.ini | 5 +++ src/couch_jobs/src/couch_jobs_fdb.erl | 3 +- src/fabric/src/fabric2_dir_prefix_tests.erl | 69 +++++++++++++++++++++++++++++ src/fabric/src/fabric2_fdb.erl | 6 ++- src/fabric/src/fabric2_server.erl | 28 +++++++++++- src/fabric/src/fabric2_txids.erl | 6 ++- 6 files changed, 111 insertions(+), 6 deletions(-) diff --git a/rel/overlay/etc/default.ini b/rel/overlay/etc/default.ini index 59c89b0..1579c4f 100644 --- a/rel/overlay/etc/default.ini +++ b/rel/overlay/etc/default.ini @@ -200,6 +200,11 @@ port = 6984 ; attachments_timeout = 60000 ; view_timeout = 3600000 ; partition_view_timeout = 3600000 +; +; Custom FDB directory prefix. All the nodes of the same CouchDB instance +; should have a matching directory prefix in order to read and write the same +; data. Changes to this value take effect only on node start-up. +;fdb_directory = custom_prefix ; [rexi] ; buffer_count = 2000 diff --git a/src/couch_jobs/src/couch_jobs_fdb.erl b/src/couch_jobs/src/couch_jobs_fdb.erl index 1317d03..6903801 100644 --- a/src/couch_jobs/src/couch_jobs_fdb.erl +++ b/src/couch_jobs/src/couch_jobs_fdb.erl @@ -616,7 +616,8 @@ init_jtx(undefined) -> init_jtx({erlfdb_transaction, _} = Tx) -> Root = erlfdb_directory:root(), - CouchDB = erlfdb_directory:create_or_open(Tx, Root, [<<"couchdb">>]), + Dir = fabric2_server:fdb_directory(), + CouchDB = erlfdb_directory:create_or_open(Tx, Root, Dir), LayerPrefix = erlfdb_directory:get_name(CouchDB), Jobs = erlfdb_tuple:pack({?JOBS}, LayerPrefix), Version = erlfdb:wait(erlfdb:get(Tx, ?METADATA_VERSION_KEY)), diff --git a/src/fabric/src/fabric2_dir_prefix_tests.erl b/src/fabric/src/fabric2_dir_prefix_tests.erl new file mode 100644 index 0000000..bff0a3a --- /dev/null +++ b/src/fabric/src/fabric2_dir_prefix_tests.erl @@ -0,0 +1,69 @@ +% 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. + +-module(fabric2_dir_prefix_tests). + + +-include_lib("couch/include/couch_eunit.hrl"). +-include_lib("eunit/include/eunit.hrl"). + + +-define(TDEF(A), {atom_to_list(A), fun A/0}). + + +dir_prefix_test_() -> + { + "Test couchdb fdb directory prefix", + foreach, + fun() -> + % erlfdb, rexi and mem3 are all dependent apps for fabric. We make + % sure to start them so when fabric is started during the test it + % already has its dependencies + test_util:start_couch([erlfdb, rexi, mem3]) + end, + fun(Ctx) -> + config:delete("fabric", "fdb_directory"), + ok = application:stop(fabric), + test_util:stop_couch(Ctx) + end, + [ + ?TDEF(default_prefix), + ?TDEF(custom_prefix) + ] + }. + + +default_prefix() -> + ok = application:start(fabric), + + ?assertEqual([<<"couchdb">>], fabric2_server:fdb_directory()), + + % Try again to test pdict caching code + ?assertEqual([<<"couchdb">>], fabric2_server:fdb_directory()), + + % Check that we can create dbs + DbName = ?tempdb(), + ?assertMatch({ok, _}, fabric2_db:create(DbName, [])). + + +custom_prefix() -> + ok = config:set("fabric", "fdb_directory", "foo"), + ok = application:start(fabric), + + ?assertEqual([<<"couchdb">>, <<"foo">>], fabric2_server:fdb_directory()), + + % Try again to test pdict caching code + ?assertEqual([<<"couchdb">>, <<"foo">>], fabric2_server:fdb_directory()), + + % Check that we can create dbs + DbName = ?tempdb(), + ?assertMatch({ok, _}, fabric2_db:create(DbName, [])). diff --git a/src/fabric/src/fabric2_fdb.erl b/src/fabric/src/fabric2_fdb.erl index 3f02e6a..c58b5f6 100644 --- a/src/fabric/src/fabric2_fdb.erl +++ b/src/fabric/src/fabric2_fdb.erl @@ -258,7 +258,8 @@ exists(#{name := DbName} = Db) when is_binary(DbName) -> list_dbs(Tx, Callback, AccIn, Options) -> Root = erlfdb_directory:root(), - CouchDB = erlfdb_directory:create_or_open(Tx, Root, [<<"couchdb">>]), + Dir = fabric2_server:fdb_directory(), + CouchDB = erlfdb_directory:create_or_open(Tx, Root, Dir), LayerPrefix = erlfdb_directory:get_name(CouchDB), Prefix = erlfdb_tuple:pack({?ALL_DBS}, LayerPrefix), fold_range({tx, Tx}, Prefix, fun({K, _V}, Acc) -> @@ -737,7 +738,8 @@ debug_cluster(Start, End) -> init_db(Tx, DbName, Options) -> Root = erlfdb_directory:root(), - CouchDB = erlfdb_directory:create_or_open(Tx, Root, [<<"couchdb">>]), + Dir = fabric2_server:fdb_directory(), + CouchDB = erlfdb_directory:create_or_open(Tx, Root, Dir), Prefix = erlfdb_directory:get_name(CouchDB), Version = erlfdb:wait(erlfdb:get(Tx, ?METADATA_VERSION_KEY)), #{ diff --git a/src/fabric/src/fabric2_server.erl b/src/fabric/src/fabric2_server.erl index 5b826cd..7b07731 100644 --- a/src/fabric/src/fabric2_server.erl +++ b/src/fabric/src/fabric2_server.erl @@ -19,7 +19,8 @@ start_link/0, fetch/1, store/1, - remove/1 + remove/1, + fdb_directory/0 ]). @@ -37,6 +38,8 @@ -define(CLUSTER_FILE, "/usr/local/etc/foundationdb/fdb.cluster"). +-define(FDB_DIRECTORY, fdb_directory). +-define(DEFAULT_FDB_DIRECTORY, <<"couchdb">>). start_link() -> @@ -81,6 +84,14 @@ init(_) -> end, application:set_env(fabric, db, Db), + Dir = case config:get("fabric", "fdb_directory") of + undefined -> + [?DEFAULT_FDB_DIRECTORY]; + Val when is_list(Val), length(Val) > 0 -> + [?DEFAULT_FDB_DIRECTORY, ?l2b(Val)] + end, + application:set_env(fabric, ?FDB_DIRECTORY, Dir), + {ok, nil}. @@ -102,3 +113,18 @@ handle_info(Msg, St) -> code_change(_OldVsn, St, _Extra) -> {ok, St}. + + +fdb_directory() -> + case get(?FDB_DIRECTORY) of + undefined -> + case application:get_env(fabric, ?FDB_DIRECTORY) of + undefined -> + erlang:error(fabric_application_not_started); + {ok, Dir} -> + put(?FDB_DIRECTORY, Dir), + Dir + end; + Dir -> + Dir + end. diff --git a/src/fabric/src/fabric2_txids.erl b/src/fabric/src/fabric2_txids.erl index ba42741..06704f0 100644 --- a/src/fabric/src/fabric2_txids.erl +++ b/src/fabric/src/fabric2_txids.erl @@ -45,7 +45,8 @@ start_link() -> create(Tx, undefined) -> Root = erlfdb_directory:root(), - CouchDB = erlfdb_directory:create_or_open(Tx, Root, [<<"couchdb">>]), + Dir = fabric2_server:fdb_directory(), + CouchDB = erlfdb_directory:create_or_open(Tx, Root, Dir), Prefix = erlfdb_directory:get_name(CouchDB), create(Tx, Prefix); @@ -136,7 +137,8 @@ clean(St, NeedsSweep) -> sweep(Tx, {Mega, Secs, Micro}) -> Root = erlfdb_directory:root(), - CouchDB = erlfdb_directory:create_or_open(Tx, Root, [<<"couchdb">>]), + Dir = fabric2_server:fdb_directory(), + CouchDB = erlfdb_directory:create_or_open(Tx, Root, Dir), Prefix = erlfdb_directory:get_name(CouchDB), StartKey = erlfdb_tuple:pack({?TX_IDS}, Prefix), EndKey = erlfdb_tuple:pack({?TX_IDS, Mega, Secs, Micro}, Prefix),
