这里例举一些关于 mongoDB备份 的相关资料以供参考,小伙伴可以在此修正或增加其它方案以供学习。

一、常规备份方式

1.1、文件系统快照备份

这种方式较为直接,只需要满足:

  • 1、文件系统本身支持快照技术 。
  • 2、在运行mongod时必须开启日记系统(journaling)。

1.2、复制数据文件备份

这种方式直接copy数据目录文件,但是在copy过程中是需要预防数据文件发生改变的,因此在copy过程中需要对数据库加锁以防止数据写入。

  1 > db.fsyncLock()		 #锁定,将阻塞写入操作,并将脏数据刷新到磁盘上,确保数据一致。   
  2 # cp -R /home/sanyuanse/mongodb/db/*  /backup  #拷贝数据文件到备份目录下。
  3 > db.fsyncUnlock()		    #文件复制完成后,对数据库进行解锁,允许写操作。

【注意】:不要同时使用fsyncLock和mongodump。数据库被锁定可能会使得mongodump永远处于挂起状态,这取决于数据库正在进行的其他操作

1.3、mongodump方式备份

mongoDB内部数据保存用的是bson格式,json是bson的子集,部分数据类型无法用json保存,因此导出为json格式,可能会导致丢失部分复杂类型的数据。官方建议生产环境采用mongodump/mongorestore,相关《官方说明》可以点击此链接查阅,这和我们先前常用的mongoexport/mongoimport是有些区别的,详实如下:

mongoimport/mongoexportmongodump/mongorestore
主要用途小规模的或部分的Mongo的数据的,测试期间的数据备份/恢复简单且高效的小型的MongoDB的数据库的备份/恢复
导出格式jsonbson
额外说明导出数据时使用严格模式仅支持UTF-8编码的数据不适合备份/恢复大型MongoDB数据库,默认是不拷贝local这个(特殊的)数据库
经验/结论不支持普通导出单个db的所有的collection支持普通导出单个db的所有的collection,建议:普通的,简单的,数据的备份和恢复,都还是用mongodump/mongorestore这套工具

1、当想备份单独的数据库、集合甚至集合中的子集时mongodump是个很好的选择。
2、如果运行mongod时使用了–replSet选项,则可使用mongodump的–oplog选项。这会将转储过程中服务器进行的所有操作记录下来,这样在恢复备份时就会重新执行这些操作。这样就可以得到源服务器上某一时间点的数据快照。
3、如果转储数据库时使用了–oplog参数,运行mongorestore时必须使用–oplogReplay选项,以得到某一时间点的快照。

# mongoimport/mongoexport方式
## 导入数据:
./mongoimport --port 27022 -d kas_code -c QCC_QUALITY_RECORD -uroot -p lww123 --authenticationDatabase admin --file /home/sanyuanse/kas/QCC_QUALITY_RECORD.json
## 导出数据:
./mongoexport --port 27022 -d kas_code -c QCC_CODE_LOG -uroot -p kas_2020_roo --authenticationDatabase admin -o /home/sanyuanse/kas/QCC_CODE_LOG.json

# mongodump/mongorestore方式
--备份单个表
mongodump -u  superuser -p 123456  --port 27017 --authenticationDatabase admin -d myTest -c d -o /backup/mongodb/myTest_d_bak_201507021701.bak
--备份单个库
mongodump  -u  superuser -p 123456 --port 27017  --authenticationDatabase admin -d myTest -o  /backup/mongodb/
--备份所有库
mongodump  -u  superuser -p 123456 --authenticationDatabase admin  --port 27017 -o /root/bak 
--备份所有库推荐使用添加--oplog参数的命令,这样的备份是基于某一时间点的快照,只能用于备份全部库时才可用,单库和单表不适用:
mongodump -h 127.0.0.1 --port 27017   --oplog -o  /root/bak 
--同时,恢复时也要加上--oplogReplay参数,具体命令如下(下面是恢复单库的命令):
mongorestore  -d swrd --oplogReplay  /home/mongo/swrdbak/swrd/
--恢复单个库:
mongorestore  -u  superuser -p 123456 --port 27017  --authenticationDatabase admin -d myTest   /backup/mongodb/
--恢复所有库:
mongorestore   -u  superuser -p 123456 --port 27017  --authenticationDatabase admin  /root/bak
--恢复单表
mongorestore -u  superuser -p 123456  --authenticationDatabase admin -d myTest -c d /backup/mongodb/myTest_d_bak_201507021701.bak/myTest/d.bson

