MariaDB 대용량 로그·이력 테이블 운영
DB 작성 · 수정 · 글쓴이 미션비
핵심 답변
MariaDB에서 빠르게 커지는 로그·이력 테이블은 처음부터 '어떻게 쌓고, 어떻게 읽고, 언제 정리할지'를 정해 두어야 합니다. 요약(요청 1건)과 상세(대상별 행)를 나누고, 상세는 기간 단위로 분리하며, 통계는 지난 날짜를 일별 집계본에서 읽고 오늘만 원본에서 계산해 합칩니다. 문자셋·정렬 규칙을 모든 테이블에서 통일하고, 대형 테이블 구조 변경과 테스트는 운영 DB가 아닌 환경에서 먼저 검증합니다.
빨리 커지는 테이블은 따로 있다
업무 시스템의 테이블 대부분은 천천히 자랍니다. 회원, 상품, 주문은 비즈니스가 커지는 속도로 늘어납니다. 반면 발송내역, 방문 로그, 변경 이력, 외부 연동 로그는 한 번의 행동에 여러 행이 쌓여 훨씬 빨리 커집니다. 처음에는 문제가 없다가 어느 날 목록 화면과 통계 화면이 동시에 느려집니다.
아래는 미션비가 문자발송 플랫폼, 쇼핑몰, 홈페이지 방문 통계를 MariaDB로 운영하며 정리한 기준입니다.
1. 요약과 상세를 나눈다
문자 발송 한 번에 수신자 1만 명이면 상세는 1만 행이지만, 사용자가 목록에서 보고 싶은 것은 "한 번 보냈다"는 한 줄입니다. 요청 단위의 요약(마스터)에 전체·성공·실패 건수를 담아 두면 목록은 요약만 읽고, 상세는 특정 요청을 열 때만 읽습니다. 같은 원리로 방문 로그도 원본 행과 일별 집계를 분리합니다.
2. 상세는 기간 단위로 나눈다
문자발송 플랫폼 센드엠은 수신 상세를 월 단위 테이블로 나눠 둡니다. 최근 기간은 현재 테이블에서, 지난 달은 해당 월 테이블에서 읽고, 어느 테이블을 읽을지는 요약 행의 등록 월로 정합니다.
- 장점 — 최근 데이터 조회가 전체 이력 크기에 영향을 덜 받고, 오래된 월을 통째로 백업·정리하기 쉽습니다.
- 비용 — 여러 달에 걸친 조회는 테이블을 합쳐야 하고, 테이블 이름을 동적으로 정하는 쿼리는 입력값 검증을 엄격하게 해야 합니다.
MariaDB의 파티션 기능으로 같은 효과를 낼 수도 있습니다. 어느 방식이든 "어떤 기간을 얼마나 자주 읽는가"를 먼저 보고 정합니다.
3. 통계는 지난 날은 집계본, 오늘은 원본
미션비 홈페이지의 방문 통계는 원본 방문 로그를 매일 배치로 일별 집계 테이블에 요약합니다. 대시보드는 어제까지는 집계 테이블에서, 오늘은 원본 로그에서 계산해 합치는 방식으로 보여 줍니다. 기간을 30일로 넓혀도 원본 30일치를 매번 훑지 않으므로 화면이 느려지지 않고, 오늘 수치는 실시간에 가깝게 유지됩니다.
집계 배치는 같은 날짜를 다시 돌려도 결과가 같도록(기존 집계를 지우고 다시 쓰거나 키 기준으로 갱신) 만들어야 누락·중복을 수동으로 바로잡을 수 있습니다.
4. 문자셋과 정렬 규칙을 하나로
로그 테이블은 급하게 만들어지는 경우가 많아 표준에서 벗어나기 쉽습니다. 정렬 규칙(collation)이 다른 컬럼끼리 조인하면 "Illegal mix of collations" 오류로 쿼리가 실패하고, 이 문제는 두 테이블을 처음 조인하는 날에야 드러납니다.
- 새 테이블 DDL에는
CHARSET과COLLATE를 모두 적습니다. COLLATE를 생략하면 의도하지 않은 서버 기본값이 붙을 수 있습니다. information_schema.COLUMNS를 조회해 표준에서 벗어난 컬럼을 찾는 점검 쿼리를 두고 주기적으로 돌립니다.- utf8mb4 끼리 정렬 규칙만 바꾸는 것은 가벼운 편이지만, utf8(utf8mb3)을 utf8mb4로 바꾸는 것은 재인코딩과 테이블 재구축입니다. 인덱스 키 길이와 행 크기 제한을 먼저 점검합니다.
5. 지우기 전에 남기고, 조건은 늘 같이
대용량 테이블에서 실수로 지운 데이터는 복구가 어렵습니다. 사용자 데이터 삭제는 삭제 직전 상태를 이력 테이블에 복사한 뒤 삭제하고, 두 쿼리에 같은 조건(사용자 소유 범위 포함)을 겁니다. 엑셀로 올리는 원장 데이터는 업로드 직전 백업 테이블에 복사해 두면 잘못 올린 파일을 되돌릴 수 있습니다.
6. 인덱스는 화면의 검색 조건에서 시작한다
- 느린 쿼리는 대개 목록 화면의 검색 조건과 정렬에서 나옵니다. 화면에서 실제로 쓰는 조건 조합을 기준으로 인덱스를 만듭니다.
- 로그 테이블은 쓰기가 많으므로 인덱스를 무작정 늘리지 않습니다. 조회용 인덱스가 많이 필요하면 집계 테이블로 옮기는 편이 낫습니다.
- 정렬에 계산이 필요한 값(최근 판매량 등)은 조회 때마다 계산하지 말고 배치로 컬럼에 저장합니다.
주의사항
- 대형 테이블의 구조 변경(컬럼 추가, 문자셋 변경)은 운영 DB에서 바로 하지 않습니다. 로컬이나 별도 환경에서 같은 크기에 가까운 데이터로 시간을 재 보고 작업 시간대를 정합니다.
- 운영 DB에 테스트를 돌리지 않습니다. 검증은 로컬 또는 별도 환경에서만 합니다.
- 백업은 복구를 해 봐야 백업입니다. 기간 단위로 나눈 테이블은 월 단위 백업·복구 절차를 따로 확인합니다.
- 로그의 보관 기간과 정리 방식은 개인정보 처리 기준과 함께 정합니다.
정리
빨리 커지는 테이블은 요약과 상세로 나누고, 상세는 기간으로 나누고, 통계는 집계본과 당일 원본을 합쳐 보여 줍니다. 문자셋은 처음부터 통일하고, 삭제 전에는 이력을 남기고, 구조 변경과 테스트는 운영 DB 밖에서 먼저 합니다. 데이터가 적을 때 정해 두면 비용이 거의 들지 않는 규칙들입니다.