自动清理归档日志_从MYSQL 数据库归档 到 归档设计

1d5651e571c1e34d38d8df9471f67979.png

到数据归档,很多人的第一个概念就是,不就是无用的数据,换个地方放吗,直接拷贝,删除不就得了,有那么麻烦。

我见到过的,听到过的数据库归档的方法有以下几种

1  数据通过人工的手段来进行清理,直接将表换名字,然后在重建一个新的表,承接数据。

首先这样的做法一个字,快,这是这样做法的好处所在,但另一方面要考虑的问题就是,业务要不要停,涉及的人有多少,如果光是IT 的还好说,但恰恰这样做,绝对不会光光牵扯 IT, 业务的人一定是要牵扯进来,然后就是各种流程和通知,要在几点几点,某个业务,甚至整体业务暂时停止。

2  数据通过MYSQL dump 或者其他的备份方式,将数据备份出来,在将数据恢复到数据归档库中,然后将备份的数据直接手动清理掉,这样的做法速度也很快,对业务的影响也比较小,基本上可以算是透明的方式了,但还是避免不了人工的介入,并且也不可能是天天这样做。

3  数据通过工具的方式来进行处理,例如pt-archiver 的方式来进行数据的归档和清理,但这个工具貌似bug不少,pt-1126

a34ad7784145cea14fccd5c31b434afd.png

4  自己设计数据归档

自己设计数据归档的面就广了,有使用程序来做的,例如JAVA ,Python等等,也有使用存储过程来进行的。

下面就是一个MYSQL 针对一个数据库表归档的案例(这个案例也是有缺陷的,但目前是秉承着够用就好,以及时间成本的原则)

首先设计一个归档要考虑的问题如下

1 归档表的大小,以及每日最大,或最小的归档数据量,或者数据过期时间

   同时归档表是否必须是全量的数据归档,还是可以抛弃一些数据,例如有一些日志的归档中可能存在一些无用的数据,是否还必须全量的归档等等都是要考虑的问题,归档数据并不一定是原封不动的归档,有的逻辑上,只归档一些数据关键点也是可以的。

2 归档的数据量,数据归档一般根据上面的东西,归档有一次性归档,和规律有固定日期的归档,一次性的归档一般归档的数据量比较大,而有规律的归档则归档的数据量并不大,对比两者的方式,其实定期归档(有规律)的要有优势一些,主要是数据是不断灌入的,而数据的归档如果也是不断输出的,这样整体这个表的数据量就会有一个平衡,不会一下子少了很多,要不就是在清理的前一天,数据量已经大到一定的水平,有可能影响性能。

3 归档的方法,自己定义数据的归档方面,可以每次归档将数据灌入一个表,也可以定期的将数据写入不同的归档表,例如已归档日期和后缀的方式来将每次写入的数据进行分割,或者建立分区表的方式来进行归档。

4  归档的方式是否灵活,有的归档的方法仅仅针对一个表来进行归档,有的方法是可以灵活配置,可以任意扩展。那就都任意扩展,灵活配置不就好了,其实随着能任意扩展或者灵活配置,则工作量就会变大,这也要考虑一个性价比,具体要考虑表的数量以及归档的方式。

下面就是一个简单的例子,需求是一张表每天数据量在40- 50 万,主要都是来自于客户的短信以及消息发送的内容。表中的数据要保留半年之内的,其余的数据可以移走。

以下以最简单的自动化的方案来讲

下图是基于案例来讲的

因为数据库是MYSQL 所以考虑了归档一次是多大的批量,避免归档数据量过大的时候将生产库hang 死,另外配置表主要的功能是有两个 1 限制一次拷贝和清理的数据量,2 控制拷贝过期数据的日期限制

75eeddbd09a5cf917ad546f0d32fe98b.png

下面是这段代码,如果看的不方便,下面有截图

DELIMITER $$

DROP PROCEDURE IF EXISTS  archive_data;

create PROCEDURE archive_data()

