mongoDB的备份
这里例举一些关于 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/mongoexport | mongodump/mongorestore | |
---|---|---|
主要用途 | 小规模的或部分的Mongo的数据的,测试期间的数据备份/恢复 | 简单且高效的小型的MongoDB的数据库的备份/恢复 |
导出格式 | json | bson |
额外说明 | 导出数据时使用严格模式仅支持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 4月 19 11:27 2021-04-19T03:27:02Z.pbm.json
-rw-rw-r-- 1 pbm pbm 19K 4月 19 11:27 2021-04-19T03:27:02Z_xuehui.dump.s2
-rw-rw-r-- 1 pbm pbm 881 4月 19 11:27 2021-04-19T03:27:02Z_xuehui.oplog.s2
-rw-rw-r-- 1 pbm pbm 26K 4月 19 11:29 2021-04-19T03:29:21Z_xuehui.dump.gz
-rw-rw-r-- 1 pbm pbm 823 4月 19 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: 如果目的库表存在,是否先删除目的库再进行同步。
以上便是大致的调研情况,后续有修改或其它方案再罗列分享出来!