본문 바로가기
T./MongoDB

[DB Internel]killSessions, 누가 이거 돌렸어 !

by IT Journeyman 2024. 8. 16.

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