BEGIN

  declare row_s int;  #最大执行多少次每次1000条

  declare save_month tinyint;  #保留多少月之前的数据

  declare times int;  #执行次数记录

  declare min_row_s int;  # 当前数据库最小的tid

  declare archive_date datetime;

  select @times := 1;  #设置每天初始清理次数初始值 

  select @row_s := max_row_clean from db_archive.db_config order by id limit 1;  #获取当前配置库数据

  select @save_month := archive_save_date from db_archive.db_config order by id limit 1; 

  select @min_row_s := min(tid) from msgcdb.t_sms_message; #获取当前系统最小的TID号

  select @max_row_s := max(tid) from msgcdb.t_sms_message; #获取当前系统最大的TID号

  select @archive_date := DATE_SUB(CURDATE(), INTERVAL @save_month MONTH);

  select @row_s, @save_month,@archive_date,@min_row_s,@max_row_s;

    if @min_row_s = @max_row_s then 

    set @times = @row_s + 1;

    elseif @min_row_s is null then

    set @times = @row_s + 1;

    end if; 

   insert into db_archive.archive_log (save_month,times,min_row_s,max_row_s,archive_date,row_s,insert_time,delete_time,type_s) values (@save_month,@times,@min_row_s,@max_row_s,@archive_date,@row_s,sysdate(),sysdate(),'initial');

   select @times, @min_row_s;

     while @times < @row_s DO

        begin

insert into db_archive.t_sms_message (tid,summary_id,uid,code,channel,batch_id,done_time,phone,sms_content,create_time,send_time,storage_time,status,estimatedTime,operate_type,origin,creator_id ,dept_id,del_flag,priority,template_id,repetitions_num) 

        select tid,summary_id,uid,code,channel,batch_id,done_time,phone,sms_content,create_time,send_time,storage_time,status,estimatedTime,operate_type,origin,creator_id ,dept_id,del_flag,priority,template_id,repetitions_num 

        from msgcdb.t_sms_message 

        where tid >= @min_row_s and tid < @min_row_s + 1000 and status <> 0 and storage_time < @archive_date; 

set @times = @times + 1;

         insert into db_archive.archive_log (save_month,times,min_row_s,max_row_s,archive_date,row_s,insert_time,delete_time,type_s) values (@save_month,@times,@min_row_s,@max_row_s,@archive_date,@row_s,sysdate(),sysdate(),'inserted');

    delete from msgcdb.t_sms_message where tid >= @min_row_s and tid < @min_row_s + 1000 and status <> 0 and storage_time < @archive_date;

        insert into db_archive.archive_log (save_month,times,min_row_s,max_row_s,archive_date,row_s,insert_time,delete_time,type_s) values (@save_month,@times,@min_row_s,@max_row_s,@archive_date,@row_s,sysdate(),sysdate(),'deleted');

        select @min_row_s,@max_row_s;

        select @min_row_s := min(tid) from msgcdb.t_sms_message;

        select @max_row_s := max(tid) from msgcdb.t_sms_message;

        select @min_row_s,@max_row_s;

            if @min_row_s = @max_row_s then 

set @times = @row_s + 1;

            elseif @min_row_s is null then

            set @times = @row_s + 1;

            end if; 

        end;

     END WHILE;

END$$

DELIMITER ;

7f917f0623b5c6740da869f8774f0003.png

b2dcb51a9dbd46ee379e3993a67a1636.png

465f262fb42be27147afb4513c22afdc.png

配置表

09b60161e3dcdf8b249e4126f80ad1ad.png

归档日志表

9763cdfaf57435a30659f70ed027cf8d.png

为什么要这么设计,其实寻根溯源有两点

1 简单有效,够用原则

2 设计配置表的主要原因是对于非IT 人员,例如project manager 或者其他的人员,也可以调整归档的时间,例如 archive_save_date 的数字就是保留多少月的数据,max_row_clean,就是当前的数字 *1000 就是每天最大的归档数据量。通过这两个参数双重限制每天的归档的数据量,避免归档的时间太长,影响了备份,或其他操作。而日志表本身就是一个查看归档成功失败的东西,其中的type_s  就是表现数据归档操作状态的东西,通过日志表可以反映归档多少数据,每次操作消耗的时间,以及当前操作获取的系统变量是什么,方便出现故障时,查看到底归档的数据少不少,或者大致可能出现问题。

下面是这两个表的结构

a3ec70681e5f47e8403b95bed423eea7.png

