OceanBaseV4.0.0 系统时间变更问题

【 使用环境 】测试环境
【 OB or 其他组件 】OB
【 使用版本 】oceanbase-all-in-one-4.0.0.0-beta-100120221214162701
【问题描述】变更oceanbase所在系统的时间,将系统时间往前调整一小时 例如:从上午9点变成8点后,数据库无法使用 无法增删改查
【复现路径】date -s “” 修改时间 obclient root进入sys租户 查询table数据卡住
【问题现象及影响】ob数据库中select查询后 使用date -s 将系统时间改到23年11月2号



【附件】

是单节点还是多节点?

单节点

OB 内部版本号(SCN)跟时间还是有一定关系。你这个属于 时间回退了。
你这个表如果在8点时候没有数据,这个是查不出来的。

单就这个 CASE 而言,你把集群停掉 1个小时,等 主机的时间自然推进到9点,你开启集群,应该 能恢复正常。

那国外夏令时、冬令时问题咋办

重新修改时间到修改前的时间之后 可以继续操作了 我测试可以这样完 但是业务上这样是不行的吧 如果系统一段时间没关机后 系统时间快过硬件时间 重启后系统时间同步硬件时间 那每次重启都得调整时间 :rofl: 有点坑 有别的解决方法吗?

没有

夏令时、冬令时 应该不影响时间戳

夏令时结束时,时间给人的感觉像是回退了一个小时,其实是时区的变化导致。时区 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规避一下展示出这个时间戳 结果是变小了。

2 个赞

可以了解一下 时间同步服务 ntpd 或 chrony ,时间同步的时候是能够做到 系统时间跟硬件时间的同步。
主机团队要保证这一点,OB 不负责解决这个时间回退问题。

请问这个问题要如何解决? 通过ntpdate更新了系统默认时间,只能调整date -s “”调回时间吗