채워진 컬렉션을 기반으로 하는 인덱스 빌드
이 페이지의 내용
인덱스 빌드는 인덱스 빌드의 시작과 끝에서 컬렉션에 대한 독점 잠금을 유지하는 최적화된 빌드 프로세스를 사용합니다. 빌드 프로세스의 나머지 부분은 읽기 및 쓰기 작업과 교차하여 진행됩니다. 인덱스 빌드 프로세스 및 잠금 동작에 대한 자세한 설명은 인덱스 빌드 프로세스를 참조하세요.
복제본 세트 또는 샤딩된 클러스터에서 인덱스 빌드가 데이터를 보유한 모든 복제본 세트 멤버에서 동시에 진행됩니다. 프라이머리는 인덱스를 사용할 준비가 되었다고 표시하기 전에 빌드를 완료해야 하는 최소한의 데이터 보유 투표 멤버(자신 포함)를 요구합니다. '투표' 멤버는 members[n].votes
가 0
보다 큰 모든 복제본 세트 멤버를 말합니다. 자세한 내용은 복제된 환경에서의 인덱스 빌드를 참조하세요.
MongoDB 7.1부터 오류 보고 속도가 빨라지고 회복 탄력성이 향상되어 인덱스 빌드가 개선되었습니다. 디스크 공간이 너무 부족하면 인덱스 빌드를 중지하는 새로운 indexBuildMinAvailableDiskSpaceMB
매개 변수를 사용하여 인덱스 빌드에 필요한 최소 사용 가능한 디스크 공간을 설정할 수도 있습니다.
다음 표에서는 MongoDB 7.1부터 인덱스 빌드 동작을 이전 버전과 비교합니다.
MongoDB 7.1부터 시작되는 동작 | 이전 MongoDB 버전의 동작 |
---|---|
중복 키 오류를 제외하고 컬렉션 스캔 단계에서 발견된 인덱스 오류는 즉시 반환된 후 인덱스 빌드가 중지됩니다. 이전 MongoDB 버전은 인덱스 빌드가 거의 끝날 무렵에 발생하는 커밋 단계에서 오류를 반환합니다. MongoDB 7.1을 사용하면 인덱스 오류를 신속하게 진단할 수 있습니다. 예를 들어 호환되지 않는 인덱스 값 형식이 발견되면 오류가 즉시 반환됩니다. | 인덱스 빌드 오류는 커밋 단계에서 인덱스 빌드가 끝날 무렵에 오류가 반환되기 때문에 MongoDB 7.1에 비해 반환하는 데 시간이 오래 걸릴 수 있습니다. |
인덱스 빌드 오류로 인해 세컨더리 멤버가 충돌할 수 있습니다. | |
인덱스 빌드를 위한 디스크 공간 관리가 개선되었습니다. 사용 가능한 디스크 공간이 indexBuildMinAvailableDiskSpaceMB 매개변수에 지정된 최소값보다 작으면 인덱스 빌드가 자동으로 중지될 수 있습니다. 노드가 인덱스 커밋에 이미 투표한 경우 인덱스 빌드가 중단되지 않습니다. | 사용 가능한 디스크 공간이 부족한 경우 인덱스 빌드가 중지되지 않습니다. |
참고
Atlas에서 인덱스를 만드는 방법에 대한 자세한 내용은 Atlas 설명서의 인덱스 관리 페이지를 참조하세요.
행동
포 그라운드(Foreground) 및 백그라운드 빌드와의 비교
이전 버전의 MongoDB는 전경 또는 배경에서 인덱스 빌드를 지원했습니다. 전경 인덱스 빌드는 속도가 빠르고 더 효율적인 인덱스 데이터 구조를 생성하지만, 빌드 기간 동안 컬렉션의 상위 데이터베이스에 대한 모든 읽기-쓰기 액세스를 차단해야 했습니다. 전경 인덱스 빌드는 속도가 느리고 결과 효율성이 낮았지만 빌드 프로세스 중에 데이터베이스 및 해당 컬렉션에 대한 읽기-쓰기 액세스를 허용했습니다.
이제 인덱스 빌드는 메타데이터 변경을 보호하기 위해 빌드 프로세스의 시작과 종료 중에 인덱싱 중인 컬렉션에만 독점 잠금을 적용합니다. 빌드 프로세스의 나머지 부분은 백그라운드 인덱스 빌드의 양보 행위를 사용하여 구축 중 컬렉션의 읽기-쓰기 액세스를 최대화합니다. 인덱스 빌드는 보다 허용적인 잠금 동작에도 불구하고 여전히 효율적인 인덱스 데이터 구조를 생성합니다.
최적화된 인덱스 빌드 성능은 최소한 배경 인덱스 빌드와 동등합니다. 빌드 프로세스 중에 업데이트를 거의 또는 전혀 수신하지 않는 워크로드의 경우, 최적화된 인덱스 빌드는 동일한 데이터에 대한 전경 인덱스 빌드만큼 빠를 수 있습니다.
db.currentOp()
를 사용하여 진행 중인 인덱스 빌드의 진행 상황을 모니터링합니다.
MongoDB는 createIndexes
또는 해당 셸 헬퍼인 createIndex()
및 createIndexes()
에 지정된 background
인덱스 빌드 옵션을 무시합니다.
인덱스 빌드 중 제약 조건 위반
고유 인덱스와 같이 컬렉션에 제약 조건을 적용하는 인덱스의 경우, mongod
는 인덱스 빌드가 완료된 후에 모든 기존 문서와 동시에 작성된 문서를 검사하여 해당 제약 조건을 위반하는지 확인합니다. 인덱스 제약 조건을 위반하는 문서가 인덱스 빌드 중에 존재할 수 있습니다. 빌드가 끝날 때 인덱스 제약 조건을 위반하는 문서가 있으면 mongod
이 빌드를 종료하고 오류를 발생시킵니다.
예를 들어 채워진 컬렉션 inventory
을 생각해 보세요. 관리자가 product_sku
필드에 고유 인덱스를 만들고자 한다고 가정해 봅시다. 컬렉션 내의 문서들이 product_sku
필드에 대해 중복된 값을 가지고 있어도 인덱스 빌드는 성공적으로 시작할 수 있습니다. 하지만 빌드가 끝날 때까지 위반 사항이 여전히 존재한다면 mongod
는 빌드를 종료하고 오류를 발생시킵니다.
마찬가지로 인덱스 빌드가 진행되는 동안 애플리케이션이 product_sku
값을 중복하여 inventory
컬렉션에 문서를 성공적으로 작성할 수 있습니다. 하지만 빌드가 끝날 때까지 위반 사항이 여전히 존재한다면 mongod
는 빌드를 종료하고 오류를 발생시킵니다.
제약 조건 위반으로 인한 인덱스 빌드 실패 위험을 줄이기 위해서는 다음 조치를 취해야 합니다:
컬렉션 내의 문서들이 인덱스 제약 조건을 위반하지 않는지 확인합니다.
위반 없는 쓰기 작업을 보장할 수 없는 애플리케이션의 컬렉션에 대한 모든 쓰기를 중.
샤드 컬렉션
여러 샤드에 분산된 샤드 컬렉션의 경우 하나 이상의 샤드에 중복 문서가 있는 청크가 포함될 수 있습니다. 따라서 인덱스 생성 작업은 일부 샤드(즉, 중복이 없는 샤드)에서는 성공하지만 다른 샤드(즉, 중복이 있는 샤드)에서는 실패할 수 있습니다. 샤드 간에 일관성 없는 인덱스가 남지 않도록 하려면 mongos
에서 db.collection.dropIndex()
실행을 통해 컬렉션에서 인덱스를 제거할 수 있습니다.
이러한 상황이 발생할 위험을 줄이려면 인덱스를 만들기 전에 다음을 수행하세요.
컬렉션 내의 문서들이 인덱스 제약 조건을 위반하지 않는지 확인합니다.
위반 없는 쓰기 작업을 보장할 수 없는 애플리케이션의 컬렉션에 대한 모든 쓰기를 중.
최대 동시 인덱스 빌드.
기본적으로 서버는 최대 3개의 동시 인덱스 빌드를 허용합니다. 허용되는 동시 인덱스 빌드 수를 변경하려면 maxNumActiveUserIndexBuilds
매개 변수를 수정합니다.
동시에 진행되는 인덱스 빌드의 수가 maxNumActiveUserIndexBuilds
에 의해 지정된 한도에 도달하면, 서버는 추가 인덱스 빌드를 차단하고 동시 인덱스 빌드의 수가 한도 아래로 떨어질 때까지 기다립니다.
인덱스 작성이 데이터베이스 성능에 미치는 영향
쓰기 작업량이 많은 워크로드 중 인덱스 빌드
대상 컬렉션에 쓰기 부하가 많은 기간에 인덱스를 빌드하면 쓰기 성능이 저하되고 인덱스 빌드 시간이 길어질 수 있습니다.
애플리케이션이 컬렉션에 대한 쓰기 작업을 중지하거나 줄이는 유지 관리 기간을 지정하는 것이 좋습니다. 빌드 프로세스의 잠재적인 부정적인 영향을 완화하려면 이 유지 관리 기간 동안 인덱스 빌드를 시작하세요.
사용 가능한 시스템 메모리(RAM) 부족
createIndexes
는 컬렉션에 하나 이상의 인덱스 빌드를 지원합니다. createIndexes
는 메모리와 디스크의 임시 파일 조합을 사용하여 인덱스 빌드를 완료합니다. createIndexes
의 메모리 사용량에 대한 기본 제한은 200MB이며 단일 createIndexes
명령을 사용하여 빌드된 모든 인덱스 간에 공유됩니다. 메모리 제한에 도달하면 createIndexes
는 --dbpath
디렉토리 내의 _tmp
라는 하위 디렉토리에 있는 임시 디스크 파일을 사용하여 빌드를 완료합니다.
maxIndexBuildMemoryUsageMegabytes
서버 매개변수를 설정하여 메모리 제한을 덮어쓸 수 있습니다. 메모리 제한을 높게 설정하면 인덱스 빌드가 더 빨리 완료될 수 있습니다. 하지만 이 제한을 시스템의 미사용 RAM에 비해 너무 높게 설정하면 메모리가 고갈되고 서버가 종료될 수 있습니다.
호스트 컴퓨터의 사용 가능한 여유 RAM이 제한적일 경우, 시스템 RAM을 늘리기 위해 유지 관리 시간을 예약할 필요가 있을 수 있습니다. 이는 mongod
의 RAM 사용량을 조정하기 전에 필요한 조치입니다.
복제된 환경에서의 인덱스 빌드
참고
featureCompatibilityVersion 4.4 이상이 필요합니다.
복제본 세트 또는 샤딩된 클러스터에서 인덱스 빌드가 데이터를 보유한 모든 복제본 세트 멤버에서 동시에 진행됩니다. 샤딩된 클러스터의 경우 인덱스 빌드는 인덱싱되는 컬렉션에 대한 데이터가 포함된 샤드에서만 발생합니다. 프라이머리에는 인덱스를 사용할 준비가 된 것으로 표시하기 전에 빌드를 완료해야 하는 자신을 포함한 최소한의 데이터 보유 voting
멤버(즉, 쿼럼 커밋)가 필요합니다.
중요
데이터를 보유하는 투표 노드 에 연결할 수 없게 되고 commitQuorum 이 기본값 votingMembers
로 설정하다 되면 해당 노드 가 온라인 가 될 때까지 인덱스 빌드가 중단될 수 있습니다.
빌드 프로세스는 다음과 같이 요약됩니다:
프라이머리는
createIndexes
명령을 받고 즉시 "startIndexBuild" oplog 항목을 생성하여 인덱스 빌드와 연결합니다.세컨더리는 "startIndexBuild" oplog 항목을 복제한 후 인덱스 빌드를 시작합니다.
컬렉션의 데이터 인덱싱이 완료되면 각 멤버가 빌드를 커밋하기 위해 '투표'합니다.
세컨더리 멤버는 프라이머리 멤버가 투표 쿼럼을 확인하기를 기다리는 동안 인덱스에 대한 새로운 쓰기 작업을 처리합니다.
투표 쿼럼을 확보한 후 프라이머리는 중복 키 오류와 같은 키 제약 조건 위반을 검사합니다.
키 제약 조건 위반 사항이 없으면 프라이머리는 인덱스 빌드를 완료하고, 인덱스를 사용할 준비가 되었음을 표시한 후 "commitIndexBuild" oplog 항목을 생성합니다.
키 제약 조건 위반이 있는 경우 인덱스 빌드가 실패합니다. 프라이머리는 인덱스 빌드를 중단하고 관련 " AbortIndexBuild " oplog 항목을 생성합니다.
보조 노드는 "commitIndexBuild" oplog 항목을 복제하여 인덱스 빌드를 완료합니다.
세컨더리가 대신 "abortIndexBuild" oplog 항목을 복제하는 경우 인덱스 빌드를 중단하고 빌드 작업을 삭제합니다.
샤딩된 클러스터의 경우 인덱스 빌드는 인덱싱되는 컬렉션에 대한 데이터가 포함된 샤드에서만 발생합니다.
인덱스 빌드 프로세스에 대한 자세한 설명은 인덱스 빌드 프로세스를 참조하세요.
기본적으로 인덱스 빌드는 "votingMembers"
의 쿼럼 커밋, 즉 데이터를 보유한 모든 투표 멤버를 사용합니다. 기본이 아닌 쿼럼 커밋을 사용하여 인덱스 빌드를 시작하려면 commitQuorum 매개 변수를 createIndexes
또는 해당 셸 헬퍼 db.collection.createIndex()
및 db.collection.createIndexes()
로 지정합니다.
진행 중인 동시 인덱스 빌드에 필요한 쿼럼 커밋을 수정하려면 setIndexCommitQuorum
명령을 사용합니다.
참고
인덱스 빌드는 복제본 세트 성능에 영향을 미칠 수 있습니다. 인덱스 빌드로 인한 성능 저하를 견딜 수 없는 워크로드의 경우, 롤링 인덱스 빌드 프로세스를 고려하는 것이 좋습니다. 롤링 인덱스 빌드는 한 번에 하나의 복제본 세트 노드만 중단시키며, 보조 노드부터 시작하여 해당 노드에서 독립적으로 인덱스를 빌드합니다. 롤링 인덱스 빌드에는 하나 이상의 복제본 선거가 필요합니다.
복제본 세트에 대한 인덱스 빌드 롤링에 대한 자세한 내용은 제본 세트에 대한 인덱스 빌드 롤링을 참조하세요.
샤딩된 클러스터의 롤링 인덱스 빌드에 대해서는 샤딩된 클러스터의 롤링 인덱스 빌드를 참조하세요.
쓰기 우려와 대조되는 쿼럼 커밋
쿼럼 커밋과 쓰기 고려 간에는 중요한 차이점이 있습니다.
인덱스 빌드는 쿼럼 커밋 사용합니다.
쓰기 작업은 쓰기 고려 사용합니다.
클러스터 내의 각 데이터 보유 노드는 투표권을 가진 노드입니다.
커밋 쿼럼은 프라이머리 멤버를 포함하여 몇 명의 데이터 보유 투표 멤버 또는 어떤 투표 멤버가 동시 인덱스 빌드를 커밋할 준비가 되어 있어야 하는지를 지정합니다. 이 준비가 완료되면 프라이머리 멤버가 커밋을 실행합니다.
쓰기 고려는 쓰기 작업이 지정된 수의 인스턴스로 전파되었다는 확인 수준입니다.
8.0 버전 변경 사항: 커밋 쿼럼은 프라이머리가 인덱스 빌드를 커밋하기 전에 인덱스 빌드를 완료할 준비가 되어 있어야 하는 노드 수를 지정합니다. 반대로 프라이머리가 인덱스 빌드를 커밋한 경우 쓰기 고려는 명령이 성공을 반환하기 전에 인덱스 빌드 oplog 항목을 복제해야 하는 노드 수를 지정합니다.
이전 릴리스에서는 프라이머리가 인덱스 빌드를 커밋했을 때 쓰기 고려가 명령이 성공적으로 반환되기 전에 인덱스 빌드를 완료해야 하는 노드 수를 지정했습니다.
빌드 실패 및 복구
프라이머리 인덱스에서 중단된 인덱스 빌드 mongod
MongoDB 5.0부터 프라이머리 mongod
가 "force" : true
를 사용하여 완전한 shutdown
를 수행하거나 인덱스 빌드 중에 SIGTERM
신호를 수신하고 commitQuorum이 기본 votingMembers
로 설정된 경우 인덱스 빌드 진행 상황이 디스크에 저장됩니다. mongod
는 재시작될 때 인덱스 빌드를 자동으로 복구하고 저장된 체크포인트에서 계속 진행합니다. 이전 버전에서는 인덱스 빌드가 중단되면 처음부터 다시 시작해야 했습니다.
세컨더리 인덱스에서 중단된 인덱스 빌드 mongod
MongoDB 5.0부터 세컨더리 mongod
가 "force" : true
를 사용하여 완전한 shutdown
를 수행하거나 인덱스 빌드 중에 SIGTERM
신호를 수신하고 commitQuorum이 기본 votingMembers
로 설정된 경우 인덱스 빌드 진행 상황이 디스크에 저장됩니다. mongod
는 재시작될 때 인덱스 빌드를 자동으로 복구하고 저장된 체크포인트에서 계속 진행합니다. 이전 버전에서는 인덱스 빌드가 중단되면 처음부터 다시 시작해야 했습니다.
mongod
는 복구 인덱스가 빌드되는 동안 시작 프로세스를 수행할 수 있습니다.
mongod
를 독립형으로 다시 시작하는 경우(예: replication.replSetName
을 제거 또는 주석 처리하거나 --replSetName
을 생략)mongod
인덱스 빌드를 다시 시작할 수 없습니다. 인덱스 빌드는 수동으로dropped
될 때까지 일시 중지된 상태로 유지됩니다.
독립 실행형에서 중단된 인덱스 빌드 mongod
mongod
가 인덱스 빌드 중 종료되면 인덱스 빌드 작업과 모든 진행 상황이 손실됩니다. mongod
를 다시 시작해도 인덱스 빌드는 재시작되지 않습니다. 인덱스 빌드를 재시작하려면 createIndex()
작업을 다시 실행해야 합니다.
빌드 프로세스 중 롤백
MongoDB 5.0부터 인덱스 빌드 중에 노드가 이전 상태로 롤백되면 인덱스 작성 진행률이 디스크에 저장됩니다. 롤백이 완료될 때 아직 수행해야 할 작업이 남아 있다면 mongod
는 인덱스 빌드를 자동으로 복구하고 저장된 체크포인트에서부터 계속 작업을 진행합니다.
MongoDB는 진행 중인 인덱스 빌드를 일시 중지하여 롤백을 수행할 수 있습니다.
롤백이 인덱스 빌드를 되돌리지 않으면 MongoDB는 롤백을 완료한 후 인덱스 빌드를 다시 시작합니다.
롤백으로 인덱스 빌드가 되돌려진 경우에는 롤백 완료 후 인덱스를 다시 생성해야 합니다.
샤드 컬렉션의 인덱스 일관성 검사
샤드된 컬렉션이 일관성 없는 인덱스를 가지게 되는 경우는 컬렉션에 대한 청크를 포함하는 각 샤드에 정확히 동일한 인덱스(인덱스 옵션 포함)가 없을 때입니다. 일반 작업 중에는 일관성 없는 인덱스가 발생하지 않아야 하지만,
예를 들어 사용자가
unique
키 제약 조건을 사용하여 인덱스를 생성 중이고 하나의 샤드에 중복 문서가 있는 청크가 포함되어 있는 경우와 같이 일관성 없는 인덱스가 발생할 수 있습니다. 이러한 경우 인덱스 생성 작업은 중복이 없는 샤드에서는 성공할 수 있지만 중복이 있는 샤드에서는 실패할 수 있습니다.사용자가 샤드 전체에 걸쳐 인덱스를 롤링 방식(즉, 샤드 전체에 걸쳐 하나씩 수동으로 인덱스를 생성)으로 생성하는 경우, 연결된 샤드에 대한 인덱스를 생성하지 못하거나 다른 사양으로 인덱스를 잘못 생성하는 경우입니다.
config 서버 프라이머리는 주기적으로 샤딩된 컬렉션의 샤드 간 인덱스 불일치가 있는지 확인합니다. 이러한 주기적 검사를 구성하려면 enableShardedIndexConsistencyCheck
및 shardedIndexConsistencyCheckIntervalMS
를 참조하세요.
serverStatus
명령은 config 서버 프라이머리에서 실행될 때 인덱스 불일치를 보고하기 위해 shardedIndexConsistency
필드를 반환합니다.
샤드 컬렉션에 인덱스가 일관되지 않은지 확인하려면 샤드에서 일관되지 않은 인덱스 찾기를 참조하세요.
진행 중인 인덱스 빌드 모니터링
인덱스 빌드 작업의 상태를 보려면 mongosh
에서 db.currentOp()
메서드를 사용할 수 있습니다. 인덱스 생성 작업에 대한 현재 작업을 필터링하려면 활성 인덱싱 작업의 예를 참조하세요.
msg
필드에는 인덱스 빌드 프로세스의 현재 단계에 대한 완료율 측정이 포함됩니다.
로그에서 중지된 인덱스 빌드와 다시 시작된 인덱스 빌드 관찰
인덱스가 작성되는 동안 진행률이 MongoDB 로그에 기록됩니다. 인덱스 빌드가 중지되었다가 재개되면 다음과 같은 필드가 포함된 로그 메시지가 표시됩니다.
"msg":"Index build: wrote resumable state to disk", "msg":"Found index from unfinished build",
진행 중인 인덱스 빌드 종료
dropIndexes
명령 또는 해당 셸 헬퍼 dropIndex()
또는 dropIndexes()
을 사용하여 진행 중인 인덱스 빌드를 종료합니다. 자세한 내용은 진행 중인 인덱스 빌드 중지를 참조하십시오.
복제 세트 또는 샤딩된 클러스터에서 진행 중인 인덱스 빌드를 종료하기 위해 killOp
를 사용하지 마세요.
인덱스 빌드 프로세스
다음 표에서는 인덱스 빌드 프로세스의 각 단계를 설명합니다.
단계 | 설명 |
---|---|
잠금 | mongod 는 인덱싱 중인 컬렉션에 대해 독점적인 X 잠금을 얻습니다. 이렇게 하면 컬렉션을 대상으로 하는 복제된 쓰기 작업이나 메타데이터 명령의 적용을 포함하여 컬렉션에 대한 모든 읽기 및 쓰기 작업이 차단됩니다. mongod 는 이 잠금을 양보하지 않습니다. |
초기화 |
|
잠금 | mongod 는 독점적인 X 컬렉션 락을 인텐트 독점적인 IX 락으로 다운그레이드합니다. mongod 는 이 잠금을 주기적으로 양보하여 읽기 및 쓰기 작업을 중간에 끼워 넣습니다. |
스캔 컬렉션 | 컬렉션의 각 문서에 대해
만약
|
프로세스 측 쓰기 테이블 |
키를 처리하는 동안
|
투표하고 쿼럼 커밋 대기 | 복제본 세트의 일부가 아닌
커밋 쿼럼을 기다리는 동안 |
잠금 | mongod 는 컬렉션에 대한 인텐트 독점적인 IX 락을 공유 S 락으로 업그레이드합니다. 이는 컬렉션을 대상으로 하는 복제된 쓰기 작업이나 메타데이터 명령의 적용을 포함하여 컬렉션에 대한 모든 쓰기 작업을 차단합니다. |
임시 사이드 쓰기 테이블 처리 완료 |
키를 처리하는 동안 |
잠금 | mongod 는 컬렉션의 공유 S 잠금을 독점적인 X 잠금으로 업그레이드합니다. 이는 컬렉션을 대상으로 하는 복제된 쓰기 작업이나 메타데이터 명령의 적용을 포함하여 컬렉션에 대한 모든 읽기 및 쓰기 작업을 차단합니다. mongod 는 이 잠금을 양보하지 않습니다. |
사이드 쓰기 테이블 제거 |
키를 처리하는 동안 이 지점에서 인덱스에는 컬렉션에 기록된 모든 데이터가 포함됩니다. |
제약 조건 위반 테이블 처리 |
|
인덱스을 준비됨으로 표시 |
|
잠금 | mongod 는 컬렉션에 대한 X 잠금을 해제합니다. |