MySQL中幾個關於時間/時區的變量

1、log_timestamps

1.一、官方解釋

log_timestamps: Log timestamp format. Added in MySQL 5.7.2.
This variable controls the timestamp time zone of error log messages, and of general query log and slow query log messages written to files. It does not affect the time zone of general query log and slow query log messages written to tables.
Permitted log_timestamps values are UTC (the default) and SYSTEM (local system time zone).

簡單來講log_timestamps變量控制着error log、general log、slow log這些文件中的時間信息。log_timestamps有效的值爲UTC(默認)和SYSTEM(本地系統時區)html

1.二、使用樣例

能夠使用下面方式設置log_timestampsmysql

# 啓動命令
--log_timestamps=[UTC|SYSTEM]
# 配置文件
log_timestamps=[UTC|SYSTEM]
# 運行期間
set global log_timestamps = ['UTC'|'SYSTEM']
View Code

查看並修改log_timestamps的值sql

# 查看log_timestamps
mydba@192.168.85.132,3306 [replcrash]> show variables like '%log_timestamps%';
+----------------+-------+
| Variable_name  | Value |
+----------------+-------+
| log_timestamps | UTC   |
+----------------+-------+
row in set (0.01 sec)
# 設置log_timestamps爲system
mydba@192.168.85.132,3306 [replcrash]> set global log_timestamps = 'system';
Query OK, 0 rows affected (0.03 sec)

# 默認UTC時間的日誌信息
2018-01-10T02:45:37.093284Z 21 [Note] Access denied for user 'mydba'@'192.168.85.132' (using password: YES)
# 設置log_timestamps爲system(東八區)的日誌信息
2018-01-10T10:46:07.031340+08:00 22 [Note] Access denied for user 'mydba'@'192.168.85.132' (using password: YES)
View Code

能夠看到日誌中時間格式爲:YYYY-MM-DDThh:mm:ss.uuuuuu+Z(UTC)/±hh:mm(相對UTC的偏移量)shell

2、time_zone

2.一、官方解釋

The current time zone. This variable is used to initialize the time zone for each client that connects. By default, the initial value of this is 'SYSTEM' (which means, 「use the value of system_time_zone」). 

2.二、使用樣例

能夠使用下面方式設置global server time zone服務器

# 啓動命令
--default-time-zone=timezone
# 配置文件
default-time-zone=timezone
# 運行期間
set global time_zone = timezone

timezone values can be given in several formats, none of which are case sensitive:
• The value 'SYSTEM' indicates that the time zone should be the same as the system time zone.
• The value can be given as a string indicating an offset from UTC, such as '+10:00' or '-6:00'.
• The value can be given as a named time zone, such as 'Europe/Helsinki', 'US/Eastern', or 'MET'. Named time zones can be used only if the time zone information tables in the mysql database have been created and populated.
View Code

查看並修改time_zone的值session

# 查看MySQL當前時區、時間
mydba@192.168.85.132,3306 [replcrash]> show variables like '%time_zone%';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone | CST    |
| time_zone        | SYSTEM |
+------------------+--------+
2 rows in set (0.01 sec)

mydba@192.168.85.132,3306 [replcrash]> select now();
+---------------------+
| now()               |
+---------------------+
| 2018-01-10 11:29:25 |
+---------------------+
1 row in set (0.00 sec)
time_zone說明MySQL使用system的時區,system_time_zone說明system使用CST時區


# 修改MySQL全局時區爲西八區
mydba@192.168.85.132,3306 [replcrash]> set global time_zone = '-8:00';
Query OK, 0 rows affected (0.00 sec)
# 修改當前會話時區
mydba@192.168.85.132,3306 [replcrash]> set time_zone = '-8:00';
Query OK, 0 rows affected (0.00 sec)
# 查看MySQL當前時區、時間
mydba@192.168.85.132,3306 [replcrash]> show variables like '%time_zone%';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone | CST    |
| time_zone        | -08:00 |
+------------------+--------+
2 rows in set (0.02 sec)

mydba@192.168.85.132,3306 [replcrash]> select now();
+---------------------+
| now()               |
+---------------------+
| 2018-01-09 19:31:15 |
+---------------------+
1 row in set (0.00 sec)

# 當前的time_zone
mydba@192.168.85.132,3306 [replcrash]> select @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| -08:00             | -08:00              |
+--------------------+---------------------+
1 row in set (0.00 sec)
View Code