二、第三方备份方式

2.1、使用PMH工具备份

参考文档:perconar热备

  • Percona MongoDB HotBackup热备份类似于xtrabackup工具。
  • 在当前dbpath中对数据库进行热备份,请在admin数据库上以管理员身份运行createBackup命令,并指定备份目录。
  • 可以替换一台从库为Percona MongoDB,做备份使用。

备份:
1、首先会启动一个后台检测的进程,实时检测MongoDB Oplog的变化,一旦发现oplog有新的日志写入,立刻将日志写入到日志文件WiredTiger.backup中(你可以strings WiredTiger.backup查看oplog操作日志的变化);
2、复制MongoDB dbpath的数据文件和索引文件到指定的备份目录里
恢复:
1、将WiredTiger.backup日志进行回放,将操作日志变更应用到WiredTiger引擎里,最终得到一致性快照恢复。
2、把备份目录里的数据文件直接拷贝到你的dbpath下,然后启动MongoDB即可,会自动接入副本集集群。

1、环境准备

# 准备
[root@worker02 ~]# yum install -y php-pear php-devel php gcc openssl openssl-devel cyrus-sasl cyrus-sasl-devel
# php-mongo驱动安装
[root@worker02 ~]# pecl install mongo
# 增加参数
[root@worker02 ~]# tail -1 /etc/php.ini
extension=mongo.so
# 创建超级用户权限
> db.createUser({user:"admin",pwd:"lww123",roles:[{role:"root",db:"admin"}]})

2、修改pmongo_bak.php文件配置信息

<?php

/**
 * https://github.com/hcymysql/PMongo-HotBackup
 *
 * UPDATE:
 * 1、在线热备份(物理文件拷贝)替代mongodump逻辑备份导出bson
 *
 * 环境准备: 
 * shell> yum install -y php-pear php-devel php gcc openssl openssl-devel cyrus-sasl cyrus-sasl-devel 
 * shell> pecl install mongo
 * You should add "extension=mongo.so" to php.ini
 */
 
ini_set('date.timezone','Asia/Shanghai');
error_reporting(7);

//*************修改下面的配置信息***************//
$user = "admin"; //使用root用户权限
$pwd = 'lww123'; //密码
$host = '192.168.52.143'; //在从库上热备
$port = '27017'; //端口非默认的话需修改
$authdb = 'admin'; //权限认证数据库
$BAKDIR = "/data/bak/"; //备份目录
$BAKDIR .= date('Y_m_d_H_i_s');


//*************下面的代码不用修改***************//
$m = new MongoBak($user,$pwd,$host,$port,$authdb,$BAKDIR);

Class MongoBak{

    function __construct(){ 
	     $a = func_get_args();
            $f = 'backup';
            call_user_func_array(array($this,$f),$a); 
    }

    function backup($p1,$p2,$p3,$p4,$p5,$p6){
           $this->mkdirs("{$p6}");
	    $mongo = new MongoClient("mongodb://{$p1}:{$p2}@{$p3}:{$p4}/{$p5}");
	    $mongo->setReadPreference(MongoClient::RP_SECONDARY); //如果你想在主库上备份,把这行代码注销掉即可,并把脚本部署在主库上。
           $db = $mongo->admin;
	    echo "\n".date('Y-m-d H:i:s')."    backup is running......\n";
           $r = $db->command(
  	          array(
          	       'createBackup' => 1,
                    'backupDir' => $p6),
     	          array('timeout' => -1)    
	    );

	//print_r($r); //调试备份错误日志使用,如备份失败,打开注释。

	    if($r['ok'] == 1){
  	           echo date('Y-m-d H:i:s')."    backup is success.\n";
	    } else{
      	    echo date('Y-m-d_H:i:s')."    backup is failure.\n";
	    }	
    }
    
    function mkdirs($dir, $mode = 0777){
        if (!is_dir($dir)){
            mkdir($dir, $mode, true);
            chmod($dir, $mode);
            echo "BackupDir : ${dir} is created.\n";
    	}
    }

}

