Windows 네이티브 MySQL에 타임존 테이블 적재하기

강정우·2026년 6월 9일

DB

목록 보기
33/33
post-thumbnail

Windows 네이티브 MySQL에 타임존 테이블 적재하기 (CONVERT_TZ 살리기)

__date / __year / __month 같은 날짜 필터가 로컬에서만 0건 나온다면, 로컬 MySQL의 타임존 테이블이 비어 있어서 CONVERT_TZNULL을 반환하는 게 원인일 수 있다. (배경 개념은 Django + MySQL 타임존 글 참고)
이 글은 Windows에 직접 설치된 MySQL에서 공식 SQL 덤프로 타임존 테이블을 적재하는 실전 절차다.

TL;DR

  1. https://dev.mysql.com/downloads/timezones.html 에서 POSIX standard zip을 받는다.
  2. 압축을 풀어 timezone_posix.sql을 꺼낸다.
  3. PowerShell에서 Get-Content ...sql | mysql.exe -u root -p mysql 로 import.
  4. CONVERT_TZ('2026-06-08 05:00:00','UTC','Asia/Seoul')NULL이 아니라 14:00:00이면 성공.

사전 확인 — 정말 비어 있는가

먼저 문제가 실재하는지 확인한다. (읽기 전용, 안전)

& "C:\Program Files\MySQL\MySQL Server 8.4\bin\mysql.exe" -u root -p -e "SELECT COUNT(*) AS tz_rows FROM mysql.time_zone_name; SELECT CONVERT_TZ('2026-06-08 05:00:00','UTC','Asia/Seoul') AS converted;"

mysql.exe는 보통 PATH에 등록돼 있지 않다. C:\Program Files\MySQL\MySQL Server <버전>\bin\mysql.exe 전체 경로로 호출한다. (경로에 공백이 있어 PowerShell에서는 & 호출 연산자가 필요하다.)

적재 전 결과 예:

+---------+
| tz_rows |
+---------+
|       1 |   <- 사실상 비어 있음
+---------+
+-----------+
| converted |
+-----------+
| NULL      |   <- CONVERT_TZ 실패
+-----------+

convertedNULL이면 타임존 테이블 적재가 필요하다.


STEP 1 — 공식 타임존 SQL 덤프 다운로드

https://dev.mysql.com/downloads/timezones.html 에 접속하면 두 종류가 보인다.

timezone_2026b_posix_sql.zip - POSIX standard                 ← 이것을 받는다
timezone_2026b_leaps_sql.zip - Non POSIX with leap seconds    ← 받지 않는다

POSIX standard를 받아야 하는 이유

  • leap seconds(윤초) 버전은 피한다. 1972년 이후 누적된 윤초(현재 27초)를 시각 계산에 반영해서, 일반 애플리케이션에서는 오히려 시각이 수십 초 어긋날 수 있다.
  • 목적은 Asia/Seoul(UTC+9 고정, 서머타임 없음) 날짜 변환을 프로덕션과 동일하게 만드는 것이다. 프로덕션도 일반적으로 POSIX 기준이므로 POSIX를 받아야 동작이 일치한다.
  • 파일명의 2026b는 IANA 타임존 DB 버전이다. 한국은 서머타임이 없어 버전 차이의 영향을 받지 않으니, 페이지에 보이는 최신 POSIX 버전을 받으면 된다.

다운로드에는 Oracle 계정 로그인이 요구될 수 있다. 페이지 하단의 "No thanks, just start my download" 링크로 로그인 없이 받을 수도 있다.


STEP 2 — 압축 해제

받은 zip을 풀면 timezone_posix.sql 파일이 들어 있다.

Expand-Archive -Path "$env:USERPROFILE\Downloads\timezone_2026b_posix_sql.zip" -DestinationPath "$env:USERPROFILE\Downloads\timezone_2026b_posix_sql" -Force
Get-ChildItem "$env:USERPROFILE\Downloads\timezone_2026b_posix_sql" -Recurse -Filter *.sql | Select-Object FullName

출력된 .sql 전체 경로를 STEP 3에 사용한다. (예: C:\Users\<사용자>\Downloads\timezone_2026b_posix_sql\timezone_posix.sql)


STEP 3 — 시스템 스키마 mysql에 import

