Erlang 您如何在生产上初始化mnesia?
我正在使用rebar3生成一个发行版,但如何在生产版上初始化mnesia 如果我写了一个“install”escript来执行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
mnesia:create_schema([node()])
——它将使用与发行版完全不同的节点名
因此,我最终为“创建了一个模式”nonode@nonode“当我使用my-app-1.0.0 start启动我的应用程序时,
尝试访问”myapp@localhost“节点
此外,这是一种鸡和蛋的问题:
#!/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
或其他脚本检查其返回代码。