2016-12-03 150 views
1

我正在嘗試升級正在運行的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).返回不同的值。有任何想法嗎?

回答

1

我發現升級之後,所有的環境值將被清除:

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

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

不知道這是我提出的最優雅的解決方案。任何想法都歡迎。