root 비밀번호 입력이 필요하므로, 비밀번호가 로그에 남지 않도록 터미널에서 직접 실행한다.

Get-Content "C:\Users\<사용자>\Downloads\timezone_2026b_posix_sql\timezone_posix.sql" | & "C:\Program Files\MySQL\MySQL Server 8.4\bin\mysql.exe" -u root -p mysql

Enter password: 프롬프트에 root 비밀번호를 입력한다. 에러 없이 프롬프트로 돌아오면 성공이다.

명령 구조 해설

  • Get-Content ...sql | — PowerShell은 mysql < file.sql 같은 입력 리다이렉션을 지원하지 않는다('<' 연산자는 예약되어 있습니다 에러). 대신 Get-Content로 파일을 읽어 파이프로 넘긴다.
  • & "...\mysql.exe" — 경로에 공백(Program Files)이 있으므로 &(호출 연산자)로 실행한다.
  • -u root -p-p만 쓰면 프롬프트로 비밀번호를 물어본다. 명령줄에 비밀번호를 붙이지 않는 편이 안전하다.
  • 맨 끝의 mysql — import 대상 데이터베이스 이름이다. 앱 DB(smartsilvercenter)가 아니라 시스템 스키마 mysql에 넣는다. 타임존 테이블은 서버 전역으로 공유되므로, 한 번 넣으면 모든 DB의 쿼리에 자동 적용된다. 이 인자를 빼면 No database selected 에러가 난다.

즉, "특정 DB에 적용"이 아니라 "이 MySQL 서버 전체에 적용"이다. 결과적으로 smartsilvercenterCONVERT_TZ가 동작하게 된다.


STEP 4 — 검증

& "C:\Program Files\MySQL\MySQL Server 8.4\bin\mysql.exe" -u root -p -e "SELECT COUNT(*) AS tz_rows FROM mysql.time_zone_name; SELECT CONVERT_TZ('2026-06-08 05:00:00','UTC','Asia/Seoul') AS converted;"

적재 후 결과 예:

+---------+
| tz_rows |
+---------+
|     598 |   <- 타임존 이름이 채워짐
+---------+
+---------------------+
| converted           |
+---------------------+
| 2026-06-08 14:00:00 |   <- UTC 05:00 + 9 = KST 14:00, 정상 동작
+---------------------+
항목적재 전적재 후
tz_rows1598
convertedNULL2026-06-08 14:00:00

convertedNULL에서 한국시간으로 바뀌면 CONVERT_TZ가 정상 동작하는 것이다.


STEP 5 — 실제 애플리케이션에서 확인

개념 검증(CONVERT_TZ)이 끝났으면, 실제로 깨졌던 날짜 필터 API가 정상 응답하는지 확인한다.

/api/v2/broadcasting/?start_date=2026-04-26&end_date=2026-06-07

적재 전 0건이던 응답이 정상 건수로 돌아오면 완전히 해결된 것이다.


트러블슈팅

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
→ 비밀번호 오타. 명령을 다시 실행하고 비밀번호를 정확히 입력한다. (이 경우 import는 아무것도 적재되지 않았으므로, 올바른 비밀번호로 STEP 3를 다시 실행하면 된다.)

'<' 연산자는 나중에 사용하도록 예약되어 있습니다
→ PowerShell에서 mysql < file.sql을 쓴 경우다. Get-Content file.sql | mysql.exe ... 파이프 형태로 바꾼다.

'mysql'은(는) ... 인식되지 않습니다
mysql이 PATH에 없다. & "C:\Program Files\MySQL\MySQL Server 8.4\bin\mysql.exe" 전체 경로로 호출한다.

No database selected
→ import 명령 끝에 대상 DB mysql을 빠뜨린 경우다. ... mysql.exe -u root -p mysql처럼 맨 끝에 mysql을 붙인다.


한 줄 정리

Windows 네이티브 MySQL에서 CONVERT_TZNULL을 뱉으면, MySQL 공식 사이트의 POSIX standard 타임존 SQL 덤프를 받아 Get-Content ...sql | mysql.exe -u root -p mysql로 시스템 스키마 mysql에 import하면 된다. 코드 변경 없이 로컬이 프로덕션과 동일하게 동작한다.

profile
智(지)! 德(덕)! 體(체)!

0개의 댓글