-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
Low
-
None
-
Affects Version/s: 8.20.11
-
Component/s: Sprint
-
None
-
8.2
-
2
-
Severity 3 - Minor
-
1
Problem
When a user filter has more than 50+ sprint names selected in the advanced JQL query, it will cause the query to be running slowly. For example:
project in (TEST) AND sprint in (Sprint-A, Sprint-B, Sprint-C, Sprint-D and so on....)
The searching does not impact admin users.
Diagnose
In the thread dumps, we can see the long-running stack trace hitting 99% CPU usage is checking the number of sprints for each issue and user permissions:
13:17:52 - http-nio-8080-exec-6 url: /issues/, /secure/IssueNavAction!default.jspa; user: username State:RUNNABLE CPU usage:99.90% Running for: 1:35.33 Waiting for This thread is not waiting for notification on any lock Locks held This thread holds [0x7fca4dcb0680, 0x7fc988f45820] Stack trace com.atlassian.greenhopper.customfield.sprint.IssueCountPerSprintCollector.collect(IssueCountPerSprintCollector.java:45) org.apache.lucene.search.Weight$DefaultBulkScorer.scoreAll(Weight.java:233) org.apache.lucene.search.Weight$DefaultBulkScorer.score(Weight.java:184) org.apache.lucene.search.BulkScorer.score(BulkScorer.java:39) org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:660) org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:462) com.atlassian.jira.index.stats.IndexSearcherWithStats.search(IndexSearcherWithStats.java:88) com.atlassian.jira.index.DelegateSearcher.search(DelegateSearcher.java:169) com.atlassian.jira.index.DelegateSearcher.search(DelegateSearcher.java:169) com.atlassian.jira.index.UnmanagedIndexSearcher.search(UnmanagedIndexSearcher.java:9) com.atlassian.jira.index.DelegateSearcher.search(DelegateSearcher.java:169) com.atlassian.jira.index.ManagedIndexSearcher.search(ManagedIndexSearcher.java:15) com.atlassian.jira.issue.search.providers.LuceneSearchProvider.search(LuceneSearchProvider.java:324) com.atlassian.jira.issue.search.providers.LuceneSearchProvider.search(LuceneSearchProvider.java:158) jdk.internal.reflect.GeneratedMethodAccessor2973.invoke(Unknown Source) jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@11.0.19/DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(java.base@11.0.19/Method.java:566) com.atlassian.plugin.util.ContextClassLoaderSettingInvocationHandler.invoke(ContextClassLoaderSettingInvocationHandler.java:26) com.sun.proxy.$Proxy403.search(Unknown Source) jdk.internal.reflect.GeneratedMethodAccessor2973.invoke(Unknown Source) jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@11.0.19/DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(java.base@11.0.19/Method.java:566) com.atlassian.plugin.osgi.bridge.external.HostComponentFactoryBean$DynamicServiceInvocationHandler.invoke(HostComponentFactoryBean.java:130) com.sun.proxy.$Proxy403.search(Unknown Source) com.atlassian.greenhopper.service.sprint.SprintIssueServiceImpl.getIssuesCountForSprints(SprintIssueServiceImpl.java:382) com.atlassian.greenhopper.service.sprint.SprintServiceImpl.getSprintsAccessibleFromIssue(SprintServiceImpl.java:750) com.atlassian.greenhopper.service.sprint.SprintServiceImpl.getSprints(SprintServiceImpl.java:190) com.atlassian.greenhopper.customfield.sprint.SprintResolver.getSprintsStreamByPredicate(SprintResolver.java:84) com.atlassian.greenhopper.customfield.sprint.SprintResolver.findSprintIdsByName(SprintResolver.java:42) com.atlassian.greenhopper.customfield.sprint.SprintClauseValidator.validate(SprintClauseValidator.java:70) com.atlassian.jira.jql.validator.ValidatorVisitor.validateClause(ValidatorVisitor.java:132) com.atlassian.jira.jql.validator.ValidatorVisitor.visit(ValidatorVisitor.java:73) com.atlassian.jira.jql.validator.ValidatorVisitor.visit(ValidatorVisitor.java:36) com.atlassian.query.clause.TerminalClauseImpl.accept(TerminalClauseImpl.java:143) com.atlassian.jira.jql.validator.ValidatorVisitor.getMessagesFromSubClauses(ValidatorVisitor.java:165) com.atlassian.jira.jql.validator.ValidatorVisitor.visit(ValidatorVisitor.java:55) com.atlassian.jira.jql.validator.ValidatorVisitor.visit(ValidatorVisitor.java:36) com.atlassian.query.clause.AndClause.accept(AndClause.java:28) com.atlassian.jira.bc.issue.search.DefaultSearchService.validateQuery(DefaultSearchService.java:272)
Current Design
Every time user asks for sprint we're checking if the user has access to it and it has if the user:
- is an admin,
- OR has access to the board
- OR has access to any issue from this sprint.
Suggestions
To fix that problem by creating a feature flag or cache the results to improve the performance in the future.
Workaround
To speed up the searching process, we recommend a workaround by replacing sprint names with sprint IDs.
To find the Sprint ID, please paste the sprint names and run the SQL query:
SELECT ID, NAME FROM AO_60DB71_SPRINT WHERE NAME like '%SPRINT_NAME%';
Replace SPRINT_NAME with the sprint name from the filter.
Or you can find the sprint id following the Jira Software: How to identify the ID of a sprint KB article.
Update all the sprint names to id from the filter and then saved the filter.