지난 블로그에서 Replica Set을 Archive 목적으로 StandAlone 으로 변경 후, 보안 이슈로 인해 Version Upgrade 도중 Local DB 관련하여 에러가 발생하여 Trouble Shooting 을 진행 하였습니다.
그래서 이번에는 Replica Set에서 StandAlone 으로 문제 없이 깨끗?하게 변경하는 부분에 대하여 테스트를 진행 하였습니다.
이번 테스트를 진행하면서 느낀점은, 몇몇 외국 블로그에 나온 내용들을 보면, 인증을 사용안하는 것일까 라는 의문이 생겼습니다. 왜냐하면 이번 테스트를 진행 하면서 인증(authorization) 로 인해 Local DB가 삭제가 되지 않는 이슈가 발생하였기 때문입니다.
글보다는 제가 진행한 방법에 대해서 이미지와 방법을 보시면 쉽게 변경 가능할 것 같습니다.
진행 방법
Replica Set 멤버들 제거 (primary는 제거되지 않습니다. 물론 제거하는 방법도 존재-맨 하단 리플리케이션-멤버-재설정 참고)
mongod.conf 에서 replication / security 모두 주석 처리 후 재 시작
local DB 삭제 진행
mongod.conf 에서 security 모두 원복 후 재 시작
Local DB에서 startup_log collection 만 생성 되었는지 확인 및 방금 startup 로그만 존재하는 지도 확인
정상적으로 StandAlone DB 변경 완료
# 1. 멤버 삭제
# Primary 에서 진행되며, 각 멤버들만 삭제가 가능
# 기본형태 : rs.remove("host명:port")
replSet:PRIMARY> rs.remove("127.0.0.1:57018")
replSet:PRIMARY> rs.remove("127.0.0.1:57019")
----------------------------------------------------------------------------
# 2. config 수정 및 mongodb 재시작
$ vi /etc/mongod.conf
systemLog:
destination: file
path: /data/mongo_test/log/mongo.log
...
net:
bindIp: 0.0.0.0
port: 57017
#replication:
# replSetName: "replSet"
#security:
# authorization: enabled
# keyFile: /data/mongo_test_repl.key
$ systemctl restart mongod.service
----------------------------------------------------------------------------
# 3. local DB 삭제 진행
$ mongo --port 57017
# 현재 standalone 으로 올라왔으며, security를 주석처리하였기 때문에 인증 없이 접속
> use local
> db.dropDatabase()
# 정상적으로 local DB가 삭제 된 것을 확인 가능
----------------------------------------------------------------------------
# 4. mongod.conf 에서 security 모두 원복 후 재시작
$ vi /etc/mongod.conf
systemLog:
destination: file
path: /data/mongo_test/log/mongo.log
...
net:
bindIp: 0.0.0.0
port: 57017
#replication:
# replSetName: "replSet"
security:
authorization: enabled
keyFile: /data/mongo_test_repl.key
----------------------------------------------------------------------------
# 5. Local DB 확인
$ mongo admin -uadmin -p --port 57017
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
test 0.000GB
>
> use local
switched to db local
> db.startup_log.find().pretty()
----------------------------------------------------------------------------
# 6. 완료
Replica Set 멤버 삭제
Stand Alone 형태의 단독 Mongodb 의 초기 모습
단순 local 내에는 startup_log collection 만 존재하며, 해당 collection 에는 startup 에 대한 로그들이 존재
Authorization 상태에서 Local DB삭제 시 다음과 같은 에러 발생
참고로, 4.2 부터는 writeConcern이 majority 라서 majority를 1로 주고 진행 하더라도 에러 발생하는 것을 확인 가능 (writeConcern의 문제가 아님)
그외
일부 블로그에서는 각 collection 마다 삭제하는 것도 있었는데, 실제로 삭제가 되는 collection 이 있는가 하면, 반대로 동일하게 Auth 로 인해서 삭제가 되지 않는 collection 도 존재 하는 것을 확인
아래 내용은 replication 재설정 관련하여 도움을 받았던 블로그 입니다.
이 부분도 실제로 진행하였는데, 자료를 남기지 않아 추후 테스트하여 공유 하도록 하겠습니다.
하나의 yum Repository 로도 가능하나, 별도의 repository 추가하여 진행 하였습니다. (별다른 이유는 없습니다.)
여기 까지는 위의 문서와 동일
cp /etc/yum.repos.d/mongodb-org-3.4.repo /etc/yum.repos.d/mongodb-org-3.6.repo
$ cp /etc/yum.repos.d/mongodb-org-3.4.repo /etc/yum.repos.d/mongodb-org-4.0.repo
$ cp /etc/yum.repos.d/mongodb-org-3.4.repo /etc/yum.repos.d/mongodb-org-4.2.repo
# 3.6 추가
$ vi /etc/yum.repos.d/mongodb-org-3.6.repo
[mongodb-org-3.6]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/amazon/2/mongodb-org/3.6/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.6.asc
# 4.0 추가
$ vi /etc/yum.repos.d/mongodb-org-4.0.repo
[mongodb-org-4.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/amazon/2/mongodb-org/4.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc
# 4.2 추가
$ vi /etc/yum.repos.d/mongodb-org-4.2.repo
[mongodb-org-4.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/amazon/2/mongodb-org/4.2/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.2.asc
# yum 초기화 진행
$ yum clean all
$ yum update list
MongoDB Replica Set to Standalone
단순히 conf 파일에서 replication 관련 항목을 주석 후 진행 (<- 원인)
$ vi /etc/mongod.conf
# 아래 replication 내역 주석 처리
...
#replication:
# replSetName: "replSet"
...
$ systemctl stop mongod.service
MongoDB 3.4 to 4.2 Upgrade 진행
해당 문서를 보면서 upgrade 를 진행 한다면 4.0 까지만 upgrade 진행 후 아래 모든 내용의 글을 읽으신 후에 4.2 로 진행 하시기 바랍니다.!!!!!
############ 3.6 ############
# mongo 서버 종료
$ systemctl stop mongod.service
# yum 으로 update 진행
$ yum -y update mongodb-org-3.6.23
# mongodb 서버 시작
$ systemctl start mongod.service
# mongodb 접속 후 확인
$ mongo admin -uadmin -p
# 현재값 확인
> db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )
# 중요!!!# featureCompatibilityVersion 수정
> db.adminCommand( { setFeatureCompatibilityVersion: "3.6" } )
# 정상적으로 변경되었는지 확인
> db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )
############ 4.0 ############
# mongo 서버 종료
$ systemctl stop mongod.service
# yum 으로 update 진행
$ yum -y update mongodb-org-4.0.27
# mongodb 서버 시작
$ systemctl start mongod.service
# mongodb 접속 후 확인
$ mongo admin -uadmin -p
# 현재값 확인
> db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )
# 중요!!!# featureCompatibilityVersion 수정
> db.adminCommand( { setFeatureCompatibilityVersion: "4.0" } )
# 정상적으로 변경되었는지 확인
> db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )
############ 4.2 ############
# mongo 서버 종료
$ systemctl stop mongod.service
# yum 으로 update 진행
$ yum -y update mongodb-org-4.2.18
# mongodb 서버 시작
$ systemctl start mongod.service
############################### 에러 발생하면서 startup 이 안되는 이슈 발생
발생 이슈
전제 : 기존 Replica Set에서 StandAlone 형태로 변경 후 버전 업그레이드 진행
cf) Replica set 에서 업그레이드 진행시 다음과 같은 문제는 발생하지 않음
문제 : 4.0 에서 4.2로 업그레이드 진행 후 startup 진행 시 startup 이 되지 않는 이슈
에러 내역 (로그)
주요 에러 내역
shutting down with code:100
exception in initAndListen: Location40415: BSON field 'MinValidDocument.oplogDeleteFromPoint' is an unknown field., terminating
$ systemctl start mongod.service
-> error 발생하면서 startup 이 되지 않음
mongod.log
2022-07-01T17:02:59.368+0900 I CONTROL [main] ***** SERVER RESTARTED *****
2022-07-01T17:02:59.370+0900 I CONTROL [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
2022-07-01T17:02:59.373+0900 W ASIO [main] No TransportLayer configured during NetworkInterface startup
2022-07-01T17:02:59.373+0900 I CONTROL [initandlisten] MongoDB starting : pid=36325 port=27017 dbpath=/data/mongo/repl_0 64-bit host=192.168.0.1
2022-07-01T17:02:59.373+0900 I CONTROL [initandlisten] db version v4.2.21
2022-07-01T17:02:59.373+0900 I CONTROL [initandlisten] git version: b0aeed9445ff41af57e1f231bce990b3
2022-07-01T17:02:59.373+0900 I CONTROL [initandlisten] OpenSSL version: OpenSSL 1.0.2k-fips 26 Jan 2017
2022-07-01T17:02:59.373+0900 I CONTROL [initandlisten] allocator: tcmalloc
2022-07-01T17:02:59.373+0900 I CONTROL [initandlisten] modules: none
2022-07-01T17:02:59.373+0900 I CONTROL [initandlisten] build environment:
2022-07-01T17:02:59.373+0900 I CONTROL [initandlisten] distmod: amazon2
2022-07-01T17:02:59.373+0900 I CONTROL [initandlisten] distarch: x86_64
2022-07-01T17:02:59.373+0900 I CONTROL [initandlisten] target_arch: x86_64
2022-07-01T17:02:59.373+0900 I CONTROL [initandlisten] options: { config: "/etc/mongod.conf", net: { bindIp: "0.0.0.0", port: 27017 }, processManagement: { fork: true, pidFilePath: "/var/run/mongodb/mongod.pid" }, security: { authorization: "enabled" }, storage: { dbPath: "/data/mongo/repl_0", journal: { enabled: true } }, systemLog: { destination: "file", logAppend: true, path: "/var/log/mongodb/mongod.log", quiet: true } }
2022-07-01T17:02:59.373+0900 I STORAGE [initandlisten] Detected data files in /data/mongo/repl_0 created by the 'wiredTiger' storage engine, so setting the active storage engine to 'wiredTiger'.
2022-07-01T17:02:59.373+0900 I STORAGE [initandlisten] wiredtiger_open config: create,cache_size=7360M,cache_overflow=(file_max=0M),session_max=33000,eviction=(threads_min=4,threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000,close_scan_interval=10,close_handle_minimum=250),statistics_log=(wait=0),verbose=[recovery_progress,checkpoint_progress],
2022-07-01T17:02:59.914+0900 I STORAGE [initandlisten] WiredTiger message [1656662579:914502][36325:0x7ff6d143a080], txn-recover: Recovering log 71644 through 71645
2022-07-01T17:02:59.985+0900 I STORAGE [initandlisten] WiredTiger message [1656662579:985670][36325:0x7ff6d143a080], txn-recover: Recovering log 71645 through 71645
...
2022-07-01T17:03:00.247+0900 I STORAGE [initandlisten] WiredTiger message [1656662580:247926][36325:0x7ff6d143a080], txn-recover: Set global recovery timestamp: (0, 0)
2022-07-01T17:03:00.258+0900 I RECOVERY [initandlisten] WiredTiger recoveryTimestamp. Ts: Timestamp(0, 0)
2022-07-01T17:03:00.260+0900 I STORAGE [initandlisten] No table logging settings modifications are required for existing WiredTiger tables. Logging enabled? 1
2022-07-01T17:03:00.267+0900 I STORAGE [initandlisten] Starting OplogTruncaterThread local.oplog.rs
2022-07-01T17:03:00.267+0900 I STORAGE [initandlisten] The size storer reports that the oplog contains 44774827 records totaling to 53269933556 bytes
2022-07-01T17:03:00.267+0900 I STORAGE [initandlisten] Sampling the oplog to determine where to place markers for truncation
2022-07-01T17:03:00.269+0900 I STORAGE [initandlisten] Sampling from the oplog between Jun 12 09:53:56:57 and Jun 30 10:45:36:1 to determine where to place markers for truncation
2022-07-01T17:03:00.269+0900 I STORAGE [initandlisten] Taking 992 samples and assuming that each section of oplog contains approximately 451255 records totaling to 536871395 bytes
2022-07-01T17:03:00.743+0900 I STORAGE [initandlisten] Placing a marker at optime Jun 12 13:10:49:4
2022-07-01T17:03:00.743+0900 I STORAGE [initandlisten] Placing a marker at optime Jun 12 17:58:42:4
....
2022-07-01T17:03:00.743+0900 I STORAGE [initandlisten] Placing a marker at optime Jun 30 08:04:48:175
2022-07-01T17:03:00.743+0900 I STORAGE [initandlisten] WiredTiger record store oplog processing took 475ms
2022-07-01T17:03:00.744+0900 I STORAGE [initandlisten] Timestamp monitor starting
2022-07-01T17:03:00.771+0900 I STORAGE [initandlisten] exception in initAndListen: Location40415: BSON field 'MinValidDocument.oplogDeleteFromPoint' is an unknown field., terminating
2022-07-01T17:03:00.771+0900 I REPL [initandlisten] Stepping down the ReplicationCoordinator for shutdown, waitTime: 10000ms
2022-07-01T17:03:00.771+0900 I SHARDING [initandlisten] Shutting down the WaitForMajorityService
2022-07-01T17:03:00.771+0900 I NETWORK [initandlisten] shutdown: going to close listening sockets...
2022-07-01T17:03:00.771+0900 I NETWORK [initandlisten] Shutting down the global connection pool
2022-07-01T17:03:00.771+0900 I STORAGE [initandlisten] Shutting down the FlowControlTicketholder
2022-07-01T17:03:00.771+0900 I - [initandlisten] Stopping further Flow Control ticket acquisitions.
2022-07-01T17:03:00.771+0900 I STORAGE [initandlisten] Shutting down the PeriodicThreadToAbortExpiredTransactions
2022-07-01T17:03:00.771+0900 I STORAGE [initandlisten] Shutting down the PeriodicThreadToDecreaseSnapshotHistoryIfNotNeeded
2022-07-01T17:03:00.771+0900 I REPL [initandlisten] Shutting down the ReplicationCoordinator
2022-07-01T17:03:00.771+0900 I SHARDING [initandlisten] Shutting down the ShardingInitializationMongoD
2022-07-01T17:03:00.771+0900 I REPL [initandlisten] Enqueuing the ReplicationStateTransitionLock for shutdown
2022-07-01T17:03:00.771+0900 I - [initandlisten] Killing all operations for shutdown
...
2022-07-01T17:03:01.196+0900 I STORAGE [initandlisten] WiredTiger message [1656662581:196670][36325:0x7ff6d143a080], txn-recover: Set global recovery timestamp: (0, 0)
2022-07-01T17:03:01.335+0900 I STORAGE [initandlisten] shutdown: removing fs lock...
2022-07-01T17:03:01.335+0900 I - [initandlisten] Dropping the scope cache for shutdown
2022-07-01T17:03:01.335+0900 I CONTROL [initandlisten] now exiting
2022-07-01T17:03:01.335+0900 I CONTROL [initandlisten] shutting down with code:100
해결 방안
4.0 Downgrade 진행 및 local DB의 replset.minvalid 컬렉션의 oplogDeleteFromPoint 필드 unset 진행
# 4.0 Downgrade 진행
$ yum -y downgrade mongodb-org-4.0.27
# mongodb startup 진행
$ systemctl start mongod.service
# mongodb 접속 후 확인
$ mongo admin -uadmin -p
# local 에서 replset.minvalid Collection 의 oplogDeleteFromPoint 필드 $unset 진행
> use local
switched to db local
> db.replset.minvalid.find({}).pretty ();
{
"_id" : ObjectId("5ec3b7c56db7b066b3f5d5e3"),
"ts" : Timestamp(1643225280, 1),
"t" : NumberLong(7),
"oplogDeleteFromPoint" : Timestamp(0, 0)
}
# update 진행 검색 조건은 _id 결과로 $unset 진행
> db.replset.minvalid.update(
... { "_id" : ObjectId("5ec3b7c56db7b066b3f5d5e3")},
... { $unset: { oplogDeleteFromPoint: ""} }
... );
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
# 해당 필드 값 확인
> db.replset.minvalid.find({}).pretty ();
{
"_id" : ObjectId("5ec3b7c56db7b066b3f5d5e3"),
"ts" : Timestamp(1643225280, 1),
"t" : NumberLong(7)
}
> exit
# 이후 다시 mongodb 4.2 upgrade 진행
# mongo 서버 종료
$systemctl stop mongod.service
# yum 으로 update 진행
yum -y update mongodb-org-4.2.18
# mongodb 서버 시작
$ systemctl start mongod.service
# mongodb 접속 후 확인
$ mongo admin -uadmin -p
# 현재값 확인
> db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )
# 중요!!!# featureCompatibilityVersion 수정
> db.adminCommand( { setFeatureCompatibilityVersion: "4.2" } )
# 정상적으로 변경되었는지 확인
> db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )
발생 원인
Replica set 을 정상적으로 삭제 하지 않고 단순 config 파일에서 수정 후 진행하다가 발생한 이유
Secondary 를 standalone 형태로 변경 후, 업그레이드 한다면 Downtime 없이 가능하며, 실제로 진행한 결과 문제 없이 업그레이드 진행 하였습니다.
이 부분에 대해서는 별도로 문서는 만들지 않았습니다.
PSA 구조로 진행하였으며, PSS 구조로 진행 한다면 Arbiter 업그레이드 대신 Secondary 진행한 그대로 대신 진행 하면 됩니다.
MongoDB 3.4 to 4.2 로 진행 합니다.
aws ec2 - amazon2 에서 진행 하였습니다.
Repo 추가 및 설정
하나의 yum Repository 로도 가능하나, 별도의 repository 추가하여 진행 하였습니다. (별다른 이유는 없습니다.)
cp /etc/yum.repos.d/mongodb-org-3.4.repo /etc/yum.repos.d/mongodb-org-3.6.repo
$ cp /etc/yum.repos.d/mongodb-org-3.4.repo /etc/yum.repos.d/mongodb-org-4.0.repo
$ cp /etc/yum.repos.d/mongodb-org-3.4.repo /etc/yum.repos.d/mongodb-org-4.2.repo
# 3.6 추가
$ vi /etc/yum.repos.d/mongodb-org-3.6.repo
[mongodb-org-3.6]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/amazon/2/mongodb-org/3.6/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.6.asc
# 4.0 추가
$ vi /etc/yum.repos.d/mongodb-org-4.0.repo
[mongodb-org-4.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/amazon/2/mongodb-org/4.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc
# 4.2 추가
$ vi /etc/yum.repos.d/mongodb-org-4.2.repo
[mongodb-org-4.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/amazon/2/mongodb-org/4.2/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.2.asc
# yum 초기화 진행
$ yum clean all
$ yum update list
MongoDB 3.6 Upgrade 진행
Secondary -> Arbiter -> Primary 순으로 진행 합니다.
############ Secondary ############
# mongo 서버 종료
$ systemctl stop mongod.service
# yum 으로 update 진행
$ yum update mongodb-org-3.6.23
# mongodb 서버 시작
$ systemctl start mongod.service
# mongodb 접속 후 확인
$ mongo admin -uadmin -p
# replica 접속 되었는지 확인
repl_set:SECONDARY> rs.status()
############ Arbiter ############
# mongo 서버 종료
$ systemctl stop mongod_arb.service
# yum 으로 update 진행
$ yum update mongodb-org-3.6.23
# mongodb 서버 시작
$ systemctl start mongod_arb.service
# mongodb 접속 후 확인
$ mongo --port 27018
# replica 접속 되었는지 확인
repl_set:ARBITER> rs.status()
############ Primary ############
# mongo 서버 종료
$ systemctl stop mongod.service
# yum 으로 update 진행
$ yum update mongodb-org-3.6.23
# mongodb 서버 시작
$ systemctl start mongod.service
# mongodb 접속 후 확인
$ mongo admin -uadmin -p
# replica 접속 되었는지 확인
repl_set:PRIMARY> rs.status()
############ 중요!!! ############
# featureCompatibilityVersion 수정
repl_set:PRIMARY> db.adminCommand( { setFeatureCompatibilityVersion: "3.6" } )
# 정상적으로 변경되었는지 확인
repl_set:PRIMARY> db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )
MongoDB 4.0 Upgrade 진행
Secondary -> Arbiter -> Primary 순으로 진행 합니다.
############ Secondary ############
# mongo 서버 종료
$ systemctl stop mongod.service
# yum 으로 update 진행
$ yum update mongodb-org-4.0.27
# mongodb 서버 시작
$ systemctl start mongod.service
# mongodb 접속 후 확인
$ mongo admin -uadmin -p
# replica 접속 되었는지 확인
repl_set:SECONDARY> rs.status()
############ Arbiter ############
# mongo 서버 종료
$ systemctl stop mongod_arb.service
# yum 으로 update 진행
$ yum update mongodb-org-4.0.27
# mongodb 서버 시작
$ systemctl start mongod_arb.service
# mongodb 접속 후 확인
$ mongo --port 27018
# replica 접속 되었는지 확인
repl_set:ARBITER> rs.status()
############ Primary ############
# mongo 서버 종료
$ systemctl stop mongod.service
# yum 으로 update 진행
$ yum update mongodb-org-4.0.27
# mongodb 서버 시작
$ systemctl start mongod.service
# mongodb 접속 후 확인
$ mongo admin -uadmin -p
# replica 접속 되었는지 확인
repl_set:PRIMARY> rs.status()
############ 중요!!! ############
# featureCompatibilityVersion 수정
repl_set:PRIMARY> db.adminCommand( { setFeatureCompatibilityVersion: "4.0" } )
# 정상적으로 변경되었는지 확인
repl_set:PRIMARY> db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )
MongoDB 4.2 Upgrade 진행
Secondary -> Arbiter -> Primary 순으로 진행 합니다.
############ Secondary ############
# mongo 서버 종료
$ systemctl stop mongod.service
# yum 으로 update 진행
$ yum update mongodb-org-4.2.18
# mongodb 서버 시작
$ systemctl start mongod.service
# mongodb 접속 후 확인
$ mongo admin -uadmin -p
# replica 접속 되었는지 확인
repl_set:SECONDARY> rs.status()
############ Arbiter ############
# mongo 서버 종료
$ systemctl stop mongod_arb.service
# yum 으로 update 진행
$ yum update mongodb-org-4.2.18
# mongodb 서버 시작
$ systemctl start mongod_arb.service
# mongodb 접속 후 확인
$ mongo --port 27018
# replica 접속 되었는지 확인
repl_set:ARBITER> rs.status()
############ Primary ############
# mongo 서버 종료
$ systemctl stop mongod.service
# yum 으로 update 진행
$ yum update mongodb-org-4.2.18
# mongodb 서버 시작
$ systemctl start mongod.service
# mongodb 접속 후 확인
$ mongo admin -uadmin -p
# replica 접속 되었는지 확인
repl_set:PRIMARY> rs.status()
############ 중요!!! ############
# featureCompatibilityVersion 수정
repl_set:PRIMARY> db.adminCommand( { setFeatureCompatibilityVersion: "4.2" } )
# 정상적으로 변경되었는지 확인
repl_set:PRIMARY> db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )
반복 작업이지만, MongoDB는 순차적으로 upgrade 하는 것이 권고 사항 입니다.
또한, featureCompatibilityVersion 을 수정하지 않는 경우 다음 version upgrade 이후 startup 이 되지 않는 이슈가 발생 합니다.
이 때, 이전 version으로 downgrade 이 후, featureCompatibilityVersion 수정 후 다시 업그레이드를 하게 되면 진행이 가능합니다.
모든 upgrade 작업은 백업은 필수! 입니다.
가령, 문제가 발생하여 repair 명령어를 이용하여 startup 을 하게 되면, 모든 collection repair 및 index rebuild 까지 진행 하기 때문에 데이터 size 가 작은 사이트에서는 크게 이슈가 발생하지 않겠지만, 저희처럼 테라바이트 단위라면 repair 시간을 예측 하기 힘든 상황이 발생 합니다. (6테라 size의 db를 repair 로 만 하루 넘어가도 끝나지 않아 포기하고 기존 ec2 snapshot 으로 복구 진행 하였습니다.)
이후, 다른 글에서 upgrade 과정에서 MinValidDocument.oplogDeleteFromPoint is an unknown field 이슈에 대해 해결 방법을 공유 하도록 하겠습니다.
메모리 DB (높은 처리량 - Replication 읽기 및 쓰기, 대기 시간 등 높은 처리 가능)
레디스와 호환이 되며, 레디스 관련한 것들을 모두 사용 가능 (v6.2)
Multi-AZ 를 지원하여 빠르게 failover 및 복구, 재시작이 가능
특징
Primary / Replica 간의 강력한 일관성 보장
ms 단위의 읽기,쓰기 지연시간 (클러스터당 최대 1억6천만 tps)
redis 호환
빠른 데이터 복구 및 재시작 제공 (multi-az, transaction log )
multi-az를 통한 자동 페일오버 및 노드 fail에 대한 감지 및 복구
replication 및 shard를 이용한 노드 추가, scale out, scale up-down 가능
primary 에 대한 read/write 일관성 보장 및 복제 노드에 대한 일관성 보장 가능(read / write concern으로 예상)
사용자 인증 및 네트워크 인증, 암호화 기능 제공
s3로 자동 스냅샷 (최대 35일 - rds 와 동일)
하나의 클러스터로 최대 500개 노드 및 100tb 이상의 storage 지원(레플리카 포함)
AWS KMS keys를 사용한 TLS 암호화(8번과 동일)
Redis를 통한 사용자 인증 및 권한 부여(ACL)(8번과 동일)
AWS Graviton2 인스턴스 유형 지원
VPC, Cloudwatch, CloudTrail, AWS SNS 서비스와의 통합
완전 관리형 소프트웨어 패치 및 업그레이드 지원
관리 API를 위한 AWS IAM(Identity and Access Management) 통합 및 태그 기반 액세스 제어
주요 기능
Cluster
MemoryDB 서비스를 운영하는 하나 이상의 노드 모음 (서비스의 개념)
Shard는 Memory DB Set 단위들의 모임으로 Cluster 내에 존재
Noes ⊂ Shard ⊂ Cluster = 서비스 DB
Memory DB Set 에는 하나의 Primary 와 최대 5개의 Replica 노드들을 보유 가능
Primary 는 read/write 가능하며, Replica node들은 only read 만 처리
Primary 장애 시 replica node들 중 하나를 primary 로 승격
cluster 생성 시 redis 버전을 지정
cluster 내 Memory DB 기능
cluster 추가
cluster 수정
cluster 스냅샷 가져오기
cluster 삭제
cluster 내 요소 보기
cluster 에 비용 할당 태그 추가 / 삭제
Nodes
MemoryDB 구성 중 가장 작은 단위 (EC2 기반)
클러스터에 속하며, cluster 생성 시 정해진 버전의 엔진 기반
필요한 경우 클러스터의 노드를 다른 유형으로 up / down 가능
단독으로 up / down 가능은 체크 필요
Shards
하나의 샤드에는 1~6개의 노드로 구성되며, primary 1개에 5개의 replica 로 구성
MemoryDB Cluster는 항상 적어도 하나의 샤드로 구성
클러스터 내 최대 500개의 샤드를 생성 가능
최대 500개 노드를 가질 수 있으므로, 1샤드=1 Primary 노드로 하는 경우 500샤드 구성 가능
단, IP주소가 충분한지 체크 필요
Parameter groups
parameter group 을 적용함으로써 각기 다른 parameter 를 적용 가능
RDS 와 동일 개념
Subnet Groups
VPC 내 subnet group 으로 구성
Access Control Lists
Redis ACL 규칙을 적용 가능 (Access Control List)
Users
이름과 암호를 가진 User를 생성하여 접속 가능
2. 사용자는 ACL 구성원
Redis vs Elasticache Redis vs MemoryDB for Redis
성능 : Elasticache 가 Memory DB 보다 쓰기 읽기 성능이 더 좋음
Redis
ElastiCache for Redis
MemoryDB for Redis
내구성
AOF, RDB 로 내구성 처리 (AOF 파일에 쓰기 전 장애 시 데이터 손실 발생 가능성)
Primary 리턴 응답이라, Replica node에 데이터 적재 전 장애 시 손실 발생 가능성 존재 Redis 데이터구조 및 API
내구성이 뛰어난 Inmemory DB (장애 시 무손실 복구) (Transaction log 까지 작성 후 응답이기 때문에 무손실 가능) Redis 데이터구조 및 API
성능
12만/sec
read/write :μs (마이크로초)
read :μs (마이크로초) write : ms (한자리 Millisecond)
Cluster mode
Cluster mode 활성화 비활성화 모두 가능
cluster mode 활성화, 비활성화 모두 가능
cluster mode 활성화 필수
접속
redis-cli 로 접속
백업
조건부 RDB 백업 가능
AOF 로 모든 DML 쿼리 저장
24시간 동안 20개까지 스냅샷 생성 제한
cluster mode에서만 백업
해당 Region에서 수동 스냅샷 보유 개수 제한은 없음
24시간 동안 20개까지 스냅샷 생성 제한
cluster mode에서만 백업
해당 Region에서 수동 스냅샷 보유 개수 제한은 없음
복원
RDB 시점 복원 가능
AOF 이용하여 원하는 명령문까지 복원 가능
RDB 스냅샷 복원
별도의 Replica node가 없을 경우 유실(마지막 스냅샷 이후 부터 유실)
RDB 스냅샷 복원
특정시점복원은 불가 (Point in time Recovery 불가)
Transaction log를 이용하여 장애 최종 복원 가능
고가용성
replica shard 구성
Replica Shard 구성
replica node의 복제가 실패하는 경우
실패 노드를 감지하여 오프라인 전환 및 동일한 AZ에 교체노드를 실행하여 동기화 진행
MemoryDB Multi-AZ primary 장애
MemoryDB에서 Primary 오류 감지하면, replica node들 중 primary 정합성체크 후 primary 승격 후 다른 AZ에 있는 primary를 spin up 이후 동기화 진행 (다른 AZ의 primary 를 spin up 이후 동기화 하는 것보다 더 빠름)
US East (N. Virginia), US East (Ohio), US West (Oregon), US West (Northern California), EU (Ireland), EU (London), EU (Stockholm), Asia Pacific (Mumbai), Asia Pacific (Seoul), Asia Pacific (Singapore), Asia Pacific (Sydney), Asia Pacific (Tokyo), Canada (Central), and South America (Sao Paulo) - 21년10월 정보
메모리 DB (높은 처리량 - Replication 읽기 및 쓰기, 대기 시간 등 높은 처리 가능)
레디스와 호환이 되며, 레디스 관련한 것들을 모두 사용 가능 (v6.2)
Multi-AZ 를 지원하여 빠르게 failover 및 복구, 재시작이 가능
특징
Primary / Replica 간의 강력한 일관성 보장
ms 단위의 읽기,쓰기 지연시간 (클러스터당 최대 1억6천만 tps)
redis 호환
빠른 데이터 복구 및 재시작 제공 (multi-az, transaction log )
multi-az를 통한 자동 페일오버 및 노드 fail에 대한 감지 및 복구
replication 및 shard를 이용한 노드 추가, scale out, scale up-down 가능
primary 에 대한 read/write 일관성 보장 및 복제 노드에 대한 일관성 보장 가능(read / write concern으로 예상)
사용자 인증 및 네트워크 인증, 암호화 기능 제공
s3로 자동 스냅샷 (최대 35일 - rds 와 동일)
하나의 클러스터로 최대 500개 노드 및 100tb 이상의 storage 지원(레플리카 포함)
AWS KMS keys를 사용한 TLS 암호화(8번과 동일)
Redis를 통한 사용자 인증 및 권한 부여(ACL)(8번과 동일)
AWS Graviton2 인스턴스 유형 지원
VPC, Cloudwatch, CloudTrail, AWS SNS 서비스와의 통합
완전 관리형 소프트웨어 패치 및 업그레이드 지원
관리 API를 위한 AWS IAM(Identity and Access Management) 통합 및 태그 기반 액세스 제어
주요 기능
Cluster
MemoryDB 서비스를 운영하는 하나 이상의 노드 모음 (서비스의 개념)
Shard는 Memory DB Set 단위들의 모임으로 Cluster 내에 존재
Noes ⊂ Shard ⊂ Cluster = 서비스 DB
Memory DB Set 에는 하나의 Primary 와 최대 5개의 Replica 노드들을 보유 가능
Primary 는 read/write 가능하며, Replica node들은 only read 만 처리
Primary 장애 시 replica node들 중 하나를 primary 로 승격
cluster 생성 시 redis 버전을 지정
cluster 내 Memory DB 기능
cluster 추가
cluster 수정
cluster 스냅샷 가져오기
cluster 삭제
cluster 내 요소 보기
cluster 에 비용 할당 태그 추가 / 삭제
Nodes
MemoryDB 구성 중 가장 작은 단위 (EC2 기반)
클러스터에 속하며, cluster 생성 시 정해진 버전의 엔진 기반
필요한 경우 클러스터의 노드를 다른 유형으로 up / down 가능
단독으로 up / down 가능은 체크 필요
Shards
하나의 샤드에는 1~6개의 노드로 구성되며, primary 1개에 5개의 replica 로 구성
MemoryDB Cluster는 항상 적어도 하나의 샤드로 구성
클러스터 내 최대 500개의 샤드를 생성 가능
최대 500개 노드를 가질 수 있으므로, 1샤드=1 Primary 노드로 하는 경우 500샤드 구성 가능
단, IP주소가 충분한지 체크 필요
Parameter groups
parameter group 을 적용함으로써 각기 다른 parameter 를 적용 가능
RDS 와 동일 개념
Subnet Groups
VPC 내 subnet group 으로 구성
Access Control Lists
Redis ACL 규칙을 적용 가능 (Access Control List)
Users
이름과 암호를 가진 User를 생성하여 접속 가능
2. 사용자는 ACL 구성원
Redis vs Elasticache Redis vs MemoryDB for Redis
성능 : Elasticache 가 Memory DB 보다 쓰기 읽기 성능이 더 좋음
Redis
ElastiCache for Redis
MemoryDB for Redis
내구성
AOF, RDB 로 내구성 처리 (AOF 파일에 쓰기 전 장애 시 데이터 손실 발생 가능성)
Primary 리턴 응답이라, Replica node에 데이터 적재 전 장애 시 손실 발생 가능성 존재 Redis 데이터구조 및 API
내구성이 뛰어난 Inmemory DB (장애 시 무손실 복구) (Transaction log 까지 작성 후 응답이기 때문에 무손실 가능) Redis 데이터구조 및 API
성능
12만/sec
read/write :μs (마이크로초)
read :μs (마이크로초) write : ms (한자리 Millisecond)
Cluster mode
Cluster mode 활성화 비활성화 모두 가능
cluster mode 활성화, 비활성화 모두 가능
cluster mode 활성화 필수
접속
redis-cli 로 접속
백업
조건부 RDB 백업 가능
AOF 로 모든 DML 쿼리 저장
24시간 동안 20개까지 스냅샷 생성 제한
cluster mode에서만 백업
해당 Region에서 수동 스냅샷 보유 개수 제한은 없음
24시간 동안 20개까지 스냅샷 생성 제한
cluster mode에서만 백업
해당 Region에서 수동 스냅샷 보유 개수 제한은 없음
복원
RDB 시점 복원 가능
AOF 이용하여 원하는 명령문까지 복원 가능
RDB 스냅샷 복원
별도의 Replica node가 없을 경우 유실(마지막 스냅샷 이후 부터 유실)
RDB 스냅샷 복원
특정시점복원은 불가 (Point in time Recovery 불가)
Transaction log를 이용하여 장애 최종 복원 가능
고가용성
replica shard 구성
Replica Shard 구성
replica node의 복제가 실패하는 경우
실패 노드를 감지하여 오프라인 전환 및 동일한 AZ에 교체노드를 실행하여 동기화 진행
MemoryDB Multi-AZ primary 장애
MemoryDB에서 Primary 오류 감지하면, replica node들 중 primary 정합성체크 후 primary 승격 후 다른 AZ에 있는 primary를 spin up 이후 동기화 진행 (다른 AZ의 primary 를 spin up 이후 동기화 하는 것보다 더 빠름)
US East (N. Virginia), US East (Ohio), US West (Oregon), US West (Northern California), EU (Ireland), EU (London), EU (Stockholm), Asia Pacific (Mumbai), Asia Pacific (Seoul), Asia Pacific (Singapore), Asia Pacific (Sydney), Asia Pacific (Tokyo), Canada (Central), and South America (Sao Paulo) - 21년10월 정보
MongoDB 는 보안 관점으로 크게 5가지로 정리를 할 수 있으며, 해당 문서에서는 인증과 권한, 테스트한 내역만 작성
인증(Authentication)
권한(Authorization)
암호화(Encryption) - TDE - Mongo DB Enterprise 에서 제공
감사 (Auditing) - MongoDB Enterprise 및 Percona 제공
데이터 관리 (Data Governance) - 데이터의 일관성을 유지라 해당 서적에서는 언급 안함
인증(Authentication)
내부 인증
MongoDB와 MongoDB 라우터 서버 간(레플리카 셋에서 각 멤버간)의 통신을 위해서 사용되는 인증
내부 인증은 키 파일과 x.509인증서 2가지 방식을 선택 가능
인증 활성화 하기 위해서 설정파일에서 인증과 관련된 옵션 활성화 해야 함
$ /etc/mongod.conf
security :
authorization: enabled # 내부 및 사용자 인증까지 모두 활성화(내부/사용자 인증을 개별로 설정 못함)
#key 파일 생성은 기존 문서로 대체 합니다.
#기존 key 파일 생성 및 auth 내용
clusterAuthMode : keyFile
keyFile : /etc/mongod.key
keyFile은 평문의 단순 문자열로 구성된 비밀번호 파일을 MongoDB 서버(OS)가 내부 인증으로 사용하도록 하는 방식
keyFile 생성할 때 주의점
해당 파일은 클러스터에 참여하는 모든 MongoDB가 공유해야함-동일한 파일을 모든 멤버의 서버에 복사해서 사용해야 함
keyFile 은 MongoDB 서버 프로세스가 읽을 수 있어야 함
keyFile의 접근권한은 반드시 600, 700으로 파일의 소유주만 접근할 수 있어야 함
keyFile의 내용에서 공백문자는 자동으로 무시
keyFile은 6개 이상 1024개 이하의 문자로 구성돼야 하며, Base-64셋에 포함되는 문자만 사용할 수 있음
사용자 인증
MongoDB서버 외부의 응용 프로그램이 MongoDB 클라이언트 드라이버 이용해서 접속 시도할 때
사용자를 생성할 때 반드시 특정 데이터베이스로 이동해서 생성해야 함 > 인증 데이터베이스라고 함(Authentication Database)
여러 DB에 대해 권한을 가질 수 있지만, 인증 데이터베이스(로그인을 위한)는 하나만 가질 수 있음 (admin 에서 생성 하고, test 에서 또 권한을 주더라도 test를 인증하는 데이터베이스로 할수 없고 로그인할 때는 무조건 admin으로 먼저 접속)
활성화기 위해서 /etc/mongod.conf 파일을 수정. 클러스터 멤버 간 통신의 인증을 위해서 clusterAuthMode 및 keyFile 옵션을 추가 더 사용해야 함
db.system.users.find().pretty() 명령 으로 유저 정보를 확인 가능
동일한 계정명과 패스워드를 하더라도 다음과 같이 생성하면 두 계정은 mongoDB에서는 서로 다른 계정으로 인식함
만약 하나의 사용자 계정이 여러 데이터베이스 대해서 권한을 가지도록 한다면 다음과 같이 해야 함
단순 사용자 인증을 위한 설정
security:
authorization : enabled
use mysns
db.createUser({user:"user",pwd:"password", roles:["readWrite" ] })
use myblog
db.createUser({user:"user",pwd:"password", roles:["readWrite" ] })
#유저 생성 여부 확인
show users
use mysns
db.createUser({user:"user",pwd:"password", roles:[ "readWrite", {role:"readWrite", db:"myblog" } ] })
또는
use mysns
db.createUser({user:"user",pwd:"password", roles:["readWrite" ] })
db.grantRolesToUser("user", [{ role:"readWrite", db:"myblog" }])
생성된 유저 확인
db.system.users.find().pretty()
외부 인증 방식
LDAP나 Active Directory 를 이용해서 사용자 인증을 의미 하며 Enterprise 버전에서만 사용 가능
This article will walk you through using the SASL library to allow your Percona Server for MongoDB instance to authenticate with your company’s Active Directory server. Percona Server for MongoDB includes enterprise level features, such as LDAP authentication, audit logging and with the 3.6.8 release a beta version of data encryption at rest, all in its open source offering.
권한 (Authorization)
액션
명령이 처리되는 동안 발생하는 각 단위 작업을 나누어서 MongoDB의 명령들이 하나 이상의 단위 액션들의 집합으로 처리되는 개념
버전에 따라 미리 정의해 둔 액션의 종류는 매우 다양하고 개수도 많으며, 추가/제거되는 명령도 많기 때문에 MongoDB에서 직접 체크가 필요
최소 단위의 권한으로 일반적인 명령어를 실행하기 위해서는 여러 액션의 권한이 필요 (aggregate라는 명령어를 실행하기 위해서는 find / insert / bypassDocumentValidation이라는 3가지 액션이 필요)
내장된 역할(Role)
MongoDB에서 내부적으로 default로 만든 role로 여러 액션들의 집합체
ex) read 라는 내장된 롤에는 collStats, dbHash, dbStats, find, killCursors, listIndexes, listCollections 의 액션으로 만들어짐
mysns 데이터베이스에 대해서 readWrite 역할을 가지고 myblog 데이터베이스에 대해서 read 역할만 가지는 사용자 계정 생성
mongodb > use mysns
Mongodb > db.createUser({user:"mysns_user",pwd:"mypassword",roles:["readWrite",{role:"read",db:"myblog"}]})
cf ) User 생성 시 인증 DB를 admin 으로 하되, 권한은 DB 단위의 권한만 부여 되는지 여부
changeStream, collStats, dbHash, dbStats, find, killCursors, listIndexes, listCollections 등과 같은 명령어를 처리
readWrite
읽기 + 쓰기
system collection 제외
read에 해당하는 명령어에 convertToCapped, createCollection, dropCollection, createIndex, dropIndex, emptycapped, insert, remove, renameCollectionSameDB, update 와 같은 명령어를 처리
Database Administration Roles
dbAdmin
indexing, gathering, statistics 등 역할을 할 수 있으며
user와 role에 대한 management는 제외
collStats, dbHash, dbStats, find, killCursors, lisstIndexes, listCollections 및 dropCollection, createCollection on system.profile only
기술PM : dbAdmin + readWrite 권한 부여
dbOwner
readWrite + dbAdmin + userAdmin
userAdmin
해당 DB에 대한 user의 roles를 생성하거나 변경을 수행하며, admin에 대한 userAdmin 권한을 받았을 경우 superuser를 생성 가능
WARNING
It is important to understand the security implications of granting the userAdmin role: a user with this role for a database can assign themselves any privilege on that database. Granting the userAdmin role on the admin database has further security implications as this indirectly provides superuser access to a cluster. With admin scope a user with the userAdmin role can grant cluster-wide roles or privileges including userAdminAnyDatabase.
Primary로만 쿼리 실행하며, Primary가 없으면 쿼리 실행은 실패(장애 발생하고 fail over 이전)
PrimaryPreferred
가능하면 Primary로 전송하며 장애로 Primary가 없는 경우 Secondary 로 요청
Secondary
Secondary 멤버로만 전송하며, Primary로는 요청하지 않음. 멤버가 2개 이상일 경우 적절히 분산하여 요청
Secondary가 없는 경우 실패 발생
secondaryPreferred
Secondary와 동일하지만 없는 경우 Primary로 요청
nearest
쿼리 요청 응답시간이 가장 빠른 멤버로 요청 (Primary, Secondary 고려 안함)
동일한 대역에서는 미흡하지만, 레플리카 셋이 글로벌하게 분산되어 멤버들간의 응답시간이 차이가 나는 경우 적절
샤딩 환경의 중복 Document 처리
샤딩된 클러스터는 2가지 경우에만 Document 샤드의 소유권(Ownership)을 체크
쿼리에 샤드의 메타 정보 버전이 포함된 경우
쿼리의 조건에 샤드 키가 포함된 경우
청크가 이동될 때마다 컨피그 서버의 메타 정보가 변경됨(메타 정보의 버전이 1씩 증가)
버전 정보를 쿼리 실행시마다 전달하는데, 버전이 포함된 쿼리를 'Versioned Query'라고 명칭
청크가 이동되더라도 한 시점의 일괄된 데이터를 보장하는 이유가 버전 정보를 포함하고 있기 때문
하지만 Primary에서 실행한 경우만 Versioned Query를 사용하며 Secondary에서는 버전 정보를 포함하지 않음(Unversioned Query)
Shard key를 포함한 쿼리의 경우 특정 샤드로만 쿼리가 전달되므로 해당 샤드가 가진 청크에 포함된 Document만 반환
Shard Key가 없으며, Secondary에서 조회하는 경우 Document의 중복이 발생 가능성 존재
[ Multi-Document Transaction]
Mongodb Client API도 반드시 4.2 버전으로 사용
4.4 부터 명시적으로 Transaction 내에서 collection 을 생성 가능(Client API 또한 4.4로 사용해야 가능)
MongoDB 버전 4.0부터 제공되었지만, Replica Sets 환경에서 만 지원되었으며 4.2부터 Shard-Cluster 환경에서도 지원
Multi-Document Transation 은 여러 작업, Collection, DB에 적용할 수 있으며 Transaction 이 Commit 되면 변경된 모든 데이터를 저장하고 Rollback 되면 모든 데이터 변경을 취소
Commit 이 확정될 때까지 변경 중인 데이터는 누구도 참조할 수 없음( dirty_read : no)
Embedded Document 및 Array 구조와 같은 단일-Dcoument Transaction 에 비해 성능지연 문제가 발생할 가능성이 있기 때문에, 이를 대체해서 사용하면 안됨
FeatureCompatibility Version(fCV) 4.0 이후 환경에서 사용할 수 있으며 wiredTiger Storage Engine과 In-Memory Storage Engine에서 만 사용할수 있음(admin DB에서 설정 가능)db.adminCommand({ getParameter:1, featureCompatibilityVersion:1})