MongoDb部署机器修改域名可能导致move chunk失败
来源:互联网 发布:女生铅笔袋淘宝 编辑:程序博客网 时间:2024/05/16 04:56
版本: 2.2.0
以下内容涉及之前的文章<MongoDb move chunk 故障分析和处理 (SERVER-5351)> .
在前面的文章<MongoDb move chunk 故障分析和处理 (SERVER-5351)> 提到的问题, 我们move chunk失败了. 问题的调查直指变量 vector _slaves, 该变量只会在关闭mongod和启动mongod的时候做clear操作, 而其他时候只会增或者改.从我们move chunk日志里面看出来, 我们的mongod的_slaves变量里面应该有 5/2+1 或者 4/2+1 个元素, 那么怎么来的呢? 我们明明只有3个secondary.
经过代码的追查, 发现了几个点
1) 在secondary mongod的rs.me里有唯一一条记录, 我们暂时叫它作 M. M有两个关键的元素 _id 和 host, _id是这个mongod的一个唯一id, 由ObjectId生成, host是这个mongod部署的机器的域名.
2) 在move chunk的过程中primary会向secondary获取一个remoteid, 也就是上面提到的_id
3) secondary在启动后, 一旦需要获取记录M, 则会去rs.me里面查, 源码码是这样的:
bool replHandshake(DBClientConnection *conn) { string myname = getHostName(); BSONObj me; { Lock::DBWrite l("local"); if ( ! Helpers::getSingleton( "local.me" , me ) || //从数据库local.me里面取出来机器的id, 这个就是所谓的_remoteId ! me.hasField("host") || me["host"].String() != myname ) {//这条记录里面的host和机器当前的host不同, 则需要清空重新设置, 此时就会重置_id Helpers::emptyCollection("local.me"); BSONObjBuilder b; b.appendOID( "_id" , 0 , true );//如果从local.me里面取不到id, 则创建一个id, 作为所谓的_remoteId b.append( "host", myname ); me = b.obj(); Helpers::putSingleton( "local.me" , me ); } } BSONObjBuilder cmd; //把id封装为 {"handshake": _remoteId}, 这个和我们在日志里面看到的一致, _remoteId在bsonobj里面的key是 "handshake" cmd.appendAs( me["_id"] , "handshake" ); if (theReplSet) { cmd.append("member", theReplSet->selfId()); } BSONObj res; bool ok = conn->runCommand( "admin" , cmd.obj() , res );//执行handshake命令 return true;}
4) 所以, 如果某一个作为secondary的mongod的机器改过域名, 那么这个mongod就前后两次的rs.me里文档的_id就不一样, 我们称id1为改域名前的_id, id2为改域名后的_id. 那么前后两次做过move chunk的时候分别有一个optime1和optime2. 这样 (id1,optime1) 和 (id2,optime2)都在_slaves里面, 但是表示的是同一个mongod, 而且optime1是早就过时的了. 这样就导致了_slaves里面的元素个数比实际secondary多.(ps: _slaves的元素不止这两个值, 只是这两个值是最重要的, 确定唯一的)
5) 经过确认, 我们的集群确实经历过搬机房, 修改域名, 重启过这些部署了secondary的机器. 加上我自己在另外搭建的集群上面实验, 2次修改域名之后就发生了move chunk失败的现象, 加上日志的输出, 和第4)点的结论一致.
到此为止, 总结一下
联系另外一篇博文<MongoDb move chunk 故障分析和处理>, _slaves这个变量是primary用来确定自己需要去跟踪多少个secondary的同步状态, map<Ident,OpTime> _slaves 的key值是secondary机器的唯一标识, value是Oplog同步到哪一条状态. 只要是曾经有一次作为secondary去跟primary同步数据, 那么primary的_slaves里面就会记录这个机器的Ident(是_remoteId和host(在我们的集群里面用ip, 我们ip没有修改)和ns(日志显示是local.oplog.rs)的组合), Ident确定了唯一的一条_slaves记录.
如果修改过域名, 那么就会导致新的Ident被插入到_slaves里面, 其对应的opTime会非常过时, 导致movechunk的时候, 要的等带多数secondary同步完成发生了错误.
- MongoDb部署机器修改域名可能导致move chunk失败
- MongoDb move chunk失败分析和处理(SERVER-5351)
- MongoDB move chunk and balancing
- move chunk failed
- mongodb chunk 大小设置
- mongodb中的chunk
- 【法克鱿】域名DNS设置修改失败!
- dll引用错误导致部署失败
- 微信分享非安全域名链接导致分享失败
- 修改oplogsize导致无法启动mongodb
- Tip - MSXML可能导致.net framework 3.5 sp1安装失败
- 修改linux主机名导致mysql启动失败
- 修改机器名导致发布不能用
- GCC 链接顺序导致使用MongoDB的应用链接失败
- 内存溢出导致jenkins自动部署到tomcat失败
- SharePoint2007修改机器名,域名后,出现问题及解决
- 修改ThinkPHP使其支持多级域名部署
- chunk
- 规范
- 初学者指针指南
- dd指令使用
- Android 底层学习札记
- 而发热管他
- MongoDb部署机器修改域名可能导致move chunk失败
- C++资源之不完全导引 [上]
- AFNetworking速成教程 (2)
- 自然对齐/指定字节对齐---个人笔记
- nyoj-115-城市平乱
- 各回各家
- 2013C++第10周项目——循环结构程序设计【项目4:输出完数】
- 可空类型"int?" 解决: 【数据库里的int类型可以为null,而在c#里int类型不能为Nul】的问题
- C++资源之不完全导引 [下]