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

备份和还原MongoDB分片集群数据

2015-03-18 00:26 731 查看
1.使用mongodump备份小量分片集群数据
如果一个分片集群的数据集比较小,可以直接使用mongodump连接到mongos实例进行数据备份。默认情况下,mongodump到非primary的节点进行数据查询。
如:

mongodump --host 192.168.100.200 --port 28018 -d taiwan_game1 -o .

mongorestore --host 192.168.100.200 --port 28018 taiwan_game1


需要注意的是如果使用mongodump的时候不指定库名或者集合名称,mongodump将直接从config server中获取集合数据和分片集群的元数据
mongodump --host 192.168.100.200 --port 28018

mongodump --host 192.168.100.200 --port 28018 -o .
不能使用--oplog参数从mongos获取数据,否则会报错。

can't use 'local' database through mongos
如果要获取集群某一时刻的备份数据,需要停掉整个集群的写操作。

mongodump备份出来的数据不能反映集群中的集合的数据快和数据的分布情况。可以将数据恢复到任何MongoDB实例,或者是单个MongoDB实例,MongoDB Replica Set或者一个新的分片集群。

2.从文件系统快照中备份分片集群数据
如果要备份point-in-time实时集群数据,必须要停止集群中的所有写操作,在生产环境中,只能获取接近实时的数据备份。
1)停掉balancer进程,停止各个shard间数据的均匀分配。

在进行备份之前停掉balancer进程是基本操作,如果在备份的时候没有停掉balancer进程,那么备份出来的数据可能会有重复的或者丢失的情况发生,因为在备份的时候可能会有数据块迁移。
mongos> use config;
switched to db config
mongos> sh.stopBalancer();
Waiting for active hosts...
Waiting for the balancer lock...
Waiting again for active hosts after balancer is off...


2)锁定每个分片中的每个replica set中的一个Secondary成员。所以这时备份的数据可以最接近某一个的实时数据。使用db.fsyncLock()将所有挂起的写操作数据刷新到磁盘然后锁定mongodb实例。

3)备份其中一个config server数据。备份config server的数据就是备份整个集群的元数据。只需要备份其中一个的数据就行,因为每个config server的数据都是一样的。
可以使用以下两种方式备份:

A.创建一个文件系统快照。参见 Backup and Restore with Filesystem Snapshots
B.使用mongodump备份config server数据。
连接到其中一台config server

mongodump --host 192.168.100.65 --port 28018 --oplog  -o .


4)备份锁定的Replica Set成员数据。 Backup and Restore with Filesystem Snapshots.
5)解锁被锁定的Replica Set成员。使用db.fsyncUnlock()

6)重新启动balancer进程

mongos> use config;
switched to db config
mongos> sh.setBalancerState(true);


3.使用Database Dumps备份集群数据
以下步骤将先停掉balancer进程,然后备份config server的数据,然后使用mongodump备份每个shard的数据。如果需要某一个时刻的准确数据,就需要停掉应用的写操作。否则,只能备份接近实时的数据。
1)停掉balancer进程
mongos> use config;
switched to db config
mongos> sh.getBalancerState();
true
mongos> sh.stopBalancer();
Waiting for active hosts...
Waiting for the balancer lock...
Waiting again for active hosts after balancer is off...
mongos> sh.getBalancerState();
false
mongos>
2)锁定每个shard的replica set的一个secondary成员.关掉每个replica set的一个secondary成员。确保这些secondary的oplog的大小足够使他们在备份数据完成以后可以同步到Primary的数据

使用db.shutdownServer()关掉实例

taiwan_shard1:SECONDARY> use admin;
switched to db admin
taiwan_shard1:SECONDARY> db.shutdownServer();
Thu Mar 19 02:15:22.815 DBClientCursor::init call() failed
server should be down...
Thu Mar 19 02:15:22.816 trying reconnect to 127.0.0.1:28018
Thu Mar 19 02:15:22.816 reconnect 127.0.0.1:28018 failed couldn't connect to server 127.0.0.1:28018
>
Thu Mar 19 02:15:24.083 trying reconnect to 127.0.0.1:28018
Thu Mar 19 02:15:24.083 reconnect 127.0.0.1:28018 failed couldn't connect to server 127.0.0.1:28018


3)备份其中一个config server的数据。
mongodump --host 192.168.100.64 --port 28018 --oplog


4)使用mogodump备份被关掉的Secondary成员

mongodump --journal --dbpath /data/app_data/mongodb/data2822/game/ --out .


5)重新启动被关掉的Secondary成员

6)重新启动balancer进程

mongos> use config;
switched to db config
mongos> sh.getBalancerState();
false
mongos> sh.startBalancer();
mongos> sh.getBalancerState();
true


4.调整分片集群备份窗口时间

在一个分片集群中,balancer进程负责集群中分片数据在均匀分布在每个分片上。但是在作备份操作时,需要确保停掉balancer进程,以免当备份时还有数据块在迁移。可以设置一个备份窗口时间用于自动化备份操作,在这个时间段内,balancer进程一直处于停止状态。

mongos> use config;
switched to db config
mongos> db.settings.update( { _id : "balancer" }, { $set : { activeWindow : { start : "6:00", stop : "23:00" } } }, true );


设置balancer进程从6点开始运行,晚上23点停止,其余的时间段可以用来作备份操作。

5.恢复单个分片数据
总是将分片集群作为一个整体来恢复数据。当恢复单个分片数据的时候,牢记balancer进程可能从上次备份后已经从这个分片上移走数据快或者从其他分片移动数据块到这个分片上。如果有这种情况发生,需要手动移动这些数据块,按照以下的步骤执行:
1)恢复这个分片的数据
2)对于那些从这个分片移走的数据块不需要做任何操作。不需要删除这个分片上已经被移走的文档,因为mongos会自动过滤数据块。
3)对于那些在最近一次备份后移动到这个分片的数据块,必须手动从其他分片备份中恢复。判断有哪些数据块移动了,可以查看conifg数据块的changelog 集合。

6.恢复分片集群数据
1)停掉所有的mongos和mongod进程

2)恢复每个分片中的每个服务器的数据文件和每个config server的数据文件
3)重新启动所有的config server
4)如果分片名称有变更,执行以下操作:

a.启动一个mongos实例,启动之前更新新的configdb参数指定的字符串
b.更新config库的shards集合
c.停掉mongos实例
5)重新启动所有的分片mongod实例

6)重新启动所有的mongos实例,启动之前更新正确的configdb
7)连接到一个mongos实例,确保集群可用。db.printShardingStatus();

本文出自 “Linux SA John” 博客,请务必保留此出处http://john88wang.blog.51cto.com/2165294/1621654
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: