Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What's the best way to auto truncate good_job_executions table #1607

Open
daya opened this issue Feb 19, 2025 · 1 comment
Open

What's the best way to auto truncate good_job_executions table #1607

daya opened this issue Feb 19, 2025 · 1 comment

Comments

@daya
Copy link

daya commented Feb 19, 2025

Just wondering how does good_job manage the size and truncation of good_job_executions table?

Coz it seems good_job_executions table will continue to increase forever.

@bensheldon
Copy link
Owner

This is the method that deletes old records:

good_job/lib/good_job.rb

Lines 198 to 248 in b557525

# Destroys preserved job and batch records.
# By default, GoodJob destroys job records when the job is performed and this
# method is not necessary. However, when `GoodJob.preserve_job_records = true`,
# the jobs will be preserved in the database. This is useful when wanting to
# analyze or inspect job performance.
# If you are preserving job records this way, use this method regularly to
# destroy old records and preserve space in your database.
# @param older_than [nil,Numeric,ActiveSupport::Duration] Jobs older than this will be destroyed (default: +86400+).
# @param include_discarded [Boolean] Whether or not to destroy discarded jobs (default: per +cleanup_discarded_jobs+ config option)
# @return [Integer] Number of job execution records and batches that were destroyed.
def self.cleanup_preserved_jobs(older_than: nil, in_batches_of: 1_000, include_discarded: GoodJob.configuration.cleanup_discarded_jobs?)
older_than ||= GoodJob.configuration.cleanup_preserved_jobs_before_seconds_ago
timestamp = Time.current - older_than
ActiveSupport::Notifications.instrument("cleanup_preserved_jobs.good_job", { older_than: older_than, timestamp: timestamp }) do |payload|
deleted_jobs_count = 0
deleted_batches_count = 0
deleted_executions_count = 0
jobs_query = GoodJob::Job.finished_before(timestamp).order(finished_at: :asc).limit(in_batches_of)
jobs_query = jobs_query.succeeded unless include_discarded
loop do
active_job_ids = jobs_query.pluck(:active_job_id)
break if active_job_ids.empty?
deleted_executions = GoodJob::Execution.where(active_job_id: active_job_ids).delete_all
deleted_executions_count += deleted_executions
deleted_jobs = GoodJob::Job.where(active_job_id: active_job_ids).delete_all
deleted_jobs_count += deleted_jobs
end
batches_query = GoodJob::BatchRecord.finished_before(timestamp).limit(in_batches_of)
batches_query = batches_query.succeeded unless include_discarded
loop do
deleted = batches_query.delete_all
break if deleted.zero?
deleted_batches_count += deleted
end
payload[:destroyed_batches_count] = deleted_batches_count
payload[:destroyed_executions_count] = deleted_executions_count
payload[:destroyed_jobs_count] = deleted_jobs_count
destroyed_records_count = deleted_batches_count + deleted_executions_count + deleted_jobs_count
payload[:destroyed_records_count] = destroyed_records_count
destroyed_records_count
end
end

In operation, the GoodJob::Scheduler tracks the number of jobs that have been executed with the GoodJob::CleanupTracker, and after a certain number of jobs have been performed, the Scheduler then calls JobPerformer#cleanup, which then calls GoodJob.cleanup_preserved_jobs.

If the Job never finishes/discards, then yes, the executions for that job will pile up as the job+execution records are not cleaned up until it finishes/discards.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Inbox
Development

No branches or pull requests

2 participants