vTiger 记录在回收站清空后仍然在数据库里面存在

来源:互联网 发布:c语言控制台好看界面 编辑:程序博客网 时间:2024/06/06 19:43

在Vtiger 的首页Dashbaod 中存在一个数据完整性的问题,主要存在的情况是对用户进行登录名的修改后的遗留问题。

具体情况是,查看当前首页中的 Dashboard 里面关于当前用户的日历有2项内容。



如果通过单击柱状图的链接,进入到事件日志中,我们发现实际上,当前用户只有一个事件。



如果我们尝试删除这个记录,不用清除回收站,我们会发现在首页里面仍然还有一个记录。

就算我们清除回收站,也还有同样的问题,这条记录不能完全删除。


这时候你可以打开SQL, 让Vtiger将执行的SQL给你打印到日志文件中。

在日志文件中有一个SQL,语句内容如下:

  1. SELECT count( * ) AS count
  2.   FROM    vtiger_crmentity se
  3.        INNER JOIN
  4.           vtiger_activity act
  5.        ON act.activityid = se.crmid
  6. WHERE se.deleted = 0 AND se.smownerid = 6
  7.        AND((act.status != 'Completed' AND act.status != 'Deferred')
  8.            OR act.status IS NULL)
  9.        AND((act.eventstatus != 'Held' AND act.eventstatus != 'Not Held')
  10.            OR act.eventstatus IS NULL)
复制代码
执行的结果为 1 ,这就是这个1 的来源。


现在,你可以修改这个 SQL ,在这SQL 里面加一个输出项se.crmid ,这样你就可以知道是那个ID 导致的这问题。

新的SQL 如下:

  1. SELECT count( * ) AS count, se.crmid
  2.   FROM    vtiger_crmentity se
  3.        INNER JOIN
  4.           vtiger_activity act
  5.        ON act.activityid = se.crmid
  6. WHERE se.deleted = 0 AND se.smownerid = 6
  7.        AND((act.status != 'Completed' AND act.status != 'Deferred')
  8.            OR act.status IS NULL)
  9.        AND((act.eventstatus != 'Held' AND act.eventstatus != 'Not Held')
  10.            OR act.eventstatus IS NULL)
复制代码
从输出中,你应该知道是 ID= 126 的记录导致的这个重复记录

下面就好了,直接看为什么是这条记录导致的这个重复



现在你可以分析下这个SQL 了,主要是看判断条件。

  1. se.deleted = 0 AND se.smownerid = 6
复制代码
第一个判断条件就比较明白了: se.deleted = 0 这个0肯定是删除标记,

se.smownerid 是当前登录的用户ID 号。按照逻辑来说,如果数据被物理删掉了,这2个表里面是不应该有数据存在的,就是因为没有被物理删除掉,所以这2个表会有数据存在。

这时候可以尝试将 ID = 126 的记录的删除标记修改为 1 试试了。

首先你执行SQL
  1. select * from vtiger_crmentity se where  se.deleted = 0 AND se.smownerid = 6
复制代码
我蓝色高亮显示的记录是 ID =126 的记录,看最后的那条删除标记为 0, 你将这个栏位修改为 1 。




你再执行下面的SQL

  1. SELECT count( * ) AS count, se.crmid
  2.   FROM    vtiger_crmentity se
  3.        INNER JOIN
  4.           vtiger_activity act
  5.        ON act.activityid = se.crmid
  6. WHERE se.deleted = 0 AND se.smownerid = 6
  7.        AND((act.status != 'Completed' AND act.status != 'Deferred')
  8.            OR act.status IS NULL)
  9.        AND((act.eventstatus != 'Held' AND act.eventstatus != 'Not Held')
  10.            OR act.eventstatus IS NULL)
复制代码
你应该可以看到已经输出为 0 了。



这时候,你到前台刷新下首页的 Dashboard 看看,应该是显示没有任何记录了。



这个就是这个问题的原因。主要是数据库数据的逻辑错误,理论上,如果删掉了数据,这2个表里面的数据要不就打上了删除标记,要不就直接删了。

这种错误最难找也最隐蔽。

这时候只能依赖日志了。


还记得我们曾经删除掉一条事件记录吗?

这时候,你可以到回收站里面将这条记录恢复。



恢复后执行下面的语句

  1. select * from vtiger_crmentity se where  se.deleted = 0 AND se.smownerid = 6
复制代码
我们看结果 ID = 168 的数据被我们恢复到这个表来了。



从这里我们可以知道,就算是数据被删除到回收站了,一旦数据被删除了,那应该会给这个数据打上删除标记的,这个表里面就不应该有相关这条记录的。

你可以使用下面的SQL
  1. select * from vtiger_crmentity se where  se.deleted = 0 AND se.smownerid = 6
