Class: Gitlab::Database::Partitioning::Time::MonthlyStrategy

Inherits:
BaseStrategy show all
Defined in:
lib/gitlab/database/partitioning/time/monthly_strategy.rb

Constant Summary collapse

HEADROOM =
6.months
PARTITION_SUFFIX =
'%Y%m'

Instance Attribute Summary

Attributes inherited from BaseStrategy

#analyze_interval, #model, #partitioning_key, #retain_for, #retain_non_empty_partitions

Instance Method Summary collapse

Methods inherited from BaseStrategy

#after_adding_partitions, #initialize, #validate_and_fix

Constructor Details

This class inherits a constructor from Gitlab::Database::Partitioning::Time::BaseStrategy

Instance Method Details

#current_partitionsObject



11
12
13
14
15
16
17
# File 'lib/gitlab/database/partitioning/time/monthly_strategy.rb', line 11

def current_partitions
  ensure_connection_set

  Gitlab::Database::PostgresPartition.for_parent_table(table_name).map do |partition|
    TimePartition.from_sql(table_name, partition.name, partition.condition)
  end
end

#desired_partitionsObject



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/gitlab/database/partitioning/time/monthly_strategy.rb', line 35

def desired_partitions
  ensure_connection_set

  [].tap do |parts|
    min_date, max_date = relevant_range

    if pruning_old_partitions? && min_date <= oldest_active_date
      min_date = oldest_active_date.beginning_of_month
    else
      parts << partition_for(upper_bound: min_date)
    end

    while min_date < max_date
      next_date = min_date.next_month

      parts << partition_for(lower_bound: min_date, upper_bound: next_date)

      min_date = next_date
    end
  end
end

#extra_partitionsObject



26
27
28
29
30
31
32
33
# File 'lib/gitlab/database/partitioning/time/monthly_strategy.rb', line 26

def extra_partitions
  ensure_connection_set

  partitions = current_partitions - desired_partitions
  partitions.reject!(&:holds_data?) if retain_non_empty_partitions

  partitions
end

#missing_partitionsObject

Check the currently existing partitions and determine which ones are missing



20
21
22
23
24
# File 'lib/gitlab/database/partitioning/time/monthly_strategy.rb', line 20

def missing_partitions
  ensure_connection_set

  desired_partitions - current_partitions
end

#oldest_active_dateObject

no explicit connection needed since no queries are executed (pure date math on static value)



87
88
89
# File 'lib/gitlab/database/partitioning/time/monthly_strategy.rb', line 87

def oldest_active_date
  retain_for.ago.beginning_of_month.to_date
end

#partition_name(lower_bound) ⇒ Object

no explicit connection needed since no queries are executed (pure string formatting on static value)



92
93
94
95
96
# File 'lib/gitlab/database/partitioning/time/monthly_strategy.rb', line 92

def partition_name(lower_bound)
  suffix = lower_bound&.strftime(PARTITION_SUFFIX) || '000000'

  "#{table_name}_#{suffix}"
end

#relevant_rangeObject

This determines the relevant time range for which we expect to have data (and therefore need to create partitions for).

Note: We typically expect the first partition to be half-unbounded, i.e.

to start from MINVALUE to a specific date `x`. The range returned
does not include the range of the first, half-unbounded partition.


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/gitlab/database/partitioning/time/monthly_strategy.rb', line 63

def relevant_range
  ensure_connection_set

  first_partition = current_partitions.min

  if first_partition
    # Case 1: First partition starts with MINVALUE, i.e. from is nil -> start with first real partition
    # Case 2: Rather unexpectedly, first partition does not start with MINVALUE, i.e. from is not nil
    #         In this case, use first partition beginning as a start
    min_date = first_partition.from || first_partition.to
  end

  min_date ||= oldest_active_date if pruning_old_partitions?

  # In case we don't have a partition yet
  min_date ||= Date.current
  min_date = min_date.beginning_of_month

  max_date = Date.current.end_of_month + HEADROOM

  [min_date, max_date]
end