pghero 1.1.1 → 1.1.2
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 -0
- data/app/views/pg_hero/home/index.html.erb +30 -0
- data/guides/Rails.md +1 -0
- data/lib/pghero.rb +55 -27
- data/lib/pghero/database.rb +21 -0
- 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: b2ceee79d2694edb6770f2fd2f41d466c530e552
|
4
|
+
data.tar.gz: 0ea166a5189ee67ac67a96a0dc30f7f9b4835727
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35d700acc843dab6c8cd99186da0314ef04440fed39eb911ec322290508d84595441766698c399efe89a09a003c5b6c50c9a4f154f67498e9d06792d35532e98
|
7
|
+
data.tar.gz: 80c608de2ad8dfe8bccb4ee34d39cdfb28d7859e089500378ef83ba304081151e89386a45549471007a06be583bf828de6bb7ec2e5b3ffcbcb48e7df5f9c9bf5
|
data/CHANGELOG.md
CHANGED
@@ -17,6 +17,7 @@ module PgHero
|
|
17
17
|
@table_hit_rate = PgHero.table_hit_rate
|
18
18
|
@missing_indexes = PgHero.missing_indexes
|
19
19
|
@unused_indexes = PgHero.unused_indexes.select { |q| q["index_scans"].to_i == 0 }
|
20
|
+
@invalid_indexes = PgHero.invalid_indexes
|
20
21
|
@good_cache_rate = @table_hit_rate >= 0.99 && @index_hit_rate >= 0.99
|
21
22
|
@query_stats_available = PgHero.query_stats_available?
|
22
23
|
@total_connections = PgHero.total_connections
|
@@ -40,6 +40,13 @@
|
|
40
40
|
No slow queries
|
41
41
|
<% end %>
|
42
42
|
</div>
|
43
|
+
<div class="alert alert-<%= @invalid_indexes.empty? ? "success" : "warning" %>">
|
44
|
+
<% if @invalid_indexes.any? %>
|
45
|
+
<%= pluralize(@invalid_indexes.size, "invalid index", "invalid indexes") %>
|
46
|
+
<% else %>
|
47
|
+
No invalid indexes
|
48
|
+
<% end %>
|
49
|
+
</div>
|
43
50
|
<div class="alert alert-<%= @missing_indexes.empty? ? "success" : "warning" %>">
|
44
51
|
<% if @missing_indexes.any? %>
|
45
52
|
<%= pluralize(@missing_indexes.size, "table appears", "tables appear") %> to be missing indexes
|
@@ -126,6 +133,29 @@ pg_stat_statements.track = all</pre>
|
|
126
133
|
</div>
|
127
134
|
<% end %>
|
128
135
|
|
136
|
+
<% if @invalid_indexes.any? %>
|
137
|
+
<div class="content">
|
138
|
+
<h1>Invalid Indexes</h1>
|
139
|
+
|
140
|
+
<p>These indexes exist, but can’t be used. You should recreate them.</p>
|
141
|
+
|
142
|
+
<table class="table">
|
143
|
+
<thead>
|
144
|
+
<tr>
|
145
|
+
<th>Name</th>
|
146
|
+
</tr>
|
147
|
+
</thead>
|
148
|
+
<tbody>
|
149
|
+
<% @invalid_indexes.each do |query| %>
|
150
|
+
<tr>
|
151
|
+
<td><%= query["index"] %></td>
|
152
|
+
</tr>
|
153
|
+
<% end %>
|
154
|
+
</tbody>
|
155
|
+
</table>
|
156
|
+
</div>
|
157
|
+
<% end %>
|
158
|
+
|
129
159
|
<% if @missing_indexes.any? %>
|
130
160
|
<div class="content">
|
131
161
|
<h1>Missing Indexes</h1>
|
data/guides/Rails.md
CHANGED
data/lib/pghero.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "pghero/version"
|
2
2
|
require "active_record"
|
3
|
+
require "pghero/database"
|
3
4
|
require "pghero/engine" if defined?(Rails)
|
4
5
|
require "pghero/tasks"
|
5
6
|
|
@@ -49,8 +50,18 @@ module PgHero
|
|
49
50
|
end
|
50
51
|
end
|
51
52
|
|
53
|
+
def databases
|
54
|
+
@databases ||= begin
|
55
|
+
Hash[
|
56
|
+
config["databases"].map do |id, c|
|
57
|
+
[id, PgHero::Database.new(id, c)]
|
58
|
+
end
|
59
|
+
]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
52
63
|
def primary_database
|
53
|
-
|
64
|
+
databases.keys.first
|
54
65
|
end
|
55
66
|
|
56
67
|
def current_database
|
@@ -58,20 +69,11 @@ module PgHero
|
|
58
69
|
end
|
59
70
|
|
60
71
|
def current_database=(database)
|
61
|
-
raise "Database not found" unless
|
72
|
+
raise "Database not found" unless databases[database]
|
62
73
|
Thread.current[:pghero_current_database] = database.to_s
|
63
|
-
Thread.current[:pghero_connection] = nil
|
64
74
|
database
|
65
75
|
end
|
66
76
|
|
67
|
-
def database_config(database)
|
68
|
-
config["databases"][database.to_s]
|
69
|
-
end
|
70
|
-
|
71
|
-
def current_config
|
72
|
-
database_config(current_database)
|
73
|
-
end
|
74
|
-
|
75
77
|
def with(database)
|
76
78
|
previous_database = current_database
|
77
79
|
begin
|
@@ -238,6 +240,26 @@ module PgHero
|
|
238
240
|
SQL
|
239
241
|
end
|
240
242
|
|
243
|
+
def invalid_indexes
|
244
|
+
select_all <<-SQL
|
245
|
+
SELECT
|
246
|
+
c.relname AS index
|
247
|
+
FROM
|
248
|
+
pg_catalog.pg_class c,
|
249
|
+
pg_catalog.pg_namespace n,
|
250
|
+
pg_catalog.pg_index i
|
251
|
+
WHERE
|
252
|
+
i.indisvalid = false
|
253
|
+
AND i.indexrelid = c.oid
|
254
|
+
AND c.relnamespace = n.oid
|
255
|
+
AND n.nspname != 'pg_catalog'
|
256
|
+
AND n.nspname != 'information_schema'
|
257
|
+
AND n.nspname != 'pg_toast'
|
258
|
+
ORDER BY
|
259
|
+
c.relname
|
260
|
+
SQL
|
261
|
+
end
|
262
|
+
|
241
263
|
def relation_sizes
|
242
264
|
select_all <<-SQL
|
243
265
|
SELECT
|
@@ -414,7 +436,7 @@ module PgHero
|
|
414
436
|
|
415
437
|
def ssl_used?
|
416
438
|
ssl_used = nil
|
417
|
-
|
439
|
+
connection_model.transaction do
|
418
440
|
execute("CREATE EXTENSION IF NOT EXISTS sslinfo")
|
419
441
|
ssl_used = select_all("SELECT ssl_is_used()").first["ssl_is_used"] == "t"
|
420
442
|
raise ActiveRecord::Rollback
|
@@ -436,9 +458,15 @@ module PgHero
|
|
436
458
|
|
437
459
|
def rds_stats(metric_name)
|
438
460
|
if system_stats_enabled?
|
439
|
-
|
461
|
+
client =
|
462
|
+
if defined?(Aws)
|
463
|
+
Aws::CloudWatch::Client.new(access_key_id: access_key_id, secret_access_key: secret_access_key)
|
464
|
+
else
|
465
|
+
AWS::CloudWatch.new(access_key_id: access_key_id, secret_access_key: secret_access_key).client
|
466
|
+
end
|
467
|
+
|
440
468
|
now = Time.now
|
441
|
-
resp =
|
469
|
+
resp = client.get_metric_statistics(
|
442
470
|
namespace: "AWS/RDS",
|
443
471
|
metric_name: metric_name,
|
444
472
|
dimensions: [{name: "DBInstanceIdentifier", value: db_instance_identifier}],
|
@@ -458,7 +486,7 @@ module PgHero
|
|
458
486
|
end
|
459
487
|
|
460
488
|
def system_stats_enabled?
|
461
|
-
!!(defined?(AWS) && access_key_id && secret_access_key && db_instance_identifier)
|
489
|
+
!!((defined?(Aws) || defined?(AWS)) && access_key_id && secret_access_key && db_instance_identifier)
|
462
490
|
end
|
463
491
|
|
464
492
|
def random_password
|
@@ -469,7 +497,7 @@ module PgHero
|
|
469
497
|
def create_user(user, options = {})
|
470
498
|
password = options[:password] || random_password
|
471
499
|
schema = options[:schema] || "public"
|
472
|
-
database = options[:database] ||
|
500
|
+
database = options[:database] || connection_model.connection_config[:database]
|
473
501
|
|
474
502
|
commands =
|
475
503
|
[
|
@@ -496,7 +524,7 @@ module PgHero
|
|
496
524
|
end
|
497
525
|
|
498
526
|
# run commands
|
499
|
-
|
527
|
+
connection_model.transaction do
|
500
528
|
commands.each do |command|
|
501
529
|
execute command
|
502
530
|
end
|
@@ -507,7 +535,7 @@ module PgHero
|
|
507
535
|
|
508
536
|
def drop_user(user, options = {})
|
509
537
|
schema = options[:schema] || "public"
|
510
|
-
database = options[:database] ||
|
538
|
+
database = options[:database] || connection_model.connection_config[:database]
|
511
539
|
|
512
540
|
# thanks shiftb
|
513
541
|
commands =
|
@@ -524,7 +552,7 @@ module PgHero
|
|
524
552
|
]
|
525
553
|
|
526
554
|
# run commands
|
527
|
-
|
555
|
+
connection_model.transaction do
|
528
556
|
commands.each do |command|
|
529
557
|
execute command
|
530
558
|
end
|
@@ -542,7 +570,7 @@ module PgHero
|
|
542
570
|
end
|
543
571
|
|
544
572
|
def db_instance_identifier
|
545
|
-
|
573
|
+
databases[current_database].db_instance_identifier
|
546
574
|
end
|
547
575
|
|
548
576
|
def explain(sql)
|
@@ -551,7 +579,7 @@ module PgHero
|
|
551
579
|
explain_safe = explain_safe?
|
552
580
|
|
553
581
|
# use transaction for safety
|
554
|
-
|
582
|
+
connection_model.transaction do
|
555
583
|
if !explain_safe && (sql.sub(/;\z/, "").include?(";") || sql.upcase.include?("COMMIT"))
|
556
584
|
raise ActiveRecord::StatementInvalid, "Unsafe statement"
|
557
585
|
end
|
@@ -575,7 +603,7 @@ module PgHero
|
|
575
603
|
maintenance_work_mem checkpoint_segments checkpoint_completion_target
|
576
604
|
wal_buffers default_statistics_target
|
577
605
|
)
|
578
|
-
values = Hash[select_all(
|
606
|
+
values = Hash[select_all(connection_model.send(:sanitize_sql_array, ["SELECT name, setting, unit FROM pg_settings WHERE name IN (?)", names])).sort_by { |row| names.index(row["name"]) }.map { |row| [row["name"], friendly_value(row["setting"], row["unit"])] }]
|
579
607
|
Hash[names.map { |name| [name, values[name]] }]
|
580
608
|
end
|
581
609
|
|
@@ -696,12 +724,12 @@ module PgHero
|
|
696
724
|
connection.execute(sql)
|
697
725
|
end
|
698
726
|
|
727
|
+
def connection_model
|
728
|
+
databases[current_database].connection_model
|
729
|
+
end
|
730
|
+
|
699
731
|
def connection
|
700
|
-
|
701
|
-
Connection.establish_connection(current_config["url"])
|
702
|
-
Thread.current[:pghero_connection] = true
|
703
|
-
end
|
704
|
-
Connection.connection
|
732
|
+
connection_model.connection
|
705
733
|
end
|
706
734
|
|
707
735
|
# from ActiveSupport
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module PgHero
|
2
|
+
class Database
|
3
|
+
attr_reader :id, :config, :connection_model
|
4
|
+
|
5
|
+
def initialize(id, config)
|
6
|
+
@id = id
|
7
|
+
@config = config
|
8
|
+
@connection_model =
|
9
|
+
Class.new(PgHero::Connection) do
|
10
|
+
def self.name
|
11
|
+
"PgHero::Connection::#{object_id}"
|
12
|
+
end
|
13
|
+
establish_connection(config["url"]) if config["url"]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def db_instance_identifier
|
18
|
+
@config["database_instance_identifier"]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
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.1.
|
4
|
+
version: 1.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -120,6 +120,7 @@ files:
|
|
120
120
|
- lib/generators/pghero/query_stats_generator.rb
|
121
121
|
- lib/generators/pghero/templates/query_stats.rb
|
122
122
|
- lib/pghero.rb
|
123
|
+
- lib/pghero/database.rb
|
123
124
|
- lib/pghero/engine.rb
|
124
125
|
- lib/pghero/tasks.rb
|
125
126
|
- lib/pghero/version.rb
|