MySQL数据库中没有SQLServer数据库中那种传统的定时作业的概念。但是提供了一种【事件】的东西,基本和定时作业貌离神合。
下面我们在MySQL中创建一个事件,它的作用是去监测时间很长的异常查询,并且去主动杀掉该线程以防止数据库发生死锁的风险。
-- 开启事件调度器,以便能够运行周期性的事件
SET GLOBAL event_scheduler = ON;CREATE EVENT IF NOT EXISTS kill_long_running_queries
-- 设置事件调度,这里设置为每10秒执行一次
ON SCHEDULE EVERY 10 SECOND
-- 定义事件要执行的SQL代码块
DOBEGIN-- 声明一个变量`done`用于控制循环的结束,默认为FALSEDECLARE done INT DEFAULT FALSE;-- 声明一个变量`course_id`用于存储查询的进程IDDECLARE course_id INT;-- 创建一个游标`cur1`,用于遍历查询超过10分钟的查询进程DECLARE cur1 CURSOR FOR SELECT id FROM information_schema.PROCESSLIST WHERE COMMAND = 'Query' AND TIME > 300;-- 当游标遍历完成后,设置`done`为TRUE以退出循环DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;-- 打开游标OPEN cur1;-- 开始循环遍历游标中的结果read_loop: LOOP-- 从游标中获取下一行数据到变量`course_id`FETCH cur1 INTO course_id;-- 如果游标遍历完成,则退出循环IF done THENLEAVE read_loop;END IF;-- 杀掉进程ID为`course_id`的查询KILL course_id;END LOOP;-- 关闭游标CLOSE cur1;END;
以上仅是查询了当前数据库中的所有异常进程(或线程),要做完善的话还可以查询异常的事务并且杀掉。即SELECT * FROM information_schema.INNODB_TRX。等日后有空闲时间我会去完善。
下面是查询当前数据库中有哪些【事件】
SHOW EVENTS;
以上就是我为解决MySQL数据库死锁而出的解决方案以及方案的落地。大家有什么好的方案可以提出来在评论区交流。可以是从数据库为出发点的方案,也可以是以代码请求为出发点的方案。