pghero 2.2.1 → 2.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7edafa3113ab1d1e6dd6df9c2abb1fe90ccd1077811475c001cfef05c021e8d9
4
- data.tar.gz: f7e65b01aa540e9023c30c9cefcbf2fd7381fb71b24852043c82e81e878bc8f7
3
+ metadata.gz: 4874b649139843b2369ad67f3b6620b764fd83ffc61c06dfdc1a79955ebed872
4
+ data.tar.gz: 60e7beb266ac32ca3d2dc9de5c1a57b3641c6eed6a754a1dc4c71e5cab4876c2
5
5
  SHA512:
6
- metadata.gz: 857502906ac831709d69a371f4da5ca2bce260f55f72731f3db48be28b159d0816080e2dd90f87301653c609dc5d0dd27ec36d0e58f0649c45d18e9046851bc0
7
- data.tar.gz: f54eb2b5e13a75b691fcb3efcc3b63d921a33194caf2f4d62147f8d7090faa4cfa70abfc379315bed61378176f2ef8919747990ed9ba8ff4f3886a32f54edbd3
6
+ metadata.gz: ee85c07246b1941f9cb1086f684ab79c43847f2435b8ed588bb188821c67e735e2362a048fe522ce732dd9f921d282c794b629f94ba8611820322b1a1b14312c
7
+ data.tar.gz: a4de31e8bb1762fe2a7a0ed5f1aea4caca2e9f016f7d9c6c8c7515a1d6067e933d6bdf8d8f8a85615e9718d6aadef23d4b7db3ee00590372d340d0f256256ce8
@@ -1,3 +1,9 @@
1
+ ## 2.3.0
2
+
3
+ - Added support for Postgres 12 beta 1
4
+ - Added methods and tasks for cleaning up stats
5
+ - Dropped support for Rails < 5
6
+
1
7
  ## 2.2.1
2
8
 
3
9
  - Added `config_path` option
@@ -390,11 +390,7 @@ module PgHero
390
390
  end
391
391
 
392
392
  def render_text(message)
393
- if Rails::VERSION::MAJOR >= 5
394
- render plain: message
395
- else
396
- render text: message
397
- end
393
+ render plain: message
398
394
  end
399
395
 
400
396
  def ensure_query_stats
@@ -20,8 +20,7 @@
20
20
  <% end %>
21
21
  </td>
22
22
  <td class="text-right">
23
- <% button_path, button_options = Rails.version >= "4.1" ? [explain_path, {params: {query: query[:query]}}] : [explain_path(query: query[:query]), {}] %>
24
- <%= button_to "Explain", button_path, button_options.merge(form: {target: "_blank"}, class: "btn btn-info") %>
23
+ <%= button_to "Explain", explain_path, params: {query: query[:query]}, form: {target: "_blank"}, class: "btn btn-info" %>
25
24
  <%= button_to "Kill", kill_path(pid: query[:pid]), class: "btn btn-danger" %>
26
25
  </td>
27
26
  </tr>
@@ -6,8 +6,7 @@
6
6
 
7
7
  <% if @explainable_query %>
8
8
  <p>
9
- <% button_path, button_options = Rails.version >= "4.1" ? [explain_path, {params: {query: @explainable_query}}] : [explain_path(query: @explainable_query), {}] %>
10
- <%= button_to "Explain", button_path, button_options.merge(form: {target: "_blank"}, class: "btn btn-info") %>
9
+ <%= button_to "Explain", explain_path, params: {query: @explainable_query}, form: {target: "_blank"}, class: "btn btn-info" %>
11
10
  </p>
12
11
  <% end %>
13
12
 
@@ -3,7 +3,7 @@ require "rails/generators"
3
3
  module Pghero
4
4
  module Generators
5
5
  class ConfigGenerator < Rails::Generators::Base
6
- source_root File.expand_path("../templates", __FILE__)
6
+ source_root File.join(__dir__, "templates")
7
7
 
8
8
  def create_initializer
9
9
  template "config.yml", "config/pghero.yml"
@@ -1,34 +1,17 @@
1
- # taken from https://github.com/collectiveidea/audited/blob/master/lib/generators/audited/install_generator.rb
2
- require "rails/generators"
3
- require "rails/generators/migration"
4
- require "active_record"
5
1
  require "rails/generators/active_record"
6
2
 
7
3
  module Pghero
8
4
  module Generators
9
5
  class QueryStatsGenerator < Rails::Generators::Base
