Skip to content

Fetch pending builds with denormalized shared runners

Max Orefice requested to merge mo-update-shared-runners-query into master

Ref: #329762 (closed)

What does this MR do?

Following up !64644 (merged) where we start to denormalize shared runners information in ci_pending_builds.

This MR fetches pending builds with our denormalized shared runners data and get rid of joins condition to accelerate our big SQL query.

Why are we doing this?

This is part of our epic to scale up the Ci::Build table.

By avoiding to query the ci_builds we simplify our queuing system to determine which build will get pick up by shared runners.

Queries

Old query:

WITH project_builds AS MATERIALIZED (
    SELECT
        ci_running_builds.project_id,
        COUNT(
            *
) AS running_builds
    FROM
        ci_running_builds
    WHERE
        ci_running_builds.runner_type = 1
    GROUP BY
        ci_running_builds.project_id
)
SELECT
    ci_pending_builds.*
FROM
    ci_pending_builds
    INNER JOIN projects ON ci_pending_builds.project_id = projects.id
-    LEFT JOIN project_features ON ci_pending_builds.project_id = project_features.project_id
    LEFT JOIN project_builds ON ci_pending_builds.project_id = project_builds.project_id
 WHERE
-    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 (projects.visibility_level = 20
        OR EXISTS (
            SELECT
                1
            FROM
                namespaces
                INNER JOIN namespaces AS project_namespaces ON project_namespaces.id = projects.namespace_id
                LEFT JOIN namespace_statistics ON namespace_statistics.namespace_id = namespaces.id
            WHERE (namespaces.id = project_namespaces.traversal_ids[1])
            AND (COALESCE(namespaces.shared_runners_minutes_limit, 0, 0) = 0
                OR COALESCE(namespace_statistics.shared_runners_seconds, 0) < COALESCE((namespaces.shared_runners_minutes_limit + COALESCE(namespaces.extra_shared_runners_minutes_limit, 0)), (0 + 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_pending_builds.build_id)
            AND 1 = 1))
ORDER BY
    COALESCE(project_builds.running_builds, 0) ASC,
    ci_pending_builds.build_id ASC

New query:

WITH project_builds AS MATERIALIZED (
    SELECT
        ci_running_builds.project_id,
        COUNT(
            *
) AS running_builds
    FROM
        ci_running_builds
    WHERE
        ci_running_builds.runner_type = 1
    GROUP BY
        ci_running_builds.project_id
)
SELECT
    ci_pending_builds.*
FROM
    ci_pending_builds
    INNER JOIN projects ON ci_pending_builds.project_id = projects.id
    LEFT JOIN project_builds ON ci_pending_builds.project_id = project_builds.project_id
WHERE
+    ci_pending_builds.instance_runners_enabled = TRUE
    AND (projects.visibility_level = 20
        OR EXISTS (
            SELECT
                1
            FROM
                namespaces
                INNER JOIN namespaces AS project_namespaces ON project_namespaces.id = projects.namespace_id
                LEFT JOIN namespace_statistics ON namespace_statistics.namespace_id = namespaces.id
            WHERE (namespaces.id = project_namespaces.traversal_ids[1])
            AND (COALESCE(namespaces.shared_runners_minutes_limit, 0, 0) = 0
                OR COALESCE(namespace_statistics.shared_runners_seconds, 0) < COALESCE((namespaces.shared_runners_minutes_limit + COALESCE(namespaces.extra_shared_runners_minutes_limit, 0)), (0 + 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_pending_builds.build_id)
            AND 1 = 1))
ORDER BY
    COALESCE(project_builds.running_builds, 0) ASC,
    ci_pending_builds.build_id ASC

Does this MR meet the acceptance criteria?

Conformity

Edited by Max Orefice

Merge request reports