数据库历史数据年度备份

数据库历史数据年度备份

1、文件说明

matomo_backup.sql 备份库表结构脚本(这个根据自己数据结构准备,对于时间命名的表结构就不要加了,只加非时间命名的表结构)

export.sh 数据导出脚本

clean.sh 源数据库历史数据清除脚本

2、需求与思路

需求

对于一些统计功能,我们需要对历史数据进行数据备份,以降低统计查询的压力,备份方式为按年度备份,每年度备份的数据都单独创建一个数据库,如下:

在这里插入图片描述

思路

整体业务通过shell脚本执行数据库操作,思路如下:

  1. 先导出数据备份,再清除对应的历史数据(好像是废话)
  2. 通过mysqldump命令导出源数据库结构及数据,生成脚本matomo.sql
  3. 切换到目标数据库
    • 创建备份库,通过source命令执行matomo_backup.sql备份库脚本
    • 创建数据源临时库,通过source命令执行第二步生成的源数据库结构及数据
    • 非时间命名的表同步,直接使用create_date作为条件insert
    • 时间命名的表同步,切换到备份库,先创建对应导出年份的时间表,然后全表导入源库数据(这个用存储过程来实现,因为涉及到了动态表,采用游标的形式遍历)
  4. 删除存储过程
  5. 切换回数据源临时库,删除临时库
  6. 删除mysqldump命令生成的源数据库结构及数据脚本matomo.sql
  7. 删除已备份数据
    • 非时间命名的表直接通过create_date作为条件delete
    • 时间命名的表直接drop掉(同理,使用存储过程实现)

3、操作

数据导出备份

  1. ​ 将matomo_backup.sql放export.sh同级目录
  2. ​ 根据实际情况修改export.sh中源数据库和备份数据库服务连接信息
  3. ​ export.sh 执行,传参:$1为要导出数据年份,$2为需要创建备份数据库名称

​ 执行效果如下表示执行成功:

在这里插入图片描述

历史数据清除

  1. ​ 确保数据已经导出备份!!!!

  2. ​ 根据实际情况修改clean.sh中源数据库服务连接信息

  3. ​ clean.sh 执行,传参:$1为要清除数据年份

    执行效果如下表示执行成功:

在这里插入图片描述

4、脚本附件

export.sh

#!/bin/bash 
echo "Start Export Matomo Data..."
#$1为要导出数据年份,$2为需要创建备份数据库名称(不需要手动创建,matomo_backup.sql放export.sh同级目录)
echo "导出$1年的数据到备份数据库$2...";
#mysqldump导出源数据库结构及数据,具体数据库连接信息请自行修改
mysqldump -h192.168.137.128 -P3306 -uroot -proot matomo --column-statistics=0 > ./matomo.sql;

#切换到目标数据库服务器,具体数据库连接信息请自行修改
mysql -h192.168.137.128 -P3307 -uroot -proot -e"
#创建备份库
CREATE DATABASE IF NOT EXISTS $2 DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_bin;
use $2;
source ./matomo_backup.sql;

#创建数据源临时库
CREATE DATABASE IF NOT EXISTS matomo DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_bin;
use matomo;
set names utf8;
source ./matomo.sql;

#导入需要备份年份的数据
INSERT IGNORE INTO $2.matomo_user_token_auth SELECT * FROM matomo_user_token_auth where DATE_FORMAT(last_used,'%Y') = $1;
INSERT IGNORE INTO $2.new_user_model SELECT * FROM new_user_model where DATE_FORMAT(query_date,'%Y') = $1;
INSERT IGNORE INTO $2.visit_statics_model SELECT * FROM visit_statics_model where DATE_FORMAT(query_date,'%Y') = $1;
...

#切换到备份库,通过存储过程、游标创建备份库中不存在的数据表及数据插入
use $2;

