diff --git a/db/migrate/20240313144611_recreate_good_job_cron_indexes_with_conditional.rb b/db/migrate/20240313144611_recreate_good_job_cron_indexes_with_conditional.rb new file mode 100644 index 00000000..56cab35c --- /dev/null +++ b/db/migrate/20240313144611_recreate_good_job_cron_indexes_with_conditional.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +class RecreateGoodJobCronIndexesWithConditional < ActiveRecord::Migration[7.1] + disable_ddl_transaction! + + def change + reversible do |dir| + dir.up do + unless connection.index_name_exists?(:good_jobs, :index_good_jobs_on_cron_key_and_created_at_cond) + add_index :good_jobs, [:cron_key, :created_at], where: "(cron_key IS NOT NULL)", + name: :index_good_jobs_on_cron_key_and_created_at_cond, algorithm: :concurrently + end + unless connection.index_name_exists?(:good_jobs, :index_good_jobs_on_cron_key_and_cron_at_cond) + add_index :good_jobs, [:cron_key, :cron_at], where: "(cron_key IS NOT NULL)", unique: true, + name: :index_good_jobs_on_cron_key_and_cron_at_cond, algorithm: :concurrently + end + + if connection.index_name_exists?(:good_jobs, :index_good_jobs_on_cron_key_and_created_at) + remove_index :good_jobs, name: :index_good_jobs_on_cron_key_and_created_at + end + if connection.index_name_exists?(:good_jobs, :index_good_jobs_on_cron_key_and_cron_at) + remove_index :good_jobs, name: :index_good_jobs_on_cron_key_and_cron_at + end + end + + dir.down do + unless connection.index_name_exists?(:good_jobs, :index_good_jobs_on_cron_key_and_created_at) + add_index :good_jobs, [:cron_key, :created_at], + name: :index_good_jobs_on_cron_key_and_created_at, algorithm: :concurrently + end + unless connection.index_name_exists?(:good_jobs, :index_good_jobs_on_cron_key_and_cron_at) + add_index :good_jobs, [:cron_key, :cron_at], unique: true, + name: :index_good_jobs_on_cron_key_and_cron_at, algorithm: :concurrently + end + + if connection.index_name_exists?(:good_jobs, :index_good_jobs_on_cron_key_and_created_at_cond) + remove_index :good_jobs, name: :index_good_jobs_on_cron_key_and_created_at_cond + end + if connection.index_name_exists?(:good_jobs, :index_good_jobs_on_cron_key_and_cron_at_cond) + remove_index :good_jobs, name: :index_good_jobs_on_cron_key_and_cron_at_cond + end + end + end + end +end diff --git a/db/migrate/20240313144612_create_good_job_labels.rb b/db/migrate/20240313144612_create_good_job_labels.rb new file mode 100644 index 00000000..1ba514e8 --- /dev/null +++ b/db/migrate/20240313144612_create_good_job_labels.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class CreateGoodJobLabels < ActiveRecord::Migration[7.1] + def change + reversible do |dir| + dir.up do + # Ensure this incremental update migration is idempotent + # with monolithic install migration. + return if connection.column_exists?(:good_jobs, :labels) + end + end + + add_column :good_jobs, :labels, :text, array: true + end +end diff --git a/db/migrate/20240313144613_create_good_job_labels_index.rb b/db/migrate/20240313144613_create_good_job_labels_index.rb new file mode 100644 index 00000000..65dedd47 --- /dev/null +++ b/db/migrate/20240313144613_create_good_job_labels_index.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class CreateGoodJobLabelsIndex < ActiveRecord::Migration[7.1] + disable_ddl_transaction! + + def change + reversible do |dir| + dir.up do + unless connection.index_name_exists?(:good_jobs, :index_good_jobs_on_labels) + add_index :good_jobs, :labels, using: :gin, where: "(labels IS NOT NULL)", + name: :index_good_jobs_on_labels, algorithm: :concurrently + end + end + + dir.down do + if connection.index_name_exists?(:good_jobs, :index_good_jobs_on_labels) + remove_index :good_jobs, name: :index_good_jobs_on_labels + end + end + end + end +end diff --git a/db/migrate/20240313144614_remove_good_job_active_id_index.rb b/db/migrate/20240313144614_remove_good_job_active_id_index.rb new file mode 100644 index 00000000..8601f071 --- /dev/null +++ b/db/migrate/20240313144614_remove_good_job_active_id_index.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class RemoveGoodJobActiveIdIndex < ActiveRecord::Migration[7.1] + disable_ddl_transaction! + + def change + reversible do |dir| + dir.up do + if connection.index_name_exists?(:good_jobs, :index_good_jobs_on_active_job_id) + remove_index :good_jobs, name: :index_good_jobs_on_active_job_id + end + end + + dir.down do + unless connection.index_name_exists?(:good_jobs, :index_good_jobs_on_active_job_id) + add_index :good_jobs, :active_job_id, name: :index_good_jobs_on_active_job_id + end + end + end + end +end diff --git a/db/migrate/20240313144615_create_index_good_job_jobs_for_candidate_lookup.rb b/db/migrate/20240313144615_create_index_good_job_jobs_for_candidate_lookup.rb new file mode 100644 index 00000000..70e52562 --- /dev/null +++ b/db/migrate/20240313144615_create_index_good_job_jobs_for_candidate_lookup.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class CreateIndexGoodJobJobsForCandidateLookup < ActiveRecord::Migration[7.1] + disable_ddl_transaction! + + def change + reversible do |dir| + dir.up do + # Ensure this incremental update migration is idempotent + # with monolithic install migration. + return if connection.index_name_exists?(:good_jobs, :index_good_job_jobs_for_candidate_lookup) + end + end + + add_index :good_jobs, [:priority, :created_at], order: { priority: "ASC NULLS LAST", created_at: :asc }, + where: "finished_at IS NULL", name: :index_good_job_jobs_for_candidate_lookup, + algorithm: :concurrently + end +end diff --git a/db/schema.rb b/db/schema.rb index 8f356d51..daa20e86 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_03_05_173627) do +ActiveRecord::Schema[7.1].define(version: 2024_03_13_144615) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" enable_extension "plpgsql" @@ -184,14 +184,16 @@ t.integer "executions_count" t.text "job_class" t.integer "error_event", limit: 2 + t.text "labels", array: true t.index ["active_job_id", "created_at"], name: "index_good_jobs_on_active_job_id_and_created_at" - t.index ["active_job_id"], name: "index_good_jobs_on_active_job_id" t.index ["batch_callback_id"], name: "index_good_jobs_on_batch_callback_id", where: "(batch_callback_id IS NOT NULL)" t.index ["batch_id"], name: "index_good_jobs_on_batch_id", where: "(batch_id IS NOT NULL)" t.index ["concurrency_key"], name: "index_good_jobs_on_concurrency_key_when_unfinished", where: "(finished_at IS NULL)" - t.index ["cron_key", "created_at"], name: "index_good_jobs_on_cron_key_and_created_at" - t.index ["cron_key", "cron_at"], name: "index_good_jobs_on_cron_key_and_cron_at", unique: true + t.index ["cron_key", "created_at"], name: "index_good_jobs_on_cron_key_and_created_at_cond", where: "(cron_key IS NOT NULL)" + t.index ["cron_key", "cron_at"], name: "index_good_jobs_on_cron_key_and_cron_at_cond", unique: true, where: "(cron_key IS NOT NULL)" t.index ["finished_at"], name: "index_good_jobs_jobs_on_finished_at", where: "((retried_good_job_id IS NULL) AND (finished_at IS NOT NULL))" + t.index ["labels"], name: "index_good_jobs_on_labels", where: "(labels IS NOT NULL)", using: :gin + t.index ["priority", "created_at"], name: "index_good_job_jobs_for_candidate_lookup", where: "(finished_at IS NULL)" t.index ["priority", "created_at"], name: "index_good_jobs_jobs_on_priority_created_at_when_unfinished", order: { priority: "DESC NULLS LAST" }, where: "(finished_at IS NULL)" t.index ["queue_name", "scheduled_at"], name: "index_good_jobs_on_queue_name_and_scheduled_at", where: "(finished_at IS NULL)" t.index ["scheduled_at"], name: "index_good_jobs_on_scheduled_at", where: "(finished_at IS NULL)"