使用relup升级riak_core应用程序

问题描述:

我正在尝试升级正在运行的riak_core erlang应用程序。使用relup升级riak_core应用程序

简单的升级正在工作。我使用rebar3和relflow来成功升级应用程序。但是,如果我更改vnode的内部并使用relflow和rebar3重新生成新版本,则vnode将停止工作。 vnode被称为'cavv'。

热升级后,它崩溃,在这一点上:

DocIdx = riak_core_util:chash_key({<<"run">>, term_to_binary(os:timestamp())}), 

导致这个错误:

** exception error: bad argument 
    in function lists:keyfind/3 
     called as lists:keyfind(chash_keyfun,1,[{name,<<"run">>}|undefined]) 
    in call from riak_core_util:chash_key/2 (_build/default/lib/riak_core/src/riak_core_util.erl, line 266) 
    in call from cavv_vnode:run/0 (_build/prod/lib/cavv/src/cavv_vnode.erl, line 38) 

我relup看起来是这样的:

{"0.1.2", 
[{"0.1.1",[], 
    [{load_object_code,{cavv,"20161203-211601-relflow",[cavv_vnode]}}, 
    point_of_no_return, 
    {load,{cavv_vnode,brutal_purge,brutal_purge}}]}], 
[{"0.1.1",[],[point_of_no_return]}]}. 

上午我遗漏了什么?我必须重新启动一些主vnode吗?我尝试重新启动一些主管,但没有成功。

望着riak_core的源代码:

%% @spec chash_key(BKey :: riak_object:bkey()) -> chash:index() 
%% @doc Create a binary used for determining replica placement. 
chash_key({Bucket,_Key}=BKey) -> 
    BucketProps = riak_core_bucket:get_bucket(Bucket), 
    chash_key(BKey, BucketProps). 

%% @spec chash_key(BKey :: riak_object:bkey(), [{atom(), any()}]) -> 
%%   chash:index() 
%% @doc Create a binary used for determining replica placement. 
chash_key({Bucket,Key}, BucketProps) -> 
    {_, {M, F}} = lists:keyfind(chash_keyfun, 1, BucketProps), %% <-- Line 266 
    M:F({Bucket,Key}). 

我试图了解发生了什么事,但有一个很难把握发生了什么。不知何故BucketProps中的某些内容未定义升级后不应该定义的内容?

当我重新启动整个应用程序时,它就像一个魅力。

我在用riak_core进行热升级时错过了什么吗?或者关闭整个节点,然后升级并重新启动并忘记热代码升级更好?

UPDATE 同时我发现riak_core_bucket出现了问题。

运行以下:riak_core_bucket:get_bucket(<<"run">>).

升级之前:

[{name,<<"run">>}, 
{allow_mult,false}, 
{basic_quorum,false}, 
{big_vclock,50}, 
{chash_keyfun,{riak_core_util,chash_std_keyfun}}, 
{dvv_enabled,false}, 
{dw,quorum}, 
{last_write_wins,false}, 
{linkfun,{modfun,riak_kv_wm_link_walker,mapreduce_linkfun}}, 
{n_val,3}, 
{notfound_ok,true}, 
{old_vclock,86400}, 
{postcommit,[]}, 
{pr,0}, 
{precommit,[]}, 
{pw,0}, 
{r,quorum}, 
{rw,quorum}, 
{small_vclock,50}, 
{w,quorum}, 
{young_vclock,20}] 

升级后:

[{name,<<"run">>}|undefined] 

未定义由app_helper:get_env(riak_core, default_bucket_props).升级后返回。

我发现它试图在升级过程中处理sys.config:

Warning: "_build/prod/rel/cavv/releases/0.1.2/sys.config" missing (optional) 

使用生成的app.conf是不够的,因为它不包含以前显示的所有配置值。使用它只能输出:[{n_val,3}]

也许乌贼没有正确地重新加载conf文件的东西?

UPDATE2

做了一些更多的挖掘。升级后application:get_all_env(riak_core).返回不同的值。有任何想法吗?

我发现升级之后,所有的环境值将被清除:

http://erlang.org/doc/design_principles/release_handling.html#id84983

Specifically, the application configuration parameters are automatically updated according to (in increasing priority order):

The data in the boot script, fetched from the new application resource file App.app The new sys.config Command-line arguments -App Par Val This means that parameter values set in the other system configuration files and values set using application:set_env/3 are disregarded.

可以重设riak_core设置的值,我用一个简单的函数:

set_defaults() -> 
    riak_core_bucket:append_bucket_defaults(riak_core_bucket_type:defaults(default_type)). 

我把这个叫做我的继续档:

{apply,{cavv_app,set_defaults,[]}}, 

默认设置在这里的riak_core应用的开始时进行设置:

https://github.com/basho/riak_core/blob/develop/src/riak_core_app.erl#L42

但不导出此功能,而不是暴露。

不知道这是我提出的最优雅的解决方案。任何想法都欢迎。