2016-12-14 71 views
12

我有一个MongoDB实例,set up using a config file and a key file。我想initiate a replica set using pymongo。当我尝试启动replcia集,通过执行对服务器的Python脚本,这将成为副本集小学,因为这样的:MongoDB:无法启动副本集; '已有数据,无法启动设置'

from pymongo import MongoClient 

uri = "mongodb://correctWorkingUsername:[email protected]:27017" 
c = MongoClient(uri) 

config = {'_id': 'RelicaSetName', 'members': [ 
{'_id': 0, 'host': 'FirstServer:27017'}, 
{'_id': 1, 'host': 'SecondServer:27017'}, 
{'_id': 2, 'host': 'ThirdServer:27017'}]} 

c.admin.command("replSetInitiate", config) 

我得到一个错误信息,如下:

'SecondSErver:27017' has data already, cannot initiate set 

但是,如果我验证使用

mongo admin -u correctWorkingUsername -p password 

我可以启动复制的数据库,并成功添加成员:

rs.initiate() 
rs.add('SecondServer:27017') 

我不确定这是与密钥文件身份验证有关,还是用户已经通过脚本在其他服务器上创建的事实。每个服务器也已经启动了一个配置文件mongod.conf,其中包含一个副本集名称。

这是为什么会失败? rs.initiate()和rs.add()完美地工作,但python脚本不起作用,尽管它可以连接到数据库。

+1

鉴于我无法找到这个特定问题的'解决方案',我决定使用shell脚本直接执行mongodb副本启动。基本上我使用一个shell脚本来完成他们遍历的步骤。 https://api.mongodb.com/python/current/examples/high_availability.html –

+1

你是否对副本集的所有成员运行这个相同的python脚本?如果是这种情况,那就是你的问题。 – helmy

+0

@helmy不,我只对RS的主要版本运行脚本。为了清晰起见编辑了这个问题。 –

回答

4

当您一次初始化完整副本集时,每个节点都不应该有数据。

将现有的单个节点转换为副本集时,其数据将成为副本集数据,然后添加其他节点会将数据复制到擦除其现有数据。

你应该做的是启动节点,初始化副本集和,然后创建用户(仅在主节点上)。这本来是一个副本集的未初始化的成员是,如果上完成的唯一途径 -

用户是通过一个脚本

这是在核问题上的其他服务器上已经创建它首先作为非复制设置节点提出,添加了用户,然后用replSet选项重新启动。这不是正确的顺序。有关步骤的正确列表check the docs

+0

有趣的是,在亚马逊Linux上正式回购mongo 3.4之后,我得到了同样的行为。我想他们可能会添加一个默认用户或其他东西。我通过删除'/ var/lib/mongo /'中的所有内容来解决这个问题,但似乎不应该这样。 –

+0

我刚刚用python试过,它的工作方式和我的预期一样,但我从干净的实例开始。我猜你正在使用一些试图有帮助的安装/部署脚本。如果你仍想用Python做这件事,你可以启动第一个节点,然后通过Python命令添加其他节点,就像通过mongo shell一样。 –

+0

@AsyaKamsky有关为什么这个操作顺序(在启动副本集之前在主节点上创建用户)为什么每次使用mongo shell都适用,但使用此脚本失败?只有在使用python脚本时,我们才会从shell中启动RS。 –