The current session time zone setting affects display and storage of time values that are zone-sensitive. This includes the values displayed by functions such as NOW() or CURTIME(), and values stored in and retrieved from TIMESTAMP columns. Values for TIMESTAMP columns are converted from the current time zone to UTC for storage, and from UTC to the current time zone for retrieval.
The current time zone setting does not affect values displayed by functions such as UTC_TIMESTAMP() or values in DATE, TIME, or DATETIME columns. Nor are values in those data types stored in UTC; the time zone applies for them only when converting from TIMESTAMP values. If you want locale-specific arithmetic for DATE, TIME, or DATETIME values, convert them to UTC, perform the arithmetic, and then convert back.
time_zone變量對時區敏感的time values有影響,好比now()、curtime()、timestamp columns(TIMESTAMP列,在庫中存儲的是TIMESTAMP(一串數字))app

3、system_time_zone

3.一、官方解釋

The server system time zone. When the server begins executing, it inherits a time zone setting from the machine defaults, possibly modified by the environment of the account used for running the server or the startup script. The value is used to set system_time_zone. Typically the time zone is specified by the TZ environment variable. It also can be specified using the --timezone option of the mysqld_safe script.
The system_time_zone variable differs from time_zone. Although they might have the same value, the latter variable is used to initialize the time zone for each client that connects.

前面提到的log_timestamps能夠設置爲SYSTEM,time_zone默認初始化爲SYSTEM,這些SYSTEM就是指system_time_zone。實例啓動時默認會繼承當前服務器的時區,咱們能夠經過TZ環境變量或者mysqld_safe --timezone選項設置system_time_zoneide

3.二、跨時區主從複製的潛在問題

跨時區主從複製的潛在問題參考這裏函數

# 主庫執行(東六區)
mysql> insert into mytable values(now())
mysql> select * from mytable --返回2018-01-10 13:50:33

# 從庫應用relay-log(東八區)
mysql> select * from mytable --返回2018-01-10 13:50:33

# 咱們但願從庫查詢的結果是
mysql> select * from mytable --返回2018-01-10 15:50:33

東六區的 2018-01-10 13:50:33 和東八區的 2018-01-10 15:50:33 纔是同一時間,咱們就是要解決這樣的問題
View Code

這種問題應該只存在於SBR環境,RBR的binlog中記錄的是具體數值,不會記錄now()之類的函數
By default, master and slave servers assume that they are in the same time zone. If you are replicating between servers in different time zones, the time zone must be set on both master and slave. Otherwise, statements depending on the local time on the master are not replicated properly, such as statements that use the NOW() or FROM_UNIXTIME() functions. Set the time zone in which MySQL server runs by using the --timezone=timezone_name option of the mysqld_safe script or by setting the TZ environment variable. 
下面測試在主、從設置time zone後是否如你所願測試

# mysqld_safe --timezone
shell> /usr/local/mysql/bin/mysqld_safe --defaults-file=/data/mysql/mysql3306/my.cnf --timezone=UTC &
shell> /usr/local/mysql/bin/mysqld_safe --defaults-file=/data/mysql/mysql3308/my.cnf --timezone=MET &
影響的是system_time_zone變量,主從複製,statement格式下,now()複製到從庫
2018-01-10 07:41:17->2018-01-10 08:41:17

# mysqld --default-time-zone
shell> /usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/mysql3306/my.cnf --default-time-zone=+6:00 &
shell> /usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/mysql3308/my.cnf --default-time-zone=+8:00 &
影響的是time_zone變量,主從複製,statement格式下,now()複製到從庫
2018-01-10 13:50:33->2018-01-10 13:50:33

緣由:mysqld_safe --timezone參數,在從庫的binlog能夠看到
SET TIMESTAMP=1515570077;
SET @@session.time_zone='SYSTEM'; #會根據system_time_zone中的時區去設置
insert ... select now();

mysqld --default-time-zone參數,在從庫的binlog能夠看到
SET TIMESTAMP=1515570633;
SET @@session.time_zone='+06:00'; #直接複製主庫,時間不會變化
insert ... select now();

# time_zone、timestamp對now()的影響
mysql> set time_zone='+6:00';set timestamp=1515570633;select now();
mysql> set time_zone='+8:00';set timestamp=1515570633;select now();
# 恢復timestamp
mysql> set timestamp=0;select now();


# timezone_name須要手動load
mysql> SELECT CONVERT_TZ('2018-01-10 12:00:00','+8:00','+6:00');
mysql> SELECT CONVERT_TZ('2018-01-10 12:00:00','US/Eastern','US/Central');
mysql> SELECT FROM_UNIXTIME(1515570633),UNIX_TIMESTAMP(now());
View Code

能夠看出只有主、從設置system_time_zone後,以前的潛在問題纔會按咱們預期的結果顯示~

4、參考文檔

MySQL Server Time Zone Support:https://dev.mysql.com/doc/refman/5.7/en/time-zone-support.html
Replication and System Functions:https://dev.mysql.com/doc/refman/5.7/en/replication-features-functions.html
Replication and Time Zones:https://dev.mysql.com/doc/refman/5.7/en/replication-features-timezone.html

相關文章
相關標籤/搜索