?>

3、运行
不支持远程备份,需将备份脚本部署在从库里。如果你想把数据备份到远程,可以采用NFS等文件系统mount挂载上

[root@worker02 ~]# php pmongo_bak.php
[root@worker02 ~]# crontab -l
00 01 * * * /usr/bin/php /root/php_mongodb/pmongo_bak.php > /root/php_mongodb/bak_status.log 2 >&1

2.2、使用PBM工具备份

pbm是percona公司提供的mongodb的备份恢复工具。

  • 支持版本 > v3.6
  • 底层是调用mongodump/mongorestore进行转储备份
  • 不过目前对分片集群的支持力度较弱,不支持增量备份

1、下载软件,点击软件下载,并安装

[root@worker02 ~]# yum localinstall percona-backup-mongodb-1.4.1-1.el7.x86_64.rpm -y
[root@worker02 ~]# ll /usr/bin/pbm*
-rwxr-xr-x 1 root root 20869248 1月  28 03:16 /usr/bin/pbm
-rwxr-xr-x 1 root root 22789240 1月  28 03:16 /usr/bin/pbm-agent
-rwxr-xr-x 1 root root 21838568 1月  28 03:16 /usr/bin/pbm-speed-test

2、创建备份用户

db.getSiblingDB("admin").createRole({ "role": "pbmAnyAction", "privileges": [ { "resource": { "anyResource": true }, "actions": [ "anyAction" ] } ], "roles": [] });
db.getSiblingDB("admin").createUser({user: "pbmuser", "pwd": "secretpwd", "roles" : [ { "db" : "admin", "role" : "readWrite", "collection": "" }, { "db" : "admin", "role" : "backup" }, { "db" : "admin", "role" : "clusterMonitor" }, { "db" : "admin", "role" : "restore" }, { "db" : "admin", "role" : "pbmAnyAction" } ] });

3、配置PBM_MONGODB_URI

[root@worker02 ~]# cat /etc/sysconfig/pbm-agent
PBM_MONGODB_URI="mongodb://pbmuser:secretpwd@127.0.0.1:27022/?authSource=admin&replicaSet=xuehui"
[root@worker02 ~]# #配置环境变量
[root@worker02 ~]# echo $PBM_MONGODB_URI

4、 配置文件存储
pbm备份的存储类型支持s3存储,远程文件系统服务器,仅单实例或单节点副本集支持本地存储

[root@worker02 ~]# cat /etc/pbm_config.yaml
storage:
  type: filesystem
  filesystem: path: /data/mongodbbackup
[root@worker02 ~]# mkdir -pv /data/mongodbbackup
[root@worker02 ~]# chown -R pbm.pbm /data/mongodbbackup/
[root@worker02 ~]# pbm config --mongodb-uri="mongodb://root:970125@127.0.0.1:27022/test?authSource=admin&replicaSet=xuehui" --file /etc/pbm_config.yaml

5、 启动pbm-agent代理进程

[root@worker02 ~]#  systemctl start pbm-agent
[root@worker02 ~]#  systemctl status pbm-agent

6、相关操作

#备份
[root@worker02 data]# pbm backup
Starting backup '2021-04-19T03:27:02Z'....................
Backup '2021-04-19T03:27:02Z' to remote store '/data/mongodbbackup' has started

