MongoDB中4种日志的详细介绍

69次阅读
没有评论

共计 3852 个字符,预计需要花费 10 分钟才能阅读完成。

前言

任何一种数据库都有各种各样的日志,MongoDB 也不例外。MongoDB 中有 4 种日志,分别是系统日志、Journal 日志、oplog 主从日志、慢查询日志等。这些日志记录着 MongoDB 数据库不同方面的踪迹。下面分别介绍这几种日志。

系统日志

系统日志在 MongoDB 数据库中很重要,它记录着 MongoDB 启动和停止的操作,以及服务器在运行过程中发生的任何异常信息。
配置系统日志的方法比较简单,在启动 mongod 时指定 logpath 参数即可

mongod -logpath=/data/log/mongodb/serverlog.log -logappend

系统日志会向 logpath 指定的文件持续追加。

Journal 日志

journaling(日记) 日志功能则是 MongoDB 里面非常重要的一个功能,它保证了数据库服务器在意外断电、自然灾害等情况下数据的完整性。它通过预写式的 redo 日志为 MongoDB 增加了额外的可靠性保障。开启该功能时,MongoDB 会在进行写入时建立一条 Journal 日志, 其中包含了此次写入操作具体更改的磁盘地址和字节。因此一旦服务器突然停机,可在启动时对日记进行重放,从而重新执行那些停机前没能够刷新到磁盘的写入操作。

MongoDB 配置 WiredTiger 引擎使用内存缓冲区来保存 journal 记录,WiredTiger 根据以下间隔或条件将缓冲的日志记录同步到磁盘

从 MongoDB 3.2 版本开始每隔 50ms 将缓冲的 journal 数据同步到磁盘
如果写入操作设置了 j:true,则 WiredTiger 强制同步日志文件
由于 MongoDB 使用的 journal 文件大小限制为 100MB, 因此 WiredTiger 大约每 100MB 数据创建一个新的日志文件。当 WiredTiger 创建新的 journal 文件时,WiredTiger 会同步以前 journal 文件

MongoDB 达到上面的提交,便会将更新操作写入日志。这意味着 MongoDB 会批量地提交更改,即每次写入不会立即刷新到磁盘。不过在默认设置下,系统发生崩溃时,不可能丢失超过 50ms 的写入数据。

数据文件默认每 60 秒刷新到磁盘一次,因此 Journal 文件只需记录约 60s 的写入数据。日志系统为此预先分配了若干个空文件,这些文件存放在 /data/db/journal 目录中,目录名为_j.0、_j.1 等

长时间运行 MongoDB 后,日志目录中会出现类似_j.6217、_j.6218 的文件,这些是当前的日志文件,文件中的数值会随着 MongoDB 运行时间的增长而增大。数据库正常关闭后,日记文件会被清除(因为正常关闭后就不在需要这些文件了).

向 mongodb 中写入数据是先写入内存,然后每隔 60s 在刷盘,同样写入 journal, 也是先写入对应的 buffer,然后每隔 50ms 在刷盘到磁盘的 journal 文件
使用 WiredTiger,即使没有 journal 功能,MongoDB 也可以从最后一个检查点 (checkpoint, 可以想成镜像) 恢复; 但是,要恢复在上一个检查点之后所做的更改,还是需要使用 Journal

如发生系统崩溃或使用 kill - 9 命令强制终止数据库的运行,mongod 会在启动时重放 journal 文件,同时会显示出大量的校验信息。

上面说的都是针对 WiredTiger 引擎, 对于 MMAPv1 引擎来说有一点不一样,首先它是每 100ms 进行刷盘,其次它是通过 private view 写入 journal 文件, 通过 shared view 写入数据文件。这里就不过多讲解了,因为 MongoDB 4.0 已经不推荐使用这个存储引擎了。

从 MongoDB 3.2 版本开始 WiredTiger 是 MongoDB 推荐的默认存储引擎

需要注意的是如果客户端的写入速度超过了日记的刷新速度,mongod 则会限制写入操作,直到日记完成磁盘的写入。这是 mongod 会限制写入的唯一情况。

固定集合(Capped Collection)

在讲下面两种日志之前先来认识下 capped collection。

MongoDB 中的普通集合是动态创建的,而且可以自动增长以容纳更多的数据。MongoDB 中还有另一种不同类型的集合,叫做固定集合。固定集合需要事先创建好,而且它的大小是固定的。固定集合的行为类型与循环队列一样。如果没有空间了,最老的文档会被删除以释放空间,新插入的文档会占据这块空间。

创建固定集合:

db.createCollection("collectionName",{"capped":true, "size":100000, "max":100})

