pghero 1.3.0 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of pghero might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG.md +5 -0
- data/README.md +2 -0
- data/app/controllers/pg_hero/home_controller.rb +2 -0
- data/app/views/pg_hero/home/_query_stats_slider.html.erb +7 -1
- data/app/views/pg_hero/home/index.html.erb +6 -2
- data/lib/pghero/methods/queries.rb +28 -0
- data/lib/pghero/methods/query_stats.rb +35 -15
- data/lib/pghero/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 33902e779edd42795e8f3c48d51a8f0abf4edf6c
|
4
|
+
data.tar.gz: b16a37597ad809d2aefe83fd0ff6f6478319c655
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 65850829e7cd4071748b03b453f1ee91e0739048001802d5d8ecc290bb0f3e137d7c08bfa2f51cb0bc76ced94087865c6e8d276ed98b5b86c88916fea56e52a6
|
7
|
+
data.tar.gz: 1cf67bd24d6e2780b63b44466f8e964ea10be8ef6bfbf4286e636a3b0f7baee16e20ab5e25bf3092ece33095ea22e7688596e7227b19c1093ea1243c41612b1d
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -31,3 +31,5 @@ A big thanks to [Craig Kerstiens](http://www.craigkerstiens.com/2013/01/10/more-
|
|
31
31
|
Know a bit about PostgreSQL? [Suggestions](https://github.com/ankane/pghero/issues) are greatly appreciated.
|
32
32
|
|
33
33
|
:tangerine: Battle-tested at [Instacart](https://www.instacart.com/opensource)
|
34
|
+
|
35
|
+
[![Build Status](https://travis-ci.org/ankane/pghero.svg?branch=master)](https://travis-ci.org/ankane/pghero)
|
@@ -95,6 +95,8 @@ module PgHero
|
|
95
95
|
|
96
96
|
set_suggested_indexes
|
97
97
|
|
98
|
+
# fix back button issue with caching
|
99
|
+
response.headers["Cache-Control"] = "must-revalidate, no-store, no-cache, private"
|
98
100
|
if request.xhr?
|
99
101
|
render layout: false, partial: "queries_table", locals: {queries: @query_stats, xhr: true}
|
100
102
|
end
|
@@ -153,7 +153,13 @@
|
|
153
153
|
$(this).attr("href", queriesPath(p));
|
154
154
|
});
|
155
155
|
|
156
|
-
|
156
|
+
|
157
|
+
var callback = function (response, status, xhr) {
|
158
|
+
if (status === "error" ) {
|
159
|
+
$(".queries-info").css("color", "red").html(xhr.status + " " + xhr.statusText);
|
160
|
+
}
|
161
|
+
};
|
162
|
+
$("#queries").html('<tr><td colspan="3"><p class="queries-info text-muted">...</p></td></tr>').load(path, callback);
|
157
163
|
|
158
164
|
if (push && history.pushState) {
|
159
165
|
history.pushState(null, null, path);
|
@@ -158,13 +158,14 @@
|
|
158
158
|
<% if @sequence_danger.any? %>
|
159
159
|
<div class="content">
|
160
160
|
<h2>Columns Near Overflow</h2>
|
161
|
-
<p>Consider changing
|
161
|
+
<p>Consider changing columns to bigint to support a larger range of values.</p>
|
162
162
|
<table class="table">
|
163
163
|
<thead>
|
164
164
|
<tr>
|
165
165
|
<th>Column</th>
|
166
166
|
<th style="width: 20%;">Type</th>
|
167
167
|
<th style="width: 20%;">Values Left</th>
|
168
|
+
<th style="width: 10%;">% Left</th>
|
168
169
|
</tr>
|
169
170
|
</thead>
|
170
171
|
<tbody>
|
@@ -174,11 +175,14 @@
|
|
174
175
|
<%= query["table"] %>.<%= query["column"] %>
|
175
176
|
</td>
|
176
177
|
<td>
|
177
|
-
|
178
|
+
<%= query["column_type"] %>
|
178
179
|
</td>
|
179
180
|
<td>
|
180
181
|
<%= number_with_delimiter(query["max_value"].to_i - query["last_value"].to_i) %>
|
181
182
|
</td>
|
183
|
+
<td>
|
184
|
+
<%= number_to_percentage((query["max_value"].to_i - query["last_value"].to_i) * 100.0 / query["max_value"].to_i, precision: 2, significant: true) %>
|
185
|
+
</td>
|
182
186
|
</tr>
|
183
187
|
<% end %>
|
184
188
|
</tbody>
|
@@ -73,6 +73,34 @@ module PgHero
|
|
73
73
|
query_start
|
74
74
|
SQL
|
75
75
|
end
|
76
|
+
|
77
|
+
# from https://wiki.postgresql.org/wiki/Lock_Monitoring
|
78
|
+
def blocked_queries
|
79
|
+
select_all <<-SQL
|
80
|
+
SELECT
|
81
|
+
bl.pid AS blocked_pid,
|
82
|
+
a.usename AS blocked_user,
|
83
|
+
ka.query AS current_or_recent_query_in_blocking_process,
|
84
|
+
ka.state AS state_of_blocking_process,
|
85
|
+
age(now(), ka.query_start) AS blocking_duration,
|
86
|
+
kl.pid AS blocking_pid,
|
87
|
+
ka.usename AS blocking_user,
|
88
|
+
a.query AS blocked_query,
|
89
|
+
age(now(), a.query_start) AS blocked_duration
|
90
|
+
FROM
|
91
|
+
pg_catalog.pg_locks bl
|
92
|
+
JOIN
|
93
|
+
pg_catalog.pg_stat_activity a ON a.pid = bl.pid
|
94
|
+
JOIN
|
95
|
+
pg_catalog.pg_locks kl ON kl.transactionid = bl.transactionid AND kl.pid != bl.pid
|
96
|
+
JOIN
|
97
|
+
pg_catalog.pg_stat_activity ka ON ka.pid = kl.pid
|
98
|
+
WHERE
|
99
|
+
NOT bl.GRANTED
|
100
|
+
ORDER BY
|
101
|
+
blocked_duration DESC
|
102
|
+
SQL
|
103
|
+
end
|
76
104
|
end
|
77
105
|
end
|
78
106
|
end
|
@@ -2,23 +2,19 @@ module PgHero
|
|
2
2
|
module Methods
|
3
3
|
module QueryStats
|
4
4
|
def query_stats(options = {})
|
5
|
-
current_query_stats =
|
6
|
-
historical_query_stats =
|
7
|
-
current_query_stats.default = {}
|
8
|
-
historical_query_stats.default = {}
|
5
|
+
current_query_stats = options[:historical] && options[:end_at] && options[:end_at] < Time.now ? [] : current_query_stats(options)
|
6
|
+
historical_query_stats = options[:historical] ? historical_query_stats(options) : []
|
9
7
|
|
10
|
-
query_stats = []
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
value["average_time"] = value["total_minutes"] * 1000 * 60 / value["calls"]
|
19
|
-
value["total_percent"] = value["total_minutes"] * 100.0 / (current_query_stats[query_hash]["all_queries_total_minutes"].to_f + historical_query_stats[query_hash]["all_queries_total_minutes"].to_f)
|
20
|
-
query_stats << value
|
8
|
+
query_stats = combine_query_stats((current_query_stats + historical_query_stats).group_by { |q| q["query_hash"] })
|
9
|
+
query_stats = combine_query_stats(query_stats.group_by { |q| normalize_query(q["query"]) })
|
10
|
+
|
11
|
+
# add percentages
|
12
|
+
all_queries_total_minutes = [current_query_stats, historical_query_stats].sum { |s| (s.first || {})["all_queries_total_minutes"].to_f }
|
13
|
+
query_stats.each do |query|
|
14
|
+
query["average_time"] = query["total_minutes"] * 1000 * 60 / query["calls"]
|
15
|
+
query["total_percent"] = query["total_minutes"] * 100.0 / all_queries_total_minutes
|
21
16
|
end
|
17
|
+
|
22
18
|
sort = options[:sort] || "total_minutes"
|
23
19
|
query_stats = query_stats.sort_by { |q| -q[sort] }.first(100)
|
24
20
|
if options[:min_average_time]
|
@@ -235,6 +231,30 @@ module PgHero
|
|
235
231
|
@server_version ||= {}
|
236
232
|
@server_version[current_database] ||= select_all("SHOW server_version_num").first["server_version_num"].to_i
|
237
233
|
end
|
234
|
+
|
235
|
+
private
|
236
|
+
|
237
|
+
def combine_query_stats(grouped_stats)
|
238
|
+
query_stats = []
|
239
|
+
grouped_stats.each do |_, stats2|
|
240
|
+
value = {
|
241
|
+
"query" => (stats2.find { |s| s["query"] } || {})["query"],
|
242
|
+
"query_hash" => (stats2.find { |s| s["query"] } || {})["query_hash"],
|
243
|
+
"total_minutes" => stats2.sum { |s| s["total_minutes"].to_f },
|
244
|
+
"calls" => stats2.sum { |s| s["calls"].to_i },
|
245
|
+
"all_queries_total_minutes" => stats2.sum { |s| s["all_queries_total_minutes"].to_f }
|
246
|
+
}
|
247
|
+
value["total_percent"] = value["total_minutes"] * 100.0 / value["all_queries_total_minutes"]
|
248
|
+
query_stats << value
|
249
|
+
end
|
250
|
+
query_stats
|
251
|
+
end
|
252
|
+
|
253
|
+
# removes comments
|
254
|
+
# combines ?, ?, ? => ?
|
255
|
+
def normalize_query(query)
|
256
|
+
squish(query.to_s.gsub(/\?(, ?\?)+/, "?").gsub(/\/\*.+?\*\//, ""))
|
257
|
+
end
|
238
258
|
end
|
239
259
|
end
|
240
260
|
end
|
data/lib/pghero/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pghero
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-07-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|