MongoDB中主要有四种日志。分别是系统日志、Journal日志、oplog主从日志、慢查询日志。这些日志记录着MongoDB数据库不同的信息。下面分别介绍这四种日志:
一、系统日志
系统日志在MongoDB中十分重要,它记录MongoDB启动和停止的操作,以及服务器在运行过程中发生的任何异常信息;配置系统日志非常简单,在运行mongod时候增加额外参数或者写入配置文件即可:
#在启动mongoDB时使用-logpath指定日志的路径,-logappend表示使用追加的方式写日志mongod -logpath='/usr/local/mongodb/log/rs1.log' -logappend#也可以在配置文件中指定参数进行配置:logpath=/usr/local/mongodb/log/rs1.log #日志文件路径logappend=true #表示使用追加的方式写日志verbose=true #表示会打印debug信息vv=true #表示debug级别,有vv-vvvvv,v越多则记录的日志信息越详细。#quiet=true #quiet=true,表示安静地输出,不会再有debug信息,日志中只会打印一些关键的信息,比如自动故障切换,系统错误等信息,相当于error log。这时需要注释掉verbose参数。
二、Journal日志
不开启journal日志,写入wiredtiger的数据,并不会立即持久化存储;而是每分钟会做一次全量的checkpoint,将所有的数据持久化。
开启journal日志后,数据的更新就先写入Journal日志(其中包含了此次写入操作具体更改的磁盘地址和字节),定期集中提交,然后在正式数据执行更改。这样即使出现宕机,启动时Wiredtiger会先将数据恢复到最近的一次checkpoint的点,然后重放后续的journal操作日志来恢复数据。
由于MongoDB使用的journal文件大小限制为100MB,因此WiredTiger大约每100MB数据创建一个新的日志文件。
向MongoDB中写入数据是先写入内存,然后每隔60s在刷盘,同样写入journal,也是先写入对应的buffer,然后每隔50ms在刷盘到磁盘的journal文件。
需要注意的是如果客户端的写入速度超过了日志的刷新速度,mongod则会限制写入操作,直到日志完成磁盘的写入。这是mongod会限制写入的唯一情况。
Jouranl日志就是预写入的redo日志,是用于数据故障恢复和持久化数据的,为mongodb增加了额外的可靠性保障。journal除了故障恢复的作用之外,还可以提高写入的性能,批量提交。在这个过程中,所有的写入都可以一次提交,是单事务的,全部成功或者全部失败。启动数据库的Journal功能非常简单,只需写入配置文件即可:
#在启动时指定--journal代表启动journal日志。mongod --journaljournal=true #启用journal日志journalCommitInterval=100 #刷写提交机制。可修改范围是2~300,值越低,刷新输出频率越高,数据安全度也就越高,但磁盘性能上的开销也更高。
三、oplog主从日志与慢查询日志
3.1 固定集合
在讲下面两种日志之前先来认识下固定集合。MongoDB中的普通集合是动态创建的,而且可以自动增长以容纳更多的数据。MongoDB中还有另一种不同类型的集合,叫做固定集合。固定集合需要先创建好,而且它的大小是固定的。固定集合的行为类型与循环队列一样。如果没有空间了,最老的文档会被删除以释放空间,新插入的文档会占据这块空间。
固定集合创建之后就不能改变,无法将固定集合转换为非固定集合,但是可以将常规集合转换为固定集合。
固定集合可以进行一种特殊的排序,称为自然排序,自然排序返回结果集中文档的顺序就是文档在磁盘的顺序。自然顺序就是文档的插入顺序,因此自然排序得到的文档是从旧到新排列的。
3.2 oplog主从日志
MongoDB的高可用复制策略有一个叫做副本集。副本集的复制过程中有一个服务器充当主服务器,而一个或多个充当从服务器,主服务器将更新写入oplog,oplog记录着发生在主服务器的更新操作,oplog是主节点的local数据库中的固定集合(oplog.rs)中,并将这些操作分发到从服务器上。
每个备份节点都维护着自己的oplog,记录着每一次从主节点复制数据的操作。这样,每个成员都可以作为同步源给其他成员使用。
备份节点从当前使用的同步源中获取需要执行的操作,然后在自己的数据集上执行这些操作,最后再将这些操作写入自己的oplog,如果遇到某个操作失败的情况(只有当同步源的数据损坏或者数据与主节点不一致时才可能发生),那么备份节点就会停止从当前的同步源复制数据。
oplog中按顺序保存着所有执行过的写操作,副本集中每个成员都维护着一份自己的oplog,每个成员的oplog都应该跟主节点的oplog完全一致。
如果某个备份节点由于某些原因挂了,但它重新启动后,就会自动从oplog中最后一个操作开始进行同步。由于复制操作的过程是复制数据再写入oplog,所以备份节点可能会在已经同步过的数据上再次执行复制操作。MongoDB在设计之初就考虑到了这种情况:将oplog中的同一个操作执行多次,与只执行一次的效果是一样的。
oplog是固定集合,MongoDB默认将其大小设置为可用disk空间的5%(默认最小为1G,最大为50G),也可以在MongoDB复制集实例初始化之前将mongo.conf中oplogSize设置为我们需要的值。它只能保持特定数量的操作日志,并且如果执行大量的批量操作,oplog很快就会被填满。
#oplog各字段详解ts: 8字节的时间戳,由4字节unix timestamp + 4字节自增计数表示。这个值很重要,在选举(如master宕机时)新primary时,会选择ts最大的那个secondary作为新primaryop:1字节的操作类型"i": insert"u": update"d": delete"c": db cmd"db":声明当前数据库 (其中ns 被设置成为=>数据库名称+ '.')"n": no op,即空操作,其会定期执行以确保时效性ns:操作所在的namespaceo:操作所对应的document,即当前操作的内容(比如更新操作时要更新的的字段和值)o2: 在执行更新操作时的where条件,仅限于update时才有该属性
通过"db.printReplicationInfo()"命令可以查看oplog的信息:
通过"db.printSlaveReplicationInfo()"可以查看slave的同步状态:
3.3 慢查询日志
说到MongoDB的慢查询日志,就不得不提到profile分析器,profile分析器将记录的慢日志写到当前库下的system.profile集合下,这个集合是一个固定集合,使用db.system.profile.find()进行查询,慢日志可以在启动时或者在配置文件中进行指定。
#在启动mongoDB时使用--profile=1启动慢日志,--slowms表示慢日志阈值时间mongod --profile=1 --slowms=5 #也可以在配置文件中指定参数slowms=100 #单位是毫秒profile = 1#0:关闭,不收集任何数据。1:收集慢查询数据,默认是100毫秒。2:收集所有数据#慢日志内容格式详解{ "op" : "query