mongodb备份与恢复(下)—ttlsa教程系列之mongodb(九)
来源:互联网 发布:安卓graviboard软件 编辑:程序博客网 时间:2024/05/29 14:43
一. 适用于mongodb任何架构(standalon、replic set、sharding)备份脚本
需要安装perl的MongoDB模块,安装方法参见:使用cpanm安装perl相关模块 http://www.ttlsa.com/html/2030.html 。代码这东西,仁者见仁智者见智,一分价钱一分货,所以对于优秀的程序员不要抠门。对语言的熟练度高,编程经验丰富的程序员,写出来的代码,两个字:漂亮!
下面的脚本只需更改变量$mongodb相关参数即可,如有更好的更便捷的方法请赐教。
#!/bin/perl
#################################
### author: www.ttlsa.com ###
### QQ群:
39514058
###
### E-mail: service@ttlsa.com ###
#################################
use
strict;
use
File::Path;
use
POSIX;
use
MongoDB;
use
Data::Dumper;
my $mongodump=
'/usr/local/mongodb/bin/mongodump'
;
my $mongodb={
'admin_1'
=>{ #定义组别
'email'
=>
'39514058@qq.com'
, #定义备份出错时邮件通知地址,此处未包含该功能。
'server'
=>[ #定义mongodb相关信息
{
'replset'
=>
1
, #是否复制集
'sharding'
=>
0
, #是否分片
'setname'
=>
"TTLSA_COM"
, #复制集名称
'mongodsvr'
=>[
"10.1.11.155:27017"
,
"10.1.11.156:27017"
,
"10.1.11.157:27017"
], #mongod服务器IP和端口号
'configsvr'
=>[], #config server服务器IP和端口号
'mongossvr'
=>[], #mongos server服务器IP和端口号
'backupdir'
=>
"/data/backup/mongodb_ttlsa_com"
, #备份目录
'user'
=>
""
, #用户名
'passwd'
=>
""
, #密码
'interval'
=>
15
, #备份轮滚周期
},
{
'replset'
=>
1
,
'sharding'
=>
1
,
'setname'
=>
"shard1"
,
'mongodsvr'
=>[
"10.1.22.21:27029"
,
"10.1.22.22:27029"
,
"10.1.22.23:27029"
],
'configsvr'
=>[
"10.1.22.21:27028"
,
"10.1.22.22:27028"
,
"10.1.22.23:27028"
],
'mongossvr'
=>[
"10.1.22.21:27027"
,
"10.1.22.22:27027"
,
"10.1.22.23:27027"
],
'backupdir'
=>
"/data/backup/mongodb_shard1"
,
'user'
=>
""
,
'passwd'
=>
""
,
'interval'
=>
15
,
},
{
'replset'
=>
0
,
'sharding'
=>
0
,
'setname'
=>
"shard1"
,
'mongodsvr'
=>[
"10.1.27.22:30000"
,
"10.1.27.22:30001"
,
"10.1.20.16"
],
'configsvr'
=>[],
'mongossvr'
=>[],
'backupdir'
=>
"/data/backup/mongodb_standalon"
,
'user'
=>
"root"
,
'passwd'
=>
"www.ttlsa.com"
,
'interval'
=>
15
,
}
]},
#
'admin_2'
=>{}
};
while
(my($group,$value)=
each
(%$mongodb)){
foreach my $node (@{$value->{
'server'
}}){
my $tmp_stdout = tmpnam();
my $tmp_stderr = tmpnam();
if
($node->{
'replset'
} && !$node->{
'sharding'
}){
my $dir = $node->{
'backupdir'
};
mkpath $dir unless -e $dir;
my $
return
=backup_rotate($dir,$node->{
'interval'
});
my $hosts = $node->{
'setname'
}.
'/'
.join(
','
, @{$node->{
'mongodsvr'
}});
if
(($node->{
'user'
} ne
''
) && ($node->{
'passwd'
} ne
''
)){
my $retval=system(
"$mongodump -vvvvv -h $hosts -u $node->{'user'} -p $node->{'passwd'} --oplog -o $dir/dump.1 >$tmp_stdout 2>$tmp_stderr"
);
}
else
{
my $retval=system(
"$mongodump -vvvvv -h $hosts --oplog -o $dir/dump.1 >$tmp_stdout 2>$tmp_stderr"
);
}
}elsif($node->{
'sharding'
}){
my $mongod_hosts=$node->{
'setname'
}.
'/'
.join(
','
, @{$node->{
'mongodsvr'
}});
my $mongos_hosts=$node->{
'setname'
}.
'/'
.join(
','
, @{$node->{
'mongossvr'
}});
my $mongod_dir = $node->{
'backupdir'
}.
'/'
.
'mongodsvr'
;
my $config_dir = $node->{
'backupdir'
}.
'/'
.
'configsvr'
;
mkpath $mongod_dir unless -e $mongod_dir;
mkpath $config_dir unless -e $config_dir;
my $
return
=backup_rotate($mongod_dir,$node->{
'interval'
});
my $
return
=backup_rotate($config_dir,$node->{
'interval'
});
if
(($node->{
'user'
} ne
''
) && ($node->{
'passwd'
} ne
''
)){
my $conn = MongoDB::Connection->
new
(
"host"
=>
"mongodb://$mongos_hosts"
,
"db_name"
=>
"admin"
,
"username"
=>
"$node->{'user'}"
,
"password"
=>
"$node->{'passwd'}"
);
my $db = $conn->get_database(
'config'
);
my $coll=$db->get_collection(
'settings'
);
my $ret=$coll->update({ _id =>
"balancer"
}, {
'$set'
=> {
'stopped'
=>
'true'
} },{
'false'
},{
'true'
});
my $retval=system(
"$mongodump -h $mongos_hosts -u $node->{'user'} -p $node->{'passwd'} --db config -o $config_dir/dump.1 >$tmp_stdout 2>$tmp_stderr"
);
my $retval=system(
"$mongodump -h $mongod_hosts -u $node->{'user'} -p $node->{'passwd'} --oplog -o $mongod_dir/dump.1 >$tmp_stdout 2>$tmp_stderr"
);
my $ret=$coll->update({ _id =>
"balancer"
}, {
'$set'
=> {
'stopped'
=>
'false'
} },{
'false'
},{
'true'
});
}
else
{
my $conn = MongoDB::Connection->
new
(
"host"
=>
"mongodb://$mongos_hosts"
);
my $db = $conn->get_database(
'config'
);
my $coll=$db->get_collection(
'settings'
);
my $ret=$coll->update({ _id =>
"balancer"
}, {
'$set'
=> {
'stopped'
=>
'true'
} },{
'false'
},{
'true'
});
my $retval=system(
"$mongodump -h $mongos_hosts --db config -o $config_dir/dump.1 >$tmp_stdout 2>$tmp_stderr"
);
my $retval=system(
"$mongodump -h $mongod_hosts --oplog -o $mongod_dir/dump.1 >$tmp_stdout 2>$tmp_stderr"
);
my $ret=$coll->update({ _id =>
"balancer"
}, {
'$set'
=> {
'stopped'
=>
'false'
} },{
'false'
},{
'true'
});
}
}
else
{
foreach my $
each
(@{$node->{
'mongodsvr'
}}){
my $dir = $node->{
'backupdir'
}.
'/'
.$
each
;
mkpath $dir unless -e $dir;
my $
return
=backup_rotate($dir,$node->{
'interval'
});
if
(($node->{
'user'
} ne
''
) && ($node->{
'passwd'
} ne
''
)){
my $retval=system(
"$mongodump -h $each -u $node->{'user'} -p $node->{'passwd'} -o $dir/dump.1 >$tmp_stdout 2>$tmp_stderr"
);
}
else
{
my $retval=system(
"$mongodump -h $each -o $dir/dump.1 >$tmp_stdout 2>$tmp_stderr"
);
}
}
}
}
}
sub backup_rotate {
my $backup_dir=shift;
my $retral=shift;
my @aa=sort{$b<=>$a}
1
..$retral;
if
(chdir
"/$backup_dir"
){
for
my $num (@aa){
my $old=$num+
1
;
if
(-e
"dump.$num"
){
if
(-e
"dump.$old"
){
system(
"rm -rf dump.$old && mv dump.$num dump.$old"
);
}
else
{
system(
"mv dump.$num dump.$old"
);
}
}
}
}
else
{
return
"Failed to change dir $backup_dir : $!"
;
}
}
二. MongoDB增量备份方法
上一篇《mongodb备份与恢复(上)》http://www.ttlsa.com/html/1938.html 说到的方法都需要拷贝所有数据,即使数据发生很少的改变。如果数据量很大的话,备份整个数据库将消耗更多的时间和磁盘空间。这时增量备份将会是个必然的选择,记录前一次的完整备份点,后续的备份只备份从该点发生改变的数据。
这种方法需要一台专门的备份服务器backup_server,当然backup_server需要一个完整的备份,然后通过mongooplog工具来拷贝并应用mongodb_server的oplog日志。
在mongodb_server上执行以下操作:
> op = db.oplog.rs.find().sort({$natural: -
1
}).limit(
1
).next();
> start = op[
'ts'
][
't'
]/
1000
在backup_server上执行:
# mongooplog --from A --seconds SECOND
SECOND值位于start值与当前时间之间。
mongooplog工具介绍:
mongooplog从远程拉取oplog日志并应用。
# ./mongooplog --help
--help 显示帮助信息
-v [ --verbose ] 打印出更多信息,如时间等等 -vvvvv
--version 打印版本信息
-h [ --host ] arg 指定连接的mongodb主机,复制集时设置为<
set
name>/s1,s2
--port arg 指定mongodb端口号,也可以这么指定--host hostname:port
--ipv6 启用支持IPv6
-u [ --username ] arg 用户名
-p [ --password ] arg 密码
--dbpath arg 直接访问mongod的数据库文件,而不是连接到mongodb服务器。需要锁定数据目录,如果mongod当前在访问相同路径将不能使用。也就是说,mongod运行的情况下不能使用--dbpath,mongod未运行的情况下可以直接指定--dbpath
--directoryperdb 每个db一个单独的目录,需要指定dbpath
--journal 启用journaling
-d [ --db ] arg 指定数据库
-c [ --collection ] arg 指定集合(some commands)
-f [ --fields ] arg 逗号分隔的列名,如-f name,age
--fieldFile arg file
with
fields names -
1
per line
-s [ --seconds ] arg seconds to go back
default
:
86400
--from arg host to pull from
--oplogns arg (=local.oplog.rs) ns to pull from
三. 10gen发布MongoDB增量备份服务
提供支持按照指定时间点恢复的持续增量备份功能, 不过需要支付的。
提供的特性有:mongodb备份与恢复(下)
1. 用于数据传输的SSL加密
2. 高可用性
3. 指定时间点恢复
4. 支持分片集群
5. 较低的开销
工作原理:
是一个轻量级代理,它从所有正在备份的副本集合中收集oplog,将其压缩并加密,然后通过SSL发送到运行备份服务的数据中心。
此方法的好处有:
1. 数据是增量备份的,因此传输的数据相对较小
2. 备份服务中的数据与主系统中的数据在时间上非常接近
3. 对主系统的影响不会比向副本集合中添加另一个副本大(后者非常缓慢, 可先恢复到最新备份状态,然后在加入集群中同步)
4. oplog支持将副本集合恢复到任意时间点。
有两个备份选项:快照和自定义快照。
备份服务依据一套策略创建和维持备份快照。这些快照中的任何一个都可以用于恢复。同样的,用户也可以指定一个自己希望使用的精确时间点创建一份快照。在这种情况下,将使用该时间点之前最新的快照,并会根据用户指定的时间点应用oplog。
上篇《mongodb备份与恢复(上)》 http://www.ttlsa.com/html/1938.html
- mongodb备份与恢复(下)—ttlsa教程系列之mongodb(九)
- mongodb架构mongodb分片集群与简易搭建方案—ttlsa教程系列之mongodb(六)
- mongodb架构mongodb分片集群与简易搭建方案---ttlsa教程系列之mongodb
- ttlsa教程系列之mongodb——(五)mongodb架构-复制原理&复制集
- MongoDB之备份与恢复
- mongodb备份与恢复
- MongoDB备份与恢复
- MongoDB备份与恢复
- mongodb备份与恢复
- mongodb备份与恢复
- MongoDB备份与恢复
- mongodb备份与恢复
- mongodb备份与恢复
- mongoDB备份与恢复
- mongodb 备份与恢复
- MongoDB -- 备份与恢复
- MongoDB备份与恢复
- mongodb备份与恢复
- RippleView(波纹按钮)的效果实现
- 燎原之星星火种
- CM12.1源码编译并刷机到三星N5100
- ios6方向旋转问题
- Android Bander设计与实现 - 设计篇
- mongodb备份与恢复(下)—ttlsa教程系列之mongodb(九)
- rbac权限设计思路
- [leetcode] 132.Palindrome Partitioning II
- hdu4497 GCD and LCM
- JSP页面中预览本地图片
- 暑假期望和学习
- Light OJ 1049 - One Way Roads (暴力 or DFS)
- Redis_conf配置文件说明
- c++ 常量指针 const*const