你如何在生产中初始化mnesia?

时间:2016-04-22 21:04:58

标签: erlang mnesia rebar3

我正在使用rebar3来制作版本,但是如何在制作时初始化mnesia?

如果我编写一个执行mnesia:create_schema([node()])的“安装”escript,它将使用与发布使用的节点名完全不同的节点名。

所以我最终为“nonode @ nonode”创建了一个模式,而当我使用my-app-1.0.0 start启动我的应用程序时生成mnesia尝试访问“myapp @ localhost”节点。

此外,这是一种鸡与蛋的问题:

  1. 如果没有mnesia表,我就无法启动我的应用程序
  2. 我无法在没有运行应用程序的情况下安装我的mnesia表(与应用程序将使用的node()名称相同)。
  3. 如果有一个很好的方法可以解决这个问题吗?

    这是我独立运行的安装escript:

    #!/usr/bin/env escript
    %% -*- erlang -*-
    %%! -smp enable ls-mnesia debug verbose
    -include("../include/rr.hrl").
    
    main(_) ->
        application:set_env(mnesia, dir, "/usr/local/src/db/mnesia"),
        application:stop(mnesia),
        install([node()|nodes()]).
    
    install(Nodes) ->
        case mnesia:create_schema(Nodes) of
            ok -> 
                rpc:multicall(Nodes, application, start, [mnesia]),
                read_store_create_tables(Nodes),
                event_store_create_tables(Nodes),
                rpc:multicall(Nodes, application, stop, [mnesia]);
            Err -> 
                error_logger:warning_msg("Could not create schema: ~p~n", [Err]),
                Err
        end.    
    
    event_store_create_tables(Nodes) ->
        {_, ok} = mnesia:create_table(rr_events,
                [{attributes, record_info(fields, rr_events)},
                 {disc_copies, Nodes},
                 {type, bag}]).
    
    read_store_create_tables(Nodes) ->
        % Initialize the actual data-tables for the projections
        {_, ok} = mnesia:create_table(rr_competencies,
                [{attributes, record_info(fields, rr_competencies)},
                 {disc_copies, Nodes}]).
    

    P.S。:我正在使用rebar3使用relx来构建版本。

1 个答案:

答案 0 :(得分:1)

我正在使用自己的build system,这主要是因为确切的要求 - 在启动节点之前安装和初始化节点的能力。这个想法非常简单:two releases就是reltool.config,在这个特殊的例子中称为cmdhumbundeecmd版本不会启动主应用程序,只会加载它们。然后执行特殊功能以初始化节点。该功能在hbd_setup文件中配置。在这种情况下,来自deploy应用程序的bottom of the humbundee project's README。该函数读取配置文件,并从备份创建和初始化mnesia数据库,或者如果备份不存在则创建新数据库。安装节点后,它就开始使用正确的版本。在开发中(直接从源代码)和生产中(从OTP版本)执行相同的步骤。

使用该设置,您所描述的问题并不存在,因为两个版本都是从同一位置启动的,使用几乎相同的命令和配置文件(builderlreltool.config的配置生成它们})。

您可以使用任何构建工具(包括rebar3relx)使用相同的想法,手动执行这些步骤或使用某种脚本执行这些步骤。

builderl所做的是它自动执行这些步骤并提供一个环境,以便在开发和生产中以相同的方式执行它们,例如:请参阅dependencies that depend on other projects文件:

安装节点。这将启动cmd版本并执行hbd_setup:install/2函数来初始化节点:

./bin/init.esh

启动节点。这将启动humbundee版本,它会启动所有应用程序及其相应的主管树:

./bin/start.esh

builderl实际上使用rebar来提取和编译project-wide dependency file,但它仅使用OTP来创建发布。它还可以使用compiled with make自行下载依赖项,然后work in progress(编译时make不是{{3}})。我希望有所帮助。