48 mysql 全局变量修改了时区, 客户端拿到的依然是旧时区

前言

这是一个 我们最近碰到的问题

在我们的一个 服务平台 查询到的时间字段 比 当前时区的当前时间多 8 小时 

然后 这个问题 也是挺神奇的, navicate 上面查询到的 时间是在正常的时间

然后 查询环境变量 tz_zone 是 “+08:00”, 也没有问题, 但是 客户端这边 拿到的是 当前时间 + 8小时 

时间相关数据传输以及转换 请参见 mysql date/time/datetime/year 的数据存储 

 

从结果上来看 可以大致的推断是 

客户端这边的 serverTimeZone 拿到的应该是 “+00:00”, 然后 将服务器传回来的字符串 “2023-07-25 00:00:00” 以 “+00:00” 转换为时间戳, 然后在转换为客户端本地的时间, 客户端本地的时区为 “+08:00”, 因此 得到 “2023-07-25 08:00:00”

 

问题的上下文是

同事 查看了 mysql 的 timezone 为 “+00:00”, 然后 将其时区更新为了 “+08:00”

但是 我不清楚他是怎么更新的, 是直接设置 全局变量, 还是说 改配置文件重启, 我最开始的理解是 改配置文件重启, 但是 后来怎么都发现不对, 原来是 直接设置的全局变量

然后 之后发现 服务平台这边 查询到的数据 还是有问题, 比当前时间 多了 8 个小时 

 

 

测试用例

测试用例如下, 关键的地方 是需要使用连接池 来复用连接 

