MongoDB的Journal
2024-12-02 19:30 abce 阅读(65) 评论(0) 编辑 收藏 举报注:这里提到的日志(即journal)指的是 WiredTiger 提前写日志,而不是 MongoDB 日志文件。
为了在发生故障时能提供耐久性,MongoDB 使用write ahead logging 机制,提前写入磁盘上的日志(journal)文件。
WiredTiger使用检查点为磁盘上的数据提供一致的视图,并支持 MongoDB 从最后一个检查点进行恢复。但是,如果 MongoDB 在两次检查点之间意外退出,则需要日志来恢复自上次检查点之后发生的信息。
从 MongoDB 6.1 开始,日志始终处于启用状态。因此,MongoDB 删除了storage.journal.enabled选项以及相应的--journal和--nojournal命令行选项。
有了日志,恢复过程是这样的:
1.在数据文件中查找最后一个检查点的标识符。
2.在日志文件中查找与最后一个检查点标识符匹配的记录。
3.应用最后一个检查点后日志文件中的操作记录。
日志过程
有了日志,WiredTiger 会为每个客户端启动的写操作创建一条日志记录。日志记录包括由初始写入引起的任何内部写入操作。例如,对集合中文档的更新可能会导致对索引的修改;WiredTiger 会创建一条日志记录,其中包括更新操作及其相关的索引修改。
MongoDB 将 WiredTiger 配置为使用内存缓冲来存储日志记录。线程协调分配并复制到各自的缓冲区中。所有不超过 128 kB 的日志记录都会被缓冲。
出现以下情况时,WiredTiger 会将缓冲的日志记录同步到磁盘:
1.对于副本集成员(主成员和辅助成员):
· 如果写操作包含或隐式包含了写关注j:true (如果writeConcernMajorityJournalDefault被设置为true,"majority"写关注就隐式包含了j:true)
· 此外,对于二级成员,在每次批量应用 oplog 条目后
2.每 100 毫秒(请参阅storage.journal.commitIntervalMs )
3.当 WiredTiger 创建新的日志文件时。由于 MongoDB 使用的日志文件大小限制为 100 MB,因此 WiredTiger 大约每 100 MB 数据创建一个新日志文件。
serverStatus命令的wiredTiger.log列会返回日志的统计信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | > db.serverStatus().wiredTiger.log { "busy returns attempting to switch slots" : 33345816, "force archive time sleeping (usecs)" : 0, "log bytes of payload data" : NumberLong( "2410249794860" ), "log bytes written" : NumberLong( "2465646805120" ), "log files manually zero-filled" : 0, "log flush operations" : 530806245, "log force write operations" : 568960680, "log force write operations skipped" : 345671770, "log records compressed" : 178201264, "log records not compressed" : 172711326, "log records too small to compress" : 546926861, "log release advances write LSN" : 575248, "log scan operations" : 8, "log scan records requiring two reads" : 1, "log server thread advances write LSN" : 227661859, "log server thread write LSN walk skipped" : 53111249, "log sync operations" : 223684164, "log sync time duration (usecs)" : NumberLong( "223213885794" ), "log sync_dir operations" : 23539, "log sync_dir time duration (usecs)" : 740774, "log write operations" : 897839425, "logging bytes consolidated" : NumberLong( "2465641101184" ), "maximum log file size" : 104857600, "number of pre-allocated log files to create" : 1, "pre-allocated log files not ready and missed" : 1, "pre-allocated log files prepared" : 23539, "pre-allocated log files used" : 23538, "records processed by log scan" : 20, "slot close lost race" : 0, "slot close unbuffered waits" : 0, "slot closures" : 228237116, "slot join atomic update races" : 20939, "slot join calls atomic updates raced" : 20928, "slot join calls did not yield" : 897694949, "slot join calls found active slot closed" : 123645, "slot join calls slept" : 1205, "slot join calls yielded" : 144504, "slot join found active slot closed" : 2677443, "slot joins yield time (usecs)" : 5093155, "slot transitions unable to find free slot" : 0, "slot unbuffered writes" : 3762652, "total in-memory size of compressed records" : NumberLong( "4778668147941" ), "total log buffer size" : 33554432, "total size of compressed records" : NumberLong( "2292315590289" ), "written slots coalesced" : 9, "yields waiting for previous log file close" : 0 |
在写操作期间,日志记录还存在与 WiredTiger 缓存中,如果硬关闭mongod实例,可能会丢失数据的。详见:https://www.mongodb.com/docs/manual/core/journaling/
日志文件
对于日志文件,MongoDB 会在 dbPath 目录下创建一个名为 journal 的子目录。WiredTiger 日志文件的名称格式如下:WiredTigerLog.<sequence>,其中<sequence>是一个从0000000001 开始的零填充数字。例如:
1 2 | -rw ------- 1 mongod mongod 104857600 Nov 21 10:34 WiredTigerLog.0000026125 -rw ------- 1 mongod mongod 104857600 Nov 21 10:31 WiredTigerPreplog.0000023540 |
日志记录
日志文件包含每个客户端启动的写操作的记录
· 日志记录包括由初始写入引起的任何内部写入操作。例如,对集合中文档的更新可能会导致对索引的修改;WiredTiger 会创建一条日志记录,其中包括更新操作及其相关的索引修改。
· 每条记录都有唯一标识符。
· WiredTiger 的最小日志记录大小为 128 字节。
日志压缩
默认情况下,MongoDB 会配置 WiredTiger 对日志数据使用snappy 压缩。要指定不同的压缩算法或不使用压缩算法,请使用storage.wiredTiger.engineConfig.journalCompressor设置。如果日志记录小于或等于 128 字节(WiredTiger 的最小日志记录大小),WiredTiger 不会压缩该记录。
改变压缩配置的之前,请先干净的关闭mongodb实例:
1 | db.getSiblingDB( 'admin' ).shutdownServer() |
日志文件大小限制
WiredTiger 日志文件的最大大小限制约为 100 MB。一旦文件超过该限制,WiredTiger 就会创建一个新的日志文件。
WiredTiger 会自动删除旧的日志文件,只保留从上次检查点恢复所需的文件。要确定为日志文件预留多少磁盘空间,请考虑以下几点:
· 检查点的默认最大大小为 2 GB
· MongoDB 在从检查点恢复时写入新日志文件可能需要额外空间
· MongoDB 会压缩日志文件
· 恢复检查点所需的时间取决于你的使用情况
· 如果覆盖了最大检查点大小或禁用了压缩,计算结果可能会大不相同
由于上述原因,很难准确计算出你需要多少额外空间。高估磁盘空间总是一种更安全的方法。如果没有为日志文件预留足够的磁盘空间,MongoDB 实例会崩溃。
此外 WiredTiger 会预先分配日志文件。
日志和 In-Memory 存储引擎
在 MongoDB 企业版中,In-Memory 引擎是通用版本 (GA) 的一部分。由于其数据保存在内存中,因此没有单独的日志。写关注为 j: true 的写操作会立即被确认。
如果副本集的任何投票成员使用内存存储引擎,则必须将 writeConcernMajorityJournalDefault 设为 false。
更多的注意事项请参考官方文档!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
2015-12-02 Consolidated Seed Table Upgrade Patch(Patch 17204589)
2015-12-02 adop - ERRORMSG: Since earlier patching session failed and you are invoking apply again