This is an automated email from the ASF dual-hosted git repository.
nickva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/couchdb.git
The following commit(s) were added to refs/heads/main by this push:
new 7d9d2d360 Limit couch_server sharding
7d9d2d360 is described below
commit 7d9d2d36093b43d13a870ab4e9109c3bce98f5fb
Author: Nick Vatamaniuc <[email protected]>
AuthorDate: Thu Jun 4 15:50:59 2026 -0400
Limit couch_server sharding
With a default setting `max_dbs_open = 500` on servers with 128 CPU cores,
per-instance LRU cache limits would become tiny (500/128 = 4). In that
case, if
just 4 db names on any gen_server randomly pick any the same server the
cluster
will start emitting `all_dbs_active` errors, even though in aggregate across
all instances there will still be plenty of available LRU slots left.
As a simple solution, let's limit the sharding factor with a config setting.
Use the scheduler count on small instances and those will more schedulers
are
limited by the limit.
---
rel/overlay/etc/default.ini | 8 ++++++++
src/couch/src/couch_server.erl | 15 ++++++++++++++-
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/rel/overlay/etc/default.ini b/rel/overlay/etc/default.ini
index ff148b271..0662e6afd 100644
--- a/rel/overlay/etc/default.ini
+++ b/rel/overlay/etc/default.ini
@@ -16,6 +16,14 @@ view_index_dir = {{view_index_dir}}
; among them.
;max_dbs_open = 500
+; Limit the maximum number of couch_server shards. Normally couch_server
+; instances equal the number of Erlang schedulers, which by default equal the
+; number of CPUs available on a node. However, to avoid over-sharding and
+; getting too low of a per-couch-server max_dbs_open threshold it's beneficial
+; to limit the sharding factor. This setting cannot be dynamically changed at
+; runtime, the node must be restarted for it to take effect.
+;max_couch_server_shards = 16
+
; 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/src/couch/src/couch_server.erl b/src/couch/src/couch_server.erl
index 9a4d8bffb..7eca53f3a 100644
--- a/src/couch/src/couch_server.erl
+++ b/src/couch/src/couch_server.erl
@@ -40,6 +40,8 @@
-include("couch_server_int.hrl").
-define(MAX_DBS_OPEN, 500).
+-define(DEFAULT_SHARDS, 16).
+-define(SHARD_COUNT_PKEY, {?MODULE, max_couch_server_shards}).
-define(RELISTEN_DELAY, 5000).
-define(DEFAULT_ENGINE, "couch").
-define(AVAILABLE_JS_ENGINES, ["spidermonkey", "quickjs"]).
@@ -998,7 +1000,18 @@ name(BaseName, N) when is_integer(N), N > 0 ->
list_to_atom(BaseName ++ "_" ++ integer_to_list(N)).
num_servers() ->
- erlang:system_info(schedulers).
+ % This value is not allowed to change at runtime. When we call this the
+ % first time from the supervisor we'll fix the value at that point and
+ % always return that from then on.
+ case persistent_term:get(?SHARD_COUNT_PKEY, undefined) of
+ undefined ->
+ Max = config:get_integer("couchdb", "max_couch_server_shards",
?DEFAULT_SHARDS),
+ N = max(1, min(Max, erlang:system_info(schedulers))),
+ ok = persistent_term:put(?SHARD_COUNT_PKEY, N),
+ N;
+ N when is_integer(N), N >= 1 ->
+ N
+ end.
aggregate_queue_len() ->
N = num_servers(),