背景
项目上线了两年,却在最近总是莫名其妙的宕机,然后就有了这篇分析文章
问题分析
项目稳定跑了两年,数据库没有做分库分表,数据库中有的表已经达到了上千万,并且每天还以11w+的速度
在增长着。还有几张主要业务数据表也达到500w+的数据量,并且每天仍以1w+的速度在增长,于是leader就叫
我想个方案解决一下。不光是mysql的数据达到了瓶颈,mongodb也有几个占用了10多G的空间。
因为项目是做物流方面的,所以并不打算做分库分表来解决,只是将历史数据转移,表里只保留一个季度的热
点数据,提供给业务使用。
单表的数据分析![在这里插入图片描述](https://img-blog.csdnimg.cn/11a04b0e7c4f4e389230b22f136b61c3.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdmFuMjkxNw==,size_13,color_FFFFFF,t_70,g_se,x_16#pic_center)
解决方案
1.数据库脚本
简单快捷,但是处理关联数据比较麻烦根据sql进行数据删除
2.程序代码
场景复杂,需要考虑各种异常场景并做好补偿机制,代码实现也相对复杂,但是处理关联数据简单
如果归档过程中,造成数据丢失怎么处理?归档期间,导致服务不可用如何处理?等等
将归档的步骤模块化、任务化,并记录删除记录和结果,防止异常情况,导致失败可以进行重试,或者二次处理。
可以采用先标识再删除,分步处理(eg:添加标识,间隔一天后再对以表示的数据进行删除)
程序上分批次多次手动提交的方式进行处理
简易代码实现
@Autowired
private TransactionDefinition transactionDefinition;
@Autowired
private DataSourceTransactionManager dataSourceTransactionManager;
/**
* 添加归档标识
* @param start 开始日期
* @param end 结束日期
*/
public void addDataArchiveFlag(Date start,Date end){
// 1.查询需要归档的数据
int totalSize = 0;
while (totalSize>0){
TransactionStatus transaction = dataSourceTransactionManager.getTransaction(transactionDefinition);
try {
// 2.每次归档1000条数据
dataSourceTransactionManager.commit(transaction);
}catch (Exception e){
dataSourceTransactionManager.rollback(transaction);
}
totalSize-=1000;
}
}
/**
* 删除归档数据
* @param start 开始日期
* @param end 结束日期
*/
public void delDataArchive(Date start,Date end){
// 1.查询需要删除的数据
int totalSize = 0;
while (totalSize>0){
TransactionStatus transaction = dataSourceTransactionManager.getTransaction(transactionDefinition);
try {
// 2.每次删除1000条数据
dataSourceTransactionManager.commit(transaction);
}catch (Exception e){
dataSourceTransactionManager.rollback(transaction);
}
totalSize-=1000;
}
}
3.mongodb归档
由于mongodb的数据量太庞大,采用新建文档的方式进行归档
1.日志操作记录--->直接备份/删除旧文档,新建文档
2.流程数据--->新建文档,利用程序将需要归档的数据从原文档中移除到新建文档中,这种新文档就是备份
文档,原文档就是热点数据文档
后记
归档的方式有很多种,据了解DBA有一种工具--pt-archiver,也可以使用,因为小编拿不到服务器的权限所以
就果断放弃了。
最重要的还是要根据自身业务去进行分析,采用合适的方法去解决。