Last active
February 13, 2018 08:11
-
-
Save kwon37xi/9205428 to your computer and use it in GitHub Desktop.
MySQL 5.6의 DATETIME ms 반올림 버그와 구버전 JDBC 드라이버의 ms 절삭 버그 조합
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
MySQL 5.6의 DATETIME 타입에 대한 밀리세컨드 부분 절삭 버그 재현 | |
MySQL 5.6.4 ms 지원 : http://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html | |
MySQL 5.6 DATETIME 타입에서 ms 반올림(round) 버그 : http://bugs.mysql.com/bug.php?id=68760 | |
MySQL Connector/J 5.1.22 까지는 Date 객체의 ms 부분을 미리 절삭해 전송하는 버그 있음 | |
MySQL Connector/J 5.1.23 부터는 Date 객체의 ms 부분도 함께 전송 -> MySQL 5.6 서버의 ms 반올림 버그 유발 -> 초,분,날짜가 바뀌는 현상 유발 | |
** 아래코드를 반올림 버그가 있는 MySQL 5.6서버에서 JDBC 드라이버 바꿔가며 실행한 결과 | |
* Conector/J 5.1.22 이하 | |
insert into datetest (normaldate, longdate) values('1999-12-31 23:59:59', '1999-12-31 23:59:59') -- ms 부분이 절삭된 SQL이 날아간다. | |
-- 입력된 데이터를 select 해보면 앞에가 DATETIME, 뒤는 DATETIME(6) | |
1999/12/31 23:59:59.000 | 1999/12/31 23:59:59.000 | |
* Connector/J 5.1.23 이상 | |
insert into datetest (normaldate, longdate) values('1999-12-31 23:59:59.555', '1999-12-31 23:59:59.555') -- ms 부분이 존재하는 SQL이 날아간다. | |
-- 입력된 데이터 select 해보면 DATETIME 타입의 경우 ms 부분을 반올림 해서 2000년으로 년도가 바뀌어버린다. | |
2000/01/01 00:00:00.000 | 1999/12/31 23:59:59.555 | |
*/ | |
@GrabConfig(systemClassLoader = true) | |
@Grab(group = 'mysql', module = 'mysql-connector-java', version = '5.1.22') // 여기서 5.1.23으로 업그레이드하면 현상이 바뀜 | |
import groovy.sql.Sql | |
import java.util.Date | |
/* | |
drop table datetest; | |
create table datetest ( | |
id int auto_increment primary key, | |
normaldate datetime not null, | |
longdate datetime(6) not null | |
); | |
*/ | |
def driver = "com.mysql.jdbc.Driver" | |
def jdbcUrl = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8" | |
def sql = Sql.newInstance(jdbcUrl, 'root', 'root', driver) | |
def format = 'yyyy/MM/dd HH:mm:ss.SSS' | |
Date date = Date.parse(format, '1999/12/31 23:59:59.555') | |
println "#Date to test ${date.format(format)}" | |
sql.execute('insert into datetest (normaldate, longdate) values(?, ?)', [date, date]) | |
sql.eachRow('select id, normaldate, longdate from datetest order by id') { | |
println "${it.id} : ${it.normaldate.format(format)} | ${it.longdate.format(format)}" | |
} | |
sql.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment