pghero 2.0.2 → 2.0.3
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 +6 -0
- data/app/assets/images/pghero/favicon.png +0 -0
- data/app/assets/stylesheets/pghero/application.css +6 -0
- data/app/controllers/pg_hero/home_controller.rb +2 -1
- data/app/views/layouts/pg_hero/application.html.erb +1 -0
- data/app/views/pg_hero/home/_queries_table.html.erb +1 -1
- data/app/views/pg_hero/home/index.html.erb +12 -1
- data/app/views/pg_hero/home/index_bloat.html.erb +4 -1
- data/app/views/pg_hero/home/space.html.erb +2 -2
- data/guides/Docker.md +16 -4
- data/guides/Linux.md +41 -48
- data/guides/Rails.md +5 -12
- data/lib/pghero.rb +2 -1
- data/lib/pghero/methods/indexes.rb +19 -5
- data/lib/pghero/methods/query_stats.rb +3 -1
- data/lib/pghero/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1a3cb7c5c2090aa6b4dcc0fb11aca000945a5a4
|
4
|
+
data.tar.gz: 2304979bb7676c7a346bfbd490e697f16379f8bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cb6cc9c80f2ea049225b3f8d4da5eefb7d3ac754a33ba6da644fff7adbb385626f4f5967fb9e91bb3328575d42e52a064c9d7d5cef43273b8d7ac894155c4197
|
7
|
+
data.tar.gz: 964c90c704e2049d3d2a47cad1479146409a0ad49ffa7a1436dc913ac8cbb992dd101cf3021ba288dbfc45736bd2c3b4f687627fbd9b5373fe24bb54cb631a5e
|
data/CHANGELOG.md
CHANGED
Binary file
|
@@ -76,7 +76,8 @@ module PgHero
|
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
-
|
79
|
+
across = params[:across].to_s.split(",")
|
80
|
+
@unused_indexes = @database.unused_indexes(max_scans: 0, across: across)
|
80
81
|
@unused_index_names = Set.new(@unused_indexes.map { |r| r[:index] })
|
81
82
|
@show_migrations = PgHero.show_migrations
|
82
83
|
@system_stats_enabled = @database.system_stats_enabled?
|
@@ -4,6 +4,7 @@
|
|
4
4
|
<title><%= [@databases.size > 1 ? @database.name : "PgHero", @title].compact.join(" / ") %></title>
|
5
5
|
|
6
6
|
<meta charset="utf-8" />
|
7
|
+
<%= favicon_link_tag "pghero/favicon.png" %>
|
7
8
|
<%= stylesheet_link_tag "pghero/application" %>
|
8
9
|
<%= javascript_include_tag "pghero/application" %>
|
9
10
|
</head>
|
@@ -247,7 +247,18 @@
|
|
247
247
|
<tbody>
|
248
248
|
<% @invalid_indexes.each do |index| %>
|
249
249
|
<tr>
|
250
|
-
<td
|
250
|
+
<td>
|
251
|
+
<%= index[:name] %>
|
252
|
+
<% if index[:schema] != "public" %>
|
253
|
+
<span class="text-muted"><%= query[:schema] %></span>
|
254
|
+
<% end %>
|
255
|
+
</td>
|
256
|
+
</tr>
|
257
|
+
<tr>
|
258
|
+
<td style="border-top: none; padding: 0;">
|
259
|
+
<pre><code>DROP INDEX CONCURRENTLY <%= pghero_pretty_ident(index[:name], schema: index[:schema]) %>;
|
260
|
+
<%= index[:definition].sub("CREATE INDEX ", "CREATE INDEX CONCURRENTLY ") %>;</code></pre>
|
261
|
+
</td>
|
251
262
|
</tr>
|
252
263
|
<% end %>
|
253
264
|
</tbody>
|
@@ -34,11 +34,14 @@ ALTER INDEX new_index RENAME TO index;</code></pre>
|
|
34
34
|
<tr>
|
35
35
|
<td>
|
36
36
|
<span style="word-break: break-all;"><%= index[:index] %></span>
|
37
|
+
<% if index[:primary] %>
|
38
|
+
<span class="primary-key">PRIMARY</span>
|
39
|
+
<% end %>
|
37
40
|
</td>
|
38
41
|
<td><%= PgHero.pretty_size(index[:bloat_bytes]) %></td>
|
39
42
|
<td><%= PgHero.pretty_size(index[:index_bytes]) %></td>
|
40
43
|
</tr>
|
41
|
-
<% if @show_sql %>
|
44
|
+
<% if @show_sql && !index[:primary] %>
|
42
45
|
<tr>
|
43
46
|
<td colspan="3" style="border-top: none; padding: 0;">
|
44
47
|
<% new_index = "new_#{index[:index]}".first(63) %>
|
@@ -32,7 +32,7 @@
|
|
32
32
|
<div id="migration" style="display: none;">
|
33
33
|
<pre>rails g migration remove_unused_indexes</pre>
|
34
34
|
<p>And paste</p>
|
35
|
-
<pre style="overflow: scroll; white-space: pre; word-break: normal;"><% @unused_indexes.sort_by { |q| q[:index] }.each do |query| %>
|
35
|
+
<pre style="overflow: scroll; white-space: pre; word-break: normal;"><% @unused_indexes.sort_by { |q| [-q[:size_bytes], q[:index]] }.each do |query| %>
|
36
36
|
remove_index <%= query[:table].to_sym.inspect %>, name: <%= query[:index].to_s.inspect %><% end %></pre>
|
37
37
|
</div>
|
38
38
|
<% end %>
|
@@ -62,7 +62,7 @@ remove_index <%= query[:table].to_sym.inspect %>, name: <%= query[:index].to_s.i
|
|
62
62
|
<% if query[:schema] != "public" %>
|
63
63
|
<span class="text-muted"><%= query[:schema] %></span>
|
64
64
|
<% end %>
|
65
|
-
<% if @unused_index_names.include?(query[:
|
65
|
+
<% if @unused_index_names.include?(query[:relation]) %>
|
66
66
|
<span class="unused-index">UNUSED</span>
|
67
67
|
<% end %>
|
68
68
|
</td>
|
data/guides/Docker.md
CHANGED
@@ -26,8 +26,8 @@ CREATE TABLE "pghero_query_stats" (
|
|
26
26
|
"total_time" float,
|
27
27
|
"calls" bigint,
|
28
28
|
"captured_at" timestamp
|
29
|
-
)
|
30
|
-
CREATE INDEX ON "pghero_query_stats" ("database", "captured_at")
|
29
|
+
);
|
30
|
+
CREATE INDEX ON "pghero_query_stats" ("database", "captured_at");
|
31
31
|
```
|
32
32
|
|
33
33
|
Schedule the task below to run every 5 minutes.
|
@@ -50,8 +50,8 @@ CREATE TABLE "pghero_space_stats" (
|
|
50
50
|
"relation" text,
|
51
51
|
"size" bigint,
|
52
52
|
"captured_at" timestamp
|
53
|
-
)
|
54
|
-
CREATE INDEX ON "pghero_space_stats" ("database", "captured_at")
|
53
|
+
);
|
54
|
+
CREATE INDEX ON "pghero_space_stats" ("database", "captured_at");
|
55
55
|
```
|
56
56
|
|
57
57
|
Schedule the task below to run once a day.
|
@@ -60,6 +60,18 @@ Schedule the task below to run once a day.
|
|
60
60
|
docker run -ti -e DATABASE_URL=... ankane/pghero bin/rake pghero:capture_space_stats
|
61
61
|
```
|
62
62
|
|
63
|
+
## Multiple Databases
|
64
|
+
|
65
|
+
Create a file at `/app/config/pghero.yml` with:
|
66
|
+
|
67
|
+
```yml
|
68
|
+
databases:
|
69
|
+
primary:
|
70
|
+
url: postgres://...
|
71
|
+
replica:
|
72
|
+
url: postgres://...
|
73
|
+
```
|
74
|
+
|
63
75
|
## Credits
|
64
76
|
|
65
77
|
Thanks to [Brian Morton](https://github.com/bmorton) for the [original Docker image](https://github.com/bmorton/pghero_solo).
|
data/guides/Linux.md
CHANGED
@@ -1,82 +1,73 @@
|
|
1
1
|
# PgHero for Linux
|
2
2
|
|
3
|
-
|
3
|
+
Distributions
|
4
4
|
|
5
|
-
- Ubuntu 16.04 (Xenial)
|
6
|
-
- Ubuntu 14.04 (Trusty)
|
7
|
-
-
|
8
|
-
- Debian 7 (Wheezy)
|
9
|
-
-
|
10
|
-
-
|
11
|
-
- SUSE Linux Enterprise Server 12
|
5
|
+
- [Ubuntu 16.04 (Xenial)](#ubuntu-1604-xenial)
|
6
|
+
- [Ubuntu 14.04 (Trusty)](#ubuntu-1404-trusty)
|
7
|
+
- [Debian 8 (Jesse)](#debian-8-jesse)
|
8
|
+
- [Debian 7 (Wheezy)](#debian-7-wheezy)
|
9
|
+
- [CentOS / RHEL 7](#centos--rhel-7)
|
10
|
+
- [SUSE Linux Enterprise Server 12](#suse-linux-enterprise-server-12)
|
12
11
|
|
13
12
|
64-bit only
|
14
13
|
|
15
14
|
## Installation
|
16
15
|
|
17
|
-
Ubuntu 16.04 (Xenial)
|
16
|
+
### Ubuntu 16.04 (Xenial)
|
18
17
|
|
19
18
|
```sh
|
20
|
-
wget -qO
|
21
|
-
|
19
|
+
wget -qO- https://dl.packager.io/srv/pghero/pghero/key | sudo apt-key add -
|
20
|
+
sudo wget -O /etc/apt/sources.list.d/pghero.list \
|
21
|
+
https://dl.packager.io/srv/pghero/pghero/master/installer/ubuntu/16.04.repo
|
22
22
|
sudo apt-get update
|
23
23
|
sudo apt-get -y install pghero
|
24
24
|
```
|
25
25
|
|
26
|
-
Ubuntu 14.04 (Trusty)
|
26
|
+
### Ubuntu 14.04 (Trusty)
|
27
27
|
|
28
28
|
```sh
|
29
|
-
wget -qO
|
30
|
-
|
29
|
+
wget -qO- https://dl.packager.io/srv/pghero/pghero/key | sudo apt-key add -
|
30
|
+
sudo wget -O /etc/apt/sources.list.d/pghero.list \
|
31
|
+
https://dl.packager.io/srv/pghero/pghero/master/installer/ubuntu/14.04.repo
|
31
32
|
sudo apt-get update
|
32
33
|
sudo apt-get -y install pghero
|
33
34
|
```
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
```sh
|
38
|
-
wget -qO - https://deb.packager.io/key | sudo apt-key add -
|
39
|
-
echo "deb https://deb.packager.io/gh/pghero/pghero precise master" | sudo tee /etc/apt/sources.list.d/pghero.list
|
40
|
-
sudo apt-get update
|
41
|
-
sudo apt-get -y install pghero
|
42
|
-
```
|
43
|
-
|
44
|
-
Debian 7 (Wheezy)
|
36
|
+
### Debian 8 (Jesse)
|
45
37
|
|
46
38
|
```sh
|
47
39
|
sudo apt-get -y install apt-transport-https
|
48
|
-
wget -qO
|
49
|
-
|
40
|
+
wget -qO- https://dl.packager.io/srv/pghero/pghero/key | sudo apt-key add -
|
41
|
+
sudo wget -O /etc/apt/sources.list.d/pghero.list \
|
42
|
+
https://dl.packager.io/srv/pghero/pghero/master/installer/debian/8.repo
|
50
43
|
sudo apt-get update
|
51
44
|
sudo apt-get -y install pghero
|
52
45
|
```
|
53
46
|
|
54
|
-
Debian
|
47
|
+
### Debian 7 (Wheezy)
|
55
48
|
|
56
49
|
```sh
|
57
50
|
sudo apt-get -y install apt-transport-https
|
58
|
-
wget -qO
|
59
|
-
|
51
|
+
wget -qO- https://dl.packager.io/srv/pghero/pghero/key | sudo apt-key add -
|
52
|
+
sudo wget -O /etc/apt/sources.list.d/pghero.list \
|
53
|
+
https://dl.packager.io/srv/pghero/pghero/master/installer/debian/7.repo
|
60
54
|
sudo apt-get update
|
61
55
|
sudo apt-get -y install pghero
|
62
56
|
```
|
63
57
|
|
64
|
-
CentOS / RHEL 7
|
58
|
+
### CentOS / RHEL 7
|
65
59
|
|
66
60
|
```sh
|
67
|
-
sudo
|
68
|
-
|
69
|
-
name=Repository for pghero/pghero application.
|
70
|
-
baseurl=https://rpm.packager.io/gh/pghero/pghero/centos7/master
|
71
|
-
enabled=1" | sudo tee /etc/yum.repos.d/pghero.repo
|
61
|
+
sudo wget -O /etc/yum.repos.d/pghero.repo \
|
62
|
+
https://dl.packager.io/srv/pghero/pghero/master/installer/el/7.repo
|
72
63
|
sudo yum -y install pghero
|
73
64
|
```
|
74
65
|
|
75
|
-
SUSE Linux Enterprise Server 12
|
66
|
+
### SUSE Linux Enterprise Server 12
|
76
67
|
|
77
68
|
```sh
|
78
|
-
sudo
|
79
|
-
|
69
|
+
sudo wget -O /etc/zypp/repos.d/pghero.repo \
|
70
|
+
https://dl.packager.io/srv/pghero/pghero/master/installer/sles/12.repo
|
80
71
|
sudo zypper install pghero
|
81
72
|
```
|
82
73
|
|
@@ -158,8 +149,8 @@ CREATE TABLE "pghero_query_stats" (
|
|
158
149
|
"total_time" float,
|
159
150
|
"calls" bigint,
|
160
151
|
"captured_at" timestamp
|
161
|
-
)
|
162
|
-
CREATE INDEX ON "pghero_query_stats" ("database", "captured_at")
|
152
|
+
);
|
153
|
+
CREATE INDEX ON "pghero_query_stats" ("database", "captured_at");
|
163
154
|
```
|
164
155
|
|
165
156
|
This table can be in the current database or another database. If another database, run:
|
@@ -188,8 +179,8 @@ CREATE TABLE "pghero_space_stats" (
|
|
188
179
|
"relation" text,
|
189
180
|
"size" bigint,
|
190
181
|
"captured_at" timestamp
|
191
|
-
)
|
192
|
-
CREATE INDEX ON "pghero_space_stats" ("database", "captured_at")
|
182
|
+
);
|
183
|
+
CREATE INDEX ON "pghero_space_stats" ("database", "captured_at");
|
193
184
|
```
|
194
185
|
|
195
186
|
Schedule the task below to run once a day.
|
@@ -212,12 +203,11 @@ sudo pghero config:set PGHERO_DB_INSTANCE_IDENTIFIER=epona
|
|
212
203
|
Create a `pghero.yml` with:
|
213
204
|
|
214
205
|
```yml
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
url: postgres://...
|
206
|
+
databases:
|
207
|
+
primary:
|
208
|
+
url: postgres://...
|
209
|
+
replica:
|
210
|
+
url: postgres://...
|
221
211
|
```
|
222
212
|
|
223
213
|
And run:
|
@@ -260,6 +250,7 @@ Ubuntu and Debian
|
|
260
250
|
```sh
|
261
251
|
sudo apt-get update
|
262
252
|
sudo apt-get install --only-upgrade pghero
|
253
|
+
sudo service pghero restart
|
263
254
|
```
|
264
255
|
|
265
256
|
CentOS and RHEL
|
@@ -267,12 +258,14 @@ CentOS and RHEL
|
|
267
258
|
```sh
|
268
259
|
sudo yum update
|
269
260
|
sudo yum install pghero
|
261
|
+
sudo service pghero restart
|
270
262
|
```
|
271
263
|
|
272
264
|
SUSE
|
273
265
|
|
274
266
|
```sh
|
275
267
|
sudo zypper update pghero
|
268
|
+
sudo service pghero restart
|
276
269
|
```
|
277
270
|
|
278
271
|
## Credits
|
data/guides/Rails.md
CHANGED
@@ -118,18 +118,11 @@ PGHERO_DB_INSTANCE_IDENTIFIER=epona
|
|
118
118
|
Create `config/pghero.yml` with:
|
119
119
|
|
120
120
|
```yml
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
url: <%= ENV["REPLICA_DATABASE_URL"] %>
|
127
|
-
|
128
|
-
development:
|
129
|
-
<<: *default
|
130
|
-
|
131
|
-
production:
|
132
|
-
<<: *default
|
121
|
+
databases:
|
122
|
+
primary:
|
123
|
+
url: <%= ENV["PGHERO_DATABASE_URL"] %>
|
124
|
+
replica:
|
125
|
+
url: <%= ENV["REPLICA_DATABASE_URL"] %>
|
133
126
|
```
|
134
127
|
|
135
128
|
## Customize
|
data/lib/pghero.rb
CHANGED
@@ -68,8 +68,8 @@ module PgHero
|
|
68
68
|
SQL
|
69
69
|
end
|
70
70
|
|
71
|
-
def unused_indexes(max_scans: 50)
|
72
|
-
select_all_size <<-SQL
|
71
|
+
def unused_indexes(max_scans: 50, across: [])
|
72
|
+
result = select_all_size <<-SQL
|
73
73
|
SELECT
|
74
74
|
schemaname AS schema,
|
75
75
|
relname AS table,
|
@@ -87,6 +87,15 @@ module PgHero
|
|
87
87
|
pg_relation_size(i.indexrelid) DESC,
|
88
88
|
relname ASC
|
89
89
|
SQL
|
90
|
+
|
91
|
+
across.each do |database_id|
|
92
|
+
database = PgHero.databases.values.find { |d| d.id == database_id }
|
93
|
+
raise PgHero::Error, "Database not found: #{database_id}" unless database
|
94
|
+
across_result = Set.new(database.unused_indexes(max_scans: max_scans).map { |v| [v[:schema], v[:index]] })
|
95
|
+
result.select! { |v| across_result.include?([v[:schema], v[:index]]) }
|
96
|
+
end
|
97
|
+
|
98
|
+
result
|
90
99
|
end
|
91
100
|
|
92
101
|
def reset_stats
|
@@ -108,7 +117,9 @@ module PgHero
|
|
108
117
|
def invalid_indexes
|
109
118
|
select_all <<-SQL
|
110
119
|
SELECT
|
111
|
-
|
120
|
+
n.nspname AS schema,
|
121
|
+
c.relname AS index,
|
122
|
+
pg_get_indexdef(i.indexrelid) AS definition
|
112
123
|
FROM
|
113
124
|
pg_catalog.pg_class c,
|
114
125
|
pg_catalog.pg_namespace n,
|
@@ -297,9 +308,12 @@ module PgHero
|
|
297
308
|
index_name AS index,
|
298
309
|
wastedbytes AS bloat_bytes,
|
299
310
|
totalbytes AS index_bytes,
|
300
|
-
pg_get_indexdef(indexrelid) AS definition
|
311
|
+
pg_get_indexdef(rb.indexrelid) AS definition,
|
312
|
+
indisprimary AS primary
|
301
313
|
FROM
|
302
|
-
raw_bloat
|
314
|
+
raw_bloat rb
|
315
|
+
INNER JOIN
|
316
|
+
pg_index i ON i.indexrelid = rb.indexrelid
|
303
317
|
WHERE
|
304
318
|
wastedbytes >= #{min_size.to_i}
|
305
319
|
ORDER BY
|
@@ -103,6 +103,8 @@ module PgHero
|
|
103
103
|
query_stats[database_id] = query_stats(limit: 1000000, database: database_name)
|
104
104
|
end
|
105
105
|
|
106
|
+
supports_query_hash = supports_query_hash?
|
107
|
+
|
106
108
|
if query_stats.any? { |_, v| v.any? } && reset_query_stats
|
107
109
|
query_stats.each do |db_id, db_query_stats|
|
108
110
|
if db_query_stats.any?
|
@@ -114,7 +116,7 @@ module PgHero
|
|
114
116
|
qs[:total_minutes] * 60 * 1000,
|
115
117
|
qs[:calls],
|
116
118
|
now,
|
117
|
-
qs[:query_hash],
|
119
|
+
supports_query_hash ? qs[:query_hash] : nil,
|
118
120
|
qs[:user]
|
119
121
|
]
|
120
122
|
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: 2.0.
|
4
|
+
version: 2.0.3
|
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-08-
|
11
|
+
date: 2017-08-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -122,6 +122,7 @@ files:
|
|
122
122
|
- LICENSE.txt
|
123
123
|
- README.md
|
124
124
|
- Rakefile
|
125
|
+
- app/assets/images/pghero/favicon.png
|
125
126
|
- app/assets/javascripts/pghero/Chart.bundle.js
|
126
127
|
- app/assets/javascripts/pghero/application.js
|
127
128
|
- app/assets/javascripts/pghero/chartkick.js
|