【问题标题】:Database timestamp mismatch数据库时间戳不匹配
【发布时间】:2018-10-09 04:21:18
【问题描述】:

在我们的数据库中有一个名为 order 的表,该表有一个名为 created_at 的列,它是一个时间戳列。 当客户创建订单时,我们通过当前时间戳设置该字段。 所以问题是当我们通过 mysqldump(直接从服务器)转储我们的 SQL 文件时,sql 文件显示,在 - 2017-01-01 10:27:35 创建的第一订单,这是完全正确。

SQL 转储查询:

INSERT INTO `orders` VALUES (1,'2017-01-01 10:27:35'');

但是,当我们从 Web 应用程序打开该订单时,它显示该订单创建于 - 2017 年 1 月 1 日下午 4:27(提前 6 小时,这是错误的)。

此外,当我们创建 MySQL 查询时,它还显示订单创建于 - 2017 年 1 月 1 日下午 4:27(提前 6 小时,这是错误的)。

这个问题发生在 2018 年 4 月 24 日,当天的 ubuntu 将我们的 MySQL 服务器从 5.7.21 更新到 5.7.22。在 MySQL 错误日志中,有一个不匹配的 +6 小时。

在第 44 行 - 缓冲池。转储完成于 180424 21:34:16(log 在 15:34:16 进入,但详细日志显示转储在 180424 完成 21:34:16 延迟 6 小时)。


目前,当我们创建订单时,created_at 字段会显示 在 web 应用程序和 mysql 查询上完美,但是当我们转储 sql 时 数据,它显示延迟 6 小时创建

注意:

  1. 我们的申请时区设置为 UTC + 6, Asia/Dhaka
  2. Mysql版本:服务器版本5.7.22-0ubuntu0.16.04.1
  3. SQL 再次转储 - /*!40103 SET TIME_ZONE='+00:00' */;
  4. 有问题的字段 - 所有时间戳列
  5. 我们的系统时间设置为 UTC + 6,mysql 全局和会话时间设置为系统。
  6. systemctl status systemd-timesyncd.service

输出:

$ systemctl status systemd-timesyncd.service
● systemd-timesyncd.service - Network Time Synchronization
   Loaded: loaded (/lib/systemd/system/systemd-timesyncd.service; enabled; vendor preset: enabled)
  Drop-In: /lib/systemd/system/systemd-timesyncd.service.d
           └─disable-with-time-daemon.conf
   Active: active (running) since Tue 2018-02-06 16:53:59 +06; 2 months 18 days ago
     Docs: man:systemd-timesyncd.service(8)
 Main PID: 11383 (systemd-timesyn)
   Status: "Synchronized to time server 91.189.94.4:123 (ntp.ubuntu.com)."
    Tasks: 2
   Memory: 564.0K
      CPU: 4.272s
   CGroup: /system.slice/systemd-timesyncd.service
           └─11383 /lib/systemd/systemd-timesyncd

【问题讨论】:

  • 请不要在一篇文章中提出多个问题。
  • @Shadow 对此感到抱歉,但这两个问题是相同的并且彼此相关。
  • 10:27:35 +0600 不是和04:27 PM UTC 完全相同的时刻吗?
  • @ÁlvaroGonzález 是的,完全一样,但在 4 月 24 日之前,我们的 Web 应用程序显示上午 10:27

标签: mysql amazon-ec2 timezone


【解决方案1】:

来自the MySQL documentation(强调我的):

当前会话时区设置会影响区域敏感时间值的显示和存储。这包括NOW()CURTIME() 等函数显示的值,以及在TIMESTAMP 列中存储和检索的值。 TIMESTAMP 列的值从当前时区转换为 UTC 以进行存储,并从 UTC 转换为当前时区以进行检索。

既然你说你的 MySQL 全局和会话时区变量设置为 SYSTEM,系统时区是 Asia/Dhaka (UTC+6),那么看起来一切都按设计工作。

请注意,对于 --tz-utc 选项,每个 mysqldump docs

... mysqldump 将其连接时区设置为 UTC 并将SET TIME_ZONE='+00:00' 添加到转储文件中。 ... --tz-utc 默认启用。要禁用它,请使用--skip-tz-utc

既然您说转储文件的输出具有正确的时间,那么除非您传递 --skip-tz-utc 标志,否则您的数据是以 UTC 格式插入的(即会话时区设置为 +00:00在插入期间)。

那么,由于您的应用程序看到时间提前了 6 小时,您的应用程序可能没有设置会话时区,因此SYSTEM 占上风。

有两种选择:

  • 在插入语句之前调用SET TIME_ZONE='SYSTEM'(或找出设置+00:00 的位置并停止这样做)这将使数据库中的项目基于系统时区。

  • 在您的应用程序中调用 SET TIME_ZONE='+00:00',以便您以 UTC 格式查询值,而不是提前 6 小时查询。这使得数据库中的项目基于 UTC(这是首选)。

【讨论】:

    猜你喜欢
    • 2021-02-26
    • 2016-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-27
    相关资源
    最近更新 更多