mysql 时区问题
2023-05-30
基本流程
个人大概的理解如下, 至于细节需要反复查看文档才能确认.
首先需要理解的是, 时区问题是为了解决存储local datetime数据才引入的问题, 如果全局都保存为epoch timestamp long 字段, 就没有这类问题需要处理了, 也就摆脱了这类烦心事.
上传数据: 客户端连接的时候是有时区信息的, 默认是本地
mysql client机器上的时区, 要么是数据库连接字符串上的时区信息, 于是看起来无时区的local datetime, 在上传保存到服务器仍然是有时区信息的.存储数据: mysql server服务端存储的local datetime会根据mysql server的时区进行转换, 默认取决于安装所在的操作系统时区(system 时区), 或者直接在
my.cnf上进行配置.查看数据: 在客户端查询数据的时候, 也会根据本地时区或是连接串的时区信息进行展示, 因此shell上看到的时间信息已经是通过时区转换的了.
问题出来了, 如果服务器的数据进行了跨操作系统迁移, 或者客户端连接串里的时区信息出现错误, 最终客户交互侧就是一团乱. 直接使用绝对时间戳, 就可以不用再纠结这些细节了.
咨询chatgpt
由于自己有大概的了解, chatgpt这段解释看起来可信度就非常高了
CST 代表什么时区
有些问题去问chatgpt, 一质问他就换另一种结果, 最后问完也不能确认到底对不对
这时候还不如问他有什么办法可以去确认, 然后按照方法执行就可以了, 授人以鱼不如授人以渔, 自己测试反而靠谱了许多.
要验证的话需要确保当前的session timezone使用的是system时区, 然后再执行now进行查询.
经过测试, mysql查询timezone返回的cst代表了中国时区.
MariaDB [(none)]> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| SYSTEM | SYSTEM |
+--------------------+---------------------+
1 row in set (0.000 sec)
MariaDB [(none)]> SELECT @@system_time_zone;
+--------------------+
| @@system_time_zone |
+--------------------+
| CST |
+--------------------+
1 row in set (0.000 sec)
MariaDB [(none)]> SELECT NOW();
+---------------------+
| NOW() |
+---------------------+
| 2023-06-04 15:37:19 |
+---------------------+
1 row in set (0.000 sec)
基本操作
MySQL Time Zones
https://stackoverflow.com/questions/9808160/mysql-time-zones
- 启动mysql server时可以配置时区
MySQL's default timezone variable can be initialised to a different value at start-up by providing the following command line option:
--default-time-zone=timezone
- 超级管理员支持runtime设置全局时区
f you are a MySQL SUPER user, you can set the SYSTEM time_zone variable at runtime from the MYSQL> prompt using the following syntax:
SET GLOBAL time_zone=timezone;
- 每个session支持设置时区
MySQL also supports individual SESSION timezone values which defaults to the GLOBAL time_zone environment variable value. To change the session timezone value during a SESSION, use the following syntax:
SET time_zone=timezone;
- 查看全局mysql时区与当前连接进程的时区
SELECT @@global.time_zone, @@session.time_zone;