1. MongoDB 잠금
MongoDB 서버에서는 멀티 쓰레드의 동시 처리 중에 발생할 수 있는 쓰레드 간의 충돌 문제를 방지하기 위해 잠금을 사용한다.
1-1. MongoDB 잠금유형
유형 | 설명 |
묵시적 잠금 | 쿼리가 실행될 때 자동으로 획득했다 해제되는 잠금 |
명시적 잠금 | 사용자가 명령어로 잠금을 획득 |
2. MongoDB 테스트 버전
유형 | 버전 | 구성 |
mongosh | 2.2.10 | |
mongodb | 7.0.12 | Config : 1개, 포트 20000 Route : 1개, 포트 20001 Shard1 : 1개, 포트 30001 Shard2 : 1개, 포트 40001 |
3. 글로벌 잠금 획득 해제
3-1. fsyncLock 로 획득
fsyncLock 은 글로벌 잠금을 획득하는 함수이다.
MongoDB 서버 인스턴스에 단 하나만 있는 잠금으로, 이를 인스턴스 잠금이라고 한다.
아래와 같은 명령어로 잠금을 획득할 수 있다.
db.fsyncLock( { fsync : 1, lock : true } )
fsync 옵션을 1로 설정하면 디스크에 기록되지 못한 데이터를 모두 디스크로 플러시한다.
lock 옵션이 true 이면 글로벌 잠금을 획득한다. 만약 false 면 데이터파일만 디스크로 플러시하고 잠금을 걸지는 않는다.
3-2. fsyncUnLock 으로 해제
fsyncUnLock 으로 글로벌 잠금을 해제한다.
db.fsyncUnlock()
4. 글로벌 잠금 lock=true 테스트
4-1. Session1 적재
글로벌잠금이 활성화 되기 전 적재가 잘 되고 있다.
[direct: mongos] fsyncDB> db.fsynCollection.insert( { "id" : 1, "description" : "Before fsyncLock" } )
DeprecationWarning: Collection.insert() is deprecated. Use insertOne, insertMany, or bulkWrite.
{
acknowledged: true,
insertedIds: { '0': ObjectId('66c52b881b30070ca91b157d') }
}
4-2. Session 2 글로벌잠금 획득
fsyncLock 함수를 사용하여 글로벌 잠금을 획득한다.
글로벌잠금을 획득하면 info 에 now locked against writes 가 출력된다.
[direct: mongos] test> db.fsyncLock( { fsync : 1, lock : true } )
{
numFiles: 1,
all: {
raw: {
'rs2/127.0.0.1:40001': {
info: 'now locked against writes, use db.fsyncUnlock() to unlock',
lockCount: Long('1'),
seeAlso: 'http://dochub.mongodb.org/core/fsynccommand',
ok: 1
},
'rs1/127.0.0.1:30001': {
info: 'now locked against writes, use db.fsyncUnlock() to unlock',
lockCount: Long('1'),
seeAlso: 'http://dochub.mongodb.org/core/fsynccommand',
ok: 1
},
'configRepl/127.0.0.1:20000': {
info: 'now locked against writes, use db.fsyncUnlock() to unlock',
lockCount: Long('1'),
seeAlso: 'http://dochub.mongodb.org/core/fsynccommand',
ok: 1
}
}
},
ok: 1,
'$clusterTime': {
clusterTime: Timestamp({ t: 1724197771, i: 1 }),
signature: {
hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0),
keyId: Long('0')
}
},
operationTime: Timestamp({ t: 1724197771, i: 1 })
}
참고로 글로벌잠금을 획득한 세션도 쓰기를 할 수 없다.
[direct: mongos] fsyncDB> db.fsynCollection.insert( { "id" : 3, "description" : "Global Lock Session" } )
4-3. Session 1 적재대기
이제 아래의 적재 명령어는 완료되지 못하고 대기하게 된다.
[direct: mongos] fsyncDB> db.fsynCollection.insert( { "id" : 2, "description" : "After fsyncLock" } )
4-5. Session 3 조회가능
같은 컬렉션과 다른 데이터베이스의 컬렉션을 조회할 때 모두 대기가 발생하지 않고 바로 조회된다.
[direct: mongos] fsyncDB> db.fsynCollection.find()
[
{
_id: ObjectId('66c52b881b30070ca91b157d'),
id: 1,
description: 'Before fsyncLock'
}
]
[direct: mongos] fsyncDB> use indexDB()
switched to db indexDB
[direct: mongos] indexDB> db.ttlIndex.find()
[
{
_id: ObjectId('66baf3d401027809e11b1585'),
Number: 4,
createdAt: 'Sample String'
},
{
_id: ObjectId('66bb014c28fe1d22af1b157e'),
Number: 1,
createdAt: '2024-08-10T05:42:36.666Z'
}
]
4-6. Session 2 글로벌잠금 해제
글로벌 잠금을 해제한다.
[direct: mongos] test> db.fsyncUnlock()
{
raw: {
'rs2/127.0.0.1:40001': { info: 'fsyncUnlock completed', lockCount: Long('1'), ok: 1 },
'configRepl/127.0.0.1:20000': { info: 'fsyncUnlock completed', lockCount: Long('1'), ok: 1 },
'rs1/127.0.0.1:30001': { info: 'fsyncUnlock completed', lockCount: Long('1'), ok: 1 }
},
ok: 1,
'$clusterTime': {
clusterTime: Timestamp({ t: 1724197771, i: 1 }),
signature: {
hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0),
keyId: Long('0')
}
},
operationTime: Timestamp({ t: 1724197771, i: 1 })
}
4-7. Session 1 적재
글로벌잠금이 해제될 때 적재가 시도된 Session 1 의 적재가 완료된다.
[direct: mongos] fsyncDB> db.fsynCollection.insert( { "id" : 2, "description" : "After fsyncLock" } )
5. 글로벌 잠금 lock=false 테스트
5-1. Session2 글로벌잠금 획득
[direct: mongos] test> db.fsyncLock( { fsync : 1, lock : false } )
{
numFiles: 1,
all: {
raw: {
'rs2/127.0.0.1:40001': {
info: 'now locked against writes, use db.fsyncUnlock() to unlock',
lockCount: Long('1'),
seeAlso: 'http://dochub.mongodb.org/core/fsynccommand',
ok: 1
},
'configRepl/127.0.0.1:20000': {
info: 'now locked against writes, use db.fsyncUnlock() to unlock',
lockCount: Long('1'),
seeAlso: 'http://dochub.mongodb.org/core/fsynccommand',
ok: 1
},
'rs1/127.0.0.1:30001': {
info: 'now locked against writes, use db.fsyncUnlock() to unlock',
lockCount: Long('1'),
seeAlso: 'http://dochub.mongodb.org/core/fsynccommand',
ok: 1
}
}
},
ok: 1,
'$clusterTime': {
clusterTime: Timestamp({ t: 1724201731, i: 1 }),
signature: {
hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0),
keyId: Long('0')
}
},
operationTime: Timestamp({ t: 1724201731, i: 1 })
}
5-2. Session1 적재대기
여전히 적재는 대기한다. 스터디하는 책의 설명과는 다른부분이 있어 7버전에서는 변경되었나 싶다.
참고로 아래 6. 에서 설명하는 currentOp 에서 fsyncLock 필드값은 true 로 되어있다.
[direct: mongos] fsyncDB> db.fsynCollection.insert( { "id" : 4, "description" : "After fsyncLock lock=false" } )
6. 글로벌 잠금 설정 확인
currentOp 명령으로 확인이 가능하다. 필드명중 fsyncLock 이 true 값을 가진다.
만약 글로벌잠금이 해제되어 있다면 fsyncLock 필드가 조회되지 않는다.
[direct: mongos] fsyncDB> db.currentOp()
{
inprog: [
{
shard: 'rs2',
fsyncLock: true,
type: 'op',
host: 'ip-172-31-7-169.ap-northeast-2.compute.internal:40001',
desc: 'Checkpointer',
active: true,
currentOpTime: '2024-08-21T00:26:38.863+00:00',
opid: 'rs2:28779150',
op: 'none',
ns: '',
redacted: false,
command: {},
numYields: 0,
locks: {},
waitingForLock: false,
lockStats: {},
waitingForFlowControl: false,
flowControlStats: {}
},
{
shard: 'rs2',
fsyncLock: true,
type: 'op',
host: 'ip-172-31-7-169.ap-northeast-2.compute.internal:40001',
desc: 'OplogCapMaintainerThread-local.oplog.rs',
active: true,
currentOpTime: '2024-08-21T00:26:38.863+00:00',
opid: 'rs2:17',
op: 'none',
ns: '',
redacted: false,
command: {},
numYields: 0,
locks: {},
waitingForLock: false,
lockStats: {
FeatureCompatibilityVersion: { acquireCount: { w: Long('1') } },
ReplicationStateTransition: { acquireCount: { w: Long('1') } },
Global: { acquireCount: { w: Long('1') } }
},
waitingForFlowControl: false,
flowControlStats: {}
},
{
shard: 'rs2',
fsyncLock: true,
...
}
'Database > MongoDB 실습' 카테고리의 다른 글
[MongoDB] OpLog 로 현재실행중인 쿼리 상태조회 (0) | 2024.08.21 |
---|---|
[MongoDB] Yield 잠금 테스트 (0) | 2024.08.21 |
[MongoDB] TTL 인덱스 생성과 도큐먼트 적재 (0) | 2024.08.13 |
[MongoDB] Partial 인덱스 생성과 주의사항 (0) | 2024.08.12 |
[MongoDB] 유니크 인덱스 생성 방법 (0) | 2024.08.12 |