复制代码
你会看到ID = 168的这条记录已经被打上了删除标记了。



在进行清空回收站操作之前,这条记录是不会被物理删除掉的。

所有对于有逻辑错误的地方,你就将删除标记打上就可以了。


个人认为,这个问题主要是在我们曾经安装过数据的测试数据。

最开始,我们安装的时候,都会安装自带的Demo数据,这部分的数据有助于我们能更好的理解系统,同时也为数据的一致性带来了一些麻烦。

比如说,你习惯于用admin这个用户登录,忽然有一天你心里不舒服了,把这个admin用户改成别的用户了,新改的这个用户可能会继承admin这个用户的一些东西过来。有时候你就很奇怪了,明明我没有做这些东西,为什么我会看到这些记录呢?

这个就是系统数据完整性带来的麻烦。

这种问题没有办法完全克服,只要是系统,只要有人用,就会出现各种各样的问题。所以我的习惯是不轻易删除数据库里面的数据。一些系统的设计思路是将记录打上删除标志,这样只是控制显示,而不是控制物理删除。

从这个例子,我们也可以知道Vtiger是这样做的。这样的好处是一旦有问题了,我们可以根据删除标志恢复数据,不好的是造成了数据冗余。

在过去,计算机只有几百兆内存的时候,这种冗余会带来系统负担。现在数据库的理念已经有所变化了,保持必要的冗余是非常好的习惯。

同时,现在的系统单一硬盘都能做到1个TB了,存储早就不是问题,而且内存已经跨入了数十 GB的时代了。这时候你还担心有数据冗余吗?

比较数据损失和数据冗余,我宁愿要数据冗余。


如果你单击了刷新Dashboard 的按钮,会执行下面的一些SQL,我摘录了出来。

可以供以后分析的时候参考, 这部分其实日志输出中有关SQL的部分。

可以放到你的客户端软件里面执行下,你就知道这个这个操作后,Vtiger 都干了些什么事情了,找问题也会容易些,因为范围缩小了。


  1. 05/13/10 09:15:46,459 [3912] DEBUG index - Prepared sql query being executed : SELECT presence FROM vtiger_tab WHERE name=?
  2. 05/13/10 09:15:46,460 [3912] DEBUG index - Prepared sql query parameters : [Dashboard]
  3. 05/13/10 09:15:46,578 [3912] DEBUG index - query being executed : SELECT count(*) as count FROM vtiger_crmentity se INNER JOIN vtiger_leaddetails le on le.leadid = se.crmid
  4.                 WHERE se.deleted = 0 AND se.smownerid = 6 AND (le.converted = 0 OR le.converted IS NULL)
  5. 05/13/10 09:15:46,583 [3912] DEBUG index - query being executed : SELECT count(*) as count FROM vtiger_crmentity se INNER JOIN vtiger_troubletickets tt ON tt.ticketid = se.crmid
  6.                 WHERE se.deleted = 0 AND se.smownerid = 6 AND (tt.status != 'Closed' OR tt.status IS NULL)
  7. 05/13/10 09:15:46,587 [3912] DEBUG index - query being executed : SELECT count(*) as count FROM vtiger_crmentity se INNER JOIN vtiger_potential pot ON pot.potentialid = se.crmid
  8.                 WHERE se.deleted = 0 AND se.smownerid = 6 AND (pot.sales_stage NOT IN ('Closed Won','Closed Lost') OR pot.sales_stage IS NULL)
  9. 05/13/10 09:15:46,591 [3912] DEBUG index - query being executed : SELECT count(*) as count FROM vtiger_crmentity se INNER JOIN vtiger_activity act ON act.activityid = se.crmid
  10.                 WHERE se.deleted = 0 AND se.smownerid = 6 AND ((act.status!='Completed' AND act.status!='Deferred') OR act.status IS NULL)
  11.                 AND ((act.eventstatus!='Held' AND act.eventstatus!='Not Held') OR act.eventstatus IS NULL)
  12.                 
  13. 05/13/10 09:15:46,636 [3912] DEBUG index - query being executed : SELECT setype, count(setype) setype_count FROM vtiger_crmentity se WHERE 
  14.                 se.deleted = 0 AND se.smownerid=6 AND se.setype in ('Accounts','Contacts','Quotes','SalesOrder','PurchaseOrder','Invoice','Campaigns') GROUP BY se.setype
  15. 05/13/10 09:15:46,642 [3912] DEBUG index - query being executed : SELECT cvid,entitytype FROM vtiger_customview WHERE viewname='All' AND entitytype in ('Leads','HelpDesk','Potentials','Calendar')

复制代码



转自:http://ip-64-15-152-108.static.privatedns.com/thread-576-1-1.html

原创粉丝点击