我有以下JDBC输入:

input {
  jdbc {
    id => "mypipeline"
    jdbc_driver_class => "com.mysql.jdbc.Driver"
    jdbc_driver_library => "/usr/share/logstash/drivers/mysql-connector-j-8.0.32.jar"
    jdbc_connection_string => "my-connection-string"
    jdbc_password => "my-user"
    jdbc_user => "my-pass"
    jdbc_fetch_size => 5000
    schedule => "*/5 * * * *"
    statement => "SELECT l.id, l.name, l.log_date FROM logs l WHERE l.created_at >= :sql_last_value"
  }
}

LOG_DATE列如下:

log_date DATE NULL DEFAULT NULL,

警告;created_atlog_date不是同一列.正在执行的查询如下所示:

SELECT l.id, l.name, l.log_date FROM logs l WHERE l.created_at >= '1970-01-01 02:00:00'

这是错误的,因为伊斯坦布尔没有进入DST,值应该是'1970-01-01 03:00:00',例如LOG_DATE的1949-04-10,我收到了这个错误:

[2023-06-02T11:50:30,470][WARN ][logstash.inputs.jdbc     ][main][mypipeline] Exception when executing JDBC query {:exception=>Sequel::DatabaseError, :message=>"Java::OrgJodaTime::IllegalInstantException: Illegal instant due to time zone offset transition (daylight savings time 'gap'): 1949-04-10T00:00:00.000 (Europe/Istanbul)", :cause=>"#<Java::OrgJodaTime::IllegalInstantException: Illegal instant due to time zone offset transition (daylight savings time 'gap'): 1949-04-10T00:00:00.000 (Europe/Istanbul)>"}

我该如何解决这个问题?

推荐答案

"Illegal instant due to time zone offset transition"--伊斯坦布尔在夏令时和标准时间之间不是currently,而是it has done in the past.

它目前正在观测实际上全年都是DST的时间-自2016年3月27日以来一直是这样做的,当时时钟从UCT时区偏移+2小时向前拨了1小时至+3小时.


更具体地说,关于"Illegal instant"错误:1949年4月10日午夜,时钟快了1小时--所以当地时间1949-04-10 00:00实际上从未发生过.这就是为什么它是一个"间隙"值,如错误消息中所指出的.

这个时区数据是在IANA Time Zone Database(TZDB)中捕获的,我认为它是您的应用程序在幕后使用的(例如,如果您使用的是Joda-Time).

你可以使用像this one这样的在线工具(以及其他工具):

enter image description here

WARNING-我不能保证这个网站上数据的准确性,但它确实符合this specific example的TZDB规则,我使用Java(使用TZDB数据)提取了如下规则:

 - on 1949-04-10 at 00:00
 - the clocks moved forward by 1 hr (daylight saving)
 - from TZ offset +02:00 to offset +03:00

关于您的 comments :

"should be '1970-01-01 03:00:00'"

对于1970年,TZDB表示没有进行任何调整.因此,与协调世界时的有效补偿是在1964年进行的:

 - on 1964-10-01 at 00:00
 - the clocks moved back by 1 hr
 - from TZ offset +03:00 to offset +02:00

而这+02:00就是你(正确地)在1970年的数据中看到的.


如果您希望避免使用落入这些间隔之一的DateTime(由于时钟向前移动而导致),则可以通过编程来实现,例如:

其他主流语言也应该有类似的能力.


另外,既然您提到了Joda,也许您现在可以考虑使用Java的java.time个类(如果您有合适的Java版本),instead of using Joda-Time:

请注意,从Java SE 8开始,用户被要求迁移到java.time(JSR-310)--这是取代该项目的JDK的核心部分.


Specific solution to the case with Logstash

jdbc_default_timezone => "GMT"添加到Logstash配置并更改主机的时区将使Logstash在查询数据库时不会收到此错误.

Java相关问答推荐

是否可以从@ TrustMapping中删除特定方法的基路径?

Java自定义ThreadPool—暂停任务提交并取消当前排队任务

Java .类参数不通过构造函数传递

如何找到MongoDB文档并进行本地化?

为什么我的在一个范围内寻找素数的程序不能像S所期望的那样工作

Helidon 4和Http API

当Volatile关键字真的是必要的时候?

Docker不支持弹性APM服务器

使用用户引入的参数生成人员数组

将PNG转换为位图自定义十六进制字符串

Regex以查找不包含捕获组的行

如何在Java中为thunk创建映射器函数

当b是一个字节并且在Java中值为-1时,为什么b>;>;>;1总是等于-1?

如何使用Criteria Builder处理一对多关系中的空值?

通过Java列表中的某些字段搜索值

在Spring Boot JPA for MySQL中为我的所有类创建Bean时出错?

在Oracle中调用输出参数在索引处缺少IN或OUT参数的函数

在WHILE()循环初始化部分中声明和初始化变量的Java语法?

Java 21保护模式的穷尽性

具有 DayOfWeek 列表的 JPA 实体