manageiq-postgres_ha_admin 3.1.4 → 3.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 302246b3dedf536233f20df1c381932adbbe7c85366e400dd3678eda57f8ebf4
4
- data.tar.gz: cfc4aee15059200a0dddd56dea7a6f4563b89b24742682dd1c10b66e26bd9ac5
3
+ metadata.gz: 7c6e01b8391b55a231ec81a0e050a97b2ccd02cc1fb576dc9272021f2130e593
4
+ data.tar.gz: d0b27f3b48ab6e843175d740e98bc6758d3facb9815c97dfa1de3147072f2fe2
5
5
  SHA512:
6
- metadata.gz: 3169f9907e9b75c426dfea5908945921e82ef27a68769427ae556ab703d683ca0a5b4887d7206526417acdee0f908a1660ddbc90717d18ff09fabd873b8b5b6b
7
- data.tar.gz: 15766ce8377afa98450b7928d46dc790fb2a9f874760914fa929583d4951bae18288c1ff3b5dff7e75d07247723c17e0db87d71703fb22f7103db0d7e573b875
6
+ metadata.gz: dad10a7c85d3d5a30ced79733e407a84584fc3cd32ff6c0c77350cf3f84cfa3f43206ad2e806499ba8f28f6804296f8c7c4d45fe6ccb4fc09899ce62ca388540
7
+ data.tar.gz: 8b80044d67bf6f6215f59f3e21a9c88b9b32fb8d8eb402881e582a7c869eb25d81409076d4dde8def21778e831b391bd43704384a0ee317c5b9f16caa549f3af
@@ -40,6 +40,7 @@ jobs:
40
40
  with:
41
41
  ruby-version: ${{ matrix.ruby-version }}
42
42
  bundler-cache: true
43
+ timeout-minutes: 30
43
44
  - name: Run tests
44
45
  run: bundle exec rake
45
46
  - name: Report code coverage
data/CHANGELOG.md CHANGED
@@ -5,36 +5,50 @@ This project adheres to [Semantic Versioning](http://semver.org/).
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [3.2.1] - 2023-03-22
9
+ ### Changed
10
+ - Improve failover logging [#39](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/39)
11
+
12
+ ## [3.2.0] - 2022-09-26
13
+ ### Added
14
+ - Add simple prefix to all log lines [#38](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/38)
15
+
16
+ ### Changed
17
+ - 5 minute db checks is too long, use 2 minutes [#37](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/37)
18
+
19
+ ### Removed
20
+ - Remove unused pglogical_config_handler [#35](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/35)
21
+
22
+ ### Fixed
23
+ - Don't attempt a database failover without a known standby [#36](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/36)
24
+
8
25
  ## [3.1.4] - 2022-04-30
9
26
  ### Changed
10
- - Loosed rails dependency to include rails 6.1
11
- - Support Ruby 3.0
27
+ - Loosen rails dependency to include rails 6.1 [#28](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/28)
12
28
 
13
29
  ## [3.1.3] - 2021-09-27
14
-
15
30
  ### Changed
16
31
  - Loosen manageiq-password dependency to < 2 [#26](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/26)
17
- - Update ruby versions to 2.5.8 minimum [#25](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/25)
32
+ - Update ruby versions to 2.5.8 minimum and support Ruby 3.0 [#25](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/25)
18
33
  - Switch to manageiq-style [#24](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/24)
19
34
 
20
35
  ## [3.1.2] - 2020-12-21
36
+ ### Changed
21
37
  - Allow for Rails 6.0 [#23](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/23)
22
38
 
23
39
  ## [3.1.1] - 2019-12-12
40
+ ### Changed
24
41
  - Remove the dependency on linux_admin [#19](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/19)
25
42
 
26
43
  ## [3.1.0] - 2019-05-09
27
-
28
44
  ### Added
29
45
  - Add a logical replication config handler [#17](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/17)
30
46
 
31
47
  ## [3.0.1] - 2019-03-19
32
-
33
48
  ### Changed
34
49
  - Remove references to MiqPassword [#15](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/15)
35
50
 
36
51
  ## [3.0.0] - 2018-09-05
37
-
38
52
  ### Added
39
53
  - Allow users of the gem to specify a logger object [#7](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/7)
40
54
 
@@ -44,7 +58,6 @@ This project adheres to [Semantic Versioning](http://semver.org/).
44
58
  - Make failover monitor generic [#10](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/10)
45
59
 
46
60
  ## [2.0.0] - 2018-08-01
47
-
48
61
  ### Added
49
62
  - Add pg-dsn_parser to the gemspec [#5](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/5)
50
63
  - Add postgresql addon for travis [#6](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/6)
@@ -52,7 +65,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
52
65
  ### Changed
53
66
  - Make changes for upgrading repmgr to version 4 [#4](https://github.com/ManageIQ/manageiq-postgres_ha_admin/pull/4)
54
67
 
55
- [Unreleased]: https://github.com/ManageIQ/manageiq-postgres_ha_admin/compare/v3.1.4...master
68
+ [Unreleased]: https://github.com/ManageIQ/manageiq-postgres_ha_admin/compare/v3.2.1...master
69
+ [3.2.1]: https://github.com/ManageIQ/manageiq-postgres_ha_admin/compare/v3.2.0...v3.2.1
70
+ [3.2.0]: https://github.com/ManageIQ/manageiq-postgres_ha_admin/compare/v3.1.4...v3.2.0
56
71
  [3.1.4]: https://github.com/ManageIQ/manageiq-postgres_ha_admin/compare/v3.1.3...v3.1.4
57
72
  [3.1.3]: https://github.com/ManageIQ/manageiq-postgres_ha_admin/compare/v3.1.2...v3.1.3
58
73
  [3.1.2]: https://github.com/ManageIQ/manageiq-postgres_ha_admin/compare/v3.1.1...v3.1.2
@@ -27,9 +27,12 @@ module PostgresHaAdmin
27
27
  @before_failover_cb&.call
28
28
  end
29
29
 
30
+ # Upon successful failover
30
31
  def do_after_failover(new_primary_conn_info)
31
32
  @after_failover_cb&.call(new_primary_conn_info)
32
33
  end
34
+
35
+ # If needed, we can add an unsuccessful failover hook
33
36
  end
34
37
  end
35
38
  end
@@ -7,7 +7,7 @@ module PostgresHaAdmin
7
7
  include Logging
8
8
 
9
9
  FAILOVER_ATTEMPTS = 10
10
- DB_CHECK_FREQUENCY = 300
10
+ DB_CHECK_FREQUENCY = 120
11
11
  FAILOVER_CHECK_FREQUENCY = 60
12
12
  attr_accessor :failover_attempts, :db_check_frequency, :failover_check_frequency
13
13
  attr_reader :config_handlers
@@ -26,22 +26,22 @@ module PostgresHaAdmin
26
26
  begin
27
27
  connection = pg_connection(handler.read)
28
28
  if connection
29
- server_store.update_servers(connection)
29
+ server_store.update_servers(connection, handler.name)
30
30
  connection.finish
31
31
  next
32
32
  end
33
33
 
34
- logger.error("Primary Database is not available for #{handler.name}. Starting to execute failover...")
34
+ log_settings
35
+ server_store.log_current_server_store(handler.name)
36
+ logger.error("#{log_prefix(__callee__)} Primary Database is not available for #{handler.name}. Starting to execute failover...")
35
37
  handler.do_before_failover
36
38
 
37
39
  new_conn_info = execute_failover(handler, server_store)
38
- if new_conn_info
39
- handler.do_after_failover(new_conn_info)
40
- else
41
- logger.error("Failover failed")
42
- end
40
+
41
+ # Upon success, we pass a connection hash
42
+ handler.do_after_failover(new_conn_info) if new_conn_info
43
43
  rescue => e
44
- logger.error("Received #{e.class} error while monitoring #{handler.name}: #{e.message}")
44
+ logger.error("#{log_prefix(__callee__)} Received #{e.class} error while monitoring #{handler.name}: #{e.message}")
45
45
  logger.error(e.backtrace)
46
46
  end
47
47
  end
@@ -52,7 +52,7 @@ module PostgresHaAdmin
52
52
  begin
53
53
  monitor
54
54
  rescue => err
55
- logger.error("#{err.class}: #{err}")
55
+ logger.error("#{log_prefix(__callee__)} #{err.class}: #{err}")
56
56
  logger.error(err.backtrace.join("\n"))
57
57
  end
58
58
  sleep(db_check_frequency)
@@ -67,37 +67,59 @@ module PostgresHaAdmin
67
67
 
68
68
  private
69
69
 
70
+ def log_settings
71
+ logger.info("#{log_prefix(__callee__)} Current HA settings: FAILOVER_ATTEMPTS=#{@failover_attempts} DB_CHECK_FREQUENCY=#{@db_check_frequency} FAILOVER_CHECK_FREQUENCY=#{@failover_check_frequency}")
72
+ end
73
+
70
74
  def initialize_settings(ha_admin_yml_file)
71
75
  ha_admin_yml = {}
72
76
  begin
73
77
  ha_admin_yml = YAML.load_file(ha_admin_yml_file) if File.exist?(ha_admin_yml_file)
74
78
  rescue SystemCallError, IOError => err
75
- logger.error("#{err.class}: #{err}")
76
- logger.info("File not loaded: #{ha_admin_yml_file}. Default settings for failover will be used.")
79
+ logger.error("#{log_prefix(__callee__)} #{err.class}: #{err}")
80
+ logger.info("#{log_prefix(__callee__)} File not loaded: #{ha_admin_yml_file}. Default settings for failover will be used.")
77
81
  end
78
82
  @failover_attempts = ha_admin_yml['failover_attempts'] || FAILOVER_ATTEMPTS
79
83
  @db_check_frequency = ha_admin_yml['db_check_frequency'] || DB_CHECK_FREQUENCY
80
84
  @failover_check_frequency = ha_admin_yml['failover_check_frequency'] || FAILOVER_CHECK_FREQUENCY
81
- logger.info("FAILOVER_ATTEMPTS=#{@failover_attempts} DB_CHECK_FREQUENCY=#{@db_check_frequency} FAILOVER_CHECK_FREQUENCY=#{@failover_check_frequency}")
85
+ log_settings
86
+ end
87
+
88
+ def any_known_standby?(handler, server_store)
89
+ current_host = handler.read[:host]
90
+ server_store.servers.any? do |server|
91
+ server[:host] != current_host && server[:type] == "standby"
92
+ end
82
93
  end
83
94
 
84
95
  def execute_failover(handler, server_store)
96
+ # TODO: Instead of returning false, we should raise:
97
+ # "No active standby"
98
+ # "Standby in recovery"
99
+ # "Exhausted all failover retry attempts" exceptions
100
+ unless any_known_standby?(handler, server_store)
101
+ logger.error("#{log_prefix(__callee__)} Cannot attempt failover without a known active standby for #{handler.name}. Please verify the database.yml and ensure the database is started.")
102
+ return false
103
+ end
104
+
85
105
  failover_attempts.times do
86
106
  with_each_standby_connection(handler, server_store) do |connection, params|
87
107
  next if database_in_recovery?(connection)
88
108
  next unless server_store.host_is_primary?(params[:host], connection)
89
- logger.info("Failing over to server using conninfo: #{params.reject { |k, _v| k == :password }}")
90
- server_store.update_servers(connection)
109
+ logger.info("#{log_prefix(__callee__)} Failing over for #{handler.name} to server using conninfo: #{server_store.sanitized_connection_parameters(params)}")
110
+ server_store.update_servers(connection, handler.name)
91
111
  handler.write(params)
92
112
  return params
93
113
  end
94
114
  sleep(failover_check_frequency)
95
115
  end
116
+ logger.error("#{log_prefix(__callee__)} Failover failed for #{handler.name}")
96
117
  false
97
118
  end
98
119
 
99
120
  def with_each_standby_connection(handler, server_store)
100
121
  active_servers_conninfo(handler, server_store).each do |params|
122
+ logger.info("#{log_prefix(__callee__)} Checking active server for #{handler.name} using conninfo: #{server_store.sanitized_connection_parameters(params)}")
101
123
  connection = pg_connection(params)
102
124
  next if connection.nil?
103
125
  begin
@@ -111,7 +133,7 @@ module PostgresHaAdmin
111
133
  def pg_connection(params)
112
134
  PG::Connection.open(params)
113
135
  rescue PG::Error => e
114
- logger.error("Failed to establish PG connection: #{e.message}")
136
+ logger.error("#{log_prefix(__callee__)} Failed to establish PG connection: #{e.message}")
115
137
  nil
116
138
  end
117
139
 
@@ -4,6 +4,10 @@ module PostgresHaAdmin
4
4
  def logger
5
5
  ManageIQ::PostgresHaAdmin.logger
6
6
  end
7
+
8
+ def log_prefix(method)
9
+ "(PostgresHaAdmin##{method})"
10
+ end
7
11
  end
8
12
  end
9
13
  end
@@ -22,14 +22,15 @@ module PostgresHaAdmin
22
22
  end
23
23
  end
24
24
 
25
- def update_servers(connection)
25
+ def update_servers(connection, handler_name = "unspecified handler")
26
26
  new_servers = query_repmgr(connection)
27
27
  if servers_changed?(new_servers)
28
- logger.info("Updating servers cache to #{new_servers}")
28
+ log_current_server_store(handler_name)
29
+ logger.info("#{log_prefix(__callee__)} Updating servers cache to #{sanitized_servers_array(new_servers)} for #{handler_name}")
29
30
  @servers = new_servers
30
31
  end
31
32
  rescue IOError => err
32
- logger.error("#{err.class}: #{err}")
33
+ logger.error("#{log_prefix(__callee__)} #{err.class}: #{err}")
33
34
  logger.error(err.backtrace.join("\n"))
34
35
  end
35
36
 
@@ -42,6 +43,18 @@ module PostgresHaAdmin
42
43
  false
43
44
  end
44
45
 
46
+ def log_current_server_store(handler_name)
47
+ logger.info("#{log_prefix(__callee__)} Current servers cache: #{sanitized_servers_array(@servers)} for #{handler_name}")
48
+ end
49
+
50
+ def sanitized_servers_array(server_array)
51
+ server_array.collect { |p| sanitized_connection_parameters(p) }
52
+ end
53
+
54
+ def sanitized_connection_parameters(params)
55
+ params.reject { |k, _v| k.to_s == "password" }
56
+ end
57
+
45
58
  private
46
59
 
47
60
  def servers_changed?(new_servers)
@@ -59,7 +72,7 @@ module PostgresHaAdmin
59
72
  db_result.clear
60
73
  result
61
74
  rescue PG::Error => err
62
- logger.error("#{err.class}: #{err}")
75
+ logger.error("#{log_prefix(__callee__)} #{err.class}: #{err}")
63
76
  logger.error(err.backtrace.join("\n"))
64
77
  result
65
78
  end
@@ -1,5 +1,5 @@
1
1
  module ManageIQ
2
2
  module PostgresHaAdmin
3
- VERSION = '3.1.4'.freeze
3
+ VERSION = '3.2.1'.freeze
4
4
  end
5
5
  end
@@ -8,7 +8,6 @@ require 'manageiq/postgres_ha_admin/failover_monitor'
8
8
 
9
9
  require 'manageiq/postgres_ha_admin/config_handler'
10
10
  require 'manageiq/postgres_ha_admin/config_handler/rails_config_handler'
11
- require 'manageiq/postgres_ha_admin/config_handler/pglogical_config_handler'
12
11
  require 'manageiq/postgres_ha_admin/config_handler/logical_replication_config_handler'
13
12
 
14
13
  module ManageIQ
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: manageiq-postgres_ha_admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.4
4
+ version: 3.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - ManageIQ Developers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-29 00:00:00.000000000 Z
11
+ date: 2023-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -180,7 +180,6 @@ files:
180
180
  - lib/manageiq-postgres_ha_admin.rb
181
181
  - lib/manageiq/postgres_ha_admin/config_handler.rb
182
182
  - lib/manageiq/postgres_ha_admin/config_handler/logical_replication_config_handler.rb
183
- - lib/manageiq/postgres_ha_admin/config_handler/pglogical_config_handler.rb
184
183
  - lib/manageiq/postgres_ha_admin/config_handler/rails_config_handler.rb
185
184
  - lib/manageiq/postgres_ha_admin/failover_monitor.rb
186
185
  - lib/manageiq/postgres_ha_admin/logging.rb
@@ -210,7 +209,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
210
209
  - !ruby/object:Gem::Version
211
210
  version: '0'
212
211
  requirements: []
213
- rubygems_version: 3.3.5
212
+ rubygems_version: 3.2.33
214
213
  signing_key:
215
214
  specification_version: 4
216
215
  summary: ManageIQ Postgres H.A. Admin
@@ -1,36 +0,0 @@
1
- require 'pg'
2
- require 'pg/dsn_parser'
3
-
4
- module ManageIQ
5
- module PostgresHaAdmin
6
- class PglogicalConfigHandler < ConfigHandler
7
- attr_reader :subscription, :conn_info
8
-
9
- def initialize(options = {})
10
- @subscription = options[:subscription]
11
- @conn_info = options[:conn_info]
12
- end
13
-
14
- def name
15
- "pglogical subscription #{subscription} Config Handler"
16
- end
17
-
18
- def read
19
- conn = PG::Connection.open(@conn_info)
20
- dsn = conn.exec_params(<<~SQL, [@subscription]).first["if_dsn"]
21
- SELECT if_dsn
22
- FROM pglogical.subscription s
23
- JOIN pglogical.node_interface i
24
- ON s.sub_origin_if = i.if_id
25
- WHERE s.sub_name = $1
26
- SQL
27
- PG::DSNParser.new.parse(dsn)
28
- end
29
-
30
- def write(_params)
31
- # Nothing to do here as the expectation is that the user will
32
- # remove and re-add the subscription in the after failover callback
33
- end
34
- end
35
- end
36
- end