这样归档有没有缺点,当然有,缺点马上就可以说出几个

1 为什么还要在本地机归档数据,不应该是传送到其他机器上吗

2 为什么不设置每次归档的数量限制(每次限制操作的行数),这对MYSQL不是很用吗,为什么要写死。

3  为什么要用MYSQL 存储过程来做,使用python不是更灵活

其实一言难尽,都和需求有关,所以很多设计出来的东西,外人一看一堆毛病,如果你进入到他的内部,一段时间估计你就懂得为什么会设计出这样或那样的东西。

最近有一句话挺时髦,资本根本不care你技术不技术,除非你做到行业NO.1,才有可能翻个身。

76bc9d7131f859112b30547d02599123.png

群里有一些免费书,可自取

20a5fdc93670d444ec010936a3688d9f.png

e8fcfa9d3c8813e83c358c294f6c96f1.png

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

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

相关文章

Android支付宝SDK开发笔记

一、准备工作 〉1、下载开发包 https://b.alipay.com/order/productDetail.htm?productId2014110308141993&tabId4#ps-tabinfo-hash 压缩包下的“支付宝钱包支付接口开发包”中即有Andoid使用支付宝的JAR和Demo 〉2、创建支付宝应用 在支付宝开放平台申请创建应用 https:/…

全栈测试:平衡单元测试和端到端测试

全栈开发人员的特点是能够从头到尾交付并发布一个特性。教程和书籍常常侧重于搭建全栈开发环境和让测试能够进行所需要的“管件&#xff08;plumbing&#xff09;”&#xff08;我综合运用了Angular、Rails、Bootstrap和Postgres&#xff09;。但对于如何贯穿整个Web开发栈进行…

linux 命令/目录 名称 英文单词 缩写 助记

注&#xff1a;以下内容转自https://www.zhihu.com/question/49073893?sortcreated&#xff0c;作者是一个高中的学生&#xff0c;能总结这么多这么好&#xff0c;真心赞扬。这么好的知识我怕在互联网上流失&#xff0c;所以在这里做了一个备份。 以下内容仅供参考&#xff0c…

python文件处理seek()方法的参数是_Python 文件(File) seek() 方法

例如&#xff1a;将当前文件位置更改为4&#xff0c;然后返回其余行&#xff1a;f open("demofile.txt", "r")f.seek(4)print(f.readline())1、定义和用法seek()方法设置文件流中的当前文件位置。seek()方法如果操作成功&#xff0c;则返回新的文件位置&a…

一天一个类,一点也不累之HashSet

最近忙着一个小项目结题&#xff0c;故没能按时完成【一天一个类&#xff0c;一点也不累】&#xff0c;还好项目优秀&#xff0c;算是对自己一点点的安慰和鼓励。~~~ 今天要说的是HashSet 既然是继承自Set&#xff0c;那么就必须有Set的一些属性&#xff0c;比如不能容许有相同…

[BZOJ1502]月下柠檬树(自适应辛普森积分)

1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1387 Solved: 739[Submit][Status][Discuss]Description 李哲非常非常喜欢柠檬树&#xff0c;特别是在静静的夜晚&#xff0c;当天空中有一弯明月温柔地照亮地面上的景物时&#xff0c;他必会悠闲地…

擎天出口退税软件_新版申报系统退税申报注意事项

前言&#xff1a;随着税务信息化建设“后金三”时代的不断深入,2019年年底国家税务总局启动出口退税管理系统整合(进入金税三期)项目&#xff0c;经过广东、大连两个地区试点&#xff0c;即将于今年年底前在全国完成金税三期审核系统的上线工作&#xff0c;至此&#xff0c;出口…

词性标注

4.10 词性标注 词性用来描写叙述一个词在上下文中的作用。比如描写叙述一个概念的词叫做名词&#xff0c;在下文引用这个名词的词叫做代词。有的词性常常会出现一些新的词&#xff0c;比如名词&#xff0c;这种词性叫做开放式词性。另外一些词性中的词比較固定&#xff0c;比如…

MVCC浅析(转)

在并发读写数据库时&#xff0c;读操作可能会不一致的数据&#xff08;脏读&#xff09;。为了避免这种情况&#xff0c;需要实现数据库的并发访问控制&#xff0c;最简单的方式就是加锁访问。由于&#xff0c;加锁会将读写操作串行化&#xff0c;所以不会出现不一致的状态。但…

