{"action":"opened","issue":{"url":"https://api.github.com/repos/ma6174/blog/issues/12","labels_url":"https://api.github.com/repos/ma6174/blog/issues/12/labels{/name}","comments_url":"https://api.github.com/repos/ma6174/blog/issues/12/comments","events_url":"https://api.github.com/repos/ma6174/blog/issues/12/events","html_url":"https://github.com/ma6174/blog/issues/12","id":54202263,"number":12,"title":"mongodb灾难修复","user":{"login":"ma6174","id":1449133,"avatar_url":"https://avatars.githubusercontent.com/u/1449133?v=3","gravatar_id":"","url":"https://api.github.com/users/ma6174","html_url":"https://github.com/ma6174","followers_url":"https://api.github.com/users/ma6174/followers","following_url":"https://api.github.com/users/ma6174/following{/other_user}","gists_url":"https://api.github.com/users/ma6174/gists{/gist_id}","starred_url":"https://api.github.com/users/ma6174/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ma6174/subscriptions","organizations_url":"https://api.github.com/users/ma6174/orgs","repos_url":"https://api.github.com/users/ma6174/repos","events_url":"https://api.github.com/users/ma6174/events{/privacy}","received_events_url":"https://api.github.com/users/ma6174/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-01-13T14:53:42Z","updated_at":"2015-01-13T14:53:42Z","closed_at":null,"body":"数据库采用一个master两个slave方式部署，分别设置priority为3,2,1，当master数据库受到毁灭性的破坏（比如文件误删，系统挂掉）之后，master已经完全不可用，此时两个slave会进行选举，priority为2的slave会被选为master。此时数据库处在一个危险状态，如果再有任何一个数据库挂掉那么整个集群将变只读。\r\n\r\n如何修复？要分几种情况：\r\n\r\n1. master所在机器在一段时间能完全恢复，并且预期恢复的时间远小于oplog记录时间，那么等机器恢复后只要重新启动数据库就可以了，数据会自动同步，数据同步完成会被重新选举为master。\r\n\r\n2. 如果机器有硬件问题，即使恢复了最好将数据库移走，或者最起码要将master移走。\r\n\r\n3. 如果是人为误操作破坏了数据库文件，那么只需要在原来机器上将数据库恢复即可。如果oplog记录了所有操作，那么只要启动一个新的数据库即可，数据库加入集群后会自动同步数据。如果不幸oplog不全，那么只能手动恢复。恢复方案基本就是停一台slave，拷贝数据库文件到别的机器，再将数据库重新启动。但是上面提到，数据库现在不允许停机，因为只有两个节点，再停掉一个后数据库将无法选出master。这时候有一种解决方案是给集群增加两个选举节点，这时候整个集群机器数为5个，现在的状态是挂掉1个，如果再停掉一台进行数据拷贝，那么集群中还有3台数据库，大于总数的一半，此时集群也是能正常工作的。\r\n\r\n数据库当发生重新选举的时候，会导致数据库短时无master而不能正常提供服务。根据经验，在集群中增加一个节点是安全的，不会触发重新选举。但是删除节点会导致重新选举。不管是添加还是删除节点，都会或多或少的导致数据库出现慢请求。还有一个问题是当需要移除一个节点的时候，最好先将该节点停掉再移除，因为测试发现不停机直接移除导致数据库出现不可用和慢请求的个数远比停机操作多。\r\n\r\n从上面的分析看，网上有人为了节省，只设置了一个master和一个slave，再加一个选举节点，当某个非选举节点挂掉之后有很大可能性是无法恢复的。所以集群中至少应该设置3个数据节点。"}}