postgres-vacuum-monitor 0.6.0 → 0.10.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: 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: []