Schedule async creation of route indexes
What does this MR do and why?
If we want to create routes for ProjectNamespaces with the same path is corresponding Project route, we first need to replace existing index_routes_on_path
unique index with a couple of indexes so uniqueness is checked only for "not project namespace paths".
Because routes
table is big, these indexes will be created asynchronously (https://docs.gitlab.com/ee/development/adding_database_indexes.html#schedule-the-index-to-be-created).
Additional info
There are two possible migration strategies discussed in &7184 (comment 755099066). This MR assumes that we would use strategy when project namespace routes are first backfilled for all projects, then project routes are deleted. If DB team suggests rather different strategy (in line replacement of existing project route with project namespace route, this MR wouldn't be needed. Pros/cons of each strategy is discussed in the linked discussion.
DB migration
$ rake db:migrate
== 20211208081833 ExcludeProjectNamespaceFromRoutePathUniqueIndex: migrating ==
== 20211208081833 ExcludeProjectNamespaceFromRoutePathUniqueIndex: migrated (0.0022s)
$ rake db:rollback
== 20211208081833 ExcludeProjectNamespaceFromRoutePathUniqueIndex: reverting ==
== 20211208081833 ExcludeProjectNamespaceFromRoutePathUniqueIndex: reverted (0.0015s)
The output above is not very helpful, if done synchronously with add/remove_concurrent_indexes, the output is:
$ rake db:migrate
== 20211208081833 ExcludeProjectNamespaceFromRoutePathUniqueIndex: migrating ==
-- transaction_open?()
-> 0.0000s
-- index_exists?(:routes, :path, {:where=>"source_type = 'Namespaces::ProjectNamespace'", :unique=>true, :name=>"tmp_index_routes_on_path_where_project_namespace", :algorithm=>:concurrently})
-> 0.0030s
-- execute("SET statement_timeout TO 0")
-> 0.0004s
-- add_index(:routes, :path, {:where=>"source_type = 'Namespaces::ProjectNamespace'", :unique=>true, :name=>"tmp_index_routes_on_path_where_project_namespace", :algorithm=>:concurrently})
-> 0.0216s
-- execute("RESET statement_timeout")
-> 0.0005s
-- transaction_open?()
-> 0.0000s
-- index_exists?(:routes, :path, {:where=>"source_type != 'Namespaces::ProjectNamespace'", :unique=>true, :name=>"tmp_index_routes_on_path_where_not_project_namespace", :algorithm=>:concurrently})
-> 0.0022s
-- add_index(:routes, :path, {:where=>"source_type != 'Namespaces::ProjectNamespace'", :unique=>true, :name=>"tmp_index_routes_on_path_where_not_project_namespace", :algorithm=>:concurrently})
-> 1.2125s
== 20211208081833 ExcludeProjectNamespaceFromRoutePathUniqueIndex: migrated (1.2430s)
$ rake db:rollback
== 20211208081833 ExcludeProjectNamespaceFromRoutePathUniqueIndex: reverting ==
-- transaction_open?()
-> 0.0000s
-- index_exists?(:routes, :path, {:name=>"tmp_index_routes_on_path_where_project_namespace", :algorithm=>:concurrently})
-> 0.0036s
-- execute("SET statement_timeout TO 0")
-> 0.0011s
-- remove_index(:routes, {:name=>"tmp_index_routes_on_path_where_project_namespace", :algorithm=>:concurrently, :column=>:path})
-> 0.0207s
-- execute("RESET statement_timeout")
-> 0.0004s
-- transaction_open?()
-> 0.0000s
-- index_exists?(:routes, :path, {:name=>"tmp_index_routes_on_path_where_not_project_namespace", :algorithm=>:concurrently})
-> 0.0021s
-- remove_index(:routes, {:name=>"tmp_index_routes_on_path_where_not_project_namespace", :algorithm=>:concurrently, :column=>:path})
-> 0.0077s
== 20211208081833 ExcludeProjectNamespaceFromRoutePathUniqueIndex: reverted (0.0396s)
Estimated creation time for "other than project namespace" routes is ~5 minutes:
exec CREATE UNIQUE INDEX CONCURRENTLY "tmp_index_routes_on_path_where_not_project_namespace" ON "routes" ("path") WHERE source_type != 'Namespaces::ProjectNamespace'
Session: webui-i7534
The query has been executed. Duration: 5.759 min
Related to #346448 (closed)
Screenshots or screen recordings
These are strongly recommended to assist reviewers and reduce the time to merge your change.
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.
-
I have evaluated the MR acceptance checklist for this MR.