pghero 1.5.2 → 1.5.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 +5 -0
- data/app/controllers/pg_hero/home_controller.rb +1 -1
- data/guides/Docker.md +40 -2
- data/guides/Heroku.md +11 -2
- data/guides/Linux.md +37 -39
- data/guides/Rails.md +102 -104
- data/lib/generators/pghero/templates/query_stats.rb +1 -0
- data/lib/pghero/database.rb +4 -0
- data/lib/pghero/methods/indexes.rb +1 -1
- data/lib/pghero/methods/queries.rb +2 -2
- 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: 822e5e1791b9a405db29590569bad48b312738aa
|
4
|
+
data.tar.gz: 628fdcaad3d38fedd644bd2574582c3676cfb37b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f586c4e66499887b8694463665b0be0bf4b90f4428b470635750cd65d83e1071018730f9954819e8203b8b5cafefad360d254e7e843174c3afb4d3a940ffcd51
|
7
|
+
data.tar.gz: 2a0ef31b0a3a9510ae835535cf9563180974781f9d4d761a2224866a82b5e845ac5750d00709c054700416479bc3492d09d0cc28e978f05cdb76dfd5bc63d628
|
data/CHANGELOG.md
CHANGED
@@ -213,7 +213,7 @@ module PgHero
|
|
213
213
|
if params[:database]
|
214
214
|
@database = PgHero.databases[params[:database]]
|
215
215
|
elsif @databases.size > 1
|
216
|
-
redirect_to url_for(
|
216
|
+
redirect_to url_for(controller: controller_name, action: action_name, database: @databases.first.id)
|
217
217
|
else
|
218
218
|
@database = @databases.first
|
219
219
|
end
|
data/guides/Docker.md
CHANGED
@@ -1,5 +1,43 @@
|
|
1
1
|
# PgHero for Docker
|
2
2
|
|
3
|
-
|
3
|
+
PgHero is available as a [Docker image](https://hub.docker.com/r/ankane/pghero/).
|
4
4
|
|
5
|
-
|
5
|
+
```sh
|
6
|
+
docker run -ti -e DATABASE_URL=postgres://user:password@hostname:5432/dbname -p 8080:8080 ankane/pghero
|
7
|
+
```
|
8
|
+
|
9
|
+
And visit [http://localhost:8080](http://localhost:8080).
|
10
|
+
|
11
|
+
## Query Stats
|
12
|
+
|
13
|
+
Query stats can be enabled from the dashboard. If you run into issues, [view the guide](Query-Stats.md).
|
14
|
+
|
15
|
+
## Historical Query Stats
|
16
|
+
|
17
|
+
To track query stats over time, create a table to store them.
|
18
|
+
|
19
|
+
```sql
|
20
|
+
CREATE TABLE "pghero_query_stats" (
|
21
|
+
"id" serial primary key,
|
22
|
+
"database" text,
|
23
|
+
"user" text,
|
24
|
+
"query" text,
|
25
|
+
"query_hash" bigint,
|
26
|
+
"total_time" float,
|
27
|
+
"calls" bigint,
|
28
|
+
"captured_at" timestamp
|
29
|
+
)
|
30
|
+
CREATE INDEX ON "pghero_query_stats" ("database", "captured_at")
|
31
|
+
```
|
32
|
+
|
33
|
+
Schedule the task below to run every 5 minutes.
|
34
|
+
|
35
|
+
```sh
|
36
|
+
docker run -ti -e DATABASE_URL=... ankane/pghero bin/rake pghero:capture_query_stats
|
37
|
+
```
|
38
|
+
|
39
|
+
After this, a time range slider will appear on the Queries tab.
|
40
|
+
|
41
|
+
## Credits
|
42
|
+
|
43
|
+
Thanks to [Brian Morton](https://github.com/bmorton) for the [original Docker image](https://github.com/bmorton/pghero_solo).
|
data/guides/Heroku.md
CHANGED
@@ -26,8 +26,17 @@ If you run into issues, [view the guide](Query-Stats.md).
|
|
26
26
|
To track query stats over time, create a table to store them.
|
27
27
|
|
28
28
|
```sql
|
29
|
-
CREATE TABLE "pghero_query_stats" (
|
30
|
-
|
29
|
+
CREATE TABLE "pghero_query_stats" (
|
30
|
+
"id" serial primary key,
|
31
|
+
"database" text,
|
32
|
+
"user" text,
|
33
|
+
"query" text,
|
34
|
+
"query_hash" bigint,
|
35
|
+
"total_time" float,
|
36
|
+
"calls" bigint,
|
37
|
+
"captured_at" timestamp
|
38
|
+
)
|
39
|
+
CREATE INDEX ON "pghero_query_stats" ("database", "captured_at")
|
31
40
|
```
|
32
41
|
|
33
42
|
This table can be in the current database or another database. If another database, run:
|
data/guides/Linux.md
CHANGED
@@ -2,19 +2,27 @@
|
|
2
2
|
|
3
3
|
Packaged for:
|
4
4
|
|
5
|
+
- Ubuntu 16.04 (Xenial)
|
5
6
|
- Ubuntu 14.04 (Trusty)
|
6
7
|
- Ubuntu 12.04 (Precise)
|
7
8
|
- Debian 7 (Wheezy)
|
8
9
|
- Debian 8 (Jesse)
|
9
|
-
- CentOS / RHEL 6
|
10
10
|
- CentOS / RHEL 7
|
11
|
-
-
|
12
|
-
- SUSE Linux Enterprise Server
|
11
|
+
- SUSE Linux Enterprise Server 12
|
13
12
|
|
14
13
|
64-bit only
|
15
14
|
|
16
15
|
## Installation
|
17
16
|
|
17
|
+
Ubuntu 16.04 (Xenial)
|
18
|
+
|
19
|
+
```sh
|
20
|
+
wget -qO - https://deb.packager.io/key | sudo apt-key add -
|
21
|
+
echo "deb https://deb.packager.io/gh/pghero/pghero xenial master" | sudo tee /etc/apt/sources.list.d/pghero.list
|
22
|
+
sudo apt-get update
|
23
|
+
sudo apt-get -y install pghero
|
24
|
+
```
|
25
|
+
|
18
26
|
Ubuntu 14.04 (Trusty)
|
19
27
|
|
20
28
|
```sh
|
@@ -36,6 +44,7 @@ sudo apt-get -y install pghero
|
|
36
44
|
Debian 7 (Wheezy)
|
37
45
|
|
38
46
|
```sh
|
47
|
+
sudo apt-get -y install apt-transport-https
|
39
48
|
wget -qO - https://deb.packager.io/key | sudo apt-key add -
|
40
49
|
echo "deb https://deb.packager.io/gh/pghero/pghero wheezy master" | sudo tee /etc/apt/sources.list.d/pghero.list
|
41
50
|
sudo apt-get update
|
@@ -52,17 +61,6 @@ sudo apt-get update
|
|
52
61
|
sudo apt-get -y install pghero
|
53
62
|
```
|
54
63
|
|
55
|
-
CentOS / RHEL 6
|
56
|
-
|
57
|
-
```sh
|
58
|
-
sudo rpm --import https://rpm.packager.io/key
|
59
|
-
echo "[pghero]
|
60
|
-
name=Repository for pghero/pghero application.
|
61
|
-
baseurl=https://rpm.packager.io/gh/pghero/pghero/centos6/master
|
62
|
-
enabled=1" | sudo tee /etc/yum.repos.d/pghero.repo
|
63
|
-
sudo yum install pghero
|
64
|
-
```
|
65
|
-
|
66
64
|
CentOS / RHEL 7
|
67
65
|
|
68
66
|
```sh
|
@@ -71,21 +69,10 @@ echo "[pghero]
|
|
71
69
|
name=Repository for pghero/pghero application.
|
72
70
|
baseurl=https://rpm.packager.io/gh/pghero/pghero/centos7/master
|
73
71
|
enabled=1" | sudo tee /etc/yum.repos.d/pghero.repo
|
74
|
-
sudo yum install pghero
|
72
|
+
sudo yum -y install pghero
|
75
73
|
```
|
76
74
|
|
77
|
-
|
78
|
-
|
79
|
-
```sh
|
80
|
-
sudo rpm --import https://rpm.packager.io/key
|
81
|
-
echo "[pghero]
|
82
|
-
name=Repository for pghero/pghero application.
|
83
|
-
baseurl=https://rpm.packager.io/gh/pghero/pghero/fedora20/master
|
84
|
-
enabled=1" | sudo tee /etc/yum.repos.d/pghero.repo
|
85
|
-
sudo yum install pghero
|
86
|
-
```
|
87
|
-
|
88
|
-
SUSE Linux Enterprise Server
|
75
|
+
SUSE Linux Enterprise Server 12
|
89
76
|
|
90
77
|
```sh
|
91
78
|
sudo rpm --import https://rpm.packager.io/key
|
@@ -108,16 +95,18 @@ sudo pghero config:set PGHERO_USERNAME=link
|
|
108
95
|
sudo pghero config:set PGHERO_PASSWORD=hyrule
|
109
96
|
```
|
110
97
|
|
111
|
-
Start the server
|
98
|
+
Start the server
|
112
99
|
|
113
100
|
```sh
|
101
|
+
sudo pghero config:set PORT=3001
|
102
|
+
sudo pghero config:set RAILS_LOG_TO_STDOUT=disabled
|
114
103
|
sudo pghero scale web=1
|
115
104
|
```
|
116
105
|
|
117
106
|
Confirm it’s running with:
|
118
107
|
|
119
108
|
```sh
|
120
|
-
curl -v http://localhost:
|
109
|
+
curl -v http://localhost:3001/
|
121
110
|
```
|
122
111
|
|
123
112
|
To open to the outside world, add a proxy. Here’s how to do it with Nginx on Ubuntu.
|
@@ -129,7 +118,7 @@ server {
|
|
129
118
|
listen 80;
|
130
119
|
server_name "";
|
131
120
|
location / {
|
132
|
-
proxy_pass http://localhost:
|
121
|
+
proxy_pass http://localhost:3001;
|
133
122
|
}
|
134
123
|
}
|
135
124
|
EOF
|
@@ -145,6 +134,12 @@ sudo service pghero stop
|
|
145
134
|
sudo service pghero restart
|
146
135
|
```
|
147
136
|
|
137
|
+
View logs
|
138
|
+
|
139
|
+
```sh
|
140
|
+
sudo pghero logs
|
141
|
+
```
|
142
|
+
|
148
143
|
## Query Stats
|
149
144
|
|
150
145
|
Query stats can be enabled from the dashboard. If you run into issues, [view the guide](Query-Stats.md).
|
@@ -154,8 +149,17 @@ Query stats can be enabled from the dashboard. If you run into issues, [view the
|
|
154
149
|
To track query stats over time, create a table to store them.
|
155
150
|
|
156
151
|
```sql
|
157
|
-
CREATE TABLE "pghero_query_stats" (
|
158
|
-
|
152
|
+
CREATE TABLE "pghero_query_stats" (
|
153
|
+
"id" serial primary key,
|
154
|
+
"database" text,
|
155
|
+
"user" text,
|
156
|
+
"query" text,
|
157
|
+
"query_hash" bigint,
|
158
|
+
"total_time" float,
|
159
|
+
"calls" bigint,
|
160
|
+
"captured_at" timestamp
|
161
|
+
)
|
162
|
+
CREATE INDEX ON "pghero_query_stats" ("database", "captured_at")
|
159
163
|
```
|
160
164
|
|
161
165
|
This table can be in the current database or another database. If another database, run:
|
@@ -184,12 +188,6 @@ sudo pghero config:set PGHERO_DB_INSTANCE_IDENTIFIER=epona
|
|
184
188
|
|
185
189
|
## Customize
|
186
190
|
|
187
|
-
Change the port - you cannot use a privileged port like `80` or `443`
|
188
|
-
|
189
|
-
```sh
|
190
|
-
sudo pghero config:set PORT=6000 # default
|
191
|
-
```
|
192
|
-
|
193
191
|
Minimum time for long running queries
|
194
192
|
|
195
193
|
```sh
|
@@ -223,7 +221,7 @@ sudo apt-get update
|
|
223
221
|
sudo apt-get install --only-upgrade pghero
|
224
222
|
```
|
225
223
|
|
226
|
-
CentOS
|
224
|
+
CentOS and RHEL
|
227
225
|
|
228
226
|
```sh
|
229
227
|
sudo yum update
|
data/guides/Rails.md
CHANGED
@@ -1,9 +1,5 @@
|
|
1
1
|
# PgHero for Rails
|
2
2
|
|
3
|
-
:gem:
|
4
|
-
|
5
|
-
## Installation
|
6
|
-
|
7
3
|
Add this line to your application’s Gemfile:
|
8
4
|
|
9
5
|
```ruby
|
@@ -28,100 +24,6 @@ gem 'pg_query'
|
|
28
24
|
|
29
25
|
and make sure [query stats](#query-stats) are enabled. Read about how it works [here](Suggested-Indexes.md).
|
30
26
|
|
31
|
-
## Insights
|
32
|
-
|
33
|
-
```ruby
|
34
|
-
PgHero.running_queries
|
35
|
-
PgHero.long_running_queries
|
36
|
-
PgHero.index_usage
|
37
|
-
PgHero.invalid_indexes
|
38
|
-
PgHero.missing_indexes
|
39
|
-
PgHero.unused_indexes
|
40
|
-
PgHero.unused_tables
|
41
|
-
PgHero.database_size
|
42
|
-
PgHero.relation_sizes
|
43
|
-
PgHero.index_hit_rate
|
44
|
-
PgHero.table_hit_rate
|
45
|
-
PgHero.total_connections
|
46
|
-
PgHero.locks
|
47
|
-
```
|
48
|
-
|
49
|
-
Kill queries
|
50
|
-
|
51
|
-
```ruby
|
52
|
-
PgHero.kill(pid)
|
53
|
-
PgHero.kill_long_running_queries
|
54
|
-
PgHero.kill_all
|
55
|
-
```
|
56
|
-
|
57
|
-
Query stats
|
58
|
-
|
59
|
-
```ruby
|
60
|
-
PgHero.query_stats_enabled?
|
61
|
-
PgHero.enable_query_stats
|
62
|
-
PgHero.disable_query_stats
|
63
|
-
PgHero.reset_query_stats
|
64
|
-
PgHero.query_stats
|
65
|
-
PgHero.slow_queries
|
66
|
-
```
|
67
|
-
|
68
|
-
Suggested indexes
|
69
|
-
|
70
|
-
```ruby
|
71
|
-
PgHero.suggested_indexes
|
72
|
-
PgHero.best_index(query)
|
73
|
-
```
|
74
|
-
|
75
|
-
Security
|
76
|
-
|
77
|
-
```ruby
|
78
|
-
PgHero.ssl_used?
|
79
|
-
```
|
80
|
-
|
81
|
-
Replication
|
82
|
-
|
83
|
-
```ruby
|
84
|
-
PgHero.replica?
|
85
|
-
PgHero.replication_lag
|
86
|
-
```
|
87
|
-
|
88
|
-
## Users
|
89
|
-
|
90
|
-
**Note:** It’s unsafe to pass user input to these commands.
|
91
|
-
|
92
|
-
Create a user
|
93
|
-
|
94
|
-
```ruby
|
95
|
-
PgHero.create_user("link")
|
96
|
-
# {password: "zbTrNHk2tvMgNabFgCo0ws7T"}
|
97
|
-
```
|
98
|
-
|
99
|
-
This generates and returns a secure password. The user has full access to the `public` schema.
|
100
|
-
|
101
|
-
Read-only access
|
102
|
-
|
103
|
-
```ruby
|
104
|
-
PgHero.create_user("epona", readonly: true)
|
105
|
-
```
|
106
|
-
|
107
|
-
Set the password
|
108
|
-
|
109
|
-
```ruby
|
110
|
-
PgHero.create_user("zelda", password: "hyrule")
|
111
|
-
```
|
112
|
-
|
113
|
-
Grant access to only certain tables
|
114
|
-
|
115
|
-
```ruby
|
116
|
-
PgHero.create_user("navi", tables: ["triforce"])
|
117
|
-
```
|
118
|
-
|
119
|
-
Drop a user
|
120
|
-
|
121
|
-
```ruby
|
122
|
-
PgHero.drop_user("ganondorf")
|
123
|
-
```
|
124
|
-
|
125
27
|
## Security
|
126
28
|
|
127
29
|
#### Basic Authentication
|
@@ -210,12 +112,6 @@ production:
|
|
210
112
|
<<: *default
|
211
113
|
```
|
212
114
|
|
213
|
-
Specify a database with:
|
214
|
-
|
215
|
-
```ruby
|
216
|
-
PgHero.with(:replica) { PgHero.running_queries }
|
217
|
-
```
|
218
|
-
|
219
115
|
## Customize
|
220
116
|
|
221
117
|
Minimum time for long running queries
|
@@ -242,6 +138,108 @@ Minimum connections for high connections warning
|
|
242
138
|
PgHero.total_connections_threshold = 100 # default
|
243
139
|
```
|
244
140
|
|
141
|
+
## Methods
|
142
|
+
|
143
|
+
Insights
|
144
|
+
|
145
|
+
```ruby
|
146
|
+
PgHero.running_queries
|
147
|
+
PgHero.long_running_queries
|
148
|
+
PgHero.index_usage
|
149
|
+
PgHero.invalid_indexes
|
150
|
+
PgHero.missing_indexes
|
151
|
+
PgHero.unused_indexes
|
152
|
+
PgHero.unused_tables
|
153
|
+
PgHero.database_size
|
154
|
+
PgHero.relation_sizes
|
155
|
+
PgHero.index_hit_rate
|
156
|
+
PgHero.table_hit_rate
|
157
|
+
PgHero.total_connections
|
158
|
+
PgHero.locks
|
159
|
+
```
|
160
|
+
|
161
|
+
Kill queries
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
PgHero.kill(pid)
|
165
|
+
PgHero.kill_long_running_queries
|
166
|
+
PgHero.kill_all
|
167
|
+
```
|
168
|
+
|
169
|
+
Query stats
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
PgHero.query_stats_enabled?
|
173
|
+
PgHero.enable_query_stats
|
174
|
+
PgHero.disable_query_stats
|
175
|
+
PgHero.reset_query_stats
|
176
|
+
PgHero.query_stats
|
177
|
+
PgHero.slow_queries
|
178
|
+
```
|
179
|
+
|
180
|
+
Suggested indexes
|
181
|
+
|
182
|
+
```ruby
|
183
|
+
PgHero.suggested_indexes
|
184
|
+
PgHero.best_index(query)
|
185
|
+
```
|
186
|
+
|
187
|
+
Security
|
188
|
+
|
189
|
+
```ruby
|
190
|
+
PgHero.ssl_used?
|
191
|
+
```
|
192
|
+
|
193
|
+
Replication
|
194
|
+
|
195
|
+
```ruby
|
196
|
+
PgHero.replica?
|
197
|
+
PgHero.replication_lag
|
198
|
+
```
|
199
|
+
|
200
|
+
If you have multiple databases, specify a database with:
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
PgHero.databases["db2"].running_queries
|
204
|
+
```
|
205
|
+
|
206
|
+
## Users
|
207
|
+
|
208
|
+
**Note:** It’s unsafe to pass user input to these commands.
|
209
|
+
|
210
|
+
Create a user
|
211
|
+
|
212
|
+
```ruby
|
213
|
+
PgHero.create_user("link")
|
214
|
+
# {password: "zbTrNHk2tvMgNabFgCo0ws7T"}
|
215
|
+
```
|
216
|
+
|
217
|
+
This generates and returns a secure password. The user has full access to the `public` schema.
|
218
|
+
|
219
|
+
Read-only access
|
220
|
+
|
221
|
+
```ruby
|
222
|
+
PgHero.create_user("epona", readonly: true)
|
223
|
+
```
|
224
|
+
|
225
|
+
Set the password
|
226
|
+
|
227
|
+
```ruby
|
228
|
+
PgHero.create_user("zelda", password: "hyrule")
|
229
|
+
```
|
230
|
+
|
231
|
+
Grant access to only certain tables
|
232
|
+
|
233
|
+
```ruby
|
234
|
+
PgHero.create_user("navi", tables: ["triforce"])
|
235
|
+
```
|
236
|
+
|
237
|
+
Drop a user
|
238
|
+
|
239
|
+
```ruby
|
240
|
+
PgHero.drop_user("ganondorf")
|
241
|
+
```
|
242
|
+
|
245
243
|
## Upgrading
|
246
244
|
|
247
245
|
### 1.5.0
|
data/lib/pghero/database.rb
CHANGED
@@ -51,6 +51,10 @@ module PgHero
|
|
51
51
|
(config["slow_query_calls"] || PgHero.config["slow_query_calls"] || PgHero.slow_query_calls).to_i
|
52
52
|
end
|
53
53
|
|
54
|
+
def long_running_query_sec
|
55
|
+
(config["long_running_query_sec"] || PgHero.config["long_running_query_sec"] || PgHero.long_running_query_sec).to_i
|
56
|
+
end
|
57
|
+
|
54
58
|
private
|
55
59
|
|
56
60
|
def connection_model
|
@@ -141,7 +141,7 @@ module PgHero
|
|
141
141
|
|
142
142
|
indexes_by_table = self.indexes.group_by { |i| i["table"] }
|
143
143
|
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"] && PgHero.truthy?(i["valid"]) }
|
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"]) }
|
145
145
|
if covering_index
|
146
146
|
indexes << {"unneeded_index" => index, "covering_index" => covering_index}
|
147
147
|
end
|
@@ -27,12 +27,12 @@ module PgHero
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def long_running_queries
|
30
|
-
running_queries(min_duration:
|
30
|
+
running_queries(min_duration: long_running_query_sec)
|
31
31
|
end
|
32
32
|
|
33
33
|
def slow_queries(options = {})
|
34
34
|
query_stats = options[:query_stats] || self.query_stats(options.except(:query_stats))
|
35
|
-
query_stats.select { |q| q["calls"].to_i >=
|
35
|
+
query_stats.select { |q| q["calls"].to_i >= slow_query_calls.to_i && q["average_time"].to_i >= slow_query_ms.to_i }
|
36
36
|
end
|
37
37
|
|
38
38
|
def locks
|
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.5.
|
4
|
+
version: 1.5.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: 2016-10-
|
11
|
+
date: 2016-10-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|