Module: Gitlab::Database::AsyncIndexes::MigrationHelpers
- Included in:
- MigrationHelpers
- Defined in:
- lib/gitlab/database/async_indexes/migration_helpers.rb
Instance Method Summary collapse
- #async_index_creation_available? ⇒ Boolean
-
#prepare_async_index(table_name, column_name, **options) ⇒ Object
Prepares an index for asynchronous creation.
- #prepare_async_index_from_sql(definition) ⇒ Object
-
#prepare_async_index_removal(table_name, column_name, options = {}) ⇒ Object
Prepares an index for asynchronous destruction.
- #unprepare_async_index(table_name, column_name, **options) ⇒ Object
- #unprepare_async_index_by_name(table_name, index_name, **options) ⇒ Object
Instance Method Details
#async_index_creation_available? ⇒ Boolean
142 143 144 |
# File 'lib/gitlab/database/async_indexes/migration_helpers.rb', line 142 def async_index_creation_available? table_exists?(:postgres_async_indexes) end |
#prepare_async_index(table_name, column_name, **options) ⇒ Object
Prepares an index for asynchronous creation.
Stores the index information in the postgres_async_indexes table to be created later. The index will be always be created CONCURRENTLY, so that option does not need to be given. If an existing asynchronous definition exists with the same name, the existing entry will be updated with the new definition.
If the requested index has already been created, it is not stored in the table for asynchronous creation.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/gitlab/database/async_indexes/migration_helpers.rb', line 38 def prepare_async_index(table_name, column_name, **) Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas.require_ddl_mode! return unless async_index_creation_available? raise "Table #{table_name} does not exist" unless table_exists?(table_name) index_name = [:name] || index_name(table_name, column_name) raise 'Specifying index name is mandatory - specify name: argument' unless index_name = .merge({ algorithm: :concurrently }) if index_exists?(table_name, column_name, **) Gitlab::AppLogger.warn( message: 'Index not prepared because it already exists', table_name: table_name, index_name: index_name) return end index, algorithm, if_not_exists = (table_name, column_name, **) create_index = ActiveRecord::ConnectionAdapters::CreateIndexDefinition.new(index, algorithm, if_not_exists) schema_creation = ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaCreation.new(ApplicationRecord.connection) definition = schema_creation.accept(create_index) async_index = PostgresAsyncIndex.find_or_create_by!(name: index_name) do |rec| rec.table_name = table_name rec.definition = definition end async_index.definition = definition async_index.save! # No-op if definition is not changed Gitlab::AppLogger.info( message: 'Prepared index for async creation', table_name: async_index.table_name, index_name: async_index.name) async_index end |
#prepare_async_index_from_sql(definition) ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/gitlab/database/async_indexes/migration_helpers.rb', line 81 def prepare_async_index_from_sql(definition) Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas.require_ddl_mode! return unless async_index_creation_available? table_name, index_name = extract_table_and_index_names_from_concurrent_index!(definition) if index_name_exists?(table_name, index_name) Gitlab::AppLogger.warn( message: 'Index not prepared because it already exists', table_name: table_name, index_name: index_name) return end async_index = Gitlab::Database::AsyncIndexes::PostgresAsyncIndex.find_or_create_by!(name: index_name) do |rec| rec.table_name = table_name rec.definition = definition.to_s.strip end Gitlab::AppLogger.info( message: 'Prepared index for async creation', table_name: async_index.table_name, index_name: async_index.name) async_index end |
#prepare_async_index_removal(table_name, column_name, options = {}) ⇒ Object
Prepares an index for asynchronous destruction.
Stores the index information in the postgres_async_indexes table to be removed later. The index will be always be removed CONCURRENTLY, so that option does not need to be given.
If the requested index has already been removed, it is not stored in the table for asynchronous destruction.
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/gitlab/database/async_indexes/migration_helpers.rb', line 117 def prepare_async_index_removal(table_name, column_name, = {}) index_name = .fetch(:name) raise 'prepare_async_index_removal must get an index name defined' if index_name.blank? unless index_exists?(table_name, column_name, **) Gitlab::AppLogger.warn "Index not removed because it does not exist (this may be due to an aborted migration or similar): table_name: #{table_name}, index_name: #{index_name}" return end definition = "DROP INDEX CONCURRENTLY #{quote_column_name(index_name)}" async_index = PostgresAsyncIndex.find_or_create_by!(name: index_name) do |rec| rec.table_name = table_name rec.definition = definition end Gitlab::AppLogger.info( message: 'Prepared index for async destruction', table_name: async_index.table_name, index_name: async_index.name ) async_index end |
#unprepare_async_index(table_name, column_name, **options) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 |
# File 'lib/gitlab/database/async_indexes/migration_helpers.rb', line 7 def unprepare_async_index(table_name, column_name, **) Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas.require_ddl_mode! return unless async_index_creation_available? index_name = [:name] || index_name(table_name, column_name) raise 'Specifying index name is mandatory - specify name: argument' unless index_name unprepare_async_index_by_name(table_name, index_name) end |
#unprepare_async_index_by_name(table_name, index_name, **options) ⇒ Object
19 20 21 22 23 24 25 26 27 |
# File 'lib/gitlab/database/async_indexes/migration_helpers.rb', line 19 def unprepare_async_index_by_name(table_name, index_name, **) Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas.require_ddl_mode! return unless async_index_creation_available? PostgresAsyncIndex.find_by(name: index_name).try do |async_index| async_index.destroy! end end |