Class: Gitlab::Database::Partitioning::SlidingListStrategy
- Inherits:
-
Object
- Object
- Gitlab::Database::Partitioning::SlidingListStrategy
- Defined in:
- lib/gitlab/database/partitioning/sliding_list_strategy.rb
Direct Known Subclasses
Instance Attribute Summary collapse
-
#analyze_interval ⇒ Object
readonly
Returns the value of attribute analyze_interval.
-
#detach_partition_if ⇒ Object
readonly
Returns the value of attribute detach_partition_if.
-
#model ⇒ Object
readonly
Returns the value of attribute model.
-
#next_partition_if ⇒ Object
readonly
Returns the value of attribute next_partition_if.
-
#partitioning_key ⇒ Object
readonly
Returns the value of attribute partitioning_key.
Instance Method Summary collapse
- #active_partition ⇒ Object
- #after_adding_partitions ⇒ Object
- #current_partitions ⇒ Object
- #extra_partitions ⇒ Object
- #initial_partition ⇒ Object
-
#initialize(model, partitioning_key, next_partition_if:, detach_partition_if:, analyze_interval: nil) ⇒ SlidingListStrategy
constructor
A new instance of SlidingListStrategy.
- #missing_partitions ⇒ Object
- #next_partition ⇒ Object
- #no_partitions_exist? ⇒ Boolean
- #validate_and_fix ⇒ Object
Constructor Details
#initialize(model, partitioning_key, next_partition_if:, detach_partition_if:, analyze_interval: nil) ⇒ SlidingListStrategy
Returns a new instance of SlidingListStrategy.
11 12 13 14 15 16 17 18 19 |
# File 'lib/gitlab/database/partitioning/sliding_list_strategy.rb', line 11 def initialize(model, partitioning_key, next_partition_if:, detach_partition_if:, analyze_interval: nil) @model = model @partitioning_key = partitioning_key @next_partition_if = next_partition_if @detach_partition_if = detach_partition_if @analyze_interval = analyze_interval ensure_partitioning_column_ignored_or_readonly! end |
Instance Attribute Details
#analyze_interval ⇒ Object (readonly)
Returns the value of attribute analyze_interval.
7 8 9 |
# File 'lib/gitlab/database/partitioning/sliding_list_strategy.rb', line 7 def analyze_interval @analyze_interval end |
#detach_partition_if ⇒ Object (readonly)
Returns the value of attribute detach_partition_if.
7 8 9 |
# File 'lib/gitlab/database/partitioning/sliding_list_strategy.rb', line 7 def detach_partition_if @detach_partition_if end |
#model ⇒ Object (readonly)
Returns the value of attribute model.
7 8 9 |
# File 'lib/gitlab/database/partitioning/sliding_list_strategy.rb', line 7 def model @model end |
#next_partition_if ⇒ Object (readonly)
Returns the value of attribute next_partition_if.
7 8 9 |
# File 'lib/gitlab/database/partitioning/sliding_list_strategy.rb', line 7 def next_partition_if @next_partition_if end |
#partitioning_key ⇒ Object (readonly)
Returns the value of attribute partitioning_key.
7 8 9 |
# File 'lib/gitlab/database/partitioning/sliding_list_strategy.rb', line 7 def partitioning_key @partitioning_key end |
Instance Method Details
#active_partition ⇒ Object
70 71 72 73 74 |
# File 'lib/gitlab/database/partitioning/sliding_list_strategy.rb', line 70 def active_partition # The current partitions list is sorted, so the last partition has the highest value # This is the only partition that receives inserts. current_partitions.last end |
#after_adding_partitions ⇒ Object
65 66 67 68 |
# File 'lib/gitlab/database/partitioning/sliding_list_strategy.rb', line 65 def after_adding_partitions active_value = active_partition.value model.connection.change_column_default(model.table_name, partitioning_key, active_value) end |
#current_partitions ⇒ Object
21 22 23 24 25 |
# File 'lib/gitlab/database/partitioning/sliding_list_strategy.rb', line 21 def current_partitions Gitlab::Database::PostgresPartition.for_parent_table(table_name).map do |partition| SingleNumericListPartition.from_sql(table_name, partition.name, partition.condition) end.sort end |
#extra_partitions ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/gitlab/database/partitioning/sliding_list_strategy.rb', line 45 def extra_partitions possibly_extra = current_partitions[0...-1] # Never consider the most recent partition extra = possibly_extra.take_while { |p| detach_partition_if.call(p) } default_value = current_default_value if extra.any? { |p| p.value == default_value } Gitlab::AppLogger.error( message: "Inconsistent partition detected: partition with value #{current_default_value} should " \ "not be deleted because it's used as the default value.", partition_number: current_default_value, table_name: model.table_name ) extra = extra.reject { |p| p.value == default_value } end extra end |
#initial_partition ⇒ Object
37 38 39 |
# File 'lib/gitlab/database/partitioning/sliding_list_strategy.rb', line 37 def initial_partition SingleNumericListPartition.new(table_name, 1) end |
#missing_partitions ⇒ Object
27 28 29 30 31 32 33 34 35 |
# File 'lib/gitlab/database/partitioning/sliding_list_strategy.rb', line 27 def missing_partitions if no_partitions_exist? [initial_partition] elsif next_partition_if.call(active_partition) [next_partition] else [] end end |
#next_partition ⇒ Object
41 42 43 |
# File 'lib/gitlab/database/partitioning/sliding_list_strategy.rb', line 41 def next_partition SingleNumericListPartition.new(table_name, active_partition.value + 1) end |
#no_partitions_exist? ⇒ Boolean
76 77 78 |
# File 'lib/gitlab/database/partitioning/sliding_list_strategy.rb', line 76 def no_partitions_exist? current_partitions.empty? end |
#validate_and_fix ⇒ Object
80 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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/gitlab/database/partitioning/sliding_list_strategy.rb', line 80 def validate_and_fix unless model.connection_db_config.name == Gitlab::Database.db_config_name(Gitlab::Database::SharedModel.connection) Gitlab::AppLogger.warn( message: 'Skipping fixing column default because connections mismatch', event: :partition_manager_validate_and_fix_connection_mismatch, model_connection_name: Gitlab::Database.db_config_name(model.connection), shared_connection_name: Gitlab::Database.db_config_name(Gitlab::Database::SharedModel.connection) ) return end return if no_partitions_exist? old_default_value = current_default_value expected_default_value = active_partition.value if old_default_value != expected_default_value with_lock_retries do model.connection.execute("LOCK TABLE #{model.table_name} IN ACCESS EXCLUSIVE MODE") old_default_value = current_default_value expected_default_value = active_partition.value if old_default_value == expected_default_value Gitlab::AppLogger.warn( message: "Table partitions or partition key default value have been changed by another process", table_name: table_name, default_value: expected_default_value ) raise ActiveRecord::Rollback end model.connection.change_column_default(model.table_name, partitioning_key, expected_default_value) Gitlab::AppLogger.warn( message: "Fixed default value of sliding_list_strategy partitioning_key", column: partitioning_key, table_name: table_name, connection_name: model.connection.pool.db_config.name, old_value: old_default_value, new_value: expected_default_value ) end end end |