一起数据库中过期用户数据堆积问题的排查过程

【文章摘要

对于使用数据库来存放大量用户的软件来说,过期数据的清理机制需要慎重设计。如果设计不当,则会导致数据的误删除或清理不完全。

本文对某数据清理模块因参数配置不当而导致的过期用户数据堆积问题进行了详细的分析,为相关软件问题的分析及解决提供了有益的参考。

 

一、问题描述

在某软件系统中,为了让不同种类的用户享受对应的服务,引入了一个信箱服务等级的概念,即不同服务等级的用户具有不同的权限。“一分钱,一分货”,对于运营商来说,高服务等级的用户收取高的资费,提供高质量的服务。

为了维护不同用户的信息,在数据库中建立了用户数据表,表中包含了用户号码(如手机号)、状态(如正常使用、停用、欠费等)、服务等级(称作cos值)、用户属性(A或B类用户)等字段。

近期,该软件系统的某商用局点的支持人员反馈回一个问题:数据库中过期用户数据堆积,很多本该被删除掉的数据依然存在。

 

二、问题原因初步分析

在该软件系统中,有一个过期数据清理模块专门用于清理过期用户数据。既然数据库中出现了大量未被删除的过期用户数据,那么一定是这个模块出了问题。

我们让现场的支持人员将使用的数据库打包返回,并在开发小组的自测数据库中将数据恢复了。我们查看了用户数据表,发现的确有大量过期用户数据还保存在数据库中的。那么,这些本该删除的数据有什么特点呢?

我们对部分过期用户数据进行了观察,发现它们具有以下两个方面的特点:

第一,某个cos值对应的过期用户数据特别多,占到了未被清理的数据量的80%以上。

第二,未被删除的过期用户数据的用户属性大多为B类。

 

三、问题定位

基于以上分析,我们参照代码和数据库脚本来查找问题原因。

首先,为什么某个cos值对应的过期用户数据特别多呢?难道是这类数据很特别,程序不会对其执行删除操作吗?

我们详细追踪了程序执行流程,发现在数据库脚本中,有一个参数值用于控制是否将过期用户数据删除以及过期多少天的数据要删除。而这个参数的值是在一个cos参数表中定义的。cos参数表的定义如下:

create table tb_cosparamter
(
  cosname   varchar(100)  not  null,
  cosid     int           not  null,
  cosvalue  int           not  null
)

控制过期用户数据删除的cos参数的名字“cosname”为“DelOverdueData”,“cosid”对应的是用户数据表中的服务等级,“cosvalue”表示删除数据的时间阈值。

我们在数据库中执行SQL语句“select cosid, cosvalue from tb_cosparamterwhere cosname = ‘DelOverdueData’”,结果如下:

cosid              cosvalue

1                     0

2                     30

3                     30

4                     40

5                     50

可以看到,服务等级为1的用户数据对应的时间阈值为0,表示不删除。而我们之前查看数据库,确实是cos值1对应的过期用户数据特别多。看来,就是因为这个cos值配得不对,导致了该服务等级对应的过期用户数据无法删除掉。

我们执行SQL语句“update tb_cosparamter set cosvalue= 30 where cosname = ‘DelOverdueData’ and cosid = 1”将cosid为1时对应的cosvalue值修改为30,重新启动清理模块之后,发现确有大量过期数据被删除掉了,但仍有少量用户属性为B的过期数据还存在,什么原因呢?

我们继续追踪数据库脚本,发现有一个参数值用于控制要删除哪类用户数据,这个参数也是在cos参数表tb_cosparamter中定义的。cos参数的名字“cosname”为“DelUserType”,“cosid”对应的是用户数据表中的服务等级,“cosvalue”为1表示只删除A类用户,为0表示A或B类用户都要删除。

我们在数据库中执行SQL语句“select cosid, cosvalue from tb_cosparamterwhere cosname = ‘DelUserType’”,结果如下:

cosid             cosvalue

1                    1

2                    1

3                    1

4                    1

5                    1

可以看到,各个服务等级对应的cos值均为1,表示只删除A类用户。这与我们观察到的情况是一致的。看来,就是因为这个cos值配得不对,导致了用户属性为B的过期数据无法删除掉。

我们执行SQL语句“update tb_cosparamter set cosvalue= 0 where cosname = ‘DelUserType’”将cosname为“DelUserType”对应的cosvalue值修改为0,重新启动清理模块之后,发现用户属性为B的过期数据被删除掉了,数据库中再也没有多余的过期数据了。

 

四、总结

在过期用户数据堆积问题的排查过程中,我们首先通过对问题数据进行分析来初步查找问题原因,之后通过追踪程序流程来定位问题。

通过本次问题排查,我们总结出的经验有以下几个:

第一,遇到程序问题,我们不要惊慌,可以先从表面上观察问题的现象并推测问题原因,然后再根据之前的分析深入研究程序流程,找到问题关键所在。

第二,对于数据库中的重要数据,要有人员定期进行维护,并作相应的记录。这样才能够避免出现某些参数值不一致的情况。

