summaryrefslogtreecommitdiff
path: root/db
diff options
context:
space:
mode:
authorSean McGivern <sean@gitlab.com>2018-07-03 13:23:17 +0100
committerOswaldo Ferreira <oswaldo@gitlab.com>2018-07-10 09:43:57 -0300
commit3acf7ba9caf19b1a02b34071454a631c959b5c58 (patch)
tree7b77ee8a8367b5da887790d833e34fa1693962a3 /db
parent3d4873fa64c833c71ab7ee274002d854eb93ef96 (diff)
downloadgitlab-ce-3acf7ba9caf19b1a02b34071454a631c959b5c58.tar.gz
Revert "Temporarily remove MR diffs removal migration"
This reverts commit 15ec6a13eb4d839d252315bf5b0a50d28351cb5f.
Diffstat (limited to 'db')
-rw-r--r--db/post_migrate/20180619121030_enqueue_delete_diff_files_workers.rb70
1 files changed, 70 insertions, 0 deletions
diff --git a/db/post_migrate/20180619121030_enqueue_delete_diff_files_workers.rb b/db/post_migrate/20180619121030_enqueue_delete_diff_files_workers.rb
new file mode 100644
index 00000000000..5fb3d545624
--- /dev/null
+++ b/db/post_migrate/20180619121030_enqueue_delete_diff_files_workers.rb
@@ -0,0 +1,70 @@
+class EnqueueDeleteDiffFilesWorkers < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ class MergeRequestDiff < ActiveRecord::Base
+ self.table_name = 'merge_request_diffs'
+
+ belongs_to :merge_request
+
+ include EachBatch
+ end
+
+ DOWNTIME = false
+ BATCH_SIZE = 1000
+ MIGRATION = 'DeleteDiffFiles'
+ DELAY_INTERVAL = 8.minutes
+ TMP_INDEX = 'tmp_partial_diff_id_with_files_index'.freeze
+
+ disable_ddl_transaction!
+
+ def up
+ # We add temporary index, to make iteration over batches more performant.
+ # Conditional here is to avoid the need of doing that in a separate
+ # migration file to make this operation idempotent.
+ #
+ unless index_exists_by_name?(:merge_request_diffs, TMP_INDEX)
+ add_concurrent_index(:merge_request_diffs, :id, where: "(state NOT IN ('without_files', 'empty'))", name: TMP_INDEX)
+ end
+
+
+ diffs_with_files = MergeRequestDiff.where.not(state: ['without_files', 'empty'])
+
+ # explain (analyze, buffers) example for the iteration:
+ #
+ # Index Only Scan using tmp_index_20013 on merge_request_diffs (cost=0.43..1630.19 rows=60567 width=4) (actual time=0.047..9.572 rows=56976 loops=1)
+ # Index Cond: ((id >= 764586) AND (id < 835298))
+ # Heap Fetches: 8
+ # Buffers: shared hit=18188
+ # Planning time: 0.752 ms
+ # Execution time: 12.430 ms
+ #
+ diffs_with_files.each_batch(of: BATCH_SIZE) do |relation, outer_index|
+ ids = relation.pluck(:id)
+
+ ids.each_with_index do |diff_id, inner_index|
+ # This will give some space between batches of workers.
+ interval = DELAY_INTERVAL * outer_index + inner_index.minutes
+
+ # A single `merge_request_diff` can be associated with way too many
+ # `merge_request_diff_files`. It's better to avoid batching these and
+ # schedule one at a time.
+ #
+ # Considering roughly 6M jobs, this should take ~30 days to process all
+ # of them.
+ #
+ BackgroundMigrationWorker.perform_in(interval, MIGRATION, [diff_id])
+ end
+ end
+
+ # We remove temporary index, because it is not required during standard
+ # operations and runtime.
+ #
+ remove_concurrent_index_by_name(:merge_request_diffs, TMP_INDEX)
+ end
+
+ def down
+ if index_exists_by_name?(:merge_request_diffs, TMP_INDEX)
+ remove_concurrent_index_by_name(:merge_request_diffs, TMP_INDEX)
+ end
+ end
+end