当前位置:首页 > MySQL
使用存储过程和事件,自动删除 2 周前的数据
来源:靑龍一笑的博客  作者:靑龍一笑  发布时间:2021-08-25 10:16:37  点击量:354  评论:0

    假设,要对 logs 表自动删除 2 周前的数据。
    删除 2 周前数据可以使用如下命令:

mysql> delete from `logs` where `crtime` < DATE(DATE_SUB(NOW(), INTERVAL 14 day));

    其中,INTERVAL 关键字是确定间隔值的表达式,以及指定间隔的单位。NOW() 函数返回当前的日期和时间。DATE_SUB() 函数是从日期中减去指定的时间间隔。DATE() 函数返回的是一个日期。
    但是,这样的删除操作,针对大量的数据时,会造成死锁。比较好的做法是使用 limit 进行批量删除,即:

mysql> delete from `logs` where `crtime` < DATE(DATE_SUB(NOW(), INTERVAL 14 day)) order by `crtime` asc limit 1000;

    这条命令在使用 limit 进行批量删除的同时,还对 crtime 字段进行了 asc 排序操作,保证了从最早的数据开始删除。
    可以使用 max() 函数来获取最近一条要删除的数据:

mysql> select max(`crtime`) from `logs` where `crtime` < DATE(DATE_SUB(NOW(), INTERVAL 14 day));

    可以使用 min() 函数来获取最早一条要删除的数据:

mysql> select min(`crtime`) from `logs` where `crtime` < DATE(DATE_SUB(NOW(), INTERVAL 14 day));

    每执行一次删除操作,改变的是最早一条要删除的数据。
    可以定义两个值:max_time 和 next_time

mysql> select max(`crtime`) into max_time from `logs` where `crtime` < DATE(DATE_SUB(NOW(), INTERVAL 14 day));
mysql> select min(`crtime`) into next_time from `logs` where `crtime` < DATE(DATE_SUB(NOW(), INTERVAL 14 day));

    当 next_time > max_time 时,删除任务结束。
    根据以上思路,创建一个存储过程:

delimiter $
create procedure auto_del_logs()
begin
    declare max_time varchar(30);
    declare next_time varchar(30);
    select max(`crtime`) into max_time from `logs` where `crtime` < DATE(DATE_SUB(NOW(), INTERVAL 14 day));
    set next_time = '1970-01-01 00:00:00';
    while max_time > next_time do
        delete from `logs` where `crtime` < DATE(DATE_SUB(NOW(), INTERVAL 14 day)) order by `crtime` asc limit 1000;
        select min(`crtime`) into next_time from `logs` where `crtime` < DATE(DATE_SUB(NOW(), INTERVAL 14 day));
    end while;
end $
delimiter ;


    其中,auto_del_logs 为存储过程名。
    可以使用如下命令,查看指定数据库中所存在的存储过程:

mysql> show procedure status where db='test';

    可以使用如下命令,删除指定的存储过程:

mysql> drop procedure auto_del_logs;

    有了存储过程,可以使用如下命令进行调用:

mysql> call auto_del_logs();

    接下来,要解决自动删除的问题。
    创建一个事件,定制每天执行 auto_del_logs() 的存储过程:

create event if not exists del_logs_event_job
on schedule every 1 day starts now()
on completion not preserve enable
do call auto_del_logs();


    其中,del_logs_event_job 为事件名,now() 表示当前时间立即执行。也可以指定一个具体的时间(例如:2021-08-25 03:00:00),即,把 now() 替换成:'2021-08-25 03:00:00'。
    可以使用如下命令,查看已创建的事件:

mysql> show events;

    可以使用如下命令,删除指定的事件:

mysql> drop event del_logs_event_job;

    可以使用如下命令,查看当前是否开启事件计划:

mysql> show variables like 'event_scheduler';


    如果未开启,可以使用如下命令开启:

mysql> set global event_scheduler = on;


    可以使用如下命令,查看事件执行记录:

mysql> select * from information_schema.events \G

    可以使用如下命令,开启指定的事件:

mysql> alter event del_logs_event_job on completion preserve enable;

    可以使用如下命令,关闭指定的事件:

mysql> alter event del_logs_event_job on completion preserve disable;

    可以使用如下命令,查看当前运行的所有事务:

mysql> select * from information_schema.innodb_trx \G

    其中,trx_rows_modified 代表锁影响的行数,当数值为 0 时,锁将会释放。

版权所有 © 2005-2023 靑龍一笑的博客  Powered by C.S.Ricen
Copyright © 2005-2023 by www.ricensoftwares.com.cn  All Rights Reserved.

欢迎光临本站,这里是靑龍一笑的博客。

因资金匮乏,本站已迁到国外的免费空间,可能导致本站的访问速度较慢,由此给您带来的不便,敬请谅解。

您可以通过下方的“支持本站建设”链接,给本站提供资金支持。

Free Web Hosting