一、背景
作为NoSQL的优秀代表-mongodb数据库,在很多互联网公司得到广泛应用,不同的公司,mongodb数据量从几个GB到几个TB不等。无论数据量大小,都面临一个同样的问题:备份。
目前,常用的mongodb备份方案如下:
1)mongodump/mongoexport备份
这是mongodb官方提供的工具,属于逻辑备份,适合于数据量不大的情况(比如<50GB),在数据量比较大的情况下显得力不从心。
2)冷备份
所谓冷备份,就是停止mongodb服务,拷贝数据文件。优点是备份速度快,缺点是:需要停止服务,对应用服务影响比较大;在高并发情况下,可能无法追上同步。
如果为了不影响应用服务,专门部署一个备份节点,缺点也很明显:资源浪费。
那么,有没有mongodb在线热备份(物理备份)的方法呢?有,这就是createBackup,接下来详细探讨一下。
二、MongoDB HotBackup
1)mongodb版本
首先说明一点,mongodb官方版本不支持hot backup,percona mongodb 3.2及以上版本开始支持。本文使用的是percona mongodb 3.2.17版本,建议使用percona mongodb3.2最新版本。
2)存储引擎
percoan mongodb 3.2支持多种引擎,包括WiredTiger、mmapv1、rocksdb、inMemory、PerconaFT等,其中,WiredTiger和rocksdb支持hot backup操作,实现在线热备份;mmapv1库级锁,不建议使用;PerconaFT接下来会被废弃,不建议使用
建议:根据具体场景,选择WiredTiger或者rocksdb引擎。
3)备份类型
createBackup备份属于物理备份,备份mongodb的数据文件。
说明:此处的物理备份不包括mongodb配置文件,keyFile等,需要用户自行备份。
4)热备命令
下载软件包:
centos 6.x:
centos 7.x:
解压生成mongodb二进制文件目录,不需要编译安装,然后启动mongod,执行:
1 2 |
> use admin > db.runCommand({createBackup: 1,backupDir: "<backupDir>"}) |
建议:在mongodb副本集的secondary节点上执行上述命令,并且,backupDir目录可以为空或者不存在,mognodb会自行创建,如果该目录已经存在备份文件,此次备份可能失败报错。
备份创建的所有文件均位于backupDir目录下,如图所示:
5)备份粒度
该操作会备份整个mongodb实例,包括系统db文件、WT引擎文件和用户db文件
不支持单个db级别的备份。
6)恢复数据
备份文件可以用于恢复数据,也可以用于做从库。
把备份文件连同mongodb配置文件等放置于mongodb数据目录下,然后启动mongodb服务。如果是做从库,可以在mongodb副本集主库里执行rs.add(“<ip1>:<port1>”)。ip1是恢复节点的IP,port1是恢复节点的端口。
三、备份原理探讨
主要源文件:
backup_commands.cpp
wiredtiger_kv_engine.cpp
1、mongodb调用文件系统API,验证backupDir参数设置
如果backupDir不是绝对路径,那么报错退出;否则自动创建该目录;如果该目录已经存在备份文件,那么报错退出。
2、刷新wt文件
调用函数:WiredTigerKVEngine::flushAllFiles
将文件cache信息刷新到磁盘上
3、执行热备操作
在backupDir创建journal文件夹
在新的session开启backupcursor;需要获取CHECKPOINT LOCK、SCHEMA LOCK、HOT_BACKUP LOCK;hot backup是单线程,同一时间内,只能有一个hot backup在执行。
3.3 拷贝目录中的所有文件
此处的目录包括mongodb数据目录(dbpath)下的目录,包括admin、local、以业务db命名的目录。
如果目标路径backupDir不存在这些目录,自动创建。
4、拷贝存储引擎元信息文件storage.bson WiredTiger
5、备份结束,释放LOCK
以上是hot backup大致过程,也是笔者对mongodb hot backup的一个初步探索,仅供参考,欢迎交流。
四、总结
和MySQL在线热备类似,createBackup备份同样涉及到LOCK操作,对应用服务还是有一点影响的,所以,建议在流量低峰期(比如夜间或者凌晨)在secondary节点执行备份,最大限度降低对业务的影响。
原文公众号: EKX技术俱乐部