postgres-vacuum-monitor 0.6.0 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0fee499969b39fb4a978796ea02938e41b3bcfd2bc9cc359c6ccd7bc3f899baf
4
- data.tar.gz: 8560faf84d65d94e45bcaff906ca32ec85f2e8f2f917445f5fb2ed26eb162196
3
+ metadata.gz: 2bade52e5e9f33c876eeb297422bb537fdc08385858d5cff63b53534da656435
4
+ data.tar.gz: f9e898dcfb96040f1b4ea0b6d3f59374bac36b42e2015c9a8c5c30dca9cff5ae
5
5
  SHA512:
6
- metadata.gz: a56a0f9106ed71b00cfe4121065a441ffbf35c5365217d1e2f0ac4ae7d41dfbd6d7ba1b8693727f06bed87c8ebe2d73358aed33bbd8fdd16d70af9f1ee2437e9
7
- data.tar.gz: 3c1c355e1fd736f397faef12c9ca96520b2266a7747fd65db49da17bd752c99d1d11db09d943b324ddb05e65c2bfdb7fe6ec441720a436b8fcddba1a3f95679e
6
+ metadata.gz: f3658515adbc097c69990e9c15f6a6b73e735ddd214840e0860ce540a362c3216eeac55f4dfef57c00cb1b59d32a1cb855efa2b6c12d6924021d41b69133d1bb
7
+ data.tar.gz: 65c6285452b08ee88853ad8f8be2b2bc37f2c2184c9ac1718f2b60c1491d51b8b8fb167b46072a7682c6535cb1aa02fae91cc60791d6640b16638dc208c88fc8
data/.gitignore CHANGED
@@ -9,5 +9,5 @@
9
9
  *.iml
10
10
  .idea/
11
11
  Gemfile.lock
