4 管理
Mongodb Manual阅读笔记:CH2 Mongodb CRUD 操作
Mongodb Manual阅读笔记:CH3 数据模型(Data Models)
Mongodb Manual阅读笔记:CH4 管理
Mongodb Manual阅读笔记:CH5 安全性
Mongodb Manual阅读笔记:CH6 聚合
Mongodb Manual阅读笔记:CH7 索引
Mongodb Manual阅读笔记:CH8 复制集
Mongodb Manual阅读笔记:CH9 Sharding
4.1.3.2 使用Capped Collection做先入先出
4.2.1.6 管理日志(同mysql bin-log,sql server的事务日志)
4.1 管理概念
本节介绍操作mongodb的策略和实践
4.1.1 操作策略
主要介绍1,Mongodb系统的备份策略,2.Mongodb的监控,3.在线配置,4.导入导出
5.注意点
4.1.1.1 备份策略
备份可以让数据保持一致性和可用性,并测试备份保证备份的可用。
备份的考虑
1.在位子上,要和主库分开
2.系统错误,当出现硬件错误或者磁盘错误是,可以从备份中成功恢复
3.生产环境约束,备份操作有时会要求大量的系统资源,所以要和业务高峰分开,避免影响
4.系统兼容性,如一些block-level快照工具需要支持的系统或者一些基础设备
5.数据库配置,复制集和shard会影响备份的实现
6.实际的需求,对重要数据和不重要数据区别对待
备份方法
备份方法分为2种:
1.二进制方式的备份,使用mongodbdump工具对数据库进行dump,但是不能抓取到某个时间点的备份。
2.创建文件系统镜像,有时候会使用block level备份,会产生比较大的备份,但是快速,可以体现某个时间点的备份。
备份的选择依赖于部署和容灾恢复的需要。
对于某些场景来说,备份是很困难的或者不太可能的,因为数据量很大,又是分布式的,这样的情况下,可以考虑增加复制集。
备份的策略和部署
Shard集群备份考虑:对于shard集群来说抓取某个点的数据,必须停止所有的写入,不然抓取的只可能是近似某个时间点的快照。你可以备份shard的复制集的secondary的近似某个点的备份,前提是应用可以接受近视某个点的数据。
复制集备份考虑:复制集备份2个方案:
1.在secondary上创建一个快照,然后备份,当然也可以创建一个隐藏的成员专门用于
2.也可以使用mongodump程序使用 --oplog来备份,用mongorestore程序--oplogReplay 来恢复。
如果在shard下,每个shard都是一个复制集,可以备份某个成员来完成,但是还是要关闭均衡器。在secondary上创建备份可以不影响primary性能。
4.1.1.2 Mongodb监控
主要介绍一些监控方法和一些监控工具
监控策略
有3种方法收集当前mongodb的状态:
1.使用和mongodb一起发布的试试报表
2.使用数据库命令,获取当先数据库的状态
3.使用MMS mongodb 监控服务,收集Mongodb信息,提供可视化的,和一些告警,目前是免费的。
报表工具
工具:Mongodb发布时带了一些报告工具,Mongostat,mongotop,
REST接口:mongodb提供了一个REST接口,可以用来配置监控,和设置告警,要开启要带上启动参数--rest或者在配置文件上面rest=true
HTTP 命令行:mongodb提供web版命令行,可以数据localhost:<port>这个端口是mongod端口加1000。
命令
mongodb还提供了一些命令开报告数据库当前状态。
serverStatus:serverStatus或者db.serverStatus()可以看数据库当前状态,这个命令一般不直接运行,一般是通过统计
dbStatus:dbStats或者db.stats()范围当前存储的使用,监控指定数据库的状态,存储能力
collstats:collStats提供Collection级别的一些信息
replSetGetStatus:replSetGetStatus命令也可以使用rs.status(),查看大概的复制集的状态,使用这个数据确保复制是否配置,并检查host和复制集的状态
第三方工具
有一些开源的工具,可以看手册p140,还有就是SaaS服务。
进程日志
mongod和mongos会记录所有的服务状态到标准输出或者日志文件中有一些配置参数:
1.quite. 限制大量信息被写入到日志或者标准输出
2.verbose.增加大量信息写入到日志或者输出
3.logpath.写入到日志文件
4.logappend.增加信息到已有文件中,而不是覆盖。
有2个命令会影响日志:
1.getLog.输出当前进程日志
2.logRotate.切换日志
诊断性能问题
性能降低往往和数据量,内存,连接数,锁定时间有关。性能问题涉及,负荷,访问方式,可用资源,索引设计,甚至程序设计。
锁:mongodb使用锁来保证数据的可用性,如果serverStatus输出中globalLock.currentQueue.total一直很高,那么说明又大量请求在等待这个锁,说明是并发引起的问题。
globalLock.totaltime相当于服务启动时间,gobalLoc.radio=locktime/totaltime,比例越高说明被锁定的时间越长,可能是慢查询,系统结构问题,或者内存不够。
内存使用:Mongodb使用文件映射的方式来保存数据,让数据都在内存,这样才能保证数据库较高的性能,serverStatus会输出内存使用的情况,mem.resident如果超过内存系统内存那么表示数据在硬盘而不是在内存。mem.mapped如果这个值大于系统内存,有可能会造成页错误。
页错误:如果mongodb请求数据不再内存中,那么就会发生也错误,要到虚拟文件中加载数据。可以查看serverStatus中的extra_info.page_faults。一个错误页并不是问题,但是出现很多错误页的时候,就表示内存不足,mongodb中发生页错误时,线程会退让,让其他线程先运行以提高并发。
连接数:连接数过大会给服务带来巨大的性能问题,serverStatus提供一下几个关于连接的信息:
1.globalLock.activeClients 包含了活动的客户端总数
2.connections包含2个current当前客户端的总数,available所有未使用的连接的总数
对于包并发的请求,可以根据需求使用读写分离或者shard。
大量固定的连接也可能是驱动的问题,每个驱动都是实现连接池的,大量的连接但是没有被使用就说明驱动或者其他配置有问题。
Database Profiling:Profile可以帮忙记录所有的非有效查询,有3个级别:
1.0表示关闭
2.1表示值抓取slow
3.2表示全部抓取
当配置1时可以使用db.setProfilingLevel()来设置级别也可以用来指定slow阀值。
复制和监控
监控复制集一定要监控复制延迟,有2个问题可能会是复制延迟造成的:
1.若出现延迟,并没有复制到secondary,一旦崩溃就会造成一致性问题
2.如果secondary落后超过了oplog,mongodb会启动重新初始化同步。oplog可以在配置文件中配置,如果不配置使用默认大小,默认所有可用空间的5%。
复制延迟要不就是网络问题,要就是primary资源不足以支持应用。可以通过rs.status(),其中有个值optimeDate反应最后一个项被应用到复制集的时间。
Shard和监控
配置服务:配置服务维护了哪些数据是放在哪个shard下面的。shard之间会更新这样的记录,当配置服务不可访问的时候,整个shard操作就不能进行了,已经在访问的不受影响。
所以配置服务不可用是一个很严重的问题。要监控配置服务是否运行正常。
均衡和记录复制:高效的shard集群,会把配置服务器也放在均衡器下,提高配置服务的可用性。
锁过期:在均衡器上使用的锁,当过期之后就会被自动释放,任何长时间的锁都会影响均衡器的性能。可以切换到config数据库,然后使用db.locks.find()查看锁情况。
4.1.1.3 在线数据库配置
介绍通用的配置,最佳实践配置的场景,主要通过配置文件为接口,使用--config或者-f 加配置文件。
数据库配置
基本配置参数:
1.fork,如果为true以服务方式运行
2.bind_ip,指定一个ip,表示服务器只侦听这个这个ip
3.port,是指绑定的端口默认为27017
4.quite,为true表示大多数信息都不写入日志文件,可以在在线的时候用setParameter修改
5.logpath,指定mongod进程日志输出位置
6.logappend,为true追加到文件中,而不是覆盖
7.journal,为true表中写入操作的可持久性
安全性考虑
1.bind_ip,可以配置多个用逗号隔开,只允许这些ip访问
2.nounixsocket,为true禁用unix socket,默认为可用
3.auth,为true,开启mongodb认证系统,要创建用户认证信息
复制和shard配置
复制配置:复制很简单,只要设置replSet=set0,通过设置keyFile启动复制集认证。设置keyFile启动认证并且指定一个key file对应复制集成员的使用。
Shard配置:configsvr=true表示创建一个config 服务,运行在bind_ip的port上,shardsvr配置shard服务,shard还要配置configdb,通过chunkSize修改chunk大小,但是不建议修改。
单服务器多实例
dbpath,指定数据库文件夹位置,padfilepath指定mongod的进程id文件。
诊断配置
1.slowms用于配置数据库profile slow阀值
2.profile 设置profiler级别,
3.verbose 启动verbose日志模式,mongod输出和增加日志的事件。verbose一般只在看不出问题的时候使用,v=ture表示启动verbose,每增加一个v表示额外的日志。
4.diaglog,启动争端日志,Level 3记录所有的读取和写入
5.objcheck,强制mongod验证所有从客户端的执回
6.cpu,强制mongod报告,最后一个间隔花在write lock上面的比例,这个间隔通常是4s
4.1.1.4导入导出
数据类型精度
JSON不支持BSON很多数据类型,当decode BSON文档到JSON会造成一些精度丢失
数据导入导出和备份操作
不管你决定如何导入导出数据,考虑一下几条:
1.标记文件制定什么时候启动的备份
2.标记标记可以描述备份的上下文那些数据备份了
3.如果对备份有不利影响时,不要启动导出
4.保证能够反映数据一致性
5.通过恢复和导入,测试备份和导出
简单明了的导入导出的格式
可以使用copydb,clone,cloneCollection命令,mongo提供db.copyDatabase()方法。
使用mongoexport导出Collection : mongpexport --collection collection --out collection.json。
默认可以使用--jsonArray导出json数组,--csv导出csv。如果没有开mongod可以指定数据库文件。被指定数据库文件后,文件会被锁定,mongod不能附加这些文件。
使用mongoimport导入Collection:格式和导出类似,可以指定--upsert表示会试图更新已有的文档。还可以使用--journal指定生产日志。
4.1.1.5 产品注意点
包
MongoDB:一般都使用64bit,对于32bit,mongodb可以用于测试开发环境,并不适合产品部署,但是不能保存大于2GB数据。
操作系统:mongodb目前支持,MAC OS X,Linux,Windows Server 2008 R2,Windows7
并发
每个数据库都有一个读写锁。
日志
MongoDB使用顺序写入的方式写入到磁盘来保证数据操作的持久性。为了保证crash后可用,你可以启动journal。
网络
使用信任的网络环境:默认mongo不启动认证,认为环境是可信任的。如果是敏感的系统可以指定只被某些服务器访问。
连接池:为了避免连接占用过大资源,应该注意连接池的大小。
硬件考虑
配置足够的CPU和内存:cpu对于数据库来说没有很大的需求,因为数据库不是cpu密集型的,但是对于内存来说是比较重要的。
使用SSD硬盘:SSD硬盘在随机读写上面的性能很出色,可以很好的提高随机io性能
避免使用远程文件系统:这会给Mongo带来性能问题
NUMA硬件:在linux 上,NUMA会给mongo带来一些性能问题,应该禁用NUMA。禁用方法:
numactl --interleave=all /usr/bin/local/mongod
echo 0 > /proc/sys/vm/zone_reclaim_mode
硬盘和存储
SWAP:分配足够的空间,避免出现内存争用现象,对于mongod来说数据映射的,都是并不会被放到swap中
RAID:IO密集型,建议选择RAID10
远程文件系统:并不建议使用远程文件系统,当数据和日志放在同一个NFS的时候会出现性能问题,如果非要用,可以考虑把日志放在iscsi数据房子啊NFS中
分别存储:可以考虑把数据,日志,和进程日志分开存放到不同存储上以提高io性能。
体系结构
Write Concern:Write Concern保证了Mongodb写入安全性。可以根据不同的数据划分write Concern。
复制集:看p390
shard集群:看p502
平台
内核和文件系统:mongodb可以在使用大文件之前,预先分配数据库文件,所以你要使用ext4和xfs文件系统。ext4至少内核要2.6.23,xfs内核至少要2.6.25.
推荐配置:
1.关闭数据库文件所在的存储卷的atime
2.设置描述符限制(-n)和用户进程限制(-u)
3.不要使用hugepages虚拟内存地址
4.关闭NUMA
5.确保预读设置比较适合
6.使用NTP(Nwtwork Time Protocol)来同步时间
虚拟环境:mongodb可以在EC2,VMWare,OpenVZ上运行
性能监控
iostat: linux上用于检查次磁盘io的工具
bwm-ng:命令行命令用户监控网络的使用
备份
查看p136页,关于备份的策略
4.1.2 数据管理
数据管理包括,多数据中心部署,管理大文件存储,数据生命周期工具
4.1.2.1数据中心意识
mongodb可以通过函数参数来隔离,确定mongod实例是用户report的工作负荷,还是用于高频率shard的一部分
Mongodb部署上的操作性策略
概述:mongodb可以通过方法或者地理位置隔离应用程序操作。
这个能力允许应用程序通过地理位置的不同来考虑mongodb的部署,mongodb可以更具操作的不同来区分,可能被区分到不停的地理位置的不同的数据中心。你可以:
1.保证写入操作只传播到特定的复制集的成员
2.指定特定的复制集成员来响应数据读取
3.确保特定的shard key对于到指定的shard上
4.可以整个以上特性到一个复制部署上
具体请看:
读偏好,从那个复制成员上面读数据
写注意(write Concern),控制写操作广播到几个成员
复制集tags,用于创建用户化的读取偏好和write concern
Tag Aware Sharding,用于指定均衡策略
4.1.2.2 Capped Collection
Capped Collection是一个环形buffer,新的数据会覆盖最老的数据。
Capped Collection有一下好处:
1.保证插入的顺序
2.只能更新,更新前后文档大小一样的。
3.自动删除最好的数据
使用场景:
1.保存高层生成的日志
2.保存小量的数据
推荐和限制
1.可以插入后更新,但是更新不能让文档增长
2.不能删除
3.不能shard
4.默认在_id上有个索引
5.使用自然顺序,有效的从collection读取数据
过程
可以使用createCollection()创建capped collection如:
db.createCollection( "log", { capped: true, size: 100000 } )
db.createCollection("log", { capped : true, size : 5242880, max : 5000 } )
查询Capped Collection:使用find()查询,用sort排序。
转化成Collection:可以通过convertToCapped命令把capped Collection转化为普通Collection。
到期之后自动删除数据:Mongodb可以创建TTL索引,允许你删除过期数据。
Tailable Cursor:你可以使用Tailable Cursor连续取回数据,用于capped collection
4.1.2.3 TTL Collection
TTL Collection过期后数据会自动删除,TTL依赖于后台的线程,读取时间类型的值,并且删除过期数据。
启动TTL Collection
使用ensureIndex()创建一个TTL索引来启动TTL 功能,创建后即可启动,过期数据的删除可以使用db.currentOp()或者profile查看。
过期数据的指定有2种方法:
1.超过了指定的秒数
2.超过了指定时间
指定秒数:
db.log.events.ensureIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )
指定时间:
db.app.events.ensureIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )
在创建TTL Collection时需要一个时间字段,在创建索引是指定这个时间字段即可。
限制
1._id字段在TTL索引中不支持
2.不能再已经有索引的字段创建TTL索引
3.如果索引字段不存在,文档不会过期
4.如果不是BSON日期类型或者不是日期数组类型,不会过期
5.TTL索引不能复合
6.如果TTL域如果是一个时间数组,最小一个过期就算过期
7.不能再capped collection上创建TTL索引
8.不能用ensureIndex()改变过期时间
4.1.3 Mongodb优化策略
很多因素都会影响mongodb性能,如查询,索引,数据模型,应用设计,结构和系统配置
4.1.3.1评估当前操作的性能
使用Profile评估操作性能
直接开启profile然后抓取慢查询,适当调节索引
使用db.currentOp()评估性能
直接使用db.currentOp()的shell命令
使用$explain来评估查询性能
使用explain()返回查询的执行计划,看是否有有效的索引等
4.1.3.2 使用Capped Collection做先入先出
First Write
Capped Collection是以环形的方式,新数据覆盖老数据的方式,并且空间时固定的,可以又很好的写入性能和顺序读性能。
first Read
因为写入都是自然顺序的,按自然顺序读取就会很快。
4.1.3.3 优化查询性能
使用索引来优化
用索引覆盖查询,以提高查询性能。但是索引也是有写入操作的性能消耗的。查询是顺序还是逆序,都可以利用索引。
限制查询结果减少网络需求
减少查询结果,尽量少输出,减少网络需求可以使用limit()
使用Porjection返回有必要的列
同样是为了减少输出
使用$hint指定索引
用hint()强制使用某个索引
使用服务端的自增操作
使用$inc这样自增操作可以在服务端上运行,可以不用先查询,后修改。
4.1.3.4 设计注意点
Schema考虑
动态Schema:mongodb中schema是动态的,并不强制要求文档结构,虽然collection是保存结构类似的数据。注意点:
1.准确的设置使用的collection
2.只有_id索引是不需要定义的,其他都需要定义
3.选择合适的shard key一旦定义就不能被修改
大小写敏感:Mongodb中字符串是大小写敏感的
类型敏感:如果在字符串的字段上,用数字去搜索是不会返回结果的
基本考虑
1.默认update只影响一行
2.BSON文档大小的限制默认为16MB,若更大可以使用GirdFS
3.没有一般意义上的事务,如果要做事务,需要通过2阶段提交方法,用户自己实现。
复制集考虑
1.使用奇数个复制成员,为了保证当选成功要不使用奇数个成员(通常是3个),要不用仲裁
2.保持成员up-to-date,考虑以下方法:
a.使用监控告警复制延迟
b.指定write concern
c.如果你使用手动failover,你可以吧secondary配置成优先级为0
shard考虑
1.配置shard小心,不能为已经shard的collection重新指定shard key
2.shard key不能修改
3.当在已存在的collection上使用shard,mongodb会使用collection中最大的大小来保证创建chunk。
4.shard key要求唯一
5.在大批量导入之前考虑使用预分配
4.2 管理教程
管理教程一步一步的演示如何执行Mongodb的安装,维护和配置。
主要从以下几个方面:
1.配置,维护和分析
a. 管理mongod进程
b. 日志切换
2.备份和还原
a.使用文件系统快照做备份还原
b.备份还原shard集群
3.Mongodb脚本化
4.Mongodb教程
4.2.1 配置,维护和分析
从以下几个介绍:
1.使用数据库命令,2.管理mongod进程,3.分析数据库操作的性能,4.使用SNMP管理Mongodb,5.切换日志文件,6.管理日志,7.保存javascript方法,8.更新mongodb,9.Mongodb教程
4.2.1.1 使用数据库命令
mongodb命令接口包含了所有非CRUD的操作。
数据库命令格式
数据库命令的格式就是BSON格式
使用命令
使用db.runCommand(BSON格式)就可以使用了
admin 数据库命令
如果要在admin数据库运行一些命令可以使用一下:
use admin
db.runCommand()
对于admin的命令也可以使用一下,会自动应用到admin上下文
db._adminCommand()
命令返回
所有的命令返回都有一个ok标记不管命令运行是否成功,如果运行失败,ok标记就会返回0。
4.2.1.2 管理Mongod进程
Mongod进程是主数据库进程运行在独立的服务器上,Mongos提供一些Mongod的服务对客户端透明。
启动mongod:使用命令mongod启动命令
指定特殊目录:使用--dbpath 来指定数据库文件所在的位置
指定TCP端口: 使用--port选项指定
以服务方式启动: --fork指令表明可以以服务方式启动
额外的配置选项:看手册page 145
停止服务:使用shutdownServer()方法,从shell中停止mongod服务,也可以使用mongod --shutdown 来关闭服务。也可以使用ctrl-c,kill命令。
停止复制集:
1.检查备机替换。
2.如果10秒内没有备机,mongod会返回一条消息不回被关闭。
3.如果在10秒有备机,primary会逐步关闭,并等待备机接上。
4.如果60秒后或一旦备机接上,主机就会关闭。
强制复制集关闭:使用db.adminCommand({shutdown:1,force:true})。db.adminCommand({shutdown:1,timeoutSecs:5})(db.shutdownServer({timeoutsecs:5})),也可以指定一个时间,如果在这个时间内备机没接上,就不会关闭。如果接上了就可以关闭。
4.2.1.3 数据库操作的性能分析
通过profile就可以抓取每个数据库的操作。并存放在一个capped collection内。
profiling levels:
0,关闭profile;1,只抓取slow查询;2,抓取所有数据。
启动profile并且设置Profile级别:
可以通过mongo shell启动,也可以通过驱动中的profile命令启动,启动后记录会被保存在system.profile collection下,可以使用db.setProfilingLevel来启动。默认slow为100 毫秒。db.setProfilingLevel可以有2个参数,第一个参数指定Profiling 级别,第二个参 数指定slow阀值。
检查当前Profiling 级别:可以通过db.getProfilingStatus()获取当前profiling级别,slowms 标记慢查询阀值。
关闭Profiling:还是使用db.setProfilingLevel(0)来关闭profiling
整个实例开启Profiling:mongod --prifile=1 --slowms=15
shard的Profiling:对shard的profiling要对每一个实例进行profiling
查看Profiling数据
可以直接在system.profile的collection上查看如:db.systen.profile.find()。或者使用show profile,会显示最近至少1ms时间运行的前5条记录。
Profiler概述
要修改system.profile collection的大小必须:1.关闭profiling,2.删除system.profile,3.然后重新创建system.profile,4.重启profile。
shell如下:db.setProfilingLevel(0)
,db.system.profile.drop()
,db.createCollect("system.profile",{cappedLtrue,size:4000000})
,db.setProfilingLevel(1)
4.2.1.4 使用SNMP监控Mongodb
这个功能只有在企业版中可用:www.mongodb.com/products/mongodb-enterprise
要求:
安装版本:企业版
包含文件:1.MONGO-MIB.txt这个文件包含了mongodb的SNMP输出。2.mongod.conf,SNMP的配置文件,用来配置SNMP的公有名称,权限,访问权限等。
要求的包:
1.Ubuntu 11.04 要求libssl0.9.8, snmp-mibs-downloader, snmp, 和 snmpd. 使用如下命令: sudo apt-get install libssl0.9.8 snmp snmpd snmp-mibs-downloader
2.Red Hat Enterprise Linux 6.x series和Amazon Linux AMI 要求 libssl, net-snmp,net-snmp-libs,和net-snmp-utils.使用如下命令:sudo yum install libssl net-snmp net-snmp-libs net-snmp-utils
3.SUSE Enterprise Linux 要求 libopenssl0_9_8, libsnmp15, slessp1-libsnmp15, andsnmp-mibs.使用如下命令:sudo zypper install libopenssl0_9_8 libsnmp15 slessp1-libsnmp15 snmp-mibs
配置SNMP:
安装MIB配置文件:要确保路径/usr/share/snmp/mibs 存在,如果不能保证使用mkdir 创建,然后在路径上创建一个MONGO-MIB.txt连接,然后用把配置文件复制到该路径下:
sudo mkdir -p /usr/share/snmp/mibs
sudo ln -s <path>MONGO-MIB.txt /usr/share/snmp/mibs/
cp mongod.conf /etc/snmp/mongod.conf
启动:可以使用mongod --help | grep snmp来抓取和snmp有关的选项。
保证路径/data/db和/var/log/mongodb文件夹存在,然后启动mongod实例,指定snmp选项:
mongod --help | grep snmp
mkdir -p /var/log/mongodb/ /data/db/
mongod --snmp-master --port 3001 --fork --dbpath /data/db/ --logpath /var/log/mongodb/1.log
测试SNMP:检查是否有监听关口1161,使用命令lsof -i <port>或者使用netstat -anp | grep 1161。
本地使用snmpwalk:snmpwalk提供从MIB文件中获取和分析数据的工具。使用如下:
snmpwalk -m MONGO-MIB -v 2c -c mongodb 127.0.0.1:1161 1.3.6.1.4.1.37601
snmpwalk -m /usr/share/snmp/mibs/MONGO-MIB -v 2c -c mongodb 127.0.0.1:1161 1.3.6.1.4.1.37601
Troubleshooting
出现异常是可以检查:/var/log/mongodb/1.log文件,当出现以下问题的时候表示无法读取配置文件:[SNMPAgent] warning: error starting SNMPAgent as master err:1
4.2.1.5 切换日志文件
日志切换是归档当前的日志,然后重开一个新的,日志文件的切换用UTC时间戳来命名,创建新文件,关闭老文件,把日志写入到新文件中。当mongod或mongos收到SIGUSR1信号或者logRoate命令时,才会被切换。
日志文件切换:
use admin
db.runCommand({logRoate:1})或者kill -SIGUSR1 <mongodb 进程id>
syslog切换:
1.mongod启动要有syslog选项
2.使用系统日志自带的切换方式切换
4.2.1.6 管理日志(同mysql bin-log,sql server的事务日志)
mongodb使用顺序写的方式保证写操作的持久性和崩溃恢复。在修改数据库文件直线,mongodb会先写入日志,若遇到错误或者崩溃就可以从日志中redo。若没有日志,mongod出现不可预期错误,就要假设你的数据就是不一致的,不许运行数据库修复,或者在复制集中使用数据库同步。若有日志就可以通过日志让数据库回到一致性状态。
如果使用了日志,你又要想把一个数据集放入内存,除了数据占用的内存之外,还需要加入write working set。write working set 是想要在重新映射之间看到的数据差距。
过程
启动日志:在启动mongod的时候加入选项--journall。如果没有日志,当mongod重启的时候,会预先分配这些文件。在创建期间,mongod不会去侦听任何连接。
禁用日志:使用--nojournal命令
获取提交通知:可以通过getLastError命令的j选项来获取通知
避免预分配延迟:如果想要避免预分配延迟,可以先分配,然后复制:
1.创建一个临时文件夹mkdir ~/tmpDbpath
2. 通过mongod启动创建日志文件mongod --port 10000 --dbpath ~/tmpDbpath --journal
3. 当看到以下输出的时候,用ctrl-c关闭服务进程web admin interface listening on port 11000
4. 然后复制这些文件到数据文件夹下mv ~/tmpDbpath/journal /data/db/
5. 重启实例mongod --port 27017 --dbpath /data/db --journal
监控日志状态:可以使用serverStatus命令返回数据库状态中查看,也可以用journalLatencyTest命令查看
获取组提交间隔:可以设置组提交间隔,使用--journalCommitInterval选线,范围在2-300MS之间。
崩溃后恢复数据:当崩溃后重启,mongodb回放这些日志
4.2.1.7在服务端保存JavaScript函数
保存javascript都保存在system.js中,可以使用save命令保存。并且可以使用db.eval(方法)来调用。当然也可以使用db.loadServerScripts()一旦load完之后,就可以直接调用。
4.2.1.8 更新mongodb版本
更新前
在更新前要保证以下几点:
1.保证有最新的备份
2.通过Release Notes和驱动文档,注意兼容性和特殊要求
3.若有复制,要有一个更新维护窗口
4.在生产库上更新之前,现在备用库上使用,确保兼容性等问题。
更新过程
1.部署认证,先更新mongodb驱动
2.更新shard集群
3.更新standalone实例
4.更新非shard集群的复制集
更新实例
更新方法有以下2种:
1.使用官方的工具更新 如apt-get
2.直接覆盖已有的二进制文件
替换已有的二进制
1.复制最新版的二进制文件包
2.关闭实例
3.替换
4.起送实例
更新shard集群(CHECK?)
1.关闭均衡器
2.更新mongos实例
3.独立更新config server,根据config server列表独立启动,为了保证集群online,保证至少有一个config 服务是在运行。
4.更新shard节点,若shard是一个复制集,要用更新复制集一样的 方式更新
5.开启均衡器
更新复制集
更新备份库:
1.更新这个实例
2.然后等待备份库状态,在shell 里面可以使用rs.status()
3.若状态变为了STARTUP2或者RECONVERING,为了保证备份库就绪,状态等到SCEONDARY,然后再继续下一个备份库的更新。
更新主库:
1.让主库进入failover,使用rs.stepDown()或者replSetStepDown命令
2.一旦主库step down,调用rs.status()方法,知道发现被成功转移,其他节点变成primary
3.更新这个实例。
4.2.2 备份和恢复
4.2.2.1 备份和恢复工具
如果在快照备份不可用的情况下,用工具被分是最合理的。
使用mongodump备份
基本mongodump选项:mongodump备份有2中方式:
1.连接到一个mongodb实例
2.直接访问mongodb数据库文件
如果没有参数默认连接到local的27017端口下。
使用oplog指定事件:在复制集中使用--oplog选项收集oplog项来创建一个事件点的快照。然后使用mongorestore --oplogReplay来恢复备份
不使用实例还创建备份:可以直接可以通过--dbpath参数指定数据库文件,不需要连接到实例。
从非本地实例创建备份:直接接入--host和--port就可以连接到远程的实例进行备份,如:
mongodump --host mongodb1.example.net --port 3017 --username user --password pass --out /opt/backup/mongodump-2012-10-24
使用mongorestore还原数据库
mongorestore的参数基本和mongodump类似。
还原Oplog备份:还原这个备份是要但是原想 --oplogReplay,也可以考虑加入 --objcheck来检查对象的一致性,加入--drop会在导入前删除数据库中的所有collection
还原数据子集:可以使用--filter 来过滤数据然后到处子集
不用mongod还原:和备份一样可以直接通过--dbpath连接到数据文件,不需要连接到实例。
还原非本地数据:mongorestore --host mongodb1.example.net --port 3017 --username user --password pass /opt/backup/mongodump-2012-10-24
4.2.2.2使用文件系统快照备份和恢复
快照概述
创建完快照之后,你可以mount快照卷,然后把快照里面的数据复制到你的文件系统中,备份就是完全拷贝。快照有一下几个限制:
1.当快照发生时,数据库必须可用,要求所有的写入操作必须被写入到磁盘,要不放到journal要不放到数据库文件。如果不再磁盘上,那么这些修改不会被备份反映。
2.快照是对整个磁盘做image。可以考虑把数据文件放到单独的一个盘上面
3.把快照备份放到其他服务器上保证不会出现单点故障
4.不同的快照有不同的能力,但是lvm方式,不支持增量备份。
带journal的备份:如果有journal,你可以使用任何方式的快照来创建备份
在Amazon EBS的Raid 10配置下的快照:在这个环境下,你不可能伙同快照工具保证一致性,有一下方法:
1.先把写入都写到磁盘上确保一致性,加写锁,然后在备份确保一致性
2.配置lvm运行,让数据文件在raid上面。
linux系统中使用lvm备份还原
创建备份:lvcreate --size 100M --snapshot --name mdb-snap01 /dev/vg0/mongodb
创建了一个快照名字叫做mdb-snap01,这个快照有100MB,这个大小不是数据文件的大小,而是快照和当前状态之间差距的大小。
当命令返回,快照就已经被创建好了,虽然快照备份速度非常快,但是对于备份存放来说快照不是一个很好的方式。因此还需要把这些快照复制出来,进行归档。
归档快照:创建好了快照之后,要mount快照并且把数据放到一个独立的存储上面,如:
umount /dev/vg0/mdb-snap01
dd if=/dev/vg0/mdb-snap01 | gzip > mdb-snap01.gz
先保证是unmount状态,然后使用dd进行复制和压缩
还原快照:
lvcreate --size 1G --name mdb-new vg0
gzip -d -c mdb-snap01.gz | dd of=/dev/vg0/mdb-new
mount /dev/vg0/mdb-new /srv/mongodb
先创建一个逻辑卷,然后制定设备路径,这里指定了1g大小,那么原文件大小必须小于1g。然后解压到这个逻辑卷上,然后把这个逻辑卷mount到/srv/mongodb上。
直接从快照上还原:
umount /dev/vg0/mdb-snap01
lvcreate --size 1G --name mdb-new vg0
dd if=/dev/vg0/mdb-snap01 of=/dev/vg0/mdb-new
mount /dev/vg0/mdb-new /srv/mongodb
远程备份:
umount /dev/vg0/mdb-snap01
dd if=/dev/vg0/mdb-snap01 | ssh username@example.com gzip > /opt/backup/mdb-snap01.gz
lvcreate --size 1G --name mdb-new vg0
ssh username@example.com gzip -d -c /opt/backup/mdb-snap01.gz | dd of=/dev/vg0/mdb-new
mount /dev/vg0/mdb-new /srv/mongodb
没有journal创建根据实例备份
如果实例没有启用journal或者journal在独立的卷里面,备份会相对的复杂,你必须刷新所有的写入,并且锁定数据库在备份时禁止写入。
1.刷新数据库并且锁定,使用db.fsyncLock()
2.创建备份
3.然后解锁,使用db.fsyncUnlock()
当开着profile的时候不能db.fsyncLock(),需要先关闭db.setProfilingLevel()
4.2.2.3从备份中还原复制集
还原到复制集单个节点
1.获取备份文件
2.启动mongod,使用这些备份文件启动
3.把单个实例转为复制集的一个节点,使用--replSet
4.连接到mongod
5.执行rs.initiate()进行初始化
添加成员到复制集中
1. 手动复制数据库文件目录到所有的实例
2. 使用初始化同步数据,同步到成员
复制数据库文件并重启实例:
1. 关闭实例使用shell 命令db.shutdownServer()
2. 复制primary的数据文件到其他成员的dbpatch下
3. 重启mongodb实例
4. 用mongo shell连接到primary,使用rs.add()添加secondary
使用初始化同步更新secondary:
1. 确保预期的成员遍历数据文档都是空的
2. 添加预期的成员到复制集,然后使用初始化同步,复制primary到其他的复制成员
4.2.2.4备份还原Shard集群
使用mongodump备份小shard集群
概述:
小集群数据量比较小,如果备份执行时间可以接受,并且数据集有独立的存储就可以考虑,使用dump直接备份。
过程:
抓取数据:如果mongodump没有指定数据库或者collection,mongodump会抓取collection数据和config server的集群数据。不能使用—oplog,这个参数只作用于复制集。可以用--host连接到mongos,进行备份。
恢复数据:和所有的dump备份一样,备份为每个数据库创建了独立的文件夹,每个collection包含一个独立的BSON文件。
使用文件系统快照备份shard集群
概述:
这个过程使用系统快照来抓取Mongdb实例的副本,进行备份。
过程:
这个过程是先停止均衡器,然后备份config数据库,然后再备份每个shard,在备份shard的时候,在创建快照的时候先要停止写入。
可以通过备份secondary成员来达到近似的时间点快照,并且最小化影响集群。
1. 关闭均衡器使用,sh.stopBalancer()来停止
2. 锁定shard复制集中一个成员,这样备份就能够反应某个时间点数据库的状态。为了锁定shard 集群需要做一下2步
a) 使用db.fsyncLock()锁定secondary成员
b) 关闭一个config服务,在备份期间阻止所有元数据的变化。
3. 使用mongodump备份config数据库,使用 mongodump –db_config 备份
4. 使用快照备份,备份复制集成员。
5. 使用db.fsyncUnlock()解锁所有的成员
6. 启用均衡器,use config sh.setBalancerState(true)
使用数据库dump备份shard集群
概述:
介绍一个使用mongodump创建一个实例的dump过程。
过程:
1. 停止均衡器, sh.stopBalancer()
2. 锁定shard复制集中一个成员,这样备份就能够反应某个时间点数据库的状态,锁定步骤:
a) 关闭复制集的一个成员,确保oplog有足够的空间,支撑到备份结束
b) 关闭一个config数据库,阻止所有的元数据修改
3. 使用mongodump备份config数据库。
4. 使用mongodump在关闭实例的服务器上备份并指定dbpath
5. 启动所有停止的成员
6. 启动均衡器
使用shard集群的调度备份窗口
概述:
Shard集群中,均衡器的用处是在集群中分发数据,在备份时,停止均衡器这样数据块就不会在shard之间移动影响备份,可以手动停止均衡器,也可以用均衡器调度窗口。
过程:
若有例行的备份,囊而就可以用以下方法,开一个调度窗口自动停止均衡器。
useconfig
db.settings.update({_id:"balancer"},{$set:{activeWindow:{start:"6:00",stop:"23:00"}}},true)
但是例行的备份必须在这个时间范围内结束
恢复单个shard
概述:
从备份中还原一个shard需要一些其他的考虑和实践
过程:
当你还原备份的时候,要记住得,均衡器可能从这个shard移动chunk,所以你必须要手动移动这些chunk。
1. 和还原其他实例一样,先还原这个shard
2. 对于要从这个shard移出的chunk就不用处理,mongos会自动过滤掉这些数据
3. 对于要迁移到这个shard的数据,你必须要手动通过备份其他shard或者其他资源恢复这些数据,可以通过config数据库查看chunk是否被移动。
还原一个shard集群
概述:
首先要有备份,备份可以从文件系统快照备份获得,也可以通过数据库dump获得
过程:
1. 停掉mongos和mongod
2. 如果主机名被修改,你必须手动更新config数据库中的shards,使用新的主机名:
a) 使用一下命令启动config 服务
mongod --configsvr --dbpath /data/configdb --port 27019
b) 恢复config数据库
c) 启动和一个mongos实例
d) 更新config数据库中shards指向新的主机名
3. 还原一下信息:
a) 每个shard的数据库文件
b) 每个config的数据库文件
4. 重启mongos
5. 重启mongod
6. 连接到mongos实例,使用db.printShardingStatus()方法确保集群式可用的。
db.printShardingStatus()
show collections
4.2.2.5从异常关闭中恢复数据
mongodb没有干净的关闭会导致数据文件不一致,导致数据异常,当然可以干净关闭,或者使用持久性日志,默认mongodb会在每100ms写入数据库journal,这样mongodb在不干净关闭,断电的情况下很快的恢复一致性。
如果你没有复制集和journal你可以使用一下过程恢复数据,当你有复制集的时候,可以从备份中恢复,也可以使用初始化同步恢复。
处理
说明:
当你运行在没有复制集,没有journall的mongod的实例上,要意识到,当你数据库非正常关闭的时候,总是要使用数据库修复选项,如果有复制则可以直接还原备份或者初始化同步。
如果数据文件夹下有个mongod.lock,mongod会拒绝启动,在启动是,进程日志会出现以下信息:
Unclean shutdown detected
这就表示,你需要使用--repair选项来恢复,当你运行是带了选项并且有mongodb.lock文件,进程日志有一下信息:
old lock file: /data/db/mongod.lock.probably means unclean shutdown
出现这个信息,就应该删除这个文件,并且在正常启动前修复数据库
注意:
如果是有复制集就不要使用这个方法,可以使用备份或者使用初始化同步
这里有2中方法修复数据库文件:
1. 用--repair选项并使用--repairpath选线,这样mongod会读取已存在的数据文件,并写入到新的文件中,不修改老文件。使用这个过程可以不删除lock文件
2. 只用--repair,读取存在的文件,写入到新的文件中,并且覆盖老文件,在这个过程前要删除lock文件。
过程:
方法1:
1. 启动mongod带选项--repair,当完成时新的文件会出现在/data/db
mongod --dbpath /data/db --repair --repairpath /data/db0
2. 启动mongod,dbpath指向 /data/db0
这个方法会保留原文件
方法2:
1. 删除lock文件
rm /data/db/mongod.lock
2. 带--repair启动mongod实例
mongod --dbpath /data/db --repair
3. 然后启动mongod实例
mongod --dbpath /data/db
mongod.lock
有lock文件就不能启动mongod,如果在很特殊的情况先可以直接删除然后启动恢复数据,这样的话数据库的状态就很难预测
4.2.3 MongoDB脚本
主要介绍:服务端javascript脚本,mongo shell的数据类型,为mongo shell 编写脚本,mongo shell入门,mongo shell帮助信息。mongo shell 快速参考手册
4.2.3.1服务端javascript
概述
Mongodb支持在服务端运行javascript以下方式运行:
1. mapReduce和db.collection.mapReduce()
2. 使用eval命令或者使用db.eval()
3. $where运算符
4. 直接运行.js文件
可以通过选项--noscripting选项或者noscripting配置文件设置,不执行脚本
通过Mongoshell 直接运行js文件
可以直接通过mongo shell 执行js文件。
并发
查看concurrencytable p594
4.2.3.2 Mongo Shell中的数据类型
MongoDB的BSON提供了比JSON多的数据类型
类型
日期类型:BSON提供了多个返回时间类型的方法:
1.Date()直接返回一个表示时间的字符串 如:
varmyDateString= Date();
2.Date()可以是用new来构建一个时间类型
varmyDateObject= new Date();
3.ISODate()构建一个ISO时间
varmyDateObject2= ISODate();
ObjectId:对于ObjectId Mongo shell提供了一个ObjectId()的封装类来生成ObjectId,如:
new ObjectId
NumberLong:默认mongo shell中的所有数值全是浮点型,mongo使用了NumberLong()生成一个8字节整型。
NumberInt:提供了NumberInt()生成4字节整型
检查数据类型
mongo shell中提供了检查类型的方法:
1.instanceof,然会测试的值是否是某个类型的,返回true,false
2.typeof,直接返回一个值的类型
4.2.3.3 为mongo shell 编写脚本
打开新连接
在mongoshell 或者js文件中,可以使用Mongo()连接到实例 如:
new Mongo()
new Mongo(<host>)
new Mongo(<host:port>)
另外也可以使用connect()方法,如:
db = connect("localhost:27020/myDatabase");
互动mongo和脚本mongo区别
考虑一下几点:
1.设置db全局变量,假设当前数据库并不是你要使用的数据库
2.使用db.getLastError()显示的等待写入操作
3.不能够使用 shell help(如use db,showdbs等)具体可以查看p 211中的表格
4.在交互模式下,游标会自动输出内容,在脚本下要使用print(),如:
cursor = db.collection.find();
while ( cursor.hasNext() ) {
printjson( cursor.next() );}
脚本
对于prompt也可以使用,javascript脚本建立。
--eval选项:mongo --eval <script>即可
执行js文件:mongo localhost:27017/testmyjsfile.js,直接在实例上运行js文件。替代方法,也可以先连接到实例,然后使用load()方法执行。
mongo shell简单入门
启动shell:
1.进入mongodb安装目录
2.键入 ./bin/mongo
3.使用db查看当前数据库,使用use 切换数据库
执行查询:使用db.collection.find()查询,db指示了当前的数据库,collection是所查的
打印
find的结果如果赋值给变量,就会直接输出,可以在后面加.pretty()
有一下输出函数:
1.print()不带格式直接输出
2.print(tojson<obj>),和printJson效果一样
3.printJson()带json格式输出
执行js文件
可以直接使用load()执行一个js文件,如:
load("/data/db/scripts/myjstest.js")
用户化Prompt
可以通过脚本修改Prompt,如:
host = db.serverStatus().host;
prompt = function() {
return db+"@"+host+"$ ";}
使用其他编辑器
设定环境变量,EDITOR然后再启动mongo,在shell中使用edit 就可以在其他编辑器上编辑。如:
export EDITOR=vim
mongo
MongoDB shell version: 2.2.0
> function f() {}
> edit f
> f
function f() {
print("this really works");
}
> f()
this really works
4.2.2.4 访问shell帮助信息
命令行查看帮助
mongo --help
mongo shell查看帮助
输入help
数据库帮助
1.通过show dbs查看数据库
2.db.help查看db下可用的方法
3.查看方法的实现,比如 db.addUser(),输入db.addUser不加括号就可以看方法的实现
collection 帮助信息
1.使用show collections 查看已经存在的collection
2.使用db.collection.help 查看collection的帮助
3.不用括号可以查看方法实现
游标帮助信息
1.db.collection.find().help()查看游标的帮助信息
2.不加括号可以看方法的实现
类型帮助
使用helpmisc查看 mongo shell中疯长的可用类。
4.2.2.5 Mongo shell快速参考手册
mongo shell 命令历史
可以通过方向键获取上一条,下一条命令,这些命令被存放在~/.dbshell文件中。
命令行选项
mongo也有很多命令行选项:
--help:查看所有命令行选项
--nodb:启动mongo shell 但是不连接到数据库
--shell:关联一个文件,运行完文件之后,shell继续运行
帮助命令
help显示帮助
db.help 显示数据库方法
db.collection.help 显示collection方法
show dbs 显示已有数据库
use db 切换数据库上下文
show collections 显示当前数据库下已有collection
show users 显示当前数据库先所有的用户
show profile 显示花费了1ms以上的前5个操作
show database 显示所有可用shujk
load() 执行js文件
4.3管理参考
包含以下内容,ulimit设置,system collection,Mongodb扩展JSON,数据库profile输出,journaling机制,退出代码和状态。
4.3.1 Unix ulimit设置
很多类似unix系统都提供了资源控制,当然有时候默认值太低会导致大量的mongodb常用操作。
4.3.1.1 资源利用
通常,所有的mongod和mongos实例会跟踪一下信息:
1.使用1个文件描述符和1个线程跟踪每个income 连接。
2.跟踪每个内部的线程或者pthread都作为一个系统进程
mongod
1.mongod实例中每个文件1个文件描述符
2.当journal为true,每个journal文件1个描述符
3.在复制集中,每个mongod维护了到其他所有成员的连接
mongod使用后台线程,用于TTL collection,复制,复制集的健康检查,这些都会消耗一些性能。
mongos
客户端连接所使用的线程和文件描述符,所有config数据库和shard的连接,复制集所有成员的连接。考虑一下几点:
1.mongos维护一个连接池,可以直接重用连接不需要重新创建
2.使用maxConns选项限制income连接数
4.3.1.2查看和设置资源限制
ulimit
硬ulimit:类似有多少cpu可以让一个用户使用
软ulimit:强制对一个session或者进程的可用资源的限制
所以软ulimit可能会导致无法创建连接的情况,所以ulimit配置很重要。
ulimit是针对每个用户的不同的资源,然后可以通过ulimit -n <value>这种方式修改
/proc 文件系统
可以通过以下shell脚本查看进程限制的状况:
return-limits(){
for process in $@; do
process_pids=`ps-C $process -o pid --no-headers | cut -d "" -f 2`
if[ -z $@ ]; then
echo"[no $process running]"
else
forpid in $process_pids; do
echo"[$process #$pid -- limits]"
cat/proc/$pid/limits
done
fi
done
}
如:return-limitsmongod mongos
4.3.1.3推荐设置
-f (file size): unlimited
-t (cpu time): unlimited
-v (virtual memory): unlimited58
-n (open files): 64000
-m (memory size): unlimited1
-u (processes/threads): 32000
4.3.2 系统collection
4.3.2.1简介
mongodb把一些系统信息都存放在<database>.system.*namespace下面,不要创建以system开头的collection
4.3.2.2 Collections
系统collection包含如下:
<database>.system.namespaces:包含了数据库collection的所有信息
<database>.system.indexs:包含了数据库中所有的索引
<database>.system.profile:包含了数据库profiling信息
<database>.system.users:包含了用户证书信息
<database>.system.js:包含了所有服务端javascript代码
4.3.3 MongoDB扩展JSON
mongodb 手册 2.4.8 page 227自己查看
4.3.4 数据库profile输出
profile开启后,mongodb会把数据写入到system.profile这个capped collection中,可以直接查询这个capped collection查看捕获的数据。
4.3.4.1输出例子
{
"ts": ISODate("2012-12-10T19:31:28.977Z"),
"op": "update",
"ns": "social.users",
"query": {
"name": "jane"
},
"updateobj": {
"$set": {
"likes": [
"basketball",
"trekking"
]
}
},
"nscanned": 8,
"moved": true,
"nmoved": 1,
"nupdated": 1,
"keyUpdates": 0,
"numYield": 0,
"lockStats": {
"timeLockedMicros": {
"r": NumberLong(0),
"w": NumberLong(258)
},
"timeAcquiringMicros": {
"r": NumberLong(0),
"w": NumberLong(7)
}
},
"millis": 0,
"client": "127.0.0.1",
"user": ""
}
具体每个域表示什么意思查 Mongodb手册 v2.4.8 page 261
4.3.5 journaling 机制
当启动journal,mongodb会在把写入操作应用到数据文件之前先写入journal文件,写入的间隔为commitIntervalMs,所以当出现故障可能会丢失commitIntervalMs时间的数据。
4.3.5.1 journal 文件
journal启动后就会创建journal文件,在dbpath下,journal文件被保存在journal文件夹下,文件都是以顺序写的方式写入,干净关闭实例,会把journal文件夹下的文件全部删除。
journal文件是只能追加的,并且都是以j._开头,当journal文件超过1gb的数据,就会自动创建新的文件,一旦文件中的操作都被mongodb应用,那么文件就会被删除,所以一般只会保留2-3个文件。
可以启用smallfiles配置选项,把journal 文件最大设置为128MB。
为了保证写入的速度,可以把文件放到其他系统上。注意如果journal和数据文件不再同一个文件系统中,不要直接使用快照来抓取备份,请查看快照备份。
可能会在mongodb启动的时候经历,预分配延迟,导致这一段时间内,无法连接到数据库。由mongodb决定是通过预分配的方式还是需要的是后再创建文件的方式处理。
4.3.5.2 journal使用的存储视图
journal使用了3部分存储视图:shared view,private view,private cache。
shared view:shared view 保存了更新到数据库文件的数据,是唯一一个可以访问数据库文件的view,当启用journal,mongod要求操作系统映射磁盘上的文件到shared view上,但是不加载他们,然后mongodb把数据库文件按需加载到shared view 上。
private view:保存用户读操作的数据,当新的写入操作时,mongodb把private view 映射到shared view。
private cache:journal是磁盘上的视图,在写入到数据文件之前,把写入操作先写入到了privatecache上,用于写入到journal文件上。
4.3.5.3 journal如何写入
journal批量复制写入操作到journal成为组提交。
当写入操作发生,mongodb写入数据到private view,然后批量复制写入操作到journal上,每个块都说明了那些字节在数据库文件中被修改。
然后mongodb把应用journal的写入操作到shared view,这时shared view和数据库文件变得不一致。然后默认60s后,mongodb要求系统刷新shared view 到磁盘上,数据库文件更新。
当mongodb刷新写入操作到磁盘时,mongodb从后面的指针删除这些写入操作。后面的指针和当前活动指针(要刷新到磁盘)差很远。
然后mongodb要求操作系统吧shared view 重新映射到 private view 保持一致性。
扩展阅读:
journal工作原理:http://f.dataguru.cn/thread-139560-1-1.html
4.3.6 退出代码和状态
当mongodb退出的时候会更一下代码和状态,可以用于troubleshooting。
0:mongodb正常退出
2:和其他选项不兼容导致的错误
3:当命令行指定的主机名和local.sources不符时返回,当oplog collection不可读是也可能会返回。
4:数据库版本和mongod的版本不同。重启mongod加上--upgrade选项更新数据库到mongod支持的版本即可。
5:moveChunk错误是发生
12:在windows下,当mongod接收到ctrl-c,关闭,break或者关闭命令时返回
14:当mongodb发生不可恢复的错误,无法处理的异常或者无法捕捉的signal。会干净的关闭。
20:在windows下,的WSAStartup函数中出错时返回,也可能是,windows下,不能成功安装,启动,删除服务是出现。
45:当mongodb不能打开文件或者不能获取文件上的锁时,出现
47:当mongodb退出,需要大量的时间
48:如果socket关闭,mongod干净退出
49:mongod,mongos收到SCM的关闭信息
100:mongod抛出一个无法捕获的异常