数据库历史数据年度备份

news2024/11/17 23:40:09

数据库历史数据年度备份

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; 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/160237.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

怎么把PDF转换成图片?来看看这几个方法吧!

要说我们手机里最多的一种文件格式是什么&#xff1f;那应该就是图片了。相信在智能手机的时代&#xff0c;每个人手机里都会有至少几百上千张照片吧。毕竟有许多的事情我们都希望通过图片、照片的形式来记录下来。所以说如何将其他格式的文件变成图片格式就成了一个不大不小的…

开发那点事(十八)Vue开发PC桌面应用案例

写在前面的话 最近有在研究electron框架&#xff0c;踩了不少坑 &#xff0c;现在把这几天研究的成果分享给大家。 研究成果 vue项目打包成exe可安装程序pc应用版本升级&#xff08;需要配合oss服务器&#xff09; vue应用配置 路由文件base配置为空mode模式为默认的hashv…

智慧门户、信创门户、国产门户、数字化门户,如何构建出七大特色亮点?

作者&#xff1a;郑文平 概述 调研结果显示&#xff0c;世界500强企业100%建设了适合自己的集团门户管理系统&#xff0c;也叫作办公门户或内网门户&#xff0c;并通过统一门户最终提升各自整体的业务管理水平和流转效率&#xff0c;没有建设门户的公司面临如下制约&#xff…

二,Spring IOC以及整合mybatis

0 复习 工厂设计模式 工厂设计模式代替new方式创建对象&#xff0c;目的是解耦合。 Spring做为工厂的使用 applicationContext.xml配置bean标签 如何从工厂中获取对象 //创建工厂 ApplicationContext ctx new ClassPathXmlApplicationContext("classpath:applicationCont…

AWS实战:Aurora到Redshift数据同步

什么是AuroraAmazon Aurora是一种基于云且完全托管关系型数据库服务&#xff0c;与MySQL 和 PostgreSQL 数据库兼容&#xff0c;完全托管意味着自动对数据库进行管理&#xff0c;包括管理数据备份、硬件配置和软件更新等操作Amazon Aurora提供了企业级性能Amazon Aurora提供了多…

【C/C++】动态顺序表详解(附完整源码)

本章内容 写在前面 1.静态与动态是指什么&#xff1f; 2.动态顺序表结构的定义 3.动态顺序表的函数接口实现 4.动态顺序表的问题及思考 5.关于顺序表的OJ题 6.OJ答案及解析 1.移除元素 2.删除有序数组中的重复项 ​3.合并两个有序数组 7.动态顺序表完整源码 1.SeqL…

《mSystems》最新研究| 李香真老师亲临凌波微课LorMe云讲堂解读贡嘎山反硝化菌群组装模式和驱动因素

2021年11月2日&#xff0c;李香真团队在《mSystems》期刊正式发表了题为“Patterns and Drivers of nirK-Typeand nirS-Type Denitrifier Community Assembly along an Elevation Gradient”的研究论文。该研究以青藏高原东部边界最高山——贡嘎山作为研究平台&#xff0c;比较…

小程序与普通网页开发有什么区别?

小程序的开发同普通的网页开发相比有很大的相似性&#xff0c;小程序的主要开发语言也是 JavaScript&#xff0c;但是二者还是有些差别的。 普通网页开发可以使用各种浏览器提供的 DOM API&#xff0c;进行 DOM 操作&#xff0c;小程序的逻辑层和渲染层是分开的&#xff0c;逻…

[前端笔记] 1.WEB基本概念

[前端笔记] 1.WEB基本概念基本概念1.资源 resourse2.链接3.HTTP 协议4.网页的真实样子&#xff1a;HTML静态网页与动态网页1.静态网页2.动态网页现代网站架构1.网站架构当我们访问一个网站时&#xff0c;后台都会发生什么事情捏?www——万维网 www&#xff1a;World Wide Web …

JAVA中医舌诊接口使用示例代码,JAVA舌象图特征人工智能识别代码,JAVA实现舌象特征检测与识别