#处理matomo_archive_blob_*;matomo_archive_numeric_*数据表集合
DROP PROCEDURE IF EXISTS export_list;
delimiter $
CREATE PROCEDURE export_list()
BEGIN
	#遍历结束标志
	DECLARE var_flag INT DEFAULT 0;
	#遍历表名变量
	DECLARE var_table_name VARCHAR(100);
	#表集合
	DECLARE table_name_list CURSOR FOR
	  SELECT table_name FROM information_schema.tables
      WHERE table_schema = 'matomo' AND table_type = 'base table'
      AND
      (
        table_name like 'matomo_archive_blob_%' AND SUBSTR(table_name,21,4) = $1
        OR
        table_name like 'matomo_archive_numeric_%' AND SUBSTR(table_name,24,4) = $1
      ) ;
	#将结束标志绑定到游标
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET var_flag = 1;
	#打开游标
	OPEN table_name_list;
	FETCH table_name_list INTO var_table_name;
		WHILE var_flag !=1 DO
			#判断表类型
			IF FIND_IN_SET('matomo_archive_blob_',var_table_name)
				THEN
					#需要先判断该表在备份库是否存在,不存在需要先创建,然后再插入数据
					SET @createTableStr = CONCAT('CREATE TABLE IF NOT EXISTS ',var_table_name,'(
						idarchive int(10) UNSIGNED NOT NULL,
						name varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
						idsite int(10) UNSIGNED NULL DEFAULT NULL,
						date1 date NULL DEFAULT NULL,
						date2 date NULL DEFAULT NULL,
						period tinyint(3) UNSIGNED NULL DEFAULT NULL,
						ts_archived datetime NULL DEFAULT NULL,
						value mediumblob NULL,
						PRIMARY KEY (idarchive, name) USING BTREE,
						INDEX index_period_archived(period, ts_archived) USING BTREE
					) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = COMPACT');
				ELSE
					#先判断该表在备份库是否存在,不存在需要先创建,然后再插入数据
					SET @createTableStr = CONCAT('CREATE TABLE IF NOT EXISTS ',var_table_name,'(
						idarchive int(10) UNSIGNED NOT NULL,
						name varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
						idsite int(10) UNSIGNED NULL DEFAULT NULL,
						date1 date NULL DEFAULT NULL,
						date2 date NULL DEFAULT NULL,
						period tinyint(3) UNSIGNED NULL DEFAULT NULL,
						ts_archived datetime NULL DEFAULT NULL,
						value mediumblob NULL,
						PRIMARY KEY (idarchive, name) USING BTREE,
						INDEX index_period_archived(period, ts_archived) USING BTREE
					) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = COMPACT');
			END IF;
			PREPARE stmt FROM @createTableStr;
			EXECUTE stmt;
			#对matomo_archive_blob_*;matomo_archive_numeric_*数据表数据进行备份
			SET @insertStr = CONCAT('INSERT IGNORE INTO ',var_table_name,' SELECT * FROM matomo.',var_table_name);
      PREPARE stmt FROM @insertStr;
      EXECUTE stmt;
			FETCH table_name_list INTO var_table_name;
		END WHILE;
	CLOSE table_name_list;
END;

#执行存储过程
CALL export_list();

#删除存储过程
DROP PROCEDURE export_list;

#切换回matomo临时库
use matomo;

#删除临时源库
DROP DATABASE matomo;
commit;"

#remove dump file
rm ./matomo.sql;

echo "Export Data Successful."
exit; 

clean.sh

#!/bin/bash 
echo "Start Clean Matomo Data..."
echo "开始清除已备份的$1年数据,请确保已执行export.sh进行备份...";
mysql -h192.168.137.128 -P3306 -uroot -proot -e"
use matomo;

#删除已备份年份的历史数据
DELETE FROM matomo_user_token_auth where DATE_FORMAT(last_used,'%Y') = $1;
DELETE FROM new_user_model where DATE_FORMAT(query_date,'%Y') = $1;
DELETE FROM visit_statics_model where DATE_FORMAT(query_date,'%Y') = $1;
......

#删除matomo_archive_blob_*;matomo_archive_numeric_*已备份年份的数据表
DROP PROCEDURE IF EXISTS drop_table_list;
delimiter $
CREATE PROCEDURE drop_table_list()
BEGIN
  DECLARE i INT DEFAULT 1;
	WHILE i <= 12 DO
	    IF i < 10
  			THEN
  				SET @dropTableStr = CONCAT('DROP table IF EXISTS matomo_archive_blob_$1_0' , i , ',' , 'matomo_archive_numeric_$1_0' , i);
  			ELSE
  				SET @dropTableStr = CONCAT('DROP table IF EXISTS matomo_archive_blob_$1_' , i , ',' , 'matomo_archive_numeric_$1_' , i);
  		END IF;
    PREPARE stmt FROM @dropTableStr;
    EXECUTE stmt;
    SET i = i+1;
	END WHILE;
END;

#执行存储过程
CALL drop_table_list();
#删除存储过程
DROP PROCEDURE drop_table_list;
commit;"

echo "Clean Data Successful."
exit; 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值