代码改变世界

MongoDB的Journal

  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。

 

更多的注意事项请参考官方文档!

相关博文:
阅读排行:
· 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
点击右上角即可分享
微信分享提示