第三,修改数据库中的相关字段值时,一定要谨慎。在修改之前,尽量将重要表中的数据备份,避免对数据库造成破坏而无法恢复。

 

不管是程序bug也好,数据库问题也罢,我们的目标都是要尽力将它们解决掉。在解决问题的过程中,我们要采用灵活的处理方法,并沿着发现的蛛丝马迹追查下去。如此这般,不管是什么样的bug都是可以被消灭的。

 

 

 --------------------------

本人微信公众号:zhouzxi,请扫描以下二维码:

 

时间: 2024-08-22 14:34:47

一起数据库中过期用户数据堆积问题的排查过程的相关文章

oracle数据库中如何导出数据

Oracle数据导入导出imp/exp 功能:Oracle数据导入导出imp/exp就相当与oracle数据还原与备份. 大多情况都可以用Oracle数据导入导出完成数据的备份和还原(不会造成数据的丢失). Oracle有个好处,虽然你的电脑不是服务器,但是你装了oracle客户端,并建立了连接 (通过Net Configuration Assistant添加正确的服务命名,其实你可以想成是客户端与服务器端 修了条路,然后数据就可以被拉过来了) 这样你可以把数据导出到本地,虽然可能服务器离你很远

oracle数据库中如何导入数据

Oracle数据导入导出imp/exp 功能:Oracle数据导入导出imp/exp就相当与oracle数据还原与备份. 大多情况都可以用Oracle数据导入导出完成数据的备份和还原(不会造成数据的丢失). Oracle有个好处,虽然你的电脑不是服务器,但是你装了oracle客户端,并建立了连接 (通过Net Configuration Assistant添加正确的服务命名,其实你可以想成是客户端与服务器端 修了条路,然后数据就可以被拉过来了) 这样你可以把数据导出到本地,虽然可能服务器离你很远

在visual studio2010中,从数据库中获取的数据在GridView中显示出来

问题描述 在visual studio2010中,从数据库中获取的数据在GridView中显示出来 public partial class WebForm1 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { SqlConnection conn = new SqlConnection(); conn.ConnectionString = "Server=.;DataBase=HRM_26w

SQL Server数据库中批量导入数据的2种方法_MsSql

在软件项目实施的时候,数据导入一直是项目人员比较头疼的问题.其实,在SQL Server中集成了很多成批导入数据的方法.有些项目实施顾问头疼的问题,在我们数据库管理员眼中,是小菜一碟.现在的重点就是,如何让用户了解这些方法,让数据导入变得轻松一些.相信以下方法大家都用过了,温故而知新哈,如果有更好的方法希望大家都提出来~ 一.使用Select Into语句 若企业数据库都采用的是SQL Server数据库的话,则可以利用Select Into语句来实现数据的导入.Select Into语句,他的

SQL Server数据库中批量导入数据的2种方法

在软件项目实施的时候,数据导入一直是项目人员比较头疼的问题.其实,在SQL Server中集成了很多成批导入数据的方法.有些项目实施顾问头疼的问题,在我们数据库管理员眼中,是小菜一碟.现在的重点就是,如何让用户了解这些方法,让数据导入变得轻松一些.相信以下方法大家都用过了,温故而知新哈,如果有更好的方法希望大家都提出来~ 一.使用Select Into语句 若企业数据库都采用的是SQL Server数据库的话,则可以利用Select Into语句来实现数据的导入.Select Into语句,他的

如何使用C#实现网易博客中圈子用户数据的采集

新浪博客,网易博客,都是博客中的佼佼者,其中网易提供的圈子信息,更胜一筹,使得一般用户能够通过访问圈子进入相关的群组,或者获取相关圈子用户的信息等,以实现各种精准营销的目的.虽然新浪遮遮掩掩不提供圈子的相关信息,相对而言,网易博客提供圈子,能够使得更多的人.更多的程序支持,推高博客的知名度及实用性.网易博客可以通过地址http://q.163.com/ 访问,它是经过两级分类的,如下所示.    点击分类进入即可查看到每个子分类都有很多圈子,圈子累死QQ的群组,是某一兴趣团体的博客,里面收集很多

存储过程-如何删除sybase数据库中某个用户所拥有的全部对象

问题描述 如何删除sybase数据库中某个用户所拥有的全部对象 如何删除sybase数据库中某个用户所拥有的全部对象,可以写一个存储过程来实现

怎么用c++的ado.net将access数据库中得到的数据存入一维数组,并返回。

问题描述 怎么用c++的ado.net将access数据库中得到的数据存入一维数组,并返回. RecordsetPtr pRs;pRs.CreateInstance(_uuidof(Recordset));//创建记录集对象 try{ char a[800]; sprintf(aselect 光强 from 光强数据表 where 月份 between 1 and 3 and 时间=%d""num_t); pRs->Open(_bstr_t(a)m_pConn.GetInterf

具体流程-记录用户的浏览记录并保存到数据库中当用户在次浏览时显示上次

问题描述 记录用户的浏览记录并保存到数据库中当用户在次浏览时显示上次 记录用户的浏览记录并保存到数据库中当用户在次浏览时显示上次浏览相关的内容, 写出具体流程. 求解 ...