MongoDB deleteMany() 사용 시, 주의사항

김하영·2025년 11월 4일

최근 실무에서 인덱스가 약 25개나 정의되어 있고,
document 내 배열 필드가 여러 개 정의된 컬렉션의 bulk delete time out 건을 해결하기 위해 분석한 내용을 정리한다.

20개의 문서를 삭제했더니 attr.keysDeleted(삭제된 인덱스키 건수) 값이 13,000건이 나왔고, 결과적으로는 3초 타임아웃 + 서비스 에러가 발생했다.

문제 상황 요약

컬렉션에 인덱스가 약 25개 존재.

문서 구조가 단순하지 않고, 내부에 배열 필드가 여러 개 있음 → 멀티키 인덱스 가능성 또는 배열 요소마다 인덱스 키 생성 가능성이 높음.

삭제 요청: 20건의 문서 → 삭제된 인덱스 키 수(keysDeleted) 약 13,000건 발생.

그 결과로 3 초 타임아웃 및 서비스 에러가 발생.

삭제 요청이 문서 건수 단위가 아닌,

문서 내부 배열 요소 수 × 인덱스 수 × 문서 수 등에 의해 삭제되는 인덱스 키 수가 폭증할 수 있다는 사실을 인지하게 되었다.

왜 이런 일이 벌어지는가?

인덱스 수와 삭제 오버헤드

MongoDB에서 인덱스는 문서의 필드 또는 배열 내부 요소에 대해 키(key) 항목을 생성한다.
특히 배열 필드가 있는 경우, 해당 배열의 각 요소가 인덱스 키 항목으로 들어갈 수 있으며(멀티키 인덱스) 배열 요소 수가 많으면 그만큼 인덱스 키 수가 많아진다.

인덱스가 많을수록 삭제 시에는 해당 문서에 연결된 모든 인덱스 키 항목을 삭제해야 하므로 오버헤드가 커지게 된다.

따라서 “문서 20개 삭제”라고 단순히 생각했지만, 실제로는 문서 20개 × (문서 내부 배열 요소 수) × (인덱스 수) → 매우 많은 키 삭제 연산이 발생했다.

배열 필드 + 멀티키 인덱스의 결합

배열 필드가 있다면 멀티키 인덱스가 자동으로 적용되거나 수동으로 정의되어 있을 수 있고, 이 경우 배열 요소 각각이 인덱스 키로 들어간다.

예컨대 한 문서 내부에 배열이 50개 요소였고 인덱스가 25개 있었다면, 이론상 인덱스 키 삭제 수는 50 × 25 = 1250건/문서 수준이 될 수 있고, 문서 20개면 약 25,000건 수준이 될 수 있다.

실제 사례에서 키 삭제 수가 13,000건 나왔던 것은 이와 유사한 복합 요인이 작용했을 가능성이 높다.

삭제 연산에 대한 실행 시간 리스크

삭제 연산이 이렇게 과다한 인덱스 키 작업을 내부적으로 수행하면 I/O, 잠금(lock), 복제 지연(replication lag) 등의 부하가 발생할 가능성이 높다.

또한 컬렉션이 샤딩 또는 복제된 환경이라면 더 복잡한 동작이 생길 수 있고, 삭제 도중 장애가 발생하면 일부만 삭제된 상태로 남을 수도 있다.

이런 이유로 작은 삭제 요청이라도 “삭제해야 할 키 수”가 많으면 타임아웃, 서비스 장애를 유발할 수 있다.

실무용 체크리스트

삭제 작업을 계획할 때 다음 사항을 미리 확인하면 리스크를 줄일 수 있다.

  1. 인덱스 개수 및 정의 확인

컬렉션에 정의된 인덱스 수가 많지는 않은가? (예: 20개 이상)

배열 필드, 중첩 객체(nested object) 필드 등이 인덱스 대상이 되어 있는가?

불필요하거나 쓰기 부하를 유발하는 인덱스가 존재하지 않는가?

  1. 문서 구조 복잡성 점검

배열 필드가 많거나, 각 문서 내부 요소가 많지는 않은가?

배열 요소 × 인덱스 항목 수 × 삭제 건수 = 잠재적 키 삭제 수 → 대략 산정 가능

  1. 삭제 대상 규모 산정

삭제하려는 문서 수만 고려하지 말고 삭제될 인덱스 키 수도 산정한다.

예컨대: 문서 수 × (내부 배열 요소 평균 수) × (적용된 인덱스 수) ≈ 키 삭제 수

키 삭제 수가 수천~수만 건 이상이면 작업 리스크 존재

  1. 배치(Batch) 삭제 고려

한꺼번에 많은 문서를 삭제하기보다는 작은 단위로 나눠서 삭제하는 것이 안전하다.
( 실제 어떻게 해결 했는지 해결 방법도 추후 정리하겠다. )

  1. 모니터링 및 로그 확인

삭제 시 keysDeleted, docsDeleted, durationMillis, locks 등의 로그를 확인한다.

삭제 이후 인덱스 크기 증가/단편화(fragmentation) 여부도 체크할 필요가 있다.

  1. 인덱스 정리 및 재검토

정말 필요한 인덱스만 유지하고, 사용되지 않거나 중복된 인덱스는 제거한다.

결론

작은 규모의 문서 삭제라도 문서 내부 구조 복잡성(배열, 중첩 필드) + 인덱스 수 조합에 의해 삭제 작업이
예상외로 많은 인덱스 키 작업을 수행하게 되고, 이로 인해 성능 저하나 서비스 장애로 연결될 수 있다.

삭제 작업을 계획할 때는 단순히 “문서 N건 삭제”라는 숫자만 보는 것이 아니라, 삭제될 인덱스 키 수라는 관점에서 리스크를 미리 산정하는 것이 좋다.

그 전에 컬렉션 구조와 인덱스 설계를 할 때 이러한 점들을 고려해서 이슈 없게 설계하는게 젤 중요한 것 같다.

profile
Developer

0개의 댓글