pghero 2.1.1 → 2.2.0
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 +8 -0
- data/CONTRIBUTING.md +9 -7
- data/README.md +6 -4
- data/app/controllers/pg_hero/home_controller.rb +10 -2
- data/app/views/pg_hero/home/explain.html.erb +1 -1
- data/app/views/pg_hero/home/index.html.erb +16 -6
- data/lib/generators/pghero/templates/{config.yml → config.yml.tt} +3 -3
- data/lib/generators/pghero/templates/{query_stats.rb → query_stats.rb.tt} +0 -0
- data/lib/generators/pghero/templates/{space_stats.rb → space_stats.rb.tt} +0 -0
- data/lib/pghero.rb +2 -2
- data/lib/pghero/methods/connections.rb +16 -0
- data/lib/pghero/methods/indexes.rb +32 -26
- data/lib/pghero/methods/maintenance.rb +1 -1
- data/lib/pghero/methods/query_stats.rb +2 -2
- data/lib/pghero/methods/replication.rb +1 -1
- data/lib/pghero/methods/sequences.rb +6 -2
- data/lib/pghero/methods/suggested_indexes.rb +1 -5
- data/lib/pghero/version.rb +1 -1
- metadata +9 -45
- data/.gitattributes +0 -1
- data/.github/ISSUE_TEMPLATE.md +0 -7
- data/.gitignore +0 -22
- data/.travis.yml +0 -16
- data/Gemfile +0 -6
- data/Rakefile +0 -8
- data/guides/Contributing.md +0 -16
- data/guides/Docker.md +0 -89
- data/guides/Heroku.md +0 -102
- data/guides/Linux.md +0 -296
- data/guides/Permissions.md +0 -57
- data/guides/Query-Stats.md +0 -60
- data/guides/Rails.md +0 -339
- data/guides/Suggested-Indexes.md +0 -19
- data/pghero.gemspec +0 -35
- data/test/basic_test.rb +0 -38
- data/test/best_index_test.rb +0 -180
- data/test/gemfiles/activerecord41.gemfile +0 -6
- data/test/gemfiles/activerecord42.gemfile +0 -6
- data/test/suggested_indexes_test.rb +0 -18
- data/test/test_helper.rb +0 -66
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 344a413582024c07e65a19f69e4e5a8aa5bd9024d40ce82357ce234349c8f52f
|
4
|
+
data.tar.gz: a9c4c8f537f9e2067582d9dba2b44f7fd83b43ed8ab6cc5aeaeaa04107087e96
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b7999bab7e77cba83016ed05dde01778f4e79cbe4fa5982750dfedfe46c74438f2700d13ff8e07744c92f1a4c87b2c740bf455921d6004f047a57d2aa982720
|
7
|
+
data.tar.gz: eb91e9b0f35115de7369e521cfa5c0c39854f4d2e8ea650782af2fd28a465e825daa5f7a1f485b6944c00dc7f14855524c034cd7f953d93a4f55718d43110183
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## 2.2.0
|
2
|
+
|
3
|
+
- Added check for connections idle in transaction
|
4
|
+
- Improved duplicate index logic to detect more duplicates
|
5
|
+
- Don't report concurrent indexes in-progress as invalid on dashboard
|
6
|
+
- Fixed error with large number of sequences
|
7
|
+
- Bumped `total_connections_threshold` to 500 by default
|
8
|
+
|
1
9
|
## 2.1.1
|
2
10
|
|
3
11
|
- Added `explain_timeout_sec` option
|
data/CONTRIBUTING.md
CHANGED
@@ -2,17 +2,15 @@
|
|
2
2
|
|
3
3
|
First, thanks for wanting to contribute. You’re awesome! :heart:
|
4
4
|
|
5
|
-
##
|
5
|
+
## Help
|
6
6
|
|
7
|
-
|
7
|
+
We’re not able to provide support through GitHub Issues. If you’re looking for help with your code, try posting on [Stack Overflow](https://stackoverflow.com/).
|
8
8
|
|
9
|
-
|
9
|
+
All features should be documented. If you don’t see a feature in the docs, assume it doesn’t exist.
|
10
10
|
|
11
|
-
|
11
|
+
## Bugs
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
Think you’ve discovered an issue?
|
13
|
+
Think you’ve discovered a bug?
|
16
14
|
|
17
15
|
1. Search existing issues to see if it’s been reported.
|
18
16
|
2. Try the `master` branch to make sure it hasn’t been fixed.
|
@@ -26,6 +24,10 @@ If the above steps don’t help, create an issue. Include:
|
|
26
24
|
- Detailed steps to reproduce
|
27
25
|
- Complete backtraces for exceptions
|
28
26
|
|
27
|
+
## New Features
|
28
|
+
|
29
|
+
If you’d like to discuss a new feature, create an issue and start the title with `[Idea]`.
|
30
|
+
|
29
31
|
## Pull Requests
|
30
32
|
|
31
33
|
Fork the project and create a pull request. A few tips:
|
data/README.md
CHANGED
@@ -1,14 +1,16 @@
|
|
1
1
|
# PgHero
|
2
2
|
|
3
|
-
A performance dashboard for Postgres
|
3
|
+
A performance dashboard for Postgres
|
4
4
|
|
5
5
|
[See it in action](https://pghero.dokkuapp.com/)
|
6
6
|
|
7
|
-
|
7
|
+
---
|
8
|
+
|
9
|
+
**NEW** PgHero is also available as a [hosted service](https://pghero.org). Get real-time alerts, single sign-on, and more :tada:
|
8
10
|
|
9
|
-
|
11
|
+
---
|
10
12
|
|
11
|
-
|
13
|
+
[![Screenshot](https://pghero.dokkuapp.com/assets/screenshot-5a368624ada55b32e7668c96926840f9.png)](https://pghero.dokkuapp.com/)
|
12
14
|
|
13
15
|
## Installation
|
14
16
|
|
@@ -33,8 +33,12 @@ module PgHero
|
|
33
33
|
|
34
34
|
@autovacuum_queries, @long_running_queries = @database.long_running_queries.partition { |q| q[:query].starts_with?("autovacuum:") }
|
35
35
|
|
36
|
-
|
36
|
+
connection_states = @database.connection_states
|
37
|
+
@total_connections = connection_states.values.sum
|
38
|
+
@idle_connections = connection_states["idle in transaction"].to_i
|
39
|
+
|
37
40
|
@good_total_connections = @total_connections < @database.total_connections_threshold
|
41
|
+
@good_idle_connections = @idle_connections < 100
|
38
42
|
|
39
43
|
@transaction_id_danger = @database.transaction_id_danger(threshold: 1500000000)
|
40
44
|
|
@@ -43,7 +47,7 @@ module PgHero
|
|
43
47
|
@sequence_danger = @database.sequence_danger(threshold: (params[:sequence_threshold] || 0.9).to_f, sequences: @readable_sequences)
|
44
48
|
|
45
49
|
@indexes = @database.indexes
|
46
|
-
@invalid_indexes = @indexes
|
50
|
+
@invalid_indexes = @database.invalid_indexes(indexes: @indexes)
|
47
51
|
@duplicate_indexes = @database.duplicate_indexes(indexes: @indexes)
|
48
52
|
|
49
53
|
if @query_stats_enabled
|
@@ -109,6 +113,10 @@ module PgHero
|
|
109
113
|
@title = "Live Queries"
|
110
114
|
@running_queries = @database.running_queries(all: true)
|
111
115
|
@vacuum_progress = @database.vacuum_progress.index_by { |q| q[:pid] }
|
116
|
+
|
117
|
+
if params[:state]
|
118
|
+
@running_queries.select! { |q| q[:state] == params[:state] }
|
119
|
+
end
|
112
120
|
end
|
113
121
|
|
114
122
|
def queries
|
@@ -12,7 +12,7 @@
|
|
12
12
|
|
13
13
|
<% if @explanation %>
|
14
14
|
<% if @visualize %>
|
15
|
-
<p>Paste the output below into the <%= link_to "Postgres Explain Visualizer", "
|
15
|
+
<p>Paste the output below into the <%= link_to "Postgres Explain Visualizer", "https://tatiyants.com/pev/#/plans/new", target: "_blank" %></p>
|
16
16
|
<% end %>
|
17
17
|
<pre><code><%= @explanation %></code></pre>
|
18
18
|
<% unless @visualize %>
|
@@ -36,13 +36,14 @@
|
|
36
36
|
<% end %>
|
37
37
|
</div>
|
38
38
|
<% end %>
|
39
|
-
<div class="alert alert-<%= @good_total_connections ? "success" : "warning" %>">
|
40
|
-
<% if
|
41
|
-
|
39
|
+
<div class="alert alert-<%= @good_total_connections && @good_idle_connections ? "success" : "warning" %>">
|
40
|
+
<% if !@good_total_connections %>
|
41
|
+
High number of connections <span class="tiny"><%= @total_connections %></span>
|
42
|
+
<% elsif !@good_idle_connections %>
|
43
|
+
High number of connections idle in transaction <span class="tiny"><%= @idle_connections %></span>
|
42
44
|
<% else %>
|
43
|
-
|
45
|
+
Connections healthy <span class="tiny"><%= @total_connections %></span>
|
44
46
|
<% end %>
|
45
|
-
<span class="tiny"><%= @total_connections %></span>
|
46
47
|
</div>
|
47
48
|
<div class="alert alert-<%= @transaction_id_danger.empty? ? "success" : "warning" %>">
|
48
49
|
<% if @transaction_id_danger.any? %>
|
@@ -217,10 +218,19 @@
|
|
217
218
|
</div>
|
218
219
|
<% end %>
|
219
220
|
|
221
|
+
<% if !@good_idle_connections %>
|
222
|
+
<div class="content">
|
223
|
+
<h1>High Number of Connections Idle in Transaction</h1>
|
224
|
+
<p><%= pluralize(@idle_connections, "connection") %> idle in transaction</p>
|
225
|
+
<p>Avoid opening transactions and doing work outside the database.</p>
|
226
|
+
<p><%= link_to "View queries", live_queries_path(state: "idle in transaction") %></p>
|
227
|
+
</div>
|
228
|
+
<% end %>
|
229
|
+
|
220
230
|
<% if @transaction_id_danger.any? %>
|
221
231
|
<div class="content">
|
222
232
|
<h2>Vacuuming Needed</h2>
|
223
|
-
<p>The database <strong>will shutdown</strong> when there are fewer than 1,000,000 transactions left. <%= link_to "Read more", "
|
233
|
+
<p>The database <strong>will shutdown</strong> when there are fewer than 1,000,000 transactions left. <%= link_to "Read more", "https://www.postgresql.org/docs/current/static/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND", target: "_blank" %>.</p>
|
224
234
|
|
225
235
|
<p>Try <%= link_to "tuning autovacuum", "https://blog.2ndquadrant.com/autovacuum-tuning-basics/", target: "_blank" %> - specifically autovacuum_vacuum_cost_limit.</p>
|
226
236
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
databases:
|
2
2
|
main:
|
3
3
|
# Database URL (defaults to app database)
|
4
|
-
# url:
|
4
|
+
# url: <%%= ENV["DATABASE_URL"] %>
|
5
5
|
|
6
6
|
# Minimum time for long running queries
|
7
7
|
# long_running_query_sec: 60
|
@@ -13,14 +13,14 @@ databases:
|
|
13
13
|
# slow_query_calls: 100
|
14
14
|
|
15
15
|
# Minimum connections for high connections warning
|
16
|
-
# total_connections_threshold:
|
16
|
+
# total_connections_threshold: 500
|
17
17
|
|
18
18
|
# Statement timeout for explain
|
19
19
|
# explain_timeout_sec: 10
|
20
20
|
|
21
21
|
# Add more databases
|
22
22
|
# other:
|
23
|
-
# url:
|
23
|
+
# url: <%%= ENV["OTHER_DATABASE_URL"] %>
|
24
24
|
|
25
25
|
# Time zone (defaults to app time zone)
|
26
26
|
# time_zone: "Pacific Time (US & Canada)"
|
File without changes
|
File without changes
|
data/lib/pghero.rb
CHANGED
@@ -38,7 +38,7 @@ module PgHero
|
|
38
38
|
self.slow_query_ms = (ENV["PGHERO_SLOW_QUERY_MS"] || 20).to_i
|
39
39
|
self.slow_query_calls = (ENV["PGHERO_SLOW_QUERY_CALLS"] || 100).to_i
|
40
40
|
self.explain_timeout_sec = (ENV["PGHERO_EXPLAIN_TIMEOUT_SEC"] || 10).to_i
|
41
|
-
self.total_connections_threshold = (ENV["PGHERO_TOTAL_CONNECTIONS_THRESHOLD"] ||
|
41
|
+
self.total_connections_threshold = (ENV["PGHERO_TOTAL_CONNECTIONS_THRESHOLD"] || 500).to_i
|
42
42
|
self.cache_hit_rate_threshold = 99
|
43
43
|
self.env = ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
|
44
44
|
self.show_migrations = true
|
@@ -46,7 +46,7 @@ module PgHero
|
|
46
46
|
class << self
|
47
47
|
extend Forwardable
|
48
48
|
def_delegators :primary_database, :access_key_id, :analyze, :analyze_tables, :autoindex, :autovacuum_danger,
|
49
|
-
:best_index, :blocked_queries, :connection_sources, :connection_stats,
|
49
|
+
:best_index, :blocked_queries, :connection_sources, :connection_states, :connection_stats,
|
50
50
|
:cpu_usage, :create_user, :database_size, :db_instance_identifier, :disable_query_stats, :drop_user,
|
51
51
|
:duplicate_indexes, :enable_query_stats, :explain, :historical_query_stats_enabled?, :index_caching,
|
52
52
|
:index_hit_rate, :index_usage, :indexes, :invalid_indexes, :kill, :kill_all, :kill_long_running_queries,
|
@@ -5,6 +5,22 @@ module PgHero
|
|
5
5
|
select_one("SELECT COUNT(*) FROM pg_stat_activity")
|
6
6
|
end
|
7
7
|
|
8
|
+
def connection_states
|
9
|
+
states = select_all <<-SQL
|
10
|
+
SELECT
|
11
|
+
state,
|
12
|
+
COUNT(*) AS connections
|
13
|
+
FROM
|
14
|
+
pg_stat_activity
|
15
|
+
GROUP BY
|
16
|
+
1
|
17
|
+
ORDER BY
|
18
|
+
2 DESC, 1
|
19
|
+
SQL
|
20
|
+
|
21
|
+
Hash[states.map { |s| [s[:state], s[:connections]] }]
|
22
|
+
end
|
23
|
+
|
8
24
|
def connection_sources
|
9
25
|
select_all <<-SQL
|
10
26
|
SELECT
|
@@ -114,32 +114,19 @@ module PgHero
|
|
114
114
|
SQL
|
115
115
|
end
|
116
116
|
|
117
|
-
def invalid_indexes
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
pg_catalog.pg_class c,
|
125
|
-
pg_catalog.pg_namespace n,
|
126
|
-
pg_catalog.pg_index i
|
127
|
-
WHERE
|
128
|
-
i.indisvalid = false
|
129
|
-
AND i.indexrelid = c.oid
|
130
|
-
AND c.relnamespace = n.oid
|
131
|
-
AND n.nspname != 'pg_catalog'
|
132
|
-
AND n.nspname != 'information_schema'
|
133
|
-
AND n.nspname != 'pg_toast'
|
134
|
-
ORDER BY
|
135
|
-
c.relname
|
136
|
-
SQL
|
117
|
+
def invalid_indexes(indexes: nil)
|
118
|
+
indexes = (indexes || self.indexes).select { |i| !i[:valid] && !i[:creating] }
|
119
|
+
indexes.each do |index|
|
120
|
+
# map name -> index for backward compatibility
|
121
|
+
index[:index] = index[:name]
|
122
|
+
end
|
123
|
+
indexes
|
137
124
|
end
|
138
125
|
|
139
126
|
# TODO parse array properly
|
140
|
-
#
|
127
|
+
# https://stackoverflow.com/questions/2204058/list-columns-with-indexes-in-postgresql
|
141
128
|
def indexes
|
142
|
-
select_all(<<-SQL
|
129
|
+
indexes = select_all(<<-SQL
|
143
130
|
SELECT
|
144
131
|
schemaname AS schema,
|
145
132
|
t.relname AS table,
|
@@ -166,15 +153,28 @@ module PgHero
|
|
166
153
|
1, 2
|
167
154
|
SQL
|
168
155
|
).map { |v| v[:columns] = v[:columns].sub(") WHERE (", " WHERE ").split(", ").map { |c| unquote(c) }; v }
|
156
|
+
|
157
|
+
# determine if any invalid indexes being created
|
158
|
+
# hacky, but works for simple cases
|
159
|
+
# can be a race condition, but that's fine
|
160
|
+
invalid_indexes = indexes.select { |i| !i[:valid] }
|
161
|
+
if invalid_indexes.any?
|
162
|
+
create_index_queries = running_queries.select { |q| /\s*CREATE\s+INDEX\s+CONCURRENTLY\s+/i.match(q[:query]) }
|
163
|
+
invalid_indexes.each do |index|
|
164
|
+
index[:creating] = create_index_queries.any? { |q| q[:query].include?(index[:table]) && index[:columns].all? { |c| q[:query].include?(c) } }
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
indexes
|
169
169
|
end
|
170
170
|
|
171
171
|
def duplicate_indexes(indexes: nil)
|
172
172
|
dup_indexes = []
|
173
173
|
|
174
|
-
indexes_by_table = (indexes || self.indexes).group_by { |i| i[:table] }
|
175
|
-
indexes_by_table.values.flatten.select { |i|
|
176
|
-
covering_index = indexes_by_table[index[:table]].find { |i|
|
177
|
-
if covering_index && (covering_index[:columns] != index[:columns] || index[:name] > covering_index[:name])
|
174
|
+
indexes_by_table = (indexes || self.indexes).group_by { |i| [i[:schema], i[:table]] }
|
175
|
+
indexes_by_table.values.flatten.select { |i| i[:valid] && !i[:primary] && !i[:unique] }.each do |index|
|
176
|
+
covering_index = indexes_by_table[[index[:schema], index[:table]]].find { |i| i[:valid] && i[:name] != index[:name] && index_covers?(i[:columns], index[:columns]) && i[:using] == index[:using] && i[:indexprs] == index[:indexprs] && i[:indpred] == index[:indpred] }
|
177
|
+
if covering_index && (covering_index[:columns] != index[:columns] || index[:name] > covering_index[:name] || covering_index[:primary] || covering_index[:unique])
|
178
178
|
dup_indexes << {unneeded_index: index, covering_index: covering_index}
|
179
179
|
end
|
180
180
|
end
|
@@ -321,6 +321,12 @@ module PgHero
|
|
321
321
|
index_name
|
322
322
|
SQL
|
323
323
|
end
|
324
|
+
|
325
|
+
protected
|
326
|
+
|
327
|
+
def index_covers?(indexed_columns, columns)
|
328
|
+
indexed_columns.first(columns.size) == columns
|
329
|
+
end
|
324
330
|
end
|
325
331
|
end
|
326
332
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module PgHero
|
2
2
|
module Methods
|
3
3
|
module Maintenance
|
4
|
-
#
|
4
|
+
# https://www.postgresql.org/docs/9.1/static/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND
|
5
5
|
# "the system will shut down and refuse to start any new transactions
|
6
6
|
# once there are fewer than 1 million transactions left until wraparound"
|
7
7
|
# warn when 10,000,000 transactions left
|
@@ -64,7 +64,7 @@ module PgHero
|
|
64
64
|
false
|
65
65
|
end
|
66
66
|
|
67
|
-
#
|
67
|
+
# https://stackoverflow.com/questions/20582500/how-to-check-if-a-table-exists-in-a-given-schema
|
68
68
|
def historical_query_stats_enabled?
|
69
69
|
# TODO use schema from config
|
70
70
|
# make sure primary database is PostgreSQL first
|
@@ -143,7 +143,7 @@ module PgHero
|
|
143
143
|
total_time / 1000 / 60 AS total_minutes,
|
144
144
|
(total_time / calls) AS average_time,
|
145
145
|
calls,
|
146
|
-
(SELECT regexp_matches(query, '
|
146
|
+
(SELECT regexp_matches(query, '.*/\\*(.+?)\\*/'))[1] AS origin
|
147
147
|
FROM
|
148
148
|
pghero_query_stats
|
149
149
|
WHERE
|
@@ -8,7 +8,7 @@ module PgHero
|
|
8
8
|
@replica
|
9
9
|
end
|
10
10
|
|
11
|
-
#
|
11
|
+
# https://www.postgresql.org/message-id/CADKbJJWz9M0swPT3oqe8f9+tfD4-F54uE6Xtkh4nERpVsQnjnw@mail.gmail.com
|
12
12
|
def replication_lag
|
13
13
|
with_feature_support do
|
14
14
|
lag_condition =
|
@@ -36,8 +36,12 @@ module PgHero
|
|
36
36
|
|
37
37
|
add_sequence_attributes(sequences)
|
38
38
|
|
39
|
-
|
40
|
-
|
39
|
+
sequences.select { |s| s[:readable] }.each_slice(1024) do |slice|
|
40
|
+
sql = slice.map { |s| "SELECT last_value FROM #{quote_ident(s[:schema])}.#{quote_ident(s[:sequence])}" }.join(" UNION ALL ")
|
41
|
+
|
42
|
+
select_all(sql).zip(slice) do |row, seq|
|
43
|
+
seq[:last_value] = row[:last_value]
|
44
|
+
end
|
41
45
|
end
|
42
46
|
|
43
47
|
sequences.sort_by { |s| s[:sequence] }
|
@@ -217,12 +217,8 @@ module PgHero
|
|
217
217
|
{table: table, where: where, sort: sort}
|
218
218
|
end
|
219
219
|
|
220
|
-
def index_covers?(indexed_columns, columns)
|
221
|
-
indexed_columns.first(columns.size) == columns
|
222
|
-
end
|
223
|
-
|
224
220
|
# TODO better row estimation
|
225
|
-
#
|
221
|
+
# https://www.postgresql.org/docs/current/static/row-estimation-examples.html
|
226
222
|
def row_estimates(stats, total_rows, rows_left, op)
|
227
223
|
case op
|
228
224
|
when "null"
|
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.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -109,22 +109,15 @@ dependencies:
|
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
description:
|
112
|
-
email:
|
113
|
-
- andrew@chartkick.com
|
112
|
+
email: andrew@chartkick.com
|
114
113
|
executables: []
|
115
114
|
extensions: []
|
116
115
|
extra_rdoc_files: []
|
117
116
|
files:
|
118
|
-
- ".gitattributes"
|
119
|
-
- ".github/ISSUE_TEMPLATE.md"
|
120
|
-
- ".gitignore"
|
121
|
-
- ".travis.yml"
|
122
117
|
- CHANGELOG.md
|
123
118
|
- CONTRIBUTING.md
|
124
|
-
- Gemfile
|
125
119
|
- LICENSE.txt
|
126
120
|
- README.md
|
127
|
-
- Rakefile
|
128
121
|
- app/assets/images/pghero/favicon.png
|
129
122
|
- app/assets/javascripts/pghero/Chart.bundle.js
|
130
123
|
- app/assets/javascripts/pghero/application.js
|
@@ -156,20 +149,12 @@ files:
|
|
156
149
|
- app/views/pg_hero/home/system.html.erb
|
157
150
|
- app/views/pg_hero/home/tune.html.erb
|
158
151
|
- config/routes.rb
|
159
|
-
- guides/Contributing.md
|
160
|
-
- guides/Docker.md
|
161
|
-
- guides/Heroku.md
|
162
|
-
- guides/Linux.md
|
163
|
-
- guides/Permissions.md
|
164
|
-
- guides/Query-Stats.md
|
165
|
-
- guides/Rails.md
|
166
|
-
- guides/Suggested-Indexes.md
|
167
152
|
- lib/generators/pghero/config_generator.rb
|
168
153
|
- lib/generators/pghero/query_stats_generator.rb
|
169
154
|
- lib/generators/pghero/space_stats_generator.rb
|
170
|
-
- lib/generators/pghero/templates/config.yml
|
171
|
-
- lib/generators/pghero/templates/query_stats.rb
|
172
|
-
- lib/generators/pghero/templates/space_stats.rb
|
155
|
+
- lib/generators/pghero/templates/config.yml.tt
|
156
|
+
- lib/generators/pghero/templates/query_stats.rb.tt
|
157
|
+
- lib/generators/pghero/templates/space_stats.rb.tt
|
173
158
|
- lib/pghero.rb
|
174
159
|
- lib/pghero/connection.rb
|
175
160
|
- lib/pghero/database.rb
|
@@ -193,13 +178,6 @@ files:
|
|
193
178
|
- lib/pghero/query_stats.rb
|
194
179
|
- lib/pghero/version.rb
|
195
180
|
- lib/tasks/pghero.rake
|
196
|
-
- pghero.gemspec
|
197
|
-
- test/basic_test.rb
|
198
|
-
- test/best_index_test.rb
|
199
|
-
- test/gemfiles/activerecord41.gemfile
|
200
|
-
- test/gemfiles/activerecord42.gemfile
|
201
|
-
- test/suggested_indexes_test.rb
|
202
|
-
- test/test_helper.rb
|
203
181
|
homepage: https://github.com/ankane/pghero
|
204
182
|
licenses:
|
205
183
|
- MIT
|
@@ -212,7 +190,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
212
190
|
requirements:
|
213
191
|
- - ">="
|
214
192
|
- !ruby/object:Gem::Version
|
215
|
-
version: 2.2
|
193
|
+
version: '2.2'
|
216
194
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
217
195
|
requirements:
|
218
196
|
- - ">="
|
@@ -220,22 +198,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
220
198
|
version: '0'
|
221
199
|
requirements: []
|
222
200
|
rubyforge_project:
|
223
|
-
rubygems_version: 2.7.
|
201
|
+
rubygems_version: 2.7.7
|
224
202
|
signing_key:
|
225
203
|
specification_version: 4
|
226
204
|
summary: A performance dashboard for Postgres
|
227
|
-
test_files:
|
228
|
-
- guides/Contributing.md
|
229
|
-
- guides/Docker.md
|
230
|
-
- guides/Heroku.md
|
231
|
-
- guides/Linux.md
|
232
|
-
- guides/Permissions.md
|
233
|
-
- guides/Query-Stats.md
|
234
|
-
- guides/Rails.md
|
235
|
-
- guides/Suggested-Indexes.md
|
236
|
-
- test/basic_test.rb
|
237
|
-
- test/best_index_test.rb
|
238
|
-
- test/gemfiles/activerecord41.gemfile
|
239
|
-
- test/gemfiles/activerecord42.gemfile
|
240
|
-
- test/suggested_indexes_test.rb
|
241
|
-
- test/test_helper.rb
|
205
|
+
test_files: []
|