서론
정말 너무 화나서 찾아보고자 블로그를 쓴다
이전에도 같은 문제를 겪은 기억이 있고 해결한 기억이 있었다.
데이터베이스에 어떤 값을 넣을 때 timezone이 맞지 않아서 발생한 문제였고, application.yml에 db url을 지정할 때 timezone을 지정해줌으로써 해결했다.
spring:
r2dbc:
url: r2dbc:mysql://localhost:3306/database?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Seoul
이번에도 습관적으로 timezone을 지정해줬고, 혹시모를 오류를 대비해 인코딩도 지정해줬다.
하지만 또 발생해버렸다..
로그를 보아하니 인코딩도 박살나있고, 당연히 timezone도 맞지 않는다고 한다.
인텔리제이의 인코딩도 utf8로 설정해뒀는데 또 발생해서 너무 화가났다. 그래서 원인을 찾고자 블로그 글을 써본다.
MySql timezone이란?
문제를 해결하기 전 timezone에 대해 조금 정리해보려고 한다. (문제해결만 원하시는 분은 밑으로 쭉 내려주시면 됩니다)
세계협정시인 UTC는 국제적인 표준 시간의 기준으로 쓰이는 시각이다. 위치는 그리니치 천문대가 있는 곳이다.
표준시는 여러 개로 나뉘는데, 영토가 넓은 국가들은 timezone이 여러 개인 경우도 있다.
UTC-8의 경우 세계협정시에서 8시간을 뺀 시간이고, UTC+9의 경우 세계 협정시에서 9시간을 더한 시간이다.
한국의 표준시인 KST의 경우 UTC+9이다.
현재 자신의 mysql 서버에서 time_zone이 어떻게 설정되어있는지 보려면 다음과 같은 쿼리를 쳐보면 된다.
select @@global.time_zone, @@session.time_zone;
글쓴이의 경우 time_zone을 미리 설정해뒀기 때문에 +09:00 KST 시간으로 나온다.
select now();
이 쿼리를 통해 현재 노트북 시간과 mysql 서버의 시간이 다른지도 확인가능하다.
timezone이 맞지 않다는 오류의 원인
mysql의 기본 timezone이 없는 상태에서 클라이언트가 접속하면 경고로그가 뜬다.
timezone이 맞지 않아도 동작은 하지만, 잘못 설정된 값때문에 제대로 된 값이 들어가지 않을 수 있기 때문에 경로 로그를 띄워주는 것 같다.
예를 들어 한국 현재시간을 저장하고 싶었는데, 9시간이나 느린 UTC값으로 지정되면 혼란이 있을 수 있을 것이다.
MySQL Timezone 설정하는 방법
1. JDBC URL 변경하기
jdbc를 연결할 때 timezone을 설정하는 방법이다.
spring의 경우 yml 파일에 다음과 같이 적으면 된다.
spring:
r2dbc:
url: r2dbc:mysql://localhost:3306/database?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Seoul
spring:
r2dbc:
url: r2dbc:mysql://localhost:3306/yeminjilim?useUnicode=true&characterEncoding=utf8&serverTimezone=+09:00
2. MySQL 서버 timezone 설정하기
mysql 설정파일인 my.ini(windows) 에 time zone을 설정한다.
my.ini 파일은 설정에 따라 다를 수 있는데, 글쓴이의 경우 (C:)\ProgramData\MySQL\MySQL Server 8.0\ 에 있었다.
(참고로 파일 수정 권한을 변경한 후 해당 파일을 수정해야한다. 참고자료: https://nongue.tistory.com/75)
timezone은 UTC를 기준으로 빠르면 +시간차이, 느리면 -시간차이 를 적어줘야한다.
한국의 time zone인 Asia/Seoul은 UTC보다 9시간 빠르므로, +09:00을 적어주면 된다.
default_time_zone = '+09:00'
이 한 줄을 추가하고 저장한 후, mysql 서버를 다시시작하면 된다.
mysql서버 재시작의 경우, 서비스에 들어가서 재시작을 누르면 된다. (참고자료: https://like-or-like.tistory.com/68)
글쓴이의 문제해결
내가 마주친 오류는 yml에서 지정한 timezone과 mysql 서버의 timezone이 맞지 않아서 발생한 것이었다.
mysql 서버의 기본 timezone이 설정되어있지 않았기 때문에 자동으로 yml에서 지정한 값이 들어갈 것 같았는데 아니었나보다. 그래서 mysql의 설정파일인 my.ini파일을 수정하니 경고 로그가 더이상 뜨지 않게 되었다.
(직접 설정파일을 고치지 않더라도 global timezone을 설정하는 방법으로도 가능)
원래는 잘 되던 설정값인데 안된 이유는 다음 중 하나일 것 같다.
- yml의 인코딩을 제대로 해석하지 못한 것
- r2dbc에서 timezone을 설정하는 코드가 잘못된 것
참고자료
'Backend > Spring' 카테고리의 다른 글
[Spring] 클라이언트의 ip를 가져오는 방법(HttpServletRequest) (0) | 2023.08.13 |
---|---|
[Spring] jwt 로그아웃을 구현하는 방법 (0) | 2023.08.07 |
[Spring] REST API 버전을 관리하는 이름짓기 (0) | 2023.07.24 |
[Spring] 인프런 tdd 수업3 - 상품조회 기능 tdd (0) | 2023.07.15 |
[Spring] 인프런 tdd 수업2 - api테스트로 변환 (0) | 2023.07.15 |