mnesia

模块

mnesia

模块摘要

分布式电信DBMS

描述

以下是Mnesia提供的一些最重要和有吸引力的功能:

  • 适用于电信应用的关系/对象混合数据模型。
  • DBMS查询语言,Query List Comprehension(QLC)作为附加库。
  • 持久性。表格可以连贯地保存在光盘和主存储器中。
  • 复制。表可以在多个节点上复制。
  • 原子事务。可以将一系列表操作操作分组到单个原子事务中。
  • 位置透明度。程序可以在不了解实际数据位置的情况下编写。
  • 非常快的实时数据搜索。
  • 模式操作例程。可以在运行时重新配置DBMS,而无需停止系统。

本参考手册描述了Mnesia API。这包括定义和操作Mnesia表的函数。

本参考手册中的所有功能都可以与使用列表理解符号的查询结合使用。有关查询符号的信息,请参阅qlcSTDLIB中的手册页。

Mnesia中的数据被组织成一组表。每个表都有一个必须是原子的名称。每个表都由Erlang记录组成。用户负责记录定义。每个表还具有一组属性。以下是与每个表相关联的一些属性:

  • type。每个表都可以拥有setordered_setbag语义。请注意,目前ordered_set不支持disc_only_copies。如果一个表是类型的set,则每个键都会导致一个或零个记录。如果使用与现有记录相同的密钥插入新项目,则旧记录将被覆盖。但是,如果某个表是键入的bag,则每个键都可以映射到多个记录。类型bag表中的所有记录都是唯一的,只有密钥可以重复。
  • record_name存储在表中的所有记录必须具有相同的名称。这些记录必须是同一记录类型的实例。
  • ram_copies一个表可以复制到多个Erlang节点上。财产ram_copies指定保存RAM副本的Erlang节点列表。这些副本可以定期倒入光盘。但是,对这些副本的更新并不是在事务处理的基础上写入光盘的。
  • disc_copies。该属性指定了表格保存在RAM和光盘上的Erlang节点列表。表格的所有更新都在实际表格中执行,并且也记录到光盘中。如果一个表是disc_copies某个节点的类型,整个表就驻留在RAM存储器和光盘上。在表上执行的每个事务都附加到一个LOG文件并写入RAM表中。
  • disc_only_copies。一些或全部表副本只能保存在光盘上。这些副本比基于RAM的副本慢得多。
  • index这是一个属性名或整数的列表,它指定Mnesia要在其上构建和维护一个额外索引表的元组位置。
  • local_content当应用程序需要内容为每个节点本地的表时,local_content可以使用表。表名对所有Mnesia节点都是已知的,但其内容在每个节点上是唯一的。这意味着必须在本地访问这样的表。集场local_contenttrue若要启用local_content行为。默认值是false...
  • majority.这个属性是truefalse;默认值是false.何时true,大多数表副本必须可用,才能使更新成功。大多数检查都可以在具有关键任务数据的表上启用,在这些表中,避免由于网络分裂而导致的不一致是至关重要的。
  • snmp。每个(基于集合的)Mnesia表也可以自动变成简单网络管理协议(SNMP)有序表。该属性指定了SNMP密钥的类型。
  • attributes表中插入的记录的属性名称。

有关完整的表属性集及其详细信息,请参见mnesia:create_table/2...

本参考手册使用了一个人表来说明各种例子。假定记录定义如下:

-record(person, {name,
                 age = 0,
                 address = unknown,
                 salary = 0,
                 children = []}),

第一个记录属性是主键,或者简称为键。

功能描述按字母顺序排序。 建议开始阅读有关mnesia:create_table / 2,mnesia:lock / 2和mnesia:activity / 4,然后继续学习其余知识。

在事务上下文中写入或删除会在事务中创建每个修改记录的本地副本。 迭代过程中,mnesia:fold [lr] / 4,mnesia:next / 2,mnesia:prev / 2和mnesia:snmp_get_next_index / 2,Mnesia会补偿每个写入或删除的记录,从而降低性能。

如果可能,避免在迭代表之前写入或删除同一事务中的记录。

输出

abort(Reason) -> transaction abort

使交易返回元组{aborted, Reason}。 Mnesia事务的终止意味着一个异常被抛出到一个封闭的catch上。 因此,表达式catch mnesia:abort(x)不会终止事务。

activate_checkpoint(Args) -> {ok,Name,Nodes} | {error,Reason}

检查点是系统的一致视图。一组检查点可以在一组表上激活。然后可以遍历该检查点,并在检查点被激活时呈现系统视图,即使该表正在或已经被操纵。

Args是以下元组的列表:

  • {name,Name}.Name是检查点名称。每个检查点必须具有对关联节点唯一的名称。只有在检查点停用后,名称才能重新使用。默认情况下,会生成一个可能唯一的名称。
  • {max,MaxTabs}.MaxTabs是要包含在检查点中的表的列表。默认是[]。对于这些表,冗余是最大化的,检查点信息与所有副本一起保留。如果表有多个副本,则检查点变得更容错。当模式操作功能添加新副本时mnesia:add_table_copy/3,保持器也会自动附加。
  • {min,MinTabs}.MinTabs是要包含在检查点中的表的列表。默认是[]。对于这些表,冗余最小化,检查点信息仅保留一个副本,最好在本地节点上。
  • {allow_remote,Bool}.false意味着所有的保留必须是本地的。如果表格不在本地驻留,则无法激活检查点。true允许在任何节点上分配保持器。默认是true
  • {ram_overrides_dump,布尔}。仅适用于ram_copies。 Bool允许您选择将表状态备份到RAM中,也可以将它备份到光盘上。 true表示RAM中的最新提交记录将包含在检查点中。这些是应用程序访问的记录。 false表示转储到DAT文件的记录将包含在检查点中。这些记录在启动时加载。默认为false.Returns {ok,Name,Nodes}或{error,Reason}。名称是(可能生成的)检查点名称。节点是涉及检查点的节点。只有保持checkpoint retainer的节点知道checkpoint.activity(AccessContext,Fun [,Args]) - > ResultOfFun | exit(Reason)调用mnesia:activity(AccessContext,Fun,Args,AccessMod),其中AccessMod是mnesia:system_info(access_module)获取的默认访问回调模块。参数默认为[](空列表).activity(AccessContext,Fun,Args,AccessMod) - > ResultOfFun | exit(Reason)使用参数Args执行功能对象Fun。在活动内执行的代码可以由一系列表操作函数组成,这些函数在AccessContext中执行。目前,支持以下访问上下文:事务处理{transaction,infinity} {transaction,Retries}的简称调用mnesia:transaction(Fun,Args,Retries)。请注意,如果事务成功(原子),则返回Fun的结果,否则该函数将以中止原因退出。 sync_transaction简称{sync_transaction,infinity} {sync_transaction,Retries}调用mnesia:sync_transaction(Fun,Args,Retries)。请注意,如果事务成功(原子),则返回Fun的结果,否则该函数将以中止原因退出。 async_dirty调用mnesia:async_dirty(Fun,Args)。 sync_dirty调用mnesia:sync_dirty(Fun,Args)。 ets(Fun,Args)。这个函数(mnesia:activity / 4)与函数mnesia:transaction,mnesia:sync_transaction,mnesia:async_dirty,mnesia:sync_dirty和mnesia:ets有很大不同。参数AccessMod是实现mnesia_access行为的回调模块的名称.Mnesia将调用转发给以下函数:
  • mnesia:lock / 2(read_lock_table / 1,write_lock_table / 1)
  • mnesia:write/3 (write/1, s_write/1)

  • mnesia:delete/3 (delete/1, s_delete/1)

  • mnesia:delete_object/3 (delete_object/1, s_delete_object/1)

  • mnesia:read/3 (read/1, wread/1)

  • mnesia:match_object/3 (match_object/1)

  • mnesia:all_keys/1

  • mnesia:first/1

  • mnesia:last/1

  • Mnesia:PRV/2
  • Mnesia:Next/2
  • mnesia:index_match_object/4 (index_match_object/2)

  • mnesia:index_read/3

  • mnesia:table_info/2

相应的:

  • AccessMod:lock(ActivityId, Opaque, LockItem, LockKind)

  • AccessMod:write(ActivityId, Opaque, Tab, Rec, LockKind)

  • AccessMod:delete(ActivityId, Opaque, Tab, Key, LockKind)

  • AccessMod:delete_object(ActivityId, Opaque, Tab, RecXS, LockKind)

  • AccessMod:read(ActivityId, Opaque, Tab, Key, LockKind)

  • AccessMod:match_object(ActivityId, Opaque, Tab, Pattern, LockKind)

  • AccessMod:all_keys(ActivityId, Opaque, Tab, LockKind)

  • AccessMod:first(ActivityId, Opaque, Tab)

  • AccessMod:last(ActivityId, Opaque, Tab)

  • AccessMod:prev(ActivityId, Opaque, Tab, Key)

  • AccessMod:next(ActivityId, Opaque, Tab, Key)

  • AccessMod:index_match_object(ActivityId, Opaque, Tab, Pattern, Attr, LockKind)

  • AccessMod:index_read(ActivityId, Opaque, Tab, SecondaryKey, Attr, LockKind)

  • AccessMod:table_info(ActivityId, Opaque, Tab, InfoItem)

