【问题标题】:MySQL select records missing occasionally when inserted by an EVENT由 EVENT 插入时,MySQL 选择记录偶尔会丢失
【发布时间】:2021-11-22 20:58:45
【问题描述】:

我正在运行事件以从主表中获取数据并将其插入到Summary 表中

我每 2 分钟运行一次 MySQL 事件,并在我的事件中调用存储过程,以便从主表到汇总表进行一些分组、解析和计算。

但在选择 2 分钟记录时,有时会在创建摘要时错过最后一条记录

丢失记录的频率在 1 天 90-100 条记录(主表中 1 天记录数为 30K)。

存储过程中的 MySQL 选择查询:

SELECT ID, COUNT(*) AS TOT_COUNT
FROM CUSTOMER 
WHERE (TIMESTAMP > (DATE_FORMAT((NOW() - INTERVAL 3 MINUTE),"%Y-%m-%d 
%H:%i:00"))
  AND TIMESTAMP <= (DATE_FORMAT((NOW() - INTERVAL 1 MINUTE),"%Y-%m-%d %H:%i:00")))
GROUP BY ID, NAME;

注意:选择前2分钟记录,跳过当前分钟记录

我已尝试更新 select 语句 where 条件如下(缺失记录频率降低到 50%)

SELECT ID, NAME, COUNT(*) AS TOT_COUNT
FROM CUSTOMER 
WHERE (SUBSTRING_INDEX(TIMESTAMP, ':', 2) !=  SUBSTRING_INDEX((NOW()), ':', 2)
  AND SUBSTRING_INDEX(TIMESTAMP,':',2) >= SUBSTRING_INDEX((NOW() - INTERVAL 2 MINUTE),':',2))
GROUP BY ID,NAME;

还可以尝试在存储过程中使用以下语句来捕获异常。

DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
    GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE, 
    @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT;
    SET @full_error = CONCAT("ERROR ", @errno, " (", @sqlstate, "): ", @text);
    SELECT @full_error;
    INSERT INTO ERRORS_TABLE (Level,Code,Message,INSERT_TMST) VALUES ("ERROR ", @errno, @full_error, now());
END;

未找到事件或存储过程失败日志或 MySQL 错误日志。 还检查了空值。

如果我手动为该错过的分钟记录集手动调用存储过程,那么它会返回正确的计数。

你能帮我调试一下这个问题,还有其他完美的选择查询来获取 2 分钟的记录还是我遗漏了什么?

提前致谢

【问题讨论】:

  • 我不会依赖我的查询准确地每两分钟运行一次。谁保证它不会跑得太晚,让我在回顾仅两分钟时错过第一秒?如果我知道“每两分钟”向我保证它不会花费比暂停时间更长的时间,比如三分钟,我可能会很想选择过去的三分钟并在插入时忽略所有重复项。但不,我不会。我将存储我处理的最后一个 ID,并在下一次运行时选择所有具有更高 ID 的行。这将使我独立于批量运行的实际频率。
  • 你真的在比较时间戳和字符串吗?这看起来不太好。
  • 感谢通知 where 子句,让我试试 where 子句中的 DATE_FORMAT & DATE_SUB,你有什么建议?我不断收到主表中的记录,这就是我跳过当前分钟记录的原因。
  • 在 08:30:59,您将获得 08:27:00.00001 到 08:29:00.00000。然后,如果您的查询在 2 分 1 秒后再次运行:在 08:33:00,您会得到 08:30:00.00001 到 08:32:00.00000。因此,如果我没记错的话,您会错过从 08:29:00.00001 到 08:30:00.00000 的所有内容。如前所述:我的建议是记住 ID(如果它保证是升序的)并改为使用它。
  • 我的活动每隔一分钟 07:31 运行一次,我选择 07:29:00 到 07:30:59 记录,在接下来的 07:33 我选择 07:31:00 到 07: 32:59 记录

标签: mysql datetime stored-procedures mysql-event


【解决方案1】:

您根本无法依赖准时运行的事件。你就是不能。你已经知道如果你这样做了会发生什么。

您正在尝试在汇总表中创建所谓的materialized view 数据。你能做些什么呢?一些不同的东西。

  1. 您可以使用普通的、非物化的数据视图。如果您的表上有正确的索引,则 VIEW 很可能会表现良好。这是一个强大的解决方案。

  2. 您可以重写事件中存储的代码,以便它处理自上次事件运行以来的所有内容。为此,您可能需要一个小单行表,其中包含上一次运行中使用的 TIMESTAMP。

  3. 切换到原生支持物化视图的 RDBMS。那可能是甲骨文,所以要花一大笔钱。

【讨论】:

  • 但这不是毫秒的情况,它也可能在完整的分钟之间有一段时间错过记录?但记录模式总是丢失最后一条记录,我正在获取完全完成分钟的记录事务,即使 mysql 事件在 1 毫秒之后或之前运行它也不应该错过给定条件的选择
猜你喜欢
  • 1970-01-01
  • 2020-05-19
  • 2015-07-11
  • 2020-05-02
  • 2013-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多