1. 程式人生 > >基於MYSQL事件的按月備份表,滾動,保留6次備份

基於MYSQL事件的按月備份表,滾動,保留6次備份

數據 gin command 操作 margin 技術分享 man lob rda

要求:

    • 每月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
ON SCHEDULE EVERY 1 MONTH STARTS DATE_ADD(DATE_ADD(DATE_SUB(CURDATE(),INTERVAL DAY(CURDATE())-1 DAY), INTERVAL 1 MONTH),INTERVAL 1 HOUR)
ON COMPLETION PRESERVE ENABLE 
DO 
BEGIN
    select now();
END ;; DELIMITER ;
技術分享圖片
返回日期
CURDATE()

返回前一天的數字
DAY(CURDATE()-1)

日期減法函數:計算當天減去月初到昨天的天數,等於這個月的1號
DATE_SUB(CURDATE(),INTERVAL DAY(CURDATE())-1 DAY)

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

日期加法函數:得到下月1號的淩晨1點的時間
DATE_ADD(DATE_ADD(DATE_SUB(CURDATE(),INTERVAL 
DAY(CURDATE())-1 DAY), INTERVAL 1 MONTH),INTERVAL 1 HOUR)
實現細節
創建表實現
CREATE TABLE `version_replace` (
  `table_name` varchar(32) NOT NULL,
  `table_version` int(10) unsigned NOT NULL DEFAULT 0,
  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次之前的備份

SET @command=concat(DROP TABLE version_backup_,date_format(date_sub(now(), interval 6 month),%y%m),‘‘);
PREPARE modify FROM @command;
EXECUTE modify;
技術分享圖片
獲取格式化後的年月份
select date_format(now(),%y%m);

獲取當前日期的前6個月
select date_sub(now(), interval 6 month);

取得當前日期的前6個月,並格式化顯示,為拼接表名稱做準備
select date_format(date_sub(now(), interval 6 month),%y%m);
實現細節


最終實現

DELIMITER ;;
CREATE EVENT BACKUP
ON SCHEDULE EVERY 1 MONTH STARTS DATE_ADD(DATE_ADD(DATE_SUB(CURDATE(),INTERVAL DAY(CURDATE())-1 DAY), INTERVAL 1 MONTH),INTERVAL 0 HOUR)
ON COMPLETION PRESERVE ENABLE 
DO 
BEGIN
    /*創建一個待替換的空表*/
    CREATE TABLE `version_replace` (
    `table_name` varchar(32) NOT NULL,
    `table_version` int(10) unsigned NOT NULL DEFAULT 0,
    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個月前的那次備份*/
    SET @command=concat(DROP TABLE version_backup_,date_format(date_sub(now(), interval 6 month),%y%m),‘‘);
    PREPARE modify FROM @command;
    EXECUTE modify;
END
;;
DELIMITER ;

文章寫的不錯?請掃下面作者的討飯專用碼,贊助一下。

技術分享圖片

基於MYSQL事件的按月備份表,滾動,保留6次備份