ActivityId是一个记录,表示包含Mnesia活动的身份。 第一个字段(由元素(1,ActivityId)获得)包含一个原子,可以将其解释为活动类型:ets,async_dirty,sync_dirty或tid。 tid表示该活动是一项交易。 其余身份记录的结构是Mnesia的内部结构。

Opaque 是Mnesia内部的一个不透明的数据结构。

add_table_copy(Tab, Node, Type) -> {aborted, R} | {atomic, ok}

在节点上创建另一个表副本Node。参数Type必须是原子的ram_copiesdisc_copiesdisc_only_copies。例如,以下调用可确保表中的光盘副本person也存在于节点Node

mnesia:add_table_copy(person, Node, disc_copies)

此函数还可用于添加名为schema...

add_table_index(Tab, AttrName) -> {aborted, R} | {atomic, ok}

只要用户想要频繁使用除关键字段之外的其他字段来查找记录,就可以使用表索引。 如果这个其他字段有一个关联的索引,这些查找可以在恒定的时间和空间中进行。 例如,如果您的应用程序希望使用字段时间来有效地查找具有特定年龄的所有人,那么在字段年龄上设置索引可能是个好主意。 这可以通过以下调用完成:

mnesia:add_table_index(person, age)

索引不是免费的。它们占据与表大小成正比的空间,并且它们导致插入到表中执行稍慢。

all_keys(Tab) -> KeyList | transaction abort

返回名为的表中所有键的列表Tab。这个函数的语义是上下文敏感的。有关更多信息,请参阅mnesia:activity/4。在事务上下文中,它获取整个表上的读锁。

async_dirty(Fun, [, Args]) -> ResultOfFun | exit(Reason)

在未受交易保护的环境中调用Fun。 Fun中执行的Mnesia函数调用映射到相应的脏函数。 这仍然涉及日志记录,复制和预订,但是不涉及锁定,本地事务存储或提交协议。 检查点保留器和索引已更新,但它们被更新为脏。 至于正常的mnesia:dirty_ *操作,操作是以半异步方式执行的。 有关详细信息,请参阅mnesia:activity / 4和用户指南。

Mnesia表可以在不使用事务的情况下进行操作。这有一些严重的缺点,但速度要快得多,因为事务管理器没有涉及,也没有设置锁。但是,脏操作确保了一定程度的一致性,脏操作不能返回乱码记录。所有肮脏的操作为程序员提供了位置透明性,程序不必知道某个表的行踪功能。

请注意,读取记录比在事务中更有效10倍以上。

根据应用程序的不同,对某些操作使用脏函数可能是一个好主意。几乎所有可以在交易中调用的Mnesia函数都有一个脏等价物,效率更高。

但是,请注意,如果使用脏操作来更新数据库,则可能会使数据库处于不一致的状态。脏操作只有在绝对必要时才能用于性能方面的考虑。

注意,mnesia:[a]sync_dirty在事务上下文中调用(嵌套)会继承事务语义。

backup(Opaque [, BackupMod]) -> ok | {error,Reason}

激活覆盖所有mnesia表(包括架构)的新检查点,最大程度的冗余,并使用backup_checkpoint/2/3备份回调模块的默认值BackupModmnesia:system_info(backup_module)...

backup_checkpoint(Name, Opaque [, BackupMod]) -> ok | {error,Reason}

使用备份模块BackupMod将表格备份到外部介质。 备份本地内容属性的表格,因为它们存在于当前节点上。 BackupMod是由mnesia:system_info(backup_module)获取的默认备份回调模块。 有关确切的回调接口(mnesia_backup行为)的信息,请参阅用户指南。

change_config(Config, Value) -> {error, Reason} | {ok, ReturnValue}

Config是以下配置参数的原子:

extra_db_nodes

Value是Mnesia尝试连接的节点列表。 ReturnValue是Mnesia连接到的Value中的那些节点。

请注意,此功能只能用于以空模式连接到新启动的RAM节点(NDRSN)。例如,如果在网络分区后使用此功能,则可能导致表格不一致。

注意,mnesia可以连接到ReturnValue中以外的节点

dc_dump_limit

Value是一个数字。请参阅中的说明Section Configuration ParametersReturnValue是新的价值。注意这个配置参数不是持久的。当Mnesia停止时它就会失去。

change_table_access_mode(Tab, AccessMode) -> {aborted, R} | {atomic, ok}

AcccessMode默认是原子read_write,但它也可以设置为原子read_only。 如果AccessMode设置为read_only,则无法执行对表的更新。 在启动时,Mnesia始终在本地加载read_only表,无论Mnesia何时以及是否在其他节点上终止。

change_table_copy_type(Tab, Node, To) -> {aborted, R} | {atomic, ok}

例如:

mnesia:change_table_copy_type(person, node(), disc_copies)

person表格从RAM表格转换为基于光盘的表格Node

该函数也可用于更改名为schema的表的存储类型。 模式表只能包含ram_copies或disc_copies作为存储类型。 如果模式的存储类型是ram_copies,则不能在该节点上驻留其他表。

change_table_load_order(Tab, LoadOrder) -> {aborted, R} | {atomic, ok}

LoadOrder优先级是默认为0(零),但可以设置为任意整数。具有最高LoadOrder优先级的表在启动时首先加载。

change_table_majority(Tab, Majority) -> {aborted, R} | {atomic, ok}

Majority必须是布尔值。默认是false。何时true,大部分表副本必须可用于更新才能成功。在分段表上使用时,Tab必须是基表的名称。不允许直接更改单个片段的大多数设置。

clear_table(Tab) -> {aborted, R} | {atomic, ok}

删除表格中的所有条目Tab

create_schema(DiscNodes) -> ok | {error,Reason}

在光盘上创建一个新的数据库。在每个节点的本地Mnesia目录中创建各种文件。请注意,该目录对于每个节点必须是唯一的。两个节点绝不能共享相同的目录。如果可能,请使用本地磁盘设备来提高性能。

mnesia:create_schema / 1会失败,如果任何Erlang节点作为DiscNodes提供的都不存在,如果Mnesia正在任何节点上运行,或者任何节点已经有一个模式。 使用mnesia:delete_schema / 1来摆脱旧的错误模式。

请注意,只有包含光盘的节点才会包含在DiscNodes中。 不包含无盘节点,即所有包括架构的表都只驻留在RAM中的节点,不得包含在内。

create_table(Name, TabDef) -> {atomic, ok} | {aborted, Reason}

根据参数TabDef创建名为Name的Mnesia表。 该列表必须是{Item,Value}元组列表,其中允许使用以下值:

  • {access_mode,Atom}。 访问模式默认为原子read_write,但也可以设置为原子read_only。 如果AccessMode设置为read_only,则无法执行对表的更新。在启动时,Mnesia始终在本地加载read_only表,无论何时以及如果Mnesia在其他节点上终止。 该参数返回表的访问模式。 访问模式可以是read_only或read_write。
  • {attributes, AtomList}用于填充表的记录的属性名列表。默认值是[key, val]该表除键外至少必须有一个额外的属性。

在访问记录中的单个属性时,没有必要或甚至不推荐将任何属性名称作为原子进行硬编码。 改为使用构造record_info(fields,RecordName)。 它可以用于RecordName类型的记录。

  • {disc_copies, Nodelist},其中Nodelist是该表应该具有光盘副本的节点的列表。如果表副本是类型的disc_copies,则表的这个特定副本上的所有写入操作都写入到光盘和表的RAM副本中。有可能disc_copies在一个节点上有一个复制的类型表,在另一个节点上有另一个类型的表。默认是[]
  • {disc_only_copies,Nodelist},其中Nodelist是该表应该具有disc_only_copies的节点的列表。 仅光盘表副本仅保留在光盘上,与其他副本类型不同,副本的内容不驻留在RAM中。 这些副本比保存在RAM中的副本慢得多。
  • {index, Intlist},其中Intlist是Mnesia建立和维护额外索引表的属性名称(原子)或记录字段的列表。如果有索引可用,qlc查询编译器可能能够优化查询。
  • {load_order,Integer}。 加载顺序优先级默认为0(零),但可以设置为任何整数。 启动时首先加载具有最高加载顺序优先级的表。
  • {majority,Flag},其中Flag必须是布尔值。 如果为true,则表中的任何(非肮脏)更新都会中止,除非大多数表副本可用于提交。 在碎片表格上使用时,所有碎片都被赋予相同的多数设置。
  • {ram_copies,Nodelist},其中Nodelist是该表应该拥有RAM副本的节点列表。 类型ram_copies的表副本不会写入到每个事务基础的光盘上。 使用mnesia:dump_tables(Tabs)函数可以将ram_copies副本转储到光盘。 此属性的默认值是[node()]。
  • {record_name,Name},其中Name必须是一个原子。 存储在表中的所有记录必须具有该名称作为第一个元素。 它的默认名称与表名相同。
  • {snmp, SnmpStruct}。有关说明SnmpStruct,请参阅mnesia:snmp_open_table/2。如果此属性出现在ArgListmnesia:create_table/2,该表是立即SNMP访问。因此,使用SNMP来操纵和控制系统的应用程序可以很容易地进行设计,因为Mnesia在构成SNMP控制应用程序的逻辑表与构成Mnesia表的物理数据之间提供了直接映射。
  • {storage_properties,[{Backend,Properties}]将更多属性转发到后端存储。 后端当前可以是ets或dets。 属性是在创建表时发送到后端存储的选项列表。 属性不能包含Mnesia已经使用的属性,例如type或named_table。例如:mnesia:create_table(table,[{ram_copies,node()},{disc_only_copies,nodes()},{storage_properties,[{ets,compressed},{dets,{auto_save,5000}}]}]))
  • {type, Type},其中Type必须是原子的setordered_setbag。默认是set。在a中set,所有记录都有唯一的密钥。在a中bag,多个记录可以具有相同的密钥,但是记录内容是唯一的。如果存储了非唯一记录,则旧的冲突记录将被覆盖。

