大多数指南建议使用mongodump / mongorestore,但对于大型产品数据库,停机时间可能很长 p>
答案 0 :(得分:1)
如果加载允许,您可以为此服务器或同一服务器使用复制和附加服务器。
您需要运行3个MongoDB实例:
无论如何,您需要备份数据库。您可以在没有参数的情况下运行“ mongodump ”,并且将使用数据库转储创建目录“ ./ dump ”。您可以使用“ - gzip ”参数来压缩结果大小。
mongodump --gzip
以防万一,恢复命令:
mongorestore --gzip
它应该在“ ./ dump ”目录的同一目录中运行,如果在“ mongodump中使用”,则应添加“ - gzip ”参数”
从其他服务器开始配置。我的目标系统是没有Internet的Linux RedHat,所以我手动下载并通过RPM安装MongoDB。将该部分添加到 /etc/mongod.conf :
replication:
oplogSizeMB: 10240
replSetName: REPLICA
检查网段是否允许从其他服务器访问:
net:
bindIp: 0.0.0.0
port: 27017
并运行:
service mongod start
运行第三个MongoDB实例 - 仲裁器。它可以在不同端口上的其他服务器上运行。为仲裁数据库创建一个临时目录:
mkdir /tmp/mongo
chmod 777 -R /tmp/mongo
并运行:
mongod --dbpath /tmp/mongo --port 27001 --replSet REPLICA \
--fork --logpath /tmp/mongo/db1.log
现在配置主服务器。编辑/etc/mongod.conf
replication:
oplogSizeMB: 10240
replSetName: REPLICA
并在主服务器上重启MongoDB:
service mongod restart
这很重要!重新启动主服务器后,读取操作可能不可用。我收到以下错误:
{ "ok" : 0, "errmsg" : "node is recovering", "code" : 13436 }
因此,您需要尽快通过“ mongo ”控制台连接到主服务器上的MongoDB并运行以下命令来配置复制:
rs.initiate(
{
_id: "REPLICA",
members: [
{ _id: 0, host : "<IP address of main server>:27017",
priority: 1.0 },
{ _id: 1, host : "<IP address of additional server>:27017",
priority: 0.5 },
{ _id: 2, host : "<IP address of additional server(the arbiter)>:27001",
arbiterOnly : true, priority: 0.5 }
]
}
)
在此操作之后,MongoDB的所有操作都将可用,并且将启动数据同步。
我不建议在没有参数的主服务器上使用 rs.initiate(),因为在大多数教程中,因为主服务器的名称默认配置为DNS-name来自的/ etc /主机名。这对我来说不太方便,因为我在我的项目中使用IP地址进行通信。
要检查同步进度,您可以从“ mongo ”控制台调用:
rs.status()
结果示例:
{
"set" : "REPLICA",
"date" : ISODate("2017-01-19T14:30:34.292Z"),
"myState" : 1,
"term" : NumberLong(1),
"heartbeatIntervalMillis" : NumberLong(2000),
"members" : [
{
"_id" : 0,
"name" : "<IP address of main server>:27017",
"health" : 1.0,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 165,
"optime" : {
"ts" : Timestamp(6377323060650835, 3),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2017-01-19T14:30:33.000Z"),
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(6377322974751490, 1),
"electionDate" : ISODate("2017-01-19T14:30:13.000Z"),
"configVersion" : 1,
"self" : true
},
{
"_id" : 1,
"name" : "<IP address of additional server>:27017",
"health" : 1.0,
"state" : 5,
"stateStr" : "STARTUP2",
"uptime" : 30,
"optime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("1970-01-01T00:00:00.000Z"),
"lastHeartbeat" : ISODate("2017-01-19T14:30:33.892Z"),
"lastHeartbeatRecv" : ISODate("2017-01-19T14:30:34.168Z"),
"pingMs" : NumberLong(3),
"syncingTo" : "<IP address of main server>:27017",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "<IP address of additional server (the arbiter)>:27001",
"health" : 1.0,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 30,
"lastHeartbeat" : ISODate("2017-01-19T14:30:33.841Z"),
"lastHeartbeatRecv" : ISODate("2017-01-19T14:30:30.158Z"),
"pingMs" : NumberLong(0),
"configVersion" : 1
}
],
"ok" : 1.0
}
将附加服务器的“ stateStr ”从“ STARTUP2 ”替换为“ SECONDARY ”后,我们的服务器将同步。 / p>
当我们等待同步结束时,有必要稍微修改一下客户端应用程序,它们可以与副本中的所有服务器一起使用。
如果您使用ConnectionString,则应将其替换为:
mongodb://<IP address of main server>:27017,<IP address of additional server>:27017,<IP address of additional server (the arbiter)>:27001/?replicaSet=REPLICA
如果您像我一样使用C ++ mongo-cxx-driver遗留,则应使用 mongo :: DBClientReplicaSet 而不是 mongo :: DBClientConnection 并列出连接参数中的所有三个服务器,包括仲裁器。
还有第三个选项 - 您可以在切换 PRIMARY - SECONDARY 之后更改客户端中的MongoDB服务器的IP,但它不是很公平。
同步结束并且其他服务器状态已建立为 SECONDARY 后,我们需要切换 PRIMARY 和 SECONDARY 通过在主服务器上的“ mongo ”控制台中执行命令。这很重要,因为命令不能在附加服务器上运行。
cfg = rs.conf()
cfg.members[0].priority = 0.5
cfg.members[1].priority = 1
cfg.members[2].priority = 0.5
rs.reconfig(cfg)
然后执行以下命令检查服务器状态:
rs.status()
停止主服务器上的MongoDB
service mongod stop
并简单地删除包含数据库的目录的全部内容。这是安全的,因为我们在附加服务器上有一个工作副本,并且在开始时我们已经进行了备份。小心。 MongoDB本身不会创建数据库目录。如果您已将其删除,则不仅需要恢复
mkdir /var/lib/mongo
和设置所有者:
chown -R mongod:mongod /var/lib/mongo
检查存储引擎wiredTiger是在 /etc/mongod.conf 中配置的。从3.2开始默认使用它:
storage:
...
engine: wiredTiger
...
运行MongoDB:
service mongod start
主服务器将自动从辅助服务器获取配置,数据将同步回WiredTiger存储。
同步完成后,切换 PRIMARY 服务器。此操作应在其他服务器上执行,因为它现在是 PRIMARY 。
cfg = rs.conf()
cfg.members[0].priority = 1
cfg.members[1].priority = 0.5
cfg.members[2].priority = 0.5
rs.reconfig(cfg)
返回旧版本的数据库客户端或更改 ConnectionString 。
现在,如有必要,请关闭复制。从主服务器中删除2个复制服务器:
rs.remove("<IP address of additional server>:27017")
rs.remove("<IP address of additional server (the arbiter)>:27001")
从 /etc/mongod.conf 中删除所有“复制”部分并重新启动MongoDB:
service mongod restart
在通过“ mongo ”控制台连接后,我们会收到警告:
2017-01-19T12:26:51.948+0300 I STORAGE [initandlisten] ** WARNING: mongod started without --replSet yet 1 documents are present in local.system.replset
2017-01-19T12:26:51.948+0300 I STORAGE [initandlisten] ** Restart with --replSet unless you are doing maintenance and no other clients are connected.
2017-01-19T12:26:51.948+0300 I STORAGE [initandlisten] ** The TTL collection monitor will not start because of this.
要摆脱它,您需要删除数据库“ local ”。此数据库中只有一个集合“ startup_log ”处于默认状态,因此您可以通过“ mongo ”控制台轻松完成此操作
use local
db.dropDatabase()
并重启MongoDB:
service mongod restart
如果要从 /etc/mongod.conf 中的“复制”部分之前删除“本地”数据库,则会立即恢复。所以我不能只重启一次MongoDB。
在其他服务器上执行相同的操作:
仲裁者只需停止并删除:
pkill -f /tmp/mongo
rm -r /tmp/mongo