IoTDB关于时区和夏令时的bug

背景:使用中发现iotdb关于时区处理的相关bug,iotdb 版本1.1.2,对于反馈的bug,iotdb会在新版本中修复。所以老版本如果希望修复bug只有两个选择,1是自己修复,2是升级到修复后的新版本。当然也可以考虑企业版,企业版会有更多支持。

原创文字,IoTDB 社区可进行使用与传播

问题发现:

最近新增了国际业务,应用查询时新增了基于时区的查询,在使用iotdb时区时,发现其java-api在使用了sessionPool.setTimeZone(xxx)后,接口耗时增加。

于是查看该处源码(org.apache.iotdb.session.pool.SessionPool#setTimeZone),可以发现默认的RETRY值为3,而此处SetTimeZone执行完之后没有return,导致setTimeZone不管是否成功都会连续执行3次。

在相关监控中也可以验证,对于每次查询,setTimeZone都执行了3次。

解决:

这里自己修改源码打包修复即可。打包方法可以参考链接
修改完源码后执行

mvn clean package -pl  distribution -am -Dmaven.test.skip=true

即可获取修改后的包
在这里插入图片描述

补充:关于夏令时的bug

iotdb时区在夏令时处理时的相关bug

命令行或者api中设置了时区为德国时区Europe/Berlin,查询当天按小时分组的聚合数据,发现结果返回24条数据,但是理论上由于德国在2024-03-31T02:00:00+02:00 开始进入夏令时,时钟会拨快1小时,这一天只有23个小时,应该返回23条数据。

在社区提问后,得到回复为

sql解析是根据ZoneOffset给你的字符串加上对应的时区信息。 比如[2024-03-31, 2024-04-01),如果你设置了德国时区,在IoTDB里会被翻译成 [2024-03-31T00:00:00+02:00, 2024-04-01T00:00:00+02:00)

实际验证后发现当前iotdb对于时区的处理是以设置时区后当前时区对应的ZoneOffset来解析处理sql,而不是以SQL中指定的开始和结束时间来设置。
即如果现实中当前时间在2024-03-31T01:00:00+00:00时间之前执行sql的时间区间为

[2024-03-31, 2024-04-01)

此时sql会被解析为

 [2024-03-31T00:00:00+01:00, 2024-04-01T00:00:00+01:00)

而当现实世界过了2024-03-31T01:00:00+00:00后,德国从中欧时间(CET,Central European Time,UTC+1)进入中欧夏令时(CEST,Central European Summer Time,UTC+2)
此时sql的时间区间会被解析为

 [2024-03-31T00:00:00+02:00, 2024-04-01T00:00:00+02:00)

而我们期望的时间区间其实是

 [2024-03-31T00:00:00+01:00, 2024-04-01T00:00:00+02:00)

明白了原因后,这个问题的解决方案也很简单,既然当前sql解析是有这个bug的,我们就在查询前自己解析时区的信息,实现将查询的时间区间[2024-03-31, 2024-04-01),在德国时区时翻译为 [2024-03-31T00:00:00+01:00, 2024-04-01T00:00:00+02:00),同时也不需要在执行查询时再设置TimeZone

下面是方法

public static String getOffsetFormat(LocalDateTime time, String timeZone) {
    if (timeZone == null || timeZone.trim().isEmpty()) {
        timeZone = "UTC+00:00";
    }
    ZonedDateTime zonedDateTime = ZonedDateTime.of(time, ZoneId.of(timeZone));
    return zonedDateTime.format(IConstants.IOT_TIME_FORMAT);
}
//其中 IOT_TIME_FORMAT的值是   
DateTimeFormatter IOT_TIME_FORMAT = new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd'T'HH:mm:ssxxx").toFormatter();


用此方式可以实现规避setTimeZone bug同时解决夏令时问题。
可以看到返回结果正常
在这里插入图片描述

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值