mysql内部时区_一文解决MySQL时区相关问题

前言:

在使用MySQL的过程中,你可能会遇到时区相关问题,比如说时间显示错误、时区不是东八区、程序取得的时间和数据库存储的时间不一致等等问题。其实,这些问题都与数据库时区设置有关,本篇文章将从数据库参数入手,逐步介绍时区相关内容。

1.log_timestamps参数介绍

首先说明下log_timestamps参数并不影响时区,只是设置不同会影响某些日志记录的时间。该参数主要是控制 error log、slow log、genera log 日志文件中的显示时间,但不会影响 general log 和 slow log 写到表 (mysql.general_log, mysql.slow_log) 中的显示时间。

log_timestamps是全局参数,可动态修改,默认使用UTC时区,这样会使得日志中记录的时间比北京时间慢8个小时,导致查看日志不方便。可以修改为SYSTEM变成使用系统时区。下面简单测试下该参数的作用及修改方法:

# 查看参数值

mysql> show global variables like 'log_timestamps';

+----------------+-------+

| Variable_name | Value |

+----------------+-------+

| log_timestamps | UTC |

+----------------+-------+

1 row in set (0.00 sec)

# 产生慢日志

mysql> select sleep(10),now();

+-----------+---------------------+

| sleep(10) | now() |

+-----------+---------------------+

| 0 | 2020-06-24 17:12:40 |

+-----------+---------------------+

1 row in set (10.00 sec)

# 慢日志文件记录内容 发现时间是UTC时间

# Time: 2020-06-24T09:12:50.555348Z

# User@Host: root[root] @ localhost [] Id: 10

# Query_time: 10.000354 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 1

SET timestamp=1592989960;

select sleep(10),now();

# 修改参数值 再次测试

mysql> set global log_timestamps = SYSTEM;

Query OK, 0 rows affected (0.00 sec)

mysql> select sleep(10),now();

+-----------+---------------------+

| sleep(10) | now() |

+-----------+---------------------+

| 0 | 2020-06-24 17:13:44 |

+-----------+---------------------+

1 row in set (10.00 sec)

# 慢日志文件记录内容 时间是对的

# Time: 2020-06-24T17:13:54.514413+08:00

# User@Host: root[root] @ localhost [] Id: 10

# Query_time: 10.000214 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 1

SET timestamp=1592990024;

select sleep(10),now();

2.time_zone参数介绍

time_zone参数用来设置每个连接会话的时区,该参数分为全局和会话级别,可以动态修改。默认值为SYSTEM,此时使用的是全局参数system_time_zone的值,而system_time_zone默认继承自当前系统的时区,即默认情况下MySQL时区和系统时区相同。

时区设置主要影响时区敏感的时间值的显示和存储。包括一些函数(如now()、curtime())显示的值,以及存储在TIMESTAMP类型中的值,但不影响DATE、TIME和DATETIME列中的值,因为这些数据类型在存取时未进行时区转换,而TIMESTAMP类型存入数据库的实际是UTC的时间,查询显示时会根据具体的时区来显示不同的时间。

下面我们来测试下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 如何避免出现时区问题

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

首先保证系统时区准确。

jdbc连接串中指定时区,并与数据库时区一致。

time_zone参数建议设置为'+8:00',不使用容易误解的CST。

各环境数据库实例时区参数保持相同。

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

总结:

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

2f65deb287714bd3fd3c7157dfd951ef.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/552413.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

制作 mysql的rpm文件_自制mysql.rpm安装包

RPM安装比源码更快更方便,更利于统一版本,省去了繁琐的编译过程,下面以制作mysql的rpm安装包为例。编译环境1、 安装rpm-build;检查是否配置rpm环境1 # sudo yum list | greprpm2 This system is not registered with RHN.3 RHN s…

mysql远程授权格式_MySQL远程访问授权

开启 MySQL 的远程登陆帐号有两大步:1、确定服务器上的防火墙没有阻止 3306 端口。MySQL 默认的端口是 3306 ,需要确定防火墙没有阻止 3306 端口,否则远程是无法通过 3306 端口连接到 MySQL 的。如果您在安装 MySQL 时指定了其他端口&#xf…

mysql multi主从复制_mysqld_multi方式配置Mysql数据库主从复制

mysqld_multi设计用于管理在同一台机器上运行的多个mysqld进程,这些进程使用不同的socket文件并监听在不同的端口上。mysqld_multi可以批量启动、关闭、或者报告这些mysqld进程的状态。在这里我们通过这种方式来在同一个机器上启动多个数据库实例,并配置…

mysql 日志节点恢复_基于binlog二进制日志的MySQL恢复笔记

基于binlog二进制日志的MySQL恢复笔记刚好复习到这里,顺手做个小实验,记录下。总的操作流程:step0、关掉数据库的对外访问【防止用户操作继续写入这个库】step1、mysqlbinlog 导出相关时间段数据库的二进制日志step2、编辑today.sql找到误操作…

mysql中if在oracle怎么用_mysql和oracle的mybatis操作

