diff --git a/.hgignore b/.hgignore deleted file mode 100644 index adf4ceac4..000000000 --- a/.hgignore +++ /dev/null @@ -1,5 +0,0 @@ -syntax regex -.*~ -^ebin/.*.beam -include/riak_core_pb.hrl -^.eunit \ No newline at end of file diff --git a/.hgtags b/.hgtags deleted file mode 100644 index 6fb0f2bd2..000000000 --- a/.hgtags +++ /dev/null @@ -1,9 +0,0 @@ -e716ebd150ff8698a89a1ae28bc868385a164497 riak_kv-0.13.0rc1 -04f5cfd0b8ca7c195e67658367afa5625c186218 riak_kv-0.13.0rc2 -a5e0a7b843b52fe846b8006543d1484b548b9a18 riak_kv-0.13.0rc3 -cda3363808baaae930bd21cc160f02d66a1b0e45 riak_kv-0.13.0rc5 -3a8621c61c539b47e391ae413deec196b5825fd8 riak_kv-0.13.0rc6 -3169321d36e79b4149fe8868ac079befb3fa9fa1 riak_kv-0.13.0rc7 -00e6b6e1e9a286fced87b2f8772fc7e716f47334 riak_kv-0.13.0rc8 -c21191095c7f75fe7651930b9b0ee891852fdf7a riak_kv-0.13.0rc9 -3fd46b5a5e9c2c8461e0de1837d38d9dbf04632c riak_kv-0.13.0 diff --git a/README.md b/README.md index 9af2fcdb1..db8746de0 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ * riak_kv ** Overview -[![Erlang CI Actions Status](https://github.com/basho/riak_kv/workflows/Erlang%20CI/badge.svg)](https://github.com/basho/riak_kv/actions) +[[https://github.com/basho/riak_kv/actions][Build Status]] - [[https://github.com/basho/riak_kv/actions/workflows/erlang.yml/badge.svg?branch=develop]] -Riak KV is an open source Erlang application that is distributed using the [[https://github.com/basho/riak_core][riak_core]] Erlang +Riak KV is an open source Erlang application that is distributed using the [[https://github.com/basho/riak_core][riak_core]] Erlang library. Riak KV provides a key/value datastore and features MapReduce, lightweight data relations, and several different client APIs. ** Quick Start - You must have [[http://erlang.org/download.html][Erlang/OTP 20 or 22]] or later and a GNU-style build + You must have [[http://erlang.org/download.html][Erlang/OTP 22, 24 or 25]] or later and a GNU-style build system to compile and run =riak_kv=. The easiest way to utilize riak_kv is by installing the full Riak application available on [[https://github.com/basho/riak][Github]]. diff --git a/src/riak_client.erl b/src/riak_client.erl index c01ebf906..7c18dd9bf 100644 --- a/src/riak_client.erl +++ b/src/riak_client.erl @@ -907,7 +907,7 @@ aae_fold(Query, {?MODULE, [Node, _ClientId]}) -> true -> riak_kv_clusteraae_fsm_sup:start_clusteraae_fsm(Node, [{raw, ReqId, Me}, - [Query, TimeOut]]), + [Q0, TimeOut]]), wait_for_fold_results(ReqId, TimeOut); false -> {error, "Invalid AAE fold definition"} diff --git a/src/riak_kv_clusteraae_fsm.erl b/src/riak_kv_clusteraae_fsm.erl index 66b9f779e..d92fcda1a 100644 --- a/src/riak_kv_clusteraae_fsm.erl +++ b/src/riak_kv_clusteraae_fsm.erl @@ -893,6 +893,8 @@ convert_fold({find_tombs, B, KR, SF, MR}) -> {find_tombs, B, KR, SF, convert_modrange(MR)}; convert_fold({reap_tombs, B, KR, SF, MR, CM}) -> {reap_tombs, B, KR, SF, convert_modrange(MR), CM}; +convert_fold({repair_keys_range, B, KR, MR, L}) -> + {repair_keys_range, B, KR, convert_modrange(MR), L}; convert_fold({erase_keys, B, KR, SF, MR, CM}) -> {erase_keys, B, KR, SF, convert_modrange(MR), CM}; convert_fold(Fold) -> diff --git a/src/riak_kv_console.erl b/src/riak_kv_console.erl index e6cb38eea..f2350f0ea 100644 --- a/src/riak_kv_console.erl +++ b/src/riak_kv_console.erl @@ -31,6 +31,7 @@ status/1, vnode_status/1, reip/1, + reip_manual/1, ringready/1, cluster_info/1, down/1, @@ -234,6 +235,40 @@ reip([OldNode, NewNode]) -> error end. +reip_manual([OldNode, NewNode, Dir, ClusterName]) -> + try + %% reip/1 requires riak_core to be loaded to learn the Ring Directory + %% and the Cluster Name. In reip_manual/1 these can be passed in + %% instead + RingDir = atom_to_list(Dir), + Cluster = atom_to_list(ClusterName), + {ok, RingFile} = + riak_core_ring_manager:find_latest_ringfile(RingDir, Cluster), + io:format("~nCHANGE DETAILS:~n"), + io:format("RingFile to update ~p~n", [RingFile]), + BackupFN = + filename:join([RingDir, filename:basename(RingFile)++".BAK"]), + {ok, _} = file:copy(RingFile, BackupFN), + io:format("Backed up existing ring file to ~p~n", [BackupFN]), + Ring = riak_core_ring_manager:read_ringfile(RingFile), + NewRing = riak_core_ring:rename_node(Ring, OldNode, NewNode), + NewRingFN = + riak_core_ring_manager:generate_ring_filename( + RingDir, Cluster), + ok = riak_core_ring_manager:do_write_ringfile(NewRing, NewRingFN), + io:format("New ring file written to ~p~n", [NewRingFN]), + io:format("~nATTENTION REQUIRED:~n"), + io:format( + "Update required to riak.conf nodename before restarting node;" + ++ " nodename should be changed to ~s~n", + [atom_to_list(NewNode)]), + io:format("~nok~n") + catch + Exception:Reason -> + io:format("Reip failed ~p:~p", [Exception, Reason]), + error + end. + %% Check if all nodes in the cluster agree on the partition assignment -spec(ringready([]) -> ok | error). ringready([]) -> diff --git a/src/riak_kv_get_fsm.erl b/src/riak_kv_get_fsm.erl index baad9375b..1a1ad42f2 100644 --- a/src/riak_kv_get_fsm.erl +++ b/src/riak_kv_get_fsm.erl @@ -90,9 +90,8 @@ -define(DEFAULT_TIMEOUT, 60000). -define(DEFAULT_R, default). --define(DEFAULT_PR, 0). +-define(DEFAULT_PR, default). -define(DEFAULT_RT, head). --define(DEFAULT_NC, 0). -define(QUEUE_EMPTY_LOOPS, 8). %% =================================================================== diff --git a/src/riak_kv_index_hashtree.erl b/src/riak_kv_index_hashtree.erl index 7c74af222..6302b57f5 100644 --- a/src/riak_kv_index_hashtree.erl +++ b/src/riak_kv_index_hashtree.erl @@ -710,8 +710,10 @@ fold_fun(HashtreePid, _HasIndexTree = true) -> -spec handle_corrupted_object( riak_object:bucket(), riak_object:key(), term(), term()) -> ok. handle_corrupted_object(Bucket, Key, Error, Reason) -> - ?LOG_WARNING("Unable to read B=~p K=~p", [Bucket, Key]), - ?LOG_WARNING("Read failure due to ~w ~w", [Error, Reason]), + ?LOG_WARNING( + "Unable to read B=~p K=~p due to ~p ~p during tree rebuild " ++ + "so will prompt read_repair - ignore warning during shutdown", + [Bucket, Key, Error, Reason]), riak_kv_reader:request_read({Bucket, Key}). -spec object_fold_fun(pid()) -> diff --git a/src/riak_object.erl b/src/riak_object.erl index a1ace4308..318f89b23 100644 --- a/src/riak_object.erl +++ b/src/riak_object.erl @@ -350,6 +350,8 @@ find_bestobject(FetchedItems) -> -spec is_head({ok, riak_object()}|riak_object()) -> boolean(). %% @private Check if an object is simply a head response +is_head({ok, #r_object{contents=[]}}) -> + false; is_head({ok, #r_object{contents=Contents}}) -> C0 = lists:nth(1, Contents), case C0#r_content.value of @@ -1678,6 +1680,17 @@ delete_hash(ObjOrClock) -> -ifdef(TEST). +%% See https://github.com/basho/riak_kv/issues/1707 +object_with_empty_contents_test() -> + B = <<"buckets_are_binaries">>, + K = <<"keys are binaries">>, + + Contents = [], + O = #r_object{bucket=B,key=K, + contents=Contents,vclock=vclock:fresh()}, + + ?assertEqual(false, is_head(O)). + object_test() -> B = <<"buckets_are_binaries">>, K = <<"keys are binaries">>,