夏令时结束时,时间给人的感觉像是回退了一个小时,其实是时区的变化导致。时区 America/New_York" 解析的时区会从 "-04:00"变为”-05:00“。
这个跟手动将时间回调一个小时原理是不同的。
OB 内部版本跟时间的关系是会根据时间生成一个时间戳(用函数:time_to_usec 可以类比)。
这个问题很有趣。2023 年夏令时结束是 2023-11-05 02:00:00 AM 。
下面是 OB 4.2的测试。
将主机时区设置为支持夏令时的时区
OB 会话不支持设置时区为 ‘America/New_York’
测试夏令时需要将将时区改为美国纽约时区。主机上很好改
[root@server20 /]# ll /etc/localtime
lrwxrwxrwx 1 root root 36 Nov 2 03:05 /etc/localtime -> /usr/share/zoneinfo/America/New_York
容器里如果没有生效,就设置环境变量方式。
[root@server20 /]# export TZ=America/New_York
[root@server20 /]# date -R
Sun, 05 Nov 2023 00:03:14 -0400
设置后 ,OB 重启。
还要将 OB 实例的时区设置为该时区。不过目前OB 实例的 time_zone还不支持 America/New_York 这种格式,只能用 '-04:00’这种了。
MySQL [oceanbase]> set global time_zone='America/New_York';
ERROR 1298 (HY000): Unknown or incorrect time zone: 'America/New_York'
MySQL [oceanbase]> set global time_zone='-04:00';
正常情况下,如果用地域名的话,当夏令时结束后,这个时区偏差会自动变化为 ‘-05:00’ 。现在不能自动变化,需要后面手动调整为 ‘-05:00’。
夏令时结束之前
[root@server20 /]# date -s "2023-11-05 01:30:00"
Sun Nov 5 01:30:00 EDT 2023
[root@server20 /]# date -R
Sun, 05 Nov 2023 01:30:02 -0400
[root@server20 /]# mysql -h127.1 -uroot@sys#obcedemo -P2883 -paaAA11__ -c -A oceanbase
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.6.25 OceanBase_CE 4.2.0.0 (r100010022023081817-0bdf1c0c5674e88c5ae9a8d0ae4f8077465d7fae) (Built Aug 18 2023 17:32:49)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [oceanbase]> select time_to_usec(current_timestamp),current_timestamp;
+---------------------------------+---------------------+
| time_to_usec(current_timestamp) | current_timestamp |
+---------------------------------+---------------------+
| 1699162209000000 | 2023-11-05 13:30:09 |
+---------------------------------+---------------------+
1 row in set (0.00 sec)
记住上面时间戳。
快进时间到夏令时结束前的一分钟
[root@server20 /]# date -s "2023-11-05 01:59:00"
Sun Nov 5 01:59:00 EDT 2023
[root@server20 /]# date -R
Sun, 05 Nov 2023 01:59:02 -0400
[root@server20 /]# mysql -h127.1 -uroot@sys#obcedemo -P2883 -paaAA11__ -c -A oceanbase
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 5.6.25 OceanBase_CE 4.2.0.0 (r100010022023081817-0bdf1c0c5674e88c5ae9a8d0ae4f8077465d7fae) (Built Aug 18 2023 17:32:49)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [oceanbase]> select time_to_usec(current_timestamp),current_timestamp;
+---------------------------------+---------------------+
| time_to_usec(current_timestamp) | current_timestamp |
+---------------------------------+---------------------+
| 1699163947000000 | 2023-11-05 01:59:07 |
+---------------------------------+---------------------+
1 row in set (0.01 sec)
MySQL [oceanbase]> show variables like '%time_zone%';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | +08:00 |
| time_zone | -04:00 |
+------------------+--------+
2 rows in set (0.00 sec)
时间在推进,时间戳也在增长。
等时间自然推进到 02:00:00 .
[root@server20 /]# date -R
Sun, 05 Nov 2023 01:00:39 -0500
[root@server20 /]# mysql -h127.1 -uroot@sys#obcedemo -P2883 -paaAA11__ -c -A oceanbase
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 5.6.25 OceanBase_CE 4.2.0.0 (r100010022023081817-0bdf1c0c5674e88c5ae9a8d0ae4f8077465d7fae) (Built Aug 18 2023 17:32:49)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [oceanbase]> show variables like '%time_zone%';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | +08:00 |
| time_zone | -04:00 |
+------------------+--------+
2 rows in set (0.00 sec)
MySQL [oceanbase]> select time_to_usec(current_timestamp),current_timestamp;
+---------------------------------+---------------------+
| time_to_usec(current_timestamp) | current_timestamp |
+---------------------------------+---------------------+
| 1699164048000000 | 2023-11-05 02:00:48 |
+---------------------------------+---------------------+
1 row in set (0.00 sec)
MySQL [oceanbase]> set session time_zone='-05:00';
Query OK, 0 rows affected (0.00 sec)
MySQL [oceanbase]> select time_to_usec(current_timestamp),current_timestamp;
+---------------------------------+---------------------+
| time_to_usec(current_timestamp) | current_timestamp |
+---------------------------------+---------------------+
| 1699164058000000 | 2023-11-05 01:00:58 |
+---------------------------------+---------------------+
1 row in set (0.00 sec)
夏令时结束后,主机的时区自动变为 “-05:00”。
OB 实例的变量不会自动变,手动设置为 “-05:00”。然后时间倒退了一个小时。
但是此时的时间戳依然是增长的。
所以, 夏令时结束并不会影响 OB 的运行。只是OB 目前还没有完美支持夏令时时区的设置。需要手动设置一下。
下面再看看时间手动回退。
时间手动回退测试
先把时间推进到一个不毗邻 夏令时切换的时间。
[root@server20 /]# date -s "2023-11-05 03:10:00"
Sun Nov 5 03:10:00 EST 2023
<....>
[root@server20 /]# date -R
Sun, 05 Nov 2023 03:13:38 -0500
[root@server20 /]# mysql -h127.1 -uroot@sys#obcedemo -P2883 -paaAA11__ -c -A oceanbase
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.6.25 OceanBase_CE 4.2.0.0 (r100010022023081817-0bdf1c0c5674e88c5ae9a8d0ae4f8077465d7fae) (Built Aug 18 2023 17:32:49)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [oceanbase]> show variables like '%time_zone%';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | +08:00 |
| time_zone | -05:00 |
+------------------+--------+
2 rows in set (0.00 sec)
MySQL [oceanbase]> select time_to_usec(current_timestamp),current_timestamp;
+---------------------------------+---------------------+
| time_to_usec(current_timestamp) | current_timestamp |
+---------------------------------+---------------------+
| 1699172022000000 | 2023-11-05 03:13:42 |
+---------------------------------+---------------------+
1 row in set (0.00 sec)
强行将时间回退一个小时。
[root@server20 /]# date -s "2023-11-05 02:13:00"
Sun Nov 5 02:13:00 EST 2023
[root@server20 /]# date -R
Sun, 05 Nov 2023 02:13:03 -0500
[root@server20 /]# mysql -h127.1 -uroot@sys#obcedemo -P2883 -paaAA11__ -c -A oceanbase
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.6.25
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [oceanbase]> show variables like '%time_zone%';
ERROR 4012 (HY000): Timeout, query has reached the maximum query timeout: 10000000(us), maybe you can adjust the session variable ob_query_timeout or query_timeout hint, and try again.
MySQL [oceanbase]> select time_to_usec(current_timestamp),current_timestamp;
ERROR 4012 (HY000): Timeout, query has reached the maximum query timeout: 10000000(us), maybe you can adjust the session variable ob_query_timeout or query_timeout hint, and try again.
MySQL [oceanbase]> select /*+ query_timeout(1000000000000000) */ time_to_usec(current_timestamp),current_timestamp;
+---------------------------------+---------------------+
| time_to_usec(current_timestamp) | current_timestamp |
+---------------------------------+---------------------+
| 1699168395000000 | 2023-11-05 02:13:15 |
+---------------------------------+---------------------+
1 row in set (0.00 sec)
看这个时间戳 1699168395000000 比前面的 时间戳 1699172022000000 要小了。此时 OB 查询报超时了,估计是内部在计算sql执行时间时候用的两个值,其中一个减数受时间回退影响了导致结果超出正常的时间。用hint规避一下展示出这个时间戳 结果是变小了。