Commit ef4d7992 authored by Andreas Brandl's avatar Andreas Brandl

Only reindex btree and gist indexes

This basically excludes GIN indexes from automatic reindexing. Reason is
that those indexes are slow to build (in particular trigram indexes) and
this would cause problems on GitLab.com.

Relates to https://gitlab.com/gitlab-org/gitlab/-/issues/335211

Changelog: other
parent 71bea374
# frozen_string_literal: true
class AddIndexTypeToPostgresIndexesView < ActiveRecord::Migration[6.1]
def up
execute(<<~SQL)
DROP VIEW IF EXISTS postgres_indexes;
CREATE VIEW postgres_indexes AS
SELECT (pg_namespace.nspname::text || '.'::text) || i.relname::text AS identifier,
pg_index.indexrelid,
pg_namespace.nspname AS schema,
i.relname AS name,
pg_indexes.tablename,
a.amname AS type,
pg_index.indisunique AS "unique",
pg_index.indisvalid AS valid_index,
i.relispartition AS partitioned,
pg_index.indisexclusion AS exclusion,
pg_index.indexprs IS NOT NULL AS expression,
pg_index.indpred IS NOT NULL AS partial,
pg_indexes.indexdef AS definition,
pg_relation_size(i.oid::regclass) AS ondisk_size_bytes
FROM pg_index
JOIN pg_class i ON i.oid = pg_index.indexrelid
JOIN pg_namespace ON i.relnamespace = pg_namespace.oid
JOIN pg_indexes ON i.relname = pg_indexes.indexname
LEFT JOIN pg_class t ON t.oid = pg_index.indrelid
LEFT JOIN pg_am a ON i.relam = a.oid
WHERE pg_namespace.nspname <> 'pg_catalog'::name AND (pg_namespace.nspname = ANY (ARRAY["current_schema"(), 'gitlab_partitions_dynamic'::name, 'gitlab_partitions_static'::name]));
SQL
end
def down
execute(<<~SQL)
DROP VIEW IF EXISTS postgres_indexes;
CREATE VIEW postgres_indexes AS
SELECT (((pg_namespace.nspname)::text || '.'::text) || (pg_class.relname)::text) AS identifier,
pg_index.indexrelid,
pg_namespace.nspname AS schema,
pg_class.relname AS name,
pg_indexes.tablename,
pg_index.indisunique AS "unique",
pg_index.indisvalid AS valid_index,
pg_class.relispartition AS partitioned,
pg_index.indisexclusion AS exclusion,
(pg_index.indexprs IS NOT NULL) AS expression,
(pg_index.indpred IS NOT NULL) AS partial,
pg_indexes.indexdef AS definition,
pg_relation_size((pg_class.oid)::regclass) AS ondisk_size_bytes
FROM (((pg_index
JOIN pg_class ON ((pg_class.oid = pg_index.indexrelid)))
JOIN pg_namespace ON ((pg_class.relnamespace = pg_namespace.oid)))
JOIN pg_indexes ON ((pg_class.relname = pg_indexes.indexname)))
WHERE ((pg_namespace.nspname <> 'pg_catalog'::name) AND (pg_namespace.nspname = ANY (ARRAY["current_schema"(), 'gitlab_partitions_dynamic'::name, 'gitlab_partitions_static'::name])));
SQL
end
end
45ec2dd6113d112050a1ac062064950fa18b3b5903a9fd60234e9e9fa48c7070
\ No newline at end of file
...@@ -16583,23 +16583,26 @@ END AS attrelname ...@@ -16583,23 +16583,26 @@ END AS attrelname
ORDER BY relation_stats.nspname, relation_stats.tblname, relation_stats.idxname; ORDER BY relation_stats.nspname, relation_stats.tblname, relation_stats.idxname;
CREATE VIEW postgres_indexes AS CREATE VIEW postgres_indexes AS
SELECT (((pg_namespace.nspname)::text || '.'::text) || (pg_class.relname)::text) AS identifier, SELECT (((pg_namespace.nspname)::text || '.'::text) || (i.relname)::text) AS identifier,
pg_index.indexrelid, pg_index.indexrelid,
pg_namespace.nspname AS schema, pg_namespace.nspname AS schema,
pg_class.relname AS name, i.relname AS name,
pg_indexes.tablename, pg_indexes.tablename,
a.amname AS type,
pg_index.indisunique AS "unique", pg_index.indisunique AS "unique",
pg_index.indisvalid AS valid_index, pg_index.indisvalid AS valid_index,
pg_class.relispartition AS partitioned, i.relispartition AS partitioned,
pg_index.indisexclusion AS exclusion, pg_index.indisexclusion AS exclusion,
(pg_index.indexprs IS NOT NULL) AS expression, (pg_index.indexprs IS NOT NULL) AS expression,
(pg_index.indpred IS NOT NULL) AS partial, (pg_index.indpred IS NOT NULL) AS partial,
pg_indexes.indexdef AS definition, pg_indexes.indexdef AS definition,
pg_relation_size((pg_class.oid)::regclass) AS ondisk_size_bytes pg_relation_size((i.oid)::regclass) AS ondisk_size_bytes
FROM (((pg_index FROM (((((pg_index
JOIN pg_class ON ((pg_class.oid = pg_index.indexrelid))) JOIN pg_class i ON ((i.oid = pg_index.indexrelid)))
JOIN pg_namespace ON ((pg_class.relnamespace = pg_namespace.oid))) JOIN pg_namespace ON ((i.relnamespace = pg_namespace.oid)))
JOIN pg_indexes ON ((pg_class.relname = pg_indexes.indexname))) JOIN pg_indexes ON ((i.relname = pg_indexes.indexname)))
LEFT JOIN pg_class t ON ((t.oid = pg_index.indrelid)))
LEFT JOIN pg_am a ON ((i.relam = a.oid)))
WHERE ((pg_namespace.nspname <> 'pg_catalog'::name) AND (pg_namespace.nspname = ANY (ARRAY["current_schema"(), 'gitlab_partitions_dynamic'::name, 'gitlab_partitions_static'::name]))); WHERE ((pg_namespace.nspname <> 'pg_catalog'::name) AND (pg_namespace.nspname = ANY (ARRAY["current_schema"(), 'gitlab_partitions_dynamic'::name, 'gitlab_partitions_static'::name])));
CREATE VIEW postgres_partitioned_tables AS CREATE VIEW postgres_partitioned_tables AS
...@@ -7,6 +7,7 @@ module Gitlab ...@@ -7,6 +7,7 @@ module Gitlab
self.table_name = 'postgres_indexes' self.table_name = 'postgres_indexes'
self.primary_key = 'identifier' self.primary_key = 'identifier'
self.inheritance_column = :_type_disabled
has_one :bloat_estimate, class_name: 'Gitlab::Database::PostgresIndexBloatEstimate', foreign_key: :identifier has_one :bloat_estimate, class_name: 'Gitlab::Database::PostgresIndexBloatEstimate', foreign_key: :identifier
has_many :reindexing_actions, class_name: 'Gitlab::Database::Reindexing::ReindexAction', foreign_key: :index_identifier has_many :reindexing_actions, class_name: 'Gitlab::Database::Reindexing::ReindexAction', foreign_key: :index_identifier
...@@ -22,10 +23,10 @@ module Gitlab ...@@ -22,10 +23,10 @@ module Gitlab
# is defined on a table that is not partitioned. # is defined on a table that is not partitioned.
# #
# Deprecated: Switch to scope .reindexing_support # Deprecated: Switch to scope .reindexing_support
scope :regular, -> { where(unique: false, partitioned: false, exclusion: false, expression: false)} scope :regular, -> { where(unique: false, partitioned: false, exclusion: false, expression: false, type: Gitlab::Database::Reindexing::SUPPORTED_TYPES)}
# Indexes for reindexing with PG12 # Indexes for reindexing with PG12
scope :reindexing_support, -> { where(partitioned: false, exclusion: false, expression: false) } scope :reindexing_support, -> { where(partitioned: false, exclusion: false, expression: false, type: Gitlab::Database::Reindexing::SUPPORTED_TYPES) }
scope :not_match, ->(regex) { where("name !~ ?", regex)} scope :not_match, ->(regex) { where("name !~ ?", regex)}
......
...@@ -6,6 +6,8 @@ module Gitlab ...@@ -6,6 +6,8 @@ module Gitlab
# Number of indexes to reindex per invocation # Number of indexes to reindex per invocation
DEFAULT_INDEXES_PER_INVOCATION = 2 DEFAULT_INDEXES_PER_INVOCATION = 2
SUPPORTED_TYPES = %w(btree gist).freeze
# candidate_indexes: Array of Gitlab::Database::PostgresIndex # candidate_indexes: Array of Gitlab::Database::PostgresIndex
def self.perform(candidate_indexes, how_many: DEFAULT_INDEXES_PER_INVOCATION) def self.perform(candidate_indexes, how_many: DEFAULT_INDEXES_PER_INVOCATION)
IndexSelection.new(candidate_indexes).take(how_many).each do |index| IndexSelection.new(candidate_indexes).take(how_many).each do |index|
......
...@@ -38,6 +38,12 @@ RSpec.describe Gitlab::Database::PostgresIndex do ...@@ -38,6 +38,12 @@ RSpec.describe Gitlab::Database::PostgresIndex do
it 'only non-expression indexes' do it 'only non-expression indexes' do
expect(described_class.regular).to all(have_attributes(expression: false)) expect(described_class.regular).to all(have_attributes(expression: false))
end end
it 'only btree and gist indexes' do
types = described_class.regular.map(&:type).uniq
expect(types & %w(btree gist)).to eq(types)
end
end end
describe '.reindexing_support' do describe '.reindexing_support' do
...@@ -52,6 +58,12 @@ RSpec.describe Gitlab::Database::PostgresIndex do ...@@ -52,6 +58,12 @@ RSpec.describe Gitlab::Database::PostgresIndex do
it 'only non-expression indexes' do it 'only non-expression indexes' do
expect(described_class.reindexing_support).to all(have_attributes(expression: false)) expect(described_class.reindexing_support).to all(have_attributes(expression: false))
end end
it 'only btree and gist indexes' do
types = described_class.reindexing_support.map(&:type).uniq
expect(types & %w(btree gist)).to eq(types)
end
end end
describe '.not_match' do describe '.not_match' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment