Erlang 您如何在生产上初始化mnesia?

Erlang 您如何在生产上初始化mnesia?,erlang,mnesia,rebar3,Erlang,Mnesia,Rebar3,我正在使用rebar3生成一个发行版,但如何在生产版上初始化mnesia 如果我写了一个“install”escript来执行mnesia:create_schema([node()])——它将使用与发行版完全不同的节点名 因此,我最终为“创建了一个模式”nonode@nonode“当我使用my-app-1.0.0 start启动我的应用程序时,尝试访问”myapp@localhost“节点 此外,这是一种鸡和蛋的问题: 没有记忆表,我无法启动我的应用程序 如果应用程序不运行,我无法安装mnes

我正在使用rebar3生成一个发行版,但如何在生产版上初始化mnesia

如果我写了一个“install”escript来执行
mnesia:create_schema([node()])
——它将使用与发行版完全不同的节点名

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

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

  • 没有记忆表,我无法启动我的应用程序
  • 如果应用程序不运行,我无法安装mnesia表(与应用程序将使用的名称相同)
  • 只是想知道是否有一个好方法来处理这个问题

    这是我独立运行的安装脚本:

    #!/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}]).
    
    注意:我正在使用
    rebar3
    ,它使用
    relx
    来构建发行版

    我正在使用我自己的,主要是因为这个确切的需求——在启动节点之前安装和初始化节点的能力。想法很简单:在这个特殊的例子中,有
    cmd
    humbundee
    cmd
    版本不启动主应用程序,只加载它们。然后执行一个特殊函数来初始化节点。该函数在文件中配置。在本例中,它来自
    deploy
    应用程序。该函数读取配置文件,然后从备份中创建并初始化mnesia数据库,或者如果备份不存在,则创建新数据库。安装节点后,将使用适当的版本启动节点。在开发(直接从源代码)和生产(从OTP版本)中执行相同的步骤

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


    通过手动或使用某种脚本执行这些步骤,您可以对任何构建工具(包括
    rebar3
    relx
    )采用相同的思想

    builderl
    所做的是,它自动执行这些步骤,并提供一个在开发和生产中以相同方式执行这些步骤的环境,例如,请参见以下文件:

    安装节点。这将启动
    cmd
    释放并执行
    hbd\u安装:安装/2
    功能以初始化节点:

    ./bin/init.esh
    
    启动节点。这将启动
    humbendee
    版本,该版本将启动所有应用程序及其相应的管理器树:

    ./bin/start.esh
    


    builderl
    实际上使用
    rebar
    来拉取和编译,但是它只使用OTP来创建发布。它还可以使用下载依赖项本身,然后(编译时不使用
    make
    is)。我希望这会有所帮助。

    但如何通过构建脚本(即ansible)实现这一切的自动化?问题在于,应用程序启动时与脚本不同,它作为服务运行,因此脚本不知道应用程序何时完成数据库初始化。(哇,这比我想象的要复杂得多。)请检查这个答案(搜索
    init:stop()
    ):然后这个函数:基本上,有两个Erlang实例。当执行
    /bin/init.esh
    builderl
    时,它在自己的虚拟机中运行。然后,它使用
    cmd
    版本启动已安装的VM,对其进行配置,然后将其关闭。如果出现问题,它将返回代码
    1
    。当
    builderl
    完成时,可以通过
    make
    或其他脚本检查其返回代码。