mongodb fsync和锁 从属备份
2014-02-21 14:36
239 查看
fsync和锁
通过fsync和锁可以在MongoDB运行时,安全有效地使用复制数据目录的方式进行备份!fsync命令会强制服务器将所有缓冲区内容写入到磁盘!通过上锁,可以阻止数据库的进一步写入!下面演示具体做法:
[javascript] view
plaincopy
> use admin;
switched to db admin
> db.runCommand({"fsync" : 1, "lock" : 1});
{
"info" : "now locked against writes, use db.fsyncUnlock() to unlock",
"seeAlso" : "http://www.mongodb.org/display/DOCS/fsync+Command",
"ok" : 1
}
>
注意运行fsync命令需要在admin数据库下进行!通过执行上述命令,缓冲区内数据已经被写入磁盘数据库文件中,并且数据库此时无法执行写操作(写操作阻塞)!这样,我们可以很安全地备份数据目录了!备份后,我们通过下面的调用,来解锁:
[javascript] view
plaincopy
> use admin;
switched to db admin
> db.$cmd.sys.unlock.findOne();
{ "ok" : 1, "info" : "unlock completed" }
> db.currentOp();
{ "inprog" : [ ] }
>
在admin数据库下解锁。通过执行db.currentOp()来确认解锁成功!通过fsync和写入锁的使用,可以非常安全地备份实时数据,也不用停止数据库服务。但其弊端就是,在备份期间,数据库的写操作请求会阻塞!
从属备份
上面提到的备份技术已经非常灵活,但默认都是指直接在主服务器上进行!MongoDB更推荐备份工作在从服务器上进行!从服务器上的数据基本上和主服务器是实时同步的,并且从服务器不在乎停机或写阻塞!所以我们可以利用上述3种方式的任意一种在从服务器上进行备份操作!
Master-Slave
主从复制模式:即一台主写入服务器,多台从备份服务器。从服务器可以实现备份,和读扩展,分担主服务器读密集时压力,充当查询服务器。但是主服务器故障时,我们只能手动去切换备份服务器接替主服务器工作。这种灵活的方式,使扩展多如备份或查询服务器相对比较容易,当然查询服务器也不是无限扩展的,因为这些从服务器定期在轮询读取主服务器的更新,当从服务器过多时反而会对主服务器造成过载。
我们以之前创建的端口为27017做为主服务器,再创建个端口为27018从服务器
重新启动27017为主服务器 --master 主服务器
....bin>mongod --dbpath "C:\Program Files\mongodb\data\dbs\master" --master
创建27018为从服务器 --slave 从服务器 --source 指定主服务器
....bin>mongod --port 27018 --dbpath "C:\Program Files\mongodb\data\dbs\slave27018" --slave --source localhost:27017
主服务器可以通过自己local库的slave集合查看从服务器列表
从服务器可以通过自己local库的source集合查看主服务器信息或维护多个主服务器。 (一个slave服务器可以服务多个master服务器)
或者我们可以通过http console查看状态
Replica Sets
副本集模式:具有Master-Slave模式所有特点,但是副本集没有固定的主服务器,当初始化的时候会通过多个服务器投票选举出一个主服务器。当主服务器故障时会再次通过投票选举出新的主服务器,而原先的主服务器恢复后则转为从服务器。Replica Sets的在故障发生时自动切换的机制可以极时保证写入操作。
创建多个副本集节点 --replSet (注意要区分大小写,官方建议命名空间使用IP地址)
....bin>mongod --dbpath "C:\Program Files\mongodb\data\dbs\replset27017" --port 27017 --replSet replset/127.0.0.1:27018
....bin>mongod --dbpath "C:\Program Files\mongodb\data\dbs\replset27018" --port 27018 --replSet replset/127.0.0.1:27017
....bin>mongod --dbpath "C:\Program Files\mongodb\data\dbs\replset27019" --port 27019 --replSet replset/127.0.0.1:27017
首先建立3个是为了投票不会冲突,当服务器为偶数时可能会导致无法正常选举出主服务器。
其次上面3个replset 节点没有全部串联起来,是因为replset 有自检测功可以自动搜索连接其它服务器。
完成上面的工作后,要初始化副本集,随便连接一台服务器执行以下命令 (priority 0~1,被选为主服务器的优先级)
>use admin
>db.runCommand(
{"replSetInitiate":{
"_id":"replset",
"members":[
{
"_id":1,
"host":"127.0.0.1:27017",
"priority":1
},
{
"_id":2,
"host":"127.0.0.1:27018",
"priority":1
},
{
"_id":3,
"host":"127.0.0.1:27019",
"priority":1
}]}}
)
查看结果,可以看出127.0.0.1:27017 被自动选为replSet:Primary>
在增加一个从服务器节点
....bin>mongod --dbpath "C:\Program Files\mongodb\data\dbs\replset27020" --port 27020 --replSet replset/127.0.0.1:27017
通过rs.add命令往system.replset添加新的从服务器成员
rs.add("127.0.0.1:27020"); 或者rs.add({"_id":4,"host":"127.0.0.1:27020"})
这里在简单的介绍一下Master Slave/ Replica Sets 备份机制,这两种模式都是基于主服务器的oplog 来实现所有从服务器的同步。
oplog记录了增删改操作的记录信息(不包含查询的操作),但是oplog有大小限制,当超过指定大小,oplog会清空之前的记录,重新开始记录。
Master Slave方式主服备器会产生 oplog.$main 的日志集合。
Replica Sets 方式 所有服务器都会产生oplog.rs 日志集合。
两种机制下,所有从服务器都会去轮询主服务器oplog日志,若主服务器的日志较新,就会同步这些新的操作记录。但是这里有个很重要的问题,从服务器由于网络阻塞,死机等原因无法极时同步主服务器oplog记录:一种情况 主服务器oplog不断刷新,这样从服务器永远无法追上主服务器。另外一种情况,刚好主服务器oplog超出大小,清空了之前的oplog,这样从服务器就与主服务器数据就可能会不一致了,这第二种情况,我是推断的,没有证实。
另外要说明一下Replica Sets 备份的缺点,当主服务器发生故障时,一台从服务器被投票选为了主服务器,但是这台从服务的oplog 如果晚于之前的主服务器oplog的话,那之前的主服务器恢复后,会回滚自己的oplog操作和新的主服务器oplog保持一致。由于这个过程是自动切换的,所以在无形之中就导致了部分数据丢失。
【修复】
做备份是为了以备不测,比如停电,或自然灾害等,不管怎样,数据是安全的!但总有一些意外情况:不测发生了,但我们还没来得及备份!这时数据目录中的数据可能出于损毁状态,如果在这样的数据目录上启动服务,MongoDB会给出特定的提示!MongoDB提供了修复数据目录的启动方式,就是在启动服务时使用选项--repair。修复过程就是,将所有的文档导出后立即导入,忽略无效的错误文档。并且需要将所有的索引重新建立!修复后,我们重新启动服务即可!
对于大数据量的数据库,恢复是一个非常耗时的操作!因为所有数据都需要验证,并且所有索引都需要重新建立!
Shell中通过调用db.repairDatabase()可以在数据库服务运行时修复特定的数据库(也可通过运行命令的方式进行,命令参数为:{"repairDatabase" :1})!
修复数据库是万不得已才进行的,最佳实践是经常备份数据库,并且利用数据库的复制功能(马上会讲到)来实现故障恢复!
通过fsync和锁可以在MongoDB运行时,安全有效地使用复制数据目录的方式进行备份!fsync命令会强制服务器将所有缓冲区内容写入到磁盘!通过上锁,可以阻止数据库的进一步写入!下面演示具体做法:
[javascript] view
plaincopy
> use admin;
switched to db admin
> db.runCommand({"fsync" : 1, "lock" : 1});
{
"info" : "now locked against writes, use db.fsyncUnlock() to unlock",
"seeAlso" : "http://www.mongodb.org/display/DOCS/fsync+Command",
"ok" : 1
}
>
注意运行fsync命令需要在admin数据库下进行!通过执行上述命令,缓冲区内数据已经被写入磁盘数据库文件中,并且数据库此时无法执行写操作(写操作阻塞)!这样,我们可以很安全地备份数据目录了!备份后,我们通过下面的调用,来解锁:
[javascript] view
plaincopy
> use admin;
switched to db admin
> db.$cmd.sys.unlock.findOne();
{ "ok" : 1, "info" : "unlock completed" }
> db.currentOp();
{ "inprog" : [ ] }
>
在admin数据库下解锁。通过执行db.currentOp()来确认解锁成功!通过fsync和写入锁的使用,可以非常安全地备份实时数据,也不用停止数据库服务。但其弊端就是,在备份期间,数据库的写操作请求会阻塞!
从属备份
上面提到的备份技术已经非常灵活,但默认都是指直接在主服务器上进行!MongoDB更推荐备份工作在从服务器上进行!从服务器上的数据基本上和主服务器是实时同步的,并且从服务器不在乎停机或写阻塞!所以我们可以利用上述3种方式的任意一种在从服务器上进行备份操作!
Master-Slave
主从复制模式:即一台主写入服务器,多台从备份服务器。从服务器可以实现备份,和读扩展,分担主服务器读密集时压力,充当查询服务器。但是主服务器故障时,我们只能手动去切换备份服务器接替主服务器工作。这种灵活的方式,使扩展多如备份或查询服务器相对比较容易,当然查询服务器也不是无限扩展的,因为这些从服务器定期在轮询读取主服务器的更新,当从服务器过多时反而会对主服务器造成过载。
我们以之前创建的端口为27017做为主服务器,再创建个端口为27018从服务器
重新启动27017为主服务器 --master 主服务器
....bin>mongod --dbpath "C:\Program Files\mongodb\data\dbs\master" --master
创建27018为从服务器 --slave 从服务器 --source 指定主服务器
....bin>mongod --port 27018 --dbpath "C:\Program Files\mongodb\data\dbs\slave27018" --slave --source localhost:27017
主服务器可以通过自己local库的slave集合查看从服务器列表
从服务器可以通过自己local库的source集合查看主服务器信息或维护多个主服务器。 (一个slave服务器可以服务多个master服务器)
或者我们可以通过http console查看状态
Replica Sets
副本集模式:具有Master-Slave模式所有特点,但是副本集没有固定的主服务器,当初始化的时候会通过多个服务器投票选举出一个主服务器。当主服务器故障时会再次通过投票选举出新的主服务器,而原先的主服务器恢复后则转为从服务器。Replica Sets的在故障发生时自动切换的机制可以极时保证写入操作。
创建多个副本集节点 --replSet (注意要区分大小写,官方建议命名空间使用IP地址)
....bin>mongod --dbpath "C:\Program Files\mongodb\data\dbs\replset27017" --port 27017 --replSet replset/127.0.0.1:27018
....bin>mongod --dbpath "C:\Program Files\mongodb\data\dbs\replset27018" --port 27018 --replSet replset/127.0.0.1:27017
....bin>mongod --dbpath "C:\Program Files\mongodb\data\dbs\replset27019" --port 27019 --replSet replset/127.0.0.1:27017
首先建立3个是为了投票不会冲突,当服务器为偶数时可能会导致无法正常选举出主服务器。
其次上面3个replset 节点没有全部串联起来,是因为replset 有自检测功可以自动搜索连接其它服务器。
完成上面的工作后,要初始化副本集,随便连接一台服务器执行以下命令 (priority 0~1,被选为主服务器的优先级)
>use admin
>db.runCommand(
{"replSetInitiate":{
"_id":"replset",
"members":[
{
"_id":1,
"host":"127.0.0.1:27017",
"priority":1
},
{
"_id":2,
"host":"127.0.0.1:27018",
"priority":1
},
{
"_id":3,
"host":"127.0.0.1:27019",
"priority":1
}]}}
)
查看结果,可以看出127.0.0.1:27017 被自动选为replSet:Primary>
在增加一个从服务器节点
....bin>mongod --dbpath "C:\Program Files\mongodb\data\dbs\replset27020" --port 27020 --replSet replset/127.0.0.1:27017
通过rs.add命令往system.replset添加新的从服务器成员
rs.add("127.0.0.1:27020"); 或者rs.add({"_id":4,"host":"127.0.0.1:27020"})
这里在简单的介绍一下Master Slave/ Replica Sets 备份机制,这两种模式都是基于主服务器的oplog 来实现所有从服务器的同步。
oplog记录了增删改操作的记录信息(不包含查询的操作),但是oplog有大小限制,当超过指定大小,oplog会清空之前的记录,重新开始记录。
Master Slave方式主服备器会产生 oplog.$main 的日志集合。
Replica Sets 方式 所有服务器都会产生oplog.rs 日志集合。
两种机制下,所有从服务器都会去轮询主服务器oplog日志,若主服务器的日志较新,就会同步这些新的操作记录。但是这里有个很重要的问题,从服务器由于网络阻塞,死机等原因无法极时同步主服务器oplog记录:一种情况 主服务器oplog不断刷新,这样从服务器永远无法追上主服务器。另外一种情况,刚好主服务器oplog超出大小,清空了之前的oplog,这样从服务器就与主服务器数据就可能会不一致了,这第二种情况,我是推断的,没有证实。
另外要说明一下Replica Sets 备份的缺点,当主服务器发生故障时,一台从服务器被投票选为了主服务器,但是这台从服务的oplog 如果晚于之前的主服务器oplog的话,那之前的主服务器恢复后,会回滚自己的oplog操作和新的主服务器oplog保持一致。由于这个过程是自动切换的,所以在无形之中就导致了部分数据丢失。
【修复】
做备份是为了以备不测,比如停电,或自然灾害等,不管怎样,数据是安全的!但总有一些意外情况:不测发生了,但我们还没来得及备份!这时数据目录中的数据可能出于损毁状态,如果在这样的数据目录上启动服务,MongoDB会给出特定的提示!MongoDB提供了修复数据目录的启动方式,就是在启动服务时使用选项--repair。修复过程就是,将所有的文档导出后立即导入,忽略无效的错误文档。并且需要将所有的索引重新建立!修复后,我们重新启动服务即可!
对于大数据量的数据库,恢复是一个非常耗时的操作!因为所有数据都需要验证,并且所有索引都需要重新建立!
Shell中通过调用db.repairDatabase()可以在数据库服务运行时修复特定的数据库(也可通过运行命令的方式进行,命令参数为:{"repairDatabase" :1})!
修复数据库是万不得已才进行的,最佳实践是经常备份数据库,并且利用数据库的复制功能(马上会讲到)来实现故障恢复!
相关文章推荐
- MongoDB数据备份与恢复
- MongoDB 如何实现备份压缩
- Mongodb定时备份脚本和清除脚本
- mongodb主从备份 和 手动主从切换
- MongoDB数据库的文件备份恢复以及文件导入导出
- mongoDB的基本操作以及数据的导入导出,备份和恢复
- mongodb备份与恢复(下)---ttlsa教程系列之mongodb(九)
- mongodb数据备份还原及主从搭建
- MongoDB 数据库备份脚本
- MongoDB 状态监控、备份复制及自动分片
- mongodb的备份与恢复
- mongodb 数据库操作--备份 还原 导出 导入
- MongoDB备份与恢复
- MongoDB 数据备份 mongodump 和数据恢复mongorestore
- mongodb 数据备份,还原笔记
- mongodb备份、还原
- mongodb的备份与恢复
- Mongodb 远程备份数据
- MongoDB的备份方式
- mongodb 数据备份和恢复