mysql - 我可以避免两个 MySQL 事件同时运行吗?

标签 mysql mysql-event

我在 MySQL 中有一个事件,我希望至少每 30 秒频繁运行一次。

它正在处理包含最近更新记录的队列表中的数据。有时我会收到大批量的更新。发生这种情况时,事件的运行时间可能比通常的 2-3 秒更长。如果它在下一个计划时仍在运行,我希望下一个事件跳过执行。

我能想到的最好方法是创建一个“状态”表,在该表中,当进程开始时我将特定键设置为 1,当进程完成时将其设置回 0。 然后我会更改事件以检查当前状态。

我更愿意做一些比这更好的事情。有没有我完全缺少的功能?

我研究了全局变量,但根据文档,这些变量似乎只允许用于系统变量。

当前示例代码

这是我当前正在测试的示例代码。

acca_sync: BEGIN

  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);
    call pa.log(concat("acca-acc_sync"," - Error - ", ifnull(@full_error,    "no error message")));
    UPDATE `acca`.`processing_state`
      SET `value` = 0
      WHERE `key` = 'acca_sync';
  END;

  call pa.log(CONCAT("Started acca_sync @ ", NOW()));
  SELECT `value`
    into @is_locked
    from `acca`.`processing_state`
    where `key` = 'acca_sync';

  IF @is_locked = 0 THEN
    UPDATE `acca`.`processing_state`
      SET `value` = 1
      WHERE `key` = 'acca_sync';
  ELSE
    CALL pa.log(CONCAT("acca_sync deferred due to active sync. @ ", NOW()));
    LEAVE acca_sync;
  END IF;

  call acca.event_sync();
  call pa.log(CONCAT("Completed acca_sync @ ", NOW()));

  UPDATE `acca`.`processing_state`
    SET `value` = 0
    WHERE `key` = 'acca_sync';

END

表锁定

根据评论,我想解释为什么我不使用表锁。我对表锁的经验有限,所以我希望以下内容是正确且有意义的。

源数据表

我有通知队列表中更新的触发器。这些是我的源数据表,我从中读取数据来处理它。

我的理解是,这些表上的 READ 锁不会锁定刚刚读取的任何其他事件。 如果我要使用WRITE锁,我会阻止对我当前未访问的任何行的任何更新。

目标数据表

我有多个数据源,用于处理不同事件中的数据。这些行将在目标表中修改。可能有两个不同的事件同时运行写入同一个表,所以我不想人为地阻塞目标表

其他表

我可以创建一个假表,仅用于设置锁,然后检查锁是否存在。这看起来很荒谬,我宁愿使用每次查询的 lock_keyis_locked 列创建一个表锁。

最佳答案

您可以验证是否有任何事件正在运行:

 SELECT * 
 FROM performance_schema.threads 
 WHERE NAME LIKE '%event_worker%' 
      AND TYPE='FOREGROUND'

其他值得关注的有趣表格:

 SELECT * FROM information_schema.processlist

关于mysql - 我可以避免两个 MySQL 事件同时运行吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38141988/

相关文章:

python - 从 python-alpine 安装 MySQL-python 失败

php - MySQL查询,计算可用资金

mysql - 创建事件在 MySQL 中出现语法错误

mysql - 如何创建存储过程并在预定时间运行它(在 MYSQL 中)

mysql - MySQL 中的列值在 1 小时后设置为某个值后如何重置?

MySQL MyISAM 如何在不锁定表的情况下执行读取?

mysql - 尝试使用解码获取 native 错误根据加入年份获取员工数量

MySQL - 无法添加外键约束 - 缺少索引

MySQL 查询在 phpMyAdmin 事件调度程序中不起作用