mysql解决时区相关问题


当前第2页 返回上一页

下面我们来测试下 time_zone 参数修改产生的影响:

# 查看linux系统时间及时区
[root@centos ~]# date
Sun Jun 28 14:29:10 CST 2020

# 查看MySQL当前时区、时间
mysql> show global variables like '%time_zone%';
+------------------+--------+
| Variable_name  | Value |
+------------------+--------+
| system_time_zone | CST  |
| time_zone    | SYSTEM |
+------------------+--------+
2 rows in set (0.00 sec)

mysql> select now();
+---------------------+
| now()        |
+---------------------+
| 2020-06-28 14:31:12 |
+---------------------+
1 row in set (0.00 sec)

# 创建测试表、插入部分数据
mysql> CREATE TABLE `time_zone_test` (
  ->  `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  ->  `dt_col` datetime DEFAULT NULL COMMENT 'datetime时间',
  ->  `ts_col` timestamp DEFAULT NULL COMMENT 'timestamp时间',
  ->  PRIMARY KEY (`id`)
  -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='time_zone测试表';
Query OK, 0 rows affected, 1 warning (0.07 sec)

mysql> insert into time_zone_test (dt_col,ts_col) values ('2020-06-01 17:30:00','2020-06-01 17:30:00'),(now(),now());
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0

mysql> select * from time_zone_test;
+----+---------------------+---------------------+
| id | dt_col       | ts_col       |
+----+---------------------+---------------------+
| 1 | 2020-06-01 17:30:00 | 2020-06-01 17:30:00 |
| 2 | 2020-06-28 14:34:55 | 2020-06-28 14:34:55 |
+----+---------------------+---------------------+

# 改为UTC时区 并重新连接 发现timestamp存储的时间会随时区变化
mysql> set global time_zone='+0:00';
Query OK, 0 rows affected (0.00 sec)
mysql> set time_zone='+0:00';
Query OK, 0 rows affected (0.00 sec)

mysql> show global variables like '%time_zone%';
+------------------+--------+
| Variable_name  | Value |
+------------------+--------+
| system_time_zone | CST  |
| time_zone    | +00:00 |
+------------------+--------+
2 rows in set (0.00 sec)

mysql> select now();
+---------------------+
| now()        |
+---------------------+
| 2020-06-28 06:36:16 |
+---------------------+
1 row in set (0.00 sec)

mysql> select * from time_zone_test;
+----+---------------------+---------------------+
| id | dt_col       | ts_col       |
+----+---------------------+---------------------+
| 1 | 2020-06-01 17:30:00 | 2020-06-01 09:30:00 |
| 2 | 2020-06-28 14:34:55 | 2020-06-28 06:34:55 |
+----+---------------------+---------------------+
2 rows in set (0.00 sec)

# 改回东八时区,恢复正常
mysql> set global time_zone='+8:00';
Query OK, 0 rows affected (0.00 sec)

mysql> set time_zone='+8:00';
Query OK, 0 rows affected (0.00 sec)

mysql> show global variables like '%time_zone%';
+------------------+--------+
| Variable_name  | Value |
+------------------+--------+
| system_time_zone | CST  |
| time_zone    | +08:00 |
+------------------+--------+
2 rows in set (0.00 sec)

mysql> select now();
+---------------------+
| now()        |
+---------------------+
| 2020-06-28 14:39:14 |
+---------------------+
1 row in set (0.00 sec)

mysql> select * from time_zone_test;
+----+---------------------+---------------------+
| id | dt_col       | ts_col       |
+----+---------------------+---------------------+
| 1 | 2020-06-01 17:30:00 | 2020-06-01 17:30:00 |
| 2 | 2020-06-28 14:34:55 | 2020-06-28 14:34:55 |
+----+---------------------+---------------------+
2 rows in set (0.00 sec)

如果需要永久生效,还需写入配置文件中。例如将时区改为东八区,则需要在配置文件[mysqld]部分增加一行:default_time_zone = '+8:00'。

3.时区常见问题及如何避免

时区设置不妥可能会产生各种问题,下面我们列举下几个常见的问题及解决方法:

3.1 MySQL 内部时间不是北京时间

遇到这类问题,首先检查下系统时间及时区是否正确,然后看下 MySQL 的 time_zone,建议将 time_zone 改为'+8:00'。

3.2 Java 程序存取的时间与数据库中的时间相差 8 小时

出现此问题的原因大概率是程序时区与数据库时区不一致导致的。我们可以检查下两边的时区,如果想统一采用北京时间,则可以在 jdbc 连接串中增加 serverTimezone=Asia/Shanghai,并且 MySQL 方面也可以将 time_zone 改为'+8:00'。

3.3 程序时间与数据库时间相差 13 小时或 14 小时

如果说相差 8 小时不够让人惊讶,那相差 13 小时可能会让很多人摸不着头脑。出现这个问题的原因是 JDBC 与 MySQL 对 “CST” 时区协商不一致。因为 CST 时区是一个很混乱的时区,有四种含义:

  • 美国中部时间 Central Standard Time (USA) UTC-05:00 或 UTC-06:00
  • 澳大利亚中部时间 Central Standard Time (Australia) UTC+09:30
  • 中国标准时 China Standard Time UTC+08:00
  • 古巴标准时 Cuba Standard Time UTC-04:00

MySQL 中,如果 time_zone 为默认的 SYSTEM 值,则时区会继承为系统时区 CST,MySQL 内部将其认为是 UTC+08:00。而 jdbc 会将 CST 认为是美国中部时间,这就导致会相差 13 小时,如果处在冬令时还会相差 14 个小时。

解决此问题的方法也很简单,我们可以明确指定 MySQL 数据库的时区,不使用引发误解的 CST,可以将 time_zone 改为'+8:00',同时 jdbc 连接串中也可以增加 serverTimezone=Asia/Shanghai。

3.4 如何避免出现时区问题

如何避免上述时区问题,可能你心里也有了些方法,简要总结几点如下:

  1. 首先保证系统时区准确。
  2. jdbc 连接串中指定时区,并与数据库时区一致。
  3. time_zone 参数建议设置为'+8:00',不使用容易误解的 CST。
  4. 各环境数据库实例时区参数保持相同。

可能有的同学说了,我们数据库中 time_zone 参数选择的是默认的 SYSTEM 值,也没有发生程序时间和数据库时间不一致的问题。此时是否需要将 time_zone 改为'+8:00'?在这种情况下还是建议将 time_zone 改为'+8:00',特别是经常查询 TIMESTAMP 字段,因为当 time_zone=system 的时候,查询 timestamp 字段会调用系统的时区做时区转换,有全局锁__libc_lock_lock 的保护,可能导致线程并发环境下系统性能受限。而改为'+8:00'则不会触发系统时区转换,使用 MySQL 自身转换,大大提高了性能。

总结:

读完本篇文章,你是否对数据库时区有了更深刻的认识呢。希望这篇文章对你有所帮助,特别是想了解 MySQL 时区相关内容时,可以拿来多读读。如果你遇到过其他时区相关问题,欢迎留言讨论。

以上就是mysql解决时区相关问题的详细内容,更多关于mysql时区相关问题的资料请关注其它相关文章!

更多相关Mysql内容来自木庄网络博客


标签:Mysql

返回前面的内容

相关阅读 >>

mysql用什么代替in

怎么用win r启动mysql

.net 怎么连接mysql数据库

mysql可以设置联合唯一索引吗?

mysql如何导出表的字段和相关属性(附示例)

mysq中l建立测试父表、子表及测试用例归纳总结

了解mysql如何优化

如何使用navicat连接mysql数据库?

mysql怎么进去已有数据库

mysql数据库索引以及失效场景详解

更多相关阅读请进入《mysql》频道 >>


数据库系统概念 第6版
书籍

数据库系统概念 第6版

机械工业出版社

本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...