MYSQL数据库表按月备份,滚动,保留6次备份

时间:2023-03-10 02:44:16
MYSQL数据库表按月备份,滚动,保留6次备份

要求:

    • 每月1日0点:在不影响业务的情况下,备份整月的数据,保留6次备份。

思路:

    1. 基于MYSQL事件功能,每月按时完成操作
    2. RENAME语句具有原子性,新旧表无缝切换
    3. RENAME语句仅修改表定义,大表瞬间完成
    4. 基于上面三点,实现了表数据按月切割

步骤:

    1. 新建一个待替换的空表
    2. 重命名原表为日期备份表,空表为原表
    3. 删除6次前备份的那张表

参考官方文章

https://dev.mysql.com/doc/refman/5.6/en/rename-table.html


前提要求:打开MYSQL的事件功能

打开事件功能
set global event_scheduler = on;

查看事件功能是否打开
show variables like 'event_scheduler';

MYSQL事件实现

DELIMITER ;;
CREATE EVENT BACKUP
    HOUR)
ON COMPLETION PRESERVE ENABLE
DO
BEGIN
    select now();
END
;;
DELIMITER ;
返回日期
CURDATE()

返回前一天的数字
)

日期减法函数:计算当天减去月初到昨天的天数,等于这个月的1号
DATE_SUB(CURDATE(),INTERVAL  DAY)

日期加法函数:得到下月1号的日期
DATE_ADD
DATE_ADD(DATE_SUB(CURDATE(),INTERVAL  DAY)

日期加法函数:得到下月1号的凌晨1点的时间
DATE_ADD(DATE_ADD(DATE_SUB(CURDATE(),INTERVAL    HOUR)

实现细节


创建表实现
CREATE TABLE `version_replace` (
  `table_name` ) NOT NULL,
  `table_version` ) unsigned ',
  UNIQUE KEY `table_name_idx` (`table_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

动态SQL语句实现改表名称为日期变量

SET @command=concat('RENAME TABLE `version` TO `version_backup_',date_format(now(),'%y%m'),'` , `version_replace` TO `version`');
PREPARE modify FROM @command;
EXECUTE modify;

动态SQL语句实现删除6次之前的备份

 month),'%y%m'),'');
PREPARE modify FROM @command;
EXECUTE modify;
获取格式化后的年月份
select date_format(now(),'%y%m');

获取当前日期的前6个月
 month);

取得当前日期的前6个月,并格式化显示,为拼接表名称做准备
 month),'%y%m');

实现细节


最终实现

DELIMITER ;;
CREATE EVENT BACKUP
    HOUR)
ON COMPLETION PRESERVE ENABLE
DO
BEGIN
    /*创建一个待替换的空表*/
    CREATE TABLE `version_replace` (
    `table_name` ) NOT NULL,
    `table_version` ) unsigned ',
    UNIQUE KEY `table_name_idx` (`table_name`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    /*RENAME语句具有原子性,把原表重命名为日期备份表,并且将创建的新表重命名为原表*/
    SET @command=concat('RENAME TABLE `version` TO `version_backup_',date_format(now(),'%y%m'),'` , `version_replace` TO `version`');
    PREPARE modify FROM @command;
    EXECUTE modify;

    /*删除6个月前的那次备份*/
     month),'%y%m'),'');
    PREPARE modify FROM @command;
    EXECUTE modify;
END
;;
DELIMITER ;

https://dev.mysql.com/doc/refman/5.6/en/rename-table.html