请注意,目前ordered_set不支持disc_only_copies

{local_content,Bool},其中Bool是true或false。例如,以下调用将创建person表(前面定义)并将其复制到两个节点上:mnesia:create_table(person,

    [{ram_copies,[N1,N2]},

     {attributes,record_info(fields,person)}])。如果要求Mnesia必须在表中插入的所有人员记录的属性地址上建立和维护一个额外的索引表,则会发出以下代码:mnesia :CREATE_TABLE(人,

    [{ram_copies,[N1,N2]},

     {index,[address]},

     {attributes,record_info(fields,person)}])。

   索引和属性的规范可分别硬编码为{index,[2]}和{attributes,[name,age,address,salary,children]}。mnesia:create_table / 2将记录写入表模式。该功能以及所有其他模式处理功能都是使用普通事务管理系统实现的。这保证以原子方式在所有节点上执行模式更新.deactivate_checkpoint(Name) - > ok | {错误,原因}当涉及的某些表没有附加保持器时,检查点会自动停用。这可能发生在节点关闭或复制副本被删除时。使用此功能也可以禁用检查点。 Name是活动checkpoint.del_table_copy(Tab,Node) - > {aborted,R} |的名称{atomic,ok}删除节点Node上表格Tab的副本。当使用此函数删除最后一个副本时,该表将完全消失。此函数也可用于删除名为schema的表的副本。 Mnesia节点然后被删除。注意Mnesia必须先在节点上停止.del_table_index(Tab,AttrName) - > {aborted,R} | {atomic,ok}在table.delete({Tab,Key}) - >事务异常中删除名称为AttrName的属性索引。 okCalls mnesia:删除(Tab,Key,write).delete(Tab,Key,LockKind) - >事务中止| ok使用键Key删除表Tab中的所有记录。此函数的语义是上下文相关的。有关详细信息,请参阅mnesia:activity / 4。在事务上下文中,它获取记录中的LockKind类型的锁。目前,锁类型write和sticky_write是被支持的.delete_object(Record) - > transaction abort | okCalls mnesia:delete_object(Tab,Record,write),其中Tab是element(1,Record).delete_object(Tab,Record,LockKind) - > transaction abort | ok如果一个表的类型是bag,有时可能需要用某个键删除一些记录。这可以通过函数delete_object / 3来完成。一个完整的记录必须提供给这个函数。这个函数的语义是上下文敏感的。有关详细信息,请参阅mnesia:activity / 4。在事务上下文中,它获取记录上的LockKind类型的锁。目前,锁定类型write和sticky_write是supported.delete_schema(DiscNodes) - > ok | {error,Reason}删除使用mnesia:create_schema / 1创建的数据库。 mnesia:如果作为DiscNodes提供的任何Erlang节点都没有活动,或者Mnesia正在任何节点上运行,则delete_schema / 1会失败。删除数据库后,仍然可以启动Mnesia作为无盘节点。这取决于如何设置配置参数schema_location。警告请谨慎使用此函数,因为它会使现有的持久数据过时。在使用it.delete_table(Tab) - > {aborted,Reason} |之前要三思{atomic,ok}永久删除表Tab.dirty_all_keys(Tab)的所有副本 - > KeyList |退出({aborted,Reason})函数mnesia:all_keys / 1.dirty_delete({Tab,Key}) - > ok |退出({aborted,Reason})调用mnesia:dirty_delete(Tab,Key).dirty_delete(Tab,Key) - > ok |退出({aborted,Reason})mnesia:delete / 3.dirty_delete_object(Record)调用脏等价物调用mnesia:dirty_delete_object(Tab,Record),其中Tab是element(1,Record).dirty_delete_object(Tab,Record)Dirty相当于函数mnesia:delete_object / 3.dirty_first(Tab) - > Key |退出({aborted,Reason})集合或包表格中的记录未被排序。但是,用户不知道记录的排序。因此,可以用函数mnesia:dirty_next / 2来遍历一个表。如果表中没有记录,则该函数返回原子'$ end_of_table'。因此,使用这个原子作为任何用户记录的关键是非常不可取的,但并不是不允许的。

