热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mnesia之dump

2019独角兽企业重金招聘Python工程师标准在《mnesia之transaction》里提到事务操作的数据及最终结果都会记录到latest.log文件中。注意只有涉及类型

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

在《mnesia之transaction》里提到事务操作的数据及最终结果都会记录到latest.log文件中。注意只有涉及类型为disc_copies和disc_only_copies的表的操作才会记录日志到latest.log文件中,仅针对ram_copies类型的表的操作不会记录日志。

log(C) when C#commit.disc_copies == [],C#commit.disc_only_copies == [],C#commit.schema_ops == [] ->ignore;

为了防止日志文件不断增长从而导致占用大量的磁盘空间,mnesia会进行dump工作。所谓dump就是分析日志文件中记录的事务操作及最终结果,将实际的数据记录到*.DAT,*.DCL,*.DCD等文件中。

说明:mnesia数据存储实际上使用的是ets和dets,对于ram_copies类型的表使用ets;disc_copies类型的表使用也是ets,通过mnesia的dump将数据保存到后缀名为DCD(disc copy data)或者后缀名为DCL(disc copy log)的文件中,以做到数据的持久化;而disc_only_copies类型的表使用的是dets,保存的文件后缀名为DAT;schema表比较特殊,虽然使用的是dets表,但是同时会在内存中保存相关信息。

有几种情况会触发mnesia的dump:

(1)定时触发

mnesia启动后,由mnesia_controller进程设置定时器,触发dump

代码片段:

