Skip to content

Draft: Add migrations to clear undesireable artifact expiration dates

drew stachon requested to merge clear-expire-at-migrations into master

What does this MR do and why?

This migration adds two migrations, one background migration and another to schedule it. This is the main effort to address &7097.

We backfilled the expire_at column in ci_job_artifacts, but didn't do this with any respect to the file_type or whether or not users intend to keep these artifacts forever. This includes users who, for compliance reasons, may need to keep their artifacts forever. It also includes job traces, which we we have never had a policy of removing, and so should not without telling anyone in advance. It also affected self-hosted customers who do not have concerns about the total consumption of ObjectStorage.

To remedy this, we'll be erasing the expire_at timestamp for any artifact set to expire at midnight on the 22nd of any month, in the applications configured time zone. This logic is intended to be the mirror image of the logic in !47723 (merged) which originally wrote these timestamps.

While this will persist some artifacts that users may prefer to let expire, preserving the data and letting users explicitly erase it themselves instead of accidentally deleting recoverable files.

Migration impact

In !47723 (diffs) we explicitly operated on artifacts created before 2020-06-22, so we can use that scope again here and ignore everything afterward.

Within artifacts created before that date, we need to query all artifacts that have a expire_at value at midnight on the 22nd of any month, in the application's configured time zone. Therefore, we unfortunately need to instantiate ActiveRecord objects for every single record in order to convert the database timestamp into the correct time zone.

I'm not sure what this means for an installation that has changed their configured time zone since running the original migration.

On gitlab.com, we have ~492m rows created before 2020-06-22:

SELECT count(*) FROM legacy.gitlab_dotcom_ci_job_artifacts WHERE expire_at IS NOT NULL AND (created_at < '2020-06-22'::date)

> 492724205

and of these, ~474m need to be rewritten:

SELECT count(*) FROM legacy.gitlab_dotcom_ci_job_artifacts
  WHERE expire_at IS NOT NULL
  AND (created_at < '2020-06-22'::date)
  AND extract(day from expire_at) = 22
  AND extract(hour from expire_at) = 0
  AND extract(minute from expire_at) = 0
  AND extract(second from expire_at) = 0

> 474348791

Out of 1.6b rows currently in the table:

SELECT count(*) FROM legacy.gitlab_dotcom_ci_job_artifacts

> 1589406477 

This proportion of artifacts needing to be written makes me think an index is not worth building, but I'd be open to counter arguments.

How to set up and validate locally

Numbered steps to set up and validate the change are strongly suggested.

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by drew stachon

Merge request reports