在非 UTC 服务器上所有带有时间戳的 mysql 导出文件中是否存在错误?
Is there a bug in all mysql export file with timestamp on non UTC servers?
只需将 sql 数据库从一台服务器移动到另一台服务器
我了解 MYSQL 中的时间戳字段存储为 4 字节整数(时区不可知)并在当前服务器(mysql 服务器)时区设置中呈现给用户
我说得对吗?
现在10月份欧洲夏令时到冬令时(UTC+2到UTC+1)时,有一个小时的时间重叠。
这是有道理的,不是问题,因为我们'know'服务器知道差异,因为它以 unix utc 时间戳存储它们。
我还是对的吗?
现在,当我将数据库导出从一个数据库移动到另一个数据库时,时间戳字段不会像整数那样移动,而是作为人类可读的时间字符串移动:
只是一个示例:
(1,'AAAA01',6.50,NULL,NULL,NULL,'2017-07-28 17:38:16',0,NULL,NULL,NULL,NULL,0,NULL),
(2,'AAAA01',6.50,NULL,NULL,NULL,'2017-07-28 20:00:00',1,NULL,NULL,NULL,NULL,0,NULL),
(3,'AAAA01',6.00,NULL,NULL,NULL,'2017-07-28 21:39:07',0,NULL,NULL,NULL,NULL,0,NULL),
(4,'AAAA01',5.50,NULL,NULL,NULL,'2017-07-28 21:42:15',0,NULL,NULL,NULL,NULL,0,NULL),
(5,'AAAA01',5.00,NULL,NULL,NULL,'2017-07-29 12:55:48',0,NULL,NULL,NULL,NULL,0,NULL),
您可以看到这个字段:
`received` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
但存储为人类可读字段。
接收服务器如何知道该字段是在时间更改之前还是之后(十月)
时差每年发生 2 次,在 spring 中它向前推进一个小时,因此不会混淆,因为只有一个小时的差距,但在秋天它会向后并且 'overwrites'同样的时间..
时区转换
Mysql服务器怎么能给出这个时间的答案,因为它代表了两个不同的时间:
SELECT CONVERT_TZ( '2018-10-28 02:40', 'Europe/Paris', 'UTC' )
MySQL 服务器的时区只是用于这些转换的默认 时区。它可以在每个连接的基础上被覆盖。这就是在这里发生的事情,使这项工作。
当mysqldump
查询服务器以检索要写入备份文件的数据时,它首先发送:
SET TIME_ZONE='+00:00';
这将 mysqldump 连接的会话(连接)时区设置为 UTC,这导致服务器以 UTC 发送那些 TIMESTAMP
列,并以这种方式写入备份文件。
在转储文件的顶部附近,它还添加了:
/*!40103 SET TIME_ZONE='+00:00' */;
/*! ... */
is not really a comment,虽然看起来像一个。 !40103
向任何 MySQL 服务器版本 4.01.03 或更高版本发出信号以正常执行嵌入式语句——因此将正在恢复转储的连接上的会话时区也设置为 UTC,以便这些时间戳字符串存储正确。
DATETIME
列不进行这些转换——仅 TIMESTAMP
... 但对于 TIMESTAMP
列,新服务器上不应有不正确的值。转储文件中的值是 UTC——这也是本机内部存储格式的时区(在技术上根本不是不可知的)。
另请注意,将服务器时区设置为 UTC 以外的任何时区不再被视为最佳做法。当地时间是一个表示问题,最好由应用程序处理,而不是数据库。 UTC 没有像本地时区那样的模糊性——例如 spring 中缺失的小时和秋季的重复小时,在许多本地时区中都可以找到。
只需将 sql 数据库从一台服务器移动到另一台服务器
我了解 MYSQL 中的时间戳字段存储为 4 字节整数(时区不可知)并在当前服务器(mysql 服务器)时区设置中呈现给用户 我说得对吗?
现在10月份欧洲夏令时到冬令时(UTC+2到UTC+1)时,有一个小时的时间重叠。
这是有道理的,不是问题,因为我们'know'服务器知道差异,因为它以 unix utc 时间戳存储它们。
我还是对的吗?
现在,当我将数据库导出从一个数据库移动到另一个数据库时,时间戳字段不会像整数那样移动,而是作为人类可读的时间字符串移动:
只是一个示例:
(1,'AAAA01',6.50,NULL,NULL,NULL,'2017-07-28 17:38:16',0,NULL,NULL,NULL,NULL,0,NULL),
(2,'AAAA01',6.50,NULL,NULL,NULL,'2017-07-28 20:00:00',1,NULL,NULL,NULL,NULL,0,NULL),
(3,'AAAA01',6.00,NULL,NULL,NULL,'2017-07-28 21:39:07',0,NULL,NULL,NULL,NULL,0,NULL),
(4,'AAAA01',5.50,NULL,NULL,NULL,'2017-07-28 21:42:15',0,NULL,NULL,NULL,NULL,0,NULL),
(5,'AAAA01',5.00,NULL,NULL,NULL,'2017-07-29 12:55:48',0,NULL,NULL,NULL,NULL,0,NULL),
您可以看到这个字段:
`received` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
但存储为人类可读字段。
接收服务器如何知道该字段是在时间更改之前还是之后(十月)
时差每年发生 2 次,在 spring 中它向前推进一个小时,因此不会混淆,因为只有一个小时的差距,但在秋天它会向后并且 'overwrites'同样的时间..
时区转换
Mysql服务器怎么能给出这个时间的答案,因为它代表了两个不同的时间:
SELECT CONVERT_TZ( '2018-10-28 02:40', 'Europe/Paris', 'UTC' )
MySQL 服务器的时区只是用于这些转换的默认 时区。它可以在每个连接的基础上被覆盖。这就是在这里发生的事情,使这项工作。
当mysqldump
查询服务器以检索要写入备份文件的数据时,它首先发送:
SET TIME_ZONE='+00:00';
这将 mysqldump 连接的会话(连接)时区设置为 UTC,这导致服务器以 UTC 发送那些 TIMESTAMP
列,并以这种方式写入备份文件。
在转储文件的顶部附近,它还添加了:
/*!40103 SET TIME_ZONE='+00:00' */;
/*! ... */
is not really a comment,虽然看起来像一个。 !40103
向任何 MySQL 服务器版本 4.01.03 或更高版本发出信号以正常执行嵌入式语句——因此将正在恢复转储的连接上的会话时区也设置为 UTC,以便这些时间戳字符串存储正确。
DATETIME
列不进行这些转换——仅 TIMESTAMP
... 但对于 TIMESTAMP
列,新服务器上不应有不正确的值。转储文件中的值是 UTC——这也是本机内部存储格式的时区(在技术上根本不是不可知的)。
另请注意,将服务器时区设置为 UTC 以外的任何时区不再被视为最佳做法。当地时间是一个表示问题,最好由应用程序处理,而不是数据库。 UTC 没有像本地时区那样的模糊性——例如 spring 中缺失的小时和秋季的重复小时,在许多本地时区中都可以找到。