Loading...
MySQL 9.5 Reference Manual 9.5의 7.1.15 MySQL Server Time Zone Support의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
이 절에서는 MySQL이 유지 관리하는 타임존 설정, 명명된 시간대 지원에 필요한 시스템 테이블을 로드하는 방법, 타임존 변경에 맞추어 최신 상태를 유지하는 방법, 그리고 윤초 지원을 활성화하는 방법에 대해 설명합니다.
타임존 오프셋은 삽입된 datetime 값에 대해서도 지원됩니다. 자세한 내용은 Section 13.2.2, “The DATE, DATETIME, and TIMESTAMP Types”를 참조하십시오.
복제 구성을 위한 타임존 설정에 대한 정보는 Section 19.5.1.14, “Replication and System Functions” 및
Section 19.5.1.34, “Replication and Time Zones”를 참조하십시오.
MySQL Server는 여러 타임존 설정을 유지합니다:
system_time_zone 시스템 변수를 설정합니다.MySQL Server의 시스템 타임존을 시작 시 명시적으로 지정하려면, mysqld를 시작하기 전에 TZ 환경 변수를 설정하십시오. mysqld_safe를 사용해 서버를 시작하는 경우, --timezone 옵션은 시스템 타임존을 설정하는 또 다른 방법을 제공합니다. TZ 및 --timezone의 허용 가능한 값은 시스템에 따라 다릅니다. 어떤 값이 허용되는지 알아보려면 운영체제 문서를 참조하십시오.
time_zone 시스템 변수는 서버가 현재 어떤 타임존에서 동작 중인지 나타냅니다. 초기 time_zone 값은 'SYSTEM'이며, 이는 서버 타임존이 시스템 타임존과 동일함을 나타냅니다.참고
SYSTEM으로 설정되어 있으면, 타임존 계산이 필요한 모든 MySQL 함수 호출은 현재 시스템 타임존을 확인하기 위해 시스템 라이브러리 호출을 수행합니다. 이 호출은 글로벌 뮤텍스로 보호될 수 있으며, 그 결과 경합이 발생할 수 있습니다.
초기 글로벌 서버 타임존 값은 시작 시 커맨드 라인에서 --default-time-zone 옵션으로 명시적으로 지정할 수 있으며, 또는 옵션 파일에 다음과 같은 행을 사용할 수 있습니다:
1default-time-zone='timezone'
SYSTEM_VARIABLES_ADMIN 권한(또는 폐기 예정인 SUPER 권한)을 가지고 있다면, 다음 문장을 사용하여 실행 중에 글로벌 서버 타임존 값을 설정할 수 있습니다:
1SET GLOBAL time_zone = timezone;
time_zone 변수로 주어지는 고유한 세션 타임존 설정을 가집니다. 초기에는 세션 변수는 글로벌 time_zone 변수에서 값을 가져오지만, 클라이언트는 다음 문장을 사용하여 자신의 타임존을 변경할 수 있습니다:1SET time_zone = timezone;
세션 타임존 설정은 타임존에 따라 달라지는 시간 값의 표시 및 저장에 영향을 미칩니다. 여기에는 NOW()나 CURTIME() 같은 함수가 표시하는 값, 그리고 TIMESTAMP 컬럼에 저장되고 조회되는 값이 포함됩니다. TIMESTAMP 컬럼의 값은 저장 시 세션 타임존에서 UTC로 변환되며, 조회 시 UTC에서 세션 타임존으로 변환됩니다.
세션 타임존 설정은 UTC_TIMESTAMP()와 같은 함수가 표시하는 값이나 DATE, TIME, 또는 DATETIME 컬럼의 값에는 영향을 미치지 않습니다. 또한 이러한 데이터 타입의 값은 UTC로 저장되지 않습니다. 이들에는 TIMESTAMP 값에서 변환할 때만 타임존이 적용됩니다. DATE, TIME, 또는 DATETIME 값에 대해 로케일 특화 산술 연산이 필요하다면, 먼저 UTC로 변환한 후 연산을 수행하고 다시 변환하십시오.
현재 글로벌 및 세션 타임존 값은 다음과 같이 조회할 수 있습니다:
1SELECT @@GLOBAL.time_zone, @@SESSION.time_zone;
timezone 값은 여러 형식으로 지정할 수 있으며, 어느 것도 대소문자를 구분하지 않습니다:
'SYSTEM' 값으로 지정하여, 서버 타임존이 시스템 타임존과 동일함을 나타낼 수 있습니다.
+ 또는 -로 접두된, [H]H:MM 형식의 UTC에서의 오프셋을 나타내는 문자열로 지정할 수 있습니다. 예: '+10:00', '-6:00', '+05:30'. 10 미만의 시간 값에 대해 앞에 0을 붙이는 것은 선택 사항입니다. 이 경우 MySQL은 값을 저장하고 가져올 때 앞에 0을 붙입니다. MySQL은 '-00:00' 또는 '-0:00'을 '+00:00'으로 변환합니다.
이 값은 '-13:59'에서 '+14:00'까지(포함)의 범위여야 합니다.
'Europe/Helsinki', 'US/Eastern', 'MET', 'UTC'와 같은 명명된 타임존으로 지정할 수 있습니다.참고
명명된 타임존은 mysql 데이터베이스 내 타임존 정보 테이블이 생성되고 데이터가 채워져 있는 경우에만 사용할 수 있습니다. 그렇지 않으면 명명된 타임존을 사용하려 할 때 에러가 발생합니다:
1mysql> SET time_zone = 'UTC'; 2ERROR 1298 (HY000): Unknown or incorrect time zone: 'UTC'
mysql 시스템 스키마에는 타임존 정보를 저장하기 위한 여러 테이블이 존재합니다(참조: Section 7.3, “The mysql System Schema”). MySQL 설치 절차는 타임존 테이블을 생성하지만, 데이터를 로드하지는 않습니다. 수동으로 로드하려면 다음 지침을 사용하십시오.
참고
타임존 정보를 로드하는 작업은 반드시 한 번만 수행되는 것은 아닙니다. 해당 정보는 가끔 변경됩니다. 이러한 변경이 발생하면, 이전 규칙을 사용하는 애플리케이션은 오래된 상태가 되며, MySQL 서버에서 사용하는 정보를 최신 상태로 유지하기 위해 타임존 테이블을 다시 로드해야 할 수 있습니다. 자세한 내용은 Staying Current with Time Zone Changes를 참조하십시오.
시스템에 자체 zoneinfo 데이터베이스(타임존을 설명하는 파일 집합)가 있는 경우, mysql_tzinfo_to_sql 프로그램을 사용하여 타임존 테이블을 로드하십시오. 이러한 시스템의 예로는 Linux, macOS, FreeBSD, Solaris가 있습니다. 이 파일의 잠재적인 위치 중 하나는 /usr/share/zoneinfo 디렉터리입니다. 시스템에 zoneinfo 데이터베이스가 없는 경우, 이 절 후반에 설명된 대로 다운로드 가능한 패키지를 사용할 수 있습니다.
커맨드 라인에서 타임존 테이블을 로드하려면, zoneinfo 디렉터리 경로명을 mysql_tzinfo_to_sql에 전달하고 출력을 mysql 프로그램으로 파이프 하십시오. 예:
1mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
여기에서 사용된 mysql 명령은 root와 같이 mysql 시스템 스키마 내 테이블을 수정할 권한이 있는 계정으로 서버에 연결한다고 가정합니다. 필요에 따라 연결 파라미터를 조정하십시오.
mysql_tzinfo_to_sql은 시스템의 타임존 파일을 읽고 그로부터 SQL 문을 생성합니다. mysql은 이 문을 처리하여 타임존 테이블을 로드합니다.
mysql_tzinfo_to_sql은 단일 타임존 파일을 로드하거나 윤초 정보를 생성하는 데에도 사용할 수 있습니다:
tz_name 에 해당하는 단일 타임존 파일 tz_file 을 로드하려면 다음과 같이 mysql_tzinfo_to_sql을 호출합니다:1mysql_tzinfo_to_sql tz_file tz_name | mysql -u root -p mysql
이 방법을 사용하는 경우, 서버가 알아야 하는 각 명명된 존의 타임존 파일을 로드하기 위해 별도의 명령을 실행해야 합니다.
tz_file 을 타임존 파일 이름으로 하여 다음과 같이 윤초 정보를 초기화합니다:1mysql_tzinfo_to_sql --leap tz_file | mysql -u root -p mysql
mysql_tzinfo_to_sql을 실행한 후, 서버가 이전에 캐시된 타임존 데이터를 계속 사용하지 않도록 서버를 재시작하십시오.
시스템에 zoneinfo 데이터베이스가 없는 경우(예: Windows), MySQL Developer Zone에서 SQL 문을 포함하는 패키지를 다운로드하여 사용할 수 있습니다:
1https://dev.mysql.com/downloads/timezones.html
주의
시스템에 zoneinfo 데이터베이스가 있는 경우에는 다운로드 가능한 타임존 패키지를 사용하지 마십시오. 대신 mysql_tzinfo_to_sql 유틸리티를 사용하십시오. 그렇지 않으면, 해당 시스템의 다른 애플리케이션과 MySQL 사이에 datetime 처리 방식의 차이를 초래할 수 있습니다.
다운로드한 SQL 문 타임존 패키지를 사용하려면, 먼저 압축을 풀고, 압축 해제된 파일 내용을 타임존 테이블에 로드하십시오:
1mysql -u root -p mysql < file_name
그런 다음 서버를 재시작하십시오.
주의
MyISAM 테이블을 포함하는 다운로드 가능한 타임존 패키지는 사용하지 마십시오. 이는 이전 버전 MySQL을 위한 것입니다. MySQL은 이제 타임존 테이블에 InnoDB를 사용합니다. 이를 MyISAM 테이블로 대체하려 하면 문제가 발생합니다.
타임존 규칙이 변경되면, 이전 규칙을 사용하는 애플리케이션은 오래된 상태가 됩니다. 최신 상태를 유지하려면, 시스템에서 최신 타임존 정보가 사용되도록 해야 합니다. MySQL의 경우, 최신 상태를 유지하는 데 고려해야 할 요소가 여러 가지 있습니다:
운영체제 시간은 서버의 타임존이 SYSTEM으로 설정되어 있을 때 MySQL 서버가 사용하는 시간 값에 영향을 줍니다. 운영체제가 최신 타임존 정보를 사용하고 있는지 확인하십시오. 대부분의 운영체제에서는 최신 업데이트 또는 서비스 팩이 시간 변경에 대비해 시스템을 준비합니다. 시간 변경을 다루는 업데이트가 있는지 운영체제 벤더의 웹사이트를 확인하십시오.
시스템의 /etc/localtime 타임존 파일을 mysqld 시작 시점에 사용되던 규칙과 다른 규칙을 사용하는 버전으로 교체한 경우, mysqld를 재시작하여 업데이트된 규칙을 사용하도록 하십시오. 그렇지 않으면, 시스템이 시간을 변경할 때 mysqld가 이를 감지하지 못할 수 있습니다.
MySQL에서 명명된 타임존을 사용하는 경우, mysql 데이터베이스 내 타임존 테이블이 최신 상태인지 확인하십시오:
시스템에 자체 zoneinfo 데이터베이스가 있는 경우, zoneinfo 데이터베이스가 업데이트될 때마다 MySQL 타임존 테이블을 다시 로드하십시오.
자체 zoneinfo 데이터베이스가 없는 시스템의 경우, MySQL Developer Zone에서 업데이트를 확인하십시오. 새로운 업데이트가 제공되면 이를 다운로드하여 현재 타임존 테이블의 내용을 교체하십시오.
두 방법 모두에 대한 지침은 Populating the Time Zone Tables를 참조하십시오. mysqld는 조회한 타임존 정보를 캐시하므로, 타임존 테이블을 업데이트한 후에는 mysqld를 재시작하여 오래된 타임존 데이터를 계속 제공하지 않도록 하십시오.
서버의 타임존 설정으로 또는 자신의 타임존을 설정하는 클라이언트에서 명명된 타임존을 사용할 수 있는지 확실하지 않은 경우, 타임존 테이블이 비어 있는지 확인하십시오. 다음 쿼리는 타임존 이름을 포함하는 테이블에 로우가 있는지 여부를 확인합니다:
1mysql> SELECT COUNT(*) FROM mysql.time_zone_name; 2+----------+ 3| COUNT(*) | 4+----------+ 5| 0 | 6+----------+
카운트가 0이면 테이블이 비어 있음을 나타냅니다. 이 경우 명명된 타임존을 사용하는 애플리케이션은 현재 없으며, (명명된 타임존 지원을 활성화하려는 것이 아니라면) 테이블을 업데이트할 필요가 없습니다. 0보다 큰 카운트는 테이블이 비어 있지 않으며, 그 내용이 명명된 타임존 지원을 위해 사용 가능함을 나타냅니다. 이 경우 명명된 타임존을 사용하는 애플리케이션이 올바른 쿼리 결과를 얻을 수 있도록 타임존 테이블을 다시 로드해야 합니다.
서머타임(Daylight Saving Time, DST) 규칙 변경에 대해 MySQL 설치가 제대로 업데이트되었는지 확인하려면, 다음과 같은 테스트를 사용할 수 있습니다. 이 예에서는 미국에서 2007년 3월 11일 오전 2시에 발생하는 DST 1시간 변경에 해당하는 값을 사용합니다.
테스트에서는 다음 쿼리를 사용합니다:
1SELECT 2 CONVERT_TZ('2007-03-11 2:00:00','US/Eastern','US/Central') AS time1, 3 CONVERT_TZ('2007-03-11 3:00:00','US/Eastern','US/Central') AS time2;
두 시간 값은 DST 변경이 발생하는 시점을 나타내며, 명명된 타임존 사용에는 타임존 테이블의 사용이 필요합니다. 원하는 결과는 두 쿼리 모두가 동일한 결과(입력 시간을 'US/Central' 타임존의 동등한 값으로 변환한 값)를 반환하는 것입니다.
타임존 테이블을 업데이트하기 전에는 다음과 같이 잘못된 결과를 보게 됩니다:
1+---------------------+---------------------+ 2| time1 | time2 | 3+---------------------+---------------------+ 4| 2007-03-11 01:00:00 | 2007-03-11 02:00:00 | 5+---------------------+---------------------+
테이블을 업데이트한 후에는 다음과 같은 올바른 결과를 보게 됩니다:
1+---------------------+---------------------+ 2| time1 | time2 | 3+---------------------+---------------------+ 4| 2007-03-11 01:00:00 | 2007-03-11 01:00:00 | 5+---------------------+---------------------+
윤초 값은 시간 부분이 :59:59로 끝나는 값으로 반환됩니다. 이는 NOW()와 같은 함수가 윤초 동안 연속된 두세 초 동안 동일한 값을 반환할 수 있음을 의미합니다. 시간 부분이 :59:60 또는 :59:61로 끝나는 리터럴 시간 값은 여전히 유효하지 않은 것으로 간주됩니다.
윤초 직전 1초의 TIMESTAMP 값을 검색해야 할 경우, 'YYYY-MM-DD hh:mm:ss' 값과의 비교를 사용하면 이상한 결과가 나올 수 있습니다. 다음 예는 이를 보여 줍니다. 예에서는 세션 타임존을 UTC로 변경하여 (UTC인) 내부 TIMESTAMP 값과 (타임존 보정이 적용된) 표시 값 사이에 차이가 없도록 합니다.
1mysql> CREATE TABLE t1 ( 2 a INT, 3 ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 4 PRIMARY KEY (ts) 5 ); 6Query OK, 0 rows affected (0.01 sec) 7 8mysql> -- change to UTC 9mysql> SET time_zone = '+00:00'; 10Query OK, 0 rows affected (0.00 sec) 11 12mysql> -- Simulate NOW() = '2008-12-31 23:59:59' 13mysql> SET timestamp = 1230767999; 14Query OK, 0 rows affected (0.00 sec) 15 16mysql> INSERT INTO t1 (a) VALUES (1); 17Query OK, 1 row affected (0.00 sec) 18 19mysql> -- Simulate NOW() = '2008-12-31 23:59:60' 20mysql> SET timestamp = 1230768000; 21Query OK, 0 rows affected (0.00 sec) 22 23mysql> INSERT INTO t1 (a) VALUES (2); 24Query OK, 1 row affected (0.00 sec) 25 26mysql> -- values differ internally but display the same 27mysql> SELECT a, ts, UNIX_TIMESTAMP(ts) FROM t1; 28+------+---------------------+--------------------+ 29| a | ts | UNIX_TIMESTAMP(ts) | 30+------+---------------------+--------------------+ 31| 1 | 2008-12-31 23:59:59 | 1230767999 | 32| 2 | 2008-12-31 23:59:59 | 1230768000 | 33+------+---------------------+--------------------+ 342 rows in set (0.00 sec) 35 36mysql> -- only the non-leap value matches 37mysql> SELECT * FROM t1 WHERE ts = '2008-12-31 23:59:59'; 38+------+---------------------+ 39| a | ts | 40+------+---------------------+ 41| 1 | 2008-12-31 23:59:59 | 42+------+---------------------+ 431 row in set (0.00 sec) 44 45mysql> -- the leap value with seconds=60 is invalid 46mysql> SELECT * FROM t1 WHERE ts = '2008-12-31 23:59:60'; 47Empty set, 2 warnings (0.00 sec)
이 문제를 해결하려면, 윤초 보정이 적용된 컬럼에 실제 저장된 UTC 값을 기준으로 비교를 사용할 수 있습니다:
1mysql> -- selecting using UNIX_TIMESTAMP value return leap value 2mysql> SELECT * FROM t1 WHERE UNIX_TIMESTAMP(ts) = 1230768000; 3+------+---------------------+ 4| a | ts | 5+------+---------------------+ 6| 2 | 2008-12-31 23:59:59 | 7+------+---------------------+ 81 row in set (0.00 sec)
7.1.14 Network Namespace Support
7.1.16 Resource Groups