12
- log/*.log
13
12
  gemfiles/*.gemfile.lock
13
+ log/
@@ -1,7 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.5.6
4
- - 2.6.3
3
+ - 2.5.8
4
+ - 2.6.6
5
+ - 2.7.1
5
6
  gemfile:
6
7
  - gemfiles/activerecord_5.gemfile
7
8
  - gemfiles/activerecord_6.gemfile
@@ -1,5 +1,22 @@
1
1
  # postgres-vacuum-monitor
2
- ## v.0.5.0
2
+
3
+ ## v.10.1
4
+ - Query bug fix.
5
+
6
+ ## v.10.0
7
+ - Add events for connection idle time and state.
8
+
9
+ ## v.0.9.0
10
+ - Add the application name in the event.
11
+
12
+ ## v.0.8.0
13
+ - Report on queries that are being blocked by another process.
14
+
15
+ ## v.0.7.0
16
+ - Lower the default `LongTransactions` threshold from 1 hour to 5 minutes and make this configurable via
17
+ the `long_running_transaction_threshold_seconds` setting.
18
+
19
+ ## v.0.6.0
3
20
  - Add `wait_event_type`, `transaction_id` and `min_transaction_id` to `LongTransactions` events.
4
21
 
5
22
  ## v.0.5.0
data/README.md CHANGED
@@ -33,6 +33,8 @@ The job itself needs a class to report the information and can be configured by
33
33
  ```ruby
34
34
  Postgres::Vacuum::Monitor.configure do |config|
35
35
  config.monitor_reporter_class_name = 'MetricsReporter'
36
+ # Optionally change the default threshold of 5 minutes for reporting long running transactions
37
+ config.long_running_transaction_threshold_seconds = 10 * 60
36
38
  end
37
39
  ```
38
40
 
@@ -1,10 +1,12 @@
1
1
  module Postgres
2
2
  module Vacuum
3
3
  class Configuration
4
- attr_accessor :monitor_reporter_class_name
4
+ DEFAULT_LONG_RUNNING_TRANSACTION_THRESHOLD_SECONDS = 5 * 60
5
+ attr_accessor :monitor_reporter_class_name, :long_running_transaction_threshold_seconds
5
6
 
6
7
  def initialize
7
- @monitor_reporter_class_name = nil
8
+ self.monitor_reporter_class_name = nil
9
+ self.long_running_transaction_threshold_seconds = DEFAULT_LONG_RUNNING_TRANSACTION_THRESHOLD_SECONDS
8
10
  end
9
11
  end
10
12
  end
@@ -5,6 +5,9 @@ module Postgres
5
5
 
6
6
  AUTOVACUUM_LAGGING_EVENT = 'AutoVacuumLagging'.freeze
7
7
  LONG_TRANSACTIONS = 'LongTransactions'.freeze
8
+ BLOCKED_QUERIES = 'BlockedQueries'.freeze
9
+ CONNECTION_STATE = 'ConnectionState'.freeze
10
+ CONNECTION_IDLE_TIME = 'ConnectionIdleTime'.freeze
8
11
 
9
12
  def perform(*)
10
13
  with_each_db_name_and_connection do |name, connection|
@@ -33,6 +36,33 @@ module Postgres
33
36
  tuples_over_limit: row['dead_tuples'].to_i - row['autovacuum_vacuum_tuples'].to_i
34
37
  )
35
38
  end
39
+
40
+ connection.execute(Postgres::Vacuum::Monitor::Query.blocked_queries).each do |row|
41
+ reporter_class.report_event(
42
+ BLOCKED_QUERIES,
43
+ database_name: name,
44
+ blocked_pid: row['blocked_pid'],
45
+ blocked_application: row['blocked_application'],
46
+ blocked_statement: row['blocked_statement'],
47
+ blocking_pid: row['blocking_pid'],
48
+ blocking_application: row['blocking_application'],
49
+ current_statement_in_blocking_process: row['current_statement_in_blocking_process']
50
+ )
51
+ end
52
+
53
+ connection.execute(Postgres::Vacuum::Monitor::Query.connection_state).each do |row|
54
+ reporter_class.report_event(CONNECTION_STATE, database_name: name, state: row['state'], connection_count: row['connection_count'])
55
+ end
56
+
57
+ connection.execute(Postgres::Vacuum::Monitor::Query.connection_idle_time).each do |row|
58
+ reporter_class.report_event(
59
+ CONNECTION_IDLE_TIME,
60
+ database_name: name,
61
+ max: row['max'],
62
+ median: row['median'],
63
+ percentile_90: row['percentile_90']
64
+ )
65
+ end
36
66
  end
37
67
 
38
68
  true
@@ -5,7 +5,6 @@ module Postgres
5
5
  extend self
6
6
 
7
7
  STATES = ["'idle in transaction'", "'active'"].freeze
8
- TIME_LIMIT = 3600
9
8
  THRESHOLD_SETTING = "'autovacuum_vacuum_threshold'".freeze
10
9
  SCALE_FACTOR_SETTING = "'autovacuum_vacuum_scale_factor'".freeze
11
10
  MAX_AGE_SETTING = "'autovacuum_freeze_max_age'".freeze
@@ -29,7 +28,7 @@ module Postgres
29
28
  WHERE state IN (#{STATES.join(', ')})
30
29
  ORDER BY seconds DESC
31
30
  ) AS long_queries
32
- WHERE seconds > #{TIME_LIMIT};
31
+ WHERE seconds > #{Postgres::Vacuum::Monitor.configuration.long_running_transaction_threshold_seconds};
33
32
  SQL
34
33
  end
35
34
 
@@ -68,6 +67,58 @@ module Postgres
68
67
  ORDER BY age(relfrozenxid) DESC LIMIT 50;
69
68
  SQL
70
69
  end
70
+
71
+ def blocked_queries
72
+ # The query was taken from https://wiki.postgresql.org/wiki/Lock_Monitoring
73
+ <<-SQL
74
+ SELECT blocked_locks.pid AS blocked_pid,
75
+ blocked_activity.usename AS blocked_user,
76
+ blocking_locks.pid AS blocking_pid,
77
+ blocking_activity.usename AS blocking_user,
78
+ blocked_activity.query AS blocked_statement,
79
+ blocking_activity.query AS current_statement_in_blocking_process,
80
+ blocked_activity.application_name AS blocked_application,
81
+ blocking_activity.application_name AS blocking_application
82
+ FROM pg_catalog.pg_locks blocked_locks
83
+ JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
84
+ JOIN pg_catalog.pg_locks blocking_locks
85
+ ON blocking_locks.locktype = blocked_locks.locktype
86
+ AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE
87
+ AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
88
+ AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
89
+ AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
90
+ AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
91
+ AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
92
+ AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
93
+ AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
94
+ AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
95
+ AND blocking_locks.pid != blocked_locks.pid
96
+ JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
97
+ WHERE NOT blocked_locks.GRANTED;
98
+ SQL
99
+ end
100
+
101
+ def connection_state
102
+ <<-SQL
103
+ SELECT
104
+ state, count(*) as connection_count
105
+ FROM pg_stat_activity
106
+ GROUP BY state
107
+ ORDER BY connection_count DESC;
108
+ SQL
109
+ end
110
+
111
+ def connection_idle_time
112
+ <<-SQL
113
+ SELECT
114
+ max(EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - state_change))) as max,
115
+ percentile_cont(0.5) within GROUP (ORDER BY EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - state_change)) DESC) AS median,
116
+ percentile_cont(0.9) within GROUP (ORDER BY EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - state_change)) DESC) AS percentile_90
117
+ FROM pg_stat_activity
118
+ WHERE state = 'idle'
119
+ LIMIT 1000;
120
+ SQL
121
+ end
71
122
  end
72
123
  end
73
124
  end
@@ -1,7 +1,7 @@
1
1
  module Postgres
2
2
  module Vacuum
3
3
  module Monitor
4
- VERSION = '0.6.0'.freeze
4
+ VERSION = '0.10.1'.freeze
5
5
  end
6
6
  end
7
7
  end
@@ -24,9 +24,9 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.add_development_dependency 'appraisal'
26
26
  spec.add_development_dependency 'bundler'
27
- spec.add_development_dependency 'coveralls'
27
+ spec.add_development_dependency 'coveralls_reborn', '>= 0.18.0'
28
28
  spec.add_development_dependency 'database_cleaner'
29
- spec.add_development_dependency 'rake', '~> 10.0'
29
+ spec.add_development_dependency 'rake', '>= 12.3.3'
30
30
  spec.add_development_dependency 'rspec', '~> 3.2'
31
31
  spec.add_development_dependency 'salsify_rubocop'
32
32
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: postgres-vacuum-monitor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fernando Garces
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-02-07 00:00:00.000000000 Z
11
+ date: 2020-10-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: appraisal
@@ -39,19 +39,19 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: coveralls
42
+ name: coveralls_reborn
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 0.18.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: 0.18.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: database_cleaner
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -70,16 +70,16 @@ dependencies:
70
70
  name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '10.0'
75
+ version: 12.3.3
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '10.0'
82
+ version: 12.3.3
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rspec
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -180,7 +180,7 @@ files:
180
180
  homepage: https://github.com/salsify/postgres-vacuum-monitor
181
181
  licenses: []
182
182
  metadata: {}
183
- post_install_message:
183
+ post_install_message:
184
184
  rdoc_options: []
185
185
  require_paths:
186
186
  - lib
@@ -195,8 +195,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
195
195
  - !ruby/object:Gem::Version
196
196
  version: '0'
197
197
  requirements: []
198
- rubygems_version: 3.0.6
199
- signing_key:
198
+ rubygems_version: 3.1.2
199
+ signing_key:
200
200
  specification_version: 4
201
201
  summary: Simple stats collector for postgres auto vacuumer.
202
202
  test_files: []