Mnesia在由Yaws运行时无法创建表,但是可以在从Erlang shell运行时创建

use*_*131 2 erlang yaws mnesia erlang-shell web

我有一个.yaws文件,它调用我写setup/0authenticate模块中的函数,我把它放在ebin目录中.当我authenticate:setup/0从Erlang shell 调用时,它创建一个表就好了,但是当我在浏览器中加载something.yaws时,调用该authenticate:setup/0函数,它返回{aborted,{bad_type,users,disc_copies,nonode@nohost}}(something.yaws只返回authenticate:setup/0嵌入在html中的返回值以进行调试) .

这是setup/0功能:

setup() ->
    mnesia:create_schema([node()]),
    mnesia:start(),
    mnesia:create_table(users, [{type, set}, {record_name, user}, {disc_copies, [node()]}, {attributes, record_info(fields, user)}]).
Run Code Online (Sandbox Code Playgroud)

这是user记录:

-record(user, {username, hashed_pw, salt}).
Run Code Online (Sandbox Code Playgroud)

(我已经尝试在浏览器中尝试之后从Erlang shell调用它,因此无法干扰它.)

如果我跑yaws --mnesiadir /usr/local/lib/yaws-appmods/mnesia/,我得到

Erlang/OTP 19 [erts-8.1] [source] [64-bit] [smp:8:8] [async-threads:10] [kernel-poll:true]

Eshell V8.1  (abort with ^G)
1> 
=INFO REPORT==== 7-Nov-2016::00:04:49 ===
Yaws: Using config file /etc/yaws/yaws.conf

=INFO REPORT==== 7-Nov-2016::00:04:49 ===
Yaws: Using global subconfig file /etc/yaws/conf.d/localhost.conf

=INFO REPORT==== 7-Nov-2016::00:04:49 ===
Ctlfile : /home/username/.yaws/yaws/default/CTL

=INFO REPORT==== 7-Nov-2016::00:04:49 ===
Yaws: Listening to 0.0.0.0:8080 for <1> virtual servers:
 - http://localhost:8080 under /usr/share/yaws/www
rd(user, {username, hashed_pw, salt}).
user
2> mnesia:create_schema([node()]), mnesia:start(), mnesia:create_table(users, [{type, set}, {record_name, user}, {disc_copies, [node()]}, {attributes, record_info(fields, user)}]).
{aborted,{bad_type,users,disc_copies,nonode@nohost}}
Run Code Online (Sandbox Code Playgroud)

如果我在开始使用的Erlang shell中运行相同的erlang代码erl -mnesia dir '"/usr/local/lib/yaws-appmods/mnesia/"',它就可以正常工作.

Ste*_*ski 5

运行Yaws时,请传递命令行选项--mnesiadir dir,告诉它您希望它存储mnesia数据的位置.dir选项的参数应该是您希望数据存在的目录的路径名.例如,传递--mnesiadir /tmp将导致Yaws将mnesia数据存储在/tmp目录中.

顺便说一下,如果你传递一个mnesia dir选项,将mnesia数据目录设置为不存在的东西,你可以看到没有Yaws的Erlang shell出现同样的错误:

$ erl -mnesia dir '"/xyzfoo"'
Erlang/OTP 19 [erts-8.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V8.1  (abort with ^G)
1> rd(user, {username, hashed_pw, salt}).
user
2> mnesia:create_schema([node()]), mnesia:start(), mnesia:create_table(users, [{type, set}, {record_name, user}, {disc_copies, [node()]}, {attributes, record_info(fields, user)}]).
{aborted,{bad_type,users,disc_copies,nonode@nohost}}
Run Code Online (Sandbox Code Playgroud)

在这里,我们假设没有这样的目录/xyzfoo.第一个Erlang shell命令定义user您正在使用的相同记录,第二个命令执行与您的authenticate:setup/0函数相同的步骤.如图所示,它返回与Yaws相同的错误.

请注意,'"/xyzfoo"'对于Yaws --mnesiadir选项,不需要将选项正确地传递给Erlang shell(在典型的基于UNIX的系统上)所需的目录名称的异常引用.还要注意的是Erlang的选择是一个连字符后面两个词,mnesiadir,其次是引用目录名,而对于雅司病的选择是一个字mnesiadir由两个连字符之前和之后一个普通的目录名.

编辑:如果在为Yaws设置mnesia目录之后你仍然会遇到问题,那是因为你在mnesia已经运行之后尝试创建你的模式.当Yaws看到该--mnesiadir选项时,它会启动mnesia应用程序.因此,您应该在运行Yaws之前创建模式,或者在创建模式之前停止mnesia.将您的authenticate:setup/0功能更改为以下内容,它将起Yaws的作用:

setup() ->
    mnesia:stop(),
    mnesia:create_schema([node()]),
    mnesia:start(),
    mnesia:create_table(users, [{type, set}, {record_name, user}, {disc_copies, [node()]}, {attributes, record_info(fields, user)}]).
Run Code Online (Sandbox Code Playgroud)