oplog.rs 컬렉션을 삭제하고 재생성하는 구버전 방식은 아랫부분에 있음.
// oplog size가 줄었을 때 사용되지 않는 디스크 공간을 반환하기 위해 compact를 해야하는데,
// 이때 local 데이터베이스에 대한 compact 권한이 필요함.
// primary에 접속하여 필요한 권한 부여.
// user는 admin_user 라고 가정함
rs01 [direct: primary] test> use admin
switched to db admin
// dbAdmin role이면 compact 권한을 부여할 수 있음
rs01 [direct: primary] admin> db.grantRolesToUser('admin_user', [ { role:'dbAdmin', db:'local' } ])
// 권한을 부여했으므로 이제 secondary부터 oplog resize를 진행
// MongoDB 버전이 올라가면서 replicaSet의 멤버로 구동되는 상태로 compact까지 진행할 수 있지만,
// 그냥 안전을 위해 shutdown 하고 진행하는게 마음 편함.
// 아래는 db.shutdownServer()를 통해 secondary를 내리고 stand alone으로 실행한 상태라고 가정.
// 인증
test> use admin
switched to db admin
admin> db.auth('admin_user', '비밀번호')
{ ok: 1 }
admin> use local
switched to db local
// 기존 oplog size 확인 (2G)
local> db.oplog.rs.stats().maxSize
2147483648
// oplog size 1G로 변경
local> db.adminCommand({ replSetResizeOplog:1, size:Double(1024) })
// 확인
local> db.oplog.rs.stats().maxSize
1073741824
// 줄어든 oplog size에 맞게 disk space도 줄이기 위해 compact
local> db.runCommand({ compact: 'oplog.rs' })
{ bytesFreed: 49152, ok: 1 }
/*
이후 compact까지 완료된 secondary를 다시 replicaSet에 복귀시키고,
primary를 rs.stepDown() 하고 db.shutdownServer() 를 통해 안전하게 내린 다음 stand-alone으로 다시 올린 후,
secondary에서 했던 것과 동일하게 replSetResizeOplog, compact를 실행한 후 다시 replicaSet으로 복귀시키면 완료.
*/
여기서부턴 구버전 방식
Replication을 위해 존재하는 oplog는 아무 설정을 하지 않았을 경우,
처음 생성될 때 기본값으로 디스크의 사용가능한 공간의 5% 크기로 설정된다. (64비트 리눅스 기준)
아무 생각없이 클러스터를 구성했다가 나중에 좀 쓰다가 보니 oplog 사이즈가 너무 크거나 작을 경우가 있다.
예를 들어,
secondary가 한 3일 내려가도 나중에 sync를 맞출 수 있도록 하려면 oplog 사이즈가 3일치 정도는 되어야 하지만,
oplog도 나머지 data+index와 함께 서버의 RAM 사이즈에 맞으면 좋으므로 서버당 데이터 수용량을 늘이려면 oplog가 좀 작아야 할 필요도 있다.
아래 명령어로 현재 oplog가 얼마나 커버가 가능한지 확인가능하다.
// 확인하고자 하는 mongod에 접속해서 아래 명령어로 확인 가능 (mongos 아님)
// 2.4버전 이하는 db.printReplicationInfo()
shard_001:PRIMARY> rs.printReplicationInfo()configured oplog size: 2048MB // 설정된 oplog 사이즈는 2Glog length start to end: 77899secs (21.64hrs) // secondary가 내려가도 21시간 안에 복구하면 sync할 수 있음oplog first event time: Mon Aug 03 2015 10:56:08 GMT+0900 (KST) oplog last event time: Tue Aug 04 2015 08:34:27 GMT+0900 (KST)now: Tue Aug 04 2015 08:34:28 GMT+0900 (KST)
권장 oplog 사이즈는 상황마다 다르므로 여기선 oplog 사이즈 변경하는 방법만 적는다.
oplog 사이즈 변경도 기본적으로 rolling 방식을 이용해 ReplicaSet의 secondary들부터 하나씩 내리고 stand-alone 모드로 올린 다음 oplog 사이즈를 변경하고 다시 ReplicaSet에 복귀시키는 방식이다.
우선 oplog 사이즈를 변경하고자 하는 secondary mongod에 접속해서 아래 명령어로 shutdown
shard_001:SECONDARY> use admin
// 인증이 필요하면 인증
shard_001:SECONDARY> db.shutdownServer()
그리고 ReplicaSet관련 설정을 뺀 포트와 데이터 디렉토리만 지정한 상태의 stand-alone 모드로 재시작.
(헷갈리지 않게 포트번호도 기존과 다르게 하는게 좋음)
[root@shard001-secondary]# mongod --port 37017 --dbpath /mongodb/data
혹시 모르니 불안하면 백업을 하자.
[root@shard001-secondary]# mongodump --db local --collection 'oplog.rs' --port 37017
이제 mongo로 접속해서 oplog를 재생성하면서 사이즈를 조정하자.
// local db 선택
mongo> use local
// temp라는 collection을 임시로 사용할건데 혹시 모르니 일단 drop
mongo> db.temp.drop()
// temp collection에 oplog의 마지막 document 하나만 넣기
// oplog를 재생성하고 다시 replicaSet에 복귀했을때 이 값을 기준으로 sync를 맞추게 됨
mongo> db.temp.save( db.oplog.rs.find({}, {ts:1, h:1}).sort({$natural: -1}).limit(1).next() )
// temp collection에 잘 들어갔는지 확인
mongo> db.temp.find()
// 기존 oplog collection 삭제
mongo> db.oplog.rs.drop()
// 새로운 oplog 생성 (사이즈는 1G)
mongo> db.runCommand({create: 'oplog.rs', capped: true, size: (1 * 1024 * 1024 * 1024)})
// 아까 temp collection에 insert했던 직전 oplog 하나를 새로 생성한 oplog에 insert
mongo> db.oplog.rs.save( db.temp.findOne() )
// 잘 들어갔는지 확인
mongo> db.oplog.rs.find()
여기까지 완료한 후 stand-alone으로 띄운 mongod는 shutdown하고 다시 ReplicaSet의 멤버로 설정하여 mongod를 재시작하면,
마지막 oplog를 기준으로 resync가 시작된다.
rs.status() 명령어로 복귀한 secondary의 stateStr 값이 STARTUP2에서 SECONDARY로 바뀌는 것을 확인하자. (순식간일수도 있다..)
그리고 나머지 secondary들도 동일한 작업을 반복한 후 마지막으로 primary의 oplog 사이즈를 조정하면 된다.
(primary shutdown시에는 rs.stepDown()으로 새로운 primary를 선출한 다음 shutdown 할 것)
[참고]
http://docs.mongodb.org/manual/tutorial/change-oplog-size
'DataBase' 카테고리의 다른 글
[MongoDB] ReplicaSet의 SECONDARY 멤버를 ARBITER로 변환하기 (0) | 2015.09.10 |
---|---|
[MongoDB] Transparent Huge Page 관련 warning 뜰 경우 (0) | 2015.09.01 |
[MongoDB] 사이즈 줄이기 (compact, repairDatabase) (0) | 2015.07.31 |
[MongoDB] chunk 이동 실패 (failed to sh.moveChunk, chunk too big to move) (0) | 2015.07.02 |
[MongoDB] config server 교체 (0) | 2015.06.30 |