10
- include Rails::Generators::Migration
11
-
12
- source_root File.expand_path("../templates", __FILE__)
13
-
14
- # Implement the required interface for Rails::Generators::Migration.
15
- def self.next_migration_number(dirname) #:nodoc:
16
- next_migration_number = current_migration_number(dirname) + 1
17
- if ::ActiveRecord::Base.timestamped_migrations
18
- [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max
19
- else
20
- "%.3d" % next_migration_number
21
- end
22
- end
6
+ include ActiveRecord::Generators::Migration
7
+ source_root File.join(__dir__, "templates")
23
8
 
24
9
  def copy_migration
25
10
  migration_template "query_stats.rb", "db/migrate/create_pghero_query_stats.rb", migration_version: migration_version
26
11
  end
27
12
 
28
13
  def migration_version
29
- if ActiveRecord::VERSION::MAJOR >= 5
30
- "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
31
- end
14
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
32
15
  end
33
16
  end
34
17
  end
@@ -1,34 +1,17 @@
1
- # taken from https://github.com/collectiveidea/audited/blob/master/lib/generators/audited/install_generator.rb
2
- require "rails/generators"
3
- require "rails/generators/migration"
4
- require "active_record"
5
1
  require "rails/generators/active_record"
6
2
 
7
3
  module Pghero
8
4
  module Generators
9
5
  class SpaceStatsGenerator < Rails::Generators::Base
10
- include Rails::Generators::Migration
11
-
12
- source_root File.expand_path("../templates", __FILE__)
13
-
14
- # Implement the required interface for Rails::Generators::Migration.
15
- def self.next_migration_number(dirname) #:nodoc:
16
- next_migration_number = current_migration_number(dirname) + 1
17
- if ::ActiveRecord::Base.timestamped_migrations
18
- [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max
19
- else
20
- "%.3d" % next_migration_number
21
- end
22
- end
6
+ include ActiveRecord::Generators::Migration
7
+ source_root File.join(__dir__, "templates")
23
8
 
24
9
  def copy_migration
25
10
  migration_template "space_stats.rb", "db/migrate/create_pghero_space_stats.rb", migration_version: migration_version
26
11
  end
27
12
 
28
13
  def migration_version
29
- if ActiveRecord::VERSION::MAJOR >= 5
30
- "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
31
- end
14
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
32
15
  end
33
16
  end
34
17
  end
@@ -26,7 +26,9 @@ require "pghero/version"
26
26
 
27
27
  module PgHero
28
28
  autoload :Connection, "pghero/connection"
29
+ autoload :Stats, "pghero/stats"
29
30
  autoload :QueryStats, "pghero/query_stats"
31
+ autoload :SpaceStats, "pghero/space_stats"
30
32
 
31
33
  class Error < StandardError; end
32
34
  class NotEnabled < Error; end
@@ -137,7 +139,7 @@ module PgHero
137
139
 
138
140
  def autoindex_all(create: false, verbose: true)
139
141
  each_database do |database|
140
- puts "Autoindexing #{database}..." if verbose
142
+ puts "Autoindexing #{database.id}..." if verbose
141
143
  database.autoindex(create: create)
142
144
  end
143
145
  end
@@ -146,6 +148,21 @@ module PgHero
146
148
  ActiveSupport::NumberHelper.number_to_human_size(value, precision: 3)
147
149
  end
148
150
 
151
+ # delete previous stats
152
+ # go database by database to use an index
153
+ # stats for old databases are not cleaned up since we can't use an index
154
+ def clean_query_stats
155
+ each_database do |database|
156
+ PgHero::QueryStats.where(database: database.id).where("captured_at < ?", 14.days.ago).delete_all
157
+ end
158
+ end
159
+
160
+ def clean_space_stats
161
+ each_database do |database|
162
+ PgHero::SpaceStats.where(database: database.id).where("captured_at < ?", 90.days.ago).delete_all
163
+ end
164
+ end
165
+
149
166
  private
150
167
 
151
168
  def each_database
@@ -38,8 +38,7 @@ module PgHero
38
38
  retries = 0
39
39
  begin
40
40
  result = conn.select_all(add_source(squish(sql)))
41
- cast_method = ActiveRecord::VERSION::MAJOR < 5 ? :type_cast : :cast_value
42
- result.map { |row| Hash[row.map { |col, val| [col.to_sym, result.column_types[col].send(cast_method, val)] }] }
41
+ result.map { |row| Hash[row.map { |col, val| [col.to_sym, result.column_types[col].send(:cast_value, val)] }] }
43
42
  rescue ActiveRecord::StatementInvalid => e
44
43
  # fix for random internal errors
45
44
  if e.message.include?("PG::InternalError") && retries < 2
@@ -81,7 +80,7 @@ module PgHero
81
80
  end
82
81
 
83
82
  def stats_connection
84
- ::PgHero::QueryStats.connection
83
+ ::PgHero::Stats.connection
85
84
  end
86
85
 
87
86
  def insert_stats(table, columns, values)
@@ -125,22 +124,7 @@ module PgHero
125
124
  end
126
125
 
127
126
  def table_exists?(table)
128
- ["PostgreSQL", "PostGIS"].include?(stats_connection.adapter_name) &&
129
- select_one_stats(<<-SQL
130
- SELECT EXISTS (
131
- SELECT
132
- 1
133
- FROM
134
- pg_catalog.pg_class c
135
- INNER JOIN
136
- pg_catalog.pg_namespace n ON n.oid = c.relnamespace
137
- WHERE
138
- n.nspname = 'public'
139
- AND c.relname = #{quote(table)}
140
- AND c.relkind = 'r'
141
- )
142
- SQL
143
- )
127
+ stats_connection.table_exists?(table)
144
128
  end
145
129
  end
146
130
  end
@@ -31,7 +31,7 @@ module PgHero
31
31
  end
32
32
 
33
33
  # from https://wiki.postgresql.org/wiki/Lock_Monitoring
34
- # and http://big-elephants.com/2013-09/exploring-query-locks-in-postgres/
34
+ # and https://big-elephants.com/2013-09/exploring-query-locks-in-postgres/
35
35
  def blocked_queries
36
36
  select_all <<-SQL
37
37
  SELECT
@@ -25,7 +25,7 @@ module PgHero
25
25
  WHERE
26
26
  NOT a.attisdropped
27
27
  AND a.attnum > 0
28
- AND d.adsrc LIKE 'nextval%'
28
+ AND pg_get_expr(d.adbin, d.adrelid) LIKE 'nextval%'
29
29
  AND n.nspname NOT LIKE 'pg\\_temp\\_%'
30
30
  SQL
31
31
 
@@ -1,7 +1,5 @@
1
1
  module PgHero
2
- class QueryStats < ActiveRecord::Base
3
- self.abstract_class = true
2
+ class QueryStats < Stats
4
3
  self.table_name = "pghero_query_stats"
5
- establish_connection ENV["PGHERO_STATS_DATABASE_URL"] if ENV["PGHERO_STATS_DATABASE_URL"]
6
4
  end
7
5
  end
@@ -0,0 +1,5 @@
1
+ module PgHero
2
+ class SpaceStats < Stats
3
+ self.table_name = "pghero_space_stats"
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ module PgHero
2
+ class Stats < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ establish_connection ENV["PGHERO_STATS_DATABASE_URL"] if ENV["PGHERO_STATS_DATABASE_URL"]
5
+ end
6
+ end
@@ -1,3 +1,3 @@
1
1
  module PgHero
2
- VERSION = "2.2.1"
2
+ VERSION = "2.3.0"
3
3
  end
@@ -1,21 +1,27 @@
1
1
  namespace :pghero do
2
- desc "capture query stats"
2
+ desc "Capture query stats"
3
3
  task capture_query_stats: :environment do
4
4
  PgHero.capture_query_stats(verbose: true)
5
5
  end
6
6
 
7
- desc "capture space stats"
7
+ desc "Capture space stats"
8
8
  task capture_space_stats: :environment do
9
9
  PgHero.capture_space_stats(verbose: true)
10
10
  end
11
11
 
12
- desc "analyze tables"
12
+ desc "Analyze tables"
13
13
  task analyze: :environment do
14
14
  PgHero.analyze_all(verbose: true, min_size: ENV["MIN_SIZE_GB"].to_f.gigabytes)
15
15
  end
16
16
 
17
- desc "autoindex"
17
+ desc "Autoindex tables"
18
18
  task autoindex: :environment do
19
19
  PgHero.autoindex_all(verbose: true, create: true)
20
20
  end
21
+
22
+ desc "Remove old query stats"
23
+ task clean_query_stats: :environment do
24
+ puts "Deleting old query stats..."
25
+ PgHero.clean_query_stats
26
+ end
21
27
  end
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.2.1
4
+ version: 2.3.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: 2019-06-05 00:00:00.000000000 Z
11
+ date: 2019-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '5'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '5'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activerecord-import
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -84,16 +84,16 @@ dependencies:
84
84
  name: pg
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "<"
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: 1.0.0
89
+ version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - "<"
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
- version: 1.0.0
96
+ version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: pg_query
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -176,6 +176,8 @@ files:
176
176
  - lib/pghero/methods/tables.rb
177
177
  - lib/pghero/methods/users.rb
178
178
  - lib/pghero/query_stats.rb
179
+ - lib/pghero/space_stats.rb
180
+ - lib/pghero/stats.rb
179
181
  - lib/pghero/version.rb
180
182
  - lib/tasks/pghero.rake
181
183
  homepage: https://github.com/ankane/pghero
@@ -190,7 +192,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
190
192
  requirements:
191
193
  - - ">="
192
194
  - !ruby/object:Gem::Version
193
- version: '2.2'
195
+ version: '2.4'
194
196
  required_rubygems_version: !ruby/object:Gem::Requirement
195
197
  requirements:
196
198
  - - ">="