您的位置:首页 > 数据库 > Mongodb

浅谈MongoDB之二 备份与修复(13/04 补充)

2013-04-10 07:20 381 查看
在创建数据库之初,会多次加入或删除一些键值。最后为了节省空间,将键名与键值精简一番,但占用空间却只会随着内容增加而增加,却不会反之减小。这样,我的数据库“越长越胖”就成了我的问题,复制做备份也很不方便。终于今天在《实战MongoDB》一书中学到了相关的压紧方法,并试用了一下,以此写篇心得。

在写到压紧修复数据库之前,先从备份说起吧。书中介绍了两种备份方法:1.使用mongodump与mongorestore来备份。大概意思是用mongodump命令将数据库导出BSON文件,然后使用mongorestore再恢复回来。但是制作出的备份并不包含索引,需要恢复数据库后自行完成。并且mongorestore不会删除数据库,如果目前存在所要还原的那个,需要手动添加--drop标识。

第二种方法据称是较为常用的,就是直接复制数据库文件。还原备份速度较快,并且包含索引。唯一问题就是需要数据库锁定,即使在开启journaling的状态下。简单来说就是控制端也许只在内存中执行,并没有对磁盘做出操作,就被复制了。为了保证复制的完备,就需要使用锁定命令。

>use admin

>db.runCommand({fsync:1, lock:true})

确保同步并锁定后,就可以复制当前数据库了。在解锁时,未必能立刻解锁。可用db.currentOp()来查询状态。解锁命令为

>db.$cmd.sys.unlock.findOne()

>("ok":1, "info":"unlock requested")

说完开关锁和备份数据库之后,就该说困扰我的“胖数据”问题了。我使用的db.repairDatabase()命令来修复了我的数据库,空间大小从76G减小到35G,将近一半的空间,可观啊。但问题是时间也比较可观,用了我将近3个小时。书上说对大型数据库要repair的话可能需要几天的时间,所以这是修复受损的最后一道防线。在官网说,开启journaling状态下,理论上永远也不用修复。但是我的64位默认为开启journaling,却还是“越吃越胖”。为了节省时间开销,避免不必要的修复,有专门提供压紧的指令来帮助数据库“减肥”。

>db.runCommand({compact:"spreadsheets"})

若要修复索引

>use cloud-docs

>db.spreadsheets.reIndex()

这里加点说明,压紧或修复是肯定要锁定数据库,所以一般是在从节点上执行compact,之后可以将主节点降级,然后进行修复。如果想要强行在主节点锁死压紧,可以使用force.

>db.runCommand({compact:"spreadsheets",force:true})

这里对目前遇到的修复问题作了一次总结与说明,但是对journaling还有待研究。曾经把它写入log并可以type出来,但是有一次长时间运行后崩溃了。倒出了日志,并禁止写入就又可以运行。所以初步猜测对Log的大小可能也会有限制,等有了深入研究后会后续写出。这里先给出一篇链接。
http://www.kchodorow.com/blog/2012/10/04/how-mongodbs-journaling-works/

13/04 补充说明

自写完这篇博客后,在实验中又多次遇到数据库需要整理的情况,所以想试下上面写到的压缩命令。这里找到一个链接介绍了compact命令。
http://learnmongo.com/posts/compacting-a-mongodb-collections/
里面比较了压缩和修复命令的优缺点,例如压缩占用更少的空间、内存,更好的收集碎片等。

> db.yourCollection.runCommand("compact");


但当我调用压缩命令后,数据库在硬盘上的体积并未缩小。可能是这个命令要对collection操作,而直接将一些collection drop()了。最后还是用了repairDatabase,它的对象是db,成功的为数据库减了肥。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: