본문 바로가기
개발/성능 개선

서버 리소스 절약하면서 데이터 정리하기 - MySQL Event 활용기

by nineteen 2025. 7. 5.
반응형

들어가며

최근 알림 시스템을 개발하면서 알게된 기능을 활용해 조금의 성능을 개선한 경험을 담아보았습니다.


문제 상황

‼️ 사용된 코드와 MySQL Event 정의 script 는 예시입니다..!

알림 시스템을 개발하면서 NotificationHistory 엔티티를 만들어 알림 히스토리를 관리했습니다.

@Entity
@Table(name = "notification_history")
class NotificationHistory(
    @Column(name = "created_at", nullable = false)
    val createdAt: Long = System.currentTimeMillis(),
    // ... 다른 필드들
)

아래의 상황을 문제로 정의했습니다:

  • 의미 없는 오래된 데이터: 1주일이 지난 알림은 누가 봐도 의미가 없음
  • 데이터베이스 부담: 불필요한 데이터가 계속 누적되어 성능 저하 우려

Spring Scheduler

당연히 가장 먼저 떠오른 해결책은 Spring Scheduler였습니다.

@Scheduled(cron = "0 0 1 * * *") // 매일 새벽 1시
public void deleteExpiredNotifications() {
    // 7일이 지난 데이터 삭제 로직
}

이렇게 문제를 해결할 수 있었지만, "굳이?"라는 생각이 들었습니다.
굳이 서버를 통해 실행하지 않아도 데이터베이스 단에서 직접 처리가 가능했고, 데이터베이스 레벨에서 처리하는 것이 조금이라도 더 효율적일 것 같았습니다.


MySQL Event

데이터베이스 레벨에서 직접 예약 작업을 수행할 수 있는 기능이었죠.

MySQL Event란?

  • 데이터베이스에서 예약된 작업을 자동으로 실행
  • 애플리케이션 레벨 스케줄러 불필요
  • MySQL 서버가 실행 중이면 계속 동작

구현 과정

1. 이벤트 생성

CREATE EVENT delete_expired_notifications
ON SCHEDULE EVERY 1 HOUR
STARTS '2025-01-01 00:00:00.000'
ON COMPLETION NOT PRESERVE
ENABLE
DO BEGIN
  DELETE FROM notification_history
  WHERE created_at IS NOT NULL
    AND created_at + (7 * 24 * 60 * 60 * 1000) < UNIX_TIMESTAMP() * 1000;
END

알림센터에 표출할 데이터의 만료기간을 7일로 설정해, 7일 이후의 데이터들을 자동으로 삭제되도록 처리했습니다.

2. 이벤트 관리 명령어

-- 이벤트 스케줄러 활성화 확인
SHOW VARIABLES LIKE 'event_scheduler';

-- 이벤트 목록 확인
SHOW EVENTS;

-- 이벤트 활성화/비활성화
ALTER EVENT delete_expired_notifications ENABLE;
ALTER EVENT delete_expired_notifications DISABLE;

개선 효과

1. 서버 리소스 절약

  • CPU/메모리 사용량 감소: 애플리케이션 스케줄러 불필요함에 따라 별도 스레드나 프로세스 불필요
  • 네트워크 트래픽 감소: 애플리케이션 ↔ 데이터베이스 통신 최소화

2. 안정성 향상

  • 데이터베이스 레벨 처리: 더 안정적이고 일관성 있는 처리
  • 애플리케이션 독립성: 서버 재시작과 무관하게 동작
  • 오류 처리: 데이터베이스 레벨에서 직접 처리

3. 운영 편의성

  • 유연한 조정: 필요시 즉시 스케줄 변경 가능

마무리

MySQL Event는 로그성 데이터와 같이 단순한 데이터 처리에 유용했습니다.
다만 복잡한 데이터를 다루거나 비즈니스 로직이 필요한 경우에는 아쉽게도 한계가 있을 듯 합니다.