[root@worker02 mongodbbackup]# pbm backup --compression=gzip
Starting backup '2021-04-19T03:29:21Z'....................
Backup '2021-04-19T03:29:21Z' to remote store '/data/mongodbbackup' has started

[root@worker02 mongodbbackup]# ll
总用量 60K
-rw-rw-r-- 1 pbm pbm 1.4K 419 11:27 2021-04-19T03:27:02Z.pbm.json
-rw-rw-r-- 1 pbm pbm  19K 419 11:27 2021-04-19T03:27:02Z_xuehui.dump.s2
-rw-rw-r-- 1 pbm pbm  881 419 11:27 2021-04-19T03:27:02Z_xuehui.oplog.s2
-rw-rw-r-- 1 pbm pbm  26K 419 11:29 2021-04-19T03:29:21Z_xuehui.dump.gz
-rw-rw-r-- 1 pbm pbm  823 419 11:29 2021-04-19T03:29:21Z_xuehui.oplog.gz
#备份列表
[root@worker02 mongodbbackup]# pbm list
Backup snapshots:
  2021-04-19T03:27:02Z [complete: 2021-04-19T03:27:23]
  2021-04-19T03:29:21Z [complete: 2021-04-19T03:29:42]
#数据恢复
[root@worker02 mongodbbackup]# pbm restore 2021-04-19T03:27:02Z
...Restore of the snapshot from '2021-04-19T03:27:02Z' has started
#取消备份
[root@worker02 mongodbbackup]# pbm cancel-backup
Backup cancellation has started
#删除备份
[root@worker02 mongodbbackup]# pbm delete-backup 2021-04-19T03:27:02Z
Are you sure you want delete backup(s)? [y/N] y
Waiting for delete to be done ...[done]
Backup snapshots:
  2021-04-19T03:29:21Z [complete: 2021-04-19T03:29:42]
#查看备份恢复日志
[root@worker02 mongodbbackup]# pbm logs --event=backup
[root@worker02 mongodbbackup]# pbm logs --event=restore

7、时间点恢复查看,及PBM状态
针对分片集群的恢复,需要提前关闭balancer,最直接的方式是关闭所有mongos节点

[root@worker02 pbmPitr]# pbm list
Backup snapshots:
	...
PITR <on>:
	...	
[root@worker02 pbmPitr]# pbm status

Cluster:
========
xuehui:
	...

8、PBM的相关集合

admin.pbmBackups-每个备份的日志/状态
admin.pbmAgents-包含有关pbm-agents状态和运行状况的信息
admin.pbmConfig-包含Percona Backup for MongoDB的配置信息
admin.pbmCmd-用于定义和触发操作
admin.pbmLock - pbm代理同步锁定结构
admin.pbmLockOp-用于协调不互斥的操作,例如make备份和delete备份。
admin.pbmLog-pbm-agents在MongoDB环境中存储所有日志信息。从1.4.0版开始的Percona Backup for MongoDB中可用
admin.pbmOpLog-存储操作ID
admin.pbmPITRChunks-存储时间点恢复操作日志片
admin.pbmPITRState-包含时间点恢复增量备份的当前状态
admin.pbmRestores-包含所有副本集的还原历史记录和还原状态
admin.pbmStatus-为Pergoa备份存储MongoDB状态记录

9、Percona Server for MongoDB为默认WiredTiger存储引擎提供了一个集成的开源热备份系统。它在运行中的服务器上创建物理数据备份,而不会造成显著的性能和操作降级。
【要恢复备份,需要停止mongod服务,清理数据目录,然后从中复制备份目录文件到数据目录】

chown mongod:mongod <backupDir>

xuehui:SECONDARY> use admin;
switched to db admin
xuehui:SECONDARY>  db.runCommand({createBackup: 1, archive: "/data/mongodbbackup/archive.tar" })
{
	"ok" : 1,
	"$clusterTime" : {
		"clusterTime" : Timestamp(1615466288, 1),
		"signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0)
		}
	},
	"operationTime" : Timestamp(1615466288, 1)
}

