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 +4 -4
- data/.gitignore +1 -1
- data/.travis.yml +3 -2
- data/CHANGELOG.md +18 -1
- data/README.md +2 -0
- data/lib/postgres/vacuum/configuration.rb +4 -2
- data/lib/postgres/vacuum/jobs/monitor_job.rb +30 -0
- data/lib/postgres/vacuum/monitor/query.rb +53 -2
- data/lib/postgres/vacuum/monitor/version.rb +1 -1
- data/postgres-vacuum-monitor.gemspec +2 -2
- metadata +13 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2bade52e5e9f33c876eeb297422bb537fdc08385858d5cff63b53534da656435
|
4
|
+
data.tar.gz: f9e898dcfb96040f1b4ea0b6d3f59374bac36b42e2015c9a8c5c30dca9cff5ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f3658515adbc097c69990e9c15f6a6b73e735ddd214840e0860ce540a362c3216eeac55f4dfef57c00cb1b59d32a1cb855efa2b6c12d6924021d41b69133d1bb
|
7
|
+
data.tar.gz: 65c6285452b08ee88853ad8f8be2b2bc37f2c2184c9ac1718f2b60c1491d51b8b8fb167b46072a7682c6535cb1aa02fae91cc60791d6640b16638dc208c88fc8
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
# postgres-vacuum-monitor
|
2
|
-
|
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
|
-
|
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
|
-
|
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 > #{
|
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
|
@@ -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 '
|
27
|
+
spec.add_development_dependency 'coveralls_reborn', '>= 0.18.0'
|
28
28
|
spec.add_development_dependency 'database_cleaner'
|
29
|
-
spec.add_development_dependency 'rake', '
|
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.
|
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-
|
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:
|
42
|
+
name: coveralls_reborn
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
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:
|
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:
|
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:
|
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.
|
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: []
|