dirty_index_match_object(Pattern,Pos)开始mnesia:dirty_index_match_object(Tab,Pattern,Pos),其中Tab是element(1,Pattern).dirty_index_match_object(Tab,Pattern,Pos)函数mnesia的脏等价物:index_match_object / 4.dirty_index_read(Tab ,SecondaryKey,Pos)脏函数mnesia:index_read / 3.dirty_last(Tab) - > Key | exit({aborted,Reason})与mnesia:dirty_first / 1完全相同,但返回ordered_set表类型的Erlang术语顺序中的最后一个对象。对于所有其他表类型,mnesia:dirty_first / 1和mnesia:dirty_last / 1是synonym.dirty_match_object(Pattern) - > RecordList |调用mnesia:dirty_match_object(Tab,Pattern),其中Tab是element(1,Pattern).dirty_match_object(Tab,Pattern) - > RecordList |退出({aborted,Reason})功能相当于mnesia:match_object / 3.dirty_next(Tab,Key) - > Key |退出({aborted,Reason})遍历一个表并对表中的所有记录执行操作。当到达表的末尾时,返回特殊键“$ end_of_table”。否则,该函数返回一个可用于读取实际记录的密钥。如果另一个Erlang进程正在使用mnesia函数遍历表时执行写操作,则行为未定义:dirty_next / 2.dirty_prev(Tab,Key) - > Key |退出({aborted,Reason})与mnesia:dirty_next / 2完全相同,但返回以Erlang术语顺序排列的ordered_set表类型的前一个对象。对于所有其他表类型,mnesia:dirty_next / 2和mnesia:dirty_prev / 2是synonym.dirty_read({Tab,Key}) - > ValueList | ({aborted,Reason}调用mnesia:dirty_read(Tab,Key).dirty_read(Tab,Key) - > ValueList | exit({aborted,Reason}函数mnesia的脏等效函数:read / 3.dirty_select(Tab,MatchSpec ) - > ValueList | exit({aborted,Reason}函数mnesia的脏方法:select / 2.dirty_slot(Tab,Slot) - > RecordList | exit({aborted,Reason})以类似于函数mnesia:dirty_next / 2。一个表有多个从0(零)到一个未知上限的槽。当达到表的末尾时,函数mnesia:dirty_slot / 2返回特殊原子'$ end_of_table' 。如果在表中执行写操作时,此函数的行为是未定义的.dirty_update_counter({Tab,Key},Incr) - > NewVal | exit({aborted,Reason})调用mnesia:dirty_update_counter( Tab,Key,Incr).dirty_update_counter(Tab,Key,Incr) - > NewVal | exit({aborted,Reason})Mnesia没有特殊的计数记录,但是{Tab,Key,I当Tab是一个集合时,它可以用作(可能是磁盘驻留)计数器。该函数用正数或负数更新计数器。但是,计数器永远不会小于零。这个函数与第一次读取记录,执行算术操作,然后写入记录之间有两个显着的区别:

  • 它的效率要高得多。
  • mnesia:dirty_update_counter/3作为原子操作执行,尽管它不受事务的保护。

如果两个进程mnesia:dirty_update_counter/3同时执行,则两个更新都会生效,而不会有丢失其中一个更新的风险。返回计数器的新值NewVal

如果Key不存在,如果Incr大于0,则创建一个带有值的新记录,否则将其设置为0。

dirty_write(Record) -> ok | exit({aborted, Reason})

调用mnesia:dirty_write(Tab, Record),其中Tabelement(1, Record)

dirty_write(Tab, Record) -> ok | exit({aborted, Reason})

函数的脏等价mnesia:write/3...

dump_log() -> dumped

执行用户启动的本地日志文件转储。这通常是不必要的,因为默认情况下,Mnesia会自动管理。见配置参数dump_log_time_thresholddump_log_write_threshold...

dump_tables(TabList) -> {atomic, ok} | {aborted, Reason}

转储一组ram_copies桌子到光盘。下次系统启动时,这些表将使用转储的结果文件中的数据启动。所有的表都不能有磁盘驻留的副本。

dump_to_textfile(Filename)

将Mnesia系统的所有本地表转换为文本文件,可以编辑文本文件(通过普通的文本编辑器),然后重新加载mnesia:load_textfile/1。只能将此功能用于教育目的。使用其他功能来处理真实的备份。

error_description(Error) -> String

所有Mnesia事务,包括所有模式更新函数,都是返回值{atomic, Val}或元组{aborted, Reason}Reason可以是以下列表中的任一原子。该函数error_description/1返回描述错误的描述性字符串。

  • nested_transaction在此上下文中不允许嵌套事务。
  • badarg。错误或无效的说法,可能是错误的类型。
  • no_transaction.不允许进行外部交易的操作。
  • combine_error表选项非法合并。
  • bad_index索引已经存在,或者超出了范围。
  • already_exists要激活的架构选项已经打开。
  • index_exists某些操作不能对具有索引的表执行。
  • no_exists。试图在不存在的(不存在的)项目上执行操作。
  • system_limit一个制度限制已经用尽。
  • mnesia_down事务涉及远程节点上的记录,该记录在事务完成前就变得不可用。网络中的其他地方不再提供记录。
  • not_a_db_node.提到架构中不存在的节点。
  • bad_type参数中指定的错误类型。
  • node_not_running节点未运行。
  • truncated_binary_file文件中截断的二进制文件。
  • active一些删除操作要求删除所有活动记录。
  • illegal本记录不支持的操作。

Error可以是Reason{error, Reason},或{aborted, Reason}Reason可以是原子或元组,Reason并在第一场中作为原子。

下面的示例演示返回错误的函数以及检索更详细错误信息的方法:

  • 函数mnesia:create_table(bar,[{attributes,3.14}])返回元组{aborted,Reason},其中Reason是元组{bad_type,bar,3.14000}。
  • 该函数mnesia:error_description(Reason)返回该术语{"Bad type on some provided arguments",bar,3.14000},该术语是适合显示的错误描述。

ets(Fun, [, Args]) -> ResultOfFun | exit(Reason)

调用Fun未被事务保护的原始上下文。Mnesia函数调用Fun在本地ETS表中执行并直接执行,假设本地存储类型为ram_copies,并且表不复制到其他节点。订阅不会被触发,检查点也不会更新,但速度非常快。disc_copies如果所有操作都是只读的,则该函数也可以应用于表格。有关详细信息,请参阅mnesia:activity/4和用户指南。

注意调用(嵌套)mnesia:ets事务上下文内部会继承事务语义。

first(Tab) -> Key | transaction abort

记录setbag表格没有排序。但是,用户不知道记录的排序。因此可以通过该功能使用该功能遍历表格mnesia:next/2

如果表中没有记录,则此函数返回原子'$end_of_table'。因此,使用这个原子作为任何用户记录的关键是非常不可取的,但并不是不允许的。

foldl(Function, Acc, Table) -> NewAcc | transaction abort

遍历表Table并为表中的每个记录调用Function(Record,NewAcc)。 从函数返回的术语用作下一次函数调用的第二个参数。

foldl返回与返回的最后一次调用相同的期限Function

foldr(Function, Acc, Table) -> NewAcc | transaction abort

工作方式与foldl / 3完全相同,但以ordered_set表类型的相反顺序迭代表。 对于所有其他表类型,foldr / 3和foldl / 3是同义词。

force_load_table(Tab) -> yes | ErrorDescription

表格加载的Mnesia算法会导致表格无法加载的情况。这种情况发生在节点启动时,Mnesia得出结论或怀疑由于系统崩溃导致此本地副本变为非活动状态后表的另一副本处于活动状态。

如果这种情况不可接受,则可以使用此函数来覆盖Mnesia表加载算法的策略。这可能会导致一些事务效应因结果不一致而丢失,但对于某些应用程序来说,高可用性比一致性数据更重要。

index_match_object(Pattern, Pos) -> transaction abort | ObjList

开始mnesia:index_match_object(Tab, Pattern, Pos, read),这里Tab就是element(1, Pattern)

index_match_object(Tab, Pattern, Pos, LockKind) -> transaction abort | ObjList

以类似于该功能的方式mnesia:index_read/3,在尝试匹配记录时可以使用任何索引信息。该函数采用与函数相同的规则mnesia:match_object/3,但该函数需要以下条件:

  • 该表Tab必须具有位置索引Pos
  • 位置Pos中的元素Pattern必须被绑定。Pos是一个整数(#record.Field)或一个属性名称。

qlc当使用列表解析搜索表格时以及在使用低级mnesia:[dirty_]match_object函数时,这里描述的两个索引搜索函数会自动启动。

这个函数的语义是上下文敏感的。 有关详细信息,请参阅mnesia:activity / 4。 在事务上下文中,它获取整个表或单个记录上的LockKind类型的锁。 目前,支持读锁类型。

index_read(Tab, SecondaryKey, Pos) -> transaction abort | RecordList

假设某个记录类型的位置Pos有索引。 此功能可用于在不知道记录的实际密钥的情况下读取记录。 例如,对于人员表1中的索引,调用mnesia:index_read(person,36,#person.age)返回所有具有年龄36的人员的列表.pos也可以是属性名称(atom),但是 如果使用符号mnesia:index_read(person,36,age),则会在运行时为每个调用搜索字段位置。

这个函数的语义是上下文敏感的.。有关详细信息,请参阅mnesia:activity/4.在事务上下文中,它获取整个表的读锁。

info() -> ok

在终端上打印系统信息。即使未启动Mnesia,也可以使用此函数。但是,如果启动Mnesia,则会显示更多信息。

install_fallback(Opaque) -> ok | {error,Reason}

调用mnesia:install_fallback(Opaque, Args),其中Args[{scope, global}]

install_fallback(Opaque), BackupMod) -> ok | {error,Reason}

调用mnesia:install_fallback(Opaque, Args),其中Args[{scope, global}, {module, BackupMod}]

install_fallback(Opaque, Args) -> ok | {error,Reason}

安装备份作为后备。回退用于在下次启动时恢复数据库。安装回退需要Erlang在所有涉及的节点上运行,但是如果Mnesia运行或不运行则无关紧要。如果本地节点不是备份中的磁盘驻留节点之一,则回退的安装将失败。

Args是以下元组的列表:

  • {module,BackupMod}。 备份媒体的所有访问均通过名为BackupMod的回调模块执行。 参数不透明转发给回调模块,回调模块可以根据需要进行解释。 默认回调模块称为mnesia_backup,它将参数Opaque解释为本地文件名。 此模块的默认值也可以通过配置参数-mnesia mnesia_backup进行配置。
  • {scope, Scope}。 回退的范围对于整个数据库来说是全局的,或者对于一个节点来说是本地的。 默认情况下,回退的安装是全局操作,可以在具有磁盘驻留模式的所有节点上执行,也可以不执行。 哪些磁盘驻留节点是根据备份中的架构信息确定的。

如果Scope操作是local,则回退仅安装在本地节点上。

{mnesia_dir,AlternateDir}。此参数仅在安装的范围是本地时才有效。正常情况下,回退的安装将针对Mnesia目录,配置参数为-mnesia dir。但通过显式提供AlternateDir,无论Mnesia目录配置参数设置如何,均会安装回退。在替代Mnesia目录上安装回退后,该目录已完全准备好用作活动的Mnesia目录。

这是一个必须小心使用的危险功能。如果在多个directory.is_transaction() - > boolean上安装了相同的备份,则无意中混合了目录,那么最终可能会导致数据库不一致。如果此函数在事务上下文中执行,则返回true,否则返回false .last(Tab) - > Key |事务abortWorks与mnesia:first / 1完全相同,但返回ordered_set表类型的Erlang术语顺序中的最后一个对象。对于所有其他表类型,mnesia:first / 1和mnesia:last / 1是synonym.load_textfile(Filename)将文本文件中找到的一系列定义和数据(使用mnesia:dump_to_textfile / 1生成)加载到Mnesia中。这个函数也启动Mnesia并可能创建一个新的模式。此功能仅用于教育目的。建议使用其他函数来处理真正的backups.lock(LockItem,LockKind) - > Nodes |好的|事务abortWrite锁通常在表的副本驻留(并处于活动状态)的所有节点上获取。在一个节点(本地节点,如果存在本地副本)上获取读取锁定。如果在事务上下文中启动了大多数上下文敏感的访问函数,则会获取隐式锁。锁的粒度可以是单个记录,也可以是整个表。正常使用是在不检查返回值的情况下调用该函数,因为如果它失败并且事务由事务管理器重新启动,它将退出。如果获得了写入锁定,它将返回所有锁定的节点,并确定它是否为读取锁定。函数mnesia:lock / 2旨在支持对表格的显式锁定,但也适用于需要获取锁定的情况如何复制表格。目前,支持两种LockKind:write写锁定是独占的。这意味着如果一个事务设法获取对一个项目的写入锁定,则其他事务不能在同一个项目上获取任何类型的锁定。读取锁可以共享。这意味着如果一个事务设法获取对一个项目的读取锁定,其他事务也可以获得对同一项目的读取锁定。但是,如果某人有读锁定,则没有人可以在同一项目上获取写锁定。如果某人有写入锁定,则任何人都不能在同一个项目上获取读取锁定或写入锁定。如果没有死锁风险,则会自动排队冲突锁定请求。否则,交易必须终止并再次执行。只要未达到最大重试次数的上限,Mnesia会自动执行此操作。有关详细信息,请参阅mnesia:transaction / 3.为了完整起见,即使此函数不支持粘滞写入锁,也会在此描述粘滞写入锁:sticky_write粘滞写入锁是一种可用于优化写入的机制锁定采集。如果您的应用程序使用主要用于容错的复制表(而不是读取访问优化目的),则粘滞锁可能是最佳选择。当获取粘滞写入锁时,将通知所有节点哪个节点被锁定。然后,来自同一节点的粘滞锁定请求将作为本地操作执行,而不与其他节点进行任何通信。即使在交易结束后,粘滞的锁仍会留在节点上。有关详细信息,请参见用户指南。目前,此函数支持两种LockItem:{table,Tab}这将在整个表Tab中获取LockKind类型的锁。 {global,GlobalKey,Nodes}这将在全局资源GlobalKey上获取LockKind类型的锁。锁在节点列表中的所有活动节点上获取。最外层事务结束时释放锁。此函数的语义是上下文敏感的。有关详细信息,请参阅mnesia:activity / 4。在事务上下文中,它获取锁,否则它将忽略request.match_object(Pattern) - >事务中止| RecListCalls mnesia:match_object(Tab,Pattern,read),其中Tab是element(1,Pattern).match_object(Tab,Pattern,LockKind) - > transaction abort | RecList使用“不关心”变量表示为'_'参数的模式。这个函数返回一个匹配模式的记录列表。由于表中记录的第二个元素被认为是记录的关键字,因此此函数的性能取决于该键是否被绑定。

例如,调用mnesia:match_object(person,{person,'_',36,'_','_'},read)返回一个年龄字段为36的所有人员记录的列表。函数mnesia:match_object / 3会自动使用索引(如果存在的话)。然而,没有启发式选择最好的索引。这个函数的语义是上下文敏感的。有关详细信息,请参阅mnesia:activity / 4。在事务上下文中,它在整个表或单个记录上获取LockKind类型的锁。目前,锁类型的读取是supported.move_table_copy(Tab,From,To) - > {aborted,Reason} | {atomic,ok}将表格Tab的副本从节点From移动到节点To.将保留存储类型。例如,从一个节点移动的RAM表仍然是新节点上的RAM。其他事务在移动时仍然可以在表中读写。此函数不能用于local_content tables.next(Tab,Key) - > Key |事务abortTranseing一个表,并对表中的所有记录执行操作。当到达表的末尾时,返回特殊键“$ end_of_table”。否则,函数返回一个可用于读取实际记录的密钥.prev(Tab,Key) - > Key |事务abortWorks与mnesia:next / 2完全相同,但返回的是以Erlang术语顺序排列的ordered_set表类型的前一个对象。对于所有其他表类型,mnesia:next / 2和mnesia:prev / 2是synonym.read({Tab,Key}) - >事务中止| RecordListCalls函数mnesia:read(Tab,Key,read).read(Tab,Key) - >事务中止| RecordListCalls函数mnesia:read(Tab,Key,read).read(Tab,Key,LockKind) - > transaction abort | RecordList使用键Key从表Tab中读取所有记录。无论Tab的位置如何,此函数都具有相同的语义。如果表的类型是bag,则函数mnesia:read(Tab,Key)可以返回一个任意长的列表。如果该表的类型是set,则该列表的长度为1或[]。此函数的语义是上下文相关的。有关详细信息,请参阅mnesia:activity / 4。在事务上下文中,它获取LockKind类型的锁。目前,支持锁定类型读取,写入和sticky_write。如果用户想要更新记录,使用write / sticky_write作为LockKind会更高效。如果大多数检查在表上处于活动状态,则在尝试写入锁定时立即检查它。如果不满足大多数条件,这可以用于快速结束.read_lock_table(Tab) - > ok |事务abortCalls函数mnesia:lock({table,Tab},read).report_event(Event) - > ok当追踪Mnesia应用程序系统时,能够将Mnesia自己的事件与应用程序相关事件交错,应用程序上下文。无论何时应用程序开始一个新的要求Mnesia任务,或者如果它在执行中进入一个新的有趣阶段,使用mnesia:report_event / 1可能是一个好主意。事件可以是任何术语,并为订阅Mnesia系统events.restore(Opaque,Args) - > {atomic,RestoredTabs} | {aborted,Reason}的任何进程生成{mnesia_user,Event}事件。使用此函数,表可以无需重新启动Mnesia即可从备份在线恢复。不透明被转发到备份模块。参数是以下元组的列表:

  • {module,BackupMod}.备份模块BackupMod用于访问备份媒体。如果省略,则使用默认备份模块。
  • {skip_tables, TabList},其中TabList是不能从备份中读取的表的列表。
  • {clear_tables, TabList},其中TabList是在插入备份记录之前要清除的表的列表。也就是说,在恢复表之前,表中的所有记录都将被删除。有关这些表的架构信息不会被清除或从备份中读取。
  • {keep_tables, TabList},其中TabList是在插入备份记录之前不会被清除的表的列表。也就是说,备份中的记录被添加到表中的记录中。有关这些表的架构信息不会被清除或从备份中读取。
  • {recreate_tables, TabList},其中TabList是在插入备份记录之前要重新创建的表的列表。表格首先被删除,然后使用备份中的模式信息创建。备份中的所有节点都需要运行。
  • {default_op,Operation},其中Operation是操作skip_tables,clear_tables,keep_tables或recreate_tables中的任一个。 默认操作指定在备份中未在任何提及的列表中指定的表上使用哪个操作。 如果省略,则使用clear_tables操作。

受影响的表在还原过程中被写锁定。但是,不管由此导致的锁冲突,应用程序可以在执行还原时继续执行其工作。恢复是作为一个事务执行的。

如果数据库是巨大的,它并不总是能够在线恢复它。在这种情况下,通过安装回退程序恢复旧数据库,然后重新启动。

s_delete({Tab, Key}) -> ok | transaction abort

调用函数mnesia:delete(Tab, Key, sticky_write)

s_delete_object(Record) -> ok | transaction abort

调用函数mnesia:delete_object(Tab, Record, sticky_write),这里的Tabelement(1, Record)

s_write(Record) -> ok | transaction abort

调用函数mnesia:write(Tab, Record, sticky_write),这里的Tabelement(1, Record)

schema() -> ok

打印有关终端上所有表定义的信息。

schema(Tab) -> ok

在终端上打印有关一个表定义的信息。

select(Tab, MatchSpec [, Lock]) -> transaction abort | [Object]

按照ets:select / 3中的描述使用match_spec匹配表Tab中的对象。 可选地,锁读取或写入可以作为第三个参数给出。 默认被读取。 返回值取决于MatchSpec。

请注意,为了获得最好的表现,select将在同一事务中对该表执行任何修改操作之前使用。也就是说,不要使用writedeleteselect之前

在最简单的形式中,match_spec如下所示:

  • MatchSpec = [MatchFunction]
  • MatchFunction = {MatchHead, [Guard], [Result]}
  • MatchHead = tuple() | record()
  • Guard = {"Guardtest name", ...}
  • Result = "Term construct"

有关完整的说明select,请参见ERTS用户指南和etsSTDLIB中的手册页。

例如,要查找表中所有30岁以上的男性的姓名Tab

MatchHead = #person{name='$1', sex=male, age='$2', _='_'},
Guard = {'>', '$2', 30},
Result = '$1',
mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),

select(Tab, MatchSpec, NObjects, Lock) -> transaction abort | {[Object],Cont} | '$end_of_table'

按照用户指南中的描述Tab使用a 匹配表中的对象,并返回一大堆术语和一个延续。返回的术语的所需数量由参数指定。锁定参数可以是或。如果需要更多或全部答案,则继续将用作参数。match_specERTSNObjectsreadwritemnesia:select/1

请注意,为获得最佳性能,在同一事务中对该表执行任何修改操作之前,应使用select。 也就是说,不要在mnesia:select之前使用mnesia:write或mnesia:delete。 为了提高效率,NObjects只是一个建议,结果可以包含从空列表到所有可用结果的任何内容。

select(Cont) -> transaction abort | {[Object],Cont} | '$end_of_table'

选择更多的对象,其中由匹配规范发起mnesia:select/4

请注意,任何修改操作,mnesia:write或者mnesia:deletemnesia:select/4mnesia:select/1调用之间完成的修改操作在结果中都不可见。

set_debug_level(Level) -> OldLevel

更改Mnesia的内部调试级别。有关详情,请参阅Section Configuration Parameters

set_master_nodes(MasterNodes) -> ok | {error, Reason}

对于每个表,Mnesia确定其复制节点(TabNodes)并启动mnesia:set_master_nodes(Tab,TabMasterNodes)。 其中TabMasterNodes是MasterNode和TabNodes的交集。 有关语义,请参阅mnesia:set_master_nodes / 2。

set_master_nodes(Tab, MasterNodes) -> ok | {error, Reason}

如果应用程序检测到可能导致数据库不一致的通信故障(在潜在的分区网络中),则可以使用该功能mnesia:set_master_nodes(Tab, MasterNodes)来定义每个表将从哪个节点加载。在启动时,Mnesia正常表加载算法被绕过,并且从为该表定义的主节点之一加载该表,而不管何时以及如果Mnesia在其他节点上终止。MasterNodes只能包含表具有副本的节点。如果MasterNodes列表为空,则重置特定表的主节点恢复机制,并在下次重新启动时使用正常加载机制。

主节点设置始终是本地的。无论Mnesia启动与否,它都可以更改。

如果使用配置参数max_wait_for_decision或者如果mnesia:force_load_table/1使用,数据库也可能会变得不一致。

snmp_close_table(Tab) -> {aborted, R} | {atomic, ok}

消除SNMP操作表的可能性。

snmp_get_mnesia_key(Tab, RowIndex) -> {ok, Key} | undefined

类型

将SNMP索引转换为相应的Mnesia键。如果SNMP表有多个键,则键是键列的元组。

snmp_get_next_index(Tab, RowIndex) -> {ok, NextIndex} | endOfTable

类型

RowIndex可以指定不存在的行。具体来说,它可以是空列表。返回下一个词典行的索引。如果RowIndex为空列表,此函数返回表中第一行的索引。

snmp_get_row(Tab, RowIndex) -> {ok, Row} | undefined

类型

按其SNMP索引读取行。此索引指定为SNMP对象标识符,即整数列表。

snmp_open_table(Tab, SnmpStruct) -> {aborted, R} | {atomic, ok}

类型

可以在Mnesia表和SNMP表之间建立直接的一对一映射。许多电信应用都是由SNMP协议控制和监控的。Mnesia和SNMP之间的这种连接使得实现此映射变得简单方便。

参数SnmpStruct是SNMP信息的列表。 目前,唯一需要的信息是关于表格中关键类型的信息。 Mnesia无法处理多个密钥,但许多SNMP表都有多个密钥。 因此,使用以下约定:如果一个表具有多个键,则这些键必须始终作为键的元组存储。 有关键类型的信息被指定为描述类型的原子的元组。 唯一重要的类型是fix_string。 这意味着一个字符串具有固定的大小。

例如,以下原因表person作为SNMP表进行排序:

mnesia:snmp_open_table(person, [{key, string}])

请考虑公司员工表的下列架构。每个员工都按部门编号和名称进行标识。另一个表列存储电话号码:

mnesia:create_table(employee,
    [{snmp, [{key, {integer, string}}]},
     {attributes, record_info(fields, employees)}]),

相应的SNMP表将有三列:departmentnametelno

一个选项是具有通过SNMP协议不可见的表列。 这些列必须是表格的最后一列。 在前面的示例中,SNMP表可能只有列部门和名称。 然后应用程序可以在内部使用列telno,但SNMP管理器不可见。

在SNMP监视的表中,所有元素都必须是整数、字符串或整数列表。

当表格是SNMP订购的时候,修改比平常更昂贵,O(logN)。此外,使用更多的内存。

请注意,只有在Mnesia中实现的是字典SNMP排序,而不是实际的SNMP监视。

start() -> ok | {error, Reason}

一组Mnesia节点的启动过程是一个相当复杂的操作。Mnesia系统由一组节点组成,Mnesia在所有参与节点上本地启动。通常,每个节点都有一个目录,其中所有的Mnesia文件都被写入。这个目录被称为Mnesia目录。Mnesia也可以在无盘节点上启动。有关无盘节点的更多信息,请参阅mnesia:create_schema/1用户指南。

组成Mnesia系统的一组节点保存在一个模式中。Mnesia节点可以添加到架构或从架构中移除。通常使用该功能在光盘上创建初始架构mnesia:create_schema/1。在无盘节点上,每次启动Mnesia时都会生成一个微小的默认模式。在启动过程中,Mnesia在节点之间交换模式信息以验证表定义是否兼容。

每个模式都有一个唯一的cookie,这可以被视为一个唯一的模式标识符。在Mnesia应该运行的所有节点上,Cookie必须相同。有关详细信息,请参阅用户指南。

模式文件和Mnesia需要的所有其他文件都保存在Mnesia目录中。命令行选项-mnesia dir Dir可用于指定此目录到Mnesia系统的位置。如果没有找到这样的命令行选项,则该目录的名称默认为Mnesia.Node

也可以使用application:start(mnesia)

stop() -> stopped

在当前节点上本地停止Mnesia。

也可以使用application:stop(mnesia)

subscribe(EventCategory) -> {ok, Node} | {error, Reason}

确保将类型为EventCategory的所有事件的副本发送给调用者。 用户指南中介绍了可用的事件类型。

sync_dirty(Fun, [, Args]) -> ResultOfFun | exit(Reason)

在未受交易保护的环境中调用Fun。 Fun中执行的Mnesia函数调用映射到相应的脏函数。 它在与mnesia:async_dirty / 1,2几乎相同的上下文中执行。 不同之处在于操作是同步执行的。 在Fun返回之前,调用方将等待所有活动副本上执行的更新。 有关详细信息,请参阅mnesia:activity / 4和用户指南。

sync_log() -> ok | {error, Reason}

确保本地事务日志文件同步到磁盘。在单节点系统上,如果发生停电,自上次转储以来写入磁盘表的数据可能会丢失。参阅dump_log/0

sync_transaction(Fun, [[, Args], Retries]) -> {aborted, Reason} | {atomic, ResultOfFun}

等到数据被提交并记录到每个涉及的节点上的磁盘(如果使用了磁盘)后再返回,否则它的行为如下mnesia:transaction/[1,2,3]

该功能可用于避免一个进程重载另一个节点上的数据库。

system_info(InfoKey) -> Info | exit({aborted, Reason})

返回有关Mnesia系统的信息,例如事务统计信息db_nodes和配置参数。有效的密钥如下所示:

  • all。返回所有本地系统信息的列表。每个元素都是一个{InfoKey, InfoVal}元组。InfoKey可以添加新的s,并且InfoKey可以在不通知的情况下删除旧的未记录的s。
  • access_module。返回配置为活动访问回调模块的模块的名称。
  • auto_repair.返回truefalse指示mnesia是否配置为启动损坏的光盘文件上的自动修复工具。
  • backup_module返回配置为备份回调模块的模块的名称。
  • checkpoints返回此节点上当前活动的检查点的名称列表。
  • event_module返回作为事件处理程序回调模块的模块的名称。
  • db_nodes返回构成持久数据库的节点。只有在节点列表中显式地将无盘节点添加到架构中时,才会将它们包括在内,例如,使用mnesia:add_table_copy/3即使Mnesia还没有运行,也可以启动该函数。
  • debug返回Mnesia的当前调试级别。
  • directory返回Mnesia目录的名称。即使Mnesia还没有运行,它也可以被调用。
  • dump_log_load_regulation返回一个布尔值,该布尔值指示Mnesia是否被配置为调节翻车进程负载。

此功能是暂时的,将在以后的版本中删除。

  • dump_log_time_threshold返回事务日志转储的时间阈值(毫秒)。
  • dump_log_update_in_place返回一个布尔值,该布尔值指示Mnesia是否被配置为直接执行Dets文件中的更新,或者是否要在Dets文件的副本中执行更新。
  • dump_log_write_threshold返回事务日志转储的写入阈值,作为事务日志的写入次数。
  • extra_db_nodes。返回额外的列表。db_nodes在启动时联系。
  • fallback_activated。 如果后备已激活,则返回true,否则返回false。
  • held_locks返回本地Mnesia锁管理器持有的所有锁的列表。
  • 在跑。 返回是或否来指示Mnesia是否正在运行。 它也可以返回开始或停止。 即使Mnesia尚未运行,也可以调用。
  • local_tables返回配置为驻留在本地的所有表的列表。
  • lock_queue返回本地锁管理器排队执行的所有事务的列表。
  • log_version返回Mnesia事务日志格式的版本号。
  • master_node_tables返回至少有一个主节点的所有表的列表。
  • protocol_version返回Mnesia进程间通信协议的版本号.
  • running_db_nodes。返回Mnesia当前正在运行的节点列表。即使Mnesia尚未运行,也可以调用此函数,但它的语义略有不同。如果Mnesia在本地节点上运行,该函数会返回其他节点,db_nodes并且extra_db_nodes目前正在运行。如果启动了Mnesia,则该函数返回本地节点上的Mnesia完全连接到的节点。只有那些Mnesia已经交换过模式信息的节点才被包含在内running_db_nodes。模式合并后,本地Mnesia系统完全可操作,应用程序可以执行远程副本的访问。在模式合并之前,Mnesia只在本地运行。有时,包含在多个节点running_db_nodes列表比所有db_nodesextra_db_nodes在一起。
  • schema_location返回初始架构位置。
  • subscribers返回当前订阅系统事件的本地进程的列表。
  • tables返回所有本地已知表的列表。
  • transactions返回所有当前活动的本地事务的列表。
  • transaction_failures返回一个数字,该数字指示自Mnesia启动以来有多少事务失败。
  • transaction_commits返回一个数字,该数字指示自Mnesia启动以来有多少事务已成功终止。
  • transaction_restarts返回一个数字,该数字指示自Mnesia启动以来已重新启动了多少事务。
  • transaction_log_writes返回一个数字,该数字指示自启动以来对事务日志执行了多少次写入操作。
  • use_dir返回一个布尔值,该布尔值指示是否使用Mnesia目录。即使Mnesia还没有运行也可以启动。
  • version 返回Mnesia.table的当前版本号(Tab [,[Option]]) - > QueryHandle返回Query List Comprehension(QLC)查询句柄,请参阅STDLIB中的qlc(3)手册页。 模块qlc实现了一种可以使用Mnesia表作为数据源的查询语言。 调用mnesia:table / 1,2是使mnesia表Tab可用于QLC的方法.Option可以包含Mnesia选项或QLC选项。 Mnesia认识到以下选项(任何其他选项转发给QLC)。
  • {lock, Lock}lock可以为readwrite。默认是read
  • {n_objects,Number},其中n_objects指定(粗略地)从Mnesia的返回QLC对象的数目。对远程表的查询可能需要更大的块来减少网络开销。默认情况下,100一次返回对象。
  • {traverse, SelectMethod},其中traverse确定遍历整个表的方法(如果需要)。默认方法是select

有两种选择select*

  • select。通过调用mnesia:select/4和遍历表mnesia:select/1select/3QLC 的匹配规范(第二个参数)由简单的过滤器翻译成等效的匹配规范。select/3给定与所有对象相匹配的匹配规范,需要将更复杂的过滤器应用于返回的所有对象。
  • {select, MatchSpec}。至于select这个表是通过调用mnesia:select/3和遍历的mnesia:select/1。区别在于明确给出了匹配规范。这是如何陈述在QLC提供的语法中不容易表达的匹配规范。

table_info(Tab, InfoKey) -> Info | exit({aborted, Reason})

table_info/2函数采用两个参数。第一个是Mnesia表的名称。第二个键是以下键之一:

  • all返回所有本地表信息的列表。每个元素都是{InfoKey, ItemVal}元组。 新InfoItems可以添加和旧的无文件记录。InfoItem我们可以不经通知就把它移走。
  • access_mode返回表的访问模式。访问模式可以是read_onlyread_write...
  • arity返回架构中指定的表中记录的一致性。
  • attributes返回架构中指定的表属性名称。
  • checkpoints返回当前活动检查点的名称,该检查点涉及此节点上的此表。
  • cookie返回表cookie,它是表的唯一系统生成标识符.。Cookie在内部使用,以确保使用相同表名的两个不同表定义不会意外地混合在一起。Cookie是在最初创建表时生成的。
  • disc_copies返回disc_copy根据架构驻留表。
  • disc_only_copiesdisc_only_copy根据模式返回表所在的节点。
  • index返回表的索引位置整数列表。
  • load_node。返回Mnesia从中加载表的节点的名称。返回值的结构未指定,但可用于调试目的。
  • load_order。返回表的加载顺序优先级。它是一个整数,默认为0(零)。
  • load_reason。返回Mnesia决定加载表格的原因。返回值的结构未指定,但可用于调试目的。
  • local_content.返回truefalse指示表是否配置为在每个节点上具有本地唯一内容。
  • master_nodes返回表的主节点。
  • memory返回分配给此节点上的表的字数。
  • ram_copiesram_copy根据模式返回表所在的节点。
  • record_name。返回表中所有记录的通用记录名称。
  • size返回插入到表中的记录数。
  • snmp返回SNMP结构。[]表示表当前没有SNMP属性。
  • storage_type返回表的本地存储类型。可能是disc_copiesram_copiesdisc_only_copies,或者原子unknown...unknown为仅驻留在远程的所有表返回。
  • subscribers。返回当前订阅本节点上涉及此表的本地表事件的本地进程列表。
  • type。返回表类型,它是bagsetordered_set
  • user_properties返回表的与用户关联的表属性。它是存储的财产记录的列表。
  • version返回表定义的当前版本。表定义更改后,表版本将增加。在模式事务中更改表定义时,或者在启动时将提交的表定义与其他节点的表定义合并时,表定义可以直接递增。
  • where_to_read返回可以读取表的节点。中频值nowhere返回时,表要么未加载,要么驻留在未运行的远程节点上。
  • where_to_write返回当前保存表的活动副本的节点的列表。
  • wild_pattern。 返回可以赋予某个表的各种匹配函数的结构。 记录元组是所有记录字段都具有值'_'的地方。transaction(Fun [[,Args],Retries]) - > {aborted,Reason} | {atomic,ResultOfFun}使用参数Args作为事务执行功能对象Fun。在事务内部执行的代码可以由一系列表操作函数组成。 如果由于用户错误或某个表不可用而导致事务内部出现问题,则整个事务终止,并且函数transaction / 1返回元组{aborted,Reason}。如果一切进展顺利,{atomic ,ResultOfFun}被返回,其中ResultOfFun是Fun中最后一个表达式的值。如果存在结构{family,Father,Mother,ChildrenList},可以将一个族添加到数据库中,函数的写法如下:

add_family({family, F, M, Children}) -> ChildOids = lists:map(fun oid/1, Children), Trans = fun() -> mnesia:write(F#person{children = ChildOids}, mnesia:write(M#person{children = ChildOids}, Write = fun(Child) -> mnesia:write(Child) end, lists:foreach(Write, Children) end, mnesia:transaction(Trans). oid(Rec) -> {element(1, Rec), element(2, Rec)}.

此代码将一组人员添加到数据库中。 在一个事务中运行此代码可确保将整个系列添加到数据库,或者整个事务终止。 例如,如果最后一个孩子的格式不正确,或执行过程由于执行家庭代码时出现“退出”信号而终止,则事务终止。 因此,添加一半家族的情况决不会发生。如果多个进程同时更新相同的记录,那么更新事务内的数据库也很有用。 例如,将金额添加到某个人的薪金字段的函数raise(Name,Amount)将按如下方式实施:

raise(Name, Amount) -> mnesia:transaction(fun() -> case mnesia:wread({person, Name}) of [P] -> Salary = Amount + P#person.salary, P2 = P#person{salary = Salary}, mnesia:write(P2); _ -> mnesia:abort("No such person") end end).

当这个函数在一个事务中执行时,在不同节点上运行的几个进程可以同时执行raise / 2函数而不会相互干扰。由于Mnesia检测到死锁,事务可以重新启动任意次。该功能按重试中指定的方式尝试重新启动。重试次数必须是大于0的整数或原子无穷大。默认是infinity.transform_table(Tab,Fun,NewAttributeList,NewRecordName) - > {aborted,R} | {atomic,ok}将参数Fun应用于表中的所有记录。 Fun是一个函数,它记录旧类型并返回新类型的转换记录。参数Fun也可以是原子忽略,它表示只有关于表的元数据被更新。不推荐使用忽略,但是包含在用户自己进行转换的可能性中.NewAttributeList和NewRecordName指定转换表的属性和新记录类型。表名称始终保持不变。如果record_name被更改,只有使用表标识符的Mnesia函数可以工作,例如,mnesia:write / 3工作,但不是mnesia:write / 1.transform_table(Tab,Fun,NewAttributeList) - > {aborted,R} | {atomic,ok}调用mnesia:transform_table(Tab,Fun,NewAttributeList,RecName),其中RecName是mnesia:table_info(Tab,record_name).traverse_backup(Source,[SourceMod,] Target,[TargetMod,] Fun,Acc) - > {ok,LastAcc} | {error,Reason}迭代备份,将其转换为新备份或读取。这里对这些论点进行简要解释。有关详细信息,请参阅用户指南。

  • SourceModTargetMod实际访问备份媒体的模块的名称。
  • SourceTarget是否模块只使用不透明数据?SourceModTargetMod若要初始化备份媒体,请执行以下操作。
  • Acc是初始累加器值。
  • Fun(BackupItems, Acc)应用于备份中的每个项目。在Fun必须返回一个元组{BackupItems,NewAcc},其中BackupItems有效备份项目的列表,NewAcc是一个新的累加值。返回的备份项目写入目标备份中。
  • LastAcc是最后的累加器值。这是NewAcc返回的最后一个值Fun

uninstall_fallback() -> ok | {error,Reason}

调用函数mnesia:uninstall_fallback([{scope, global}])...

uninstall_fallback(Args) -> ok | {error,Reason}

在用于还原数据库之前,先安装回退。这通常是一种分布式操作,它要么在所有具有磁盘驻留模式的节点上执行,要么不对任何节点执行。卸载备份要求Erlang在所有涉及的节点上运行,但Mnesia是否正在运行并不重要。根据本地回退中的架构信息确定哪些节点被视为磁盘驻留节点。

Args是以下元组的列表:

  • {module, BackupMod}有关语义,请参见mnesia:install_fallback/2...
  • {scope, Scope}有关语义,请参见mnesia:install_fallback/2...
  • {mnesia_dir, AlternateDir}有关语义,请参见mnesia:install_fallback/2...

unsubscribe(EventCategory) -> {ok, Node} | {error, Reason}

停止发送类型的事件EventCategory打电话的人。

Node是本地节点。

wait_for_tables(TabList, Timeout) -> ok | {timeout, BadTabList} | {error, Reason}

有些应用程序需要等待某些表可以访问才能完成有用的工作。mnesia:wait_for_tables/2要么挂起直到所有的表在TabList是可以访问的,或者直到timeout到达了。

wread({Tab, Key}) -> transaction abort | RecordList

调用函数mnesia:read(Tab, Key, write)...

write(Record) -> transaction abort | ok

调用函数mnesia:write(Tab, Record, write),其中Tabelement(1, Record)...

write(Tab, Record, LockKind) -> transaction abort | ok

将记录写入Record表格Tab

该函数返回ok,或者在发生错误时终止。 例如,如果不存在人员表,则该事务终止。

这个函数的语义是上下文敏感的。 有关详细信息,请参阅mnesia:activity / 4。 在事务上下文中,它获取LockKind类型的锁。 锁类型write和sticky_write被支持。

write_lock_table(Tab) -> ok | transaction abort

调用函数mnesia:lock({table, Tab}, write)...

配置参数

Mnesia读取以下应用程序配置参数:

  • -mnesia access_module ModuleMnesia活动访问回调模块的名称。默认值是mnesia...
  • -mnesia auto_repair true | false此标志控制Mnesia是否自动尝试修复未正确关闭的文件。默认值是true...
  • -mnesia backup_module ModuleMnesia备份回调模块的名称。默认值是mnesia_backup...
  • -mnesia debug Level控制Mnesia的调试级别。可能的价值如下:

none没有跟踪输出。这是默认的。

verbose 激活重要调试事件的跟踪。这些事件产生{mnesia_info, Format, Args}系统事件。进程可以用这些事件来订阅这些事件mnesia:subscribe/1。事件总是发送给Mnesia事件处理程序。

debug 以详细级别激活所有事件并全部跟踪所有调试事件。这些调试事件生成{mnesia_info, Format, Args}系统事件。进程可以用这些事件来订阅这些事件mnesia:subscribe/1。事件总是发送给Mnesia事件处理程序。在这个调试级别上,Mnesia事件处理程序开始订阅架构表中的更新。

trace 在调试级别激活所有事件。在这个层面上,Mnesia事件处理程序开始订阅所有Mnesia表上的更新。这个级别仅用于调试小型玩具系统,因为可以生成许多大型事件。

false没有别名。 true调试的别名。

  • -mnesia core_dir Directory。Mnesia核心文件存储目录的名称,或者为false。设置它意味着如果发生崩溃,也只有RAM的节点才会生成核心文件。
  • -mnesia dc_dump_limit Number。控制disc_copies表格从内存中转储的频率。桌子倾倒时filesize(Log) > (filesize(Tab)/Dc_dump_limit)。较低的值可减少CPU开销,但会增加磁盘空间和启动时间。缺省值是4。
  • -mnesia dir Directory。所有Mnesia数据存储目录的名称。目录名称对于当前节点必须是唯一的。两个节点绝不能共享相同的Mnesia目录。结果是不可预测的。
  • -mnesia dump_disc_copies_at_startup true | false。如果设置为false,disc_copies则会在加载表时加载启动期间的表转储。默认值是true。
  • -mnesia dump_log_load_regulation true | false。控制是否尽可能快地执行日志转储,或者如果自卸车要执行自己的负载调节。默认是false。此功能是暂时性的,将在未来版本中删除
  • -mnesia dump_log_update_in_place true | false。控制是在原始数据文件的副本上执行日志转储,还是在原始数据文件上执行日志转储。默认是true
  • -mnesia dump_log_write_threshold MaxMax是一个整数,指定在执行日志的新转储之前允许事务日志的最大写入次数。默认是100日志写入。
  • -mnesia dump_log_time_threshold Max...Max指定转储日志间隔(以毫秒为单位)的整数。默认为3分钟。如果转储没有在dump_log_time_threshold毫秒内,不管执行的写操作数如何,都会执行新的转储。
  • -mnesia event_module Module.Mnesia事件处理程序回调模块的名称。默认值是mnesia_event...
  • -mnesia extra_db_nodes Nodes除了在架构中找到的节点之外,还指定了一个节点列表,Mnesia也与之建立联系。默认是[](空列表)。
  • -mnesia fallback_error_function {UserModule, UserFunc}。指定用户提供的回调函数,如果安装了回退并且Mnesia在另一个节点上关闭,则会调用该函数。例如,Mnesia使用一个参数调用该函数,即死亡节点的名称UserModule:UserFunc(DyingNode)。Mnesia必须重新启动,否则数据库可能不一致。默认行为是终止Mnesia。
  • -mnesia max_wait_for_decision Timeout。指定Mnesia等待其他节点分享他们对不明交易结果的知识的时间。默认情况下,Timeout设置为原子infinity。这意味着如果Mnesia在启动时检测到结果不明确的“重量级事务”,则当地Mnesia会等到Mnesia启动其中一些参与中断事务的其他节点(最糟糕的情况下)。这种情况很少见,但如果发生,Mnesia不会猜测其他节点上的事务是否已提交或终止。Mnesia一直等到它知道结果,然后采取相应行动。

如果Timeout设置为以毫秒为单位的整数值,则即使目前的交易结果不清楚,Mnesia也会强制完成“重量级交易”。Timeout毫秒后,Mnesia的提交或终止交易,并启动继续。这可能会导致事务在某些节点上提交并在其他节点上终止。如果事务是模式事务,则不一致可能是致命的。

  • -mnesia no_table_loaders NUMBER。指定启动期间的并行表加载器的数量。如果网络延迟很高或许多表包含少量记录,那么更多的加载器可能会更好。默认是2
  • -mnesia send_compressed Level。指定将表从本地节点复制到另一个时要使用的压缩级别。默认是0

Level必须是间隔中的整数[0, 9],其中0意味着没有压缩并且9意味着最大压缩。在将其设置为非零值之前,请确保远程节点了解此配置。

  • -mnesia schema_location Loc。控制Mnesia在哪里查找其模式。参数Loc可以是以下原子之一:

disc 强制光盘。模式假定位于Mnesia目录中。如果无法找到模式,Mnesia拒绝启动。这是旧的行为。

ram 强制性内存。模式仅驻留在RAM中。在启动时,会生成一个小小的新模式。此默认架构仅包含架构表的定义,并且仅驻留在本地节点上。由于在默认模式中找不到其他节点,因此extra_db_nodes必须使用配置参数让节点与其他节点共享其表格定义。

参数extra_db_nodes也可以在基于磁盘的节点上使用。

opt_disc 可选光盘。模式可以驻留在光盘或RAM中。如果在光盘上找到架构,则Mnesia将作为基于光盘的节点启动,并且架构表的存储类型为disc_copies。如果在光盘上找不到模式,Mnesia将作为无盘节点启动,模式表的存储类型为ram_copies。应用程序参数的默认值是opt_disc

首先,检查SASL应用程序参数,然后检查命令行标志,最后选择默认值。

另见

application(3)dets(3)disk_log(3)ets(3)mnesia_registry(3)qlc(3)

扫码关注云+社区

领取腾讯云代金券