1.Oracle、MySQL插入时返回下一个主键的操作Xml代码 Oracle:SELECT SEQ_ROLE.NEXTVAL AS ID FROM DUALinsert into ROLE(ID, NAME, CREATE, MODIFY) values (#{id}, #{name}, sysdate, sysdate)注意:这边的keyProperty"id"中"id"指的…

mysql数据库的三级模式_2016年计算机三级MySQL数据库试题

2016年计算机三级MySQL数据库试题一、选择题1.E-R图提供了表示信息世界中实体、属性和________的方法。A.数据B.联系C.表D.模式2.数据库系统的核心是________。A.数据模型B.数据库管理系统C.数据库D.数据库管理员3.E-R图是数据库设计的工具之一,它一般适用于建立数据…

python对角线图_python对角线图_python – 在Seaborn Jointplot上绘制对角线(相等的线)...

错误是一个有用的暗示:JointPlot是子图的集合,你必须找到特定的斧头来绘制.修改Seaborn示例:import numpy as npimport pandas as pdimport seaborn as snsfrom matplotlib.pyplot import showsns.set(style"white")# Generate a random corre…

python编程求极限_Sympy笔记一

from IPython.display import displayfrom sympy import *前置知识理解这份笔记的内容需,读者需要具备基础的python知识并且对函数,微积分和矩阵有一定的基础。辅助函数由于后面的笔记中, 我们会大量将一个Sympy object和应用某个函数之后&am…

python语言逆序符号_python的逆序

下面的代码片段可以帮助您完成最后一个任务。如果在字符串的开始或结尾之外的其他地方发现了特殊字符,则对于子集的恢复没有特殊处理。在# Special chars which should be ignored for revertingSPECIALCHARS [ , ., ,]def reverse( string_ ):# Find occurence of…

wpf mysql存储过程_MySQL存储过程的创建及调用

# SQL语句:先编译后执行存储过程(Stored Procedure):一组可编程的函数,是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。优点(为什么要用存储过…

mysql没加引号导致全表扫描_mysql隐蔽的索引规则导致数据全表扫描

索引是为了加速数据的检索,但是不合理的表结构或适应不当则会起到反作用。我们在项目中就遇到过类似的问题,两个十万级别的数据表,在做连接查询的时候,查询时间达到了7000多秒还没有查出结果。首先说明,关联的字段都已…

python123测验7程序题答案_Python语言程序设计 Python123 测验7: 文件和数据格式化(编程题)...

版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明。本文链接:https://blog.csdn.net/weixin_42067082/article/details/97661863文本的平均列数描述:打印输出附件文件的平均列数…

mysql 多个密码登录_mysql 多实例登录密码测试

最近在做mysql 多实例的时候,采用不同的方式登录mysql数据库,发现mysql -uroot -p -h 127.0.0.1 -P3308 ,登录时居然不要密码就可以登录,吓得我一身汗,经过检查终于找到原因记录下来,给小白们参考。[rootmy…

设置MySQL排序方式_设置MySQL设置字符集和排序方式

1. 编辑/etc/my.cnf文件, 在"[client]"下添加"default-character-setutf8"2. 编辑/etc/my.cnf文件, 在"[mysqld]"下添加"default-character-setutf8"3. 重新启动mysql服务# sudo /etc/init.d/mysqld restart* 查看系统字符集和排序方式…

redhat5.4 安装mysql_Linux redhat 5.4上安装MYDNS

Linux redhat 5.4上安装MYDNS一、1,MYDNS 的简介:MyDNS是一个UNIX平台下的免费DNS服务器端软件。它被设计成直接从数据库中读取DNS记录软件,并且修改记录后也可时时生效。在MyDNS上,你可随心所欲地增加你自己的次级域名的同时建站…

mysql 5.7 flashback_Flashback for MySQL 5.7

实现原理flashback的概念最早出现于Oracle数据库,用于快速恢复用户的误操作。flashback for MySQL用于恢复由DML语句引起的误操作,目前不支持DDL语句。例如下面的语句:DELETE FROM XXX;UPDATE XXX SET YYYZZZ;若没有flashback功能&#xff0c…

给mysql数据库设计编码_MYSQL数据库编码原理

很多站长可能与织梦CMS小编一样,觉得MYSQL数据库即熟悉又神秘。熟悉是因为我们每天都会用到MYSQL进行安装织梦程序,陌生是因为mysql经常与linux联系,是基于linux系统的下的应用,而我们平常使用的都是windows主机系统。织梦CMS就基…

Java2精要_java知识精要(一)

一、java数组 (疯狂java讲义 第4.5 ~ 4.6章节)1) 声明形式:type[] arrayName; 推荐方式type arrayName[];2) 初始化:方式一:type[] arrayName;arrayName new type[] {element1, element2, element3, ...}方式二:type[] arrayName…

java的反射机制是什么_JAVA反射机制

一、什么是反射机制 简单的来说,反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息。二、哪里用到反射机制 有些时候,我们用过一些知识&#xf…

java dot画图_小O的图案 (Java代码)(最简单的解法)

解题思路:注意事项:参考代码:import java.util.Scanner;public class C1788 {public static void main(String[] args) {Scanner sc new Scanner(System.in);while (sc.hasNext()) {F(sc.nextInt());}sc.close();}private static void F(int n){System.out.println(n);int len…