/*** Test06MysqlTimezone02** @author Jerry.X.He* @version 1.0* @date 2023/7/26 9:58*/
public class Test06MysqlTimezone02 {// Test06MysqlTimezonepublic static void main(String[] args) throws Exception {QueryRunner jdbcTemplate = initDbConnect();String sql = " select * from tz_zone; ";while (true) {Map<String, Object> entity = jdbcTemplate.query(sql, new MapHandler());System.out.println((entity.get("field1")).toString());Tools.sleep(10_000);}}public static QueryRunner initDbConnect() {//        String url = "jdbc:mysql://10.60.50.16:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&autoReconnectForPools=true&useSSL=false&serverTimezone=GMT%2B0";
//        String url = "jdbc:mysql://10.60.50.16:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&autoReconnectForPools=true&useSSL=false";String host = "10.60.50.16";String port = "3306";String db = "test";String username = "root";String password = "root";String URL_TEMPLATE = "jdbc:mysql://%s:%s/%s";Properties prop = new Properties();prop.put("url", String.format(URL_TEMPLATE, host, port, db));prop.put("username", username);prop.put("password", password);prop.put("driver", "com.mysql.jdbc.Driver");prop.put("validationQuery", "select 1");prop.put("initialSize", 10);prop.put("minIdle", 10);prop.put("maxIdle", 10);prop.put("maxActive", 10);prop.put("maxWait", 100 * 1000);prop.put("timeBetWeenEvictionRunsMillis", 100 * 1000);prop.put("minEvictableIdleTimeMillis", 300000);prop.put("poolPreparedStatements", true);prop.put("testWhileIdle", true);DataSource dataSource = null;try {dataSource = BasicDataSourceFactory.createDataSource(prop);} catch (Exception e) {e.printStackTrace();}return new QueryRunner(dataSource);}}

 

 

确定客户端的时区

将字节序列转换为 Timestamp 的地方是在 SqlTimestampValueFactory 中进行处理的 

这里传入的时间为 当前 session 缓存的 time_zone 为 “+00:00”, 然后传入的 time_zone 是来自于 session 的环境变量 

222d19c9d7c75bc273b6d97f33730fbd.png

 

session 的 serverTimeZone 的初始化如下, 有限获取的是客户端这边本地配置的 serverTimeZone, 其次获取的是 从服务器这边获取到的 time_zone 的值 

f4aabd16c6f832e3bd63578622350d91.png

 

所以 我们这边从 NativeServerSession 这边开始出发, 查看 它的 serverTimeZone

754d7de48a4b6d9d0e9a08ddc81affaf.png 

其值为 “GMT+00:00”, 这就是 上面转换 相比于本地时间 多了八个小时的原因

4997e20f22dccb49d2cacbe009c10dbf.png 

然后 我们再来看一下 它是获取的是 客户端这边本地配置的参数, 还是 服务器这边拿回来的 tz_zone 呢? 

服务器这边 拿回来的配置 time_zone 如下, 可以看到的是 “+00:00”

1149dc4aba258d1811a05313c7df42d5.png

42394817630bd1d0230c949d1f25a3f4.png 

查看一下 客户度这边的配置如下, 可以看到 值为 null

357531481842ee92d31ce9f6e26e2e79.png

69b686cdc7b152f662d60162985696f8.png 

123a1db7faf5f5ebec0be98248949b4f.png

e5ae260d2605450b675cf1a92b1f4dbf.png

 

综上 客户端这边拿到的转换 Timestamp 使用的时区是 “GMT+00:00“

因此 我当时的做法是 直接重启了一下 服务, 解决了问题

 

 

重启服务是否能够复现问题?

回到 开始的地方, 是直接设置 全局变量, 还是说 改配置文件重启, 我最开始的理解是 改配置文件重启, 但是 后来怎么都发现不对, 原来是 直接设置的全局变量

假设 我们这里是 更新了配置之后, 重启 mysql 服务, 更新时区为 “GMT+08:00”

可以看到的是, 这里重新建立的连接, 然后 自然从服务器这边 拿到的是最新的时区配置 “GMT+08:00”

fd2fcefb8accee73e0e6a3e3d374e7b6.png

 

具体的处理是 客户端连接池这边的处理, 先是原有的连接已经关闭, 然后移除该连接 

然后是 新建和数据库这边的连接

c5dc78cf01492e91ff4241a02c688452.png

3863466bbcc9cceabe3243877bf92000.png 

获取到的数据如下, 可以看到 中途数据同一个字段的时间更新了

2023-07-25 08:00:00.0
2023-07-25 08:00:00.0
2023-07-25 08:00:00.0
2023-07-25 00:00:00.0
2023-07-25 00:00:00.0
2023-07-25 00:00:00.0

 

 

更新服务器的全局变量是否能够复现问题?

执行 sql 如下 “set global time_zone = '+08:00';”

然后 服务器这边 全局变量的时区为 “GMT+08:00”, 然后 客户端那边的时区为创建连接的时候获取到的 “GMT+00:00”

然后 和同事咨询了一下, 他确实是 直接在 服务器这边 直接设置的全局变量 time_zone

 

获取到的数据如下, 可以看到 该字段的时间在调整 time_zone 前后, 客户端这边的处理 没有任何变化

2023-07-25 08:00:00.0
2023-07-25 08:00:00.0
2023-07-25 08:00:00.0
2023-07-25 08:00:00.0
2023-07-25 08:00:00.0
2023-07-25 08:00:00.0

 

 

Navicate 这边展示的时间是否随着 serverTimeZone 变化? 

呵呵 令我意外的是, navicate 这边展示的 时间字段的信息 貌似是直接是 服务器响应回来的时间字符串, 而没有根据服务器时区转换为时间戳, 然后再根据客户端时区转换为具体的时间 

 

观察一下 session 和 全局 级别的 time_zone 的配置, 均是配置的 “GMT+00:00”

e4c9fa777c0cf3092727f9d0305da4b9.png

2bbe0c28a41e8cbaae9ce1438bce254b.png 

 

然后查询结果如下, field1 为 正确的 “GMT+08:00” 的时间 

或者说 是最开始存放给 mysql 的那个 “时间字符串”

2cb4b247203f6c75e9d84d48668e7604.png

 

从服务器这边 拿到的数据如下

9193f032ff04d84cd383dd2fb460e5b4.png 

为了验证这个, 我们可以调整一下 服务器这边的输出

原始输出如下, 我们调整一下, 改一下 年月日 和 时分秒 中间的分隔符

5aee5f907900e5be05da251d896f3021.png

 

调整之后 日期如下

0d623c6f30c7b75ed96faae1f97e0d5d.png 

客户端这边 展示如下, 可以看到 navicate 这边展示的服务器响应回来的字符串本身 

28363de2f3f4f7605b3a37d4d843aa7b.png 

 

 

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【HTML+CSS】HTML超链接:构建网页导航的基石

目录 什么是HTML超链接&#xff1f; 基本语法 示例 链接到另一个网页 链接到同一页面内的不同部分 常用属性 在Web开发的广阔世界中&#xff0c;HTML&#xff08;HyperText Markup Language&#xff09;作为网页内容的标准标记语言&#xff0c;扮演着至关重要的角色。而在…

nodejs安装及环境配置轨道交通运维检测系统App-OA人事办公排班故障维修

✌网站介绍&#xff1a;✌10年项目辅导经验、专注于计算机技术领域学生项目实战辅导。 ✌服务范围&#xff1a;Java(SpringBoo/SSM)、Python、PHP、Nodejs、爬虫、数据可视化、小程序、安卓app、大数据等设计与开发。 ✌服务内容&#xff1a;免费功能设计、免费提供开题答辩P…

【SpringCloud】企业认证、分布式事务,分布式锁方案落地-2

目录 高并发缓存三问 - 穿透 缓存穿透 概念 现象举例 解决方案 缓存穿透 - 预热架构 缓存穿透 - 布隆过滤器 布隆过滤器 布隆过滤器基本思想​编辑 了解 高并发缓存三问 - 击穿 缓存击穿 高并发缓存三问 - 雪崩 缓存雪崩 解决方案 总结 为什么要使用数据字典&…

对Linux目录结构的补充

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 ☁️运维工程师的职责&#xff1a;监…

白鲸开源CEO郭炜荣获「2024中国数智化转型升级先锋人物」称号

2024年7月24日&#xff0c;由数据猿主办&#xff0c;IDC协办&#xff0c;新华社中国经济信息社、上海大数据联盟、上海市数商协会、上海超级计算中心作为支持单位&#xff0c;举办“数智新质力拓未来 2024企业数智化转型升级发展论坛——暨AI大模型趋势论坛”数据猿“年中特别策…

数据结构_study(一)

术语 程序设计数据结构算法 数据结构&#xff1a;相互之间存在一种或多种特定关系的数据元素的集合 数据&#xff1a;输入到计算机中可以操作的对象&#xff0c;数值类型&#xff08;整型&#xff0c;浮点型&#xff09;&#xff0c;非数值类型&#xff08;字符&#xff0c;…

算法——二分查找(day10)

目录 69. x 的平方根 题目解析&#xff1a; 算法解析&#xff1a; 代码&#xff1a; 35. 搜索插入位置 题目解析&#xff1a; 算法解析&#xff1a; 代码&#xff1a; 69. x 的平方根 69. x 的平方根 - 力扣&#xff08;LeetCode&#xff09; 题目解析&#xff1a; 老…

Linux 安装mysql-client-core-8.0

在Linux上安装mysql-client-core-8.0 安装流程 下面是安装mysql-client-core-8.0的步骤和相应的命令&#xff1a; 步骤1&#xff1a;更新系统软件源 我们首先需要更新系统的软件源&#xff0c;以确保我们能够获取到最新的软件包列表。使用以下命令更新软件源&#xff1a; …

C语言——运算符及表达式

C语言——运算符及表达式 运算符运算符的分类&#xff08;自增运算符&#xff09;、--&#xff08;自减运算符&#xff09;赋值运算符逗号运算符&#xff08;顺序求值运算符&#xff09; 表达式 运算符 运算符的分类 C语言的运算符范围很宽&#xff0c;除了控制语句和输入输出…

go语音进阶 Goroutine

什么是 Goroutine&#xff1f; 在Go语言中 是通过 ‘协程’ 来实现并发&#xff0c; Goroutine 是 Go 语言特有的名词&#xff0c; 区别于进程 Process&#xff0c; 线程Thread&#xff0c; 协程 Coroutine, 因为 Go语言的作者们觉得是有所区别的&#xff0c;所有专门创造做 Go…

python-绝对值排序(赛氪OJ)

[题目描述] 输入 n 个整数&#xff0c;按照绝对值从大到小排序后输出。保证所有整数的绝对值不同。输入格式&#xff1a; 输入数据有多组&#xff0c;每组占一行&#xff0c;每行的第一个数字为 n ,接着是 n 个整数&#xff0c; n0 表示输入数据的结束&#xff0c;不做处理。输…

Ruoyi-WMS本地运行

所需软件 1、JDK&#xff1a;8 安装包&#xff1a;https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.htmlopen in new window 安装文档&#xff1a;https://cloud.tencent.com/developer/article/1698454open in new window 2、Redis 3.0 安装包&a…

[Vulnhub] Acid-Reloaded SQLI+图片数据隐写提取+Pkexec权限提升+Overlayfs权限提升

信息收集 IP AddressOpening Ports192.168.101.158TCP:22,33447 $ nmap -p- 192.168.101.158 --min-rate 1000 -sC -sV Not shown: 65534 closed tcp ports (conn-refused) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 6.7p1 Ubuntu 5ubuntu1.3 (Ubuntu Lin…

C语言玩一下标准输出——颜色、闪烁、加粗、下划线属性

文章目录 C语言玩一下标准输出——颜色、闪烁、加粗、下划线属性转换Tip切换内容介绍显示方式字体色背景色 常用光标控制附示例和运行结果 C语言玩一下标准输出——颜色、闪烁、加粗、下划线属性 标准输出格式其属性可控制&#xff0c;控制由一系列的控制码指定。标准输出函数可…

【微信小程序实战教程】之微信小程序 WXS 语法详解

WXS语法 WXS是微信小程序的一套脚本语言&#xff0c;其特性包括&#xff1a;模块、变量、注释、运算符、语句、数据类型、基础类库等。在本章我们主要介绍WXS语言的特性与基本用法&#xff0c;以及 WXS 与 JavaScript 之间的不同之处。 1 WXS介绍 在微信小程序中&#xff0c…

【Socket编程】了解应用层协议HTTP

HTTP协议 HTTP又叫超文本传输协议。它定义了客户端和服务端之间该如何通信&#xff0c;以交换或者传输超文本&#xff08;如HTML文档&#xff09;。HTTP协议是一个无连接、无状态的协议&#xff0c;即每次请求都需要建立新的连接&#xff0c;且服务器不会保存客户端的状态信息…

智谱OpenDay“大有可玩”:30秒将任意文字生成视频

Sora毫无疑问带来AI大模型的全新玩法&#xff0c;大模型可基于任意文字生成视频&#xff0c;这也是这个“大家庭”若干努力&#xff08;包括Runway的Gen系列、微软的Nuwa、Meta的Emu、谷歌的Phenaki/VideoPoet、CogVideo等&#xff09;的一个全新高度。 7月26日&#xff0c;这…

FastAPI(七十七)实战开发《在线课程学习系统》接口开发-- 课程编辑和查看评论

源码见&#xff1a;"fastapi_study_road-learning_system_online_courses: fastapi框架实战之--在线课程学习系统" 课程编辑 先来看下课程编辑 1.判断是否登录 2.判断课程是否存在 3.是否有权限&#xff08;只有自己可以修改自己的课程&#xff09; 4.名称是否重复…

Docker(十)-Docker运行elasticsearch7.4.2容器实例以及分词器相关的配置

1.下载镜像 1.1存储和检索数据 docker pull elasticsearch:7.4.2 1.2可视化检索数据 docker pull kibana:7.4.22.创建elasticsearch实例 创建本地挂载数据卷配置目录 mkdir -p /software/elasticsearch/config 创建本地挂载数据卷数据目录 mkdir -p /software/elasticse…

【LeetCode:3098. 求出所有子序列的能量和 + 记忆化缓存】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…