xuehui:SECONDARY> db.runCommand({createBackup: 1, backupDir: "/data/mongodbbackup/"})
{
	"ok" : 1,
	"$clusterTime" : {
		"clusterTime" : Timestamp(1615466303, 2),
		"signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0)
		}
	},
	"operationTime" : Timestamp(1615466303, 2)
}

2.3、mongoshake备份

参考文档:MongoShake帮助说明
1、安装go环境
点击这里下载:GO下载安装包
2、安装go依赖
需要将go安装在家目录下

[root@worker02 go]# echo $GOPATH
/root/go
[root@worker02 github.com]# go get -u -v github.com/kardianos/govendor
#bin目录下生成govender
[root@worker02 vendor]# cd /root/go/src/vendor
[root@worker02 vendor]# govendor sync

3、编译MongoShake

[root@worker02 go]# cd /home/sanyuanse/MongoShake
[root@worker02 MongoShake]# ./build.sh 
[ BUILD RELEASE ]
try build goos=linux
Build collector
...
Build receiver
build linux successfully!
try build goos=darwin
Build collector
Build receiver
build darwin successfully!
try build goos=windows
Build collector
Build receiver
build windows successfully!

二进制安装的话下载:Mongo-shake

4、从MongoDB副本集同步到MongoDB副本集的配置

# collector.conf文件
## 源端连接串信息,逗号分隔不同的mongod
mongo_urls = mongodb://test:test123@192.168.52.128:1001,192.168.52.130:2001,192.168.52.132:3001
## 同步模式,all表示全量+增量同步,full表示全量同步,oplog表示增量同步。
sync_mode = all
## 目的端连接串信息,逗号分隔不同的mongod
tunnel.address = mongodb://test:test123@192.168.52.132:4001,192.168.52.130:5001,192.168.52.128:6001

# receiver.conf文件
## 有rpc、tcp、file、mock、kafka类型
tunnel = rpc
tunnel.address = 127.0.0.1:30033

5、从MongoDB副本集同步到MongoDB集群版的配置

# collector.conf文件
## 源端连接串信息,逗号分隔不同的mongod
mongo_urls = mongodb://test:test123@192.168.52.128:1002,192.168.52.130:2002,192.168.52.132:3002
## 同步模式,all表示全量+增量同步,full表示全量同步,oplog表示增量同步。
sync_mode = all
## 目的端连接串信息是配置mongos,逗号分隔不同的mongos可以实现负载均衡
tunnel.address = mongodb://test:test123@192.168.52.132:2021

6、从MongoDB集群版同步到MongoDB集群版的配置

  • 例如源是2节点
  • 节点1:192.168.52.128:1001, 192.168.52.130:2002, 192.168.52.132:3003
  • 节点2:192.168.54.1:1001, 192.168.54.2:2002, 192.168.54.3:3003
    目的端是sharding
    有多个mongos:192.168.52.132:2021, 192.168.54.132:2022, 192.168.54.133:3033
# collector.conf文件
## 源端连接串信息,逗号分隔同一个shard不同的mongod,分号分隔不同的shard。
mongo_urls = mongodb://test:test123@192.168.52.128:1001,192.168.52.130:2002,192.168.52.132:3003;mongodb://test2:test345@192.168.54.1:1001,192.168.54.2:2002,192.168.54.3:3003
sync_mode = all
## 目的端连接串信息,分号分割不同的mongos。也可以只配置部分,配置多个mongos可以做负载均衡写入。
tunnel.address = mongodb://test2:test345@192.168.52.132:2021;192.168.54.132:2022;192.168.54.133:3033
## 如果源端是sharding,此处需要配置源端sharding的cs的地址
context.storage.url = mongodb://test:test123@192.168.52.128:5555,192.168.52.130:5556 

