mongodb 3.0.6을 설치했었다.

http://knight76.tistory.com/entry/mongodb-replica-set-%EB%A7%8C%EB%93%A4%EA%B8%B0


이제 안정화 버전 3.2.0으로 업그레이드했다. (참고로 홀수 버전은 (3.1버전) 테스트 버전이다..)

이미 wiredtiger storage를 쓰고 있어서 특별한 설정(/etc/mongod.conf) 변경은 없다.



0, 1, 2 번 레플리카 (replica set)을 구축한 상태이고, 0 번이 master 이고, 1 번이 master를 바라보는 secondary 이며, 2번은 1번을 바라보는 sencondary로 되어 있다.


즉, 0 <----1 <----- 2 형태로 replica가 구축되어 있다. 

(참고로, redis에서는 이렇게 master-slave 작업을 해야 했었는데, mongodb는 자동으로 되어 있다.)


작업시 안전하게 redis 에서 작업한 경험대로 2, 1, 0번 순서대로 업그레이드를 했다.






먼저 2번 몽고에서 mongo shutdown을 한다. (참조 : https://docs.mongodb.org/manual/tutorial/manage-mongodb-processes/)


$mongo --port 27017 --eval 'db.adminCommand("shutdown")'


3.2.0 mongodb를 다운받고, 심볼링 링크를 걸고, 재시작한다. 


$ cd /usr/local

$ wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.2.0.tgz

$ sudo tar zxvf mongodb-linux-x86_64-3.2.0.tgz

$ sudo chown -R www.www mongodb-linux-x86_64-3.2.0

$ sudo rm mongodb

$ sudo ln -sf mongodb-linux-x86_64-3.2.0 mongodb

$  /usr/local/mongodb/bin/mongod -f /etc/mongod.conf


이런 식으로 하나씩 재시작하면 된다.  wiredtiger를 사용하는 3.0.6의 설정(위의 링크 참조)을 바꾸지 않고 그대로 3.2.0에서 사용했다.


재미있는 것은 replica 구성시 primary 서버에서 rs.status() 명령을 이용해서 레플리카의 상태를 체크할 수 있다.


1. 2번 slave에서 몽고 데몬을 내린 후, primary 서버에서 rs.status()로 확인하면 다음 상태를 확인할 수 있다. 



{

"_id" : 2,

"name" : "2.2.2.2:27017",

"health" : 0,

"state" : 8,

"stateStr" : "(not reachable/healthy)",

"uptime" : 0,

"optime" : Timestamp(0, 0),

"optimeDate" : ISODate("1970-01-01T00:00:00Z"),

"lastHeartbeat" : ISODate("2015-12-30T11:03:02.452Z"),

"lastHeartbeatRecv" : ISODate("2015-12-30T10:54:27.856Z"),

"pingMs" : 0,

"lastHeartbeatMessage" : "Failed attempt to connect to 1.1.1.1:27017; couldn't connect to server 1.1.1.1:27017 , connection attempt failed",

"configVersion" : -1

}


2. 2번 slave에서 몽고 데몬을 업그레이드 한 후, 실행한 후, primary 에서 rs.status()를 실행한다. 

2번 slave가 잘 동기화했고(syncingTo), optime이 1번과 동일해졌다. 잘 동기화되었음을 표시한다. 


{

"_id" : 1,

"name" : "1.1.1.1:27017",

"health" : 1,

"state" : 2,

"stateStr" : "SECONDARY",

"optime" : Timestamp(1451473740, 44),

                        "syncingTo" : "0.0.0.0:27017",

}

{

"_id" : 2,

"name" : "2.2.2.2:27017",

"health" : 1,

"state" : 2,

"stateStr" : "SECONDARY",

"optime" : Timestamp(1451473740, 44)

"syncingTo" : "1.1.1.1:27017",

}


3. 1번도 2번 몽고에서 작업한 것처럼 처리한다.


4. 원래 0번이 primary 몽고인데, shutdown했다.

원래는 내부적인 쿼럼 투표를 진행한다고 적혀 있긴 한데.

사실상 1번 slave 가 primary가 되었다. (0 <--------- 1 <--------- 2) 의 구성이라 직관적으로 1번이 primary가 되니 기분이 나쁘지 않았다 (redis쪽도 그렇게 되서..)



5. 1번 primary에서 rs.status()로 보면,  0번 mongo는 다음 상태가 된다. 

{

"_id" : 0,

"name" : "1.1.1.1:27017",

"health" : 0,

"state" : 8,

"stateStr" : "(not reachable/healthy)",

"uptime" : 0,

"optime" : Timestamp(0, 0),

"optimeDate" : ISODate("1970-01-01T00:00:00Z"),

"lastHeartbeat" : ISODate("2015-12-30T11:24:54.301Z"),

"lastHeartbeatRecv" : ISODate("2015-12-30T11:24:27.674Z"),

"pingMs" : NumberLong(0),

"lastHeartbeatMessage" : "Connection refused",

"configVersion" : -1

},


6. 0번 mongodb에서 업그레이드 후 데몬을 실행하면, secondary 몽고가 된다.


{

"_id" : 0,

"name" : "0.0.0.0:27017",

"health" : 1,

"state" : 2,

"stateStr" : "SECONDARY",

"uptime" : 7,

"optime" : Timestamp(1451474879, 6),

"optimeDate" : ISODate("2015-12-30T11:27:59Z"),

"lastHeartbeat" : ISODate("2015-12-30T11:28:30.481Z"),

"lastHeartbeatRecv" : ISODate("2015-12-30T11:28:32.258Z"),

"pingMs" : NumberLong(0),

"lastHeartbeatMessage" : "syncing from: 2.2.2.2:27017",

"syncingTo" : "2.2.2.2:27017",

"configVersion" : 89449

},



레플리카의 동기여부는 unique한 optime(operation log time)이 서로 맞는지 확인하면 된다. 자세한 내용은 몽고 문서 참조(https://docs.mongodb.org/v3.0/reference/command/replSetGetStatus/)한다. 




* 참고

자동으로 잘 동작하면,  혹시 확인차 테스트해보았다. 처음 하는 사람이라면, rs.slaveOk()를 사용하여 테스트하는 것도 괜찮을 것 같다. 

http://knight76.tistory.com/entry/mongodb-replicaset-%EC%97%90%EC%84%9C-slave%EC%97%90%EC%84%9C-%EC%BF%BC%EB%A6%AC-%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0






Posted by '김용환'
,