버그도 경험이다

Docker 내 MySQL 테이블 파티션 자동화: 크론탭으로 매달 처리

잉여인간 2025. 5. 13. 14:23

목차

  1. 상황
  2. 처리
  3. 본문
  4. 마무리 한마디


1. 상황

  • 도커 환경에서 동작중인 Mysql
  • 인수인계 받은 프로젝트의 API 로그 테이블 파티션을 인지못함
  • 4월 -> 5월 넘어감에 따라 파티션 자동생성이 되지 않음
  • 데이터 적재 X (API 서버에서 에러만 뱉고 있었다.)

2. 처리

  • 우선 정상화를 빠르게 시켰어야 해서 수동으로 파티션 생성
  • 도커내의 DB에 해당 테이블에 파티션을 생성하는 스크립트 작성
  • 크론탭에 해당 스크립트를 매월 1일 0시0분에 동작하도록 설정

3. 본문

Script(add_partition.sh)

#!/bin/bash

# ✅ 도커 컨테이너 이름
CONTAINER_NAME="A"

# ✅ DB 접속 정보
DB_USER="your_user"
DB_PASS="your_password"

# ✅ 대상 DB 및 테이블 정보
DB_NAME="your_database"
TABLE_NAME="B"
PARTITION_COLUMN="RECV_DT"  # UNIX_TIMESTAMP로 감쌀 파티션 기준 컬럼

# ✅ 현재 월 기준 파티션 이름 (예: p202505)
CUR_MONTH_LABEL="p$(date +%Y%m)"

# ✅ 다음 달 1일 00:00 (KST 기준) → UTC 기준으로 변환
NEXT_MONTH_UTC=$(date -d "$(date +%Y-%m-01) +1 month -9 hours" +"%Y-%m-%d %H:%M:%S")
NEXT_TS=$(docker exec -i "$CONTAINER_NAME" mysql -u$DB_USER -p$DB_PASS -Nse "SELECT UNIX_TIMESTAMP('$NEXT_MONTH_UTC');")

# ✅ 이미 존재하는 파티션인지 확인
EXISTS=$(docker exec -i "$CONTAINER_NAME" mysql -u$DB_USER -p$DB_PASS -Nse "
  SELECT 1 FROM information_schema.PARTITIONS
  WHERE TABLE_SCHEMA = '$DB_NAME'
    AND TABLE_NAME = '$TABLE_NAME'
    AND PARTITION_NAME = '$CUR_MONTH_LABEL'
  LIMIT 1;
")

# ✅ 파티션 추가 실행
if [ "$EXISTS" == "1" ]; then
  echo "⚠️ Partition $CUR_MONTH_LABEL already exists. Skipping."
else
  echo "✅ Adding partition: $CUR_MONTH_LABEL (LESS THAN $NEXT_TS)"
  docker exec -i "$CONTAINER_NAME" mysql -u$DB_USER -p$DB_PASS -D "$DB_NAME" -e "
    ALTER TABLE $TABLE_NAME
    ADD PARTITION (
      PARTITION $CUR_MONTH_LABEL VALUES LESS THAN ($NEXT_TS)
    );
  "
fi

 

변수

CONTAINER_NAME="{MYSQL 컨테이너명}"
DB_USER="{DB ID}"
DB_PASS="{DB PW}"
DB_NAME="{DB명}"
TABLE_NAME="A"
PARTITION_COLUMN="REG_DT"

Crontab

0 0 1 * * /{스크립트가 위치한 디렉토리}/add_partition.sh >> /{스크립트가 위치한 디렉토리}/logs/partition_add.log 2>&1

 

 

4. 마무리 한마디

  • 인수인계를 받을 때에는 꼼꼼히 받자.
  • 파티션도 생각하자.
  • 왜 자동화는 안돼있지?

 

공감과 댓글은 쓸데잡에 영양이 됩니다 😊
쓸데없는 같지만 은근 쓸모 있는 정보, 계속 나눌게요 🙌