[카테고리:] MongoDB

  • MongoDB에서 Oplog 사이즈 확인하는 법

    MongoDB에서 Oplog 사이즈 확인하는 법

    MongoDB에서 Oplog 사이즈 확인하는 법

    MongoDB의 oplog(Operation Log, 작업 로그)는 MongoDB 복제(replication)에서 사용되는 특별한 컬렉션으로, 변경 사항을 기록하는 역할.

    📦 oplog란?

    • oplog(rs.oplog)는 MongoDB 복제 세트(replica set)에서 Primary 노드의 데이터 변경 사항을 기록하는 컬렉션입니다.

    • Secondary 노드는 Primary의 oplog를 읽고 동일한 작업을 수행하여 데이터를 동기화함.

    • 컬렉션 이름: local.oplog.rs

    • Capped Collection(고정 크기 컬렉션)으로 동작하며, 일정 크기가 차면 가장 오래된 데이터부터 삭제!

    📦 oplog의 동작 방식

    1. Primary 노드에서 변경 발생

    • insert, update, delete 작업이 수행될 때, oplog에 기록됨.

    2. Secondary 노드가 oplog를 읽음

    • Secondary 노드는 Primary의 oplog를 주기적으로 읽어 적용함.

    3. 동기화 유지

    • Primary에서 발생한 변경 사항을 Secondary가 동일하게 수행하여 데이터 일관성을 유지.

    📦 oplog 확인 방법

    MongoDB에서 oplog를 직접 확인하려면 아래 명령을 실행

    use local
    db.oplog.rs.find().limit(10).pretty()
    • local 데이터베이스에 oplog.rs 컬렉션이 저장.
    • 위 명령을 실행하면 최근 10개의 oplog 항목을 확인가능.

    📦 oplog 항목 예시

    {
       "ts" : Timestamp(1712432874, 1),
       "t" : NumberLong(2),
       "h" : NumberLong("890273918273918273"),
       "v" : 2,
       "op" : "i",
       "ns" : "mydb.users",
       "o" : {
           "_id" : ObjectId("65f3b69ad2b3e6b5d3a6f6d1"),
           "name" : "Alice",
           "age" : 28
       }
    }
    • “op”: 작업 유형 (“i”: insert, “u”: update, “d”: delete)
    • “ns”: 네임스페이스(데이터베이스 및 컬렉션 정보)
    • “o”: 변경된 문서 내용.

    📦 oplog의 크기 확인 및 조정

    • oplog의 크기를 확인
    db.getReplicationInfo()
    • oplog 크기를 늘리려면 (예: 10GB)
    db.adminCommand({ replSetResizeOplog: 1, size: 10240 })

    🚀 정리.

    • oplog는 MongoDB 복제(replication)에서 Primary의 변경 사항을 기록하는 로그
    • Secondary 노드는 oplog를 읽고 동일한 작업을 수행하여 데이터 일관성을 유지
    • oplog 크기가 고정되어 있으며, 오래된 로그는 자동으로 삭제
  • MongoDB 설치한 OS 에서 “Too many open files” 에러 발생 시 해결 가이드

    MongoDB 설치한 OS 에서 “Too many open files” 에러 발생 시 해결 가이드

    Linux 서버(여기선 AWS EC2)를 운영하다보면 어제만해도 잘 돌아가던 서버 어플리케이션이 “Too many open files” 에러를 뱉고 죽는 현상이 발생함.

    이런 오류가 생기는 이유는 프로세스가 OS에 요청할수 있는 리소스의 개수/양 (여기서는 NOFILE 이라 불리는 최대 Open 가능한 파일 개수)에 Limit가 있고, 프로세스가 그 제한을 넘었기 때문이다.

    해결방법

    각 프로세스의 Limit는 그 프로세스가 실행되는 계정의 Limit를 바탕으로 만들어지므로 프로세스의 Limit를 올려준다고 해서 문제가 해결되진 않는다. 계정과 프로세스 모두 변경해 주어야 그 프로세스를 다시 시작했을때에도 같은 문제가 생기지 않음.

    $ ulimit -Hn
    4096
    $ ulimit -Sn
    1024

    Limit는 Soft와 Hard 2가지가 있는데 Soft Limit은 non-root 계정에서도 설정 가능하며 일시적으로 이를 넘어도 시스템 상에서 경고 이메일만 보낼뿐 큰 문제가 되지 않지만 Hard Limit는 root 계정에서만 세팅이 가능하고 절대로 넘을수 없는 Limit이다. Too many open files가 계속 발생하고 아예 기능이 동작하지 않을 경우 프로세스에 기본 할당된 Hard Limit를 넘었다고 볼수 있음.

    root 계정으로 /etc/security/limits.conf에 다음 내용을 추가.

    * hard nofile 500000
    * soft nofile 500000
    root hard nofile 500000
    root soft nofile 500000
    $ cat /proc/sys/fs/file-max

    계정에 할당된 Limit을 변경했다면 터미널을 로그아웃 했다가 다시 로그인 한 후에 앞에서 실행한 ulimit으로 값이 변경되어 있는지 확인해야 한다.

    이제 프로세스에 대한 Limit을 올려줄 차례다. 프로세스를 죽였다가 다시 살리면 되지만 운영환경에선 프로세스를 죽이면 안되는 때가 있음.

    방법

    $ ps -ef | grep foobar
    1234
    $ prlimit --nofile --output RESOURCE,SOFT,HARD --pid 1234
    $ prlimit --nofile=500000 --pid=1234

    이렇게 변경을 하면 Soft Limit과 Hard Limit이 동일하게 500000으로 맞춰진다. 다시 이전 command를 실행해서 더블체크.

  • MongoDB 에서 Replica Set Secondary Node 동기화 시간 확인하는 방법

    MongoDB 에서 Replica Set Secondary Node 동기화 시간 확인하는 방법

    MongoDB 에서 Replica Set Secondary Node 동기화 시간 확인하는 방법

    몽고디비 레플리카 셋으로 구축 되어 있을 때 secondary node가 primary node를 어느정도 동기화 하고 있는지, 알아 볼 수 있다.

    use admin
    db.auth({...})
    
    rs.printSecondaryReplicationInfo()

    나오는 시간이 Primary Node에 대해 동기화 하는 정도까지의 지연시간이다.

  • MongoDB DB 다운 시 재가동 방법

    MongoDB DB 다운 시 재가동 방법

    MongoDB DB 다운 시 재가동 방법

    mongoDB가 어떤 이유로 인해 DB 프로세스가 다운될 수 있다. 이유는 log를 살펴봐야한다. 보통 /var/log/mongodb/ 쪽에 기록되어 있다. 실제로 root로 접속 후, mongo가 죽었는지 확인해봐야 한다.

    mongo
    • 다시 살리는 code
    # root 권한으로.
    mongod --config /etc/mongod.conf

    만약에 다시 살리지 못하면, 백업 시켜둔 파일을 교체해서 다시 기동해야 한다.

    /var/lib/ 폴더를 봐야 한다.

    rm -rf mongo # 기존 파일 지우기.
    mv mongo.203.20240505 mongo # 파일 교체.

    그 다음, 재기동 해보자

    # root 권한으로.
    mongod --config /etc/mongod.conf

    그럼, 보통 재기동이 된다.

    이제, db단에서 레플리카셋 서버끼리 얼마나 동기화가 되었고, 지연이 얼마나 되는지 알아보자.

    ### 복제 지연 확인
    o 현재 어디까지 동기화를 진행했으며 얼마나 지연이 발생하는지 파악.
       PRIMARY> rs.printSecondaryReplicationInfo()
  • MongoDB 에서 wiredTiger engine 파일 찾는 법

    MongoDB 에서 wiredTiger engine 파일 찾는 법

    MongoDB 에서 wiredTiger engine 파일 찾는 법

    찾게 된 이유 : 몽고디비에서 CRUD를 할때 checksum이 match가 되지 않는 오류 발생 => 몽고디비 다운으로 이어졌다.

    log를 찾아보면, collection-218–4990451227493674325.wt 식의 파일 이름들이 보임.

    해당 wt파일이 어떤 database의 collection인지 찾아 볼 수 있음.

    from pymongo import MongoClient
    conn = MongoClient(host='host', port=port, username='username', password='password')
    databases = conn.list_database_names()
    # 몽고디비에서 wt파일 찾는 법.
    for db_name in databases:
        db = conn[db_name]
        collections = db.list_collection_names()
        for coll_name in collections:
            stats = db.command("collstats", coll_name)
            if 'wiredTiger' in stats and 'uri' in stats['wiredTiger']:
                uri = stats['wiredTiger']['uri']
                if "~~파일이름~~" in uri:
                    print(f"Found in {db_name}.{coll_name}")

    이렇게 하면 wt파일이 어느 database의 collection인지 찾아볼 수 있다.

  • MongoDB TooManyLogicalSessions 에러

    MongoDB TooManyLogicalSessions 에러

    ERROR Case
    pymongo.errors.OperationFailure: cannot add session into the cache, full error: {‘operationTime’: Timestamp(1714353661, 2), ‘ok’: 0.0, ‘errmsg’: ‘cannot add session into the cache’, ‘code’: 261, ‘codeName’: ‘TooManyLogicalSessions’, ‘$clusterTime’: {‘clusterTime’: Timestamp(1714353661, 2), ‘signature’: {‘hash’: b’\x81\xd5\x8f0[\x82\xcb{\xd8]\xd4\xba\x97\xc4\x0f+R \x88"’, ‘keyId’: 7317447343970713660}}}

    참고자료

    maxsession 관련 정보 :

    Maxsession 관련 정보의 reference

    서버세션 또는 논리적세션 명령 :

    서버세션 또는 논리적세션


    🚀 확인 Commmand

    ### 로지컬 세션 확인. (PRIMARY)
    # mongo
    mongo
    use admin
    db.auth({user:'', pwd:''})
    db.serverStatus().logicalSessionRecordCache

  • MongoDB 레플리카 셋 구축 가이드

    MongoDB 레플리카 셋 구축 가이드

    MongoDB 레플리카 셋 구축 가이드

    • 몽고디비 레플리카 셋 구축.

    ON-premise 서버 교체로 인해 몽고디비 레플리카셋 테스트의 기록

    몽고디비를 같은 버전으로 설치

    sudo vi /etc/yum.repos.d/mongodb-org-4.0.repo
    
    ---
    [mongodb-org-4.0]
    name=MongoDB Repository
    baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.0/x86_64/
    gpgcheck=1
    enabled=1
    gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc

    몽고디비 4.0.28 버전 설치

    sudo yum install -y mongodb-org-4.0.28

    설치되는 것들


    • mongodb-org-server: MongoDB 서버
    • mongodb-org-mongos: MongoDB의 라우팅 서버
    • mongodb-org-shell: MongoDB 셸 도구
    • mongodb-org-tools: 백업 및 복구 도구

    🚨 몽고디비 config 파일 구성을 바꾸거나, security 관련해서 키파일을 넣어주면 systemctl 로는 몽고디비 실행 불가.

    mongod --config /etc/mongod.conf

    이 명령어로 실행해야 함

    한개의 서버에 포트를 나누어 몽고디비 2개 실행

    포트를 나누는 conf 파일을 하나 더 만든다. 기존 mongod.conf 파일을 copy => mongod02.conf로..

    • 바뀌는 부분.
    • path: /var/log/mongodb02/mongod02.log
      dbPath: /var/lib/mongo02
      pidFilePath: /var/run/mongodb/mongod02.pid
    • 디렉토리는 직접 생성해줘야 함.
    • chmod, chown 둘 다 확인해야 함. => 안그러면 오류남.
    # mongod02.conf
    
    ---
    # for documentation of all options, see:
    #   http://docs.mongodb.org/manual/reference/configuration-options/
    # where to write logging data.
    systemLog:
      destination: file
      logAppend: true
      logRotate: rename
      path: /var/log/mongodb02/mongod02.log
    # Where and how to store data.
    storage:
      dbPath: /var/lib/mongo02
      journal:
        enabled: true
    #  engine:
    #  mmapv1:
    #  wiredTiger:
    # how the process runs
    processManagement:
      fork: true  # fork and run in background
      pidFilePath: /var/run/mongodb/mongod02.pid  # location of pidfile
      timeZoneInfo: /usr/share/zoneinfo
    # network interfaces
    net:
      port: 27018
      # bindIp: 127.0.0.1  # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.
      bindIp: 0.0.0.0
    security:
      keyFile: /etc/mongodb.key
      authorization: enabled
    #operationProfiling:
    replication:
      replSetName: rs0
    #sharding:
    ## Enterprise-Only Options
    #auditLog:
    #snmp:
    • 실행 하려면..
    mongod --config /etc/mongod02.conf
    
    ### 설정 포트에 몽고디비 접속하려면.
    mongo --port 27018

    replica set 설정

    먼저 primary로 원하는 서버에 들어가 mongo shell 접속. mongo shell 에서,

    use admin
    -> 계정을 안만들었으면, conf 파일에서 security를 주석 처리해준 다음, mongo shell 다시 들어와 admin 계정 생성.
    만든 다음, conf 파일에서 security 주석 제거 한 다음, mongo shell 들어와서,
    rs.initiate({
      _id: "설정한 레플리카 셋 이름",
      members: [
        { _id: 0, host: "primary_host:27017" },     // Primary 노드
        { _id: 1, host: "secondary_host_1:27017" }, // Secondary 노드
        { _id: 2, host: "secondary_host_2:27017" }  // Secondary 노드
      ]
    })
    이런식으로, 코드 날리기.

    rs.status() 로 상태확인 하기

    포트는 열려 있어야 함. 포트 안열리면 통신 안됨 (27017)

  • Mongo DB | Logical Session vs 일반 Session

    Mongo DB | Logical Session vs 일반 Session

    몽고디비에서는 일반적으로 사용되는 세션과 Logical Session 두 가지 유형의 세션이 있습니다.

    일반 세션(Session):
    이전 버전의 MongoDB에서 사용되는 일반적인 세션입니다.
    클라이언트가 데이터베이스와 상호 작용할 때 일반 세션을 사용하여 트랜잭션을 관리합니다.
    클라이언트가 데이터를 변경할 때 해당 변경 사항을 확정(commit)하거나 취소(abort)할 수 있습니다.

    Logical Session (논리적 세션):
    MongoDB 4.0부터 도입된 개념으로, 클라이언트와 서버 간의 통신을 추적하는 데 사용됩니다.
    Logical Session은 트랜잭션을 실행하거나 관리하는 것이 아니라, 클라이언트와 데이터베이스 간의 일관된 상태를 유지하기 위해 사용됩니다.
    Logical Session은 일련의 연속적인 데이터베이스 작업에 대해 일관된 뷰를 제공하고, 장애 복구 시 클라이언트 상태를 복원하는 데 도움이 됩니다.
    따라서 Logical Session은 단일 트랜잭션을 관리하는 데 사용되지 않고, 클라이언트 상태를 유지하고 일관된 뷰를 제공하는 데 사용됩니다. 일반 세션은 트랜잭션 관리에 중점을 두고 있습니다.

    Session 별 최대 허용 갯수

    일반 세션(Session)의 최대 허용 갯수:
    MongoDB의 구성 파일(/etc/mongod.conf)에서 maxSession 또는 maxClientSessions와 같은 매개변수를 통해 설정할 수 있습니다.
    MongoDB의 기본 설정은 일반적으로 수천 개의 세션을 지원할 수 있도록 되어 있습니다.
    그러나 MongoDB가 실행 중인 호스트의 메모리 및 기타 자원에 따라 최대 허용 세션 수가 달라질 수 있습니다.

    Logical Session (논리적 세션)의 최대 허용 갯수:
    논리적 세션은 클라이언트와 서버 간의 통신을 추적하는 데 사용되므로, 일반적으로 매우 많은 수의 세션을 생성할 수 있습니다.
    MongoDB의 구성 파일을 통해 논리적 세션의 최대 허용 수를 직접 설정할 필요는 없습니다. 이러한 세션은 MongoDB 서버의 리소스를 직접적으로 소모하지 않으므로 일반적으로 제한되는 경우는 드물습니다.