中医舌诊接口使用示例-Java示例项目 中医舌诊健康状态检测API 1&#xff0e;此文档适用于集成中国中医舌诊开放平台功能的用户。 2&#xff0e;此文档说明了与中国中医舌诊开放平台的数据交互方法&#xff08;restful接口&#xff09;&#xff0c;按需使用体质健康API、脏腑健…

盖子的c++小课堂——第十讲:字符

前言 我呢&#xff0c;早上刚发布第九讲&#xff0c;心里想的是马桶盖终于保住了&#xff0c;结果…… 生产队的刘同学&#xff1a;快&#xff0c;继续更&#xff0c;不然你下次吃泡面没调料包 其他粉丝&#xff1a;啊……啊对对对 啊&#xff01;&#xff01;&#xff01;&…

OPTEE TA介绍

前言 本文主要介绍OPTEE的TA(Trusted Applications)&#xff0c;翻译自官方文档&#xff1a;Trusted Applications — OP-TEE documentation documentation (optee.readthedocs.io) 有两种方法可以实现可信应用程序 &#xff08;TA&#xff09;&#xff1a;伪 TA 和用户模式 T…

Speedoffice(word)如何输入特殊符号?

Word文档有时需要输入人民币单位“元”&#xff08;&#xff09;的符号&#xff0c;那么怎么打出来了&#xff0c;以我最常用的Speedoffice为例和大家分享一下方法。步骤&#xff1a;1&#xff0c;首先运行office软件&#xff0c;新建一份word&#xff0c;找到“插入”菜单栏里…

再学C语言33:函数——地址运算符

C中最重要、最复杂的概念之一就是指针&#xff08;pointer&#xff09; 指针是用于存储地址的变量 例如&#xff1a;scanf()函数中使用地址作为参数 当需要改变调用函数中的某个值时&#xff0c;任何被调用的无返回值的C函数都需要使用地址参数完成该任务 一、地址运算符&a…

c语言重点

1、以下代码循环几次&#xff1f;&#xff08;面试题&#xff09; void test(){int i; // 局部变量 i 的值是不确定的for(;i<10;i){;} }答案是---------不确定&#xff0c;在 c 语言中局部变量 i 没有初始化&#xff0c;值是不确定的&#xff0c;所以 i 的值可能是…

GeoHash 的编码方法

对一组经纬度进行 GeoHash 编码时&#xff0c;我们要先对经度和纬度分别编码&#xff0c;然后再把经纬度各自的编码组合成一个最终编码。 对于一个地理位置信息来说&#xff0c;它的经度范围是[-180,180]。GeoHash 编码会把一个经度值编码成一个 N 位的二进制值&#xff0c;我…

MySQL进阶篇之存储引擎

01、存储引擎 1.1、MySQL体系结构 连接层 最上层是一些客户端和链接服务&#xff0c;主要完成一些类似于连接处理、授权认证、及相关的安全方案。服务器也会为安全接入的每个客户端验证它所具有的操作权限。 服务层 第二层架构主要完成大多数的核心服务功能&#xff0c;如SQL…

重要的字符(串)函数的使用及其实现

目录 字符串函数注意点 1、\0 2、适当使用const修饰 3、多使用assert断言 4、库函数不可能完全安全 1、求字符串长度strlen 1、计数实现 2、递归实现 3、指针相减求元素个数 2、长度不受限制的字符串函数 1、strcpy 2、strcat 3、strcmp 3、长度受限制的字符串函数…

ESP32设备驱动-MLX90614红外测温传感器驱动

MLX90614红外测温传感器驱动 1、MLX90614介绍 MLX90614 是一款用于非接触式温度测量的红外温度计。IR 敏感型热电堆检测器芯片和信号调节 ASIC 都集成在同一 TO-39 罐封装中。MLX90614 集成有低噪声放大器、17 位 ADC 和强大的 DSP 单元,因此温度计兼具高精度和高分辨率。 …

少儿Python每日一题(22):杨辉三角

原题解答 本次的题目如下所示: 杨辉三角形又称Pascal三角形,它的第i+1i+1行是的展开式的系数。 它的一个重要性质是:三角形中的每个数字等于它两肩上的数字相加。 下面给出了杨辉三角形的前4行: 1 1 1 1 2 1 1 3 3 1 给出n,输出它的前n行。 输入: 输入包含一个数n。 输出…