Skip to content

Commit 24825ad

Browse files
committed
MB-66812: Use sha-256 hash instead of full VC for metakv rev
This change addresses the issue where vector clock revisions were too long. Switch to the new format: - Use a SHA256 hash of the vector clock This does not change anything about the metakv vector clocks internally. Services use `rev` to perform a CAS operation. `rev` is queried on a node and passed on subsequent mutate operations - to ensure that the underlying value is updated atomically. During a mutate operation, `rev` is computed afresh and compared (strict equality) with `rev` in the incoming request. If they differ, the operation is aborted. This does not require any changes in the API nor to services because: - Services treat `rev` as an opaque identifier. `rev` is queried using a GET. The raw bytes are sent in subsequent mutate operations. (PUT sends rev as raw bytes in a form URL-encoded body, DELETE as percent- encoded raw bytes in the query string.) - Services use `rev` on a node-local basis. There is no need to consider distinct `rev` formats on nodes running different versions. - During an upgrade, a service is restarted along with ns_server/cbauth. i.e. a node running a particular version always uses the same format for metakv Get/Set/Delete. Filed MB-68058 for further cleanup. Change-Id: I9f9bf165ac486fe213f1219a1a5b52e78e8b3d98 Reviewed-on: https://review.couchbase.org/c/ns_server/+/232169 Reviewed-by: Peter Searby <[email protected]> Well-Formed: Restriction Checker Well-Formed: Build Bot <[email protected]> Tested-by: Neelima Premsankar <[email protected]>
1 parent c8572d1 commit 24825ad

File tree

2 files changed

+17
-8
lines changed

2 files changed

+17
-8
lines changed

src/menelaus_metakv.erl

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ handle_normal_get(Req, Key) ->
5252
true ->
5353
menelaus_util:reply_json(Req, [], 404);
5454
false ->
55-
Rev = base64:encode(erlang:term_to_binary(VC)),
55+
Rev = base64:encode(metakv:convert_vc_to_opaque_hash(VC)),
5656
Val = base64:encode(Val0),
5757
menelaus_util:reply_json(Req, {[{rev, Rev},
5858
{value, Val}]})
@@ -70,8 +70,7 @@ handle_mutate(Req, Key, Value, Params) ->
7070
missing
7171
end;
7272
XRev ->
73-
XRevB = list_to_binary(XRev),
74-
binary_to_term(XRevB)
73+
list_to_binary(XRev)
7574
end,
7675
Sensitive = proplists:get_value("sensitive", Params) =:= "true",
7776
case metakv:mutate(Key, Value,
@@ -142,7 +141,7 @@ handle_iterate(Req, Path, Continuous) ->
142141
output_kv(HTTPRes, {K, V}) ->
143142
write_chunk(HTTPRes, null, K, base64:encode(V), false);
144143
output_kv(HTTPRes, {K, V, VC, Sensitive}) ->
145-
Rev0 = base64:encode(erlang:term_to_binary(VC)),
144+
Rev0 = base64:encode(metakv:convert_vc_to_opaque_hash(VC)),
146145
{Rev, Value} = case V of
147146
?DELETED_MARKER ->
148147
{null, null};

src/metakv.erl

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
ns_config_get/2,
2121
mutate/2, mutate/3,
2222
iterate_matching/1, iterate_matching/2, iterate_matching/3,
23-
check_continuous_allowed/1]).
23+
check_continuous_allowed/1,
24+
convert_vc_to_opaque_hash/1]).
2425

2526
%% Exported APIs
2627

@@ -180,12 +181,17 @@ ns_config_mutation(Key, Value, Params) ->
180181
false ->
181182
RV = ns_config:run_txn(
182183
fun (Cfg, SetFn) ->
183-
OldData = ns_config:search_with_vclock(Cfg, K),
184+
OldData = ns_config:search_with_vclock(Cfg,
185+
K),
184186
OldValue = get_old_value(OldData),
185187
NewValue = add_sensitive(Sensitive,
186188
OldValue, Value),
187-
OldVC = get_old_vclock(OldData),
188-
case Rev =:= OldVC of
189+
OldVCHash =
190+
case get_old_vclock(OldData) of
191+
missing -> missing;
192+
VC -> convert_vc_to_opaque_hash(VC)
193+
end,
194+
case Rev =:= OldVCHash of
189195
true ->
190196
{commit, SetFn(K, NewValue, Cfg)};
191197
false ->
@@ -351,3 +357,7 @@ ns_config_matching_kvs(Key, KVList) ->
351357
%% This will retain the behaviour as it existed
352358
%% before this code was moved here from menelaus_metakv.erl.
353359
[{K, V} || {K, V} <- KVList, Filter(K)].
360+
361+
%% Takes in a vector clock and returns an opaque SHA256 hash of that clock.
362+
convert_vc_to_opaque_hash(VC) ->
363+
crypto:hash(sha256, erlang:term_to_binary(VC)).

0 commit comments

Comments
 (0)