
TL;DR
MongoDB Atlas에서 Running중인 Session을 Kill 하는 방법입니다.
IT Journeyman
DBA의 고난한 일 중에 하나가 악성 쿼리를 날리거나 Deadlock을 일으킨 세션을 찾아 Kill하는 일입니다.
MongoDB에서 Dealock은 자주 발생하지는 않습니다만, 악성 쿼리는 간혹 발생합니다. 그 때 해당 세션을 정리하는 방법입니다.
Oracle에서는 RESOURCE_LIMIT을 TRUE로 설정하고 Profile을 설정하여 일정 이상의 리소스를 사용하는 세션의 오퍼레이션을 중단시키는 기능이 있습니다만, 그게 그렇게 적용하기가 쉽지 않았습니다. MongoDB의 Deadlock관련해서는 이 링크를 [DB Internal]Deadlock 참조하시기 바랍니다.
Table of Contents
1. killSessions
1-1. Run Long Running Operation at MongoShell
1-2. 3초 이상 실행 중인 세션을 조회하는 명령어
1-3. Output : 3초 이상 실행 중인 세션을 조회하는 명령어
1-4. 실행 중인 세션을 Kill하는 명령어
1-5. 실행 중인 세션에서의 에러메시지
1-6. 특정 네임스페이스에서 3초 이상 실행 중인 세션을 조회하는 명령어
Appendix
Long Running Query with sample_airbnb.listingsAndReviews
1. killSessions
1-1. Run Long Running Operation at MongoShell
(Query longops.js는 Appendix에)
Atlas atlas-10wsuf-shard-0 [primary] test> load('./longops.js');
Query started at: 2024-09-11T01:08:35.834Z
Query executed successfully. Number of results: 1000
Query ended at: 2024-09-11T01:09:25.829Z
Total execution time: 49995 ms (49.995 seconds)
true
1-2. 3초 이상 실행 중인 세션을 조회하는 명령어
longops.js 수행 후, 3초 이후에 아래 명령을 실행
db.adminCommand({
currentOp: 1,
"$and": [
{ "secs_running": { "$gt": 3 } } // 3초 이상 실행 중인 작업 필터링
]
});
1-3. Output : 3초 이상 실행 중인 세션을 조회하는 명령어
{
inprog: [
{
type: 'op',
host: 'atlas-10wsuf-shard-00-01.npgjj.mongodb.net:27017',
desc: 'conn6671',
connectionId: 6671,
client: '58.123.207.194:50933',
appName: 'mongosh 2.2.15',
clientMetadata: {
application: { name: 'mongosh 2.2.15' },
driver: { name: 'nodejs|mongosh', version: '6.8.0|2.2.15' },
platform: 'Node.js v22.5.1, LE',
os: {
name: 'darwin',
architecture: 'arm64',
version: '23.6.0',
type: 'Darwin'
}
},
active: true,
currentOpTime: '2024-09-11T01:28:16.167+00:00',
effectiveUsers: [ { user: 'it_admin', db: 'admin' } ],
threaded: true,
opid: 3585502,
lsid: {
id: UUID('a571e5ce-1122-42af-9877-66d402278a33'),
uid: Binary.createFromBase64('o8JNkQa8jG+IuXCheqNUlAplY+1r+G3GFRMzpNnbB+k=', 0)
},
secs_running: Long('14'),
microsecs_running: Long('14040717'),
op: 'command',
ns: 'sample_airbnb.listingsAndReviews',
redacted: false,
command: {
aggregate: 'listingsAndReviews',
pipeline: [
{
'$match': { 'review_scores.review_scores_rating': [Object] }
},
{
'$lookup': {
from: 'listingsAndReviews',
localField: 'host.host_id',
foreignField: 'host.host_id',
as: 'same_host_listings'
}
},
{ '$unwind': '$same_host_listings' },
{
'$group': {
_id: '$host.host_id',
totalListings: [Object],
averageRating: [Object],
totalReviews: [Object]
}
},
{ '$sort': { totalListings: -1 } },
{ '$limit': 1000 }
],
cursor: {},
apiVersion: '1',
lsid: { id: UUID('a571e5ce-1122-42af-9877-66d402278a33') },
'$clusterTime': {
clusterTime: Timestamp({ t: 1726017267, i: 1 }),
signature: {
hash: Binary.createFromBase64('9KCBQmgeZS0Dt2Uthje4Y1WPC4E=', 0),
keyId: Long('7381693487713878021')
}
},
'$db': 'sample_airbnb'
},
queryFramework: 'classic',
planSummary: 'COLLSCAN',
numYields: 5658,
locks: { FeatureCompatibilityVersion: 'r', Global: 'r' },
waitingForLock: false,
lockStats: {
FeatureCompatibilityVersion: { acquireCount: { r: Long('7921') } },
Global: { acquireCount: { r: Long('7921') } }
},
waitingForFlowControl: false,
flowControlStats: {}
}
],
ok: 1,
'$clusterTime': {
clusterTime: Timestamp({ t: 1726018087, i: 1 }),
signature: {
hash: Binary.createFromBase64('pWdpmpcG7dfQ2pNZ2GUTfqU5sk0=', 0),
keyId: Long('7381693487713878021')
}
},
operationTime: Timestamp({ t: 1726018087, i: 1 })
}
1-4. 실행 중인 세션을 Kill하는 명령어
1-3에서 확인 opid를 입력하여 아래 명령을 실행
// 특정 opid를 종료하는 명령어
db.killOp(3602659);
해당 명령이 성공적으로 수행됨을 확인(ok: 1)
Atlas atlas-10wsuf-shard-0 [primary] test> db.killOp(3602659);
{
info: 'attempting to kill op',
ok: 1,
'$clusterTime': {
clusterTime: Timestamp({ t: 1726018577, i: 1 }),
signature: {
hash: Binary.createFromBase64('S2xZUG2IX8JyBVvvF3jl41kpAbI=', 0),
keyId: Long('7381693487713878021')
}
},
operationTime: Timestamp({ t: 1726018577, i: 1 })
}
1-5. 실행 중인 세션에서의 에러메시지
Atlas atlas-10wsuf-shard-0 [primary] test> load('./longops.js');
Query started at: 2024-09-11T01:36:03.817Z
MongoServerError[Interrupted]: PlanExecutor error during aggregation :: caused by :: operation was interrupted
Atlas atlas-10wsuf-shard-0 [primary] test>
1-6. 특정 네임스페이스에서 3초 이상 실행 중인 세션을 조회하는 명령어
db.adminCommand({
currentOp: 1,
"$and": [
{ "secs_running": { "$gt": 3 } }, // 3초 이상 실행 중인 작업
{ "ns": "sample_airbnb.listingsAndReviews" } // 특정 네임스페이스 (예: your_database.your_collection)
]
})
Appendix
Long Running Query with sample_airbnb.listingsAndReviews
// 시작 시간 기록
const startTime = new Date();
print("Query started at: " + startTime.toISOString());
// 쿼리 실행
const result = db.getSiblingDB("sample_airbnb").listingsAndReviews.aggregate([
{
$match: {
"review_scores.review_scores_rating": { $gte: 80 }
}
},
{
$lookup: {
from: "listingsAndReviews",
localField: "host.host_id",
foreignField: "host.host_id",
as: "same_host_listings"
}
},
{
$unwind: "$same_host_listings"
},
{
$group: {
_id: "$host.host_id",
totalListings: { $sum: 1 },
averageRating: { $avg: "$review_scores.review_scores_rating" },
totalReviews: { $sum: "$number_of_reviews" }
}
},
{
$sort: { totalListings: -1 }
},
{
$limit: 1000
}
]);
// 결과 개수 출력 (옵션)
print("Query executed successfully. Number of results: " + result.toArray().length);
// 종료 시간 기록
const endTime = new Date();
print("Query ended at: " + endTime.toISOString());
// 수행 시간 계산 (밀리초)
const executionTime = endTime - startTime;
print("Total execution time: " + executionTime + " ms (" + (executionTime / 1000) + " seconds)");
'T. > MongoDB' 카테고리의 다른 글
| MongoDB Certifications Tips (1) | 2025.02.19 |
|---|---|
| [AI]Enable Natural Language Querying (1) | 2024.09.25 |
| [DB Internal]Deadlock (0) | 2024.08.07 |
| [Data Lake]Atlas Data Federation (0) | 2024.07.30 |
| [Sizing]Extended Storage Sizes (0) | 2024.07.27 |