创建了一个大小为 100000 字节的固定大小集合, 文档数量为 100. 不管先到达哪个限制,之后插入的新文档就会把最老的文档挤出集合:固定集合的文档数量不能超过文档数量限制,也不能超过大小限制。

固定集合创建之后就不能改变, 无法将固定集合转换为非固定集合, 但是可以将常规集合转换为固定集合。

db.runCommand({"convertToCapped": "test", "size" : 10000});

固定集合可以进行一种特殊的排序,称为自然排序(natural sort), 自然排序返回结果集中文档的顺序就是文档在磁盘的顺序。自然顺序就是文档的插入顺序,因此自然排序得到的文档是从旧到新排列的。当然也可以按照从新到旧:

db.my_capped_collection.find().sort({"$natural": -1});

oplog 主从日志

Replica Sets 复制集用于在多台服务器之间备份数据。MongoDB 的复制功能是使用操作日志 oplog 实现的,操作日志包含了主节点的每一次写操作。oplog 是主节点的 local 数据库中的一个固定集合。备份节点通过查询这个集合就可以知道需要进行复制的操作。

一个 mongod 实例中的所有数据库都使用同一个 oplog,也就是所有数据库的操作日志 (插入,删除,修改) 都会记录到 oplog 中

每个备份节点都维护着自己的 oplog, 记录着每一次从主节点复制数据的操作。这样,每个成员都可以作为同步源给其他成员使用。

如图所示,备份节点从当前使用的同步源中获取需要执行的操作,然后在自己的数据集上执行这些操作,最后再将这些操作写入自己的 oplog, 如果遇到某个操作失败的情况(只有当同步源的数据损坏或者数据与主节点不一致时才可能发生), 那么备份节点就会停止从当前的同步源复制数据。

MongoDB 中 4 种日志的详细介绍

oplog 中按顺序保存着所有执行过的写操作,replica sets 中每个成员都维护者一份自己的 oplog,每个成员的 oplog 都应该跟主节点的 oplog 完全一致(可能会有一些延迟)

如果某个备份节点由于某些原因挂了,但它重新启动后,就会自动从 oplog 中最后一个操作开始进行同步。由于复制操作的过程是想复制数据在写入 oplog, 所以备份节点可能会在已经同步过的数据上再次执行复制操作。MongoDB 在设计之初就考虑到了这种情况: 将 oplog 中的同一个操作执行多次,与只执行一次的效果是一样的。

由于 oplog 大小是固定的,它只能保持特定数量的操作日志。通常,oplog 使用空间的增长速度与系统处理写请求的速率几乎相同:如果主节点上每分钟处理了 1KB 的写入请求,那么 oplog 很可能也会在一分钟内写入 1KB 条操作日志。

但是,有一些例外:如果单次请求能够影响到多个文档 (比如删除多个文档或者多文档更新),oplog 中就会出现多条操作日志。如果单个操作会影响多个文档,那么每个受影响的文档都会对应 oplog 的一条日志。因此,如果执行 db.student.remove() 删除了 10w 个文档,那么 oplog 中也就会有 10w 条操作日志,每个日志对应一个被删除的文档。如果执行大量的批量操作,oplog 很快就会被填满。

慢查询日志

MongoDB 中使用系统分析器 (system profiler) 来查找耗时过长的操作。系统分析器记录固定集合 system.profile 中的操作,并提供大量有关耗时过长的操作信息,但相应的 mongod 的整体性能也会有所下降。因此我们一般定期打开分析器来获取信息。

默认情况下,系统分析器处于关闭状态,不会进行任何记录。可以在 shell 中运行 db.setProfilingLevel()开启分析器

db.setProfilingLevel(level, slowms) 0=off 1=slow 2=all

第一个参数是指定级别,不同的级别代表不同的意义,0 表示关闭,1 表示默认记录耗时大于 100 毫秒的操作,2 表示记录所有操作。第二个参数则是自定义“耗时过长 ” 标准,比如记录所有耗时操作 500ms 的操作

db.setProfilingLevel(1,500);

如果开启了分析器而 system.profile 集合并不存在,MongoDB 会为其建立一个大小为若干 MB 的固定集合(capped collection)。如希望分析器运行更长时间,可能需要更大的空间记录更多的操作。此时可以关闭分析器,删除并重新建立一个新的名为 system.profile 的固定集合,并令其容量符合要求。然后在数据库上重新启用分析器。

可以通过 db.system.profile.stats()查看集合的最大容量.

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对丸趣 TV 的支持。

向 AI 问一下细节

丸趣 TV 网 – 提供最优质的资源集合!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-12-18发表,共计3852字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)