pghero 1.6.3 → 1.6.4
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/CHANGELOG.md +7 -0
- data/app/assets/stylesheets/pghero/application.css +1 -0
- data/app/views/layouts/pg_hero/application.html.erb +3 -1
- data/app/views/pg_hero/home/connections.html.erb +28 -26
- data/app/views/pg_hero/home/explain.html.erb +0 -2
- data/app/views/pg_hero/home/maintenance.html.erb +2 -2
- data/lib/pghero/methods/indexes.rb +7 -4
- data/lib/pghero/methods/replica.rb +4 -1
- 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: eb291e1e354b3844fd5d54ff4894fb841054a272
|
4
|
+
data.tar.gz: cdc3dcdb41c9fd5f11f945fb127c3e5ab64eedf2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 345b0973aa418742ce6b8624112a1e7a3b67dcb9910c5749c7217e4a6cc029d16dac0b42b66bf0fff4863ee413738a2212f4b155ab7e5cdc40beac5ec1283bda
|
7
|
+
data.tar.gz: c28162b603ffe0ae7a7c7040eeefec7a9a0880d0f9c185fa16f18bd605894b71387c669795fb0a862bcc2614dd30b8a0e60c0dd2cdc283dc2da95bf38fca1bf6
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## 1.6.4
|
2
|
+
|
3
|
+
- Only show connection charts if there are connections
|
4
|
+
- Fixed duplicate indexes for multiple schemas
|
5
|
+
- Fixed display issue for queries without word break
|
6
|
+
- Removed maintenance tab for replicas
|
7
|
+
|
1
8
|
## 1.6.3
|
2
9
|
|
3
10
|
- Added 10 second timeout for explain
|
@@ -39,7 +39,9 @@
|
|
39
39
|
<li class="<%= controller.action_name == "space" ? "active" : "" %>"><%= link_to "Space", space_path %></li>
|
40
40
|
<li class="<%= controller.action_name == "connections" ? "active" : "" %>"><%= link_to "Connections", connections_path %></li>
|
41
41
|
<li class="<%= controller.action_name == "live_queries" ? "active" : "" %>"><%= link_to "Live Queries", live_queries_path %></li>
|
42
|
-
|
42
|
+
<% unless @database.replica? %>
|
43
|
+
<li class="<%= controller.action_name == "maintenance" ? "active" : "" %>"><%= link_to "Maintenance", maintenance_path %></li>
|
44
|
+
<% end %>
|
43
45
|
<li class="<%= controller.action_name == "explain" ? "active" : "" %>"><%= link_to "Explain", explain_path %></li>
|
44
46
|
<li class="<%= controller.action_name == "tune" ? "active" : "" %>"><%= link_to "Tune", tune_path %></li>
|
45
47
|
</ul>
|
@@ -3,31 +3,33 @@
|
|
3
3
|
|
4
4
|
<p><%= pluralize(@total_connections, "connection") %></p>
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
<%
|
6
|
+
<% if @total_connections > 0 %>
|
7
|
+
<h3>By Database</h3>
|
8
|
+
|
9
|
+
<% top_connections = Hash.new(0) %>
|
10
|
+
<% @connection_sources.each do |source| %>
|
11
|
+
<% top_connections[source["database"]] += source["total_connections"].to_i %>
|
12
|
+
<% end %>
|
13
|
+
<% top_connections = top_connections.sort_by { |k, v| [-v, k] } %>
|
14
|
+
|
15
|
+
<div id="chart-1" class="chart" style="height: 260px; line-height: 260px; margin-bottom: 20px;">Loading...</div>
|
16
|
+
<script>
|
17
|
+
new Chartkick.PieChart("chart-1", <%= json_escape(top_connections.to_json).html_safe %>);
|
18
|
+
</script>
|
19
|
+
|
20
|
+
<h3>By User</h3>
|
21
|
+
|
22
|
+
<% top_connections = Hash.new(0) %>
|
23
|
+
<% @connection_sources.each do |source| %>
|
24
|
+
<% top_connections[source["user"]] += source["total_connections"].to_i %>
|
25
|
+
<% end %>
|
26
|
+
<% top_connections = top_connections.sort_by { |k, v| [-v, k] } %>
|
27
|
+
|
28
|
+
<div id="chart-2" class="chart" style="height: 260px; line-height: 260px; margin-bottom: 20px;">Loading...</div>
|
29
|
+
<script>
|
30
|
+
new Chartkick.PieChart("chart-2", <%= json_escape(top_connections.to_json).html_safe %>);
|
31
|
+
</script>
|
32
|
+
|
33
|
+
<%= render partial: "connections_table", locals: {connection_sources: @connection_sources} %>
|
11
34
|
<% end %>
|
12
|
-
<% top_connections = top_connections.sort_by { |k, v| [-v, k] } %>
|
13
|
-
|
14
|
-
<div id="chart-1" class="chart" style="height: 260px; line-height: 260px; margin-bottom: 20px;">Loading...</div>
|
15
|
-
<script>
|
16
|
-
new Chartkick.PieChart("chart-1", <%= json_escape(top_connections.to_json).html_safe %>);
|
17
|
-
</script>
|
18
|
-
|
19
|
-
<h3>By User</h3>
|
20
|
-
|
21
|
-
<% top_connections = Hash.new(0) %>
|
22
|
-
<% @connection_sources.each do |source| %>
|
23
|
-
<% top_connections[source["user"]] += source["total_connections"].to_i %>
|
24
|
-
<% end %>
|
25
|
-
<% top_connections = top_connections.sort_by { |k, v| [-v, k] } %>
|
26
|
-
|
27
|
-
<div id="chart-2" class="chart" style="height: 260px; line-height: 260px; margin-bottom: 20px;">Loading...</div>
|
28
|
-
<script>
|
29
|
-
new Chartkick.PieChart("chart-2", <%= json_escape(top_connections.to_json).html_safe %>);
|
30
|
-
</script>
|
31
|
-
|
32
|
-
<%= render partial: "connections_table", locals: {connection_sources: @connection_sources} %>
|
33
35
|
</div>
|
@@ -23,7 +23,5 @@
|
|
23
23
|
<% end %>
|
24
24
|
<% elsif @error %>
|
25
25
|
<div class="alert alert-danger"><%= @error %></div>
|
26
|
-
<% else %>
|
27
|
-
<p class="text-muted">Note: The analyze and visualize buttons can add load to your database for long running queries, so be careful.</p>
|
28
26
|
<% end %>
|
29
27
|
</div>
|
@@ -21,7 +21,7 @@
|
|
21
21
|
<td>
|
22
22
|
<% time = [table["last_autovacuum"], table["last_vacuum"]].compact.max %>
|
23
23
|
<% if time %>
|
24
|
-
<%= @time_zone.parse(time).strftime("
|
24
|
+
<%= @time_zone.parse(time).strftime("%-m/%-e %l:%M %P") %>
|
25
25
|
<% else %>
|
26
26
|
<span class="text-muted">Unknown</span>
|
27
27
|
<% end %>
|
@@ -29,7 +29,7 @@
|
|
29
29
|
<td>
|
30
30
|
<% time = [table["last_autoanalyze"], table["last_analyze"]].compact.max %>
|
31
31
|
<% if time %>
|
32
|
-
<%= @time_zone.parse(time).strftime("
|
32
|
+
<%= @time_zone.parse(time).strftime("%-m/%-e %l:%M %P") %>
|
33
33
|
<% else %>
|
34
34
|
<span class="text-muted">Unknown</span>
|
35
35
|
<% end %>
|
@@ -114,22 +114,25 @@ module PgHero
|
|
114
114
|
def indexes
|
115
115
|
select_all(<<-SQL
|
116
116
|
SELECT
|
117
|
+
schemaname AS schema,
|
117
118
|
t.relname AS table,
|
118
119
|
ix.relname AS name,
|
119
|
-
regexp_replace(pg_get_indexdef(indexrelid), '^[^\\(]*\\((.*)\\)$', '\\1') AS columns,
|
120
|
-
regexp_replace(pg_get_indexdef(indexrelid), '.* USING ([^ ]*) \\(.*', '\\1') AS using,
|
120
|
+
regexp_replace(pg_get_indexdef(i.indexrelid), '^[^\\(]*\\((.*)\\)$', '\\1') AS columns,
|
121
|
+
regexp_replace(pg_get_indexdef(i.indexrelid), '.* USING ([^ ]*) \\(.*', '\\1') AS using,
|
121
122
|
indisunique AS unique,
|
122
123
|
indisprimary AS primary,
|
123
124
|
indisvalid AS valid,
|
124
125
|
indexprs::text,
|
125
126
|
indpred::text,
|
126
|
-
pg_get_indexdef(indexrelid) AS definition
|
127
|
+
pg_get_indexdef(i.indexrelid) AS definition
|
127
128
|
FROM
|
128
129
|
pg_index i
|
129
130
|
INNER JOIN
|
130
131
|
pg_class t ON t.oid = i.indrelid
|
131
132
|
INNER JOIN
|
132
133
|
pg_class ix ON ix.oid = i.indexrelid
|
134
|
+
LEFT JOIN
|
135
|
+
pg_stat_user_indexes ui ON ui.indexrelid = i.indexrelid
|
133
136
|
ORDER BY
|
134
137
|
1, 2
|
135
138
|
SQL
|
@@ -141,7 +144,7 @@ module PgHero
|
|
141
144
|
|
142
145
|
indexes_by_table = self.indexes.group_by { |i| i["table"] }
|
143
146
|
indexes_by_table.values.flatten.select { |i| PgHero.falsey?(i["primary"]) && PgHero.falsey?(i["unique"]) && !i["indexprs"] && !i["indpred"] && PgHero.truthy?(i["valid"]) }.each do |index|
|
144
|
-
covering_index = indexes_by_table[index["table"]].find { |i| index_covers?(i["columns"], index["columns"]) && i["using"] == index["using"] && i["name"] != index["name"] && !i["indexprs"] && !i["indpred"] && PgHero.truthy?(i["valid"]) }
|
147
|
+
covering_index = indexes_by_table[index["table"]].find { |i| index_covers?(i["columns"], index["columns"]) && i["using"] == index["using"] && i["name"] != index["name"] && i["schema"] == index["schema"] && !i["indexprs"] && !i["indpred"] && PgHero.truthy?(i["valid"]) }
|
145
148
|
if covering_index && (covering_index["columns"] != index["columns"] || index["name"] > covering_index["name"])
|
146
149
|
indexes << {"unneeded_index" => index, "covering_index" => covering_index}
|
147
150
|
end
|
@@ -2,7 +2,10 @@ module PgHero
|
|
2
2
|
module Methods
|
3
3
|
module Replica
|
4
4
|
def replica?
|
5
|
-
|
5
|
+
unless defined?(@replica)
|
6
|
+
@replica = select_all("SELECT setting FROM pg_settings WHERE name = 'hot_standby'").first["setting"] == "on"
|
7
|
+
end
|
8
|
+
@replica
|
6
9
|
end
|
7
10
|
|
8
11
|
# http://www.postgresql.org/message-id/CADKbJJWz9M0swPT3oqe8f9+tfD4-F54uE6Xtkh4nERpVsQnjnw@mail.gmail.com
|
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.6.
|
4
|
+
version: 1.6.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-03-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|