Class: Gitlab::Database::Partitioning::List::ConvertTable

Inherits:
Object
  • Object
show all
Defined in:
lib/gitlab/database/partitioning/list/convert_table.rb

Constant Summary collapse

UnableToPartition =
Class.new(StandardError)
SQL_STATEMENT_SEPARATOR =
";\n\n"
PARTITIONING_CONSTRAINT_NAME =
'partitioning_constraint'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(migration_context:, table_name:, parent_table_name:, partitioning_column:, zero_partition_value:) ⇒ ConvertTable

Returns a new instance of ConvertTable.



16
17
18
19
20
21
22
23
24
25
26
# File 'lib/gitlab/database/partitioning/list/convert_table.rb', line 16

def initialize(
  migration_context:, table_name:, parent_table_name:, partitioning_column:,
  zero_partition_value:)

  @migration_context = migration_context
  @connection = migration_context.connection
  @table_name = table_name
  @parent_table_name = parent_table_name
  @partitioning_column = partitioning_column
  @zero_partition_value = zero_partition_value
end

Instance Attribute Details

#parent_table_nameObject (readonly)

Returns the value of attribute parent_table_name.



14
15
16
# File 'lib/gitlab/database/partitioning/list/convert_table.rb', line 14

def parent_table_name
  @parent_table_name
end

#partitioning_columnObject (readonly)

Returns the value of attribute partitioning_column.



14
15
16
# File 'lib/gitlab/database/partitioning/list/convert_table.rb', line 14

def partitioning_column
  @partitioning_column
end

#table_nameObject (readonly)

Returns the value of attribute table_name.



14
15
16
# File 'lib/gitlab/database/partitioning/list/convert_table.rb', line 14

def table_name
  @table_name
end

#zero_partition_valueObject (readonly)

Returns the value of attribute zero_partition_value.



14
15
16
# File 'lib/gitlab/database/partitioning/list/convert_table.rb', line 14

def zero_partition_value
  @zero_partition_value
end

Instance Method Details

#partitionObject



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/gitlab/database/partitioning/list/convert_table.rb', line 38

def partition
  # If already partitioned, the table is no longer partitionable. Thus we skip checks leading up
  # to partitioning if the partitioning transaction has already succeeded.
  unless already_partitioned?
    assert_existing_constraints_partitionable
    assert_partitioning_constraint_present

    create_parent_table

    migration_context.with_lock_retries do
      redefine_loose_foreign_key_triggers do
        migration_context.execute(sql_to_convert_table)
      end
    end
  end

  # Attaching foreign keys handles cases where one or more foreign keys already exists, so it doesn't
  # need a check similar to the rest of this method
  attach_foreign_keys_to_parent
end

#prepare_for_partitioning(async: false) ⇒ Object



28
29
30
31
32
# File 'lib/gitlab/database/partitioning/list/convert_table.rb', line 28

def prepare_for_partitioning(async: false)
  assert_existing_constraints_partitionable

  add_partitioning_check_constraint(async: async)
end

#revert_partitioningObject



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/partitioning/list/convert_table.rb', line 59

def revert_partitioning
  migration_context.with_lock_retries(raise_on_exhaustion: true) do
    migration_context.execute(<<~SQL)
    ALTER TABLE #{connection.quote_table_name(parent_table_name)}
    DETACH PARTITION #{connection.quote_table_name(table_name)};
    SQL

    alter_sequences_sql = alter_sequence_statements(old_table: parent_table_name, new_table: table_name)
                            .join(SQL_STATEMENT_SEPARATOR)

    migration_context.execute(alter_sequences_sql)

    # This takes locks for all the foreign keys that the parent table had.
    # However, those same locks were taken while detaching the partition, and we can't avoid that.
    # If we dropped the foreign key before detaching the partition to avoid this locking,
    # the drop would cascade to the child partitions and drop their foreign keys as well
    migration_context.drop_table(parent_table_name)
  end

  add_partitioning_check_constraint
end

#revert_preparation_for_partitioningObject



34
35
36
# File 'lib/gitlab/database/partitioning/list/convert_table.rb', line 34

def revert_preparation_for_partitioning
  migration_context.remove_check_constraint(table_name, partitioning_constraint.name)
end