关于单链表,二叉树,图,查找和排序的软件编程

课程名称&#xff1a;计算机软件 使用软件&#xff1a;devcpp 注意&#xff1a;这里列出了关于单链表&#xff0c;二叉树&#xff0c;图&#xff0c;查找和排序的编程&#xff0c;全部程序由博主一人编写&#xff0c;会有瑕疵&#xff0c;谨慎使用。 1.单链表 要求&#xff1a;…

pcie 的function_PCIe扫盲——BDF与配置空间

前面的文章中介绍过&#xff0c;每一个PCIe设备可以只有一个功能(Function)&#xff0c;即Fun0。也可以拥有最多8个功能&#xff0c;即多功能设备(Multi-Fun)。不管这个PCIe设备拥有多少个功能&#xff0c;其每一个功能都有一个唯一独立的配置空间(Configuration Space)与之对应…

微信二维码扫描下载APK

前几天给客户制作的app需要上线&#xff0c;生成二维码扫描进行下载&#xff0c;把生成好的apk挂在服务器端&#xff0c;将地址复制下来&#xff0c;通过草料二维码&#xff08;http://cli.im/&#xff09;生成一个二维码它需要一个应用宝ID。上传到应用宝&#xff0c;光审批就…

mysql 字段 as_mysql 字段as详解及实例代码

mysql 字段使用as在mysql中&#xff0c;select查询可以使用AS关键字为查询的字段起一个别名&#xff0c;该别名用作表达式的列名&#xff0c;并且别名可以在GROUP BY&#xff0c;ORDER BY或HAVING等语句中使用。例如&#xff1a;SELECT CONCAT(last_name,, ,first_name) AS ful…

dubbo接口快速测试技巧

在分布式系统的开发中&#xff0c;用到了dubbozookeeper技术&#xff0c;最近遇到一个问题&#xff0c;产品上线后&#xff0c;我负责的模块出了问题&#xff0c;某个bean中某个字段的值一直为null&#xff0c;而这个bean是我调用注册在zookeeper上的一个服务查询到的&#xff…

跳出多重循环 JS

关于如何跳出多重循环loop: //循环标记for(var key in jsonObj){for(var i0;i<jsonObj[key].length;i){if(jsonObj[key][i].password123456){break loop;//跳出双重循环 }}}转载于:https://blog.51cto.com/9381188/1790457

webservice引用spring的bean

1 <jaxws:endpoint address"/test/webservice" implementor"#testBean" /> 这行代码里面的#号表示webservice自动装配到spring的bean。转载于:https://www.cnblogs.com/xiluhua/p/4472544.html

mysql 5.0 数据库_mysql5.0常用命令

MySQL常用操作基本操作&#xff0c;以下都是MySQL5.0下测试通过首先说明下&#xff0c;记住在每个命令结束时加上&#xff1b;(分号)1.导出整个数据库mysqldump -u 用户名 -p --default-character-setlatin1 数据库名 > 导出的文件名(数据库默认编码是latin1)mysqldump -u w…

IISASP.NET 站点IP跳转到域名

前言&#xff1a;先到微软的 https://www.iis.net/downloads/microsoft/url-rewrite 下载URL Rewrite 目标&#xff1a;输入ip跳转到域名所在的网站 比如58的115.159.231.173 跳转到https://passport.58.com/login 先看下58的例子 我们在地址栏输入ip之后 箭头指向的地方是跳转…

java基础五

继承 1. 继承含义 在面向对象编程中&#xff0c;可以通过扩展一个已有的类&#xff0c;并继承该类的属性和行为&#xff0c;来创建一个新的类&#xff0c;这种方式称为继承&#xff08;inheritance&#xff09;. 2. 继承的优点 A&#xff0e;代码的可重用性 B&#xff0e;子类可…

Mac OS X 下Java开发环境配置

首先自己又装的jdk1.8版本目录&#xff1a;/Library/Java/JavaVirtualMachines/jdk1.8.0_91.jdk/Contents/Home待添加。。。转载于:https://blog.51cto.com/jiyanle/1790537