7、从MongoDB副本集同步到kafka通道的配置

  • 假设源同样是三副本:10.1.1.1:1001, 10.2.2.2:2002, 10.3.3.3:3003
  • 目的kafka:50.1.1.1:6379,topic是test
#源端连接串信息,逗号分隔不同的mongod
mongo_urls = mongodb://username:password@10.1.1.1:1001,10.2.2.2:2002,10.3.3.3:3003
# 如果目的端不是mongodb,仅支持增量同步模式 
sync_mode = oplog 
tunnel.type = kafka
tunnel.address = test@50.1.1.1:6379

相关资料:kafka拉取数据问题FAQ

相关参数注释
  • mongo_urls: 源mongodb的连接地址
  • mongo_connect_mode: 源端连接的模式,有几种模式可选:从seconary拉取;从primary拉取;secondary优先拉取;单节点拉取
  • sync_mode: sync模式,有几种模式可选:全量,增量,全量+增量
  • http_profile: 提供restful接口,用户可以查看一些内部运行情况,也可以对接监控。
  • system_profile: profile端口,可以查看进程运行的堆栈情况。
  • log: log日志相关参数。
  • filter.namespace.black: 黑名单过滤。黑名单内的库表不会被同步,剩下的同步。
  • filter.namespace.white: 白名单过滤。白名单内的库表会被同步,剩下的过滤掉。黑白名单最多只能配置一个,不配置会同步所有库表。
  • filter.pass.special.db: 有些特别的库表会被过滤,如admin,local, config库,如果一定要开启,可以在这里进行配置。
  • oplog.gids: 用于云上双向同步。
  • shard_key: 内部对数据多线程的哈希方式,默认collection表示按表级别进行哈希。
  • worker: 增量阶段并发写入的线程数,如果增量阶段性能不够,可以提高这个配置。
  • worker内部相关配置: worker.batch_queue_size, adaptive.batching_max_size, fetcher.buffer_capacity, 关于内部队列的相关配置,具体请参考github wiki文档。
  • worker.oplog_compressor: 压缩模式,如果是非direct模式开启这个可以减少网络传输的开销。
  • tunnel.address: 目的端对接的地址。
  • context.storage: checkpoint存储的位置,database表示把数据存入MongoDB,api表示把数据存入用户自己提供的http接口。
  • context.storage.url: checkpoint写入到哪个MongoDB,如果源是sharding,此处配置cs地址,checkpoint会写入admin库;如果是副本集,不配置,会默认写入源库,配置则写入配置的库里面。
  • context.address: checkpoint写入的表的名字。
  • context.start_position: checkpoint启动开始拉取的增量时间位点。如果本身checkpoint已经存在(参考上述context的位置),那么则按照context信息进行拉取,如果不存在,则按照这个位点进行增量拉取。
  • master_quorum: 如果以主备模式拉取同一个源,则这个参数需要启用。
  • transform.namespace: 命名空间的转换,a.b:c.d表示把源端a库下面的c表同步到目的端c库下面的d表。
  • replayer.dml_only: 默认不同步DDL,false表示同步DDL。DDL包括建表,删库,建索引等语句。
  • replayer.executor.upsert: 目的端如果update语句对应的主键id不存在,是否将update语句更改为insert语句。
  • replayer.executor.insert_on_dup_update: 目的端如果insert语句对应的主键id已经存在,是否将insert语句更改为update语句。
  • replayer.conflict_write_to: 对于写入冲突的情况,是否需要记录冲突的文档。
  • replayer.durable: 测试选项,false表示取消写入,只用于拉取调试。
  • replayer.collection_parallel: 全量同步按表并发的并发度。
  • replayer.document_parallel: 全量同步同一个表内并发写入的线程数。
  • replayer.document_batch_size: 全量同步一次性batch的大小。
  • replayer.collection_drop: 如果目的库表存在,是否先删除目的库再进行同步。

以上便是大致的调研情况,后续有修改或其它方案再罗列分享出来!

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