You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Logstash执行JDBC查询时遇时区偏移异常的解决方法

解决Logstash JDBC输入的时区与夏令时异常问题

问题概述

你的Logstash JDBC输入配置存在两个核心问题:

  1. 时区配置错误:sql_last_value生成的起始时间为'1970-01-01 02:00:00',但伊斯坦布尔时区(Europe/Istanbul)无夏令时,正确起始时间应为'1970-01-01 03:00:00'
  2. 旧日期夏令时间隙异常:当查询到log_date为1949-04-10这类历史日期时,触发JodaTime的IllegalInstantException,原因是该日期对应伊斯坦布尔时区的夏令时切换间隙,时间点不存在

你的原始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"
  }
}

触发的错误日志:

[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)>"}

解决方案

1. 修正时区配置,确保sql_last_value使用正确时区

需要在JDBC连接和Logstash JDBC输入中明确指定伊斯坦布尔时区:

  • 在jdbc_connection_string中添加MySQL时区参数,确保数据库连接使用正确时区
  • 添加jdbc_default_timezone参数,强制Logstash生成sql_last_value时使用指定时区

修改后的配置片段:

jdbc_connection_string => "my-connection-string?serverTimezone=Europe/Istanbul"
jdbc_default_timezone => "Europe/Istanbul"

2. 纠正用户名/密码的配置错误

将配置中搞反的用户名和密码修正:

jdbc_user => "my-user"
jdbc_password => "my-pass"

3. 解决旧日期的夏令时间隙异常

由于1949年伊斯坦布尔时区的夏令时切换导致1949-04-10 00:00:00这个时间点不存在,JDBC驱动解析log_date字段时会触发异常,推荐采用以下方式解决:

方式一:在SQL查询中将日期转换为字符串

修改statement,把log_date用DATE_FORMAT转换为字符串,避免JDBC驱动解析为时间对象:

statement => "SELECT l.id, l.name, DATE_FORMAT(l.log_date, '%Y-%m-%d') AS log_date FROM logs l WHERE l.created_at >= :sql_last_value"

后续如果需要在Logstash中处理这个日期字段,可通过date过滤器将字符串转换为时间类型,并指定时区:

filter {
  date {
    match => ["log_date", "yyyy-MM-dd"]
    timezone => "Europe/Istanbul"
    target => "log_date"
  }
}

完整修正后的配置示例

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?serverTimezone=Europe/Istanbul"
    jdbc_user => "my-user"
    jdbc_password => "my-pass"
    jdbc_fetch_size => 5000
    jdbc_default_timezone => "Europe/Istanbul"
    schedule => "*/5 * * * *"
    statement => "SELECT l.id, l.name, DATE_FORMAT(l.log_date, '%Y-%m-%d') AS log_date FROM logs l WHERE l.created_at >= :sql_last_value"
  }
}

filter {
  date {
    match => ["log_date", "yyyy-MM-dd"]
    timezone => "Europe/Istanbul"
    target => "log_date"
  }
}

内容的提问来源于stack exchange,提问作者Hasan Can Saral

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 03:32:50