init([Parent]) ->process_flag(trap_exit, true),mnesia_lib:verbose("~p starting: ~p~n", [?SERVER_NAME, self()]),All = mnesia_lib:all_nodes(),Diff = All -- [node() | val(original_nodes)],mnesia_lib:unset(original_nodes),mnesia_recover:connect_nodes(Diff),Ref = next_async_dump_log(),mnesia_dumper:start_regulator(),Empty = gb_trees:empty(),{ok, #state{supervisor = Parent,dump_log_timer_ref = Ref,loader_queue = Empty,late_loader_queue = Empty}}.next_async_dump_log() ->Interval = mnesia_monitor:get_env(dump_log_time_threshold),Msg = {next_async_dump_log, time_threshold},Ref = erlang:send_after(Interval, self(), Msg),Ref.handle_info({next_async_dump_log, InitBy}, State) ->async_dump_log(InitBy),Ref = next_async_dump_log(),noreply(State#state{dump_log_timer_ref=Ref});

定时dump的默认的时间间隔为3分钟

default_env(dump_log_time_threshold) ->timer:minutes(3); 可以在程序启动是增加参数 -mnesia dump_log_time_threshold 300000 来设置时间间隔。

(2)一定数量的日志记录后触发

每次调用mnesia_log:log(C)或者mnesia_log:slog(C)进行日志记录时,都会将trans_log_writes_left的值减1,当该值小于等于0时,触发dump

mnesia_log:
log(C) ->case mnesia_monitor:use_dir() oftrue ->...mnesia_dumper:incr_log_writes();false ->ignoreend.mnesia_dumper:
incr_log_writes() ->Left = mnesia_lib:incr_counter(trans_log_writes_left, -1),ifLeft > 0 ->ignore;true ->adjust_log_writes(true)end.adjust_log_writes(DoCast) ->...case DoCast offalse ->ignore;true ->mnesia_controller:async_dump_log(write_threshold)end,...
默认情况下,写入100条记录到latest文件中,便会触发dump

mnesia_monitor:
init(Parent) ->...Left = get_env(dump_log_write_threshold),mnesia_lib:set_counter(trans_log_writes_left, Left),...

同样可以通过在程序启动是增加参数 -mnesia dump_log_write_threshold 5000 进行设置。

dump操作会做如下几个事情:

(1) dump latest.log文件

将latest.log文件改名为previous.log,然后新建latest.log文件,然后分析previous.log文件中的内容,对于存储类型为disc_copies的表(非schema),检查DCL与DCD文件中的数据量,当sizeof(DCD)/sizeof(DCL)小于指定的阈值时,把表中的内容全部存储到DCD文件中,否则直接写到DCL文件中。默认的阈值大小为4,可以通过-mnesia dc_dump_limit Num进行设置。对于存储类型为disc_only_copies的表不做任何处理。

open_disc_copies(Tab, InitBy) ->DclF &#61; mnesia_lib:tab2dcl(Tab),DumpEts &#61;case file:read_file_info(DclF) of{error, enoent} ->false;{ok, DclInfo} ->DcdF &#61; mnesia_lib:tab2dcd(Tab),case file:read_file_info(DcdF) of{error, Reason} ->mnesia_lib:dbg_out("File ~p info_error ~p ~n",[DcdF, Reason]),true;{ok, DcdInfo} ->Mul &#61; case ?catch_val(dc_dump_limit) of{&#39;EXIT&#39;, _} -> ?DumpToEtsMultiplier;Val -> Valend,DcdInfo#file_info.size &#61;<(DclInfo#file_info.size * Mul)endend,ifDumpEts &#61;&#61; false; InitBy &#61;&#61; startup ->mnesia_log:open_log({?MODULE,Tab},mnesia_log:dcl_log_header(),DclF,mnesia_lib:exists(DclF),mnesia_monitor:get_env(auto_repair),read_write),put({?MODULE, Tab}, {opened_dumper, dcl}),true;true ->mnesia_log:ets2dcd(Tab),put({?MODULE, Tab}, already_dumped),falseend.

&#xff08;2&#xff09;dump mnesia_decision表

将当前mnesia_decision表中的数据以覆盖形式存储到decision_tab.log文件中

&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;

另外&#xff0c;mnesia启动和执行schema transaction时都会触发dump&#xff0c;schema transaction触发的dump会忽略日志文件中的内容&#xff0c;也不会对mnesia_decision表进行dump&#xff0c;仅针对本次操作涉及的内容进行dump&#xff0c;并且schema transaction触发的dump不会和其他情况触发的dump并行执行。

prepare_commit时锁住&#xff1a;

mnesia_schema:prepare_commit(Tid, Commit, WaitFor) ->...case Ops of[] ->ignore;_ ->%% We need to grab a dumper lock here, the log may not%% be dumped by others, during the schema commit phase.mnesia_controller:wait_for_schema_commit_lock()end... do_commit时进行dump&#xff0c;然后释放锁

mnesia_tm:do_commit(Tid, C, DumperMode) ->mnesia_dumper:update(Tid, C#commit.schema_ops, DumperMode),...mnesia_dumper:update(Tid, SchemaOps, DumperMode) ->UseDir &#61; mnesia_monitor:use_dir(),Res &#61; perform_update(Tid, SchemaOps, DumperMode, UseDir),mnesia_controller:release_schema_commit_lock(),Res.




转:https://my.oschina.net/hncscwc/blog/161763



推荐阅读
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • PHP预处理常量详解:如何定义与使用常量 ... [详细]
  • Objective-C 中的委托模式详解与应用 ... [详细]
  • 本文介绍如何使用 Python 的 DOM 和 SAX 方法解析 XML 文件,并通过示例展示了如何动态创建数据库表和处理大量数据的实时插入。 ... [详细]
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
  • Android 构建基础流程详解
    Android 构建基础流程详解 ... [详细]
  • 本文介绍了如何利用Shell脚本高效地部署MHA(MySQL High Availability)高可用集群。通过详细的脚本编写和配置示例,展示了自动化部署过程中的关键步骤和注意事项。该方法不仅简化了集群的部署流程,还提高了系统的稳定性和可用性。 ... [详细]
  • 本文详细解析了 Android 系统启动过程中的核心文件 `init.c`,探讨了其在系统初始化阶段的关键作用。通过对 `init.c` 的源代码进行深入分析,揭示了其如何管理进程、解析配置文件以及执行系统启动脚本。此外,文章还介绍了 `init` 进程的生命周期及其与内核的交互方式,为开发者提供了深入了解 Android 启动机制的宝贵资料。 ... [详细]
  • 本文介绍了如何利用 Delphi 中的 IdTCPServer 和 IdTCPClient 控件实现高效的文件传输。这些控件在默认情况下采用阻塞模式,并且服务器端已经集成了多线程处理,能够支持任意大小的文件传输,无需担心数据包大小的限制。与传统的 ClientSocket 相比,Indy 控件提供了更为简洁和可靠的解决方案,特别适用于开发高性能的网络文件传输应用程序。 ... [详细]
  • CTF竞赛中文件上传技巧与安全绕过方法深入解析
    CTF竞赛中文件上传技巧与安全绕过方法深入解析 ... [详细]
  • 本文探讨了利用Python实现高效语音识别技术的方法。通过使用先进的语音处理库和算法,本文详细介绍了如何构建一个准确且高效的语音识别系统。提供的代码示例和实验结果展示了该方法在实际应用中的优越性能。相关文件可从以下链接下载:链接:https://pan.baidu.com/s/1RWNVHuXMQleOrEi5vig_bQ,提取码:p57s。 ... [详细]
  • 本文主要探讨了Java中处理ActionEvent事件的接口,以及一些常见的编程问题和解决方案,包括方法重载、成员变量访问、镜片质量检测等。 ... [详细]
  • 在C#编程中,数值结果的格式化展示是提高代码可读性和用户体验的重要手段。本文探讨了多种格式化方法和技巧,如使用格式说明符、自定义格式字符串等,以实现对数值结果的精确控制。通过实例演示,展示了如何灵活运用这些技术来满足不同的展示需求。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有