MongoDB TTL 컬렉션
파일 시스템 관련 개발하던 중, MongoDB에 재밌는 컬렉션이 있어서 기록을 남겨본다. 민감 정보가 있는 다운로드 내역이라면, signedUrl로 일정 시간만 다운로드를 가능하게 하고 일정 기간이 지나면 완전히 컬렉션에서 사라지게 한다면 조금 더 안전한 운영이 가능하지 않을까? 또는 일정 기간만 로깅용으로 데이터를 보유하고 그 이후에는 사용하지 않는다면, 이 컬렉션은 매력적일 거 같다.

TTL 컬렉션(Time-To-Live)
MongoDB는 컬렉션에서 특별한 인덱스를 사용하여 구현한, 특정 시간이 경과한 도큐먼트를 자동으로 제거(remove)시킬 수 있는 기능을 제공한다.
위 명령을 통해 lastModifiedDate에 인덱스를 생성하게 된다. TTL 인덱스를 생성하는 조건은 날짜 또는 날짜 값을 포함하는 필드에서 인덱스를 생성하며, expireAfterSeconds 옵션을 함께 주면 된다. 아래의 코드는 privacy_history 컬렉션에 TTL 인덱스를 생성하는 과정이다.
// 당연히 타임스탬프 값이 lastModifiedDate에 이미 들어가 있어야 동작한다.
> db.privacy_history.creatIndex({"lastModifiedDate": 1}, {expireAfterSeconds: 3600})
이 필드는 주기적으로 타임스탬프 값을 체크하며, lastModifiedDate 값과 현재 시간 사이에 차이가 expireAfterSeconds보다 크면 해당 도큐먼트를 자동으로 삭제할 것이다. 위 코드에서는 lastModifiedData 값은 3600(60*60)초 후에 삭제된다.
언제 삭제 되는가?
백그라운드 스레드에서 해당 인덱스 값을 읽고, 컬렉션에서 만료된 도큐먼트를 제거한다. 물론 expireAfterSeconds가 지났다고 해서 정확히 그 시간에 삭제되지는 않는다. 왜냐하면 만료된 도큐먼트를 제거하는 백그라운드 작업이 60초마다 실행되기 때문이다. 그래서 expireAfterSeconds가 지났더라도, 최대 60초의 시간(초)이 소요될 수 있다.
예제 1) 지정 시간(초) 후에 삭제
> db.privacy_history.creatIndex({"lastModifiedDate": 1}, {expireAfterSeconds: 3600})
> db.privacy_history.insert({
> "휴대폰번호": "01012345678",
> "고객명": "제이코",
> "lastModifiedDate": new Date(),
> })
3600초가 경과하면 위 도큐먼트는 삭제된다.
예제 2) 지정 시점 후에 삭제
> db.privacy_history.creatIndex({"expireAt": 1}, {expireAfterSeconds: 0})
> db.privacy_history.insert({
"휴대폰번호": "01012345678",
"고객명": "제이코",
"expireAt": new Date("2020-12-30 09:00"),
})
2020년 12월 30일 09시가 경과되면 위 도큐먼트는 삭제된다.
제약 사항
- 캡드(capped) 컬렉션에는 사용할 수 없다. -> 캡드 컬렉션은 개별 도큐먼트를 삭제하는 것을 지원하지 않기 때문이다.
- _id 필드 혹은 이미 인덱스에서 사용되고 있는 필드에 대해서는 TTL 인덱스를 가질 수 없다.
- 단일 인덱스만 사용될 수 있으며, 복합(Compound) 인덱스에서는 사용할 수 없다.
TTL Indexes — MongoDB Manual
TTL Indexes TTL indexes are special single-field indexes that MongoDB can use to automatically remove documents from a collection after a certain amount of time or at a specific clock time. Data expiration is useful for certain types of information like ma
docs.mongodb.com