Skip to content

Cleanup temp indexes from reindexing

Andreas Brandl requested to merge ab/reindexing-cleanup into master

What does this MR do?

With this change, we cleanup any "leftover" indexes from previous reindexing attempts (if any - it'll be a rare event).

During reindexing (REINDEX CONCURRENTLY), postgres creates a $index_ccnew or $index_ccnew1... index. This is meant to be temporary and upon successful creation, the index is being swapped out with the original one (and the original index is dropped). However, if the reindexing run gets aborted (cancelling REINDEX CONCURRENTLY for whatever reason), the _ccnew[0-9]*$ index sticks around. This is what we call a "leftover" index here. Upon the next reindexing run, we scan for these indexes and drop those if any.

We already introduced a rule/spec to make sure we don't have any indexes added that also match the ccnew[0-9]*$ pattern: https://gitlab.com/gitlab-org/gitlab/blob/master/spec/db/schema_spec.rb#L269

Here's how a local reindexing invocation looks like including queries. In this case, we have two leftover indexes lingering around:

abrandl:gitlab/ (ab/reindexing-cleanup✗) $ LOG_QUERIES_TO_CONSOLE=true spring rake gitlab:db:reindex                                                                                                                                                
...
D, [2021-07-14T13:51:57.607719 #1372784] DEBUG -- :   Gitlab::Database::PostgresIndex Load (6.5ms)  SELECT "postgres_indexes".* FROM "postgres_indexes" WHERE (name ~* '\_ccnew[0-9]*$') /*application:web,line:/lib/gitlab/database/reindexing.rb:26:in `cleanup_leftovers!'*/
D, [2021-07-14T13:51:57.608104 #1372784] DEBUG -- :   ↳ lib/gitlab/database/reindexing.rb:26:in `cleanup_leftovers!'
I, [2021-07-14T13:51:57.617376 #1372784]  INFO -- : Removing index public.foobar_ccnew which is a leftover, temporary index from previous reindexing activity
D, [2021-07-14T13:51:57.618798 #1372784] DEBUG -- :    (0.2ms)  SET lock_timeout TO '60000ms' /*application:web,line:/lib/gitlab/database/with_lock_retries.rb:168:in `execute'*/
D, [2021-07-14T13:51:57.619107 #1372784] DEBUG -- :   ↳ lib/gitlab/database/with_lock_retries.rb:168:in `execute'
D, [2021-07-14T13:51:57.624411 #1372784] DEBUG -- :    (4.7ms)  DROP INDEX CONCURRENTLY IF EXISTS "public"."foobar_ccnew" /*application:web,line:/lib/gitlab/database/reindexing.rb:37:in `block (3 levels) in cleanup_leftovers!'*/
D, [2021-07-14T13:51:57.624599 #1372784] DEBUG -- :   ↳ lib/gitlab/database/reindexing.rb:37:in `block (3 levels) in cleanup_leftovers!'
D, [2021-07-14T13:51:57.625226 #1372784] DEBUG -- :    (0.1ms)  RESET idle_in_transaction_session_timeout; RESET lock_timeout /*application:web,line:/lib/gitlab/database/with_lock_retries.rb:168:in `execute'*/
D, [2021-07-14T13:51:57.625398 #1372784] DEBUG -- :   ↳ lib/gitlab/database/with_lock_retries.rb:168:in `execute'
I, [2021-07-14T13:51:57.625464 #1372784]  INFO -- : Removing index public.foobar_ccnew1 which is a leftover, temporary index from previous reindexing activity
D, [2021-07-14T13:51:57.625676 #1372784] DEBUG -- :    (0.1ms)  SET lock_timeout TO '60000ms' /*application:web,line:/lib/gitlab/database/with_lock_retries.rb:168:in `execute'*/
D, [2021-07-14T13:51:57.625847 #1372784] DEBUG -- :   ↳ lib/gitlab/database/with_lock_retries.rb:168:in `execute'
D, [2021-07-14T13:51:57.629337 #1372784] DEBUG -- :    (3.0ms)  DROP INDEX CONCURRENTLY IF EXISTS "public"."foobar_ccnew1" /*application:web,line:/lib/gitlab/database/reindexing.rb:37:in `block (3 levels) in cleanup_leftovers!'*/
D, [2021-07-14T13:51:57.629915 #1372784] DEBUG -- :   ↳ lib/gitlab/database/reindexing.rb:37:in `block (3 levels) in cleanup_leftovers!'
D, [2021-07-14T13:51:57.631936 #1372784] DEBUG -- :    (0.3ms)  RESET idle_in_transaction_session_timeout; RESET lock_timeout /*application:web,line:/lib/gitlab/database/with_lock_retries.rb:168:in `execute'*/
D, [2021-07-14T13:51:57.632483 #1372784] DEBUG -- :   ↳ lib/gitlab/database/with_lock_retries.rb:168:in `execute'
D, [2021-07-14T13:51:57.733552 #1372784] DEBUG -- :   Gitlab::Database::PostgresIndex Load (91.1ms)  SELECT "postgres_indexes".* FROM "postgres_indexes" WHERE "postgres_indexes"."partitioned" = FALSE AND "postgres_indexes"."exclusion" = FALSE AND "postgres_indexes"."expression" = FALSE AND "postgres_indexes"."type" IN ('btree', 'gist') AND (name !~ '\_ccnew[0-9]*$') AND (NOT EXISTS (SELECT "postgres_reindex_actions".* FROM "postgres_reindex_actions" WHERE "postgres_reindex_actions"."state" = 1 AND (action_end > '2021-07-04 11:51:57.641293') AND (index_identifier = identifier))) AND "postgres_indexes"."ondisk_size_bytes" BETWEEN 1073741824 AND 107374182400 /*application:web,line:/lib/gitlab/database/reindexing/index_selection.rb:36:in `sort_by'*/
D, [2021-07-14T13:51:57.733895 #1372784] DEBUG -- :   ↳ lib/gitlab/database/reindexing/index_selection.rb:36:in `sort_by'

Does this MR meet the acceptance criteria?

Conformity

Edited by Andreas Brandl

Merge request reports