Merged HEAD-BUG-FIX (5.0/Cloud) to HEAD (5.0/Cloud)

84121: Merged V4.2-BUG-FIX (4.2.4) to HEAD-BUG-FIX (5.0/Cloud)
      82508: Merged V4.1-BUG-FIX (4.1.10) to V4.2-BUG-FIX (4.2.4)
         82319: Merged DEV to V4.1-BUG-FIX (4.1.10)
            81073 : MNT-9532 : SQL performance issue - WHERE ... IS NULL statements
               - Initial commit to revert fixes for MNT-8527 (r48757) and MNT-9483 (r56137) as this fixes causes performance issue for Oracle.
            81966 : MNT-9532 : SQL performance issue - WHERE ... IS NULL statements
               - Default value for feed_user_id and site_network is now @@NULL@@.
               - IS NULL clause was completly removed from activities queries.
               - Upgrade sql script was added to replace nulls for Oracle (empty strings for other dialect) with @@NULL@@.
               - Version schema was incremented by 1.
            82278 : MNT-9532 : SQL performance issue - WHERE ... IS NULL statements
               - Fixed unit test failure. 
      83431: MNT-9532 : SQL performance issue - WHERE ... IS NULL statements
         - Fixed build failure
      84115: MNT-9532/MNT-11871: with the revert of MNT-11871 patch, MNT-9532 should be using a lower schema number.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@84632 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Alan Davis
2014-09-18 17:26:23 +00:00
parent 862e07f3e2
commit 2b5e64a359
15 changed files with 139 additions and 31 deletions

View File

@@ -56,6 +56,7 @@
<ref bean="patch.db-V3.3-modify-index-permission_id" /> <ref bean="patch.db-V3.3-modify-index-permission_id" />
<ref bean="patch.db-V3.2-AddFKIndexes" /> <ref bean="patch.db-V3.2-AddFKIndexes" />
<ref bean="patch.db-V3.2-AddFKIndexes-2" /> <ref bean="patch.db-V3.2-AddFKIndexes-2" />
<ref bean="patch.db-V4.1-update-activiti-nullable-columns" />
</list> </list>
</property> </property>
<property name="postUpdateScriptPatches"> <property name="postUpdateScriptPatches">

View File

