Create partial indexes for pending/running builds
What does this MR do?
This creates partial indexes on ci_builds
for pending and running builds.
- Issue: #327142 (closed)
- Incident: gitlab-com/gl-infra/production#4473 (closed)
Query:
SELECT
"ci_builds"."id"
FROM
"ci_builds"
INNER JOIN "projects" ON "projects"."id" = "ci_builds"."project_id"
LEFT JOIN project_features ON ci_builds.project_id = project_features.project_id
LEFT JOIN (
SELECT
"ci_builds"."project_id",
count(*) AS running_builds
FROM
"ci_builds"
WHERE
"ci_builds"."type" = 'Ci::Build'
AND ("ci_builds"."status" IN ('running'))
AND "ci_builds"."runner_id" IN (
SELECT
"ci_runners"."id"
FROM
"ci_runners"
WHERE
"ci_runners"."runner_type" = 1)
GROUP BY
"ci_builds"."project_id") AS project_builds ON ci_builds.project_id = project_builds.project_id
WHERE ("ci_builds"."status" IN ('pending'))
AND "ci_builds"."runner_id" IS NULL
AND "projects"."shared_runners_enabled" = TRUE
AND "projects"."pending_delete" = FALSE
AND (project_features.builds_access_level IS NULL
OR project_features.builds_access_level > 0)
AND "ci_builds"."type" = 'Ci::Build'
AND ("projects"."visibility_level" = 20
OR (EXISTS ( WITH RECURSIVE "base_and_ancestors" AS ((
SELECT
"namespaces".*
FROM
"namespaces"
WHERE (namespaces.id = projects.namespace_id))
UNION (
SELECT
"namespaces".*
FROM
"namespaces",
"base_and_ancestors"
WHERE
"namespaces"."id" = "base_and_ancestors"."parent_id"))
SELECT DISTINCT
1
FROM
"base_and_ancestors" AS "namespaces"
LEFT JOIN namespace_statistics ON namespace_statistics.namespace_id = namespaces.id
WHERE
"namespaces"."parent_id" IS NULL
AND (COALESCE(namespaces.shared_runners_minutes_limit, 400, 0) = 0
OR COALESCE(namespace_statistics.shared_runners_seconds, 0) < COALESCE((namespaces.shared_runners_minutes_limit + COALESCE(namespaces.extra_shared_runners_minutes_limit, 0)), (400 + COALESCE(namespaces.extra_shared_runners_minutes_limit, 0)), 0) * 60))))
AND (NOT EXISTS (
SELECT
1
FROM
"taggings"
WHERE
"taggings"."taggable_type" = 'CommitStatus'
AND "taggings"."context" = 'tags'
AND (taggable_id = ci_builds.id)
AND "taggings"."tag_id" != 26114))
AND (EXISTS (
SELECT
1
FROM
"taggings"
WHERE
"taggings"."taggable_type" = 'CommitStatus'
AND "taggings"."context" = 'tags'
AND (taggable_id = ci_builds.id)))
ORDER BY
COALESCE(project_builds.running_builds, 0) ASC,
ci_builds.id ASC;
Query plans
- Plan (under normal operations): https://explain.depesz.com/s/5Rjp
- Plan (when things are on
🔥 - cause still unknown ): https://explain.depesz.com/s/QHTx - Plan (from dblab with indexes
foobar2, foobar3
created): https://explain.depesz.com/s/2q2g
The full execution plan from dblab is here: https://explain.depesz.com/s/1e3A
After seeing this, we included the type = 'Ci::Build'
into the partial condition.
Stats
- Index sizes: Both < 11 MB
- Creation times: Both around 9h on dblab (will be much faster in prod)
Does this MR meet the acceptance criteria?
Conformity
-
📋 Does this MR need a changelog?-
I have included a changelog entry. -
I have not included a changelog entry because _____.
-
-
Documentation (if required) -
Code review guidelines -
Merge request performance guidelines -
Style guides -
Database guides -
Separation of EE specific content
Availability and Testing
-
Review and add/update tests for this feature/bug. Consider all test levels. See the Test Planning Process. -
Tested in all supported browsers -
Informed Infrastructure department of a default or new setting change, if applicable per definition of done
Security
If this MR contains changes to processing or storing of credentials or tokens, authorization and authentication methods and other items described in the security review guidelines:
-
Label as security and @ mention @gitlab-com/gl-security/appsec
-
The MR includes necessary changes to maintain consistency between UI, API, email, or other methods -
Security reports checked/validated by a reviewer from the AppSec team
Edited by Andreas Brandl