elasticsearch 日志存储:sql_last_值显示错误的垃圾日期(将6个月前的日期显示为上次运行时间),elasticsearch,logstash,elastic-stack,elk,logstash-jdbc,elasticsearch,Logstash,Elastic Stack,Elk,Logstash Jdbc" /> elasticsearch 日志存储:sql_last_值显示错误的垃圾日期(将6个月前的日期显示为上次运行时间),elasticsearch,logstash,elastic-stack,elk,logstash-jdbc,elasticsearch,Logstash,Elastic Stack,Elk,Logstash Jdbc" />

elasticsearch 日志存储:sql_last_值显示错误的垃圾日期(将6个月前的日期显示为上次运行时间)

elasticsearch 日志存储:sql_last_值显示错误的垃圾日期(将6个月前的日期显示为上次运行时间),elasticsearch,logstash,elastic-stack,elk,logstash-jdbc,elasticsearch,Logstash,Elastic Stack,Elk,Logstash Jdbc,我正在观察一个非常奇怪的问题 我正在使用logstash+jdbc将数据从oracledb加载到Elasticsearch 下面是我的配置文件的样子 input{ jdbc{ clean_run => "false" jdbc_driver_library => "<path_to_ojdbc8-12.1.0.jar>" jdbc_driver_class => "Java::oracle

我正在观察一个非常奇怪的问题 我正在使用logstash+jdbc将数据从oracledb加载到Elasticsearch 下面是我的配置文件的样子

input{
  jdbc{
    clean_run => "false"
    jdbc_driver_library => "<path_to_ojdbc8-12.1.0.jar>"
    jdbc_driver_class => "Java::oracle.jdbc.driver.OracleDriver"
    jdbc_connection_string => "<connection_string>"
    jdbc_user => "<usename>"
    jdbc_password_filepath => ".\pwd.txt"
    statement=> "SELECT * FROM customers WHERE CUSTOMER_NAME  LIKE 'PE%' AND UPD_DATE  > :sql_last_value "
    schedule=>"*/1 * * * * "
    use_column_value => true
    tracking_column_type => "timestamp"
    
    tracking_column => "upd_date"
    
    last_run_metadata_path =>"<path to logstash_metadata>"
    record_last_run => true
    }
}

filter {
  mutate {
    copy => { "id" => "[@metadata][_id]"}
    remove_field => ["@version","@timestamp"]
  }
}
output {
      elasticsearch{
    hosts => ["<host>"]
    index => "<index_name>"
    document_id=>"%{[@metadata][_id]}"
    user => "<user>"
    password => "<pwd>"
}

   stdout{
      codec => dots
   }
}
现在,我每分钟都会在2021年3月8日的今天触发这个文件。 当我第一次加载时,它的所有良好-:sql\u last\u值是'1970-01-01 00:00:00.000000+00:00'

但在第一次加载之后,理想情况下,logstash_元数据应该显示为“2021-03-08”,但奇怪的是,它在logstash_元数据:sql_last_值中更新为-2020-09-11 01:05:09.000000000 Z

正如你所看到的,差异大约在180天左右

我尝试了很多次,但仍然以同样的方式更新,因此我的增量负载被破坏了

我的日志存储版本是7.10.2

非常感谢您的帮助


注意:我没有使用分页,因为对于我的查询,结果集中的结果数总是非常少

记录的日期是最后处理行的日期

看到您的查询,您没有从DB读取记录的特定顺序。 Logstash jdbc输入插件将您的查询封装为按[1]排序的查询,1是它排序的列的序号

因此,要以正确的顺序处理记录并获取最新的upd_日期值,需要将upd_日期作为select语句的第一列

input{
  jdbc{
    clean_run => "false"
    jdbc_driver_library => "<path_to_ojdbc8-12.1.0.jar>"
    jdbc_driver_class => "Java::oracle.jdbc.driver.OracleDriver"
    jdbc_connection_string => "<connection_string>"
    jdbc_user => "<usename>"
    jdbc_password_filepath => ".\pwd.txt"
    statement=> "SELECT c.UPD_DATE, c.CUSTOMER_NAME, c.<Other field> 
                 FROM customers c 
                 WHERE c.CUSTOMER_NAME LIKE 'PE%' AND c.UPD_DATE > :sql_last_value 
                 ORDER BY c.UPD_DATE ASC"
    schedule=>"*/1 * * * * "
    use_column_value => true
    tracking_column_type => "timestamp"
    tracking_column => "upd_date"        
    last_run_metadata_path =>"<path to logstash_metadata>"
    record_last_run => true
    }
}
还要注意,这种方法将在第一次运行logstash时耗尽表,即使您设置了jdbc_page_大小。如果你想要这个,没关系

但是,如果希望logstash每分钟运行一批X行,并在下一次执行之前停止,那么必须结合使用jdbc_page_size和带限制的查询,使logstash以正确的顺序准确地检索所需的记录量。在SQL Server中,它的工作方式如下:

input{
  jdbc{
    jdbc_driver_library => ...
    jdbc_driver_class => ...
    jdbc_connection_string => ...
    jdbc_user => ...
    jdbc_password_filepath => ...
    statement=> "SELECT TOP 10000 c.UPD_DATE, c.CUSTOMER_NAME
                 FROM customers c 
                 WHERE c.CUSTOMER_NAME  LIKE 'PE%' AND c.UPD_DATE  > :sql_last_value 
                 ORDER BY c.UPD_DATE ASC"
    schedule=>"*/1 * * * * "
    use_column_value => true
    tracking_column_type => "timestamp"
    tracking_column => "upd_date"
    jdbc_page_size => 10000
    last_run_metadata_path =>"<path to logstash_metadata>"
    record_last_run => true
    }
}
对于Oracle DB,您必须根据版本更改查询,或者使用 仅获取前x行;使用Oracle 12,或使用ROWNUM(旧版本)


在任何情况下,我建议您查看日志以检查日志存储运行的查询。

您能澄清一件事吗?:sql\u last\u值是否与数据库中上次更新的记录的时间戳相同,或者它是上次日志存储的运行时间?当使用\u column\u value=>true和tracking\u column=>upd\u date时,那么:sql\u last\u值应该是上次处理的记录的upd\u date字段的值。对于use\u column\u value=>false,它使用最后一次查询执行的时间戳。请注意,在这种情况下,不能在查询中使用带TOP的批处理,否则会跳过记录。从文档中设置为true时,使用定义的跟踪列值作为:sql\u last\u值。当设置为false时,:sql\u last\u值反映上次执行查询的时间。谢谢,现在我的理解很清楚了