@@ -0,0 +1,48 @@
--
-- Title: Update ALF_ACTIVITY_FEED and ALF_ACTIVITY_FEED_CONTROL tables by setting special @@NULL@@ value for nullable columns feed_user_id and site_network.
-- Database: Generic
-- Since: V4.1 Schema 5149
-- Author: Pavel Yurkevich
--
-- Please contact support@alfresco.com if you need assistance with the upgrade.
--
-- MNT-9532: SQL performance issue - WHERE ... IS NULL statements
--
-- Record script finish
--
-- Since oracle treats empty strings as NULLs, we have to use following format in where clause
-- ((feed_user_id IS NULL AND '' IS NULL) OR feed_user_id = '')
-- (feed_user_id IS NULL AND '' IS NULL) is Oracle specific part
--FOREACH alf_activity_feed.id system.upgrade.alf_activity_feed.batchsize
UPDATE alf_activity_feed af
SET feed_user_id = '@@NULL@@'
WHERE
((feed_user_id IS NULL AND '' IS NULL) OR feed_user_id = '') AND af.id >= ${LOWERBOUND} AND af.id <= ${UPPERBOUND};
--FOREACH alf_activity_feed.id system.upgrade.alf_activity_feed.batchsize
UPDATE alf_activity_feed af
SET site_network = '@@NULL@@'
WHERE
((site_network IS NULL AND '' IS NULL) OR site_network = '') AND af.id >= ${LOWERBOUND} AND af.id <= ${UPPERBOUND};
--FOREACH alf_activity_feed_control.id system.upgrade.alf_activity_feed_control.batchsize
UPDATE alf_activity_feed_control afc
SET feed_user_id = '@@NULL@@'
WHERE
((feed_user_id IS NULL AND '' IS NULL) OR feed_user_id = '') AND afc.id >= ${LOWERBOUND} AND afc.id <= ${UPPERBOUND};
--FOREACH alf_activity_feed_control.id system.upgrade.alf_activity_feed_control.batchsize
UPDATE alf_activity_feed_control afc
SET site_network = '@@NULL@@'
WHERE
((site_network IS NULL AND '' IS NULL) OR site_network = '') AND afc.id >= ${LOWERBOUND} AND afc.id <= ${UPPERBOUND};
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V4.1-update-activiti-nullable-columns';
INSERT INTO alf_applied_patch
(id, description, fixes_from_schema, fixes_to_schema, applied_to_schema, target_schema, applied_on_date, applied_to_server, was_executed, succeeded, report)
VALUES
(
'patch.db-V4.1-update-activiti-nullable-columns', 'Manually executed script upgrade V4.1: ALF_ACTIVITY_FEED and ALF_ACTIVITY_FEED_CONTROL tables. Updates feed_user_id and site_network columns with @@NULL@@ value',
0, 5149, -1, 5150, null, 'UNKNOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -87,22 +87,22 @@
</select> </select>
<!-- select user feeds for cleaning --> <!-- select user feeds for cleaning -->
<select id="select_activity_user_feeds_greater_than_max" parameterType="int" resultType="ActivityFeed"> <select id="select_activity_user_feeds_greater_than_max" parameterType="ActivityFeedQuery" resultType="ActivityFeed">
<![CDATA[ <![CDATA[
select feed_user_id as feedUserId select feed_user_id as feedUserId
from alf_activity_feed from alf_activity_feed
where feed_user_id IS NOT NULL AND ('' IS NULL OR '' != feed_user_id) where feed_user_id != #{nullValue}
group by feed_user_id group by feed_user_id
having count(*) > #{maxFeedSize} having count(*) > #{maxFeedSize}
]]> ]]>
</select> </select>
<!-- select site feeds for cleaning --> <!-- select site feeds for cleaning -->
<select id="select_activity_site_feeds_greater_than_max" parameterType="int" resultType="ActivityFeed"> <select id="select_activity_site_feeds_greater_than_max" parameterType="ActivityFeedQuery" resultType="ActivityFeed">
<![CDATA[ <![CDATA[
select site_network as siteNetwork select site_network as siteNetwork
from alf_activity_feed from alf_activity_feed
where site_network IS NOT NULL AND ('' IS NULL OR '' != site_network) where site_network != #{nullValue}
group by site_network group by site_network
having count(*) > #{maxFeedSize} having count(*) > #{maxFeedSize}
]]> ]]>
@@ -171,8 +171,8 @@
<![CDATA[ <![CDATA[
select id as id select id as id
from alf_activity_feed_control from alf_activity_feed_control
where (feed_user_id IS NULL and #{feedUserId} IS NULL OR feed_user_id = #{feedUserId}) where feed_user_id = #{feedUserId}
and ((site_network = #{siteNetwork}) or ((#{siteNetwork} is null) and (site_network is null))) and site_network = #{siteNetwork}
and ((app_tool = #{appTool}) or ((#{appTool} is null) and (app_tool is null))) and ((app_tool = #{appTool}) or ((#{appTool} is null) and (app_tool is null)))
]]> ]]>
</select> </select>
@@ -181,7 +181,7 @@
<![CDATA[ <![CDATA[
select id as id, feed_user_id as feedUserId, site_network as siteNetwork, app_tool as appTool select id as id, feed_user_id as feedUserId, site_network as siteNetwork, app_tool as appTool
from alf_activity_feed_control from alf_activity_feed_control
where (feed_user_id IS NULL and #{feedUserId} IS NULL OR feed_user_id = #{feedUserId}) where feed_user_id = #{feedUserId}
]]> ]]>
</select> </select>
@@ -218,20 +218,20 @@
<![CDATA[ <![CDATA[
delete from alf_activity_feed delete from alf_activity_feed
where post_date < #{postDate} where post_date < #{postDate}
and (feed_user_id IS NULL and #{feedUserId} IS NULL OR feed_user_id = #{feedUserId}) and feed_user_id = #{feedUserId}
]]> ]]>
</delete> </delete>
<delete id="delete_activity_feed_for_feeduser_entries" parameterType="ActivityFeed"> <delete id="delete_activity_feed_for_feeduser_entries" parameterType="ActivityFeed">
delete from alf_activity_feed delete from alf_activity_feed
where (feed_user_id IS NULL and #{feedUserId} IS NULL OR feed_user_id = #{feedUserId}) where feed_user_id = #{feedUserId}
</delete> </delete>
<delete id="delete_activity_feedcontrol" parameterType="FeedControl"> <delete id="delete_activity_feedcontrol" parameterType="FeedControl">
<![CDATA[ <![CDATA[
delete from alf_activity_feed_control delete from alf_activity_feed_control
where (feed_user_id IS NULL and #{feedUserId} IS NULL OR feed_user_id = #{feedUserId}) where feed_user_id = #{feedUserId}
and ((site_network = #{siteNetwork}) or ((#{siteNetwork} is null) and (site_network is null))) and site_network = #{siteNetwork}
and ((app_tool = #{appTool}) or ((#{appTool} is null) and (app_tool is null))) and ((app_tool = #{appTool}) or ((#{appTool} is null) and (app_tool is null)))
]]> ]]>
</delete> </delete>

View File

@@ -78,7 +78,7 @@
<![CDATA[ <![CDATA[
select id as id, activity_type as activityType, activity_summary as activitySummary, post_user_id as postUserId, site_network as siteNetwork, post_date as postDate select id as id, activity_type as activityType, activity_summary as activitySummary, post_user_id as postUserId, site_network as siteNetwork, post_date as postDate
from alf_activity_feed from alf_activity_feed
where (feed_user_id = '' or feed_user_id is null) where feed_user_id = #{nullValue}
and site_network = #{siteNetwork} and site_network = #{siteNetwork}
order by post_date desc order by post_date desc
]]> ]]>

View File

@@ -78,7 +78,7 @@
<![CDATA[ <![CDATA[
select id as id, activity_type as activityType, activity_summary as activitySummary, post_user_id as postUserId, site_network as siteNetwork, post_date as postDate select id as id, activity_type as activityType, activity_summary as activitySummary, post_user_id as postUserId, site_network as siteNetwork, post_date as postDate
from alf_activity_feed from alf_activity_feed
where (feed_user_id = '' or feed_user_id is null) where feed_user_id = #{nullValue}
and site_network = #{siteNetwork} and site_network = #{siteNetwork}
order by post_date desc order by post_date desc
]]> ]]>

View File

@@ -3391,4 +3391,15 @@
</property> </property>
</bean> </bean>
<bean id="patch.db-V4.1-update-activiti-nullable-columns" class="org.alfresco.repo.admin.patch.impl.SchemaUpgradeScriptPatch" parent="basePatch">
<property name="id" value="patch.db-V4.1-update-activiti-nullable-columns" />
<property name="description" value="patch.schemaUpgradeScript.description" />
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>8005</value></property>
<property name="targetSchema"><value>8006</value></property>
<property name="scriptUrl">
<value>classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/update-activiti-nullable-columns.sql</value>
</property>
</bean>
</beans> </beans>

View File

@@ -23,4 +23,4 @@ version.build=r@scm-revision@-b@build-number@
# Schema number # Schema number
version.schema=8005 version.schema=8006

View File

@@ -39,6 +39,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import org.alfresco.repo.activities.post.lookup.PostLookup; import org.alfresco.repo.activities.post.lookup.PostLookup;
import org.alfresco.repo.domain.activities.ActivitiesDAO;
import org.alfresco.repo.domain.activities.ActivityFeedDAO; import org.alfresco.repo.domain.activities.ActivityFeedDAO;
import org.alfresco.repo.domain.activities.ActivityFeedEntity; import org.alfresco.repo.domain.activities.ActivityFeedEntity;
import org.alfresco.repo.domain.activities.ActivityPostEntity; import org.alfresco.repo.domain.activities.ActivityPostEntity;
@@ -649,7 +650,7 @@ public abstract class FeedTaskProcessor
for (FeedControlEntity feedControl : feedControls) for (FeedControlEntity feedControl : feedControls)
{ {
if (((feedControl.getSiteNetwork() == null) || (feedControl.getSiteNetwork().length() == 0)) && (feedControl.getAppTool() != null)) if (ActivitiesDAO.KEY_ACTIVITY_NULL_VALUE.equals(feedControl.getSiteNetwork()) && (feedControl.getAppTool() != null))
{ {
if (feedControl.getAppTool().equals(activityPost.getAppTool())) if (feedControl.getAppTool().equals(activityPost.getAppTool()))
{ {

View File

@@ -27,6 +27,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.domain.activities.ActivitiesDAO;
import org.alfresco.repo.domain.activities.ActivityFeedDAO; import org.alfresco.repo.domain.activities.ActivityFeedDAO;
import org.alfresco.repo.domain.activities.ActivityFeedEntity; import org.alfresco.repo.domain.activities.ActivityFeedEntity;
import org.alfresco.repo.lock.JobLockService; import org.alfresco.repo.lock.JobLockService;
@@ -305,7 +306,7 @@ public class FeedCleaner implements NodeServicePolicies.BeforeDeleteNodePolicy
String feedUserId = userFeedTooMany.getFeedUserId(); String feedUserId = userFeedTooMany.getFeedUserId();
// Rather than filter out the two usernames that indicate site-specific // Rather than filter out the two usernames that indicate site-specific
// feed entries, we can just filter them out now. // feed entries, we can just filter them out now.
if (feedUserId == null || feedUserId.length() == 0) if (ActivitiesDAO.KEY_ACTIVITY_NULL_VALUE.equals(feedUserId))
{ {
if (logger.isTraceEnabled()) if (logger.isTraceEnabled())
{ {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2010 Alfresco Software Limited. * Copyright (C) 2005-2014 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -25,6 +25,8 @@ import java.sql.SQLException;
*/ */
public interface ActivitiesDAO public interface ActivitiesDAO
{ {
public static final String KEY_ACTIVITY_NULL_VALUE = "@@NULL@@";
public void startTransaction() throws SQLException; public void startTransaction() throws SQLException;
public void commitTransaction() throws SQLException; public void commitTransaction() throws SQLException;

View File

@@ -46,10 +46,10 @@ public class ActivityFeedEntity
private Long id; // internal DB-generated id private Long id; // internal DB-generated id
private String activityType; private String activityType;
private String activitySummary; private String activitySummary;
private String feedUserId; private String feedUserId = ActivitiesDAO.KEY_ACTIVITY_NULL_VALUE;
private String postUserId; private String postUserId;
private NodeRef postUserAvatarNodeRef; private NodeRef postUserAvatarNodeRef;
private String siteNetwork; private String siteNetwork = ActivitiesDAO.KEY_ACTIVITY_NULL_VALUE;
private String appTool; private String appTool;
private Date postDate; private Date postDate;
private Date feedDate; // for debug private Date feedDate; // for debug
@@ -82,9 +82,12 @@ public class ActivityFeedEntity
} }
public void setFeedUserId(String userid) public void setFeedUserId(String userid)
{
if (userid != null && userid.length() > 0)
{ {
this.feedUserId = userid; this.feedUserId = userid;
} }
}
public String getPostUserId() public String getPostUserId()
{ {
@@ -102,9 +105,12 @@ public class ActivityFeedEntity
} }
public void setSiteNetwork(String siteNetwork) public void setSiteNetwork(String siteNetwork)
{
if (siteNetwork != null && siteNetwork.length() > 0)
{ {
this.siteNetwork = siteNetwork; this.siteNetwork = siteNetwork;
} }
}
public String getActivityType() public String getActivityType()
{ {

View File

@@ -28,9 +28,15 @@ public class ActivityFeedQueryEntity
{ {
private Long minId; private Long minId;
private Long maxId; private Long maxId;
private int maxFeedSize;
private String feedUserId; private String feedUserId;
private String siteNetwork; private String siteNetwork;
public String getNullValue()
{
return ActivitiesDAO.KEY_ACTIVITY_NULL_VALUE;
}
public Long getMinId() public Long getMinId()
{ {
return minId; return minId;
@@ -51,6 +57,16 @@ public class ActivityFeedQueryEntity
this.maxId = maxId; this.maxId = maxId;
} }
public int getMaxFeedSize()
{
return maxFeedSize;
}
public void setMaxFeedSize(int maxFeedSize)
{
this.maxFeedSize = maxFeedSize;
}
public String getFeedUserId() public String getFeedUserId()
{ {
return feedUserId; return feedUserId;

View File

@@ -28,8 +28,8 @@ import org.alfresco.service.cmr.activities.FeedControl;
public class FeedControlEntity public class FeedControlEntity
{ {
private Long id; // internal DB-generated id private Long id; // internal DB-generated id
private String feedUserId; private String feedUserId = ActivitiesDAO.KEY_ACTIVITY_NULL_VALUE;
private String siteNetwork; private String siteNetwork = ActivitiesDAO.KEY_ACTIVITY_NULL_VALUE;
private String appTool; private String appTool;
private Date lastModified; // when inserted private Date lastModified; // when inserted
@@ -43,14 +43,23 @@ public class FeedControlEntity
} }
public FeedControlEntity(String feedUserId) public FeedControlEntity(String feedUserId)
{
if (feedUserId != null && feedUserId.length() > 0)
{ {
this.feedUserId = feedUserId; this.feedUserId = feedUserId;
} }
}
public FeedControlEntity(String feedUserId, FeedControl feedControl) public FeedControlEntity(String feedUserId, FeedControl feedControl)
{
if (feedUserId != null && feedUserId.length() > 0)
{ {
this.feedUserId = feedUserId; this.feedUserId = feedUserId;
}
if (feedControl.getSiteId() != null && feedControl.getSiteId().length() > 0)
{
this.siteNetwork = feedControl.getSiteId(); this.siteNetwork = feedControl.getSiteId();
}
this.appTool = feedControl.getAppToolId(); this.appTool = feedControl.getAppToolId();
this.lastModified = new Date(); this.lastModified = new Date();
} }
@@ -76,9 +85,12 @@ public class FeedControlEntity
} }
public void setSiteNetwork(String siteNetwork) public void setSiteNetwork(String siteNetwork)
{
if (siteNetwork != null && siteNetwork.length() > 0)
{ {
this.siteNetwork = siteNetwork; this.siteNetwork = siteNetwork;
} }
}
public String getAppTool() public String getAppTool()
{ {
@@ -96,9 +108,12 @@ public class FeedControlEntity
} }
public void setFeedUserId(String feedUserId) public void setFeedUserId(String feedUserId)
{
if (feedUserId != null && feedUserId.length() > 0)
{ {
this.feedUserId = feedUserId; this.feedUserId = feedUserId;
} }
}
public Date getLastModified() public Date getLastModified()
{ {

View File

@@ -127,7 +127,10 @@ public class ActivityFeedDAOImpl extends ActivitiesDAOImpl implements ActivityFe
@Override @Override
public List<ActivityFeedEntity> selectUserFeedsToClean(int maxFeedSize) throws SQLException public List<ActivityFeedEntity> selectUserFeedsToClean(int maxFeedSize) throws SQLException
{ {
return template.selectList("alfresco.activities.select_activity_user_feeds_greater_than_max", maxFeedSize); ActivityFeedQueryEntity params = new ActivityFeedQueryEntity();
params.setMaxFeedSize(maxFeedSize);
return template.selectList("alfresco.activities.select_activity_user_feeds_greater_than_max", params);
} }
@Override @Override
@@ -197,7 +200,10 @@ public class ActivityFeedDAOImpl extends ActivitiesDAOImpl implements ActivityFe
@Override @Override
public List<ActivityFeedEntity> selectSiteFeedsToClean(int maxFeedSize) throws SQLException public List<ActivityFeedEntity> selectSiteFeedsToClean(int maxFeedSize) throws SQLException
{ {
return template.selectList("alfresco.activities.select_activity_site_feeds_greater_than_max", maxFeedSize); ActivityFeedQueryEntity params = new ActivityFeedQueryEntity();
params.setMaxFeedSize(maxFeedSize);
return template.selectList("alfresco.activities.select_activity_site_feeds_greater_than_max", params);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

View File

@@ -24,6 +24,7 @@ import static org.junit.Assert.assertTrue;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.activities.post.lookup.PostLookup; import org.alfresco.repo.activities.post.lookup.PostLookup;
import org.alfresco.repo.domain.activities.ActivitiesDAO;
import org.alfresco.repo.domain.activities.ActivityFeedEntity; import org.alfresco.repo.domain.activities.ActivityFeedEntity;
import org.alfresco.repo.domain.activities.ActivityPostDAO; import org.alfresco.repo.domain.activities.ActivityPostDAO;
import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory; import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
@@ -317,7 +318,7 @@ public class FeedNotifierTest
boolean found = false; boolean found = false;
for (ActivityFeedEntity feed : feeds) for (ActivityFeedEntity feed : feeds)
{ {
if (feed.getActivityType().equals(activityType) && (feed.getSiteNetwork() == null || feed.getSiteNetwork().isEmpty())) if (feed.getActivityType().equals(activityType) && ActivitiesDAO.KEY_ACTIVITY_NULL_VALUE.equals(feed.getSiteNetwork()))
{ {
found = true; found = true;
} }